From 211db8bf28002dcfefca32bb83c488265347c3cf Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 8 Dec 2016 10:37:36 -0800 Subject: [PATCH 001/185] Improvements to GIA visualization. --- src/aig/gia/giaShow.c | 770 +++++++++++++++++++++++++++--------------- 1 file changed, 505 insertions(+), 265 deletions(-) diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index 872ba6ec1..bc3727469 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -33,151 +33,6 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -/* -Vec_Int_t * Gia_WriteDotAigMarks( Gia_Man_t * p, Vec_Int_t * vFadds, Vec_Int_t * vHadds ) -{ - int i; - Vec_Int_t * vMarks = Vec_IntStart( Gia_ManObjNum(p) ); - for ( i = 0; i < Vec_IntSize(vHadds)/2; i++ ) - { - Vec_IntWriteEntry( vMarks, Vec_IntEntry(vHadds, 2*i+0), Abc_Var2Lit(i+1, 0) ); - Vec_IntWriteEntry( vMarks, Vec_IntEntry(vHadds, 2*i+1), Abc_Var2Lit(i+1, 0) ); - } - for ( i = 0; i < Vec_IntSize(vFadds)/5; i++ ) - { - Vec_IntWriteEntry( vMarks, Vec_IntEntry(vFadds, 5*i+3), Abc_Var2Lit(i+1, 1) ); - Vec_IntWriteEntry( vMarks, Vec_IntEntry(vFadds, 5*i+4), Abc_Var2Lit(i+1, 1) ); - } - return vMarks; -} -int Gia_WriteDotAigLevel_rec( Gia_Man_t * p, Vec_Int_t * vMarks, Vec_Int_t * vFadds, Vec_Int_t * vHadds, int Id, Vec_Int_t * vLevel ) -{ - int Level = Vec_IntEntry(vLevel, Id), Mark = Vec_IntEntry(vMarks, Id); - if ( Level || Mark == -1 ) - return Level; - if ( Mark == 0 ) - { - Gia_Obj_t * pObj = Gia_ManObj( p, Id ); - int Level0 = Gia_WriteDotAigLevel_rec( p, vMarks, vFadds, vHadds, Gia_ObjFaninId0(pObj, Id), vLevel ); - int Level1 = Gia_WriteDotAigLevel_rec( p, vMarks, vFadds, vHadds, Gia_ObjFaninId1(pObj, Id), vLevel ); - Level = Abc_MaxInt(Level0, Level1) + 1; - Vec_IntWriteEntry( vLevel, Id, Level ); - Vec_IntWriteEntry( vMarks, Id, -1 ); - } - else if ( Abc_LitIsCompl(Mark) ) // FA - { - int i, * pFanins = Vec_IntEntryP( vFadds, 5*(Abc_Lit2Var(Mark)-1) ); - assert( pFanins[3] == Id || pFanins[4] == Id ); - for ( i = 0; i < 3; i++ ) - Level = Abc_MaxInt( Level, Gia_WriteDotAigLevel_rec( p, vMarks, vFadds, vHadds, pFanins[i], vLevel ) ); - Vec_IntWriteEntry( vLevel, pFanins[3], Level+1 ); - Vec_IntWriteEntry( vLevel, pFanins[4], Level+1 ); - } - else // HA - { - int * pFanins = Vec_IntEntryP( vHadds, 2*(Abc_Lit2Var(Mark)-1) ); - Gia_Obj_t * pObj = Gia_ManObj( p, pFanins[1] ); - int Level0 = Gia_WriteDotAigLevel_rec( p, vMarks, vFadds, vHadds, Gia_ObjFaninId0(pObj, Id), vLevel ); - int Level1 = Gia_WriteDotAigLevel_rec( p, vMarks, vFadds, vHadds, Gia_ObjFaninId1(pObj, Id), vLevel ); - assert( pFanins[0] == Id || pFanins[1] == Id ); - Level = Abc_MaxInt(Level0, Level1) + 1; - Vec_IntWriteEntry( vLevel, pFanins[0], Level ); - Vec_IntWriteEntry( vLevel, pFanins[1], Level ); - } - return Level; -} -int Gia_WriteDotAigLevel( Gia_Man_t * p, Vec_Int_t * vFadds, Vec_Int_t * vHadds, Vec_Int_t ** pvMarks, Vec_Int_t ** pvLevel ) -{ - Vec_Int_t * vMarks = Gia_WriteDotAigMarks( p, vFadds, vHadds ); - Vec_Int_t * vLevel = Vec_IntStart( Gia_ManObjNum(p) ); - int i, Id, Level = 0; - Vec_IntWriteEntry( vMarks, 0, -1 ); - Gia_ManForEachCiId( p, Id, i ) - Vec_IntWriteEntry( vMarks, Id, -1 ); - Gia_ManForEachCoDriverId( p, Id, i ) - Level = Abc_MaxInt( Level, Gia_WriteDotAigLevel_rec(p, vMarks, vFadds, vHadds, Id, vLevel) ); - Gia_ManForEachCoId( p, Id, i ) - Vec_IntWriteEntry( vMarks, Id, -1 ); - *pvMarks = vMarks; - *pvLevel = vLevel; - return Level; -} -*/ -int Gia_WriteDotAigLevel( Gia_Man_t * p, Vec_Int_t * vFadds, Vec_Int_t * vHadds, Vec_Int_t * vRecord, Vec_Int_t ** pvLevel, Vec_Int_t ** pvMarks, Vec_Int_t ** pvRemap, Vec_Int_t ** pvRemap2 ) -{ - Vec_Int_t * vLevel = Vec_IntStart( Gia_ManObjNum(p) ); - Vec_Int_t * vMarks = Vec_IntStart( Gia_ManObjNum(p) ); - Vec_Int_t * vRemap = Vec_IntStartNatural( Gia_ManObjNum(p) ); - Vec_Int_t * vRemap2 = Vec_IntStartNatural( Gia_ManObjNum(p) ); - int i, k, Id, Entry, LevelMax = 0; - - Vec_IntWriteEntry( vMarks, 0, -1 ); - Gia_ManForEachCiId( p, Id, i ) - Vec_IntWriteEntry( vMarks, Id, -1 ); - Gia_ManForEachCoId( p, Id, i ) - Vec_IntWriteEntry( vMarks, Id, -1 ); - - Vec_IntForEachEntry( vRecord, Entry, i ) - { - int Level = 0; - int Node = Abc_Lit2Var2(Entry); - int Attr = Abc_Lit2Att2(Entry); - if ( Attr == 2 ) - { - int * pFanins = Vec_IntEntryP( vFadds, 5*Node ); - for ( k = 0; k < 3; k++ ) - Level = Abc_MaxInt( Level, Vec_IntEntry(vLevel, pFanins[k]) ); - Vec_IntWriteEntry( vLevel, pFanins[3], Level+1 ); - Vec_IntWriteEntry( vLevel, pFanins[4], Level+1 ); - Vec_IntWriteEntry( vMarks, pFanins[4], Entry ); - Vec_IntWriteEntry( vRemap, pFanins[3], pFanins[4] ); - Vec_IntWriteEntry( vRemap2, pFanins[4], pFanins[3] ); - //printf( "Making FA output %d.\n", pFanins[4] ); - } - else if ( Attr == 1 ) - { - int * pFanins = Vec_IntEntryP( vHadds, 2*Node ); - Gia_Obj_t * pObj = Gia_ManObj( p, pFanins[1] ); - int pFaninsIn[2] = { Gia_ObjFaninId0(pObj, pFanins[1]), Gia_ObjFaninId1(pObj, pFanins[1]) }; - for ( k = 0; k < 2; k++ ) - Level = Abc_MaxInt( Level, Vec_IntEntry(vLevel, pFaninsIn[k]) ); - Vec_IntWriteEntry( vLevel, pFanins[0], Level+1 ); - Vec_IntWriteEntry( vLevel, pFanins[1], Level+1 ); - Vec_IntWriteEntry( vMarks, pFanins[1], Entry ); - Vec_IntWriteEntry( vRemap, pFanins[0], pFanins[1] ); - Vec_IntWriteEntry( vRemap2, pFanins[1], pFanins[0] ); - //printf( "Making HA output %d %d.\n", pFanins[0], pFanins[1] ); - } - else // if ( Attr == 3 || Attr == 0 ) - { - Gia_Obj_t * pObj = Gia_ManObj( p, Node ); - int pFaninsIn[2] = { Gia_ObjFaninId0(pObj, Node), Gia_ObjFaninId1(pObj, Node) }; - for ( k = 0; k < 2; k++ ) - Level = Abc_MaxInt( Level, Vec_IntEntry(vLevel, pFaninsIn[k]) ); - Vec_IntWriteEntry( vLevel, Node, Level+1 ); - Vec_IntWriteEntry( vMarks, Node, -1 ); - //printf( "Making node %d.\n", Node ); - } - LevelMax = Abc_MaxInt( LevelMax, Level+1 ); - } - *pvLevel = vLevel; - *pvMarks = vMarks; - *pvRemap = vRemap; - *pvRemap2 = vRemap2; - return LevelMax; -} - /**Function************************************************************* Synopsis [Writes the graph structure of AIG for DOT.] @@ -190,17 +45,16 @@ int Gia_WriteDotAigLevel( Gia_Man_t * p, Vec_Int_t * vFadds, Vec_Int_t * vHadds, SeeAlso [] ***********************************************************************/ -void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int fAdders ) +void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold ) { - Vec_Int_t * vFadds = NULL, * vHadds = NULL, * vRecord = NULL, * vMarks = NULL, * vRemap = NULL, * vRemap2 = NULL; FILE * pFile; Gia_Obj_t * pNode;//, * pTemp, * pPrev; int LevelMax, Prev, Level, i; int fConstIsUsed = 0; - if ( Gia_ManAndNum(pMan) > 1000 ) + if ( Gia_ManAndNum(p) > 200 ) { - fprintf( stdout, "Cannot visualize AIG with more than 1000 nodes.\n" ); + fprintf( stdout, "Cannot visualize AIG with more than 200 nodes.\n" ); return; } if ( (pFile = fopen( pFileName, "w" )) == NULL ) @@ -211,28 +65,17 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int // mark the nodes if ( vBold ) - Gia_ManForEachObjVec( vBold, pMan, pNode, i ) + Gia_ManForEachObjVec( vBold, p, pNode, i ) pNode->fMark0 = 1; - else if ( pMan->nXors || pMan->nMuxes ) - Gia_ManForEachObj( pMan, pNode, i ) - if ( Gia_ObjIsXor(pNode) || Gia_ObjIsMux(pMan, pNode) ) + else if ( p->nXors || p->nMuxes ) + Gia_ManForEachObj( p, pNode, i ) + if ( Gia_ObjIsXor(pNode) || Gia_ObjIsMux(p, pNode) ) pNode->fMark0 = 1; // compute levels - if ( fAdders ) - { - Vec_IntFreeP( &pMan->vLevels ); - vFadds = Gia_ManDetectFullAdders( pMan, 0, NULL ); - vHadds = Gia_ManDetectHalfAdders( pMan, 0 ); - vRecord = Gia_PolynFindOrder( pMan, vFadds, vHadds, 0, 0 ); - LevelMax = 1 + Gia_WriteDotAigLevel( pMan, vFadds, vHadds, vRecord, &pMan->vLevels, &vMarks, &vRemap, &vRemap2 ); - } - else - LevelMax = 1 + Gia_ManLevelNum( pMan ); - - // set output levels - Gia_ManForEachCo( pMan, pNode, i ) - Vec_IntWriteEntry( pMan->vLevels, Gia_ObjId(pMan, pNode), LevelMax ); + LevelMax = 1 + Gia_ManLevelNum( p ); + Gia_ManForEachCo( p, pNode, i ) + Vec_IntWriteEntry( p->vLevels, Gia_ObjId(p, pNode), LevelMax ); // write the DOT header fprintf( pFile, "# %s\n", "AIG structure generated by IVY package" ); @@ -309,7 +152,7 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int fprintf( pFile, " fontsize=18,\n" ); fprintf( pFile, " fontname = \"Times-Roman\",\n" ); fprintf( pFile, " label=\"" ); - fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Gia_ManAndNum(pMan), LevelMax ); + fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Gia_ManAndNum(p), LevelMax ); fprintf( pFile, "\\n" ); fprintf( pFile, "\"\n" ); fprintf( pFile, " ];\n" ); @@ -323,9 +166,9 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int // the labeling node of this level fprintf( pFile, " Level%d;\n", LevelMax ); // generate the CO nodes - Gia_ManForEachCo( pMan, pNode, i ) + Gia_ManForEachCo( p, pNode, i ) { - if ( Gia_ObjFaninId0p(pMan, pNode) == 0 ) + if ( Gia_ObjFaninId0p(p, pNode) == 0 ) fConstIsUsed = 1; /* if ( fHaig || pNode->pEquiv == NULL ) @@ -336,7 +179,7 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int (Gia_ObjIsLatch(pNode)? "_in":""), pNode->Id, (Gia_ObjIsLatch(pNode)? "_in":""), Gia_Regular(pNode->pEquiv)->Id, Gia_IsComplement(pNode->pEquiv)? "\'":"" ); */ - fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(pMan, pNode), Gia_ObjId(pMan, pNode) ); + fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(p, pNode), Gia_ObjId(p, pNode) ); fprintf( pFile, ", shape = %s", "invtriangle" ); fprintf( pFile, ", color = coral, fillcolor = coral" ); @@ -353,11 +196,9 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int fprintf( pFile, " rank = same;\n" ); // the labeling node of this level fprintf( pFile, " Level%d;\n", Level ); - Gia_ManForEachObj( pMan, pNode, i ) + Gia_ManForEachObj( p, pNode, i ) { - if ( vMarks && Vec_IntEntry(vMarks, i) == 0 ) - continue; - if ( (int)Gia_ObjLevel(pMan, pNode) != Level ) + if ( (int)Gia_ObjLevel(p, pNode) != Level ) continue; /* if ( fHaig || pNode->pEquiv == NULL ) @@ -366,29 +207,14 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int fprintf( pFile, " Node%d [label = \"%d(%d%s)\"", pNode->Id, pNode->Id, Gia_Regular(pNode->pEquiv)->Id, Gia_IsComplement(pNode->pEquiv)? "\'":"" ); */ - if ( vMarks && Vec_IntEntry(vMarks, i) > 0 ) - { - fprintf( pFile, " Node%d [label = \"%d_%d\"", i, Vec_IntEntry(vRemap2, i), i ); - if ( Abc_Lit2Att2(Vec_IntEntry(vMarks, i)) == 2 ) - fprintf( pFile, ", shape = doubleoctagon" ); - else - fprintf( pFile, ", shape = octagon" ); - } - else if ( Gia_ObjIsXor(pNode) ) - { - fprintf( pFile, " Node%d [label = \"%d\"", i, i ); + fprintf( pFile, " Node%d [label = \"%d\"", i, i ); + + if ( Gia_ObjIsXor(pNode) ) fprintf( pFile, ", shape = doublecircle" ); - } - else if ( Gia_ObjIsMux(pMan, pNode) ) - { - fprintf( pFile, " Node%d [label = \"%d\"", i, i ); + else if ( Gia_ObjIsMux(p, pNode) ) fprintf( pFile, ", shape = trapezium" ); - } else - { - fprintf( pFile, " Node%d [label = \"%d\"", i, i ); fprintf( pFile, ", shape = ellipse" ); - } if ( pNode->fMark0 ) fprintf( pFile, ", style = filled" ); @@ -405,7 +231,7 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int // the labeling node of this level fprintf( pFile, " Level%d;\n", 0 ); // generate constant node - if ( fConstIsUsed || pMan->fGiaSimple ) + if ( fConstIsUsed ) { // check if the costant node is present fprintf( pFile, " Node%d [label = \"Const0\"", 0 ); @@ -414,7 +240,7 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int fprintf( pFile, "];\n" ); } // generate the CI nodes - Gia_ManForEachCi( pMan, pNode, i ) + Gia_ManForEachCi( p, pNode, i ) { /* if ( fHaig || pNode->pEquiv == NULL ) @@ -425,7 +251,7 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int (Gia_ObjIsLatch(pNode)? "_out":""), pNode->Id, (Gia_ObjIsLatch(pNode)? "_out":""), Gia_Regular(pNode->pEquiv)->Id, Gia_IsComplement(pNode->pEquiv)? "\'":"" ); */ - fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(pMan, pNode), Gia_ObjId(pMan, pNode) ); + fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(p, pNode), Gia_ObjId(p, pNode) ); fprintf( pFile, ", shape = %s", "triangle" ); fprintf( pFile, ", color = coral, fillcolor = coral" ); @@ -437,73 +263,37 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int // generate invisible edges from the square down fprintf( pFile, "title1 -> title2 [style = invis];\n" ); - Gia_ManForEachCo( pMan, pNode, i ) - fprintf( pFile, "title2 -> Node%d [style = invis];\n", Gia_ObjId(pMan, pNode) ); + Gia_ManForEachCo( p, pNode, i ) + fprintf( pFile, "title2 -> Node%d [style = invis];\n", Gia_ObjId(p, pNode) ); // generate invisible edges among the COs Prev = -1; - Gia_ManForEachCo( pMan, pNode, i ) + Gia_ManForEachCo( p, pNode, i ) { if ( i > 0 ) - fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Gia_ObjId(pMan, pNode) ); - Prev = Gia_ObjId(pMan, pNode); + fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Gia_ObjId(p, pNode) ); + Prev = Gia_ObjId(p, pNode); + } + // generate invisible edges among the CIs + Prev = -1; + Gia_ManForEachCi( p, pNode, i ) + { + if ( i > 0 ) + fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Gia_ObjId(p, pNode) ); + Prev = Gia_ObjId(p, pNode); } // generate edges - Gia_ManForEachObj( pMan, pNode, i ) + Gia_ManForEachObj( p, pNode, i ) { if ( !Gia_ObjIsAnd(pNode) && !Gia_ObjIsCo(pNode) && !Gia_ObjIsBuf(pNode) ) continue; - if ( vMarks && Vec_IntEntry(vMarks, i) == 0 ) - continue; - // consider half/full-adder - if ( vMarks && Vec_IntEntry(vMarks, i) > 0 ) - { - int k, Mark = Vec_IntEntry(vMarks, i); - if ( Abc_Lit2Att2(Mark) == 2 ) // FA - { - int * pFanins = Vec_IntEntryP( vFadds, 5*Abc_Lit2Var2(Mark) ); - if ( pFanins[3] == i ) - continue; - assert( pFanins[4] == i ); - // generate the edge from this node to the next - for ( k = 0; k < 3; k++ ) - { - fprintf( pFile, "Node%d", i ); - fprintf( pFile, " -> " ); - fprintf( pFile, "Node%d", Vec_IntEntry(vRemap, pFanins[k]) ); - fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", "bold" ); - fprintf( pFile, "]" ); - fprintf( pFile, ";\n" ); - } - } - else // HA - { - int * pFanins = Vec_IntEntryP( vHadds, 2*Abc_Lit2Var2(Mark) ); - int pFaninsIn[2] = { Vec_IntEntry(vRemap, Gia_ObjFaninId0(pNode, i)), Vec_IntEntry(vRemap, Gia_ObjFaninId1(pNode, i)) }; - if ( pFanins[0] == i ) - continue; - assert( pFanins[1] == i ); - for ( k = 0; k < 2; k++ ) - { - fprintf( pFile, "Node%d", i ); - fprintf( pFile, " -> " ); - fprintf( pFile, "Node%d", Vec_IntEntry(vRemap, pFaninsIn[k]) ); - fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", "bold" ); - fprintf( pFile, "]" ); - fprintf( pFile, ";\n" ); - } - } - continue; - } // generate the edge from this node to the next fprintf( pFile, "Node%d", i ); fprintf( pFile, " -> " ); - fprintf( pFile, "Node%d", vRemap ? Vec_IntEntry(vRemap, Gia_ObjFaninId0(pNode, i)) : Gia_ObjFaninId0(pNode, i) ); + fprintf( pFile, "Node%d", Gia_ObjFaninId0(pNode, i) ); fprintf( pFile, " [" ); fprintf( pFile, "style = %s", Gia_ObjFaninC0(pNode)? "dotted" : "bold" ); -// if ( Gia_NtkIsSeq(pNode->pMan) && Seq_ObjFaninL0(pNode) > 0 ) +// if ( Gia_NtkIsSeq(pNode->p) && Seq_ObjFaninL0(pNode) > 0 ) // fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,0) ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); @@ -512,23 +302,23 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int // generate the edge from this node to the next fprintf( pFile, "Node%d", i ); fprintf( pFile, " -> " ); - fprintf( pFile, "Node%d", vRemap ? Vec_IntEntry(vRemap, Gia_ObjFaninId1(pNode, i)) : Gia_ObjFaninId1(pNode, i) ); + fprintf( pFile, "Node%d", Gia_ObjFaninId1(pNode, i) ); fprintf( pFile, " [" ); fprintf( pFile, "style = %s", Gia_ObjFaninC1(pNode)? "dotted" : "bold" ); -// if ( Gia_NtkIsSeq(pNode->pMan) && Seq_ObjFaninL1(pNode) > 0 ) +// if ( Gia_NtkIsSeq(pNode->p) && Seq_ObjFaninL1(pNode) > 0 ) // fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,1) ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); - if ( !Gia_ObjIsMux(pMan, pNode) ) + if ( !Gia_ObjIsMux(p, pNode) ) continue; // generate the edge from this node to the next fprintf( pFile, "Node%d", i ); fprintf( pFile, " -> " ); - fprintf( pFile, "Node%d", vRemap ? Vec_IntEntry(vRemap, Gia_ObjFaninId2(pMan, i)) : Gia_ObjFaninId2(pMan, i) ); + fprintf( pFile, "Node%d", Gia_ObjFaninId2(p, i) ); fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", Gia_ObjFaninC2(pMan, pNode)? "dotted" : "bold" ); -// if ( Gia_NtkIsSeq(pNode->pMan) && Seq_ObjFaninL1(pNode) > 0 ) + fprintf( pFile, "style = %s", Gia_ObjFaninC2(p, pNode)? "dotted" : "bold" ); +// if ( Gia_NtkIsSeq(pNode->p) && Seq_ObjFaninL1(pNode) > 0 ) // fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,1) ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); @@ -564,18 +354,440 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int // unmark nodes if ( vBold ) - Gia_ManForEachObjVec( vBold, pMan, pNode, i ) + Gia_ManForEachObjVec( vBold, p, pNode, i ) pNode->fMark0 = 0; - else if ( pMan->nXors || pMan->nMuxes ) - Gia_ManCleanMark0( pMan ); + else if ( p->nXors || p->nMuxes ) + Gia_ManCleanMark0( p ); - Vec_IntFreeP( &vFadds ); - Vec_IntFreeP( &vHadds ); - Vec_IntFreeP( &vRecord ); + Vec_IntFreeP( &p->vLevels ); +} - Vec_IntFreeP( &pMan->vLevels ); - Vec_IntFreeP( &vMarks ); - Vec_IntFreeP( &vRemap ); +/**Function************************************************************* + + Synopsis [Writes the graph structure of AIG for DOT.] + + Description [Useful for graph visualization using tools such as GraphViz: + http://www.graphviz.org/] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ShowAddOut( Vec_Int_t * vAdds, Vec_Int_t * vMapAdds, int Node ) +{ + int iBox = Vec_IntEntry( vMapAdds, Node ); + if ( iBox >= 0 ) + return Vec_IntEntry( vAdds, 6*iBox+3 ); + return Node; +} +void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_Int_t * vXors, Vec_Int_t * vMapAdds, Vec_Int_t * vMapXors, Vec_Int_t * vOrder ) +{ + FILE * pFile; + Gia_Obj_t * pNode;//, * pTemp, * pPrev; + int LevelMax, Prev, Level, i; + int fConstIsUsed = 0; + + if ( Gia_ManAndNum(p) > 500 ) + { + fprintf( stdout, "Cannot visualize AIG with more than 200 nodes.\n" ); + return; + } + if ( (pFile = fopen( pFileName, "w" )) == NULL ) + { + fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName ); + return; + } + + // compute levels + LevelMax = 1 + p->nLevels; + Gia_ManForEachCo( p, pNode, i ) + Vec_IntWriteEntry( p->vLevels, Gia_ObjId(p, pNode), LevelMax ); + + // write the DOT header + fprintf( pFile, "# %s\n", "AIG structure generated by IVY package" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "digraph AIG {\n" ); + fprintf( pFile, "size = \"7.5,10\";\n" ); +// fprintf( pFile, "ranksep = 0.5;\n" ); +// fprintf( pFile, "nodesep = 0.5;\n" ); + fprintf( pFile, "center = true;\n" ); +// fprintf( pFile, "orientation = landscape;\n" ); +// fprintf( pFile, "edge [fontsize = 10];\n" ); +// fprintf( pFile, "edge [dir = none];\n" ); + fprintf( pFile, "edge [dir = back];\n" ); + fprintf( pFile, "\n" ); + + // labels on the left of the picture + fprintf( pFile, "{\n" ); + fprintf( pFile, " node [shape = plaintext];\n" ); + fprintf( pFile, " edge [style = invis];\n" ); + fprintf( pFile, " LevelTitle1 [label=\"\"];\n" ); + fprintf( pFile, " LevelTitle2 [label=\"\"];\n" ); + // generate node names with labels + for ( Level = LevelMax; Level >= 0; Level-- ) + { + // the visible node name + fprintf( pFile, " Level%d", Level ); + fprintf( pFile, " [label = " ); + // label name + fprintf( pFile, "\"" ); + fprintf( pFile, "\"" ); + fprintf( pFile, "];\n" ); + } + + // genetate the sequence of visible/invisible nodes to mark levels + fprintf( pFile, " LevelTitle1 -> LevelTitle2 ->" ); + for ( Level = LevelMax; Level >= 0; Level-- ) + { + // the visible node name + fprintf( pFile, " Level%d", Level ); + // the connector + if ( Level != 0 ) + fprintf( pFile, " ->" ); + else + fprintf( pFile, ";" ); + } + fprintf( pFile, "\n" ); + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate title box on top + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + fprintf( pFile, " LevelTitle1;\n" ); + fprintf( pFile, " title1 [shape=plaintext,\n" ); + fprintf( pFile, " fontsize=20,\n" ); + fprintf( pFile, " fontname = \"Times-Roman\",\n" ); + fprintf( pFile, " label=\"" ); + fprintf( pFile, "%s", "AIG structure visualized by ABC" ); + fprintf( pFile, "\\n" ); + fprintf( pFile, "Benchmark \\\"%s\\\". ", "aig" ); +// fprintf( pFile, "Time was %s. ", Extra_TimeStamp() ); + fprintf( pFile, "\"\n" ); + fprintf( pFile, " ];\n" ); + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate statistics box + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + fprintf( pFile, " LevelTitle2;\n" ); + fprintf( pFile, " title2 [shape=plaintext,\n" ); + fprintf( pFile, " fontsize=18,\n" ); + fprintf( pFile, " fontname = \"Times-Roman\",\n" ); + fprintf( pFile, " label=\"" ); + fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Gia_ManAndNum(p), LevelMax ); + fprintf( pFile, "\\n" ); + fprintf( pFile, "\"\n" ); + fprintf( pFile, " ];\n" ); + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate the COs + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + // the labeling node of this level + fprintf( pFile, " Level%d;\n", LevelMax ); + // generate the CO nodes + Gia_ManForEachCo( p, pNode, i ) + { + if ( Gia_ObjFaninId0p(p, pNode) == 0 ) + fConstIsUsed = 1; + fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(p, pNode), Gia_ObjId(p, pNode) ); + + fprintf( pFile, ", shape = %s", "invtriangle" ); + fprintf( pFile, ", color = coral, fillcolor = coral" ); + fprintf( pFile, "];\n" ); + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate nodes of each rank + for ( Level = LevelMax - 1; Level > 0; Level-- ) + { + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + // the labeling node of this level + fprintf( pFile, " Level%d;\n", Level ); + Gia_ManForEachObjVec( vOrder, p, pNode, i ) + { + int iNode = Gia_ObjId( p, pNode ); + if ( (int)Gia_ObjLevel(p, pNode) != Level ) + continue; +/* + fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(p, pNode), Gia_ObjId(p, pNode) ); + if ( Gia_ObjIsXor(pNode) ) + fprintf( pFile, ", shape = doublecircle" ); + else if ( Gia_ObjIsMux(p, pNode) ) + fprintf( pFile, ", shape = trapezium" ); + else + fprintf( pFile, ", shape = ellipse" ); +*/ + if ( Vec_IntEntry(vMapAdds, iNode) >= 0 ) + { + int iBox = Vec_IntEntry(vMapAdds, iNode); + fprintf( pFile, " Node%d [label = \"%d_%d\"", Gia_ShowAddOut(vAdds, vMapAdds, iNode), Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) ); + if ( Vec_IntEntry(vAdds, 6*iBox+2) == 0 ) + fprintf( pFile, ", shape = octagon" ); + else + fprintf( pFile, ", shape = doubleoctagon" ); + } + else if ( Vec_IntEntry(vMapXors, iNode) >= 0 ) + { + int iXor = Vec_IntEntry(vMapXors, iNode); + fprintf( pFile, " Node%d [label = \"%d\"", iNode, iNode ); + fprintf( pFile, ", shape = doublecircle" ); + } + else if ( Gia_ObjIsXor(pNode) ) + { + fprintf( pFile, " Node%d [label = \"%d\"", iNode, iNode ); + fprintf( pFile, ", shape = doublecircle" ); + } + else if ( Gia_ObjIsMux(p, pNode) ) + { + fprintf( pFile, " Node%d [label = \"%d\"", iNode, iNode ); + fprintf( pFile, ", shape = trapezium" ); + } + else + { + fprintf( pFile, " Node%d [label = \"%d\"", iNode, iNode ); + fprintf( pFile, ", shape = ellipse" ); + } +// if ( pNode->fMark0 ) +// fprintf( pFile, ", style = filled" ); + fprintf( pFile, "];\n" ); + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + } + + // generate the CI nodes + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + // the labeling node of this level + fprintf( pFile, " Level%d;\n", 0 ); + // generate constant node + if ( fConstIsUsed ) + { + // check if the costant node is present + fprintf( pFile, " Node%d [label = \"Const0\"", 0 ); + fprintf( pFile, ", shape = ellipse" ); + fprintf( pFile, ", color = coral, fillcolor = coral" ); + fprintf( pFile, "];\n" ); + } + // generate the CI nodes + Gia_ManForEachCi( p, pNode, i ) + { + fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(p, pNode), Gia_ObjId(p, pNode) ); + + fprintf( pFile, ", shape = %s", "triangle" ); + fprintf( pFile, ", color = coral, fillcolor = coral" ); + fprintf( pFile, "];\n" ); + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate invisible edges from the square down + fprintf( pFile, "title1 -> title2 [style = invis];\n" ); + Gia_ManForEachCo( p, pNode, i ) + fprintf( pFile, "title2 -> Node%d [style = invis];\n", Gia_ObjId(p, pNode) ); + // generate invisible edges among the COs + Prev = -1; + Gia_ManForEachCo( p, pNode, i ) + { + if ( i > 0 ) + fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Gia_ObjId(p, pNode) ); + Prev = Gia_ObjId(p, pNode); + } + // generate invisible edges among the CIs + Prev = -1; + Gia_ManForEachCi( p, pNode, i ) + { + if ( i > 0 ) + fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Gia_ObjId(p, pNode) ); + Prev = Gia_ObjId(p, pNode); + } + + // generate edges + Gia_ManForEachCo( p, pNode, i ) + { + int iNode = Gia_ObjId( p, pNode ); + fprintf( pFile, "Node%d", iNode ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Gia_ObjFaninId0(pNode, iNode)) ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", Gia_ObjFaninC0(pNode)? "dotted" : "bold" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + } + Gia_ManForEachObjVec( vOrder, p, pNode, i ) + { + int iNode = Gia_ObjId( p, pNode ); +// if ( !Gia_ObjIsAnd(pNode) && !Gia_ObjIsCo(pNode) && !Gia_ObjIsBuf(pNode) ) +// continue; + if ( Vec_IntEntry(vMapAdds, Gia_ObjId(p, pNode)) >= 0 ) + { + int k, iBox = Vec_IntEntry(vMapAdds, iNode); + for ( k = 0; k < 3; k++ ) + if ( Vec_IntEntry(vAdds, 6*iBox+k) ) + { + fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, iNode) ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Vec_IntEntry(vAdds, 6*iBox+k)) ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", 0? "dotted" : "bold" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + } + continue; + } + if ( Vec_IntEntry(vMapXors, Gia_ObjId(p, pNode)) >= 0 ) + { + int k, iXor = Vec_IntEntry(vMapXors, iNode); + for ( k = 1; k < 4; k++ ) + if ( Vec_IntEntry(vXors, 4*iXor+k) ) + { + fprintf( pFile, "Node%d", iNode ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Vec_IntEntry(vXors, 4*iXor+k)) ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", 0? "dotted" : "bold" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + } + continue; + } + // generate the edge from this node to the next + fprintf( pFile, "Node%d", iNode ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Gia_ObjFaninId0(pNode, iNode)) ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", Gia_ObjFaninC0(pNode)? "dotted" : "bold" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + if ( !Gia_ObjIsAnd(pNode) ) + continue; + // generate the edge from this node to the next + fprintf( pFile, "Node%d", iNode ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Gia_ObjFaninId1(pNode, iNode)) ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", Gia_ObjFaninC1(pNode)? "dotted" : "bold" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + + if ( !Gia_ObjIsMux(p, pNode) ) + continue; + // generate the edge from this node to the next + fprintf( pFile, "Node%d", iNode ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Gia_ObjFaninId2(p, iNode)) ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", Gia_ObjFaninC2(p, pNode)? "dotted" : "bold" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + } + + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + fclose( pFile ); + + Vec_IntFreeP( &p->vLevels ); +} + +/**Function************************************************************* + + Synopsis [Returns DFS ordered array of objects and their levels.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ShowMapAdds( Gia_Man_t * p, Vec_Int_t * vAdds ) +{ + Vec_Int_t * vMapAdds = Vec_IntStartFull( Gia_ManObjNum(p) ); int i; + for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) + { + Vec_IntWriteEntry( vMapAdds, Vec_IntEntry(vAdds, 6*i+3), i ); + Vec_IntWriteEntry( vMapAdds, Vec_IntEntry(vAdds, 6*i+4), i ); + } + return vMapAdds; +} +Vec_Int_t * Gia_ShowMapXors( Gia_Man_t * p, Vec_Int_t * vXors ) +{ + Vec_Int_t * vMapXors = Vec_IntStartFull( Gia_ManObjNum(p) ); int i; + for ( i = 0; 4*i < Vec_IntSize(vXors); i++ ) + Vec_IntWriteEntry( vMapXors, Vec_IntEntry(vXors, 4*i), i ); + return vMapXors; +} +int Gia_ShowCollectObjs_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vAdds, Vec_Int_t * vXors, Vec_Int_t * vMapAdds, Vec_Int_t * vMapXors, Vec_Int_t * vOrder ) +{ + int Level0, Level1, Level2 = 0, Level = 0; + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return Gia_ObjLevel(p, pObj); + Gia_ObjSetTravIdCurrent(p, pObj); + if ( Gia_ObjIsCi(pObj) ) + return 0; + if ( Vec_IntEntry(vMapAdds, Gia_ObjId(p, pObj)) >= 0 ) + { + int iBox = Vec_IntEntry(vMapAdds, Gia_ObjId(p, pObj)); + Gia_ObjSetTravIdCurrentId(p, Vec_IntEntry(vAdds, 6*iBox+3) ); + Gia_ObjSetTravIdCurrentId(p, Vec_IntEntry(vAdds, 6*iBox+4) ); + Level0 = Gia_ShowCollectObjs_rec( p, Gia_ManObj( p, Vec_IntEntry(vAdds, 6*iBox+0) ), vAdds, vXors, vMapAdds, vMapXors, vOrder ); + Level1 = Gia_ShowCollectObjs_rec( p, Gia_ManObj( p, Vec_IntEntry(vAdds, 6*iBox+1) ), vAdds, vXors, vMapAdds, vMapXors, vOrder ); + if ( Vec_IntEntry(vAdds, 6*iBox+2) ) + Level2 = Gia_ShowCollectObjs_rec( p, Gia_ManObj( p, Vec_IntEntry(vAdds, 6*iBox+2) ), vAdds, vXors, vMapAdds, vMapXors, vOrder ); + Level = 1 + Abc_MaxInt( Abc_MaxInt(Level0, Level1), Level2 ); + Gia_ObjSetLevelId( p, Vec_IntEntry(vAdds, 6*iBox+3), Level ); + Gia_ObjSetLevelId( p, Vec_IntEntry(vAdds, 6*iBox+4), Level ); + pObj = Gia_ManObj( p, Vec_IntEntry(vAdds, 6*iBox+3) ); + } + else if ( Vec_IntEntry(vMapXors, Gia_ObjId(p, pObj)) >= 0 ) + { + int iXor = Vec_IntEntry(vMapXors, Gia_ObjId(p, pObj)); + Level0 = Gia_ShowCollectObjs_rec( p, Gia_ManObj( p, Vec_IntEntry(vXors, 4*iXor+1) ), vAdds, vXors, vMapAdds, vMapXors, vOrder ); + Level1 = Gia_ShowCollectObjs_rec( p, Gia_ManObj( p, Vec_IntEntry(vXors, 4*iXor+2) ), vAdds, vXors, vMapAdds, vMapXors, vOrder ); + if ( Vec_IntEntry(vXors, 4*iXor+3) ) + Level2 = Gia_ShowCollectObjs_rec( p, Gia_ManObj( p, Vec_IntEntry(vXors, 4*iXor+3) ), vAdds, vXors, vMapAdds, vMapXors, vOrder ); + Level = 1 + Abc_MaxInt( Abc_MaxInt(Level0, Level1), Level2 ); + Gia_ObjSetLevel( p, pObj, Level ); + } + else + { + assert( !Gia_ObjIsMux(p, pObj) ); + Level0 = Gia_ShowCollectObjs_rec( p, Gia_ObjFanin0(pObj), vAdds, vXors, vMapAdds, vMapXors, vOrder ); + Level1 = Gia_ShowCollectObjs_rec( p, Gia_ObjFanin1(pObj), vAdds, vXors, vMapAdds, vMapXors, vOrder ); + Level = 1 + Abc_MaxInt(Level0, Level1); + Gia_ObjSetLevel( p, pObj, Level ); + } + Vec_IntPush( vOrder, Gia_ObjId(p, pObj) ); + p->nLevels = Abc_MaxInt( p->nLevels, Level ); + return Level; +} +Vec_Int_t * Gia_ShowCollectObjs( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vXors, Vec_Int_t * vMapAdds, Vec_Int_t * vMapXors ) +{ + Gia_Obj_t * pObj; int i; + Vec_Int_t * vOrder = Vec_IntAlloc( 100 ); + Gia_ManCleanLevels( p, Gia_ManObjNum(p) ); + p->nLevels = 0; + Gia_ManIncrementTravId( p ); + Gia_ObjSetTravIdCurrent(p, Gia_ManConst0(p)); + Gia_ManForEachCi( p, pObj, i ) + Gia_ObjSetTravIdCurrent(p, pObj); + Gia_ManForEachCo( p, pObj, i ) + Gia_ShowCollectObjs_rec( p, Gia_ObjFanin0(pObj), vAdds, vXors, vMapAdds, vMapXors, vOrder ); + return vOrder; } /**Function************************************************************* @@ -589,12 +801,31 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int SeeAlso [] ***********************************************************************/ +void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_Int_t * vXors ) +{ + Vec_Int_t * vMapAdds = Gia_ShowMapAdds( p, vAdds ); + Vec_Int_t * vMapXors = Gia_ShowMapXors( p, vXors ); + Vec_Int_t * vOrder = Gia_ShowCollectObjs( p, vAdds, vXors, vMapAdds, vMapXors ); + Gia_WriteDotAig( p, pFileName, vAdds, vXors, vMapAdds, vMapXors, vOrder ); + Vec_IntFree( vMapAdds ); + Vec_IntFree( vMapXors ); + Vec_IntFree( vOrder ); +} void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders ) { + extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); + extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ); + extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds ); + extern void Abc_ShowFile( char * FileNameDot ); static int Counter = 0; char FileNameDot[200]; FILE * pFile; + + Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( pMan, &vXors, 0 ); + Ree_ManRemoveTrivial( pMan, vAdds ); + Ree_ManRemoveContained( pMan, vAdds ); + // create the file name // Gia_ShowGetFileName( pMan->pName, FileNameDot ); sprintf( FileNameDot, "temp%02d.dot", Counter++ ); @@ -606,12 +837,21 @@ void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders ) } fclose( pFile ); // generate the file - Gia_WriteDotAig( pMan, FileNameDot, vBold, fAdders ); + if ( fAdders ) + Gia_ShowProcess( pMan, FileNameDot, vAdds, vXors ); + else + Gia_WriteDotAigSimple( pMan, FileNameDot, vBold ); // visualize the file Abc_ShowFile( FileNameDot ); + + Vec_IntFree( vAdds ); + Vec_IntFree( vXors ); } + + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// From cd92b1fea386707bd1dd3003d3fa630385528373 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 8 Dec 2016 10:39:11 -0800 Subject: [PATCH 002/185] Improvements to GIA visualization. --- src/aig/gia/giaShow.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index bc3727469..c68ba26cf 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -539,7 +539,6 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In } else if ( Vec_IntEntry(vMapXors, iNode) >= 0 ) { - int iXor = Vec_IntEntry(vMapXors, iNode); fprintf( pFile, " Node%d [label = \"%d\"", iNode, iNode ); fprintf( pFile, ", shape = doublecircle" ); } From 5351ab4b13aa46db5710ca3ffe659e8e691ba126 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Mon, 12 Dec 2016 16:20:38 -0200 Subject: [PATCH 003/185] =?UTF-8?q?xSAT=20is=20an=20experimental=20SAT=20S?= =?UTF-8?q?olver=20based=20on=20Glucose=20v3(see=20Glucose=20copyrights=20?= =?UTF-8?q?below)=20and=20ABC=20C=20version=20of=20MiniSat=20(bsat)=20deve?= =?UTF-8?q?loped=20by=20Niklas=20Sorensson=20and=20modified=20by=20Alan=20?= =?UTF-8?q?Mishchenko.=20It=E2=80=99s=20development=20has=20reached=20suff?= =?UTF-8?q?icient=20maturity=20to=20be=20committed=20in=20ABC,=20but=20sti?= =?UTF-8?q?ll=20in=20a=20beta=20state.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TODO: * Read compressed CNF files. * Study the use of floating point for variables and clauses activity. * Better documentation. * Improve verbose messages. * Expose parameters for tuning. --- Makefile | 2 +- src/base/abci/abc.c | 339 ++++++++---- src/sat/xsat/license | 39 ++ src/sat/xsat/module.make | 3 + src/sat/xsat/xsat.h | 59 +++ src/sat/xsat/xsatBQueue.h | 189 +++++++ src/sat/xsat/xsatClause.h | 109 ++++ src/sat/xsat/xsatCnfReader.c | 236 +++++++++ src/sat/xsat/xsatHeap.h | 330 ++++++++++++ src/sat/xsat/xsatMemory.h | 225 ++++++++ src/sat/xsat/xsatSolver.c | 995 +++++++++++++++++++++++++++++++++++ src/sat/xsat/xsatSolver.h | 247 +++++++++ src/sat/xsat/xsatSolverAPI.c | 345 ++++++++++++ src/sat/xsat/xsatUtils.h | 106 ++++ src/sat/xsat/xsatWatchList.h | 268 ++++++++++ 15 files changed, 3392 insertions(+), 100 deletions(-) create mode 100644 src/sat/xsat/license create mode 100644 src/sat/xsat/module.make create mode 100644 src/sat/xsat/xsat.h create mode 100644 src/sat/xsat/xsatBQueue.h create mode 100644 src/sat/xsat/xsatClause.h create mode 100644 src/sat/xsat/xsatCnfReader.c create mode 100644 src/sat/xsat/xsatHeap.h create mode 100644 src/sat/xsat/xsatMemory.h create mode 100644 src/sat/xsat/xsatSolver.c create mode 100644 src/sat/xsat/xsatSolver.h create mode 100644 src/sat/xsat/xsatSolverAPI.c create mode 100644 src/sat/xsat/xsatUtils.h create mode 100644 src/sat/xsat/xsatWatchList.h diff --git a/Makefile b/Makefile index 6010aaac9..2385431ce 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ MODULES := \ src/opt/cut src/opt/fxu src/opt/fxch src/opt/rwr src/opt/mfs src/opt/sim \ src/opt/ret src/opt/fret src/opt/res src/opt/lpk src/opt/nwk src/opt/rwt \ src/opt/cgt src/opt/csw src/opt/dar src/opt/dau src/opt/dsc src/opt/sfm src/opt/sbd \ - src/sat/bsat src/sat/csat src/sat/msat src/sat/psat src/sat/cnf src/sat/bmc \ + src/sat/bsat src/sat/xsat src/sat/csat src/sat/msat src/sat/psat src/sat/cnf src/sat/bmc \ src/bool/bdc src/bool/deco src/bool/dec src/bool/kit src/bool/lucky \ src/bool/rsb src/bool/rpo \ src/proof/pdr src/proof/abs src/proof/live src/proof/ssc src/proof/int \ diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 7da88d3c1..dabeb9822 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -1,15 +1,15 @@ /**CFile**************************************************************** - - FileName [abc.c] + + FileName [abc.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Network and node package.] - + Synopsis [Command file.] Author [Alan Mishchenko] - + Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 20, 2005.] @@ -42,6 +42,7 @@ #include "bool/kit/kit.h" #include "map/amap/amap.h" #include "opt/ret/retInt.h" +#include "sat/xsat/xsat.h" #include "sat/cnf/cnf.h" #include "proof/cec/cec.h" #include "proof/acec/acec.h" @@ -306,6 +307,7 @@ static int Abc_CommandDCec ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandDSec ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandDSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandXSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandIProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -520,7 +522,7 @@ extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan ); Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -545,7 +547,7 @@ void Abc_FrameReplaceCex( Abc_Frame_t * pAbc, Abc_Cex_t ** ppCex ) Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -623,7 +625,7 @@ Vec_Int_t * Abc_FrameDeriveStatusArray( Vec_Ptr_t * vCexes ) Vec_PtrForEachEntry( Abc_Cex_t *, vCexes, pCex, i ) if ( pCex != NULL ) Vec_IntWriteEntry( vStatuses, i, 0 ); // set this output as SAT - return vStatuses; + return vStatuses; } /**Function************************************************************* @@ -951,6 +953,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Verification", "match", Abc_CommandMatch, 0 ); Cmd_CommandAdd( pAbc, "Verification", "sat", Abc_CommandSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "dsat", Abc_CommandDSat, 0 ); + Cmd_CommandAdd( pAbc, "Verification", "xsat", Abc_CommandXSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "psat", Abc_CommandPSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "prove", Abc_CommandProve, 1 ); Cmd_CommandAdd( pAbc, "Verification", "iprove", Abc_CommandIProve, 1 ); @@ -966,8 +969,8 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Verification", "constr", Abc_CommandConstr, 0 ); Cmd_CommandAdd( pAbc, "Verification", "unfold", Abc_CommandUnfold, 1 ); Cmd_CommandAdd( pAbc, "Verification", "fold", Abc_CommandFold, 1 ); - Cmd_CommandAdd( pAbc, "Verification", "unfold2", Abc_CommandUnfold2, 1 ); // jlong - Cmd_CommandAdd( pAbc, "Verification", "fold2", Abc_CommandFold2, 1 ); // jlong + Cmd_CommandAdd( pAbc, "Verification", "unfold2", Abc_CommandUnfold2, 1 ); // jlong + Cmd_CommandAdd( pAbc, "Verification", "fold2", Abc_CommandFold2, 1 ); // jlong Cmd_CommandAdd( pAbc, "Verification", "bm", Abc_CommandBm, 1 ); Cmd_CommandAdd( pAbc, "Verification", "bm2", Abc_CommandBm2, 1 ); Cmd_CommandAdd( pAbc, "Verification", "saucy3", Abc_CommandSaucy, 1 ); @@ -2717,8 +2720,8 @@ int Abc_CommandPrintStatus( Abc_Frame_t * pAbc, int argc, char ** argv ) { if ( fShort ) { - printf( "Status array contains %d SAT, %d UNSAT, and %d UNDEC entries (out of %d).", - Vec_IntCountEntry(pAbc->vStatuses, 0), Vec_IntCountEntry(pAbc->vStatuses, 1), + printf( "Status array contains %d SAT, %d UNSAT, and %d UNDEC entries (out of %d).", + Vec_IntCountEntry(pAbc->vStatuses, 0), Vec_IntCountEntry(pAbc->vStatuses, 1), Vec_IntCountEntry(pAbc->vStatuses, -1), Vec_IntSize(pAbc->vStatuses) ); } else @@ -5296,7 +5299,7 @@ int Abc_CommandMfs2( Abc_Frame_t * pAbc, int argc, char ** argv ) } if ( Vec_IntSize(pAbc->vIndFlops) != Abc_NtkLatchNum(pNtk) ) { - Abc_Print( -1, "The saved flop count (%d) does not match that of the current network (%d).\n", + Abc_Print( -1, "The saved flop count (%d) does not match that of the current network (%d).\n", Vec_IntSize(pAbc->vIndFlops), Abc_NtkLatchNum(pNtk) ); return 0; } @@ -6380,7 +6383,7 @@ int Abc_CommandTestRPO(Abc_Frame_t * pAbc, int argc, char ** argv) { goto usage; } } - if (argc != globalUtilOptind + 1) + if (argc != globalUtilOptind + 1) { Abc_Print(1, "Input file is not given.\n"); goto usage; @@ -12007,7 +12010,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) } */ // if ( pNtk ) -// Abc_NtkMakeLegit( pNtk ); +// Abc_NtkMakeLegit( pNtk ); { // extern void Ifd_ManDsdTest(); // Ifd_ManDsdTest(); @@ -14270,7 +14273,7 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -14311,7 +14314,7 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -14390,7 +14393,7 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -15765,7 +15768,7 @@ int Abc_CommandMap( Abc_Frame_t * pAbc, int argc, char ** argv ) } nGatesMin = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( nGatesMin < 0 ) + if ( nGatesMin < 0 ) goto usage; break; case 'a': @@ -16468,7 +16471,7 @@ usage: SeeAlso [] ***********************************************************************/ -#if 0 +#if 0 int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv ) { char Buffer[100]; @@ -16839,7 +16842,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nRelaxRatio = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nRelaxRatio < 0 ) + if ( pPars->nRelaxRatio < 0 ) goto usage; break; case 'N': @@ -17213,7 +17216,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; } } - + // complain if truth tables are requested but the cut size is too large if ( pPars->fTruth && pPars->nLutSize > IF_MAX_FUNC_LUTSIZE ) { @@ -18120,7 +18123,7 @@ int Abc_CommandInit( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_LatchSetInit0( pObj ); else if ( pInitStr[i] == '1' ) Abc_LatchSetInit1( pObj ); - else + else Abc_LatchSetInitDc( pObj ); return 0; } @@ -18302,7 +18305,7 @@ int Abc_CommandUndc( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( fUseCex ) { - char * pInit; + char * pInit; Abc_Cex_t * pTemp; int k, nFlopsX = 0; if ( pAbc->pCex == NULL ) @@ -18317,7 +18320,7 @@ int Abc_CommandUndc( Abc_Frame_t * pAbc, int argc, char ** argv ) // compare this value if ( Abc_NtkPiNum(pNtk) + nFlopsX != pAbc->pCex->nPis ) { - Abc_Print( -1, "The number of PIs (%d) plus X-valued flops (%d) in the original network does not match the number of PIs in the current CEX (%d).\n", + Abc_Print( -1, "The number of PIs (%d) plus X-valued flops (%d) in the original network does not match the number of PIs in the current CEX (%d).\n", Abc_NtkPiNum(pNtk), Abc_NtkLatchNum(pNtk), pAbc->pCex->nPis ); return 1; } @@ -20701,7 +20704,7 @@ int Abc_CommandSim3( Abc_Frame_t * pAbc, int argc, char ** argv ) extern int Abc_NtkDarSeqSim3( Abc_Ntk_t * pNtk, Ssw_RarPars_t * pPars ); Ssw_RarPars_t Pars, * pPars = &Pars; Abc_Ntk_t * pNtkRes, * pNtk = Abc_FrameReadNtk(pAbc); - Vec_Ptr_t * vSeqModelVec; + Vec_Ptr_t * vSeqModelVec; int c; Ssw_RarSetDefaultParams( pPars ); Extra_UtilGetoptReset(); @@ -23157,6 +23160,144 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandXSat( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + abctime clk; + int c; + int fVerbose = 0; + int nConfLimit = 0; + int nInsLimit = 0; + int nLearnedStart = 0; + int nLearnedDelta = 0; + int nLearnedPerce = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "CILDEhv" ) ) != EOF ) + { + switch ( c ) + { + case 'C': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); + goto usage; + } + nConfLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nConfLimit < 0 ) + goto usage; + break; + case 'I': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); + goto usage; + } + nInsLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nInsLimit < 0 ) + goto usage; + break; + case 'L': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-L\" should be followed by an integer.\n" ); + goto usage; + } + nLearnedStart = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nLearnedStart < 0 ) + goto usage; + break; + case 'D': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-D\" should be followed by an integer.\n" ); + goto usage; + } + nLearnedDelta = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nLearnedDelta < 0 ) + goto usage; + break; + case 'E': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-E\" should be followed by an integer.\n" ); + goto usage; + } + nLearnedPerce = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nLearnedPerce < 0 ) + goto usage; + break; + case 'h': + goto usage; + case 'v': + fVerbose ^= 1; + break; + + default: + goto usage; + } + } + + if ( argc == globalUtilOptind + 1 ) + { + char * pFileName = argv[globalUtilOptind]; + xSAT_Solver_t * p; + int status; + + FILE * pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + { + printf( "Cannot open file \"%s\" for writing.\n", pFileName ); + return 0; + } + xSAT_SolverParseDimacs( pFile, &p ); + + clk = Abc_Clock(); + status = xSAT_SolverSolve( p ); + fclose( pFile ); + + xSAT_SolverPrintStats( p ); + if ( status == 0 ) + Abc_Print( 1, "UNDECIDED " ); + else if ( status == 1 ) + Abc_Print( 1, "SATISFIABLE " ); + else + Abc_Print( 1, "UNSATISFIABLE " ); + + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + + xSAT_SolverDestroy( p ); + return 0; + } + +usage: + Abc_Print( -2, "usage: xsat [-CILDE num] [-hv].cnf\n" ); + Abc_Print( -2, "\t solves the combinational miter using SAT solver MiniSat-1.14\n" ); + Abc_Print( -2, "\t derives CNF from the current network and leaves it unchanged\n" ); + Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfLimit ); + Abc_Print( -2, "\t-I num : limit on the number of inspections [default = %d]\n", nInsLimit ); + Abc_Print( -2, "\t-L num : starting value for learned clause removal [default = %d]\n", nLearnedStart ); + Abc_Print( -2, "\t-D num : delta value for learned clause removal [default = %d]\n", nLearnedDelta ); + Abc_Print( -2, "\t-E num : ratio percentage for learned clause removal [default = %d]\n", nLearnedPerce ); + Abc_Print( -2, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* Synopsis [] @@ -24155,7 +24296,7 @@ int Abc_CommandBmc3( Abc_Frame_t * pAbc, int argc, char ** argv ) } } vStatuses = Abc_FrameDeriveStatusArray( vSeqModelVec ); - Abc_FrameReplacePoStatuses( pAbc, &vStatuses ); + Abc_FrameReplacePoStatuses( pAbc, &vStatuses ); if ( vSeqModelVec ) Abc_FrameReplaceCexVec( pAbc, &vSeqModelVec ); else @@ -25483,47 +25624,47 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_CommandBm2( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ +{ FILE * pOut, * pErr; Abc_Ntk_t *pNtk, *pNtk1, *pNtk2; - int fDelete1, fDelete2; + int fDelete1, fDelete2; Abc_Obj_t * pObj; char ** pArgvNew; - int c, nArgcNew, i; + int c, nArgcNew, i; extern void saucyGateWay( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodePo, FILE * gFile, int fBooleanMatching, int fLookForSwaps, int fFixOutputs, int fFixInputs, int fQuiet, int fPrintTree); pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - + pErr = Abc_FrameReadErr(pAbc); + Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) { switch ( c ) { case 'h': - goto usage; + goto usage; default: Abc_Print( -2, "Unknown switch.\n"); goto usage; } } - + pArgvNew = argv + globalUtilOptind; nArgcNew = argc - globalUtilOptind; if ( !Abc_NtkPrepareTwoNtks( pErr, pNtk, pArgvNew, nArgcNew , &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) ) return 1; - - if( (unsigned)Abc_NtkPiNum(pNtk1) != (unsigned)Abc_NtkPiNum(pNtk2) || + + if( (unsigned)Abc_NtkPiNum(pNtk1) != (unsigned)Abc_NtkPiNum(pNtk2) || (unsigned)Abc_NtkPoNum(pNtk1) != (unsigned)Abc_NtkPoNum(pNtk2) ) { Abc_Print( -2, "Mismatch in the number of inputs or outputs\n"); @@ -25532,7 +25673,7 @@ int Abc_CommandBm2( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( fDelete2 ) Abc_NtkDelete( pNtk2 ); return 1; } - + Abc_NtkPermute(pNtk2, 1, 1, 0, NULL ); Abc_NtkShortNames(pNtk2); @@ -25562,7 +25703,7 @@ int Abc_CommandBm2( Abc_Frame_t * pAbc, int argc, char ** argv ) saucyGateWay( pNtk1, NULL, NULL, 1, 0, 0, 0, 0, 0); if ( fDelete1 ) Abc_NtkDelete( pNtk1 ); - if ( fDelete2 ) Abc_NtkDelete( pNtk2 ); + if ( fDelete2 ) Abc_NtkDelete( pNtk2 ); return 0; usage: @@ -25570,8 +25711,8 @@ usage: Abc_Print( -2, "\t performs Boolean matching (PP-equivalence)\n" ); Abc_Print( -2, "\t for equivalent circuits, permutation that maps one circuit\n" ); Abc_Print( -2, "\t to another is printed to standard output (PIs and POs of the\n" ); - Abc_Print( -2, "\t first network have prefix \"N1:\", while PIs and POs of the\n" ); - Abc_Print( -2, "\t second network have prefix \"N2:\")\n" ); + Abc_Print( -2, "\t first network have prefix \"N1:\", while PIs and POs of the\n" ); + Abc_Print( -2, "\t second network have prefix \"N2:\")\n" ); Abc_Print( -2, "\t-h : print the command usage\n"); Abc_Print( -2, "\tfile1 : the file with the first network\n"); Abc_Print( -2, "\tfile2 : the file with the second network\n"); @@ -25593,14 +25734,14 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_CommandSaucy( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ +{ Abc_Ntk_t *pNtk; char * outputName = NULL; FILE * gFile = NULL; @@ -25629,20 +25770,20 @@ int Abc_CommandSaucy( Abc_Frame_t * pAbc, int argc, char ** argv ) outputName = argv[globalUtilOptind]; if ( !strcmp(argv[globalUtilOptind], "all") ) fOutputsOneAtTime ^= 1; - globalUtilOptind++; + globalUtilOptind++; break; case 'F': if ( globalUtilOptind >= argc ) { Abc_Print( -1, "Command line switch \"-F\" should be followed by a file name.\n" ); goto usage; - } + } if ( (gFile = fopen( argv[globalUtilOptind], "w" )) == NULL ) { - Abc_Print( -1, "Cannot create output file \"%s\". ", argv[globalUtilOptind] ); + Abc_Print( -1, "Cannot create output file \"%s\". ", argv[globalUtilOptind] ); return 1; } - globalUtilOptind++; + globalUtilOptind++; break; case 'i': fFixOutputs ^= 1; @@ -25665,9 +25806,9 @@ int Abc_CommandSaucy( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -2, "Unknown switch.\n"); goto usage; } - } - - pNtk = Abc_FrameReadNtk(pAbc); + } + + pNtk = Abc_FrameReadNtk(pAbc); if ( pNtk == NULL ) { @@ -25690,21 +25831,21 @@ int Abc_CommandSaucy( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_NtkForEachPo( pNtk, pNodePo, i ) { printf("Ouput %s\n\n", Abc_ObjName(pNodePo)); saucyGateWay( pNtk, pNodePo, gFile, 0, fLookForSwaps, fFixOutputs, fFixInputs, fQuiet, fPrintTree ); - printf("----------------------------------------\n"); + printf("----------------------------------------\n"); } fclose(hadi); } else if (outputName != NULL) { int i; - Abc_Obj_t * pNodePo; + Abc_Obj_t * pNodePo; Abc_NtkForEachPo( pNtk, pNodePo, i ) { if (!strcmp(Abc_ObjName(pNodePo), outputName)) { saucyGateWay( pNtk, pNodePo, gFile, 0, fLookForSwaps, fFixOutputs, fFixInputs, fQuiet, fPrintTree ); Abc_NtkDelete( pNtk ); return 0; - } + } } Abc_Print( -1, "Output not found\n" ); - return 1; + return 1; } else saucyGateWay( pNtk, NULL, gFile, 0, fLookForSwaps, fFixOutputs, fFixInputs, fQuiet, fPrintTree ); @@ -25715,9 +25856,9 @@ int Abc_CommandSaucy( Abc_Frame_t * pAbc, int argc, char ** argv ) usage: Abc_Print( -2, "usage: saucy3 [-O ] [-F ] [-iosqvh]\n\n" ); Abc_Print( -2, "\t computes functional symmetries of the netowrk\n" ); - Abc_Print( -2, "\t prints symmetry generators to the standard output\n" ); + Abc_Print( -2, "\t prints symmetry generators to the standard output\n" ); Abc_Print( -2, "\t-O : (optional) compute symmetries only for output given by name\n"); - Abc_Print( -2, "\t only inputs in the output cone are permuted\n"); + Abc_Print( -2, "\t only inputs in the output cone are permuted\n"); Abc_Print( -2, "\t (special case) name=all, compute symmetries for each\n" ); Abc_Print( -2, "\t output, but only one output at a time\n" ); Abc_Print( -2, "\t [default = compute symmetries by permuting all I/Os]\n" ); @@ -25726,8 +25867,8 @@ usage: Abc_Print( -2, "\t-o : permute just the outputs (fix the inputs) [default = no]\n"); Abc_Print( -2, "\t-s : only look for swaps of inputs [default = no]\n"); Abc_Print( -2, "\t-q : quiet (do not print symmetry generators) [default = no]\n"); - Abc_Print( -2, "\t-v : verbose (print the search tree) [default = no]\n"); - Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "\t-v : verbose (print the search tree) [default = no]\n"); + Abc_Print( -2, "\t-h : print the command usage\n"); Abc_Print( -2, "\t \n" ); Abc_Print( -2, "\t This command was contributed by Hadi Katebi from U Michigan.\n" ); @@ -27055,7 +27196,7 @@ int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv ) pAig = Gia_ManReadMiniLut( FileName ); // else if ( Extra_FileIsType( FileName, ".v", NULL, NULL ) ) // Abc3_ReadShowHie( FileName, fSkipStrash ); - else + else pAig = Gia_AigerRead( FileName, fGiaSimple, fSkipStrash, 0 ); if ( pAig ) Abc_FrameUpdateGia( pAbc, pAig ); @@ -27466,8 +27607,8 @@ int Abc_CommandAbc9Get( Abc_Frame_t * pAbc, int argc, char ** argv ) Vec_FltFreeP( &pGia->vOutReqs ); pGia->DefInArrs = Abc_NtkReadDefaultArrivalWorst(pNtk); pGia->DefOutReqs = Abc_NtkReadDefaultRequiredWorst(pNtk); - pGia->vInArrs = Vec_FltAllocArray( Abc_NtkGetCiArrivalFloats(pNtk), Abc_NtkCiNum(pNtk) ); - pGia->vOutReqs = Vec_FltAllocArray( Abc_NtkGetCoRequiredFloats(pNtk), Abc_NtkCoNum(pNtk) ); + pGia->vInArrs = Vec_FltAllocArray( Abc_NtkGetCiArrivalFloats(pNtk), Abc_NtkCiNum(pNtk) ); + pGia->vOutReqs = Vec_FltAllocArray( Abc_NtkGetCoRequiredFloats(pNtk), Abc_NtkCoNum(pNtk) ); } Abc_FrameUpdateGia( pAbc, pGia ); return 0; @@ -27626,7 +27767,7 @@ usage: Synopsis [Compares to versions of the design and finds the best.] Description [] - + SideEffects [] SeeAlso [] @@ -27637,11 +27778,11 @@ static inline int Gia_ManCompareWithBest( Gia_Man_t * pBest, Gia_Man_t * p, int int nCurLuts, nCurEdges, nCurLevels; Gia_ManLutParams( p, &nCurLuts, &nCurEdges, &nCurLevels ); if ( pBest == NULL || - Gia_ManPiNum(pBest) != Gia_ManPiNum(p) || - Gia_ManPoNum(pBest) != Gia_ManPoNum(p) || + Gia_ManPiNum(pBest) != Gia_ManPiNum(p) || + Gia_ManPoNum(pBest) != Gia_ManPoNum(p) || Gia_ManRegNum(pBest) != Gia_ManRegNum(p) || strcmp(Gia_ManName(pBest), Gia_ManName(p)) || - (!fArea && (*pnBestLevels > nCurLevels || (*pnBestLevels == nCurLevels && 2*(*pnBestLuts) + *pnBestEdges > 2*nCurLuts + nCurEdges))) || + (!fArea && (*pnBestLevels > nCurLevels || (*pnBestLevels == nCurLevels && 2*(*pnBestLuts) + *pnBestEdges > 2*nCurLuts + nCurEdges))) || ( fArea && (*pnBestLuts > nCurLuts || (*pnBestLuts == nCurLuts && *pnBestLevels > nCurLevels))) ) { @@ -27659,7 +27800,7 @@ static inline int Gia_ManCompareWithBest( Gia_Man_t * pBest, Gia_Man_t * p, int Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -27697,7 +27838,7 @@ int Abc_CommandAbc9Save( Abc_Frame_t * pAbc, int argc, char ** argv ) // save the design as best Gia_ManStopP( &pAbc->pGiaBest ); pAbc->pGiaBest = Gia_ManDupWithAttributes( pAbc->pGia ); - return 0; + return 0; usage: Abc_Print( -2, "usage: &save [-ah]\n" ); @@ -27712,7 +27853,7 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -30868,7 +31009,7 @@ int Abc_CommandAbc9Syn2( Abc_Frame_t * pAbc, int argc, char ** argv ) } nRelaxRatio = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( nRelaxRatio < 0 ) + if ( nRelaxRatio < 0 ) goto usage; break; case 'a': @@ -30908,7 +31049,7 @@ int Abc_CommandAbc9Syn2( Abc_Frame_t * pAbc, int argc, char ** argv ) printf( "DSD manager has incompatible number of variables. Delay minimization is not performed.\n" ); fDelayMin = 0; } - } + } pTemp = Gia_ManAigSyn2( pAbc->pGia, fOldAlgo, fCoarsen, fCutMin, nRelaxRatio, fDelayMin, fVerbose, fVeryVerbose ); Abc_FrameUpdateGia( pAbc, pTemp ); return 0; @@ -31005,7 +31146,7 @@ int Abc_CommandAbc9Synch2( Abc_Frame_t * pAbc, int argc, char ** argv ) } nRelaxRatio = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( nRelaxRatio < 0 ) + if ( nRelaxRatio < 0 ) goto usage; break; case 'f': @@ -32857,7 +32998,7 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) pAbc->Status = Cec_ManVerify( pTemp, pPars ); ABC_SWAP( Abc_Cex_t *, pAbc->pGia->pCexComb, pTemp->pCexComb ); Gia_ManStop( pTemp ); - } + } Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb ); return 0; } @@ -33749,7 +33890,7 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nRelaxRatio = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nRelaxRatio < 0 ) + if ( pPars->nRelaxRatio < 0 ) goto usage; break; case 'T': @@ -34867,7 +35008,7 @@ int Abc_CommandAbc9Lf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nRelaxRatio = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nRelaxRatio < 0 ) + if ( pPars->nRelaxRatio < 0 ) goto usage; break; case 'L': @@ -34878,7 +35019,7 @@ int Abc_CommandAbc9Lf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nCoarseLimit = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nCoarseLimit < 0 ) + if ( pPars->nCoarseLimit < 0 ) goto usage; break; case 'E': @@ -34889,7 +35030,7 @@ int Abc_CommandAbc9Lf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nAreaTuner = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nAreaTuner < 0 ) + if ( pPars->nAreaTuner < 0 ) goto usage; break; case 'D': @@ -35099,7 +35240,7 @@ int Abc_CommandAbc9Mf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nRelaxRatio = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nRelaxRatio < 0 ) + if ( pPars->nRelaxRatio < 0 ) goto usage; break; case 'L': @@ -35110,7 +35251,7 @@ int Abc_CommandAbc9Mf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nCoarseLimit = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nCoarseLimit < 0 ) + if ( pPars->nCoarseLimit < 0 ) goto usage; break; case 'E': @@ -35121,7 +35262,7 @@ int Abc_CommandAbc9Mf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nAreaTuner = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nAreaTuner < 0 ) + if ( pPars->nAreaTuner < 0 ) goto usage; break; case 'D': @@ -35303,7 +35444,7 @@ int Abc_CommandAbc9Nf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nRelaxRatio = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nRelaxRatio < 0 ) + if ( pPars->nRelaxRatio < 0 ) goto usage; break; case 'L': @@ -35314,7 +35455,7 @@ int Abc_CommandAbc9Nf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nCoarseLimit = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nCoarseLimit < 0 ) + if ( pPars->nCoarseLimit < 0 ) goto usage; break; case 'E': @@ -35325,7 +35466,7 @@ int Abc_CommandAbc9Nf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nAreaTuner = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nAreaTuner < 0 ) + if ( pPars->nAreaTuner < 0 ) goto usage; break; case 'D': @@ -35518,7 +35659,7 @@ int Abc_CommandAbc9Of( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nRelaxRatio = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nRelaxRatio < 0 ) + if ( pPars->nRelaxRatio < 0 ) goto usage; break; case 'L': @@ -35529,7 +35670,7 @@ int Abc_CommandAbc9Of( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nCoarseLimit = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nCoarseLimit < 0 ) + if ( pPars->nCoarseLimit < 0 ) goto usage; break; case 'E': @@ -35540,7 +35681,7 @@ int Abc_CommandAbc9Of( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nAreaTuner = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nAreaTuner < 0 ) + if ( pPars->nAreaTuner < 0 ) goto usage; break; case 'D': @@ -35886,7 +36027,7 @@ int Abc_CommandAbc9Edge( Abc_Frame_t * pAbc, int argc, char ** argv ) { //Edg_ManAssignEdgeNew( pAbc->pGia, nEdges, fVerbose ); Seg_ManComputeDelay( pAbc->pGia, DelayMax, nFanouts, nEdges==2, fVerbose ); - return 0; + return 0; } if ( pAbc->pGia->pManTime && fReverse ) { @@ -35895,7 +36036,7 @@ int Abc_CommandAbc9Edge( Abc_Frame_t * pAbc, int argc, char ** argv ) } if ( fReverse ) DelayMax = Gia_ManComputeEdgeDelay2( pAbc->pGia ); - else + else DelayMax = Gia_ManComputeEdgeDelay( pAbc->pGia, nEdges == 2 ); //printf( "The number of edges = %d. Delay = %d.\n", Gia_ManEvalEdgeCount(pAbc->pGia), DelayMax ); return 0; @@ -38307,7 +38448,7 @@ int Abc_CommandAbc9MultiProve( Abc_Frame_t * pAbc, int argc, char ** argv ) } pAbc->Status = Gia_ManMultiProve( pAbc->pGia, pPars ); vStatuses = Abc_FrameDeriveStatusArray( pAbc->pGia->vSeqModelVec ); - Abc_FrameReplacePoStatuses( pAbc, &vStatuses ); + Abc_FrameReplacePoStatuses( pAbc, &vStatuses ); Abc_FrameReplaceCexVec( pAbc, &pAbc->pGia->vSeqModelVec ); return 0; @@ -38454,7 +38595,7 @@ int Abc_CommandAbc9Bmc( Abc_Frame_t * pAbc, int argc, char ** argv ) Bmc_AndPar_t Pars, * pPars = &Pars; memset( pPars, 0, sizeof(Bmc_AndPar_t) ); pPars->nStart = 0; // starting timeframe - pPars->nFramesMax = 0; // maximum number of timeframes + pPars->nFramesMax = 0; // maximum number of timeframes pPars->nFramesAdd = 50; // the number of additional frames pPars->nConfLimit = 0; // maximum number of conflicts at a node pPars->nTimeOut = 0; // timeout in seconds @@ -38463,9 +38604,9 @@ int Abc_CommandAbc9Bmc( Abc_Frame_t * pAbc, int argc, char ** argv ) pPars->fDumpFrames = 0; // dump unrolled timeframes pPars->fUseSynth = 0; // use synthesis pPars->fUseOldCnf = 0; // use old CNF construction - pPars->fVerbose = 0; // verbose - pPars->fVeryVerbose = 0; // very verbose - pPars->fNotVerbose = 0; // skip line-by-line print-out + pPars->fVerbose = 0; // verbose + pPars->fVeryVerbose = 0; // very verbose + pPars->fNotVerbose = 0; // skip line-by-line print-out pPars->iFrame = 0; // explored up to this frame pPars->nFailOuts = 0; // the number of failed outputs pPars->nDropOuts = 0; // the number of dropped outputs @@ -39166,7 +39307,7 @@ usage: Abc_Print( -2, "\t ((a&b)^p) complement at the output\n"); Abc_Print( -2, "\t (((a^p)&(b^q))^r) complement at the inputs and at the output\n"); Abc_Print( -2, "\t (a?(b?~s:r):(b?q:p)) functionally observable fault at the output\n"); - Abc_Print( -2, "\t (p?(a|b):(a&b)) replace AND by OR\n"); + Abc_Print( -2, "\t (p?(a|b):(a&b)) replace AND by OR\n"); return 1; } @@ -40039,7 +40180,7 @@ int Abc_CommandAbc9Demiter( Abc_Frame_t * pAbc, int argc, char ** argv ) { char pName0[1000] = "miter_part0.aig"; char pName1[1000] = "miter_part1.aig"; - Gia_Man_t * pPart1, * pPart2; + Gia_Man_t * pPart1, * pPart2; if ( Gia_ManPoNum(pAbc->pGia) % 2 != 0 ) { Abc_Print( -1, "Abc_CommandAbc9Demiter(): Does not look like a dual-output miter.\n" ); @@ -40481,7 +40622,7 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) Gia_ManDemiterDual( pDual, &pGia0, &pGia1 ); Gia_ManStop( pDual ); pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars ); - } + } Abc_FrameReplaceCex( pAbc, &pGia0->pCexComb ); Gia_ManStop( pGia0 ); Gia_ManStop( pGia1 ); @@ -40687,7 +40828,7 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -40701,7 +40842,7 @@ int Abc_CommandAbc9Mfs( Abc_Frame_t * pAbc, int argc, char ** argv ) Sfm_ParSetDefault( pPars ); pPars->nTfoLevMax = 5; pPars->nDepthMax = 100; - pPars->nWinSizeMax = 2000; + pPars->nWinSizeMax = 2000; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "WFDMLCNdaebvwh" ) ) != EOF ) { @@ -40852,7 +40993,7 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -41324,7 +41465,7 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -41385,7 +41526,7 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] diff --git a/src/sat/xsat/license b/src/sat/xsat/license new file mode 100644 index 000000000..a6389ab13 --- /dev/null +++ b/src/sat/xsat/license @@ -0,0 +1,39 @@ +xSAT - Copyright (c) 2016, Bruno Schmitt - UC Berkeley / UFRGS (boschmitt@inf.ufrgs.br) + +xSAT is based on Glucose v3(see Glucose copyrights below) and ABC C version of +MiniSat (bsat) developed by Niklas Sorensson and modified by Alan Mishchenko. +Permissions and copyrights of xSAT are exactly the same as Glucose v3/Minisat. +(see below). + +--------------- + +Glucose -- Copyright (c) 2013, Gilles Audemard, Laurent Simon + CRIL - Univ. Artois, France + LRI - Univ. Paris Sud, France + +Glucose sources are based on MiniSat (see below MiniSat copyrights). Permissions +and copyrights of Glucose are exactly the same as Minisat on which it is based +on. (see below). + +--------------- + +Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson +Copyright (c) 2007-2010, Niklas Sorensson + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*******************************************************************************/ diff --git a/src/sat/xsat/module.make b/src/sat/xsat/module.make new file mode 100644 index 000000000..1d7352e2b --- /dev/null +++ b/src/sat/xsat/module.make @@ -0,0 +1,3 @@ +SRC += src/sat/xsat/xsatSolver.c \ + src/sat/xsat/xsatSolverAPI.c \ + src/sat/xsat/xsatCnfReader.c diff --git a/src/sat/xsat/xsat.h b/src/sat/xsat/xsat.h new file mode 100644 index 000000000..b2962d91c --- /dev/null +++ b/src/sat/xsat/xsat.h @@ -0,0 +1,59 @@ +/**CFile**************************************************************** + + FileName [xsat.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [xSAT - A SAT solver written in C. + Read the license file for more info.] + + Synopsis [External definitions of the solver.] + + Author [Bruno Schmitt ] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - November 10, 2016.] + + Revision [] + +***********************************************************************/ +#ifndef ABC__sat__xSAT__xSAT_h +#define ABC__sat__xSAT__xSAT_h + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// +#include "misc/util/abc_global.h" +#include "misc/vec/vecInt.h" + +ABC_NAMESPACE_HEADER_START + +//////////////////////////////////////////////////////////////////////// +/// STRUCTURE DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// +struct xSAT_Solver_t_; +typedef struct xSAT_Solver_t_ xSAT_Solver_t; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// +/*=== xsatCnfReader.c ================================================*/ +extern int xSAT_SolverParseDimacs( FILE *, xSAT_Solver_t ** ); + +/*=== xsatSolverAPI.c ================================================*/ +extern xSAT_Solver_t * xSAT_SolverCreate(); +extern void xSAT_SolverDestroy( xSAT_Solver_t * ); + +extern int xSAT_SolverAddClause( xSAT_Solver_t *, Vec_Int_t * ); +extern int xSAT_SolverSimplify( xSAT_Solver_t * ); +extern int xSAT_SolverSolve( xSAT_Solver_t * ); + +extern void xSAT_SolverPrintStats( xSAT_Solver_t * ); + +ABC_NAMESPACE_HEADER_END + +#endif +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// diff --git a/src/sat/xsat/xsatBQueue.h b/src/sat/xsat/xsatBQueue.h new file mode 100644 index 000000000..37951684e --- /dev/null +++ b/src/sat/xsat/xsatBQueue.h @@ -0,0 +1,189 @@ +/**CFile**************************************************************** + + FileName [xsatBQueue.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [xSAT - A SAT solver written in C. + Read the license file for more info.] + + Synopsis [Bounded queue implementation.] + + Author [Bruno Schmitt ] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - November 10, 2016.] + + Revision [] + +***********************************************************************/ +#ifndef ABC__sat__xSAT__xsatBQueue_h +#define ABC__sat__xSAT__xsatBQueue_h + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// +#include "misc/util/abc_global.h" + +ABC_NAMESPACE_HEADER_START + +//////////////////////////////////////////////////////////////////////// +/// STRUCTURE DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// +typedef struct xSAT_BQueue_t_ xSAT_BQueue_t; +struct xSAT_BQueue_t_ +{ + int nSize; + int nCap; + int iFirst; + int iEmpty; + uint64_t nSum; + uint32_t * pData; +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xSAT_BQueue_t * xSAT_BQueueNew( int nCap ) +{ + xSAT_BQueue_t * p = ABC_CALLOC( xSAT_BQueue_t, 1 ); + p->nCap = nCap; + p->pData = ABC_CALLOC( uint32_t, nCap ); + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_BQueueFree( xSAT_BQueue_t * p ) +{ + ABC_FREE( p->pData ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_BQueuePush( xSAT_BQueue_t * p, uint32_t Value ) +{ + if ( p->nSize == p->nCap ) + { + assert(p->iFirst == p->iEmpty); + p->nSum -= p->pData[p->iFirst]; + p->iFirst = ( p->iFirst + 1 ) % p->nCap; + } + else + p->nSize++; + + p->nSum += Value; + p->pData[p->iEmpty] = Value; + if ( ( ++p->iEmpty ) == p->nCap ) + { + p->iEmpty = 0; + p->iFirst = 0; + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int xSAT_BQueuePop( xSAT_BQueue_t * p ) +{ + assert( p->nSize >= 1 ); + int RetValue = p->pData[p->iFirst]; + p->nSum -= RetValue; + p->iFirst = ( p->iFirst + 1 ) % p->nCap; + p->nSize--; + return RetValue; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline uint32_t xSAT_BQueueAvg( xSAT_BQueue_t * p ) +{ + return ( uint32_t )( p->nSum / ( ( uint64_t ) p->nSize ) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int xSAT_BQueueIsValid( xSAT_BQueue_t * p ) +{ + return ( p->nCap == p->nSize ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_BQueueClean( xSAT_BQueue_t * p ) +{ + p->iFirst = 0; + p->iEmpty = 0; + p->nSize = 0; + p->nSum = 0; +} + +ABC_NAMESPACE_HEADER_END + +#endif diff --git a/src/sat/xsat/xsatClause.h b/src/sat/xsat/xsatClause.h new file mode 100644 index 000000000..39f0a0c8c --- /dev/null +++ b/src/sat/xsat/xsatClause.h @@ -0,0 +1,109 @@ +/**CFile**************************************************************** + + FileName [xsatClause.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [xSAT - A SAT solver written in C. + Read the license file for more info.] + + Synopsis [Clause data type definition.] + + Author [Bruno Schmitt ] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - November 10, 2016.] + + Revision [] + +***********************************************************************/ +#ifndef ABC__sat__xSAT__xsatClause_h +#define ABC__sat__xSAT__xsatClause_h + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// +#include "misc/util/abc_global.h" + +ABC_NAMESPACE_HEADER_START + +//////////////////////////////////////////////////////////////////////// +/// STRUCTURE DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// +typedef struct xSAT_Clause_t_ xSAT_Clause_t; +struct xSAT_Clause_t_ +{ + unsigned fLearnt : 1; + unsigned fMark : 1; + unsigned fReallocd : 1; + unsigned fCanBeDel : 1; + unsigned nLBD : 28; + unsigned nSize; + union { + int Lit; + unsigned Act; + } pData[0]; +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static int xSAT_ClauseCompare( const void * p1, const void * p2 ) +{ + xSAT_Clause_t * pC1 = ( xSAT_Clause_t * ) p1; + xSAT_Clause_t * pC2 = ( xSAT_Clause_t * ) p2; + + if ( pC1->nSize > 2 && pC2->nSize == 2 ) + return 1; + if ( pC1->nSize == 2 && pC2->nSize > 2 ) + return 0; + if ( pC1->nSize == 2 && pC2->nSize == 2 ) + return 0; + + if ( pC1->nLBD > pC2->nLBD ) + return 1; + if ( pC1->nLBD < pC2->nLBD ) + return 0; + + return pC1->pData[pC1->nSize].Act < pC2->pData[pC2->nSize].Act; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static void xSAT_ClausePrint( xSAT_Clause_t * pCla ) +{ + int i; + + printf("{ "); + for ( i = 0; i < pCla->nSize; i++ ) + printf("%d ", pCla->pData[i].Lit ); + printf("}\n"); +} + +ABC_NAMESPACE_HEADER_END + +#endif +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// diff --git a/src/sat/xsat/xsatCnfReader.c b/src/sat/xsat/xsatCnfReader.c new file mode 100644 index 000000000..d23e8a0a6 --- /dev/null +++ b/src/sat/xsat/xsatCnfReader.c @@ -0,0 +1,236 @@ +/**CFile**************************************************************** + + FileName [xsatCnfReader.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [xSAT - A SAT solver written in C. + Read the license file for more info.] + + Synopsis [CNF DIMACS file format parser.] + + Author [Bruno Schmitt ] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - November 10, 2016.] + + Revision [] + +***********************************************************************/ + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// +#include + +#include "misc/util/abc_global.h" +#include "misc/vec/vecInt.h" + +#include "xsatSolver.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Read the file into the internal buffer.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * xSAT_FileRead( FILE * pFile ) +{ + int nFileSize; + char * pBuffer; + int RetValue; + // get the file size, in bytes + fseek( pFile, 0, SEEK_END ); + nFileSize = ftell( pFile ); + // move the file current reading position to the beginning + rewind( pFile ); + // load the contents of the file into memory + pBuffer = ABC_ALLOC( char, nFileSize + 3 ); + RetValue = fread( pBuffer, nFileSize, 1, pFile ); + // terminate the string with '\0' + pBuffer[ nFileSize + 0] = '\n'; + pBuffer[ nFileSize + 1] = '\0'; + return pBuffer; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static void skipLine( char ** pIn ) +{ + while ( 1 ) + { + if (**pIn == 0) + return; + if (**pIn == '\n') + { + (*pIn)++; + return; + } + (*pIn)++; + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static int xSAT_ReadInt( char ** pIn ) +{ + int val = 0; + int neg = 0; + + for(; isspace(**pIn); (*pIn)++); + if ( **pIn == '-' ) + neg = 1, + (*pIn)++; + else if ( **pIn == '+' ) + (*pIn)++; + if ( !isdigit(**pIn) ) + fprintf(stderr, "PARSE ERROR! Unexpected char: %c\n", **pIn), + exit(1); + while ( isdigit(**pIn) ) + val = val*10 + (**pIn - '0'), + (*pIn)++; + return neg ? -val : val; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static void xSAT_ReadClause( char ** pIn, xSAT_Solver_t * p, Vec_Int_t * vLits ) +{ + int token, var, sign; + + Vec_IntClear( vLits ); + while ( 1 ) + { + token = xSAT_ReadInt( pIn ); + if ( token == 0 ) + break; + var = abs(token) - 1; + sign = (token > 0); + Vec_IntPush( vLits, xSAT_Var2Lit( var, !sign ) ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static int xSAT_ParseDimacs( char * pText, xSAT_Solver_t ** pS ) +{ + xSAT_Solver_t * p = NULL; + Vec_Int_t * vLits = NULL; + char * pIn = pText; + int nVars, nClas; + while ( 1 ) + { + for(; isspace(*pIn); pIn++); + if ( *pIn == 0 ) + break; + else if ( *pIn == 'c' ) + skipLine( &pIn ); + else if ( *pIn == 'p' ) + { + pIn++; + for(; isspace(*pIn); pIn++); + for(; !isspace(*pIn); pIn++); + + nVars = xSAT_ReadInt( &pIn ); + nClas = xSAT_ReadInt( &pIn ); + skipLine( &pIn ); + + /* start the solver */ + p = xSAT_SolverCreate(); + /* allocate the vector */ + vLits = Vec_IntAlloc( nVars ); + } + else + { + if ( p == NULL ) + { + printf( "There is no parameter line.\n" ); + exit(1); + } + xSAT_ReadClause( &pIn, p, vLits ); + if ( !xSAT_SolverAddClause( p, vLits ) ) + { + Vec_IntPrint(vLits); + return 0; + } + } + } + Vec_IntFree( vLits ); + *pS = p; + return xSAT_SolverSimplify( p ); +} + +/**Function************************************************************* + + Synopsis [Starts the solver and reads the DIMAC file.] + + Description [Returns FALSE upon immediate conflict.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int xSAT_SolverParseDimacs( FILE * pFile, xSAT_Solver_t ** p ) +{ + char * pText; + int Value; + pText = xSAT_FileRead( pFile ); + Value = xSAT_ParseDimacs( pText, p ); + ABC_FREE( pText ); + return Value; +} + +ABC_NAMESPACE_IMPL_END + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// diff --git a/src/sat/xsat/xsatHeap.h b/src/sat/xsat/xsatHeap.h new file mode 100644 index 000000000..2e873e590 --- /dev/null +++ b/src/sat/xsat/xsatHeap.h @@ -0,0 +1,330 @@ +/**CFile**************************************************************** + + FileName [xsatHeap.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [xSAT - A SAT solver written in C. + Read the license file for more info.] + + Synopsis [Heap implementation.] + + Author [Bruno Schmitt ] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - November 10, 2016.] + + Revision [] + +***********************************************************************/ +#ifndef ABC__sat__xSAT__xsatHeap_h +#define ABC__sat__xSAT__xsatHeap_h + +#include "misc/util/abc_global.h" +#include "misc/vec/vecInt.h" + +ABC_NAMESPACE_HEADER_START + +//////////////////////////////////////////////////////////////////////// +/// STRUCTURE DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// +typedef struct xSAT_Heap_t_ xSAT_Heap_t; +struct xSAT_Heap_t_ +{ + Vec_Int_t * vActivity; + Vec_Int_t * vIndices; + Vec_Int_t * vHeap; +}; + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +inline int xSAT_HeapSize( xSAT_Heap_t * h ) +{ + return Vec_IntSize( h->vHeap ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +inline int xSAT_HeapInHeap( xSAT_Heap_t * h, int Var ) +{ + return ( Var < Vec_IntSize( h->vIndices ) ) && ( Vec_IntEntry( h->vIndices, Var ) >= 0 ); +} + +static inline int Left ( int i ) { return 2 * i + 1; } +static inline int Right ( int i ) { return ( i + 1 ) * 2; } +static inline int Parent( int i ) { return ( i - 1 ) >> 1; } +static inline int Compare( xSAT_Heap_t * p, int x, int y ) +{ + return ( unsigned )Vec_IntEntry( p->vActivity, x ) > ( unsigned )Vec_IntEntry( p->vActivity, y ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_HeapPercolateUp( xSAT_Heap_t * h, int i ) +{ + int x = Vec_IntEntry( h->vHeap, i ); + int p = Parent( i ); + + while ( i != 0 && Compare( h, x, Vec_IntEntry( h->vHeap, p ) ) ) + { + Vec_IntWriteEntry( h->vHeap, i, Vec_IntEntry( h->vHeap, p ) ); + Vec_IntWriteEntry( h->vIndices, Vec_IntEntry( h->vHeap, p ), i ); + i = p; + p = Parent(p); + } + Vec_IntWriteEntry( h->vHeap, i, x ); + Vec_IntWriteEntry( h->vIndices, x, i ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_HeapPercolateDown( xSAT_Heap_t * h, int i ) +{ + int x = Vec_IntEntry( h->vHeap, i ); + + while ( Left( i ) < Vec_IntSize( h->vHeap ) ) + { + int child = Right( i ) < Vec_IntSize( h->vHeap ) && + Compare( h, Vec_IntEntry( h->vHeap, Right( i ) ), Vec_IntEntry( h->vHeap, Left( i ) ) ) ? + Right( i ) : Left( i ); + + if ( !Compare( h, Vec_IntEntry( h->vHeap, child ), x ) ) + break; + + Vec_IntWriteEntry( h->vHeap, i, Vec_IntEntry( h->vHeap, child ) ); + Vec_IntWriteEntry( h->vIndices, Vec_IntEntry( h->vHeap, i ), i ); + i = child; + } + Vec_IntWriteEntry( h->vHeap, i, x ); + Vec_IntWriteEntry( h->vIndices, x, i ); +} + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xSAT_Heap_t * xSAT_HeapAlloc( Vec_Int_t * vActivity ) +{ + xSAT_Heap_t * p = ABC_ALLOC( xSAT_Heap_t, 1 ); + p->vActivity = vActivity; + p->vIndices = Vec_IntAlloc( 0 ); + p->vHeap = Vec_IntAlloc( 0 ); + + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_HeapFree( xSAT_Heap_t * p ) +{ + Vec_IntFree( p->vIndices ); + Vec_IntFree( p->vHeap ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_HeapIncrease( xSAT_Heap_t * h, int e ) +{ + assert( xSAT_HeapInHeap( h, e ) ); + xSAT_HeapPercolateDown( h, Vec_IntEntry( h->vIndices, e ) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_HeapDecrease( xSAT_Heap_t * p, int e ) +{ + assert( xSAT_HeapInHeap( p, e ) ); + xSAT_HeapPercolateUp( p , Vec_IntEntry( p->vIndices, e ) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_HeapInsert( xSAT_Heap_t * p, int n ) +{ + Vec_IntFillExtra( p->vIndices, n + 1, -1); + assert( !xSAT_HeapInHeap( p, n ) ); + + Vec_IntWriteEntry( p->vIndices, n, Vec_IntSize( p->vHeap ) ); + Vec_IntPush( p->vHeap, n ); + xSAT_HeapPercolateUp( p, Vec_IntEntry( p->vIndices, n ) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_HeapUpdate( xSAT_Heap_t * p, int i ) +{ + if ( !xSAT_HeapInHeap( p, i ) ) + xSAT_HeapInsert( p, i ); + else + { + xSAT_HeapPercolateUp( p, Vec_IntEntry( p->vIndices, i ) ); + xSAT_HeapPercolateDown( p, Vec_IntEntry( p->vIndices, i ) ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_HeapBuild( xSAT_Heap_t * p, Vec_Int_t * Vars ) +{ + int i, Var; + + Vec_IntForEachEntry( p->vHeap, Var, i ) + Vec_IntWriteEntry( p->vIndices, Var, -1 ); + Vec_IntClear( p->vHeap ); + + Vec_IntForEachEntry( Vars, Var, i ) + { + Vec_IntWriteEntry( p->vIndices, Var, i ); + Vec_IntPush( p->vHeap, Var ); + } + + for ( ( i = Vec_IntSize( p->vHeap ) / 2 - 1 ); i >= 0; i-- ) + xSAT_HeapPercolateDown( p, i ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_HeapClear( xSAT_Heap_t * p ) +{ + Vec_IntFill( p->vIndices, Vec_IntSize( p->vIndices ), -1 ); + Vec_IntClear( p->vHeap ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int xSAT_HeapRemoveMin( xSAT_Heap_t * p ) +{ + int x = Vec_IntEntry( p->vHeap, 0 ); + Vec_IntWriteEntry( p->vHeap, 0, Vec_IntEntryLast( p->vHeap ) ); + Vec_IntWriteEntry( p->vIndices, Vec_IntEntry( p->vHeap, 0), 0 ); + Vec_IntWriteEntry( p->vIndices, x, -1 ); + Vec_IntPop( p->vHeap ); + if ( Vec_IntSize( p->vHeap ) > 1 ) + xSAT_HeapPercolateDown( p, 0 ); + return x; +} + +ABC_NAMESPACE_HEADER_END + +#endif diff --git a/src/sat/xsat/xsatMemory.h b/src/sat/xsat/xsatMemory.h new file mode 100644 index 000000000..3a961b977 --- /dev/null +++ b/src/sat/xsat/xsatMemory.h @@ -0,0 +1,225 @@ +/**CFile**************************************************************** + + FileName [xsatMemory.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [xSAT - A SAT solver written in C. + Read the license file for more info.] + + Synopsis [Memory management implementation.] + + Author [Bruno Schmitt ] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - November 10, 2016.] + + Revision [] + +***********************************************************************/ +#ifndef ABC__sat__xSAT__xsatMemory_h +#define ABC__sat__xSAT__xsatMemory_h + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// +#include "misc/util/abc_global.h" + +#include "xsatClause.h" + +ABC_NAMESPACE_HEADER_START + +//////////////////////////////////////////////////////////////////////// +/// STRUCTURE DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// +typedef struct xSAT_Mem_t_ xSAT_Mem_t; +struct xSAT_Mem_t_ +{ + uint32_t nSize; + uint32_t nCap; + uint32_t nWasted; + uint32_t * pData; +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xSAT_Clause_t * xSAT_MemClauseHand( xSAT_Mem_t * p, int h ) +{ + return h != UINT32_MAX ? ( xSAT_Clause_t * )( p->pData + h ) : NULL; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_MemGrow( xSAT_Mem_t * p, uint32_t nCap ) +{ + if ( p->nCap >= nCap ) + return; + + uint32_t nPrevCap = p->nCap; + while (p->nCap < nCap) + { + uint32_t delta = ((p->nCap >> 1) + (p->nCap >> 3) + 2) & ~1; + p->nCap += delta; + assert(p->nCap >= nPrevCap); + } + + assert(p->nCap > 0); + p->pData = ABC_REALLOC(uint32_t, p->pData, p->nCap); +} + +/**Function************************************************************* + + Synopsis [Allocating vector.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xSAT_Mem_t * xSAT_MemAlloc( int nCap ) +{ + xSAT_Mem_t * p; + p = ABC_CALLOC( xSAT_Mem_t, 1 ); + if (nCap <= 0) + nCap = 1024*1024; + + xSAT_MemGrow(p, nCap); + return p; +} + +/**Function************************************************************* + + Synopsis [Resetting vector.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_MemRestart( xSAT_Mem_t * p ) +{ + p->nSize = 0; + p->nWasted = 0; +} + +/**Function************************************************************* + + Synopsis [Freeing vector.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_MemFree( xSAT_Mem_t * p ) +{ + ABC_FREE( p->pData ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Creates new clause.] + + Description [The resulting clause is fully initialized.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline uint32_t xSAT_MemAppend( xSAT_Mem_t * p, int nSize ) +{ + assert(nSize > 0); + xSAT_MemGrow(p, p->nSize + nSize); + + uint32_t nPrevSize = p->nSize; + p->nSize += nSize; + assert(p->nSize > nPrevSize); + + return nPrevSize; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline uint32_t xSAT_MemCRef( xSAT_Mem_t * p, uint32_t * pC ) +{ + return ( uint32_t )( pC - &(p->pData[0]) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline uint32_t xSAT_MemCap( xSAT_Mem_t * p ) +{ + return p->nCap; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline uint32_t xSAT_MemWastedCap( xSAT_Mem_t * p ) +{ + return p->nWasted; +} + +ABC_NAMESPACE_HEADER_END + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// diff --git a/src/sat/xsat/xsatSolver.c b/src/sat/xsat/xsatSolver.c new file mode 100644 index 000000000..d6968a2d3 --- /dev/null +++ b/src/sat/xsat/xsatSolver.c @@ -0,0 +1,995 @@ +/**CFile**************************************************************** + + FileName [xsatSolver.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [xSAT - A SAT solver written in C. + Read the license file for more info.] + + Synopsis [Solver internal functions implementation.] + + Author [Bruno Schmitt ] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - November 10, 2016.] + + Revision [] + +***********************************************************************/ +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// +#include +#include +#include +#include + +#include "xsatHeap.h" +#include "xsatSolver.h" +#include "xsatUtils.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int xSAT_SolverDecide( xSAT_Solver_t* s ) +{ + int NextVar = VarUndef; + + while ( NextVar == VarUndef || Vec_StrEntry( s->vAssigns, NextVar ) != VarX ) + { + if ( xSAT_HeapSize( s->hOrder ) == 0 ) + { + NextVar = VarUndef; + break; + } + else + NextVar = xSAT_HeapRemoveMin( s->hOrder ); + } + return NextVar; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void xSAT_SolverRebuildOrderHeap( xSAT_Solver_t* s ) +{ + Vec_Int_t * vTemp = Vec_IntAlloc( Vec_StrSize( s->vAssigns ) ); + int Var; + + for ( Var = 0; Var < Vec_StrSize( s->vAssigns ); Var++ ) + if ( Vec_StrEntry( s->vAssigns, Var ) == VarX ) + Vec_IntPush( vTemp, Var ); + + xSAT_HeapBuild( s->hOrder, vTemp ); + Vec_IntFree( vTemp ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_SolverVarActRescale( xSAT_Solver_t * s ) +{ + unsigned * pActivity = (unsigned *) Vec_IntArray( s->vActivity ); + + for ( int i = 0; i < Vec_IntSize( s->vActivity ); i++ ) + pActivity[i] >>= 19; + + s->nVarActInc >>= 19; + s->nVarActInc = Abc_MaxInt( s->nVarActInc, (1 << 5) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_SolverVarActBump( xSAT_Solver_t* s, int Var ) +{ + unsigned * pActivity = (unsigned *) Vec_IntArray( s->vActivity ); + + pActivity[Var] += s->nVarActInc; + if ( pActivity[Var] & 0x80000000 ) + xSAT_SolverVarActRescale( s ); + + if ( xSAT_HeapInHeap( s->hOrder, Var ) ) + xSAT_HeapDecrease( s->hOrder, Var ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_SolverVarActDecay( xSAT_Solver_t * s ) +{ + s->nVarActInc += ( s->nVarActInc >> 4 ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_SolverClaActRescale( xSAT_Solver_t * s ) +{ + xSAT_Clause_t * pC; + int i, CRef; + + Vec_IntForEachEntry( s->vLearnts, CRef, i ) + { + pC = xSAT_SolverReadClause( s, (uint32_t) CRef ); + pC->pData[pC->nSize].Act >>= 14; + } + s->nClaActInc >>= 14; + s->nClaActInc = Abc_MaxInt( s->nClaActInc, ( 1 << 10 ) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_SolverClaActBump( xSAT_Solver_t* s, xSAT_Clause_t * pCla ) +{ + pCla->pData[pCla->nSize].Act += s->nClaActInc; + if ( pCla->pData[pCla->nSize].Act & 0x80000000 ) + xSAT_SolverClaActRescale( s ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_SolverClaActDecay( xSAT_Solver_t * s ) +{ + s->nClaActInc += ( s->nClaActInc >> 10 ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int xSAT_SolverClaCalcLBD( xSAT_Solver_t * s, xSAT_Clause_t * pCla ) +{ + int nLBD = 0; + + s->nStamp++; + for ( int i = 0; i < pCla->nSize; i++ ) + { + int Level = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( pCla->pData[i].Lit ) ); + if ( (unsigned) Vec_IntEntry( s->vStamp, Level ) != s->nStamp ) + { + Vec_IntWriteEntry( s->vStamp, Level, (int) s->nStamp ); + nLBD++; + } + } + return nLBD; +} + +static inline int xSAT_SolverClaCalcLBD2( xSAT_Solver_t * s, Vec_Int_t * vLits ) +{ + int nLBD = 0; + + s->nStamp++; + for ( int i = 0; i < Vec_IntSize( vLits ); i++ ) + { + int Level = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( Vec_IntEntry( vLits, i ) ) ); + if ( (unsigned) Vec_IntEntry( s->vStamp, Level ) != s->nStamp ) + { + Vec_IntWriteEntry( s->vStamp, Level, (int) s->nStamp ); + nLBD++; + } + } + return nLBD; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +uint32_t xSAT_SolverClaNew( xSAT_Solver_t * s, Vec_Int_t * vLits , int fLearnt ) +{ + assert( Vec_IntSize( vLits ) > 1); + assert( fLearnt == 0 || fLearnt == 1 ); + + uint32_t CRef; + xSAT_Clause_t * pCla; + xSAT_Watcher_t w1; + xSAT_Watcher_t w2; + + uint32_t nWords = 3 + fLearnt + Vec_IntSize( vLits ); + CRef = xSAT_MemAppend( s->pMemory, nWords ); + pCla = xSAT_SolverReadClause( s, CRef ); + pCla->fLearnt = fLearnt; + pCla->fMark = 0; + pCla->fReallocd = 0; + pCla->fCanBeDel = fLearnt; + pCla->nSize = Vec_IntSize( vLits ); + memcpy( &( pCla->pData[0].Lit ), Vec_IntArray( vLits ), sizeof( int ) * Vec_IntSize( vLits ) ); + + if ( fLearnt ) + { + Vec_IntPush( s->vLearnts, CRef ); + pCla->nLBD = xSAT_SolverClaCalcLBD2( s, vLits ); + pCla->pData[pCla->nSize].Act = 0; + s->Stats.nLearntLits += Vec_IntSize( vLits ); + xSAT_SolverClaActBump(s, pCla); + } + else + { + Vec_IntPush( s->vClauses, CRef ); + s->Stats.nClauseLits += Vec_IntSize( vLits ); + } + + w1.CRef = CRef; + w2.CRef = CRef; + w1.Blocker = pCla->pData[1].Lit; + w2.Blocker = pCla->pData[0].Lit; + + if ( Vec_IntSize( vLits ) == 2 ) + { + xSAT_WatchListPush( xSAT_VecWatchListEntry( s->vBinWatches, xSAT_NegLit( pCla->pData[0].Lit ) ), w1 ); + xSAT_WatchListPush( xSAT_VecWatchListEntry( s->vBinWatches, xSAT_NegLit( pCla->pData[1].Lit ) ), w2 ); + } + else + { + xSAT_WatchListPush( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( pCla->pData[0].Lit ) ), w1 ); + xSAT_WatchListPush( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( pCla->pData[1].Lit ) ), w2 ); + } + return CRef; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int xSAT_SolverEnqueue( xSAT_Solver_t* s, int Lit, uint32_t Reason ) +{ + int Var = xSAT_Lit2Var( Lit ); + + Vec_StrWriteEntry( s->vAssigns, Var, xSAT_LitSign( Lit ) ); + Vec_IntWriteEntry( s->vLevels, Var, xSAT_SolverDecisionLevel( s ) ); + Vec_IntWriteEntry( s->vReasons, Var, (int) Reason ); + Vec_IntPush( s->vTrail, Lit ); + + return true; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_SolverNewDecision( xSAT_Solver_t* s, int Lit ) +{ + assert( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lit ) ) == VarX ); + s->Stats.nDecisions++; + Vec_IntPush( s->vTrailLim, Vec_IntSize( s->vTrail ) ); + xSAT_SolverEnqueue( s, Lit, CRefUndef ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void xSAT_SolverCancelUntil( xSAT_Solver_t * s, int Level ) +{ + if ( xSAT_SolverDecisionLevel( s ) <= Level ) + return; + + for ( int c = Vec_IntSize( s->vTrail ) - 1; c >= Vec_IntEntry( s->vTrailLim, Level ); c-- ) + { + int Var = xSAT_Lit2Var( Vec_IntEntry( s->vTrail, c ) ); + + Vec_StrWriteEntry( s->vAssigns, Var, VarX ); + Vec_IntWriteEntry( s->vReasons, Var, ( int ) CRefUndef ); + Vec_StrWriteEntry( s->vPolarity, Var, xSAT_LitSign( Vec_IntEntry( s->vTrail, c ) ) ); + + if ( !xSAT_HeapInHeap( s->hOrder, Var ) ) + xSAT_HeapInsert( s->hOrder, Var ); + } + + s->iQhead = Vec_IntEntry( s->vTrailLim, Level ); + Vec_IntShrink( s->vTrail, Vec_IntEntry( s->vTrailLim, Level ) ); + Vec_IntShrink( s->vTrailLim, Level ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static int xSAT_SolverIsLitRemovable( xSAT_Solver_t* s, int Lit, int MinLevel ) +{ + int top = Vec_IntSize( s->vTagged ); + + assert( (uint32_t) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Lit ) ) != CRefUndef ); + Vec_IntClear( s->vStack ); + Vec_IntPush( s->vStack, xSAT_Lit2Var( Lit ) ); + + while ( Vec_IntSize( s->vStack ) ) + { + int v = Vec_IntPop( s->vStack ); + assert( (uint32_t) Vec_IntEntry( s->vReasons, v ) != CRefUndef); + xSAT_Clause_t* c = xSAT_SolverReadClause(s, ( uint32_t ) Vec_IntEntry( s->vReasons, v ) ); + int* Lits = &( c->pData[0].Lit ); + int i; + + if( c->nSize == 2 && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[0] ) ) == xSAT_LitSign( xSAT_NegLit( Lits[0] ) ) ) + { + assert( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[1] ) ) == xSAT_LitSign( ( Lits[1] ) ) ); + ABC_SWAP( int, Lits[0], Lits[1] ); + } + + for (i = 1; i < c->nSize; i++) + { + int v = xSAT_Lit2Var( Lits[i] ); + if ( !Vec_StrEntry( s->vSeen, v ) && Vec_IntEntry( s->vLevels, v ) ) + { + if ( (uint32_t) Vec_IntEntry( s->vReasons, v ) != CRefUndef && ((1 << (Vec_IntEntry( s->vLevels, v ) & 31)) & MinLevel)) + { + Vec_IntPush( s->vStack, v ); + Vec_IntPush( s->vTagged, Lits[i] ); + Vec_StrWriteEntry( s->vSeen, v, 1 ); + } + else + { + int Lit; + Vec_IntForEachEntryStart( s->vTagged, Lit, i, top ) + Vec_StrWriteEntry( s->vSeen, xSAT_Lit2Var(Lit), 0 ); + Vec_IntShrink( s->vTagged, top ); + return 0; + } + } + } + } + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static void xSAT_SolverClaMinimisation( xSAT_Solver_t * s, Vec_Int_t * vLits ) +{ + int * pLits = Vec_IntArray( vLits ); + int MinLevel = 0; + int i, j; + + for ( i = 1; i < Vec_IntSize( vLits ); i++ ) + { + int Level = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( pLits[i] ) ); + MinLevel |= 1 << ( Level & 31 ); + } + + /* Remove reduntant literals */ + Vec_IntAppend( s->vTagged, vLits ); + for ( i = j = 1; i < Vec_IntSize( vLits ); i++ ) + if ( (uint32_t) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( pLits[i] ) ) == CRefUndef || !xSAT_SolverIsLitRemovable( s, pLits[i], MinLevel ) ) + pLits[j++] = pLits[i]; + Vec_IntShrink( vLits, j ); + + /* Binary Resolution */ + if( Vec_IntSize( vLits ) <= 30 && xSAT_SolverClaCalcLBD2( s, vLits ) <= 6 ) + { + int Lit; + int FlaseLit = xSAT_NegLit( pLits[0] ); + + s->nStamp++; + Vec_IntForEachEntry( vLits, Lit, i ) + Vec_IntWriteEntry( s->vStamp, xSAT_Lit2Var( Lit ), s->nStamp ); + + xSAT_WatchList_t * ws = xSAT_VecWatchListEntry( s->vBinWatches, FlaseLit ); + xSAT_Watcher_t * begin = xSAT_WatchListArray( ws ); + xSAT_Watcher_t * end = begin + xSAT_WatchListSize( ws ); + xSAT_Watcher_t * pWatcher; + + int nb = 0; + for ( pWatcher = begin; pWatcher < end; pWatcher++ ) + { + int ImpLit = pWatcher->Blocker; + + if ( Vec_IntEntry( s->vStamp, xSAT_Lit2Var( ImpLit ) ) == s->nStamp && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( ImpLit ) ) == xSAT_LitSign( ImpLit ) ) + { + nb++; + Vec_IntWriteEntry( s->vStamp, xSAT_Lit2Var( ImpLit ), s->nStamp - 1 ); + } + } + + int l = Vec_IntSize( vLits ) - 1; + if ( nb > 0 ) + { + for ( i = 1; i < Vec_IntSize( vLits ) - nb; i++ ) + if ( Vec_IntEntry( s->vStamp, xSAT_Lit2Var( pLits[i] ) ) != s->nStamp ) + { + int TempLit = pLits[l]; + pLits[l] = pLits[i]; + pLits[i] = TempLit; + i--; l--; + } + + Vec_IntShrink( vLits, Vec_IntSize( vLits ) - nb ); + } + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static void xSAT_SolverAnalyze( xSAT_Solver_t* s, uint32_t ConfCRef, Vec_Int_t * vLearnt, int * OutBtLevel, unsigned * nLBD ) +{ + int* trail = Vec_IntArray( s->vTrail ); + int Count = 0; + int p = LitUndef; + int Idx = Vec_IntSize( s->vTrail ) - 1; + int* Lits; + int i, j; + + Vec_IntPush( vLearnt, LitUndef ); + do + { + assert( ConfCRef != CRefUndef ); + xSAT_Clause_t * c = xSAT_SolverReadClause(s, ConfCRef); + Lits = &( c->pData[0].Lit ); + + if( p != LitUndef && c->nSize == 2 && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var(Lits[0])) == xSAT_LitSign( xSAT_NegLit( Lits[0] ) ) ) + { + assert( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[1] ) ) == xSAT_LitSign( ( Lits[1] ) ) ); + ABC_SWAP( int, Lits[0], Lits[1] ); + } + + if ( c->fLearnt ) + xSAT_SolverClaActBump( s, c ); + + if ( c->fLearnt && c->nLBD > 2 ) + { + unsigned int nblevels = xSAT_SolverClaCalcLBD(s, c); + if ( nblevels + 1 < c->nLBD ) + { + if (c->nLBD <= s->Config.nLBDFrozenClause) + c->fCanBeDel = 0; + c->nLBD = nblevels; + } + } + + for ( j = ( p == LitUndef ? 0 : 1 ); j < c->nSize; j++ ) + { + int Var = xSAT_Lit2Var( Lits[j] ); + + if ( Vec_StrEntry( s->vSeen, Var ) == 0 && Vec_IntEntry( s->vLevels, Var ) > 0 ) + { + Vec_StrWriteEntry( s->vSeen, Var, 1 ); + xSAT_SolverVarActBump( s, Var ); + if ( Vec_IntEntry( s->vLevels, Var ) >= xSAT_SolverDecisionLevel( s ) ) + { + Count++; + if ( Vec_IntEntry( s->vReasons, Var ) != CRefUndef && xSAT_SolverReadClause( s, Vec_IntEntry( s->vReasons, Var ) )->fLearnt ) + Vec_IntPush( s->vLastDLevel, Var ); + } + else + Vec_IntPush( vLearnt, Lits[j] ); + } + } + + while ( !Vec_StrEntry( s->vSeen, xSAT_Lit2Var( trail[Idx--] ) ) ); + + // Next clause to look at + p = trail[Idx+1]; + ConfCRef = (uint32_t) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( p ) ); + Vec_StrWriteEntry( s->vSeen, xSAT_Lit2Var( p ), 0 ); + Count--; + + } while ( Count > 0 ); + + Vec_IntArray( vLearnt )[0] = xSAT_NegLit( p ); + + xSAT_SolverClaMinimisation( s, vLearnt ); + + // Find the backtrack level + Lits = Vec_IntArray( vLearnt ); + if ( Vec_IntSize( vLearnt ) == 1 ) + *OutBtLevel = 0; + else + { + int iMax = 1; + int Max = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( Lits[1] ) ); + int Tmp; + + for (i = 2; i < Vec_IntSize( vLearnt ); i++) + if ( Vec_IntEntry( s->vLevels, xSAT_Lit2Var( Lits[i]) ) > Max) + { + Max = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( Lits[i]) ); + iMax = i; + } + + Tmp = Lits[1]; + Lits[1] = Lits[iMax]; + Lits[iMax] = Tmp; + *OutBtLevel = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( Lits[1] ) ); + } + + *nLBD = xSAT_SolverClaCalcLBD2( s, vLearnt ); + if ( Vec_IntSize( s->vLastDLevel ) > 0 ) + { + int Var; + Vec_IntForEachEntry( s->vLastDLevel, Var, i ) + { + if ( xSAT_SolverReadClause( s, Vec_IntEntry( s->vReasons, Var ) )->nLBD < *nLBD ) + xSAT_SolverVarActBump( s, Var ); + } + + Vec_IntClear( s->vLastDLevel ); + } + + int Lit; + Vec_IntForEachEntry( s->vTagged, Lit, i ) + Vec_StrWriteEntry( s->vSeen, xSAT_Lit2Var( Lit ), 0 ); + Vec_IntClear( s->vTagged ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +uint32_t xSAT_SolverPropagate( xSAT_Solver_t* s ) +{ + uint32_t hConfl = CRefUndef; + int * Lits; + int NegLit; + int nProp = 0; + + while ( s->iQhead < Vec_IntSize( s->vTrail ) ) + { + int p = Vec_IntEntry( s->vTrail, s->iQhead++ ); + + xSAT_WatchList_t* ws = xSAT_VecWatchListEntry( s->vBinWatches, p ); + xSAT_Watcher_t* begin = xSAT_WatchListArray( ws ); + xSAT_Watcher_t* end = begin + xSAT_WatchListSize( ws ); + xSAT_Watcher_t *i, *j; + + nProp++; + for (i = begin; i < end; i++) + { + if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var(i->Blocker)) == xSAT_LitSign(xSAT_NegLit(i->Blocker))) + { + return i->CRef; + } + else if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var(i->Blocker)) == VarX) + xSAT_SolverEnqueue(s, i->Blocker, i->CRef); + } + + + ws = xSAT_VecWatchListEntry( s->vWatches, p); + begin = xSAT_WatchListArray( ws ); + end = begin + xSAT_WatchListSize( ws ); + + for ( i = j = begin; i < end; ) + { + if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( i->Blocker ) ) == xSAT_LitSign( i->Blocker ) ) + { + *j++ = *i++; + continue; + } + + xSAT_Clause_t* c = xSAT_SolverReadClause( s, i->CRef ); + Lits = &( c->pData[0].Lit ); + + // Make sure the false literal is data[1]: + NegLit = xSAT_NegLit( p ); + if ( Lits[0] == NegLit ) + { + Lits[0] = Lits[1]; + Lits[1] = NegLit; + } + assert( Lits[1] == NegLit ); + + xSAT_Watcher_t w = { .CRef = i->CRef, + .Blocker = Lits[0] }; + // If 0th watch is true, then clause is already satisfied. + if ( Lits[0] != i->Blocker && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[0] ) ) == xSAT_LitSign( Lits[0] ) ) + *j++ = w; + else + { + // Look for new watch: + int* stop = Lits + c->nSize; + int* k; + for ( k = Lits + 2; k < stop; k++ ) + { + if (Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( *k ) ) != !xSAT_LitSign( *k ) ) + { + Lits[1] = *k; + *k = NegLit; + xSAT_WatchListPush( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( Lits[1] ) ), w ); + goto next; + } + } + + *j++ = w; + + // Clause is unit under assignment: + if (Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[0] ) ) == xSAT_LitSign( xSAT_NegLit( Lits[0] ) ) ) + { + hConfl = i->CRef; + i++; + s->iQhead = Vec_IntSize( s->vTrail ); + // Copy the remaining watches: + while (i < end) + *j++ = *i++; + } + else + xSAT_SolverEnqueue( s, Lits[0], i->CRef ); + } + next: + i++; + } + + s->Stats.nInspects += j - xSAT_WatchListArray( ws ); + xSAT_WatchListShrink( ws, j - xSAT_WatchListArray( ws ) ); + } + + s->Stats.nPropagations += nProp; + s->nPropSimplify -= nProp; + + return hConfl; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void xSAT_SolverReduceDB( xSAT_Solver_t * s ) +{ + static abctime TimeTotal = 0; + abctime clk = Abc_Clock(); + int nLearnedOld = Vec_IntSize( s->vLearnts ); + int i, limit; + uint32_t CRef; + xSAT_Clause_t * c; + xSAT_Clause_t ** learnts_cls; + + learnts_cls = ABC_ALLOC( xSAT_Clause_t *, nLearnedOld ); + Vec_IntForEachEntry( s->vLearnts, CRef, i ) + learnts_cls[i] = xSAT_SolverReadClause(s, CRef); + + limit = nLearnedOld / 2; + + xSAT_UtilSort((void *) learnts_cls, nLearnedOld, + (int (*)( const void *, const void * )) xSAT_ClauseCompare); + + if ( learnts_cls[nLearnedOld / 2]->nLBD <= 3 ) + s->nRC2 += s->Config.nSpecialIncReduce; + if ( learnts_cls[nLearnedOld - 1]->nLBD <= 5 ) + s->nRC2 += s->Config.nSpecialIncReduce; + + Vec_IntClear( s->vLearnts ); + for ( i = 0; i < nLearnedOld; i++ ) + { + c = learnts_cls[i]; + uint32_t CRef = xSAT_MemCRef( s->pMemory, (uint32_t * ) c ); + assert(c->fMark == 0); + if ( c->fCanBeDel && c->nLBD > 2 && c->nSize > 2 && (uint32_t) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( c->pData[0].Lit ) ) != CRef && ( i < limit ) ) + { + c->fMark = 1; + s->Stats.nLearntLits -= c->nSize; + xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( c->pData[0].Lit ) ), CRef ); + xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( c->pData[1].Lit ) ), CRef ); + } + else + { + if (!c->fCanBeDel) + limit++; + c->fCanBeDel = 1; + Vec_IntPush( s->vLearnts, CRef ); + } + } + ABC_FREE( learnts_cls ); + + TimeTotal += Abc_Clock() - clk; + if ( s->Config.fVerbose ) + { + Abc_Print(1, "reduceDB: Keeping %7d out of %7d clauses (%5.2f %%) ", + Vec_IntSize( s->vLearnts ), nLearnedOld, 100.0 * Vec_IntSize( s->vLearnts ) / nLearnedOld ); + Abc_PrintTime( 1, "Time", TimeTotal ); + } + xSAT_SolverGarbageCollect(s); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char xSAT_SolverSearch( xSAT_Solver_t * s ) +{ + ABC_INT64_T conflictC = 0; + + s->Stats.nStarts++; + for (;;) + { + uint32_t hConfl = xSAT_SolverPropagate( s ); + + if ( hConfl != CRefUndef ) + { + /* Conflict */ + int BacktrackLevel; + unsigned nLBD; + uint32_t CRef; + + s->Stats.nConflicts++; + conflictC++; + + if ( xSAT_SolverDecisionLevel( s ) == 0 ) + return LBoolFalse; + + xSAT_BQueuePush( s->bqTrail, Vec_IntSize( s->vTrail ) ); + if ( s->Stats.nConflicts > s->Config.nFirstBlockRestart && xSAT_BQueueIsValid( s->bqLBD ) && ( Vec_IntSize( s->vTrail ) > ( s->Config.R * xSAT_BQueueAvg( s->bqTrail ) ) ) ) + xSAT_BQueueClean(s->bqLBD); + + Vec_IntClear( s->vLearntClause ); + xSAT_SolverAnalyze( s, hConfl, s->vLearntClause, &BacktrackLevel, &nLBD ); + + s->nSumLBD += nLBD; + xSAT_BQueuePush( s->bqLBD, nLBD ); + xSAT_SolverCancelUntil( s, BacktrackLevel ); + + CRef = Vec_IntSize( s->vLearntClause ) == 1 ? CRefUndef : xSAT_SolverClaNew( s, s->vLearntClause , 1 ); + xSAT_SolverEnqueue( s, Vec_IntEntry( s->vLearntClause , 0 ), CRef ); + + xSAT_SolverVarActDecay( s ); + xSAT_SolverClaActDecay( s ); + } + else + { + /* No conflict */ + int NextVar; + if ( xSAT_BQueueIsValid( s->bqLBD ) && ( ( xSAT_BQueueAvg( s->bqLBD ) * s->Config.K ) > ( s->nSumLBD / s->Stats.nConflicts ) ) ) + { + xSAT_BQueueClean( s->bqLBD ); + xSAT_SolverCancelUntil( s, 0 ); + return LBoolUndef; + } + + // Simplify the set of problem clauses: + if ( xSAT_SolverDecisionLevel( s ) == 0 ) + xSAT_SolverSimplify( s ); + + // Reduce the set of learnt clauses: + if ( s->Stats.nConflicts >= s->nConfBeforeReduce ) + { + s->nRC1 = ( s->Stats.nConflicts / s->nRC2 ) + 1; + xSAT_SolverReduceDB(s); + s->nRC2 += s->Config.nIncReduce; + s->nConfBeforeReduce = s->nRC1 * s->nRC2; + } + + // New variable decision: + NextVar = xSAT_SolverDecide( s ); + + if ( NextVar == VarUndef ) + return LBoolTrue; + + xSAT_SolverNewDecision( s, xSAT_Var2Lit( NextVar, ( int ) Vec_StrEntry( s->vPolarity, NextVar ) ) ); + } + } + + return LBoolUndef; // cannot happen +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void xSAT_SolverClaRealloc( xSAT_Mem_t * pDest, xSAT_Mem_t * pSrc, uint32_t * pCRef ) +{ + xSAT_Clause_t * pOldCla = xSAT_MemClauseHand( pSrc, *pCRef ); + if ( pOldCla->fReallocd ) + { + *pCRef = (uint32_t) pOldCla->nSize; + return; + } + + uint32_t nNewCRef = xSAT_MemAppend( pDest, 3 + pOldCla->fLearnt + pOldCla->nSize ); + xSAT_Clause_t * pNewCla = xSAT_MemClauseHand( pDest, nNewCRef ); + + memcpy( pNewCla, pOldCla, ( 3 + pOldCla->fLearnt + pOldCla->nSize ) * 4 ); + + pOldCla->fReallocd = 1; + pOldCla->nSize = (unsigned) nNewCRef; + *pCRef = nNewCRef; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void xSAT_SolverGarbageCollect( xSAT_Solver_t * s ) +{ + int i; + uint32_t * pArray; + xSAT_Mem_t * pNewMemMngr = xSAT_MemAlloc( xSAT_MemCap( s->pMemory ) - xSAT_MemWastedCap( s->pMemory ) ); + + for ( i = 0; i < 2 * Vec_StrSize( s->vAssigns ); i++ ) + { + xSAT_WatchList_t* ws = xSAT_VecWatchListEntry( s->vWatches, i); + xSAT_Watcher_t* begin = xSAT_WatchListArray(ws); + xSAT_Watcher_t* end = begin + xSAT_WatchListSize(ws); + xSAT_Watcher_t *w; + + for ( w = begin; w != end; w++ ) + xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &(w->CRef) ); + + ws = xSAT_VecWatchListEntry( s->vBinWatches, i); + begin = xSAT_WatchListArray(ws); + end = begin + xSAT_WatchListSize(ws); + for ( w = begin; w != end; w++ ) + xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &(w->CRef) ); + } + + for ( i = 0; i < Vec_IntSize( s->vTrail ); i++ ) + if ( (uint32_t) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) ) ) != CRefUndef ) + xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &( Vec_IntArray( s->vReasons )[xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) )] ) ); + + pArray = ( uint32_t * ) Vec_IntArray( s->vLearnts ); + for ( i = 0; i < Vec_IntSize( s->vLearnts ); i++ ) + xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &(pArray[i]) ); + + pArray = (uint32_t *) Vec_IntArray( s->vClauses ); + for ( i = 0; i < Vec_IntSize( s->vClauses ); i++ ) + xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &(pArray[i]) ); + + xSAT_MemFree( s->pMemory ); + s->pMemory = pNewMemMngr; +} + +ABC_NAMESPACE_IMPL_END diff --git a/src/sat/xsat/xsatSolver.h b/src/sat/xsat/xsatSolver.h new file mode 100644 index 000000000..a6d646c61 --- /dev/null +++ b/src/sat/xsat/xsatSolver.h @@ -0,0 +1,247 @@ +/**CFile**************************************************************** + + FileName [xsatSolver.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [xSAT - A SAT solver written in C. + Read the license file for more info.] + + Synopsis [Internal definitions of the solver.] + + Author [Bruno Schmitt ] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - November 10, 2016.] + + Revision [] + +***********************************************************************/ +#ifndef ABC__sat__xSAT__xsatSolver_h +#define ABC__sat__xSAT__xsatSolver_h + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// +#include +#include +#include +#include + +#include "misc/util/abc_global.h" +#include "misc/vec/vecStr.h" + +#include "xsat.h" +#include "xsatBQueue.h" +#include "xsatClause.h" +#include "xsatHeap.h" +#include "xsatMemory.h" +#include "xsatWatchList.h" + +ABC_NAMESPACE_HEADER_START + +#ifndef __cplusplus +#ifndef false +# define false 0 +#endif +#ifndef true +# define true 1 +#endif +#endif + +enum +{ + Var0 = 1, + Var1 = 0, + VarX = 3 +}; + +enum +{ + LBoolUndef = 0, + LBoolTrue = 1, + LBoolFalse = -1 +}; + +enum +{ + VarUndef = -1, + LitUndef = -2 +}; + +#define CRefUndef UINT32_MAX + +//////////////////////////////////////////////////////////////////////// +/// STRUCTURE DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// +typedef struct xSAT_SolverOptions_t_ xSAT_SolverOptions_t; +struct xSAT_SolverOptions_t_ +{ + char fVerbose; + + // Limits + ABC_INT64_T nConfLimit; // external limit on the number of conflicts + ABC_INT64_T nInsLimit; // external limit on the number of implications + abctime nRuntimeLimit; // external limit on runtime + + // Constants used for restart heuristic + double K; // Forces a restart + double R; // Block a restart + int nFirstBlockRestart; // Lower bound number of conflicts for start blocking restarts + int nSizeLBDQueue; // Size of the moving avarege queue for LBD (force restart) + int nSizeTrailQueue; // Size of the moving avarege queue for Trail size (block restart) + + // Constants used for clause database reduction heuristic + int nConfFirstReduce; // Number of conflicts before first reduction + int nIncReduce; // Increment to reduce + int nSpecialIncReduce; // Special increment to reduce + unsigned nLBDFrozenClause; +}; + +typedef struct xSAT_Stats_t_ xSAT_Stats_t; +struct xSAT_Stats_t_ +{ + unsigned nStarts; + unsigned nReduceDB; + + ABC_INT64_T nDecisions; + ABC_INT64_T nPropagations; + ABC_INT64_T nInspects; + ABC_INT64_T nConflicts; + + ABC_INT64_T nClauseLits; + ABC_INT64_T nLearntLits; +}; + +struct xSAT_Solver_t_ +{ + /* Clauses Database */ + xSAT_Mem_t * pMemory; + Vec_Int_t * vLearnts; + Vec_Int_t * vClauses; + xSAT_VecWatchList_t * vWatches; + xSAT_VecWatchList_t * vBinWatches; + + /* Activity heuristic */ + int nVarActInc; /* Amount to bump next variable with. */ + int nClaActInc; /* Amount to bump next clause with. */ + + /* Variable Information */ + Vec_Int_t * vActivity; /* A heuristic measurement of the activity of a variable. */ + xSAT_Heap_t * hOrder; + Vec_Int_t * vLevels; /* Decision level of the current assignment */ + Vec_Int_t * vReasons; /* Reason (clause) of the current assignment */ + Vec_Str_t * vAssigns; /* Current assignment. */ + Vec_Str_t * vPolarity; + Vec_Str_t * vTags; + + /* Assignments */ + Vec_Int_t * vTrail; + Vec_Int_t * vTrailLim; // Separator indices for different decision levels in 'trail'. + int iQhead; // Head of propagation queue (as index into the trail). + + int nAssignSimplify; /* Number of top-level assignments since last + * execution of 'simplify()'. */ + int64_t nPropSimplify; /* Remaining number of propagations that must be + * made before next execution of 'simplify()'. */ + + /* Temporary data used by Search method */ + xSAT_BQueue_t * bqTrail; + xSAT_BQueue_t * bqLBD; + float nSumLBD; + int nConfBeforeReduce; + long nRC1; + int nRC2; + + /* Temporary data used by Analyze */ + Vec_Int_t * vLearntClause; + Vec_Str_t * vSeen; + Vec_Int_t * vTagged; + Vec_Int_t * vStack; + Vec_Int_t * vLastDLevel; + + /* Misc temporary */ + unsigned nStamp; + Vec_Int_t * vStamp; /* Multipurpose stamp used to calculate LBD and + * clauses minimization with binary resolution */ + + xSAT_SolverOptions_t Config; + xSAT_Stats_t Stats; +}; + +static inline int xSAT_Var2Lit( int Var, int c ) +{ + return Var + Var + ( c != 0 ); +} + +static inline int xSAT_NegLit( int Lit ) +{ + return Lit ^ 1; +} + +static inline int xSAT_Lit2Var( int Lit ) +{ + return Lit >> 1; +} + +static inline int xSAT_LitSign( int Lit ) +{ + return Lit & 1; +} + +static inline int xSAT_SolverDecisionLevel( xSAT_Solver_t * s ) +{ + return Vec_IntSize( s->vTrailLim ); +} + +static inline xSAT_Clause_t * xSAT_SolverReadClause( xSAT_Solver_t * s, uint32_t h ) +{ + return xSAT_MemClauseHand( s->pMemory, h ); +} + +static inline int xSAT_SolverIsClauseSatisfied( xSAT_Solver_t * s, xSAT_Clause_t * pCla ) +{ + int * lits = &( pCla->pData[0].Lit ); + + for ( int i = 0; i < pCla->nSize; i++ ) + if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( lits[i] ) ) == xSAT_LitSign( ( lits[i] ) ) ) + return true; + + return false; +} + +static inline void xSAT_SolverPrintClauses( xSAT_Solver_t * s ) +{ + int i; + unsigned CRef; + + Vec_IntForEachEntry( s->vClauses, CRef, i ) + xSAT_ClausePrint( xSAT_SolverReadClause( s, CRef ) ); +} + +static inline void xSAT_SolverPrintState( xSAT_Solver_t * s ) +{ + printf( "starts : %10d\n", s->Stats.nStarts ); + printf( "conflicts : %10ld\n", s->Stats.nConflicts ); + printf( "decisions : %10ld\n", s->Stats.nDecisions ); + printf( "propagations : %10ld\n", s->Stats.nPropagations ); +} + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// +extern uint32_t xSAT_SolverClaNew( xSAT_Solver_t* s, Vec_Int_t * vLits, int fLearnt ); +extern char xSAT_SolverSearch( xSAT_Solver_t * s ); + +extern void xSAT_SolverGarbageCollect( xSAT_Solver_t * s ); + +extern int xSAT_SolverEnqueue( xSAT_Solver_t* s, int Lit, uint32_t From ); +extern void xSAT_SolverCancelUntil( xSAT_Solver_t* s, int Level); +extern uint32_t xSAT_SolverPropagate( xSAT_Solver_t* s ); +extern void xSAT_SolverRebuildOrderHeap( xSAT_Solver_t* s ); + +ABC_NAMESPACE_HEADER_END + +#endif diff --git a/src/sat/xsat/xsatSolverAPI.c b/src/sat/xsat/xsatSolverAPI.c new file mode 100644 index 000000000..7ee817eeb --- /dev/null +++ b/src/sat/xsat/xsatSolverAPI.c @@ -0,0 +1,345 @@ +/**CFile**************************************************************** + + FileName [xsatSolverAPI.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [xSAT - A SAT solver written in C. + Read the license file for more info.] + + Synopsis [Solver external API functions implementation.] + + Author [Bruno Schmitt ] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - November 10, 2016.] + + Revision [] + +***********************************************************************/ +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// +#include +#include +#include +#include + +#include "xsatSolver.h" + +ABC_NAMESPACE_IMPL_START + +xSAT_SolverOptions_t DefaultConfig = +{ + .fVerbose = 1, + + .nConfLimit = 0, + .nInsLimit = 0, + .nRuntimeLimit = 0, + + .K = 0.8, + .R = 1.4, + .nFirstBlockRestart = 10000, + .nSizeLBDQueue = 50, + .nSizeTrailQueue = 5000, + + .nConfFirstReduce = 2000, + .nIncReduce = 300, + .nSpecialIncReduce = 1000, + + .nLBDFrozenClause = 30 +}; + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +xSAT_Solver_t* xSAT_SolverCreate() +{ + xSAT_Solver_t * s = (xSAT_Solver_t *) ABC_CALLOC( char, sizeof( xSAT_Solver_t ) ); + s->Config = DefaultConfig; + + s->pMemory = xSAT_MemAlloc(0); + s->vClauses = Vec_IntAlloc(0); + s->vLearnts = Vec_IntAlloc(0); + s->vWatches = xSAT_VecWatchListAlloc( 0 ); + s->vBinWatches = xSAT_VecWatchListAlloc( 0 ); + + s->vTrailLim = Vec_IntAlloc(0); + s->vTrail = Vec_IntAlloc( 0 ); + + s->vActivity = Vec_IntAlloc( 0 ); + s->hOrder = xSAT_HeapAlloc( s->vActivity ); + + s->vPolarity = Vec_StrAlloc( 0 ); + s->vTags = Vec_StrAlloc( 0 ); + s->vAssigns = Vec_StrAlloc( 0 ); + s->vLevels = Vec_IntAlloc( 0 ); + s->vReasons = Vec_IntAlloc( 0 ); + s->vStamp = Vec_IntAlloc( 0 ); + + s->vTagged = Vec_IntAlloc(0); + s->vStack = Vec_IntAlloc(0); + + s->vSeen = Vec_StrAlloc( 0 ); + s->vLearntClause = Vec_IntAlloc(0); + s->vLastDLevel = Vec_IntAlloc(0); + + + s->bqTrail = xSAT_BQueueNew( s->Config.nSizeTrailQueue ); + s->bqLBD = xSAT_BQueueNew( s->Config.nSizeLBDQueue ); + + s->nVarActInc = (1 << 5); + s->nClaActInc = (1 << 11); + + s->nConfBeforeReduce = s->Config.nConfFirstReduce; + s->nRC1 = 1; + s->nRC2 = s->Config.nConfFirstReduce; + return s; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void xSAT_SolverDestroy( xSAT_Solver_t * s ) +{ + xSAT_MemFree( s->pMemory ); + Vec_IntFree( s->vClauses ); + Vec_IntFree( s->vLearnts ); + xSAT_VecWatchListFree( s->vWatches ); + xSAT_VecWatchListFree( s->vBinWatches ); + + // delete vectors + xSAT_HeapFree(s->hOrder); + Vec_IntFree( s->vTrailLim ); + Vec_IntFree( s->vTrail ); + Vec_IntFree( s->vTagged ); + Vec_IntFree( s->vStack ); + + Vec_StrFree( s->vSeen ); + Vec_IntFree( s->vLearntClause ); + Vec_IntFree( s->vLastDLevel ); + + Vec_IntFree( s->vActivity ); + Vec_StrFree( s->vPolarity ); + Vec_StrFree( s->vTags ); + Vec_StrFree( s->vAssigns ); + Vec_IntFree( s->vLevels ); + Vec_IntFree( s->vReasons ); + + xSAT_BQueueFree(s->bqLBD); + xSAT_BQueueFree(s->bqTrail); + + ABC_FREE(s); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int xSAT_SolverSimplify( xSAT_Solver_t * s ) +{ + int i, j; + uint32_t CRef; + assert( xSAT_SolverDecisionLevel(s) == 0 ); + + if ( xSAT_SolverPropagate(s) != CRefUndef ) + return false; + + if ( s->nAssignSimplify == Vec_IntSize( s->vTrail ) || s->nPropSimplify > 0 ) + return true; + + j = 0; + Vec_IntForEachEntry( s->vClauses, CRef, i ) + { + xSAT_Clause_t * pCla = xSAT_SolverReadClause( s, CRef ); + if ( xSAT_SolverIsClauseSatisfied( s, pCla ) ) + { + pCla->fMark = 1; + s->Stats.nClauseLits -= pCla->nSize; + + if ( pCla->nSize == 2 ) + { + xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vBinWatches, xSAT_NegLit(pCla->pData[0].Lit) ), CRef ); + xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vBinWatches, xSAT_NegLit(pCla->pData[1].Lit) ), CRef ); + } + else + { + xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit(pCla->pData[0].Lit) ), CRef ); + xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit(pCla->pData[1].Lit) ), CRef ); + } + } + else + Vec_IntWriteEntry( s->vClauses, j++, CRef ); + } + Vec_IntShrink( s->vClauses, j ); + xSAT_SolverRebuildOrderHeap( s ); + + s->nAssignSimplify = Vec_IntSize( s->vTrail ); + s->nPropSimplify = s->Stats.nClauseLits + s->Stats.nLearntLits; + + return true; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void xSAT_SolverAddVariable( xSAT_Solver_t* s, int Sign ) +{ + int Var = Vec_IntSize( s->vActivity ); + + xSAT_VecWatchListPush( s->vWatches ); + xSAT_VecWatchListPush( s->vWatches ); + xSAT_VecWatchListPush( s->vBinWatches ); + xSAT_VecWatchListPush( s->vBinWatches ); + + Vec_IntPush( s->vActivity, 0 ); + Vec_IntPush( s->vLevels, 0 ); + Vec_StrPush( s->vAssigns, VarX ); + Vec_StrPush( s->vPolarity, 1 ); + Vec_StrPush( s->vTags, 0 ); + Vec_IntPush( s->vReasons, ( int ) CRefUndef ); + Vec_IntPush( s->vStamp, 0 ); + Vec_StrPush( s->vSeen, 0 ); + + xSAT_HeapInsert( s->hOrder, Var ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int xSAT_SolverAddClause( xSAT_Solver_t * s, Vec_Int_t * vLits ) +{ + int i, j; + int Lit, PrevLit; + int MaxVar; + + Vec_IntSort( vLits, 0 ); + MaxVar = xSAT_Lit2Var( Vec_IntEntryLast( vLits ) ); + while ( MaxVar >= Vec_IntSize( s->vActivity ) ) + xSAT_SolverAddVariable( s, 1 ); + + j = 0; + PrevLit = LitUndef; + Vec_IntForEachEntry( vLits, Lit, i ) + { + if ( Lit == xSAT_NegLit( PrevLit ) || Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lit ) ) == xSAT_LitSign( Lit ) ) + return true; + else if ( Lit != PrevLit && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lit ) ) == VarX ) + { + PrevLit = Lit; + Vec_IntWriteEntry( vLits, j++, Lit ); + } + } + Vec_IntShrink( vLits, j ); + + if ( Vec_IntSize( vLits ) == 0 ) + return false; + if ( Vec_IntSize( vLits ) == 1 ) + { + xSAT_SolverEnqueue( s, Vec_IntEntry( vLits, 0 ), CRefUndef ); + return ( xSAT_SolverPropagate( s ) == CRefUndef ); + } + + xSAT_SolverClaNew( s, vLits, 0 ); + return true; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int xSAT_SolverSolve( xSAT_Solver_t* s ) +{ + char status = LBoolUndef; + + assert(s); + if ( s->Config.fVerbose ) + { + printf( "==========================================[ BLACK MAGIC ]================================================\n" ); + printf( "| | | |\n" ); + printf( "| - Restarts: | - Reduce Clause DB: | - Minimize Asserting: |\n" ); + printf( "| * LBD Queue : %6d | * First : %6d | * size < %3d |\n", s->Config.nSizeLBDQueue, s->Config.nConfFirstReduce, 0 ); + printf( "| * Trail Queue : %6d | * Inc : %6d | * lbd < %3d |\n", s->Config.nSizeTrailQueue, s->Config.nIncReduce, 0 ); + printf( "| * K : %6.2f | * Special : %6d | |\n", s->Config.K, s->Config.nSpecialIncReduce ); + printf( "| * R : %6.2f | * Protected : (lbd)< %2d | |\n", s->Config.R, s->Config.nLBDFrozenClause ); + printf( "| | | |\n" ); + printf( "=========================================================================================================\n" ); + } + + while ( status == LBoolUndef ) + status = xSAT_SolverSearch( s ); + + if ( s->Config.fVerbose ) + printf( "=========================================================================================================\n" ); + + xSAT_SolverCancelUntil( s, 0 ); + return status; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void xSAT_SolverPrintStats( xSAT_Solver_t * s ) +{ + printf( "starts : %10d\n", s->Stats.nStarts ); + printf( "conflicts : %10ld\n", s->Stats.nConflicts ); + printf( "decisions : %10ld\n", s->Stats.nDecisions ); + printf( "propagations : %10ld\n", s->Stats.nPropagations ); +} + +ABC_NAMESPACE_IMPL_END diff --git a/src/sat/xsat/xsatUtils.h b/src/sat/xsat/xsatUtils.h new file mode 100644 index 000000000..7f774d85b --- /dev/null +++ b/src/sat/xsat/xsatUtils.h @@ -0,0 +1,106 @@ +/**CFile**************************************************************** + + FileName [xsatUtils.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [xSAT - A SAT solver written in C. + Read the license file for more info.] + + Synopsis [Utility functions used in xSAT] + + Author [Bruno Schmitt ] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - November 10, 2016.] + + Revision [] + +***********************************************************************/ +#ifndef ABC__sat__xSAT__xsatUtils_h +#define ABC__sat__xSAT__xsatUtils_h + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// +#include "misc/util/abc_global.h" + +ABC_NAMESPACE_HEADER_START + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_UtilSelectSort( void** pArray, int nSize, int(* CompFnct )( const void *, const void * ) ) +{ + int i, j, iBest; + void* pTmp; + + for ( i = 0; i < ( nSize - 1 ); i++ ) + { + iBest = i; + for ( j = i + 1; j < nSize; j++ ) + { + if ( CompFnct( pArray[j], pArray[iBest] ) ) + iBest = j; + } + pTmp = pArray[i]; + pArray[i] = pArray[iBest]; + pArray[iBest] = pTmp; + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static void xSAT_UtilSort( void** pArray, int nSize, int(* CompFnct )( const void *, const void *) ) +{ + if ( nSize <= 15 ) + xSAT_UtilSelectSort( pArray, nSize, CompFnct ); + else + { + void* pPivot = pArray[nSize / 2]; + void* pTmp; + int i = -1; + int j = nSize; + + for(;;) + { + do i++; while( CompFnct( pArray[i], pPivot ) ); + do j--; while( CompFnct( pPivot, pArray[j] ) ); + + if ( i >= j ) + break; + + pTmp = pArray[i]; + pArray[i] = pArray[j]; + pArray[j] = pTmp; + } + + xSAT_UtilSort( pArray, i, CompFnct ); + xSAT_UtilSort( pArray + i, ( nSize - i ), CompFnct ); + } +} + +ABC_NAMESPACE_HEADER_END + +#endif +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// diff --git a/src/sat/xsat/xsatWatchList.h b/src/sat/xsat/xsatWatchList.h new file mode 100644 index 000000000..454cfe44d --- /dev/null +++ b/src/sat/xsat/xsatWatchList.h @@ -0,0 +1,268 @@ +/**CFile**************************************************************** + + FileName [xsatWatchList.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [xSAT - A SAT solver written in C. + Read the license file for more info.] + + Synopsis [Watch list and its related structures implementation] + + Author [Bruno Schmitt ] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - November 10, 2016.] + + Revision [] + +***********************************************************************/ +#ifndef ABC__sat__xSAT__xsatWatchList_h +#define ABC__sat__xSAT__xsatWatchList_h + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// +#include "misc/util/abc_global.h" + +ABC_NAMESPACE_HEADER_START + +//////////////////////////////////////////////////////////////////////// +/// STRUCTURE DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// +typedef struct xSAT_Watcher_t_ xSAT_Watcher_t; +struct xSAT_Watcher_t_ +{ + uint32_t CRef; + int Blocker; +}; + +typedef struct xSAT_WatchList_t_ xSAT_WatchList_t; +struct xSAT_WatchList_t_ +{ + int nCap; + int nSize; + xSAT_Watcher_t * pArray; +}; + +typedef struct xSAT_VecWatchList_t_ xSAT_VecWatchList_t; +struct xSAT_VecWatchList_t_ +{ + int nCap; + int nSize; + xSAT_WatchList_t * pArray; +}; + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_WatchListFree( xSAT_WatchList_t * v ) +{ + if ( v->pArray ) + ABC_FREE( v->pArray ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int xSAT_WatchListSize( xSAT_WatchList_t * v ) +{ + return v->nSize; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_WatchListShrink( xSAT_WatchList_t * v, int k ) +{ + assert(k <= v->nSize); + v->nSize = k; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_WatchListPush( xSAT_WatchList_t * v, xSAT_Watcher_t e ) +{ + assert( v ); + if (v->nSize == v->nCap) + { + int newsize = (v->nCap < 4) ? 4 : (v->nCap / 2) * 3; + + v->pArray = ABC_REALLOC( xSAT_Watcher_t, v->pArray, newsize ); + if ( v->pArray == NULL ) + { + printf( "Failed to realloc memory from %.1f MB to %.1f MB.\n", + 1.0 * v->nCap / (1<<20), 1.0 * newsize / (1<<20) ); + fflush( stdout ); + } + v->nCap = newsize; + } + + v->pArray[v->nSize++] = e; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xSAT_Watcher_t* xSAT_WatchListArray( xSAT_WatchList_t * v ) +{ + return v->pArray; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_WatchListRemove( xSAT_WatchList_t * v, uint32_t CRef ) +{ + xSAT_Watcher_t* ws = xSAT_WatchListArray(v); + int j = 0; + + for (; ws[j].CRef != CRef; j++); + assert(j < xSAT_WatchListSize(v)); + memmove(v->pArray + j, v->pArray + j + 1, (v->nSize - j - 1) * sizeof(xSAT_Watcher_t)); + v->nSize -= 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xSAT_VecWatchList_t * xSAT_VecWatchListAlloc( int nCap ) +{ + xSAT_VecWatchList_t * v = ABC_ALLOC( xSAT_VecWatchList_t, 1 ); + + v->nCap = 4; + v->nSize = 0; + v->pArray = (xSAT_WatchList_t *) ABC_CALLOC(xSAT_WatchList_t, sizeof( xSAT_WatchList_t ) * v->nCap); + return v; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_VecWatchListFree( xSAT_VecWatchList_t* v ) +{ + for( int i = 0; i < v->nSize; i++ ) + xSAT_WatchListFree( v->pArray + i ); + + ABC_FREE( v->pArray ); + ABC_FREE( v ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_VecWatchListPush( xSAT_VecWatchList_t* v ) +{ + if ( v->nSize == v->nCap ) + { + int newsize = (v->nCap < 4) ? v->nCap * 2 : (v->nCap / 2) * 3; + + v->pArray = ABC_REALLOC( xSAT_WatchList_t, v->pArray, newsize ); + memset( v->pArray + v->nCap, 0, sizeof(xSAT_WatchList_t) * (newsize - v->nCap) ); + if ( v->pArray == NULL ) + { + printf( "Failed to realloc memory from %.1f MB to %.1f MB.\n", + 1.0 * v->nCap / (1<<20), 1.0 * newsize / (1<<20) ); + fflush( stdout ); + } + v->nCap = newsize; + } + + v->nSize++; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xSAT_WatchList_t * xSAT_VecWatchListEntry( xSAT_VecWatchList_t* v, int iEntry ) +{ + assert( iEntry < v->nCap ); + assert( iEntry < v->nSize ); + return v->pArray + iEntry; +} + +ABC_NAMESPACE_HEADER_END + +#endif From 81af996fee2626daf45936e892ab34f26bea2ada Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 13 Dec 2016 10:02:28 +0800 Subject: [PATCH 004/185] Bug fix in 'dsat ' when the number of classes in listed incorrectly. --- abclib.dsp | 48 +++++++++ src/aig/gia/giaShow.c | 12 +-- src/proof/acec/acecCl.c | 204 +++++++++++++++++++++++++++++++++++ src/sat/cnf/cnfUtil.c | 2 +- src/sat/xsat/xsatBQueue.h | 17 +-- src/sat/xsat/xsatClause.h | 2 +- src/sat/xsat/xsatMemory.h | 31 +++--- src/sat/xsat/xsatSolver.c | 129 ++++++++++++---------- src/sat/xsat/xsatSolver.h | 31 +++--- src/sat/xsat/xsatSolverAPI.c | 29 ++--- src/sat/xsat/xsatWatchList.h | 7 +- 11 files changed, 396 insertions(+), 116 deletions(-) diff --git a/abclib.dsp b/abclib.dsp index 3ffe0e448..9b1c9d945 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -1938,6 +1938,54 @@ SOURCE=.\src\sat\bmc\bmcUnroll.c # PROP Default_Filter "" # End Group +# Begin Group "xsat" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\sat\xsat\xsat.h +# End Source File +# Begin Source File + +SOURCE=.\src\sat\xsat\xsatBQueue.h +# End Source File +# Begin Source File + +SOURCE=.\src\sat\xsat\xsatClause.h +# End Source File +# Begin Source File + +SOURCE=.\src\sat\xsat\xsatCnfReader.c +# End Source File +# Begin Source File + +SOURCE=.\src\sat\xsat\xsatHeap.h +# End Source File +# Begin Source File + +SOURCE=.\src\sat\xsat\xsatMemory.h +# End Source File +# Begin Source File + +SOURCE=.\src\sat\xsat\xsatSolver.c +# End Source File +# Begin Source File + +SOURCE=.\src\sat\xsat\xsatSolver.h +# End Source File +# Begin Source File + +SOURCE=.\src\sat\xsat\xsatSolverAPI.c +# End Source File +# Begin Source File + +SOURCE=.\src\sat\xsat\xsatUtils.h +# End Source File +# Begin Source File + +SOURCE=.\src\sat\xsat\xsatWatchList.h +# End Source File +# End Group # End Group # Begin Group "opt" diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index c68ba26cf..afc58bf8e 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -52,9 +52,9 @@ void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold ) int LevelMax, Prev, Level, i; int fConstIsUsed = 0; - if ( Gia_ManAndNum(p) > 200 ) + if ( Gia_ManAndNum(p) > 500 ) { - fprintf( stdout, "Cannot visualize AIG with more than 200 nodes.\n" ); + fprintf( stdout, "Cannot visualize AIG with more than 500 nodes.\n" ); return; } if ( (pFile = fopen( pFileName, "w" )) == NULL ) @@ -378,7 +378,7 @@ int Gia_ShowAddOut( Vec_Int_t * vAdds, Vec_Int_t * vMapAdds, int Node ) { int iBox = Vec_IntEntry( vMapAdds, Node ); if ( iBox >= 0 ) - return Vec_IntEntry( vAdds, 6*iBox+3 ); + return Vec_IntEntry( vAdds, 6*iBox+4 ); return Node; } void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_Int_t * vXors, Vec_Int_t * vMapAdds, Vec_Int_t * vMapXors, Vec_Int_t * vOrder ) @@ -388,9 +388,9 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In int LevelMax, Prev, Level, i; int fConstIsUsed = 0; - if ( Gia_ManAndNum(p) > 500 ) + if ( Gia_ManAndNum(p) > 1000 ) { - fprintf( stdout, "Cannot visualize AIG with more than 200 nodes.\n" ); + fprintf( stdout, "Cannot visualize AIG with more than 1000 nodes.\n" ); return; } if ( (pFile = fopen( pFileName, "w" )) == NULL ) @@ -750,7 +750,7 @@ int Gia_ShowCollectObjs_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vAdds, Level = 1 + Abc_MaxInt( Abc_MaxInt(Level0, Level1), Level2 ); Gia_ObjSetLevelId( p, Vec_IntEntry(vAdds, 6*iBox+3), Level ); Gia_ObjSetLevelId( p, Vec_IntEntry(vAdds, 6*iBox+4), Level ); - pObj = Gia_ManObj( p, Vec_IntEntry(vAdds, 6*iBox+3) ); + pObj = Gia_ManObj( p, Vec_IntEntry(vAdds, 6*iBox+4) ); } else if ( Vec_IntEntry(vMapXors, Gia_ObjId(p, pObj)) >= 0 ) { diff --git a/src/proof/acec/acecCl.c b/src/proof/acec/acecCl.c index 32be3b300..b60c2bf9e 100644 --- a/src/proof/acec/acecCl.c +++ b/src/proof/acec/acecCl.c @@ -45,6 +45,210 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ +void Acec_ManDerive_rec( Gia_Man_t * pNew, Gia_Man_t * p, int Node, Vec_Int_t * vMirrors ) +{ + Gia_Obj_t * pObj; + int Obj = Node; + if ( Vec_IntEntry(vMirrors, Node) >= 0 ) + Obj = Abc_Lit2Var( Vec_IntEntry(vMirrors, Node) ); + pObj = Gia_ManObj( p, Obj ); + if ( !~pObj->Value ) + { + assert( Gia_ObjIsAnd(pObj) ); + Acec_ManDerive_rec( pNew, p, Gia_ObjFaninId0(pObj, Obj), vMirrors ); + Acec_ManDerive_rec( pNew, p, Gia_ObjFaninId1(pObj, Obj), vMirrors ); + if ( Gia_ObjIsXor(pObj) ) + pObj->Value = Gia_ManAppendXorReal( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + else + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + } + // set the original node as well + if ( Obj != Node ) + Gia_ManObj(p, Node)->Value = Abc_LitNotCond( pObj->Value, Abc_LitIsCompl(Vec_IntEntry(vMirrors, Node)) ); +} +Gia_Man_t * Acec_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + assert( p->pMuxes == NULL ); + Gia_ManFillValue( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManConst0(p)->Value = 0; + Gia_ManHashAlloc( pNew ); + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManForEachCo( p, pObj, i ) + Acec_ManDerive_rec( pNew, p, Gia_ObjFaninId0p(p, pObj), vMirrors ); + Gia_ManForEachCo( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManHashStop( pNew ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Acec_CollectXorTops( Gia_Man_t * p ) +{ + Vec_Int_t * vRootXorSet = Vec_IntAlloc( Gia_ManCoNum(p) ); + Gia_Obj_t * pObj, * pFan0, * pFan1, * pFan00, * pFan01, * pFan10, * pFan11; + int i, fXor0, fXor1, fFirstXor = 0; + Gia_ManForEachCoDriver( p, pObj, i ) + { + if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) ) + { + if ( fFirstXor ) + { + printf( "XORs do not form a continuous sequence\n" ); + Vec_IntFreeP( &vRootXorSet ); + break; + } + continue; + } + fFirstXor = 1; + fXor0 = Gia_ObjRecognizeExor(Gia_Regular(pFan0), &pFan00, &pFan01); + fXor1 = Gia_ObjRecognizeExor(Gia_Regular(pFan1), &pFan10, &pFan11); + if ( fXor0 == fXor1 ) + { + printf( "Both inputs of top level XOR have XOR/non-XOR\n" ); + Vec_IntFreeP( &vRootXorSet ); + break; + } + Vec_IntPush( vRootXorSet, Gia_ObjId(p, pObj) ); + Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan1)) : Gia_ObjId(p, Gia_Regular(pFan0)) ); + Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan10)) : Gia_ObjId(p, Gia_Regular(pFan00)) ); + Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan11)) : Gia_ObjId(p, Gia_Regular(pFan01)) ); + } + for ( i = 0; 4*i < Vec_IntSize(vRootXorSet); i++ ) + { + printf( "%2d : ", i ); + printf( "%4d <- ", Vec_IntEntry(vRootXorSet, 4*i) ); + printf( "%4d ", Vec_IntEntry(vRootXorSet, 4*i+1) ); + printf( "%4d ", Vec_IntEntry(vRootXorSet, 4*i+2) ); + printf( "%4d ", Vec_IntEntry(vRootXorSet, 4*i+3) ); + printf( "\n" ); + } + return vRootXorSet; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_DetectLitPolarity( Gia_Man_t * p, int Node, int Leaf ) +{ + Gia_Obj_t * pNode; + int Lit0, Lit1; + if ( Node < Leaf ) + return -1; + if ( Node == Leaf ) + return Abc_Var2Lit(Node, 0); + pNode = Gia_ManObj( p, Node ); + Lit0 = Acec_DetectLitPolarity( p, Gia_ObjFaninId0(pNode, Node), Leaf ); + Lit1 = Acec_DetectLitPolarity( p, Gia_ObjFaninId1(pNode, Node), Leaf ); + Lit0 = Lit0 == -1 ? Lit0 : Abc_LitNotCond( Lit0, Gia_ObjFaninC0(pNode) ); + Lit1 = Lit1 == -1 ? Lit1 : Abc_LitNotCond( Lit1, Gia_ObjFaninC1(pNode) ); + if ( Lit0 == -1 && Lit1 == -1 ) + return -1; + assert( Lit0 != -1 || Lit1 != -1 ); + if ( Lit0 != -1 && Lit1 != -1 ) + { + assert( Lit0 == Lit1 ); + return Lit0; + } + return Lit0 != -1 ? Lit0 : Lit1; +} +Gia_Man_t * Acec_DetectXorBuildNew( Gia_Man_t * p, Vec_Int_t * vRootXorSet ) +{ + Gia_Man_t * pNew; + int i, k, iOr1, iAnd1, iAnd2, pLits[3]; // carry, in1, in2 + Vec_Int_t * vMirrors = Vec_IntStart( Gia_ManObjNum(p) ); + for ( i = 0; 4*i < Vec_IntSize(vRootXorSet); i++ ) + { + pLits[0] = Acec_DetectLitPolarity( p, Vec_IntEntry(vRootXorSet, 4*i), Vec_IntEntry(vRootXorSet, 4*i+1) ); + // get polarity of two new ones + for ( k = 1; k < 3; k++ ) + pLits[k] = Acec_DetectLitPolarity( p, Vec_IntEntry(vRootXorSet, 4*i), Vec_IntEntry(vRootXorSet, 4*i+k+1) ); + // create the gate + iOr1 = Gia_ManAppendOr( p, pLits[1], pLits[2] ); + iAnd1 = Gia_ManAppendAnd( p, pLits[0], iOr1 ); + iAnd2 = Gia_ManAppendAnd( p, pLits[1], pLits[2] ); + pLits[0] = Gia_ManAppendOr( p, iAnd1, iAnd2 ); + Vec_IntWriteEntry( vMirrors, Vec_IntEntry(vRootXorSet, 4*i+1), pLits[0] ); + } + // remap the AIG using map + pNew = Acec_ManDerive( p, vMirrors ); + Vec_IntFree( vMirrors ); + return pNew; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Acec_DetectAdditional( Gia_Man_t * p, int fVerbose ) +{ + extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); + extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ); + extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds ); + extern int Ree_ManCountFadds( Vec_Int_t * vAdds ); + extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose ); + + abctime clk = Abc_Clock(); + Gia_Man_t * pNew; + Vec_Int_t * vRootXorSet; +// Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( p, &vXors, 0 ); +// Ree_ManRemoveTrivial( p, vAdds ); +// Ree_ManRemoveContained( p, vAdds ); + + //Ree_ManPrintAdders( vAdds, 1 ); +// printf( "Detected %d full-adders and %d half-adders. Found %d XOR-cuts. ", Ree_ManCountFadds(vAdds), Vec_IntSize(vAdds)/6-Ree_ManCountFadds(vAdds), Vec_IntSize(vXors)/4 ); +// Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + + clk = Abc_Clock(); + vRootXorSet = Acec_CollectXorTops( p ); + if ( vRootXorSet ) + { + pNew = Acec_DetectXorBuildNew( p, vRootXorSet ); + Vec_IntFree( vRootXorSet ); + } + else + pNew = Gia_ManDup( p ); + + printf( "Detected %d top XORs. ", Vec_IntSize(vRootXorSet)/4 ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + +// Vec_IntFree( vXors ); +// Vec_IntFree( vAdds ); + return pNew; +} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/sat/cnf/cnfUtil.c b/src/sat/cnf/cnfUtil.c index 96002df89..5ccbeb0dd 100644 --- a/src/sat/cnf/cnfUtil.c +++ b/src/sat/cnf/cnfUtil.c @@ -374,7 +374,7 @@ Cnf_Dat_t * Cnf_DataReadFromFile( char * pFileName ) // create pCnf = ABC_CALLOC( Cnf_Dat_t, 1 ); pCnf->nVars = nVars; - pCnf->nClauses = nClas; + pCnf->nClauses = Vec_IntSize(vClas)-1; pCnf->nLiterals = Vec_IntSize(vLits); pCnf->pClauses = ABC_ALLOC( int *, Vec_IntSize(vClas) ); pCnf->pClauses[0] = Vec_IntReleaseArray(vLits); diff --git a/src/sat/xsat/xsatBQueue.h b/src/sat/xsat/xsatBQueue.h index 37951684e..6c170c93e 100644 --- a/src/sat/xsat/xsatBQueue.h +++ b/src/sat/xsat/xsatBQueue.h @@ -24,6 +24,7 @@ //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// + #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START @@ -31,6 +32,7 @@ ABC_NAMESPACE_HEADER_START //////////////////////////////////////////////////////////////////////// /// STRUCTURE DEFINITIONS /// //////////////////////////////////////////////////////////////////////// + typedef struct xSAT_BQueue_t_ xSAT_BQueue_t; struct xSAT_BQueue_t_ { @@ -38,13 +40,14 @@ struct xSAT_BQueue_t_ int nCap; int iFirst; int iEmpty; - uint64_t nSum; - uint32_t * pData; + word nSum; + word * pData; }; //////////////////////////////////////////////////////////////////////// /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// + /**Function************************************************************* Synopsis [] @@ -60,7 +63,7 @@ static inline xSAT_BQueue_t * xSAT_BQueueNew( int nCap ) { xSAT_BQueue_t * p = ABC_CALLOC( xSAT_BQueue_t, 1 ); p->nCap = nCap; - p->pData = ABC_CALLOC( uint32_t, nCap ); + p->pData = ABC_CALLOC( word, nCap ); return p; } @@ -92,7 +95,7 @@ static inline void xSAT_BQueueFree( xSAT_BQueue_t * p ) SeeAlso [] ***********************************************************************/ -static inline void xSAT_BQueuePush( xSAT_BQueue_t * p, uint32_t Value ) +static inline void xSAT_BQueuePush( xSAT_BQueue_t * p, word Value ) { if ( p->nSize == p->nCap ) { @@ -125,8 +128,8 @@ static inline void xSAT_BQueuePush( xSAT_BQueue_t * p, uint32_t Value ) ***********************************************************************/ static inline int xSAT_BQueuePop( xSAT_BQueue_t * p ) { - assert( p->nSize >= 1 ); int RetValue = p->pData[p->iFirst]; + assert( p->nSize >= 1 ); p->nSum -= RetValue; p->iFirst = ( p->iFirst + 1 ) % p->nCap; p->nSize--; @@ -144,9 +147,9 @@ static inline int xSAT_BQueuePop( xSAT_BQueue_t * p ) SeeAlso [] ***********************************************************************/ -static inline uint32_t xSAT_BQueueAvg( xSAT_BQueue_t * p ) +static inline word xSAT_BQueueAvg( xSAT_BQueue_t * p ) { - return ( uint32_t )( p->nSum / ( ( uint64_t ) p->nSize ) ); + return ( word )( p->nSum / ( ( word ) p->nSize ) ); } /**Function************************************************************* diff --git a/src/sat/xsat/xsatClause.h b/src/sat/xsat/xsatClause.h index 39f0a0c8c..d05eb6dee 100644 --- a/src/sat/xsat/xsatClause.h +++ b/src/sat/xsat/xsatClause.h @@ -96,7 +96,7 @@ static void xSAT_ClausePrint( xSAT_Clause_t * pCla ) int i; printf("{ "); - for ( i = 0; i < pCla->nSize; i++ ) + for ( i = 0; i < (int)pCla->nSize; i++ ) printf("%d ", pCla->pData[i].Lit ); printf("}\n"); } diff --git a/src/sat/xsat/xsatMemory.h b/src/sat/xsat/xsatMemory.h index 3a961b977..3324a563e 100644 --- a/src/sat/xsat/xsatMemory.h +++ b/src/sat/xsat/xsatMemory.h @@ -36,10 +36,10 @@ ABC_NAMESPACE_HEADER_START typedef struct xSAT_Mem_t_ xSAT_Mem_t; struct xSAT_Mem_t_ { - uint32_t nSize; - uint32_t nCap; - uint32_t nWasted; - uint32_t * pData; + unsigned nSize; + unsigned nCap; + unsigned nWasted; + unsigned * pData; }; //////////////////////////////////////////////////////////////////////// @@ -58,7 +58,7 @@ struct xSAT_Mem_t_ ***********************************************************************/ static inline xSAT_Clause_t * xSAT_MemClauseHand( xSAT_Mem_t * p, int h ) { - return h != UINT32_MAX ? ( xSAT_Clause_t * )( p->pData + h ) : NULL; + return h != 0xFFFFFFFF ? ( xSAT_Clause_t * )( p->pData + h ) : NULL; } /**Function************************************************************* @@ -72,21 +72,21 @@ static inline xSAT_Clause_t * xSAT_MemClauseHand( xSAT_Mem_t * p, int h ) SeeAlso [] ***********************************************************************/ -static inline void xSAT_MemGrow( xSAT_Mem_t * p, uint32_t nCap ) +static inline void xSAT_MemGrow( xSAT_Mem_t * p, unsigned nCap ) { + unsigned nPrevCap = p->nCap; if ( p->nCap >= nCap ) return; - uint32_t nPrevCap = p->nCap; while (p->nCap < nCap) { - uint32_t delta = ((p->nCap >> 1) + (p->nCap >> 3) + 2) & ~1; + unsigned delta = ((p->nCap >> 1) + (p->nCap >> 3) + 2) & ~1; p->nCap += delta; assert(p->nCap >= nPrevCap); } assert(p->nCap > 0); - p->pData = ABC_REALLOC(uint32_t, p->pData, p->nCap); + p->pData = ABC_REALLOC(unsigned, p->pData, p->nCap); } /**Function************************************************************* @@ -156,12 +156,13 @@ static inline void xSAT_MemFree( xSAT_Mem_t * p ) SeeAlso [] ***********************************************************************/ -static inline uint32_t xSAT_MemAppend( xSAT_Mem_t * p, int nSize ) +static inline unsigned xSAT_MemAppend( xSAT_Mem_t * p, int nSize ) { + unsigned nPrevSize; assert(nSize > 0); xSAT_MemGrow(p, p->nSize + nSize); - uint32_t nPrevSize = p->nSize; + nPrevSize = p->nSize; p->nSize += nSize; assert(p->nSize > nPrevSize); @@ -179,9 +180,9 @@ static inline uint32_t xSAT_MemAppend( xSAT_Mem_t * p, int nSize ) SeeAlso [] ***********************************************************************/ -static inline uint32_t xSAT_MemCRef( xSAT_Mem_t * p, uint32_t * pC ) +static inline unsigned xSAT_MemCRef( xSAT_Mem_t * p, unsigned * pC ) { - return ( uint32_t )( pC - &(p->pData[0]) ); + return ( unsigned )( pC - &(p->pData[0]) ); } /**Function************************************************************* @@ -195,7 +196,7 @@ static inline uint32_t xSAT_MemCRef( xSAT_Mem_t * p, uint32_t * pC ) SeeAlso [] ***********************************************************************/ -static inline uint32_t xSAT_MemCap( xSAT_Mem_t * p ) +static inline unsigned xSAT_MemCap( xSAT_Mem_t * p ) { return p->nCap; } @@ -211,7 +212,7 @@ static inline uint32_t xSAT_MemCap( xSAT_Mem_t * p ) SeeAlso [] ***********************************************************************/ -static inline uint32_t xSAT_MemWastedCap( xSAT_Mem_t * p ) +static inline unsigned xSAT_MemWastedCap( xSAT_Mem_t * p ) { return p->nWasted; } diff --git a/src/sat/xsat/xsatSolver.c b/src/sat/xsat/xsatSolver.c index d6968a2d3..91b0c5952 100644 --- a/src/sat/xsat/xsatSolver.c +++ b/src/sat/xsat/xsatSolver.c @@ -101,8 +101,9 @@ void xSAT_SolverRebuildOrderHeap( xSAT_Solver_t* s ) static inline void xSAT_SolverVarActRescale( xSAT_Solver_t * s ) { unsigned * pActivity = (unsigned *) Vec_IntArray( s->vActivity ); + int i; - for ( int i = 0; i < Vec_IntSize( s->vActivity ); i++ ) + for ( i = 0; i < Vec_IntSize( s->vActivity ); i++ ) pActivity[i] >>= 19; s->nVarActInc >>= 19; @@ -166,7 +167,7 @@ static inline void xSAT_SolverClaActRescale( xSAT_Solver_t * s ) Vec_IntForEachEntry( s->vLearnts, CRef, i ) { - pC = xSAT_SolverReadClause( s, (uint32_t) CRef ); + pC = xSAT_SolverReadClause( s, (unsigned) CRef ); pC->pData[pC->nSize].Act >>= 14; } s->nClaActInc >>= 14; @@ -221,9 +222,10 @@ static inline void xSAT_SolverClaActDecay( xSAT_Solver_t * s ) static inline int xSAT_SolverClaCalcLBD( xSAT_Solver_t * s, xSAT_Clause_t * pCla ) { int nLBD = 0; + int i; s->nStamp++; - for ( int i = 0; i < pCla->nSize; i++ ) + for ( i = 0; i < (int)pCla->nSize; i++ ) { int Level = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( pCla->pData[i].Lit ) ); if ( (unsigned) Vec_IntEntry( s->vStamp, Level ) != s->nStamp ) @@ -238,9 +240,10 @@ static inline int xSAT_SolverClaCalcLBD( xSAT_Solver_t * s, xSAT_Clause_t * pCla static inline int xSAT_SolverClaCalcLBD2( xSAT_Solver_t * s, Vec_Int_t * vLits ) { int nLBD = 0; + int i; s->nStamp++; - for ( int i = 0; i < Vec_IntSize( vLits ); i++ ) + for ( i = 0; i < Vec_IntSize( vLits ); i++ ) { int Level = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( Vec_IntEntry( vLits, i ) ) ); if ( (unsigned) Vec_IntEntry( s->vStamp, Level ) != s->nStamp ) @@ -263,17 +266,18 @@ static inline int xSAT_SolverClaCalcLBD2( xSAT_Solver_t * s, Vec_Int_t * vLits ) SeeAlso [] ***********************************************************************/ -uint32_t xSAT_SolverClaNew( xSAT_Solver_t * s, Vec_Int_t * vLits , int fLearnt ) +unsigned xSAT_SolverClaNew( xSAT_Solver_t * s, Vec_Int_t * vLits , int fLearnt ) { - assert( Vec_IntSize( vLits ) > 1); - assert( fLearnt == 0 || fLearnt == 1 ); - - uint32_t CRef; + unsigned CRef; xSAT_Clause_t * pCla; xSAT_Watcher_t w1; xSAT_Watcher_t w2; + unsigned nWords; - uint32_t nWords = 3 + fLearnt + Vec_IntSize( vLits ); + assert( Vec_IntSize( vLits ) > 1); + assert( fLearnt == 0 || fLearnt == 1 ); + + nWords = 3 + fLearnt + Vec_IntSize( vLits ); CRef = xSAT_MemAppend( s->pMemory, nWords ); pCla = xSAT_SolverReadClause( s, CRef ); pCla->fLearnt = fLearnt; @@ -326,11 +330,11 @@ uint32_t xSAT_SolverClaNew( xSAT_Solver_t * s, Vec_Int_t * vLits , int fLearnt ) SeeAlso [] ***********************************************************************/ -int xSAT_SolverEnqueue( xSAT_Solver_t* s, int Lit, uint32_t Reason ) +int xSAT_SolverEnqueue( xSAT_Solver_t* s, int Lit, unsigned Reason ) { int Var = xSAT_Lit2Var( Lit ); - Vec_StrWriteEntry( s->vAssigns, Var, xSAT_LitSign( Lit ) ); + Vec_StrWriteEntry( s->vAssigns, Var, (char)xSAT_LitSign( Lit ) ); Vec_IntWriteEntry( s->vLevels, Var, xSAT_SolverDecisionLevel( s ) ); Vec_IntWriteEntry( s->vReasons, Var, (int) Reason ); Vec_IntPush( s->vTrail, Lit ); @@ -370,16 +374,17 @@ static inline void xSAT_SolverNewDecision( xSAT_Solver_t* s, int Lit ) ***********************************************************************/ void xSAT_SolverCancelUntil( xSAT_Solver_t * s, int Level ) { + int c; if ( xSAT_SolverDecisionLevel( s ) <= Level ) return; - for ( int c = Vec_IntSize( s->vTrail ) - 1; c >= Vec_IntEntry( s->vTrailLim, Level ); c-- ) + for ( c = Vec_IntSize( s->vTrail ) - 1; c >= Vec_IntEntry( s->vTrailLim, Level ); c-- ) { int Var = xSAT_Lit2Var( Vec_IntEntry( s->vTrail, c ) ); Vec_StrWriteEntry( s->vAssigns, Var, VarX ); Vec_IntWriteEntry( s->vReasons, Var, ( int ) CRefUndef ); - Vec_StrWriteEntry( s->vPolarity, Var, xSAT_LitSign( Vec_IntEntry( s->vTrail, c ) ) ); + Vec_StrWriteEntry( s->vPolarity, Var, ( char )xSAT_LitSign( Vec_IntEntry( s->vTrail, c ) ) ); if ( !xSAT_HeapInHeap( s->hOrder, Var ) ) xSAT_HeapInsert( s->hOrder, Var ); @@ -405,17 +410,17 @@ static int xSAT_SolverIsLitRemovable( xSAT_Solver_t* s, int Lit, int MinLevel ) { int top = Vec_IntSize( s->vTagged ); - assert( (uint32_t) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Lit ) ) != CRefUndef ); + assert( (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Lit ) ) != CRefUndef ); Vec_IntClear( s->vStack ); Vec_IntPush( s->vStack, xSAT_Lit2Var( Lit ) ); while ( Vec_IntSize( s->vStack ) ) { int v = Vec_IntPop( s->vStack ); - assert( (uint32_t) Vec_IntEntry( s->vReasons, v ) != CRefUndef); - xSAT_Clause_t* c = xSAT_SolverReadClause(s, ( uint32_t ) Vec_IntEntry( s->vReasons, v ) ); + xSAT_Clause_t* c = xSAT_SolverReadClause(s, ( unsigned ) Vec_IntEntry( s->vReasons, v ) ); int* Lits = &( c->pData[0].Lit ); int i; + assert( (unsigned) Vec_IntEntry( s->vReasons, v ) != CRefUndef); if( c->nSize == 2 && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[0] ) ) == xSAT_LitSign( xSAT_NegLit( Lits[0] ) ) ) { @@ -423,12 +428,12 @@ static int xSAT_SolverIsLitRemovable( xSAT_Solver_t* s, int Lit, int MinLevel ) ABC_SWAP( int, Lits[0], Lits[1] ); } - for (i = 1; i < c->nSize; i++) + for (i = 1; i < (int)c->nSize; i++) { int v = xSAT_Lit2Var( Lits[i] ); if ( !Vec_StrEntry( s->vSeen, v ) && Vec_IntEntry( s->vLevels, v ) ) { - if ( (uint32_t) Vec_IntEntry( s->vReasons, v ) != CRefUndef && ((1 << (Vec_IntEntry( s->vLevels, v ) & 31)) & MinLevel)) + if ( (unsigned) Vec_IntEntry( s->vReasons, v ) != CRefUndef && ((1 << (Vec_IntEntry( s->vLevels, v ) & 31)) & MinLevel)) { Vec_IntPush( s->vStack, v ); Vec_IntPush( s->vTagged, Lits[i] ); @@ -474,7 +479,7 @@ static void xSAT_SolverClaMinimisation( xSAT_Solver_t * s, Vec_Int_t * vLits ) /* Remove reduntant literals */ Vec_IntAppend( s->vTagged, vLits ); for ( i = j = 1; i < Vec_IntSize( vLits ); i++ ) - if ( (uint32_t) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( pLits[i] ) ) == CRefUndef || !xSAT_SolverIsLitRemovable( s, pLits[i], MinLevel ) ) + if ( (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( pLits[i] ) ) == CRefUndef || !xSAT_SolverIsLitRemovable( s, pLits[i], MinLevel ) ) pLits[j++] = pLits[i]; Vec_IntShrink( vLits, j ); @@ -483,33 +488,40 @@ static void xSAT_SolverClaMinimisation( xSAT_Solver_t * s, Vec_Int_t * vLits ) { int Lit; int FlaseLit = xSAT_NegLit( pLits[0] ); + int nb; + int l; + + xSAT_WatchList_t * ws; + xSAT_Watcher_t * begin; + xSAT_Watcher_t * end; + xSAT_Watcher_t * pWatcher; s->nStamp++; Vec_IntForEachEntry( vLits, Lit, i ) Vec_IntWriteEntry( s->vStamp, xSAT_Lit2Var( Lit ), s->nStamp ); - xSAT_WatchList_t * ws = xSAT_VecWatchListEntry( s->vBinWatches, FlaseLit ); - xSAT_Watcher_t * begin = xSAT_WatchListArray( ws ); - xSAT_Watcher_t * end = begin + xSAT_WatchListSize( ws ); - xSAT_Watcher_t * pWatcher; + ws = xSAT_VecWatchListEntry( s->vBinWatches, FlaseLit ); + begin = xSAT_WatchListArray( ws ); + end = begin + xSAT_WatchListSize( ws ); + pWatcher; - int nb = 0; + nb = 0; for ( pWatcher = begin; pWatcher < end; pWatcher++ ) { int ImpLit = pWatcher->Blocker; - if ( Vec_IntEntry( s->vStamp, xSAT_Lit2Var( ImpLit ) ) == s->nStamp && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( ImpLit ) ) == xSAT_LitSign( ImpLit ) ) + if ( Vec_IntEntry( s->vStamp, xSAT_Lit2Var( ImpLit ) ) == (int)s->nStamp && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( ImpLit ) ) == xSAT_LitSign( ImpLit ) ) { nb++; Vec_IntWriteEntry( s->vStamp, xSAT_Lit2Var( ImpLit ), s->nStamp - 1 ); } } - int l = Vec_IntSize( vLits ) - 1; + l = Vec_IntSize( vLits ) - 1; if ( nb > 0 ) { for ( i = 1; i < Vec_IntSize( vLits ) - nb; i++ ) - if ( Vec_IntEntry( s->vStamp, xSAT_Lit2Var( pLits[i] ) ) != s->nStamp ) + if ( Vec_IntEntry( s->vStamp, xSAT_Lit2Var( pLits[i] ) ) != (int)s->nStamp ) { int TempLit = pLits[l]; pLits[l] = pLits[i]; @@ -533,20 +545,22 @@ static void xSAT_SolverClaMinimisation( xSAT_Solver_t * s, Vec_Int_t * vLits ) SeeAlso [] ***********************************************************************/ -static void xSAT_SolverAnalyze( xSAT_Solver_t* s, uint32_t ConfCRef, Vec_Int_t * vLearnt, int * OutBtLevel, unsigned * nLBD ) +static void xSAT_SolverAnalyze( xSAT_Solver_t* s, unsigned ConfCRef, Vec_Int_t * vLearnt, int * OutBtLevel, unsigned * nLBD ) { int* trail = Vec_IntArray( s->vTrail ); int Count = 0; int p = LitUndef; int Idx = Vec_IntSize( s->vTrail ) - 1; int* Lits; + int Lit; int i, j; Vec_IntPush( vLearnt, LitUndef ); do { + xSAT_Clause_t * c; assert( ConfCRef != CRefUndef ); - xSAT_Clause_t * c = xSAT_SolverReadClause(s, ConfCRef); + c = xSAT_SolverReadClause(s, ConfCRef); Lits = &( c->pData[0].Lit ); if( p != LitUndef && c->nSize == 2 && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var(Lits[0])) == xSAT_LitSign( xSAT_NegLit( Lits[0] ) ) ) @@ -569,7 +583,7 @@ static void xSAT_SolverAnalyze( xSAT_Solver_t* s, uint32_t ConfCRef, Vec_Int_t * } } - for ( j = ( p == LitUndef ? 0 : 1 ); j < c->nSize; j++ ) + for ( j = ( p == LitUndef ? 0 : 1 ); j < (int)c->nSize; j++ ) { int Var = xSAT_Lit2Var( Lits[j] ); @@ -592,7 +606,7 @@ static void xSAT_SolverAnalyze( xSAT_Solver_t* s, uint32_t ConfCRef, Vec_Int_t * // Next clause to look at p = trail[Idx+1]; - ConfCRef = (uint32_t) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( p ) ); + ConfCRef = (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( p ) ); Vec_StrWriteEntry( s->vSeen, xSAT_Lit2Var( p ), 0 ); Count--; @@ -638,7 +652,6 @@ static void xSAT_SolverAnalyze( xSAT_Solver_t* s, uint32_t ConfCRef, Vec_Int_t * Vec_IntClear( s->vLastDLevel ); } - int Lit; Vec_IntForEachEntry( s->vTagged, Lit, i ) Vec_StrWriteEntry( s->vSeen, xSAT_Lit2Var( Lit ), 0 ); Vec_IntClear( s->vTagged ); @@ -655,9 +668,9 @@ static void xSAT_SolverAnalyze( xSAT_Solver_t* s, uint32_t ConfCRef, Vec_Int_t * SeeAlso [] ***********************************************************************/ -uint32_t xSAT_SolverPropagate( xSAT_Solver_t* s ) +unsigned xSAT_SolverPropagate( xSAT_Solver_t* s ) { - uint32_t hConfl = CRefUndef; + unsigned hConfl = CRefUndef; int * Lits; int NegLit; int nProp = 0; @@ -689,13 +702,16 @@ uint32_t xSAT_SolverPropagate( xSAT_Solver_t* s ) for ( i = j = begin; i < end; ) { + xSAT_Clause_t* c; + xSAT_Watcher_t w; + if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( i->Blocker ) ) == xSAT_LitSign( i->Blocker ) ) { *j++ = *i++; continue; } - xSAT_Clause_t* c = xSAT_SolverReadClause( s, i->CRef ); + c = xSAT_SolverReadClause( s, i->CRef ); Lits = &( c->pData[0].Lit ); // Make sure the false literal is data[1]: @@ -707,8 +723,9 @@ uint32_t xSAT_SolverPropagate( xSAT_Solver_t* s ) } assert( Lits[1] == NegLit ); - xSAT_Watcher_t w = { .CRef = i->CRef, - .Blocker = Lits[0] }; + w.CRef = i->CRef; + w.Blocker = Lits[0]; + // If 0th watch is true, then clause is already satisfied. if ( Lits[0] != i->Blocker && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[0] ) ) == xSAT_LitSign( Lits[0] ) ) *j++ = w; @@ -774,7 +791,7 @@ void xSAT_SolverReduceDB( xSAT_Solver_t * s ) abctime clk = Abc_Clock(); int nLearnedOld = Vec_IntSize( s->vLearnts ); int i, limit; - uint32_t CRef; + unsigned CRef; xSAT_Clause_t * c; xSAT_Clause_t ** learnts_cls; @@ -795,10 +812,11 @@ void xSAT_SolverReduceDB( xSAT_Solver_t * s ) Vec_IntClear( s->vLearnts ); for ( i = 0; i < nLearnedOld; i++ ) { + unsigned CRef; c = learnts_cls[i]; - uint32_t CRef = xSAT_MemCRef( s->pMemory, (uint32_t * ) c ); + CRef = xSAT_MemCRef( s->pMemory, (unsigned * ) c ); assert(c->fMark == 0); - if ( c->fCanBeDel && c->nLBD > 2 && c->nSize > 2 && (uint32_t) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( c->pData[0].Lit ) ) != CRef && ( i < limit ) ) + if ( c->fCanBeDel && c->nLBD > 2 && c->nSize > 2 && (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( c->pData[0].Lit ) ) != CRef && ( i < limit ) ) { c->fMark = 1; s->Stats.nLearntLits -= c->nSize; @@ -838,19 +856,19 @@ void xSAT_SolverReduceDB( xSAT_Solver_t * s ) ***********************************************************************/ char xSAT_SolverSearch( xSAT_Solver_t * s ) { - ABC_INT64_T conflictC = 0; + iword conflictC = 0; s->Stats.nStarts++; for (;;) { - uint32_t hConfl = xSAT_SolverPropagate( s ); + unsigned hConfl = xSAT_SolverPropagate( s ); if ( hConfl != CRefUndef ) { /* Conflict */ int BacktrackLevel; unsigned nLBD; - uint32_t CRef; + unsigned CRef; s->Stats.nConflicts++; conflictC++; @@ -859,7 +877,7 @@ char xSAT_SolverSearch( xSAT_Solver_t * s ) return LBoolFalse; xSAT_BQueuePush( s->bqTrail, Vec_IntSize( s->vTrail ) ); - if ( s->Stats.nConflicts > s->Config.nFirstBlockRestart && xSAT_BQueueIsValid( s->bqLBD ) && ( Vec_IntSize( s->vTrail ) > ( s->Config.R * xSAT_BQueueAvg( s->bqTrail ) ) ) ) + if ( s->Stats.nConflicts > s->Config.nFirstBlockRestart && xSAT_BQueueIsValid( s->bqLBD ) && ( Vec_IntSize( s->vTrail ) > ( s->Config.R * (iword)xSAT_BQueueAvg( s->bqTrail ) ) ) ) xSAT_BQueueClean(s->bqLBD); Vec_IntClear( s->vLearntClause ); @@ -879,7 +897,7 @@ char xSAT_SolverSearch( xSAT_Solver_t * s ) { /* No conflict */ int NextVar; - if ( xSAT_BQueueIsValid( s->bqLBD ) && ( ( xSAT_BQueueAvg( s->bqLBD ) * s->Config.K ) > ( s->nSumLBD / s->Stats.nConflicts ) ) ) + if ( xSAT_BQueueIsValid( s->bqLBD ) && ( ( (iword)xSAT_BQueueAvg( s->bqLBD ) * s->Config.K ) > ( s->nSumLBD / (iword)s->Stats.nConflicts ) ) ) { xSAT_BQueueClean( s->bqLBD ); xSAT_SolverCancelUntil( s, 0 ); @@ -923,17 +941,20 @@ char xSAT_SolverSearch( xSAT_Solver_t * s ) SeeAlso [] ***********************************************************************/ -void xSAT_SolverClaRealloc( xSAT_Mem_t * pDest, xSAT_Mem_t * pSrc, uint32_t * pCRef ) +void xSAT_SolverClaRealloc( xSAT_Mem_t * pDest, xSAT_Mem_t * pSrc, unsigned * pCRef ) { xSAT_Clause_t * pOldCla = xSAT_MemClauseHand( pSrc, *pCRef ); + unsigned nNewCRef; + xSAT_Clause_t * pNewCla; + if ( pOldCla->fReallocd ) { - *pCRef = (uint32_t) pOldCla->nSize; + *pCRef = (unsigned) pOldCla->nSize; return; } - uint32_t nNewCRef = xSAT_MemAppend( pDest, 3 + pOldCla->fLearnt + pOldCla->nSize ); - xSAT_Clause_t * pNewCla = xSAT_MemClauseHand( pDest, nNewCRef ); + nNewCRef = xSAT_MemAppend( pDest, 3 + pOldCla->fLearnt + pOldCla->nSize ); + pNewCla = xSAT_MemClauseHand( pDest, nNewCRef ); memcpy( pNewCla, pOldCla, ( 3 + pOldCla->fLearnt + pOldCla->nSize ) * 4 ); @@ -956,7 +977,7 @@ void xSAT_SolverClaRealloc( xSAT_Mem_t * pDest, xSAT_Mem_t * pSrc, uint32_t * pC void xSAT_SolverGarbageCollect( xSAT_Solver_t * s ) { int i; - uint32_t * pArray; + unsigned * pArray; xSAT_Mem_t * pNewMemMngr = xSAT_MemAlloc( xSAT_MemCap( s->pMemory ) - xSAT_MemWastedCap( s->pMemory ) ); for ( i = 0; i < 2 * Vec_StrSize( s->vAssigns ); i++ ) @@ -977,14 +998,14 @@ void xSAT_SolverGarbageCollect( xSAT_Solver_t * s ) } for ( i = 0; i < Vec_IntSize( s->vTrail ); i++ ) - if ( (uint32_t) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) ) ) != CRefUndef ) + if ( (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) ) ) != CRefUndef ) xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &( Vec_IntArray( s->vReasons )[xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) )] ) ); - pArray = ( uint32_t * ) Vec_IntArray( s->vLearnts ); + pArray = ( unsigned * ) Vec_IntArray( s->vLearnts ); for ( i = 0; i < Vec_IntSize( s->vLearnts ); i++ ) xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &(pArray[i]) ); - pArray = (uint32_t *) Vec_IntArray( s->vClauses ); + pArray = (unsigned *) Vec_IntArray( s->vClauses ); for ( i = 0; i < Vec_IntSize( s->vClauses ); i++ ) xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &(pArray[i]) ); diff --git a/src/sat/xsat/xsatSolver.h b/src/sat/xsat/xsatSolver.h index a6d646c61..2bcd93b74 100644 --- a/src/sat/xsat/xsatSolver.h +++ b/src/sat/xsat/xsatSolver.h @@ -70,7 +70,7 @@ enum LitUndef = -2 }; -#define CRefUndef UINT32_MAX +#define CRefUndef 0xFFFFFFFF //////////////////////////////////////////////////////////////////////// /// STRUCTURE DEFINITIONS /// @@ -81,8 +81,8 @@ struct xSAT_SolverOptions_t_ char fVerbose; // Limits - ABC_INT64_T nConfLimit; // external limit on the number of conflicts - ABC_INT64_T nInsLimit; // external limit on the number of implications + word nConfLimit; // external limit on the number of conflicts + word nInsLimit; // external limit on the number of implications abctime nRuntimeLimit; // external limit on runtime // Constants used for restart heuristic @@ -105,13 +105,13 @@ struct xSAT_Stats_t_ unsigned nStarts; unsigned nReduceDB; - ABC_INT64_T nDecisions; - ABC_INT64_T nPropagations; - ABC_INT64_T nInspects; - ABC_INT64_T nConflicts; + word nDecisions; + word nPropagations; + word nInspects; + word nConflicts; - ABC_INT64_T nClauseLits; - ABC_INT64_T nLearntLits; + word nClauseLits; + word nLearntLits; }; struct xSAT_Solver_t_ @@ -143,7 +143,7 @@ struct xSAT_Solver_t_ int nAssignSimplify; /* Number of top-level assignments since last * execution of 'simplify()'. */ - int64_t nPropSimplify; /* Remaining number of propagations that must be + word nPropSimplify; /* Remaining number of propagations that must be * made before next execution of 'simplify()'. */ /* Temporary data used by Search method */ @@ -195,16 +195,17 @@ static inline int xSAT_SolverDecisionLevel( xSAT_Solver_t * s ) return Vec_IntSize( s->vTrailLim ); } -static inline xSAT_Clause_t * xSAT_SolverReadClause( xSAT_Solver_t * s, uint32_t h ) +static inline xSAT_Clause_t * xSAT_SolverReadClause( xSAT_Solver_t * s, unsigned h ) { return xSAT_MemClauseHand( s->pMemory, h ); } static inline int xSAT_SolverIsClauseSatisfied( xSAT_Solver_t * s, xSAT_Clause_t * pCla ) { + int i; int * lits = &( pCla->pData[0].Lit ); - for ( int i = 0; i < pCla->nSize; i++ ) + for ( i = 0; i < (int)pCla->nSize; i++ ) if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( lits[i] ) ) == xSAT_LitSign( ( lits[i] ) ) ) return true; @@ -232,14 +233,14 @@ static inline void xSAT_SolverPrintState( xSAT_Solver_t * s ) //////////////////////////////////////////////////////////////////////// /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -extern uint32_t xSAT_SolverClaNew( xSAT_Solver_t* s, Vec_Int_t * vLits, int fLearnt ); +extern unsigned xSAT_SolverClaNew( xSAT_Solver_t* s, Vec_Int_t * vLits, int fLearnt ); extern char xSAT_SolverSearch( xSAT_Solver_t * s ); extern void xSAT_SolverGarbageCollect( xSAT_Solver_t * s ); -extern int xSAT_SolverEnqueue( xSAT_Solver_t* s, int Lit, uint32_t From ); +extern int xSAT_SolverEnqueue( xSAT_Solver_t* s, int Lit, unsigned From ); extern void xSAT_SolverCancelUntil( xSAT_Solver_t* s, int Level); -extern uint32_t xSAT_SolverPropagate( xSAT_Solver_t* s ); +extern unsigned xSAT_SolverPropagate( xSAT_Solver_t* s ); extern void xSAT_SolverRebuildOrderHeap( xSAT_Solver_t* s ); ABC_NAMESPACE_HEADER_END diff --git a/src/sat/xsat/xsatSolverAPI.c b/src/sat/xsat/xsatSolverAPI.c index 7ee817eeb..43c2d06e1 100644 --- a/src/sat/xsat/xsatSolverAPI.c +++ b/src/sat/xsat/xsatSolverAPI.c @@ -32,23 +32,23 @@ ABC_NAMESPACE_IMPL_START xSAT_SolverOptions_t DefaultConfig = { - .fVerbose = 1, + 1, //.fVerbose = 1, - .nConfLimit = 0, - .nInsLimit = 0, - .nRuntimeLimit = 0, + 0, //.nConfLimit = 0, + 0, //.nInsLimit = 0, + 0, //.nRuntimeLimit = 0, - .K = 0.8, - .R = 1.4, - .nFirstBlockRestart = 10000, - .nSizeLBDQueue = 50, - .nSizeTrailQueue = 5000, + 0.8, //.K = 0.8, + 1.4, //.R = 1.4, + 10000, //.nFirstBlockRestart = 10000, + 50, //.nSizeLBDQueue = 50, + 5000, //.nSizeTrailQueue = 5000, - .nConfFirstReduce = 2000, - .nIncReduce = 300, - .nSpecialIncReduce = 1000, + 2000, //.nConfFirstReduce = 2000, + 300, //.nIncReduce = 300, + 1000, //.nSpecialIncReduce = 1000, - .nLBDFrozenClause = 30 + 30 //.nLBDFrozenClause = 30 }; /**Function************************************************************* @@ -142,6 +142,7 @@ void xSAT_SolverDestroy( xSAT_Solver_t * s ) Vec_StrFree( s->vAssigns ); Vec_IntFree( s->vLevels ); Vec_IntFree( s->vReasons ); + Vec_IntFree( s->vStamp ); xSAT_BQueueFree(s->bqLBD); xSAT_BQueueFree(s->bqTrail); @@ -163,7 +164,7 @@ void xSAT_SolverDestroy( xSAT_Solver_t * s ) int xSAT_SolverSimplify( xSAT_Solver_t * s ) { int i, j; - uint32_t CRef; + unsigned CRef; assert( xSAT_SolverDecisionLevel(s) == 0 ); if ( xSAT_SolverPropagate(s) != CRefUndef ) diff --git a/src/sat/xsat/xsatWatchList.h b/src/sat/xsat/xsatWatchList.h index 454cfe44d..2ba13c24d 100644 --- a/src/sat/xsat/xsatWatchList.h +++ b/src/sat/xsat/xsatWatchList.h @@ -34,7 +34,7 @@ ABC_NAMESPACE_HEADER_START typedef struct xSAT_Watcher_t_ xSAT_Watcher_t; struct xSAT_Watcher_t_ { - uint32_t CRef; + unsigned CRef; int Blocker; }; @@ -162,7 +162,7 @@ static inline xSAT_Watcher_t* xSAT_WatchListArray( xSAT_WatchList_t * v ) SeeAlso [] ***********************************************************************/ -static inline void xSAT_WatchListRemove( xSAT_WatchList_t * v, uint32_t CRef ) +static inline void xSAT_WatchListRemove( xSAT_WatchList_t * v, unsigned CRef ) { xSAT_Watcher_t* ws = xSAT_WatchListArray(v); int j = 0; @@ -207,7 +207,8 @@ static inline xSAT_VecWatchList_t * xSAT_VecWatchListAlloc( int nCap ) ***********************************************************************/ static inline void xSAT_VecWatchListFree( xSAT_VecWatchList_t* v ) { - for( int i = 0; i < v->nSize; i++ ) + int i; + for( i = 0; i < v->nSize; i++ ) xSAT_WatchListFree( v->pArray + i ); ABC_FREE( v->pArray ); From cb49c5d0067bc2630c86d258bba5bfbbc5a5d916 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 13 Dec 2016 10:34:17 +0800 Subject: [PATCH 005/185] Bug fix in 'dsat ' when the number of classes in listed incorrectly. --- src/sat/xsat/xsatHeap.h | 4 ++-- src/sat/xsat/xsatSolver.c | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/sat/xsat/xsatHeap.h b/src/sat/xsat/xsatHeap.h index 2e873e590..409ce4604 100644 --- a/src/sat/xsat/xsatHeap.h +++ b/src/sat/xsat/xsatHeap.h @@ -48,7 +48,7 @@ struct xSAT_Heap_t_ SeeAlso [] ***********************************************************************/ -inline int xSAT_HeapSize( xSAT_Heap_t * h ) +static inline int xSAT_HeapSize( xSAT_Heap_t * h ) { return Vec_IntSize( h->vHeap ); } @@ -64,7 +64,7 @@ inline int xSAT_HeapSize( xSAT_Heap_t * h ) SeeAlso [] ***********************************************************************/ -inline int xSAT_HeapInHeap( xSAT_Heap_t * h, int Var ) +static inline int xSAT_HeapInHeap( xSAT_Heap_t * h, int Var ) { return ( Var < Vec_IntSize( h->vIndices ) ) && ( Vec_IntEntry( h->vIndices, Var ) >= 0 ); } diff --git a/src/sat/xsat/xsatSolver.c b/src/sat/xsat/xsatSolver.c index 91b0c5952..5806409e6 100644 --- a/src/sat/xsat/xsatSolver.c +++ b/src/sat/xsat/xsatSolver.c @@ -503,7 +503,6 @@ static void xSAT_SolverClaMinimisation( xSAT_Solver_t * s, Vec_Int_t * vLits ) ws = xSAT_VecWatchListEntry( s->vBinWatches, FlaseLit ); begin = xSAT_WatchListArray( ws ); end = begin + xSAT_WatchListSize( ws ); - pWatcher; nb = 0; for ( pWatcher = begin; pWatcher < end; pWatcher++ ) @@ -999,7 +998,7 @@ void xSAT_SolverGarbageCollect( xSAT_Solver_t * s ) for ( i = 0; i < Vec_IntSize( s->vTrail ); i++ ) if ( (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) ) ) != CRefUndef ) - xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &( Vec_IntArray( s->vReasons )[xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) )] ) ); + xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, (unsigned *)&( Vec_IntArray( s->vReasons )[xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) )] ) ); pArray = ( unsigned * ) Vec_IntArray( s->vLearnts ); for ( i = 0; i < Vec_IntSize( s->vLearnts ); i++ ) From 123b425052636beceaa52e47ea695d35b75fb40a Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Tue, 13 Dec 2016 11:29:38 -0200 Subject: [PATCH 006/185] Fixes to make xSAT compile with old compilers. Small typos and variables renaming. --- src/sat/xsat/xsatBQueue.h | 15 ++- src/sat/xsat/xsatClause.h | 8 +- src/sat/xsat/xsatHeap.h | 4 +- src/sat/xsat/xsatMemory.h | 10 +- src/sat/xsat/xsatSolver.c | 178 +++++++++++++++++------------------ src/sat/xsat/xsatSolver.h | 26 ++--- src/sat/xsat/xsatSolverAPI.c | 2 +- src/sat/xsat/xsatWatchList.h | 14 +-- 8 files changed, 120 insertions(+), 137 deletions(-) diff --git a/src/sat/xsat/xsatBQueue.h b/src/sat/xsat/xsatBQueue.h index 6c170c93e..560f75c0e 100644 --- a/src/sat/xsat/xsatBQueue.h +++ b/src/sat/xsat/xsatBQueue.h @@ -24,7 +24,6 @@ //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// - #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START @@ -32,7 +31,6 @@ ABC_NAMESPACE_HEADER_START //////////////////////////////////////////////////////////////////////// /// STRUCTURE DEFINITIONS /// //////////////////////////////////////////////////////////////////////// - typedef struct xSAT_BQueue_t_ xSAT_BQueue_t; struct xSAT_BQueue_t_ { @@ -41,13 +39,12 @@ struct xSAT_BQueue_t_ int iFirst; int iEmpty; word nSum; - word * pData; + unsigned * pData; }; //////////////////////////////////////////////////////////////////////// /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// - /**Function************************************************************* Synopsis [] @@ -63,7 +60,7 @@ static inline xSAT_BQueue_t * xSAT_BQueueNew( int nCap ) { xSAT_BQueue_t * p = ABC_CALLOC( xSAT_BQueue_t, 1 ); p->nCap = nCap; - p->pData = ABC_CALLOC( word, nCap ); + p->pData = ABC_CALLOC( unsigned, nCap ); return p; } @@ -95,7 +92,7 @@ static inline void xSAT_BQueueFree( xSAT_BQueue_t * p ) SeeAlso [] ***********************************************************************/ -static inline void xSAT_BQueuePush( xSAT_BQueue_t * p, word Value ) +static inline void xSAT_BQueuePush( xSAT_BQueue_t * p, unsigned Value ) { if ( p->nSize == p->nCap ) { @@ -128,8 +125,8 @@ static inline void xSAT_BQueuePush( xSAT_BQueue_t * p, word Value ) ***********************************************************************/ static inline int xSAT_BQueuePop( xSAT_BQueue_t * p ) { - int RetValue = p->pData[p->iFirst]; assert( p->nSize >= 1 ); + int RetValue = p->pData[p->iFirst]; p->nSum -= RetValue; p->iFirst = ( p->iFirst + 1 ) % p->nCap; p->nSize--; @@ -147,9 +144,9 @@ static inline int xSAT_BQueuePop( xSAT_BQueue_t * p ) SeeAlso [] ***********************************************************************/ -static inline word xSAT_BQueueAvg( xSAT_BQueue_t * p ) +static inline unsigned xSAT_BQueueAvg( xSAT_BQueue_t * p ) { - return ( word )( p->nSum / ( ( word ) p->nSize ) ); + return ( unsigned )( p->nSum / ( ( word ) p->nSize ) ); } /**Function************************************************************* diff --git a/src/sat/xsat/xsatClause.h b/src/sat/xsat/xsatClause.h index d05eb6dee..ef353198d 100644 --- a/src/sat/xsat/xsatClause.h +++ b/src/sat/xsat/xsatClause.h @@ -39,7 +39,7 @@ struct xSAT_Clause_t_ unsigned fReallocd : 1; unsigned fCanBeDel : 1; unsigned nLBD : 28; - unsigned nSize; + int nSize; union { int Lit; unsigned Act; @@ -60,7 +60,7 @@ struct xSAT_Clause_t_ SeeAlso [] ***********************************************************************/ -static int xSAT_ClauseCompare( const void * p1, const void * p2 ) +static inline int xSAT_ClauseCompare( const void * p1, const void * p2 ) { xSAT_Clause_t * pC1 = ( xSAT_Clause_t * ) p1; xSAT_Clause_t * pC2 = ( xSAT_Clause_t * ) p2; @@ -91,12 +91,12 @@ static int xSAT_ClauseCompare( const void * p1, const void * p2 ) SeeAlso [] ***********************************************************************/ -static void xSAT_ClausePrint( xSAT_Clause_t * pCla ) +static inline void xSAT_ClausePrint( xSAT_Clause_t * pCla ) { int i; printf("{ "); - for ( i = 0; i < (int)pCla->nSize; i++ ) + for ( i = 0; i < pCla->nSize; i++ ) printf("%d ", pCla->pData[i].Lit ); printf("}\n"); } diff --git a/src/sat/xsat/xsatHeap.h b/src/sat/xsat/xsatHeap.h index 409ce4604..2e873e590 100644 --- a/src/sat/xsat/xsatHeap.h +++ b/src/sat/xsat/xsatHeap.h @@ -48,7 +48,7 @@ struct xSAT_Heap_t_ SeeAlso [] ***********************************************************************/ -static inline int xSAT_HeapSize( xSAT_Heap_t * h ) +inline int xSAT_HeapSize( xSAT_Heap_t * h ) { return Vec_IntSize( h->vHeap ); } @@ -64,7 +64,7 @@ static inline int xSAT_HeapSize( xSAT_Heap_t * h ) SeeAlso [] ***********************************************************************/ -static inline int xSAT_HeapInHeap( xSAT_Heap_t * h, int Var ) +inline int xSAT_HeapInHeap( xSAT_Heap_t * h, int Var ) { return ( Var < Vec_IntSize( h->vIndices ) ) && ( Vec_IntEntry( h->vIndices, Var ) >= 0 ); } diff --git a/src/sat/xsat/xsatMemory.h b/src/sat/xsat/xsatMemory.h index 3324a563e..129c2f503 100644 --- a/src/sat/xsat/xsatMemory.h +++ b/src/sat/xsat/xsatMemory.h @@ -77,16 +77,14 @@ static inline void xSAT_MemGrow( xSAT_Mem_t * p, unsigned nCap ) unsigned nPrevCap = p->nCap; if ( p->nCap >= nCap ) return; - while (p->nCap < nCap) { - unsigned delta = ((p->nCap >> 1) + (p->nCap >> 3) + 2) & ~1; + unsigned delta = ( ( p->nCap >> 1 ) + ( p->nCap >> 3 ) + 2 ) & ~1; p->nCap += delta; assert(p->nCap >= nPrevCap); } - assert(p->nCap > 0); - p->pData = ABC_REALLOC(unsigned, p->pData, p->nCap); + p->pData = ABC_REALLOC( unsigned, p->pData, p->nCap ); } /**Function************************************************************* @@ -160,12 +158,10 @@ static inline unsigned xSAT_MemAppend( xSAT_Mem_t * p, int nSize ) { unsigned nPrevSize; assert(nSize > 0); - xSAT_MemGrow(p, p->nSize + nSize); - + xSAT_MemGrow( p, p->nSize + nSize ); nPrevSize = p->nSize; p->nSize += nSize; assert(p->nSize > nPrevSize); - return nPrevSize; } diff --git a/src/sat/xsat/xsatSolver.c b/src/sat/xsat/xsatSolver.c index 5806409e6..467f5f8d3 100644 --- a/src/sat/xsat/xsatSolver.c +++ b/src/sat/xsat/xsatSolver.c @@ -46,7 +46,7 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -static inline int xSAT_SolverDecide( xSAT_Solver_t* s ) +static inline int xSAT_SolverDecide( xSAT_Solver_t * s ) { int NextVar = VarUndef; @@ -74,7 +74,7 @@ static inline int xSAT_SolverDecide( xSAT_Solver_t* s ) SeeAlso [] ***********************************************************************/ -void xSAT_SolverRebuildOrderHeap( xSAT_Solver_t* s ) +void xSAT_SolverRebuildOrderHeap( xSAT_Solver_t * s ) { Vec_Int_t * vTemp = Vec_IntAlloc( Vec_StrSize( s->vAssigns ) ); int Var; @@ -100,14 +100,14 @@ void xSAT_SolverRebuildOrderHeap( xSAT_Solver_t* s ) ***********************************************************************/ static inline void xSAT_SolverVarActRescale( xSAT_Solver_t * s ) { - unsigned * pActivity = (unsigned *) Vec_IntArray( s->vActivity ); int i; + unsigned * pActivity = ( unsigned * ) Vec_IntArray( s->vActivity ); for ( i = 0; i < Vec_IntSize( s->vActivity ); i++ ) pActivity[i] >>= 19; s->nVarActInc >>= 19; - s->nVarActInc = Abc_MaxInt( s->nVarActInc, (1 << 5) ); + s->nVarActInc = Abc_MaxInt( s->nVarActInc, ( 1 << 5 ) ); } /**Function************************************************************* @@ -121,9 +121,9 @@ static inline void xSAT_SolverVarActRescale( xSAT_Solver_t * s ) SeeAlso [] ***********************************************************************/ -static inline void xSAT_SolverVarActBump( xSAT_Solver_t* s, int Var ) +static inline void xSAT_SolverVarActBump( xSAT_Solver_t * s, int Var ) { - unsigned * pActivity = (unsigned *) Vec_IntArray( s->vActivity ); + unsigned * pActivity = ( unsigned * ) Vec_IntArray( s->vActivity ); pActivity[Var] += s->nVarActInc; if ( pActivity[Var] & 0x80000000 ) @@ -167,7 +167,7 @@ static inline void xSAT_SolverClaActRescale( xSAT_Solver_t * s ) Vec_IntForEachEntry( s->vLearnts, CRef, i ) { - pC = xSAT_SolverReadClause( s, (unsigned) CRef ); + pC = xSAT_SolverReadClause( s, ( unsigned ) CRef ); pC->pData[pC->nSize].Act >>= 14; } s->nClaActInc >>= 14; @@ -221,16 +221,16 @@ static inline void xSAT_SolverClaActDecay( xSAT_Solver_t * s ) ***********************************************************************/ static inline int xSAT_SolverClaCalcLBD( xSAT_Solver_t * s, xSAT_Clause_t * pCla ) { - int nLBD = 0; int i; + int nLBD = 0; s->nStamp++; - for ( i = 0; i < (int)pCla->nSize; i++ ) + for ( i = 0; i < pCla->nSize; i++ ) { int Level = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( pCla->pData[i].Lit ) ); - if ( (unsigned) Vec_IntEntry( s->vStamp, Level ) != s->nStamp ) + if ( ( unsigned ) Vec_IntEntry( s->vStamp, Level ) != s->nStamp ) { - Vec_IntWriteEntry( s->vStamp, Level, (int) s->nStamp ); + Vec_IntWriteEntry( s->vStamp, Level, ( int ) s->nStamp ); nLBD++; } } @@ -239,16 +239,16 @@ static inline int xSAT_SolverClaCalcLBD( xSAT_Solver_t * s, xSAT_Clause_t * pCla static inline int xSAT_SolverClaCalcLBD2( xSAT_Solver_t * s, Vec_Int_t * vLits ) { - int nLBD = 0; int i; + int nLBD = 0; s->nStamp++; for ( i = 0; i < Vec_IntSize( vLits ); i++ ) { int Level = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( Vec_IntEntry( vLits, i ) ) ); - if ( (unsigned) Vec_IntEntry( s->vStamp, Level ) != s->nStamp ) + if ( ( unsigned ) Vec_IntEntry( s->vStamp, Level ) != s->nStamp ) { - Vec_IntWriteEntry( s->vStamp, Level, (int) s->nStamp ); + Vec_IntWriteEntry( s->vStamp, Level, ( int ) s->nStamp ); nLBD++; } } @@ -330,13 +330,13 @@ unsigned xSAT_SolverClaNew( xSAT_Solver_t * s, Vec_Int_t * vLits , int fLearnt ) SeeAlso [] ***********************************************************************/ -int xSAT_SolverEnqueue( xSAT_Solver_t* s, int Lit, unsigned Reason ) +int xSAT_SolverEnqueue( xSAT_Solver_t * s, int Lit, unsigned Reason ) { int Var = xSAT_Lit2Var( Lit ); - Vec_StrWriteEntry( s->vAssigns, Var, (char)xSAT_LitSign( Lit ) ); + Vec_StrWriteEntry( s->vAssigns, Var, xSAT_LitSign( Lit ) ); Vec_IntWriteEntry( s->vLevels, Var, xSAT_SolverDecisionLevel( s ) ); - Vec_IntWriteEntry( s->vReasons, Var, (int) Reason ); + Vec_IntWriteEntry( s->vReasons, Var, ( int ) Reason ); Vec_IntPush( s->vTrail, Lit ); return true; @@ -353,7 +353,7 @@ int xSAT_SolverEnqueue( xSAT_Solver_t* s, int Lit, unsigned Reason ) SeeAlso [] ***********************************************************************/ -static inline void xSAT_SolverNewDecision( xSAT_Solver_t* s, int Lit ) +static inline void xSAT_SolverNewDecision( xSAT_Solver_t * s, int Lit ) { assert( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lit ) ) == VarX ); s->Stats.nDecisions++; @@ -375,6 +375,7 @@ static inline void xSAT_SolverNewDecision( xSAT_Solver_t* s, int Lit ) void xSAT_SolverCancelUntil( xSAT_Solver_t * s, int Level ) { int c; + if ( xSAT_SolverDecisionLevel( s ) <= Level ) return; @@ -410,30 +411,30 @@ static int xSAT_SolverIsLitRemovable( xSAT_Solver_t* s, int Lit, int MinLevel ) { int top = Vec_IntSize( s->vTagged ); - assert( (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Lit ) ) != CRefUndef ); + assert( ( unsigned ) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Lit ) ) != CRefUndef ); Vec_IntClear( s->vStack ); Vec_IntPush( s->vStack, xSAT_Lit2Var( Lit ) ); while ( Vec_IntSize( s->vStack ) ) { + int i; int v = Vec_IntPop( s->vStack ); xSAT_Clause_t* c = xSAT_SolverReadClause(s, ( unsigned ) Vec_IntEntry( s->vReasons, v ) ); - int* Lits = &( c->pData[0].Lit ); - int i; - assert( (unsigned) Vec_IntEntry( s->vReasons, v ) != CRefUndef); + int * Lits = &( c->pData[0].Lit ); + assert( (unsigned) Vec_IntEntry( s->vReasons, v ) != CRefUndef); if( c->nSize == 2 && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[0] ) ) == xSAT_LitSign( xSAT_NegLit( Lits[0] ) ) ) { assert( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[1] ) ) == xSAT_LitSign( ( Lits[1] ) ) ); ABC_SWAP( int, Lits[0], Lits[1] ); } - for (i = 1; i < (int)c->nSize; i++) + for ( i = 1; i < c->nSize; i++ ) { int v = xSAT_Lit2Var( Lits[i] ); if ( !Vec_StrEntry( s->vSeen, v ) && Vec_IntEntry( s->vLevels, v ) ) { - if ( (unsigned) Vec_IntEntry( s->vReasons, v ) != CRefUndef && ((1 << (Vec_IntEntry( s->vLevels, v ) & 31)) & MinLevel)) + if ( ( unsigned ) Vec_IntEntry( s->vReasons, v ) != CRefUndef && ( ( 1 << (Vec_IntEntry( s->vLevels, v ) & 31 ) ) & MinLevel ) ) { Vec_IntPush( s->vStack, v ); Vec_IntPush( s->vTagged, Lits[i] ); @@ -443,7 +444,7 @@ static int xSAT_SolverIsLitRemovable( xSAT_Solver_t* s, int Lit, int MinLevel ) { int Lit; Vec_IntForEachEntryStart( s->vTagged, Lit, i, top ) - Vec_StrWriteEntry( s->vSeen, xSAT_Lit2Var(Lit), 0 ); + Vec_StrWriteEntry( s->vSeen, xSAT_Lit2Var( Lit ), 0 ); Vec_IntShrink( s->vTagged, top ); return 0; } @@ -479,40 +480,34 @@ static void xSAT_SolverClaMinimisation( xSAT_Solver_t * s, Vec_Int_t * vLits ) /* Remove reduntant literals */ Vec_IntAppend( s->vTagged, vLits ); for ( i = j = 1; i < Vec_IntSize( vLits ); i++ ) - if ( (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( pLits[i] ) ) == CRefUndef || !xSAT_SolverIsLitRemovable( s, pLits[i], MinLevel ) ) + if ( ( unsigned ) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( pLits[i] ) ) == CRefUndef || !xSAT_SolverIsLitRemovable( s, pLits[i], MinLevel ) ) pLits[j++] = pLits[i]; Vec_IntShrink( vLits, j ); /* Binary Resolution */ if( Vec_IntSize( vLits ) <= 30 && xSAT_SolverClaCalcLBD2( s, vLits ) <= 6 ) { + int nb, l; int Lit; int FlaseLit = xSAT_NegLit( pLits[0] ); - int nb; - int l; - - xSAT_WatchList_t * ws; - xSAT_Watcher_t * begin; - xSAT_Watcher_t * end; + xSAT_WatchList_t * ws = xSAT_VecWatchListEntry( s->vBinWatches, FlaseLit ); + xSAT_Watcher_t * begin = xSAT_WatchListArray( ws ); + xSAT_Watcher_t * end = begin + xSAT_WatchListSize( ws ); xSAT_Watcher_t * pWatcher; s->nStamp++; Vec_IntForEachEntry( vLits, Lit, i ) - Vec_IntWriteEntry( s->vStamp, xSAT_Lit2Var( Lit ), s->nStamp ); - - ws = xSAT_VecWatchListEntry( s->vBinWatches, FlaseLit ); - begin = xSAT_WatchListArray( ws ); - end = begin + xSAT_WatchListSize( ws ); + Vec_IntWriteEntry( s->vStamp, xSAT_Lit2Var( Lit ), ( int ) s->nStamp ); nb = 0; for ( pWatcher = begin; pWatcher < end; pWatcher++ ) { int ImpLit = pWatcher->Blocker; - if ( Vec_IntEntry( s->vStamp, xSAT_Lit2Var( ImpLit ) ) == (int)s->nStamp && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( ImpLit ) ) == xSAT_LitSign( ImpLit ) ) + if ( ( unsigned ) Vec_IntEntry( s->vStamp, xSAT_Lit2Var( ImpLit ) ) == s->nStamp && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( ImpLit ) ) == xSAT_LitSign( ImpLit ) ) { nb++; - Vec_IntWriteEntry( s->vStamp, xSAT_Lit2Var( ImpLit ), s->nStamp - 1 ); + Vec_IntWriteEntry( s->vStamp, xSAT_Lit2Var( ImpLit ), ( int )( s->nStamp - 1 ) ); } } @@ -520,7 +515,7 @@ static void xSAT_SolverClaMinimisation( xSAT_Solver_t * s, Vec_Int_t * vLits ) if ( nb > 0 ) { for ( i = 1; i < Vec_IntSize( vLits ) - nb; i++ ) - if ( Vec_IntEntry( s->vStamp, xSAT_Lit2Var( pLits[i] ) ) != (int)s->nStamp ) + if ( ( unsigned ) Vec_IntEntry( s->vStamp, xSAT_Lit2Var( pLits[i] ) ) != s->nStamp ) { int TempLit = pLits[l]; pLits[l] = pLits[i]; @@ -546,43 +541,44 @@ static void xSAT_SolverClaMinimisation( xSAT_Solver_t * s, Vec_Int_t * vLits ) ***********************************************************************/ static void xSAT_SolverAnalyze( xSAT_Solver_t* s, unsigned ConfCRef, Vec_Int_t * vLearnt, int * OutBtLevel, unsigned * nLBD ) { - int* trail = Vec_IntArray( s->vTrail ); - int Count = 0; + int * trail = Vec_IntArray( s->vTrail ); + int Count = 0; int p = LitUndef; int Idx = Vec_IntSize( s->vTrail ) - 1; - int* Lits; + int * Lits; int Lit; int i, j; Vec_IntPush( vLearnt, LitUndef ); do { - xSAT_Clause_t * c; - assert( ConfCRef != CRefUndef ); - c = xSAT_SolverReadClause(s, ConfCRef); - Lits = &( c->pData[0].Lit ); + xSAT_Clause_t * pCla; - if( p != LitUndef && c->nSize == 2 && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var(Lits[0])) == xSAT_LitSign( xSAT_NegLit( Lits[0] ) ) ) + assert( ConfCRef != CRefUndef ); + pCla = xSAT_SolverReadClause(s, ConfCRef); + Lits = &( pCla->pData[0].Lit ); + + if( p != LitUndef && pCla->nSize == 2 && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[0] ) ) == xSAT_LitSign( xSAT_NegLit( Lits[0] ) ) ) { assert( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[1] ) ) == xSAT_LitSign( ( Lits[1] ) ) ); ABC_SWAP( int, Lits[0], Lits[1] ); } - if ( c->fLearnt ) - xSAT_SolverClaActBump( s, c ); + if ( pCla->fLearnt ) + xSAT_SolverClaActBump( s, pCla ); - if ( c->fLearnt && c->nLBD > 2 ) + if ( pCla->fLearnt && pCla->nLBD > 2 ) { - unsigned int nblevels = xSAT_SolverClaCalcLBD(s, c); - if ( nblevels + 1 < c->nLBD ) + unsigned int nLevels = xSAT_SolverClaCalcLBD( s, pCla ); + if ( nLevels + 1 < pCla->nLBD ) { - if (c->nLBD <= s->Config.nLBDFrozenClause) - c->fCanBeDel = 0; - c->nLBD = nblevels; + if ( pCla->nLBD <= s->Config.nLBDFrozenClause ) + pCla->fCanBeDel = 0; + pCla->nLBD = nLevels; } } - for ( j = ( p == LitUndef ? 0 : 1 ); j < (int)c->nSize; j++ ) + for ( j = ( p == LitUndef ? 0 : 1 ); j < pCla->nSize; j++ ) { int Var = xSAT_Lit2Var( Lits[j] ); @@ -605,14 +601,13 @@ static void xSAT_SolverAnalyze( xSAT_Solver_t* s, unsigned ConfCRef, Vec_Int_t * // Next clause to look at p = trail[Idx+1]; - ConfCRef = (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( p ) ); + ConfCRef = ( unsigned ) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( p ) ); Vec_StrWriteEntry( s->vSeen, xSAT_Lit2Var( p ), 0 ); Count--; } while ( Count > 0 ); Vec_IntArray( vLearnt )[0] = xSAT_NegLit( p ); - xSAT_SolverClaMinimisation( s, vLearnt ); // Find the backtrack level @@ -677,41 +672,38 @@ unsigned xSAT_SolverPropagate( xSAT_Solver_t* s ) while ( s->iQhead < Vec_IntSize( s->vTrail ) ) { int p = Vec_IntEntry( s->vTrail, s->iQhead++ ); - xSAT_WatchList_t* ws = xSAT_VecWatchListEntry( s->vBinWatches, p ); xSAT_Watcher_t* begin = xSAT_WatchListArray( ws ); xSAT_Watcher_t* end = begin + xSAT_WatchListSize( ws ); xSAT_Watcher_t *i, *j; nProp++; - for (i = begin; i < end; i++) + for ( i = begin; i < end; i++ ) { - if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var(i->Blocker)) == xSAT_LitSign(xSAT_NegLit(i->Blocker))) + if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( i->Blocker ) ) == xSAT_LitSign( xSAT_NegLit( i->Blocker ) ) ) { return i->CRef; } - else if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var(i->Blocker)) == VarX) - xSAT_SolverEnqueue(s, i->Blocker, i->CRef); + else if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( i->Blocker ) ) == VarX ) + xSAT_SolverEnqueue( s, i->Blocker, i->CRef ); } - - ws = xSAT_VecWatchListEntry( s->vWatches, p); + ws = xSAT_VecWatchListEntry( s->vWatches, p ); begin = xSAT_WatchListArray( ws ); end = begin + xSAT_WatchListSize( ws ); for ( i = j = begin; i < end; ) { - xSAT_Clause_t* c; + xSAT_Clause_t * pCla; xSAT_Watcher_t w; - if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( i->Blocker ) ) == xSAT_LitSign( i->Blocker ) ) { *j++ = *i++; continue; } - c = xSAT_SolverReadClause( s, i->CRef ); - Lits = &( c->pData[0].Lit ); + pCla = xSAT_SolverReadClause( s, i->CRef ); + Lits = &( pCla->pData[0].Lit ); // Make sure the false literal is data[1]: NegLit = xSAT_NegLit( p ); @@ -731,8 +723,8 @@ unsigned xSAT_SolverPropagate( xSAT_Solver_t* s ) else { // Look for new watch: - int* stop = Lits + c->nSize; - int* k; + int * stop = Lits + pCla->nSize; + int * k; for ( k = Lits + 2; k < stop; k++ ) { if (Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( *k ) ) != !xSAT_LitSign( *k ) ) @@ -791,7 +783,7 @@ void xSAT_SolverReduceDB( xSAT_Solver_t * s ) int nLearnedOld = Vec_IntSize( s->vLearnts ); int i, limit; unsigned CRef; - xSAT_Clause_t * c; + xSAT_Clause_t * pCla; xSAT_Clause_t ** learnts_cls; learnts_cls = ABC_ALLOC( xSAT_Clause_t *, nLearnedOld ); @@ -812,21 +804,22 @@ void xSAT_SolverReduceDB( xSAT_Solver_t * s ) for ( i = 0; i < nLearnedOld; i++ ) { unsigned CRef; - c = learnts_cls[i]; - CRef = xSAT_MemCRef( s->pMemory, (unsigned * ) c ); - assert(c->fMark == 0); - if ( c->fCanBeDel && c->nLBD > 2 && c->nSize > 2 && (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( c->pData[0].Lit ) ) != CRef && ( i < limit ) ) + + pCla = learnts_cls[i]; + CRef = xSAT_MemCRef( s->pMemory, ( unsigned * ) pCla ); + assert( pCla->fMark == 0 ); + if ( pCla->fCanBeDel && pCla->nLBD > 2 && pCla->nSize > 2 && (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( pCla->pData[0].Lit ) ) != CRef && ( i < limit ) ) { - c->fMark = 1; - s->Stats.nLearntLits -= c->nSize; - xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( c->pData[0].Lit ) ), CRef ); - xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( c->pData[1].Lit ) ), CRef ); + pCla->fMark = 1; + s->Stats.nLearntLits -= pCla->nSize; + xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( pCla->pData[0].Lit ) ), CRef ); + xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( pCla->pData[1].Lit ) ), CRef ); } else { - if (!c->fCanBeDel) + if ( !pCla->fCanBeDel ) limit++; - c->fCanBeDel = 1; + pCla->fCanBeDel = 1; Vec_IntPush( s->vLearnts, CRef ); } } @@ -876,7 +869,7 @@ char xSAT_SolverSearch( xSAT_Solver_t * s ) return LBoolFalse; xSAT_BQueuePush( s->bqTrail, Vec_IntSize( s->vTrail ) ); - if ( s->Stats.nConflicts > s->Config.nFirstBlockRestart && xSAT_BQueueIsValid( s->bqLBD ) && ( Vec_IntSize( s->vTrail ) > ( s->Config.R * (iword)xSAT_BQueueAvg( s->bqTrail ) ) ) ) + if ( s->Stats.nConflicts > s->Config.nFirstBlockRestart && xSAT_BQueueIsValid( s->bqLBD ) && ( Vec_IntSize( s->vTrail ) > ( s->Config.R * ( iword ) xSAT_BQueueAvg( s->bqTrail ) ) ) ) xSAT_BQueueClean(s->bqLBD); Vec_IntClear( s->vLearntClause ); @@ -896,7 +889,7 @@ char xSAT_SolverSearch( xSAT_Solver_t * s ) { /* No conflict */ int NextVar; - if ( xSAT_BQueueIsValid( s->bqLBD ) && ( ( (iword)xSAT_BQueueAvg( s->bqLBD ) * s->Config.K ) > ( s->nSumLBD / (iword)s->Stats.nConflicts ) ) ) + if ( xSAT_BQueueIsValid( s->bqLBD ) && ( ( ( iword )xSAT_BQueueAvg( s->bqLBD ) * s->Config.K ) > ( s->nSumLBD / s->Stats.nConflicts ) ) ) { xSAT_BQueueClean( s->bqLBD ); xSAT_SolverCancelUntil( s, 0 ); @@ -942,23 +935,20 @@ char xSAT_SolverSearch( xSAT_Solver_t * s ) ***********************************************************************/ void xSAT_SolverClaRealloc( xSAT_Mem_t * pDest, xSAT_Mem_t * pSrc, unsigned * pCRef ) { - xSAT_Clause_t * pOldCla = xSAT_MemClauseHand( pSrc, *pCRef ); unsigned nNewCRef; xSAT_Clause_t * pNewCla; + xSAT_Clause_t * pOldCla = xSAT_MemClauseHand( pSrc, *pCRef ); if ( pOldCla->fReallocd ) { - *pCRef = (unsigned) pOldCla->nSize; + *pCRef = ( unsigned ) pOldCla->nSize; return; } - nNewCRef = xSAT_MemAppend( pDest, 3 + pOldCla->fLearnt + pOldCla->nSize ); pNewCla = xSAT_MemClauseHand( pDest, nNewCRef ); - memcpy( pNewCla, pOldCla, ( 3 + pOldCla->fLearnt + pOldCla->nSize ) * 4 ); - pOldCla->fReallocd = 1; - pOldCla->nSize = (unsigned) nNewCRef; + pOldCla->nSize = ( unsigned ) nNewCRef; *pCRef = nNewCRef; } @@ -997,14 +987,14 @@ void xSAT_SolverGarbageCollect( xSAT_Solver_t * s ) } for ( i = 0; i < Vec_IntSize( s->vTrail ); i++ ) - if ( (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) ) ) != CRefUndef ) - xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, (unsigned *)&( Vec_IntArray( s->vReasons )[xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) )] ) ); + if ( ( unsigned ) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) ) ) != CRefUndef ) + xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, ( unsigned * ) &( Vec_IntArray( s->vReasons )[xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) )] ) ); pArray = ( unsigned * ) Vec_IntArray( s->vLearnts ); for ( i = 0; i < Vec_IntSize( s->vLearnts ); i++ ) xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &(pArray[i]) ); - pArray = (unsigned *) Vec_IntArray( s->vClauses ); + pArray = ( unsigned * ) Vec_IntArray( s->vClauses ); for ( i = 0; i < Vec_IntSize( s->vClauses ); i++ ) xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &(pArray[i]) ); diff --git a/src/sat/xsat/xsatSolver.h b/src/sat/xsat/xsatSolver.h index 2bcd93b74..bf8bf4197 100644 --- a/src/sat/xsat/xsatSolver.h +++ b/src/sat/xsat/xsatSolver.h @@ -81,9 +81,9 @@ struct xSAT_SolverOptions_t_ char fVerbose; // Limits - word nConfLimit; // external limit on the number of conflicts - word nInsLimit; // external limit on the number of implications - abctime nRuntimeLimit; // external limit on runtime + iword nConfLimit; // external limit on the number of conflicts + iword nInsLimit; // external limit on the number of implications + abctime nRuntimeLimit; // external limit on runtime // Constants used for restart heuristic double K; // Forces a restart @@ -105,13 +105,13 @@ struct xSAT_Stats_t_ unsigned nStarts; unsigned nReduceDB; - word nDecisions; - word nPropagations; - word nInspects; - word nConflicts; + iword nDecisions; + iword nPropagations; + iword nInspects; + iword nConflicts; - word nClauseLits; - word nLearntLits; + iword nClauseLits; + iword nLearntLits; }; struct xSAT_Solver_t_ @@ -143,7 +143,7 @@ struct xSAT_Solver_t_ int nAssignSimplify; /* Number of top-level assignments since last * execution of 'simplify()'. */ - word nPropSimplify; /* Remaining number of propagations that must be + int64_t nPropSimplify; /* Remaining number of propagations that must be * made before next execution of 'simplify()'. */ /* Temporary data used by Search method */ @@ -203,10 +203,10 @@ static inline xSAT_Clause_t * xSAT_SolverReadClause( xSAT_Solver_t * s, unsigned static inline int xSAT_SolverIsClauseSatisfied( xSAT_Solver_t * s, xSAT_Clause_t * pCla ) { int i; - int * lits = &( pCla->pData[0].Lit ); + int * Lits = &( pCla->pData[0].Lit ); - for ( i = 0; i < (int)pCla->nSize; i++ ) - if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( lits[i] ) ) == xSAT_LitSign( ( lits[i] ) ) ) + for ( i = 0; i < pCla->nSize; i++ ) + if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[i] ) ) == xSAT_LitSign( ( Lits[i] ) ) ) return true; return false; diff --git a/src/sat/xsat/xsatSolverAPI.c b/src/sat/xsat/xsatSolverAPI.c index 43c2d06e1..7746dc0be 100644 --- a/src/sat/xsat/xsatSolverAPI.c +++ b/src/sat/xsat/xsatSolverAPI.c @@ -51,6 +51,7 @@ xSAT_SolverOptions_t DefaultConfig = 30 //.nLBDFrozenClause = 30 }; + /**Function************************************************************* Synopsis [] @@ -125,7 +126,6 @@ void xSAT_SolverDestroy( xSAT_Solver_t * s ) xSAT_VecWatchListFree( s->vWatches ); xSAT_VecWatchListFree( s->vBinWatches ); - // delete vectors xSAT_HeapFree(s->hOrder); Vec_IntFree( s->vTrailLim ); Vec_IntFree( s->vTrail ); diff --git a/src/sat/xsat/xsatWatchList.h b/src/sat/xsat/xsatWatchList.h index 2ba13c24d..284be1008 100644 --- a/src/sat/xsat/xsatWatchList.h +++ b/src/sat/xsat/xsatWatchList.h @@ -118,9 +118,9 @@ static inline void xSAT_WatchListShrink( xSAT_WatchList_t * v, int k ) static inline void xSAT_WatchListPush( xSAT_WatchList_t * v, xSAT_Watcher_t e ) { assert( v ); - if (v->nSize == v->nCap) + if ( v->nSize == v->nCap ) { - int newsize = (v->nCap < 4) ? 4 : (v->nCap / 2) * 3; + int newsize = ( v->nCap < 4 ) ? 4 : ( v->nCap / 2 ) * 3; v->pArray = ABC_REALLOC( xSAT_Watcher_t, v->pArray, newsize ); if ( v->pArray == NULL ) @@ -167,9 +167,9 @@ static inline void xSAT_WatchListRemove( xSAT_WatchList_t * v, unsigned CRef ) xSAT_Watcher_t* ws = xSAT_WatchListArray(v); int j = 0; - for (; ws[j].CRef != CRef; j++); - assert(j < xSAT_WatchListSize(v)); - memmove(v->pArray + j, v->pArray + j + 1, (v->nSize - j - 1) * sizeof(xSAT_Watcher_t)); + for ( ; ws[j].CRef != CRef; j++ ); + assert( j < xSAT_WatchListSize( v ) ); + memmove( v->pArray + j, v->pArray + j + 1, ( v->nSize - j - 1 ) * sizeof( xSAT_Watcher_t ) ); v->nSize -= 1; } @@ -190,7 +190,7 @@ static inline xSAT_VecWatchList_t * xSAT_VecWatchListAlloc( int nCap ) v->nCap = 4; v->nSize = 0; - v->pArray = (xSAT_WatchList_t *) ABC_CALLOC(xSAT_WatchList_t, sizeof( xSAT_WatchList_t ) * v->nCap); + v->pArray = ( xSAT_WatchList_t * ) ABC_CALLOC(xSAT_WatchList_t, sizeof( xSAT_WatchList_t ) * v->nCap); return v; } @@ -233,7 +233,7 @@ static inline void xSAT_VecWatchListPush( xSAT_VecWatchList_t* v ) int newsize = (v->nCap < 4) ? v->nCap * 2 : (v->nCap / 2) * 3; v->pArray = ABC_REALLOC( xSAT_WatchList_t, v->pArray, newsize ); - memset( v->pArray + v->nCap, 0, sizeof(xSAT_WatchList_t) * (newsize - v->nCap) ); + memset( v->pArray + v->nCap, 0, sizeof( xSAT_WatchList_t ) * ( newsize - v->nCap ) ); if ( v->pArray == NULL ) { printf( "Failed to realloc memory from %.1f MB to %.1f MB.\n", From cf5d4ad07f87e936a114afca483ed66ffb1a2120 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 21 Dec 2016 15:34:02 +0700 Subject: [PATCH 007/185] Converting some errors into warnings. --- src/base/abci/abc.c | 4 ++-- src/base/abci/abcMfs.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index dabeb9822..fb3017902 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -19532,7 +19532,7 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( Abc_NtkIsComb(pNtk) ) { - Abc_Print( -1, "The network is combinational (run \"fraig\" or \"fraig_sweep\").\n" ); + Abc_Print( 0, "The network is combinational (run \"fraig\" or \"fraig_sweep\").\n" ); return 0; } @@ -31954,7 +31954,7 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv ) } if ( Gia_ManRegNum(pAbc->pGia) == 0 ) { - Abc_Print( -1, "The network is combinational.\n" ); + Abc_Print( 0, "The network is combinational.\n" ); return 0; } pTemp = Cec_ManLSCorrespondence( pAbc->pGia, pPars ); diff --git a/src/base/abci/abcMfs.c b/src/base/abci/abcMfs.c index e33d6c73a..d44ca1a0e 100644 --- a/src/base/abci/abcMfs.c +++ b/src/base/abci/abcMfs.c @@ -259,7 +259,7 @@ int Abc_NtkPerformMfs( Abc_Ntk_t * pNtk, Sfm_Par_t * pPars ) if ( nFaninMax > 6 ) { Abc_Print( 1, "Currently \"mfs\" cannot process the network containing nodes with more than 6 fanins.\n" ); - return 0; + return 1; } if ( !Abc_NtkHasSop(pNtk) ) if ( !Abc_NtkToSop( pNtk, -1, ABC_INFINITY ) ) From b56a532682e34ae440bc6ffa939e82d06cf06e62 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 22 Dec 2016 17:27:32 +0700 Subject: [PATCH 008/185] Several changes in arithmetic circuit manipulation. --- abclib.dsp | 4 + src/aig/gia/gia.h | 2 +- src/aig/gia/giaDup.c | 112 ++++++++++++++++--- src/aig/gia/giaShow.c | 12 ++- src/base/abci/abc.c | 12 ++- src/proof/acec/acecBo.c | 216 +++++++++++++++++++++++++++++++++++++ src/proof/acec/acecCl.c | 95 +++++++++++++++- src/proof/acec/module.make | 1 + 8 files changed, 430 insertions(+), 24 deletions(-) create mode 100644 src/proof/acec/acecBo.c diff --git a/abclib.dsp b/abclib.dsp index 9b1c9d945..1d08c9508 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -5463,6 +5463,10 @@ SOURCE=.\src\proof\acec\acec.h # End Source File # Begin Source File +SOURCE=.\src\proof\acec\acecBo.c +# End Source File +# Begin Source File + SOURCE=.\src\proof\acec\acecCl.c # End Source File # Begin Source File diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index bf7bf3490..ac40f9754 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1403,7 +1403,7 @@ extern Gia_Man_t * Gia_ManCleanupOutputs( Gia_Man_t * p, int nOutputs ); extern Gia_Man_t * Gia_ManSeqCleanup( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManSeqStructSweep( Gia_Man_t * p, int fConst, int fEquiv, int fVerbose ); /*=== giaShow.c ===========================================================*/ -extern void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders ); +extern void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds ); /*=== giaShrink.c ===========================================================*/ extern Gia_Man_t * Gia_ManMapShrink4( Gia_Man_t * p, int fKeepLevel, int fVerbose ); extern Gia_Man_t * Gia_ManMapShrink6( Gia_Man_t * p, int nFanoutMax, int fKeepLevel, int fVerbose ); diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 7ced54a4a..c58596b2f 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -3377,6 +3377,26 @@ Gia_Man_t * Gia_ManDupOuts( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ +Vec_Wec_t * Gia_ManCreateNodeSupps( Gia_Man_t * p, Vec_Int_t * vNodes, int fVerbose ) +{ + abctime clk = Abc_Clock(); + Gia_Obj_t * pObj; int i, Id; + Vec_Wec_t * vSuppsNo = Vec_WecStart( Vec_IntSize(vNodes) ); + Vec_Wec_t * vSupps = Vec_WecStart( Gia_ManObjNum(p) ); + Gia_ManForEachCiId( p, Id, i ) + Vec_IntPush( Vec_WecEntry(vSupps, Id), i ); + Gia_ManForEachAnd( p, pObj, Id ) + Vec_IntTwoMerge2( Vec_WecEntry(vSupps, Gia_ObjFaninId0(pObj, Id)), + Vec_WecEntry(vSupps, Gia_ObjFaninId1(pObj, Id)), + Vec_WecEntry(vSupps, Id) ); + Gia_ManForEachObjVec( vNodes, p, pObj, i ) + Vec_IntAppend( Vec_WecEntry(vSuppsNo, i), Vec_WecEntry(vSupps, Gia_ObjId(p, pObj)) ); + Vec_WecFree( vSupps ); + if ( fVerbose ) + Abc_PrintTime( 1, "Support computation", Abc_Clock() - clk ); + return vSuppsNo; +} + Vec_Wec_t * Gia_ManCreateCoSupps( Gia_Man_t * p, int fVerbose ) { abctime clk = Abc_Clock(); @@ -3679,6 +3699,81 @@ Gia_Man_t * Gia_ManDupDemiter( Gia_Man_t * p, int fVerbose ) return pNew; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManDupDemiterOrderXors2( Gia_Man_t * p, Vec_Int_t * vXors ) +{ + int i, iObj, * pPerm; + Vec_Int_t * vSizes = Vec_IntAlloc( 100 ); + Vec_IntForEachEntry( vXors, iObj, i ) + Vec_IntPush( vSizes, Gia_ManSuppSize(p, &iObj, 1) ); + pPerm = Abc_MergeSortCost( Vec_IntArray(vSizes), Vec_IntSize(vSizes) ); + Vec_IntClear( vSizes ); + for ( i = 0; i < Vec_IntSize(vXors); i++ ) + Vec_IntPush( vSizes, Vec_IntEntry(vXors, pPerm[i]) ); + ABC_FREE( pPerm ); + Vec_IntClear( vXors ); + Vec_IntAppend( vXors, vSizes ); + Vec_IntFree( vSizes ); +} +int Gia_ManDupDemiterFindMin( Vec_Wec_t * vSupps, Vec_Int_t * vTakenIns, Vec_Int_t * vTakenOuts ) +{ + Vec_Int_t * vLevel; + int i, k, iObj, iObjBest = -1; + int Count, CountBest = ABC_INFINITY; + Vec_WecForEachLevel( vSupps, vLevel, i ) + { + if ( Vec_IntEntry(vTakenOuts, i) ) + continue; + Count = 0; + Vec_IntForEachEntry( vLevel, iObj, k ) + Count += !Vec_IntEntry(vTakenIns, iObj); + if ( CountBest > Count ) + { + CountBest = Count; + iObjBest = i; + } + } + return iObjBest; +} +void Gia_ManDupDemiterOrderXors( Gia_Man_t * p, Vec_Int_t * vXors ) +{ + extern Vec_Wec_t * Gia_ManCreateNodeSupps( Gia_Man_t * p, Vec_Int_t * vNodes, int fVerbose ); + Vec_Wec_t * vSupps = Gia_ManCreateNodeSupps( p, vXors, 0 ); + Vec_Int_t * vTakenIns = Vec_IntStart( Gia_ManCiNum(p) ); + Vec_Int_t * vTakenOuts = Vec_IntStart( Vec_IntSize(vXors) ); + Vec_Int_t * vOrder = Vec_IntAlloc( Vec_IntSize(vXors) ); + int i, k, iObj; + // add outputs in the order of increasing supports + for ( i = 0; i < Vec_IntSize(vXors); i++ ) + { + int Index = Gia_ManDupDemiterFindMin( vSupps, vTakenIns, vTakenOuts ); + assert( Index >= 0 && Index < Vec_IntSize(vXors) ); + Vec_IntPush( vOrder, Vec_IntEntry(vXors, Index) ); + assert( !Vec_IntEntry( vTakenOuts, Index ) ); + Vec_IntWriteEntry( vTakenOuts, Index, 1 ); + Vec_IntForEachEntry( Vec_WecEntry(vSupps, Index), iObj, k ) + Vec_IntWriteEntry( vTakenIns, iObj, 1 ); + } + Vec_WecFree( vSupps ); + Vec_IntFree( vTakenIns ); + Vec_IntFree( vTakenOuts ); + // reload + Vec_IntClear( vXors ); + Vec_IntAppend( vXors, vOrder ); + Vec_IntFree( vOrder ); +} + + /**Function************************************************************* Synopsis [] @@ -3781,8 +3876,8 @@ void Gia_ManCollectTopXors_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vXo } Vec_Int_t * Gia_ManCollectTopXors( Gia_Man_t * p ) { - int i, iObj, iObj2, fFlip, * pPerm, Count1 = 0; - Vec_Int_t * vXors, * vSizes, * vPart[2], * vOrder; + int i, iObj, iObj2, fFlip, Count1 = 0; + Vec_Int_t * vXors, * vPart[2], * vOrder; Gia_Obj_t * pFan[2], * pObj = Gia_ManCo(p, 0); assert( Gia_ManCoNum(p) == 1 ); vXors = Vec_IntAlloc( 100 ); @@ -3791,17 +3886,8 @@ Vec_Int_t * Gia_ManCollectTopXors( Gia_Man_t * p ) else Vec_IntPush( vXors, Gia_ObjId(p, Gia_ObjFanin0(pObj)) ); // order by support size - vSizes = Vec_IntAlloc( 100 ); - Vec_IntForEachEntry( vXors, iObj, i ) - Vec_IntPush( vSizes, Gia_ManSuppSize(p, &iObj, 1) ); - pPerm = Abc_MergeSortCost( Vec_IntArray(vSizes), Vec_IntSize(vSizes) ); - Vec_IntClear( vSizes ); - for ( i = 0; i < Vec_IntSize(vXors); i++ ) - Vec_IntPush( vSizes, Vec_IntEntry(vXors, pPerm[i]) ); - ABC_FREE( pPerm ); - Vec_IntClear( vXors ); - Vec_IntAppend( vXors, vSizes ); - Vec_IntFree( vSizes ); + Gia_ManDupDemiterOrderXors( p, vXors ); + //Vec_IntPrint( vXors ); Vec_IntReverseOrder( vXors ); // from MSB to LSB // divide into groups Gia_ManCleanMark01(p); diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index afc58bf8e..afd36fff2 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -713,11 +713,13 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In SeeAlso [] ***********************************************************************/ -Vec_Int_t * Gia_ShowMapAdds( Gia_Man_t * p, Vec_Int_t * vAdds ) +Vec_Int_t * Gia_ShowMapAdds( Gia_Man_t * p, Vec_Int_t * vAdds, int fFadds ) { Vec_Int_t * vMapAdds = Vec_IntStartFull( Gia_ManObjNum(p) ); int i; for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) { + if ( fFadds && Vec_IntEntry(vAdds, 6*i+2) == 0 ) + continue; Vec_IntWriteEntry( vMapAdds, Vec_IntEntry(vAdds, 6*i+3), i ); Vec_IntWriteEntry( vMapAdds, Vec_IntEntry(vAdds, 6*i+4), i ); } @@ -800,9 +802,9 @@ Vec_Int_t * Gia_ShowCollectObjs( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * v SeeAlso [] ***********************************************************************/ -void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_Int_t * vXors ) +void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_Int_t * vXors, int fFadds ) { - Vec_Int_t * vMapAdds = Gia_ShowMapAdds( p, vAdds ); + Vec_Int_t * vMapAdds = Gia_ShowMapAdds( p, vAdds, fFadds ); Vec_Int_t * vMapXors = Gia_ShowMapXors( p, vXors ); Vec_Int_t * vOrder = Gia_ShowCollectObjs( p, vAdds, vXors, vMapAdds, vMapXors ); Gia_WriteDotAig( p, pFileName, vAdds, vXors, vMapAdds, vMapXors, vOrder ); @@ -810,7 +812,7 @@ void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In Vec_IntFree( vMapXors ); Vec_IntFree( vOrder ); } -void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders ) +void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds ) { extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ); @@ -837,7 +839,7 @@ void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders ) fclose( pFile ); // generate the file if ( fAdders ) - Gia_ShowProcess( pMan, FileNameDot, vAdds, vXors ); + Gia_ShowProcess( pMan, FileNameDot, vAdds, vXors, fFadds ); else Gia_WriteDotAigSimple( pMan, FileNameDot, vBold ); // visualize the file diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index fb3017902..7866b22d7 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -28592,15 +28592,18 @@ usage: int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv ) { Vec_Int_t * vBold = NULL; - int c, fAdders = 0; + int c, fAdders = 0, fFadds = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "ah" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "afh" ) ) != EOF ) { switch ( c ) { case 'a': fAdders ^= 1; break; + case 'f': + fFadds ^= 1; + break; case 'h': goto usage; default: @@ -28623,14 +28626,15 @@ int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv ) Gia_ManForEachLut( pAbc->pGia, c ) Vec_IntPush( vBold, c ); } - Gia_ManShow( pAbc->pGia, vBold, fAdders ); + Gia_ManShow( pAbc->pGia, vBold, fAdders, fFadds ); Vec_IntFreeP( &vBold ); return 0; usage: - Abc_Print( -2, "usage: &show [-ah]\n" ); + Abc_Print( -2, "usage: &show [-afh]\n" ); Abc_Print( -2, "\t shows the current GIA using GSView\n" ); Abc_Print( -2, "\t-a : toggle visualazing adders [default = %s]\n", fAdders? "yes": "no" ); + Abc_Print( -2, "\t-f : toggle only showing full-adders with \"-a\" [default = %s]\n", fFadds? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } diff --git a/src/proof/acec/acecBo.c b/src/proof/acec/acecBo.c new file mode 100644 index 000000000..9cddcd132 --- /dev/null +++ b/src/proof/acec/acecBo.c @@ -0,0 +1,216 @@ +/**CFile**************************************************************** + + FileName [acecBo.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [CEC for arithmetic circuits.] + + Synopsis [Core procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: acecBo.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "acecInt.h" +#include "misc/vec/vecWec.h" +#include "misc/extra/extra.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_DetectBoothXorMux( Gia_Man_t * p, Gia_Obj_t * pMux, Gia_Obj_t * pXor, int pIns[3] ) +{ + Gia_Obj_t * pFan0, * pFan1; + Gia_Obj_t * pDat0, * pDat1, * pCtrl; + if ( !Gia_ObjIsMuxType(pMux) || !Gia_ObjIsMuxType(pXor) ) + return 0; + if ( !Gia_ObjRecognizeExor( pXor, &pFan0, &pFan1 ) ) + return 0; + pFan0 = Gia_Regular(pFan0); + pFan1 = Gia_Regular(pFan1); + if ( Gia_ObjId(p, pFan0) > Gia_ObjId(p, pFan1) ) + ABC_SWAP( Gia_Obj_t *, pFan0, pFan1 ); + if ( !(pCtrl = Gia_ObjRecognizeMux( pMux, &pDat0, &pDat1 )) ) + return 0; + pDat0 = Gia_Regular(pDat0); + pDat1 = Gia_Regular(pDat1); + pCtrl = Gia_Regular(pCtrl); + if ( !Gia_ObjIsAnd(pDat0) || !Gia_ObjIsAnd(pDat1) ) + return 0; + if ( Gia_ObjFaninId0p(p, pDat0) != Gia_ObjFaninId0p(p, pDat1) || + Gia_ObjFaninId1p(p, pDat0) != Gia_ObjFaninId1p(p, pDat1) ) + return 0; + if ( Gia_ObjFaninId0p(p, pDat0) != Gia_ObjId(p, pFan0) || + Gia_ObjFaninId1p(p, pDat0) != Gia_ObjId(p, pFan1) ) + return 0; + pIns[0] = Gia_ObjId(p, pFan0); + pIns[1] = Gia_ObjId(p, pFan1); + pIns[2] = Gia_ObjId(p, pCtrl); + return 1; +} +int Acec_DetectBoothXorFanin( Gia_Man_t * p, Gia_Obj_t * pObj, int pIns[5] ) +{ + Gia_Obj_t * pFan0, * pFan1; + //int Id = Gia_ObjId(p, pObj); + if ( !Gia_ObjIsAnd(pObj) ) + return 0; + if ( !Gia_ObjFaninC0(pObj) || !Gia_ObjFaninC1(pObj) ) + return 0; + pFan0 = Gia_ObjFanin0(pObj); + pFan1 = Gia_ObjFanin1(pObj); + if ( !Gia_ObjIsAnd(pFan0) || !Gia_ObjIsAnd(pFan1) ) + return 0; + if ( Acec_DetectBoothXorMux(p, Gia_ObjFanin0(pFan0), Gia_ObjFanin0(pFan1), pIns) ) + { + pIns[3] = Gia_ObjId(p, Gia_ObjFanin1(pFan0)); + pIns[4] = Gia_ObjId(p, Gia_ObjFanin1(pFan1)); + return 1; + } + if ( Acec_DetectBoothXorMux(p, Gia_ObjFanin0(pFan0), Gia_ObjFanin1(pFan1), pIns) ) + { + pIns[3] = Gia_ObjId(p, Gia_ObjFanin1(pFan0)); + pIns[4] = Gia_ObjId(p, Gia_ObjFanin0(pFan1)); + return 1; + } + if ( Acec_DetectBoothXorMux(p, Gia_ObjFanin1(pFan0), Gia_ObjFanin0(pFan1), pIns) ) + { + pIns[3] = Gia_ObjId(p, Gia_ObjFanin0(pFan0)); + pIns[4] = Gia_ObjId(p, Gia_ObjFanin1(pFan1)); + return 1; + } + if ( Acec_DetectBoothXorMux(p, Gia_ObjFanin1(pFan0), Gia_ObjFanin1(pFan1), pIns) ) + { + pIns[3] = Gia_ObjId(p, Gia_ObjFanin0(pFan0)); + pIns[4] = Gia_ObjId(p, Gia_ObjFanin0(pFan1)); + return 1; + } + return 0; +} +int Acec_DetectBoothOne( Gia_Man_t * p, Gia_Obj_t * pObj, int pIns[5] ) +{ + Gia_Obj_t * pFan0, * pFan1; + if ( !Gia_ObjRecognizeExor( pObj, &pFan0, &pFan1 ) ) + return 0; + pFan0 = Gia_Regular(pFan0); + pFan1 = Gia_Regular(pFan1); + if ( Acec_DetectBoothXorFanin( p, pFan0, pIns ) && pIns[2] == Gia_ObjId(p, pFan1) ) + return 1; + if ( Acec_DetectBoothXorFanin( p, pFan1, pIns ) && pIns[2] == Gia_ObjId(p, pFan0) ) + return 1; + return 0; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_DetectBoothTwoXor( Gia_Man_t * p, Gia_Obj_t * pObj, int pIns[5] ) +{ + Gia_Obj_t * pFan0, * pFan1; + if ( !Gia_ObjIsAnd(pObj) ) + return 0; + if ( Gia_ObjRecognizeExor( Gia_ObjFanin0(pObj), &pFan0, &pFan1 ) ) + { + pIns[0] = Gia_ObjId(p, Gia_Regular(pFan0)); + pIns[1] = Gia_ObjId(p, Gia_Regular(pFan1)); + pIns[2] = -1; + pIns[3] = 0; + pIns[4] = Gia_ObjId(p, Gia_ObjFanin1(pObj)); + return 1; + } + if ( Gia_ObjRecognizeExor( Gia_ObjFanin1(pObj), &pFan0, &pFan1 ) ) + { + pIns[0] = Gia_ObjId(p, Gia_Regular(pFan0)); + pIns[1] = Gia_ObjId(p, Gia_Regular(pFan1)); + pIns[2] = -1; + pIns[3] = 0; + pIns[4] = Gia_ObjId(p, Gia_ObjFanin0(pObj)); + return 1; + } + return 0; +} +int Acec_DetectBoothTwo( Gia_Man_t * p, Gia_Obj_t * pObj, int pIns[5] ) +{ + Gia_Obj_t * pFan0, * pFan1; + if ( !Gia_ObjRecognizeExor( pObj, &pFan0, &pFan1 ) ) + return 0; + pFan0 = Gia_Regular(pFan0); + pFan1 = Gia_Regular(pFan1); + if ( Acec_DetectBoothTwoXor( p, pFan0, pIns ) ) + { + pIns[2] = Gia_ObjId(p, pFan1); + return 1; + } + if ( Acec_DetectBoothTwoXor( p, pFan1, pIns ) ) + { + pIns[2] = Gia_ObjId(p, pFan0); + return 1; + } + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_DetectBoothTest( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i, pIns[5]; + Gia_ManForEachAnd( p, pObj, i ) + { + if ( !Acec_DetectBoothOne(p, pObj, pIns) && !Acec_DetectBoothTwo(p, pObj, pIns) ) + continue; + printf( "obj = %4d : b0 = %4d b1 = %4d b2 = %4d a0 = %4d a1 = %4d\n", + i, pIns[0], pIns[1], pIns[2], pIns[3], pIns[4] ); + } +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/acec/acecCl.c b/src/proof/acec/acecCl.c index b60c2bf9e..63483d57d 100644 --- a/src/proof/acec/acecCl.c +++ b/src/proof/acec/acecCl.c @@ -127,7 +127,7 @@ Vec_Int_t * Acec_CollectXorTops( Gia_Man_t * p ) break; } Vec_IntPush( vRootXorSet, Gia_ObjId(p, pObj) ); - Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan1)) : Gia_ObjId(p, Gia_Regular(pFan0)) ); + Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan0)) : Gia_ObjId(p, Gia_Regular(pFan1)) ); Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan10)) : Gia_ObjId(p, Gia_Regular(pFan00)) ); Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan11)) : Gia_ObjId(p, Gia_Regular(pFan01)) ); } @@ -173,10 +173,101 @@ int Acec_DetectLitPolarity( Gia_Man_t * p, int Node, int Leaf ) if ( Lit0 != -1 && Lit1 != -1 ) { assert( Lit0 == Lit1 ); + printf( "Problem for leaf %d\n", Leaf ); return Lit0; } return Lit0 != -1 ? Lit0 : Lit1; } + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_DetectComputeSuppOne_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp, Vec_Int_t * vNods ) +{ + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return; + Gia_ObjSetTravIdCurrent(p, pObj); + if ( pObj->fMark0 ) + { + Vec_IntPush( vSupp, Gia_ObjId(p, pObj) ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + Acec_DetectComputeSuppOne_rec( p, Gia_ObjFanin0(pObj), vSupp, vNods ); + Acec_DetectComputeSuppOne_rec( p, Gia_ObjFanin1(pObj), vSupp, vNods ); + Vec_IntPush( vNods, Gia_ObjId(p, pObj) ); +} +void Acec_DetectComputeSupports( Gia_Man_t * p, Vec_Int_t * vRootXorSet ) +{ + Vec_Int_t * vNods = Vec_IntAlloc( 100 ); + Vec_Int_t * vPols = Vec_IntAlloc( 100 ); + Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); int i, k, Node, Pol; + for ( i = 0; 4*i < Vec_IntSize(vRootXorSet); i++ ) + { + Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) )->fMark0 = 1; + Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+2) )->fMark0 = 1; + Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+3) )->fMark0 = 1; + } + for ( i = 1; 4*i < Vec_IntSize(vRootXorSet); i++ ) + { + Vec_IntClear( vSupp ); + Gia_ManIncrementTravId( p ); + + Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) )->fMark0 = 0; + Acec_DetectComputeSuppOne_rec( p, Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) ), vSupp, vNods ); + Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) )->fMark0 = 1; + + Vec_IntSort( vSupp, 0 ); + + printf( "Out %4d : %4d \n", i, Vec_IntEntry(vRootXorSet, 4*i+1) ); + Vec_IntPrint( vSupp ); + + printf( "Cone:\n" ); + Vec_IntForEachEntry( vNods, Node, k ) + Gia_ObjPrint( p, Gia_ManObj(p, Node) ); + + + Vec_IntClear( vPols ); + Vec_IntForEachEntry( vSupp, Node, k ) + Vec_IntPush( vPols, Acec_DetectLitPolarity(p, Vec_IntEntry(vRootXorSet, 4*i+1), Node) ); + + Vec_IntForEachEntryTwo( vSupp, vPols, Node, Pol, k ) + printf( "%d(%d) ", Node, Abc_LitIsCompl(Pol) ); + + printf( "\n" ); + + Vec_IntPrint( vSupp ); + } + for ( i = 0; 4*i < Vec_IntSize(vRootXorSet); i++ ) + { + Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) )->fMark0 = 0; + Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+2) )->fMark0 = 0; + Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+3) )->fMark0 = 0; + } + Vec_IntFree( vSupp ); + Vec_IntFree( vPols ); + Vec_IntFree( vNods ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ Gia_Man_t * Acec_DetectXorBuildNew( Gia_Man_t * p, Vec_Int_t * vRootXorSet ) { Gia_Man_t * pNew; @@ -236,6 +327,8 @@ Gia_Man_t * Acec_DetectAdditional( Gia_Man_t * p, int fVerbose ) vRootXorSet = Acec_CollectXorTops( p ); if ( vRootXorSet ) { + Acec_DetectComputeSupports( p, vRootXorSet ); + pNew = Acec_DetectXorBuildNew( p, vRootXorSet ); Vec_IntFree( vRootXorSet ); } diff --git a/src/proof/acec/module.make b/src/proof/acec/module.make index df6db6956..4003695e5 100644 --- a/src/proof/acec/module.make +++ b/src/proof/acec/module.make @@ -1,6 +1,7 @@ SRC += src/proof/acec/acecCl.c \ src/proof/acec/acecCore.c \ src/proof/acec/acecCo.c \ + src/proof/acec/acecBo.c \ src/proof/acec/acecRe.c \ src/proof/acec/acecPa.c \ src/proof/acec/acecPo.c \ From 7d0648e24098ed0e6a0a1471a52946303c351c87 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 23 Dec 2016 00:23:17 +0700 Subject: [PATCH 009/185] Correcting API names for inputing/outputing MiniLut. --- src/aig/miniaig/abcapis.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/aig/miniaig/abcapis.h b/src/aig/miniaig/abcapis.h index 38c0591dc..f412f5aef 100644 --- a/src/aig/miniaig/abcapis.h +++ b/src/aig/miniaig/abcapis.h @@ -54,9 +54,9 @@ extern void Abc_NtkInputMiniAig( void * pAbc, void * pMiniAig ); extern void * Abc_NtkOutputMiniAig( void * pAbc ); extern void Abc_NtkSetFlopNum( void * pAbc, int nFlops ); -// procedures to input/output 'mini AIG' -extern void Abc_NtkInputMiniLut( void * pAbc, void * pMiniLut ); -extern void * Abc_NtkOutputMiniLut( void * pAbc ); +// procedures to input/output 'mini LUT' +extern void Abc_FrameGiaInputMiniLut( void * pAbc, void * pMiniLut ); +extern void * Abc_FrameGiaOutputMiniLut( void * pAbc ); // procedures to set CI/CO arrival/required times extern void Abc_NtkSetCiArrivalTime( void * pAbc, int iCi, float Rise, float Fall ); From b9dfb992c78e3c8786dee303e4a9994d46b6990a Mon Sep 17 00:00:00 2001 From: Baruch Sterin Date: Thu, 22 Dec 2016 18:15:29 -0800 Subject: [PATCH 010/185] (1) Makefile: added a shared library target, (2) no longer compile the main function as part of libabc.a --- Makefile | 8 +++++++- readme.md | 7 +++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 2385431ce..d45978a9d 100644 --- a/Makefile +++ b/Makefile @@ -139,6 +139,8 @@ OBJ := \ $(patsubst %.c, %.o, $(filter %.c, $(SRC))) \ $(patsubst %.y, %.o, $(filter %.y, $(SRC))) +LIBOBJ := $(filter-out src/base/main/main.o,$(OBJ)) + DEP := $(OBJ:.o=.d) # implicit rules @@ -186,11 +188,15 @@ $(PROG): $(OBJ) @echo "$(MSG_PREFIX)\`\` Building binary:" $(notdir $@) $(VERBOSE)$(LD) -o $@ $^ $(LIBS) -lib$(PROG).a: $(OBJ) +lib$(PROG).a: $(LIBOBJ) @echo "$(MSG_PREFIX)\`\` Linking:" $(notdir $@) $(VERBOSE)ar rv $@ $? $(VERBOSE)ranlib $@ +lib$(PROG).so: $(LIBOBJ) + @echo "$(MSG_PREFIX)\`\` Linking:" $(notdir $@) + $(VERBOSE)$(CXX) -shared -o $@ $^ $(LIBS) + docs: @echo "$(MSG_PREFIX)\`\` Building documentation." $(notdir $@) $(VERBOSE)doxygen doxygen.conf diff --git a/readme.md b/readme.md index c7a6816db..ca9a90bae 100644 --- a/readme.md +++ b/readme.md @@ -53,6 +53,13 @@ The current version of ABC can be compiled with C compiler or C++ compiler. * To compile as C++ code with namespaces: make sure that `CC=g++` and `ABC_NAMESPACE` is set to the name of the requested namespace. For example, add `-DABC_NAMESPACE=xxx` to OPTFLAGS. +## Building a shared library + + * Compile the code as position-independent by adding `ABC_USE_PIC=1`. + * Build the `libabc.so` target: + + make ABC_USE_PIC=1 libabc.so + ## Bug reporting: Please try to reproduce all the reported bugs and unexpected features using the latest From ac3216cf238dab066b12ddb1eac57c6682e34d2b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 25 Dec 2016 15:58:54 +0700 Subject: [PATCH 011/185] Updates to delay optimization project. --- abclib.dsp | 4 + src/opt/sbd/module.make | 1 + src/opt/sbd/sbdCore.c | 166 +++++++++++++++++++------- src/opt/sbd/sbdInt.h | 11 ++ src/opt/sbd/sbdLut.c | 255 ++++++++++++++++++++++++++++++++++++++++ src/opt/sbd/sbdSat.c | 4 - src/opt/sbd/sbdWin.c | 177 +++++++++++++++++++++++++--- 7 files changed, 555 insertions(+), 63 deletions(-) create mode 100644 src/opt/sbd/sbdLut.c diff --git a/abclib.dsp b/abclib.dsp index 1d08c9508..e5583ddfa 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -2763,6 +2763,10 @@ SOURCE=.\src\opt\sbd\sbdInt.h # End Source File # Begin Source File +SOURCE=.\src\opt\sbd\sbdLut.c +# End Source File +# Begin Source File + SOURCE=.\src\opt\sbd\sbdSat.c # End Source File # Begin Source File diff --git a/src/opt/sbd/module.make b/src/opt/sbd/module.make index d966e577e..0320d3818 100644 --- a/src/opt/sbd/module.make +++ b/src/opt/sbd/module.make @@ -1,5 +1,6 @@ SRC += src/opt/sbd/sbd.c \ src/opt/sbd/sbdCnf.c \ src/opt/sbd/sbdCore.c \ + src/opt/sbd/sbdLut.c \ src/opt/sbd/sbdSat.c \ src/opt/sbd/sbdWin.c diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index b6ec70f9d..563e6e98b 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -54,10 +54,12 @@ struct Sbd_Man_t_ abctime timeTotal; // target node int Pivot; // target node + int DivCutoff; // the place where D-2 divisors begin Vec_Int_t * vTfo; // TFO (excludes node, includes roots) - precomputed Vec_Int_t * vRoots; // TFO root nodes Vec_Int_t * vWinObjs; // TFI + Pivot + sideTFI + TFO (including roots) Vec_Int_t * vObj2Var; // SAT variables for the window (indexes of objects in vWinObjs) + Vec_Int_t * vDivSet; // divisor variables Vec_Int_t * vDivVars; // divisor variables Vec_Int_t * vDivValues; // SAT variables values for the divisor variables Vec_Wec_t * vDivLevels; // divisors collected by levels @@ -200,6 +202,7 @@ Sbd_Man_t * Sbd_ManStart( Gia_Man_t * pGia, Sbd_Par_t * pPars ) p->vRoots = Vec_IntAlloc( 100 ); p->vWinObjs = Vec_IntAlloc( Gia_ManObjNum(pGia) ); p->vObj2Var = Vec_IntStart( Gia_ManObjNum(pGia) ); + p->vDivSet = Vec_IntAlloc( 100 ); p->vDivVars = Vec_IntAlloc( 100 ); p->vDivValues = Vec_IntAlloc( 100 ); p->vDivLevels = Vec_WecAlloc( 100 ); @@ -234,6 +237,7 @@ void Sbd_ManStop( Sbd_Man_t * p ) Vec_IntFree( p->vRoots ); Vec_IntFree( p->vWinObjs ); Vec_IntFree( p->vObj2Var ); + Vec_IntFree( p->vDivSet ); Vec_IntFree( p->vDivVars ); Vec_IntFree( p->vDivValues ); Vec_WecFree( p->vDivLevels ); @@ -318,12 +322,11 @@ void Sbd_ManUpdateOrder( Sbd_Man_t * p, int Pivot ) Vec_WecInit( p->vDivLevels, LevelMax + 1 ); Vec_IntForEachEntry( p->vWinObjs, Node, i ) Vec_WecPush( p->vDivLevels, Vec_IntEntry(p->vLutLevs, Node), Node ); - // sort primary inputs - Vec_IntSort( Vec_WecEntry(p->vDivLevels, 0), 0 ); // reload divisors Vec_IntClear( p->vWinObjs ); Vec_WecForEachLevel( p->vDivLevels, vLevel, i ) { + Vec_IntSort( vLevel, 0 ); Vec_IntForEachEntry( vLevel, Node, k ) { Vec_IntWriteEntry( p->vObj2Var, Node, Vec_IntSize(p->vWinObjs) ); @@ -334,8 +337,26 @@ void Sbd_ManUpdateOrder( Sbd_Man_t * p, int Pivot ) nTimeValidDivs = Vec_IntSize(p->vWinObjs); } assert( nTimeValidDivs > 0 ); - Vec_IntFill( p->vDivValues, Abc_MinInt(63, nTimeValidDivs), 0 ); - //printf( "%d ", Abc_MinInt(63, nTimeValidDivs) ); + Vec_IntClear( p->vDivVars ); + p->DivCutoff = -1; + Vec_IntForEachEntryStartStop( p->vWinObjs, Node, i, Abc_MaxInt(0, nTimeValidDivs-63), nTimeValidDivs ) + { + if ( p->DivCutoff == -1 && Vec_IntEntry(p->vLutLevs, Node) == LevelMax - 2 ) + p->DivCutoff = Vec_IntSize(p->vDivVars); + Vec_IntPush( p->vDivVars, i ); + } + if ( p->DivCutoff == -1 ) + p->DivCutoff = 0; + // verify + assert( Vec_IntSize(p->vDivVars) < 64 ); + Vec_IntForEachEntryStart( p->vDivVars, Node, i, p->DivCutoff ) + assert( Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Node)) == LevelMax - 2 ); + Vec_IntForEachEntryStop( p->vDivVars, Node, i, p->DivCutoff ) + assert( Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Node)) < LevelMax - 2 ); + Vec_IntFill( p->vDivValues, Vec_IntSize(p->vDivVars), 0 ); + //printf( "%d ", Vec_IntSize(p->vDivVars) ); +// printf( "Node %4d : Win = %5d. Divs = %5d. D1 = %5d. D2 = %5d.\n", +// Pivot, Vec_IntSize(p->vWinObjs), Vec_IntSize(p->vDivVars), Vec_IntSize(p->vDivVars)-p->DivCutoff, p->DivCutoff ); } void Sbd_ManWindowSim_rec( Sbd_Man_t * p, int NodeInit ) { @@ -408,6 +429,8 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) Gia_ObjSetTravIdCurrentId(p->pGia, 0); Sbd_ManWindowSim_rec( p, Pivot ); Sbd_ManUpdateOrder( p, Pivot ); + assert( Vec_IntSize(p->vDivVars) == Vec_IntSize(p->vDivValues) ); + assert( Vec_IntSize(p->vDivVars) < Vec_IntSize(p->vWinObjs) ); // simulate node Gia_ManObj(p->pGia, Pivot)->fMark0 = 1; Abc_TtCopy( Sbd_ObjSim1(p, Pivot), Sbd_ObjSim0(p, Pivot), p->pPars->nWords, 1 ); @@ -440,8 +463,8 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) p->timeWin += Abc_Clock() - clk; // propagate controlability to fanins for the TFI nodes starting from the pivot Sbd_ManPropagateControl( p, Pivot ); - assert( Vec_IntSize(p->vDivValues) < 64 ); - return (int)(Vec_IntSize(p->vDivValues) >= 64); + assert( Vec_IntSize(p->vDivValues) <= 64 ); + return (int)(Vec_IntSize(p->vDivValues) > 64); } /**Function************************************************************* @@ -466,8 +489,8 @@ int Sbd_ManCheckConst( Sbd_Man_t * p, int Pivot ) int RetValue, i, iObj, Ind, fFindOnset, nCares[2] = {0}; abctime clk = Abc_Clock(); extern int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, word * pVarSims[], Vec_Int_t * vInds ); - extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots ); - p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots ); + extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); + p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); p->timeCnf += Abc_Clock() - clk; if ( p->pSat == NULL ) { @@ -836,11 +859,11 @@ static inline int Sbd_ManFindCandsSimple( Sbd_Man_t * p, word Cover[64], int nDi { int c0, c1, c2, c3; word Target = Cover[nDivs]; - Vec_IntClear( p->vDivVars ); + Vec_IntClear( p->vDivSet ); for ( c0 = 0; c0 < nDivs; c0++ ) if ( Cover[c0] == Target ) { - Vec_IntPush( p->vDivVars, c0 ); + Vec_IntPush( p->vDivSet, c0 ); return 1; } @@ -848,8 +871,8 @@ static inline int Sbd_ManFindCandsSimple( Sbd_Man_t * p, word Cover[64], int nDi for ( c1 = c0+1; c1 < nDivs; c1++ ) if ( (Cover[c0] | Cover[c1]) == Target ) { - Vec_IntPush( p->vDivVars, c0 ); - Vec_IntPush( p->vDivVars, c1 ); + Vec_IntPush( p->vDivSet, c0 ); + Vec_IntPush( p->vDivSet, c1 ); return 1; } @@ -858,9 +881,9 @@ static inline int Sbd_ManFindCandsSimple( Sbd_Man_t * p, word Cover[64], int nDi for ( c2 = c1+1; c2 < nDivs; c2++ ) if ( (Cover[c0] | Cover[c1] | Cover[c2]) == Target ) { - Vec_IntPush( p->vDivVars, c0 ); - Vec_IntPush( p->vDivVars, c1 ); - Vec_IntPush( p->vDivVars, c2 ); + Vec_IntPush( p->vDivSet, c0 ); + Vec_IntPush( p->vDivSet, c1 ); + Vec_IntPush( p->vDivSet, c2 ); return 1; } @@ -871,10 +894,10 @@ static inline int Sbd_ManFindCandsSimple( Sbd_Man_t * p, word Cover[64], int nDi { if ( (Cover[c0] | Cover[c1] | Cover[c2] | Cover[c3]) == Target ) { - Vec_IntPush( p->vDivVars, c0 ); - Vec_IntPush( p->vDivVars, c1 ); - Vec_IntPush( p->vDivVars, c2 ); - Vec_IntPush( p->vDivVars, c3 ); + Vec_IntPush( p->vDivSet, c0 ); + Vec_IntPush( p->vDivSet, c1 ); + Vec_IntPush( p->vDivSet, c2 ); + Vec_IntPush( p->vDivSet, c3 ); return 1; } } @@ -891,11 +914,11 @@ static inline int Sbd_ManFindCands( Sbd_Man_t * p, word Cover[64], int nDivs ) if ( nDivs < 8 || p->pPars->fCover ) return Sbd_ManFindCandsSimple( p, Cover, nDivs ); - Vec_IntClear( p->vDivVars ); + Vec_IntClear( p->vDivSet ); for ( c0 = 0; c0 < nDivs; c0++ ) if ( Cover[c0] == Target ) { - Vec_IntPush( p->vDivVars, c0 ); + Vec_IntPush( p->vDivSet, c0 ); return 1; } @@ -903,8 +926,8 @@ static inline int Sbd_ManFindCands( Sbd_Man_t * p, word Cover[64], int nDivs ) for ( c1 = c0+1; c1 < nDivs; c1++ ) if ( (Cover[c0] | Cover[c1]) == Target ) { - Vec_IntPush( p->vDivVars, c0 ); - Vec_IntPush( p->vDivVars, c1 ); + Vec_IntPush( p->vDivSet, c0 ); + Vec_IntPush( p->vDivSet, c1 ); return 1; } @@ -923,9 +946,9 @@ static inline int Sbd_ManFindCands( Sbd_Man_t * p, word Cover[64], int nDivs ) for ( c2 = c1+1; c2 < Limits[2]; c2++ ) if ( (Cover[Order[c0]] | Cover[Order[c1]] | Cover[Order[c2]]) == Target ) { - Vec_IntPush( p->vDivVars, Order[c0] ); - Vec_IntPush( p->vDivVars, Order[c1] ); - Vec_IntPush( p->vDivVars, Order[c2] ); + Vec_IntPush( p->vDivSet, Order[c0] ); + Vec_IntPush( p->vDivSet, Order[c1] ); + Vec_IntPush( p->vDivSet, Order[c2] ); return 1; } @@ -936,10 +959,10 @@ static inline int Sbd_ManFindCands( Sbd_Man_t * p, word Cover[64], int nDivs ) { if ( (Cover[Order[c0]] | Cover[Order[c1]] | Cover[Order[c2]] | Cover[Order[c3]]) == Target ) { - Vec_IntPush( p->vDivVars, Order[c0] ); - Vec_IntPush( p->vDivVars, Order[c1] ); - Vec_IntPush( p->vDivVars, Order[c2] ); - Vec_IntPush( p->vDivVars, Order[c3] ); + Vec_IntPush( p->vDivSet, Order[c0] ); + Vec_IntPush( p->vDivSet, Order[c1] ); + Vec_IntPush( p->vDivSet, Order[c2] ); + Vec_IntPush( p->vDivSet, Order[c3] ); return 1; } } @@ -952,10 +975,10 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) int fVerbose = 0; abctime clk, clkSat = 0, clkEnu = 0, clkAll = Abc_Clock(); int nIters, nItersMax = 32; - extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivVars, Vec_Int_t * vValues, Vec_Int_t * vTemp ); + extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivSet, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp ); word MatrS[64] = {0}, MatrC[2][64] = {{0}}, Cubes[2][2][64] = {{{0}}}, Cover[64] = {0}, Cube, CubeNew[2]; - int i, k, n, Index, nCubes[2] = {0}, nRows = 0, nRowsOld; + int i, k, n, Node, Index, nCubes[2] = {0}, nRows = 0, nRowsOld; int nDivs = Vec_IntSize(p->vDivValues); int PivotVar = Vec_IntEntry(p->vObj2Var, Pivot); @@ -969,11 +992,11 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) Sbd_ManPrintObj( p, Pivot ); // collect bit-matrices - for ( i = 0; i < nDivs; i++ ) + Vec_IntForEachEntry( p->vDivVars, Node, i ) { - MatrS[63-i] = *Sbd_ObjSim0( p, Vec_IntEntry(p->vWinObjs, i) ); - MatrC[0][63-i] = *Sbd_ObjSim2( p, Vec_IntEntry(p->vWinObjs, i) ); - MatrC[1][63-i] = *Sbd_ObjSim3( p, Vec_IntEntry(p->vWinObjs, i) ); + MatrS[63-i] = *Sbd_ObjSim0( p, Vec_IntEntry(p->vWinObjs, Node) ); + MatrC[0][63-i] = *Sbd_ObjSim2( p, Vec_IntEntry(p->vWinObjs, Node) ); + MatrC[1][63-i] = *Sbd_ObjSim3( p, Vec_IntEntry(p->vWinObjs, Node) ); } MatrS[63-i] = *Sbd_ObjSim0( p, Pivot ); MatrC[0][63-i] = *Sbd_ObjSim2( p, Pivot ); @@ -1067,10 +1090,10 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) if ( p->pPars->fVerbose ) printf( "Candidate support: " ), - Vec_IntPrint( p->vDivVars ); + Vec_IntPrint( p->vDivSet ); clk = Abc_Clock(); - *pTruth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivVars, p->vDivValues, p->vLits ); + *pTruth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); clkSat += Abc_Clock() - clk; if ( *pTruth == SBD_SAT_UNDEC ) @@ -1103,7 +1126,7 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) if ( p->pPars->fVerbose ) { printf( "Node %d: UNSAT.\n", Pivot ); - Extra_PrintBinary( stdout, (unsigned *)pTruth, 1 << Vec_IntSize(p->vDivVars) ), printf( "\n" ); + Extra_PrintBinary( stdout, (unsigned *)pTruth, 1 << Vec_IntSize(p->vDivSet) ), printf( "\n" ); } RetValue = 1; break; @@ -1118,6 +1141,13 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) return RetValue; } +int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, + int nLuts, int nSels, int nVarsDivs[SBD_LUTS_MAX], + int pVarsDivs[SBD_LUTS_MAX][SBD_SIZE_MAX], word Truths[SBD_LUTS_MAX] ) +{ + return 0; +} + /**Function************************************************************* Synopsis [Computes delay-oriented k-feasible cut at the node.] @@ -1233,7 +1263,7 @@ int Sbd_ManMergeCuts( Sbd_Man_t * p, int Node ) Vec_IntWriteEntry( p->vLutLevs, Node, LevCur ); assert( pCutRes[0] <= p->pPars->nLutSize ); memcpy( Sbd_ObjCut(p, Node), pCutRes, sizeof(int) * (pCutRes[0] + 1) ); - //printf( "Setting node %d with delay %d.\n", Node, LevCur ); +//printf( "Setting node %d with delay %d.\n", Node, LevCur ); return LevCur == 1; // LevCur == Abc_MaxInt(Level0, Level1); } int Sbd_ManDelay( Sbd_Man_t * p ) @@ -1306,7 +1336,7 @@ int Sbd_ManImplement( Sbd_Man_t * p, int Pivot, word Truth ) int iNewLev; // collect leaf literals Vec_IntClear( p->vLits ); - Vec_IntForEachEntry( p->vDivVars, Node, i ) + Vec_IntForEachEntry( p->vDivSet, Node, i ) { Node = Vec_IntEntry( p->vWinObjs, Node ); if ( Vec_IntEntry(p->vMirrors, Node) >= 0 ) @@ -1429,20 +1459,68 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) ***********************************************************************/ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) { +// extern void Sbd_ManSolveSelect( Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots ); + int RetValue; word Truth = 0; if ( Sbd_ManMergeCuts( p, Pivot ) ) return; - //if ( Pivot != 344 ) - // continue; + +// if ( Pivot != 13 ) +// return; + if ( p->pPars->fVerbose ) printf( "\nLooking at node %d\n", Pivot ); if ( Sbd_ManWindow( p, Pivot ) ) return; + +// Sbd_ManSolveSelect( p->pGia, p->vMirrors, Pivot, p->vDivVars, p->vDivValues, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots ); + RetValue = Sbd_ManCheckConst( p, Pivot ); if ( RetValue >= 0 ) + { Vec_IntWriteEntry( p->vMirrors, Pivot, RetValue ); + //printf( " --> Pivot %4d. Constant %d.\n", Pivot, RetValue ); + } else if ( Sbd_ManExplore( p, Pivot, &Truth ) ) + { Sbd_ManImplement( p, Pivot, Truth ); + //printf( " --> Pivot %4d. Supp %d.\n", Pivot, Vec_IntSize(p->vDivSet) ); + } +/* + else + { + extern int Sbd_ProblemSolve( + Gia_Man_t * p, Vec_Int_t * vMirrors, + int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, + Vec_Int_t * vTfo, Vec_Int_t * vRoots, + Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0, word Truths[SBD_LUTS_MAX] + ); + + Sbd_Str_t Strs[2] = { + {1, 4, {0, 1, 2, 7}}, + {1, 4, {3, 4, 5, 6}} + }; + + word Truths[SBD_LUTS_MAX]; + + Vec_Int_t * vDivSet = Vec_IntAlloc( 8 ); + + int i, RetValue; + + for ( i = 0; i < 7; i++ ) + Vec_IntPush( vDivSet, i+1 ); + + RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, + Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, + vDivSet, 2, Strs, Truths ); + if ( RetValue ) + { + printf( "Solving succeded.\n" ); + //Sbd_ManImplement2( p, Pivot, Truth, nLuts, nSels, nVarsDivs, pVarsDivs, Truths ); + } + Vec_IntFree( vDivSet ); + } +*/ } Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) { @@ -1488,8 +1566,10 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) else { Gia_ManForEachAndId( pGia, Pivot ) + { if ( Pivot < nNodesOld ) Sbd_NtkPerformOne( p, Pivot ); + } } printf( "Found %d constants and %d replacements with delay %d. ", p->nConsts, p->nChanges, Sbd_ManDelay(p) ); p->timeTotal = Abc_Clock() - p->timeTotal; diff --git a/src/opt/sbd/sbdInt.h b/src/opt/sbd/sbdInt.h index 4c553fb45..3646c6b96 100644 --- a/src/opt/sbd/sbdInt.h +++ b/src/opt/sbd/sbdInt.h @@ -52,10 +52,21 @@ ABC_NAMESPACE_HEADER_START #define SBD_SAT_UNDEC 0x1234567812345678 #define SBD_SAT_SAT 0x8765432187654321 +#define SBD_LUTS_MAX 2 +#define SBD_SIZE_MAX 4 +#define SBD_DIV_MAX 7 + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// //////////////////////////////////////////////////////////////////////// +typedef struct Sbd_Str_t_ Sbd_Str_t; +struct Sbd_Str_t_ +{ + int fLut; // LUT or SEL + int nVarIns; // input count + int VarIns[SBD_DIV_MAX]; // input vars +}; //////////////////////////////////////////////////////////////////////// /// MACRO DEFINITIONS /// diff --git a/src/opt/sbd/sbdLut.c b/src/opt/sbd/sbdLut.c new file mode 100644 index 000000000..42bb09555 --- /dev/null +++ b/src/opt/sbd/sbdLut.c @@ -0,0 +1,255 @@ +/**CFile**************************************************************** + + FileName [sbdLut.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [SAT-based optimization using internal don't-cares.] + + Synopsis [CNF computation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: sbdLut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sbdInt.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +// count the number of parameter variables in the structure +int Sbd_ProblemCountParams( int nStrs, Sbd_Str_t * pStr0 ) +{ + Sbd_Str_t * pStr; int nPars = 0; + for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++ ) + nPars += (pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns); + return nPars; +} +// add clauses for the structure +void Sbd_ProblemAddClauses( sat_solver * pSat, int nVars, int nStrs, int * pVars, Sbd_Str_t * pStr0 ) +{ + // variable order: inputs, structure outputs, parameters + Sbd_Str_t * pStr; + int VarOut = nVars; + int VarPar = nVars + nStrs; + int m, k, n, status, pLits[SBD_SIZE_MAX+2]; + for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++, VarOut++ ) + { + if ( pStr->fLut ) + { + int nMints = 1 << pStr->nVarIns; + assert( pStr->nVarIns <= 6 ); + for ( m = 0; m < nMints; m++, VarPar++ ) + { + for ( k = 0; k < pStr->nVarIns; k++ ) + pLits[k] = Abc_Var2Lit( pVars[pStr->VarIns[k]], (m >> k) & 1 ); + for ( n = 0; n < 2; n++ ) + { + pLits[pStr->nVarIns] = Abc_Var2Lit( pVars[VarPar], n ); + pLits[pStr->nVarIns+1] = Abc_Var2Lit( pVars[VarOut], !n ); + status = sat_solver_addclause( pSat, pLits, pLits + pStr->nVarIns + 2 ); + assert( status ); + } + } + } + else + { + for ( k = 0; k < pStr->nVarIns; k++, VarPar++ ) + { + for ( n = 0; n < 2; n++ ) + { + pLits[0] = Abc_Var2Lit( pVars[VarPar], 1 ); + pLits[1] = Abc_Var2Lit( pVars[VarOut], n ); + pLits[2] = Abc_Var2Lit( pVars[pStr->VarIns[k]], !n ); + status = sat_solver_addclause( pSat, pLits, pLits + 3 ); + assert( status ); + } + } + } + } +} +void Sbd_ProblemAddClausesInit( sat_solver * pSat, int nVars, int nStrs, int * pVars, Sbd_Str_t * pStr0 ) +{ + Sbd_Str_t * pStr; + int VarPar = nVars + nStrs; + int m, m2, pLits[2], status; + // make sure selector parameters are mutually exclusive + for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++, VarPar = pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns ) + { + if ( pStr->fLut ) + continue; + for ( m = 0; m < pStr->nVarIns; m++ ) + for ( m2 = m+1; m2 < pStr->nVarIns; m2++ ) + { + pLits[0] = Abc_Var2Lit( pVars[VarPar + m], 1 ); + pLits[1] = Abc_Var2Lit( pVars[VarPar + m2], 1 ); + status = sat_solver_addclause( pSat, pLits, pLits + 2 ); + assert( status ); + } + } +} +void Sbd_ProblemPrintSolution( int nStrs, Sbd_Str_t * pStr0, Vec_Int_t * vLits ) +{ + Sbd_Str_t * pStr; + int m, nIters, iLit = 0; + printf( "Solution found:\n" ); + for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++ ) + { + nIters = pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns; + printf( "%s%d : ", pStr->fLut ? "LUT":"SEL", pStr-pStr0 ); + for ( m = 0; m < nIters; m++ ) + printf( "%d", Abc_LitIsCompl(Vec_IntEntry(vLits, iLit++)) ); + printf( "\n" ); + } + assert( iLit == Vec_IntSize(vLits) ); +} +void Sbd_ProblemCollectSolution( int nStrs, Sbd_Str_t * pStr0, Vec_Int_t * vLits, word Truths[SBD_LUTS_MAX] ) +{ +} + +/**Function************************************************************* + + Synopsis [Solves QBF problem for the given window.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, + int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, + Vec_Int_t * vTfo, Vec_Int_t * vRoots, + Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0, word Truths[SBD_LUTS_MAX] ) // divisors, structures +{ + extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); + + Vec_Int_t * vLits = Vec_IntAlloc( 100 ); + sat_solver * pSatCec = Sbd_ManSatSolver( NULL, p, vMirrors, Pivot, vWinObjs, vObj2Var, vTfo, vRoots, 1 ); + sat_solver * pSatQbf = sat_solver_new(); + + int nVars = Vec_IntSize( vDivSet ); + int nPars = Sbd_ProblemCountParams( nStrs, pStr0 ); + + int VarCecOut = Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots); + int VarCecPar = VarCecOut + 1; + int VarCecFree = VarCecPar + nPars; + + int VarQbfPar = 0; + int VarQbfFree = nPars; + + int pVarsCec[256]; + int pVarsQbf[256]; + int i, iVar, iLit; + int RetValue = 0; + + assert( Vec_IntSize(vDivSet) <= SBD_SIZE_MAX ); + assert( nVars + nStrs + nPars <= 256 ); + + // collect CEC variables + Vec_IntForEachEntry( vDivSet, iVar, i ) + pVarsCec[i] = iVar; + pVarsCec[nVars] = VarCecOut; + for ( i = 1; i < nStrs; i++ ) + pVarsCec[nVars + i] = VarCecFree++; + for ( i = 0; i < nPars; i++ ) + pVarsCec[nVars + nStrs + i] = VarCecPar + i; + + // collect QBF variables + for ( i = 0; i < nVars + nStrs; i++ ) + pVarsQbf[i] = -1; + for ( i = 0; i < nPars; i++ ) + pVarsQbf[nVars + nStrs + i] = VarQbfPar + i; + + // add clauses to the CEC problem + Sbd_ProblemAddClauses( pSatCec, nVars, nStrs, pVarsCec, pStr0 ); + + // create QBF solver + sat_solver_setnvars( pSatQbf, 1000 ); + Sbd_ProblemAddClausesInit( pSatQbf, nVars, nStrs, pVarsQbf, pStr0 ); + + // assume all parameter variables are 0 + Vec_IntClear( vLits ); + for ( i = 0; i < nPars; i++ ) + Vec_IntPush( vLits, Abc_Var2Lit(VarCecPar + i, 1) ); + while ( 1 ) + { + // check if these parameters solve the problem + int status = sat_solver_solve( pSatCec, Vec_IntArray(vLits), Vec_IntLimit(vLits), 0, 0, 0, 0 ); + if ( status == l_False ) // solution found + break; + assert( status == l_True ); + Vec_IntClear( vLits ); + // create new QBF variables + for ( i = 0; i < nVars + nStrs; i++ ) + pVarsQbf[i] = VarQbfFree++; + // set their values + Vec_IntForEachEntry( vDivSet, iVar, i ) + { + iLit = Abc_Var2Lit( pVarsQbf[i], sat_solver_var_value(pSatCec, iVar) ); + status = sat_solver_addclause( pSatQbf, &iLit, &iLit + 1 ); + assert( status ); + } + iLit = Abc_Var2Lit( pVarsQbf[nVars], sat_solver_var_value(pSatCec, VarCecOut) ); + status = sat_solver_addclause( pSatQbf, &iLit, &iLit + 1 ); + assert( status ); + // add clauses to the QBF problem + Sbd_ProblemAddClauses( pSatQbf, nVars, nStrs, pVarsQbf, pStr0 ); + // check if solution still exists + status = sat_solver_solve( pSatQbf, NULL, NULL, 0, 0, 0, 0 ); + if ( status == l_False ) // solution does not exist + break; + assert( status == l_True ); + // find the new values of parameters + assert( Vec_IntSize(vLits) == 0 ); + for ( i = 0; i < nPars; i++ ) + Vec_IntPush( vLits, Abc_Var2Lit(VarCecPar + i, sat_solver_var_value(pSatQbf, VarQbfPar + i)) ); + } + if ( Vec_IntSize(vLits) > 0 ) + { + Sbd_ProblemPrintSolution( nStrs, pStr0, vLits ); + Sbd_ProblemCollectSolution( nStrs, pStr0, vLits, Truths ); + RetValue = 1; + } + else + printf( "Solution does not exist.\n" ); + + sat_solver_delete( pSatCec ); + sat_solver_delete( pSatQbf ); + Vec_IntFree( vLits ); + return RetValue; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/opt/sbd/sbdSat.c b/src/opt/sbd/sbdSat.c index ae8656278..f0de4dbf0 100644 --- a/src/opt/sbd/sbdSat.c +++ b/src/opt/sbd/sbdSat.c @@ -37,10 +37,6 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -#define SBD_LUTS_MAX 2 -#define SBD_SIZE_MAX 4 -#define SBD_DIV_MAX 16 - // new AIG manager typedef struct Sbd_Pro_t_ Sbd_Pro_t; struct Sbd_Pro_t_ diff --git a/src/opt/sbd/sbdWin.c b/src/opt/sbd/sbdWin.c index d722f4568..fc79caa71 100644 --- a/src/opt/sbd/sbdWin.c +++ b/src/opt/sbd/sbdWin.c @@ -39,19 +39,26 @@ ABC_NAMESPACE_IMPL_START a DFS ordered array of objects (vWinObjs) whose indexed in the array (which will be used as SAT variables) are given in array vObj2Var. The TFO nodes are listed as the last ones in vWinObjs. The root nodes - are labeled with Abc_LitIsCompl() in vTfo and also given in vRoots.] + are labeled with Abc_LitIsCompl() in vTfo and also given in vRoots. + If fQbf is 1, returns the instance meant for QBF solving. It is using + the last variable (LastVar) as the placeholder for the second copy + of the pivot node.] SideEffects [] SeeAlso [] ***********************************************************************/ -sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots ) +sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, + int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, + Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ) { Gia_Obj_t * pObj; + int nAddVars = 64; int i, iLit = 1, iObj, Fan0, Fan1, Lit0m, Lit1m, Node, fCompl0, fCompl1, RetValue; int TfoStart = Vec_IntSize(vWinObjs) - Vec_IntSize(vTfo); int PivotVar = Vec_IntEntry(vObj2Var, Pivot); + int LastVar = Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots); //Vec_IntPrint( vWinObjs ); //Vec_IntPrint( vTfo ); //Vec_IntPrint( vRoots ); @@ -60,7 +67,7 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi pSat = sat_solver_new(); else sat_solver_restart( pSat ); - sat_solver_setnvars( pSat, Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots) + 32 ); + sat_solver_setnvars( pSat, Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots) + nAddVars ); // create constant 0 clause sat_solver_addclause( pSat, &iLit, &iLit + 1 ); // add clauses for all nodes @@ -100,8 +107,13 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi Fan1 = Vec_IntEntry( vObj2Var, Fan1 ); Fan0 = Fan0 < TfoStart ? Fan0 : Fan0 + Vec_IntSize(vTfo); Fan1 = Fan1 < TfoStart ? Fan1 : Fan1 + Vec_IntSize(vTfo); - fCompl0 = Gia_ObjFaninC0(pObj) ^ (Fan0 == PivotVar) ^ (Lit0m >= 0 && Abc_LitIsCompl(Lit0m)); - fCompl1 = Gia_ObjFaninC1(pObj) ^ (Fan1 == PivotVar) ^ (Lit1m >= 0 && Abc_LitIsCompl(Lit1m)); + if ( fQbf ) + { + Fan0 = Fan0 == PivotVar ? LastVar : Fan0; + Fan1 = Fan1 == PivotVar ? LastVar : Fan1; + } + fCompl0 = Gia_ObjFaninC0(pObj) ^ (!fQbf && Fan0 == PivotVar) ^ (Lit0m >= 0 && Abc_LitIsCompl(Lit0m)); + fCompl1 = Gia_ObjFaninC1(pObj) ^ (!fQbf && Fan1 == PivotVar) ^ (Lit1m >= 0 && Abc_LitIsCompl(Lit1m)); if ( Gia_ObjIsXor(pObj) ) sat_solver_add_xor( pSat, Node, Fan0, Fan1, fCompl0 ^ fCompl1 ); else @@ -127,7 +139,7 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi sat_solver_delete( pSat ); return NULL; } - assert( sat_solver_nvars(pSat) == nVars + 32 ); + assert( sat_solver_nvars(pSat) == nVars + nAddVars ); } // finalize RetValue = sat_solver_simplify( pSat ); @@ -143,7 +155,7 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi Synopsis [Solves one SAT problem.] - Description [Computes node function for PivotVar with fanins in vDivVars + Description [Computes node function for PivotVar with fanins in vDivSet using don't-care represented in the SAT solver. Uses array vValues to return the values of the first Vec_IntSize(vValues) SAT variables in case the implementation of the node with the given fanins does not exist.] @@ -153,12 +165,13 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi SeeAlso [] ***********************************************************************/ -word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivVars, Vec_Int_t * vValues, Vec_Int_t * vTemp ) +word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivSet, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp ) { int nBTLimit = 0; word uCube, uTruth = 0; int status, i, iVar, nFinal, * pFinal, pLits[2], nIter = 0; assert( FreeVar < sat_solver_nvars(pSat) ); + assert( Vec_IntSize(vDivVars) == Vec_IntSize(vDivValues) ); pLits[0] = Abc_Var2Lit( PivotVar, 0 ); // F = 1 pLits[1] = Abc_Var2Lit( FreeVar, 0 ); // iNewLit while ( 1 ) @@ -171,12 +184,12 @@ word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDi return uTruth; assert( status == l_True ); // remember variable values - for ( i = 0; i < Vec_IntSize(vValues); i++ ) - Vec_IntWriteEntry( vValues, i, 2*sat_solver_var_value(pSat, i) ); + Vec_IntForEachEntry( vDivVars, iVar, i ) + Vec_IntWriteEntry( vDivValues, i, 2*sat_solver_var_value(pSat, iVar) ); // collect divisor literals Vec_IntClear( vTemp ); Vec_IntPush( vTemp, Abc_LitNot(pLits[0]) ); // F = 0 - Vec_IntForEachEntry( vDivVars, iVar, i ) + Vec_IntForEachEntry( vDivSet, iVar, i ) Vec_IntPush( vTemp, sat_solver_var_literal(pSat, iVar) ); // check against offset status = sat_solver_solve( pSat, Vec_IntArray(vTemp), Vec_IntArray(vTemp) + Vec_IntSize(vTemp), nBTLimit, 0, 0, 0 ); @@ -195,7 +208,7 @@ word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDi if ( pFinal[i] == pLits[0] ) continue; Vec_IntPush( vTemp, pFinal[i] ); - iVar = Vec_IntFind( vDivVars, Abc_Lit2Var(pFinal[i]) ); assert( iVar >= 0 ); + iVar = Vec_IntFind( vDivSet, Abc_Lit2Var(pFinal[i]) ); assert( iVar >= 0 ); uCube &= Abc_LitIsCompl(pFinal[i]) ? s_Truths6[iVar] : ~s_Truths6[iVar]; } uTruth |= uCube; @@ -205,11 +218,11 @@ word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDi } assert( status == l_True ); // store the counter-example - for ( i = 0; i < Vec_IntSize(vValues); i++ ) - Vec_IntAddToEntry( vValues, i, sat_solver_var_value(pSat, i) ); + Vec_IntForEachEntry( vDivVars, iVar, i ) + Vec_IntAddToEntry( vDivValues, i, sat_solver_var_value(pSat, iVar) ); - for ( i = 0; i < Vec_IntSize(vValues); i++ ) - Vec_IntAddToEntry( vValues, i, 0xC ); + for ( i = 0; i < Vec_IntSize(vDivValues); i++ ) + Vec_IntAddToEntry( vDivValues, i, 0xC ); /* // reduce the counter example for ( n = 0; n < 2; n++ ) @@ -230,6 +243,138 @@ word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDi return SBD_SAT_SAT; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sbd_ManSolve2( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp, Vec_Int_t * vSop ) +{ + int nBTLimit = 0; + int status, i, iVar, nFinal, * pFinal, pLits[2], nIter = 0; + assert( FreeVar < sat_solver_nvars(pSat) ); + assert( Vec_IntSize(vDivVars) == Vec_IntSize(vDivValues) ); + pLits[0] = Abc_Var2Lit( PivotVar, 0 ); // F = 1 + pLits[1] = Abc_Var2Lit( FreeVar, 0 ); // iNewLit + Vec_IntClear( vSop ); + while ( 1 ) + { + // find onset minterm + status = sat_solver_solve( pSat, pLits, pLits + 2, nBTLimit, 0, 0, 0 ); + if ( status == l_Undef ) + return 0; + if ( status == l_False ) + return 1; + assert( status == l_True ); + // remember variable values + //for ( i = 0; i < Vec_IntSize(vValues); i++ ) + // Vec_IntWriteEntry( vValues, i, 2*sat_solver_var_value(pSat, i) ); + // collect divisor literals + Vec_IntClear( vTemp ); + Vec_IntPush( vTemp, Abc_LitNot(pLits[0]) ); // F = 0 + //Vec_IntForEachEntry( vDivSet, iVar, i ) + Vec_IntForEachEntry( vDivVars, iVar, i ) + Vec_IntPush( vTemp, sat_solver_var_literal(pSat, iVar) ); + // check against offset + status = sat_solver_solve( pSat, Vec_IntArray(vTemp), Vec_IntArray(vTemp) + Vec_IntSize(vTemp), nBTLimit, 0, 0, 0 ); + if ( status == l_Undef ) + return 0; + if ( status == l_True ) + break; + assert( status == l_False ); + // compute cube and add clause + nFinal = sat_solver_final( pSat, &pFinal ); + Vec_IntClear( vTemp ); + Vec_IntPush( vTemp, Abc_LitNot(pLits[1]) ); // NOT(iNewLit) + for ( i = 0; i < nFinal; i++ ) + { + if ( pFinal[i] == pLits[0] ) + continue; + Vec_IntPush( vTemp, pFinal[i] ); + iVar = Vec_IntFind( vDivVars, Abc_Lit2Var(pFinal[i]) ); assert( iVar >= 0 ); + //uCube &= Abc_LitIsCompl(pFinal[i]) ? s_Truths6[iVar] : ~s_Truths6[iVar]; + Vec_IntPush( vSop, Abc_Var2Lit( iVar, !Abc_LitIsCompl(pFinal[i]) ) ); + } + //uTruth |= uCube; + Vec_IntPush( vSop, -1 ); + status = sat_solver_addclause( pSat, Vec_IntArray(vTemp), Vec_IntArray(vTemp) + Vec_IntSize(vTemp) ); + assert( status ); + nIter++; + } + assert( status == l_True ); + // store the counter-example + //for ( i = 0; i < Vec_IntSize(vValues); i++ ) + // Vec_IntAddToEntry( vValues, i, sat_solver_var_value(pSat, i) ); + return 0; +} + +word Sbd_ManSolverSupp( Vec_Int_t * vSop, int * pInds, int * pnVars ) +{ + word Supp = 0; + int i, Entry, nVars = 0; + Vec_IntForEachEntry( vSop, Entry, i ) + { + if ( Entry == -1 ) + continue; + assert( Abc_Lit2Var(Entry) < 64 ); + if ( (Supp >> Abc_Lit2Var(Entry)) & 1 ) + continue; + pInds[Abc_Lit2Var(Entry)] = nVars++; + Supp |= (word)1 << Abc_Lit2Var(Entry); + } + *pnVars = nVars; + return Supp; +} +void Sbd_ManSolverPrint( Vec_Int_t * vSop ) +{ + int v, i, Entry, nVars, pInds[64]; + word Supp = Sbd_ManSolverSupp( vSop, pInds, &nVars ); + char Cube[65] = {'\0'}; + assert( Cube[nVars] == '\0' ); + for ( v = 0; v < nVars; v++ ) + Cube[v] = '-'; + Vec_IntForEachEntry( vSop, Entry, i ) + { + if ( Entry == -1 ) + { + printf( "%s\n", Cube ); + for ( v = 0; v < nVars; v++ ) + Cube[v] = '-'; + continue; + } + Cube[pInds[Abc_Lit2Var(Entry)]] = '1' - (char)Abc_LitIsCompl(Entry); + } +} +void Sbd_ManSolveSelect( Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots ) +{ + Vec_Int_t * vSop = Vec_IntAlloc( 100 ); + Vec_Int_t * vTemp = Vec_IntAlloc( 100 ); + sat_solver * pSat = Sbd_ManSatSolver( NULL, p, vMirrors, Pivot, vWinObjs, vObj2Var, vTfo, vRoots, 0 ); + int PivotVar = Vec_IntEntry(vObj2Var, Pivot); + int FreeVar = Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots); + int Status = Sbd_ManSolve2( pSat, PivotVar, FreeVar, vDivVars, vDivValues, vTemp, vSop ); + printf( "Pivot = %4d. Divs = %4d. ", Pivot, Vec_IntSize(vDivVars) ); + if ( Status == 0 ) + printf( "UNSAT.\n" ); + else + { + int nVars, pInds[64]; + word Supp = Sbd_ManSolverSupp( vSop, pInds, &nVars ); + //Sbd_ManSolverPrint( vSop ); + printf( "SAT with %d vars and %d cubes.\n", nVars, Vec_IntCountEntry(vSop, -1) ); + } + Vec_IntFree( vTemp ); + Vec_IntFree( vSop ); + sat_solver_delete( pSat ); +} + + /**Function************************************************************* Synopsis [Returns a bunch of positive/negative random care minterms.] From 398c4ec92c4e25fa588a6b3bcbd016df91e57771 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 27 Dec 2016 18:08:39 +0700 Subject: [PATCH 012/185] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 158 +++++++++++++++++++++++++++++++++++------- src/opt/sbd/sbdInt.h | 1 + src/opt/sbd/sbdLut.c | 108 ++++++++++++++++++++++------- src/opt/sbd/sbdWin.c | 35 ++++++++++ 4 files changed, 254 insertions(+), 48 deletions(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 563e6e98b..5c5fe35ab 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -777,15 +777,15 @@ void Sbd_ManPrintObj( Sbd_Man_t * p, int Pivot ) } } -void Sbd_ManMatrPrint( word Cover[64], int nCol, int nRows ) +void Sbd_ManMatrPrint( Sbd_Man_t * p, word Cover[], int nCol, int nRows ) { int i, k; for ( i = 0; i <= nCol; i++ ) { printf( "%2d : ", i ); + printf( "%d ", i == nCol ? Vec_IntEntry(p->vLutLevs, p->Pivot) : Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Vec_IntEntry(p->vDivVars, i))) ); for ( k = 0; k < nRows; k++ ) - for ( k = 0; k < nRows; k++ ) - printf( "%d", (int)((Cover[i] >> k) & 1) ); + printf( "%d", (int)((Cover[i] >> k) & 1) ); printf( "\n"); } printf( "\n"); @@ -801,18 +801,18 @@ static inline void Sbd_ManCoverReverseOrder( word Cover[64] ) } } -static inline int Sbd_ManAddCube1( word Cover[64], int nRows, word Cube ) +static inline int Sbd_ManAddCube1( int nRowLimit, word Cover[], int nRows, word Cube ) { int n, m; if ( 0 ) { printf( "Adding cube: " ); - for ( n = 0; n < 64; n++ ) + for ( n = 0; n < nRowLimit; n++ ) printf( "%d", (int)((Cube >> n) & 1) ); printf( "\n" ); } // do not add contained Cube - assert( nRows <= 64 ); + assert( nRows <= nRowLimit ); for ( n = 0; n < nRows; n++ ) if ( (Cover[n] & Cube) == Cover[n] ) // Cube is contained return nRows; @@ -820,7 +820,7 @@ static inline int Sbd_ManAddCube1( word Cover[64], int nRows, word Cube ) for ( n = m = 0; n < nRows; n++ ) if ( (Cover[n] & Cube) != Cube ) // Cover[n] is not contained Cover[m++] = Cover[n]; - if ( m < 64 ) + if ( m < nRowLimit ) Cover[m++] = Cube; for ( n = m; n < nRows; n++ ) Cover[n] = 0; @@ -855,7 +855,7 @@ static inline int Sbd_ManAddCube2( word Cover[2][64], int nRows, word Cube[2] ) return nRows; } -static inline int Sbd_ManFindCandsSimple( Sbd_Man_t * p, word Cover[64], int nDivs ) +static inline int Sbd_ManFindCandsSimple( Sbd_Man_t * p, word Cover[], int nDivs ) { int c0, c1, c2, c3; word Target = Cover[nDivs]; @@ -1052,7 +1052,7 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) { Cube = (Cubes[0][1][i] & Cubes[1][0][k]) | (Cubes[0][0][i] & Cubes[1][1][k]); assert( Cube ); - nRows = Sbd_ManAddCube1( Cover, nRows, Cube ); + nRows = Sbd_ManAddCube1( 64, Cover, nRows, Cube ); } Sbd_ManCoverReverseOrder( Cover ); @@ -1072,7 +1072,7 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) for ( nIters = 0; nIters < nItersMax && nRows < 64; nIters++ ) { if ( p->pPars->fVerbose ) - Sbd_ManMatrPrint( Cover, nDivs, nRows ); + Sbd_ManMatrPrint( p, Cover, nDivs, nRows ); clk = Abc_Clock(); if ( !Sbd_ManFindCands( p, Cover, nDivs ) ) @@ -1141,10 +1141,123 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) return RetValue; } -int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, - int nLuts, int nSels, int nVarsDivs[SBD_LUTS_MAX], - int pVarsDivs[SBD_LUTS_MAX][SBD_SIZE_MAX], word Truths[SBD_LUTS_MAX] ) +int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) { + extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); + extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); + abctime clk = Abc_Clock(); + word Onset[64] = {0}, Offset[64] = {0}, Cube; + word CoverRows[256] = {0}, CoverCols[64] = {{0}}; + int nIters, nItersMax = 32; + int i, k, nRows = 0; + + int PivotVar = Vec_IntEntry(p->vObj2Var, Pivot); + int FreeVar = Vec_IntSize(p->vWinObjs) + Vec_IntSize(p->vTfo) + Vec_IntSize(p->vRoots); + int nDivs = Vec_IntSize( p->vDivVars ); + int nConsts = 4; + int RetValue; + + if ( p->pSat ) + sat_solver_delete( p->pSat ); + p->pSat = NULL; + + p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); + p->timeCnf += Abc_Clock() - clk; + + assert( nConsts <= 8 ); + RetValue = Sbd_ManCollectConstantsNew( p->pSat, p->vDivVars, nConsts, PivotVar, Onset, Offset ); + if ( RetValue >= 0 ) + { + if ( p->pPars->fVerbose ) + printf( "Found stuck-at-%d node %d.\n", RetValue, Pivot ); + Vec_IntWriteEntry( p->vLutLevs, Pivot, 0 ); + p->nConsts++; + return RetValue; + } + + // create rows of the table + nRows = 0; + for ( i = 0; i < nConsts; i++ ) + for ( k = 0; k < nConsts; k++ ) + { + Cube = Onset[i] ^ Offset[k]; + assert( Cube ); + nRows = Sbd_ManAddCube1( 256, CoverRows, nRows, Cube ); + } + assert( nRows <= 64 ); + + // create columns of the table + for ( i = 0; i < nRows; i++ ) + for ( k = 0; k <= nDivs; k++ ) + if ( (CoverRows[i] >> k) & 1 ) + Abc_TtXorBit(&CoverCols[k], i); + + // solve the covering problem + for ( nIters = 0; nIters < nItersMax && nRows < 64; nIters++ ) + { + if ( p->pPars->fVerbose ) + Sbd_ManMatrPrint( p, CoverCols, nDivs, nRows ); + + clk = Abc_Clock(); + if ( !Sbd_ManFindCands( p, CoverCols, nDivs ) ) + { + if ( p->pPars->fVerbose ) + printf( "Cannot find a feasible cover.\n" ); + //clkEnu += Abc_Clock() - clk; + //clkAll = Abc_Clock() - clkAll - clkSat - clkEnu; + //p->timeSat += clkSat; + //p->timeCov += clkAll; + //p->timeEnu += clkEnu; + return 0; + } + //clkEnu += Abc_Clock() - clk; + + if ( p->pPars->fVerbose ) + printf( "Candidate support: " ), + Vec_IntPrint( p->vDivSet ); + + clk = Abc_Clock(); + *pTruth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); + //clkSat += Abc_Clock() - clk; + + if ( *pTruth == SBD_SAT_UNDEC ) + printf( "Node %d: Undecided.\n", Pivot ); + else if ( *pTruth == SBD_SAT_SAT ) + { + if ( p->pPars->fVerbose ) + { + int i; + printf( "Node %d: SAT.\n", Pivot ); + for ( i = 0; i < nDivs; i++ ) + printf( "%d", Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Vec_IntEntry(p->vDivVars, i))) ); + printf( "\n" ); + for ( i = 0; i < nDivs; i++ ) + printf( "%d", i % 10 ); + printf( "\n" ); + for ( i = 0; i < nDivs; i++ ) + printf( "%c", (Vec_IntEntry(p->vDivValues, i) & 0x4) ? '0' + (Vec_IntEntry(p->vDivValues, i) & 1) : 'x' ); + printf( "\n" ); + for ( i = 0; i < nDivs; i++ ) + printf( "%c", (Vec_IntEntry(p->vDivValues, i) & 0x8) ? '0' + ((Vec_IntEntry(p->vDivValues, i) >> 1) & 1) : 'x' ); + printf( "\n" ); + } + // add row to the covering table + for ( i = 0; i < nDivs; i++ ) + if ( Vec_IntEntry(p->vDivValues, i) == 0xE || Vec_IntEntry(p->vDivValues, i) == 0xD ) + CoverCols[i] |= ((word)1 << nRows); + CoverCols[nDivs] |= ((word)1 << nRows); + nRows++; + } + else + { + if ( p->pPars->fVerbose ) + { + printf( "Node %d: UNSAT. ", Pivot ); + Extra_PrintBinary( stdout, (unsigned *)pTruth, 1 << Vec_IntSize(p->vDivSet) ), printf( "\n" ); + } + return 1; + } + } return 0; } @@ -1465,7 +1578,7 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) if ( Sbd_ManMergeCuts( p, Pivot ) ) return; -// if ( Pivot != 13 ) +// if ( Pivot != 70 ) // return; if ( p->pPars->fVerbose ) @@ -1481,7 +1594,7 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) Vec_IntWriteEntry( p->vMirrors, Pivot, RetValue ); //printf( " --> Pivot %4d. Constant %d.\n", Pivot, RetValue ); } - else if ( Sbd_ManExplore( p, Pivot, &Truth ) ) + else if ( Sbd_ManExplore2( p, Pivot, &Truth ) ) { Sbd_ManImplement( p, Pivot, Truth ); //printf( " --> Pivot %4d. Supp %d.\n", Pivot, Vec_IntSize(p->vDivSet) ); @@ -1493,26 +1606,23 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, - Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0, word Truths[SBD_LUTS_MAX] + Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0 ); - Sbd_Str_t Strs[2] = { - {1, 4, {0, 1, 2, 7}}, - {1, 4, {3, 4, 5, 6}} - }; - - word Truths[SBD_LUTS_MAX]; +// Sbd_Str_t Strs[2] = { {1, 4, {0, 1, 2, 8}}, {1, 4, {3, 4, 5, 6}} }; +// Sbd_Str_t Strs[2] = { {1, 4, {1, 4, 5, 7}}, {1, 4, {0, 1, 2, 3}} }; + Sbd_Str_t Strs[3] = { {1, 4, {8, 4, 5, 7}}, {1, 4, {0, 1, 2, 3}}, {0, 4, {0, 1, 2, 3}} }; Vec_Int_t * vDivSet = Vec_IntAlloc( 8 ); int i, RetValue; - for ( i = 0; i < 7; i++ ) + for ( i = 0; i < 6; i++ ) Vec_IntPush( vDivSet, i+1 ); RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, - vDivSet, 2, Strs, Truths ); + vDivSet, 3, Strs ); if ( RetValue ) { printf( "Solving succeded.\n" ); diff --git a/src/opt/sbd/sbdInt.h b/src/opt/sbd/sbdInt.h index 3646c6b96..5395e148e 100644 --- a/src/opt/sbd/sbdInt.h +++ b/src/opt/sbd/sbdInt.h @@ -66,6 +66,7 @@ struct Sbd_Str_t_ int fLut; // LUT or SEL int nVarIns; // input count int VarIns[SBD_DIV_MAX]; // input vars + word Res; // result of solving }; //////////////////////////////////////////////////////////////////////// diff --git a/src/opt/sbd/sbdLut.c b/src/opt/sbd/sbdLut.c index 42bb09555..b68ecc26f 100644 --- a/src/opt/sbd/sbdLut.c +++ b/src/opt/sbd/sbdLut.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "sbdInt.h" +#include "misc/util/utilTruth.h" ABC_NAMESPACE_IMPL_START @@ -46,17 +47,18 @@ int Sbd_ProblemCountParams( int nStrs, Sbd_Str_t * pStr0 ) { Sbd_Str_t * pStr; int nPars = 0; for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++ ) - nPars += (pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns); + nPars += pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns; return nPars; } // add clauses for the structure -void Sbd_ProblemAddClauses( sat_solver * pSat, int nVars, int nStrs, int * pVars, Sbd_Str_t * pStr0 ) +int Sbd_ProblemAddClauses( sat_solver * pSat, int nVars, int nStrs, int * pVars, Sbd_Str_t * pStr0 ) { // variable order: inputs, structure outputs, parameters Sbd_Str_t * pStr; int VarOut = nVars; int VarPar = nVars + nStrs; int m, k, n, status, pLits[SBD_SIZE_MAX+2]; +//printf( "Start par = %d. ", VarPar ); for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++, VarOut++ ) { if ( pStr->fLut ) @@ -72,12 +74,14 @@ void Sbd_ProblemAddClauses( sat_solver * pSat, int nVars, int nStrs, int * pVars pLits[pStr->nVarIns] = Abc_Var2Lit( pVars[VarPar], n ); pLits[pStr->nVarIns+1] = Abc_Var2Lit( pVars[VarOut], !n ); status = sat_solver_addclause( pSat, pLits, pLits + pStr->nVarIns + 2 ); - assert( status ); + if ( !status ) + return 0; } } } else { + assert( pStr->nVarIns <= SBD_DIV_MAX ); for ( k = 0; k < pStr->nVarIns; k++, VarPar++ ) { for ( n = 0; n < 2; n++ ) @@ -86,22 +90,32 @@ void Sbd_ProblemAddClauses( sat_solver * pSat, int nVars, int nStrs, int * pVars pLits[1] = Abc_Var2Lit( pVars[VarOut], n ); pLits[2] = Abc_Var2Lit( pVars[pStr->VarIns[k]], !n ); status = sat_solver_addclause( pSat, pLits, pLits + 3 ); - assert( status ); + if ( !status ) + return 0; } } } } +//printf( "Stop par = %d.\n", VarPar ); + return 1; } void Sbd_ProblemAddClausesInit( sat_solver * pSat, int nVars, int nStrs, int * pVars, Sbd_Str_t * pStr0 ) { Sbd_Str_t * pStr; int VarPar = nVars + nStrs; - int m, m2, pLits[2], status; + int m, m2, status, pLits[SBD_DIV_MAX]; // make sure selector parameters are mutually exclusive - for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++, VarPar = pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns ) + for ( pStr = pStr0; pStr < pStr0 + nStrs; VarPar += pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns, pStr++ ) { if ( pStr->fLut ) continue; + // one variable should be selected + assert( pStr->nVarIns <= SBD_DIV_MAX ); + for ( m = 0; m < pStr->nVarIns; m++ ) + pLits[m] = Abc_Var2Lit( pVars[VarPar + m], 0 ); + status = sat_solver_addclause( pSat, pLits, pLits + pStr->nVarIns ); + assert( status ); + // two variables cannot be selected for ( m = 0; m < pStr->nVarIns; m++ ) for ( m2 = m+1; m2 < pStr->nVarIns; m2++ ) { @@ -120,15 +134,44 @@ void Sbd_ProblemPrintSolution( int nStrs, Sbd_Str_t * pStr0, Vec_Int_t * vLits ) for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++ ) { nIters = pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns; - printf( "%s%d : ", pStr->fLut ? "LUT":"SEL", pStr-pStr0 ); - for ( m = 0; m < nIters; m++ ) - printf( "%d", Abc_LitIsCompl(Vec_IntEntry(vLits, iLit++)) ); - printf( "\n" ); + printf( "%s%d : ", pStr->fLut ? "LUT":"SEL", (int)(pStr-pStr0) ); + for ( m = 0; m < nIters; m++, iLit++ ) + printf( "%d", !Abc_LitIsCompl(Vec_IntEntry(vLits, iLit)) ); + printf( " {" ); + for ( m = 0; m < pStr->nVarIns; m++ ) + printf( " %d", pStr->VarIns[m] ); + printf( " }\n" ); } assert( iLit == Vec_IntSize(vLits) ); } -void Sbd_ProblemCollectSolution( int nStrs, Sbd_Str_t * pStr0, Vec_Int_t * vLits, word Truths[SBD_LUTS_MAX] ) +void Sbd_ProblemCollectSolution( int nStrs, Sbd_Str_t * pStr0, Vec_Int_t * vLits ) { + Sbd_Str_t * pStr; + int m, nIters, iLit = 0; + for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++ ) + { + pStr->Res = 0; + if ( pStr->fLut ) + { + nIters = 1 << pStr->nVarIns; + for ( m = 0; m < nIters; m++, iLit++ ) + if ( !Abc_LitIsCompl(Vec_IntEntry(vLits, iLit)) ) + Abc_TtSetBit( &pStr->Res, m ); + Abc_TtStretch6( &pStr->Res, pStr->nVarIns, 6 ); + } + else + { + nIters = 0; + for ( m = 0; m < pStr->nVarIns; m++, iLit++ ) + if ( !Abc_LitIsCompl(Vec_IntEntry(vLits, iLit)) ) + { + pStr->Res = pStr->VarIns[m]; + nIters++; + } + assert( nIters == 1 ); + } + } + assert( iLit == Vec_IntSize(vLits) ); } /**Function************************************************************* @@ -145,38 +188,39 @@ void Sbd_ProblemCollectSolution( int nStrs, Sbd_Str_t * pStr0, Vec_Int_t * vLits int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, - Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0, word Truths[SBD_LUTS_MAX] ) // divisors, structures + Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0 ) // divisors, structures { extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); + int fVerbose = 1; Vec_Int_t * vLits = Vec_IntAlloc( 100 ); sat_solver * pSatCec = Sbd_ManSatSolver( NULL, p, vMirrors, Pivot, vWinObjs, vObj2Var, vTfo, vRoots, 1 ); sat_solver * pSatQbf = sat_solver_new(); + int PivotVar = Vec_IntEntry(vObj2Var, Pivot); + int nVars = Vec_IntSize( vDivSet ); int nPars = Sbd_ProblemCountParams( nStrs, pStr0 ); int VarCecOut = Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots); - int VarCecPar = VarCecOut + 1; - int VarCecFree = VarCecPar + nPars; + int VarCecPar = VarCecOut + nStrs; int VarQbfPar = 0; int VarQbfFree = nPars; int pVarsCec[256]; int pVarsQbf[256]; - int i, iVar, iLit; + int i, iVar, iLit, nIters; int RetValue = 0; - assert( Vec_IntSize(vDivSet) <= SBD_SIZE_MAX ); + assert( Vec_IntSize(vDivSet) <= SBD_DIV_MAX ); assert( nVars + nStrs + nPars <= 256 ); // collect CEC variables Vec_IntForEachEntry( vDivSet, iVar, i ) pVarsCec[i] = iVar; - pVarsCec[nVars] = VarCecOut; - for ( i = 1; i < nStrs; i++ ) - pVarsCec[nVars + i] = VarCecFree++; + for ( i = 0; i < nStrs; i++ ) + pVarsCec[nVars + i] = VarCecOut + i; for ( i = 0; i < nPars; i++ ) pVarsCec[nVars + nStrs + i] = VarCecPar + i; @@ -197,13 +241,24 @@ int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, Vec_IntClear( vLits ); for ( i = 0; i < nPars; i++ ) Vec_IntPush( vLits, Abc_Var2Lit(VarCecPar + i, 1) ); - while ( 1 ) + for ( nIters = 0; nIters < (1 << nVars); nIters++ ) { // check if these parameters solve the problem int status = sat_solver_solve( pSatCec, Vec_IntArray(vLits), Vec_IntLimit(vLits), 0, 0, 0, 0 ); if ( status == l_False ) // solution found break; assert( status == l_True ); +// Vec_IntForEachEntry( vWinObjs, iVar, i ) +// printf( "Node = %4d. SatVar = %4d. Value = %d.\n", iVar, i, sat_solver_var_value(pSatCec, i) ); + + if ( fVerbose ) + { + printf( "Iter %3d : ", nIters ); + for ( i = 0; i < nPars; i++ ) + printf( "%d", !Abc_LitIsCompl(Vec_IntEntry(vLits, i)) ); + printf( " " ); + } + Vec_IntClear( vLits ); // create new QBF variables for ( i = 0; i < nVars + nStrs; i++ ) @@ -211,15 +266,20 @@ int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, // set their values Vec_IntForEachEntry( vDivSet, iVar, i ) { - iLit = Abc_Var2Lit( pVarsQbf[i], sat_solver_var_value(pSatCec, iVar) ); + iLit = Abc_Var2Lit( pVarsQbf[i], !sat_solver_var_value(pSatCec, iVar) ); status = sat_solver_addclause( pSatQbf, &iLit, &iLit + 1 ); assert( status ); + if ( fVerbose ) + printf( "%d", sat_solver_var_value(pSatCec, iVar) ); } iLit = Abc_Var2Lit( pVarsQbf[nVars], sat_solver_var_value(pSatCec, VarCecOut) ); status = sat_solver_addclause( pSatQbf, &iLit, &iLit + 1 ); assert( status ); + if ( fVerbose ) + printf( " %d\n", !sat_solver_var_value(pSatCec, VarCecOut) ); // add clauses to the QBF problem - Sbd_ProblemAddClauses( pSatQbf, nVars, nStrs, pVarsQbf, pStr0 ); + if ( !Sbd_ProblemAddClauses( pSatQbf, nVars, nStrs, pVarsQbf, pStr0 ) ) + break; // solution does not exist // check if solution still exists status = sat_solver_solve( pSatQbf, NULL, NULL, 0, 0, 0, 0 ); if ( status == l_False ) // solution does not exist @@ -228,12 +288,12 @@ int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, // find the new values of parameters assert( Vec_IntSize(vLits) == 0 ); for ( i = 0; i < nPars; i++ ) - Vec_IntPush( vLits, Abc_Var2Lit(VarCecPar + i, sat_solver_var_value(pSatQbf, VarQbfPar + i)) ); + Vec_IntPush( vLits, Abc_Var2Lit(VarCecPar + i, !sat_solver_var_value(pSatQbf, VarQbfPar + i)) ); } if ( Vec_IntSize(vLits) > 0 ) { Sbd_ProblemPrintSolution( nStrs, pStr0, vLits ); - Sbd_ProblemCollectSolution( nStrs, pStr0, vLits, Truths ); + Sbd_ProblemCollectSolution( nStrs, pStr0, vLits ); RetValue = 1; } else diff --git a/src/opt/sbd/sbdWin.c b/src/opt/sbd/sbdWin.c index fc79caa71..d5b7dd9d6 100644 --- a/src/opt/sbd/sbdWin.c +++ b/src/opt/sbd/sbdWin.c @@ -141,6 +141,17 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi } assert( sat_solver_nvars(pSat) == nVars + nAddVars ); } + else if ( fQbf ) + { + int n, pLits[2]; + for ( n = 0; n < 2; n++ ) + { + pLits[0] = Abc_Var2Lit( PivotVar, n ); + pLits[1] = Abc_Var2Lit( LastVar, n ); + RetValue = sat_solver_addclause( pSat, pLits, pLits + 2 ); + assert( RetValue ); + } + } // finalize RetValue = sat_solver_simplify( pSat ); if ( RetValue == 0 ) @@ -418,6 +429,30 @@ int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, return -1; } +int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ) +{ + int nBTLimit = 0; + int n, i, k, status, iLit, iVar; + word * pPats[2] = {pOnset, pOffset}; + assert( Vec_IntSize(vDivVars) < 64 ); + for ( n = 0; n < 2; n++ ) + for ( i = 0; i < nConsts; i++ ) + { + sat_solver_random_polarity( pSat ); + iLit = Abc_Var2Lit( PivotVar, n ); + status = sat_solver_solve( pSat, &iLit, &iLit + 1, nBTLimit, 0, 0, 0 ); + if ( status == l_Undef ) + return -2; + if ( status == l_False ) + return n; + pPats[n][i] = ((word)!n) << Vec_IntSize(vDivVars); + Vec_IntForEachEntry( vDivVars, iVar, k ) + if ( sat_solver_var_value(pSat, iVar) ) + Abc_TtXorBit(&pPats[n][i], k); + } + return -1; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// From fcd3133a9f2817893aa60d1ec2d1b94a1f5a7b5a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 27 Dec 2016 18:15:05 +0700 Subject: [PATCH 013/185] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 5 +++-- src/opt/sbd/sbdLut.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 5c5fe35ab..15874dc67 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -75,6 +75,8 @@ static inline word * Sbd_ObjSim1( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( static inline word * Sbd_ObjSim2( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSims[2], p->pPars->nWords * i ); } static inline word * Sbd_ObjSim3( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSims[3], p->pPars->nWords * i ); } +extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivSet, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp ); + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -975,7 +977,6 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) int fVerbose = 0; abctime clk, clkSat = 0, clkEnu = 0, clkAll = Abc_Clock(); int nIters, nItersMax = 32; - extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivSet, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp ); word MatrS[64] = {0}, MatrC[2][64] = {{0}}, Cubes[2][2][64] = {{{0}}}, Cover[64] = {0}, Cube, CubeNew[2]; int i, k, n, Node, Index, nCubes[2] = {0}, nRows = 0, nRowsOld; @@ -1147,7 +1148,7 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); abctime clk = Abc_Clock(); word Onset[64] = {0}, Offset[64] = {0}, Cube; - word CoverRows[256] = {0}, CoverCols[64] = {{0}}; + word CoverRows[64] = {0}, CoverCols[64] = {0}; int nIters, nItersMax = 32; int i, k, nRows = 0; diff --git a/src/opt/sbd/sbdLut.c b/src/opt/sbd/sbdLut.c index b68ecc26f..b924a33b3 100644 --- a/src/opt/sbd/sbdLut.c +++ b/src/opt/sbd/sbdLut.c @@ -197,7 +197,7 @@ int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, sat_solver * pSatCec = Sbd_ManSatSolver( NULL, p, vMirrors, Pivot, vWinObjs, vObj2Var, vTfo, vRoots, 1 ); sat_solver * pSatQbf = sat_solver_new(); - int PivotVar = Vec_IntEntry(vObj2Var, Pivot); + //int PivotVar = Vec_IntEntry(vObj2Var, Pivot); int nVars = Vec_IntSize( vDivSet ); int nPars = Sbd_ProblemCountParams( nStrs, pStr0 ); From 3581c94fec6e3fabe36591cd57a732d3f58a29ce Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 27 Dec 2016 21:08:52 +0700 Subject: [PATCH 014/185] Updates to delay optimization project. --- abclib.dsp | 4 + src/opt/sbd/module.make | 1 + src/opt/sbd/sbdCut.c | 617 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 622 insertions(+) create mode 100644 src/opt/sbd/sbdCut.c diff --git a/abclib.dsp b/abclib.dsp index e5583ddfa..1833f013b 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -2759,6 +2759,10 @@ SOURCE=.\src\opt\sbd\sbdCore.c # End Source File # Begin Source File +SOURCE=.\src\opt\sbd\sbdCut.c +# End Source File +# Begin Source File + SOURCE=.\src\opt\sbd\sbdInt.h # End Source File # Begin Source File diff --git a/src/opt/sbd/module.make b/src/opt/sbd/module.make index 0320d3818..3bdc20b37 100644 --- a/src/opt/sbd/module.make +++ b/src/opt/sbd/module.make @@ -1,6 +1,7 @@ SRC += src/opt/sbd/sbd.c \ src/opt/sbd/sbdCnf.c \ src/opt/sbd/sbdCore.c \ + src/opt/sbd/sbdCut.c \ src/opt/sbd/sbdLut.c \ src/opt/sbd/sbdSat.c \ src/opt/sbd/sbdWin.c diff --git a/src/opt/sbd/sbdCut.c b/src/opt/sbd/sbdCut.c new file mode 100644 index 000000000..cabc301c5 --- /dev/null +++ b/src/opt/sbd/sbdCut.c @@ -0,0 +1,617 @@ +/**CFile**************************************************************** + + FileName [sbdCut.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [SAT-based optimization using internal don't-cares.] + + Synopsis [Cut computation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: sbdCut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sbdInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define SBD_MAX_CUTSIZE 8 +#define SBD_MAX_CUTNUM 64 +#define SBD_MAX_TT_WORDS ((SBD_MAX_CUTSIZE > 6) ? 1 << (SBD_MAX_CUTSIZE-6) : 1) + +#define SBD_CUT_NO_LEAF 255 + +typedef struct Sbd_Cut_t_ Sbd_Cut_t; +struct Sbd_Cut_t_ +{ + word Sign; // signature + int iFunc; // functionality + unsigned Cost : 24; // misc cut cost + unsigned nLeaves : 8; // the number of leaves + int pLeaves[SBD_MAX_CUTSIZE]; // leaves +}; + +typedef struct Sbd_Sto_t_ Sbd_Sto_t; +struct Sbd_Sto_t_ +{ + int nLutSize; + int nCutNum; + int fCutMin; + int fVerbose; + Gia_Man_t * pGia; // user's AIG manager (will be modified by adding nodes) + Vec_Int_t * vDelays; // delays for each node + Vec_Wec_t * vCuts; // cuts for each node + Vec_Mem_t * vTtMem; // truth tables + Sbd_Cut_t pCuts[3][SBD_MAX_CUTNUM]; // temporary cuts + Sbd_Cut_t * ppCuts[SBD_MAX_CUTNUM]; // temporary cut pointers + abctime clkStart; // starting time + double CutCount[4]; // cut counters +}; + +static inline word * Sbd_CutTruth( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) { return Vec_MemReadEntry(p->vTtMem, Abc_Lit2Var(pCut->iFunc)); } + +#define Sbd_ForEachCut( pList, pCut, i ) for ( i = 0, pCut = pList + 1; i < pList[0]; i++, pCut += pCut[0] + 2 ) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, int nLutSize, int nCutNum, int fCutMin, int fVerbose ) +{ + Sbd_Sto_t * p; + assert( nLutSize > 1 && nLutSize <= SBD_MAX_CUTSIZE ); + assert( nCutNum > 1 && nCutNum < SBD_MAX_CUTNUM ); + p = ABC_CALLOC( Sbd_Sto_t, 1 ); + p->clkStart = Abc_Clock(); + p->nLutSize = nLutSize; + p->nCutNum = nCutNum; + p->fCutMin = fCutMin; + p->fVerbose = fVerbose; + p->pGia = pGia; + p->vDelays = Vec_IntStart( Gia_ManObjNum(pGia) ); + p->vCuts = Vec_WecStart( Gia_ManObjNum(pGia) ); + p->vTtMem = fCutMin ? Vec_MemAllocForTT( nLutSize, 0 ) : NULL; + return p; +} +void Sbd_StoFree( Sbd_Sto_t * p ) +{ + Vec_IntFree( p->vDelays ); + Vec_WecFree( p->vCuts ); + if ( p->fCutMin ) + Vec_MemHashFree( p->vTtMem ); + if ( p->fCutMin ) + Vec_MemFree( p->vTtMem ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Check correctness of cuts.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline word Sbd_CutGetSign( Sbd_Cut_t * pCut ) +{ + word Sign = 0; int i; + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + Sign |= ((word)1) << (pCut->pLeaves[i] & 0x3F); + return Sign; +} +static inline int Sbd_CutCheck( Sbd_Cut_t * pBase, Sbd_Cut_t * pCut ) // check if pCut is contained in pBase +{ + int nSizeB = pBase->nLeaves; + int nSizeC = pCut->nLeaves; + int i, * pB = pBase->pLeaves; + int k, * pC = pCut->pLeaves; + for ( i = 0; i < nSizeC; i++ ) + { + for ( k = 0; k < nSizeB; k++ ) + if ( pC[i] == pB[k] ) + break; + if ( k == nSizeB ) + return 0; + } + return 1; +} +static inline int Sbd_CutSetCheckArray( Sbd_Cut_t ** ppCuts, int nCuts ) +{ + Sbd_Cut_t * pCut0, * pCut1; + int i, k, m, n, Value; + assert( nCuts > 0 ); + for ( i = 0; i < nCuts; i++ ) + { + pCut0 = ppCuts[i]; + assert( pCut0->nLeaves <= SBD_MAX_CUTSIZE ); + assert( pCut0->Sign == Sbd_CutGetSign(pCut0) ); + // check duplicates + for ( m = 0; m < (int)pCut0->nLeaves; m++ ) + for ( n = m + 1; n < (int)pCut0->nLeaves; n++ ) + assert( pCut0->pLeaves[m] < pCut0->pLeaves[n] ); + // check pairs + for ( k = 0; k < nCuts; k++ ) + { + pCut1 = ppCuts[k]; + if ( pCut0 == pCut1 ) + continue; + // check containments + Value = Sbd_CutCheck( pCut0, pCut1 ); + assert( Value == 0 ); + } + } + return 1; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Sbd_CutMergeOrder( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_Cut_t * pCut, int nLutSize ) +{ + int nSize0 = pCut0->nLeaves; + int nSize1 = pCut1->nLeaves; + int i, * pC0 = pCut0->pLeaves; + int k, * pC1 = pCut1->pLeaves; + int c, * pC = pCut->pLeaves; + // the case of the largest cut sizes + if ( nSize0 == nLutSize && nSize1 == nLutSize ) + { + for ( i = 0; i < nSize0; i++ ) + { + if ( pC0[i] != pC1[i] ) return 0; + pC[i] = pC0[i]; + } + pCut->nLeaves = nLutSize; + pCut->iFunc = -1; + pCut->Sign = pCut0->Sign | pCut1->Sign; + return 1; + } + // compare two cuts with different numbers + i = k = c = 0; + if ( nSize0 == 0 ) goto FlushCut1; + if ( nSize1 == 0 ) goto FlushCut0; + while ( 1 ) + { + if ( c == nLutSize ) return 0; + if ( pC0[i] < pC1[k] ) + { + pC[c++] = pC0[i++]; + if ( i >= nSize0 ) goto FlushCut1; + } + else if ( pC0[i] > pC1[k] ) + { + pC[c++] = pC1[k++]; + if ( k >= nSize1 ) goto FlushCut0; + } + else + { + pC[c++] = pC0[i++]; k++; + if ( i >= nSize0 ) goto FlushCut1; + if ( k >= nSize1 ) goto FlushCut0; + } + } + +FlushCut0: + if ( c + nSize0 > nLutSize + i ) return 0; + while ( i < nSize0 ) + pC[c++] = pC0[i++]; + pCut->nLeaves = c; + pCut->iFunc = -1; + pCut->Sign = pCut0->Sign | pCut1->Sign; + return 1; + +FlushCut1: + if ( c + nSize1 > nLutSize + k ) return 0; + while ( k < nSize1 ) + pC[c++] = pC1[k++]; + pCut->nLeaves = c; + pCut->iFunc = -1; + pCut->Sign = pCut0->Sign | pCut1->Sign; + return 1; +} +static inline int Sbd_CutMergeOrder2( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_Cut_t * pCut, int nLutSize ) +{ + int x0, i0 = 0, nSize0 = pCut0->nLeaves, * pC0 = pCut0->pLeaves; + int x1, i1 = 0, nSize1 = pCut1->nLeaves, * pC1 = pCut1->pLeaves; + int xMin, c = 0, * pC = pCut->pLeaves; + while ( 1 ) + { + x0 = (i0 == nSize0) ? ABC_INFINITY : pC0[i0]; + x1 = (i1 == nSize1) ? ABC_INFINITY : pC1[i1]; + xMin = Abc_MinInt(x0, x1); + if ( xMin == ABC_INFINITY ) break; + if ( c == nLutSize ) return 0; + pC[c++] = xMin; + if (x0 == xMin) i0++; + if (x1 == xMin) i1++; + } + pCut->nLeaves = c; + pCut->iFunc = -1; + pCut->Sign = pCut0->Sign | pCut1->Sign; + return 1; +} +static inline int Sbd_CutSetCutIsContainedOrder( Sbd_Cut_t * pBase, Sbd_Cut_t * pCut ) // check if pCut is contained in pBase +{ + int i, nSizeB = pBase->nLeaves; + int k, nSizeC = pCut->nLeaves; + if ( nSizeB == nSizeC ) + { + for ( i = 0; i < nSizeB; i++ ) + if ( pBase->pLeaves[i] != pCut->pLeaves[i] ) + return 0; + return 1; + } + assert( nSizeB > nSizeC ); + if ( nSizeC == 0 ) + return 1; + for ( i = k = 0; i < nSizeB; i++ ) + { + if ( pBase->pLeaves[i] > pCut->pLeaves[k] ) + return 0; + if ( pBase->pLeaves[i] == pCut->pLeaves[k] ) + { + if ( ++k == nSizeC ) + return 1; + } + } + return 0; +} +static inline int Sbd_CutSetLastCutIsContained( Sbd_Cut_t ** pCuts, int nCuts ) +{ + int i; + for ( i = 0; i < nCuts; i++ ) + if ( pCuts[i]->nLeaves <= pCuts[nCuts]->nLeaves && (pCuts[i]->Sign & pCuts[nCuts]->Sign) == pCuts[i]->Sign && Sbd_CutSetCutIsContainedOrder(pCuts[nCuts], pCuts[i]) ) + return 1; + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Sbd_CutCompare( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1 ) +{ + if ( pCut0->nLeaves < pCut1->nLeaves ) return -1; + if ( pCut0->nLeaves > pCut1->nLeaves ) return 1; + if ( pCut0->Cost < pCut1->Cost ) return -1; + if ( pCut0->Cost > pCut1->Cost ) return 1; + return 0; +} +static inline int Sbd_CutSetLastCutContains( Sbd_Cut_t ** pCuts, int nCuts ) +{ + int i, k, fChanges = 0; + for ( i = 0; i < nCuts; i++ ) + if ( pCuts[nCuts]->nLeaves < pCuts[i]->nLeaves && (pCuts[nCuts]->Sign & pCuts[i]->Sign) == pCuts[nCuts]->Sign && Sbd_CutSetCutIsContainedOrder(pCuts[i], pCuts[nCuts]) ) + pCuts[i]->nLeaves = SBD_CUT_NO_LEAF, fChanges = 1; + if ( !fChanges ) + return nCuts; + for ( i = k = 0; i <= nCuts; i++ ) + { + if ( pCuts[i]->nLeaves == SBD_CUT_NO_LEAF ) + continue; + if ( k < i ) + ABC_SWAP( Sbd_Cut_t *, pCuts[k], pCuts[i] ); + k++; + } + return k - 1; +} +static inline void Sbd_CutSetSortByCost( Sbd_Cut_t ** pCuts, int nCuts ) +{ + int i; + for ( i = nCuts; i > 0; i-- ) + { + if ( Sbd_CutCompare(pCuts[i - 1], pCuts[i]) < 0 )//!= 1 ) + return; + ABC_SWAP( Sbd_Cut_t *, pCuts[i - 1], pCuts[i] ); + } +} +static inline int Sbd_CutSetAddCut( Sbd_Cut_t ** pCuts, int nCuts, int nCutNum ) +{ + if ( nCuts == 0 ) + return 1; + nCuts = Sbd_CutSetLastCutContains(pCuts, nCuts); + assert( nCuts >= 0 ); + Sbd_CutSetSortByCost( pCuts, nCuts ); + // add new cut if there is room + return Abc_MinInt( nCuts + 1, nCutNum - 1 ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Sbd_CutComputeTruth6( Sbd_Sto_t * p, Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, int fCompl0, int fCompl1, Sbd_Cut_t * pCutR, int fIsXor ) +{ + int nOldSupp = pCutR->nLeaves, truthId, fCompl; word t; + word t0 = *Sbd_CutTruth(p, pCut0); + word t1 = *Sbd_CutTruth(p, pCut1); + if ( Abc_LitIsCompl(pCut0->iFunc) ^ fCompl0 ) t0 = ~t0; + if ( Abc_LitIsCompl(pCut1->iFunc) ^ fCompl1 ) t1 = ~t1; + t0 = Abc_Tt6Expand( t0, pCut0->pLeaves, pCut0->nLeaves, pCutR->pLeaves, pCutR->nLeaves ); + t1 = Abc_Tt6Expand( t1, pCut1->pLeaves, pCut1->nLeaves, pCutR->pLeaves, pCutR->nLeaves ); + t = fIsXor ? t0 ^ t1 : t0 & t1; + if ( (fCompl = (int)(t & 1)) ) t = ~t; + pCutR->nLeaves = Abc_Tt6MinBase( &t, pCutR->pLeaves, pCutR->nLeaves ); + assert( (int)(t & 1) == 0 ); + truthId = Vec_MemHashInsert(p->vTtMem, &t); + pCutR->iFunc = Abc_Var2Lit( truthId, fCompl ); + assert( (int)pCutR->nLeaves <= nOldSupp ); + return (int)pCutR->nLeaves < nOldSupp; +} +static inline int Sbd_CutComputeTruth( Sbd_Sto_t * p, Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, int fCompl0, int fCompl1, Sbd_Cut_t * pCutR, int fIsXor ) +{ + if ( p->nLutSize <= 6 ) + return Sbd_CutComputeTruth6( p, pCut0, pCut1, fCompl0, fCompl1, pCutR, fIsXor ); + { + word uTruth[SBD_MAX_TT_WORDS], uTruth0[SBD_MAX_TT_WORDS], uTruth1[SBD_MAX_TT_WORDS]; + int nOldSupp = pCutR->nLeaves, truthId; + int nLutSize = p->nLutSize, fCompl; + int nWords = Abc_Truth6WordNum(nLutSize); + word * pTruth0 = Sbd_CutTruth(p, pCut0); + word * pTruth1 = Sbd_CutTruth(p, pCut1); + Abc_TtCopy( uTruth0, pTruth0, nWords, Abc_LitIsCompl(pCut0->iFunc) ^ fCompl0 ); + Abc_TtCopy( uTruth1, pTruth1, nWords, Abc_LitIsCompl(pCut1->iFunc) ^ fCompl1 ); + Abc_TtExpand( uTruth0, nLutSize, pCut0->pLeaves, pCut0->nLeaves, pCutR->pLeaves, pCutR->nLeaves ); + Abc_TtExpand( uTruth1, nLutSize, pCut1->pLeaves, pCut1->nLeaves, pCutR->pLeaves, pCutR->nLeaves ); + if ( fIsXor ) + Abc_TtXor( uTruth, uTruth0, uTruth1, nWords, (fCompl = (int)((uTruth0[0] ^ uTruth1[0]) & 1)) ); + else + Abc_TtAnd( uTruth, uTruth0, uTruth1, nWords, (fCompl = (int)((uTruth0[0] & uTruth1[0]) & 1)) ); + pCutR->nLeaves = Abc_TtMinBase( uTruth, pCutR->pLeaves, pCutR->nLeaves, nLutSize ); + assert( (uTruth[0] & 1) == 0 ); +//Kit_DsdPrintFromTruth( uTruth, pCutR->nLeaves ), printf("\n" ), printf("\n" ); + truthId = Vec_MemHashInsert(p->vTtMem, uTruth); + pCutR->iFunc = Abc_Var2Lit( truthId, fCompl ); + assert( (int)pCutR->nLeaves <= nOldSupp ); + return (int)pCutR->nLeaves < nOldSupp; + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Sbd_CutCountBits( word i ) +{ + i = i - ((i >> 1) & 0x5555555555555555); + i = (i & 0x3333333333333333) + ((i >> 2) & 0x3333333333333333); + i = ((i + (i >> 4)) & 0x0F0F0F0F0F0F0F0F); + return (i*(0x0101010101010101))>>56; +} +static inline void Sbd_CutPrint( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) +{ + int i, nDigits = Abc_Base10Log(Gia_ManObjNum(p->pGia)); + printf( "%d {", pCut->nLeaves ); + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + printf( " %*d", nDigits, pCut->pLeaves[i] ); + for ( ; i < (int)p->nLutSize; i++ ) + printf( " %*s", nDigits, " " ); + printf( " } Cost = %4d\n", pCut->Cost ); +} +static inline int Sbd_CutCost( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) +{ + int i, Cost = 0; + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + Cost += Vec_IntEntry( p->vDelays, pCut->pLeaves[i] ); + return Cost; +} +static inline void Sbd_CutAddUnitCut( Sbd_Sto_t * p, int iObj ) +{ + Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj ); + if ( Vec_IntSize(vThis) == 0 ) + Vec_IntPush( vThis, 1 ); + else + Vec_IntAddToEntry( vThis, 0, 1 ); + Vec_IntPush( vThis, 1 ); + Vec_IntPush( vThis, iObj ); + Vec_IntPush( vThis, 2 ); +} +static inline int Sbd_StoPrepareSet( Sbd_Sto_t * p, int iObj, int Index ) +{ + Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj ); + int i, v, * pCut, * pList = Vec_IntArray( vThis ); + Sbd_ForEachCut( pList, pCut, i ) + { + Sbd_Cut_t * pCutTemp = &p->pCuts[Index][i]; + pCutTemp->nLeaves = pCut[0]; + for ( v = 1; v <= pCut[0]; v++ ) + pCutTemp->pLeaves[v-1] = pCut[v]; + pCutTemp->iFunc = pCut[pCut[0]+1]; + pCutTemp->Sign = Sbd_CutGetSign( pCutTemp ); + pCutTemp->Cost = Sbd_CutCost( p, pCutTemp ); + } + return pList[0]; +} +static inline void Sbd_StoInitResult( Sbd_Sto_t * p ) +{ + int i; + for ( i = 0; i < SBD_MAX_CUTNUM; i++ ) + p->ppCuts[i] = &p->pCuts[2][i]; +} +static inline void Sbd_StoStoreResult( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pCuts, int nCuts ) +{ + int i, v; + Vec_Int_t * vList = Vec_WecEntry( p->vCuts, iObj ); + Vec_IntPush( vList, nCuts ); + for ( i = 0; i < nCuts; i++ ) + { + Vec_IntPush( vList, pCuts[i]->nLeaves ); + for ( v = 0; v < (int)pCuts[i]->nLeaves; v++ ) + Vec_IntPush( vList, pCuts[i]->pLeaves[v] ); + Vec_IntPush( vList, pCuts[i]->iFunc ); + } +} +static inline void Sbd_StoComputeDelay( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pCuts, int nCuts ) +{ + int i, v, Delay, DelayMin = ABC_INFINITY; + assert( nCuts > 0 ); + for ( i = 0; i < nCuts; i++ ) + { + if ( (int)pCuts[i]->nLeaves > p->nLutSize ) + continue; + Delay = 0; + for ( v = 0; v < (int)pCuts[i]->nLeaves; v++ ) + Delay = Abc_MaxInt( Delay, Vec_IntEntry(p->vDelays, pCuts[i]->pLeaves[v]) ); + DelayMin = Abc_MinInt( DelayMin, Delay ); + } + assert( DelayMin < ABC_INFINITY ); + Vec_IntWriteEntry( p->vDelays, iObj, (nCuts > 1 || pCuts[0]->nLeaves > 1) ? DelayMin + 1 : DelayMin ); +} +void Sbd_StoMergeCuts( Sbd_Sto_t * p, int iObj ) +{ + Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj); + int fIsXor = Gia_ObjIsXor(pObj); + int nLutSize = p->nLutSize; + int nCutNum = p->nCutNum; + int fComp0 = Gia_ObjFaninC0(pObj); + int fComp1 = Gia_ObjFaninC1(pObj); + int nCuts0 = Sbd_StoPrepareSet( p, Gia_ObjFaninId0(pObj, iObj), 0 ); + int nCuts1 = Sbd_StoPrepareSet( p, Gia_ObjFaninId1(pObj, iObj), 1 ); + int i, k, nCutsR = 0; + Sbd_Cut_t * pCut0, * pCut1, ** pCutsR = p->ppCuts; + assert( !Gia_ObjIsBuf(pObj) ); + assert( !Gia_ObjIsMux(p->pGia, pObj) ); + Sbd_StoInitResult( p ); + p->CutCount[0] += nCuts0 * nCuts1; + for ( i = 0, pCut0 = p->pCuts[0]; i < nCuts0; i++, pCut0++ ) + for ( k = 0, pCut1 = p->pCuts[1]; k < nCuts1; k++, pCut1++ ) + { + if ( (int)(pCut0->nLeaves + pCut1->nLeaves) > nLutSize && Sbd_CutCountBits(pCut0->Sign | pCut1->Sign) > nLutSize ) + continue; + p->CutCount[1]++; + if ( !Sbd_CutMergeOrder(pCut0, pCut1, pCutsR[nCutsR], nLutSize) ) + continue; + if ( Sbd_CutSetLastCutIsContained(pCutsR, nCutsR) ) + continue; + p->CutCount[2]++; + if ( p->fCutMin && Sbd_CutComputeTruth(p, pCut0, pCut1, fComp0, fComp1, pCutsR[nCutsR], fIsXor) ) + pCutsR[nCutsR]->Sign = Sbd_CutGetSign(pCutsR[nCutsR]); + pCutsR[nCutsR]->Cost = Sbd_CutCost( p, pCutsR[nCutsR] ); + nCutsR = Sbd_CutSetAddCut( pCutsR, nCutsR, nCutNum ); + } + Sbd_StoComputeDelay( p, iObj, pCutsR, nCutsR ); + p->CutCount[3] += nCutsR; + // debug printout + if ( 0 ) + { + printf( "*** Obj = %d Delay = %d\n", iObj, Vec_IntEntry(p->vDelays, iObj) ); + for ( i = 0; i < nCutsR; i++ ) + Sbd_CutPrint( p, pCutsR[i] ); + printf( "\n" ); + } + // verify + assert( nCutsR > 0 && nCutsR < nCutNum ); + assert( Sbd_CutSetCheckArray(pCutsR, nCutsR) ); + // store the cutset + Sbd_StoStoreResult( p, iObj, pCutsR, nCutsR ); + if ( nCutsR > 1 || pCutsR[0]->nLeaves > 1 ) + Sbd_CutAddUnitCut( p, iObj ); +} +int Sbd_StoMergeCutsPlus( Sbd_Sto_t * p, int iObj ) +{ + assert( iObj == Vec_IntSize(p->vDelays) ); + assert( iObj == Vec_WecSize(p->vCuts) ); + Vec_IntPush( p->vDelays, 0 ); + Vec_WecPushLevel( p->vCuts ); + Sbd_StoMergeCuts( p, iObj ); + return Vec_IntEntry( p->vDelays, iObj ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sbd_StoComputeCuts( Sbd_Sto_t * p ) +{ + Gia_Obj_t * pObj; + int i, iObj; + Gia_ManForEachCiId( p->pGia, iObj, i ) + Sbd_CutAddUnitCut( p, iObj ); + Gia_ManForEachAnd( p->pGia, pObj, iObj ) + Sbd_StoMergeCuts( p, iObj ); + if ( !p->fVerbose ) + return; + printf( "CutPair = %.0f ", p->CutCount[0] ); + printf( "Merge = %.0f (%.2f %%) ", p->CutCount[1], 100.0*p->CutCount[1]/p->CutCount[0] ); + printf( "Eval = %.0f (%.2f %%) ", p->CutCount[2], 100.0*p->CutCount[2]/p->CutCount[0] ); + printf( "Cut = %.0f (%.2f %%) ", p->CutCount[3], 100.0*p->CutCount[3]/p->CutCount[0] ); + printf( "\n" ); +} +void Sbd_StoComputeCutsTest( Gia_Man_t * pGia ) +{ + Sbd_Sto_t * p = Sbd_StoAlloc( pGia, 8, 32, 1, 1 ); + Sbd_StoComputeCuts( p ); + Sbd_StoFree( p ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + From 1f45cca621ef5b76c5a7e8b3415530dc8182cdca Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 28 Dec 2016 09:43:28 +0700 Subject: [PATCH 015/185] C++ compatibility fix. --- src/proof/acec/acecSt.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/proof/acec/acecSt.c b/src/proof/acec/acecSt.c index 63aa81311..d97dadc9e 100644 --- a/src/proof/acec/acecSt.c +++ b/src/proof/acec/acecSt.c @@ -21,6 +21,8 @@ #include "acecInt.h" #include "misc/vec/vecWec.h" #include "misc/extra/extra.h" +#include "aig/aig/aig.h" +#include "opt/dar/dar.h" ABC_NAMESPACE_IMPL_START From fdd8404bfc47ae385b7a3684113e8a76806eba79 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 28 Dec 2016 12:34:53 +0700 Subject: [PATCH 016/185] Updates to delay optimization project. --- src/opt/sbd/sbdCut.c | 335 +++++++++++++++++++++++++++++-------------- src/opt/sbd/sbdInt.h | 11 +- 2 files changed, 239 insertions(+), 107 deletions(-) diff --git a/src/opt/sbd/sbdCut.c b/src/opt/sbd/sbdCut.c index cabc301c5..154df9145 100644 --- a/src/opt/sbd/sbdCut.c +++ b/src/opt/sbd/sbdCut.c @@ -28,36 +28,45 @@ ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// #define SBD_MAX_CUTSIZE 8 -#define SBD_MAX_CUTNUM 64 +#define SBD_MAX_CUTNUM 1001 #define SBD_MAX_TT_WORDS ((SBD_MAX_CUTSIZE > 6) ? 1 << (SBD_MAX_CUTSIZE-6) : 1) -#define SBD_CUT_NO_LEAF 255 +#define SBD_CUT_NO_LEAF 0xF typedef struct Sbd_Cut_t_ Sbd_Cut_t; struct Sbd_Cut_t_ { word Sign; // signature int iFunc; // functionality - unsigned Cost : 24; // misc cut cost - unsigned nLeaves : 8; // the number of leaves + int Cost; // cut cost + int CostLev; // cut cost + unsigned fSpec : 1; // special cut + unsigned nTreeLeaves : 27; // cut cost + unsigned nLeaves : 4; // the number of leaves int pLeaves[SBD_MAX_CUTSIZE]; // leaves }; -typedef struct Sbd_Sto_t_ Sbd_Sto_t; struct Sbd_Sto_t_ { int nLutSize; + int nCutSize; int nCutNum; int fCutMin; int fVerbose; Gia_Man_t * pGia; // user's AIG manager (will be modified by adding nodes) + Vec_Int_t * vMirrors; // mirrors for each node Vec_Int_t * vDelays; // delays for each node + Vec_Int_t * vLevels; // levels for each node + Vec_Int_t * vRefs; // refs for each node Vec_Wec_t * vCuts; // cuts for each node Vec_Mem_t * vTtMem; // truth tables Sbd_Cut_t pCuts[3][SBD_MAX_CUTNUM]; // temporary cuts Sbd_Cut_t * ppCuts[SBD_MAX_CUTNUM]; // temporary cut pointers abctime clkStart; // starting time double CutCount[4]; // cut counters + int nCutsSpec; // special cuts + int nCutsOver; // overflow cuts + int DelayMin; // minimum delay }; static inline word * Sbd_CutTruth( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) { return Vec_MemReadEntry(p->vTtMem, Abc_Lit2Var(pCut->iFunc)); } @@ -68,45 +77,6 @@ static inline word * Sbd_CutTruth( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) { return Ve /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, int nLutSize, int nCutNum, int fCutMin, int fVerbose ) -{ - Sbd_Sto_t * p; - assert( nLutSize > 1 && nLutSize <= SBD_MAX_CUTSIZE ); - assert( nCutNum > 1 && nCutNum < SBD_MAX_CUTNUM ); - p = ABC_CALLOC( Sbd_Sto_t, 1 ); - p->clkStart = Abc_Clock(); - p->nLutSize = nLutSize; - p->nCutNum = nCutNum; - p->fCutMin = fCutMin; - p->fVerbose = fVerbose; - p->pGia = pGia; - p->vDelays = Vec_IntStart( Gia_ManObjNum(pGia) ); - p->vCuts = Vec_WecStart( Gia_ManObjNum(pGia) ); - p->vTtMem = fCutMin ? Vec_MemAllocForTT( nLutSize, 0 ) : NULL; - return p; -} -void Sbd_StoFree( Sbd_Sto_t * p ) -{ - Vec_IntFree( p->vDelays ); - Vec_WecFree( p->vCuts ); - if ( p->fCutMin ) - Vec_MemHashFree( p->vTtMem ); - if ( p->fCutMin ) - Vec_MemFree( p->vTtMem ); - ABC_FREE( p ); -} - /**Function************************************************************* Synopsis [Check correctness of cuts.] @@ -181,7 +151,7 @@ static inline int Sbd_CutSetCheckArray( Sbd_Cut_t ** ppCuts, int nCuts ) SeeAlso [] ***********************************************************************/ -static inline int Sbd_CutMergeOrder( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_Cut_t * pCut, int nLutSize ) +static inline int Sbd_CutMergeOrder( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_Cut_t * pCut, int nCutSize ) { int nSize0 = pCut0->nLeaves; int nSize1 = pCut1->nLeaves; @@ -189,14 +159,14 @@ static inline int Sbd_CutMergeOrder( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_C int k, * pC1 = pCut1->pLeaves; int c, * pC = pCut->pLeaves; // the case of the largest cut sizes - if ( nSize0 == nLutSize && nSize1 == nLutSize ) + if ( nSize0 == nCutSize && nSize1 == nCutSize ) { for ( i = 0; i < nSize0; i++ ) { if ( pC0[i] != pC1[i] ) return 0; pC[i] = pC0[i]; } - pCut->nLeaves = nLutSize; + pCut->nLeaves = nCutSize; pCut->iFunc = -1; pCut->Sign = pCut0->Sign | pCut1->Sign; return 1; @@ -207,7 +177,7 @@ static inline int Sbd_CutMergeOrder( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_C if ( nSize1 == 0 ) goto FlushCut0; while ( 1 ) { - if ( c == nLutSize ) return 0; + if ( c == nCutSize ) return 0; if ( pC0[i] < pC1[k] ) { pC[c++] = pC0[i++]; @@ -227,7 +197,7 @@ static inline int Sbd_CutMergeOrder( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_C } FlushCut0: - if ( c + nSize0 > nLutSize + i ) return 0; + if ( c + nSize0 > nCutSize + i ) return 0; while ( i < nSize0 ) pC[c++] = pC0[i++]; pCut->nLeaves = c; @@ -236,7 +206,7 @@ FlushCut0: return 1; FlushCut1: - if ( c + nSize1 > nLutSize + k ) return 0; + if ( c + nSize1 > nCutSize + k ) return 0; while ( k < nSize1 ) pC[c++] = pC1[k++]; pCut->nLeaves = c; @@ -244,7 +214,7 @@ FlushCut1: pCut->Sign = pCut0->Sign | pCut1->Sign; return 1; } -static inline int Sbd_CutMergeOrder2( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_Cut_t * pCut, int nLutSize ) +static inline int Sbd_CutMergeOrder2( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_Cut_t * pCut, int nCutSize ) { int x0, i0 = 0, nSize0 = pCut0->nLeaves, * pC0 = pCut0->pLeaves; int x1, i1 = 0, nSize1 = pCut1->nLeaves, * pC1 = pCut1->pLeaves; @@ -255,7 +225,7 @@ static inline int Sbd_CutMergeOrder2( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_ x1 = (i1 == nSize1) ? ABC_INFINITY : pC1[i1]; xMin = Abc_MinInt(x0, x1); if ( xMin == ABC_INFINITY ) break; - if ( c == nLutSize ) return 0; + if ( c == nCutSize ) return 0; pC[c++] = xMin; if (x0 == xMin) i0++; if (x1 == xMin) i1++; @@ -313,10 +283,30 @@ static inline int Sbd_CutSetLastCutIsContained( Sbd_Cut_t ** pCuts, int nCuts ) ***********************************************************************/ static inline int Sbd_CutCompare( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1 ) { - if ( pCut0->nLeaves < pCut1->nLeaves ) return -1; - if ( pCut0->nLeaves > pCut1->nLeaves ) return 1; - if ( pCut0->Cost < pCut1->Cost ) return -1; - if ( pCut0->Cost > pCut1->Cost ) return 1; + if ( pCut0->nLeaves <= 4 && pCut1->nLeaves <= 4 ) + { + if ( pCut0->nLeaves < pCut1->nLeaves ) return -1; + if ( pCut0->nLeaves > pCut1->nLeaves ) return 1; + if ( pCut0->Cost < pCut1->Cost ) return -1; + if ( pCut0->Cost > pCut1->Cost ) return 1; + if ( pCut0->CostLev < pCut1->CostLev ) return -1; + if ( pCut0->CostLev > pCut1->CostLev ) return 1; + } + else if ( pCut0->nLeaves <= 4 ) + return -1; + else if ( pCut1->nLeaves <= 4 ) + return 1; + else + { + if ( pCut0->nTreeLeaves < pCut1->nTreeLeaves ) return -1; + if ( pCut0->nTreeLeaves > pCut1->nTreeLeaves ) return 1; + if ( pCut0->Cost < pCut1->Cost ) return -1; + if ( pCut0->Cost > pCut1->Cost ) return 1; + if ( pCut0->CostLev < pCut1->CostLev ) return -1; + if ( pCut0->CostLev > pCut1->CostLev ) return 1; + if ( pCut0->nLeaves < pCut1->nLeaves ) return -1; + if ( pCut0->nLeaves > pCut1->nLeaves ) return 1; + } return 0; } static inline int Sbd_CutSetLastCutContains( Sbd_Cut_t ** pCuts, int nCuts ) @@ -389,24 +379,24 @@ static inline int Sbd_CutComputeTruth6( Sbd_Sto_t * p, Sbd_Cut_t * pCut0, Sbd_Cu } static inline int Sbd_CutComputeTruth( Sbd_Sto_t * p, Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, int fCompl0, int fCompl1, Sbd_Cut_t * pCutR, int fIsXor ) { - if ( p->nLutSize <= 6 ) + if ( p->nCutSize <= 6 ) return Sbd_CutComputeTruth6( p, pCut0, pCut1, fCompl0, fCompl1, pCutR, fIsXor ); { word uTruth[SBD_MAX_TT_WORDS], uTruth0[SBD_MAX_TT_WORDS], uTruth1[SBD_MAX_TT_WORDS]; int nOldSupp = pCutR->nLeaves, truthId; - int nLutSize = p->nLutSize, fCompl; - int nWords = Abc_Truth6WordNum(nLutSize); + int nCutSize = p->nCutSize, fCompl; + int nWords = Abc_Truth6WordNum(nCutSize); word * pTruth0 = Sbd_CutTruth(p, pCut0); word * pTruth1 = Sbd_CutTruth(p, pCut1); Abc_TtCopy( uTruth0, pTruth0, nWords, Abc_LitIsCompl(pCut0->iFunc) ^ fCompl0 ); Abc_TtCopy( uTruth1, pTruth1, nWords, Abc_LitIsCompl(pCut1->iFunc) ^ fCompl1 ); - Abc_TtExpand( uTruth0, nLutSize, pCut0->pLeaves, pCut0->nLeaves, pCutR->pLeaves, pCutR->nLeaves ); - Abc_TtExpand( uTruth1, nLutSize, pCut1->pLeaves, pCut1->nLeaves, pCutR->pLeaves, pCutR->nLeaves ); + Abc_TtExpand( uTruth0, nCutSize, pCut0->pLeaves, pCut0->nLeaves, pCutR->pLeaves, pCutR->nLeaves ); + Abc_TtExpand( uTruth1, nCutSize, pCut1->pLeaves, pCut1->nLeaves, pCutR->pLeaves, pCutR->nLeaves ); if ( fIsXor ) Abc_TtXor( uTruth, uTruth0, uTruth1, nWords, (fCompl = (int)((uTruth0[0] ^ uTruth1[0]) & 1)) ); else Abc_TtAnd( uTruth, uTruth0, uTruth1, nWords, (fCompl = (int)((uTruth0[0] & uTruth1[0]) & 1)) ); - pCutR->nLeaves = Abc_TtMinBase( uTruth, pCutR->pLeaves, pCutR->nLeaves, nLutSize ); + pCutR->nLeaves = Abc_TtMinBase( uTruth, pCutR->pLeaves, pCutR->nLeaves, nCutSize ); assert( (uTruth[0] & 1) == 0 ); //Kit_DsdPrintFromTruth( uTruth, pCutR->nLeaves ), printf("\n" ), printf("\n" ); truthId = Vec_MemHashInsert(p->vTtMem, uTruth); @@ -434,15 +424,12 @@ static inline int Sbd_CutCountBits( word i ) i = ((i + (i >> 4)) & 0x0F0F0F0F0F0F0F0F); return (i*(0x0101010101010101))>>56; } -static inline void Sbd_CutPrint( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) +static inline int Sbd_CutIsSpec( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) { - int i, nDigits = Abc_Base10Log(Gia_ManObjNum(p->pGia)); - printf( "%d {", pCut->nLeaves ); + int i, Delay = Vec_IntEntry(p->vDelays, iObj), DelayMax = -ABC_INFINITY; for ( i = 0; i < (int)pCut->nLeaves; i++ ) - printf( " %*d", nDigits, pCut->pLeaves[i] ); - for ( ; i < (int)p->nLutSize; i++ ) - printf( " %*s", nDigits, " " ); - printf( " } Cost = %4d\n", pCut->Cost ); + DelayMax = Abc_MaxInt( DelayMax, Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay ); + return DelayMax < -1; } static inline int Sbd_CutCost( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) { @@ -451,7 +438,21 @@ static inline int Sbd_CutCost( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) Cost += Vec_IntEntry( p->vDelays, pCut->pLeaves[i] ); return Cost; } -static inline void Sbd_CutAddUnitCut( Sbd_Sto_t * p, int iObj ) +static inline int Sbd_CutCostLev( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) +{ + int i, Cost = 0; + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + Cost += Vec_IntEntry( p->vLevels, pCut->pLeaves[i] ); + return Cost; +} +static inline int Sbd_CutTreeLeaves( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) +{ + int i, Cost = 0; + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + Cost += Vec_IntEntry( p->vRefs, pCut->pLeaves[i] ) == 1; + return Cost; +} +static inline void Sbd_CutAddUnit( Sbd_Sto_t * p, int iObj ) { Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj ); if ( Vec_IntSize(vThis) == 0 ) @@ -474,7 +475,10 @@ static inline int Sbd_StoPrepareSet( Sbd_Sto_t * p, int iObj, int Index ) pCutTemp->pLeaves[v-1] = pCut[v]; pCutTemp->iFunc = pCut[pCut[0]+1]; pCutTemp->Sign = Sbd_CutGetSign( pCutTemp ); + pCutTemp->fSpec = Sbd_CutIsSpec( p, iObj, pCutTemp ); pCutTemp->Cost = Sbd_CutCost( p, pCutTemp ); + pCutTemp->CostLev = Sbd_CutCostLev( p, pCutTemp ); + pCutTemp->nTreeLeaves = Sbd_CutTreeLeaves( p, pCutTemp ); } return pList[0]; } @@ -511,18 +515,48 @@ static inline void Sbd_StoComputeDelay( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pC DelayMin = Abc_MinInt( DelayMin, Delay ); } assert( DelayMin < ABC_INFINITY ); - Vec_IntWriteEntry( p->vDelays, iObj, (nCuts > 1 || pCuts[0]->nLeaves > 1) ? DelayMin + 1 : DelayMin ); + DelayMin = (nCuts > 1 || pCuts[0]->nLeaves > 1) ? DelayMin + 1 : DelayMin; + Vec_IntWriteEntry( p->vDelays, iObj, DelayMin ); + p->DelayMin = Abc_MaxInt( p->DelayMin, DelayMin ); +} +static inline void Sbd_StoComputeSpec( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pCuts, int nCuts ) +{ + int i; + for ( i = 0; i < nCuts; i++ ) + { + pCuts[i]->fSpec = Sbd_CutIsSpec( p, iObj, pCuts[i] ); + p->nCutsSpec += pCuts[i]->fSpec; + } +} +static inline void Sbd_CutPrint( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) +{ + int i, nDigits = Abc_Base10Log(Gia_ManObjNum(p->pGia)); + int Delay = Vec_IntEntry(p->vDelays, iObj); + printf( "%d {", pCut->nLeaves ); + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + printf( " %*d", nDigits, pCut->pLeaves[i] ); + for ( ; i < (int)p->nCutSize; i++ ) + printf( " %*s", nDigits, " " ); + printf( " } Cost = %4d CostLev = %4d Tree = %2d ", pCut->Cost, pCut->CostLev, pCut->nTreeLeaves ); + printf( "%c ", pCut->fSpec ? '*' : ' ' ); + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + printf( "%3d ", Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay ); + printf( "\n" ); } void Sbd_StoMergeCuts( Sbd_Sto_t * p, int iObj ) { Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj); int fIsXor = Gia_ObjIsXor(pObj); - int nLutSize = p->nLutSize; + int nCutSize = p->nCutSize; int nCutNum = p->nCutNum; - int fComp0 = Gia_ObjFaninC0(pObj); - int fComp1 = Gia_ObjFaninC1(pObj); - int nCuts0 = Sbd_StoPrepareSet( p, Gia_ObjFaninId0(pObj, iObj), 0 ); - int nCuts1 = Sbd_StoPrepareSet( p, Gia_ObjFaninId1(pObj, iObj), 1 ); + int Lit0m = p->vMirrors ? Vec_IntEntry( p->vMirrors, Gia_ObjFaninId0(pObj, iObj) ) : -1; + int Lit1m = p->vMirrors ? Vec_IntEntry( p->vMirrors, Gia_ObjFaninId1(pObj, iObj) ) : -1; + int fComp0 = Gia_ObjFaninC0(pObj) ^ (Lit0m >= 0 && Abc_LitIsCompl(Lit0m)); + int fComp1 = Gia_ObjFaninC1(pObj) ^ (Lit1m >= 0 && Abc_LitIsCompl(Lit1m)); + int Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, iObj); + int Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, iObj); + int nCuts0 = Sbd_StoPrepareSet( p, Fan0, 0 ); + int nCuts1 = Sbd_StoPrepareSet( p, Fan1, 1 ); int i, k, nCutsR = 0; Sbd_Cut_t * pCut0, * pCut1, ** pCutsR = p->ppCuts; assert( !Gia_ObjIsBuf(pObj) ); @@ -532,10 +566,10 @@ void Sbd_StoMergeCuts( Sbd_Sto_t * p, int iObj ) for ( i = 0, pCut0 = p->pCuts[0]; i < nCuts0; i++, pCut0++ ) for ( k = 0, pCut1 = p->pCuts[1]; k < nCuts1; k++, pCut1++ ) { - if ( (int)(pCut0->nLeaves + pCut1->nLeaves) > nLutSize && Sbd_CutCountBits(pCut0->Sign | pCut1->Sign) > nLutSize ) + if ( (int)(pCut0->nLeaves + pCut1->nLeaves) > nCutSize && Sbd_CutCountBits(pCut0->Sign | pCut1->Sign) > nCutSize ) continue; p->CutCount[1]++; - if ( !Sbd_CutMergeOrder(pCut0, pCut1, pCutsR[nCutsR], nLutSize) ) + if ( !Sbd_CutMergeOrder(pCut0, pCut1, pCutsR[nCutsR], nCutSize) ) continue; if ( Sbd_CutSetLastCutIsContained(pCutsR, nCutsR) ) continue; @@ -543,16 +577,21 @@ void Sbd_StoMergeCuts( Sbd_Sto_t * p, int iObj ) if ( p->fCutMin && Sbd_CutComputeTruth(p, pCut0, pCut1, fComp0, fComp1, pCutsR[nCutsR], fIsXor) ) pCutsR[nCutsR]->Sign = Sbd_CutGetSign(pCutsR[nCutsR]); pCutsR[nCutsR]->Cost = Sbd_CutCost( p, pCutsR[nCutsR] ); + pCutsR[nCutsR]->CostLev = Sbd_CutCostLev( p, pCutsR[nCutsR] ); + pCutsR[nCutsR]->nTreeLeaves = Sbd_CutTreeLeaves( p, pCutsR[nCutsR] ); nCutsR = Sbd_CutSetAddCut( pCutsR, nCutsR, nCutNum ); } Sbd_StoComputeDelay( p, iObj, pCutsR, nCutsR ); + Sbd_StoComputeSpec( p, iObj, pCutsR, nCutsR ); p->CutCount[3] += nCutsR; + p->nCutsOver += nCutsR == nCutNum-1; // debug printout if ( 0 ) { - printf( "*** Obj = %d Delay = %d\n", iObj, Vec_IntEntry(p->vDelays, iObj) ); + printf( "*** Obj = %4d Delay = %4d NumCuts = %4d\n", iObj, Vec_IntEntry(p->vDelays, iObj), nCutsR ); for ( i = 0; i < nCutsR; i++ ) - Sbd_CutPrint( p, pCutsR[i] ); + if ( (int)pCutsR[i]->nLeaves <= p->nLutSize || pCutsR[i]->fSpec ) + Sbd_CutPrint( p, iObj, pCutsR[i] ); printf( "\n" ); } // verify @@ -561,21 +600,12 @@ void Sbd_StoMergeCuts( Sbd_Sto_t * p, int iObj ) // store the cutset Sbd_StoStoreResult( p, iObj, pCutsR, nCutsR ); if ( nCutsR > 1 || pCutsR[0]->nLeaves > 1 ) - Sbd_CutAddUnitCut( p, iObj ); -} -int Sbd_StoMergeCutsPlus( Sbd_Sto_t * p, int iObj ) -{ - assert( iObj == Vec_IntSize(p->vDelays) ); - assert( iObj == Vec_WecSize(p->vCuts) ); - Vec_IntPush( p->vDelays, 0 ); - Vec_WecPushLevel( p->vCuts ); - Sbd_StoMergeCuts( p, iObj ); - return Vec_IntEntry( p->vDelays, iObj ); + Sbd_CutAddUnit( p, iObj ); } /**Function************************************************************* - Synopsis [] + Synopsis [Incremental cut computation.] Description [] @@ -584,30 +614,123 @@ int Sbd_StoMergeCutsPlus( Sbd_Sto_t * p, int iObj ) SeeAlso [] ***********************************************************************/ -void Sbd_StoComputeCuts( Sbd_Sto_t * p ) +Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, Vec_Int_t * vMirrors, int nLutSize, int nCutSize, int nCutNum, int fCutMin, int fVerbose ) { - Gia_Obj_t * pObj; - int i, iObj; - Gia_ManForEachCiId( p->pGia, iObj, i ) - Sbd_CutAddUnitCut( p, iObj ); - Gia_ManForEachAnd( p->pGia, pObj, iObj ) - Sbd_StoMergeCuts( p, iObj ); - if ( !p->fVerbose ) + Sbd_Sto_t * p; + assert( nLutSize <= nCutSize ); + assert( nCutSize < SBD_CUT_NO_LEAF ); + assert( nCutSize > 1 && nCutSize <= SBD_MAX_CUTSIZE ); + assert( nCutNum > 1 && nCutNum < SBD_MAX_CUTNUM ); + p = ABC_CALLOC( Sbd_Sto_t, 1 ); + p->clkStart = Abc_Clock(); + p->nLutSize = nLutSize; + p->nCutSize = nCutSize; + p->nCutNum = nCutNum; + p->fCutMin = fCutMin; + p->fVerbose = fVerbose; + p->pGia = pGia; + p->vMirrors = vMirrors; + p->vDelays = Vec_IntAlloc( Gia_ManObjNum(pGia) ); + p->vLevels = Vec_IntAlloc( Gia_ManObjNum(pGia) ); + p->vRefs = Vec_IntAlloc( Gia_ManObjNum(pGia) ); + p->vCuts = Vec_WecAlloc( Gia_ManObjNum(pGia) ); + p->vTtMem = fCutMin ? Vec_MemAllocForTT( nCutSize, 0 ) : NULL; + return p; +} +void Sbd_StoFree( Sbd_Sto_t * p ) +{ + Vec_IntFree( p->vDelays ); + Vec_IntFree( p->vLevels ); + Vec_IntFree( p->vRefs ); + Vec_WecFree( p->vCuts ); + if ( p->fCutMin ) + Vec_MemHashFree( p->vTtMem ); + if ( p->fCutMin ) + Vec_MemFree( p->vTtMem ); + ABC_FREE( p ); +} +void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ) +{ + assert( iObj == Vec_IntSize(p->vDelays) ); + assert( iObj == Vec_IntSize(p->vLevels) ); + assert( iObj == Vec_WecSize(p->vCuts) ); + Vec_IntPush( p->vDelays, Delay ); + Vec_IntPush( p->vLevels, Level ); + Vec_WecPushLevel( p->vCuts ); +} +void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ) +{ + Sbd_StoComputeCutsObj( p, iObj, Delay, Level ); + Sbd_CutAddUnit( p, iObj ); +} +int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ) +{ + Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj); + int Lev0 = Vec_IntEntry( p->vLevels, Gia_ObjFaninId0(pObj, iObj) ); + int Lev1 = Vec_IntEntry( p->vLevels, Gia_ObjFaninId1(pObj, iObj) ); + Sbd_StoComputeCutsObj( p, iObj, -1, 1 + Abc_MaxInt(Lev0, Lev1) ); + Sbd_StoMergeCuts( p, iObj ); + return Vec_IntEntry( p->vDelays, iObj ); +} +void Sbd_StoRefObj( Sbd_Sto_t * p, int iObj, int iMirror ) +{ + Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj); + assert( iObj == Vec_IntSize(p->vRefs) ); + assert( iMirror < iObj ); + Vec_IntPush( p->vRefs, iMirror > 0 ? Vec_IntEntry(p->vRefs, iMirror) : 0 ); + if ( Gia_ObjIsAnd(pObj) ) + { + Vec_IntAddToEntry( p->vRefs, Gia_ObjFaninId0(pObj, iObj), 1 ); + Vec_IntAddToEntry( p->vRefs, Gia_ObjFaninId1(pObj, iObj), 1 ); + } + else if ( Gia_ObjIsCo(pObj) ) + Vec_IntAddToEntry( p->vRefs, Gia_ObjFaninId0(pObj, iObj), 1 ); +} +void Sbd_StoDerefObj( Sbd_Sto_t * p, int iObj ) +{ + Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj); + Vec_IntAddToEntry( p->vRefs, iObj, -1 ); + if ( Vec_IntEntry( p->vRefs, iObj ) > 0 ) return; - printf( "CutPair = %.0f ", p->CutCount[0] ); - printf( "Merge = %.0f (%.2f %%) ", p->CutCount[1], 100.0*p->CutCount[1]/p->CutCount[0] ); - printf( "Eval = %.0f (%.2f %%) ", p->CutCount[2], 100.0*p->CutCount[2]/p->CutCount[0] ); - printf( "Cut = %.0f (%.2f %%) ", p->CutCount[3], 100.0*p->CutCount[3]/p->CutCount[0] ); - printf( "\n" ); + if ( Gia_ObjIsCi(pObj) ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Sbd_StoDerefObj( p, Gia_ObjFaninId0(pObj, iObj) ); + Sbd_StoDerefObj( p, Gia_ObjFaninId1(pObj, iObj) ); } void Sbd_StoComputeCutsTest( Gia_Man_t * pGia ) { - Sbd_Sto_t * p = Sbd_StoAlloc( pGia, 8, 32, 1, 1 ); - Sbd_StoComputeCuts( p ); + Sbd_Sto_t * p = Sbd_StoAlloc( pGia, NULL, 4, 8, 100, 1, 1 ); + Gia_Obj_t * pObj; + int i, iObj; + // prepare references + Gia_ManForEachObj( p->pGia, pObj, iObj ) + Sbd_StoRefObj( p, iObj, -1 ); + // compute cuts + Sbd_StoComputeCutsObj( p, 0, 0, 0 ); + Gia_ManForEachCiId( p->pGia, iObj, i ) + Sbd_StoComputeCutsCi( p, iObj, 0, 0 ); + Gia_ManForEachAnd( p->pGia, pObj, iObj ) + Sbd_StoComputeCutsNode( p, iObj ); + if ( p->fVerbose ) + { + printf( "Running cut computation with LutSize = %d CutSize = %d CutNum = %d:\n", p->nLutSize, p->nCutSize, p->nCutNum ); + printf( "CutPair = %.0f ", p->CutCount[0] ); + printf( "Merge = %.0f (%.2f %%) ", p->CutCount[1], 100.0*p->CutCount[1]/p->CutCount[0] ); + printf( "Eval = %.0f (%.2f %%) ", p->CutCount[2], 100.0*p->CutCount[2]/p->CutCount[0] ); + printf( "Cut = %.0f (%.2f %%) ", p->CutCount[3], 100.0*p->CutCount[3]/p->CutCount[0] ); + printf( "Cut/Node = %.2f ", p->CutCount[3] / Gia_ManAndNum(p->pGia) ); + printf( "\n" ); + printf( "Spec = %4d ", p->nCutsSpec ); + printf( "Over = %4d ", p->nCutsOver ); + printf( "Lev = %4d ", p->DelayMin ); + Abc_PrintTime( 0, "Time", Abc_Clock() - p->clkStart ); + } Sbd_StoFree( p ); } + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/opt/sbd/sbdInt.h b/src/opt/sbd/sbdInt.h index 5395e148e..54174f768 100644 --- a/src/opt/sbd/sbdInt.h +++ b/src/opt/sbd/sbdInt.h @@ -60,6 +60,8 @@ ABC_NAMESPACE_HEADER_START /// BASIC TYPES /// //////////////////////////////////////////////////////////////////////// +typedef struct Sbd_Sto_t_ Sbd_Sto_t; + typedef struct Sbd_Str_t_ Sbd_Str_t; struct Sbd_Str_t_ { @@ -78,7 +80,14 @@ struct Sbd_Str_t_ /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -/*=== sbdCnf.c ==========================================================*/ +/*=== sbdCut.c ==========================================================*/ +extern Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, Vec_Int_t * vMirrors, int nLutSize, int nCutSize, int nCutNum, int fCutMin, int fVerbose ); +extern void Sbd_StoFree( Sbd_Sto_t * p ); +extern void Sbd_StoRefObj( Sbd_Sto_t * p, int iObj, int iMirror ); +extern void Sbd_StoDefefObj( Sbd_Sto_t * p, int iObj ); +extern void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ); +extern void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ); +extern int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ); ABC_NAMESPACE_HEADER_END From 4488ab83d0c36f65a349122f58c44b55025ff856 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 29 Dec 2016 14:45:16 +0700 Subject: [PATCH 017/185] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 270 +++++++++++++++++++++++++++++++++++++-- src/opt/sbd/sbdCut.c | 92 +++++++++---- src/opt/sbd/sbdInt.h | 4 +- src/sat/bsat/satSolver.h | 7 +- 4 files changed, 333 insertions(+), 40 deletions(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 15874dc67..daefb9aff 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -43,6 +43,7 @@ struct Sbd_Man_t_ Vec_Wrd_t * vSims[4]; // simulation information (main, backup, controlability) Vec_Int_t * vCover; // temporary Vec_Int_t * vLits; // temporary + Vec_Int_t * vLits2; // temporary int nConsts; // constants int nChanges; // changes abctime timeWin; @@ -52,6 +53,7 @@ struct Sbd_Man_t_ abctime timeEnu; abctime timeOther; abctime timeTotal; + Sbd_Sto_t * pSto; // target node int Pivot; // target node int DivCutoff; // the place where D-2 divisors begin @@ -201,6 +203,7 @@ Sbd_Man_t * Sbd_ManStart( Gia_Man_t * pGia, Sbd_Par_t * pPars ) // target node p->vCover = Vec_IntAlloc( 100 ); p->vLits = Vec_IntAlloc( 100 ); + p->vLits2 = Vec_IntAlloc( 100 ); p->vRoots = Vec_IntAlloc( 100 ); p->vWinObjs = Vec_IntAlloc( Gia_ManObjNum(pGia) ); p->vObj2Var = Vec_IntStart( Gia_ManObjNum(pGia) ); @@ -223,6 +226,8 @@ Sbd_Man_t * Sbd_ManStart( Gia_Man_t * pGia, Sbd_Par_t * pPars ) Gia_ManForEachCiId( pGia, Id, i ) for ( w = 0; w < p->pPars->nWords; w++ ) Sbd_ObjSim0(p, Id)[w] = Gia_ManRandomW( 0 ); + // cut enumeration + p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, 2*pPars->nLutSize-1, 64, 1, 1 ); return p; } void Sbd_ManStop( Sbd_Man_t * p ) @@ -236,6 +241,7 @@ void Sbd_ManStop( Sbd_Man_t * p ) Vec_WrdFree( p->vSims[i] ); Vec_IntFree( p->vCover ); Vec_IntFree( p->vLits ); + Vec_IntFree( p->vLits2 ); Vec_IntFree( p->vRoots ); Vec_IntFree( p->vWinObjs ); Vec_IntFree( p->vObj2Var ); @@ -246,7 +252,8 @@ void Sbd_ManStop( Sbd_Man_t * p ) Vec_IntFree( p->vCounts[0] ); Vec_IntFree( p->vCounts[1] ); Vec_WrdFree( p->vMatrix ); - if ( p->pSat ) sat_solver_delete( p->pSat ); + sat_solver_delete_p( &p->pSat ); + Sbd_StoFree( p->pSto ); ABC_FREE( p ); } @@ -1158,10 +1165,7 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) int nConsts = 4; int RetValue; - if ( p->pSat ) - sat_solver_delete( p->pSat ); - p->pSat = NULL; - + sat_solver_delete_p( &p->pSat ); p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); p->timeCnf += Abc_Clock() - clk; @@ -1262,6 +1266,125 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) return 0; } +int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) +{ + extern int Sbd_ProblemSolve( + Gia_Man_t * p, Vec_Int_t * vMirrors, + int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, + Vec_Int_t * vTfo, Vec_Int_t * vRoots, + Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0 + ); + extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); + extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); + abctime clk = Abc_Clock(); + + int PivotVar = Vec_IntEntry(p->vObj2Var, Pivot); + int FreeVar = Vec_IntSize(p->vWinObjs) + Vec_IntSize(p->vTfo) + Vec_IntSize(p->vRoots); + int nDivs = Vec_IntSize( p->vDivVars ); + int Delay = Vec_IntEntry( p->vLutLevs, Pivot ); + int i, k, iObj, nIters; + + int nLeaves, pLeaves[SBD_DIV_MAX]; + + int pNodesTop[SBD_DIV_MAX], pNodesBot[SBD_DIV_MAX], pNodeRefs[SBD_DIV_MAX]; + int nNodesTop = 0, nNodesBot = 0, nNodesDiff = 0; + + sat_solver_delete_p( &p->pSat ); + p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); + p->timeCnf += Abc_Clock() - clk; + + // extract one cut + nLeaves = Sbd_StoObjBestCut( p->pSto, Pivot, pLeaves ); + + // solve the covering problem + for ( nIters = 0; nIters < nLeaves; nIters++ ) + { + word Truth; + // try to remove one variable from divisors + Vec_IntClear( p->vDivSet ); + for ( i = 0; i < nLeaves; i++ ) + if ( i != nIters && pLeaves[i] != -1 ) + Vec_IntPush( p->vDivSet, Vec_IntEntry(p->vObj2Var, pLeaves[i]) ); + assert( Vec_IntSize(p->vDivSet) < nLeaves ); + + Truth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); + if ( Truth == SBD_SAT_UNDEC ) + printf( "Node %d: Undecided.\n", Pivot ); + else if ( Truth == SBD_SAT_SAT ) + continue; + else + pLeaves[nIters] = -1; + } + + Vec_IntClear( p->vDivSet ); + for ( i = 0; i < nLeaves; i++ ) + if ( pLeaves[i] != -1 ) + Vec_IntPush( p->vDivSet, pLeaves[i] ); + printf( "Reduced %d -> %d\n", nLeaves, Vec_IntSize(p->vDivSet) ); + assert( Vec_IntSize(p->vDivSet) > p->pPars->nLutSize ); + + //Delay++; + + // count number of nodes on each level + nNodesTop = 0, nNodesBot = 0; + Vec_IntForEachEntry( p->vDivSet, iObj, i ) + { + int DelayDiff = Vec_IntEntry(p->vLutLevs, iObj) - Delay; + if ( DelayDiff > -2 ) + break; + if ( DelayDiff == -2 ) + pNodesTop[nNodesTop++] = i; + else // if ( DelayDiff < -2 ) + pNodesBot[nNodesBot++] = i; + Vec_IntWriteEntry( p->vDivSet, iObj, Vec_IntEntry(p->vObj2Var, pLeaves[i]) ); + pNodeRefs[i] = Gia_ObjRefNumId( p->pGia, iObj ); + } + if ( i < Vec_IntSize(p->vDivSet) ) + return 0; + if ( nNodesTop > p->pPars->nLutSize-1 ) + return 0; + if ( nNodesBot > p->pPars->nLutSize ) + { + // move left-over to the top + while ( nNodesBot > p->pPars->nLutSize ) + pNodesTop[nNodesTop++] = pNodesBot[--nNodesBot]; + assert( nNodesBot == p->pPars->nLutSize ); + assert( nNodesTop <= p->pPars->nLutSize-1 ); + } + nNodesDiff = p->pPars->nLutSize-1 - nNodesTop; + + // number of structures + *pnStrs = 2 + nNodesDiff; + + Strs[0].fLut = 1; + Strs[0].nVarIns = p->pPars->nLutSize; + for ( i = 0; i < nNodesTop; i++ ) + Strs[0].VarIns[i] = pNodesTop[i]; + for ( ; i < p->pPars->nLutSize; i++ ) + Strs[0].VarIns[i] = Vec_IntSize(p->vDivSet)+1 + i-nNodesTop; + Strs[0].Res = 0; + + Strs[1].fLut = 1; + Strs[1].nVarIns = nNodesBot; + for ( i = 0; i < nNodesBot; i++ ) + Strs[1].VarIns[i] = pNodesBot[i]; + Strs[1].Res = 0; + + for ( k = 0; k < nNodesDiff; k++ ) + { + Strs[2+k].fLut = 0; + Strs[2+k].nVarIns = nNodesBot; + for ( i = 0; i < nNodesBot; i++ ) + Strs[2+k].VarIns[i] = pNodesBot[i]; + Strs[2+k].Res = 0; + } + + return Sbd_ProblemSolve( p->pGia, p->vMirrors, + Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, + p->vDivSet, *pnStrs, Strs ); +} + + /**Function************************************************************* Synopsis [Computes delay-oriented k-feasible cut at the node.] @@ -1503,6 +1626,87 @@ int Sbd_ManImplement( Sbd_Man_t * p, int Pivot, word Truth ) return 0; } +int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) +{ + int i, k, w, iLit, Node; + int iObjLast = Gia_ManObjNum(p->pGia); + int iCurLev = Vec_IntEntry(p->vLutLevs, Pivot); + int iNewLev; + // collect leaf literals + Vec_IntClear( p->vLits ); + Vec_IntForEachEntry( p->vDivSet, Node, i ) + { + Node = Vec_IntEntry( p->vWinObjs, Node ); + if ( Vec_IntEntry(p->vMirrors, Node) >= 0 ) + Vec_IntPush( p->vLits, Vec_IntEntry(p->vMirrors, Node) ); + else + Vec_IntPush( p->vLits, Abc_Var2Lit(Node, 0) ); + } + // collect structure nodes + for ( i = 0; i < nStrs; i++ ) + Vec_IntPush( p->vLits, -1 ); + // implement structures + for ( i = nStrs-1; i >= 0; i-- ) + { + if ( pStrs[i].fLut ) + { + // collect local literals + Vec_IntClear( p->vLits2 ); + for ( k = 0; k < (int)pStrs[i].nVarIns; k++ ) + Vec_IntPush( p->vLits2, Vec_IntEntry(p->vLits, pStrs[i].VarIns[k]) ); + // pretend to have MUXes + // assert( p->pGia->pMuxes == NULL ); + if ( p->pGia->nXors && p->pGia->pMuxes == NULL ) + p->pGia->pMuxes = (unsigned *)p; + // derive new function of the node + iLit = Dsm_ManTruthToGia( p->pGia, &pStrs[i].Res, p->vLits2, p->vCover ); + if ( p->pGia->pMuxes == (unsigned *)p ) + p->pGia->pMuxes = NULL; + } + else + { + iLit = Vec_IntEntry( p->vLits, (int)pStrs[i].Res ); + assert( iLit > 0 ); + } + // update literal + assert( Vec_IntEntry(p->vLits, Vec_IntSize(p->vLits)-nStrs+i) == -1 ); + Vec_IntWriteEntry( p->vLits, Vec_IntSize(p->vLits)-nStrs+i, iLit ); + } + iLit = Vec_IntEntry( p->vLits, Vec_IntSize(p->vDivSet) ); + assert( iObjLast == Gia_ManObjNum(p->pGia) || Abc_Lit2Var(iLit) == Gia_ManObjNum(p->pGia)-1 ); + // remember this function + assert( Vec_IntEntry(p->vMirrors, Pivot) == -1 ); + Vec_IntWriteEntry( p->vMirrors, Pivot, iLit ); + if ( p->pPars->fVerbose ) + printf( "Replacing node %d by literal %d.\n", Pivot, iLit ); + + // extend data-structure to accommodate new nodes + assert( Vec_IntSize(p->vLutLevs) == iObjLast ); + for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) + Sbd_StoRefObj( p->pSto, i, i == Gia_ManObjNum(p->pGia)-1 ? Pivot : -1 ); + for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) + { + int Delay = Sbd_StoComputeCutsNode( p->pSto, i ); + assert( i == Vec_IntSize(p->vLutLevs) ); + Vec_IntPush( p->vLutLevs, Delay ); + Vec_IntPush( p->vObj2Var, 0 ); + Vec_IntPush( p->vMirrors, -1 ); + Vec_IntFillExtra( p->vLutCuts, Vec_IntSize(p->vLutCuts) + p->pPars->nLutSize + 1, 0 ); + //Sbd_ManFindCut( p, i, p->vLits ); + for ( k = 0; k < 4; k++ ) + for ( w = 0; w < p->pPars->nWords; w++ ) + Vec_WrdPush( p->vSims[k], 0 ); + } + // make sure delay reduction is achieved + iNewLev = Vec_IntEntry( p->vLutLevs, Abc_Lit2Var(iLit) ); + assert( iNewLev < iCurLev ); + // update delay of the initial node + assert( Vec_IntEntry(p->vLutLevs, Pivot) == iCurLev ); + Vec_IntWriteEntry( p->vLutLevs, Pivot, iNewLev ); + p->nChanges++; + return 0; +} + /**Function************************************************************* Synopsis [Derives new AIG after resynthesis.] @@ -1537,7 +1741,7 @@ void Sbd_ManDerive_rec( Gia_Man_t * pNew, Gia_Man_t * p, int Node, Vec_Int_t * v } Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) { - Gia_Man_t * pNew; + Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; int i; Gia_ManFillValue( p ); @@ -1557,6 +1761,10 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) Gia_ManHashStop( pNew ); Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); Gia_ManTransferTiming( pNew, p ); + // remove dangling nodes + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManTransferTiming( pNew, pTemp ); + Gia_ManStop( pTemp ); return pNew; } @@ -1574,12 +1782,17 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) { // extern void Sbd_ManSolveSelect( Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots ); + Sbd_Str_t Strs[4]; + int nStrs = 0; int RetValue; word Truth = 0; - if ( Sbd_ManMergeCuts( p, Pivot ) ) - return; + if ( !p->pSto ) + { + if ( Sbd_ManMergeCuts( p, Pivot ) ) + return; + } -// if ( Pivot != 70 ) +// if ( Pivot != 15 ) // return; if ( p->pPars->fVerbose ) @@ -1595,11 +1808,28 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) Vec_IntWriteEntry( p->vMirrors, Pivot, RetValue ); //printf( " --> Pivot %4d. Constant %d.\n", Pivot, RetValue ); } - else if ( Sbd_ManExplore2( p, Pivot, &Truth ) ) + else if ( Sbd_ManExplore3( p, Pivot, &nStrs, Strs ) ) { - Sbd_ManImplement( p, Pivot, Truth ); + //Sbd_ManImplement( p, Pivot, Truth ); + Sbd_ManImplement2( p, Pivot, nStrs, Strs ); //printf( " --> Pivot %4d. Supp %d.\n", Pivot, Vec_IntSize(p->vDivSet) ); } +/* + else if ( Sbd_ManExplore2( p, Pivot, &Truth ) ) + { + int i; + Sbd_Str_t Strs; + Strs.fLut = 1; + Strs.nVarIns = Vec_IntSize( p->vDivSet ); + for ( i = 0; i < Strs.nVarIns; i++ ) + Strs.VarIns[i] = i; + Strs.Res = Truth; + //Sbd_ManImplement( p, Pivot, Truth ); + Sbd_ManImplement2( p, Pivot, 1, &Strs ); + //printf( " --> Pivot %4d. Supp %d.\n", Pivot, Vec_IntSize(p->vDivSet) ); + } +*/ + /* else { @@ -1642,6 +1872,9 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) int k, Pivot; assert( pPars->nLutSize <= 6 ); //Sbd_ManMergeTest( p ); + // prepare references + Gia_ManForEachObj( p->pGia, pObj, Pivot ) + Sbd_StoRefObj( p->pSto, Pivot, -1 ); //return NULL; if ( pGia->pManTime != NULL && Tim_ManBoxNum((Tim_Man_t*)pGia->pManTime) ) { @@ -1676,10 +1909,19 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) } else { - Gia_ManForEachAndId( pGia, Pivot ) + Gia_ManForEachObj( pGia, pObj, Pivot ) { - if ( Pivot < nNodesOld ) - Sbd_NtkPerformOne( p, Pivot ); + if ( Pivot == nNodesOld ) + break; + if ( Gia_ObjIsAnd(pObj) ) + { + int Delay = Sbd_StoComputeCutsNode( p->pSto, Pivot ); + Vec_IntWriteEntry( p->vLutLevs, Pivot, Delay ); + if ( Delay > 1 ) + Sbd_NtkPerformOne( p, Pivot ); + } + else if ( !Gia_ObjIsCo(pObj) ) + Sbd_StoComputeCutsCi( p->pSto, Pivot, 0, 0 ); } } printf( "Found %d constants and %d replacements with delay %d. ", p->nConsts, p->nChanges, Sbd_ManDelay(p) ); diff --git a/src/opt/sbd/sbdCut.c b/src/opt/sbd/sbdCut.c index 154df9145..d4c085a1e 100644 --- a/src/opt/sbd/sbdCut.c +++ b/src/opt/sbd/sbdCut.c @@ -40,9 +40,9 @@ struct Sbd_Cut_t_ int iFunc; // functionality int Cost; // cut cost int CostLev; // cut cost - unsigned fSpec : 1; // special cut - unsigned nTreeLeaves : 27; // cut cost - unsigned nLeaves : 4; // the number of leaves + unsigned nSlowLeaves : 14; // slow leaves + unsigned nTreeLeaves : 14; // tree leaves + unsigned nLeaves : 4; // leaf count int pLeaves[SBD_MAX_CUTSIZE]; // leaves }; @@ -62,11 +62,13 @@ struct Sbd_Sto_t_ Vec_Mem_t * vTtMem; // truth tables Sbd_Cut_t pCuts[3][SBD_MAX_CUTNUM]; // temporary cuts Sbd_Cut_t * ppCuts[SBD_MAX_CUTNUM]; // temporary cut pointers - abctime clkStart; // starting time + int nCutsR; // the number of cuts + int Pivot; // current object double CutCount[4]; // cut counters int nCutsSpec; // special cuts int nCutsOver; // overflow cuts int DelayMin; // minimum delay + abctime clkStart; // starting time }; static inline word * Sbd_CutTruth( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) { return Vec_MemReadEntry(p->vTtMem, Abc_Lit2Var(pCut->iFunc)); } @@ -309,6 +311,22 @@ static inline int Sbd_CutCompare( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1 ) } return 0; } +static inline int Sbd_CutCompare2( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1 ) +{ + assert( pCut0->nLeaves > 4 && pCut1->nLeaves > 4 ); + if ( pCut0->nSlowLeaves < pCut1->nSlowLeaves ) return -1; + if ( pCut0->nSlowLeaves > pCut1->nSlowLeaves ) return 1; + if ( pCut0->nTreeLeaves < pCut1->nTreeLeaves ) return -1; + if ( pCut0->nTreeLeaves > pCut1->nTreeLeaves ) return 1; + if ( pCut0->Cost < pCut1->Cost ) return -1; + if ( pCut0->Cost > pCut1->Cost ) return 1; + if ( pCut0->CostLev < pCut1->CostLev ) return -1; + if ( pCut0->CostLev > pCut1->CostLev ) return 1; + if ( pCut0->nLeaves < pCut1->nLeaves ) return -1; + if ( pCut0->nLeaves > pCut1->nLeaves ) return 1; + return 0; +} + static inline int Sbd_CutSetLastCutContains( Sbd_Cut_t ** pCuts, int nCuts ) { int i, k, fChanges = 0; @@ -424,12 +442,12 @@ static inline int Sbd_CutCountBits( word i ) i = ((i + (i >> 4)) & 0x0F0F0F0F0F0F0F0F); return (i*(0x0101010101010101))>>56; } -static inline int Sbd_CutIsSpec( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) +static inline int Sbd_CutSlowLeaves( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) { - int i, Delay = Vec_IntEntry(p->vDelays, iObj), DelayMax = -ABC_INFINITY; + int i, Count = 0, Delay = Vec_IntEntry(p->vDelays, iObj); for ( i = 0; i < (int)pCut->nLeaves; i++ ) - DelayMax = Abc_MaxInt( DelayMax, Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay ); - return DelayMax < -1; + Count += (Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay >= -1); + return Count; } static inline int Sbd_CutCost( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) { @@ -475,9 +493,9 @@ static inline int Sbd_StoPrepareSet( Sbd_Sto_t * p, int iObj, int Index ) pCutTemp->pLeaves[v-1] = pCut[v]; pCutTemp->iFunc = pCut[pCut[0]+1]; pCutTemp->Sign = Sbd_CutGetSign( pCutTemp ); - pCutTemp->fSpec = Sbd_CutIsSpec( p, iObj, pCutTemp ); pCutTemp->Cost = Sbd_CutCost( p, pCutTemp ); pCutTemp->CostLev = Sbd_CutCostLev( p, pCutTemp ); + pCutTemp->nSlowLeaves = Sbd_CutSlowLeaves( p, iObj, pCutTemp ); pCutTemp->nTreeLeaves = Sbd_CutTreeLeaves( p, pCutTemp ); } return pList[0]; @@ -524,8 +542,8 @@ static inline void Sbd_StoComputeSpec( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pCu int i; for ( i = 0; i < nCuts; i++ ) { - pCuts[i]->fSpec = Sbd_CutIsSpec( p, iObj, pCuts[i] ); - p->nCutsSpec += pCuts[i]->fSpec; + pCuts[i]->nSlowLeaves = Sbd_CutSlowLeaves( p, iObj, pCuts[i] ); + p->nCutsSpec += (pCuts[i]->nSlowLeaves == 0); } } static inline void Sbd_CutPrint( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) @@ -537,8 +555,9 @@ static inline void Sbd_CutPrint( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) printf( " %*d", nDigits, pCut->pLeaves[i] ); for ( ; i < (int)p->nCutSize; i++ ) printf( " %*s", nDigits, " " ); - printf( " } Cost = %4d CostLev = %4d Tree = %2d ", pCut->Cost, pCut->CostLev, pCut->nTreeLeaves ); - printf( "%c ", pCut->fSpec ? '*' : ' ' ); + printf( " } Cost = %3d CostL = %3d Slow = %d Tree = %d ", + pCut->Cost, pCut->CostLev, pCut->nSlowLeaves, pCut->nTreeLeaves ); + printf( "%c ", pCut->nSlowLeaves == 0 ? '*' : ' ' ); for ( i = 0; i < (int)pCut->nLeaves; i++ ) printf( "%3d ", Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay ); printf( "\n" ); @@ -585,12 +604,14 @@ void Sbd_StoMergeCuts( Sbd_Sto_t * p, int iObj ) Sbd_StoComputeSpec( p, iObj, pCutsR, nCutsR ); p->CutCount[3] += nCutsR; p->nCutsOver += nCutsR == nCutNum-1; + p->nCutsR = nCutsR; + p->Pivot = iObj; // debug printout - if ( 0 ) + if ( 1 ) { printf( "*** Obj = %4d Delay = %4d NumCuts = %4d\n", iObj, Vec_IntEntry(p->vDelays, iObj), nCutsR ); for ( i = 0; i < nCutsR; i++ ) - if ( (int)pCutsR[i]->nLeaves <= p->nLutSize || pCutsR[i]->fSpec ) + if ( (int)pCutsR[i]->nLeaves <= p->nLutSize || pCutsR[i]->nSlowLeaves < 2 ) Sbd_CutPrint( p, iObj, pCutsR[i] ); printf( "\n" ); } @@ -630,10 +651,10 @@ Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, Vec_Int_t * vMirrors, int nLutSize, p->fVerbose = fVerbose; p->pGia = pGia; p->vMirrors = vMirrors; - p->vDelays = Vec_IntAlloc( Gia_ManObjNum(pGia) ); - p->vLevels = Vec_IntAlloc( Gia_ManObjNum(pGia) ); + p->vDelays = Vec_IntStart( Gia_ManObjNum(pGia) ); + p->vLevels = Vec_IntStart( Gia_ManObjNum(pGia) ); p->vRefs = Vec_IntAlloc( Gia_ManObjNum(pGia) ); - p->vCuts = Vec_WecAlloc( Gia_ManObjNum(pGia) ); + p->vCuts = Vec_WecStart( Gia_ManObjNum(pGia) ); p->vTtMem = fCutMin ? Vec_MemAllocForTT( nCutSize, 0 ) : NULL; return p; } @@ -651,12 +672,20 @@ void Sbd_StoFree( Sbd_Sto_t * p ) } void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ) { - assert( iObj == Vec_IntSize(p->vDelays) ); - assert( iObj == Vec_IntSize(p->vLevels) ); - assert( iObj == Vec_WecSize(p->vCuts) ); - Vec_IntPush( p->vDelays, Delay ); - Vec_IntPush( p->vLevels, Level ); - Vec_WecPushLevel( p->vCuts ); + if ( iObj < Vec_IntSize(p->vDelays) ) + { + Vec_IntWriteEntry( p->vDelays, iObj, Delay ); + Vec_IntWriteEntry( p->vLevels, iObj, Level ); + } + else + { + assert( iObj == Vec_IntSize(p->vDelays) ); + assert( iObj == Vec_IntSize(p->vLevels) ); + assert( iObj == Vec_WecSize(p->vCuts) ); + Vec_IntPush( p->vDelays, Delay ); + Vec_IntPush( p->vLevels, Level ); + Vec_WecPushLevel( p->vCuts ); + } } void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ) { @@ -698,6 +727,21 @@ void Sbd_StoDerefObj( Sbd_Sto_t * p, int iObj ) Sbd_StoDerefObj( p, Gia_ObjFaninId0(pObj, iObj) ); Sbd_StoDerefObj( p, Gia_ObjFaninId1(pObj, iObj) ); } +int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int * pLeaves ) +{ + Sbd_Cut_t * pCutBest = NULL; int i; + assert( p->Pivot == iObj ); + for ( i = 0; i < p->nCutsR; i++ ) + { + if ( (int)p->ppCuts[i]->nLeaves > p->nLutSize && (pCutBest == NULL || Sbd_CutCompare2(pCutBest, p->ppCuts[i]) == 1) ) + pCutBest = p->ppCuts[i]; + } +Sbd_CutPrint( p, iObj, pCutBest ); + assert( pCutBest->nLeaves <= SBD_DIV_MAX ); + for ( i = 0; i < (int)pCutBest->nLeaves; i++ ) + pLeaves[i] = pCutBest->pLeaves[i]; + return pCutBest->nLeaves; +} void Sbd_StoComputeCutsTest( Gia_Man_t * pGia ) { Sbd_Sto_t * p = Sbd_StoAlloc( pGia, NULL, 4, 8, 100, 1, 1 ); diff --git a/src/opt/sbd/sbdInt.h b/src/opt/sbd/sbdInt.h index 54174f768..31d0ea06d 100644 --- a/src/opt/sbd/sbdInt.h +++ b/src/opt/sbd/sbdInt.h @@ -54,7 +54,7 @@ ABC_NAMESPACE_HEADER_START #define SBD_LUTS_MAX 2 #define SBD_SIZE_MAX 4 -#define SBD_DIV_MAX 7 +#define SBD_DIV_MAX 8 //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -88,6 +88,8 @@ extern void Sbd_StoDefefObj( Sbd_Sto_t * p, int iObj ); extern void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ); extern void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ); extern int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ); +extern int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int * pLeaves ); + ABC_NAMESPACE_HEADER_END diff --git a/src/sat/bsat/satSolver.h b/src/sat/bsat/satSolver.h index 7ef2c9e8c..162b91e52 100644 --- a/src/sat/bsat/satSolver.h +++ b/src/sat/bsat/satSolver.h @@ -229,7 +229,12 @@ static void sat_solver_compress(sat_solver* s) (void) RetValue; } } - +static void sat_solver_delete_p( sat_solver ** ps ) +{ + if ( *ps ) + sat_solver_delete( *ps ); + *ps = NULL; +} static void sat_solver_clean_polarity(sat_solver* s, int * pVars, int nVars ) { int i; From 54b4692d4bb2a6c5e59b5f54aaff95e2c4966e77 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 29 Dec 2016 21:26:02 +0700 Subject: [PATCH 018/185] Updates to delay optimization project. --- src/base/abci/abc.c | 16 ++- src/opt/dau/dauGia.c | 2 +- src/opt/sbd/sbd.h | 1 + src/opt/sbd/sbdCore.c | 288 +++++++++++++++++++++--------------------- src/opt/sbd/sbdCut.c | 62 ++++++--- src/opt/sbd/sbdInt.h | 3 +- src/opt/sbd/sbdLut.c | 17 +-- 7 files changed, 216 insertions(+), 173 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 7866b22d7..f9717aa8f 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -41010,7 +41010,7 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) Sbd_Par_t Pars, * pPars = &Pars; Sbd_ParSetDefault( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KWFMCacvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KSWFMCacvwh" ) ) != EOF ) { switch ( c ) { @@ -41025,6 +41025,17 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nLutSize < 0 ) goto usage; break; + case 'S': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nLutNum = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nLutNum < 0 ) + goto usage; + break; case 'W': if ( globalUtilOptind >= argc ) { @@ -41107,9 +41118,10 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &mfsd [-KWFMC ] [-acvwh]\n" ); + Abc_Print( -2, "usage: &mfsd [-KSWFMC ] [-acvwh]\n" ); Abc_Print( -2, "\t performs SAT-based delay-oriented AIG optimization\n" ); Abc_Print( -2, "\t-K : the LUT size for delay minimization (2 <= num <= 6) [default = %d]\n", pPars->nLutSize ); + Abc_Print( -2, "\t-S : the LUT structure size (1 <= num <= 2) [default = %d]\n", pPars->nLutNum ); Abc_Print( -2, "\t-W : the number of levels in the TFO cone (0 <= num) [default = %d]\n", pPars->nTfoLevels ); Abc_Print( -2, "\t-F : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nTfoFanMax ); Abc_Print( -2, "\t-M : the max node count of windows to consider (0 = no limit) [default = %d]\n", pPars->nWinSizeMax ); diff --git a/src/opt/dau/dauGia.c b/src/opt/dau/dauGia.c index 5e74ad217..683750398 100644 --- a/src/opt/dau/dauGia.c +++ b/src/opt/dau/dauGia.c @@ -241,7 +241,7 @@ int Dau_DsdBalance( Gia_Man_t * pGia, int * pFans, int nFans, int fAnd ) if ( pGia->pHTable == NULL ) { if ( fAnd ) - iFan = Gia_ManAppendAnd( pGia, iFan0, iFan1 ); + iFan = Gia_ManAppendAnd2( pGia, iFan0, iFan1 ); else if ( pGia->pMuxes ) { int fCompl = Abc_LitIsCompl(iFan0) ^ Abc_LitIsCompl(iFan1); diff --git a/src/opt/sbd/sbd.h b/src/opt/sbd/sbd.h index 89d29958b..6cdfafe48 100644 --- a/src/opt/sbd/sbd.h +++ b/src/opt/sbd/sbd.h @@ -39,6 +39,7 @@ typedef struct Sbd_Par_t_ Sbd_Par_t; struct Sbd_Par_t_ { int nLutSize; // target LUT size + int nLutNum; // target LUT count int nTfoLevels; // the number of TFO levels (windowing) int nTfoFanMax; // the max number of fanouts (windowing) int nWinSizeMax; // maximum window size (windowing) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index daefb9aff..0b399b8ab 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -1,12 +1,12 @@ /**CFile**************************************************************** - FileName [sbd.c] + FileName [sbdCore.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [SAT-based optimization using internal don't-cares.] - Synopsis [] + Synopsis [Core procedures.] Author [Alan Mishchenko] @@ -14,7 +14,7 @@ Date [Ver. 1.0. Started - June 20, 2005.] - Revision [$Id: sbd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + Revision [$Id: sbdCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ @@ -30,7 +30,6 @@ ABC_NAMESPACE_IMPL_START #define SBD_MAX_LUTSIZE 6 - typedef struct Sbd_Man_t_ Sbd_Man_t; struct Sbd_Man_t_ { @@ -44,13 +43,13 @@ struct Sbd_Man_t_ Vec_Int_t * vCover; // temporary Vec_Int_t * vLits; // temporary Vec_Int_t * vLits2; // temporary - int nConsts; // constants - int nChanges; // changes + int nLuts[3]; // 0=const, 1=1lut, 2=2lut abctime timeWin; abctime timeCnf; abctime timeSat; abctime timeCov; abctime timeEnu; + abctime timeQbf; abctime timeOther; abctime timeTotal; Sbd_Sto_t * pSto; @@ -98,6 +97,7 @@ void Sbd_ParSetDefault( Sbd_Par_t * pPars ) { memset( pPars, 0, sizeof(Sbd_Par_t) ); pPars->nLutSize = 4; // target LUT size + pPars->nLutNum = 2; // target LUT count pPars->nTfoLevels = 2; // the number of TFO levels (windowing) pPars->nTfoFanMax = 4; // the max number of fanouts (windowing) pPars->nWinSizeMax = 0; // maximum window size (windowing) @@ -489,24 +489,26 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) ***********************************************************************/ int Sbd_ManCheckConst( Sbd_Man_t * p, int Pivot ) { + extern int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, word * pVarSims[], Vec_Int_t * vInds ); + extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); extern void Sbd_ManPrintObj( Sbd_Man_t * p, int Pivot ); + int nMintCount = 1; Vec_Ptr_t * vSims; word * pSims = Sbd_ObjSim0( p, Pivot ); word * pCtrl = Sbd_ObjSim2( p, Pivot ); int PivotVar = Vec_IntEntry(p->vObj2Var, Pivot); int RetValue, i, iObj, Ind, fFindOnset, nCares[2] = {0}; + abctime clk = Abc_Clock(); - extern int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, word * pVarSims[], Vec_Int_t * vInds ); - extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); p->timeCnf += Abc_Clock() - clk; if ( p->pSat == NULL ) { - if ( p->pPars->fVerbose ) - printf( "Found stuck-at-%d node %d.\n", 0, Pivot ); + //if ( p->pPars->fVerbose ) + // printf( "Found stuck-at-%d node %d.\n", 0, Pivot ); Vec_IntWriteEntry( p->vLutLevs, Pivot, 0 ); - p->nConsts++; + p->nLuts[0]++; return 0; } //return -1; @@ -526,7 +528,7 @@ int Sbd_ManCheckConst( Sbd_Man_t * p, int Pivot ) nCares[0] = nCares[0] < nMintCount ? nMintCount - nCares[0] : 0; nCares[1] = nCares[1] < nMintCount ? nMintCount - nCares[1] : 0; - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) printf( "Computing %d offset and %d onset minterms for node %d.\n", nCares[0], nCares[1], Pivot ); if ( Vec_IntSize(p->vLits) >= nCares[0] + nCares[1] ) @@ -565,10 +567,10 @@ int Sbd_ManCheckConst( Sbd_Man_t * p, int Pivot ) Vec_PtrFree( vSims ); if ( RetValue >= 0 ) { - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) printf( "Found stuck-at-%d node %d.\n", RetValue, Pivot ); Vec_IntWriteEntry( p->vLutLevs, Pivot, 0 ); - p->nConsts++; + p->nLuts[0]++; return RetValue; } // set controlability of these minterms @@ -1153,7 +1155,7 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) { extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); - abctime clk = Abc_Clock(); + abctime clk, clkSat = 0, clkEnu = 0, clkAll; word Onset[64] = {0}, Offset[64] = {0}, Cube; word CoverRows[64] = {0}, CoverCols[64] = {0}; int nIters, nItersMax = 32; @@ -1165,20 +1167,25 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) int nConsts = 4; int RetValue; - sat_solver_delete_p( &p->pSat ); + clk = Abc_Clock(); + //sat_solver_delete_p( &p->pSat ); p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); p->timeCnf += Abc_Clock() - clk; + clkAll = Abc_Clock(); assert( nConsts <= 8 ); + clk = Abc_Clock(); RetValue = Sbd_ManCollectConstantsNew( p->pSat, p->vDivVars, nConsts, PivotVar, Onset, Offset ); + clkSat += Abc_Clock() - clk; if ( RetValue >= 0 ) { - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) printf( "Found stuck-at-%d node %d.\n", RetValue, Pivot ); Vec_IntWriteEntry( p->vLutLevs, Pivot, 0 ); - p->nConsts++; + p->nLuts[0]++; return RetValue; } + RetValue = 0; // create rows of the table nRows = 0; @@ -1200,36 +1207,35 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) // solve the covering problem for ( nIters = 0; nIters < nItersMax && nRows < 64; nIters++ ) { - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) Sbd_ManMatrPrint( p, CoverCols, nDivs, nRows ); clk = Abc_Clock(); if ( !Sbd_ManFindCands( p, CoverCols, nDivs ) ) { - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) printf( "Cannot find a feasible cover.\n" ); - //clkEnu += Abc_Clock() - clk; - //clkAll = Abc_Clock() - clkAll - clkSat - clkEnu; - //p->timeSat += clkSat; - //p->timeCov += clkAll; - //p->timeEnu += clkEnu; + clkEnu += Abc_Clock() - clk; + clkAll = Abc_Clock() - clkAll - clkSat - clkEnu; + p->timeSat += clkSat; + p->timeCov += clkAll; + p->timeEnu += clkEnu; return 0; } - //clkEnu += Abc_Clock() - clk; - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) printf( "Candidate support: " ), Vec_IntPrint( p->vDivSet ); clk = Abc_Clock(); *pTruth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); - //clkSat += Abc_Clock() - clk; + clkSat += Abc_Clock() - clk; if ( *pTruth == SBD_SAT_UNDEC ) printf( "Node %d: Undecided.\n", Pivot ); else if ( *pTruth == SBD_SAT_SAT ) { - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) { int i; printf( "Node %d: SAT.\n", Pivot ); @@ -1255,15 +1261,21 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) } else { - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) { printf( "Node %d: UNSAT. ", Pivot ); Extra_PrintBinary( stdout, (unsigned *)pTruth, 1 << Vec_IntSize(p->vDivSet) ), printf( "\n" ); } - return 1; + p->nLuts[1]++; + RetValue = 1; + break; } } - return 0; + clkAll = Abc_Clock() - clkAll - clkSat - clkEnu; + p->timeSat += clkSat; + p->timeCov += clkAll; + p->timeEnu += clkEnu; + return RetValue; } int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) @@ -1277,37 +1289,41 @@ int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); abctime clk = Abc_Clock(); + word Truth; int PivotVar = Vec_IntEntry(p->vObj2Var, Pivot); int FreeVar = Vec_IntSize(p->vWinObjs) + Vec_IntSize(p->vTfo) + Vec_IntSize(p->vRoots); - int nDivs = Vec_IntSize( p->vDivVars ); + //int nDivs = Vec_IntSize( p->vDivVars ); int Delay = Vec_IntEntry( p->vLutLevs, Pivot ); - int i, k, iObj, nIters; + int i, k, iObj, nIters, RetValue; int nLeaves, pLeaves[SBD_DIV_MAX]; - int pNodesTop[SBD_DIV_MAX], pNodesBot[SBD_DIV_MAX], pNodeRefs[SBD_DIV_MAX]; + int pNodesTop[SBD_DIV_MAX], pNodesBot[SBD_DIV_MAX];//, pNodeRefs[SBD_DIV_MAX]; int nNodesTop = 0, nNodesBot = 0, nNodesDiff = 0; - sat_solver_delete_p( &p->pSat ); + //sat_solver_delete_p( &p->pSat ); p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); p->timeCnf += Abc_Clock() - clk; // extract one cut nLeaves = Sbd_StoObjBestCut( p->pSto, Pivot, pLeaves ); + if ( nLeaves == -1 ) + return 0; // solve the covering problem for ( nIters = 0; nIters < nLeaves; nIters++ ) { - word Truth; // try to remove one variable from divisors Vec_IntClear( p->vDivSet ); for ( i = 0; i < nLeaves; i++ ) if ( i != nIters && pLeaves[i] != -1 ) Vec_IntPush( p->vDivSet, Vec_IntEntry(p->vObj2Var, pLeaves[i]) ); assert( Vec_IntSize(p->vDivSet) < nLeaves ); - + // compute truth table + clk = Abc_Clock(); Truth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); + p->timeSat += Abc_Clock() - clk; if ( Truth == SBD_SAT_UNDEC ) printf( "Node %d: Undecided.\n", Pivot ); else if ( Truth == SBD_SAT_SAT ) @@ -1315,16 +1331,34 @@ int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) else pLeaves[nIters] = -1; } - Vec_IntClear( p->vDivSet ); for ( i = 0; i < nLeaves; i++ ) if ( pLeaves[i] != -1 ) Vec_IntPush( p->vDivSet, pLeaves[i] ); - printf( "Reduced %d -> %d\n", nLeaves, Vec_IntSize(p->vDivSet) ); + //printf( "Reduced %d -> %d\n", nLeaves, Vec_IntSize(p->vDivSet) ); + if ( Vec_IntSize(p->vDivSet) <= p->pPars->nLutSize ) + { + *pnStrs = 1; + // remap divisors + Vec_IntForEachEntry( p->vDivSet, iObj, i ) + Vec_IntWriteEntry( p->vDivSet, i, Vec_IntEntry(p->vObj2Var, iObj) ); + // compute truth table + clk = Abc_Clock(); + Truth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); + p->timeSat += Abc_Clock() - clk; + assert( Truth != SBD_SAT_UNDEC && Truth != SBD_SAT_SAT ); + // create structure + Strs->fLut = 1; + Strs->nVarIns = Vec_IntSize( p->vDivSet ); + for ( i = 0; i < Strs->nVarIns; i++ ) + Strs->VarIns[i] = i; + Strs->Res = Truth; + p->nLuts[1]++; + //Extra_PrintBinary( stdout, (unsigned *)&Truth, 1 << Strs->nVarIns ), printf( "\n" ); + return 1; + } assert( Vec_IntSize(p->vDivSet) > p->pPars->nLutSize ); - //Delay++; - // count number of nodes on each level nNodesTop = 0, nNodesBot = 0; Vec_IntForEachEntry( p->vDivSet, iObj, i ) @@ -1336,8 +1370,8 @@ int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) pNodesTop[nNodesTop++] = i; else // if ( DelayDiff < -2 ) pNodesBot[nNodesBot++] = i; - Vec_IntWriteEntry( p->vDivSet, iObj, Vec_IntEntry(p->vObj2Var, pLeaves[i]) ); - pNodeRefs[i] = Gia_ObjRefNumId( p->pGia, iObj ); + Vec_IntWriteEntry( p->vDivSet, i, Vec_IntEntry(p->vObj2Var, iObj) ); + //pNodeRefs[i] = Gia_ObjRefNumId( p->pGia, iObj ); } if ( i < Vec_IntSize(p->vDivSet) ) return 0; @@ -1379,9 +1413,15 @@ int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) Strs[2+k].Res = 0; } - return Sbd_ProblemSolve( p->pGia, p->vMirrors, - Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, - p->vDivSet, *pnStrs, Strs ); + clk = Abc_Clock(); + RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, + Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, + p->vDivSet, *pnStrs, Strs ); + p->timeQbf += Abc_Clock() - clk; + + if ( RetValue ) + p->nLuts[2]++; + return RetValue; } @@ -1622,7 +1662,6 @@ int Sbd_ManImplement( Sbd_Man_t * p, int Pivot, word Truth ) // update delay of the initial node assert( Vec_IntEntry(p->vLutLevs, Pivot) == iCurLev ); Vec_IntWriteEntry( p->vLutLevs, Pivot, iNewLev ); - p->nChanges++; return 0; } @@ -1677,13 +1716,14 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) // remember this function assert( Vec_IntEntry(p->vMirrors, Pivot) == -1 ); Vec_IntWriteEntry( p->vMirrors, Pivot, iLit ); - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) printf( "Replacing node %d by literal %d.\n", Pivot, iLit ); // extend data-structure to accommodate new nodes assert( Vec_IntSize(p->vLutLevs) == iObjLast ); for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) Sbd_StoRefObj( p->pSto, i, i == Gia_ManObjNum(p->pGia)-1 ? Pivot : -1 ); + Sbd_StoDerefObj( p->pSto, Pivot ); for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) { int Delay = Sbd_StoComputeCutsNode( p->pSto, i ); @@ -1703,7 +1743,6 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) // update delay of the initial node assert( Vec_IntEntry(p->vLutLevs, Pivot) == iCurLev ); Vec_IntWriteEntry( p->vLutLevs, Pivot, iNewLev ); - p->nChanges++; return 0; } @@ -1781,11 +1820,10 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) ***********************************************************************/ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) { -// extern void Sbd_ManSolveSelect( Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots ); Sbd_Str_t Strs[4]; - int nStrs = 0; + int i, RetValue, nStrs = 0; + word Truth = 0; - int RetValue; word Truth = 0; if ( !p->pSto ) { if ( Sbd_ManMergeCuts( p, Pivot ) ) @@ -1795,83 +1833,39 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) // if ( Pivot != 15 ) // return; - if ( p->pPars->fVerbose ) - printf( "\nLooking at node %d\n", Pivot ); if ( Sbd_ManWindow( p, Pivot ) ) return; -// Sbd_ManSolveSelect( p->pGia, p->vMirrors, Pivot, p->vDivVars, p->vDivValues, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots ); - RetValue = Sbd_ManCheckConst( p, Pivot ); if ( RetValue >= 0 ) { Vec_IntWriteEntry( p->vMirrors, Pivot, RetValue ); - //printf( " --> Pivot %4d. Constant %d.\n", Pivot, RetValue ); + if ( p->pPars->fVerbose ) printf( "Node %5d: Detected constant %d.\n", Pivot, RetValue ); } - else if ( Sbd_ManExplore3( p, Pivot, &nStrs, Strs ) ) + else if ( p->pPars->nLutNum >= 1 && Sbd_ManExplore2( p, Pivot, &Truth ) ) + { + Strs->fLut = 1; + Strs->nVarIns = Vec_IntSize( p->vDivSet ); + for ( i = 0; i < Strs->nVarIns; i++ ) + Strs->VarIns[i] = i; + Strs->Res = Truth; + Sbd_ManImplement2( p, Pivot, 1, Strs ); + if ( p->pPars->fVerbose ) printf( "Node %5d: Detected LUT%d\n", Pivot, p->pPars->nLutSize ); + } + else if ( p->pPars->nLutNum >= 2 && Sbd_ManExplore3( p, Pivot, &nStrs, Strs ) ) { - //Sbd_ManImplement( p, Pivot, Truth ); Sbd_ManImplement2( p, Pivot, nStrs, Strs ); - //printf( " --> Pivot %4d. Supp %d.\n", Pivot, Vec_IntSize(p->vDivSet) ); + if ( p->pPars->fVerbose ) printf( "Node %5d: Detected %d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize ); } -/* - else if ( Sbd_ManExplore2( p, Pivot, &Truth ) ) - { - int i; - Sbd_Str_t Strs; - Strs.fLut = 1; - Strs.nVarIns = Vec_IntSize( p->vDivSet ); - for ( i = 0; i < Strs.nVarIns; i++ ) - Strs.VarIns[i] = i; - Strs.Res = Truth; - //Sbd_ManImplement( p, Pivot, Truth ); - Sbd_ManImplement2( p, Pivot, 1, &Strs ); - //printf( " --> Pivot %4d. Supp %d.\n", Pivot, Vec_IntSize(p->vDivSet) ); - } -*/ - -/* - else - { - extern int Sbd_ProblemSolve( - Gia_Man_t * p, Vec_Int_t * vMirrors, - int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, - Vec_Int_t * vTfo, Vec_Int_t * vRoots, - Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0 - ); - -// Sbd_Str_t Strs[2] = { {1, 4, {0, 1, 2, 8}}, {1, 4, {3, 4, 5, 6}} }; -// Sbd_Str_t Strs[2] = { {1, 4, {1, 4, 5, 7}}, {1, 4, {0, 1, 2, 3}} }; - Sbd_Str_t Strs[3] = { {1, 4, {8, 4, 5, 7}}, {1, 4, {0, 1, 2, 3}}, {0, 4, {0, 1, 2, 3}} }; - - Vec_Int_t * vDivSet = Vec_IntAlloc( 8 ); - - int i, RetValue; - - for ( i = 0; i < 6; i++ ) - Vec_IntPush( vDivSet, i+1 ); - - RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, - Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, - vDivSet, 3, Strs ); - if ( RetValue ) - { - printf( "Solving succeded.\n" ); - //Sbd_ManImplement2( p, Pivot, Truth, nLuts, nSels, nVarsDivs, pVarsDivs, Truths ); - } - Vec_IntFree( vDivSet ); - } -*/ } Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) { Gia_Man_t * pNew; Gia_Obj_t * pObj; Sbd_Man_t * p = Sbd_ManStart( pGia, pPars ); - int nNodesOld = Gia_ManObjNum(pGia);//, Count = 0; + int nNodesOld = Gia_ManObjNum(pGia); int k, Pivot; assert( pPars->nLutSize <= 6 ); - //Sbd_ManMergeTest( p ); // prepare references Gia_ManForEachObj( p->pGia, pObj, Pivot ) Sbd_StoRefObj( p->pSto, Pivot, -1 ); @@ -1886,32 +1880,6 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) { Pivot = Gia_ObjId( pGia, pObj ); if ( Pivot >= nNodesOld ) - continue; - if ( Gia_ObjIsAnd(pObj) ) - Sbd_NtkPerformOne( p, Pivot ); - else if ( Gia_ObjIsCi(pObj) ) - { - int arrTime = Tim_ManGetCiArrival( (Tim_Man_t*)pGia->pManTime, Gia_ObjCioId(pObj) ); - Vec_IntWriteEntry( p->vLutLevs, Pivot, arrTime ); - } - else if ( Gia_ObjIsCo(pObj) ) - { - int arrTime = Vec_IntEntry( p->vLutLevs, Gia_ObjFaninId0(pObj, Pivot) ); - Tim_ManSetCoArrival( (Tim_Man_t*)pGia->pManTime, Gia_ObjCioId(pObj), arrTime ); - } - else if ( !Gia_ObjIsConst0(pObj) ) - assert( 0 ); - } - //Tim_ManPrint( pGia->pManTime ); - Tim_ManStop( (Tim_Man_t *)pGia->pManTime ); - pGia->pManTime = pTimOld; - Vec_IntFree( vNodes ); - } - else - { - Gia_ManForEachObj( pGia, pObj, Pivot ) - { - if ( Pivot == nNodesOld ) break; if ( Gia_ObjIsAnd(pObj) ) { @@ -1920,23 +1888,61 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) if ( Delay > 1 ) Sbd_NtkPerformOne( p, Pivot ); } - else if ( !Gia_ObjIsCo(pObj) ) + else if ( Gia_ObjIsCi(pObj) ) + { + int arrTime = Tim_ManGetCiArrival( (Tim_Man_t*)pGia->pManTime, Gia_ObjCioId(pObj) ); + Vec_IntWriteEntry( p->vLutLevs, Pivot, arrTime ); + Sbd_StoComputeCutsCi( p->pSto, Pivot, arrTime, arrTime ); + } + else if ( Gia_ObjIsCo(pObj) ) + { + int arrTime = Vec_IntEntry( p->vLutLevs, Gia_ObjFaninId0(pObj, Pivot) ); + Tim_ManSetCoArrival( (Tim_Man_t*)pGia->pManTime, Gia_ObjCioId(pObj), arrTime ); + } + else if ( Gia_ObjIsConst0(pObj) ) + Sbd_StoComputeCutsConst0( p->pSto, 0 ); + else assert( 0 ); + } + //Tim_ManPrint( pGia->pManTime ); + Tim_ManStop( (Tim_Man_t *)pGia->pManTime ); + pGia->pManTime = pTimOld; + Vec_IntFree( vNodes ); + } + else + { + Sbd_StoComputeCutsConst0( p->pSto, 0 ); + Gia_ManForEachObj( pGia, pObj, Pivot ) + { + if ( Pivot >= nNodesOld ) + break; + if ( Gia_ObjIsCi(pObj) ) Sbd_StoComputeCutsCi( p->pSto, Pivot, 0, 0 ); + else if ( Gia_ObjIsAnd(pObj) ) + { + int Delay = Sbd_StoComputeCutsNode( p->pSto, Pivot ); + Vec_IntWriteEntry( p->vLutLevs, Pivot, Delay ); + if ( Delay > 1 ) + Sbd_NtkPerformOne( p, Pivot ); + } + //if ( nNodesOld != Gia_ManObjNum(pGia) ) + // break; } } - printf( "Found %d constants and %d replacements with delay %d. ", p->nConsts, p->nChanges, Sbd_ManDelay(p) ); + printf( "Found %d constants, %d one-LUT and %d two-LUT replacements with delay %d. ", + p->nLuts[0], p->nLuts[1], p->nLuts[2], Sbd_ManDelay(p) ); p->timeTotal = Abc_Clock() - p->timeTotal; Abc_PrintTime( 1, "Time", p->timeTotal ); pNew = Sbd_ManDerive( pGia, p->vMirrors ); // print runtime statistics - p->timeOther = p->timeTotal - p->timeWin - p->timeCnf - p->timeSat - p->timeCov - p->timeEnu; - if ( 0 ) + p->timeOther = p->timeTotal - p->timeWin - p->timeCnf - p->timeSat - p->timeCov - p->timeEnu - p->timeQbf; + if ( p->pPars->fVerbose ) { ABC_PRTP( "Win", p->timeWin , p->timeTotal ); ABC_PRTP( "Cnf", p->timeCnf , p->timeTotal ); ABC_PRTP( "Sat", p->timeSat , p->timeTotal ); ABC_PRTP( "Cov", p->timeCov , p->timeTotal ); ABC_PRTP( "Enu", p->timeEnu , p->timeTotal ); + ABC_PRTP( "Qbf", p->timeQbf , p->timeTotal ); ABC_PRTP( "Oth", p->timeOther, p->timeTotal ); ABC_PRTP( "ALL", p->timeTotal, p->timeTotal ); } diff --git a/src/opt/sbd/sbdCut.c b/src/opt/sbd/sbdCut.c index d4c085a1e..9c54c74ae 100644 --- a/src/opt/sbd/sbdCut.c +++ b/src/opt/sbd/sbdCut.c @@ -40,8 +40,9 @@ struct Sbd_Cut_t_ int iFunc; // functionality int Cost; // cut cost int CostLev; // cut cost - unsigned nSlowLeaves : 14; // slow leaves - unsigned nTreeLeaves : 14; // tree leaves + unsigned nTreeLeaves : 9; // tree leaves + unsigned nSlowLeaves : 9; // slow leaves + unsigned nTopLeaves : 10; // top leaves unsigned nLeaves : 4; // leaf count int pLeaves[SBD_MAX_CUTSIZE]; // leaves }; @@ -442,13 +443,6 @@ static inline int Sbd_CutCountBits( word i ) i = ((i + (i >> 4)) & 0x0F0F0F0F0F0F0F0F); return (i*(0x0101010101010101))>>56; } -static inline int Sbd_CutSlowLeaves( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) -{ - int i, Count = 0, Delay = Vec_IntEntry(p->vDelays, iObj); - for ( i = 0; i < (int)pCut->nLeaves; i++ ) - Count += (Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay >= -1); - return Count; -} static inline int Sbd_CutCost( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) { int i, Cost = 0; @@ -470,6 +464,20 @@ static inline int Sbd_CutTreeLeaves( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) Cost += Vec_IntEntry( p->vRefs, pCut->pLeaves[i] ) == 1; return Cost; } +static inline int Sbd_CutSlowLeaves( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) +{ + int i, Count = 0, Delay = Vec_IntEntry(p->vDelays, iObj); + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + Count += (Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay >= -1); + return Count; +} +static inline int Sbd_CutTopLeaves( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) +{ + int i, Count = 0, Delay = Vec_IntEntry(p->vDelays, iObj); + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + Count += (Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay == -2); + return Count; +} static inline void Sbd_CutAddUnit( Sbd_Sto_t * p, int iObj ) { Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj ); @@ -481,6 +489,14 @@ static inline void Sbd_CutAddUnit( Sbd_Sto_t * p, int iObj ) Vec_IntPush( vThis, iObj ); Vec_IntPush( vThis, 2 ); } +static inline void Sbd_CutAddZero( Sbd_Sto_t * p, int iObj ) +{ + Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj ); + assert( Vec_IntSize(vThis) == 0 ); + Vec_IntPush( vThis, 1 ); + Vec_IntPush( vThis, 0 ); + Vec_IntPush( vThis, 0 ); +} static inline int Sbd_StoPrepareSet( Sbd_Sto_t * p, int iObj, int Index ) { Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj ); @@ -495,8 +511,9 @@ static inline int Sbd_StoPrepareSet( Sbd_Sto_t * p, int iObj, int Index ) pCutTemp->Sign = Sbd_CutGetSign( pCutTemp ); pCutTemp->Cost = Sbd_CutCost( p, pCutTemp ); pCutTemp->CostLev = Sbd_CutCostLev( p, pCutTemp ); - pCutTemp->nSlowLeaves = Sbd_CutSlowLeaves( p, iObj, pCutTemp ); pCutTemp->nTreeLeaves = Sbd_CutTreeLeaves( p, pCutTemp ); + pCutTemp->nSlowLeaves = Sbd_CutSlowLeaves( p, iObj, pCutTemp ); + pCutTemp->nTopLeaves = Sbd_CutTopLeaves( p, iObj, pCutTemp ); } return pList[0]; } @@ -542,6 +559,7 @@ static inline void Sbd_StoComputeSpec( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pCu int i; for ( i = 0; i < nCuts; i++ ) { + pCuts[i]->nTopLeaves = Sbd_CutTopLeaves( p, iObj, pCuts[i] ); pCuts[i]->nSlowLeaves = Sbd_CutSlowLeaves( p, iObj, pCuts[i] ); p->nCutsSpec += (pCuts[i]->nSlowLeaves == 0); } @@ -555,8 +573,8 @@ static inline void Sbd_CutPrint( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) printf( " %*d", nDigits, pCut->pLeaves[i] ); for ( ; i < (int)p->nCutSize; i++ ) printf( " %*s", nDigits, " " ); - printf( " } Cost = %3d CostL = %3d Slow = %d Tree = %d ", - pCut->Cost, pCut->CostLev, pCut->nSlowLeaves, pCut->nTreeLeaves ); + printf( " } Cost = %3d CostL = %3d Tree = %d Slow = %d Top = %d ", + pCut->Cost, pCut->CostLev, pCut->nTreeLeaves, pCut->nSlowLeaves, pCut->nTopLeaves ); printf( "%c ", pCut->nSlowLeaves == 0 ? '*' : ' ' ); for ( i = 0; i < (int)pCut->nLeaves; i++ ) printf( "%3d ", Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay ); @@ -607,7 +625,7 @@ void Sbd_StoMergeCuts( Sbd_Sto_t * p, int iObj ) p->nCutsR = nCutsR; p->Pivot = iObj; // debug printout - if ( 1 ) + if ( 0 ) { printf( "*** Obj = %4d Delay = %4d NumCuts = %4d\n", iObj, Vec_IntEntry(p->vDelays, iObj), nCutsR ); for ( i = 0; i < nCutsR; i++ ) @@ -687,6 +705,11 @@ void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ) Vec_WecPushLevel( p->vCuts ); } } +void Sbd_StoComputeCutsConst0( Sbd_Sto_t * p, int iObj ) +{ + Sbd_StoComputeCutsObj( p, iObj, 0, 0 ); + Sbd_CutAddZero( p, iObj ); +} void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ) { Sbd_StoComputeCutsObj( p, iObj, Delay, Level ); @@ -732,11 +755,14 @@ int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int * pLeaves ) Sbd_Cut_t * pCutBest = NULL; int i; assert( p->Pivot == iObj ); for ( i = 0; i < p->nCutsR; i++ ) - { - if ( (int)p->ppCuts[i]->nLeaves > p->nLutSize && (pCutBest == NULL || Sbd_CutCompare2(pCutBest, p->ppCuts[i]) == 1) ) + if ( (int)p->ppCuts[i]->nLeaves > p->nLutSize && + (int)p->ppCuts[i]->nSlowLeaves == 0 && + (int)p->ppCuts[i]->nTopLeaves <= p->nLutSize-1 && + (pCutBest == NULL || Sbd_CutCompare2(pCutBest, p->ppCuts[i]) == 1) ) pCutBest = p->ppCuts[i]; - } -Sbd_CutPrint( p, iObj, pCutBest ); + if ( pCutBest == NULL ) + return -1; +//Sbd_CutPrint( p, iObj, pCutBest ); assert( pCutBest->nLeaves <= SBD_DIV_MAX ); for ( i = 0; i < (int)pCutBest->nLeaves; i++ ) pLeaves[i] = pCutBest->pLeaves[i]; @@ -751,7 +777,7 @@ void Sbd_StoComputeCutsTest( Gia_Man_t * pGia ) Gia_ManForEachObj( p->pGia, pObj, iObj ) Sbd_StoRefObj( p, iObj, -1 ); // compute cuts - Sbd_StoComputeCutsObj( p, 0, 0, 0 ); + Sbd_StoComputeCutsConst0( p, 0 ); Gia_ManForEachCiId( p->pGia, iObj, i ) Sbd_StoComputeCutsCi( p, iObj, 0, 0 ); Gia_ManForEachAnd( p->pGia, pObj, iObj ) diff --git a/src/opt/sbd/sbdInt.h b/src/opt/sbd/sbdInt.h index 31d0ea06d..d54285f8f 100644 --- a/src/opt/sbd/sbdInt.h +++ b/src/opt/sbd/sbdInt.h @@ -84,7 +84,8 @@ struct Sbd_Str_t_ extern Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, Vec_Int_t * vMirrors, int nLutSize, int nCutSize, int nCutNum, int fCutMin, int fVerbose ); extern void Sbd_StoFree( Sbd_Sto_t * p ); extern void Sbd_StoRefObj( Sbd_Sto_t * p, int iObj, int iMirror ); -extern void Sbd_StoDefefObj( Sbd_Sto_t * p, int iObj ); +extern void Sbd_StoDerefObj( Sbd_Sto_t * p, int iObj ); +extern void Sbd_StoComputeCutsConst0( Sbd_Sto_t * p, int iObj ); extern void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ); extern void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ); extern int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ); diff --git a/src/opt/sbd/sbdLut.c b/src/opt/sbd/sbdLut.c index b924a33b3..e8aee7900 100644 --- a/src/opt/sbd/sbdLut.c +++ b/src/opt/sbd/sbdLut.c @@ -157,7 +157,7 @@ void Sbd_ProblemCollectSolution( int nStrs, Sbd_Str_t * pStr0, Vec_Int_t * vLits for ( m = 0; m < nIters; m++, iLit++ ) if ( !Abc_LitIsCompl(Vec_IntEntry(vLits, iLit)) ) Abc_TtSetBit( &pStr->Res, m ); - Abc_TtStretch6( &pStr->Res, pStr->nVarIns, 6 ); + pStr->Res = Abc_Tt6Stretch( pStr->Res, pStr->nVarIns ); } else { @@ -192,13 +192,12 @@ int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, { extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); - int fVerbose = 1; + int fVerbose = 0; + abctime clk = Abc_Clock(); Vec_Int_t * vLits = Vec_IntAlloc( 100 ); sat_solver * pSatCec = Sbd_ManSatSolver( NULL, p, vMirrors, Pivot, vWinObjs, vObj2Var, vTfo, vRoots, 1 ); sat_solver * pSatQbf = sat_solver_new(); - //int PivotVar = Vec_IntEntry(vObj2Var, Pivot); - int nVars = Vec_IntSize( vDivSet ); int nPars = Sbd_ProblemCountParams( nStrs, pStr0 ); @@ -248,8 +247,6 @@ int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, if ( status == l_False ) // solution found break; assert( status == l_True ); -// Vec_IntForEachEntry( vWinObjs, iVar, i ) -// printf( "Node = %4d. SatVar = %4d. Value = %d.\n", iVar, i, sat_solver_var_value(pSatCec, i) ); if ( fVerbose ) { @@ -292,16 +289,16 @@ int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, } if ( Vec_IntSize(vLits) > 0 ) { - Sbd_ProblemPrintSolution( nStrs, pStr0, vLits ); + //Sbd_ProblemPrintSolution( nStrs, pStr0, vLits ); Sbd_ProblemCollectSolution( nStrs, pStr0, vLits ); RetValue = 1; } - else - printf( "Solution does not exist.\n" ); - sat_solver_delete( pSatCec ); sat_solver_delete( pSatQbf ); Vec_IntFree( vLits ); + + if ( fVerbose ) + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); return RetValue; } From 01924ca118cad9bc8bf84de0525e54f5c4a832ec Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 31 Dec 2016 20:21:46 +0700 Subject: [PATCH 019/185] Updates to delay optimization project. --- src/aig/gia/gia.h | 53 +++-- src/base/abci/abc.c | 28 ++- src/opt/dau/dauGia.c | 2 +- src/opt/sbd/sbd.h | 2 + src/opt/sbd/sbdCore.c | 442 ++++++++++++++++++++++++++++-------------- src/opt/sbd/sbdCut.c | 68 +++++-- src/opt/sbd/sbdInt.h | 39 ++-- src/opt/sbd/sbdLut.c | 1 - src/opt/sbd/sbdWin.c | 5 +- 9 files changed, 444 insertions(+), 196 deletions(-) diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index ac40f9754..d9b1716a3 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -665,21 +665,6 @@ static inline int Gia_ManAppendAnd( Gia_Man_t * p, int iLit0, int iLit1 ) } return Gia_ObjId( p, pObj ) << 1; } -static inline int Gia_ManAppendAnd2( Gia_Man_t * p, int iLit0, int iLit1 ) -{ - if ( !p->fGiaSimple ) - { - if ( iLit0 < 2 ) - return iLit0 ? iLit1 : 0; - if ( iLit1 < 2 ) - return iLit1 ? iLit0 : 0; - if ( iLit0 == iLit1 ) - return iLit1; - if ( iLit0 == Abc_LitNot(iLit1) ) - return 0; - } - return Gia_ManAppendAnd( p, iLit0, iLit1 ); -} static inline int Gia_ManAppendXorReal( Gia_Man_t * p, int iLit0, int iLit1 ) { Gia_Obj_t * pObj = Gia_ManAppendObj( p ); @@ -780,6 +765,44 @@ static inline int Gia_ManAppendXor( Gia_Man_t * p, int iLit0, int iLit1 ) { return Gia_ManAppendMux( p, iLit0, Abc_LitNot(iLit1), iLit1 ); } + +static inline int Gia_ManAppendAnd2( Gia_Man_t * p, int iLit0, int iLit1 ) +{ + if ( !p->fGiaSimple ) + { + if ( iLit0 < 2 ) + return iLit0 ? iLit1 : 0; + if ( iLit1 < 2 ) + return iLit1 ? iLit0 : 0; + if ( iLit0 == iLit1 ) + return iLit1; + if ( iLit0 == Abc_LitNot(iLit1) ) + return 0; + } + return Gia_ManAppendAnd( p, iLit0, iLit1 ); +} +static inline int Gia_ManAppendOr2( Gia_Man_t * p, int iLit0, int iLit1 ) +{ + return Abc_LitNot(Gia_ManAppendAnd2( p, Abc_LitNot(iLit0), Abc_LitNot(iLit1) )); +} +static inline int Gia_ManAppendMux2( Gia_Man_t * p, int iCtrl, int iData1, int iData0 ) +{ + int iTemp0 = Gia_ManAppendAnd2( p, Abc_LitNot(iCtrl), iData0 ); + int iTemp1 = Gia_ManAppendAnd2( p, iCtrl, iData1 ); + return Abc_LitNotCond( Gia_ManAppendAnd2( p, Abc_LitNot(iTemp0), Abc_LitNot(iTemp1) ), 1 ); +} +static inline int Gia_ManAppendMaj2( Gia_Man_t * p, int iData0, int iData1, int iData2 ) +{ + int iTemp0 = Gia_ManAppendOr2( p, iData1, iData2 ); + int iTemp1 = Gia_ManAppendAnd2( p, iData0, iTemp0 ); + int iTemp2 = Gia_ManAppendAnd2( p, iData1, iData2 ); + return Gia_ManAppendOr2( p, iTemp1, iTemp2 ); +} +static inline int Gia_ManAppendXor2( Gia_Man_t * p, int iLit0, int iLit1 ) +{ + return Gia_ManAppendMux2( p, iLit0, Abc_LitNot(iLit1), iLit1 ); +} + static inline void Gia_ManPatchCoDriver( Gia_Man_t * p, int iCoIndex, int iLit0 ) { Gia_Obj_t * pObjCo = Gia_ManCo( p, iCoIndex ); diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index f9717aa8f..fccd4f635 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -41010,7 +41010,7 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) Sbd_Par_t Pars, * pPars = &Pars; Sbd_ParSetDefault( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KSWFMCacvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KSNPWFMCacvwh" ) ) != EOF ) { switch ( c ) { @@ -41036,6 +41036,28 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nLutNum < 0 ) goto usage; break; + case 'N': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nCutSize = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nCutSize < 0 ) + goto usage; + break; + case 'P': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-P\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nCutNum = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nCutNum < 0 ) + goto usage; + break; case 'W': if ( globalUtilOptind >= argc ) { @@ -41118,10 +41140,12 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &mfsd [-KSWFMC ] [-acvwh]\n" ); + Abc_Print( -2, "usage: &mfsd [-KSNPWFMC ] [-acvwh]\n" ); Abc_Print( -2, "\t performs SAT-based delay-oriented AIG optimization\n" ); Abc_Print( -2, "\t-K : the LUT size for delay minimization (2 <= num <= 6) [default = %d]\n", pPars->nLutSize ); Abc_Print( -2, "\t-S : the LUT structure size (1 <= num <= 2) [default = %d]\n", pPars->nLutNum ); + Abc_Print( -2, "\t-N : the cut size considered for optimization (2 <= num <= 10) [default = %d]\n", pPars->nCutSize ); + Abc_Print( -2, "\t-P : the number of cuts computed at a node (1 <= num <= 500) [default = %d]\n", pPars->nCutNum ); Abc_Print( -2, "\t-W : the number of levels in the TFO cone (0 <= num) [default = %d]\n", pPars->nTfoLevels ); Abc_Print( -2, "\t-F : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nTfoFanMax ); Abc_Print( -2, "\t-M : the max node count of windows to consider (0 = no limit) [default = %d]\n", pPars->nWinSizeMax ); diff --git a/src/opt/dau/dauGia.c b/src/opt/dau/dauGia.c index 683750398..8b0a76c3e 100644 --- a/src/opt/dau/dauGia.c +++ b/src/opt/dau/dauGia.c @@ -249,7 +249,7 @@ int Dau_DsdBalance( Gia_Man_t * pGia, int * pFans, int nFans, int fAnd ) iFan = Abc_LitNotCond( iFan, fCompl ); } else - iFan = Gia_ManAppendXor( pGia, iFan0, iFan1 ); + iFan = Gia_ManAppendXor2( pGia, iFan0, iFan1 ); } else { diff --git a/src/opt/sbd/sbd.h b/src/opt/sbd/sbd.h index 6cdfafe48..6e0f6b3b0 100644 --- a/src/opt/sbd/sbd.h +++ b/src/opt/sbd/sbd.h @@ -40,6 +40,8 @@ struct Sbd_Par_t_ { int nLutSize; // target LUT size int nLutNum; // target LUT count + int nCutSize; // target cut size + int nCutNum; // target cut count int nTfoLevels; // the number of TFO levels (windowing) int nTfoFanMax; // the max number of fanouts (windowing) int nWinSizeMax; // maximum window size (windowing) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 0b399b8ab..a48e6489f 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -43,12 +43,14 @@ struct Sbd_Man_t_ Vec_Int_t * vCover; // temporary Vec_Int_t * vLits; // temporary Vec_Int_t * vLits2; // temporary - int nLuts[3]; // 0=const, 1=1lut, 2=2lut + int nLuts[6]; // 0=const, 1=1lut, 2=2lut, 3=3lut + int nTried; + int nUsed; abctime timeWin; + abctime timeCut; + abctime timeCov; abctime timeCnf; abctime timeSat; - abctime timeCov; - abctime timeEnu; abctime timeQbf; abctime timeOther; abctime timeTotal; @@ -76,8 +78,6 @@ static inline word * Sbd_ObjSim1( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( static inline word * Sbd_ObjSim2( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSims[2], p->pPars->nWords * i ); } static inline word * Sbd_ObjSim3( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSims[3], p->pPars->nWords * i ); } -extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivSet, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp ); - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -96,17 +96,19 @@ extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_ void Sbd_ParSetDefault( Sbd_Par_t * pPars ) { memset( pPars, 0, sizeof(Sbd_Par_t) ); - pPars->nLutSize = 4; // target LUT size - pPars->nLutNum = 2; // target LUT count - pPars->nTfoLevels = 2; // the number of TFO levels (windowing) - pPars->nTfoFanMax = 4; // the max number of fanouts (windowing) - pPars->nWinSizeMax = 0; // maximum window size (windowing) - pPars->nBTLimit = 0; // maximum number of SAT conflicts - pPars->nWords = 1; // simulation word count - pPars->fArea = 0; // area-oriented optimization - pPars->fCover = 0; // use complete cover procedure - pPars->fVerbose = 0; // verbose flag - pPars->fVeryVerbose = 0; // verbose flag + pPars->nLutSize = 4; // target LUT size + pPars->nLutNum = 3; // target LUT count + pPars->nCutSize = (pPars->nLutSize - 1) * pPars->nLutNum + 1; // target cut size + pPars->nCutNum = 128; // target cut count + pPars->nTfoLevels = 5; // the number of TFO levels (windowing) + pPars->nTfoFanMax = 4; // the max number of fanouts (windowing) + pPars->nWinSizeMax = 2000; // maximum window size (windowing) + pPars->nBTLimit = 0; // maximum number of SAT conflicts + pPars->nWords = 1; // simulation word count + pPars->fArea = 0; // area-oriented optimization + pPars->fCover = 0; // use complete cover procedure + pPars->fVerbose = 0; // verbose flag + pPars->fVeryVerbose = 0; // verbose flag } /**Function************************************************************* @@ -227,7 +229,7 @@ Sbd_Man_t * Sbd_ManStart( Gia_Man_t * pGia, Sbd_Par_t * pPars ) for ( w = 0; w < p->pPars->nWords; w++ ) Sbd_ObjSim0(p, Id)[w] = Gia_ManRandomW( 0 ); // cut enumeration - p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, 2*pPars->nLutSize-1, 64, 1, 1 ); + p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, pPars->nCutSize, pPars->nCutNum, 1, 1 ); return p; } void Sbd_ManStop( Sbd_Man_t * p ) @@ -437,6 +439,8 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) Gia_ManIncrementTravId( p->pGia ); Gia_ObjSetTravIdCurrentId(p->pGia, 0); Sbd_ManWindowSim_rec( p, Pivot ); + if ( p->pPars->nWinSizeMax && Vec_IntSize(p->vWinObjs) > p->pPars->nWinSizeMax ) + return 0; Sbd_ManUpdateOrder( p, Pivot ); assert( Vec_IntSize(p->vDivVars) == Vec_IntSize(p->vDivValues) ); assert( Vec_IntSize(p->vDivVars) < Vec_IntSize(p->vWinObjs) ); @@ -461,6 +465,8 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) Vec_IntWriteEntry( p->vObj2Var, Abc_Lit2Var(Node), Vec_IntSize(p->vWinObjs) ); Vec_IntPush( p->vWinObjs, Abc_Lit2Var(Node) ); } + if ( p->pPars->nWinSizeMax && Vec_IntSize(p->vWinObjs) > p->pPars->nWinSizeMax ) + return 0; // compute controlability for node if ( Vec_IntSize(p->vTfo) == 0 ) Abc_TtFill( Sbd_ObjSim2(p, Pivot), p->pPars->nWords ); @@ -473,7 +479,7 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) // propagate controlability to fanins for the TFI nodes starting from the pivot Sbd_ManPropagateControl( p, Pivot ); assert( Vec_IntSize(p->vDivValues) <= 64 ); - return (int)(Vec_IntSize(p->vDivValues) > 64); + return (int)(Vec_IntSize(p->vDivValues) <= 64); } /**Function************************************************************* @@ -489,10 +495,6 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) ***********************************************************************/ int Sbd_ManCheckConst( Sbd_Man_t * p, int Pivot ) { - extern int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, word * pVarSims[], Vec_Int_t * vInds ); - extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); - extern void Sbd_ManPrintObj( Sbd_Man_t * p, int Pivot ); - int nMintCount = 1; Vec_Ptr_t * vSims; word * pSims = Sbd_ObjSim0( p, Pivot ); @@ -984,7 +986,7 @@ static inline int Sbd_ManFindCands( Sbd_Man_t * p, word Cover[64], int nDivs ) int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) { int fVerbose = 0; - abctime clk, clkSat = 0, clkEnu = 0, clkAll = Abc_Clock(); + abctime clk; int nIters, nItersMax = 32; word MatrS[64] = {0}, MatrC[2][64] = {{0}}, Cubes[2][2][64] = {{{0}}}, Cover[64] = {0}, Cube, CubeNew[2]; @@ -1089,14 +1091,10 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) { if ( p->pPars->fVerbose ) printf( "Cannot find a feasible cover.\n" ); - clkEnu += Abc_Clock() - clk; - clkAll = Abc_Clock() - clkAll - clkSat - clkEnu; - p->timeSat += clkSat; - p->timeCov += clkAll; - p->timeEnu += clkEnu; + p->timeCov += Abc_Clock() - clk; return RetValue; } - clkEnu += Abc_Clock() - clk; + p->timeCov += Abc_Clock() - clk; if ( p->pPars->fVerbose ) printf( "Candidate support: " ), @@ -1104,7 +1102,7 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) clk = Abc_Clock(); *pTruth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); - clkSat += Abc_Clock() - clk; + p->timeSat += Abc_Clock() - clk; if ( *pTruth == SBD_SAT_UNDEC ) printf( "Node %d: Undecided.\n", Pivot ); @@ -1143,19 +1141,12 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) } //break; } - //printf( "Node %4d : Iter = %4d Start table = %4d Final table = %4d\n", Pivot, nIters, nRowsOld, nRows ); - clkAll = Abc_Clock() - clkAll - clkSat - clkEnu; - p->timeSat += clkSat; - p->timeCov += clkAll; - p->timeEnu += clkEnu; return RetValue; } int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) { - extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); - extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); - abctime clk, clkSat = 0, clkEnu = 0, clkAll; + abctime clk; word Onset[64] = {0}, Offset[64] = {0}, Cube; word CoverRows[64] = {0}, CoverCols[64] = {0}; int nIters, nItersMax = 32; @@ -1171,12 +1162,11 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) //sat_solver_delete_p( &p->pSat ); p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); p->timeCnf += Abc_Clock() - clk; - clkAll = Abc_Clock(); assert( nConsts <= 8 ); clk = Abc_Clock(); RetValue = Sbd_ManCollectConstantsNew( p->pSat, p->vDivVars, nConsts, PivotVar, Onset, Offset ); - clkSat += Abc_Clock() - clk; + p->timeSat += Abc_Clock() - clk; if ( RetValue >= 0 ) { if ( p->pPars->fVeryVerbose ) @@ -1215,21 +1205,18 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) { if ( p->pPars->fVeryVerbose ) printf( "Cannot find a feasible cover.\n" ); - clkEnu += Abc_Clock() - clk; - clkAll = Abc_Clock() - clkAll - clkSat - clkEnu; - p->timeSat += clkSat; - p->timeCov += clkAll; - p->timeEnu += clkEnu; + p->timeCov += Abc_Clock() - clk; return 0; } - + p->timeCov += Abc_Clock() - clk; + if ( p->pPars->fVeryVerbose ) printf( "Candidate support: " ), Vec_IntPrint( p->vDivSet ); clk = Abc_Clock(); *pTruth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); - clkSat += Abc_Clock() - clk; + p->timeSat += Abc_Clock() - clk; if ( *pTruth == SBD_SAT_UNDEC ) printf( "Node %d: Undecided.\n", Pivot ); @@ -1271,65 +1258,42 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) break; } } - clkAll = Abc_Clock() - clkAll - clkSat - clkEnu; - p->timeSat += clkSat; - p->timeCov += clkAll; - p->timeEnu += clkEnu; return RetValue; } -int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) +int Sbd_ManExploreCut( Sbd_Man_t * p, int Pivot, int nLeaves, int * pLeaves, int * pnStrs, Sbd_Str_t * Strs, int * pFreeVar ) { - extern int Sbd_ProblemSolve( - Gia_Man_t * p, Vec_Int_t * vMirrors, - int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, - Vec_Int_t * vTfo, Vec_Int_t * vRoots, - Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0 - ); - extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); - extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); abctime clk = Abc_Clock(); - word Truth; - int PivotVar = Vec_IntEntry(p->vObj2Var, Pivot); - int FreeVar = Vec_IntSize(p->vWinObjs) + Vec_IntSize(p->vTfo) + Vec_IntSize(p->vRoots); - //int nDivs = Vec_IntSize( p->vDivVars ); int Delay = Vec_IntEntry( p->vLutLevs, Pivot ); - int i, k, iObj, nIters, RetValue; + int pNodesTop[SBD_DIV_MAX], pNodesBot[SBD_DIV_MAX], pNodesBot1[SBD_DIV_MAX], pNodesBot2[SBD_DIV_MAX]; + int nNodesTop = 0, nNodesBot = 0, nNodesBot1 = 0, nNodesBot2 = 0, nNodesDiff = 0, nNodesDiff1 = 0, nNodesDiff2 = 0; + int i, k, iObj, nIters, RetValue = 0; - int nLeaves, pLeaves[SBD_DIV_MAX]; - - int pNodesTop[SBD_DIV_MAX], pNodesBot[SBD_DIV_MAX];//, pNodeRefs[SBD_DIV_MAX]; - int nNodesTop = 0, nNodesBot = 0, nNodesDiff = 0; - - //sat_solver_delete_p( &p->pSat ); - p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); - p->timeCnf += Abc_Clock() - clk; - - // extract one cut - nLeaves = Sbd_StoObjBestCut( p->pSto, Pivot, pLeaves ); - if ( nLeaves == -1 ) - return 0; - - // solve the covering problem + // try to remove fanins for ( nIters = 0; nIters < nLeaves; nIters++ ) { + word Truth; // try to remove one variable from divisors Vec_IntClear( p->vDivSet ); for ( i = 0; i < nLeaves; i++ ) - if ( i != nIters && pLeaves[i] != -1 ) + if ( i != nLeaves-1-nIters && pLeaves[i] != -1 ) Vec_IntPush( p->vDivSet, Vec_IntEntry(p->vObj2Var, pLeaves[i]) ); assert( Vec_IntSize(p->vDivSet) < nLeaves ); // compute truth table clk = Abc_Clock(); - Truth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); + Truth = Sbd_ManSolve( p->pSat, PivotVar, (*pFreeVar)++, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); p->timeSat += Abc_Clock() - clk; if ( Truth == SBD_SAT_UNDEC ) printf( "Node %d: Undecided.\n", Pivot ); else if ( Truth == SBD_SAT_SAT ) - continue; + { + int DelayDiff = Vec_IntEntry(p->vLutLevs, pLeaves[nLeaves-1-nIters]) - Delay; + if ( DelayDiff > -2 ) + return 0; + } else - pLeaves[nIters] = -1; + pLeaves[nLeaves-1-nIters] = -1; } Vec_IntClear( p->vDivSet ); for ( i = 0; i < nLeaves; i++ ) @@ -1338,13 +1302,14 @@ int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) //printf( "Reduced %d -> %d\n", nLeaves, Vec_IntSize(p->vDivSet) ); if ( Vec_IntSize(p->vDivSet) <= p->pPars->nLutSize ) { + word Truth; *pnStrs = 1; // remap divisors Vec_IntForEachEntry( p->vDivSet, iObj, i ) Vec_IntWriteEntry( p->vDivSet, i, Vec_IntEntry(p->vObj2Var, iObj) ); // compute truth table clk = Abc_Clock(); - Truth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); + Truth = Sbd_ManSolve( p->pSat, PivotVar, (*pFreeVar)++, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); p->timeSat += Abc_Clock() - clk; assert( Truth != SBD_SAT_UNDEC && Truth != SBD_SAT_SAT ); // create structure @@ -1360,7 +1325,7 @@ int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) assert( Vec_IntSize(p->vDivSet) > p->pPars->nLutSize ); // count number of nodes on each level - nNodesTop = 0, nNodesBot = 0; + nNodesTop = nNodesBot = nNodesBot1 = nNodesBot2 = 0; Vec_IntForEachEntry( p->vDivSet, iObj, i ) { int DelayDiff = Vec_IntEntry(p->vLutLevs, iObj) - Delay; @@ -1369,60 +1334,227 @@ int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) if ( DelayDiff == -2 ) pNodesTop[nNodesTop++] = i; else // if ( DelayDiff < -2 ) + { pNodesBot[nNodesBot++] = i; + if ( DelayDiff == -3 ) + pNodesBot1[nNodesBot1++] = i; + else // if ( DelayDiff < -3 ) + pNodesBot2[nNodesBot2++] = i; + } Vec_IntWriteEntry( p->vDivSet, i, Vec_IntEntry(p->vObj2Var, iObj) ); - //pNodeRefs[i] = Gia_ObjRefNumId( p->pGia, iObj ); } + assert( nNodesBot == nNodesBot1 + nNodesBot2 ); if ( i < Vec_IntSize(p->vDivSet) ) return 0; if ( nNodesTop > p->pPars->nLutSize-1 ) return 0; - if ( nNodesBot > p->pPars->nLutSize ) + + // try 44 + if ( Vec_IntSize(p->vDivSet) <= 2*p->pPars->nLutSize-1 ) { - // move left-over to the top - while ( nNodesBot > p->pPars->nLutSize ) - pNodesTop[nNodesTop++] = pNodesBot[--nNodesBot]; - assert( nNodesBot == p->pPars->nLutSize ); + int nMoved = 0; + if ( nNodesBot > p->pPars->nLutSize ) // need to move bottom left-over to the top + { + while ( nNodesBot > p->pPars->nLutSize ) + pNodesTop[nNodesTop++] = pNodesBot[--nNodesBot], nMoved++; + assert( nNodesBot == p->pPars->nLutSize ); + } + assert( nNodesBot <= p->pPars->nLutSize ); assert( nNodesTop <= p->pPars->nLutSize-1 ); - } - nNodesDiff = p->pPars->nLutSize-1 - nNodesTop; - - // number of structures - *pnStrs = 2 + nNodesDiff; - Strs[0].fLut = 1; - Strs[0].nVarIns = p->pPars->nLutSize; - for ( i = 0; i < nNodesTop; i++ ) - Strs[0].VarIns[i] = pNodesTop[i]; - for ( ; i < p->pPars->nLutSize; i++ ) - Strs[0].VarIns[i] = Vec_IntSize(p->vDivSet)+1 + i-nNodesTop; - Strs[0].Res = 0; + Strs[0].fLut = 1; + Strs[0].nVarIns = p->pPars->nLutSize; + for ( i = 0; i < nNodesTop; i++ ) + Strs[0].VarIns[i] = pNodesTop[i]; + for ( ; i < p->pPars->nLutSize; i++ ) + Strs[0].VarIns[i] = Vec_IntSize(p->vDivSet)+1 + i-nNodesTop; + Strs[0].Res = 0; - Strs[1].fLut = 1; - Strs[1].nVarIns = nNodesBot; - for ( i = 0; i < nNodesBot; i++ ) - Strs[1].VarIns[i] = pNodesBot[i]; - Strs[1].Res = 0; - - for ( k = 0; k < nNodesDiff; k++ ) - { - Strs[2+k].fLut = 0; - Strs[2+k].nVarIns = nNodesBot; + Strs[1].fLut = 1; + Strs[1].nVarIns = nNodesBot; for ( i = 0; i < nNodesBot; i++ ) - Strs[2+k].VarIns[i] = pNodesBot[i]; - Strs[2+k].Res = 0; + Strs[1].VarIns[i] = pNodesBot[i]; + Strs[1].Res = 0; + + nNodesDiff = p->pPars->nLutSize-1 - nNodesTop; + assert( nNodesDiff >= 0 && nNodesDiff <= 3 ); + for ( k = 0; k < nNodesDiff; k++ ) + { + Strs[2+k].fLut = 0; + Strs[2+k].nVarIns = nNodesBot; + for ( i = 0; i < nNodesBot; i++ ) + Strs[2+k].VarIns[i] = pNodesBot[i]; + Strs[2+k].Res = 0; + } + + *pnStrs = 2 + nNodesDiff; + clk = Abc_Clock(); + RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, p->vDivSet, *pnStrs, Strs ); + p->timeQbf += Abc_Clock() - clk; + if ( RetValue ) + p->nLuts[2]++; + + while ( nMoved-- ) + pNodesBot[nNodesBot++] = pNodesTop[--nNodesTop]; } - clk = Abc_Clock(); - RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, - Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, - p->vDivSet, *pnStrs, Strs ); - p->timeQbf += Abc_Clock() - clk; + if ( RetValue ) + return RetValue; + if ( p->pPars->nLutNum < 3 ) + return 0; + if ( Vec_IntSize(p->vDivSet) < 2*p->pPars->nLutSize-1 ) + return 0; - if ( RetValue ) - p->nLuts[2]++; + // try 444 -- LUT(LUT, LUT) + if ( nNodesTop <= p->pPars->nLutSize-2 ) + { + int nMoved = 0; + if ( nNodesBot > 2*p->pPars->nLutSize ) // need to move bottom left-over to the top + { + while ( nNodesBot > 2*p->pPars->nLutSize ) + pNodesTop[nNodesTop++] = pNodesBot[--nNodesBot], nMoved++; + assert( nNodesBot == 2*p->pPars->nLutSize ); + } + assert( nNodesBot > p->pPars->nLutSize ); + assert( nNodesBot <= 2*p->pPars->nLutSize ); + assert( nNodesTop <= p->pPars->nLutSize-2 ); + + Strs[0].fLut = 1; + Strs[0].nVarIns = p->pPars->nLutSize; + for ( i = 0; i < nNodesTop; i++ ) + Strs[0].VarIns[i] = pNodesTop[i]; + for ( ; i < p->pPars->nLutSize; i++ ) + Strs[0].VarIns[i] = Vec_IntSize(p->vDivSet)+1 + i-nNodesTop; + Strs[0].Res = 0; + + Strs[1].fLut = 1; + Strs[1].nVarIns = p->pPars->nLutSize; + for ( i = 0; i < Strs[1].nVarIns; i++ ) + Strs[1].VarIns[i] = pNodesBot[i]; + Strs[1].Res = 0; + + Strs[2].fLut = 1; + Strs[2].nVarIns = p->pPars->nLutSize; + for ( i = 0; i < Strs[2].nVarIns; i++ ) + Strs[2].VarIns[i] = pNodesBot[nNodesBot-p->pPars->nLutSize+i]; + Strs[2].Res = 0; + + nNodesDiff = p->pPars->nLutSize-2 - nNodesTop; + assert( nNodesDiff >= 0 && nNodesDiff <= 2 ); + for ( k = 0; k < nNodesDiff; k++ ) + { + Strs[3+k].fLut = 0; + Strs[3+k].nVarIns = nNodesBot; + for ( i = 0; i < nNodesBot; i++ ) + Strs[3+k].VarIns[i] = pNodesBot[i]; + Strs[3+k].Res = 0; + } + + *pnStrs = 3 + nNodesDiff; + clk = Abc_Clock(); + RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, p->vDivSet, *pnStrs, Strs ); + p->timeQbf += Abc_Clock() - clk; + if ( RetValue ) + p->nLuts[3]++; + + while ( nMoved-- ) + pNodesBot[nNodesBot++] = pNodesTop[--nNodesTop]; + } + if ( RetValue ) + return RetValue; + + // try 444 -- LUT(LUT(LUT)) + if ( nNodesBot1 + nNodesTop <= 2*p->pPars->nLutSize-2 ) + { + if ( nNodesBot2 > p->pPars->nLutSize ) // need to move bottom left-over to the top + { + while ( nNodesBot2 > p->pPars->nLutSize ) + pNodesBot1[nNodesBot1++] = pNodesBot2[--nNodesBot2]; + assert( nNodesBot2 == p->pPars->nLutSize ); + } + if ( nNodesBot1 > p->pPars->nLutSize-1 ) // need to move bottom left-over to the top + { + while ( nNodesBot1 > p->pPars->nLutSize-1 ) + pNodesTop[nNodesTop++] = pNodesBot1[--nNodesBot1]; + assert( nNodesBot1 == p->pPars->nLutSize-1 ); + } + assert( nNodesBot2 <= p->pPars->nLutSize ); + assert( nNodesBot1 <= p->pPars->nLutSize-1 ); + assert( nNodesTop <= p->pPars->nLutSize-1 ); + + Strs[0].fLut = 1; + Strs[0].nVarIns = p->pPars->nLutSize; + for ( i = 0; i < nNodesTop; i++ ) + Strs[0].VarIns[i] = pNodesTop[i]; + Strs[0].VarIns[i++] = Vec_IntSize(p->vDivSet)+1; + for ( ; i < p->pPars->nLutSize; i++ ) + Strs[0].VarIns[i] = Vec_IntSize(p->vDivSet)+2 + i-nNodesTop; + Strs[0].Res = 0; + nNodesDiff1 = p->pPars->nLutSize-1 - nNodesTop; + + Strs[1].fLut = 1; + Strs[1].nVarIns = p->pPars->nLutSize; + for ( i = 0; i < nNodesBot1; i++ ) + Strs[1].VarIns[i] = pNodesBot1[i]; + Strs[1].VarIns[i++] = Vec_IntSize(p->vDivSet)+2; + for ( ; i < p->pPars->nLutSize; i++ ) + Strs[1].VarIns[i] = Vec_IntSize(p->vDivSet)+2+nNodesDiff1 + i-nNodesBot1; + Strs[1].Res = 0; + nNodesDiff2 = p->pPars->nLutSize-1 - nNodesBot1; + + Strs[2].fLut = 1; + Strs[2].nVarIns = nNodesBot2; + for ( i = 0; i < Strs[2].nVarIns; i++ ) + Strs[2].VarIns[i] = pNodesBot2[i]; + Strs[2].Res = 0; + + nNodesDiff = nNodesDiff1 + nNodesDiff2; + assert( nNodesDiff >= 0 && nNodesDiff <= 3 ); + for ( k = 0; k < nNodesDiff; k++ ) + { + Strs[3+k].fLut = 0; + Strs[3+k].nVarIns = nNodesBot2; + for ( i = 0; i < nNodesBot2; i++ ) + Strs[3+k].VarIns[i] = pNodesBot2[i]; + Strs[3+k].Res = 0; + if ( k >= nNodesDiff1 ) + continue; + Strs[3+k].nVarIns += nNodesBot1; + for ( i = 0; i < nNodesBot1; i++ ) + Strs[3+k].VarIns[nNodesBot2 + i] = pNodesBot1[i]; + } + + *pnStrs = 3 + nNodesDiff; + clk = Abc_Clock(); + RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, p->vDivSet, *pnStrs, Strs ); + p->timeQbf += Abc_Clock() - clk; + if ( RetValue ) + p->nLuts[4]++; + } return RetValue; } +int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) +{ + int FreeVar = Vec_IntSize(p->vWinObjs) + Vec_IntSize(p->vTfo) + Vec_IntSize(p->vRoots); + int FreeVarStart = FreeVar; + int nSize, nLeaves, pLeaves[SBD_DIV_MAX]; + //sat_solver_delete_p( &p->pSat ); + abctime clk = Abc_Clock(); + p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); + p->timeCnf += Abc_Clock() - clk; + // extract one cut + for ( nSize = p->pPars->nLutSize + 1; nSize <= p->pPars->nCutSize; nSize++ ) + { + nLeaves = Sbd_StoObjBestCut( p->pSto, Pivot, nSize, pLeaves ); + if ( nLeaves == -1 ) + continue; + assert( nLeaves == nSize ); + if ( Sbd_ManExploreCut( p, Pivot, nLeaves, pLeaves, pnStrs, Strs, &FreeVar ) ) + return 1; + } + assert( FreeVar - FreeVarStart <= SBD_FVAR_MAX ); + return 0; +} /**Function************************************************************* @@ -1722,7 +1854,10 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) // extend data-structure to accommodate new nodes assert( Vec_IntSize(p->vLutLevs) == iObjLast ); for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) + { + Vec_IntPush( p->vMirrors, -1 ); Sbd_StoRefObj( p->pSto, i, i == Gia_ManObjNum(p->pGia)-1 ? Pivot : -1 ); + } Sbd_StoDerefObj( p->pSto, Pivot ); for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) { @@ -1730,7 +1865,6 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) assert( i == Vec_IntSize(p->vLutLevs) ); Vec_IntPush( p->vLutLevs, Delay ); Vec_IntPush( p->vObj2Var, 0 ); - Vec_IntPush( p->vMirrors, -1 ); Vec_IntFillExtra( p->vLutCuts, Vec_IntSize(p->vLutCuts) + p->pPars->nLutSize + 1, 0 ); //Sbd_ManFindCut( p, i, p->vLits ); for ( k = 0; k < 4; k++ ) @@ -1820,22 +1954,16 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) ***********************************************************************/ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) { - Sbd_Str_t Strs[4]; - int i, RetValue, nStrs = 0; - word Truth = 0; - - if ( !p->pSto ) - { - if ( Sbd_ManMergeCuts( p, Pivot ) ) - return; - } - -// if ( Pivot != 15 ) -// return; - - if ( Sbd_ManWindow( p, Pivot ) ) + Sbd_Str_t Strs[SBD_DIV_MAX]; word Truth = 0; + int RetValue, nStrs = 0; + if ( !p->pSto && Sbd_ManMergeCuts( p, Pivot ) ) return; - + if ( !Sbd_ManWindow( p, Pivot ) ) + return; + //if ( Vec_IntSize(p->vWinObjs) > 100 ) + // printf( "Obj %d : Win = %d TFO = %d. Roots = %d.\n", Pivot, Vec_IntSize(p->vWinObjs), Vec_IntSize(p->vTfo), Vec_IntSize(p->vRoots) ); + p->nTried++; + p->nUsed++; RetValue = Sbd_ManCheckConst( p, Pivot ); if ( RetValue >= 0 ) { @@ -1844,6 +1972,7 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) } else if ( p->pPars->nLutNum >= 1 && Sbd_ManExplore2( p, Pivot, &Truth ) ) { + int i; Strs->fLut = 1; Strs->nVarIns = Vec_IntSize( p->vDivSet ); for ( i = 0; i < Strs->nVarIns; i++ ) @@ -1855,8 +1984,17 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) else if ( p->pPars->nLutNum >= 2 && Sbd_ManExplore3( p, Pivot, &nStrs, Strs ) ) { Sbd_ManImplement2( p, Pivot, nStrs, Strs ); - if ( p->pPars->fVerbose ) printf( "Node %5d: Detected %d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize ); + if ( !p->pPars->fVerbose ) + return; + if ( Vec_IntSize(p->vDivSet) <= 4 ) + printf( "Node %5d: Detected %d\n", Pivot, p->pPars->nLutSize ); + else if ( Vec_IntSize(p->vDivSet) <= 6 || (Vec_IntSize(p->vDivSet) == 7 && nStrs == 2) ) + printf( "Node %5d: Detected %d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize ); + else + printf( "Node %5d: Detected %d%d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize, p->pPars->nLutSize ); } + else + p->nUsed--; } Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) { @@ -1875,6 +2013,7 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) Vec_Int_t * vNodes = Gia_ManOrderWithBoxes( pGia ); Tim_Man_t * pTimOld = (Tim_Man_t *)pGia->pManTime; pGia->pManTime = Tim_ManDup( pTimOld, 1 ); + //Tim_ManPrint( pGia->pManTime ); Tim_ManIncrementTravId( (Tim_Man_t *)pGia->pManTime ); Gia_ManForEachObjVec( vNodes, pGia, pObj, k ) { @@ -1883,9 +2022,11 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) break; if ( Gia_ObjIsAnd(pObj) ) { + abctime clk = Abc_Clock(); int Delay = Sbd_StoComputeCutsNode( p->pSto, Pivot ); + p->timeCut += Abc_Clock() - clk; Vec_IntWriteEntry( p->vLutLevs, Pivot, Delay ); - if ( Delay > 1 ) + if ( Delay > 1 )//&& Gia_ObjRefNumId(p->pGia, Pivot) > 1 ) Sbd_NtkPerformOne( p, Pivot ); } else if ( Gia_ObjIsCi(pObj) ) @@ -1903,7 +2044,6 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) Sbd_StoComputeCutsConst0( p->pSto, 0 ); else assert( 0 ); } - //Tim_ManPrint( pGia->pManTime ); Tim_ManStop( (Tim_Man_t *)pGia->pManTime ); pGia->pManTime = pTimOld; Vec_IntFree( vNodes ); @@ -1919,29 +2059,33 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) Sbd_StoComputeCutsCi( p->pSto, Pivot, 0, 0 ); else if ( Gia_ObjIsAnd(pObj) ) { + abctime clk = Abc_Clock(); int Delay = Sbd_StoComputeCutsNode( p->pSto, Pivot ); + p->timeCut += Abc_Clock() - clk; Vec_IntWriteEntry( p->vLutLevs, Pivot, Delay ); - if ( Delay > 1 ) + if ( Delay > 1 )//&& Gia_ObjRefNumId(p->pGia, Pivot) > 1 ) Sbd_NtkPerformOne( p, Pivot ); } //if ( nNodesOld != Gia_ManObjNum(pGia) ) // break; } } - printf( "Found %d constants, %d one-LUT and %d two-LUT replacements with delay %d. ", - p->nLuts[0], p->nLuts[1], p->nLuts[2], Sbd_ManDelay(p) ); + printf( "K = %d. S = %d. N = %d. P = %d. ", + p->pPars->nLutSize, p->pPars->nLutNum, p->pPars->nCutSize, p->pPars->nCutNum ); + printf( "Try = %d. Use = %d. C = %d. 1 = %d. 2 = %d. 3a = %d. 3b = %d. Lev = %d. ", + p->nTried, p->nUsed, p->nLuts[0], p->nLuts[1], p->nLuts[2], p->nLuts[3], p->nLuts[4], Sbd_ManDelay(p) ); p->timeTotal = Abc_Clock() - p->timeTotal; Abc_PrintTime( 1, "Time", p->timeTotal ); pNew = Sbd_ManDerive( pGia, p->vMirrors ); // print runtime statistics - p->timeOther = p->timeTotal - p->timeWin - p->timeCnf - p->timeSat - p->timeCov - p->timeEnu - p->timeQbf; - if ( p->pPars->fVerbose ) + p->timeOther = p->timeTotal - p->timeWin - p->timeCut - p->timeCov - p->timeCnf - p->timeSat - p->timeQbf; + //if ( p->pPars->fVerbose ) { ABC_PRTP( "Win", p->timeWin , p->timeTotal ); + ABC_PRTP( "Cut", p->timeCut , p->timeTotal ); + ABC_PRTP( "Cov", p->timeCov , p->timeTotal ); ABC_PRTP( "Cnf", p->timeCnf , p->timeTotal ); ABC_PRTP( "Sat", p->timeSat , p->timeTotal ); - ABC_PRTP( "Cov", p->timeCov , p->timeTotal ); - ABC_PRTP( "Enu", p->timeEnu , p->timeTotal ); ABC_PRTP( "Qbf", p->timeQbf , p->timeTotal ); ABC_PRTP( "Oth", p->timeOther, p->timeTotal ); ABC_PRTP( "ALL", p->timeTotal, p->timeTotal ); diff --git a/src/opt/sbd/sbdCut.c b/src/opt/sbd/sbdCut.c index 9c54c74ae..7bcf2189f 100644 --- a/src/opt/sbd/sbdCut.c +++ b/src/opt/sbd/sbdCut.c @@ -27,9 +27,9 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -#define SBD_MAX_CUTSIZE 8 -#define SBD_MAX_CUTNUM 1001 -#define SBD_MAX_TT_WORDS ((SBD_MAX_CUTSIZE > 6) ? 1 << (SBD_MAX_CUTSIZE-6) : 1) +#define SBD_MAX_CUTSIZE 10 +#define SBD_MAX_CUTNUM 501 +#define SBD_MAX_TT_WORDS ((SBD_MAX_CUTSIZE > 6) ? 1 << (SBD_MAX_CUTSIZE-6) : 1) #define SBD_CUT_NO_LEAF 0xF @@ -568,6 +568,7 @@ static inline void Sbd_CutPrint( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) { int i, nDigits = Abc_Base10Log(Gia_ManObjNum(p->pGia)); int Delay = Vec_IntEntry(p->vDelays, iObj); + if ( pCut == NULL ) { printf( "No cut.\n" ); return; } printf( "%d {", pCut->nLeaves ); for ( i = 0; i < (int)pCut->nLeaves; i++ ) printf( " %*d", nDigits, pCut->pLeaves[i] ); @@ -724,45 +725,88 @@ int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ) Sbd_StoMergeCuts( p, iObj ); return Vec_IntEntry( p->vDelays, iObj ); } +int Sbd_StoObjRefs( Sbd_Sto_t * p, int iObj ) +{ + return Vec_IntEntry(p->vRefs, iObj); +} void Sbd_StoRefObj( Sbd_Sto_t * p, int iObj, int iMirror ) { Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj); assert( iObj == Vec_IntSize(p->vRefs) ); assert( iMirror < iObj ); - Vec_IntPush( p->vRefs, iMirror > 0 ? Vec_IntEntry(p->vRefs, iMirror) : 0 ); + Vec_IntPush( p->vRefs, 0 ); +//printf( "Ref %d\n", iObj ); + if ( iMirror > 0 ) + { + Vec_IntWriteEntry( p->vRefs, iObj, Vec_IntEntry(p->vRefs, iMirror) ); + Vec_IntWriteEntry( p->vRefs, iMirror, 1 ); + } if ( Gia_ObjIsAnd(pObj) ) { - Vec_IntAddToEntry( p->vRefs, Gia_ObjFaninId0(pObj, iObj), 1 ); - Vec_IntAddToEntry( p->vRefs, Gia_ObjFaninId1(pObj, iObj), 1 ); + int Lit0m = Vec_IntEntry( p->vMirrors, Gia_ObjFaninId0(pObj, iObj) ); + int Lit1m = Vec_IntEntry( p->vMirrors, Gia_ObjFaninId1(pObj, iObj) ); + int Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, iObj); + int Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, iObj); + Vec_IntAddToEntry( p->vRefs, Fan0, 1 ); + Vec_IntAddToEntry( p->vRefs, Fan1, 1 ); } else if ( Gia_ObjIsCo(pObj) ) + { + int Lit0m = Vec_IntEntry( p->vMirrors, Gia_ObjFaninId0(pObj, iObj) ); + assert( Lit0m == -1 ); Vec_IntAddToEntry( p->vRefs, Gia_ObjFaninId0(pObj, iObj), 1 ); + } } void Sbd_StoDerefObj( Sbd_Sto_t * p, int iObj ) { - Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj); + Gia_Obj_t * pObj; + int Lit0m, Lit1m, Fan0, Fan1; + return; + + pObj = Gia_ManObj(p->pGia, iObj); + if ( Vec_IntEntry(p->vRefs, iObj) == 0 ) + printf( "Ref count mismatch at node %d\n", iObj ); + assert( Vec_IntEntry(p->vRefs, iObj) > 0 ); Vec_IntAddToEntry( p->vRefs, iObj, -1 ); if ( Vec_IntEntry( p->vRefs, iObj ) > 0 ) return; if ( Gia_ObjIsCi(pObj) ) return; +//printf( "Deref %d\n", iObj ); assert( Gia_ObjIsAnd(pObj) ); - Sbd_StoDerefObj( p, Gia_ObjFaninId0(pObj, iObj) ); - Sbd_StoDerefObj( p, Gia_ObjFaninId1(pObj, iObj) ); + Lit0m = Vec_IntEntry( p->vMirrors, Gia_ObjFaninId0(pObj, iObj) ); + Lit1m = Vec_IntEntry( p->vMirrors, Gia_ObjFaninId1(pObj, iObj) ); + Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, iObj); + Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, iObj); + if ( Fan0 ) Sbd_StoDerefObj( p, Fan0 ); + if ( Fan1 ) Sbd_StoDerefObj( p, Fan1 ); } -int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int * pLeaves ) +int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int nSize, int * pLeaves ) { + int fVerbose = 0; Sbd_Cut_t * pCutBest = NULL; int i; assert( p->Pivot == iObj ); + if ( fVerbose && iObj % 1000 == 0 ) + printf( "Node %6d : \n", iObj ); for ( i = 0; i < p->nCutsR; i++ ) + { + if ( fVerbose && iObj % 1000 == 0 ) + Sbd_CutPrint( p, iObj, p->ppCuts[i] ); + if ( nSize && (int)p->ppCuts[i]->nLeaves != nSize ) + continue; if ( (int)p->ppCuts[i]->nLeaves > p->nLutSize && - (int)p->ppCuts[i]->nSlowLeaves == 0 && + (int)p->ppCuts[i]->nSlowLeaves <= 1 && (int)p->ppCuts[i]->nTopLeaves <= p->nLutSize-1 && (pCutBest == NULL || Sbd_CutCompare2(pCutBest, p->ppCuts[i]) == 1) ) pCutBest = p->ppCuts[i]; + } + if ( fVerbose && iObj % 1000 == 0 ) + { + printf( "Best cut of size %d:\n", nSize ); + Sbd_CutPrint( p, iObj, pCutBest ); + } if ( pCutBest == NULL ) return -1; -//Sbd_CutPrint( p, iObj, pCutBest ); assert( pCutBest->nLeaves <= SBD_DIV_MAX ); for ( i = 0; i < (int)pCutBest->nLeaves; i++ ) pLeaves[i] = pCutBest->pLeaves[i]; diff --git a/src/opt/sbd/sbdInt.h b/src/opt/sbd/sbdInt.h index d54285f8f..668c12315 100644 --- a/src/opt/sbd/sbdInt.h +++ b/src/opt/sbd/sbdInt.h @@ -52,9 +52,10 @@ ABC_NAMESPACE_HEADER_START #define SBD_SAT_UNDEC 0x1234567812345678 #define SBD_SAT_SAT 0x8765432187654321 -#define SBD_LUTS_MAX 2 -#define SBD_SIZE_MAX 4 -#define SBD_DIV_MAX 8 +#define SBD_LUTS_MAX 2 +#define SBD_SIZE_MAX 4 +#define SBD_DIV_MAX 10 +#define SBD_FVAR_MAX 100 //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -81,16 +82,28 @@ struct Sbd_Str_t_ //////////////////////////////////////////////////////////////////////// /*=== sbdCut.c ==========================================================*/ -extern Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, Vec_Int_t * vMirrors, int nLutSize, int nCutSize, int nCutNum, int fCutMin, int fVerbose ); -extern void Sbd_StoFree( Sbd_Sto_t * p ); -extern void Sbd_StoRefObj( Sbd_Sto_t * p, int iObj, int iMirror ); -extern void Sbd_StoDerefObj( Sbd_Sto_t * p, int iObj ); -extern void Sbd_StoComputeCutsConst0( Sbd_Sto_t * p, int iObj ); -extern void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ); -extern void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ); -extern int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ); -extern int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int * pLeaves ); - +extern Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, Vec_Int_t * vMirrors, int nLutSize, int nCutSize, int nCutNum, int fCutMin, int fVerbose ); +extern void Sbd_StoFree( Sbd_Sto_t * p ); +extern int Sbd_StoObjRefs( Sbd_Sto_t * p, int iObj ); +extern void Sbd_StoRefObj( Sbd_Sto_t * p, int iObj, int iMirror ); +extern void Sbd_StoDerefObj( Sbd_Sto_t * p, int iObj ); +extern void Sbd_StoComputeCutsConst0( Sbd_Sto_t * p, int iObj ); +extern void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ); +extern void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ); +extern int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ); +extern int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int nSize, int * pLeaves ); +/*=== sbdWin.c ==========================================================*/ +extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivSet, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp ); +extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); +extern int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, word * pVarSims[], Vec_Int_t * vInds ); +extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); +/*=== sbdQbf.c ==========================================================*/ +extern int Sbd_ProblemSolve( + Gia_Man_t * p, Vec_Int_t * vMirrors, + int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, + Vec_Int_t * vTfo, Vec_Int_t * vRoots, + Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0 + ); ABC_NAMESPACE_HEADER_END diff --git a/src/opt/sbd/sbdLut.c b/src/opt/sbd/sbdLut.c index e8aee7900..ffcb71f84 100644 --- a/src/opt/sbd/sbdLut.c +++ b/src/opt/sbd/sbdLut.c @@ -96,7 +96,6 @@ int Sbd_ProblemAddClauses( sat_solver * pSat, int nVars, int nStrs, int * pVars, } } } -//printf( "Stop par = %d.\n", VarPar ); return 1; } void Sbd_ProblemAddClausesInit( sat_solver * pSat, int nVars, int nStrs, int * pVars, Sbd_Str_t * pStr0 ) diff --git a/src/opt/sbd/sbdWin.c b/src/opt/sbd/sbdWin.c index d5b7dd9d6..b62332d15 100644 --- a/src/opt/sbd/sbdWin.c +++ b/src/opt/sbd/sbdWin.c @@ -54,7 +54,6 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ) { Gia_Obj_t * pObj; - int nAddVars = 64; int i, iLit = 1, iObj, Fan0, Fan1, Lit0m, Lit1m, Node, fCompl0, fCompl1, RetValue; int TfoStart = Vec_IntSize(vWinObjs) - Vec_IntSize(vTfo); int PivotVar = Vec_IntEntry(vObj2Var, Pivot); @@ -67,7 +66,7 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi pSat = sat_solver_new(); else sat_solver_restart( pSat ); - sat_solver_setnvars( pSat, Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots) + nAddVars ); + sat_solver_setnvars( pSat, Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots) + SBD_FVAR_MAX ); // create constant 0 clause sat_solver_addclause( pSat, &iLit, &iLit + 1 ); // add clauses for all nodes @@ -139,7 +138,7 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi sat_solver_delete( pSat ); return NULL; } - assert( sat_solver_nvars(pSat) == nVars + nAddVars ); + assert( sat_solver_nvars(pSat) == nVars + SBD_FVAR_MAX ); } else if ( fQbf ) { From 8eb5d1896a82ef9d1d5e0f25bb6f23e29e9e2ada Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 31 Dec 2016 21:46:25 +0700 Subject: [PATCH 020/185] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 10 ++++++++++ src/opt/sbd/sbdWin.c | 2 ++ 2 files changed, 12 insertions(+) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index a48e6489f..251a4deb7 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -52,6 +52,7 @@ struct Sbd_Man_t_ abctime timeCnf; abctime timeSat; abctime timeQbf; + abctime timeNew; abctime timeOther; abctime timeTotal; Sbd_Sto_t * pSto; @@ -440,7 +441,10 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) Gia_ObjSetTravIdCurrentId(p->pGia, 0); Sbd_ManWindowSim_rec( p, Pivot ); if ( p->pPars->nWinSizeMax && Vec_IntSize(p->vWinObjs) > p->pPars->nWinSizeMax ) + { + p->timeWin += Abc_Clock() - clk; return 0; + } Sbd_ManUpdateOrder( p, Pivot ); assert( Vec_IntSize(p->vDivVars) == Vec_IntSize(p->vDivValues) ); assert( Vec_IntSize(p->vDivVars) < Vec_IntSize(p->vWinObjs) ); @@ -466,7 +470,10 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) Vec_IntPush( p->vWinObjs, Abc_Lit2Var(Node) ); } if ( p->pPars->nWinSizeMax && Vec_IntSize(p->vWinObjs) > p->pPars->nWinSizeMax ) + { + p->timeWin += Abc_Clock() - clk; return 0; + } // compute controlability for node if ( Vec_IntSize(p->vTfo) == 0 ) Abc_TtFill( Sbd_ObjSim2(p, Pivot), p->pPars->nWords ); @@ -1855,13 +1862,16 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) assert( Vec_IntSize(p->vLutLevs) == iObjLast ); for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) { + assert( i == Vec_IntSize(p->vMirrors) ); Vec_IntPush( p->vMirrors, -1 ); Sbd_StoRefObj( p->pSto, i, i == Gia_ManObjNum(p->pGia)-1 ? Pivot : -1 ); } Sbd_StoDerefObj( p->pSto, Pivot ); for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) { + abctime clk = Abc_Clock(); int Delay = Sbd_StoComputeCutsNode( p->pSto, i ); + p->timeCut += Abc_Clock() - clk; assert( i == Vec_IntSize(p->vLutLevs) ); Vec_IntPush( p->vLutLevs, Delay ); Vec_IntPush( p->vObj2Var, 0 ); diff --git a/src/opt/sbd/sbdWin.c b/src/opt/sbd/sbdWin.c index b62332d15..069a4125e 100644 --- a/src/opt/sbd/sbdWin.c +++ b/src/opt/sbd/sbdWin.c @@ -360,6 +360,7 @@ void Sbd_ManSolverPrint( Vec_Int_t * vSop ) } Cube[pInds[Abc_Lit2Var(Entry)]] = '1' - (char)Abc_LitIsCompl(Entry); } + Supp = 0; } void Sbd_ManSolveSelect( Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots ) { @@ -378,6 +379,7 @@ void Sbd_ManSolveSelect( Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int word Supp = Sbd_ManSolverSupp( vSop, pInds, &nVars ); //Sbd_ManSolverPrint( vSop ); printf( "SAT with %d vars and %d cubes.\n", nVars, Vec_IntCountEntry(vSop, -1) ); + Supp = 0; } Vec_IntFree( vTemp ); Vec_IntFree( vSop ); From 3f2899d6ea1a141f40d7fdfe4556bb349d53c250 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 31 Dec 2016 22:00:26 +0700 Subject: [PATCH 021/185] Compiler warnings. --- src/base/main/mainReal.c | 4 ++-- src/map/scl/sclLiberty.c | 6 +++--- src/misc/util/utilTruth.h | 6 +++--- src/misc/vec/vecPtr.h | 2 +- src/opt/lpk/lpkCore.c | 6 +++--- src/opt/lpk/lpkCut.c | 6 +++--- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/base/main/mainReal.c b/src/base/main/mainReal.c index ee43d38d0..31bfef754 100644 --- a/src/base/main/mainReal.c +++ b/src/base/main/mainReal.c @@ -196,7 +196,7 @@ int Abc_RealMain( int argc, char * argv[] ) case 't': if ( TypeCheck( pAbc, globalUtilOptarg ) ) { - if ( !strcmp(globalUtilOptarg, "none") == 0 ) + if ( (!strcmp(globalUtilOptarg, "none")) == 0 ) { fInitRead = 1; sprintf( sReadCmd, "read_%s", globalUtilOptarg ); @@ -211,7 +211,7 @@ int Abc_RealMain( int argc, char * argv[] ) case 'T': if ( TypeCheck( pAbc, globalUtilOptarg ) ) { - if (!strcmp(globalUtilOptarg, "none") == 0) + if ( (!strcmp(globalUtilOptarg, "none")) == 0) { fFinalWrite = 1; sprintf( sWriteCmd, "write_%s", globalUtilOptarg); diff --git a/src/map/scl/sclLiberty.c b/src/map/scl/sclLiberty.c index 50e69d08b..5ecf76bbc 100644 --- a/src/map/scl/sclLiberty.c +++ b/src/map/scl/sclLiberty.c @@ -509,7 +509,7 @@ char * Scl_LibertyFileContents( char * pFileName, int nContents ) { FILE * pFile = fopen( pFileName, "rb" ); char * pContents = ABC_ALLOC( char, nContents+1 ); - int RetValue; + int RetValue = 0; RetValue = fread( pContents, nContents, 1, pFile ); fclose( pFile ); pContents[nContents] = 0; @@ -518,7 +518,7 @@ char * Scl_LibertyFileContents( char * pFileName, int nContents ) void Scl_LibertyStringDump( char * pFileName, Vec_Str_t * vStr ) { FILE * pFile = fopen( pFileName, "wb" ); - int RetValue; + int RetValue = 0; if ( pFile == NULL ) { printf( "Scl_LibertyStringDump(): The output file is unavailable.\n" ); @@ -583,7 +583,7 @@ Scl_Tree_t * Scl_LibertyParse( char * pFileName, int fVerbose ) return NULL; pPos = p->pContents; Scl_LibertyWipeOutComments( p->pContents, p->pContents+p->nContents ); - if ( !Scl_LibertyBuildItem( p, &pPos, p->pContents + p->nContents ) == 0 ) + if ( (!Scl_LibertyBuildItem( p, &pPos, p->pContents + p->nContents )) == 0 ) { if ( p->pError ) printf( "%s", p->pError ); printf( "Parsing failed. " ); diff --git a/src/misc/util/utilTruth.h b/src/misc/util/utilTruth.h index b8a34da79..d77ed64d6 100644 --- a/src/misc/util/utilTruth.h +++ b/src/misc/util/utilTruth.h @@ -2612,7 +2612,7 @@ static inline int Abc_TtProcessBiDec( word * pTruth, int nVars, int nSuppLim ) static inline void Abc_TtProcessBiDecTest( word * pTruth, int nVars, int nSuppLim ) { word This, That, pTemp[64]; - int Res, resThis, resThat, nThis, nThat; + int Res, resThis, resThat;//, nThis, nThat; int nWords = Abc_TtWordNum(nVars); Abc_TtCopy( pTemp, pTruth, nWords, 0 ); Res = Abc_TtProcessBiDec( pTemp, nVars, nSuppLim ); @@ -2634,8 +2634,8 @@ static inline void Abc_TtProcessBiDecTest( word * pTruth, int nVars, int nSuppLi // Dau_DsdPrintFromTruth( pTemp, nVars ); - nThis = Abc_TtBitCount16(resThis); - nThat = Abc_TtBitCount16(resThat); + //nThis = Abc_TtBitCount16(resThis); + //nThat = Abc_TtBitCount16(resThat); printf( "Variable sets: " ); Abc_TtPrintVarSet( resThis, nVars ); diff --git a/src/misc/vec/vecPtr.h b/src/misc/vec/vecPtr.h index 5b40665f6..015aa1be6 100644 --- a/src/misc/vec/vecPtr.h +++ b/src/misc/vec/vecPtr.h @@ -65,7 +65,7 @@ struct Vec_Ptr_t_ #define Vec_PtrForEachEntryTwo( Type1, vVec1, Type2, vVec2, pEntry1, pEntry2, i ) \ for ( i = 0; (i < Vec_PtrSize(vVec1)) && (((pEntry1) = (Type1)Vec_PtrEntry(vVec1, i)), 1) && (((pEntry2) = (Type2)Vec_PtrEntry(vVec2, i)), 1); i++ ) #define Vec_PtrForEachEntryDouble( Type1, Type2, vVec, Entry1, Entry2, i ) \ - for ( i = 0; (i+1 < Vec_IntSize(vVec)) && (((Entry1) = (Type1)Vec_PtrEntry(vVec, i)), 1) && (((Entry2) = (Type2)Vec_PtrEntry(vVec, i+1)), 1); i += 2 ) + for ( i = 0; (i+1 < Vec_PtrSize(vVec)) && (((Entry1) = (Type1)Vec_PtrEntry(vVec, i)), 1) && (((Entry2) = (Type2)Vec_PtrEntry(vVec, i+1)), 1); i += 2 ) //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// diff --git a/src/opt/lpk/lpkCore.c b/src/opt/lpk/lpkCore.c index a9088d106..6595b3654 100644 --- a/src/opt/lpk/lpkCore.c +++ b/src/opt/lpk/lpkCore.c @@ -96,12 +96,12 @@ void Lpk_IfManStart( Lpk_Man_t * p ) int Lpk_NodeHasChanged( Lpk_Man_t * p, int iNode ) { Vec_Ptr_t * vNodes; - Abc_Obj_t * pTemp; + Abc_Obj_t * pTemp, * pTemp2; int i; vNodes = Vec_VecEntry( p->vVisited, iNode ); if ( Vec_PtrSize(vNodes) == 0 ) return 1; - Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pTemp, i ) + Vec_PtrForEachEntryDouble( Abc_Obj_t *, Abc_Obj_t *, vNodes, pTemp, pTemp2, i ) { // check if the node has changed pTemp = Abc_NtkObj( p->pNtk, (int)(ABC_PTRUINT_T)pTemp ); @@ -110,7 +110,7 @@ int Lpk_NodeHasChanged( Lpk_Man_t * p, int iNode ) // check if the number of fanouts has changed // if ( Abc_ObjFanoutNum(pTemp) != (int)Vec_PtrEntry(vNodes, i+1) ) // return 1; - i++; +// i++; } return 0; } diff --git a/src/opt/lpk/lpkCut.c b/src/opt/lpk/lpkCut.c index 73711f2b6..208facf29 100644 --- a/src/opt/lpk/lpkCut.c +++ b/src/opt/lpk/lpkCut.c @@ -234,7 +234,7 @@ void Lpk_NodeRecordImpact( Lpk_Man_t * p ) { Lpk_Cut_t * pCut; Vec_Ptr_t * vNodes = Vec_VecEntry( p->vVisited, p->pObj->Id ); - Abc_Obj_t * pNode; + Abc_Obj_t * pNode, * pNode2; int i, k; // collect the nodes that impact the given node Vec_PtrClear( vNodes ); @@ -252,11 +252,11 @@ void Lpk_NodeRecordImpact( Lpk_Man_t * p ) } } // clear the marks - Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i ) + Vec_PtrForEachEntryDouble( Abc_Obj_t *, Abc_Obj_t *, vNodes, pNode, pNode2, i ) { pNode = Abc_NtkObj( p->pNtk, (int)(ABC_PTRUINT_T)pNode ); pNode->fMarkC = 0; - i++; +// i++; } //printf( "%d ", Vec_PtrSize(vNodes) ); } From 290c70f73e023434bee208eb4d8161541096bebe Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 31 Dec 2016 22:56:30 +0700 Subject: [PATCH 022/185] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 251a4deb7..a36b4bd20 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -1883,7 +1883,7 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) } // make sure delay reduction is achieved iNewLev = Vec_IntEntry( p->vLutLevs, Abc_Lit2Var(iLit) ); - assert( iNewLev < iCurLev ); + assert( !iNewLev || iNewLev < iCurLev ); // update delay of the initial node assert( Vec_IntEntry(p->vLutLevs, Pivot) == iCurLev ); Vec_IntWriteEntry( p->vLutLevs, Pivot, iNewLev ); From ab8db51f37581f247991c16f3ec11ef2674f1934 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 31 Dec 2016 23:10:16 +0700 Subject: [PATCH 023/185] Updates to delay optimization project. --- src/opt/dau/dauGia.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opt/dau/dauGia.c b/src/opt/dau/dauGia.c index 8b0a76c3e..fa757e628 100644 --- a/src/opt/dau/dauGia.c +++ b/src/opt/dau/dauGia.c @@ -361,7 +361,7 @@ int Dau_DsdToGia_rec( Gia_Man_t * pGia, char * pStr, char ** p, int * pMatches, if ( pGia->pMuxes ) Res = Gia_ManAppendMux( pGia, Temp[0], Temp[1], Temp[2] ); else - Res = Gia_ManAppendMux( pGia, Temp[0], Temp[1], Temp[2] ); + Res = Gia_ManAppendMux2( pGia, Temp[0], Temp[1], Temp[2] ); } else { From 39f32259957884645450ba345426f7f030f14713 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Jan 2017 00:32:19 +0700 Subject: [PATCH 024/185] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index a36b4bd20..a6ae8bbb7 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -1851,7 +1851,7 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) Vec_IntWriteEntry( p->vLits, Vec_IntSize(p->vLits)-nStrs+i, iLit ); } iLit = Vec_IntEntry( p->vLits, Vec_IntSize(p->vDivSet) ); - assert( iObjLast == Gia_ManObjNum(p->pGia) || Abc_Lit2Var(iLit) == Gia_ManObjNum(p->pGia)-1 ); + //assert( iObjLast == Gia_ManObjNum(p->pGia) || Abc_Lit2Var(iLit) == Gia_ManObjNum(p->pGia)-1 ); // remember this function assert( Vec_IntEntry(p->vMirrors, Pivot) == -1 ); Vec_IntWriteEntry( p->vMirrors, Pivot, iLit ); From 278c00242f7c3ca46858ece6682749cca06a5deb Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Jan 2017 00:33:06 +0700 Subject: [PATCH 025/185] Compiler warnings. --- src/misc/zlib/inflate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc/zlib/inflate.c b/src/misc/zlib/inflate.c index 449779a97..9fae70457 100644 --- a/src/misc/zlib/inflate.c +++ b/src/misc/zlib/inflate.c @@ -1445,7 +1445,7 @@ long ZEXPORT inflateMark(z_streamp strm) { struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; + if (strm == Z_NULL || strm->state == Z_NULL) return -(1L << 16); state = (struct inflate_state FAR *)strm->state; return ((long)(state->back) << 16) + (state->mode == COPY ? state->length : From 1fef441a0dfde7887c18d218749c0f8d2d75f5ee Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Jan 2017 11:01:47 +0700 Subject: [PATCH 026/185] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index a6ae8bbb7..fa4cbc82f 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -360,12 +360,14 @@ void Sbd_ManUpdateOrder( Sbd_Man_t * p, int Pivot ) if ( p->DivCutoff == -1 ) p->DivCutoff = 0; // verify +/* assert( Vec_IntSize(p->vDivVars) < 64 ); Vec_IntForEachEntryStart( p->vDivVars, Node, i, p->DivCutoff ) assert( Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Node)) == LevelMax - 2 ); Vec_IntForEachEntryStop( p->vDivVars, Node, i, p->DivCutoff ) assert( Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Node)) < LevelMax - 2 ); Vec_IntFill( p->vDivValues, Vec_IntSize(p->vDivVars), 0 ); +*/ //printf( "%d ", Vec_IntSize(p->vDivVars) ); // printf( "Node %4d : Win = %5d. Divs = %5d. D1 = %5d. D2 = %5d.\n", // Pivot, Vec_IntSize(p->vWinObjs), Vec_IntSize(p->vDivVars), Vec_IntSize(p->vDivVars)-p->DivCutoff, p->DivCutoff ); From 4b20003e0cdec5d4d88ecf360c806e786272ab39 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Jan 2017 11:04:28 +0700 Subject: [PATCH 027/185] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index fa4cbc82f..f8af9a4a0 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -366,8 +366,8 @@ void Sbd_ManUpdateOrder( Sbd_Man_t * p, int Pivot ) assert( Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Node)) == LevelMax - 2 ); Vec_IntForEachEntryStop( p->vDivVars, Node, i, p->DivCutoff ) assert( Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Node)) < LevelMax - 2 ); - Vec_IntFill( p->vDivValues, Vec_IntSize(p->vDivVars), 0 ); */ + Vec_IntFill( p->vDivValues, Vec_IntSize(p->vDivVars), 0 ); //printf( "%d ", Vec_IntSize(p->vDivVars) ); // printf( "Node %4d : Win = %5d. Divs = %5d. D1 = %5d. D2 = %5d.\n", // Pivot, Vec_IntSize(p->vWinObjs), Vec_IntSize(p->vDivVars), Vec_IntSize(p->vDivVars)-p->DivCutoff, p->DivCutoff ); From 385cb73d32de7e7d18da68fffe6fd089cb7930b2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Jan 2017 19:47:30 +0700 Subject: [PATCH 028/185] Updates to delay optimization project. --- abclib.dsp | 4 + src/opt/sbd/module.make | 1 + src/opt/sbd/sbdCore.c | 29 ++- src/opt/sbd/sbdCut2.c | 432 ++++++++++++++++++++++++++++++++++++++++ src/opt/sbd/sbdInt.h | 7 + 5 files changed, 472 insertions(+), 1 deletion(-) create mode 100644 src/opt/sbd/sbdCut2.c diff --git a/abclib.dsp b/abclib.dsp index 1833f013b..6cc945749 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -2763,6 +2763,10 @@ SOURCE=.\src\opt\sbd\sbdCut.c # End Source File # Begin Source File +SOURCE=.\src\opt\sbd\sbdCut2.c +# End Source File +# Begin Source File + SOURCE=.\src\opt\sbd\sbdInt.h # End Source File # Begin Source File diff --git a/src/opt/sbd/module.make b/src/opt/sbd/module.make index 3bdc20b37..a9a6c3be4 100644 --- a/src/opt/sbd/module.make +++ b/src/opt/sbd/module.make @@ -2,6 +2,7 @@ SRC += src/opt/sbd/sbd.c \ src/opt/sbd/sbdCnf.c \ src/opt/sbd/sbdCore.c \ src/opt/sbd/sbdCut.c \ + src/opt/sbd/sbdCut2.c \ src/opt/sbd/sbdLut.c \ src/opt/sbd/sbdSat.c \ src/opt/sbd/sbdWin.c diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index f8af9a4a0..c9e92d730 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -56,6 +56,7 @@ struct Sbd_Man_t_ abctime timeOther; abctime timeTotal; Sbd_Sto_t * pSto; + Sbd_Srv_t * pSrv; // target node int Pivot; // target node int DivCutoff; // the place where D-2 divisors begin @@ -230,7 +231,8 @@ Sbd_Man_t * Sbd_ManStart( Gia_Man_t * pGia, Sbd_Par_t * pPars ) for ( w = 0; w < p->pPars->nWords; w++ ) Sbd_ObjSim0(p, Id)[w] = Gia_ManRandomW( 0 ); // cut enumeration - p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, pPars->nCutSize, pPars->nCutNum, 1, 1 ); + p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, pPars->nLutSize, pPars->nCutNum, 1, 1 ); + p->pSrv = Sbd_ManCutServerStart( pGia, p->vMirrors, p->vLutLevs, NULL, NULL, pPars->nLutSize, pPars->nCutSize, pPars->nCutNum, 0 ); return p; } void Sbd_ManStop( Sbd_Man_t * p ) @@ -257,6 +259,7 @@ void Sbd_ManStop( Sbd_Man_t * p ) Vec_WrdFree( p->vMatrix ); sat_solver_delete_p( &p->pSat ); Sbd_StoFree( p->pSto ); + Sbd_ManCutServerStop( p->pSrv ); ABC_FREE( p ); } @@ -1320,6 +1323,11 @@ int Sbd_ManExploreCut( Sbd_Man_t * p, int Pivot, int nLeaves, int * pLeaves, int clk = Abc_Clock(); Truth = Sbd_ManSolve( p->pSat, PivotVar, (*pFreeVar)++, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); p->timeSat += Abc_Clock() - clk; + if ( Truth == SBD_SAT_SAT ) + { + printf( "The cut at node %d is not topological.\n", p->Pivot ); + return 0; + } assert( Truth != SBD_SAT_UNDEC && Truth != SBD_SAT_SAT ); // create structure Strs->fLut = 1; @@ -1552,6 +1560,17 @@ int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); p->timeCnf += Abc_Clock() - clk; // extract one cut + if ( p->pSrv ) + { + nLeaves = Sbd_ManCutServerFirst( p->pSrv, Pivot, pLeaves ); + if ( nLeaves == -1 ) + return 0; + assert( nLeaves <= p->pPars->nCutSize ); + if ( Sbd_ManExploreCut( p, Pivot, nLeaves, pLeaves, pnStrs, Strs, &FreeVar ) ) + return 1; + return 0; + } + // extract one cut for ( nSize = p->pPars->nLutSize + 1; nSize <= p->pPars->nCutSize; nSize++ ) { nLeaves = Sbd_StoObjBestCut( p->pSto, Pivot, nSize, pLeaves ); @@ -1679,6 +1698,7 @@ int Sbd_ManMergeCuts( Sbd_Man_t * p, int Node ) assert( iFan0 != iFan1 ); assert( Vec_IntEntry(p->vLutLevs, Node) == 0 ); Vec_IntWriteEntry( p->vLutLevs, Node, LevCur ); + //Vec_IntWriteEntry( p->vLevs, Node, 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, iFan0), Vec_IntEntry(p->vLevs, iFan1)) ); assert( pCutRes[0] <= p->pPars->nLutSize ); memcpy( Sbd_ObjCut(p, Node), pCutRes, sizeof(int) * (pCutRes[0] + 1) ); //printf( "Setting node %d with delay %d.\n", Node, LevCur ); @@ -1742,6 +1762,7 @@ void Sbd_ManFindCut( Sbd_Man_t * p, int Node, Vec_Int_t * vCutLits ) // create cut assert( Vec_IntEntry(p->vLutLevs, Node) == 0 ); Vec_IntWriteEntry( p->vLutLevs, Node, LevelMax+1 ); + //Vec_IntWriteEntry( p->vLevs, Node, 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, Gia_ObjFaninId0(pObj, Node)), Vec_IntEntry(p->vLevs, Gia_ObjFaninId1(pObj, Node))) ); memcpy( Sbd_ObjCut(p, Node), pCut, sizeof(int) * (pCut[0] + 1) ); } @@ -1803,11 +1824,13 @@ int Sbd_ManImplement( Sbd_Man_t * p, int Pivot, word Truth ) // update delay of the initial node assert( Vec_IntEntry(p->vLutLevs, Pivot) == iCurLev ); Vec_IntWriteEntry( p->vLutLevs, Pivot, iNewLev ); + //Vec_IntWriteEntry( p->vLevs, Pivot, 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, Gia_ObjFaninId0(pObj, Pivot)), Vec_IntEntry(p->vLevs, Gia_ObjFaninId1(pObj, Pivot))) ); return 0; } int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) { + Gia_Obj_t * pObj = NULL; int i, k, w, iLit, Node; int iObjLast = Gia_ManObjNum(p->pGia); int iCurLev = Vec_IntEntry(p->vLutLevs, Pivot); @@ -1871,11 +1894,13 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) Sbd_StoDerefObj( p->pSto, Pivot ); for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) { + Gia_Obj_t * pObjI = Gia_ManObj( p->pGia, i ); abctime clk = Abc_Clock(); int Delay = Sbd_StoComputeCutsNode( p->pSto, i ); p->timeCut += Abc_Clock() - clk; assert( i == Vec_IntSize(p->vLutLevs) ); Vec_IntPush( p->vLutLevs, Delay ); + //Vec_IntPush( p->vLevs, 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, Gia_ObjFaninId0(pObjI, i)), Vec_IntEntry(p->vLevs, Gia_ObjFaninId1(pObjI, i))) ); Vec_IntPush( p->vObj2Var, 0 ); Vec_IntFillExtra( p->vLutCuts, Vec_IntSize(p->vLutCuts) + p->pPars->nLutSize + 1, 0 ); //Sbd_ManFindCut( p, i, p->vLits ); @@ -1887,8 +1912,10 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) iNewLev = Vec_IntEntry( p->vLutLevs, Abc_Lit2Var(iLit) ); assert( !iNewLev || iNewLev < iCurLev ); // update delay of the initial node + pObj = Gia_ManObj( p->pGia, Pivot ); assert( Vec_IntEntry(p->vLutLevs, Pivot) == iCurLev ); Vec_IntWriteEntry( p->vLutLevs, Pivot, iNewLev ); + //Vec_IntWriteEntry( p->vLevs, Pivot, Pivot ? 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, Gia_ObjFaninId0(pObj, Pivot)), Vec_IntEntry(p->vLevs, Gia_ObjFaninId1(pObj, Pivot))) : 0 ); return 0; } diff --git a/src/opt/sbd/sbdCut2.c b/src/opt/sbd/sbdCut2.c new file mode 100644 index 000000000..9422e439b --- /dev/null +++ b/src/opt/sbd/sbdCut2.c @@ -0,0 +1,432 @@ +/**CFile**************************************************************** + + FileName [sbdCut2.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [SAT-based optimization using internal don't-cares.] + + Synopsis [Cut computation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: sbdCut2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sbdInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define SBD_MAX_CUTSIZE 10 +#define SBD_MAX_CUTNUM 501 + +#define SBD_CUT_NO_LEAF 0xF + +typedef struct Sbd_Cut_t_ Sbd_Cut_t; +struct Sbd_Cut_t_ +{ + word Sign; // signature + int iFunc; // functionality + int Cost; // cut cost + int CostLev; // cut cost + unsigned nTreeLeaves : 9; // tree leaves + unsigned nSlowLeaves : 9; // slow leaves + unsigned nTopLeaves : 10; // top leaves + unsigned nLeaves : 4; // leaf count + int pLeaves[SBD_MAX_CUTSIZE]; // leaves +}; + +struct Sbd_Srv_t_ +{ + int nLutSize; + int nCutSize; + int nCutNum; + int fVerbose; + Gia_Man_t * pGia; // user's AIG manager (will be modified by adding nodes) + Vec_Int_t * vMirrors; // mirrors for each node + Vec_Int_t * vLutLevs; // delays for each node + Vec_Int_t * vLevs; // levels for each node + Vec_Int_t * vRefs; // refs for each node + Sbd_Cut_t pCuts[SBD_MAX_CUTNUM]; // temporary cuts + Sbd_Cut_t * ppCuts[SBD_MAX_CUTNUM]; // temporary cut pointers + abctime clkStart; // starting time + Vec_Int_t * vCut0; // current cut + Vec_Int_t * vCut; // current cut + Vec_Int_t * vCutTop; // current cut + Vec_Int_t * vCutBot; // current cut +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Sbd_Srv_t * Sbd_ManCutServerStart( Gia_Man_t * pGia, Vec_Int_t * vMirrors, + Vec_Int_t * vLutLevs, Vec_Int_t * vLevs, Vec_Int_t * vRefs, + int nLutSize, int nCutSize, int nCutNum, int fVerbose ) +{ + Sbd_Srv_t * p; + assert( nLutSize <= nCutSize ); + assert( nCutSize < SBD_CUT_NO_LEAF ); + assert( nCutSize > 1 && nCutSize <= SBD_MAX_CUTSIZE ); + assert( nCutNum > 1 && nCutNum < SBD_MAX_CUTNUM ); + p = ABC_CALLOC( Sbd_Srv_t, 1 ); + p->clkStart = Abc_Clock(); + p->nLutSize = nLutSize; + p->nCutSize = nCutSize; + p->nCutNum = nCutNum; + p->fVerbose = fVerbose; + p->pGia = pGia; + p->vMirrors = vMirrors; + p->vLutLevs = vLutLevs; + p->vLevs = vLevs; + p->vRefs = vRefs; + p->vCut0 = Vec_IntAlloc( 100 ); + p->vCut = Vec_IntAlloc( 100 ); + p->vCutTop = Vec_IntAlloc( 100 ); + p->vCutBot = Vec_IntAlloc( 100 ); + return p; +} +void Sbd_ManCutServerStop( Sbd_Srv_t * p ) +{ + Vec_IntFree( p->vCut0 ); + Vec_IntFree( p->vCut ); + Vec_IntFree( p->vCutTop ); + Vec_IntFree( p->vCutBot ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sbd_ManCutIsTopo_rec( Gia_Man_t * p, Vec_Int_t * vMirrors, int iObj ) +{ + Gia_Obj_t * pObj; + int Ret0, Ret1; + if ( Vec_IntEntry(vMirrors, iObj) >= 0 ) + iObj = Abc_Lit2Var(Vec_IntEntry(vMirrors, iObj)); + if ( !iObj || Gia_ObjIsTravIdCurrentId(p, iObj) ) + return 1; + Gia_ObjSetTravIdCurrentId(p, iObj); + pObj = Gia_ManObj( p, iObj ); + if ( Gia_ObjIsCi(pObj) ) + return 0; + assert( Gia_ObjIsAnd(pObj) ); + Ret0 = Sbd_ManCutIsTopo_rec( p, vMirrors, Gia_ObjFaninId0(pObj, iObj) ); + Ret1 = Sbd_ManCutIsTopo_rec( p, vMirrors, Gia_ObjFaninId1(pObj, iObj) ); + return Ret0 && Ret1; +} +int Sbd_ManCutIsTopo( Gia_Man_t * p, Vec_Int_t * vMirrors, Vec_Int_t * vCut, int iObj ) +{ + int i, Entry, RetValue; + Gia_ManIncrementTravId( p ); + Vec_IntForEachEntry( vCut, Entry, i ) + Gia_ObjSetTravIdCurrentId( p, Entry ); + RetValue = Sbd_ManCutIsTopo_rec( p, vMirrors, iObj ); + if ( RetValue == 0 ) + printf( "Cut of node %d is not tological\n", iObj ); + assert( RetValue ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Sbd_ManCutExpandOne( Gia_Man_t * p, Vec_Int_t * vMirrors, Vec_Int_t * vLutLevs, Vec_Int_t * vCut, int iThis, int iObj ) +{ + int Lit0m, Lit1m, Fan0, Fan1, iPlace0, iPlace1; + int LutLev = Vec_IntEntry( vLutLevs, iObj ); + Gia_Obj_t * pObj = Gia_ManObj(p, iObj); + if ( Gia_ObjIsCi(pObj) ) + return 0; + assert( Gia_ObjIsAnd(pObj) ); + Lit0m = Vec_IntEntry( vMirrors, Gia_ObjFaninId0(pObj, iObj) ); + Lit1m = Vec_IntEntry( vMirrors, Gia_ObjFaninId1(pObj, iObj) ); + Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, iObj); + Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, iObj); + iPlace0 = Vec_IntFind( vCut, Fan0 ); + iPlace1 = Vec_IntFind( vCut, Fan1 ); + if ( iPlace0 == -1 && iPlace1 == -1 ) + return 0; + if ( Vec_IntEntry(vLutLevs, Fan0) > LutLev || Vec_IntEntry(vLutLevs, Fan1) > LutLev ) + return 0; + Vec_IntDrop( vCut, iThis ); + if ( iPlace0 == -1 && Fan0 ) + Vec_IntPushOrder( vCut, Fan0 ); + if ( iPlace1 == -1 && Fan1 ) + Vec_IntPushOrder( vCut, Fan1 ); + return 1; +} +void Vec_IntIsOrdered( Vec_Int_t * vCut ) +{ + int i, Prev, Entry; + Prev = Vec_IntEntry( vCut, 0 ); + Vec_IntForEachEntryStart( vCut, Entry, i, 1 ) + { + assert( Prev < Entry ); + Prev = Entry; + } +} +void Sbd_ManCutExpand( Gia_Man_t * p, Vec_Int_t * vMirrors, Vec_Int_t * vLutLevs, Vec_Int_t * vCut ) +{ + int i, Entry; + do + { + Vec_IntForEachEntry( vCut, Entry, i ) + if ( Sbd_ManCutExpandOne( p, vMirrors, vLutLevs, vCut, i, Entry ) ) + break; + } + while ( i < Vec_IntSize(vCut) ); +} +void Sbd_ManCutReload( Vec_Int_t * vMirrors, Vec_Int_t * vLutLevs, int LevStop, Vec_Int_t * vCut, Vec_Int_t * vCutTop, Vec_Int_t * vCutBot ) +{ + int i, Entry; + Vec_IntClear( vCutTop ); + Vec_IntClear( vCutBot ); + Vec_IntForEachEntry( vCut, Entry, i ) + { + assert( Entry ); + assert( Vec_IntEntry(vMirrors, Entry) == -1 ); + assert( Vec_IntEntry(vLutLevs, Entry) <= LevStop ); + if ( Vec_IntEntry(vLutLevs, Entry) == LevStop ) + Vec_IntPush( vCutTop, Entry ); + else + Vec_IntPush( vCutBot, Entry ); + } + Vec_IntIsOrdered( vCut ); +} +int Sbd_ManCutCollect_rec( Gia_Man_t * p, Vec_Int_t * vMirrors, int iObj, int LevStop, Vec_Int_t * vLutLevs, Vec_Int_t * vCut ) +{ + Gia_Obj_t * pObj; + int Ret0, Ret1; + if ( Vec_IntEntry(vMirrors, iObj) >= 0 ) + iObj = Abc_Lit2Var(Vec_IntEntry(vMirrors, iObj)); + if ( !iObj || Gia_ObjIsTravIdCurrentId(p, iObj) ) + return 1; + Gia_ObjSetTravIdCurrentId(p, iObj); + pObj = Gia_ManObj( p, iObj ); + if ( Gia_ObjIsCi(pObj) || Vec_IntEntry(vLutLevs, iObj) <= LevStop ) + { + Vec_IntPush( vCut, iObj ); + return Vec_IntEntry(vLutLevs, iObj) <= LevStop; + } + assert( Gia_ObjIsAnd(pObj) ); + Ret0 = Sbd_ManCutCollect_rec( p, vMirrors, Gia_ObjFaninId0(pObj, iObj), LevStop, vLutLevs, vCut ); + Ret1 = Sbd_ManCutCollect_rec( p, vMirrors, Gia_ObjFaninId1(pObj, iObj), LevStop, vLutLevs, vCut ); + return Ret0 && Ret1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sbd_ManCutReduceTop( Gia_Man_t * p, Vec_Int_t * vMirrors, int iObj, Vec_Int_t * vLutLevs, Vec_Int_t * vCut, Vec_Int_t * vCutTop, int nCutSize ) +{ + int i, Entry, Lit0m, Lit1m, Fan0, Fan1; + int LevStop = Vec_IntEntry(vLutLevs, iObj) - 2; + Vec_IntIsOrdered( vCut ); + Vec_IntForEachEntryReverse( vCutTop, Entry, i ) + { + Gia_Obj_t * pObj = Gia_ManObj( p, Entry ); + if ( Gia_ObjIsCi(pObj) ) + continue; + assert( Gia_ObjIsAnd(pObj) ); + assert( Vec_IntEntry(vLutLevs, Entry) == LevStop ); + Lit0m = Vec_IntEntry( vMirrors, Gia_ObjFaninId0(pObj, Entry) ); + Lit1m = Vec_IntEntry( vMirrors, Gia_ObjFaninId1(pObj, Entry) ); + Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, Entry); + Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, Entry); + if ( Vec_IntEntry(vLutLevs, Fan0) > LevStop || Vec_IntEntry(vLutLevs, Fan1) > LevStop ) + continue; + assert( Vec_IntEntry(vLutLevs, Fan0) <= LevStop ); + assert( Vec_IntEntry(vLutLevs, Fan1) <= LevStop ); + if ( Vec_IntEntry(vLutLevs, Fan0) == LevStop && Vec_IntEntry(vLutLevs, Fan1) == LevStop ) + continue; + Vec_IntRemove( vCut, Entry ); + if ( Fan0 ) Vec_IntPushUniqueOrder( vCut, Fan0 ); + if ( Fan1 ) Vec_IntPushUniqueOrder( vCut, Fan1 ); + //Sbd_ManCutIsTopo( p, vMirrors, vCut, iObj ); + return 1; + } + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sbd_ManCutServerFirst( Sbd_Srv_t * p, int iObj, int * pLeaves ) +{ + int RetValue, LevStop = Vec_IntEntry(p->vLutLevs, iObj) - 2; + + Vec_IntClear( p->vCut ); + Gia_ManIncrementTravId( p->pGia ); + RetValue = Sbd_ManCutCollect_rec( p->pGia, p->vMirrors, iObj, LevStop, p->vLutLevs, p->vCut ); + if ( RetValue == 0 ) // cannot build delay-improving cut + return -1; + // check if the current cut is good + Vec_IntSort( p->vCut, 0 ); +/* + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "%d ", Vec_IntSize(p->vCut) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } +*/ + // try to expand the cut + Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut ); + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "1=(%d,%d) ", Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) ); + //printf( "%d ", Vec_IntSize(p->vCut) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } + +#if 0 + // recompute the cut + Vec_IntClear( p->vCut ); + Gia_ManIncrementTravId( p->pGia ); + RetValue = Sbd_ManCutCollect_rec( p->pGia, p->vMirrors, iObj, LevStop-1, p->vLutLevs, p->vCut ); + if ( RetValue == 0 ) // cannot build delay-improving cut + return -1; + // check if the current cut is good + Vec_IntSort( p->vCut, 0 ); +/* + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "%d ", Vec_IntSize(p->vCut) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } +*/ + // try to expand the cut + Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut ); + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "2=(%d,%d) ", Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) ); + //printf( "%d ", Vec_IntSize(p->vCut) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } +#endif + + // try to reduce the topmost + Vec_IntClear( p->vCut0 ); + Vec_IntAppend( p->vCut0, p->vCut ); + if ( Vec_IntSize(p->vCut) < p->nCutSize && Sbd_ManCutReduceTop( p->pGia, p->vMirrors, iObj, p->vLutLevs, p->vCut, p->vCutTop, p->nCutSize ) ) + { + Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut ); + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + assert( Vec_IntSize(p->vCut) <= p->nCutSize ); + if ( Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "%d -> %d (%d + %d)\n", Vec_IntSize(p->vCut0), Vec_IntSize(p->vCut), Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } + // try again + if ( Vec_IntSize(p->vCut) < p->nCutSize && Sbd_ManCutReduceTop( p->pGia, p->vMirrors, iObj, p->vLutLevs, p->vCut, p->vCutTop, p->nCutSize ) ) + { + Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut ); + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + assert( Vec_IntSize(p->vCut) <= p->nCutSize ); + if ( Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "* %d -> %d (%d + %d)\n", Vec_IntSize(p->vCut0), Vec_IntSize(p->vCut), Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } + // try again + if ( Vec_IntSize(p->vCut) < p->nCutSize && Sbd_ManCutReduceTop( p->pGia, p->vMirrors, iObj, p->vLutLevs, p->vCut, p->vCutTop, p->nCutSize ) ) + { + Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut ); + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + assert( Vec_IntSize(p->vCut) <= p->nCutSize ); + if ( Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "** %d -> %d (%d + %d)\n", Vec_IntSize(p->vCut0), Vec_IntSize(p->vCut), Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } + // try again + if ( Vec_IntSize(p->vCut) < p->nCutSize && Sbd_ManCutReduceTop( p->pGia, p->vMirrors, iObj, p->vLutLevs, p->vCut, p->vCutTop, p->nCutSize ) ) + { + Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut ); + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + assert( Vec_IntSize(p->vCut) <= p->nCutSize ); + if ( Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "*** %d -> %d (%d + %d)\n", Vec_IntSize(p->vCut0), Vec_IntSize(p->vCut), Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } + } + } + } + } + return -1; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/opt/sbd/sbdInt.h b/src/opt/sbd/sbdInt.h index 668c12315..9b4898549 100644 --- a/src/opt/sbd/sbdInt.h +++ b/src/opt/sbd/sbdInt.h @@ -62,6 +62,7 @@ ABC_NAMESPACE_HEADER_START //////////////////////////////////////////////////////////////////////// typedef struct Sbd_Sto_t_ Sbd_Sto_t; +typedef struct Sbd_Srv_t_ Sbd_Srv_t; typedef struct Sbd_Str_t_ Sbd_Str_t; struct Sbd_Str_t_ @@ -92,6 +93,12 @@ extern void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, i extern void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ); extern int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ); extern int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int nSize, int * pLeaves ); +/*=== sbdCut2.c ==========================================================*/ +extern Sbd_Srv_t * Sbd_ManCutServerStart( Gia_Man_t * pGia, Vec_Int_t * vMirrors, + Vec_Int_t * vLutLevs, Vec_Int_t * vLevs, Vec_Int_t * vRefs, + int nLutSize, int nCutSize, int nCutNum, int fVerbose ); +extern void Sbd_ManCutServerStop( Sbd_Srv_t * p ); +extern int Sbd_ManCutServerFirst( Sbd_Srv_t * p, int iObj, int * pLeaves ); /*=== sbdWin.c ==========================================================*/ extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivSet, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp ); extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); From 26eb3f3684e4478d6839d7d0a92ac67003c06b20 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Jan 2017 19:48:46 +0700 Subject: [PATCH 029/185] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index c9e92d730..7df97d3bf 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -1894,7 +1894,7 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) Sbd_StoDerefObj( p->pSto, Pivot ); for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) { - Gia_Obj_t * pObjI = Gia_ManObj( p->pGia, i ); + //Gia_Obj_t * pObjI = Gia_ManObj( p->pGia, i ); abctime clk = Abc_Clock(); int Delay = Sbd_StoComputeCutsNode( p->pSto, i ); p->timeCut += Abc_Clock() - clk; From d948f7259a61a8eec0fdc94882b530e2d7f0ba12 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Jan 2017 20:48:21 +0700 Subject: [PATCH 030/185] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 ++ src/opt/sbd/sbdCut2.c | 59 +++++++++++++++++++++---------------------- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 7df97d3bf..ed3b620ed 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -2009,6 +2009,7 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) Vec_IntWriteEntry( p->vMirrors, Pivot, RetValue ); if ( p->pPars->fVerbose ) printf( "Node %5d: Detected constant %d.\n", Pivot, RetValue ); } +/* else if ( p->pPars->nLutNum >= 1 && Sbd_ManExplore2( p, Pivot, &Truth ) ) { int i; @@ -2020,6 +2021,7 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) Sbd_ManImplement2( p, Pivot, 1, Strs ); if ( p->pPars->fVerbose ) printf( "Node %5d: Detected LUT%d\n", Pivot, p->pPars->nLutSize ); } +*/ else if ( p->pPars->nLutNum >= 2 && Sbd_ManExplore3( p, Pivot, &nStrs, Strs ) ) { Sbd_ManImplement2( p, Pivot, nStrs, Strs ); diff --git a/src/opt/sbd/sbdCut2.c b/src/opt/sbd/sbdCut2.c index 9422e439b..b4a8be74d 100644 --- a/src/opt/sbd/sbdCut2.c +++ b/src/opt/sbd/sbdCut2.c @@ -336,36 +336,6 @@ int Sbd_ManCutServerFirst( Sbd_Srv_t * p, int iObj, int * pLeaves ) return Vec_IntSize(p->vCut); } -#if 0 - // recompute the cut - Vec_IntClear( p->vCut ); - Gia_ManIncrementTravId( p->pGia ); - RetValue = Sbd_ManCutCollect_rec( p->pGia, p->vMirrors, iObj, LevStop-1, p->vLutLevs, p->vCut ); - if ( RetValue == 0 ) // cannot build delay-improving cut - return -1; - // check if the current cut is good - Vec_IntSort( p->vCut, 0 ); -/* - Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); - if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) - { - //printf( "%d ", Vec_IntSize(p->vCut) ); - memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); - return Vec_IntSize(p->vCut); - } -*/ - // try to expand the cut - Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut ); - Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); - if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) - { - //printf( "2=(%d,%d) ", Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) ); - //printf( "%d ", Vec_IntSize(p->vCut) ); - memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); - return Vec_IntSize(p->vCut); - } -#endif - // try to reduce the topmost Vec_IntClear( p->vCut0 ); Vec_IntAppend( p->vCut0, p->vCut ); @@ -420,6 +390,35 @@ int Sbd_ManCutServerFirst( Sbd_Srv_t * p, int iObj, int * pLeaves ) } } } + + // recompute the cut + Vec_IntClear( p->vCut ); + Gia_ManIncrementTravId( p->pGia ); + RetValue = Sbd_ManCutCollect_rec( p->pGia, p->vMirrors, iObj, LevStop-1, p->vLutLevs, p->vCut ); + if ( RetValue == 0 ) // cannot build delay-improving cut + return -1; + // check if the current cut is good + Vec_IntSort( p->vCut, 0 ); +/* + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "%d ", Vec_IntSize(p->vCut) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } +*/ + // try to expand the cut + Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut ); + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "2=(%d,%d) ", Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) ); + //printf( "%d ", Vec_IntSize(p->vCut) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } + return -1; } From 6e1df46cd346ace1ed118da70c5b301915fcf453 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Jan 2017 20:49:36 +0700 Subject: [PATCH 031/185] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index ed3b620ed..988ad3dba 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -1993,7 +1993,7 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) ***********************************************************************/ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) { - Sbd_Str_t Strs[SBD_DIV_MAX]; word Truth = 0; + Sbd_Str_t Strs[SBD_DIV_MAX]; //word Truth = 0; int RetValue, nStrs = 0; if ( !p->pSto && Sbd_ManMergeCuts( p, Pivot ) ) return; From 74c8d35f330f80e6e489f6829288093e798fbfc2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 2 Jan 2017 16:29:10 +0700 Subject: [PATCH 032/185] Updates to delay optimization project. --- abclib.dsp | 4 ++ src/base/abci/abc.c | 31 +++++----- src/opt/sbd/module.make | 1 + src/opt/sbd/sbd.h | 4 ++ src/opt/sbd/sbdCore.c | 113 +++++++++++++++++++++++++++++++----- src/opt/sbd/sbdCut.c | 22 ++++++- src/opt/sbd/sbdInt.h | 3 + src/opt/sbd/sbdPath.c | 124 ++++++++++++++++++++++++++++++++++++++++ 8 files changed, 272 insertions(+), 30 deletions(-) create mode 100644 src/opt/sbd/sbdPath.c diff --git a/abclib.dsp b/abclib.dsp index 6cc945749..4ec50a1f3 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -2775,6 +2775,10 @@ SOURCE=.\src\opt\sbd\sbdLut.c # End Source File # Begin Source File +SOURCE=.\src\opt\sbd\sbdPath.c +# End Source File +# Begin Source File + SOURCE=.\src\opt\sbd\sbdSat.c # End Source File # Begin Source File diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index fccd4f635..2be65ed0f 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -41010,7 +41010,7 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) Sbd_Par_t Pars, * pPars = &Pars; Sbd_ParSetDefault( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KSNPWFMCacvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KSNPWFMCmcdpvwh" ) ) != EOF ) { switch ( c ) { @@ -41102,11 +41102,17 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nBTLimit < 0 ) goto usage; break; - case 'a': - pPars->fArea ^= 1; + case 'm': + pPars->fMapping ^= 1; break; case 'c': - pPars->fCover ^= 1; + pPars->fMoreCuts ^= 1; + break; + case 'd': + pPars->fFindDivs ^= 1; + break; + case 'p': + pPars->fUsePath ^= 1; break; case 'v': pPars->fVerbose ^= 1; @@ -41122,25 +41128,22 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) } if ( pAbc->pGia == NULL ) { - Abc_Print( -1, "Abc_CommandAbc9Mfs(): There is no AIG.\n" ); + Abc_Print( -1, "Abc_CommandAbc9Mfsd(): There is no AIG.\n" ); return 0; } if ( Gia_ManBufNum(pAbc->pGia) ) { - Abc_Print( -1, "Abc_CommandAbc9Mfs(): This command does not work with barrier buffers.\n" ); + Abc_Print( -1, "Abc_CommandAbc9Mfsd(): This command does not work with barrier buffers.\n" ); return 1; } if ( Gia_ManHasMapping(pAbc->pGia) ) - { - Abc_Print( -1, "Abc_CommandAbc9Mfs(): The current AIG has mapping (run &st to unmap).\n" ); - return 0; - } + Abc_Print( 1, "The current AIG has mapping, which can be used to determine critical path if \"-p\" is selected.\n" ); pTemp = Sbd_NtkPerform( pAbc->pGia, pPars ); Abc_FrameUpdateGia( pAbc, pTemp ); return 0; usage: - Abc_Print( -2, "usage: &mfsd [-KSNPWFMC ] [-acvwh]\n" ); + Abc_Print( -2, "usage: &mfsd [-KSNPWFMC ] [-mcdpvwh]\n" ); Abc_Print( -2, "\t performs SAT-based delay-oriented AIG optimization\n" ); Abc_Print( -2, "\t-K : the LUT size for delay minimization (2 <= num <= 6) [default = %d]\n", pPars->nLutSize ); Abc_Print( -2, "\t-S : the LUT structure size (1 <= num <= 2) [default = %d]\n", pPars->nLutNum ); @@ -41150,8 +41153,10 @@ usage: Abc_Print( -2, "\t-F : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nTfoFanMax ); Abc_Print( -2, "\t-M : the max node count of windows to consider (0 = no limit) [default = %d]\n", pPars->nWinSizeMax ); Abc_Print( -2, "\t-C : the max number of conflicts in one SAT run (0 = no limit) [default = %d]\n", pPars->nBTLimit ); - Abc_Print( -2, "\t-a : toggle minimizing area or area+edges [default = %s]\n", pPars->fArea? "area": "area+edges" ); - Abc_Print( -2, "\t-c : toggle using complete slow covering procedure [default = %s]\n", pPars->fCover? "yes": "no" ); + Abc_Print( -2, "\t-m : toggle generating delay-oriented mapping [default = %s]\n", pPars->fMapping? "area": "area+edges" ); + Abc_Print( -2, "\t-c : toggle using several cuts at each node [default = %s]\n", pPars->fMoreCuts? "yes": "no" ); + Abc_Print( -2, "\t-d : toggle additional search for good divisors [default = %s]\n", pPars->fFindDivs? "yes": "no" ); + Abc_Print( -2, "\t-p : toggle optimizing critical path only [default = %s]\n", pPars->fUsePath? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-w : toggle printing detailed stats for each node [default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); diff --git a/src/opt/sbd/module.make b/src/opt/sbd/module.make index a9a6c3be4..fc176715d 100644 --- a/src/opt/sbd/module.make +++ b/src/opt/sbd/module.make @@ -4,5 +4,6 @@ SRC += src/opt/sbd/sbd.c \ src/opt/sbd/sbdCut.c \ src/opt/sbd/sbdCut2.c \ src/opt/sbd/sbdLut.c \ + src/opt/sbd/sbdPath.c \ src/opt/sbd/sbdSat.c \ src/opt/sbd/sbdWin.c diff --git a/src/opt/sbd/sbd.h b/src/opt/sbd/sbd.h index 6e0f6b3b0..9c419b164 100644 --- a/src/opt/sbd/sbd.h +++ b/src/opt/sbd/sbd.h @@ -47,6 +47,10 @@ struct Sbd_Par_t_ int nWinSizeMax; // maximum window size (windowing) int nBTLimit; // maximum number of SAT conflicts int nWords; // simulation word count + int fMapping; // generate mapping + int fMoreCuts; // use several cuts + int fFindDivs; // perform divisor search + int fUsePath; // optimize only critical path int fArea; // area-oriented optimization int fCover; // use complete cover procedure int fVerbose; // verbose flag diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 988ad3dba..275d866fc 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -38,6 +38,7 @@ struct Sbd_Man_t_ Vec_Wec_t * vTfos; // TFO for each node (roots are marked) (windowing) Vec_Int_t * vLutLevs; // LUT level for each node after resynthesis Vec_Int_t * vLutCuts; // LUT cut for each nodes after resynthesis + Vec_Int_t * vLutCuts2; // LUT cut for each nodes after resynthesis Vec_Int_t * vMirrors; // alternative node Vec_Wrd_t * vSims[4]; // simulation information (main, backup, controlability) Vec_Int_t * vCover; // temporary @@ -73,7 +74,8 @@ struct Sbd_Man_t_ sat_solver * pSat; // SAT solver }; -static inline int * Sbd_ObjCut( Sbd_Man_t * p, int i ) { return Vec_IntEntryP( p->vLutCuts, (p->pPars->nLutSize + 1) * i ); } +static inline int * Sbd_ObjCut( Sbd_Man_t * p, int i ) { return Vec_IntEntryP( p->vLutCuts, (p->pPars->nLutSize + 1) * i ); } +static inline int * Sbd_ObjCut2( Sbd_Man_t * p, int i ) { return Vec_IntEntryP( p->vLutCuts2, (p->pPars->nLutSize + 1) * i ); } static inline word * Sbd_ObjSim0( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSims[0], p->pPars->nWords * i ); } static inline word * Sbd_ObjSim1( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSims[1], p->pPars->nWords * i ); } @@ -107,6 +109,10 @@ void Sbd_ParSetDefault( Sbd_Par_t * pPars ) pPars->nWinSizeMax = 2000; // maximum window size (windowing) pPars->nBTLimit = 0; // maximum number of SAT conflicts pPars->nWords = 1; // simulation word count + pPars->fMapping = 1; // generate mapping + pPars->fMoreCuts = 0; // use several cuts + pPars->fFindDivs = 0; // perform divisor search + pPars->fUsePath = 0; // optimize only critical path pPars->fArea = 0; // area-oriented optimization pPars->fCover = 0; // use complete cover procedure pPars->fVerbose = 0; // verbose flag @@ -231,8 +237,13 @@ Sbd_Man_t * Sbd_ManStart( Gia_Man_t * pGia, Sbd_Par_t * pPars ) for ( w = 0; w < p->pPars->nWords; w++ ) Sbd_ObjSim0(p, Id)[w] = Gia_ManRandomW( 0 ); // cut enumeration - p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, pPars->nLutSize, pPars->nCutNum, 1, 1 ); - p->pSrv = Sbd_ManCutServerStart( pGia, p->vMirrors, p->vLutLevs, NULL, NULL, pPars->nLutSize, pPars->nCutSize, pPars->nCutNum, 0 ); + if ( pPars->fMoreCuts ) + p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, pPars->nCutSize, pPars->nCutNum, !pPars->fMapping, 1 ); + else + { + p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, pPars->nLutSize, pPars->nCutNum, !pPars->fMapping, 1 ); + p->pSrv = Sbd_ManCutServerStart( pGia, p->vMirrors, p->vLutLevs, NULL, NULL, pPars->nLutSize, pPars->nCutSize, pPars->nCutNum, 0 ); + } return p; } void Sbd_ManStop( Sbd_Man_t * p ) @@ -258,8 +269,8 @@ void Sbd_ManStop( Sbd_Man_t * p ) Vec_IntFree( p->vCounts[1] ); Vec_WrdFree( p->vMatrix ); sat_solver_delete_p( &p->pSat ); - Sbd_StoFree( p->pSto ); - Sbd_ManCutServerStop( p->pSrv ); + if ( p->pSto ) Sbd_StoFree( p->pSto ); + if ( p->pSrv ) Sbd_ManCutServerStop( p->pSrv ); ABC_FREE( p ); } @@ -1830,7 +1841,7 @@ int Sbd_ManImplement( Sbd_Man_t * p, int Pivot, word Truth ) int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) { - Gia_Obj_t * pObj = NULL; + //Gia_Obj_t * pObj = NULL; int i, k, w, iLit, Node; int iObjLast = Gia_ManObjNum(p->pGia); int iCurLev = Vec_IntEntry(p->vLutLevs, Pivot); @@ -1903,6 +1914,7 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) //Vec_IntPush( p->vLevs, 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, Gia_ObjFaninId0(pObjI, i)), Vec_IntEntry(p->vLevs, Gia_ObjFaninId1(pObjI, i))) ); Vec_IntPush( p->vObj2Var, 0 ); Vec_IntFillExtra( p->vLutCuts, Vec_IntSize(p->vLutCuts) + p->pPars->nLutSize + 1, 0 ); + Sbd_StoSaveBestDelayCut( p->pSto, i, Sbd_ObjCut(p, i) ); //Sbd_ManFindCut( p, i, p->vLits ); for ( k = 0; k < 4; k++ ) for ( w = 0; w < p->pPars->nWords; w++ ) @@ -1912,7 +1924,7 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) iNewLev = Vec_IntEntry( p->vLutLevs, Abc_Lit2Var(iLit) ); assert( !iNewLev || iNewLev < iCurLev ); // update delay of the initial node - pObj = Gia_ManObj( p->pGia, Pivot ); + //pObj = Gia_ManObj( p->pGia, Pivot ); assert( Vec_IntEntry(p->vLutLevs, Pivot) == iCurLev ); Vec_IntWriteEntry( p->vLutLevs, Pivot, iNewLev ); //Vec_IntWriteEntry( p->vLevs, Pivot, Pivot ? 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, Gia_ObjFaninId0(pObj, Pivot)), Vec_IntEntry(p->vLevs, Gia_ObjFaninId1(pObj, Pivot))) : 0 ); @@ -1930,6 +1942,70 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) SeeAlso [] ***********************************************************************/ +void Sbd_ManDeriveMapping_rec( Sbd_Man_t * p, Gia_Man_t * pNew, int iObj ) +{ + Gia_Obj_t * pObj; int k, * pCut; + if ( Gia_ObjIsTravIdCurrentId(pNew, iObj) ) + return; + Gia_ObjSetTravIdCurrentId(pNew, iObj); + pObj = Gia_ManObj( pNew, iObj ); + if ( Gia_ObjIsCi(pObj) ) + return; + assert( Gia_ObjIsAnd(pObj) ); + pCut = Sbd_ObjCut2( p, iObj ); + for ( k = 1; k <= pCut[0]; k++ ) + Sbd_ManDeriveMapping_rec( p, pNew, pCut[k] ); + // add mapping + Vec_IntWriteEntry( pNew->vMapping, iObj, Vec_IntSize(pNew->vMapping) ); + for ( k = 0; k <= pCut[0]; k++ ) + Vec_IntPush( pNew->vMapping, pCut[k] ); + Vec_IntPush( pNew->vMapping, iObj ); +} +void Sbd_ManDeriveMapping( Sbd_Man_t * p, Gia_Man_t * pNew ) +{ + Gia_Obj_t * pObj, * pFan; + int i, k, iFan, iObjNew, * pCut, * pCutNew; + Vec_Int_t * vLeaves = Vec_IntAlloc( 100 ); + // derive cuts for the new manager + p->vLutCuts2 = Vec_IntStart( Gia_ManObjNum(pNew) * (p->pPars->nLutSize + 1) ); + Gia_ManForEachAnd( p->pGia, pObj, i ) + { + if ( Vec_IntEntry(p->vMirrors, i) >= 0 ) + continue; + if ( pObj->Value == ~0 ) + continue; + iObjNew = Abc_Lit2Var( pObj->Value ); + if ( !Gia_ObjIsAnd(Gia_ManObj(pNew, iObjNew)) ) + continue; + pCutNew = Sbd_ObjCut2( p, iObjNew ); + pCut = Sbd_ObjCut( p, i ); + Vec_IntClear( vLeaves ); + for ( k = 1; k <= pCut[0]; k++ ) + { + iFan = Vec_IntEntry(p->vMirrors, pCut[k]) >= 0 ? Abc_Lit2Var(Vec_IntEntry(p->vMirrors, pCut[k])) : pCut[k]; + pFan = Gia_ManObj( p->pGia, iFan ); + if ( pFan->Value == ~0 ) + continue; + iObjNew = Abc_Lit2Var( pFan->Value ); + if ( iObjNew == 0 ) + continue; + Vec_IntPushUniqueOrder( vLeaves, iObjNew ); + } + assert( Vec_IntSize(vLeaves) <= p->pPars->nLutSize ); + assert( Vec_IntSize(vLeaves) > 1 ); + pCutNew[0] = Vec_IntSize(vLeaves); + memcpy( pCutNew+1, Vec_IntArray(vLeaves), sizeof(int) * Vec_IntSize(vLeaves) ); + } + Vec_IntFree( vLeaves ); + // create new mapping + Vec_IntFreeP( &pNew->vMapping ); + pNew->vMapping = Vec_IntAlloc( (p->pPars->nLutSize + 2) * Gia_ManObjNum(pNew) ); + Vec_IntFill( pNew->vMapping, Gia_ManObjNum(pNew), 0 ); + Gia_ManIncrementTravId( pNew ); + Gia_ManForEachCo( pNew, pObj, i ) + Sbd_ManDeriveMapping_rec( p, pNew, Gia_ObjFaninId0p(pNew, pObj) ); + Vec_IntFreeP( &p->vLutCuts2 ); +} void Sbd_ManDerive_rec( Gia_Man_t * pNew, Gia_Man_t * p, int Node, Vec_Int_t * vMirrors ) { Gia_Obj_t * pObj; @@ -1951,7 +2027,7 @@ void Sbd_ManDerive_rec( Gia_Man_t * pNew, Gia_Man_t * p, int Node, Vec_Int_t * v if ( Obj != Node ) Gia_ManObj(p, Node)->Value = Abc_LitNotCond( pObj->Value, Abc_LitIsCompl(Vec_IntEntry(vMirrors, Node)) ); } -Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) +Gia_Man_t * Sbd_ManDerive( Sbd_Man_t * pMan, Gia_Man_t * p, Vec_Int_t * vMirrors ) { Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; @@ -1973,9 +2049,12 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) Gia_ManHashStop( pNew ); Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); Gia_ManTransferTiming( pNew, p ); + if ( pMan->pPars->fMapping ) + Sbd_ManDeriveMapping( pMan, pNew ); // remove dangling nodes pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManTransferTiming( pNew, pTemp ); + Gia_ManTransferMapping( pNew, pTemp ); Gia_ManStop( pTemp ); return pNew; } @@ -1993,7 +2072,7 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) ***********************************************************************/ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) { - Sbd_Str_t Strs[SBD_DIV_MAX]; //word Truth = 0; + Sbd_Str_t Strs[SBD_DIV_MAX]; word Truth = 0; int RetValue, nStrs = 0; if ( !p->pSto && Sbd_ManMergeCuts( p, Pivot ) ) return; @@ -2009,8 +2088,7 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) Vec_IntWriteEntry( p->vMirrors, Pivot, RetValue ); if ( p->pPars->fVerbose ) printf( "Node %5d: Detected constant %d.\n", Pivot, RetValue ); } -/* - else if ( p->pPars->nLutNum >= 1 && Sbd_ManExplore2( p, Pivot, &Truth ) ) + else if ( p->pPars->fFindDivs && p->pPars->nLutNum >= 1 && Sbd_ManExplore2( p, Pivot, &Truth ) ) { int i; Strs->fLut = 1; @@ -2021,7 +2099,6 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) Sbd_ManImplement2( p, Pivot, 1, Strs ); if ( p->pPars->fVerbose ) printf( "Node %5d: Detected LUT%d\n", Pivot, p->pPars->nLutSize ); } -*/ else if ( p->pPars->nLutNum >= 2 && Sbd_ManExplore3( p, Pivot, &nStrs, Strs ) ) { Sbd_ManImplement2( p, Pivot, nStrs, Strs ); @@ -2041,6 +2118,7 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) { Gia_Man_t * pNew; Gia_Obj_t * pObj; + Vec_Bit_t * vPath; Sbd_Man_t * p = Sbd_ManStart( pGia, pPars ); int nNodesOld = Gia_ManObjNum(pGia); int k, Pivot; @@ -2049,6 +2127,7 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) Gia_ManForEachObj( p->pGia, pObj, Pivot ) Sbd_StoRefObj( p->pSto, Pivot, -1 ); //return NULL; + vPath = (pPars->fUsePath && Gia_ManHasMapping(pGia)) ? Sbc_ManCriticalPath(pGia) : NULL; if ( pGia->pManTime != NULL && Tim_ManBoxNum((Tim_Man_t*)pGia->pManTime) ) { Vec_Int_t * vNodes = Gia_ManOrderWithBoxes( pGia ); @@ -2065,9 +2144,10 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) { abctime clk = Abc_Clock(); int Delay = Sbd_StoComputeCutsNode( p->pSto, Pivot ); + Sbd_StoSaveBestDelayCut( p->pSto, Pivot, Sbd_ObjCut(p, Pivot) ); p->timeCut += Abc_Clock() - clk; Vec_IntWriteEntry( p->vLutLevs, Pivot, Delay ); - if ( Delay > 1 )//&& Gia_ObjRefNumId(p->pGia, Pivot) > 1 ) + if ( Delay > 1 && (!vPath || Vec_BitEntry(vPath, Pivot)) ) Sbd_NtkPerformOne( p, Pivot ); } else if ( Gia_ObjIsCi(pObj) ) @@ -2102,22 +2182,25 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) { abctime clk = Abc_Clock(); int Delay = Sbd_StoComputeCutsNode( p->pSto, Pivot ); + Sbd_StoSaveBestDelayCut( p->pSto, Pivot, Sbd_ObjCut(p, Pivot) ); p->timeCut += Abc_Clock() - clk; Vec_IntWriteEntry( p->vLutLevs, Pivot, Delay ); - if ( Delay > 1 )//&& Gia_ObjRefNumId(p->pGia, Pivot) > 1 ) + if ( Delay > 1 && (!vPath || Vec_BitEntry(vPath, Pivot)) ) Sbd_NtkPerformOne( p, Pivot ); } //if ( nNodesOld != Gia_ManObjNum(pGia) ) // break; } } + Vec_BitFreeP( &vPath ); printf( "K = %d. S = %d. N = %d. P = %d. ", p->pPars->nLutSize, p->pPars->nLutNum, p->pPars->nCutSize, p->pPars->nCutNum ); printf( "Try = %d. Use = %d. C = %d. 1 = %d. 2 = %d. 3a = %d. 3b = %d. Lev = %d. ", p->nTried, p->nUsed, p->nLuts[0], p->nLuts[1], p->nLuts[2], p->nLuts[3], p->nLuts[4], Sbd_ManDelay(p) ); p->timeTotal = Abc_Clock() - p->timeTotal; Abc_PrintTime( 1, "Time", p->timeTotal ); - pNew = Sbd_ManDerive( pGia, p->vMirrors ); + //Sbd_ManDeriveMapping2( p ); + pNew = Sbd_ManDerive( p, pGia, p->vMirrors ); // print runtime statistics p->timeOther = p->timeTotal - p->timeWin - p->timeCut - p->timeCov - p->timeCnf - p->timeSat - p->timeQbf; //if ( p->pPars->fVerbose ) diff --git a/src/opt/sbd/sbdCut.c b/src/opt/sbd/sbdCut.c index 7bcf2189f..59505c98e 100644 --- a/src/opt/sbd/sbdCut.c +++ b/src/opt/sbd/sbdCut.c @@ -65,10 +65,11 @@ struct Sbd_Sto_t_ Sbd_Cut_t * ppCuts[SBD_MAX_CUTNUM]; // temporary cut pointers int nCutsR; // the number of cuts int Pivot; // current object - double CutCount[4]; // cut counters + int iCutBest; // best-delay cut int nCutsSpec; // special cuts int nCutsOver; // overflow cuts int DelayMin; // minimum delay + double CutCount[4]; // cut counters abctime clkStart; // starting time }; @@ -540,6 +541,7 @@ static inline void Sbd_StoComputeDelay( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pC { int i, v, Delay, DelayMin = ABC_INFINITY; assert( nCuts > 0 ); + p->iCutBest = -1; for ( i = 0; i < nCuts; i++ ) { if ( (int)pCuts[i]->nLeaves > p->nLutSize ) @@ -547,8 +549,16 @@ static inline void Sbd_StoComputeDelay( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pC Delay = 0; for ( v = 0; v < (int)pCuts[i]->nLeaves; v++ ) Delay = Abc_MaxInt( Delay, Vec_IntEntry(p->vDelays, pCuts[i]->pLeaves[v]) ); - DelayMin = Abc_MinInt( DelayMin, Delay ); + //DelayMin = Abc_MinInt( DelayMin, Delay ); + if ( DelayMin > Delay ) + { + DelayMin = Delay; + p->iCutBest = i; + } + else if ( DelayMin == Delay && p->iCutBest >= 0 && pCuts[p->iCutBest]->nLeaves > pCuts[i]->nLeaves ) + p->iCutBest = i; } + assert( p->iCutBest >= 0 ); assert( DelayMin < ABC_INFINITY ); DelayMin = (nCuts > 1 || pCuts[0]->nLeaves > 1) ? DelayMin + 1 : DelayMin; Vec_IntWriteEntry( p->vDelays, iObj, DelayMin ); @@ -725,6 +735,14 @@ int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ) Sbd_StoMergeCuts( p, iObj ); return Vec_IntEntry( p->vDelays, iObj ); } +void Sbd_StoSaveBestDelayCut( Sbd_Sto_t * p, int iObj, int * pCut ) +{ + Sbd_Cut_t * pCutBest = p->ppCuts[p->iCutBest]; int i; + assert( iObj == p->Pivot ); + pCut[0] = pCutBest->nLeaves; + for ( i = 0; i < (int)pCutBest->nLeaves; i++ ) + pCut[i+1] = pCutBest->pLeaves[i]; +} int Sbd_StoObjRefs( Sbd_Sto_t * p, int iObj ) { return Vec_IntEntry(p->vRefs, iObj); diff --git a/src/opt/sbd/sbdInt.h b/src/opt/sbd/sbdInt.h index 9b4898549..eabe5355f 100644 --- a/src/opt/sbd/sbdInt.h +++ b/src/opt/sbd/sbdInt.h @@ -92,6 +92,7 @@ extern void Sbd_StoComputeCutsConst0( Sbd_Sto_t * p, int iObj ); extern void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ); extern void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ); extern int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ); +extern void Sbd_StoSaveBestDelayCut( Sbd_Sto_t * p, int iObj, int * pCut ); extern int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int nSize, int * pLeaves ); /*=== sbdCut2.c ==========================================================*/ extern Sbd_Srv_t * Sbd_ManCutServerStart( Gia_Man_t * pGia, Vec_Int_t * vMirrors, @@ -104,6 +105,8 @@ extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); extern int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, word * pVarSims[], Vec_Int_t * vInds ); extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); +/*=== sbdPath.c ==========================================================*/ +extern Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p ); /*=== sbdQbf.c ==========================================================*/ extern int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, diff --git a/src/opt/sbd/sbdPath.c b/src/opt/sbd/sbdPath.c new file mode 100644 index 000000000..417cb4078 --- /dev/null +++ b/src/opt/sbd/sbdPath.c @@ -0,0 +1,124 @@ +/**CFile**************************************************************** + + FileName [sbdPath.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [SAT-based optimization using internal don't-cares.] + + Synopsis [Critical path.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: sbdPath.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sbdInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sbc_ManAddInternalToPath_rec( Gia_Man_t * p, int iObj, Vec_Bit_t * vPath ) +{ + Gia_Obj_t * pObj; + int k, iFan, Value = 0; + if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) + return Vec_BitEntry(vPath, iObj); + Gia_ObjSetTravIdCurrentId(p, iObj); + pObj = Gia_ManObj( p, iObj ); + if ( Gia_ObjIsCi(pObj) ) + return 0; + assert( Gia_ObjIsAnd(pObj) ); + Gia_LutForEachFanin( p, iObj, iFan, k ) + Value |= Sbc_ManAddInternalToPath_rec( p, iFan, vPath ); + if ( Value ) + Vec_BitWriteEntry( vPath, iObj, 1 ); + return Value; +} +void Sbc_ManAddInternalToPath( Gia_Man_t * p, Vec_Bit_t * vPath ) +{ + int iObj; + Gia_ManForEachLut( p, iObj ) + { + if ( !Vec_BitEntry(vPath, iObj) ) + continue; + Gia_ManIncrementTravId( p ); + Sbc_ManAddInternalToPath_rec( p, iObj, vPath ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sbc_ManCriticalPath_rec( Gia_Man_t * p, int * pLevels, int iObj, int LevelFan, Vec_Bit_t * vPath ) +{ + Gia_Obj_t * pObj; int k, iFan; + if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) + return; + Gia_ObjSetTravIdCurrentId(p, iObj); + pObj = Gia_ManObj( p, iObj ); + if ( Gia_ObjIsCi(pObj) ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Vec_BitWriteEntry( vPath, iObj, 1 ); + Gia_LutForEachFanin( p, iObj, iFan, k ) + if ( pLevels[iFan] == LevelFan ) + Sbc_ManCriticalPath_rec( p, pLevels, iFan, LevelFan-1, vPath ); +} +Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p ) +{ + int * pLevels = NULL, k, iDriver; + int nLevels = p->pManTime ? Gia_ManLutLevelWithBoxes(p) : Gia_ManLutLevel(p, &pLevels); + Vec_Bit_t * vPath = Vec_BitStart( Gia_ManObjNum(p) ); + if ( p->pManTime ) + pLevels = Vec_IntArray( p->vLevels ); + Gia_ManIncrementTravId( p ); + Gia_ManForEachCoDriverId( p, iDriver, k ) + if ( pLevels[iDriver] == nLevels && iDriver ) + Sbc_ManCriticalPath_rec( p, pLevels, iDriver, nLevels-1, vPath ); + if ( !p->pManTime ) + ABC_FREE( pLevels ); + Sbc_ManAddInternalToPath( p, vPath ); + return vPath; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + From daf310cd4a98a941df164fc1deca6803723389c8 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 2 Jan 2017 17:15:00 +0700 Subject: [PATCH 033/185] Updates to delay optimization project. --- src/opt/sbd/sbdPath.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/opt/sbd/sbdPath.c b/src/opt/sbd/sbdPath.c index 417cb4078..3a040e1ea 100644 --- a/src/opt/sbd/sbdPath.c +++ b/src/opt/sbd/sbdPath.c @@ -61,12 +61,14 @@ int Sbc_ManAddInternalToPath_rec( Gia_Man_t * p, int iObj, Vec_Bit_t * vPath ) } void Sbc_ManAddInternalToPath( Gia_Man_t * p, Vec_Bit_t * vPath ) { - int iObj; + int k, iFan, iObj; Gia_ManForEachLut( p, iObj ) { if ( !Vec_BitEntry(vPath, iObj) ) continue; Gia_ManIncrementTravId( p ); + Gia_LutForEachFanin( p, iObj, iFan, k ) + Gia_ObjSetTravIdCurrentId(p, iFan); Sbc_ManAddInternalToPath_rec( p, iObj, vPath ); } } @@ -106,7 +108,7 @@ Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p ) pLevels = Vec_IntArray( p->vLevels ); Gia_ManIncrementTravId( p ); Gia_ManForEachCoDriverId( p, iDriver, k ) - if ( pLevels[iDriver] == nLevels && iDriver ) + if ( (pLevels[iDriver] == nLevels) && iDriver ) Sbc_ManCriticalPath_rec( p, pLevels, iDriver, nLevels-1, vPath ); if ( !p->pManTime ) ABC_FREE( pLevels ); From 8b898f85e6daae51e1fa4fdedeab84a23f6655bb Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 2 Jan 2017 17:18:08 +0700 Subject: [PATCH 034/185] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 275d866fc..63dc51abc 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -1945,7 +1945,7 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) void Sbd_ManDeriveMapping_rec( Sbd_Man_t * p, Gia_Man_t * pNew, int iObj ) { Gia_Obj_t * pObj; int k, * pCut; - if ( Gia_ObjIsTravIdCurrentId(pNew, iObj) ) + if ( !iObj || Gia_ObjIsTravIdCurrentId(pNew, iObj) ) return; Gia_ObjSetTravIdCurrentId(pNew, iObj); pObj = Gia_ManObj( pNew, iObj ); From 9be69dca362453a9e2f631b81e3130180eb57a97 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 2 Jan 2017 18:03:33 +0700 Subject: [PATCH 035/185] Updates to delay optimization project. --- src/aig/gia/giaIf.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c index 26f549d05..ac748f8c7 100644 --- a/src/aig/gia/giaIf.c +++ b/src/aig/gia/giaIf.c @@ -539,22 +539,14 @@ void Gia_ManPrintMappingStats( Gia_Man_t * p, char * pDumpFile ) { sprintf( FileNameOld, "%s", p->pName ); fprintf( pTable, "\n" ); - fprintf( pTable, "%s ", p->pName ); -// fprintf( pTable, "%d ", Gia_ManCiNum(p) ); -// fprintf( pTable, "%d ", Gia_ManCoNum(p) ); -// fprintf( pTable, "%d ", Gia_ManAndNum(p) ); -// fprintf( pTable, "%d ", Gia_ManPiNum(p) - Gia_ManBoxCiNum(p) - Gia_ManRegBoxNum(p) ); -// fprintf( pTable, "%d ", Gia_ManPoNum(p) - Gia_ManBoxCoNum(p) - Gia_ManRegBoxNum(p) ); -// fprintf( pTable, "%d ", Gia_ManClockDomainNum(p) ); - + fprintf( pTable, "%s ", p->pName ); fprintf( pTable, " " ); - fprintf( pTable, "%d ", p->MappedDelay ); - fprintf( pTable, "%d ", p->MappedArea ); - fprintf( pTable, "%d ", nFanins ); - fprintf( pTable, "%d ", LevelMax ); + fprintf( pTable, "%d ", Gia_ManAndNum(p) ); fprintf( pTable, "%d ", nLuts ); -// fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) ); -// fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) ); + fprintf( pTable, "%d ", Gia_ManLutLevelWithBoxes(p) ); + fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) ); + fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) ); + fprintf( pTable, "%.2f", 1.0*(Abc_Clock() - clk)/CLOCKS_PER_SEC ); clk = Abc_Clock(); } else @@ -2014,7 +2006,7 @@ void Gia_ManMappingVerify( Gia_Man_t * p ) void Gia_ManTransferMapping( Gia_Man_t * p, Gia_Man_t * pGia ) { Gia_Obj_t * pObj; - int i, k, iFan; + int i, k, iFan, iPlace; if ( !Gia_ManHasMapping(pGia) ) return; Gia_ManMappingVerify( pGia ); @@ -2023,12 +2015,20 @@ void Gia_ManTransferMapping( Gia_Man_t * p, Gia_Man_t * pGia ) Vec_IntFill( p->vMapping, Gia_ManObjNum(p), 0 ); Gia_ManForEachLut( pGia, i ) { + if ( Gia_ObjValue(Gia_ManObj(pGia, i)) == ~0 ) // handle dangling LUT + continue; assert( !Abc_LitIsCompl(Gia_ObjValue(Gia_ManObj(pGia, i))) ); pObj = Gia_ManObj( p, Abc_Lit2Var(Gia_ObjValue(Gia_ManObj(pGia, i))) ); Vec_IntWriteEntry( p->vMapping, Gia_ObjId(p, pObj), Vec_IntSize(p->vMapping) ); + iPlace = Vec_IntSize( p->vMapping ); Vec_IntPush( p->vMapping, Gia_ObjLutSize(pGia, i) ); Gia_LutForEachFanin( pGia, i, iFan, k ) - Vec_IntPush( p->vMapping, Abc_Lit2Var(Gia_ObjValue(Gia_ManObj(pGia, iFan))) ); + { + if ( Gia_ObjValue(Gia_ManObj(pGia, iFan)) == ~0 ) // handle dangling LUT fanin + Vec_IntAddToEntry( p->vMapping, iPlace, -1 ); + else + Vec_IntPush( p->vMapping, Abc_Lit2Var(Gia_ObjValue(Gia_ManObj(pGia, iFan))) ); + } iFan = Abc_Lit2Var( Gia_ObjValue(Gia_ManObj(pGia, Abc_AbsInt(Gia_ObjLutMuxId(pGia, i)))) ); Vec_IntPush( p->vMapping, Gia_ObjLutIsMux(pGia, i) ? -iFan : iFan ); } From 51e3a7c2776e671738b5e6a679214df46fe205ee Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 2 Jan 2017 18:43:41 +0700 Subject: [PATCH 036/185] Updates to delay optimization project. --- src/opt/sbd/sbdPath.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/opt/sbd/sbdPath.c b/src/opt/sbd/sbdPath.c index 3a040e1ea..7392516dc 100644 --- a/src/opt/sbd/sbdPath.c +++ b/src/opt/sbd/sbdPath.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "sbdInt.h" +#include "misc/tim/tim.h" ABC_NAMESPACE_IMPL_START @@ -92,12 +93,28 @@ void Sbc_ManCriticalPath_rec( Gia_Man_t * p, int * pLevels, int iObj, int LevelF Gia_ObjSetTravIdCurrentId(p, iObj); pObj = Gia_ManObj( p, iObj ); if ( Gia_ObjIsCi(pObj) ) + { + Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime; + int iBox = pManTime ? Tim_ManBoxForCi( pManTime, Gia_ObjCioId(pObj) ) : -1; + if ( iBox >= 0 ) + { + int curCo = Tim_ManBoxInputFirst( pManTime, iBox ); + int nBoxInputs = Tim_ManBoxInputNum( pManTime, iBox ); + for ( k = 0; k < nBoxInputs; k++ ) + { + Gia_Obj_t * pCo = Gia_ManCo( p, curCo + k ); + int iDriver = Gia_ObjFaninId0p( p, pCo ); + if ( (pLevels[iDriver] >= LevelFan-1) && iDriver ) + Sbc_ManCriticalPath_rec( p, pLevels, iDriver, pLevels[iDriver], vPath ); + } + } return; + } assert( Gia_ObjIsAnd(pObj) ); Vec_BitWriteEntry( vPath, iObj, 1 ); Gia_LutForEachFanin( p, iObj, iFan, k ) - if ( pLevels[iFan] == LevelFan ) - Sbc_ManCriticalPath_rec( p, pLevels, iFan, LevelFan-1, vPath ); + if ( pLevels[iFan] >= LevelFan-1 ) + Sbc_ManCriticalPath_rec( p, pLevels, iFan, pLevels[iFan], vPath ); } Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p ) { @@ -109,7 +126,7 @@ Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p ) Gia_ManIncrementTravId( p ); Gia_ManForEachCoDriverId( p, iDriver, k ) if ( (pLevels[iDriver] == nLevels) && iDriver ) - Sbc_ManCriticalPath_rec( p, pLevels, iDriver, nLevels-1, vPath ); + Sbc_ManCriticalPath_rec( p, pLevels, iDriver, pLevels[iDriver], vPath ); if ( !p->pManTime ) ABC_FREE( pLevels ); Sbc_ManAddInternalToPath( p, vPath ); From 378bb416462a0ce10ecb1964d8d9b424e762d7b5 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 2 Jan 2017 19:18:55 +0700 Subject: [PATCH 037/185] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 +- src/opt/sbd/sbdPath.c | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 63dc51abc..8b1de4aae 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -1992,7 +1992,7 @@ void Sbd_ManDeriveMapping( Sbd_Man_t * p, Gia_Man_t * pNew ) Vec_IntPushUniqueOrder( vLeaves, iObjNew ); } assert( Vec_IntSize(vLeaves) <= p->pPars->nLutSize ); - assert( Vec_IntSize(vLeaves) > 1 ); + //assert( Vec_IntSize(vLeaves) > 1 ); pCutNew[0] = Vec_IntSize(vLeaves); memcpy( pCutNew+1, Vec_IntArray(vLeaves), sizeof(int) * Vec_IntSize(vLeaves) ); } diff --git a/src/opt/sbd/sbdPath.c b/src/opt/sbd/sbdPath.c index 7392516dc..a2b1a9b00 100644 --- a/src/opt/sbd/sbdPath.c +++ b/src/opt/sbd/sbdPath.c @@ -52,7 +52,7 @@ int Sbc_ManAddInternalToPath_rec( Gia_Man_t * p, int iObj, Vec_Bit_t * vPath ) Gia_ObjSetTravIdCurrentId(p, iObj); pObj = Gia_ManObj( p, iObj ); if ( Gia_ObjIsCi(pObj) ) - return 0; + return Vec_BitEntry(vPath, iObj); assert( Gia_ObjIsAnd(pObj) ); Gia_LutForEachFanin( p, iObj, iFan, k ) Value |= Sbc_ManAddInternalToPath_rec( p, iFan, vPath ); @@ -85,13 +85,14 @@ void Sbc_ManAddInternalToPath( Gia_Man_t * p, Vec_Bit_t * vPath ) SeeAlso [] ***********************************************************************/ -void Sbc_ManCriticalPath_rec( Gia_Man_t * p, int * pLevels, int iObj, int LevelFan, Vec_Bit_t * vPath ) +void Sbc_ManCriticalPath_rec( Gia_Man_t * p, int * pLevels, int iObj, int LevelFan, Vec_Bit_t * vPath, int Slack ) { Gia_Obj_t * pObj; int k, iFan; if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) return; Gia_ObjSetTravIdCurrentId(p, iObj); pObj = Gia_ManObj( p, iObj ); + Vec_BitWriteEntry( vPath, iObj, 1 ); if ( Gia_ObjIsCi(pObj) ) { Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime; @@ -104,21 +105,20 @@ void Sbc_ManCriticalPath_rec( Gia_Man_t * p, int * pLevels, int iObj, int LevelF { Gia_Obj_t * pCo = Gia_ManCo( p, curCo + k ); int iDriver = Gia_ObjFaninId0p( p, pCo ); - if ( (pLevels[iDriver] >= LevelFan-1) && iDriver ) - Sbc_ManCriticalPath_rec( p, pLevels, iDriver, pLevels[iDriver], vPath ); + if ( (pLevels[iDriver]+Slack >= LevelFan-1) && iDriver ) + Sbc_ManCriticalPath_rec( p, pLevels, iDriver, pLevels[iDriver], vPath, Abc_MaxInt(0, pLevels[iDriver]+Slack-(LevelFan-1)) ); } } return; } assert( Gia_ObjIsAnd(pObj) ); - Vec_BitWriteEntry( vPath, iObj, 1 ); Gia_LutForEachFanin( p, iObj, iFan, k ) - if ( pLevels[iFan] >= LevelFan-1 ) - Sbc_ManCriticalPath_rec( p, pLevels, iFan, pLevels[iFan], vPath ); + if ( pLevels[iFan]+Slack >= LevelFan-1 ) + Sbc_ManCriticalPath_rec( p, pLevels, iFan, pLevels[iFan], vPath, Abc_MaxInt(0, pLevels[iFan]+Slack-(LevelFan-1)) ); } Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p ) { - int * pLevels = NULL, k, iDriver; + int * pLevels = NULL, k, iDriver, Slack = 1; int nLevels = p->pManTime ? Gia_ManLutLevelWithBoxes(p) : Gia_ManLutLevel(p, &pLevels); Vec_Bit_t * vPath = Vec_BitStart( Gia_ManObjNum(p) ); if ( p->pManTime ) @@ -126,7 +126,7 @@ Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p ) Gia_ManIncrementTravId( p ); Gia_ManForEachCoDriverId( p, iDriver, k ) if ( (pLevels[iDriver] == nLevels) && iDriver ) - Sbc_ManCriticalPath_rec( p, pLevels, iDriver, pLevels[iDriver], vPath ); + Sbc_ManCriticalPath_rec( p, pLevels, iDriver, pLevels[iDriver], vPath, Slack ); if ( !p->pManTime ) ABC_FREE( pLevels ); Sbc_ManAddInternalToPath( p, vPath ); From 58622ed032570bc7437762ff55058281677f5ee1 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 5 Jan 2017 12:53:15 +0700 Subject: [PATCH 038/185] Adding two external APIs. --- src/aig/miniaig/abcapis.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/aig/miniaig/abcapis.h b/src/aig/miniaig/abcapis.h index f412f5aef..eb8586fef 100644 --- a/src/aig/miniaig/abcapis.h +++ b/src/aig/miniaig/abcapis.h @@ -52,6 +52,8 @@ extern int Cmd_CommandExecute( void * pAbc, char * pCommandLine ); // procedures to input/output 'mini AIG' extern void Abc_NtkInputMiniAig( void * pAbc, void * pMiniAig ); extern void * Abc_NtkOutputMiniAig( void * pAbc ); +extern void Abc_FrameGiaInputMiniAig( void * pAbc, void * p ); +extern void * Abc_FrameGiaOutputMiniAig( void * pAbc ); extern void Abc_NtkSetFlopNum( void * pAbc, int nFlops ); // procedures to input/output 'mini LUT' From e9a7ad68c4c2f2b95695875996e713f7ae708912 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 5 Jan 2017 13:23:27 +0700 Subject: [PATCH 039/185] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 8b1de4aae..179977fba 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -2086,7 +2086,7 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) if ( RetValue >= 0 ) { Vec_IntWriteEntry( p->vMirrors, Pivot, RetValue ); - if ( p->pPars->fVerbose ) printf( "Node %5d: Detected constant %d.\n", Pivot, RetValue ); + //if ( p->pPars->fVerbose ) printf( "Node %5d: Detected constant %d.\n", Pivot, RetValue ); } else if ( p->pPars->fFindDivs && p->pPars->nLutNum >= 1 && Sbd_ManExplore2( p, Pivot, &Truth ) ) { @@ -2097,19 +2097,19 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) Strs->VarIns[i] = i; Strs->Res = Truth; Sbd_ManImplement2( p, Pivot, 1, Strs ); - if ( p->pPars->fVerbose ) printf( "Node %5d: Detected LUT%d\n", Pivot, p->pPars->nLutSize ); + //if ( p->pPars->fVerbose ) printf( "Node %5d: Detected LUT%d\n", Pivot, p->pPars->nLutSize ); } else if ( p->pPars->nLutNum >= 2 && Sbd_ManExplore3( p, Pivot, &nStrs, Strs ) ) { Sbd_ManImplement2( p, Pivot, nStrs, Strs ); if ( !p->pPars->fVerbose ) return; - if ( Vec_IntSize(p->vDivSet) <= 4 ) - printf( "Node %5d: Detected %d\n", Pivot, p->pPars->nLutSize ); - else if ( Vec_IntSize(p->vDivSet) <= 6 || (Vec_IntSize(p->vDivSet) == 7 && nStrs == 2) ) - printf( "Node %5d: Detected %d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize ); - else - printf( "Node %5d: Detected %d%d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize, p->pPars->nLutSize ); + //if ( Vec_IntSize(p->vDivSet) <= 4 ) + // printf( "Node %5d: Detected %d\n", Pivot, p->pPars->nLutSize ); + //else if ( Vec_IntSize(p->vDivSet) <= 6 || (Vec_IntSize(p->vDivSet) == 7 && nStrs == 2) ) + // printf( "Node %5d: Detected %d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize ); + //else + // printf( "Node %5d: Detected %d%d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize, p->pPars->nLutSize ); } else p->nUsed--; @@ -2193,17 +2193,19 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) } } Vec_BitFreeP( &vPath ); - printf( "K = %d. S = %d. N = %d. P = %d. ", - p->pPars->nLutSize, p->pPars->nLutNum, p->pPars->nCutSize, p->pPars->nCutNum ); - printf( "Try = %d. Use = %d. C = %d. 1 = %d. 2 = %d. 3a = %d. 3b = %d. Lev = %d. ", - p->nTried, p->nUsed, p->nLuts[0], p->nLuts[1], p->nLuts[2], p->nLuts[3], p->nLuts[4], Sbd_ManDelay(p) ); p->timeTotal = Abc_Clock() - p->timeTotal; - Abc_PrintTime( 1, "Time", p->timeTotal ); - //Sbd_ManDeriveMapping2( p ); + if ( p->pPars->fVerbose ) + { + printf( "K = %d. S = %d. N = %d. P = %d. ", + p->pPars->nLutSize, p->pPars->nLutNum, p->pPars->nCutSize, p->pPars->nCutNum ); + printf( "Try = %d. Use = %d. C = %d. 1 = %d. 2 = %d. 3a = %d. 3b = %d. Lev = %d. ", + p->nTried, p->nUsed, p->nLuts[0], p->nLuts[1], p->nLuts[2], p->nLuts[3], p->nLuts[4], Sbd_ManDelay(p) ); + Abc_PrintTime( 1, "Time", p->timeTotal ); + } pNew = Sbd_ManDerive( p, pGia, p->vMirrors ); // print runtime statistics p->timeOther = p->timeTotal - p->timeWin - p->timeCut - p->timeCov - p->timeCnf - p->timeSat - p->timeQbf; - //if ( p->pPars->fVerbose ) + if ( p->pPars->fVerbose ) { ABC_PRTP( "Win", p->timeWin , p->timeTotal ); ABC_PRTP( "Cut", p->timeCut , p->timeTotal ); From a2fcd0710d22d79ef238e1cb9ef328ce94fa5000 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 6 Jan 2017 11:52:00 +0700 Subject: [PATCH 040/185] Creating file name from design name for PDR invariant. --- src/proof/pdr/pdrCore.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index c020c56af..66cae36e8 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -922,10 +922,11 @@ int Pdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) } if ( p->pPars->fDumpInv ) { + char * pFileName = Extra_FileNameGenericAppend(p->pAig->pName, "_inv.pla"); Abc_FrameSetCnf( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); Abc_FrameSetStr( Pdr_ManDumpString(p) ); Abc_FrameSetInv( Pdr_ManCountFlopsInv(p) ); - Pdr_ManDumpClauses( p, (char *)"inv.pla", RetValue==1 ); + Pdr_ManDumpClauses( p, pFileName, RetValue==1 ); } p->tTotal += Abc_Clock() - clk; Pdr_ManStop( p ); From 5c9983d089c9cac4eb71bb5ce38838cd47b29d62 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 6 Jan 2017 12:47:57 +0700 Subject: [PATCH 041/185] Dealing wit COs driven by inverters in MiniLUT. --- src/aig/gia/giaMini.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/aig/gia/giaMini.c b/src/aig/gia/giaMini.c index a886311f1..4ee92cdda 100644 --- a/src/aig/gia/giaMini.c +++ b/src/aig/gia/giaMini.c @@ -21,6 +21,7 @@ #include "gia.h" #include "opt/dau/dau.h" #include "base/main/main.h" +#include "misc/util/utilTruth.h" #include "aig/miniaig/miniaig.h" #include "aig/miniaig/minilut.h" @@ -245,6 +246,34 @@ Gia_Man_t * Gia_ManFromMiniLut( Mini_Lut_t * p ) return pGia; } +/**Function************************************************************* + + Synopsis [Marks LUTs that should be complemented.] + + Description [These are LUTs whose all PO fanouts require them + in negative polarity. Other fanouts may require them in + positive polarity.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Bit_t * Gia_ManFindComplLuts( Gia_Man_t * pGia ) +{ + Gia_Obj_t * pObj; int i; + // mark objects pointed by COs in negative polarity + Vec_Bit_t * vMarks = Vec_BitStart( Gia_ManObjNum(pGia) ); + Gia_ManForEachCo( pGia, pObj, i ) + if ( Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) && Gia_ObjFaninC0(pObj) ) + Vec_BitWriteEntry( vMarks, Gia_ObjFaninId0p(pGia, pObj), 1 ); + // unmark objects pointed by COs in positive polarity + Gia_ManForEachCo( pGia, pObj, i ) + if ( Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) && !Gia_ObjFaninC0(pObj) ) + Vec_BitWriteEntry( vMarks, Gia_ObjFaninId0p(pGia, pObj), 0 ); + return vMarks; +} + /**Function************************************************************* Synopsis [Converts GIA into MiniLUT.] @@ -260,8 +289,9 @@ Mini_Lut_t * Gia_ManToMiniLut( Gia_Man_t * pGia ) { Mini_Lut_t * p; Vec_Wrd_t * vTruths; + Vec_Bit_t * vMarks; Gia_Obj_t * pObj, * pFanin; - int i, k, LutSize, pVars[16]; + int i, k, iFanin, LutSize, pVars[16]; word Truth; assert( Gia_ManHasMapping(pGia) ); LutSize = Gia_ManLutSizeMax( pGia ); @@ -274,12 +304,17 @@ Mini_Lut_t * Gia_ManToMiniLut( Gia_Man_t * pGia ) pObj->Value = Mini_LutCreatePi(p); // create internal nodes vTruths = Vec_WrdStart( Gia_ManObjNum(pGia) ); + vMarks = Gia_ManFindComplLuts( pGia ); Gia_ManForEachLut( pGia, i ) { pObj = Gia_ManObj( pGia, i ); Gia_LutForEachFaninObj( pGia, i, pFanin, k ) pVars[k] = pFanin->Value; Truth = Gia_LutComputeTruth6( pGia, i, vTruths ); + Truth = Vec_BitEntry(vMarks, i) ? ~Truth : Truth; + Gia_LutForEachFanin( pGia, i, iFanin, k ) + if ( Vec_BitEntry(vMarks, iFanin) ) + Truth = Abc_Tt6Flip( Truth, k ); pObj->Value = Mini_LutCreateNode( p, Gia_ObjLutSize(pGia, i), pVars, (unsigned *)&Truth ); } Vec_WrdFree( vTruths ); @@ -288,7 +323,7 @@ Mini_Lut_t * Gia_ManToMiniLut( Gia_Man_t * pGia ) { if ( Gia_ObjFanin0(pObj) == Gia_ManConst0(pGia) ) pObj->Value = Mini_LutCreatePo( p, Gia_ObjFaninC0(pObj) ); - else if ( !Gia_ObjFaninC0(pObj) ) + else if ( Gia_ObjFaninC0(pObj) == Vec_BitEntry(vMarks, Gia_ObjFaninId0p(pGia, pObj)) ) pObj->Value = Mini_LutCreatePo( p, Gia_ObjFanin0(pObj)->Value ); else // add inverter LUT { @@ -298,6 +333,7 @@ Mini_Lut_t * Gia_ManToMiniLut( Gia_Man_t * pGia ) pObj->Value = Mini_LutCreatePo( p, LutInv ); } } + Vec_BitFree( vMarks ); // set registers Mini_LutSetRegNum( p, Gia_ManRegNum(pGia) ); //Mini_LutPrintStats( p ); From 460167ec747aed778bfc13f2040dd8a205169fa2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 7 Jan 2017 08:57:08 +0700 Subject: [PATCH 042/185] Compiler warnings. --- src/aig/gia/giaJf.c | 16 ++++++++-------- src/aig/gia/giaKf.c | 14 +++++++------- src/aig/gia/giaLf.c | 10 +++++----- src/aig/gia/giaMf.c | 8 ++++---- src/base/abci/abcExact.c | 2 +- src/map/if/ifDec16.c | 2 +- src/map/scl/sclLiberty.c | 8 ++++---- src/proof/acec/acecCo.c | 2 +- 8 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/aig/gia/giaJf.c b/src/aig/gia/giaJf.c index 93dac301b..2d75581d0 100644 --- a/src/aig/gia/giaJf.c +++ b/src/aig/gia/giaJf.c @@ -1256,10 +1256,10 @@ void Jf_ManComputeCuts( Jf_Man_t * p, int fEdge ) } if ( p->pPars->fVerbose ) { - printf( "CutPair = %lu ", p->CutCount[0] ); - printf( "Merge = %lu ", p->CutCount[1] ); - printf( "Eval = %lu ", p->CutCount[2] ); - printf( "Cut = %lu ", p->CutCount[3] ); + printf( "CutPair = %lu ", (long)p->CutCount[0] ); + printf( "Merge = %lu ", (long)p->CutCount[1] ); + printf( "Eval = %lu ", (long)p->CutCount[2] ); + printf( "Cut = %lu ", (long)p->CutCount[3] ); Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart ); printf( "Memory: " ); printf( "Gia = %.2f MB ", Gia_ManMemory(p->pGia) / (1<<20) ); @@ -1702,11 +1702,11 @@ void Jf_ManPrintStats( Jf_Man_t * p, char * pTitle ) if ( !p->pPars->fVerbose ) return; printf( "%s : ", pTitle ); - printf( "Level =%6lu ", p->pPars->Delay ); - printf( "Area =%9lu ", p->pPars->Area ); - printf( "Edge =%9lu ", p->pPars->Edge ); + printf( "Level =%6lu ", (long)p->pPars->Delay ); + printf( "Area =%9lu ", (long)p->pPars->Area ); + printf( "Edge =%9lu ", (long)p->pPars->Edge ); if ( p->pPars->fGenCnf ) - printf( "Cnf =%9lu ", p->pPars->Clause ); + printf( "Cnf =%9lu ", (long)p->pPars->Clause ); Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart ); fflush( stdout ); } diff --git a/src/aig/gia/giaKf.c b/src/aig/gia/giaKf.c index caa88bfcf..a823f7262 100644 --- a/src/aig/gia/giaKf.c +++ b/src/aig/gia/giaKf.c @@ -1125,9 +1125,9 @@ void Kf_ManPrintStats( Kf_Man_t * p, char * pTitle ) if ( !p->pPars->fVerbose ) return; printf( "%s : ", pTitle ); - printf( "Level =%6lu ", p->pPars->Delay ); - printf( "Area =%9lu ", p->pPars->Area ); - printf( "Edge =%9lu ", p->pPars->Edge ); + printf( "Level =%6lu ", (long)p->pPars->Delay ); + printf( "Area =%9lu ", (long)p->pPars->Area ); + printf( "Edge =%9lu ", (long)p->pPars->Edge ); Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart ); fflush( stdout ); } @@ -1173,10 +1173,10 @@ void Kf_ManComputeMapping( Kf_Man_t * p ) Kf_ManComputeRefs( p ); if ( p->pPars->fVerbose ) { - printf( "CutPair = %lu ", p->pSett->CutCount[0] ); - printf( "Merge = %lu ", p->pSett->CutCount[1] ); - printf( "Eval = %lu ", p->pSett->CutCount[2] ); - printf( "Cut = %lu ", p->pSett->CutCount[3] ); + printf( "CutPair = %lu ", (long)p->pSett->CutCount[0] ); + printf( "Merge = %lu ", (long)p->pSett->CutCount[1] ); + printf( "Eval = %lu ", (long)p->pSett->CutCount[2] ); + printf( "Cut = %lu ", (long)p->pSett->CutCount[3] ); Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart ); printf( "Memory: " ); printf( "Gia = %.2f MB ", Gia_ManMemory(p->pGia) / (1<<20) ); diff --git a/src/aig/gia/giaLf.c b/src/aig/gia/giaLf.c index 082b19286..7973966a3 100644 --- a/src/aig/gia/giaLf.c +++ b/src/aig/gia/giaLf.c @@ -2012,14 +2012,14 @@ void Lf_ManPrintStats( Lf_Man_t * p, char * pTitle ) if ( !p->pPars->fVerbose ) return; printf( "%s : ", pTitle ); - printf( "Level =%6lu ", p->pPars->Delay ); - printf( "Area =%9lu ", p->pPars->Area ); - printf( "Edge =%9lu ", p->pPars->Edge ); - printf( "LUT =%9lu ", p->pPars->Area+p->nInverters ); + printf( "Level =%6lu ", (long)p->pPars->Delay ); + printf( "Area =%9lu ", (long)p->pPars->Area ); + printf( "Edge =%9lu ", (long)p->pPars->Edge ); + printf( "LUT =%9lu ", (long)p->pPars->Area+p->nInverters ); if ( Vec_FltSize(&p->vSwitches) ) printf( "Swt =%8.1f ", p->Switches ); if ( p->pPars->fUseMux7 ) - printf( "Mux7 =%7lu ", p->pPars->Mux7 ); + printf( "Mux7 =%7lu ", (long)p->pPars->Mux7 ); Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart ); fflush( stdout ); } diff --git a/src/aig/gia/giaMf.c b/src/aig/gia/giaMf.c index 591f5bc5e..2ded34bd0 100644 --- a/src/aig/gia/giaMf.c +++ b/src/aig/gia/giaMf.c @@ -1415,11 +1415,11 @@ void Mf_ManPrintStats( Mf_Man_t * p, char * pTitle ) if ( !p->pPars->fVerbose ) return; printf( "%s : ", pTitle ); - printf( "Level =%6lu ", p->pPars->Delay ); - printf( "Area =%9lu ", p->pPars->Area ); - printf( "Edge =%9lu ", p->pPars->Edge ); + printf( "Level =%6lu ", (long)p->pPars->Delay ); + printf( "Area =%9lu ", (long)p->pPars->Area ); + printf( "Edge =%9lu ", (long)p->pPars->Edge ); if ( p->pPars->fGenCnf ) - printf( "CNF =%9lu ", p->pPars->Clause ); + printf( "CNF =%9lu ", (long)p->pPars->Clause ); Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart ); fflush( stdout ); } diff --git a/src/base/abci/abcExact.c b/src/base/abci/abcExact.c index 757034cd0..adb64d791 100644 --- a/src/base/abci/abcExact.c +++ b/src/base/abci/abcExact.c @@ -873,7 +873,7 @@ static void Ses_StoreRead( Ses_Store_t * pStore, const char * pFilename, int fSy fclose( pFile ); - printf( "read %lu entries from file\n", nEntries ); + printf( "read %lu entries from file\n", (long)nEntries ); } // computes top decomposition of variables wrt. to AND and OR diff --git a/src/map/if/ifDec16.c b/src/map/if/ifDec16.c index 22de91baf..4b555bf86 100644 --- a/src/map/if/ifDec16.c +++ b/src/map/if/ifDec16.c @@ -902,7 +902,7 @@ void If_CluReverseOrder_old( word * pF, int nVars, int * V2P, int * P2V, int iVa // return the number of cofactors w.r.t. the topmost vars (nBSsize) int If_CluCountCofs( word * pF, int nVars, int nBSsize, int iShift, word pCofs[3][CLU_WRD_MAX/4] ) { - word iCofs[128], iCof, Result = 0; + word iCofs[128] = {0}, iCof, Result = 0; word * pCofA, * pCofB; int nMints = (1 << nBSsize); int i, c, w, nCofs; diff --git a/src/map/scl/sclLiberty.c b/src/map/scl/sclLiberty.c index 5ecf76bbc..b48cfbe16 100644 --- a/src/map/scl/sclLiberty.c +++ b/src/map/scl/sclLiberty.c @@ -765,10 +765,10 @@ Vec_Str_t * Scl_LibertyParseGenlibStr( char * pFileName, int fVerbose ) ***********************************************************************/ //#define SCL_DEBUG #ifdef SCL_DEBUG -static inline void Vec_StrPutI_( Vec_Str_t * vOut, int Val ) { printf( "%d ", Val ); Vec_StrPutI( vOut, Val ); } -static inline void Vec_StrPutW_( Vec_Str_t * vOut, word Val ) { printf( "%lu ", Val ); Vec_StrPutW( vOut, Val ); } -static inline void Vec_StrPutF_( Vec_Str_t * vOut, float Val ) { printf( "%f ", Val ); Vec_StrPutF( vOut, Val ); } -static inline void Vec_StrPutS_( Vec_Str_t * vOut, char * Val ) { printf( "%s ", Val ); Vec_StrPutS( vOut, Val ); } +static inline void Vec_StrPutI_( Vec_Str_t * vOut, int Val ) { printf( "%d ", Val ); Vec_StrPutI( vOut, Val ); } +static inline void Vec_StrPutW_( Vec_Str_t * vOut, word Val ) { printf( "%lu ", (long)Val ); Vec_StrPutW( vOut, Val ); } +static inline void Vec_StrPutF_( Vec_Str_t * vOut, float Val ) { printf( "%f ", Val ); Vec_StrPutF( vOut, Val ); } +static inline void Vec_StrPutS_( Vec_Str_t * vOut, char * Val ) { printf( "%s ", Val ); Vec_StrPutS( vOut, Val ); } static inline void Vec_StrPut_( Vec_Str_t * vOut ) { printf( "\n" ); } #else static inline void Vec_StrPutI_( Vec_Str_t * vOut, int Val ) { Vec_StrPutI( vOut, Val ); } diff --git a/src/proof/acec/acecCo.c b/src/proof/acec/acecCo.c index 1e8ed7bb6..a997eb034 100644 --- a/src/proof/acec/acecCo.c +++ b/src/proof/acec/acecCo.c @@ -109,7 +109,7 @@ Vec_Int_t * Gia_PolynCoreOrder_int( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Wec { Vec_Int_t * vOrder = Vec_IntAlloc( 1000 ); Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(pGia) ); - int i, k, Index, Driver, Entry1, Entry2 = -1; + int i, k, Index = -1, Driver, Entry1, Entry2 = -1; // mark roots Vec_IntForEachEntry( vRoots, Driver, i ) Vec_BitWriteEntry( vIsRoot, Driver, 1 ); From 3dd2325aa8572bbe0689a537101f138a0c7b8c87 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 7 Jan 2017 09:51:38 +0700 Subject: [PATCH 043/185] Adding an option to not add buffers to decouple COs driven by the same internal node. --- src/base/abc/abcUtil.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c index f01ef07ab..dd3a75b7c 100644 --- a/src/base/abc/abcUtil.c +++ b/src/base/abc/abcUtil.c @@ -1077,6 +1077,7 @@ void Abc_NtkLogicMakeSimpleCosTest( Abc_Ntk_t * pNtk, int fDuplicate ) ***********************************************************************/ int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, int fDuplicate ) { + int fAddBuffers = 1; Vec_Ptr_t * vDrivers, * vCoTerms; Abc_Obj_t * pNode, * pDriver, * pDriverNew, * pFanin; int i, k, LevelMax, nTotal = 0; @@ -1191,6 +1192,12 @@ int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, int fDuplicate ) // collect COs that needs fixing by adding buffers or duplicating vCoTerms = Vec_PtrAlloc( 100 ); Abc_NtkIncrementTravId( pNtk ); + + // The following cases should be addressed only if the network is written + // into a BLIF file. Otherwise, it is possible to skip them: + // (1) if a CO points to a CI with a different name + // (2) if an internal node drives more than one CO + if ( fAddBuffers ) Abc_NtkForEachCo( pNtk, pNode, i ) { // if the driver is a CI and has different name, this is an error From a2813847318bf22e0c36c7141047eaa82657f60d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 7 Jan 2017 14:42:47 +0700 Subject: [PATCH 044/185] Bug fix in delay-opt framework. --- src/opt/sbd/sbdCore.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 179977fba..4f560a0a7 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -1964,7 +1964,7 @@ void Sbd_ManDeriveMapping_rec( Sbd_Man_t * p, Gia_Man_t * pNew, int iObj ) void Sbd_ManDeriveMapping( Sbd_Man_t * p, Gia_Man_t * pNew ) { Gia_Obj_t * pObj, * pFan; - int i, k, iFan, iObjNew, * pCut, * pCutNew; + int i, k, iFan, iObjNew, iFanNew, * pCut, * pCutNew; Vec_Int_t * vLeaves = Vec_IntAlloc( 100 ); // derive cuts for the new manager p->vLutCuts2 = Vec_IntStart( Gia_ManObjNum(pNew) * (p->pPars->nLutSize + 1) ); @@ -1986,10 +1986,10 @@ void Sbd_ManDeriveMapping( Sbd_Man_t * p, Gia_Man_t * pNew ) pFan = Gia_ManObj( p->pGia, iFan ); if ( pFan->Value == ~0 ) continue; - iObjNew = Abc_Lit2Var( pFan->Value ); - if ( iObjNew == 0 ) + iFanNew = Abc_Lit2Var( pFan->Value ); + if ( iFanNew == 0 || iFanNew == iObjNew ) continue; - Vec_IntPushUniqueOrder( vLeaves, iObjNew ); + Vec_IntPushUniqueOrder( vLeaves, iFanNew ); } assert( Vec_IntSize(vLeaves) <= p->pPars->nLutSize ); //assert( Vec_IntSize(vLeaves) > 1 ); From 8ad3d6bec8ff89c8d742869cff05735d6f023fc8 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 8 Jan 2017 03:10:42 +0700 Subject: [PATCH 045/185] Bug fixes by Clifford Wolf. --- src/map/if/ifLibLut.c | 4 ++++ src/opt/sbd/sbdCnf.c | 4 ++-- src/opt/sfm/sfmCnf.c | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/map/if/ifLibLut.c b/src/map/if/ifLibLut.c index 26fa137ba..1033cc1f3 100644 --- a/src/map/if/ifLibLut.c +++ b/src/map/if/ifLibLut.c @@ -75,6 +75,7 @@ If_LibLut_t * If_LibLutRead( char * FileName ) Abc_Print( 1, "Error in the LUT library file \"%s\".\n", FileName ); ABC_FREE( p->pName ); ABC_FREE( p ); + fclose( pFile ); return NULL; } @@ -93,6 +94,7 @@ If_LibLut_t * If_LibLutRead( char * FileName ) ABC_FREE( p->pName ); ABC_FREE( p ); Abc_Print( 1, "LUT %d has too many pins (%d). Max allowed is %d.\n", i, k, i ); + fclose( pFile ); return NULL; } @@ -105,6 +107,7 @@ If_LibLut_t * If_LibLutRead( char * FileName ) ABC_FREE( p->pName ); ABC_FREE( p ); Abc_Print( 1, "Skipping LUTs of size more than %d.\n", i ); + fclose( pFile ); return NULL; } i++; @@ -136,6 +139,7 @@ If_LibLut_t * If_LibLutRead( char * FileName ) } } + fclose( pFile ); return p; } diff --git a/src/opt/sbd/sbdCnf.c b/src/opt/sbd/sbdCnf.c index 6291baedc..8705858e6 100644 --- a/src/opt/sbd/sbdCnf.c +++ b/src/opt/sbd/sbdCnf.c @@ -44,7 +44,7 @@ ABC_NAMESPACE_IMPL_START ***********************************************************************/ void Sbd_PrintCnf( Vec_Str_t * vCnf ) { - char Entry; + signed char Entry; int i, Lit; Vec_StrForEachEntry( vCnf, Entry, i ) { @@ -121,7 +121,7 @@ int Sbd_TruthToCnf( word Truth, int nVars, Vec_Int_t * vCover, Vec_Str_t * vCnf void Sbd_TranslateCnf( Vec_Wec_t * vRes, Vec_Str_t * vCnf, Vec_Int_t * vFaninMap, int iPivotVar ) { Vec_Int_t * vClause; - char Entry; + signed char Entry; int i, Lit; Vec_WecClear( vRes ); vClause = Vec_WecPushLevel( vRes ); diff --git a/src/opt/sfm/sfmCnf.c b/src/opt/sfm/sfmCnf.c index 0ab92258b..b4dd11f89 100644 --- a/src/opt/sfm/sfmCnf.c +++ b/src/opt/sfm/sfmCnf.c @@ -45,7 +45,7 @@ ABC_NAMESPACE_IMPL_START ***********************************************************************/ void Sfm_PrintCnf( Vec_Str_t * vCnf ) { - char Entry; + signed char Entry; int i, Lit; Vec_StrForEachEntry( vCnf, Entry, i ) { @@ -153,7 +153,7 @@ Vec_Wec_t * Sfm_CreateCnf( Sfm_Ntk_t * p ) void Sfm_TranslateCnf( Vec_Wec_t * vRes, Vec_Str_t * vCnf, Vec_Int_t * vFaninMap, int iPivotVar ) { Vec_Int_t * vClause; - char Entry; + signed char Entry; int i, Lit; Vec_WecClear( vRes ); vClause = Vec_WecPushLevel( vRes ); From feb57982a999b6c6faf58b0e279d9b8949802962 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 9 Jan 2017 10:46:29 +0700 Subject: [PATCH 046/185] Change suggested by Udi Finkelstein. --- src/base/cmd/cmd.c | 21 +-------------------- src/base/cmd/cmdLoad.c | 21 +-------------------- 2 files changed, 2 insertions(+), 40 deletions(-) diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c index 0b7c17887..ab037139a 100644 --- a/src/base/cmd/cmd.c +++ b/src/base/cmd/cmd.c @@ -1147,26 +1147,7 @@ usage: #if defined(WIN32) && !defined(__cplusplus) #include - -// these structures are defined in but are for some reason invisible -typedef unsigned long _fsize_t; // Could be 64 bits for Win32 - -struct _finddata_t { - unsigned attrib; - time_t time_create; // -1 for FAT file systems - time_t time_access; // -1 for FAT file systems - time_t time_write; - _fsize_t size; - char name[260]; -}; - -extern long _findfirst( char *filespec, struct _finddata_t *fileinfo ); -extern int _findnext( long handle, struct _finddata_t *fileinfo ); -extern int _findclose( long handle ); - -//extern char * _getcwd( char * buffer, int maxlen ); -//extern int _chdir( const char *dirname ); - +#include /**Function************************************************************* diff --git a/src/base/cmd/cmdLoad.c b/src/base/cmd/cmdLoad.c index 7f7c1b60d..accd9440f 100644 --- a/src/base/cmd/cmdLoad.c +++ b/src/base/cmd/cmdLoad.c @@ -97,26 +97,7 @@ int CmdCommandLoad( Abc_Frame_t * pAbc, int argc, char ** argv ) #if defined(WIN32) && !defined(__cplusplus) #include - - -// these structures are defined in but are for some reason invisible -typedef unsigned long _fsize_t; // Could be 64 bits for Win32 - -struct _finddata_t { - unsigned attrib; - time_t time_create; // -1 for FAT file systems - time_t time_access; // -1 for FAT file systems - time_t time_write; - _fsize_t size; - char name[260]; -}; - -extern long _findfirst( char *filespec, struct _finddata_t *fileinfo ); -extern int _findnext( long handle, struct _finddata_t *fileinfo ); -extern int _findclose( long handle ); - -//extern char * _getcwd( char * buffer, int maxlen ); -//extern int _chdir( const char *dirname ); +#include /**Function************************************************************* From 9514c327e3d8703775d138fe029b247adbf06099 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 9 Jan 2017 11:04:48 +0700 Subject: [PATCH 047/185] Bug fix in delay-opt framework. --- src/base/abci/abc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 2be65ed0f..a69737ead 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -41153,7 +41153,7 @@ usage: Abc_Print( -2, "\t-F : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nTfoFanMax ); Abc_Print( -2, "\t-M : the max node count of windows to consider (0 = no limit) [default = %d]\n", pPars->nWinSizeMax ); Abc_Print( -2, "\t-C : the max number of conflicts in one SAT run (0 = no limit) [default = %d]\n", pPars->nBTLimit ); - Abc_Print( -2, "\t-m : toggle generating delay-oriented mapping [default = %s]\n", pPars->fMapping? "area": "area+edges" ); + Abc_Print( -2, "\t-m : toggle generating delay-oriented mapping [default = %s]\n", pPars->fMapping? "yes": "no" ); Abc_Print( -2, "\t-c : toggle using several cuts at each node [default = %s]\n", pPars->fMoreCuts? "yes": "no" ); Abc_Print( -2, "\t-d : toggle additional search for good divisors [default = %s]\n", pPars->fFindDivs? "yes": "no" ); Abc_Print( -2, "\t-p : toggle optimizing critical path only [default = %s]\n", pPars->fUsePath? "yes": "no" ); From 902377a45d9fe9ab7939f31d848b48f40a612480 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 9 Jan 2017 11:16:28 +0700 Subject: [PATCH 048/185] Delay-oriented performance improvement in &dch. --- src/aig/gia/giaAig.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/aig/gia/giaAig.c b/src/aig/gia/giaAig.c index 3cf01c70b..cbfe86a47 100644 --- a/src/aig/gia/giaAig.c +++ b/src/aig/gia/giaAig.c @@ -22,6 +22,7 @@ #include "proof/fra/fra.h" #include "proof/dch/dch.h" #include "opt/dar/dar.h" +#include "opt/dau/dau.h" ABC_NAMESPACE_IMPL_START @@ -576,11 +577,16 @@ Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p, int fUpdateLevel, int fVerbose ) ***********************************************************************/ Gia_Man_t * Gia_ManPerformDch( Gia_Man_t * p, void * pPars ) { - Gia_Man_t * pGia; + Gia_Man_t * pGia, * pGia1; Aig_Man_t * pNew; if ( p->pManTime && p->vLevels == NULL ) Gia_ManLevelWithBoxes( p ); - pNew = Gia_ManToAig( p, 0 ); + if ( Gia_ManHasMapping(p) ) + pGia1 = (Gia_Man_t *)Dsm_ManDeriveGia( p, 0 ); + else + pGia1 = Gia_ManDup( p ); + pNew = Gia_ManToAig( pGia1, 0 ); + Gia_ManStop( pGia1 ); pNew = Dar_ManChoiceNew( pNew, (Dch_Pars_t *)pPars ); // pGia = Gia_ManFromAig( pNew ); pGia = Gia_ManFromAigChoices( pNew ); From ab6a87a4db2b2d9b188c09d9142b96503261e9ce Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 9 Jan 2017 11:35:13 +0700 Subject: [PATCH 049/185] Delay-oriented performance improvement in &dch (make it conditional). --- src/aig/gia/giaAig.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/aig/gia/giaAig.c b/src/aig/gia/giaAig.c index cbfe86a47..dfd4a467b 100644 --- a/src/aig/gia/giaAig.c +++ b/src/aig/gia/giaAig.c @@ -577,11 +577,12 @@ Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p, int fUpdateLevel, int fVerbose ) ***********************************************************************/ Gia_Man_t * Gia_ManPerformDch( Gia_Man_t * p, void * pPars ) { + int fUseMapping = 0; Gia_Man_t * pGia, * pGia1; Aig_Man_t * pNew; if ( p->pManTime && p->vLevels == NULL ) Gia_ManLevelWithBoxes( p ); - if ( Gia_ManHasMapping(p) ) + if ( fUseMapping && Gia_ManHasMapping(p) ) pGia1 = (Gia_Man_t *)Dsm_ManDeriveGia( p, 0 ); else pGia1 = Gia_ManDup( p ); From fbdf28e4c937067737d84db37ff6e1a65348df5f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 9 Jan 2017 19:50:05 +0700 Subject: [PATCH 050/185] Updated to arithmetic verification. --- src/aig/gia/giaDup.c | 16 +- src/base/abci/abc.c | 146 ++++++++++----- src/proof/acec/acec.h | 18 +- src/proof/acec/acecCore.c | 383 +++++++++++++++++++++++++++++++++++++- src/proof/acec/acecInt.h | 13 +- src/proof/acec/acecPa.c | 16 ++ 6 files changed, 527 insertions(+), 65 deletions(-) diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index c58596b2f..cdb6a2085 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -3879,12 +3879,20 @@ Vec_Int_t * Gia_ManCollectTopXors( Gia_Man_t * p ) int i, iObj, iObj2, fFlip, Count1 = 0; Vec_Int_t * vXors, * vPart[2], * vOrder; Gia_Obj_t * pFan[2], * pObj = Gia_ManCo(p, 0); - assert( Gia_ManCoNum(p) == 1 ); vXors = Vec_IntAlloc( 100 ); - if ( Gia_ObjFaninC0(pObj) ) - Gia_ManCollectTopXors_rec( p, Gia_ObjFanin0(pObj), vXors ); + if ( Gia_ManCoNum(p) == 1 ) + { + if ( Gia_ObjFaninC0(pObj) ) + Gia_ManCollectTopXors_rec( p, Gia_ObjFanin0(pObj), vXors ); + else + Vec_IntPush( vXors, Gia_ObjId(p, Gia_ObjFanin0(pObj)) ); + } else - Vec_IntPush( vXors, Gia_ObjId(p, Gia_ObjFanin0(pObj)) ); + { + Gia_ManForEachCo( p, pObj, i ) + if ( Gia_ObjFaninId0p(p, pObj) > 0 ) + Vec_IntPush( vXors, Gia_ObjFaninId0p(p, pObj) ); + } // order by support size Gia_ManDupDemiterOrderXors( p, vXors ); //Vec_IntPrint( vXors ); diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index a69737ead..dd157afda 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -40532,14 +40532,12 @@ usage: int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) { FILE * pFile; - Cec_ParCec_t ParsCec, * pPars = &ParsCec; - Gia_Man_t * pSecond; - char * FileName, * pTemp; + Acec_ParCec_t ParsCec, * pPars = &ParsCec; char ** pArgvNew; - int c, nArgcNew, fMiter = 0, fDualOutput = 0, fTwoOutput = 0; - Cec_ManCecSetDefaultParams( pPars ); + int c, nArgcNew; + Acec_ManCecSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "CTnmdtvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "CTmdtvh" ) ) != EOF ) { switch ( c ) { @@ -40565,17 +40563,14 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->TimeLimit < 0 ) goto usage; break; - case 'n': - pPars->fNaive ^= 1; - break; case 'm': - fMiter ^= 1; + pPars->fMiter ^= 1; break; case 'd': - fDualOutput ^= 1; + pPars->fDualOutput ^= 1; break; case 't': - fTwoOutput ^= 1; + pPars->fTwoOutput ^= 1; break; case 'v': pPars->fVerbose ^= 1; @@ -40586,15 +40581,20 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } } - if ( fMiter ) + if ( pPars->fMiter ) { Gia_Man_t * pGia0, * pGia1, * pDual; + if ( argc != globalUtilOptind ) + { + Abc_Print( -1, "Abc_CommandAbc9Acec(): If the input is a miter, it cannot be given on the command line.\n" ); + return 1; + } if ( pAbc->pGia == NULL ) { Abc_Print( -1, "Abc_CommandAbc9Acec(): There is no AIG.\n" ); return 1; } - if ( fDualOutput ) + if ( pPars->fDualOutput ) { if ( Gia_ManPoNum(pAbc->pGia) & 1 ) { @@ -40604,28 +40604,28 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( !pPars->fSilent ) Abc_Print( 1, "Assuming the current network is a double-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit ); Gia_ManDemiterDual( pAbc->pGia, &pGia0, &pGia1 ); - pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars ); + pAbc->Status = Acec_Solve( pGia0, pGia1, pPars ); } - else if ( fTwoOutput ) + else if ( pPars->fTwoOutput ) { if ( Gia_ManPoNum(pAbc->pGia) & 1 ) { - Abc_Print( -1, "The dual-output miter should have an even number of outputs.\n" ); + Abc_Print( -1, "The two-output miter should have an even number of outputs.\n" ); return 1; } if ( !pPars->fSilent ) Abc_Print( 1, "Assuming the current network is a two-word miter. (Conflict limit = %d.)\n", pPars->nBTLimit ); Gia_ManDemiterTwoWords( pAbc->pGia, &pGia0, &pGia1 ); - pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars ); + pAbc->Status = Acec_Solve( pGia0, pGia1, pPars ); } - else + else // regular single- or multi-output miter { if ( !pPars->fSilent ) - Abc_Print( 1, "Assuming the current network is a single-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit ); + Abc_Print( 1, "Assuming the current network is a regular single- or multi-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit ); pDual = Gia_ManDemiterToDual( pAbc->pGia ); Gia_ManDemiterDual( pDual, &pGia0, &pGia1 ); Gia_ManStop( pDual ); - pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars ); + pAbc->Status = Acec_Solve( pGia0, pGia1, pPars ); } Abc_FrameReplaceCex( pAbc, &pGia0->pCexComb ); Gia_ManStop( pGia0 ); @@ -40635,52 +40635,96 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) pArgvNew = argv + globalUtilOptind; nArgcNew = argc - globalUtilOptind; - if ( nArgcNew != 1 ) + if ( nArgcNew == 0 || nArgcNew == 1 ) { - if ( pAbc->pGia->pSpec == NULL ) + Gia_Man_t * pSecond; + char * pTemp, * FileName = NULL; + if ( nArgcNew == 0 ) { - Abc_Print( -1, "File name is not given on the command line.\n" ); - return 1; + FileName = pAbc->pGia->pSpec; + if ( FileName == NULL ) + { + Abc_Print( -1, "File name is not given on the command line.\n" ); + return 1; + } } - FileName = pAbc->pGia->pSpec; + else // if ( nArgcNew == 1 ) + { + FileName = pArgvNew[0]; + // fix the wrong symbol + for ( pTemp = FileName; *pTemp; pTemp++ ) + if ( *pTemp == '>' ) + *pTemp = '\\'; + if ( (pFile = fopen( FileName, "r" )) == NULL ) + { + Abc_Print( -1, "Cannot open input file \"%s\". ", FileName ); + if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", FileName ); + Abc_Print( 1, "\n" ); + return 1; + } + fclose( pFile ); + } + pSecond = Gia_AigerRead( FileName, 0, 0, 0 ); + if ( pSecond == NULL ) + { + Abc_Print( -1, "Reading AIGER has failed.\n" ); + return 0; + } + pAbc->Status = Acec_Solve( pAbc->pGia, pSecond, pPars ); + Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb ); + Gia_ManStop( pSecond ); + } + else if ( nArgcNew == 2 ) + { + Gia_Man_t * pGias[2] = {NULL}; int i; + char * pTemp, * FileName[2] = { pArgvNew[0], pArgvNew[1] }; + for ( i = 0; i < 2; i++ ) + { + // fix the wrong symbol + for ( pTemp = FileName[i]; *pTemp; pTemp++ ) + if ( *pTemp == '>' ) + *pTemp = '\\'; + if ( (pFile = fopen( FileName[i], "r" )) == NULL ) + { + Abc_Print( -1, "Cannot open input file \"%s\". ", FileName[i] ); + if ( (FileName[i] = Extra_FileGetSimilarName( FileName[i], ".aig", NULL, NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", FileName[i] ); + Abc_Print( 1, "\n" ); + return 1; + } + fclose( pFile ); + pGias[i] = Gia_AigerRead( FileName[i], 0, 0, 0 ); + if ( pGias[i] == NULL ) + { + Abc_Print( -1, "Reading AIGER has failed.\n" ); + return 0; + } + } + pAbc->Status = Acec_Solve( pGias[0], pGias[1], pPars ); + Abc_FrameReplaceCex( pAbc, &pGias[0]->pCexComb ); + Gia_ManStop( pGias[0] ); + Gia_ManStop( pGias[1] ); } else - FileName = pArgvNew[0]; - // fix the wrong symbol - for ( pTemp = FileName; *pTemp; pTemp++ ) - if ( *pTemp == '>' ) - *pTemp = '\\'; - if ( (pFile = fopen( FileName, "r" )) == NULL ) { - Abc_Print( -1, "Cannot open input file \"%s\". ", FileName ); - if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) ) - Abc_Print( 1, "Did you mean \"%s\"?", FileName ); - Abc_Print( 1, "\n" ); + Abc_Print( -1, "Too many command-line arguments.\n" ); return 1; } - fclose( pFile ); - pSecond = Gia_AigerRead( FileName, 0, 0, 0 ); - if ( pSecond == NULL ) - { - Abc_Print( -1, "Reading AIGER has failed.\n" ); - return 0; - } - pAbc->Status = Gia_PolynCec( pAbc->pGia, pSecond, pPars ); - Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb ); - Gia_ManStop( pSecond ); return 0; usage: - Abc_Print( -2, "usage: &acec [-CT num] [-nmdtvh]\n" ); + Abc_Print( -2, "usage: &acec [-CT num] [-mdtvh] \n" ); Abc_Print( -2, "\t combinational equivalence checking for arithmetic circuits\n" ); Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); Abc_Print( -2, "\t-T num : approximate runtime limit in seconds [default = %d]\n", pPars->TimeLimit ); - Abc_Print( -2, "\t-n : toggle using naive SAT-based checking [default = %s]\n", pPars->fNaive? "yes":"no"); - Abc_Print( -2, "\t-m : toggle miter vs. two circuits [default = %s]\n", fMiter? "miter":"two circuits"); - Abc_Print( -2, "\t-d : toggle using dual output miter [default = %s]\n", fDualOutput? "yes":"no"); - Abc_Print( -2, "\t-t : toggle using two-word miter [default = %s]\n", fTwoOutput? "yes":"no"); + Abc_Print( -2, "\t-m : toggle miter vs. two circuits [default = %s]\n", pPars->fMiter? "miter":"two circuits"); + Abc_Print( -2, "\t-d : toggle using dual output miter [default = %s]\n", pPars->fDualOutput? "yes":"no"); + Abc_Print( -2, "\t-t : toggle using two-word miter [default = %s]\n", pPars->fTwoOutput? "yes":"no"); Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes":"no"); Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "\tfile1 : (optional) the file with the first network\n"); + Abc_Print( -2, "\tfile2 : (optional) the file with the second network\n"); return 1; } diff --git a/src/proof/acec/acec.h b/src/proof/acec/acec.h index c61b4485a..058e0f56d 100644 --- a/src/proof/acec/acec.h +++ b/src/proof/acec/acec.h @@ -38,6 +38,21 @@ ABC_NAMESPACE_HEADER_START /// BASIC TYPES /// //////////////////////////////////////////////////////////////////////// +// combinational equivalence checking parameters +typedef struct Acec_ParCec_t_ Acec_ParCec_t; +struct Acec_ParCec_t_ +{ + int nBTLimit; // conflict limit at a node + int TimeLimit; // the runtime limit in seconds + int fMiter; // input circuit is a miter + int fDualOutput; // dual-output miter + int fTwoOutput; // two-output miter + int fSilent; // print no messages + int fVeryVerbose; // verbose stats + int fVerbose; // verbose stats + int iOutFail; // the number of failed output +}; + //////////////////////////////////////////////////////////////////////// /// MACRO DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -51,7 +66,8 @@ ABC_NAMESPACE_HEADER_START //////////////////////////////////////////////////////////////////////// /*=== acecCore.c ========================================================*/ -extern int Gia_PolynCec( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Cec_ParCec_t * pPars ); +extern void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p ); +extern int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ); /*=== acecFadds.c ========================================================*/ extern Vec_Int_t * Gia_ManDetectFullAdders( Gia_Man_t * p, int fVerbose, Vec_Int_t ** vCutsXor2 ); extern Vec_Int_t * Gia_ManDetectHalfAdders( Gia_Man_t * p, int fVerbose ); diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index ac7ee67b1..09ccb5326 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "acecInt.h" +#include "proof/cec/cec.h" ABC_NAMESPACE_IMPL_START @@ -31,6 +32,31 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [This procedure sets default parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p ) +{ + memset( p, 0, sizeof(Acec_ParCec_t) ); + p->nBTLimit = 1000; // conflict limit at a node + p->TimeLimit = 0; // the runtime limit in seconds + p->fMiter = 0; // input circuit is a miter + p->fDualOutput = 0; // dual-output miter + p->fTwoOutput = 0; // two-output miter + p->fSilent = 0; // print no messages + p->fVeryVerbose = 0; // verbose stats + p->fVerbose = 0; // verbose stats + p->iOutFail = -1; // the number of failed output +} + /**Function************************************************************* Synopsis [] @@ -42,15 +68,356 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -int Gia_PolynCec( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Cec_ParCec_t * pPars ) +void Acec_BoxFree( Acec_Box_t * pBox ) { - Vec_Int_t * vOrder0 = Gia_PolynReorder( pGia0, pPars->fVerbose, pPars->fVeryVerbose ); - Vec_Int_t * vOrder1 = Gia_PolynReorder( pGia1, pPars->fVerbose, pPars->fVeryVerbose ); - Gia_PolynBuild( pGia0, vOrder0, 0, pPars->fVerbose, pPars->fVeryVerbose ); - Gia_PolynBuild( pGia1, vOrder1, 0, pPars->fVerbose, pPars->fVeryVerbose ); - Vec_IntFree( vOrder0 ); - Vec_IntFree( vOrder1 ); - return 1; + Vec_WecFree( pBox->vUnique ); + Vec_WecFree( pBox->vShared ); + Vec_WecFree( pBox->vLeafLits ); + Vec_WecFree( pBox->vRootLits ); + ABC_FREE( pBox ); +} +void Acec_BoxFreeP( Acec_Box_t ** ppBox ) +{ + if ( *ppBox ) + Acec_BoxFree( *ppBox ); + *ppBox = NULL; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_InsertHadd( Gia_Man_t * pNew, int In[2], int Out[2] ) +{ + int And, Or; + Out[1] = Gia_ManAppendAnd2( pNew, In[0], In[1] ); + And = Gia_ManAppendAnd2( pNew, Abc_LitNot(In[0]), Abc_LitNot(In[1]) ); + Or = Gia_ManAppendOr2( pNew, Out[1], And ); + Out[0] = Abc_LitNot( Or ); +} +void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] ) +{ + int In2[2], Out1[2], Out2[2]; + Acec_InsertHadd( pNew, In, Out1 ); + In2[0] = Out1[0]; + In2[1] = In[2]; + Acec_InsertHadd( pNew, In2, Out2 ); + Out[0] = Out2[0]; + Out[1] = Gia_ManAppendOr2( pNew, Out1[1], Out2[1] ); +} +Vec_Int_t * Acec_InsertTree( Gia_Man_t * pNew, Vec_Wec_t * vLeafMap ) +{ + Vec_Int_t * vRootRanks = Vec_IntAlloc( Vec_WecSize(vLeafMap) + 5 ); + Vec_Int_t * vLevel; + int i, In[3], Out[2]; + Vec_WecForEachLevel( vLeafMap, vLevel, i ) + { + if ( Vec_IntSize(vLevel) == 0 ) + { + Vec_IntPush( vRootRanks, 0 ); + continue; + } + while ( Vec_IntSize(vLevel) > 1 ) + { + if ( Vec_IntSize(vLevel) == 2 ) + Vec_IntPush( vLevel, 0 ); + In[0] = Vec_IntPop( vLevel ); + In[1] = Vec_IntPop( vLevel ); + In[2] = Vec_IntPop( vLevel ); + Acec_InsertFadd( pNew, In, Out ); + Vec_IntPush( vLevel, Out[0] ); + if ( i-1 < Vec_WecSize(vLeafMap) ) + vLevel = Vec_WecEntry(vLeafMap, i+1); + else + vLevel = Vec_WecPushLevel(vLeafMap); + Vec_IntPush( vLevel, Out[1] ); + } + assert( Vec_IntSize(vLevel) == 1 ); + Vec_IntPush( vRootRanks, Vec_IntEntry(vLevel, 0) ); + } + return vRootRanks; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Acec_FindEquivs( Gia_Man_t * pBase, Gia_Man_t * pAdd ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManFillValue( pAdd ); + Gia_ManConst0(pAdd)->Value = 0; + if ( pBase == NULL ) + { + pBase = Gia_ManStart( Gia_ManObjNum(pAdd) ); + pBase->pName = Abc_UtilStrsav( pAdd->pName ); + pBase->pSpec = Abc_UtilStrsav( pAdd->pSpec ); + Gia_ManForEachCi( pAdd, pObj, i ) + pObj->Value = Gia_ManAppendCi(pBase); + Gia_ManHashAlloc( pBase ); + } + else + { + assert( Gia_ManCiNum(pBase) == Gia_ManCiNum(pAdd) ); + Gia_ManForEachCi( pAdd, pObj, i ) + pObj->Value = Gia_Obj2Lit( pBase, Gia_ManCi(pBase, i) ); + } + Gia_ManForEachAnd( pAdd, pObj, i ) + pObj->Value = Gia_ManHashAnd( pBase, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + return pBase; +} +Vec_Int_t * Acec_CountRemap( Gia_Man_t * pAdd ) +{ + Gia_Obj_t * pObj; int i; + Vec_Int_t * vMapNew = Vec_IntStartFull( Gia_ManObjNum(pAdd) ); + Gia_ManForEachCand( pAdd, pObj, i ) + Vec_IntWriteEntry( vMapNew, i, Abc_Lit2Var(pObj->Value) ); + return vMapNew; +} +void Acec_ComputeEquivClasses( Gia_Man_t * pOne, Gia_Man_t * pTwo, Vec_Int_t ** pvMap1, Vec_Int_t ** pvMap2 ) +{ + Gia_Man_t * pBase; + pBase = Acec_FindEquivs( NULL, pOne ); + pBase = Acec_FindEquivs( pBase, pTwo ); + *pvMap1 = Acec_CountRemap( pOne ); + *pvMap2 = Acec_CountRemap( pTwo ); + Gia_ManStop( pBase ); +} +static inline void Acec_MatchBoxesSort( int * pArray, int nSize, int * pCosts ) +{ + int i, j, best_i; + for ( i = 0; i < nSize-1; i++ ) + { + best_i = i; + for ( j = i+1; j < nSize; j++ ) + if ( pCosts[Abc_Lit2Var(pArray[j])] > pCosts[Abc_Lit2Var(pArray[best_i])] ) + best_i = j; + ABC_SWAP( int, pArray[i], pArray[best_i] ); + } +} +int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) +{ + Vec_Int_t * vMap0, * vMap1, * vLevel; + int i, nSize, nTotal; + Acec_ComputeEquivClasses( pBox0->pGia, pBox1->pGia, &vMap0, &vMap1 ); + // sort nodes in the classes by their equivalences + Vec_WecForEachLevel( pBox0->vLeafLits, vLevel, i ) + Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap0) ); + Vec_WecForEachLevel( pBox1->vLeafLits, vLevel, i ) + Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap1) ); + // reorder nodes to have the same order + assert( pBox0->vShared == NULL ); + assert( pBox1->vShared == NULL ); + pBox0->vShared = Vec_WecStart( Vec_WecSize(pBox0->vLeafLits) ); + pBox1->vShared = Vec_WecStart( Vec_WecSize(pBox1->vLeafLits) ); + pBox0->vUnique = Vec_WecStart( Vec_WecSize(pBox0->vLeafLits) ); + pBox1->vUnique = Vec_WecStart( Vec_WecSize(pBox1->vLeafLits) ); + nSize = Abc_MinInt( Vec_WecSize(pBox0->vLeafLits), Vec_WecSize(pBox1->vLeafLits) ); + Vec_WecForEachLevelStart( pBox0->vLeafLits, vLevel, i, nSize ) + Vec_IntAppend( Vec_WecEntry(pBox0->vUnique, i), vLevel ); + Vec_WecForEachLevelStart( pBox1->vLeafLits, vLevel, i, nSize ) + Vec_IntAppend( Vec_WecEntry(pBox1->vUnique, i), vLevel ); + for ( i = 0; i < nSize; i++ ) + { + Vec_Int_t * vShared0 = Vec_WecEntry( pBox0->vShared, i ); + Vec_Int_t * vShared1 = Vec_WecEntry( pBox1->vShared, i ); + Vec_Int_t * vUnique0 = Vec_WecEntry( pBox0->vUnique, i ); + Vec_Int_t * vUnique1 = Vec_WecEntry( pBox1->vUnique, i ); + + Vec_Int_t * vLevel0 = Vec_WecEntry( pBox0->vLeafLits, i ); + Vec_Int_t * vLevel1 = Vec_WecEntry( pBox1->vLeafLits, i ); + int * pBeg0 = Vec_IntArray(vLevel0); + int * pBeg1 = Vec_IntArray(vLevel1); + int * pEnd0 = Vec_IntLimit(vLevel0); + int * pEnd1 = Vec_IntLimit(vLevel1); + while ( pBeg0 < pEnd0 && pBeg1 < pEnd1 ) + { + if ( *pBeg0 == *pBeg1 ) + { + Vec_IntPush( vShared0, *pBeg0++ ); + Vec_IntPush( vShared1, *pBeg1++ ); + } + else if ( *pBeg0 > *pBeg1 ) + Vec_IntPush( vUnique0, *pBeg0++ ); + else + Vec_IntPush( vUnique1, *pBeg1++ ); + } + while ( pBeg0 < pEnd0 ) + Vec_IntPush( vUnique0, *pBeg0++ ); + while ( pBeg1 < pEnd1 ) + Vec_IntPush( vUnique1, *pBeg1++ ); + assert( Vec_IntSize(vShared0) == Vec_IntSize(vShared1) ); + assert( Vec_IntSize(vShared0) + Vec_IntSize(vUnique0) == Vec_IntSize(vLevel0) ); + assert( Vec_IntSize(vShared1) + Vec_IntSize(vUnique1) == Vec_IntSize(vLevel1) ); + } + nTotal = Vec_WecSizeSize(pBox0->vShared); + printf( "Box0: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox0->vLeafLits) ); + printf( "Box1: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox1->vLeafLits) ); + return nTotal; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_InsertBox_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( ~pObj->Value ) + return pObj->Value; + assert( Gia_ObjIsAnd(pObj) ); + Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Acec_InsertBox_rec( pNew, p, Gia_ObjFanin1(pObj) ); + return (pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) )); +} +Vec_Int_t * Acec_BuildTree( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t * vLeafLits ) +{ + Vec_Wec_t * vLeafMap = Vec_WecStart( Vec_WecSize(vLeafLits) ); + Vec_Int_t * vLevel, * vRootRanks; + int i, k, iLit, iLitNew; + Vec_WecForEachLevel( vLeafLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + { + Gia_Obj_t * pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) ); + iLitNew = Acec_InsertBox_rec( pNew, p, pObj ); + iLitNew = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) ); + Vec_WecPush( vLeafMap, i, iLitNew ); + } + // construct map of root literals + vRootRanks = Acec_InsertTree( pNew, vLeafMap ); + Vec_WecFree( vLeafMap ); + return vRootRanks; +} + +Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ) +{ + Gia_Man_t * p = pBox->pGia; + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + Vec_Int_t * vRootRanks, * vLevel; + int i, k, iLit, iLitNew; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + // implement tree + if ( fAll ) + vRootRanks = Acec_BuildTree( pNew, p, pBox->vLeafLits ); + else + { + Vec_Wec_t * vLeafLits; + assert( pBox->vShared != NULL ); + assert( pBox->vUnique != NULL ); + vRootRanks = Acec_BuildTree( p, p, pBox->vShared ); + // add these roots to the unique ones + vLeafLits = Vec_WecDup( pBox->vUnique ); + Vec_IntForEachEntry( vRootRanks, iLit, i ) + { + if ( i < Vec_WecSize(vLeafLits) ) + vLevel = Vec_WecEntry(vLeafLits, i); + else + vLevel = Vec_WecPushLevel(vLeafLits); + Vec_IntPush( vLevel, iLit ); + } + Vec_IntFree( vRootRanks ); + vRootRanks = Acec_BuildTree( pNew, p, vLeafLits ); + Vec_WecFree( vLeafLits ); + } + // update polarity of literals + Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + { + pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) ); + iLitNew = k ? 0 : Vec_IntEntry( vRootRanks, k ); + pObj->Value = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) ); + } + Vec_IntFree( vRootRanks ); + // construct the outputs + Gia_ManForEachCo( p, pObj, i ) + Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManForEachCo( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) +{ + int status = -1; + Gia_Man_t * pMiter; + Gia_Man_t * pGia0n = pGia0, * pGia1n = pGia1; + Cec_ParCec_t ParsCec, * pCecPars = &ParsCec; + Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0 ); + Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1 ); + if ( pBox0 == NULL || pBox1 == NULL ) // cannot match + printf( "Cannot find arithmetic boxes in both LHS and RHS. Trying regular CEC.\n" ); + else if ( !Acec_MatchBoxes( pBox0, pBox1 ) ) // cannot find matching + printf( "Cannot match arithmetic boxes in LHS and RHS. Trying regular CEC.\n" ); + else + { + pGia0n = Acec_InsertBox( pBox0, 1 ); + pGia1n = Acec_InsertBox( pBox1, 1 ); + printf( "Found, matched, and normalized arithmetic boxes in LHS and RHS. Solving resulting CEC.\n" ); + } + // solve regular CEC problem + Cec_ManCecSetDefaultParams( pCecPars ); + pCecPars->nBTLimit = pPars->nBTLimit; + pMiter = Gia_ManMiter( pGia0n, pGia1n, 0, 1, 0, 0, pPars->fVerbose ); + if ( pMiter ) + { + int fDumpMiter = 1; + if ( fDumpMiter ) + { + Abc_Print( 0, "The verification miter is written into file \"%s\".\n", "acec_miter.aig" ); + Gia_AigerWrite( pMiter, "acec_miter.aig", 0, 0 ); + } + status = Cec_ManVerify( pMiter, pCecPars ); + ABC_SWAP( Abc_Cex_t *, pGia0->pCexComb, pMiter->pCexComb ); + Gia_ManStop( pMiter ); + } + else + printf( "Miter computation has failed.\n" ); + if ( pGia0n != pGia0 ) + Gia_ManStop( pGia0n ); + if ( pGia1n != pGia1 ) + Gia_ManStop( pGia1n ); + Acec_BoxFreeP( &pBox0 ); + Acec_BoxFreeP( &pBox1 ); + return status; } //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index e761e56e0..d53b61c75 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -27,7 +27,6 @@ //////////////////////////////////////////////////////////////////////// #include "aig/gia/gia.h" -#include "proof/cec/cec.h" #include "acec.h" //////////////////////////////////////////////////////////////////////// @@ -38,6 +37,16 @@ ABC_NAMESPACE_HEADER_START +typedef struct Acec_Box_t_ Acec_Box_t; +struct Acec_Box_t_ +{ + Gia_Man_t * pGia; // AIG manager + Vec_Wec_t * vLeafLits; // leaf literals by rank + Vec_Wec_t * vRootLits; // root literals by rank + Vec_Wec_t * vShared; // shared leaves + Vec_Wec_t * vUnique; // unique leaves +}; + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// //////////////////////////////////////////////////////////////////////// @@ -54,6 +63,8 @@ ABC_NAMESPACE_HEADER_START /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +/*=== acecPa.c ========================================================*/ +extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p ); /*=== acecUtil.c ========================================================*/ extern void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose ); extern Vec_Int_t * Gia_PolynCollectLastXor( Gia_Man_t * pGia, int fVerbose ); diff --git a/src/proof/acec/acecPa.c b/src/proof/acec/acecPa.c index ecaf20472..b59cdbeff 100644 --- a/src/proof/acec/acecPa.c +++ b/src/proof/acec/acecPa.c @@ -273,6 +273,22 @@ void Pas_ManComputeCutsTest( Gia_Man_t * p ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p ) +{ + return NULL; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// From 5fbc0cd7f09a382241266404d78c18c5443d2b9d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 10 Jan 2017 16:58:24 +0700 Subject: [PATCH 051/185] Updates to arithmetic verification. --- abclib.dsp | 4 +++ src/aig/gia/giaShow.c | 6 ---- src/proof/acec/acec.h | 4 +++ src/proof/acec/acecCl.c | 8 ------ src/proof/acec/acecInt.h | 7 ++++- src/proof/acec/acecPa.c | 21 -------------- src/proof/acec/acecPool.c | 17 ------------ src/proof/acec/acecRe.c | 4 +++ src/proof/acec/acecTree.c | 56 ++++++++++++++++++++++++++++++++++++++ src/proof/acec/module.make | 1 + 10 files changed, 75 insertions(+), 53 deletions(-) create mode 100644 src/proof/acec/acecTree.c diff --git a/abclib.dsp b/abclib.dsp index 4ec50a1f3..a84bef073 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -5535,6 +5535,10 @@ SOURCE=.\src\proof\acec\acecSt.c # End Source File # Begin Source File +SOURCE=.\src\proof\acec\acecTree.c +# End Source File +# Begin Source File + SOURCE=.\src\proof\acec\acecUtil.c # End Source File # End Group diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index afd36fff2..986d5624d 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -814,18 +814,12 @@ void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In } void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds ) { - extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); - extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ); - extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds ); - extern void Abc_ShowFile( char * FileNameDot ); static int Counter = 0; char FileNameDot[200]; FILE * pFile; Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( pMan, &vXors, 0 ); - Ree_ManRemoveTrivial( pMan, vAdds ); - Ree_ManRemoveContained( pMan, vAdds ); // create the file name // Gia_ShowGetFileName( pMan->pName, FileNameDot ); diff --git a/src/proof/acec/acec.h b/src/proof/acec/acec.h index 058e0f56d..918119f84 100644 --- a/src/proof/acec/acec.h +++ b/src/proof/acec/acec.h @@ -76,6 +76,10 @@ extern Vec_Int_t * Gia_PolynReorder( Gia_Man_t * pGia, int fVerbose, int fVery extern Vec_Int_t * Gia_PolynFindOrder( Gia_Man_t * pGia, Vec_Int_t * vFadds, Vec_Int_t * vHadds, int fVerbose, int fVeryVerbose ); /*=== acecPolyn.c ========================================================*/ extern void Gia_PolynBuild( Gia_Man_t * pGia, Vec_Int_t * vOrder, int fSigned, int fVerbose, int fVeryVerbose ); +/*=== acecRe.c ========================================================*/ +extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); +extern int Ree_ManCountFadds( Vec_Int_t * vAdds ); +extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose ); ABC_NAMESPACE_HEADER_END diff --git a/src/proof/acec/acecCl.c b/src/proof/acec/acecCl.c index 63483d57d..145f2e0b2 100644 --- a/src/proof/acec/acecCl.c +++ b/src/proof/acec/acecCl.c @@ -306,18 +306,10 @@ Gia_Man_t * Acec_DetectXorBuildNew( Gia_Man_t * p, Vec_Int_t * vRootXorSet ) ***********************************************************************/ Gia_Man_t * Acec_DetectAdditional( Gia_Man_t * p, int fVerbose ) { - extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); - extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ); - extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds ); - extern int Ree_ManCountFadds( Vec_Int_t * vAdds ); - extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose ); - abctime clk = Abc_Clock(); Gia_Man_t * pNew; Vec_Int_t * vRootXorSet; // Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( p, &vXors, 0 ); -// Ree_ManRemoveTrivial( p, vAdds ); -// Ree_ManRemoveContained( p, vAdds ); //Ree_ManPrintAdders( vAdds, 1 ); // printf( "Detected %d full-adders and %d half-adders. Found %d XOR-cuts. ", Ree_ManCountFadds(vAdds), Vec_IntSize(vAdds)/6-Ree_ManCountFadds(vAdds), Vec_IntSize(vXors)/4 ); diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index d53b61c75..065f6300c 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -63,12 +63,17 @@ struct Acec_Box_t_ /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -/*=== acecPa.c ========================================================*/ +/*=== acecCo.c ========================================================*/ +extern Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vAddCos, Vec_Int_t ** pvIns, Vec_Int_t ** pvOuts ); +extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vRootBoxes ); +/*=== acecTree.c ========================================================*/ extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p ); /*=== acecUtil.c ========================================================*/ extern void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose ); extern Vec_Int_t * Gia_PolynCollectLastXor( Gia_Man_t * pGia, int fVerbose ); + + ABC_NAMESPACE_HEADER_END diff --git a/src/proof/acec/acecPa.c b/src/proof/acec/acecPa.c index b59cdbeff..6b382d91c 100644 --- a/src/proof/acec/acecPa.c +++ b/src/proof/acec/acecPa.c @@ -248,11 +248,6 @@ int Pas_ManComputeCuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vOrder, Ve ***********************************************************************/ void Pas_ManComputeCutsTest( Gia_Man_t * p ) { - extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); - extern Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vAddCos, Vec_Int_t ** pvIns, Vec_Int_t ** pvOuts ); - - extern int Ree_ManCountFadds( Vec_Int_t * vAdds ); - extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose ); abctime clk = Abc_Clock(); Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 ); Vec_Int_t * vIns, * vOuts; @@ -273,22 +268,6 @@ void Pas_ManComputeCutsTest( Gia_Man_t * p ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p ) -{ - return NULL; -} - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/acec/acecPool.c b/src/proof/acec/acecPool.c index 08ee37f26..0868545eb 100644 --- a/src/proof/acec/acecPool.c +++ b/src/proof/acec/acecPool.c @@ -303,17 +303,9 @@ void Acec_ManPrintRanks( Vec_Int_t * vPairs ) ***********************************************************************/ void Acec_ManProfile( Gia_Man_t * p, int fVerbose ) { - extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); - extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ); - extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds ); - extern int Ree_ManCountFadds( Vec_Int_t * vAdds ); - extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose ); - abctime clk = Abc_Clock(); Vec_Wec_t * vBoxes; int i; Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( p, &vXors, fVerbose ); - Ree_ManRemoveTrivial( p, vAdds ); - Ree_ManRemoveContained( p, vAdds ); //Ree_ManPrintAdders( vAdds, 1 ); printf( "Detected %d full-adders and %d half-adders. Found %d XOR-cuts. ", Ree_ManCountFadds(vAdds), Vec_IntSize(vAdds)/6-Ree_ManCountFadds(vAdds), Vec_IntSize(vXors)/4 ); @@ -396,13 +388,6 @@ Vec_Int_t * Acec_ManPoolTopMost( Gia_Man_t * p, Vec_Int_t * vAdds ) } void Acec_ManPool( Gia_Man_t * p ) { - extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); - extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vRootBoxes ); - - extern int Ree_ManCountFadds( Vec_Int_t * vAdds ); - extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose ); - extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ); - extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds ); Vec_Int_t * vTops, * vTree; Vec_Wec_t * vTrees; @@ -413,8 +398,6 @@ void Acec_ManPool( Gia_Man_t * p ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); clk = Abc_Clock(); - Ree_ManRemoveTrivial( p, vAdds ); - Ree_ManRemoveContained( p, vAdds ); nFadds = Ree_ManCountFadds( vAdds ); printf( "Detected %d FAs and %d HAs. ", nFadds, Vec_IntSize(vAdds)/6-nFadds ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); diff --git a/src/proof/acec/acecRe.c b/src/proof/acec/acecRe.c index 26faad006..60b894c8d 100644 --- a/src/proof/acec/acecRe.c +++ b/src/proof/acec/acecRe.c @@ -392,6 +392,8 @@ Vec_Int_t * Ree_ManDeriveAdds( Hash_IntMan_t * p, Vec_Int_t * vData, int fVerbos } Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ) { + extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ); + extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds ); Gia_Obj_t * pObj; int * pList0, * pList1, i, nCuts = 0; Hash_IntMan_t * pHash = Hash_IntManStart( 1000 ); @@ -430,6 +432,8 @@ Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose Vec_IntSize(vAdds)/6, Vec_IntSize(vData)/3, Hash_IntManEntryNum(pHash), 6.0*Hash_IntManEntryNum(pHash)/Vec_IntSize(vAdds) ); Vec_IntFree( vData ); Hash_IntManStop( pHash ); + Ree_ManRemoveTrivial( p, vAdds ); + Ree_ManRemoveContained( p, vAdds ); return vAdds; } diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c new file mode 100644 index 000000000..c2d89a1c7 --- /dev/null +++ b/src/proof/acec/acecTree.c @@ -0,0 +1,56 @@ +/**CFile**************************************************************** + + FileName [acecTree.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [CEC for arithmetic circuits.] + + Synopsis [Adder tree construction.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: acecTree.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "acecInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p ) +{ + return NULL; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/acec/module.make b/src/proof/acec/module.make index 4003695e5..4db695c51 100644 --- a/src/proof/acec/module.make +++ b/src/proof/acec/module.make @@ -11,4 +11,5 @@ SRC += src/proof/acec/acecCl.c \ src/proof/acec/acecOrder.c \ src/proof/acec/acecPolyn.c \ src/proof/acec/acecSt.c \ + src/proof/acec/acecTree.c \ src/proof/acec/acecUtil.c From 4bfb97d3e1b313f4b72ee0fa7adfa8949236db85 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 10 Jan 2017 19:19:02 +0700 Subject: [PATCH 052/185] Updates to arithmetic verification. --- src/proof/acec/acecCore.c | 10 +- src/proof/acec/acecInt.h | 2 + src/proof/acec/acecTree.c | 275 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 283 insertions(+), 4 deletions(-) diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index 09ccb5326..a8123a5ef 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -70,10 +70,12 @@ void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p ) ***********************************************************************/ void Acec_BoxFree( Acec_Box_t * pBox ) { - Vec_WecFree( pBox->vUnique ); - Vec_WecFree( pBox->vShared ); - Vec_WecFree( pBox->vLeafLits ); - Vec_WecFree( pBox->vRootLits ); + Vec_WecFreeP( &pBox->vLeafs ); + Vec_WecFreeP( &pBox->vRoots ); + Vec_WecFreeP( &pBox->vLeafLits ); + Vec_WecFreeP( &pBox->vRootLits ); + Vec_WecFreeP( &pBox->vUnique ); + Vec_WecFreeP( &pBox->vShared ); ABC_FREE( pBox ); } void Acec_BoxFreeP( Acec_Box_t ** ppBox ) diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index 065f6300c..08f163e0b 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -41,6 +41,8 @@ typedef struct Acec_Box_t_ Acec_Box_t; struct Acec_Box_t_ { Gia_Man_t * pGia; // AIG manager + Vec_Wec_t * vLeafs; // leaf literals by rank + Vec_Wec_t * vRoots; // root literals by rank Vec_Wec_t * vLeafLits; // leaf literals by rank Vec_Wec_t * vRootLits; // root literals by rank Vec_Wec_t * vShared; // shared leaves diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index c2d89a1c7..08122584d 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -31,6 +31,281 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [Find internal cut points with exactly one adder fanin/fanout.] + + Description [Returns a map of point into its input/output adder.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_TreeAddInOutPoint( Vec_Int_t * vMap, int iObj, int iAdd, int fOut ) +{ + int * pPlace = Vec_IntEntryP( vMap, Abc_Var2Lit(iObj, fOut) ); + if ( *pPlace == -1 ) + *pPlace = iAdd; + else if ( *pPlace >= 0 ) + *pPlace = -2; +} +Vec_Int_t * Acec_TreeFindPoints( Gia_Man_t * p, Vec_Int_t * vAdds ) +{ + Vec_Int_t * vMap = Vec_IntStartFull( 2*Gia_ManObjNum(p) ); + int i; + for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) + { + Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+0), i, 0 ); + Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+1), i, 0 ); + Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+2), i, 0 ); + Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+3), i, 1 ); + Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+4), i, 1 ); + } + return vMap; +} + +/**Function************************************************************* + + Synopsis [Find adder trees as groups of adders connected vis cut-points.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_TreeWhichPoint( Vec_Int_t * vAdds, int iAdd, int iObj ) +{ + int k; + for ( k = 0; k < 5; k++ ) + if ( Vec_IntEntry(vAdds, 6*iAdd+k) == iObj ) + return k; + assert( 0 ); + return -1; +} +void Acec_TreeFindTrees2_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iAdd, int Rank, Vec_Int_t * vTree, Vec_Bit_t * vFound ) +{ + extern void Acec_TreeFindTrees_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iObj, int Rank, Vec_Int_t * vTree, Vec_Bit_t * vFound ); + int k; + if ( Vec_BitEntry(vFound, iAdd) ) + return; + Vec_BitWriteEntry( vFound, iAdd, 1 ); + Vec_IntPush( vTree, iAdd ); + Vec_IntPush( vTree, Rank ); + //printf( "Assigning rank %d to (%d:%d).\n", Rank, Vec_IntEntry(vAdds, 6*iAdd+3), Vec_IntEntry(vAdds, 6*iAdd+4) ); + for ( k = 0; k < 5; k++ ) + Acec_TreeFindTrees_rec( vAdds, vMap, Vec_IntEntry(vAdds, 6*iAdd+k), k == 4 ? Rank + 1 : Rank, vTree, vFound ); +} +void Acec_TreeFindTrees_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iObj, int Rank, Vec_Int_t * vTree, Vec_Bit_t * vFound ) +{ + int In = Vec_IntEntry( vMap, Abc_Var2Lit(iObj, 1) ); + int Out = Vec_IntEntry( vMap, Abc_Var2Lit(iObj, 0) ); + if ( In < 0 || Out < 0 ) + return; + Acec_TreeFindTrees2_rec( vAdds, vMap, In, Acec_TreeWhichPoint(vAdds, In, iObj) == 4 ? Rank-1 : Rank, vTree, vFound ); + Acec_TreeFindTrees2_rec( vAdds, vMap, Out, Rank, vTree, vFound ); +} +Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds ) +{ + Vec_Wec_t * vTrees = Vec_WecAlloc( 10 ); + Vec_Int_t * vMap = Acec_TreeFindPoints( p, vAdds ); + Vec_Bit_t * vFound = Vec_BitStart( Vec_IntSize(vAdds)/6 ); + Vec_Int_t * vTree; + int i, k, In, Out, Box, Rank, MinRank; + // go through the cut-points + Vec_IntForEachEntryDouble( vMap, In, Out, i ) + { + if ( In < 0 || Out < 0 ) + continue; + assert( Vec_BitEntry(vFound, In) == Vec_BitEntry(vFound, Out) ); + if ( Vec_BitEntry(vFound, In) ) + continue; + vTree = Vec_WecPushLevel( vTrees ); + Acec_TreeFindTrees_rec( vAdds, vMap, i/2, 0, vTree, vFound ); + // normalize rank + MinRank = ABC_INFINITY; + Vec_IntForEachEntryDouble( vTree, Box, Rank, k ) + MinRank = Abc_MinInt( MinRank, Rank ); + Vec_IntForEachEntryDouble( vTree, Box, Rank, k ) + Vec_IntWriteEntry( vTree, k+1, Rank - MinRank ); + } + Vec_BitFree( vFound ); + Vec_IntFree( vMap ); + // sort by size + Vec_WecSort( vTrees, 1 ); + return vTrees; +} +void Acec_TreeFindTreesTest( Gia_Man_t * p ) +{ + Vec_Wec_t * vTrees; + + abctime clk = Abc_Clock(); + Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 ); + int nFadds = Ree_ManCountFadds( vAdds ); + printf( "Detected %d adders (%d FAs and %d HAs). ", Vec_IntSize(vAdds)/6, nFadds, Vec_IntSize(vAdds)/6-nFadds ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + + clk = Abc_Clock(); + vTrees = Acec_TreeFindTrees( p, vAdds ); + printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + Vec_WecPrint( vTrees, 0 ); + + Vec_WecFree( vTrees ); + Vec_IntFree( vAdds ); +} + + +/**Function************************************************************* + + Synopsis [Creates leaves and roots.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_PrintRootLits( Vec_Wec_t * vRoots ) +{ + Vec_Int_t * vLevel; + int i, k, iObj; + Vec_WecForEachLevel( vRoots, vLevel, i ) + { + printf( "Rank %d : ", i ); + Vec_IntForEachEntry( vLevel, iObj, k ) + { + int fFadd = Abc_LitIsCompl(iObj); + int fCout = Abc_LitIsCompl(Abc_Lit2Var(iObj)); + int Node = Abc_Lit2Var(Abc_Lit2Var(iObj)); + printf( "%d%s%s ", Node, fCout ? "*" : "", (fCout && fFadd) ? "*" : "" ); + } + printf( "\n" ); + } +} +int Acec_CreateBoxMaxRank( Vec_Int_t * vTree ) +{ + int k, Box, Rank, MaxRank = 0; + Vec_IntForEachEntryDouble( vTree, Box, Rank, k ) + MaxRank = Abc_MaxInt( MaxRank, Rank ); + return MaxRank; +} +void Acec_BoxInsOuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots ) +{ + Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; + int i, k, Box, Rank; + Vec_BitWriteEntry( vIsLeaf, 0, 1 ); + Vec_BitWriteEntry( vIsRoot, 0, 1 ); + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 ); + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 ); + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 ); + } + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + for ( k = 0; k < 3; k++ ) + { + if ( Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) ) + continue; + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k), 1 ); + Vec_WecPush( vLeaves, Rank, Vec_IntEntry(vAdds, 6*Box+k) ); + } + for ( k = 3; k < 5; k++ ) + { + if ( Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) ) + continue; + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k), 1 ); + Vec_WecPush( vRoots, k == 4 ? Rank + 1 : Rank, Abc_Var2Lit(Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), k==4), Vec_IntEntry(vAdds, 6*Box+2)!=0) ); + } + } + Vec_BitFree( vIsLeaf ); + Vec_BitFree( vIsRoot ); + // sort each level + Vec_WecForEachLevel( vLeaves, vLevel, i ) + Vec_IntSort( vLevel, 0 ); + Vec_WecForEachLevel( vRoots, vLevel, i ) + Vec_IntSort( vLevel, 0 ); +} + +/**Function************************************************************* + + Synopsis [Creates polarity.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_BoxPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits ) +{ +} + +/**Function************************************************************* + + Synopsis [Derives one adder tree.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) +{ + Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 ); + pBox->pGia = p; + + pBox->vLeafs = Vec_WecStart( Acec_CreateBoxMaxRank(vTree) + 1 ); + pBox->vRoots = Vec_WecStart( Vec_WecSize(pBox->vLeafs) + 1 ); + + Acec_BoxInsOuts( p, vAdds, vTree, pBox->vLeafs, pBox->vRoots ); + + pBox->vLeafLits = Vec_WecStart( Vec_WecSize(pBox->vLeafs) ); + pBox->vRootLits = Vec_WecStart( Vec_WecSize(pBox->vRoots) ); + + Acec_BoxPhases( p, vAdds, vTree, pBox->vLeafs, pBox->vRoots, pBox->vLeafLits, pBox->vRootLits ); + + return pBox; +} +void Acec_CreateBoxTest( Gia_Man_t * p ) +{ + extern void Acec_BoxFree( Acec_Box_t * pBox ); + Acec_Box_t * pBox; + Vec_Wec_t * vTrees; + + abctime clk = Abc_Clock(); + Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 ); + int nFadds = Ree_ManCountFadds( vAdds ); + printf( "Detected %d adders (%d FAs and %d HAs). ", Vec_IntSize(vAdds)/6, nFadds, Vec_IntSize(vAdds)/6-nFadds ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + + clk = Abc_Clock(); + vTrees = Acec_TreeFindTrees( p, vAdds ); + printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + Vec_WecPrint( vTrees, 0 ); + + pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, 0) ); + Vec_WecPrint( pBox->vLeafs, 0 ); + Vec_WecPrint( pBox->vRoots, 0 ); + Acec_PrintRootLits( pBox->vRoots ); + Acec_BoxFree( pBox ); + + Vec_WecFree( vTrees ); + Vec_IntFree( vAdds ); +} + /**Function************************************************************* Synopsis [] From 89d08cfd06ecb1653ef0613049447c91bc114f46 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 11 Jan 2017 13:36:54 +0700 Subject: [PATCH 053/185] Updates to arithmetic verification. --- src/proof/acec/acecCore.c | 2 + src/proof/acec/acecInt.h | 2 + src/proof/acec/acecRe.c | 11 +- src/proof/acec/acecTree.c | 273 +++++++++++++++++++++++++++++++++----- 4 files changed, 257 insertions(+), 31 deletions(-) diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index a8123a5ef..444e08949 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -70,12 +70,14 @@ void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p ) ***********************************************************************/ void Acec_BoxFree( Acec_Box_t * pBox ) { + Vec_WecFreeP( &pBox->vAdds ); Vec_WecFreeP( &pBox->vLeafs ); Vec_WecFreeP( &pBox->vRoots ); Vec_WecFreeP( &pBox->vLeafLits ); Vec_WecFreeP( &pBox->vRootLits ); Vec_WecFreeP( &pBox->vUnique ); Vec_WecFreeP( &pBox->vShared ); + Vec_BitFreeP( &pBox->vInvHadds ); ABC_FREE( pBox ); } void Acec_BoxFreeP( Acec_Box_t ** ppBox ) diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index 08f163e0b..3f10c6aa4 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -41,12 +41,14 @@ typedef struct Acec_Box_t_ Acec_Box_t; struct Acec_Box_t_ { Gia_Man_t * pGia; // AIG manager + Vec_Wec_t * vAdds; // adders by rank Vec_Wec_t * vLeafs; // leaf literals by rank Vec_Wec_t * vRoots; // root literals by rank Vec_Wec_t * vLeafLits; // leaf literals by rank Vec_Wec_t * vRootLits; // root literals by rank Vec_Wec_t * vShared; // shared leaves Vec_Wec_t * vUnique; // unique leaves + Vec_Bit_t * vInvHadds; // complemented half adders }; //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/acec/acecRe.c b/src/proof/acec/acecRe.c index 60b894c8d..161b6fbb5 100644 --- a/src/proof/acec/acecRe.c +++ b/src/proof/acec/acecRe.c @@ -370,7 +370,7 @@ Vec_Int_t * Ree_ManDeriveAdds( Hash_IntMan_t * p, Vec_Int_t * vData, int fVerbos Vec_IntForEachEntryDouble( vXorOne, iObj, Truth, j ) Vec_IntForEachEntryDouble( vMajOne, iObj2, Truth2, k ) { - int SignAnd[8] = {0x88, 0x44, 0x22, 0x11, 0xEE, 0xDD, 0xBB, 0x77}; + int SignAnd[8] = {0x88, 0x44, 0x22, 0x11, 0x77, 0xBB, 0xDD, 0xEE}; int SignMaj[8] = {0xE8, 0xD4, 0xB2, 0x71, 0x8E, 0x4D, 0x2B, 0x17}; int n, SignXor = (Truth == 0x99 || Truth == 0x69) << 3; for ( n = 0; n < 8; n++ ) @@ -390,6 +390,14 @@ Vec_Int_t * Ree_ManDeriveAdds( Hash_IntMan_t * p, Vec_Int_t * vData, int fVerbos Vec_WecFree( vMajMap ); return vAdds; } +int Ree_ManCompare( int * pCut0, int * pCut1 ) +{ + if ( pCut0[3] < pCut1[3] ) return -1; + if ( pCut0[3] > pCut1[3] ) return 1; + if ( pCut0[4] < pCut1[4] ) return -1; + if ( pCut0[4] > pCut1[4] ) return 1; + return 0; +} Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ) { extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ); @@ -427,6 +435,7 @@ Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose Vec_IntFree( vTemp ); Vec_IntFree( vCuts ); vAdds = Ree_ManDeriveAdds( pHash, vData, fVerbose ); + qsort( Vec_IntArray(vAdds), Vec_IntSize(vAdds)/6, 24, (int (*)(const void *, const void *))Ree_ManCompare ); if ( fVerbose ) printf( "Adders = %d. Total cuts = %d. Hashed cuts = %d. Hashed/Adders = %.2f.\n", Vec_IntSize(vAdds)/6, Vec_IntSize(vData)/3, Hash_IntManEntryNum(pHash), 6.0*Hash_IntManEntryNum(pHash)/Vec_IntSize(vAdds) ); diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index 08122584d..ba08deb5f 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -169,23 +169,6 @@ void Acec_TreeFindTreesTest( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -void Acec_PrintRootLits( Vec_Wec_t * vRoots ) -{ - Vec_Int_t * vLevel; - int i, k, iObj; - Vec_WecForEachLevel( vRoots, vLevel, i ) - { - printf( "Rank %d : ", i ); - Vec_IntForEachEntry( vLevel, iObj, k ) - { - int fFadd = Abc_LitIsCompl(iObj); - int fCout = Abc_LitIsCompl(Abc_Lit2Var(iObj)); - int Node = Abc_Lit2Var(Abc_Lit2Var(iObj)); - printf( "%d%s%s ", Node, fCout ? "*" : "", (fCout && fFadd) ? "*" : "" ); - } - printf( "\n" ); - } -} int Acec_CreateBoxMaxRank( Vec_Int_t * vTree ) { int k, Box, Rank, MaxRank = 0; @@ -193,7 +176,7 @@ int Acec_CreateBoxMaxRank( Vec_Int_t * vTree ) MaxRank = Abc_MaxInt( MaxRank, Rank ); return MaxRank; } -void Acec_BoxInsOuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots ) +void Acec_TreeInsOuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_Wec_t * vBoxes, Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots ) { Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); @@ -211,6 +194,7 @@ void Acec_BoxInsOuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_W } Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) { + Vec_WecPush( vBoxes, Rank, Box ); for ( k = 0; k < 3; k++ ) { if ( Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) ) @@ -229,12 +213,91 @@ void Acec_BoxInsOuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_W Vec_BitFree( vIsLeaf ); Vec_BitFree( vIsRoot ); // sort each level + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntSort( vLevel, 0 ); Vec_WecForEachLevel( vLeaves, vLevel, i ) Vec_IntSort( vLevel, 0 ); Vec_WecForEachLevel( vRoots, vLevel, i ) Vec_IntSort( vLevel, 0 ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_TreeVerifyPhaseOne_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + int Truth0, Truth1; + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return pObj->Value; + Gia_ObjSetTravIdCurrent(p, pObj); + assert( Gia_ObjIsAnd(pObj) ); + assert( !Gia_ObjIsXor(pObj) ); + Truth0 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin0(pObj) ); + Truth1 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin1(pObj) ); + Truth0 = Gia_ObjFaninC0(pObj) ? 0xFF & ~Truth0 : Truth0; + Truth1 = Gia_ObjFaninC1(pObj) ? 0xFF & ~Truth1 : Truth1; + return (pObj->Value = Truth0 & Truth1); +} +void Acec_TreeVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox, Vec_Bit_t * vPhase ) +{ + Gia_Obj_t * pObj; + unsigned TruthXor, TruthMaj, Truths[3] = { 0xAA, 0xCC, 0xF0 }; + int k, iObj, fFadd = Vec_IntEntry(vAdds, 6*iBox+2) > 0; + + //if ( !fFadd ) + // return; + + Gia_ManIncrementTravId( p ); + for ( k = 0; k < 3; k++ ) + { + iObj = Vec_IntEntry( vAdds, 6*iBox+k ); + if ( iObj == 0 ) + continue; + pObj = Gia_ManObj( p, iObj ); + pObj->Value = Vec_BitEntry(vPhase, iObj) ? 0xFF & ~Truths[k] : Truths[k]; + Gia_ObjSetTravIdCurrent( p, pObj ); + } + + iObj = Vec_IntEntry( vAdds, 6*iBox+3 ); + TruthXor = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) ); + TruthXor = Vec_BitEntry(vPhase, iObj) ? 0xFF & ~TruthXor : TruthXor; + + iObj = Vec_IntEntry( vAdds, 6*iBox+4 ); + TruthMaj = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) ); + TruthMaj = Vec_BitEntry(vPhase, iObj) ? 0xFF & ~TruthMaj : TruthMaj; + + if ( fFadd ) // FADD + { + if ( TruthXor != 0x96 ) + printf( "Fadd %d sum is wrong.\n", iBox ); + if ( TruthMaj != 0xE8 ) + printf( "Fadd %d carry is wrong.\n", iBox ); + } + else + { + if ( TruthXor != 0x66 ) + printf( "Hadd %d sum is wrong.\n", iBox ); + if ( TruthMaj != 0x88 ) + printf( "Hadd %d carry is wrong.\n", iBox ); + } +} +void Acec_TreeVerifyPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes, Vec_Bit_t * vPhase ) +{ + Vec_Int_t * vLevel; + int i, k, Box; + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + Acec_TreeVerifyPhaseOne( p, vAdds, Box, vPhase ); +} + /**Function************************************************************* Synopsis [Creates polarity.] @@ -246,8 +309,96 @@ void Acec_BoxInsOuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_W SeeAlso [] ***********************************************************************/ -void Acec_BoxPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits ) +Vec_Int_t * Acec_TreeCarryMap( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ) { + Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; + int i, k, Box; + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + Vec_IntWriteEntry( vMap, Vec_IntEntry(vAdds, 6*Box+4), Box ); + return vMap; +} +void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, int Node, int fPhase, + Vec_Bit_t * vPhase, Vec_Bit_t * vInvHadds, Vec_Bit_t * vVisit ) +{ + int k, iBox, iXor, Sign, fXorPhase, fPhaseThis; + assert( Node != 0 ); + if ( Vec_BitEntry(vVisit, Node) ) + { + assert( Vec_BitEntry(vPhase, Node) == fPhase ); + return; + } + Vec_BitWriteEntry( vVisit, Node, 1 ); + if ( fPhase ) + Vec_BitWriteEntry( vPhase, Node, fPhase ); + iBox = Vec_IntEntry( vMap, Node ); + if ( iBox == -1 ) + return; + assert( Node == Vec_IntEntry( vAdds, 6*iBox+4 ) ); + iXor = Vec_IntEntry( vAdds, 6*iBox+3 ); + Sign = Vec_IntEntry( vAdds, 6*iBox+5 ); + fXorPhase = ((Sign >> 3) & 1); + if ( Vec_IntEntry(vAdds, 6*iBox+2) == 0 ) + { + fPhase ^= ((Sign >> 2) & 1); + // remember complemented HADD + if ( fPhase ) + Vec_BitWriteEntry( vInvHadds, iBox, 1 ); + } + for ( k = 0; k < 3; k++ ) + { + int iObj = Vec_IntEntry( vAdds, 6*iBox+k ); + if ( iObj == 0 ) + continue; + fPhaseThis = ((Sign >> k) & 1) ^ fPhase; + fXorPhase ^= fPhaseThis; + Acec_TreePhases_rec( p, vAdds, vMap, iObj, fPhaseThis, vPhase, vInvHadds, vVisit ); + } + if ( Vec_BitEntry(vVisit, iXor) ) + assert( Vec_BitEntry(vPhase, iXor) == fXorPhase ); + if ( fXorPhase ) + Vec_BitWriteEntry( vPhase, iXor, fXorPhase ); +} +void Acec_TreePhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes, + Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots, + Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits, Vec_Bit_t * vInvHadds ) +{ + Vec_Int_t * vMap = Acec_TreeCarryMap( p, vAdds, vBoxes ); + Vec_Bit_t * vPhase = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Bit_t * vVisit = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; + int i, k, iObj; + Vec_WecForEachLevelReverse( vRoots, vLevel, i ) + { + Vec_IntForEachEntry( vLevel, iObj, k ) + { + int fFadd = Abc_LitIsCompl(iObj); + int fCout = Abc_LitIsCompl(Abc_Lit2Var(iObj)); + int Node = Abc_Lit2Var(Abc_Lit2Var(iObj)); + if ( !fCout ) + continue; + Acec_TreePhases_rec( p, vAdds, vMap, Node, fFadd, vPhase, vInvHadds, vVisit ); + } + } + Vec_IntFree( vMap ); + Vec_BitFree( vVisit ); + Acec_TreeVerifyPhases( p, vAdds, vBoxes, vPhase ); + // create leaves + Vec_WecForEachLevel( vLeaves, vLevel, i ) + Vec_IntForEachEntry( vLevel, iObj, k ) + Vec_WecPush( vLeafLits, i, Abc_Var2Lit(iObj, Vec_BitEntry(vPhase, iObj)) ); + // add constants + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntForEachEntry( vLevel, iObj, k ) + if ( Vec_BitEntry(vInvHadds, iObj) ) + Vec_WecPush( vLeafLits, i, 1 ); + // create roots + Vec_WecForEachLevel( vRoots, vLevel, i ) + Vec_IntForEachEntry( vLevel, iObj, k ) + iObj >>= 2, Vec_WecPush( vRootLits, i, Abc_Var2Lit(iObj, Vec_BitEntry(vPhase, iObj)) ); + // cleanup + Vec_BitFree( vPhase ); } /**Function************************************************************* @@ -261,20 +412,77 @@ void Acec_BoxPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_We SeeAlso [] ***********************************************************************/ +void Acec_PrintRootLits( Vec_Wec_t * vRoots ) +{ + Vec_Int_t * vLevel; + int i, k, iObj; + Vec_WecForEachLevel( vRoots, vLevel, i ) + { + printf( "Rank %d : ", i ); + Vec_IntForEachEntry( vLevel, iObj, k ) + { + int fFadd = Abc_LitIsCompl(iObj); + int fCout = Abc_LitIsCompl(Abc_Lit2Var(iObj)); + int Node = Abc_Lit2Var(Abc_Lit2Var(iObj)); + printf( "%d%s%s ", Node, fCout ? "*" : "", (fCout && fFadd) ? "*" : "" ); + } + printf( "\n" ); + } +} +void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ) +{ + Vec_Int_t * vLevel; + int i, k, iBox; + Vec_WecForEachLevel( vBoxes, vLevel, i ) + { + printf( " %4d : {", i ); + Vec_IntForEachEntry( vLevel, iBox, k ) + printf( " (%d,%d)", Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) ); + printf( " }\n" ); + } +} +void Vec_WecPrintLits( Vec_Wec_t * p ) +{ + Vec_Int_t * vVec; + int i, k, Entry; + Vec_WecForEachLevel( p, vVec, i ) + { + printf( " %4d : {", i ); + Vec_IntForEachEntry( vVec, Entry, k ) + printf( " %c%d", Abc_LitIsCompl(Entry) ? '-' : '+', Abc_Lit2Var(Entry) ); + printf( " }\n" ); + } +} +void Acec_PrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds ) +{ + printf( "Adders:\n" ); + Acec_PrintAdders( pBox->vAdds, vAdds ); + printf( "Inputs:\n" ); + Vec_WecPrintLits( pBox->vLeafLits ); + printf( "Outputs:\n" ); + Vec_WecPrintLits( pBox->vRootLits ); + //printf( "Raw outputs:\n" ); + //Acec_PrintRootLits( pBox->vRoots ); +} + Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) { + int MaxRank = Acec_CreateBoxMaxRank(vTree); + Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 ); pBox->pGia = p; - pBox->vLeafs = Vec_WecStart( Acec_CreateBoxMaxRank(vTree) + 1 ); - pBox->vRoots = Vec_WecStart( Vec_WecSize(pBox->vLeafs) + 1 ); + pBox->vAdds = Vec_WecStart( MaxRank + 1 ); + pBox->vLeafs = Vec_WecStart( MaxRank + 1 ); + pBox->vRoots = Vec_WecStart( MaxRank + 2 ); - Acec_BoxInsOuts( p, vAdds, vTree, pBox->vLeafs, pBox->vRoots ); + Acec_TreeInsOuts( p, vAdds, vTree, pBox->vAdds, pBox->vLeafs, pBox->vRoots ); pBox->vLeafLits = Vec_WecStart( Vec_WecSize(pBox->vLeafs) ); pBox->vRootLits = Vec_WecStart( Vec_WecSize(pBox->vRoots) ); + pBox->vInvHadds = Vec_BitStart( Vec_IntSize(vAdds)/6 ); - Acec_BoxPhases( p, vAdds, vTree, pBox->vLeafs, pBox->vRoots, pBox->vLeafLits, pBox->vRootLits ); + Acec_TreePhases( p, vAdds, pBox->vAdds, pBox->vLeafs, pBox->vRoots, pBox->vLeafLits, pBox->vRootLits, pBox->vInvHadds ); return pBox; } @@ -283,10 +491,11 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) extern void Acec_BoxFree( Acec_Box_t * pBox ); Acec_Box_t * pBox; Vec_Wec_t * vTrees; + Vec_Int_t * vTree; abctime clk = Abc_Clock(); Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 ); - int nFadds = Ree_ManCountFadds( vAdds ); + int i, nFadds = Ree_ManCountFadds( vAdds ); printf( "Detected %d adders (%d FAs and %d HAs). ", Vec_IntSize(vAdds)/6, nFadds, Vec_IntSize(vAdds)/6-nFadds ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); @@ -294,13 +503,17 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) vTrees = Acec_TreeFindTrees( p, vAdds ); printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); - Vec_WecPrint( vTrees, 0 ); + //Vec_WecPrint( vTrees, 0 ); - pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, 0) ); - Vec_WecPrint( pBox->vLeafs, 0 ); - Vec_WecPrint( pBox->vRoots, 0 ); - Acec_PrintRootLits( pBox->vRoots ); - Acec_BoxFree( pBox ); + Vec_WecForEachLevel( vTrees, vTree, i ) + { + pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, i) ); + printf( "Processing tree %d: Ranks = %d. Adders = %d. Leaves = %d. Roots = %d.\n", + i, Vec_WecSize(pBox->vAdds), Vec_WecSizeSize(pBox->vAdds), + Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); + //Acec_PrintBox( pBox ); + Acec_BoxFree( pBox ); + } Vec_WecFree( vTrees ); Vec_IntFree( vAdds ); From 8b8b410af2d9cc75de758516f8c7dcf7a6098edc Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 11 Jan 2017 13:44:27 +0700 Subject: [PATCH 054/185] Changing file naming in 'show' and '&show'. --- src/aig/aig/aigShow.c | 5 ++--- src/aig/gia/giaShow.c | 8 ++------ 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/aig/aig/aigShow.c b/src/aig/aig/aigShow.c index eac2a510a..d983602a6 100644 --- a/src/aig/aig/aigShow.c +++ b/src/aig/aig/aigShow.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "aig.h" +#include "misc/extra/extra.h" ABC_NAMESPACE_IMPL_START @@ -340,12 +341,10 @@ void Aig_WriteDotAig( Aig_Man_t * pMan, char * pFileName, int fHaig, Vec_Ptr_t * void Aig_ManShow( Aig_Man_t * pMan, int fHaig, Vec_Ptr_t * vBold ) { extern void Abc_ShowFile( char * FileNameDot ); - static int Counter = 0; char FileNameDot[200]; FILE * pFile; // create the file name -// Aig_ShowGetFileName( pMan->pName, FileNameDot ); - sprintf( FileNameDot, "temp%02d.dot", Counter++ ); + sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(pMan->pName, ".dot") ); // check that the file can be opened if ( (pFile = fopen( FileNameDot, "w" )) == NULL ) { diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index 986d5624d..5589d3841 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -21,6 +21,7 @@ #include "gia.h" #include "proof/cec/cec.h" #include "proof/acec/acec.h" +#include "misc/extra/extra.h" ABC_NAMESPACE_IMPL_START @@ -815,15 +816,10 @@ void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds ) { extern void Abc_ShowFile( char * FileNameDot ); - static int Counter = 0; char FileNameDot[200]; FILE * pFile; - Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( pMan, &vXors, 0 ); - - // create the file name -// Gia_ShowGetFileName( pMan->pName, FileNameDot ); - sprintf( FileNameDot, "temp%02d.dot", Counter++ ); + sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(pMan->pName, ".dot") ); // check that the file can be opened if ( (pFile = fopen( FileNameDot, "w" )) == NULL ) { From 55b6b4bdab816b34bfa81a58eb4e9fefe0c1cba4 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 11 Jan 2017 16:08:23 +0700 Subject: [PATCH 055/185] Updates to arithmetic verification. --- abclib.dsp | 4 + src/base/abci/abc.c | 48 +++++++++ src/base/wlc/wlcBlast.c | 2 +- src/proof/acec/acec.h | 2 + src/proof/acec/acecCore.c | 199 ++-------------------------------- src/proof/acec/acecInt.h | 5 +- src/proof/acec/acecNorm.c | 215 +++++++++++++++++++++++++++++++++++++ src/proof/acec/acecTree.c | 101 ++++++++++++----- src/proof/acec/module.make | 1 + 9 files changed, 356 insertions(+), 221 deletions(-) create mode 100644 src/proof/acec/acecNorm.c diff --git a/abclib.dsp b/abclib.dsp index a84bef073..e2ff005ed 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -5507,6 +5507,10 @@ SOURCE=.\src\proof\acec\acecInt.h # End Source File # Begin Source File +SOURCE=.\src\proof\acec\acecNorm.c +# End Source File +# Begin Source File + SOURCE=.\src\proof\acec\acecOrder.c # End Source File # Begin Source File diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index dd157afda..20d44227e 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -481,6 +481,7 @@ static int Abc_CommandAbc9Fadds ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9ATree ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Polyn ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Acec ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Anorm ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Esop ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Exorcism ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Mfs ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -1124,6 +1125,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&atree", Abc_CommandAbc9ATree, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&polyn", Abc_CommandAbc9Polyn, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&acec", Abc_CommandAbc9Acec, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&anorm", Abc_CommandAbc9Anorm, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&esop", Abc_CommandAbc9Esop, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&exorcism", Abc_CommandAbc9Exorcism, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&mfs", Abc_CommandAbc9Mfs, 0 ); @@ -40728,6 +40730,52 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9Anorm( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Gia_Man_t * pTemp; + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9Anorm(): There is no AIG.\n" ); + return 0; + } + pTemp = Acec_Normalize( pAbc->pGia, fVerbose ); + Abc_FrameUpdateGia( pAbc, pTemp ); + return 0; + +usage: + Abc_Print( -2, "usage: &anorm [-vh]\n" ); + Abc_Print( -2, "\t normalize adder trees in the current AIG\n" ); + Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* Synopsis [] diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index ec3b040d5..5e6a1a471 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -1509,7 +1509,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in assert( Vec_PtrSize(pNew->vNamesOut) == Gia_ManCoNum(pNew) ); } - pNew->pSpec = Abc_UtilStrsav( p->pSpec ? p->pSpec : p->pName ); + //pNew->pSpec = Abc_UtilStrsav( p->pSpec ? p->pSpec : p->pName ); // dump the miter parts if ( 0 ) { diff --git a/src/proof/acec/acec.h b/src/proof/acec/acec.h index 918119f84..7ad5baf95 100644 --- a/src/proof/acec/acec.h +++ b/src/proof/acec/acec.h @@ -80,6 +80,8 @@ extern void Gia_PolynBuild( Gia_Man_t * pGia, Vec_Int_t * vOrder, int f extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); extern int Ree_ManCountFadds( Vec_Int_t * vAdds ); extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose ); +/*=== acecTree.c ========================================================*/ +extern Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fVerbose ); ABC_NAMESPACE_HEADER_END diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index 444e08949..3e31fa360 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -57,98 +57,6 @@ void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p ) p->iOutFail = -1; // the number of failed output } -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Acec_BoxFree( Acec_Box_t * pBox ) -{ - Vec_WecFreeP( &pBox->vAdds ); - Vec_WecFreeP( &pBox->vLeafs ); - Vec_WecFreeP( &pBox->vRoots ); - Vec_WecFreeP( &pBox->vLeafLits ); - Vec_WecFreeP( &pBox->vRootLits ); - Vec_WecFreeP( &pBox->vUnique ); - Vec_WecFreeP( &pBox->vShared ); - Vec_BitFreeP( &pBox->vInvHadds ); - ABC_FREE( pBox ); -} -void Acec_BoxFreeP( Acec_Box_t ** ppBox ) -{ - if ( *ppBox ) - Acec_BoxFree( *ppBox ); - *ppBox = NULL; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Acec_InsertHadd( Gia_Man_t * pNew, int In[2], int Out[2] ) -{ - int And, Or; - Out[1] = Gia_ManAppendAnd2( pNew, In[0], In[1] ); - And = Gia_ManAppendAnd2( pNew, Abc_LitNot(In[0]), Abc_LitNot(In[1]) ); - Or = Gia_ManAppendOr2( pNew, Out[1], And ); - Out[0] = Abc_LitNot( Or ); -} -void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] ) -{ - int In2[2], Out1[2], Out2[2]; - Acec_InsertHadd( pNew, In, Out1 ); - In2[0] = Out1[0]; - In2[1] = In[2]; - Acec_InsertHadd( pNew, In2, Out2 ); - Out[0] = Out2[0]; - Out[1] = Gia_ManAppendOr2( pNew, Out1[1], Out2[1] ); -} -Vec_Int_t * Acec_InsertTree( Gia_Man_t * pNew, Vec_Wec_t * vLeafMap ) -{ - Vec_Int_t * vRootRanks = Vec_IntAlloc( Vec_WecSize(vLeafMap) + 5 ); - Vec_Int_t * vLevel; - int i, In[3], Out[2]; - Vec_WecForEachLevel( vLeafMap, vLevel, i ) - { - if ( Vec_IntSize(vLevel) == 0 ) - { - Vec_IntPush( vRootRanks, 0 ); - continue; - } - while ( Vec_IntSize(vLevel) > 1 ) - { - if ( Vec_IntSize(vLevel) == 2 ) - Vec_IntPush( vLevel, 0 ); - In[0] = Vec_IntPop( vLevel ); - In[1] = Vec_IntPop( vLevel ); - In[2] = Vec_IntPop( vLevel ); - Acec_InsertFadd( pNew, In, Out ); - Vec_IntPush( vLevel, Out[0] ); - if ( i-1 < Vec_WecSize(vLeafMap) ) - vLevel = Vec_WecEntry(vLeafMap, i+1); - else - vLevel = Vec_WecPushLevel(vLeafMap); - Vec_IntPush( vLevel, Out[1] ); - } - assert( Vec_IntSize(vLevel) == 1 ); - Vec_IntPush( vRootRanks, Vec_IntEntry(vLevel, 0) ); - } - return vRootRanks; -} - /**Function************************************************************* Synopsis [] @@ -251,12 +159,14 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) int * pEnd1 = Vec_IntLimit(vLevel1); while ( pBeg0 < pEnd0 && pBeg1 < pEnd1 ) { - if ( *pBeg0 == *pBeg1 ) + int Entry0 = Abc_Lit2LitV( Vec_IntArray(vMap0), *pBeg0 ); + int Entry1 = Abc_Lit2LitV( Vec_IntArray(vMap1), *pBeg1 ); + if ( Entry0 == Entry1 ) { Vec_IntPush( vShared0, *pBeg0++ ); Vec_IntPush( vShared1, *pBeg1++ ); } - else if ( *pBeg0 > *pBeg1 ) + else if ( Entry0 > Entry1 ) Vec_IntPush( vUnique0, *pBeg0++ ); else Vec_IntPush( vUnique1, *pBeg1++ ); @@ -269,105 +179,14 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) assert( Vec_IntSize(vShared0) + Vec_IntSize(vUnique0) == Vec_IntSize(vLevel0) ); assert( Vec_IntSize(vShared1) + Vec_IntSize(vUnique1) == Vec_IntSize(vLevel1) ); } + Vec_IntFree( vMap0 ); + Vec_IntFree( vMap1 ); nTotal = Vec_WecSizeSize(pBox0->vShared); printf( "Box0: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox0->vLeafLits) ); printf( "Box1: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox1->vLeafLits) ); return nTotal; } -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Acec_InsertBox_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) -{ - if ( ~pObj->Value ) - return pObj->Value; - assert( Gia_ObjIsAnd(pObj) ); - Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) ); - Acec_InsertBox_rec( pNew, p, Gia_ObjFanin1(pObj) ); - return (pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) )); -} -Vec_Int_t * Acec_BuildTree( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t * vLeafLits ) -{ - Vec_Wec_t * vLeafMap = Vec_WecStart( Vec_WecSize(vLeafLits) ); - Vec_Int_t * vLevel, * vRootRanks; - int i, k, iLit, iLitNew; - Vec_WecForEachLevel( vLeafLits, vLevel, i ) - Vec_IntForEachEntry( vLevel, iLit, k ) - { - Gia_Obj_t * pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) ); - iLitNew = Acec_InsertBox_rec( pNew, p, pObj ); - iLitNew = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) ); - Vec_WecPush( vLeafMap, i, iLitNew ); - } - // construct map of root literals - vRootRanks = Acec_InsertTree( pNew, vLeafMap ); - Vec_WecFree( vLeafMap ); - return vRootRanks; -} - -Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ) -{ - Gia_Man_t * p = pBox->pGia; - Gia_Man_t * pNew; - Gia_Obj_t * pObj; - Vec_Int_t * vRootRanks, * vLevel; - int i, k, iLit, iLitNew; - pNew = Gia_ManStart( Gia_ManObjNum(p) ); - pNew->pName = Abc_UtilStrsav( p->pName ); - pNew->pSpec = Abc_UtilStrsav( p->pSpec ); - Gia_ManConst0(p)->Value = 0; - Gia_ManForEachCi( p, pObj, i ) - pObj->Value = Gia_ManAppendCi( pNew ); - // implement tree - if ( fAll ) - vRootRanks = Acec_BuildTree( pNew, p, pBox->vLeafLits ); - else - { - Vec_Wec_t * vLeafLits; - assert( pBox->vShared != NULL ); - assert( pBox->vUnique != NULL ); - vRootRanks = Acec_BuildTree( p, p, pBox->vShared ); - // add these roots to the unique ones - vLeafLits = Vec_WecDup( pBox->vUnique ); - Vec_IntForEachEntry( vRootRanks, iLit, i ) - { - if ( i < Vec_WecSize(vLeafLits) ) - vLevel = Vec_WecEntry(vLeafLits, i); - else - vLevel = Vec_WecPushLevel(vLeafLits); - Vec_IntPush( vLevel, iLit ); - } - Vec_IntFree( vRootRanks ); - vRootRanks = Acec_BuildTree( pNew, p, vLeafLits ); - Vec_WecFree( vLeafLits ); - } - // update polarity of literals - Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) - Vec_IntForEachEntry( vLevel, iLit, k ) - { - pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) ); - iLitNew = k ? 0 : Vec_IntEntry( vRootRanks, k ); - pObj->Value = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) ); - } - Vec_IntFree( vRootRanks ); - // construct the outputs - Gia_ManForEachCo( p, pObj, i ) - Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) ); - Gia_ManForEachCo( p, pObj, i ) - pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); - Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); - return pNew; -} - /**Function************************************************************* Synopsis [] @@ -385,8 +204,8 @@ int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) Gia_Man_t * pMiter; Gia_Man_t * pGia0n = pGia0, * pGia1n = pGia1; Cec_ParCec_t ParsCec, * pCecPars = &ParsCec; - Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0 ); - Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1 ); + Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0, pPars->fVerbose ); + Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1, pPars->fVerbose ); if ( pBox0 == NULL || pBox1 == NULL ) // cannot match printf( "Cannot find arithmetic boxes in both LHS and RHS. Trying regular CEC.\n" ); else if ( !Acec_MatchBoxes( pBox0, pBox1 ) ) // cannot find matching @@ -403,7 +222,7 @@ int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) pMiter = Gia_ManMiter( pGia0n, pGia1n, 0, 1, 0, 0, pPars->fVerbose ); if ( pMiter ) { - int fDumpMiter = 1; + int fDumpMiter = 0; if ( fDumpMiter ) { Abc_Print( 0, "The verification miter is written into file \"%s\".\n", "acec_miter.aig" ); diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index 3f10c6aa4..c0d899e17 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -70,8 +70,11 @@ struct Acec_Box_t_ /*=== acecCo.c ========================================================*/ extern Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vAddCos, Vec_Int_t ** pvIns, Vec_Int_t ** pvOuts ); extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vRootBoxes ); +/*=== acecNorm.c ========================================================*/ +extern Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ); /*=== acecTree.c ========================================================*/ -extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p ); +extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, int fVerbose ); +extern void Acec_BoxFreeP( Acec_Box_t ** ppBox ); /*=== acecUtil.c ========================================================*/ extern void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose ); extern Vec_Int_t * Gia_PolynCollectLastXor( Gia_Man_t * pGia, int fVerbose ); diff --git a/src/proof/acec/acecNorm.c b/src/proof/acec/acecNorm.c new file mode 100644 index 000000000..9faf7acfd --- /dev/null +++ b/src/proof/acec/acecNorm.c @@ -0,0 +1,215 @@ +/**CFile**************************************************************** + + FileName [acecNorm.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [CEC for arithmetic circuits.] + + Synopsis [Adder tree normalization.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: acecNorm.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "acecInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_InsertHadd( Gia_Man_t * pNew, int In[2], int Out[2] ) +{ + int And, Or; + Out[1] = Gia_ManAppendAnd2( pNew, In[0], In[1] ); + And = Gia_ManAppendAnd2( pNew, Abc_LitNot(In[0]), Abc_LitNot(In[1]) ); + Or = Gia_ManAppendOr2( pNew, Out[1], And ); + Out[0] = Abc_LitNot( Or ); +} +void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] ) +{ + int In2[2], Out1[2], Out2[2]; + Acec_InsertHadd( pNew, In, Out1 ); + In2[0] = Out1[0]; + In2[1] = In[2]; + Acec_InsertHadd( pNew, In2, Out2 ); + Out[0] = Out2[0]; + Out[1] = Gia_ManAppendOr2( pNew, Out1[1], Out2[1] ); +} +Vec_Int_t * Acec_InsertTree( Gia_Man_t * pNew, Vec_Wec_t * vLeafMap ) +{ + Vec_Int_t * vRootRanks = Vec_IntAlloc( Vec_WecSize(vLeafMap) + 5 ); + Vec_Int_t * vLevel; + int i, In[3], Out[2]; + Vec_WecForEachLevel( vLeafMap, vLevel, i ) + { + if ( Vec_IntSize(vLevel) == 0 ) + { + Vec_IntPush( vRootRanks, 0 ); + continue; + } + while ( Vec_IntSize(vLevel) > 1 ) + { + if ( Vec_IntSize(vLevel) == 2 ) + Vec_IntPush( vLevel, 0 ); + In[2] = Vec_IntPop( vLevel ); + In[1] = Vec_IntPop( vLevel ); + In[0] = Vec_IntPop( vLevel ); + Acec_InsertFadd( pNew, In, Out ); + Vec_IntPush( vLevel, Out[0] ); + if ( i+1 < Vec_WecSize(vLeafMap) ) + vLevel = Vec_WecEntry(vLeafMap, i+1); + else + vLevel = Vec_WecPushLevel(vLeafMap); + Vec_IntPush( vLevel, Out[1] ); + vLevel = Vec_WecEntry(vLeafMap, i); + } + assert( Vec_IntSize(vLevel) == 1 ); + Vec_IntPush( vRootRanks, Vec_IntEntry(vLevel, 0) ); + } + return vRootRanks; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_InsertBox_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( ~pObj->Value ) + return pObj->Value; + assert( Gia_ObjIsAnd(pObj) ); + Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Acec_InsertBox_rec( pNew, p, Gia_ObjFanin1(pObj) ); + return (pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) )); +} +Vec_Int_t * Acec_BuildTree( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t * vLeafLits ) +{ + Vec_Wec_t * vLeafMap = Vec_WecStart( Vec_WecSize(vLeafLits) ); + Vec_Int_t * vLevel, * vRootRanks; + int i, k, iLit, iLitNew; + Vec_WecForEachLevel( vLeafLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + { + Gia_Obj_t * pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) ); + iLitNew = Acec_InsertBox_rec( pNew, p, pObj ); + iLitNew = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) ); + Vec_WecPush( vLeafMap, i, iLitNew ); + } + // construct map of root literals + vRootRanks = Acec_InsertTree( pNew, vLeafMap ); + Vec_WecFree( vLeafMap ); + return vRootRanks; +} +Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ) +{ + Gia_Man_t * p = pBox->pGia; + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + Vec_Int_t * vRootRanks, * vLevel; + int i, k, iLit, iLitNew; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManFillValue(p); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + // implement tree + if ( fAll ) + vRootRanks = Acec_BuildTree( pNew, p, pBox->vLeafLits ); + else + { + Vec_Wec_t * vLeafLits; + assert( pBox->vShared != NULL ); + assert( pBox->vUnique != NULL ); + vRootRanks = Acec_BuildTree( p, p, pBox->vShared ); + // add these roots to the unique ones + vLeafLits = Vec_WecDup( pBox->vUnique ); + Vec_IntForEachEntry( vRootRanks, iLit, i ) + { + if ( i < Vec_WecSize(vLeafLits) ) + vLevel = Vec_WecEntry(vLeafLits, i); + else + vLevel = Vec_WecPushLevel(vLeafLits); + Vec_IntPush( vLevel, iLit ); + } + Vec_IntFree( vRootRanks ); + vRootRanks = Acec_BuildTree( pNew, p, vLeafLits ); + Vec_WecFree( vLeafLits ); + } + // update polarity of literals + Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + { + pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) ); + iLitNew = k ? 0 : Vec_IntEntry( vRootRanks, i ); + pObj->Value = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) ); + } + Vec_IntFree( vRootRanks ); + // construct the outputs + Gia_ManForEachCo( p, pObj, i ) + Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManForEachCo( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fVerbose ) +{ + Acec_Box_t * pBox = Acec_DeriveBox( pGia, fVerbose ); + Gia_Man_t * pNew = Acec_InsertBox( pBox, 1 ); + Acec_BoxFreeP( &pBox ); + return pNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index ba08deb5f..1c0af00a5 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -31,6 +31,36 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_BoxFree( Acec_Box_t * pBox ) +{ + Vec_WecFreeP( &pBox->vAdds ); + Vec_WecFreeP( &pBox->vLeafs ); + Vec_WecFreeP( &pBox->vRoots ); + Vec_WecFreeP( &pBox->vLeafLits ); + Vec_WecFreeP( &pBox->vRootLits ); + Vec_WecFreeP( &pBox->vUnique ); + Vec_WecFreeP( &pBox->vShared ); + Vec_BitFreeP( &pBox->vInvHadds ); + ABC_FREE( pBox ); +} +void Acec_BoxFreeP( Acec_Box_t ** ppBox ) +{ + if ( *ppBox ) + Acec_BoxFree( *ppBox ); + *ppBox = NULL; +} + /**Function************************************************************* Synopsis [Find internal cut points with exactly one adder fanin/fanout.] @@ -412,6 +442,31 @@ void Acec_TreePhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes, SeeAlso [] ***********************************************************************/ +void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ) +{ + Vec_Int_t * vLevel; + int i, k, iBox; + Vec_WecForEachLevel( vBoxes, vLevel, i ) + { + printf( " %4d : {", i ); + Vec_IntForEachEntry( vLevel, iBox, k ) + printf( " %s%d=(%d,%d)", Vec_IntEntry(vAdds, 6*iBox+2) == 0 ? "*":"", iBox, + Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) ); + printf( " }\n" ); + } +} +void Vec_WecPrintLits( Vec_Wec_t * p ) +{ + Vec_Int_t * vVec; + int i, k, Entry; + Vec_WecForEachLevel( p, vVec, i ) + { + printf( " %4d : {", i ); + Vec_IntForEachEntry( vVec, Entry, k ) + printf( " %c%d", Abc_LitIsCompl(Entry) ? '-' : '+', Abc_Lit2Var(Entry) ); + printf( " }\n" ); + } +} void Acec_PrintRootLits( Vec_Wec_t * vRoots ) { Vec_Int_t * vLevel; @@ -429,30 +484,6 @@ void Acec_PrintRootLits( Vec_Wec_t * vRoots ) printf( "\n" ); } } -void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ) -{ - Vec_Int_t * vLevel; - int i, k, iBox; - Vec_WecForEachLevel( vBoxes, vLevel, i ) - { - printf( " %4d : {", i ); - Vec_IntForEachEntry( vLevel, iBox, k ) - printf( " (%d,%d)", Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) ); - printf( " }\n" ); - } -} -void Vec_WecPrintLits( Vec_Wec_t * p ) -{ - Vec_Int_t * vVec; - int i, k, Entry; - Vec_WecForEachLevel( p, vVec, i ) - { - printf( " %4d : {", i ); - Vec_IntForEachEntry( vVec, Entry, k ) - printf( " %c%d", Abc_LitIsCompl(Entry) ? '-' : '+', Abc_Lit2Var(Entry) ); - printf( " }\n" ); - } -} void Acec_PrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds ) { printf( "Adders:\n" ); @@ -488,7 +519,6 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree } void Acec_CreateBoxTest( Gia_Man_t * p ) { - extern void Acec_BoxFree( Acec_Box_t * pBox ); Acec_Box_t * pBox; Vec_Wec_t * vTrees; Vec_Int_t * vTree; @@ -511,8 +541,8 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) printf( "Processing tree %d: Ranks = %d. Adders = %d. Leaves = %d. Roots = %d.\n", i, Vec_WecSize(pBox->vAdds), Vec_WecSizeSize(pBox->vAdds), Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); - //Acec_PrintBox( pBox ); - Acec_BoxFree( pBox ); + Acec_PrintBox( pBox, vAdds ); + Acec_BoxFreeP( &pBox ); } Vec_WecFree( vTrees ); @@ -530,9 +560,22 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p ) +Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, int fVerbose ) { - return NULL; + Acec_Box_t * pBox = NULL; + Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, fVerbose ); + Vec_Wec_t * vTrees = Acec_TreeFindTrees( p, vAdds ); + if ( vTrees && Vec_WecSize(vTrees) > 0 ) + pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, 0) ); + if ( pBox )//&& fVerbose ) + printf( "Processing tree %d: Ranks = %d. Adders = %d. Leaves = %d. Roots = %d.\n", + 0, Vec_WecSize(pBox->vAdds), Vec_WecSizeSize(pBox->vAdds), + Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); + if ( pBox && fVerbose ) + Acec_PrintBox( pBox, vAdds ); + Vec_WecFreeP( &vTrees ); + Vec_IntFree( vAdds ); + return pBox; } //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/acec/module.make b/src/proof/acec/module.make index 4db695c51..25fa25484 100644 --- a/src/proof/acec/module.make +++ b/src/proof/acec/module.make @@ -8,6 +8,7 @@ SRC += src/proof/acec/acecCl.c \ src/proof/acec/acecPool.c \ src/proof/acec/acecCover.c \ src/proof/acec/acecFadds.c \ + src/proof/acec/acecNorm.c \ src/proof/acec/acecOrder.c \ src/proof/acec/acecPolyn.c \ src/proof/acec/acecSt.c \ From d52dafa6c2365837543f15be7abd274f8654ba14 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 12 Jan 2017 16:12:48 +0700 Subject: [PATCH 056/185] Updates to arithmetic verification. --- abclib.dsp | 4 + src/aig/gia/gia.h | 1 + src/aig/gia/giaTruth.c | 51 +++++ src/base/wlc/wlcBlast.c | 26 +++ src/proof/acec/acecInt.h | 2 + src/proof/acec/acecMult.c | 432 +++++++++++++++++++++++++++++++++++++ src/proof/acec/acecTree.c | 26 ++- src/proof/acec/module.make | 1 + 8 files changed, 534 insertions(+), 9 deletions(-) create mode 100644 src/proof/acec/acecMult.c diff --git a/abclib.dsp b/abclib.dsp index e2ff005ed..170633e49 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -5507,6 +5507,10 @@ SOURCE=.\src\proof\acec\acecInt.h # End Source File # Begin Source File +SOURCE=.\src\proof\acec\acecMult.c +# End Source File +# Begin Source File + SOURCE=.\src\proof\acec\acecNorm.c # End Source File # Begin Source File diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index d9b1716a3..7cf1feff3 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1514,6 +1514,7 @@ extern int Gia_ManVerifyWithBoxes( Gia_Man_t * pGia, int nBTLimi extern word Gia_LutComputeTruth6( Gia_Man_t * p, int iObj, Vec_Wrd_t * vTruths ); extern word Gia_ObjComputeTruthTable6Lut( Gia_Man_t * p, int iObj, Vec_Wrd_t * vTemp ); extern word Gia_ObjComputeTruthTable6( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp, Vec_Wrd_t * vTruths ); +extern word Gia_ObjComputeTruth6Cis( Gia_Man_t * p, int iLit, Vec_Int_t * vSupp, Vec_Wrd_t * vTemp ); extern void Gia_ObjCollectInternal( Gia_Man_t * p, Gia_Obj_t * pObj ); extern word * Gia_ObjComputeTruthTable( Gia_Man_t * p, Gia_Obj_t * pObj ); extern void Gia_ObjComputeTruthTableStart( Gia_Man_t * p, int nVarsMax ); diff --git a/src/aig/gia/giaTruth.c b/src/aig/gia/giaTruth.c index ce06fa0b9..f636a573c 100644 --- a/src/aig/gia/giaTruth.c +++ b/src/aig/gia/giaTruth.c @@ -137,6 +137,57 @@ word Gia_ObjComputeTruthTable6Lut( Gia_Man_t * p, int iObj, Vec_Wrd_t * vTemp ) return Vec_WrdEntry( vTemp, iObj ); } +/**Function************************************************************* + + Synopsis [Computes truth table up to 6 inputs in terms of CIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +word Gia_ObjComputeTruth6( Gia_Man_t * p, int iObj, Vec_Int_t * vSupp, Vec_Wrd_t * vTemp ) +{ + int i, Fanin; + assert( Vec_WrdSize(vTemp) == Gia_ManObjNum(p) ); + assert( Vec_IntSize(vSupp) <= 6 ); + Gia_ManIncrementTravId( p ); + Vec_IntForEachEntry( vSupp, Fanin, i ) + { + Gia_ObjSetTravIdCurrentId( p, Fanin ); + Vec_WrdWriteEntry( vTemp, Fanin, s_Truth6[i] ); + } + Gia_ObjComputeTruthTable6Lut_rec( p, iObj, vTemp ); + return Vec_WrdEntry( vTemp, iObj ); +} +void Gia_ObjComputeTruth6CisSupport_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vSupp ) +{ + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) + return; + Gia_ObjSetTravIdCurrentId(p, iObj); + if ( Gia_ObjIsCi(pObj) ) + { + Vec_IntPushOrder( vSupp, iObj ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + Gia_ObjComputeTruth6CisSupport_rec( p, Gia_ObjFaninId0p(p, pObj), vSupp ); + Gia_ObjComputeTruth6CisSupport_rec( p, Gia_ObjFaninId1p(p, pObj), vSupp ); +} +word Gia_ObjComputeTruth6Cis( Gia_Man_t * p, int iLit, Vec_Int_t * vSupp, Vec_Wrd_t * vTemp ) +{ + int iObj = Abc_Lit2Var(iLit); + Vec_IntClear( vSupp ); + if ( !iObj ) return Abc_LitIsCompl(iLit) ? ~(word)0 : (word)0; + Gia_ManIncrementTravId( p ); + Gia_ObjComputeTruth6CisSupport_rec( p, iObj, vSupp ); + Gia_ObjComputeTruth6( p, iObj, vSupp, vTemp ); + return Abc_LitIsCompl(iLit) ? ~Vec_WrdEntry(vTemp, iObj) : Vec_WrdEntry(vTemp, iObj); +} + /**Function************************************************************* Synopsis [Computes truth table up to 6 inputs.] diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index 5e6a1a471..b22ac6cdc 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -643,6 +643,31 @@ void Wlc_IntInsert( Vec_Int_t * vProd, Vec_Int_t * vLevel, int Node, int Level ) Vec_IntInsert( vProd, i + 1, Node ); Vec_IntInsert( vLevel, i + 1, Level ); } +void Wlc_BlastPrintMatrix( Gia_Man_t * p, Vec_Wec_t * vProds ) +{ + Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); + Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; word Truth; + int i, k, iLit; + Vec_WecForEachLevel( vProds, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + { + printf( "Obj = %4d : ", Abc_Lit2Var(iLit) ); + printf( "Compl = %d ", Abc_LitIsCompl(iLit) ); + printf( "Rank = %2d ", i ); + Truth = Gia_ObjComputeTruth6Cis( p, iLit, vSupp, vTemp ); + Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) ); + if ( Vec_IntSize(vSupp) == 4 ) printf( " " ); + if ( Vec_IntSize(vSupp) == 3 ) printf( " " ); + if ( Vec_IntSize(vSupp) <= 2 ) printf( " " ); + printf( " " ); + Vec_IntPrint( vSupp ); + if ( k == Vec_IntSize(vLevel)-1 ) + printf( "\n" ); + } + Vec_IntFree( vSupp ); + Vec_WrdFree( vTemp ); +} void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vLevels, Vec_Int_t * vRes ) { Vec_Int_t * vLevel, * vProd; @@ -812,6 +837,7 @@ void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int Vec_WecPush( vLevels, k, 0 ); } //Vec_WecPrint( vProds, 0 ); + //Wlc_BlastPrintMatrix( pNew, vProds ); //printf( "Cutoff ID for partial products = %d.\n", Gia_ManObjNum(pNew) ); Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes ); diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index c0d899e17..0dc3f7060 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -70,6 +70,8 @@ struct Acec_Box_t_ /*=== acecCo.c ========================================================*/ extern Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vAddCos, Vec_Int_t ** pvIns, Vec_Int_t ** pvOuts ); extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vRootBoxes ); +/*=== acecMult.c ========================================================*/ +extern Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits ); /*=== acecNorm.c ========================================================*/ extern Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ); /*=== acecTree.c ========================================================*/ diff --git a/src/proof/acec/acecMult.c b/src/proof/acec/acecMult.c new file mode 100644 index 000000000..397f6d571 --- /dev/null +++ b/src/proof/acec/acecMult.c @@ -0,0 +1,432 @@ +/**CFile**************************************************************** + + FileName [acecMult.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [CEC for arithmetic circuits.] + + Synopsis [Multiplier.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: acecMult.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "acecInt.h" +#include "misc/extra/extra.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +unsigned s_Classes4a[96] = { + 0xD728, 0xB748, 0x9F60, 0xD278, 0xB478, 0x96F0, 0xC66C, 0x96CC, 0x9C6C, 0x96AA, 0xA66A, 0x9A6A, + 0x28D7, 0x48B7, 0x609F, 0x2D87, 0x4B87, 0x690F, 0x3993, 0x6933, 0x6393, 0x6955, 0x5995, 0x6595, + 0xEB14, 0xED12, 0xF906, 0xE1B4, 0xE1D2, 0xF096, 0xC99C, 0xCC96, 0xC9C6, 0xAA96, 0xA99A, 0xA9A6, + 0x14EB, 0x12ED, 0x06F9, 0x1E4B, 0x1E2D, 0x0F69, 0x3663, 0x3369, 0x3639, 0x5569, 0x5665, 0x5659, + 0x7D82, 0x7B84, 0x6F90, 0x78D2, 0x78B4, 0x69F0, 0x6CC6, 0x69CC, 0x6C9C, 0x69AA, 0x6AA6, 0x6A9A, + 0x827D, 0x847B, 0x906F, 0x872D, 0x874B, 0x960F, 0x9339, 0x9633, 0x9363, 0x9655, 0x9559, 0x9565, + 0xBE41, 0xDE21, 0xF609, 0xB4E1, 0xD2E1, 0xF069, 0x9CC9, 0xCC69, 0xC6C9, 0xAA69, 0x9AA9, 0xA6A9, + 0x41BE, 0x21DE, 0x09F6, 0x4B1E, 0x2D1E, 0x0F96, 0x6336, 0x3396, 0x3936, 0x5596, 0x6556, 0x5956 +}; + +unsigned s_Classes4b[384] = { + 0x35C0, 0x53A0, 0x1DC0, 0x4788, 0x2788, 0x1BA0, 0x3C50, 0x5A30, 0x1CD0, 0x4878, 0x2878, 0x1AB0, + 0x34C4, 0x606C, 0x3C44, 0x660C, 0x268C, 0x286C, 0x606A, 0x52A2, 0x486A, 0x468A, 0x660A, 0x5A22, + 0x3AC0, 0x5CA0, 0x2EC0, 0x7488, 0x7288, 0x4EA0, 0x3CA0, 0x5AC0, 0x2CE0, 0x7848, 0x7828, 0x4AE0, + 0x38C8, 0x6C60, 0x3C88, 0x66C0, 0x62C8, 0x6C28, 0x6A60, 0x58A8, 0x6A48, 0x64A8, 0x66A0, 0x5A88, + 0xC530, 0xA350, 0xD10C, 0x8B44, 0x8D22, 0xB10A, 0xC350, 0xA530, 0xD01C, 0x84B4, 0x82D2, 0xB01A, + 0xC434, 0x909C, 0xC344, 0x990C, 0x8C26, 0x82C6, 0x909A, 0xA252, 0x84A6, 0x8A46, 0x990A, 0xA522, + 0xCA30, 0xAC50, 0xE20C, 0xB844, 0xD822, 0xE40A, 0xC3A0, 0xA5C0, 0xE02C, 0xB484, 0xD282, 0xE04A, + 0xC838, 0x9C90, 0xC388, 0x99C0, 0xC862, 0xC682, 0x9A90, 0xA858, 0xA684, 0xA864, 0x99A0, 0xA588, + 0x530C, 0x350A, 0x4730, 0x1D22, 0x1B44, 0x2750, 0x503C, 0x305A, 0x4370, 0x12D2, 0x14B4, 0x2570, + 0x434C, 0x06C6, 0x443C, 0x0C66, 0x194C, 0x149C, 0x06A6, 0x252A, 0x129A, 0x192A, 0x0A66, 0x225A, + 0xA30C, 0xC50A, 0x8B30, 0xD122, 0xB144, 0x8D50, 0xA03C, 0xC05A, 0x83B0, 0xD212, 0xB414, 0x85D0, + 0x838C, 0xC606, 0x883C, 0xC066, 0x91C4, 0x9C14, 0xA606, 0x858A, 0x9A12, 0x91A2, 0xA066, 0x885A, + 0x5C03, 0x3A05, 0x7403, 0x2E11, 0x4E11, 0x7205, 0x50C3, 0x30A5, 0x7043, 0x21E1, 0x41E1, 0x7025, + 0x4C43, 0x09C9, 0x44C3, 0x0C99, 0x4C19, 0x41C9, 0x09A9, 0x2A25, 0x21A9, 0x2A19, 0x0A99, 0x22A5, + 0xAC03, 0xCA05, 0xB803, 0xE211, 0xE411, 0xD805, 0xA0C3, 0xC0A5, 0xB083, 0xE121, 0xE141, 0xD085, + 0x8C83, 0xC909, 0x88C3, 0xC099, 0xC491, 0xC941, 0xA909, 0x8A85, 0xA921, 0xA291, 0xA099, 0x88A5, + 0xC035, 0xA053, 0xC01D, 0x8847, 0x8827, 0xA01B, 0xC305, 0xA503, 0xC10D, 0x8487, 0x8287, 0xA10B, + 0xC131, 0x9093, 0xC311, 0x9903, 0x8923, 0x8293, 0x9095, 0xA151, 0x8495, 0x8945, 0x9905, 0xA511, + 0xC03A, 0xA05C, 0xC02E, 0x8874, 0x8872, 0xA04E, 0xC30A, 0xA50C, 0xC20E, 0x8784, 0x8782, 0xA40E, + 0xC232, 0x9390, 0xC322, 0x9930, 0x9832, 0x9382, 0x9590, 0xA454, 0x9584, 0x9854, 0x9950, 0xA544, + 0x30C5, 0x50A3, 0x0CD1, 0x448B, 0x228D, 0x0AB1, 0x3C05, 0x5A03, 0x0DC1, 0x484B, 0x282D, 0x0BA1, + 0x31C1, 0x6063, 0x3C11, 0x6603, 0x2389, 0x2839, 0x6065, 0x51A1, 0x4859, 0x4589, 0x6605, 0x5A11, + 0x30CA, 0x50AC, 0x0CE2, 0x44B8, 0x22D8, 0x0AE4, 0x3C0A, 0x5A0C, 0x0EC2, 0x4B48, 0x2D28, 0x0EA4, + 0x32C2, 0x6360, 0x3C22, 0x6630, 0x3298, 0x3928, 0x6560, 0x54A4, 0x5948, 0x5498, 0x6650, 0x5A44, + 0x0C53, 0x0A35, 0x3047, 0x221D, 0x441B, 0x5027, 0x05C3, 0x03A5, 0x3407, 0x212D, 0x414B, 0x5207, + 0x1C13, 0x0939, 0x11C3, 0x0399, 0x4613, 0x4163, 0x0959, 0x1A15, 0x2165, 0x2615, 0x0599, 0x11A5, + 0x0CA3, 0x0AC5, 0x308B, 0x22D1, 0x44B1, 0x508D, 0x0AC3, 0x0CA5, 0x380B, 0x2D21, 0x4B41, 0x580D, + 0x2C23, 0x3909, 0x22C3, 0x3099, 0x6431, 0x6341, 0x5909, 0x4A45, 0x6521, 0x6251, 0x5099, 0x44A5, + 0x035C, 0x053A, 0x0374, 0x112E, 0x114E, 0x0572, 0x053C, 0x035A, 0x0734, 0x121E, 0x141E, 0x0752, + 0x131C, 0x0636, 0x113C, 0x0366, 0x1346, 0x1436, 0x0656, 0x151A, 0x1256, 0x1526, 0x0566, 0x115A, + 0x03AC, 0x05CA, 0x03B8, 0x11E2, 0x11E4, 0x05D8, 0x0A3C, 0x0C5A, 0x0B38, 0x1E12, 0x1E14, 0x0D58, + 0x232C, 0x3606, 0x223C, 0x3066, 0x3164, 0x3614, 0x5606, 0x454A, 0x5612, 0x5162, 0x5066, 0x445A +}; + +unsigned s_Classes4c[768] = { + 0x35C0, 0x53A0, 0x1DC0, 0x4788, 0x2788, 0x1BA0, 0x3C50, 0x5A30, 0x1CD0, 0x4878, 0x2878, 0x1AB0, + 0x34C4, 0x606C, 0x3C44, 0x660C, 0x268C, 0x286C, 0x606A, 0x52A2, 0x486A, 0x468A, 0x660A, 0x5A22, + 0xCA3F, 0xAC5F, 0xE23F, 0xB877, 0xD877, 0xE45F, 0xC3AF, 0xA5CF, 0xE32F, 0xB787, 0xD787, 0xE54F, + 0xCB3B, 0x9F93, 0xC3BB, 0x99F3, 0xD973, 0xD793, 0x9F95, 0xAD5D, 0xB795, 0xB975, 0x99F5, 0xA5DD, + 0x3AC0, 0x5CA0, 0x2EC0, 0x7488, 0x7288, 0x4EA0, 0x3CA0, 0x5AC0, 0x2CE0, 0x7848, 0x7828, 0x4AE0, + 0x38C8, 0x6C60, 0x3C88, 0x66C0, 0x62C8, 0x6C28, 0x6A60, 0x58A8, 0x6A48, 0x64A8, 0x66A0, 0x5A88, + 0xC53F, 0xA35F, 0xD13F, 0x8B77, 0x8D77, 0xB15F, 0xC35F, 0xA53F, 0xD31F, 0x87B7, 0x87D7, 0xB51F, + 0xC737, 0x939F, 0xC377, 0x993F, 0x9D37, 0x93D7, 0x959F, 0xA757, 0x95B7, 0x9B57, 0x995F, 0xA577, + 0xC530, 0xA350, 0xD10C, 0x8B44, 0x8D22, 0xB10A, 0xC350, 0xA530, 0xD01C, 0x84B4, 0x82D2, 0xB01A, + 0xC434, 0x909C, 0xC344, 0x990C, 0x8C26, 0x82C6, 0x909A, 0xA252, 0x84A6, 0x8A46, 0x990A, 0xA522, + 0x3ACF, 0x5CAF, 0x2EF3, 0x74BB, 0x72DD, 0x4EF5, 0x3CAF, 0x5ACF, 0x2FE3, 0x7B4B, 0x7D2D, 0x4FE5, + 0x3BCB, 0x6F63, 0x3CBB, 0x66F3, 0x73D9, 0x7D39, 0x6F65, 0x5DAD, 0x7B59, 0x75B9, 0x66F5, 0x5ADD, + 0xCA30, 0xAC50, 0xE20C, 0xB844, 0xD822, 0xE40A, 0xC3A0, 0xA5C0, 0xE02C, 0xB484, 0xD282, 0xE04A, + 0xC838, 0x9C90, 0xC388, 0x99C0, 0xC862, 0xC682, 0x9A90, 0xA858, 0xA684, 0xA864, 0x99A0, 0xA588, + 0x35CF, 0x53AF, 0x1DF3, 0x47BB, 0x27DD, 0x1BF5, 0x3C5F, 0x5A3F, 0x1FD3, 0x4B7B, 0x2D7D, 0x1FB5, + 0x37C7, 0x636F, 0x3C77, 0x663F, 0x379D, 0x397D, 0x656F, 0x57A7, 0x597B, 0x579B, 0x665F, 0x5A77, + 0x530C, 0x350A, 0x4730, 0x1D22, 0x1B44, 0x2750, 0x503C, 0x305A, 0x4370, 0x12D2, 0x14B4, 0x2570, + 0x434C, 0x06C6, 0x443C, 0x0C66, 0x194C, 0x149C, 0x06A6, 0x252A, 0x129A, 0x192A, 0x0A66, 0x225A, + 0xACF3, 0xCAF5, 0xB8CF, 0xE2DD, 0xE4BB, 0xD8AF, 0xAFC3, 0xCFA5, 0xBC8F, 0xED2D, 0xEB4B, 0xDA8F, + 0xBCB3, 0xF939, 0xBBC3, 0xF399, 0xE6B3, 0xEB63, 0xF959, 0xDAD5, 0xED65, 0xE6D5, 0xF599, 0xDDA5, + 0xA30C, 0xC50A, 0x8B30, 0xD122, 0xB144, 0x8D50, 0xA03C, 0xC05A, 0x83B0, 0xD212, 0xB414, 0x85D0, + 0x838C, 0xC606, 0x883C, 0xC066, 0x91C4, 0x9C14, 0xA606, 0x858A, 0x9A12, 0x91A2, 0xA066, 0x885A, + 0x5CF3, 0x3AF5, 0x74CF, 0x2EDD, 0x4EBB, 0x72AF, 0x5FC3, 0x3FA5, 0x7C4F, 0x2DED, 0x4BEB, 0x7A2F, + 0x7C73, 0x39F9, 0x77C3, 0x3F99, 0x6E3B, 0x63EB, 0x59F9, 0x7A75, 0x65ED, 0x6E5D, 0x5F99, 0x77A5, + 0x5C03, 0x3A05, 0x7403, 0x2E11, 0x4E11, 0x7205, 0x50C3, 0x30A5, 0x7043, 0x21E1, 0x41E1, 0x7025, + 0x4C43, 0x09C9, 0x44C3, 0x0C99, 0x4C19, 0x41C9, 0x09A9, 0x2A25, 0x21A9, 0x2A19, 0x0A99, 0x22A5, + 0xA3FC, 0xC5FA, 0x8BFC, 0xD1EE, 0xB1EE, 0x8DFA, 0xAF3C, 0xCF5A, 0x8FBC, 0xDE1E, 0xBE1E, 0x8FDA, + 0xB3BC, 0xF636, 0xBB3C, 0xF366, 0xB3E6, 0xBE36, 0xF656, 0xD5DA, 0xDE56, 0xD5E6, 0xF566, 0xDD5A, + 0xAC03, 0xCA05, 0xB803, 0xE211, 0xE411, 0xD805, 0xA0C3, 0xC0A5, 0xB083, 0xE121, 0xE141, 0xD085, + 0x8C83, 0xC909, 0x88C3, 0xC099, 0xC491, 0xC941, 0xA909, 0x8A85, 0xA921, 0xA291, 0xA099, 0x88A5, + 0x53FC, 0x35FA, 0x47FC, 0x1DEE, 0x1BEE, 0x27FA, 0x5F3C, 0x3F5A, 0x4F7C, 0x1EDE, 0x1EBE, 0x2F7A, + 0x737C, 0x36F6, 0x773C, 0x3F66, 0x3B6E, 0x36BE, 0x56F6, 0x757A, 0x56DE, 0x5D6E, 0x5F66, 0x775A, + 0xC035, 0xA053, 0xC01D, 0x8847, 0x8827, 0xA01B, 0xC305, 0xA503, 0xC10D, 0x8487, 0x8287, 0xA10B, + 0xC131, 0x9093, 0xC311, 0x9903, 0x8923, 0x8293, 0x9095, 0xA151, 0x8495, 0x8945, 0x9905, 0xA511, + 0x3FCA, 0x5FAC, 0x3FE2, 0x77B8, 0x77D8, 0x5FE4, 0x3CFA, 0x5AFC, 0x3EF2, 0x7B78, 0x7D78, 0x5EF4, + 0x3ECE, 0x6F6C, 0x3CEE, 0x66FC, 0x76DC, 0x7D6C, 0x6F6A, 0x5EAE, 0x7B6A, 0x76BA, 0x66FA, 0x5AEE, + 0xC03A, 0xA05C, 0xC02E, 0x8874, 0x8872, 0xA04E, 0xC30A, 0xA50C, 0xC20E, 0x8784, 0x8782, 0xA40E, + 0xC232, 0x9390, 0xC322, 0x9930, 0x9832, 0x9382, 0x9590, 0xA454, 0x9584, 0x9854, 0x9950, 0xA544, + 0x3FC5, 0x5FA3, 0x3FD1, 0x778B, 0x778D, 0x5FB1, 0x3CF5, 0x5AF3, 0x3DF1, 0x787B, 0x787D, 0x5BF1, + 0x3DCD, 0x6C6F, 0x3CDD, 0x66CF, 0x67CD, 0x6C7D, 0x6A6F, 0x5BAB, 0x6A7B, 0x67AB, 0x66AF, 0x5ABB, + 0x30C5, 0x50A3, 0x0CD1, 0x448B, 0x228D, 0x0AB1, 0x3C05, 0x5A03, 0x0DC1, 0x484B, 0x282D, 0x0BA1, + 0x31C1, 0x6063, 0x3C11, 0x6603, 0x2389, 0x2839, 0x6065, 0x51A1, 0x4859, 0x4589, 0x6605, 0x5A11, + 0xCF3A, 0xAF5C, 0xF32E, 0xBB74, 0xDD72, 0xF54E, 0xC3FA, 0xA5FC, 0xF23E, 0xB7B4, 0xD7D2, 0xF45E, + 0xCE3E, 0x9F9C, 0xC3EE, 0x99FC, 0xDC76, 0xD7C6, 0x9F9A, 0xAE5E, 0xB7A6, 0xBA76, 0x99FA, 0xA5EE, + 0x30CA, 0x50AC, 0x0CE2, 0x44B8, 0x22D8, 0x0AE4, 0x3C0A, 0x5A0C, 0x0EC2, 0x4B48, 0x2D28, 0x0EA4, + 0x32C2, 0x6360, 0x3C22, 0x6630, 0x3298, 0x3928, 0x6560, 0x54A4, 0x5948, 0x5498, 0x6650, 0x5A44, + 0xCF35, 0xAF53, 0xF31D, 0xBB47, 0xDD27, 0xF51B, 0xC3F5, 0xA5F3, 0xF13D, 0xB4B7, 0xD2D7, 0xF15B, + 0xCD3D, 0x9C9F, 0xC3DD, 0x99CF, 0xCD67, 0xC6D7, 0x9A9F, 0xAB5B, 0xA6B7, 0xAB67, 0x99AF, 0xA5BB, + 0x0C53, 0x0A35, 0x3047, 0x221D, 0x441B, 0x5027, 0x05C3, 0x03A5, 0x3407, 0x212D, 0x414B, 0x5207, + 0x1C13, 0x0939, 0x11C3, 0x0399, 0x4613, 0x4163, 0x0959, 0x1A15, 0x2165, 0x2615, 0x0599, 0x11A5, + 0xF3AC, 0xF5CA, 0xCFB8, 0xDDE2, 0xBBE4, 0xAFD8, 0xFA3C, 0xFC5A, 0xCBF8, 0xDED2, 0xBEB4, 0xADF8, + 0xE3EC, 0xF6C6, 0xEE3C, 0xFC66, 0xB9EC, 0xBE9C, 0xF6A6, 0xE5EA, 0xDE9A, 0xD9EA, 0xFA66, 0xEE5A, + 0x0CA3, 0x0AC5, 0x308B, 0x22D1, 0x44B1, 0x508D, 0x0AC3, 0x0CA5, 0x380B, 0x2D21, 0x4B41, 0x580D, + 0x2C23, 0x3909, 0x22C3, 0x3099, 0x6431, 0x6341, 0x5909, 0x4A45, 0x6521, 0x6251, 0x5099, 0x44A5, + 0xF35C, 0xF53A, 0xCF74, 0xDD2E, 0xBB4E, 0xAF72, 0xF53C, 0xF35A, 0xC7F4, 0xD2DE, 0xB4BE, 0xA7F2, + 0xD3DC, 0xC6F6, 0xDD3C, 0xCF66, 0x9BCE, 0x9CBE, 0xA6F6, 0xB5BA, 0x9ADE, 0x9DAE, 0xAF66, 0xBB5A, + 0x035C, 0x053A, 0x0374, 0x112E, 0x114E, 0x0572, 0x053C, 0x035A, 0x0734, 0x121E, 0x141E, 0x0752, + 0x131C, 0x0636, 0x113C, 0x0366, 0x1346, 0x1436, 0x0656, 0x151A, 0x1256, 0x1526, 0x0566, 0x115A, + 0xFCA3, 0xFAC5, 0xFC8B, 0xEED1, 0xEEB1, 0xFA8D, 0xFAC3, 0xFCA5, 0xF8CB, 0xEDE1, 0xEBE1, 0xF8AD, + 0xECE3, 0xF9C9, 0xEEC3, 0xFC99, 0xECB9, 0xEBC9, 0xF9A9, 0xEAE5, 0xEDA9, 0xEAD9, 0xFA99, 0xEEA5, + 0x03AC, 0x05CA, 0x03B8, 0x11E2, 0x11E4, 0x05D8, 0x0A3C, 0x0C5A, 0x0B38, 0x1E12, 0x1E14, 0x0D58, + 0x232C, 0x3606, 0x223C, 0x3066, 0x3164, 0x3614, 0x5606, 0x454A, 0x5612, 0x5162, 0x5066, 0x445A, + 0xFC53, 0xFA35, 0xFC47, 0xEE1D, 0xEE1B, 0xFA27, 0xF5C3, 0xF3A5, 0xF4C7, 0xE1ED, 0xE1EB, 0xF2A7, + 0xDCD3, 0xC9F9, 0xDDC3, 0xCF99, 0xCE9B, 0xC9EB, 0xA9F9, 0xBAB5, 0xA9ED, 0xAE9D, 0xAF99, 0xBBA5 +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + + +/**Function************************************************************* + + Synopsis [Computes NPN-canonical form using brute-force methods.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Extra_TruthCanonNPN2( unsigned uTruth, int nVars, Vec_Int_t * vRes ) +{ + static int nVarsOld, nPerms; + static char ** pPerms = NULL; + + unsigned uTruthMin, uTruthC, uPhase, uPerm; + int nMints, k, i; + + if ( pPerms == NULL ) + { + nPerms = Extra_Factorial( nVars ); + pPerms = Extra_Permutations( nVars ); + nVarsOld = nVars; + } + else if ( nVarsOld != nVars ) + { + ABC_FREE( pPerms ); + nPerms = Extra_Factorial( nVars ); + pPerms = Extra_Permutations( nVars ); + nVarsOld = nVars; + } + + nMints = (1 << nVars); + uTruthC = (unsigned)( (~uTruth) & ((~((unsigned)0)) >> (32-nMints)) ); + uTruthMin = 0xFFFFFFFF; + for ( i = 0; i < nMints; i++ ) + { + uPhase = Extra_TruthPolarize( uTruth, i, nVars ); + for ( k = 0; k < nPerms; k++ ) + { + uPerm = Extra_TruthPermute( uPhase, pPerms[k], nVars, 0 ); + Vec_IntPushUnique( vRes, uPerm ); + if ( uTruthMin > uPerm ) + uTruthMin = uPerm; + } + uPhase = Extra_TruthPolarize( uTruthC, i, nVars ); + for ( k = 0; k < nPerms; k++ ) + { + uPerm = Extra_TruthPermute( uPhase, pPerms[k], nVars, 0 ); + Vec_IntPushUnique( vRes, uPerm ); + if ( uTruthMin > uPerm ) + uTruthMin = uPerm; + } + } + return uTruthMin; +} + +void Acec_MultFuncTest5() +{ + Vec_Int_t * vRes = Vec_IntAlloc( 1000 ); + int i, Entry; + + unsigned Truth = 0xF335ACC0; + unsigned Canon = Extra_TruthCanonNPN2( Truth, 5, vRes ); + + Extra_PrintHex( stdout, (unsigned*)&Truth, 5 ); printf( "\n" ); + Extra_PrintHex( stdout, (unsigned*)&Canon, 5 ); printf( "\n" ); + + printf( "Members = %d.\n", Vec_IntSize(vRes) ); + Vec_IntForEachEntry( vRes, Entry, i ) + { + Extra_PrintHex( stdout, (unsigned*)&Entry, 5 ); + printf( ", " ); + if ( i % 8 == 7 ) + printf( "\n" ); + } + + Vec_IntFree( vRes ); +} + +void Acec_MultFuncTest4() +{ + Vec_Int_t * vRes = Vec_IntAlloc( 1000 ); + int i, Entry; + + unsigned Truth = 0x35C0; + //unsigned Truth = 0xD728; + unsigned Canon = Extra_TruthCanonNPN2( Truth, 4, vRes ); + + Extra_PrintHex( stdout, (unsigned*)&Truth, 4 ); printf( "\n" ); + Extra_PrintHex( stdout, (unsigned*)&Canon, 4 ); printf( "\n" ); + + printf( "Members = %d.\n", Vec_IntSize(vRes) ); + Vec_IntForEachEntry( vRes, Entry, i ) + { + Extra_PrintHex( stdout, (unsigned*)&Entry, 4 ); + printf( ", " ); + if ( i % 12 == 11 ) + printf( "\n" ); + } + + Vec_IntFree( vRes ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Acec_MultCollectInputs( Vec_Int_t * vPairs, Vec_Int_t * vRanks, int iObj ) +{ + Vec_Int_t * vItems = Vec_IntAlloc( 100 ); + int k, iObj1, iObj2; + // collect all those appearing with this one + Vec_IntForEachEntryDouble( vPairs, iObj1, iObj2, k ) + if ( iObj == iObj1 ) + Vec_IntPushUnique( vItems, iObj2 ); + else if ( iObj == iObj2 ) + Vec_IntPushUnique( vItems, iObj1 ); + // sort items by rank cost + Vec_IntSelectSortCost( Vec_IntArray(vItems), Vec_IntSize(vItems), vRanks ); + return vItems; +} +Vec_Int_t * Acec_MultDetectInputs1( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits ) +{ + Vec_Int_t * vInputs = Vec_IntAlloc( 100 ); + Vec_Int_t * vCounts = Vec_IntStart( Gia_ManObjNum(p) ); + Vec_Int_t * vRanks = Vec_IntStart( Gia_ManObjNum(p) ); + Vec_Int_t * vPairs = Vec_IntAlloc( 100 ); + Vec_Int_t * vItems = Vec_IntAlloc( 100 ); + Vec_Int_t * vItems0; + Vec_Int_t * vItems1; + Vec_Int_t * vLevel; + int i, k, iLit, iObj, Count; + // count how many times each input appears + Vec_WecForEachLevel( vLeafLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + { + iObj = Abc_Lit2Var(iLit); + Vec_IntAddToEntry( vCounts, Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj), 1 ); + Vec_IntAddToEntry( vCounts, Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj), 1 ); +/* + printf( "Rank %2d : Leaf = %4d : (%2d, %2d)\n", i, iObj, + Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj), Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj) ); + if ( k == Vec_IntSize(vLevel) - 1 ) + printf( "\n" ); +*/ + } + // count ranks for each one + Vec_WecForEachLevel( vLeafLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + { + iObj = Abc_Lit2Var(iLit); + if ( Vec_IntEntry(vCounts, Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj)) < 2 ) + { + printf( "Skipping %d.\n", iObj ); + continue; + } + if ( Vec_IntEntry(vCounts, Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj)) < 2 ) + { + printf( "Skipping %d.\n", iObj ); + continue; + } + Vec_IntAddToEntry( vRanks, Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj), i ); + Vec_IntAddToEntry( vRanks, Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj), i ); + + Vec_IntPushTwo( vPairs, Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj), Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj) ); + } + + // print statistics + Vec_IntForEachEntry( vCounts, Count, i ) + { + if ( !Count ) + continue; + if ( !Vec_IntEntry(vRanks, i) ) + continue; + Vec_IntPush( vItems, i ); + printf( "Obj = %3d Occurs = %3d Ranks = %3d\n", i, Count, Vec_IntEntry(vRanks, i) ); + } + // sort items by rank cost + Vec_IntSelectSortCost( Vec_IntArray(vItems), Vec_IntSize(vItems), vRanks ); + // collect all those appearing with the last one + vItems0 = Acec_MultCollectInputs( vPairs, vRanks, Vec_IntEntryLast(vItems) ); + Vec_IntAppend( vInputs, vItems0 ); + // collect all those appearing with the last one + vItems1 = Acec_MultCollectInputs( vPairs, vRanks, Vec_IntEntryLast(vItems0) ); + Vec_IntAppend( vInputs, vItems1 ); + + Vec_IntPrint( vItems0 ); + Vec_IntPrint( vItems1 ); + + Vec_IntFree( vCounts ); + Vec_IntFree( vRanks ); + Vec_IntFree( vPairs ); + Vec_IntFree( vItems ); + Vec_IntFree( vItems0 ); + Vec_IntFree( vItems1 ); + return vInputs; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits ) +{ + Vec_Int_t * vInputs = Vec_IntAlloc( 100 ); + Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); + Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); + Vec_Int_t * vRanks = Vec_IntStart( Gia_ManObjNum(p) ); + Vec_Int_t * vCounts = Vec_IntStart( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; + int i, k, iLit, iObj, j, Entry; + + ABC_FREE( p->pRefs ); + Gia_ManCreateRefs( p ); + Gia_ManForEachCiId( p, iObj, i ) + printf( "%d=%d ", iObj, Gia_ObjRefNumId(p, iObj) ); + printf( "\n" ); + Gia_ManForEachAndId( p, iObj ) + if ( Gia_ObjRefNumId(p, iObj) >= 4 ) + printf( "%d=%d ", iObj, Gia_ObjRefNumId(p, iObj) ); + printf( "\n" ); + + Vec_WecForEachLevel( vLeafLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + { + word Truth = Gia_ObjComputeTruth6Cis( p, iLit, vSupp, vTemp ); + if ( Vec_IntSize(vSupp) >= 4 ) + { + printf( "Leaf = %4d : ", Abc_Lit2Var(iLit) ); + printf( "Rank = %2d ", i ); + printf( "Supp = %2d ", Vec_IntSize(vSupp) ); + Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) ); + if ( Vec_IntSize(vSupp) == 4 ) printf( " " ); + if ( Vec_IntSize(vSupp) == 3 ) printf( " " ); + if ( Vec_IntSize(vSupp) <= 2 ) printf( " " ); + printf( " " ); + Vec_IntPrint( vSupp ); + } + // support rank counts + Vec_IntForEachEntry( vSupp, Entry, j ) + { + Vec_IntAddToEntry( vRanks, Entry, i ); + Vec_IntAddToEntry( vCounts, Entry, 1 ); + } + if ( k == Vec_IntSize(vLevel)-1 ) + printf( "\n" ); + } + + Vec_IntForEachEntry( vCounts, Entry, j ) + if ( Entry ) + printf( "%d=%d(%.2f) ", j, Entry, 1.0*Vec_IntEntry(vRanks, j)/Entry ); + printf( "\n" ); + + Vec_IntFree( vSupp ); + Vec_WrdFree( vTemp ); + Vec_IntFree( vRanks ); + Vec_IntFree( vCounts ); + return vInputs; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index 1c0af00a5..53e1cb60f 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -307,16 +307,16 @@ void Acec_TreeVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox, Vec_Bi if ( fFadd ) // FADD { if ( TruthXor != 0x96 ) - printf( "Fadd %d sum is wrong.\n", iBox ); + printf( "Fadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) ); if ( TruthMaj != 0xE8 ) - printf( "Fadd %d carry is wrong.\n", iBox ); + printf( "Fadd %d carry %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+4 ) ); } else { if ( TruthXor != 0x66 ) - printf( "Hadd %d sum is wrong.\n", iBox ); + printf( "Hadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) ); if ( TruthMaj != 0x88 ) - printf( "Hadd %d carry is wrong.\n", iBox ); + printf( "Hadd %d carry %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+4 ) ); } } void Acec_TreeVerifyPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes, Vec_Bit_t * vPhase ) @@ -356,7 +356,9 @@ void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, in assert( Node != 0 ); if ( Vec_BitEntry(vVisit, Node) ) { - assert( Vec_BitEntry(vPhase, Node) == fPhase ); + //assert( Vec_BitEntry(vPhase, Node) == fPhase ); + if ( Vec_BitEntry(vPhase, Node) != fPhase ) + printf( "Phase check failed for node %d.\n", Node ); return; } Vec_BitWriteEntry( vVisit, Node, 1 ); @@ -386,7 +388,12 @@ void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, in Acec_TreePhases_rec( p, vAdds, vMap, iObj, fPhaseThis, vPhase, vInvHadds, vVisit ); } if ( Vec_BitEntry(vVisit, iXor) ) - assert( Vec_BitEntry(vPhase, iXor) == fXorPhase ); + { + //assert( Vec_BitEntry(vPhase, iXor) == fXorPhase ); + if ( Vec_BitEntry(vPhase, iXor) != fXorPhase ) + printf( "Phase check failed for XOR %d.\n", iXor ); + return; + } if ( fXorPhase ) Vec_BitWriteEntry( vPhase, iXor, fXorPhase ); } @@ -448,7 +455,7 @@ void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ) int i, k, iBox; Vec_WecForEachLevel( vBoxes, vLevel, i ) { - printf( " %4d : {", i ); + printf( " %4d : %2d {", i, Vec_IntSize(vLevel) ); Vec_IntForEachEntry( vLevel, iBox, k ) printf( " %s%d=(%d,%d)", Vec_IntEntry(vAdds, 6*iBox+2) == 0 ? "*":"", iBox, Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) ); @@ -461,7 +468,7 @@ void Vec_WecPrintLits( Vec_Wec_t * p ) int i, k, Entry; Vec_WecForEachLevel( p, vVec, i ) { - printf( " %4d : {", i ); + printf( " %4d : %2d {", i, Vec_IntSize(vVec) ); Vec_IntForEachEntry( vVec, Entry, k ) printf( " %c%d", Abc_LitIsCompl(Entry) ? '-' : '+', Abc_Lit2Var(Entry) ); printf( " }\n" ); @@ -473,7 +480,7 @@ void Acec_PrintRootLits( Vec_Wec_t * vRoots ) int i, k, iObj; Vec_WecForEachLevel( vRoots, vLevel, i ) { - printf( "Rank %d : ", i ); + printf( "Rank %d : %2d ", i, Vec_IntSize(vLevel) ); Vec_IntForEachEntry( vLevel, iObj, k ) { int fFadd = Abc_LitIsCompl(iObj); @@ -573,6 +580,7 @@ Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, int fVerbose ) Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); if ( pBox && fVerbose ) Acec_PrintBox( pBox, vAdds ); +// Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); Vec_WecFreeP( &vTrees ); Vec_IntFree( vAdds ); return pBox; diff --git a/src/proof/acec/module.make b/src/proof/acec/module.make index 25fa25484..dbf86ac2a 100644 --- a/src/proof/acec/module.make +++ b/src/proof/acec/module.make @@ -8,6 +8,7 @@ SRC += src/proof/acec/acecCl.c \ src/proof/acec/acecPool.c \ src/proof/acec/acecCover.c \ src/proof/acec/acecFadds.c \ + src/proof/acec/acecMult.c \ src/proof/acec/acecNorm.c \ src/proof/acec/acecOrder.c \ src/proof/acec/acecPolyn.c \ From f5240276cb29e730be44b96da9013db046683a5f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 13 Jan 2017 15:25:35 +0700 Subject: [PATCH 057/185] Updates to arithmetic verification. --- src/aig/gia/giaTruth.c | 2 ++ src/proof/acec/acecMult.c | 2 +- src/proof/acec/acecTree.c | 63 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/src/aig/gia/giaTruth.c b/src/aig/gia/giaTruth.c index f636a573c..ab5f569e9 100644 --- a/src/aig/gia/giaTruth.c +++ b/src/aig/gia/giaTruth.c @@ -184,6 +184,8 @@ word Gia_ObjComputeTruth6Cis( Gia_Man_t * p, int iLit, Vec_Int_t * vSupp, Vec_Wr if ( !iObj ) return Abc_LitIsCompl(iLit) ? ~(word)0 : (word)0; Gia_ManIncrementTravId( p ); Gia_ObjComputeTruth6CisSupport_rec( p, iObj, vSupp ); + if ( Vec_IntSize(vSupp) > 6 ) + return 0; Gia_ObjComputeTruth6( p, iObj, vSupp, vTemp ); return Abc_LitIsCompl(iLit) ? ~Vec_WrdEntry(vTemp, iObj) : Vec_WrdEntry(vTemp, iObj); } diff --git a/src/proof/acec/acecMult.c b/src/proof/acec/acecMult.c index 397f6d571..33c321443 100644 --- a/src/proof/acec/acecMult.c +++ b/src/proof/acec/acecMult.c @@ -389,7 +389,7 @@ Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec Vec_IntForEachEntry( vLevel, iLit, k ) { word Truth = Gia_ObjComputeTruth6Cis( p, iLit, vSupp, vTemp ); - if ( Vec_IntSize(vSupp) >= 4 ) + if ( Vec_IntSize(vSupp) >= 0 ) { printf( "Leaf = %4d : ", Abc_Lit2Var(iLit) ); printf( "Rank = %2d ", i ); diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index 53e1cb60f..8be8a3402 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -61,6 +61,65 @@ void Acec_BoxFreeP( Acec_Box_t ** ppBox ) *ppBox = NULL; } +/**Function************************************************************* + + Synopsis [Filters trees by removing TFO of roots.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_TreeFilterOne( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) +{ + Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Bit_t * vMarked = Vec_BitStart( Gia_ManObjNum(p) ) ; + Gia_Obj_t * pObj; + int i, k = 0, Box, Rank; + // mark roots + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 ); + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 ); + } + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+0), 0 ); + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+1), 0 ); + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+2), 0 ); + } + // iterate through nodes to detect TFO of roots + Gia_ManForEachAnd( p, pObj, i ) + { + if ( Vec_BitEntry(vIsRoot, Gia_ObjFaninId0(pObj,i)) || Vec_BitEntry(vIsRoot, Gia_ObjFaninId1(pObj,i)) || + Vec_BitEntry(vMarked, Gia_ObjFaninId0(pObj,i)) || Vec_BitEntry(vMarked, Gia_ObjFaninId1(pObj,i)) ) + Vec_BitWriteEntry( vMarked, i, 1 ); + } + // remove those that overlap with roots + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + if ( Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+3)) || Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+4)) ) + { + printf( "Removing box %d=(%d,%d) of rank %d.\n", Box, Vec_IntEntry(vAdds, 6*Box+3), Vec_IntEntry(vAdds, 6*Box+4), Rank ); + continue; + } + Vec_IntWriteEntry( vTree, k++, Box ); + Vec_IntWriteEntry( vTree, k++, Rank ); + } + Vec_IntShrink( vTree, k ); + Vec_BitFree( vIsRoot ); + Vec_BitFree( vMarked ); +} +void Acec_TreeFilterTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vTrees ) +{ + Vec_Int_t * vLevel; + int i; + Vec_WecForEachLevel( vTrees, vLevel, i ) + Acec_TreeFilterOne( p, vAdds, vLevel ); +} + /**Function************************************************************* Synopsis [Find internal cut points with exactly one adder fanin/fanout.] @@ -163,6 +222,8 @@ Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds ) } Vec_BitFree( vFound ); Vec_IntFree( vMap ); + // filter trees + Acec_TreeFilterTrees( p, vAdds, vTrees ); // sort by size Vec_WecSort( vTrees, 1 ); return vTrees; @@ -580,7 +641,7 @@ Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, int fVerbose ) Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); if ( pBox && fVerbose ) Acec_PrintBox( pBox, vAdds ); -// Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); + //Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); Vec_WecFreeP( &vTrees ); Vec_IntFree( vAdds ); return pBox; From 1a39fb39462d34e40e4ed9da4615d18a463471e0 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 13 Jan 2017 17:32:58 +0700 Subject: [PATCH 058/185] Adding print-out of critical path for mapped AIGs to &show. --- src/aig/gia/gia.h | 2 +- src/aig/gia/giaShow.c | 342 +++++++++++++++++++++++++++++++++++++++--- src/base/abci/abc.c | 15 +- src/opt/sbd/sbdPath.c | 54 +++++++ 4 files changed, 381 insertions(+), 32 deletions(-) diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 7cf1feff3..680601191 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1426,7 +1426,7 @@ extern Gia_Man_t * Gia_ManCleanupOutputs( Gia_Man_t * p, int nOutputs ); extern Gia_Man_t * Gia_ManSeqCleanup( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManSeqStructSweep( Gia_Man_t * p, int fConst, int fEquiv, int fVerbose ); /*=== giaShow.c ===========================================================*/ -extern void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds ); +extern void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds, int fPath ); /*=== giaShrink.c ===========================================================*/ extern Gia_Man_t * Gia_ManMapShrink4( Gia_Man_t * p, int fKeepLevel, int fVerbose ); extern Gia_Man_t * Gia_ManMapShrink6( Gia_Man_t * p, int nFanoutMax, int fKeepLevel, int fVerbose ); diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index 5589d3841..28e874bfd 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -46,40 +46,64 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold ) +void Gia_ShowPath( Gia_Man_t * p, char * pFileName ) { FILE * pFile; - Gia_Obj_t * pNode;//, * pTemp, * pPrev; - int LevelMax, Prev, Level, i; - int fConstIsUsed = 0; + Gia_Obj_t * pNode; + Vec_Bit_t * vPath = Vec_BitStart( Gia_ManObjNum(p) ); + int i, k, iFan, LevelMax, nLevels, * pLevels, Level, Prev; + int nLuts = 0, nNodes = 0, nEdges = 0, nEdgesAll = 0; + assert( Gia_ManHasMapping(p) ); - if ( Gia_ManAndNum(p) > 500 ) + // set critical CO drivers + nLevels = Gia_ManLutLevel( p, &pLevels ); + Gia_ManForEachCoDriverId( p, iFan, i ) + if ( pLevels[iFan] == nLevels ) + Vec_BitWriteEntry( vPath, iFan, 1 ); + + // set critical internal nodes + Gia_ManForEachLutReverse( p, i ) + { + nLuts++; + if ( !Vec_BitEntry(vPath, i) ) + continue; + nNodes++; + Gia_LutForEachFanin( p, i, iFan, k ) + { + if ( pLevels[iFan] +1 < pLevels[i] ) + continue; + assert( pLevels[iFan] + 1 == pLevels[i] ); + Vec_BitWriteEntry( vPath, iFan, 1 ); + nEdges++; + //printf( "%d -> %d\n", i, iFan ); + } + } + + if ( nNodes > 500 ) { - fprintf( stdout, "Cannot visualize AIG with more than 500 nodes.\n" ); + ABC_FREE( pLevels ); + Vec_BitFree( vPath ); + fprintf( stdout, "Cannot visualize AIG with more than 500 critical nodes.\n" ); return; } if ( (pFile = fopen( pFileName, "w" )) == NULL ) { + ABC_FREE( pLevels ); + Vec_BitFree( vPath ); fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName ); return; } - // mark the nodes - if ( vBold ) - Gia_ManForEachObjVec( vBold, p, pNode, i ) - pNode->fMark0 = 1; - else if ( p->nXors || p->nMuxes ) - Gia_ManForEachObj( p, pNode, i ) - if ( Gia_ObjIsXor(pNode) || Gia_ObjIsMux(p, pNode) ) - pNode->fMark0 = 1; + Vec_IntFreeP( &p->vLevels ); + p->vLevels = Vec_IntAllocArray( pLevels, Gia_ManObjNum(p) ); - // compute levels - LevelMax = 1 + Gia_ManLevelNum( p ); + // compute CO levels + LevelMax = 1 + nLevels; Gia_ManForEachCo( p, pNode, i ) Vec_IntWriteEntry( p->vLevels, Gia_ObjId(p, pNode), LevelMax ); // write the DOT header - fprintf( pFile, "# %s\n", "AIG structure generated by IVY package" ); + fprintf( pFile, "# %s\n", "AIG structure generated by GIA package" ); fprintf( pFile, "\n" ); fprintf( pFile, "digraph AIG {\n" ); fprintf( pFile, "size = \"7.5,10\";\n" ); @@ -153,7 +177,271 @@ void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold ) fprintf( pFile, " fontsize=18,\n" ); fprintf( pFile, " fontname = \"Times-Roman\",\n" ); fprintf( pFile, " label=\"" ); - fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Gia_ManAndNum(p), LevelMax ); + fprintf( pFile, "The critical path contains %d LUTs with %d critical edges and spans %d levels.", nNodes, nEdges, nLevels ); + fprintf( pFile, "\\n" ); + fprintf( pFile, "\"\n" ); + fprintf( pFile, " ];\n" ); + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate the COs + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + // the labeling node of this level + fprintf( pFile, " Level%d;\n", LevelMax ); + // generate the CO nodes + Gia_ManForEachCo( p, pNode, i ) + { + if ( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) < nLevels ) + continue; + assert( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) == nLevels ); + fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(p, pNode), Gia_ObjId(p, pNode) ); + fprintf( pFile, ", shape = %s", "invtriangle" ); + fprintf( pFile, ", color = coral, fillcolor = coral" ); + fprintf( pFile, "];\n" ); + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate nodes of each rank + for ( Level = LevelMax - 1; Level > 0; Level-- ) + { + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + // the labeling node of this level + fprintf( pFile, " Level%d;\n", Level ); + Gia_ManForEachObj( p, pNode, i ) + { + if ( (int)Gia_ObjLevel(p, pNode) != Level || !Vec_BitEntry(vPath, i) ) + continue; + fprintf( pFile, " Node%d [label = \"%d:%d\"", i, i, Gia_ObjIsAnd(pNode)? Gia_ObjLutSize(p, i) : 0 ); + fprintf( pFile, ", shape = ellipse" ); + if ( pNode->fMark0 ) + fprintf( pFile, ", style = filled" ); + fprintf( pFile, "];\n" ); + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + } + + // generate the CI nodes + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + // the labeling node of this level + fprintf( pFile, " Level%d;\n", 0 ); + // generate the CI nodes + Gia_ManForEachCi( p, pNode, i ) + { + if ( !Vec_BitEntry(vPath, Gia_ObjId(p, pNode)) ) + continue; + fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(p, pNode), Gia_ObjId(p, pNode) ); + fprintf( pFile, ", shape = %s", "triangle" ); + fprintf( pFile, ", color = coral, fillcolor = coral" ); + fprintf( pFile, "];\n" ); + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate invisible edges from the square down + fprintf( pFile, "title1 -> title2 [style = invis];\n" ); + Gia_ManForEachCo( p, pNode, i ) + { + if ( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) < nLevels ) + continue; + fprintf( pFile, "title2 -> Node%d [style = invis];\n", Gia_ObjId(p, pNode) ); + } + // generate invisible edges among the COs + Prev = -1; + Gia_ManForEachCo( p, pNode, i ) + { + if ( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) < nLevels ) + continue; + assert( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) == nLevels ); + if ( Prev >= 0 ) + fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Gia_ObjId(p, pNode) ); + Prev = Gia_ObjId(p, pNode); + } + // generate invisible edges among the CIs + Prev = -1; + Gia_ManForEachCi( p, pNode, i ) + { + if ( !Vec_BitEntry(vPath, Gia_ObjId(p, pNode)) ) + continue; + if ( Prev >= 0 ) + fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Gia_ObjId(p, pNode) ); + Prev = Gia_ObjId(p, pNode); + } + + // generate edges + Gia_ManForEachObj( p, pNode, i ) + { + if ( Gia_ObjIsCo(pNode) ) + { + if ( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) == nLevels ) + { + // generate the edge from this node to the next + fprintf( pFile, "Node%d", i ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", Gia_ObjFaninId0p(p, pNode) ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", "bold" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + } + continue; + } + if ( !Gia_ObjIsAnd(pNode) || !Vec_BitEntry(vPath, i) ) + continue; + Gia_LutForEachFanin( p, i, iFan, k ) + { + if ( pLevels[iFan] + 1 < pLevels[i] ) + continue; + assert( pLevels[iFan] + 1 == pLevels[i] ); + // generate the edge from this node to the next + fprintf( pFile, "Node%d", i ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", iFan ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", "bold" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + } + } + + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + fclose( pFile ); + + Vec_IntFreeP( &p->vLevels ); + Vec_BitFree( vPath ); +} + + +/**Function************************************************************* + + Synopsis [Writes the graph structure of AIG for DOT.] + + Description [Useful for graph visualization using tools such as GraphViz: + http://www.graphviz.org/] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold ) +{ + FILE * pFile; + Gia_Obj_t * pNode;//, * pTemp, * pPrev; + int LevelMax, Prev, Level, i; + int fConstIsUsed = 0; + + if ( Gia_ManAndNum(p) > 500 ) + { + fprintf( stdout, "Cannot visualize AIG with more than 500 nodes.\n" ); + return; + } + if ( (pFile = fopen( pFileName, "w" )) == NULL ) + { + fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName ); + return; + } + + // mark the nodes + if ( vBold ) + Gia_ManForEachObjVec( vBold, p, pNode, i ) + pNode->fMark0 = 1; + else if ( p->nXors || p->nMuxes ) + Gia_ManForEachObj( p, pNode, i ) + if ( Gia_ObjIsXor(pNode) || Gia_ObjIsMux(p, pNode) ) + pNode->fMark0 = 1; + + // compute levels + LevelMax = 1 + Gia_ManLevelNum( p ); + Gia_ManForEachCo( p, pNode, i ) + Vec_IntWriteEntry( p->vLevels, Gia_ObjId(p, pNode), LevelMax ); + + // write the DOT header + fprintf( pFile, "# %s\n", "AIG structure generated by GIA package" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "digraph AIG {\n" ); + fprintf( pFile, "size = \"7.5,10\";\n" ); +// fprintf( pFile, "ranksep = 0.5;\n" ); +// fprintf( pFile, "nodesep = 0.5;\n" ); + fprintf( pFile, "center = true;\n" ); +// fprintf( pFile, "orientation = landscape;\n" ); +// fprintf( pFile, "edge [fontsize = 10];\n" ); +// fprintf( pFile, "edge [dir = none];\n" ); + fprintf( pFile, "edge [dir = back];\n" ); + fprintf( pFile, "\n" ); + + // labels on the left of the picture + fprintf( pFile, "{\n" ); + fprintf( pFile, " node [shape = plaintext];\n" ); + fprintf( pFile, " edge [style = invis];\n" ); + fprintf( pFile, " LevelTitle1 [label=\"\"];\n" ); + fprintf( pFile, " LevelTitle2 [label=\"\"];\n" ); + // generate node names with labels + for ( Level = LevelMax; Level >= 0; Level-- ) + { + // the visible node name + fprintf( pFile, " Level%d", Level ); + fprintf( pFile, " [label = " ); + // label name + fprintf( pFile, "\"" ); + fprintf( pFile, "\"" ); + fprintf( pFile, "];\n" ); + } + + // genetate the sequence of visible/invisible nodes to mark levels + fprintf( pFile, " LevelTitle1 -> LevelTitle2 ->" ); + for ( Level = LevelMax; Level >= 0; Level-- ) + { + // the visible node name + fprintf( pFile, " Level%d", Level ); + // the connector + if ( Level != 0 ) + fprintf( pFile, " ->" ); + else + fprintf( pFile, ";" ); + } + fprintf( pFile, "\n" ); + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate title box on top + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + fprintf( pFile, " LevelTitle1;\n" ); + fprintf( pFile, " title1 [shape=plaintext,\n" ); + fprintf( pFile, " fontsize=20,\n" ); + fprintf( pFile, " fontname = \"Times-Roman\",\n" ); + fprintf( pFile, " label=\"" ); + fprintf( pFile, "%s", "AIG structure visualized by ABC" ); + fprintf( pFile, "\\n" ); + fprintf( pFile, "Benchmark \\\"%s\\\". ", "aig" ); +// fprintf( pFile, "Time was %s. ", Extra_TimeStamp() ); + fprintf( pFile, "\"\n" ); + fprintf( pFile, " ];\n" ); + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate statistics box + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + fprintf( pFile, " LevelTitle2;\n" ); + fprintf( pFile, " title2 [shape=plaintext,\n" ); + fprintf( pFile, " fontsize=18,\n" ); + fprintf( pFile, " fontname = \"Times-Roman\",\n" ); + fprintf( pFile, " label=\"" ); + fprintf( pFile, "The AIG contains %d nodes and spans %d levels.", Gia_ManAndNum(p), LevelMax-1 ); fprintf( pFile, "\\n" ); fprintf( pFile, "\"\n" ); fprintf( pFile, " ];\n" ); @@ -388,6 +676,7 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In Gia_Obj_t * pNode;//, * pTemp, * pPrev; int LevelMax, Prev, Level, i; int fConstIsUsed = 0; + int nFadds = Ree_ManCountFadds( vAdds ); if ( Gia_ManAndNum(p) > 1000 ) { @@ -406,7 +695,7 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In Vec_IntWriteEntry( p->vLevels, Gia_ObjId(p, pNode), LevelMax ); // write the DOT header - fprintf( pFile, "# %s\n", "AIG structure generated by IVY package" ); + fprintf( pFile, "# %s\n", "AIG structure generated by GIA package" ); fprintf( pFile, "\n" ); fprintf( pFile, "digraph AIG {\n" ); fprintf( pFile, "size = \"7.5,10\";\n" ); @@ -480,7 +769,8 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In fprintf( pFile, " fontsize=18,\n" ); fprintf( pFile, " fontname = \"Times-Roman\",\n" ); fprintf( pFile, " label=\"" ); - fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Gia_ManAndNum(p), LevelMax ); + fprintf( pFile, "The AIG contains %d nodes, %d full-adders, and %d half-adders, and spans %d levels.", + Gia_ManAndNum(p), nFadds, Vec_IntSize(vAdds)/6-nFadds, LevelMax-1 ); fprintf( pFile, "\\n" ); fprintf( pFile, "\"\n" ); fprintf( pFile, " ];\n" ); @@ -813,12 +1103,12 @@ void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In Vec_IntFree( vMapXors ); Vec_IntFree( vOrder ); } -void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds ) +void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds, int fPath ) { extern void Abc_ShowFile( char * FileNameDot ); char FileNameDot[200]; FILE * pFile; - Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( pMan, &vXors, 0 ); + Vec_Int_t * vXors = NULL, * vAdds = fAdders ? Ree_ManComputeCuts( pMan, &vXors, 0 ) : NULL; sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(pMan->pName, ".dot") ); // check that the file can be opened if ( (pFile = fopen( FileNameDot, "w" )) == NULL ) @@ -828,15 +1118,17 @@ void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds ) } fclose( pFile ); // generate the file - if ( fAdders ) + if ( fPath ) + Gia_ShowPath( pMan, FileNameDot ); + else if ( fAdders ) Gia_ShowProcess( pMan, FileNameDot, vAdds, vXors, fFadds ); else Gia_WriteDotAigSimple( pMan, FileNameDot, vBold ); // visualize the file Abc_ShowFile( FileNameDot ); - Vec_IntFree( vAdds ); - Vec_IntFree( vXors ); + Vec_IntFreeP( &vAdds ); + Vec_IntFreeP( &vXors ); } diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 20d44227e..910014c6d 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -28594,9 +28594,9 @@ usage: int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv ) { Vec_Int_t * vBold = NULL; - int c, fAdders = 0, fFadds = 0; + int c, fAdders = 0, fFadds = 0, fPath = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "afh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "afph" ) ) != EOF ) { switch ( c ) { @@ -28606,6 +28606,9 @@ int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'f': fFadds ^= 1; break; + case 'p': + fPath ^= 1; + break; case 'h': goto usage; default: @@ -28628,15 +28631,16 @@ int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv ) Gia_ManForEachLut( pAbc->pGia, c ) Vec_IntPush( vBold, c ); } - Gia_ManShow( pAbc->pGia, vBold, fAdders, fFadds ); + Gia_ManShow( pAbc->pGia, vBold, fAdders, fFadds, fPath ); Vec_IntFreeP( &vBold ); return 0; usage: - Abc_Print( -2, "usage: &show [-afh]\n" ); + Abc_Print( -2, "usage: &show [-afph]\n" ); Abc_Print( -2, "\t shows the current GIA using GSView\n" ); Abc_Print( -2, "\t-a : toggle visualazing adders [default = %s]\n", fAdders? "yes": "no" ); - Abc_Print( -2, "\t-f : toggle only showing full-adders with \"-a\" [default = %s]\n", fFadds? "yes": "no" ); + Abc_Print( -2, "\t-f : toggle showing only full-adders with \"-a\" [default = %s]\n", fFadds? "yes": "no" ); + Abc_Print( -2, "\t-p : toggle showing the critical path of a LUT mapping [default = %s]\n", fPath? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } @@ -42679,7 +42683,6 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv ) // Gia_ManCheckFalseTest( pAbc->pGia, nFrames ); // Gia_ParTest( pAbc->pGia, nWords, nProcs ); // Gia_PolynExplore( pAbc->pGia ); -// Gia_ManTestSatEnum( pAbc->pGia ); // printf( "\nThis command is currently disabled.\n\n" ); return 0; diff --git a/src/opt/sbd/sbdPath.c b/src/opt/sbd/sbdPath.c index a2b1a9b00..270c81c8f 100644 --- a/src/opt/sbd/sbdPath.c +++ b/src/opt/sbd/sbdPath.c @@ -134,6 +134,60 @@ Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p ) } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sbc_ManDelayTrace( Gia_Man_t * p ) +{ + Vec_Bit_t * vPath = Vec_BitStart( Gia_ManObjNum(p) ); + int i, k, iFan, nLevels, * pLevels; + int nLuts = 0, nNodes = 0, nEdges = 0, nEdgesAll = 0; + if ( !Gia_ManHasMapping(p) ) + { + printf( "No mapping is available.\n" ); + return; + } + assert( Gia_ManHasMapping(p) ); + // set critical CO drivers + nLevels = Gia_ManLutLevel( p, &pLevels ); + Gia_ManForEachCoDriverId( p, iFan, i ) + if ( pLevels[iFan] == nLevels ) + Vec_BitWriteEntry( vPath, iFan, 1 ); + // set critical internal nodes + Gia_ManForEachLutReverse( p, i ) + { + nLuts++; + if ( !Vec_BitEntry(vPath, i) ) + continue; + nNodes++; + Gia_LutForEachFanin( p, i, iFan, k ) + { + if ( pLevels[iFan] +1 < pLevels[i] ) + continue; + assert( pLevels[iFan] + 1 == pLevels[i] ); + Vec_BitWriteEntry( vPath, iFan, 1 ); + nEdges++; + //printf( "%d -> %d\n", i, iFan ); + } + } + Gia_ManForEachLut( p, i ) + Gia_LutForEachFanin( p, i, iFan, k ) + nEdgesAll += (Vec_BitEntry(vPath, i) && Vec_BitEntry(vPath, iFan)); + + ABC_FREE( pLevels ); + Vec_BitFree( vPath ); + printf( "AIG = %d. LUT = %d. Lev = %d. Path nodes = %d. Path edges = %d. (%d.)\n", + Gia_ManAndNum(p), nLuts, nLevels, nNodes, nEdges, nEdgesAll ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// From 6d606b51ab084c96d92848be789397700bb3591f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 13 Jan 2017 21:17:00 +0700 Subject: [PATCH 059/185] Updates to arithmetic verification. --- src/aig/gia/giaShow.c | 28 ++- src/base/wlc/wlcBlast.c | 10 + src/proof/acec/acecInt.h | 3 - src/proof/acec/acecMult.c | 107 +++++++++ src/proof/acec/acecTree.c | 456 ++++++++++++++++---------------------- 5 files changed, 326 insertions(+), 278 deletions(-) diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index 28e874bfd..cf89d942d 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -52,7 +52,7 @@ void Gia_ShowPath( Gia_Man_t * p, char * pFileName ) Gia_Obj_t * pNode; Vec_Bit_t * vPath = Vec_BitStart( Gia_ManObjNum(p) ); int i, k, iFan, LevelMax, nLevels, * pLevels, Level, Prev; - int nLuts = 0, nNodes = 0, nEdges = 0, nEdgesAll = 0; + int nLuts = 0, nNodes = 0, nEdges = 0; assert( Gia_ManHasMapping(p) ); // set critical CO drivers @@ -670,7 +670,7 @@ int Gia_ShowAddOut( Vec_Int_t * vAdds, Vec_Int_t * vMapAdds, int Node ) return Vec_IntEntry( vAdds, 6*iBox+4 ); return Node; } -void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_Int_t * vXors, Vec_Int_t * vMapAdds, Vec_Int_t * vMapXors, Vec_Int_t * vOrder ) +void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_Int_t * vAdds, Vec_Int_t * vXors, Vec_Int_t * vMapAdds, Vec_Int_t * vMapXors, Vec_Int_t * vOrder ) { FILE * pFile; Gia_Obj_t * pNode;//, * pTemp, * pPrev; @@ -689,6 +689,11 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In return; } + // mark the nodes + if ( vBold ) + Gia_ManForEachObjVec( vBold, p, pNode, i ) + pNode->fMark0 = 1; + // compute levels LevelMax = 1 + p->nLevels; Gia_ManForEachCo( p, pNode, i ) @@ -819,7 +824,7 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In else fprintf( pFile, ", shape = ellipse" ); */ - if ( Vec_IntEntry(vMapAdds, iNode) >= 0 ) + if ( !pNode->fMark0 && Vec_IntEntry(vMapAdds, iNode) >= 0 ) { int iBox = Vec_IntEntry(vMapAdds, iNode); fprintf( pFile, " Node%d [label = \"%d_%d\"", Gia_ShowAddOut(vAdds, vMapAdds, iNode), Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) ); @@ -848,8 +853,8 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In fprintf( pFile, " Node%d [label = \"%d\"", iNode, iNode ); fprintf( pFile, ", shape = ellipse" ); } -// if ( pNode->fMark0 ) -// fprintf( pFile, ", style = filled" ); + if ( pNode->fMark0 ) + fprintf( pFile, ", style = filled" ); fprintf( pFile, "];\n" ); } fprintf( pFile, "}" ); @@ -920,8 +925,6 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In Gia_ManForEachObjVec( vOrder, p, pNode, i ) { int iNode = Gia_ObjId( p, pNode ); -// if ( !Gia_ObjIsAnd(pNode) && !Gia_ObjIsCo(pNode) && !Gia_ObjIsBuf(pNode) ) -// continue; if ( Vec_IntEntry(vMapAdds, Gia_ObjId(p, pNode)) >= 0 ) { int k, iBox = Vec_IntEntry(vMapAdds, iNode); @@ -990,6 +993,11 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In fprintf( pFile, "\n" ); fclose( pFile ); + // unmark nodes + if ( vBold ) + Gia_ManForEachObjVec( vBold, p, pNode, i ) + pNode->fMark0 = 0; + Vec_IntFreeP( &p->vLevels ); } @@ -1093,12 +1101,12 @@ Vec_Int_t * Gia_ShowCollectObjs( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * v SeeAlso [] ***********************************************************************/ -void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_Int_t * vXors, int fFadds ) +void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_Int_t * vAdds, Vec_Int_t * vXors, int fFadds ) { Vec_Int_t * vMapAdds = Gia_ShowMapAdds( p, vAdds, fFadds ); Vec_Int_t * vMapXors = Gia_ShowMapXors( p, vXors ); Vec_Int_t * vOrder = Gia_ShowCollectObjs( p, vAdds, vXors, vMapAdds, vMapXors ); - Gia_WriteDotAig( p, pFileName, vAdds, vXors, vMapAdds, vMapXors, vOrder ); + Gia_WriteDotAig( p, pFileName, vBold, vAdds, vXors, vMapAdds, vMapXors, vOrder ); Vec_IntFree( vMapAdds ); Vec_IntFree( vMapXors ); Vec_IntFree( vOrder ); @@ -1121,7 +1129,7 @@ void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds, if ( fPath ) Gia_ShowPath( pMan, FileNameDot ); else if ( fAdders ) - Gia_ShowProcess( pMan, FileNameDot, vAdds, vXors, fFadds ); + Gia_ShowProcess( pMan, FileNameDot, vBold, vAdds, vXors, fFadds ); else Gia_WriteDotAigSimple( pMan, FileNameDot, vBold ); // visualize the file diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index b22ac6cdc..b49c2dd7b 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -645,10 +645,20 @@ void Wlc_IntInsert( Vec_Int_t * vProd, Vec_Int_t * vLevel, int Node, int Level ) } void Wlc_BlastPrintMatrix( Gia_Man_t * p, Vec_Wec_t * vProds ) { + int fVerbose = 0; Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); Vec_Int_t * vLevel; word Truth; int i, k, iLit; + Vec_WecForEachLevel( vProds, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + if ( Gia_ObjIsAnd(Gia_ManObj(p, Abc_Lit2Var(iLit))) ) + Vec_IntPushUnique( vSupp, Abc_Lit2Var(iLit) ); + printf( "Booth partial products: %d pps, %d unique, %d nodes.\n", + Vec_WecSizeSize(vProds), Vec_IntSize(vSupp), Gia_ManAndNum(p) ); + Vec_IntPrint( vSupp ); + + if ( fVerbose ) Vec_WecForEachLevel( vProds, vLevel, i ) Vec_IntForEachEntry( vLevel, iLit, k ) { diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index 0dc3f7060..125d923fa 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -42,13 +42,10 @@ struct Acec_Box_t_ { Gia_Man_t * pGia; // AIG manager Vec_Wec_t * vAdds; // adders by rank - Vec_Wec_t * vLeafs; // leaf literals by rank - Vec_Wec_t * vRoots; // root literals by rank Vec_Wec_t * vLeafLits; // leaf literals by rank Vec_Wec_t * vRootLits; // root literals by rank Vec_Wec_t * vShared; // shared leaves Vec_Wec_t * vUnique; // unique leaves - Vec_Bit_t * vInvHadds; // complemented half adders }; //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/acec/acecMult.c b/src/proof/acec/acecMult.c index 33c321443..8ccf966ef 100644 --- a/src/proof/acec/acecMult.c +++ b/src/proof/acec/acecMult.c @@ -20,6 +20,7 @@ #include "acecInt.h" #include "misc/extra/extra.h" +#include "misc/util/utilTruth.h" ABC_NAMESPACE_IMPL_START @@ -400,6 +401,15 @@ Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec if ( Vec_IntSize(vSupp) <= 2 ) printf( " " ); printf( " " ); Vec_IntPrint( vSupp ); + /* + if ( Truth == 0xF335ACC0F335ACC0 ) + { + int iObj = Abc_Lit2Var(iLit); + Gia_Man_t * pGia0 = Gia_ManDupAndCones( p, &iObj, 1, 1 ); + Gia_ManShow( pGia0, NULL, 0, 0, 0 ); + Gia_ManStop( pGia0 ); + } + */ } // support rank counts Vec_IntForEachEntry( vSupp, Entry, j ) @@ -423,6 +433,103 @@ Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec return vInputs; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_MultFindPPs_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vBold ) +{ + Gia_Obj_t * pObj; + pObj = Gia_ManObj( p, iObj ); + if ( pObj->fMark0 ) + return; + pObj->fMark0 = 1; + if ( !Gia_ObjIsAnd(pObj) ) + return; + Acec_MultFindPPs_rec( p, Gia_ObjFaninId0(pObj, iObj), vBold ); + Acec_MultFindPPs_rec( p, Gia_ObjFaninId1(pObj, iObj), vBold ); + Vec_IntPush( vBold, iObj ); +} +Vec_Int_t * Acec_MultFindPPs( Gia_Man_t * p ) +{ + word Saved[32] = { + ABC_CONST(0xF335ACC0F335ACC0), + ABC_CONST(0x35C035C035C035C0), + ABC_CONST(0xD728D728D728D728), + ABC_CONST(0xFD80FD80FD80FD80), + ABC_CONST(0xACC0ACC0ACC0ACC0), + ABC_CONST(0x7878787878787878), + ABC_CONST(0x2828282828282828), + ABC_CONST(0xD0D0D0D0D0D0D0D0), + ABC_CONST(0x8080808080808080), + ABC_CONST(0x8888888888888888), + ABC_CONST(0xAAAAAAAAAAAAAAAA), + ABC_CONST(0x5555555555555555), + + ABC_CONST(0xD5A8D5A8D5A8D5A8), + ABC_CONST(0x2A572A572A572A57), + ABC_CONST(0xF3C0F3C0F3C0F3C0), + ABC_CONST(0x5858585858585858), + ABC_CONST(0xA7A7A7A7A7A7A7A7), + ABC_CONST(0x2727272727272727), + ABC_CONST(0xD8D8D8D8D8D8D8D8) + }; + + Vec_Int_t * vBold = Vec_IntAlloc( 100 ); + Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); + Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); + int i, iObj, nProds = 0; + Gia_ManCleanMark0(p); + Gia_ManForEachAndId( p, iObj ) + { + word Truth = Gia_ObjComputeTruth6Cis( p, Abc_Var2Lit(iObj, 0), vSupp, vTemp ); + vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize ); + if ( Vec_IntSize(vSupp) > 5 ) + continue; + for ( i = 0; i < 32; i++ ) + { + if ( Saved[i] == 0 ) + break; + if ( Truth == Saved[i] || Truth == ~Saved[i] ) + { + //Vec_IntPush( vBold, iObj ); + Acec_MultFindPPs_rec( p, iObj, vBold ); + printf( "%d ", iObj ); + nProds++; + break; + } + } +/* + Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) ); + if ( Vec_IntSize(vSupp) == 4 ) printf( " " ); + if ( Vec_IntSize(vSupp) == 3 ) printf( " " ); + if ( Vec_IntSize(vSupp) <= 2 ) printf( " " ); + printf( " " ); + Vec_IntPrint( vSupp ); +*/ + } + printf( "\n" ); + Gia_ManCleanMark0(p); + printf( "Collected %d pps and %d nodes.\n", nProds, Vec_IntSize(vBold) ); + + Vec_IntFree( vSupp ); + Vec_WrdFree( vTemp ); + return vBold; +} +void Acec_MultFindPPsTest( Gia_Man_t * p ) +{ + Vec_Int_t * vBold = Acec_MultFindPPs( p ); + Gia_ManShow( p, vBold, 1, 0, 0 ); + Vec_IntFree( vBold ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index 8be8a3402..370e8eb65 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -45,13 +45,10 @@ ABC_NAMESPACE_IMPL_START void Acec_BoxFree( Acec_Box_t * pBox ) { Vec_WecFreeP( &pBox->vAdds ); - Vec_WecFreeP( &pBox->vLeafs ); - Vec_WecFreeP( &pBox->vRoots ); Vec_WecFreeP( &pBox->vLeafLits ); Vec_WecFreeP( &pBox->vRootLits ); Vec_WecFreeP( &pBox->vUnique ); Vec_WecFreeP( &pBox->vShared ); - Vec_BitFreeP( &pBox->vInvHadds ); ABC_FREE( pBox ); } void Acec_BoxFreeP( Acec_Box_t ** ppBox ) @@ -120,6 +117,141 @@ void Acec_TreeFilterTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vTrees Acec_TreeFilterOne( p, vAdds, vLevel ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_TreeVerifyPhaseOne_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + int Truth0, Truth1; + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return pObj->Value; + Gia_ObjSetTravIdCurrent(p, pObj); + assert( Gia_ObjIsAnd(pObj) ); + assert( !Gia_ObjIsXor(pObj) ); + Truth0 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin0(pObj) ); + Truth1 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin1(pObj) ); + Truth0 = Gia_ObjFaninC0(pObj) ? 0xFF & ~Truth0 : Truth0; + Truth1 = Gia_ObjFaninC1(pObj) ? 0xFF & ~Truth1 : Truth1; + return (pObj->Value = Truth0 & Truth1); +} +void Acec_TreeVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox ) +{ + Gia_Obj_t * pObj; + unsigned TruthXor, TruthMaj, Truths[3] = { 0xAA, 0xCC, 0xF0 }; + int k, iObj, fFadd = Vec_IntEntry(vAdds, 6*iBox+2) > 0; + + int Sign = Vec_IntEntry( vAdds, 6*iBox+5 ), Phase[5]; + for ( k = 0; k < 5; k++ ) + Phase[k] = (Sign >> (4+k)) & 1; + + Gia_ManIncrementTravId( p ); + for ( k = 0; k < 3; k++ ) + { + iObj = Vec_IntEntry( vAdds, 6*iBox+k ); + if ( iObj == 0 ) + continue; + pObj = Gia_ManObj( p, iObj ); + pObj->Value = Phase[k] ? 0xFF & ~Truths[k] : Truths[k]; + Gia_ObjSetTravIdCurrent( p, pObj ); + } + + iObj = Vec_IntEntry( vAdds, 6*iBox+3 ); + TruthXor = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) ); + TruthXor = Phase[3] ? 0xFF & ~TruthXor : TruthXor; + + iObj = Vec_IntEntry( vAdds, 6*iBox+4 ); + TruthMaj = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) ); + TruthMaj = Phase[4] ? 0xFF & ~TruthMaj : TruthMaj; + + if ( fFadd ) // FADD + { + if ( TruthXor != 0x96 ) + printf( "Fadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) ); + if ( TruthMaj != 0xE8 ) + printf( "Fadd %d carry %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+4 ) ); + } + else + { + if ( TruthXor != 0x66 ) + printf( "Hadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) ); + if ( TruthMaj != 0x88 ) + printf( "Hadd %d carry %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+4 ) ); + } +} +void Acec_TreeVerifyPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ) +{ + Vec_Int_t * vLevel; + int i, k, Box; + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + Acec_TreeVerifyPhaseOne( p, vAdds, Box ); +} + +/**Function************************************************************* + + Synopsis [Creates polarity.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Acec_TreeCarryMap( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ) +{ + Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; + int i, k, Box; + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + Vec_IntWriteEntry( vMap, Vec_IntEntry(vAdds, 6*Box+4), Box ); + return vMap; +} +void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, int Node, int fPhase ) +{ + int k, iBox, iXor, Sign, fXorPhase, fPhaseThis; + assert( Node != 0 ); + iBox = Vec_IntEntry( vMap, Node ); + if ( iBox == -1 ) + return; + assert( Node == Vec_IntEntry( vAdds, 6*iBox+4 ) ); + iXor = Vec_IntEntry( vAdds, 6*iBox+3 ); + Sign = Vec_IntEntry( vAdds, 6*iBox+5 ) & 0xFFFFFFF0; + fXorPhase = ((Sign >> 3) & 1); + if ( Vec_IntEntry(vAdds, 6*iBox+2) == 0 ) + { + fPhase ^= ((Sign >> 2) & 1); + if ( fPhase ) // complemented HADD + Sign |= (1 << 6); + } + for ( k = 0; k < 3; k++ ) + { + int iObj = Vec_IntEntry( vAdds, 6*iBox+k ); + if ( iObj == 0 ) + continue; + fPhaseThis = ((Sign >> k) & 1) ^ fPhase; + fXorPhase ^= fPhaseThis; + Acec_TreePhases_rec( p, vAdds, vMap, iObj, fPhaseThis ); + if ( fPhaseThis ) + Sign |= (1 << (4+k)); + } + if ( fXorPhase ) + Sign |= (1 << 7); + if ( fPhase ) + Sign |= (1 << 8); + // save updated signature + Vec_IntWriteEntry( vAdds, 6*iBox+5, Sign ); +} + /**Function************************************************************* Synopsis [Find internal cut points with exactly one adder fanin/fanout.] @@ -249,256 +381,6 @@ void Acec_TreeFindTreesTest( Gia_Man_t * p ) } -/**Function************************************************************* - - Synopsis [Creates leaves and roots.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Acec_CreateBoxMaxRank( Vec_Int_t * vTree ) -{ - int k, Box, Rank, MaxRank = 0; - Vec_IntForEachEntryDouble( vTree, Box, Rank, k ) - MaxRank = Abc_MaxInt( MaxRank, Rank ); - return MaxRank; -} -void Acec_TreeInsOuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_Wec_t * vBoxes, Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots ) -{ - Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); - Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); - Vec_Int_t * vLevel; - int i, k, Box, Rank; - Vec_BitWriteEntry( vIsLeaf, 0, 1 ); - Vec_BitWriteEntry( vIsRoot, 0, 1 ); - Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) - { - Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 ); - Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 ); - Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 ); - Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 ); - Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 ); - } - Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) - { - Vec_WecPush( vBoxes, Rank, Box ); - for ( k = 0; k < 3; k++ ) - { - if ( Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) ) - continue; - Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k), 1 ); - Vec_WecPush( vLeaves, Rank, Vec_IntEntry(vAdds, 6*Box+k) ); - } - for ( k = 3; k < 5; k++ ) - { - if ( Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) ) - continue; - Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k), 1 ); - Vec_WecPush( vRoots, k == 4 ? Rank + 1 : Rank, Abc_Var2Lit(Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), k==4), Vec_IntEntry(vAdds, 6*Box+2)!=0) ); - } - } - Vec_BitFree( vIsLeaf ); - Vec_BitFree( vIsRoot ); - // sort each level - Vec_WecForEachLevel( vBoxes, vLevel, i ) - Vec_IntSort( vLevel, 0 ); - Vec_WecForEachLevel( vLeaves, vLevel, i ) - Vec_IntSort( vLevel, 0 ); - Vec_WecForEachLevel( vRoots, vLevel, i ) - Vec_IntSort( vLevel, 0 ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Acec_TreeVerifyPhaseOne_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) -{ - int Truth0, Truth1; - if ( Gia_ObjIsTravIdCurrent(p, pObj) ) - return pObj->Value; - Gia_ObjSetTravIdCurrent(p, pObj); - assert( Gia_ObjIsAnd(pObj) ); - assert( !Gia_ObjIsXor(pObj) ); - Truth0 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin0(pObj) ); - Truth1 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin1(pObj) ); - Truth0 = Gia_ObjFaninC0(pObj) ? 0xFF & ~Truth0 : Truth0; - Truth1 = Gia_ObjFaninC1(pObj) ? 0xFF & ~Truth1 : Truth1; - return (pObj->Value = Truth0 & Truth1); -} -void Acec_TreeVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox, Vec_Bit_t * vPhase ) -{ - Gia_Obj_t * pObj; - unsigned TruthXor, TruthMaj, Truths[3] = { 0xAA, 0xCC, 0xF0 }; - int k, iObj, fFadd = Vec_IntEntry(vAdds, 6*iBox+2) > 0; - - //if ( !fFadd ) - // return; - - Gia_ManIncrementTravId( p ); - for ( k = 0; k < 3; k++ ) - { - iObj = Vec_IntEntry( vAdds, 6*iBox+k ); - if ( iObj == 0 ) - continue; - pObj = Gia_ManObj( p, iObj ); - pObj->Value = Vec_BitEntry(vPhase, iObj) ? 0xFF & ~Truths[k] : Truths[k]; - Gia_ObjSetTravIdCurrent( p, pObj ); - } - - iObj = Vec_IntEntry( vAdds, 6*iBox+3 ); - TruthXor = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) ); - TruthXor = Vec_BitEntry(vPhase, iObj) ? 0xFF & ~TruthXor : TruthXor; - - iObj = Vec_IntEntry( vAdds, 6*iBox+4 ); - TruthMaj = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) ); - TruthMaj = Vec_BitEntry(vPhase, iObj) ? 0xFF & ~TruthMaj : TruthMaj; - - if ( fFadd ) // FADD - { - if ( TruthXor != 0x96 ) - printf( "Fadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) ); - if ( TruthMaj != 0xE8 ) - printf( "Fadd %d carry %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+4 ) ); - } - else - { - if ( TruthXor != 0x66 ) - printf( "Hadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) ); - if ( TruthMaj != 0x88 ) - printf( "Hadd %d carry %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+4 ) ); - } -} -void Acec_TreeVerifyPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes, Vec_Bit_t * vPhase ) -{ - Vec_Int_t * vLevel; - int i, k, Box; - Vec_WecForEachLevel( vBoxes, vLevel, i ) - Vec_IntForEachEntry( vLevel, Box, k ) - Acec_TreeVerifyPhaseOne( p, vAdds, Box, vPhase ); -} - -/**Function************************************************************* - - Synopsis [Creates polarity.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Acec_TreeCarryMap( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ) -{ - Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); - Vec_Int_t * vLevel; - int i, k, Box; - Vec_WecForEachLevel( vBoxes, vLevel, i ) - Vec_IntForEachEntry( vLevel, Box, k ) - Vec_IntWriteEntry( vMap, Vec_IntEntry(vAdds, 6*Box+4), Box ); - return vMap; -} -void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, int Node, int fPhase, - Vec_Bit_t * vPhase, Vec_Bit_t * vInvHadds, Vec_Bit_t * vVisit ) -{ - int k, iBox, iXor, Sign, fXorPhase, fPhaseThis; - assert( Node != 0 ); - if ( Vec_BitEntry(vVisit, Node) ) - { - //assert( Vec_BitEntry(vPhase, Node) == fPhase ); - if ( Vec_BitEntry(vPhase, Node) != fPhase ) - printf( "Phase check failed for node %d.\n", Node ); - return; - } - Vec_BitWriteEntry( vVisit, Node, 1 ); - if ( fPhase ) - Vec_BitWriteEntry( vPhase, Node, fPhase ); - iBox = Vec_IntEntry( vMap, Node ); - if ( iBox == -1 ) - return; - assert( Node == Vec_IntEntry( vAdds, 6*iBox+4 ) ); - iXor = Vec_IntEntry( vAdds, 6*iBox+3 ); - Sign = Vec_IntEntry( vAdds, 6*iBox+5 ); - fXorPhase = ((Sign >> 3) & 1); - if ( Vec_IntEntry(vAdds, 6*iBox+2) == 0 ) - { - fPhase ^= ((Sign >> 2) & 1); - // remember complemented HADD - if ( fPhase ) - Vec_BitWriteEntry( vInvHadds, iBox, 1 ); - } - for ( k = 0; k < 3; k++ ) - { - int iObj = Vec_IntEntry( vAdds, 6*iBox+k ); - if ( iObj == 0 ) - continue; - fPhaseThis = ((Sign >> k) & 1) ^ fPhase; - fXorPhase ^= fPhaseThis; - Acec_TreePhases_rec( p, vAdds, vMap, iObj, fPhaseThis, vPhase, vInvHadds, vVisit ); - } - if ( Vec_BitEntry(vVisit, iXor) ) - { - //assert( Vec_BitEntry(vPhase, iXor) == fXorPhase ); - if ( Vec_BitEntry(vPhase, iXor) != fXorPhase ) - printf( "Phase check failed for XOR %d.\n", iXor ); - return; - } - if ( fXorPhase ) - Vec_BitWriteEntry( vPhase, iXor, fXorPhase ); -} -void Acec_TreePhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes, - Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots, - Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits, Vec_Bit_t * vInvHadds ) -{ - Vec_Int_t * vMap = Acec_TreeCarryMap( p, vAdds, vBoxes ); - Vec_Bit_t * vPhase = Vec_BitStart( Gia_ManObjNum(p) ); - Vec_Bit_t * vVisit = Vec_BitStart( Gia_ManObjNum(p) ); - Vec_Int_t * vLevel; - int i, k, iObj; - Vec_WecForEachLevelReverse( vRoots, vLevel, i ) - { - Vec_IntForEachEntry( vLevel, iObj, k ) - { - int fFadd = Abc_LitIsCompl(iObj); - int fCout = Abc_LitIsCompl(Abc_Lit2Var(iObj)); - int Node = Abc_Lit2Var(Abc_Lit2Var(iObj)); - if ( !fCout ) - continue; - Acec_TreePhases_rec( p, vAdds, vMap, Node, fFadd, vPhase, vInvHadds, vVisit ); - } - } - Vec_IntFree( vMap ); - Vec_BitFree( vVisit ); - Acec_TreeVerifyPhases( p, vAdds, vBoxes, vPhase ); - // create leaves - Vec_WecForEachLevel( vLeaves, vLevel, i ) - Vec_IntForEachEntry( vLevel, iObj, k ) - Vec_WecPush( vLeafLits, i, Abc_Var2Lit(iObj, Vec_BitEntry(vPhase, iObj)) ); - // add constants - Vec_WecForEachLevel( vBoxes, vLevel, i ) - Vec_IntForEachEntry( vLevel, iObj, k ) - if ( Vec_BitEntry(vInvHadds, iObj) ) - Vec_WecPush( vLeafLits, i, 1 ); - // create roots - Vec_WecForEachLevel( vRoots, vLevel, i ) - Vec_IntForEachEntry( vLevel, iObj, k ) - iObj >>= 2, Vec_WecPush( vRootLits, i, Abc_Var2Lit(iObj, Vec_BitEntry(vPhase, iObj)) ); - // cleanup - Vec_BitFree( vPhase ); -} - /**Function************************************************************* Synopsis [Derives one adder tree.] @@ -564,25 +446,69 @@ void Acec_PrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds ) //Acec_PrintRootLits( pBox->vRoots ); } +int Acec_CreateBoxMaxRank( Vec_Int_t * vTree ) +{ + int k, Box, Rank, MaxRank = 0; + Vec_IntForEachEntryDouble( vTree, Box, Rank, k ) + MaxRank = Abc_MaxInt( MaxRank, Rank ); + return MaxRank; +} Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) { int MaxRank = Acec_CreateBoxMaxRank(vTree); + Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel, * vMap; + int i, k, Box, Rank; Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 ); - pBox->pGia = p; + pBox->pGia = p; + pBox->vAdds = Vec_WecStart( MaxRank + 1 ); + pBox->vLeafLits = Vec_WecStart( MaxRank + 1 ); + pBox->vRootLits = Vec_WecStart( MaxRank + 2 ); - pBox->vAdds = Vec_WecStart( MaxRank + 1 ); - pBox->vLeafs = Vec_WecStart( MaxRank + 1 ); - pBox->vRoots = Vec_WecStart( MaxRank + 2 ); + // collect boxes; mark inputs/outputs + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + Vec_WecPush( pBox->vAdds, Rank, Box ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 ); + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 ); + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 ); + } + // sort each level + Vec_WecForEachLevel( pBox->vAdds, vLevel, i ) + Vec_IntSort( vLevel, 0 ); - Acec_TreeInsOuts( p, vAdds, vTree, pBox->vAdds, pBox->vLeafs, pBox->vRoots ); - - pBox->vLeafLits = Vec_WecStart( Vec_WecSize(pBox->vLeafs) ); - pBox->vRootLits = Vec_WecStart( Vec_WecSize(pBox->vRoots) ); - pBox->vInvHadds = Vec_BitStart( Vec_IntSize(vAdds)/6 ); - - Acec_TreePhases( p, vAdds, pBox->vAdds, pBox->vLeafs, pBox->vRoots, pBox->vLeafLits, pBox->vRootLits, pBox->vInvHadds ); + // set phases + vMap = Acec_TreeCarryMap( p, vAdds, pBox->vAdds ); + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+4) ) ) + Acec_TreePhases_rec( p, vAdds, vMap, Vec_IntEntry(vAdds, 6*Box+4), Vec_IntEntry(vAdds, 6*Box+2) != 0 ); + Acec_TreeVerifyPhases( p, vAdds, pBox->vAdds ); + Vec_IntFree( vMap ); + // collect inputs/outputs + Vec_BitWriteEntry( vIsLeaf, 0, 0 ); + Vec_BitWriteEntry( vIsRoot, 0, 0 ); + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + int Sign = Vec_IntEntry( vAdds, 6*Box+5 ); + for ( k = 0; k < 3; k++ ) + if ( !Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) ) + Vec_WecPush( pBox->vLeafLits, Rank, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), (Sign >> (4+k)) & 1) ); + for ( k = 3; k < 5; k++ ) + if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) ) + Vec_WecPush( pBox->vRootLits, k == 4 ? Rank + 1 : Rank, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), (Sign >> (7+k)) & 1) ); + } + Vec_BitFree( vIsLeaf ); + Vec_BitFree( vIsRoot ); + // sort each level + Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i ) + Vec_IntSort( vLevel, 0 ); + Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) + Vec_IntSort( vLevel, 0 ); return pBox; } void Acec_CreateBoxTest( Gia_Man_t * p ) @@ -641,7 +567,7 @@ Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, int fVerbose ) Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); if ( pBox && fVerbose ) Acec_PrintBox( pBox, vAdds ); - //Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); + Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); Vec_WecFreeP( &vTrees ); Vec_IntFree( vAdds ); return pBox; From 79701f8b4603596095d3d04a13018c8e9598f7a0 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 14 Jan 2017 16:11:59 +0700 Subject: [PATCH 060/185] Updates to arithmetic verification. --- src/aig/gia/gia.h | 1 + src/aig/gia/giaEquiv.c | 27 ++++++- src/base/abci/abc.c | 20 +++-- src/base/abci/abcDress3.c | 30 +------ src/proof/acec/acec.h | 3 +- src/proof/acec/acecCore.c | 73 +++++++++++++---- src/proof/acec/acecInt.h | 3 +- src/proof/acec/acecMult.c | 19 +++-- src/proof/acec/acecNorm.c | 6 +- src/proof/acec/acecTree.c | 161 ++++++++++++++++++++++---------------- 10 files changed, 215 insertions(+), 128 deletions(-) diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 680601191..dc6c679ad 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1270,6 +1270,7 @@ extern void Gia_ManOrigIdsInit( Gia_Man_t * p ); extern void Gia_ManOrigIdsStart( Gia_Man_t * p ); extern void Gia_ManOrigIdsRemap( Gia_Man_t * p, Gia_Man_t * pNew ); extern Gia_Man_t * Gia_ManOrigIdsReduce( Gia_Man_t * p, Vec_Int_t * vPairs ); +extern Gia_Man_t * Gia_ManComputeGiaEquivs( Gia_Man_t * pGia, int nConfs, int fVerbose ); extern void Gia_ManEquivFixOutputPairs( Gia_Man_t * p ); extern int Gia_ManCheckTopoOrder( Gia_Man_t * p ); extern int * Gia_ManDeriveNexts( Gia_Man_t * p ); diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c index 584be4cd3..1b0bce07d 100644 --- a/src/aig/gia/giaEquiv.c +++ b/src/aig/gia/giaEquiv.c @@ -129,7 +129,7 @@ Gia_Man_t * Gia_ManOrigIdsReduce( Gia_Man_t * p, Vec_Int_t * vPairs ) } Gia_ManHashStop( pNew ); Gia_ManForEachCo( p, pObj, i ) - Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); Vec_IntFree( vMap ); // compute equivalences assert( !p->pReprs && !p->pNexts ); @@ -169,6 +169,31 @@ Gia_Man_t * Gia_ManOrigIdsReduceTest( Gia_Man_t * p, Vec_Int_t * vPairs ) return pNew; } +/**Function************************************************************* + + Synopsis [Compute equivalence classes of nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManComputeGiaEquivs( Gia_Man_t * pGia, int nConfs, int fVerbose ) +{ + Gia_Man_t * pTemp; + Cec_ParFra_t ParsFra, * pPars = &ParsFra; + Cec_ManFraSetDefaultParams( pPars ); + pPars->fUseOrigIds = 1; + pPars->fSatSweeping = 1; + pPars->nBTLimit = nConfs; + pPars->fVerbose = fVerbose; + pTemp = Cec_ManSatSweeping( pGia, pPars, 0 ); + Gia_ManStop( pTemp ); + return Gia_ManOrigIdsReduce( pGia, pGia->vIdsEquiv ); +} + /**Function************************************************************* Synopsis [Returns 1 if AIG is not in the required topo order.] diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 910014c6d..1e94f28fc 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -40543,7 +40543,7 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) int c, nArgcNew; Acec_ManCecSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "CTmdtvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "CTmdtbvh" ) ) != EOF ) { switch ( c ) { @@ -40578,6 +40578,9 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) case 't': pPars->fTwoOutput ^= 1; break; + case 'b': + pPars->fBooth ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; @@ -40720,13 +40723,14 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &acec [-CT num] [-mdtvh] \n" ); + Abc_Print( -2, "usage: &acec [-CT num] [-mdtbvh] \n" ); Abc_Print( -2, "\t combinational equivalence checking for arithmetic circuits\n" ); Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); Abc_Print( -2, "\t-T num : approximate runtime limit in seconds [default = %d]\n", pPars->TimeLimit ); Abc_Print( -2, "\t-m : toggle miter vs. two circuits [default = %s]\n", pPars->fMiter? "miter":"two circuits"); Abc_Print( -2, "\t-d : toggle using dual output miter [default = %s]\n", pPars->fDualOutput? "yes":"no"); Abc_Print( -2, "\t-t : toggle using two-word miter [default = %s]\n", pPars->fTwoOutput? "yes":"no"); + Abc_Print( -2, "\t-b : toggle working with Booth multipliers [default = %s]\n", pPars->fBooth? "yes":"no"); Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes":"no"); Abc_Print( -2, "\t-h : print the command usage\n"); Abc_Print( -2, "\tfile1 : (optional) the file with the first network\n"); @@ -40748,12 +40752,15 @@ usage: int Abc_CommandAbc9Anorm( Abc_Frame_t * pAbc, int argc, char ** argv ) { Gia_Man_t * pTemp; - int c, fVerbose = 0; + int c, fBooth = 0, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "bvh" ) ) != EOF ) { switch ( c ) { + case 'b': + fBooth ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -40768,13 +40775,14 @@ int Abc_CommandAbc9Anorm( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandAbc9Anorm(): There is no AIG.\n" ); return 0; } - pTemp = Acec_Normalize( pAbc->pGia, fVerbose ); + pTemp = Acec_Normalize( pAbc->pGia, fBooth, fVerbose ); Abc_FrameUpdateGia( pAbc, pTemp ); return 0; usage: - Abc_Print( -2, "usage: &anorm [-vh]\n" ); + Abc_Print( -2, "usage: &anorm [-bvh]\n" ); Abc_Print( -2, "\t normalize adder trees in the current AIG\n" ); + Abc_Print( -2, "\t-b : toggles working with Booth multipliers [default = %s]\n", fBooth? "yes": "no" ); Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; diff --git a/src/base/abci/abcDress3.c b/src/base/abci/abcDress3.c index 33545f0a2..ce0cb7f55 100644 --- a/src/base/abci/abcDress3.c +++ b/src/base/abci/abcDress3.c @@ -33,32 +33,6 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -/**Function************************************************************* - - Synopsis [Compute equivalence classes of nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkComputeGiaEquivs( Gia_Man_t * pGia, int nConfs, int fVerbose ) -{ - Gia_Man_t * pTemp; - Cec_ParFra_t ParsFra, * pPars = &ParsFra; - Cec_ManFraSetDefaultParams( pPars ); - pPars->fUseOrigIds = 1; - pPars->fSatSweeping = 1; - pPars->nBTLimit = nConfs; - pPars->fVerbose = fVerbose; - pTemp = Cec_ManSatSweeping( pGia, pPars, 0 ); - Gia_ManStop( pTemp ); - pTemp = Gia_ManOrigIdsReduce( pGia, pGia->vIdsEquiv ); - Gia_ManStop( pTemp ); -} - /**Function************************************************************* Synopsis [Converts AIG from HOP to GIA.] @@ -315,13 +289,15 @@ void Abc_NtkDumpEquivFile( char * pFileName, Vec_Int_t * vClasses, Abc_Ntk_t * p void Abc_NtkDumpEquiv( Abc_Ntk_t * pNtks[2], char * pFileName, int nConfs, int fByName, int fVerbose ) { //abctime clk = Abc_Clock(); + Gia_Man_t * pTemp; Vec_Int_t * vClasses; // derive shared AIG for the two networks Gia_Man_t * pGia = Abc_NtkAigToGiaTwo( pNtks[0], pNtks[1], fByName ); if ( fVerbose ) printf( "Computing equivalences for networks \"%s\" and \"%s\" with conflict limit %d.\n", Abc_NtkName(pNtks[0]), Abc_NtkName(pNtks[1]), nConfs ); // compute equivalences in this AIG - Abc_NtkComputeGiaEquivs( pGia, nConfs, fVerbose ); + pTemp = Gia_ManComputeGiaEquivs( pGia, nConfs, fVerbose ); + Gia_ManStop( pTemp ); //if ( fVerbose ) // Abc_PrintTime( 1, "Equivalence computation time", Abc_Clock() - clk ); if ( fVerbose ) diff --git a/src/proof/acec/acec.h b/src/proof/acec/acec.h index 7ad5baf95..5a24bec7d 100644 --- a/src/proof/acec/acec.h +++ b/src/proof/acec/acec.h @@ -47,6 +47,7 @@ struct Acec_ParCec_t_ int fMiter; // input circuit is a miter int fDualOutput; // dual-output miter int fTwoOutput; // two-output miter + int fBooth; // expecting Booth multiplier int fSilent; // print no messages int fVeryVerbose; // verbose stats int fVerbose; // verbose stats @@ -81,7 +82,7 @@ extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int extern int Ree_ManCountFadds( Vec_Int_t * vAdds ); extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose ); /*=== acecTree.c ========================================================*/ -extern Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fVerbose ); +extern Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fBooth, int fVerbose ); ABC_NAMESPACE_HEADER_END diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index 3e31fa360..4a91663f5 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -68,7 +68,7 @@ void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p ) SeeAlso [] ***********************************************************************/ -Gia_Man_t * Acec_FindEquivs( Gia_Man_t * pBase, Gia_Man_t * pAdd ) +Gia_Man_t * Acec_CommonStart( Gia_Man_t * pBase, Gia_Man_t * pAdd ) { Gia_Obj_t * pObj; int i; @@ -93,35 +93,69 @@ Gia_Man_t * Acec_FindEquivs( Gia_Man_t * pBase, Gia_Man_t * pAdd ) pObj->Value = Gia_ManHashAnd( pBase, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); return pBase; } -Vec_Int_t * Acec_CountRemap( Gia_Man_t * pAdd ) +void Acec_CommonFinish( Gia_Man_t * pBase ) +{ + int Id; + Gia_ManCreateRefs( pBase ); + Gia_ManForEachAndId( pBase, Id ) + if ( Gia_ObjRefNumId(pBase, Id) == 0 ) + Gia_ManAppendCo( pBase, Abc_Var2Lit(Id,0) ); +} +Vec_Int_t * Acec_CountRemap( Gia_Man_t * pAdd, Gia_Man_t * pBase ) { Gia_Obj_t * pObj; int i; Vec_Int_t * vMapNew = Vec_IntStartFull( Gia_ManObjNum(pAdd) ); + Gia_ManSetPhase( pAdd ); + Vec_IntWriteEntry( vMapNew, 0, 0 ); Gia_ManForEachCand( pAdd, pObj, i ) - Vec_IntWriteEntry( vMapNew, i, Abc_Lit2Var(pObj->Value) ); + { + int iObjBase = Abc_Lit2Var(pObj->Value); + Gia_Obj_t * pObjBase = Gia_ManObj( pBase, iObjBase ); + int iObjRepr = Abc_Lit2Var(pObjBase->Value); + Vec_IntWriteEntry( vMapNew, i, Abc_Var2Lit(iObjRepr, Gia_ObjPhase(pObj)) ); + } return vMapNew; } void Acec_ComputeEquivClasses( Gia_Man_t * pOne, Gia_Man_t * pTwo, Vec_Int_t ** pvMap1, Vec_Int_t ** pvMap2 ) { - Gia_Man_t * pBase; - pBase = Acec_FindEquivs( NULL, pOne ); - pBase = Acec_FindEquivs( pBase, pTwo ); - *pvMap1 = Acec_CountRemap( pOne ); - *pvMap2 = Acec_CountRemap( pTwo ); + Gia_Man_t * pBase, * pRepr; + pBase = Acec_CommonStart( NULL, pOne ); + pBase = Acec_CommonStart( pBase, pTwo ); + Acec_CommonFinish( pBase ); + + //Gia_ManShow( pBase, NULL, 0, 0, 0 ); + + pRepr = Gia_ManComputeGiaEquivs( pBase, 100, 0 ); + *pvMap1 = Acec_CountRemap( pOne, pBase ); + *pvMap2 = Acec_CountRemap( pTwo, pBase ); Gia_ManStop( pBase ); + Gia_ManStop( pRepr ); } -static inline void Acec_MatchBoxesSort( int * pArray, int nSize, int * pCosts ) +void Acec_MatchBoxesSort( int * pArray, int nSize, int * pCostLits ) { int i, j, best_i; for ( i = 0; i < nSize-1; i++ ) { best_i = i; for ( j = i+1; j < nSize; j++ ) - if ( pCosts[Abc_Lit2Var(pArray[j])] > pCosts[Abc_Lit2Var(pArray[best_i])] ) + if ( Abc_Lit2LitL(pCostLits, pArray[j]) > Abc_Lit2LitL(pCostLits, pArray[best_i]) ) best_i = j; ABC_SWAP( int, pArray[i], pArray[best_i] ); } } +void Acec_MatchPrintEquivLits( Vec_Wec_t * vLits, int * pCostLits ) +{ + Vec_Int_t * vLevel; + int i, k, Entry; + printf( "Leaf literals and their classes:\n" ); + Vec_WecForEachLevel( vLits, vLevel, i ) + { + printf( "Rank %2d : %2d ", i, Vec_IntSize(vLevel) ); + Vec_IntForEachEntry( vLevel, Entry, k ) + printf( "%s%d(%d) ", Abc_LitIsCompl(Entry) ? "-":"+", Abc_Lit2Var(Entry), Abc_Lit2LitL(pCostLits, Entry) ); + printf( "\n" ); + } +} int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) { Vec_Int_t * vMap0, * vMap1, * vLevel; @@ -132,6 +166,8 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap0) ); Vec_WecForEachLevel( pBox1->vLeafLits, vLevel, i ) Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap1) ); + //Acec_MatchPrintEquivLits( pBox0->vLeafLits, Vec_IntArray(vMap0) ); + //Acec_MatchPrintEquivLits( pBox1->vLeafLits, Vec_IntArray(vMap1) ); // reorder nodes to have the same order assert( pBox0->vShared == NULL ); assert( pBox1->vShared == NULL ); @@ -159,8 +195,9 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) int * pEnd1 = Vec_IntLimit(vLevel1); while ( pBeg0 < pEnd0 && pBeg1 < pEnd1 ) { - int Entry0 = Abc_Lit2LitV( Vec_IntArray(vMap0), *pBeg0 ); - int Entry1 = Abc_Lit2LitV( Vec_IntArray(vMap1), *pBeg1 ); + int Entry0 = Abc_Lit2LitL( Vec_IntArray(vMap0), *pBeg0 ); + int Entry1 = Abc_Lit2LitL( Vec_IntArray(vMap1), *pBeg1 ); + assert( *pBeg0 && *pBeg1 ); if ( Entry0 == Entry1 ) { Vec_IntPush( vShared0, *pBeg0++ ); @@ -201,11 +238,16 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) { int status = -1; + abctime clk = Abc_Clock(); Gia_Man_t * pMiter; Gia_Man_t * pGia0n = pGia0, * pGia1n = pGia1; Cec_ParCec_t ParsCec, * pCecPars = &ParsCec; - Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0, pPars->fVerbose ); - Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1, pPars->fVerbose ); + Vec_Bit_t * vIgnore0 = pPars->fBooth ? Acec_BoothFindPPG(pGia0) : NULL; + Vec_Bit_t * vIgnore1 = pPars->fBooth ? Acec_BoothFindPPG(pGia1) : NULL; + Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0, vIgnore0, pPars->fVerbose ); + Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1, vIgnore1, pPars->fVerbose ); + Vec_BitFreeP( &vIgnore0 ); + Vec_BitFreeP( &vIgnore1 ); if ( pBox0 == NULL || pBox1 == NULL ) // cannot match printf( "Cannot find arithmetic boxes in both LHS and RHS. Trying regular CEC.\n" ); else if ( !Acec_MatchBoxes( pBox0, pBox1 ) ) // cannot find matching @@ -214,7 +256,8 @@ int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) { pGia0n = Acec_InsertBox( pBox0, 1 ); pGia1n = Acec_InsertBox( pBox1, 1 ); - printf( "Found, matched, and normalized arithmetic boxes in LHS and RHS. Solving resulting CEC.\n" ); + printf( "Matching of adder trees in LHS and RHS succeeded. " ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } // solve regular CEC problem Cec_ManCecSetDefaultParams( pCecPars ); diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index 125d923fa..cc5786bb8 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -69,10 +69,11 @@ extern Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Ve extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vRootBoxes ); /*=== acecMult.c ========================================================*/ extern Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits ); +extern Vec_Bit_t * Acec_BoothFindPPG( Gia_Man_t * p ); /*=== acecNorm.c ========================================================*/ extern Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ); /*=== acecTree.c ========================================================*/ -extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, int fVerbose ); +extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fVerbose ); extern void Acec_BoxFreeP( Acec_Box_t ** ppBox ); /*=== acecUtil.c ========================================================*/ extern void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose ); diff --git a/src/proof/acec/acecMult.c b/src/proof/acec/acecMult.c index 8ccf966ef..0733c00bf 100644 --- a/src/proof/acec/acecMult.c +++ b/src/proof/acec/acecMult.c @@ -490,18 +490,16 @@ Vec_Int_t * Acec_MultFindPPs( Gia_Man_t * p ) Gia_ManForEachAndId( p, iObj ) { word Truth = Gia_ObjComputeTruth6Cis( p, Abc_Var2Lit(iObj, 0), vSupp, vTemp ); + if ( Vec_IntSize(vSupp) > 6 ) + continue; vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize ); if ( Vec_IntSize(vSupp) > 5 ) continue; - for ( i = 0; i < 32; i++ ) + for ( i = 0; i < 32 && Saved[i]; i++ ) { - if ( Saved[i] == 0 ) - break; if ( Truth == Saved[i] || Truth == ~Saved[i] ) { - //Vec_IntPush( vBold, iObj ); Acec_MultFindPPs_rec( p, iObj, vBold ); - printf( "%d ", iObj ); nProds++; break; } @@ -515,7 +513,6 @@ Vec_Int_t * Acec_MultFindPPs( Gia_Man_t * p ) Vec_IntPrint( vSupp ); */ } - printf( "\n" ); Gia_ManCleanMark0(p); printf( "Collected %d pps and %d nodes.\n", nProds, Vec_IntSize(vBold) ); @@ -523,6 +520,16 @@ Vec_Int_t * Acec_MultFindPPs( Gia_Man_t * p ) Vec_WrdFree( vTemp ); return vBold; } +Vec_Bit_t * Acec_BoothFindPPG( Gia_Man_t * p ) +{ + Vec_Bit_t * vIgnore = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Int_t * vMap = Acec_MultFindPPs( p ); + int i, Entry; + Vec_IntForEachEntry( vMap, Entry, i ) + Vec_BitWriteEntry( vIgnore, Entry, 1 ); + Vec_IntFree( vMap ); + return vIgnore; +} void Acec_MultFindPPsTest( Gia_Man_t * p ) { Vec_Int_t * vBold = Acec_MultFindPPs( p ); diff --git a/src/proof/acec/acecNorm.c b/src/proof/acec/acecNorm.c index 9faf7acfd..4ed32e7b4 100644 --- a/src/proof/acec/acecNorm.c +++ b/src/proof/acec/acecNorm.c @@ -198,11 +198,13 @@ Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ) SeeAlso [] ***********************************************************************/ -Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fVerbose ) +Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fBooth, int fVerbose ) { - Acec_Box_t * pBox = Acec_DeriveBox( pGia, fVerbose ); + Vec_Bit_t * vIgnore = fBooth ? Acec_BoothFindPPG( pGia ) : NULL; + Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, fVerbose ); Gia_Man_t * pNew = Acec_InsertBox( pBox, 1 ); Acec_BoxFreeP( &pBox ); + Vec_BitFreeP( &vIgnore ); return pNew; } diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index 370e8eb65..fef369238 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -27,6 +27,12 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +static inline int Acec_SignBit( Vec_Int_t * vAdds, int iBox, int b ) { return (Vec_IntEntry(vAdds, 6*iBox+5) >> b) & 1; } +static inline int Acec_SignBit2( Vec_Int_t * vAdds, int iBox, int b ) { return (Vec_IntEntry(vAdds, 6*iBox+5) >> (16+b)) & 1; } + +static inline void Acec_SignSetBit( Vec_Int_t * vAdds, int iBox, int b, int v ) { if ( v ) *Vec_IntEntryP(vAdds, 6*iBox+5) |= (1 << b); } +static inline void Acec_SignSetBit2( Vec_Int_t * vAdds, int iBox, int b, int v ) { if ( v ) *Vec_IntEntryP(vAdds, 6*iBox+5) |= (1 << (16+b)); } + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -147,10 +153,7 @@ void Acec_TreeVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox ) Gia_Obj_t * pObj; unsigned TruthXor, TruthMaj, Truths[3] = { 0xAA, 0xCC, 0xF0 }; int k, iObj, fFadd = Vec_IntEntry(vAdds, 6*iBox+2) > 0; - - int Sign = Vec_IntEntry( vAdds, 6*iBox+5 ), Phase[5]; - for ( k = 0; k < 5; k++ ) - Phase[k] = (Sign >> (4+k)) & 1; + int fFlip = !fFadd && Acec_SignBit2(vAdds, iBox, 2); Gia_ManIncrementTravId( p ); for ( k = 0; k < 3; k++ ) @@ -159,17 +162,17 @@ void Acec_TreeVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox ) if ( iObj == 0 ) continue; pObj = Gia_ManObj( p, iObj ); - pObj->Value = Phase[k] ? 0xFF & ~Truths[k] : Truths[k]; + pObj->Value = (Acec_SignBit2(vAdds, iBox, k) ^ fFlip) ? 0xFF & ~Truths[k] : Truths[k]; Gia_ObjSetTravIdCurrent( p, pObj ); } iObj = Vec_IntEntry( vAdds, 6*iBox+3 ); TruthXor = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) ); - TruthXor = Phase[3] ? 0xFF & ~TruthXor : TruthXor; + TruthXor = (Acec_SignBit2(vAdds, iBox, 3) ^ fFlip) ? 0xFF & ~TruthXor : TruthXor; iObj = Vec_IntEntry( vAdds, 6*iBox+4 ); TruthMaj = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) ); - TruthMaj = Phase[4] ? 0xFF & ~TruthMaj : TruthMaj; + TruthMaj = (Acec_SignBit2(vAdds, iBox, 4) ^ fFlip) ? 0xFF & ~TruthMaj : TruthMaj; if ( fFadd ) // FADD { @@ -180,6 +183,8 @@ void Acec_TreeVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox ) } else { + //printf( "Sign1 = %d%d%d %d\n", Acec_SignBit(vAdds, iBox, 0), Acec_SignBit(vAdds, iBox, 1), Acec_SignBit(vAdds, iBox, 2), Acec_SignBit(vAdds, iBox, 3) ); + //printf( "Sign2 = %d%d%d %d%d\n", Acec_SignBit2(vAdds, iBox, 0), Acec_SignBit2(vAdds, iBox, 1), Acec_SignBit2(vAdds, iBox, 2), Acec_SignBit2(vAdds, iBox, 3), Acec_SignBit2(vAdds, iBox, 4) ); if ( TruthXor != 0x66 ) printf( "Hadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) ); if ( TruthMaj != 0x88 ) @@ -194,6 +199,36 @@ void Acec_TreeVerifyPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes Vec_IntForEachEntry( vLevel, Box, k ) Acec_TreeVerifyPhaseOne( p, vAdds, Box ); } +void Acec_TreeVerifyPhases2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ) +{ + Vec_Bit_t * vPhase = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Bit_t * vRoots = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; + int i, k, n, Box; + // mark all output points and their values + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + { + Vec_BitWriteEntry( vRoots, Vec_IntEntry( vAdds, 6*Box+3 ), 1 ); + Vec_BitWriteEntry( vRoots, Vec_IntEntry( vAdds, 6*Box+4 ), 1 ); + Vec_BitWriteEntry( vPhase, Vec_IntEntry( vAdds, 6*Box+3 ), Acec_SignBit2(vAdds, Box, 3) ); + Vec_BitWriteEntry( vPhase, Vec_IntEntry( vAdds, 6*Box+4 ), Acec_SignBit2(vAdds, Box, 4) ); + } + // compare with input points + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + for ( n = 0; n < 3; n++ ) + { + if ( !Vec_BitEntry(vRoots, Vec_IntEntry(vAdds, 6*Box+n)) ) + continue; + if ( Vec_BitEntry(vPhase, Vec_IntEntry(vAdds, 6*Box+n)) == Acec_SignBit2(vAdds, Box, n) ) + continue; + printf( "Phase of input %d=%d is mismatched in box %d=(%d,%d).\n", + n, Vec_IntEntry(vAdds, 6*Box+n), Box, Vec_IntEntry(vAdds, 6*Box+3), Vec_IntEntry(vAdds, 6*Box+4) ); + } + Vec_BitFree( vPhase ); + Vec_BitFree( vRoots ); +} /**Function************************************************************* @@ -216,40 +251,40 @@ Vec_Int_t * Acec_TreeCarryMap( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBo Vec_IntWriteEntry( vMap, Vec_IntEntry(vAdds, 6*Box+4), Box ); return vMap; } -void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, int Node, int fPhase ) +void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, int Node, int fPhase, Vec_Bit_t * vVisit ) { - int k, iBox, iXor, Sign, fXorPhase, fPhaseThis; + int k, iBox, iXor, fXorPhase, fPhaseThis; assert( Node != 0 ); iBox = Vec_IntEntry( vMap, Node ); if ( iBox == -1 ) return; assert( Node == Vec_IntEntry( vAdds, 6*iBox+4 ) ); + if ( Vec_BitEntry(vVisit, iBox) ) + return; + Vec_BitWriteEntry( vVisit, iBox, 1 ); iXor = Vec_IntEntry( vAdds, 6*iBox+3 ); - Sign = Vec_IntEntry( vAdds, 6*iBox+5 ) & 0xFFFFFFF0; - fXorPhase = ((Sign >> 3) & 1); + fXorPhase = Acec_SignBit(vAdds, iBox, 3); if ( Vec_IntEntry(vAdds, 6*iBox+2) == 0 ) { - fPhase ^= ((Sign >> 2) & 1); - if ( fPhase ) // complemented HADD - Sign |= (1 << 6); + //fPhaseThis = Acec_SignBit( vAdds, iBox, 2 ) ^ fPhase; + //fXorPhase ^= fPhaseThis; + //Acec_SignSetBit2( vAdds, iBox, 2, fPhaseThis ); // complemented HADD -- create const1 input + fPhase ^= Acec_SignBit( vAdds, iBox, 2 ); + fXorPhase ^= fPhase; + Acec_SignSetBit2( vAdds, iBox, 2, fPhase ); // complemented HADD -- create const1 input } for ( k = 0; k < 3; k++ ) { int iObj = Vec_IntEntry( vAdds, 6*iBox+k ); if ( iObj == 0 ) continue; - fPhaseThis = ((Sign >> k) & 1) ^ fPhase; + fPhaseThis = Acec_SignBit(vAdds, iBox, k) ^ fPhase; fXorPhase ^= fPhaseThis; - Acec_TreePhases_rec( p, vAdds, vMap, iObj, fPhaseThis ); - if ( fPhaseThis ) - Sign |= (1 << (4+k)); + Acec_TreePhases_rec( p, vAdds, vMap, iObj, fPhaseThis, vVisit ); + Acec_SignSetBit2( vAdds, iBox, k, fPhaseThis ); } - if ( fXorPhase ) - Sign |= (1 << 7); - if ( fPhase ) - Sign |= (1 << 8); - // save updated signature - Vec_IntWriteEntry( vAdds, 6*iBox+5, Sign ); + Acec_SignSetBit2( vAdds, iBox, 3, fXorPhase ); + Acec_SignSetBit2( vAdds, iBox, 4, fPhase ); } /**Function************************************************************* @@ -271,12 +306,14 @@ void Acec_TreeAddInOutPoint( Vec_Int_t * vMap, int iObj, int iAdd, int fOut ) else if ( *pPlace >= 0 ) *pPlace = -2; } -Vec_Int_t * Acec_TreeFindPoints( Gia_Man_t * p, Vec_Int_t * vAdds ) +Vec_Int_t * Acec_TreeFindPoints( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vIgnore ) { Vec_Int_t * vMap = Vec_IntStartFull( 2*Gia_ManObjNum(p) ); int i; for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) { + if ( vIgnore && (Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+3)) || Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+4))) ) + continue; Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+0), i, 0 ); Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+1), i, 0 ); Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+2), i, 0 ); @@ -328,10 +365,10 @@ void Acec_TreeFindTrees_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iObj, int Acec_TreeFindTrees2_rec( vAdds, vMap, In, Acec_TreeWhichPoint(vAdds, In, iObj) == 4 ? Rank-1 : Rank, vTree, vFound ); Acec_TreeFindTrees2_rec( vAdds, vMap, Out, Rank, vTree, vFound ); } -Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds ) +Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vIgnore ) { Vec_Wec_t * vTrees = Vec_WecAlloc( 10 ); - Vec_Int_t * vMap = Acec_TreeFindPoints( p, vAdds ); + Vec_Int_t * vMap = Acec_TreeFindPoints( p, vAdds, vIgnore ); Vec_Bit_t * vFound = Vec_BitStart( Vec_IntSize(vAdds)/6 ); Vec_Int_t * vTree; int i, k, In, Out, Box, Rank, MinRank; @@ -371,7 +408,7 @@ void Acec_TreeFindTreesTest( Gia_Man_t * p ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); clk = Abc_Clock(); - vTrees = Acec_TreeFindTrees( p, vAdds ); + vTrees = Acec_TreeFindTrees( p, vAdds, NULL ); printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); Vec_WecPrint( vTrees, 0 ); @@ -417,23 +454,6 @@ void Vec_WecPrintLits( Vec_Wec_t * p ) printf( " }\n" ); } } -void Acec_PrintRootLits( Vec_Wec_t * vRoots ) -{ - Vec_Int_t * vLevel; - int i, k, iObj; - Vec_WecForEachLevel( vRoots, vLevel, i ) - { - printf( "Rank %d : %2d ", i, Vec_IntSize(vLevel) ); - Vec_IntForEachEntry( vLevel, iObj, k ) - { - int fFadd = Abc_LitIsCompl(iObj); - int fCout = Abc_LitIsCompl(Abc_Lit2Var(iObj)); - int Node = Abc_Lit2Var(Abc_Lit2Var(iObj)); - printf( "%d%s%s ", Node, fCout ? "*" : "", (fCout && fFadd) ? "*" : "" ); - } - printf( "\n" ); - } -} void Acec_PrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds ) { printf( "Adders:\n" ); @@ -442,8 +462,6 @@ void Acec_PrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds ) Vec_WecPrintLits( pBox->vLeafLits ); printf( "Outputs:\n" ); Vec_WecPrintLits( pBox->vRootLits ); - //printf( "Raw outputs:\n" ); - //Acec_PrintRootLits( pBox->vRoots ); } int Acec_CreateBoxMaxRank( Vec_Int_t * vTree ) @@ -456,10 +474,11 @@ int Acec_CreateBoxMaxRank( Vec_Int_t * vTree ) Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) { int MaxRank = Acec_CreateBoxMaxRank(vTree); + Vec_Bit_t * vVisit = Vec_BitStart( Vec_IntSize(vAdds)/6 ); Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); Vec_Int_t * vLevel, * vMap; - int i, k, Box, Rank; + int i, j, k, Box, Rank; Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 ); pBox->pGia = p; @@ -470,38 +489,42 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree // collect boxes; mark inputs/outputs Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) { - Vec_WecPush( pBox->vAdds, Rank, Box ); Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 ); Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 ); Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 ); Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 ); Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 ); + Vec_WecPush( pBox->vAdds, Rank, Box ); } // sort each level Vec_WecForEachLevel( pBox->vAdds, vLevel, i ) Vec_IntSort( vLevel, 0 ); - // set phases + // set phases starting from roots vMap = Acec_TreeCarryMap( p, vAdds, pBox->vAdds ); - Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) - if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+4) ) ) - Acec_TreePhases_rec( p, vAdds, vMap, Vec_IntEntry(vAdds, 6*Box+4), Vec_IntEntry(vAdds, 6*Box+2) != 0 ); + Vec_WecForEachLevelReverse( pBox->vAdds, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+4) ) ) + Acec_TreePhases_rec( p, vAdds, vMap, Vec_IntEntry(vAdds, 6*Box+4), Vec_IntEntry(vAdds, 6*Box+2) != 0, vVisit ); Acec_TreeVerifyPhases( p, vAdds, pBox->vAdds ); + Acec_TreeVerifyPhases2( p, vAdds, pBox->vAdds ); + Vec_BitFree( vVisit ); Vec_IntFree( vMap ); // collect inputs/outputs - Vec_BitWriteEntry( vIsLeaf, 0, 0 ); - Vec_BitWriteEntry( vIsRoot, 0, 0 ); - Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) - { - int Sign = Vec_IntEntry( vAdds, 6*Box+5 ); - for ( k = 0; k < 3; k++ ) - if ( !Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) ) - Vec_WecPush( pBox->vLeafLits, Rank, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), (Sign >> (4+k)) & 1) ); - for ( k = 3; k < 5; k++ ) - if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) ) - Vec_WecPush( pBox->vRootLits, k == 4 ? Rank + 1 : Rank, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), (Sign >> (7+k)) & 1) ); - } + Vec_BitWriteEntry( vIsRoot, 0, 1 ); + Vec_WecForEachLevel( pBox->vAdds, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, j ) + { + for ( k = 0; k < 3; k++ ) + if ( !Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) ) + Vec_WecPush( pBox->vLeafLits, i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) ); + for ( k = 3; k < 5; k++ ) + if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) ) + Vec_WecPush( pBox->vRootLits, k == 4 ? i + 1 : i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) ); + if ( Vec_IntEntry(vAdds, 6*Box+2) == 0 && Acec_SignBit2(vAdds, Box, 2) ) + Vec_WecPush( pBox->vLeafLits, i, 1 ); + } Vec_BitFree( vIsLeaf ); Vec_BitFree( vIsRoot ); // sort each level @@ -524,7 +547,7 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); clk = Abc_Clock(); - vTrees = Acec_TreeFindTrees( p, vAdds ); + vTrees = Acec_TreeFindTrees( p, vAdds, NULL ); printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); //Vec_WecPrint( vTrees, 0 ); @@ -554,11 +577,11 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, int fVerbose ) +Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fVerbose ) { Acec_Box_t * pBox = NULL; Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, fVerbose ); - Vec_Wec_t * vTrees = Acec_TreeFindTrees( p, vAdds ); + Vec_Wec_t * vTrees = Acec_TreeFindTrees( p, vAdds, vIgnore ); if ( vTrees && Vec_WecSize(vTrees) > 0 ) pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, 0) ); if ( pBox )//&& fVerbose ) @@ -567,7 +590,7 @@ Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, int fVerbose ) Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); if ( pBox && fVerbose ) Acec_PrintBox( pBox, vAdds ); - Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); + //Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); Vec_WecFreeP( &vTrees ); Vec_IntFree( vAdds ); return pBox; From 1b86911c4fe0b193c3a281e823de7934664da798 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 14 Jan 2017 20:28:26 +0700 Subject: [PATCH 061/185] Updates to arithmetic verification. --- src/aig/gia/giaShow.c | 14 ++--- src/base/abci/abc.c | 2 +- src/misc/vec/vecInt.h | 18 +++++++ src/misc/vec/vecWec.h | 17 ++++++ src/proof/acec/acecCore.c | 108 +++++++++++++++++++++++++++++++++++--- src/proof/acec/acecMult.c | 20 ++++--- src/proof/acec/acecNorm.c | 2 +- src/proof/acec/acecRe.c | 27 ++++++---- src/proof/acec/acecTree.c | 28 +++++++++- 9 files changed, 201 insertions(+), 35 deletions(-) diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index cf89d942d..4dd85aab6 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -30,6 +30,8 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +#define NODE_MAX 2000 + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -79,11 +81,11 @@ void Gia_ShowPath( Gia_Man_t * p, char * pFileName ) } } - if ( nNodes > 500 ) + if ( nNodes > NODE_MAX ) { ABC_FREE( pLevels ); Vec_BitFree( vPath ); - fprintf( stdout, "Cannot visualize AIG with more than 500 critical nodes.\n" ); + fprintf( stdout, "Cannot visualize AIG with more than %d critical nodes.\n", NODE_MAX ); return; } if ( (pFile = fopen( pFileName, "w" )) == NULL ) @@ -341,9 +343,9 @@ void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold ) int LevelMax, Prev, Level, i; int fConstIsUsed = 0; - if ( Gia_ManAndNum(p) > 500 ) + if ( Gia_ManAndNum(p) > NODE_MAX ) { - fprintf( stdout, "Cannot visualize AIG with more than 500 nodes.\n" ); + fprintf( stdout, "Cannot visualize AIG with more than %d nodes.\n", NODE_MAX ); return; } if ( (pFile = fopen( pFileName, "w" )) == NULL ) @@ -678,9 +680,9 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_In int fConstIsUsed = 0; int nFadds = Ree_ManCountFadds( vAdds ); - if ( Gia_ManAndNum(p) > 1000 ) + if ( Gia_ManAndNum(p) > NODE_MAX ) { - fprintf( stdout, "Cannot visualize AIG with more than 1000 nodes.\n" ); + fprintf( stdout, "Cannot visualize AIG with more than %d nodes.\n", NODE_MAX ); return; } if ( (pFile = fopen( pFileName, "w" )) == NULL ) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 1e94f28fc..9db3d7d65 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -42690,7 +42690,7 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv ) // Jf_ManTestCnf( pAbc->pGia ); // Gia_ManCheckFalseTest( pAbc->pGia, nFrames ); // Gia_ParTest( pAbc->pGia, nWords, nProcs ); -// Gia_PolynExplore( pAbc->pGia ); + Acec_MultFindPPsTest( pAbc->pGia ); // printf( "\nThis command is currently disabled.\n\n" ); return 0; diff --git a/src/misc/vec/vecInt.h b/src/misc/vec/vecInt.h index f09b8783d..d952518fb 100644 --- a/src/misc/vec/vecInt.h +++ b/src/misc/vec/vecInt.h @@ -1692,6 +1692,24 @@ static inline int Vec_IntTwoFindCommon( Vec_Int_t * vArr1, Vec_Int_t * vArr2, Ve } return Vec_IntSize(vArr); } +static inline int Vec_IntTwoFindCommonReverse( Vec_Int_t * vArr1, Vec_Int_t * vArr2, Vec_Int_t * vArr ) +{ + int * pBeg1 = vArr1->pArray; + int * pBeg2 = vArr2->pArray; + int * pEnd1 = vArr1->pArray + vArr1->nSize; + int * pEnd2 = vArr2->pArray + vArr2->nSize; + Vec_IntClear( vArr ); + while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 ) + { + if ( *pBeg1 == *pBeg2 ) + Vec_IntPush( vArr, *pBeg1 ), pBeg1++, pBeg2++; + else if ( *pBeg1 > *pBeg2 ) + pBeg1++; + else + pBeg2++; + } + return Vec_IntSize(vArr); +} /**Function************************************************************* diff --git a/src/misc/vec/vecWec.h b/src/misc/vec/vecWec.h index e4e925034..8180e9847 100644 --- a/src/misc/vec/vecWec.h +++ b/src/misc/vec/vecWec.h @@ -303,6 +303,23 @@ static inline Vec_Int_t * Vec_WecPushLevel( Vec_Wec_t * p ) ++p->nSize; return Vec_WecEntryLast( p ); } +static inline Vec_Int_t * Vec_WecInsertLevel( Vec_Wec_t * p, int i ) +{ + Vec_Int_t * pTemp; + if ( p->nSize == p->nCap ) + { + if ( p->nCap < 16 ) + Vec_WecGrow( p, 16 ); + else + Vec_WecGrow( p, 2 * p->nCap ); + } + ++p->nSize; + assert( i >= 0 && i < p->nSize ); + for ( pTemp = p->pArray + p->nSize - 2; pTemp >= p->pArray + i; pTemp-- ) + pTemp[1] = pTemp[0]; + Vec_IntZero( p->pArray + i ); + return p->pArray + i; +} /**Function************************************************************* diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index 4a91663f5..6b631a1b3 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -20,6 +20,8 @@ #include "acecInt.h" #include "proof/cec/cec.h" +#include "misc/util/utilTruth.h" +#include "misc/extra/extra.h" ABC_NAMESPACE_IMPL_START @@ -118,18 +120,19 @@ Vec_Int_t * Acec_CountRemap( Gia_Man_t * pAdd, Gia_Man_t * pBase ) } void Acec_ComputeEquivClasses( Gia_Man_t * pOne, Gia_Man_t * pTwo, Vec_Int_t ** pvMap1, Vec_Int_t ** pvMap2 ) { + abctime clk = Abc_Clock(); Gia_Man_t * pBase, * pRepr; pBase = Acec_CommonStart( NULL, pOne ); pBase = Acec_CommonStart( pBase, pTwo ); Acec_CommonFinish( pBase ); - //Gia_ManShow( pBase, NULL, 0, 0, 0 ); - pRepr = Gia_ManComputeGiaEquivs( pBase, 100, 0 ); *pvMap1 = Acec_CountRemap( pOne, pBase ); *pvMap2 = Acec_CountRemap( pTwo, pBase ); Gia_ManStop( pBase ); Gia_ManStop( pRepr ); + printf( "Finished computing equivalent nodes. " ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } void Acec_MatchBoxesSort( int * pArray, int nSize, int * pCostLits ) { @@ -143,8 +146,10 @@ void Acec_MatchBoxesSort( int * pArray, int nSize, int * pCostLits ) ABC_SWAP( int, pArray[i], pArray[best_i] ); } } -void Acec_MatchPrintEquivLits( Vec_Wec_t * vLits, int * pCostLits ) +void Acec_MatchPrintEquivLits( Gia_Man_t * p, Vec_Wec_t * vLits, int * pCostLits, int fVerbose ) { + Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); + Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); Vec_Int_t * vLevel; int i, k, Entry; printf( "Leaf literals and their classes:\n" ); @@ -155,6 +160,85 @@ void Acec_MatchPrintEquivLits( Vec_Wec_t * vLits, int * pCostLits ) printf( "%s%d(%d) ", Abc_LitIsCompl(Entry) ? "-":"+", Abc_Lit2Var(Entry), Abc_Lit2LitL(pCostLits, Entry) ); printf( "\n" ); } + if ( !fVerbose ) + return; + Vec_WecForEachLevel( vLits, vLevel, i ) + { + if ( i != 20 ) + continue; + Vec_IntForEachEntry( vLevel, Entry, k ) + { + word Truth = Gia_ObjComputeTruth6Cis( p, Entry, vSupp, vTemp ); + printf( "Rank = %4d : ", i ); + printf( "Obj = %4d ", Abc_Lit2Var(Entry) ); + if ( Vec_IntSize(vSupp) > 6 ) + { + printf( "Supp = %d.\n", Vec_IntSize(vSupp) ); + continue; + } + vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize ); + if ( Vec_IntSize(vSupp) > 5 ) + { + printf( "Supp = %d.\n", Vec_IntSize(vSupp) ); + continue; + } + Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) ); + if ( Vec_IntSize(vSupp) == 4 ) printf( " " ); + if ( Vec_IntSize(vSupp) == 3 ) printf( " " ); + if ( Vec_IntSize(vSupp) <= 2 ) printf( " " ); + printf( " " ); + Vec_IntPrint( vSupp ); + } + printf( "\n" ); + } + Vec_IntFree( vSupp ); + Vec_WrdFree( vTemp ); +} +Vec_Wec_t * Acec_MatchCopy( Vec_Wec_t * vLits, Vec_Int_t * vMap ) +{ + Vec_Wec_t * vRes = Vec_WecStart( Vec_WecSize(vLits) ); + Vec_Int_t * vLevel; int i, k, iLit; + Vec_WecForEachLevel( vLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + Vec_WecPush( vRes, i, Abc_Lit2LitL(Vec_IntArray(vMap), iLit) ); + return vRes; +} +int Acec_MatchCountCommon( Vec_Wec_t * vLits1, Vec_Wec_t * vLits2, int Shift ) +{ + Vec_Int_t * vRes = Vec_IntAlloc( 100 ); + Vec_Int_t * vLevel1, * vLevel2; + int i, nCommon = 0; + Vec_WecForEachLevel( vLits1, vLevel1, i ) + { + if ( i+Shift < 0 || i+Shift >= Vec_WecSize(vLits2) ) + continue; + vLevel2 = Vec_WecEntry( vLits2, i+Shift ); + nCommon += Vec_IntTwoFindCommonReverse( vLevel1, vLevel2, vRes ); + } + Vec_IntFree( vRes ); + return nCommon; +} +void Acec_MatchCheckShift( Vec_Wec_t * vLits0, Vec_Wec_t * vLits1, Vec_Int_t * vMap0, Vec_Int_t * vMap1, Vec_Wec_t * vRoots0, Vec_Wec_t * vRoots1 ) +{ + Vec_Wec_t * vRes0 = Acec_MatchCopy( vLits0, vMap0 ); + Vec_Wec_t * vRes1 = Acec_MatchCopy( vLits1, vMap1 ); + int nCommon = Acec_MatchCountCommon( vRes0, vRes1, 0 ); + int nCommonPlus = Acec_MatchCountCommon( vRes0, vRes1, 1 ); + int nCommonMinus = Acec_MatchCountCommon( vRes0, vRes1, -1 ); + if ( nCommonPlus >= nCommonMinus && nCommonPlus > nCommon ) + { + Vec_WecInsertLevel( vLits0, 0 ); + Vec_WecInsertLevel( vRoots0, 0 ); + } + else if ( nCommonMinus > nCommonPlus && nCommonMinus > nCommon ) + { + Vec_WecInsertLevel( vLits1, 0 ); + Vec_WecInsertLevel( vRoots1, 0 ); + } + Vec_WecPrint( vRes0, 0 ); + Vec_WecPrint( vRes1, 0 ); + Vec_WecFree( vRes0 ); + Vec_WecFree( vRes1 ); } int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) { @@ -166,8 +250,11 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap0) ); Vec_WecForEachLevel( pBox1->vLeafLits, vLevel, i ) Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap1) ); - //Acec_MatchPrintEquivLits( pBox0->vLeafLits, Vec_IntArray(vMap0) ); - //Acec_MatchPrintEquivLits( pBox1->vLeafLits, Vec_IntArray(vMap1) ); + Acec_MatchCheckShift( pBox0->vLeafLits, pBox1->vLeafLits, vMap0, vMap1, pBox0->vRootLits, pBox1->vRootLits ); + + //Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vLeafLits, Vec_IntArray(vMap0), 0 ); + //Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vLeafLits, Vec_IntArray(vMap1), 0 ); + // reorder nodes to have the same order assert( pBox0->vShared == NULL ); assert( pBox1->vShared == NULL ); @@ -216,11 +303,15 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) assert( Vec_IntSize(vShared0) + Vec_IntSize(vUnique0) == Vec_IntSize(vLevel0) ); assert( Vec_IntSize(vShared1) + Vec_IntSize(vUnique1) == Vec_IntSize(vLevel1) ); } - Vec_IntFree( vMap0 ); - Vec_IntFree( vMap1 ); nTotal = Vec_WecSizeSize(pBox0->vShared); printf( "Box0: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox0->vLeafLits) ); printf( "Box1: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox1->vLeafLits) ); + + //Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vUnique, Vec_IntArray(vMap0), 0 ); + //Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vUnique, Vec_IntArray(vMap1), 0 ); + + Vec_IntFree( vMap0 ); + Vec_IntFree( vMap1 ); return nTotal; } @@ -258,6 +349,9 @@ int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) pGia1n = Acec_InsertBox( pBox1, 1 ); printf( "Matching of adder trees in LHS and RHS succeeded. " ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + // remove the last output + //Gia_ManPatchCoDriver( pGia0n, Gia_ManCoNum(pGia0n)-1, 0 ); + //Gia_ManPatchCoDriver( pGia1n, Gia_ManCoNum(pGia1n)-1, 0 ); } // solve regular CEC problem Cec_ManCecSetDefaultParams( pCecPars ); diff --git a/src/proof/acec/acecMult.c b/src/proof/acec/acecMult.c index 0733c00bf..d868c3995 100644 --- a/src/proof/acec/acecMult.c +++ b/src/proof/acec/acecMult.c @@ -504,14 +504,18 @@ Vec_Int_t * Acec_MultFindPPs( Gia_Man_t * p ) break; } } -/* - Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) ); - if ( Vec_IntSize(vSupp) == 4 ) printf( " " ); - if ( Vec_IntSize(vSupp) == 3 ) printf( " " ); - if ( Vec_IntSize(vSupp) <= 2 ) printf( " " ); - printf( " " ); - Vec_IntPrint( vSupp ); -*/ + /* + if ( Saved[i] ) + { + printf( "Obj = %4d ", iObj ); + Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) ); + if ( Vec_IntSize(vSupp) == 4 ) printf( " " ); + if ( Vec_IntSize(vSupp) == 3 ) printf( " " ); + if ( Vec_IntSize(vSupp) <= 2 ) printf( " " ); + printf( " " ); + Vec_IntPrint( vSupp ); + } + */ } Gia_ManCleanMark0(p); printf( "Collected %d pps and %d nodes.\n", nProds, Vec_IntSize(vBold) ); diff --git a/src/proof/acec/acecNorm.c b/src/proof/acec/acecNorm.c index 4ed32e7b4..0d2095240 100644 --- a/src/proof/acec/acecNorm.c +++ b/src/proof/acec/acecNorm.c @@ -112,7 +112,7 @@ int Acec_InsertBox_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) assert( Gia_ObjIsAnd(pObj) ); Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) ); Acec_InsertBox_rec( pNew, p, Gia_ObjFanin1(pObj) ); - return (pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) )); + return (pObj->Value = Gia_ManAppendAnd2( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) )); } Vec_Int_t * Acec_BuildTree( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t * vLeafLits ) { diff --git a/src/proof/acec/acecRe.c b/src/proof/acec/acecRe.c index 161b6fbb5..7f87df854 100644 --- a/src/proof/acec/acecRe.c +++ b/src/proof/acec/acecRe.c @@ -147,6 +147,7 @@ static inline int Ree_ManCutFind( int iObj, int * pCut ) } static inline int Ree_ManCutNotFind( int iObj1, int iObj2, int * pCut ) { + assert( pCut[0] == 3 ); if ( pCut[3] != iObj1 && pCut[3] != iObj2 ) return 0; if ( pCut[2] != iObj1 && pCut[2] != iObj2 ) return 1; if ( pCut[1] != iObj1 && pCut[1] != iObj2 ) return 2; @@ -162,13 +163,19 @@ static inline int Ree_ManCutTruthOne( int * pCut0, int * pCut ) Truth0 = fComp0 ? ~Truth0 : Truth0; if ( pCut0[0] == 2 ) { - int Truths[3][8] = { - { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, // {0,1,-} - { 0x00, 0x05, 0x0A, 0x0F, 0x50, 0x55, 0x5A, 0x5F }, // {0,-,1} - { 0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F } // {-,0,1} - }; - int Truth = Truths[Ree_ManCutNotFind(pCut0[1], pCut0[2], pCut)][Truth0 & 0x7]; - return 0xFF & (fComp0 ? ~Truth : Truth); + if ( pCut[0] == 3 ) + { + int Truths[3][8] = { + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, // {0,1,-} + { 0x00, 0x05, 0x0A, 0x0F, 0x50, 0x55, 0x5A, 0x5F }, // {0,-,1} + { 0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F } // {-,0,1} + }; + int Truth = Truths[Ree_ManCutNotFind(pCut0[1], pCut0[2], pCut)][Truth0 & 0x7]; + return 0xFF & (fComp0 ? ~Truth : Truth); + } + assert( pCut[0] == 2 ); + assert( pCut[1] == pCut0[1] && pCut[2] == pCut0[2] ); + return pCut0[pCut0[0]+1]; } if ( pCut0[0] == 1 ) { @@ -236,10 +243,10 @@ int Ree_ObjComputeTruth( Gia_Man_t * p, int iObj, int * pCut ) SeeAlso [] ***********************************************************************/ -void Ree_ManCutPrint( int * pCut, int Count, word Truth ) +void Ree_ManCutPrint( int * pCut, int Count, word Truth, int iObj ) { int c; - printf( "%d : ", Count ); + printf( "%d : %d : ", Count, iObj ); for ( c = 1; c <= pCut[0]; c++ ) printf( "%3d ", pCut[c] ); for ( ; c <= 4; c++ ) @@ -290,7 +297,7 @@ void Ree_ManCutMerge( Gia_Man_t * p, int iObj, int * pList0, int * pList1, Vec_I Vec_IntPushThree( vData, iObj, Value, TruthC ); } if ( fVerbose ) - Ree_ManCutPrint( pCut, ++Count, TruthC ); + Ree_ManCutPrint( pCut, ++Count, TruthC, iObj ); } if ( !vXors ) return; diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index fef369238..295fd7387 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -392,7 +392,7 @@ Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vI Vec_BitFree( vFound ); Vec_IntFree( vMap ); // filter trees - Acec_TreeFilterTrees( p, vAdds, vTrees ); + //Acec_TreeFilterTrees( p, vAdds, vTrees ); // sort by size Vec_WecSort( vTrees, 1 ); return vTrees; @@ -478,7 +478,7 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); Vec_Int_t * vLevel, * vMap; - int i, j, k, Box, Rank; + int i, j, k, Box, Rank, Count = 0; Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 ); pBox->pGia = p; @@ -532,6 +532,30 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree Vec_IntSort( vLevel, 0 ); Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) Vec_IntSort( vLevel, 0 ); + //return pBox; + // push literals forward + //Vec_WecPrint( pBox->vLeafLits, 0 ); + Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i ) + { + int This, Prev = Vec_IntEntry(vLevel, 0); + Vec_IntForEachEntryStart( vLevel, This, j, 1 ) + { + if ( Prev != This ) + { + Prev = This; + continue; + } + if ( i+1 >= Vec_WecSize(pBox->vLeafLits) ) + continue; + Vec_IntPushOrder( Vec_WecEntry(pBox->vLeafLits, i+1), This ); + Vec_IntDrop( vLevel, j-- ); + Vec_IntDrop( vLevel, j-- ); + Prev = -1; + Count++; + } + } + printf( "Pushed forward %d input literals.\n", Count ); + //Vec_WecPrint( pBox->vLeafLits, 0 ); return pBox; } void Acec_CreateBoxTest( Gia_Man_t * p ) From 153b71c1403ed79d7650ad702bb343e0490e36c9 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 15 Jan 2017 20:59:59 +0700 Subject: [PATCH 062/185] Updates to arithmetic verification. --- abcexe.dsp | 4 ++ src/aig/gia/gia.h | 2 + src/aig/gia/giaDup.c | 65 ++++++++++++++++++ src/aig/gia/giaShow.c | 13 +++- src/base/abci/abc.c | 54 ++++++++++++++- src/misc/vec/vecWec.h | 12 ++++ src/proof/acec/acec.h | 2 + src/proof/acec/acecCl.c | 88 ++++++++++++++++++++++++ src/proof/acec/acecCore.c | 124 +++++++++++++++++++++++++++++++--- src/proof/acec/acecInt.h | 2 + src/proof/acec/acecRe.c | 5 ++ src/proof/acec/acecTree.c | 138 ++++++++++++++++++++++++++++++++++---- src/proof/acec/acecUtil.c | 23 +++++++ 13 files changed, 505 insertions(+), 27 deletions(-) diff --git a/abcexe.dsp b/abcexe.dsp index 9d5152fc2..9ef992c07 100644 --- a/abcexe.dsp +++ b/abcexe.dsp @@ -88,6 +88,10 @@ LINK32=link.exe # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File +SOURCE=.\src\proof\acec\acecTree.c +# End Source File +# Begin Source File + SOURCE=.\src\base\main\main.c # End Source File # End Group diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index dc6c679ad..3bc97e6b0 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1242,6 +1242,8 @@ extern Gia_Man_t * Gia_ManChoiceMiter( Vec_Ptr_t * vGias ); extern Gia_Man_t * Gia_ManDupWithConstraints( Gia_Man_t * p, Vec_Int_t * vPoTypes ); extern Gia_Man_t * Gia_ManDupCones( Gia_Man_t * p, int * pPos, int nPos, int fTrimPis ); extern Gia_Man_t * Gia_ManDupAndCones( Gia_Man_t * p, int * pAnds, int nAnds, int fTrimPis ); +extern Gia_Man_t * Gia_ManDupAndConesLimit( Gia_Man_t * p, int * pAnds, int nAnds, int Level ); +extern Gia_Man_t * Gia_ManDupAndConesLimit2( Gia_Man_t * p, int * pAnds, int nAnds, int Level ); extern Gia_Man_t * Gia_ManDupOneHot( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupLevelized( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupFromVecs( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos, int nRegs ); diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index cdb6a2085..b0ba3472e 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -3045,6 +3045,71 @@ Gia_Man_t * Gia_ManDupAndCones( Gia_Man_t * p, int * pAnds, int nAnds, int fTrim Vec_PtrFree( vRoots ); return pNew; +} +void Gia_ManDupAndConesLimit_rec( Gia_Man_t * pNew, Gia_Man_t * p, int iObj, int Level ) +{ + Gia_Obj_t * pObj = Gia_ManObj(p, iObj); + if ( ~pObj->Value ) + return; + if ( !Gia_ObjIsAnd(pObj) || Gia_ObjLevel(p, pObj) < Level ) + { + pObj->Value = Gia_ManAppendCi( pNew ); + //printf( "PI %d for %d.\n", Abc_Lit2Var(pObj->Value), iObj ); + return; + } + Gia_ManDupAndConesLimit_rec( pNew, p, Gia_ObjFaninId0(pObj, iObj), Level ); + Gia_ManDupAndConesLimit_rec( pNew, p, Gia_ObjFaninId1(pObj, iObj), Level ); + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + //printf( "Obj %d for %d.\n", Abc_Lit2Var(pObj->Value), iObj ); +} +Gia_Man_t * Gia_ManDupAndConesLimit( Gia_Man_t * p, int * pAnds, int nAnds, int Level ) +{ + Gia_Man_t * pNew; + int i; + pNew = Gia_ManStart( 1000 ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManLevelNum( p ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + for ( i = 0; i < nAnds; i++ ) + Gia_ManDupAndConesLimit_rec( pNew, p, pAnds[i], Level ); + for ( i = 0; i < nAnds; i++ ) + Gia_ManAppendCo( pNew, Gia_ManObj(p, pAnds[i])->Value ); + return pNew; +} + +void Gia_ManDupAndConesLimit2_rec( Gia_Man_t * pNew, Gia_Man_t * p, int iObj, int Level ) +{ + Gia_Obj_t * pObj = Gia_ManObj(p, iObj); + if ( ~pObj->Value ) + return; + if ( !Gia_ObjIsAnd(pObj) || Level <= 0 ) + { + pObj->Value = Gia_ManAppendCi( pNew ); + //printf( "PI %d for %d.\n", Abc_Lit2Var(pObj->Value), iObj ); + return; + } + Gia_ManDupAndConesLimit2_rec( pNew, p, Gia_ObjFaninId0(pObj, iObj), Level-1 ); + Gia_ManDupAndConesLimit2_rec( pNew, p, Gia_ObjFaninId1(pObj, iObj), Level-1 ); + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + //printf( "Obj %d for %d.\n", Abc_Lit2Var(pObj->Value), iObj ); +} +Gia_Man_t * Gia_ManDupAndConesLimit2( Gia_Man_t * p, int * pAnds, int nAnds, int Level ) +{ + Gia_Man_t * pNew; + int i; + pNew = Gia_ManStart( 1000 ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + for ( i = 0; i < nAnds; i++ ) + Gia_ManDupAndConesLimit2_rec( pNew, p, pAnds[i], Level ); + for ( i = 0; i < nAnds; i++ ) + Gia_ManAppendCo( pNew, Gia_ManObj(p, pAnds[i])->Value ); + return pNew; + } /**Function************************************************************* diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index 4dd85aab6..4deebd7a1 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -1014,16 +1014,23 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_In SeeAlso [] ***********************************************************************/ -Vec_Int_t * Gia_ShowMapAdds( Gia_Man_t * p, Vec_Int_t * vAdds, int fFadds ) +Vec_Int_t * Gia_ShowMapAdds( Gia_Man_t * p, Vec_Int_t * vAdds, int fFadds, Vec_Int_t * vBold ) { - Vec_Int_t * vMapAdds = Vec_IntStartFull( Gia_ManObjNum(p) ); int i; + Vec_Bit_t * vIsBold = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Int_t * vMapAdds = Vec_IntStartFull( Gia_ManObjNum(p) ); int i, Entry; + if ( vBold ) + Vec_IntForEachEntry( vBold, Entry, i ) + Vec_BitWriteEntry( vIsBold, Entry, 1 ); for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) { if ( fFadds && Vec_IntEntry(vAdds, 6*i+2) == 0 ) continue; + if ( Vec_BitEntry(vIsBold, Vec_IntEntry(vAdds, 6*i+3)) || Vec_BitEntry(vIsBold, Vec_IntEntry(vAdds, 6*i+4)) ) + continue; Vec_IntWriteEntry( vMapAdds, Vec_IntEntry(vAdds, 6*i+3), i ); Vec_IntWriteEntry( vMapAdds, Vec_IntEntry(vAdds, 6*i+4), i ); } + Vec_BitFree( vIsBold ); return vMapAdds; } Vec_Int_t * Gia_ShowMapXors( Gia_Man_t * p, Vec_Int_t * vXors ) @@ -1105,7 +1112,7 @@ Vec_Int_t * Gia_ShowCollectObjs( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * v ***********************************************************************/ void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_Int_t * vAdds, Vec_Int_t * vXors, int fFadds ) { - Vec_Int_t * vMapAdds = Gia_ShowMapAdds( p, vAdds, fFadds ); + Vec_Int_t * vMapAdds = Gia_ShowMapAdds( p, vAdds, fFadds, vBold ); Vec_Int_t * vMapXors = Gia_ShowMapXors( p, vXors ); Vec_Int_t * vOrder = Gia_ShowCollectObjs( p, vAdds, vXors, vMapAdds, vMapXors ); Gia_WriteDotAig( p, pFileName, vBold, vAdds, vXors, vMapAdds, vMapXors, vOrder ); diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 9db3d7d65..58a14e817 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -482,6 +482,7 @@ static int Abc_CommandAbc9ATree ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9Polyn ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Acec ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Anorm ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Decla ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Esop ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Exorcism ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Mfs ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -1126,6 +1127,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&polyn", Abc_CommandAbc9Polyn, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&acec", Abc_CommandAbc9Acec, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&anorm", Abc_CommandAbc9Anorm, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&decla", Abc_CommandAbc9Decla, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&esop", Abc_CommandAbc9Esop, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&exorcism", Abc_CommandAbc9Exorcism, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&mfs", Abc_CommandAbc9Mfs, 0 ); @@ -40788,6 +40790,57 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9Decla( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Gia_Man_t * pTemp; + int c, fBooth = 0, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "bvh" ) ) != EOF ) + { + switch ( c ) + { + case 'b': + fBooth ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9Decla(): There is no AIG.\n" ); + return 0; + } + pTemp = Acec_ManDecla( pAbc->pGia, fBooth, fVerbose ); + Abc_FrameUpdateGia( pAbc, pTemp ); + return 0; + +usage: + Abc_Print( -2, "usage: &decla [-bvh]\n" ); + Abc_Print( -2, "\t removes carry look ahead adders\n" ); + Abc_Print( -2, "\t-b : toggles working with Booth multipliers [default = %s]\n", fBooth? "yes": "no" ); + Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + + /**Function************************************************************* Synopsis [] @@ -42690,7 +42743,6 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv ) // Jf_ManTestCnf( pAbc->pGia ); // Gia_ManCheckFalseTest( pAbc->pGia, nFrames ); // Gia_ParTest( pAbc->pGia, nWords, nProcs ); - Acec_MultFindPPsTest( pAbc->pGia ); // printf( "\nThis command is currently disabled.\n\n" ); return 0; diff --git a/src/misc/vec/vecWec.h b/src/misc/vec/vecWec.h index 8180e9847..c8c897017 100644 --- a/src/misc/vec/vecWec.h +++ b/src/misc/vec/vecWec.h @@ -561,6 +561,18 @@ static inline void Vec_WecPrint( Vec_Wec_t * p, int fSkipSingles ) printf( " }\n" ); } } +static inline void Vec_WecPrintLits( Vec_Wec_t * p ) +{ + Vec_Int_t * vVec; + int i, k, iLit; + Vec_WecForEachLevel( p, vVec, i ) + { + printf( " %4d : %2d {", i, Vec_IntSize(vVec) ); + Vec_IntForEachEntry( vVec, iLit, k ) + printf( " %c%d", Abc_LitIsCompl(iLit) ? '-' : '+', Abc_Lit2Var(iLit) ); + printf( " }\n" ); + } +} /**Function************************************************************* diff --git a/src/proof/acec/acec.h b/src/proof/acec/acec.h index 5a24bec7d..fcbd32df1 100644 --- a/src/proof/acec/acec.h +++ b/src/proof/acec/acec.h @@ -66,6 +66,8 @@ struct Acec_ParCec_t_ /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +/*=== acecCl.c ========================================================*/ +extern Gia_Man_t * Acec_ManDecla( Gia_Man_t * pGia, int fBooth, int fVerbose ); /*=== acecCore.c ========================================================*/ extern void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p ); extern int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ); diff --git a/src/proof/acec/acecCl.c b/src/proof/acec/acecCl.c index 145f2e0b2..6a5f4040e 100644 --- a/src/proof/acec/acecCl.c +++ b/src/proof/acec/acecCl.c @@ -335,6 +335,94 @@ Gia_Man_t * Acec_DetectAdditional( Gia_Man_t * p, int fVerbose ) return pNew; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Acec_RewriteTop( Gia_Man_t * p, Acec_Box_t * pBox ) +{ + Vec_Int_t * vRes = Vec_IntAlloc( Gia_ManCoNum(p) + 1 ); + Vec_Int_t * vLevel; + int i, k, iLit; + Vec_WecPrintLits( pBox->vRootLits ); + Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) + { + int In[3] = {0}, Out[2]; + assert( Vec_IntSize(vLevel) > 0 ); + assert( Vec_IntSize(vLevel) <= 3 ); + if ( Vec_IntSize(vLevel) == 1 ) + { + Vec_IntPush( vRes, Vec_IntEntry(vLevel, 0) ); + continue; + } + Vec_IntForEachEntry( vLevel, iLit, k ) + In[k] = iLit; + Acec_InsertFadd( p, In, Out ); + Vec_IntPush( vRes, Out[0] ); + if ( i+1 < Vec_WecSize(pBox->vRootLits) ) + Vec_IntPush( Vec_WecEntry(pBox->vRootLits, i+1), Out[1] ); + else + Vec_IntPush( Vec_WecPushLevel(pBox->vRootLits), Out[1] ); + } + assert( Vec_IntSize(vRes) >= Gia_ManCoNum(p) ); + Vec_IntShrink( vRes, Gia_ManCoNum(p) ); + return vRes; +} +Gia_Man_t * Acec_RewriteReplace( Gia_Man_t * p, Vec_Int_t * vRes ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj; int i; + assert( Gia_ManCoNum(p) == Vec_IntSize(vRes) ); + // create new manager + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManSetPhase( p ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManForEachAnd( p, pObj, i ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachCo( p, pObj, i ) + { + int iLit = Vec_IntEntry( vRes, i ); + int Phase1 = Gia_ObjPhase(pObj); + int Phase2 = Abc_LitIsCompl(iLit) ^ Gia_ObjPhase(Gia_ManObj(p, Abc_Lit2Var(iLit))); + int iLitNew = Abc_Var2Lit( Abc_Lit2Var(iLit), Phase1 ^ Phase2 ); + pObj->Value = Gia_ManAppendCo( pNew, iLitNew ); + } + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} +Gia_Man_t * Acec_ManDecla( Gia_Man_t * pGia, int fBooth, int fVerbose ) +{ + int status = -1; + abctime clk = Abc_Clock(); + Gia_Man_t * pNew = NULL; + Vec_Bit_t * vIgnore = fBooth ? Acec_BoothFindPPG(pGia) : NULL; + Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, fVerbose ); + Vec_Int_t * vResult; + Vec_BitFreeP( &vIgnore ); + if ( pBox == NULL ) // cannot match + { + printf( "Cannot find arithmetic boxes.\n" ); + return Gia_ManDup( pGia ); + } + vResult = Acec_RewriteTop( pGia, pBox ); + pNew = Acec_RewriteReplace( pGia, vResult ); + Vec_IntFree( vResult ); + return pNew; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index 6b631a1b3..4fddcfab2 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -30,6 +30,8 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +#define TRUTH_UNUSED 0x1234567812345678 + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -59,6 +61,79 @@ void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p ) p->iOutFail = -1; // the number of failed output } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_VerifyClasses( Gia_Man_t * p, Vec_Wec_t * vLits, Vec_Wec_t * vReprs ) +{ + Vec_Ptr_t * vFunc = Vec_PtrAlloc( Vec_WecSize(vLits) ); + Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); + Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; + int i, j, k, Entry, Entry2, nOvers = 0, nErrors = 0; + Vec_WecForEachLevel( vLits, vLevel, i ) + { + Vec_Wrd_t * vTruths = Vec_WrdAlloc( Vec_IntSize(vLevel) ); + Vec_IntForEachEntry( vLevel, Entry, k ) + { + word Truth = Gia_ObjComputeTruth6Cis( p, Entry, vSupp, vTemp ); + if ( Vec_IntSize(vSupp) > 6 ) + { + nOvers++; + Vec_WrdPush( vTruths, TRUTH_UNUSED ); + continue; + } + vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize ); + if ( Vec_IntSize(vSupp) > 5 ) + { + nOvers++; + Vec_WrdPush( vTruths, TRUTH_UNUSED ); + continue; + } + Vec_WrdPush( vTruths, Truth ); + } + Vec_PtrPush( vFunc, vTruths ); + } + if ( nOvers ) + printf( "Detected %d oversize support nodes.\n", nOvers ); + Vec_IntFree( vSupp ); + Vec_WrdFree( vTemp ); + // verify the classes + Vec_WecForEachLevel( vReprs, vLevel, i ) + { + Vec_Wrd_t * vTruths = (Vec_Wrd_t *)Vec_PtrEntry( vFunc, i ); + Vec_IntForEachEntry( vLevel, Entry, k ) + Vec_IntForEachEntryStart( vLevel, Entry2, j, k+1 ) + { + word Truth = Vec_WrdEntry( vTruths, k ); + word Truth2 = Vec_WrdEntry( vTruths, j ); + if ( Entry == Entry2 ) + { + nErrors++; + if ( Truth != Truth2 && Truth != TRUTH_UNUSED && Truth2 != TRUTH_UNUSED ) + printf( "Rank %d: Lit %d and %d do not pass verification.\n", i, k, j ); + } + if ( Entry == Abc_LitNot(Entry2) ) + { + nErrors++; + if ( Truth != ~Truth2 && Truth != TRUTH_UNUSED && Truth2 != TRUTH_UNUSED ) + printf( "Rank %d: Lit %d and %d do not pass verification.\n", i, k, j ); + } + } + } + if ( nErrors ) + printf( "Total errors in equivalence classes = %d.\n", nErrors ); + Vec_VecFree( (Vec_Vec_t *)vFunc ); +} + /**Function************************************************************* Synopsis [] @@ -148,13 +223,15 @@ void Acec_MatchBoxesSort( int * pArray, int nSize, int * pCostLits ) } void Acec_MatchPrintEquivLits( Gia_Man_t * p, Vec_Wec_t * vLits, int * pCostLits, int fVerbose ) { - Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); - Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); + Vec_Int_t * vSupp; + Vec_Wrd_t * vTemp; Vec_Int_t * vLevel; int i, k, Entry; printf( "Leaf literals and their classes:\n" ); Vec_WecForEachLevel( vLits, vLevel, i ) { + if ( Vec_IntSize(vLevel) == 0 ) + continue; printf( "Rank %2d : %2d ", i, Vec_IntSize(vLevel) ); Vec_IntForEachEntry( vLevel, Entry, k ) printf( "%s%d(%d) ", Abc_LitIsCompl(Entry) ? "-":"+", Abc_Lit2Var(Entry), Abc_Lit2LitL(pCostLits, Entry) ); @@ -162,13 +239,25 @@ void Acec_MatchPrintEquivLits( Gia_Man_t * p, Vec_Wec_t * vLits, int * pCostLits } if ( !fVerbose ) return; + vSupp = Vec_IntAlloc( 100 ); + vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); Vec_WecForEachLevel( vLits, vLevel, i ) { - if ( i != 20 ) + //if ( i != 20 ) + // continue; + if ( Vec_IntSize(vLevel) == 0 ) continue; Vec_IntForEachEntry( vLevel, Entry, k ) { word Truth = Gia_ObjComputeTruth6Cis( p, Entry, vSupp, vTemp ); +/* + { + int iObj = Abc_Lit2Var(Entry); + Gia_Man_t * pGia0 = Gia_ManDupAndCones( p, &iObj, 1, 1 ); + Gia_ManShow( pGia0, NULL, 0, 0, 0 ); + Gia_ManStop( pGia0 ); + } +*/ printf( "Rank = %4d : ", i ); printf( "Obj = %4d ", Abc_Lit2Var(Entry) ); if ( Vec_IntSize(vSupp) > 6 ) @@ -218,7 +307,7 @@ int Acec_MatchCountCommon( Vec_Wec_t * vLits1, Vec_Wec_t * vLits2, int Shift ) Vec_IntFree( vRes ); return nCommon; } -void Acec_MatchCheckShift( Vec_Wec_t * vLits0, Vec_Wec_t * vLits1, Vec_Int_t * vMap0, Vec_Int_t * vMap1, Vec_Wec_t * vRoots0, Vec_Wec_t * vRoots1 ) +void Acec_MatchCheckShift( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Vec_Wec_t * vLits0, Vec_Wec_t * vLits1, Vec_Int_t * vMap0, Vec_Int_t * vMap1, Vec_Wec_t * vRoots0, Vec_Wec_t * vRoots1 ) { Vec_Wec_t * vRes0 = Acec_MatchCopy( vLits0, vMap0 ); Vec_Wec_t * vRes1 = Acec_MatchCopy( vLits1, vMap1 ); @@ -229,14 +318,24 @@ void Acec_MatchCheckShift( Vec_Wec_t * vLits0, Vec_Wec_t * vLits1, Vec_Int_t * v { Vec_WecInsertLevel( vLits0, 0 ); Vec_WecInsertLevel( vRoots0, 0 ); + printf( "Shifted one level up.\n" ); } else if ( nCommonMinus > nCommonPlus && nCommonMinus > nCommon ) { Vec_WecInsertLevel( vLits1, 0 ); Vec_WecInsertLevel( vRoots1, 0 ); + printf( "Shifted one level down.\n" ); } - Vec_WecPrint( vRes0, 0 ); - Vec_WecPrint( vRes1, 0 ); + //printf( "Input literals:\n" ); + //Vec_WecPrintLits( vLits0 ); + printf( "Equiv classes:\n" ); + Vec_WecPrintLits( vRes0 ); + //printf( "Input literals:\n" ); + //Vec_WecPrintLits( vLits1 ); + printf( "Equiv classes:\n" ); + Vec_WecPrintLits( vRes1 ); + //Acec_VerifyClasses( pGia0, vLits0, vRes0 ); + //Acec_VerifyClasses( pGia1, vLits1, vRes1 ); Vec_WecFree( vRes0 ); Vec_WecFree( vRes1 ); } @@ -250,10 +349,14 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap0) ); Vec_WecForEachLevel( pBox1->vLeafLits, vLevel, i ) Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap1) ); - Acec_MatchCheckShift( pBox0->vLeafLits, pBox1->vLeafLits, vMap0, vMap1, pBox0->vRootLits, pBox1->vRootLits ); + Acec_MatchCheckShift( pBox0->pGia, pBox1->pGia, pBox0->vLeafLits, pBox1->vLeafLits, vMap0, vMap1, pBox0->vRootLits, pBox1->vRootLits ); //Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vLeafLits, Vec_IntArray(vMap0), 0 ); //Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vLeafLits, Vec_IntArray(vMap1), 0 ); + printf( "Outputs:\n" ); + Vec_WecPrintLits( pBox0->vRootLits ); + printf( "Outputs:\n" ); + Vec_WecPrintLits( pBox1->vRootLits ); // reorder nodes to have the same order assert( pBox0->vShared == NULL ); @@ -350,8 +453,11 @@ int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) printf( "Matching of adder trees in LHS and RHS succeeded. " ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); // remove the last output - //Gia_ManPatchCoDriver( pGia0n, Gia_ManCoNum(pGia0n)-1, 0 ); - //Gia_ManPatchCoDriver( pGia1n, Gia_ManCoNum(pGia1n)-1, 0 ); + Gia_ManPatchCoDriver( pGia0n, Gia_ManCoNum(pGia0n)-1, 0 ); + Gia_ManPatchCoDriver( pGia1n, Gia_ManCoNum(pGia1n)-1, 0 ); + + Gia_ManPatchCoDriver( pGia0n, Gia_ManCoNum(pGia0n)-2, 0 ); + Gia_ManPatchCoDriver( pGia1n, Gia_ManCoNum(pGia1n)-2, 0 ); } // solve regular CEC problem Cec_ManCecSetDefaultParams( pCecPars ); diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index cc5786bb8..c49945dba 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -71,8 +71,10 @@ extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdd extern Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits ); extern Vec_Bit_t * Acec_BoothFindPPG( Gia_Man_t * p ); /*=== acecNorm.c ========================================================*/ +extern void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] ); extern Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ); /*=== acecTree.c ========================================================*/ +extern void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ); extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fVerbose ); extern void Acec_BoxFreeP( Acec_Box_t ** ppBox ); /*=== acecUtil.c ========================================================*/ diff --git a/src/proof/acec/acecRe.c b/src/proof/acec/acecRe.c index 7f87df854..5e5ca6886 100644 --- a/src/proof/acec/acecRe.c +++ b/src/proof/acec/acecRe.c @@ -450,6 +450,7 @@ Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose Hash_IntManStop( pHash ); Ree_ManRemoveTrivial( p, vAdds ); Ree_ManRemoveContained( p, vAdds ); + //Ree_ManPrintAdders( vAdds, 1 ); return vAdds; } @@ -523,6 +524,10 @@ void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ) { pObjX = Gia_ManObj( p, Vec_IntEntry(vAdds, 6*i+3) ); pObjM = Gia_ManObj( p, Vec_IntEntry(vAdds, 6*i+4) ); + // rule out if MAJ is a fanout of XOR + //if ( pObjX == Gia_ObjFanin0(pObjM) || pObjX == Gia_ObjFanin1(pObjM) ) + // continue; + // rule out if MAJ is a fanin of XOR and has no other fanouts if ( (pObjM == Gia_ObjFanin0(pObjX) || pObjM == Gia_ObjFanin1(pObjX)) && Gia_ObjRefNum(p, pObjM) == 1 ) continue; } diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index 295fd7387..2b3565747 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -64,6 +64,30 @@ void Acec_BoxFreeP( Acec_Box_t ** ppBox ) *ppBox = NULL; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_VerifyBoxLeaves( Acec_Box_t * pBox, Vec_Bit_t * vIgnore ) +{ + Vec_Int_t * vLevel; + int i, k, iLit, Count = 0; + if ( vIgnore == NULL ) + return; + Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + if ( Gia_ObjIsAnd(Gia_ManObj(pBox->pGia, Abc_Lit2Var(iLit))) && !Vec_BitEntry(vIgnore, Abc_Lit2Var(iLit)) ) + printf( "Internal node %d of rank %d is not part of PPG.\n", Abc_Lit2Var(iLit), i ), Count++; + printf( "Detected %d suspicious leaves.\n", Count ); +} + /**Function************************************************************* Synopsis [Filters trees by removing TFO of roots.] @@ -103,6 +127,18 @@ void Acec_TreeFilterOne( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) // remove those that overlap with roots Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) { +/* + if ( Vec_IntEntry(vAdds, 6*Box+3) == 24 && Vec_IntEntry(vAdds, 6*Box+4) == 22 ) + { + printf( "**** removing special one \n" ); + continue; + } + if ( Vec_IntEntry(vAdds, 6*Box+3) == 48 && Vec_IntEntry(vAdds, 6*Box+4) == 49 ) + { + printf( "**** removing special one \n" ); + continue; + } +*/ if ( Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+3)) || Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+4)) ) { printf( "Removing box %d=(%d,%d) of rank %d.\n", Box, Vec_IntEntry(vAdds, 6*Box+3), Vec_IntEntry(vAdds, 6*Box+4), Rank ); @@ -123,6 +159,73 @@ void Acec_TreeFilterTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vTrees Acec_TreeFilterOne( p, vAdds, vLevel ); } +/**Function************************************************************* + + Synopsis [Filters trees by removing TFO of roots.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_TreeMarkTFI_rec( Gia_Man_t * p, int Id, Vec_Bit_t * vMarked ) +{ + Gia_Obj_t * pObj = Gia_ManObj(p, Id); + if ( Vec_BitEntry(vMarked, Id) ) + return; + Vec_BitWriteEntry( vMarked, Id, 1 ); + if ( !Gia_ObjIsAnd(pObj) ) + return; + Acec_TreeMarkTFI_rec( p, Gia_ObjFaninId0(pObj, Id), vMarked ); + Acec_TreeMarkTFI_rec( p, Gia_ObjFaninId1(pObj, Id), vMarked ); +} +void Acec_TreeFilterOne2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) +{ + Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Bit_t * vMarked = Vec_BitStart( Gia_ManObjNum(p) ) ; + Gia_Obj_t * pObj; + int i, k = 0, Box, Rank; + // mark leaves + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 ); + } + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+3), 0 ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+4), 0 ); + } + // mark TFI of leaves + Gia_ManForEachAnd( p, pObj, i ) + if ( Vec_BitEntry(vIsLeaf, i) ) + Acec_TreeMarkTFI_rec( p, i, vMarked ); + // remove those that overlap with the marked TFI + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + if ( Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+3)) || Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+4)) ) + { + printf( "Removing box %d=(%d,%d) of rank %d.\n", Box, Vec_IntEntry(vAdds, 6*Box+3), Vec_IntEntry(vAdds, 6*Box+4), Rank ); + continue; + } + Vec_IntWriteEntry( vTree, k++, Box ); + Vec_IntWriteEntry( vTree, k++, Rank ); + } + Vec_IntShrink( vTree, k ); + Vec_BitFree( vIsLeaf ); + Vec_BitFree( vMarked ); +} +void Acec_TreeFilterTrees2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vTrees ) +{ + Vec_Int_t * vLevel; + int i; + Vec_WecForEachLevel( vTrees, vLevel, i ) + Acec_TreeFilterOne2( p, vAdds, vLevel ); +} + /**Function************************************************************* Synopsis [] @@ -392,7 +495,7 @@ Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vI Vec_BitFree( vFound ); Vec_IntFree( vMap ); // filter trees - //Acec_TreeFilterTrees( p, vAdds, vTrees ); + Acec_TreeFilterTrees( p, vAdds, vTrees ); // sort by size Vec_WecSort( vTrees, 1 ); return vTrees; @@ -437,20 +540,11 @@ void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ) { printf( " %4d : %2d {", i, Vec_IntSize(vLevel) ); Vec_IntForEachEntry( vLevel, iBox, k ) + { printf( " %s%d=(%d,%d)", Vec_IntEntry(vAdds, 6*iBox+2) == 0 ? "*":"", iBox, Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) ); - printf( " }\n" ); - } -} -void Vec_WecPrintLits( Vec_Wec_t * p ) -{ - Vec_Int_t * vVec; - int i, k, Entry; - Vec_WecForEachLevel( p, vVec, i ) - { - printf( " %4d : %2d {", i, Vec_IntSize(vVec) ); - Vec_IntForEachEntry( vVec, Entry, k ) - printf( " %c%d", Abc_LitIsCompl(Entry) ? '-' : '+', Abc_Lit2Var(Entry) ); + //printf( "(%d,%d,%d)", Vec_IntEntry(vAdds, 6*iBox+0), Vec_IntEntry(vAdds, 6*iBox+1), Vec_IntEntry(vAdds, 6*iBox+2) ); + } printf( " }\n" ); } } @@ -505,7 +599,10 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree Vec_WecForEachLevelReverse( pBox->vAdds, vLevel, i ) Vec_IntForEachEntry( vLevel, Box, k ) if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+4) ) ) + { + //printf( "Pushing phase of output %d of box %d\n", Vec_IntEntry(vAdds, 6*Box+4), Box ); Acec_TreePhases_rec( p, vAdds, vMap, Vec_IntEntry(vAdds, 6*Box+4), Vec_IntEntry(vAdds, 6*Box+2) != 0, vVisit ); + } Acec_TreeVerifyPhases( p, vAdds, pBox->vAdds ); Acec_TreeVerifyPhases2( p, vAdds, pBox->vAdds ); Vec_BitFree( vVisit ); @@ -521,7 +618,14 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree Vec_WecPush( pBox->vLeafLits, i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) ); for ( k = 3; k < 5; k++ ) if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) ) + { + //if ( Vec_IntEntry(vAdds, 6*Box+k) == 10942 ) + //{ + // printf( "++++++++++++ Skipping special\n" ); + // continue; + //} Vec_WecPush( pBox->vRootLits, k == 4 ? i + 1 : i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) ); + } if ( Vec_IntEntry(vAdds, 6*Box+2) == 0 && Acec_SignBit2(vAdds, Box, 2) ) Vec_WecPush( pBox->vLeafLits, i, 1 ); } @@ -531,8 +635,9 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i ) Vec_IntSort( vLevel, 0 ); Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) - Vec_IntSort( vLevel, 0 ); + Vec_IntSort( vLevel, 1 ); //return pBox; +/* // push literals forward //Vec_WecPrint( pBox->vLeafLits, 0 ); Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i ) @@ -555,6 +660,7 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree } } printf( "Pushed forward %d input literals.\n", Count ); +*/ //Vec_WecPrint( pBox->vLeafLits, 0 ); return pBox; } @@ -607,13 +713,17 @@ Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fVerbose ) Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, fVerbose ); Vec_Wec_t * vTrees = Acec_TreeFindTrees( p, vAdds, vIgnore ); if ( vTrees && Vec_WecSize(vTrees) > 0 ) + { pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, 0) ); + Acec_VerifyBoxLeaves( pBox, vIgnore ); + } if ( pBox )//&& fVerbose ) printf( "Processing tree %d: Ranks = %d. Adders = %d. Leaves = %d. Roots = %d.\n", 0, Vec_WecSize(pBox->vAdds), Vec_WecSizeSize(pBox->vAdds), Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); if ( pBox && fVerbose ) Acec_PrintBox( pBox, vAdds ); + //Acec_PrintAdders( pBox0->vAdds, vAdds ); //Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); Vec_WecFreeP( &vTrees ); Vec_IntFree( vAdds ); diff --git a/src/proof/acec/acecUtil.c b/src/proof/acec/acecUtil.c index 191856cfd..be12afeff 100644 --- a/src/proof/acec/acecUtil.c +++ b/src/proof/acec/acecUtil.c @@ -90,6 +90,29 @@ void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose ) Vec_IntFree( vXors ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupTopMostRange( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Vec_Int_t * vTops = Vec_IntAlloc( 10 ); + int i; + for ( i = 45; i < 52; i++ ) + Vec_IntPush( vTops, Gia_ObjId( p, Gia_ObjFanin0(Gia_ManCo(p, i)) ) ); + pNew = Gia_ManDupAndConesLimit( p, Vec_IntArray(vTops), Vec_IntSize(vTops), 100 ); + Vec_IntFree( vTops ); + return pNew; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// From 7457b8a64ae92880b8c04f1128298ee51becb76f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 16 Jan 2017 22:36:23 +0700 Subject: [PATCH 063/185] Updates to arithmetic verification. --- src/proof/acec/acecCl.c | 33 +++++++++++++++++++++++---------- src/proof/acec/acecCore.c | 20 ++++++++++---------- src/proof/acec/acecInt.h | 2 +- src/proof/acec/acecNorm.c | 2 +- src/proof/acec/acecTree.c | 28 ++++++++++++++++++++-------- 5 files changed, 55 insertions(+), 30 deletions(-) diff --git a/src/proof/acec/acecCl.c b/src/proof/acec/acecCl.c index 6a5f4040e..6185677b7 100644 --- a/src/proof/acec/acecCl.c +++ b/src/proof/acec/acecCl.c @@ -350,9 +350,15 @@ Vec_Int_t * Acec_RewriteTop( Gia_Man_t * p, Acec_Box_t * pBox ) { Vec_Int_t * vRes = Vec_IntAlloc( Gia_ManCoNum(p) + 1 ); Vec_Int_t * vLevel; - int i, k, iLit; - Vec_WecPrintLits( pBox->vRootLits ); - Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) + int i, k, iStart, iLit, Driver, Count = 0; + // determine how much to shift + Driver = Gia_ObjFaninId0p( p, Gia_ManCo(p, 0) ); + Vec_WecForEachLevel( pBox->vRootLits, vLevel, iStart ) + if ( Abc_Lit2Var(Vec_IntEntry(vLevel,0)) == Driver ) + break; + assert( iStart < Gia_ManCoNum(p) ); + //Vec_WecPrintLits( pBox->vRootLits ); + Vec_WecForEachLevelStart( pBox->vRootLits, vLevel, i, iStart ) { int In[3] = {0}, Out[2]; assert( Vec_IntSize(vLevel) > 0 ); @@ -370,9 +376,11 @@ Vec_Int_t * Acec_RewriteTop( Gia_Man_t * p, Acec_Box_t * pBox ) Vec_IntPush( Vec_WecEntry(pBox->vRootLits, i+1), Out[1] ); else Vec_IntPush( Vec_WecPushLevel(pBox->vRootLits), Out[1] ); + Count++; } assert( Vec_IntSize(vRes) >= Gia_ManCoNum(p) ); Vec_IntShrink( vRes, Gia_ManCoNum(p) ); + printf( "Added %d adders for replace CLAs. ", Count ); return vRes; } Gia_Man_t * Acec_RewriteReplace( Gia_Man_t * p, Vec_Int_t * vRes ) @@ -384,7 +392,6 @@ Gia_Man_t * Acec_RewriteReplace( Gia_Man_t * p, Vec_Int_t * vRes ) pNew = Gia_ManStart( Gia_ManObjNum(p) ); pNew->pName = Abc_UtilStrsav( p->pName ); pNew->pSpec = Abc_UtilStrsav( p->pSpec ); - Gia_ManSetPhase( p ); Gia_ManFillValue( p ); Gia_ManConst0(p)->Value = 0; Gia_ManForEachCi( p, pObj, i ) @@ -394,22 +401,26 @@ Gia_Man_t * Acec_RewriteReplace( Gia_Man_t * p, Vec_Int_t * vRes ) Gia_ManForEachCo( p, pObj, i ) { int iLit = Vec_IntEntry( vRes, i ); - int Phase1 = Gia_ObjPhase(pObj); - int Phase2 = Abc_LitIsCompl(iLit) ^ Gia_ObjPhase(Gia_ManObj(p, Abc_Lit2Var(iLit))); - int iLitNew = Abc_Var2Lit( Abc_Lit2Var(iLit), Phase1 ^ Phase2 ); - pObj->Value = Gia_ManAppendCo( pNew, iLitNew ); + Gia_Obj_t * pRepr = Gia_ManObj( p, Abc_Lit2Var(iLit) ); + pObj->Value = Gia_ManAppendCo( pNew, pRepr->Value ); } + // set correct phase + Gia_ManSetPhase( p ); + Gia_ManSetPhase( pNew ); + Gia_ManForEachCo( pNew, pObj, i ) + if ( Gia_ObjPhase(pObj) != Gia_ObjPhase(Gia_ManCo(p, i)) ) + Gia_ObjFlipFaninC0( pObj ); + // remove dangling nodes pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManStop( pTemp ); return pNew; } Gia_Man_t * Acec_ManDecla( Gia_Man_t * pGia, int fBooth, int fVerbose ) { - int status = -1; abctime clk = Abc_Clock(); Gia_Man_t * pNew = NULL; Vec_Bit_t * vIgnore = fBooth ? Acec_BoothFindPPG(pGia) : NULL; - Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, fVerbose ); + Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, 0, 0, fVerbose ); Vec_Int_t * vResult; Vec_BitFreeP( &vIgnore ); if ( pBox == NULL ) // cannot match @@ -418,8 +429,10 @@ Gia_Man_t * Acec_ManDecla( Gia_Man_t * pGia, int fBooth, int fVerbose ) return Gia_ManDup( pGia ); } vResult = Acec_RewriteTop( pGia, pBox ); + Acec_BoxFreeP( &pBox ); pNew = Acec_RewriteReplace( pGia, vResult ); Vec_IntFree( vResult ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); return pNew; } diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index 4fddcfab2..06385f3c6 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -328,12 +328,12 @@ void Acec_MatchCheckShift( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Vec_Wec_t * vLi } //printf( "Input literals:\n" ); //Vec_WecPrintLits( vLits0 ); - printf( "Equiv classes:\n" ); - Vec_WecPrintLits( vRes0 ); + //printf( "Equiv classes:\n" ); + //Vec_WecPrintLits( vRes0 ); //printf( "Input literals:\n" ); //Vec_WecPrintLits( vLits1 ); - printf( "Equiv classes:\n" ); - Vec_WecPrintLits( vRes1 ); + //printf( "Equiv classes:\n" ); + //Vec_WecPrintLits( vRes1 ); //Acec_VerifyClasses( pGia0, vLits0, vRes0 ); //Acec_VerifyClasses( pGia1, vLits1, vRes1 ); Vec_WecFree( vRes0 ); @@ -353,10 +353,10 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) //Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vLeafLits, Vec_IntArray(vMap0), 0 ); //Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vLeafLits, Vec_IntArray(vMap1), 0 ); - printf( "Outputs:\n" ); - Vec_WecPrintLits( pBox0->vRootLits ); - printf( "Outputs:\n" ); - Vec_WecPrintLits( pBox1->vRootLits ); + //printf( "Outputs:\n" ); + //Vec_WecPrintLits( pBox0->vRootLits ); + //printf( "Outputs:\n" ); + //Vec_WecPrintLits( pBox1->vRootLits ); // reorder nodes to have the same order assert( pBox0->vShared == NULL ); @@ -438,8 +438,8 @@ int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) Cec_ParCec_t ParsCec, * pCecPars = &ParsCec; Vec_Bit_t * vIgnore0 = pPars->fBooth ? Acec_BoothFindPPG(pGia0) : NULL; Vec_Bit_t * vIgnore1 = pPars->fBooth ? Acec_BoothFindPPG(pGia1) : NULL; - Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0, vIgnore0, pPars->fVerbose ); - Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1, vIgnore1, pPars->fVerbose ); + Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0, vIgnore0, 0, 0, pPars->fVerbose ); + Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1, vIgnore1, 0, 0, pPars->fVerbose ); Vec_BitFreeP( &vIgnore0 ); Vec_BitFreeP( &vIgnore1 ); if ( pBox0 == NULL || pBox1 == NULL ) // cannot match diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index c49945dba..b8ec24554 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -75,7 +75,7 @@ extern void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] ); extern Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ); /*=== acecTree.c ========================================================*/ extern void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ); -extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fVerbose ); +extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fFilterIn, int fFilterOut, int fVerbose ); extern void Acec_BoxFreeP( Acec_Box_t ** ppBox ); /*=== acecUtil.c ========================================================*/ extern void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose ); diff --git a/src/proof/acec/acecNorm.c b/src/proof/acec/acecNorm.c index 0d2095240..6b36589cd 100644 --- a/src/proof/acec/acecNorm.c +++ b/src/proof/acec/acecNorm.c @@ -201,7 +201,7 @@ Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ) Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fBooth, int fVerbose ) { Vec_Bit_t * vIgnore = fBooth ? Acec_BoothFindPPG( pGia ) : NULL; - Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, fVerbose ); + Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, 0, 0, fVerbose ); Gia_Man_t * pNew = Acec_InsertBox( pBox, 1 ); Acec_BoxFreeP( &pBox ); Vec_BitFreeP( &vIgnore ); diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index 2b3565747..fe5ca01b0 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -127,6 +127,10 @@ void Acec_TreeFilterOne( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) // remove those that overlap with roots Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) { + // special case of the first bit +// if ( i == 0 ) +// continue; + /* if ( Vec_IntEntry(vAdds, 6*Box+3) == 24 && Vec_IntEntry(vAdds, 6*Box+4) == 22 ) { @@ -415,7 +419,7 @@ Vec_Int_t * Acec_TreeFindPoints( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * v int i; for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) { - if ( vIgnore && (Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+3)) || Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+4))) ) + if ( vIgnore && (Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+3)) && Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+4))) ) continue; Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+0), i, 0 ); Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+1), i, 0 ); @@ -468,7 +472,7 @@ void Acec_TreeFindTrees_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iObj, int Acec_TreeFindTrees2_rec( vAdds, vMap, In, Acec_TreeWhichPoint(vAdds, In, iObj) == 4 ? Rank-1 : Rank, vTree, vFound ); Acec_TreeFindTrees2_rec( vAdds, vMap, Out, Rank, vTree, vFound ); } -Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vIgnore ) +Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vIgnore, int fFilterIn, int fFilterOut ) { Vec_Wec_t * vTrees = Vec_WecAlloc( 10 ); Vec_Int_t * vMap = Acec_TreeFindPoints( p, vAdds, vIgnore ); @@ -495,7 +499,10 @@ Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vI Vec_BitFree( vFound ); Vec_IntFree( vMap ); // filter trees - Acec_TreeFilterTrees( p, vAdds, vTrees ); + if ( fFilterIn ) + Acec_TreeFilterTrees2( p, vAdds, vTrees ); + else if ( fFilterOut ) + Acec_TreeFilterTrees( p, vAdds, vTrees ); // sort by size Vec_WecSort( vTrees, 1 ); return vTrees; @@ -511,7 +518,7 @@ void Acec_TreeFindTreesTest( Gia_Man_t * p ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); clk = Abc_Clock(); - vTrees = Acec_TreeFindTrees( p, vAdds, NULL ); + vTrees = Acec_TreeFindTrees( p, vAdds, NULL, 0, 0 ); printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); Vec_WecPrint( vTrees, 0 ); @@ -572,7 +579,7 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); Vec_Int_t * vLevel, * vMap; - int i, j, k, Box, Rank, Count = 0; + int i, j, k, Box, Rank;//, Count = 0; Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 ); pBox->pGia = p; @@ -583,6 +590,11 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree // collect boxes; mark inputs/outputs Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) { +// if ( 37 == Box && 6 == Rank ) +// { +// printf( "Skipping one adder...\n" ); +// continue; +// } Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 ); Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 ); Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 ); @@ -677,7 +689,7 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); clk = Abc_Clock(); - vTrees = Acec_TreeFindTrees( p, vAdds, NULL ); + vTrees = Acec_TreeFindTrees( p, vAdds, NULL, 0, 0 ); printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); //Vec_WecPrint( vTrees, 0 ); @@ -707,11 +719,11 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fVerbose ) +Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fFilterIn, int fFilterOut, int fVerbose ) { Acec_Box_t * pBox = NULL; Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, fVerbose ); - Vec_Wec_t * vTrees = Acec_TreeFindTrees( p, vAdds, vIgnore ); + Vec_Wec_t * vTrees = Acec_TreeFindTrees( p, vAdds, vIgnore, fFilterIn, fFilterOut ); if ( vTrees && Vec_WecSize(vTrees) > 0 ) { pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, 0) ); From b193ef056d2fb11d5e24b7e4f250e07d069c2ae2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 19 Jan 2017 13:24:47 +0800 Subject: [PATCH 064/185] Updates to arithmetic verification. --- src/proof/acec/acecCore.c | 58 +++++++++++++++++++++++++++++++++++++-- src/proof/acec/acecNorm.c | 51 ++++++++++++++++++++-------------- src/proof/acec/acecTree.c | 5 +++- 3 files changed, 90 insertions(+), 24 deletions(-) diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index 06385f3c6..a23417042 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -307,6 +307,50 @@ int Acec_MatchCountCommon( Vec_Wec_t * vLits1, Vec_Wec_t * vLits2, int Shift ) Vec_IntFree( vRes ); return nCommon; } +void Vec_IntInsertOrder( Vec_Int_t * vLits, Vec_Int_t * vClasses, int Lit, int Class ) +{ + int i; + for ( i = Vec_IntSize(vClasses)-1; i >= 0; i-- ) + if ( Vec_IntEntry(vClasses,i) >= Class ) + break; + Vec_IntInsert( vLits, i+1, Lit ); + Vec_IntInsert( vClasses, i+1, Class ); +} +void Acec_MoveDuplicates( Vec_Wec_t * vLits, Vec_Wec_t * vClasses ) +{ + Vec_Int_t * vLevel1, * vLevel2; + int i, k, Prev, This, Entry; + Vec_WecForEachLevel( vLits, vLevel1, i ) + { + if ( i == Vec_WecSize(vLits) - 1 ) + break; + vLevel2 = Vec_WecEntry(vClasses, i); + assert( Vec_IntSize(vLevel1) == Vec_IntSize(vLevel2) ); + Prev = -1; + Vec_IntForEachEntry( vLevel2, This, k ) + { + if ( Prev != This ) + { + Prev = This; + continue; + } + Prev = -1; + Entry = Vec_IntEntry( vLevel1, k ); + + Vec_IntDrop( vLevel1, k ); + Vec_IntDrop( vLevel2, k-- ); + + Vec_IntDrop( vLevel1, k ); + Vec_IntDrop( vLevel2, k-- ); + + Vec_IntInsertOrder( Vec_WecEntry(vLits, i+1), Vec_WecEntry(vClasses, i+1), Entry, This ); + + assert( Vec_IntSize(vLevel1) == Vec_IntSize(vLevel2) ); + assert( Vec_IntSize(Vec_WecEntry(vLits, i+1)) == Vec_IntSize(Vec_WecEntry(vClasses, i+1)) ); + } + } +} + void Acec_MatchCheckShift( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Vec_Wec_t * vLits0, Vec_Wec_t * vLits1, Vec_Int_t * vMap0, Vec_Int_t * vMap1, Vec_Wec_t * vRoots0, Vec_Wec_t * vRoots1 ) { Vec_Wec_t * vRes0 = Acec_MatchCopy( vLits0, vMap0 ); @@ -318,14 +362,20 @@ void Acec_MatchCheckShift( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Vec_Wec_t * vLi { Vec_WecInsertLevel( vLits0, 0 ); Vec_WecInsertLevel( vRoots0, 0 ); + Vec_WecInsertLevel( vRes0, 0 ); printf( "Shifted one level up.\n" ); } else if ( nCommonMinus > nCommonPlus && nCommonMinus > nCommon ) { Vec_WecInsertLevel( vLits1, 0 ); Vec_WecInsertLevel( vRoots1, 0 ); + Vec_WecInsertLevel( vRes1, 0 ); printf( "Shifted one level down.\n" ); } + Acec_MoveDuplicates( vLits0, vRes0 ); + Acec_MoveDuplicates( vLits1, vRes1 ); + + //Vec_WecPrintLits( vLits1 ); //printf( "Input literals:\n" ); //Vec_WecPrintLits( vLits0 ); //printf( "Equiv classes:\n" ); @@ -410,6 +460,10 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) printf( "Box0: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox0->vLeafLits) ); printf( "Box1: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox1->vLeafLits) ); + //Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vShared, Vec_IntArray(vMap0), 0 ); + //Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vShared, Vec_IntArray(vMap1), 0 ); + //printf( "\n" ); + //Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vUnique, Vec_IntArray(vMap0), 0 ); //Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vUnique, Vec_IntArray(vMap1), 0 ); @@ -448,8 +502,8 @@ int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) printf( "Cannot match arithmetic boxes in LHS and RHS. Trying regular CEC.\n" ); else { - pGia0n = Acec_InsertBox( pBox0, 1 ); - pGia1n = Acec_InsertBox( pBox1, 1 ); + pGia0n = Acec_InsertBox( pBox0, 0 ); + pGia1n = Acec_InsertBox( pBox1, 0 ); printf( "Matching of adder trees in LHS and RHS succeeded. " ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); // remove the last output diff --git a/src/proof/acec/acecNorm.c b/src/proof/acec/acecNorm.c index 6b36589cd..f2acb37b2 100644 --- a/src/proof/acec/acecNorm.c +++ b/src/proof/acec/acecNorm.c @@ -76,9 +76,19 @@ Vec_Int_t * Acec_InsertTree( Gia_Man_t * pNew, Vec_Wec_t * vLeafMap ) { if ( Vec_IntSize(vLevel) == 2 ) Vec_IntPush( vLevel, 0 ); - In[2] = Vec_IntPop( vLevel ); - In[1] = Vec_IntPop( vLevel ); - In[0] = Vec_IntPop( vLevel ); + //In[2] = Vec_IntPop( vLevel ); + //In[1] = Vec_IntPop( vLevel ); + //In[0] = Vec_IntPop( vLevel ); + + In[0] = Vec_IntEntry( vLevel, 0 ); + Vec_IntDrop( vLevel, 0 ); + + In[1] = Vec_IntEntry( vLevel, 0 ); + Vec_IntDrop( vLevel, 0 ); + + In[2] = Vec_IntEntry( vLevel, 0 ); + Vec_IntDrop( vLevel, 0 ); + Acec_InsertFadd( pNew, In, Out ); Vec_IntPush( vLevel, Out[0] ); if ( i+1 < Vec_WecSize(vLeafMap) ) @@ -114,11 +124,22 @@ int Acec_InsertBox_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) Acec_InsertBox_rec( pNew, p, Gia_ObjFanin1(pObj) ); return (pObj->Value = Gia_ManAppendAnd2( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) )); } -Vec_Int_t * Acec_BuildTree( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t * vLeafLits ) +Vec_Int_t * Acec_BuildTree( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Int_t * vRootLits ) { Vec_Wec_t * vLeafMap = Vec_WecStart( Vec_WecSize(vLeafLits) ); Vec_Int_t * vLevel, * vRootRanks; int i, k, iLit, iLitNew; + // add roo literals + if ( vRootLits ) + Vec_IntForEachEntry( vRootLits, iLit, i ) + { + if ( i < Vec_WecSize(vLeafMap) ) + vLevel = Vec_WecEntry(vLeafMap, i); + else + vLevel = Vec_WecPushLevel(vLeafMap); + Vec_IntPush( vLevel, iLit ); + } + // add other literals Vec_WecForEachLevel( vLeafLits, vLevel, i ) Vec_IntForEachEntry( vLevel, iLit, k ) { @@ -137,7 +158,7 @@ Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ) Gia_Man_t * p = pBox->pGia; Gia_Man_t * pNew; Gia_Obj_t * pObj; - Vec_Int_t * vRootRanks, * vLevel; + Vec_Int_t * vRootRanks, * vLevel, * vTemp; int i, k, iLit, iLitNew; pNew = Gia_ManStart( Gia_ManObjNum(p) ); pNew->pName = Abc_UtilStrsav( p->pName ); @@ -148,26 +169,14 @@ Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ) pObj->Value = Gia_ManAppendCi( pNew ); // implement tree if ( fAll ) - vRootRanks = Acec_BuildTree( pNew, p, pBox->vLeafLits ); + vRootRanks = Acec_BuildTree( pNew, p, pBox->vLeafLits, NULL ); else { - Vec_Wec_t * vLeafLits; assert( pBox->vShared != NULL ); assert( pBox->vUnique != NULL ); - vRootRanks = Acec_BuildTree( p, p, pBox->vShared ); - // add these roots to the unique ones - vLeafLits = Vec_WecDup( pBox->vUnique ); - Vec_IntForEachEntry( vRootRanks, iLit, i ) - { - if ( i < Vec_WecSize(vLeafLits) ) - vLevel = Vec_WecEntry(vLeafLits, i); - else - vLevel = Vec_WecPushLevel(vLeafLits); - Vec_IntPush( vLevel, iLit ); - } - Vec_IntFree( vRootRanks ); - vRootRanks = Acec_BuildTree( pNew, p, vLeafLits ); - Vec_WecFree( vLeafLits ); + vRootRanks = Acec_BuildTree( pNew, p, pBox->vShared, NULL ); + vRootRanks = Acec_BuildTree( pNew, p, pBox->vUnique, vTemp = vRootRanks ); + Vec_IntFree( vTemp ); } // update polarity of literals Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index fe5ca01b0..2461c89bd 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -207,6 +207,9 @@ void Acec_TreeFilterOne2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) Gia_ManForEachAnd( p, pObj, i ) if ( Vec_BitEntry(vIsLeaf, i) ) Acec_TreeMarkTFI_rec( p, i, vMarked ); + // additional one +//if ( 10942 < Gia_ManObjNum(p) ) +// Acec_TreeMarkTFI_rec( p, 10942, vMarked ); // remove those that overlap with the marked TFI Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) { @@ -419,7 +422,7 @@ Vec_Int_t * Acec_TreeFindPoints( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * v int i; for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) { - if ( vIgnore && (Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+3)) && Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+4))) ) + if ( vIgnore && (Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+3)) || Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+4))) ) continue; Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+0), i, 0 ); Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+1), i, 0 ); From a28be94ac79c0cbb0960565573985838d7a27a79 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 21 Jan 2017 11:59:01 +0800 Subject: [PATCH 065/185] Small fixes and a change to &cec to allow two files names given as command-line arguments. --- src/aig/gia/giaIf.c | 16 ++--- src/aig/gia/giaTim.c | 2 + src/base/abci/abc.c | 125 +++++++++++++++++++++++++------------- src/base/abci/abcVerify.c | 14 +++-- 4 files changed, 103 insertions(+), 54 deletions(-) diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c index ac748f8c7..ab80a7628 100644 --- a/src/aig/gia/giaIf.c +++ b/src/aig/gia/giaIf.c @@ -544,20 +544,20 @@ void Gia_ManPrintMappingStats( Gia_Man_t * p, char * pDumpFile ) fprintf( pTable, "%d ", Gia_ManAndNum(p) ); fprintf( pTable, "%d ", nLuts ); fprintf( pTable, "%d ", Gia_ManLutLevelWithBoxes(p) ); - fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) ); - fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) ); - fprintf( pTable, "%.2f", 1.0*(Abc_Clock() - clk)/CLOCKS_PER_SEC ); + //fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) ); + //fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) ); + //fprintf( pTable, "%.2f", 1.0*(Abc_Clock() - clk)/CLOCKS_PER_SEC ); clk = Abc_Clock(); } else { - printf( "This part of the code is currently not used.\n" ); - assert( 0 ); + //printf( "This part of the code is currently not used.\n" ); + //assert( 0 ); fprintf( pTable, " " ); fprintf( pTable, "%d ", nLuts ); - fprintf( pTable, "%d ", LevelMax ); - fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) ); - fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) ); + fprintf( pTable, "%d ", Gia_ManLutLevelWithBoxes(p) ); + //fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) ); + //fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) ); fprintf( pTable, "%.2f", 1.0*(Abc_Clock() - clk)/CLOCKS_PER_SEC ); clk = Abc_Clock(); } diff --git a/src/aig/gia/giaTim.c b/src/aig/gia/giaTim.c index 71b9a4757..29aa93f8e 100644 --- a/src/aig/gia/giaTim.c +++ b/src/aig/gia/giaTim.c @@ -584,6 +584,8 @@ int Gia_ManLutLevelWithBoxes( Gia_Man_t * p ) Gia_Obj_t * pObj, * pObjIn; int i, k, j, curCi, curCo, LevelMax; assert( Gia_ManRegNum(p) == 0 ); + if ( pManTime == NULL ) + return Gia_ManLutLevel(p, NULL); // copy const and real PIs Gia_ManCleanLevels( p, Gia_ManObjNum(p) ); Gia_ObjSetLevel( p, Gia_ManConst0(p), 0 ); diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 58a14e817..806a5de79 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -32927,8 +32927,7 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) { Cec_ParCec_t ParsCec, * pPars = &ParsCec; FILE * pFile; - Gia_Man_t * pSecond, * pMiter; - char * FileName, * pTemp; + Gia_Man_t * pGias[2] = {NULL, NULL}, * pMiter; char ** pArgvNew; int c, nArgcNew, fMiter = 0, fDualOutput = 0, fDumpMiter = 0; Cec_ManCecSetDefaultParams( pPars ); @@ -32983,13 +32982,15 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } } - if ( pAbc->pGia == NULL ) - { - Abc_Print( -1, "Abc_CommandAbc9Cec(): There is no AIG.\n" ); - return 1; - } + pArgvNew = argv + globalUtilOptind; + nArgcNew = argc - globalUtilOptind; if ( fMiter ) { + if ( pAbc->pGia == NULL || nArgcNew != 0 ) + { + Abc_Print( -1, "Abc_CommandAbc9Cec(): A miter cannot be given as an argument of command &cec and should be entered using &r.\n" ); + return 1; + } if ( fDualOutput ) { if ( Gia_ManPoNum(pAbc->pGia) & 1 ) @@ -32998,14 +32999,14 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) return 1; } if ( !pPars->fSilent ) - Abc_Print( 1, "Assuming the current network is a double-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit ); + Abc_Print( 1, "Assuming the current network is a double-output miter.\n" ); pAbc->Status = Cec_ManVerify( pAbc->pGia, pPars ); } else { Gia_Man_t * pTemp; if ( !pPars->fSilent ) - Abc_Print( 1, "Assuming the current network is a single-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit ); + Abc_Print( 1, "Assuming the current network is a single-output miter.\n" ); pTemp = Gia_ManDemiterToDual( pAbc->pGia ); pAbc->Status = Cec_ManVerify( pTemp, pPars ); ABC_SWAP( Abc_Cex_t *, pAbc->pGia->pCexComb, pTemp->pCexComb ); @@ -33014,41 +33015,81 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb ); return 0; } - - pArgvNew = argv + globalUtilOptind; - nArgcNew = argc - globalUtilOptind; - if ( nArgcNew != 1 ) + if ( nArgcNew > 2 ) { - if ( pAbc->pGia->pSpec == NULL ) - { - Abc_Print( -1, "File name is not given on the command line.\n" ); - return 1; - } - FileName = pAbc->pGia->pSpec; - } - else - FileName = pArgvNew[0]; - // fix the wrong symbol - for ( pTemp = FileName; *pTemp; pTemp++ ) - if ( *pTemp == '>' ) - *pTemp = '\\'; - if ( (pFile = fopen( FileName, "r" )) == NULL ) - { - Abc_Print( -1, "Cannot open input file \"%s\". ", FileName ); - if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) ) - Abc_Print( 1, "Did you mean \"%s\"?", FileName ); - Abc_Print( 1, "\n" ); + Abc_Print( -1, "Abc_CommandAbc9Cec(): Wrong number of command-line arguments.\n" ); return 1; } - fclose( pFile ); - pSecond = Gia_AigerRead( FileName, 0, 0, 0 ); - if ( pSecond == NULL ) + if ( nArgcNew == 2 ) { - Abc_Print( -1, "Reading AIGER has failed.\n" ); - return 0; + char * pFileNames[2] = { pArgvNew[0], pArgvNew[1] }, * pTemp; + int n; + for ( n = 0; n < 2; n++ ) + { + // fix the wrong symbol + for ( pTemp = pFileNames[n]; *pTemp; pTemp++ ) + if ( *pTemp == '>' ) + *pTemp = '\\'; + if ( (pFile = fopen( pFileNames[n], "r" )) == NULL ) + { + Abc_Print( -1, "Cannot open input file \"%s\". ", pFileNames[n] ); + if ( (pFileNames[n] = Extra_FileGetSimilarName( pFileNames[n], ".aig", NULL, NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", pFileNames[n] ); + Abc_Print( 1, "\n" ); + return 1; + } + fclose( pFile ); + pGias[n] = Gia_AigerRead( pFileNames[n], 0, 0, 0 ); + if ( pGias[n] == NULL ) + { + Abc_Print( -1, "Reading AIGER from file \"%s\" has failed.\n", pFileNames[n] ); + return 0; + } + } + } + else + { + char * FileName, * pTemp; + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9Cec(): There is no current AIG.\n" ); + return 1; + } + pGias[0] = pAbc->pGia; + if ( nArgcNew == 1 ) + FileName = pArgvNew[0]; + else + { + assert( nArgcNew == 0 ); + if ( pAbc->pGia->pSpec == NULL ) + { + Abc_Print( -1, "File name is not given on the command line.\n" ); + return 1; + } + FileName = pAbc->pGia->pSpec; + } + // fix the wrong symbol + for ( pTemp = FileName; *pTemp; pTemp++ ) + if ( *pTemp == '>' ) + *pTemp = '\\'; + if ( (pFile = fopen( FileName, "r" )) == NULL ) + { + Abc_Print( -1, "Cannot open input file \"%s\". ", FileName ); + if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", FileName ); + Abc_Print( 1, "\n" ); + return 1; + } + fclose( pFile ); + pGias[1] = Gia_AigerRead( FileName, 0, 0, 0 ); + if ( pGias[1] == NULL ) + { + Abc_Print( -1, "Reading AIGER has failed.\n" ); + return 0; + } } // compute the miter - pMiter = Gia_ManMiter( pAbc->pGia, pSecond, 0, 1, 0, 0, pPars->fVerbose ); + pMiter = Gia_ManMiter( pGias[0], pGias[1], 0, 1, 0, 0, pPars->fVerbose ); if ( pMiter ) { if ( fDumpMiter ) @@ -33057,10 +33098,12 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) Gia_AigerWrite( pMiter, "cec_miter.aig", 0, 0 ); } pAbc->Status = Cec_ManVerify( pMiter, pPars ); - Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb ); + Abc_FrameReplaceCex( pAbc, &pGias[0]->pCexComb ); Gia_ManStop( pMiter ); } - Gia_ManStop( pSecond ); + if ( pGias[0] != pAbc->pGia ) + Gia_ManStop( pGias[0] ); + Gia_ManStop( pGias[1] ); return 0; usage: @@ -36178,7 +36221,7 @@ int Abc_CommandAbc9SatLut( Abc_Frame_t * pAbc, int argc, char ** argv ) usage: Abc_Print( -2, "usage: &satlut [-NICDQ num] [-drwvh]\n" ); - Abc_Print( -2, "\t performs SAT-based remapping of the 4-LUT network\n" ); + Abc_Print( -2, "\t performs SAT-based remapping of the LUT-mapped network\n" ); Abc_Print( -2, "\t-N num : the limit on AIG nodes in the window (num <= 128) [default = %d]\n", nNumber ); Abc_Print( -2, "\t-I num : the limit on the number of improved windows [default = %d]\n", nImproves ); Abc_Print( -2, "\t-C num : the limit on the number of conflicts [default = %d]\n", nBTLimit ); diff --git a/src/base/abci/abcVerify.c b/src/base/abci/abcVerify.c index 25d1d1130..7199c5296 100644 --- a/src/base/abci/abcVerify.c +++ b/src/base/abci/abcVerify.c @@ -122,6 +122,7 @@ void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nI ***********************************************************************/ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fVerbose ) { + abctime clk = Abc_Clock(); Prove_Params_t Params, * pParams = &Params; // Fraig_Params_t Params; // Fraig_Man_t * pMan; @@ -170,18 +171,20 @@ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fV RetValue = Abc_NtkMiterIsConstant( pMiter ); if ( RetValue == 0 ) { - printf( "Networks are NOT EQUIVALENT after structural hashing.\n" ); + printf( "Networks are NOT EQUIVALENT after structural hashing. " ); // report the error pMiter->pModel = Abc_NtkVerifyGetCleanModel( pMiter, 1 ); Abc_NtkVerifyReportError( pNtk1, pNtk2, pMiter->pModel ); ABC_FREE( pMiter->pModel ); Abc_NtkDelete( pMiter ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); return; } if ( RetValue == 1 ) { - printf( "Networks are equivalent after structural hashing.\n" ); + printf( "Networks are equivalent after structural hashing. " ); Abc_NtkDelete( pMiter ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); return; } /* @@ -220,18 +223,19 @@ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fV // pParams->fVerbose = 1; RetValue = Abc_NtkIvyProve( &pMiter, pParams ); if ( RetValue == -1 ) - printf( "Networks are undecided (resource limits is reached).\n" ); + printf( "Networks are undecided (resource limits is reached). " ); else if ( RetValue == 0 ) { int * pSimInfo = Abc_NtkVerifySimulatePattern( pMiter, pMiter->pModel ); if ( pSimInfo[0] != 1 ) printf( "ERROR in Abc_NtkMiterProve(): Generated counter-example is invalid.\n" ); else - printf( "Networks are NOT EQUIVALENT.\n" ); + printf( "Networks are NOT EQUIVALENT. " ); ABC_FREE( pSimInfo ); } else - printf( "Networks are equivalent.\n" ); + printf( "Networks are equivalent. " ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); if ( pMiter->pModel ) Abc_NtkVerifyReportError( pNtk1, pNtk2, pMiter->pModel ); Abc_NtkDelete( pMiter ); From cf539dcca475d1c7f862834e8718bb318b54d5fd Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 21 Jan 2017 12:48:40 +0800 Subject: [PATCH 066/185] Fix mismatch in output formatting. --- src/aig/saig/saigMiter.c | 4 ++-- src/base/abci/abcDar.c | 12 ++++++------ src/proof/cec/cecCec.c | 6 +++--- src/proof/fra/fraCec.c | 6 +++--- src/proof/fra/fraSec.c | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/aig/saig/saigMiter.c b/src/aig/saig/saigMiter.c index 67aed490d..598103de9 100644 --- a/src/aig/saig/saigMiter.c +++ b/src/aig/saig/saigMiter.c @@ -1111,12 +1111,12 @@ int Ssw_SecSpecial( Aig_Man_t * pPart0, Aig_Man_t * pPart1, int nFrames, int fVe // report the miter if ( RetValue == 1 ) { - printf( "Networks are equivalent. " ); + printf( "Networks are equivalent. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } else if ( RetValue == 0 ) { - printf( "Networks are NOT EQUIVALENT. " ); + printf( "Networks are NOT EQUIVALENT. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); if ( pMiterCec->pData == NULL ) printf( "Counter-example is not available.\n" ); diff --git a/src/base/abci/abcDar.c b/src/base/abci/abcDar.c index 9f6724853..147f7c2ff 100644 --- a/src/base/abci/abcDar.c +++ b/src/base/abci/abcDar.c @@ -1946,17 +1946,17 @@ finish: // report the miter if ( RetValue == 1 ) { - Abc_Print( 1, "Networks are equivalent. " ); + Abc_Print( 1, "Networks are equivalent. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } else if ( RetValue == 0 ) { - Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); + Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } else { - Abc_Print( 1, "Networks are UNDECIDED. " ); + Abc_Print( 1, "Networks are UNDECIDED. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } fflush( stdout ); @@ -3695,17 +3695,17 @@ int Abc_NtkDarInduction( Abc_Ntk_t * pNtk, int nTimeOut, int nFramesMax, int nCo RetValue = Saig_ManInduction( pMan, nTimeOut, nFramesMax, nConfMax, fUnique, fUniqueAll, fGetCex, fVerbose, fVeryVerbose ); if ( RetValue == 1 ) { - Abc_Print( 1, "Networks are equivalent. " ); + Abc_Print( 1, "Networks are equivalent. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } else if ( RetValue == 0 ) { - Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); + Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } else { - Abc_Print( 1, "Networks are UNDECIDED. " ); + Abc_Print( 1, "Networks are UNDECIDED. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } if ( fGetCex ) diff --git a/src/proof/cec/cecCec.c b/src/proof/cec/cecCec.c index 77a6ed4a7..f7e45c57a 100644 --- a/src/proof/cec/cecCec.c +++ b/src/proof/cec/cecCec.c @@ -85,7 +85,7 @@ int Cec_ManVerifyOld( Gia_Man_t * pMiter, int fVerbose, int * piOutFail, abctime { if ( !fSilent ) { - Abc_Print( 1, "Networks are equivalent. " ); + Abc_Print( 1, "Networks are equivalent. " ); Abc_PrintTime( 1, "Time", Abc_Clock() - clkTotal ); } } @@ -93,7 +93,7 @@ int Cec_ManVerifyOld( Gia_Man_t * pMiter, int fVerbose, int * piOutFail, abctime { if ( !fSilent ) { - Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); + Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); Abc_PrintTime( 1, "Time", Abc_Clock() - clkTotal ); } if ( pMiterCec->pData == NULL ) @@ -120,7 +120,7 @@ int Cec_ManVerifyOld( Gia_Man_t * pMiter, int fVerbose, int * piOutFail, abctime } else if ( !fSilent ) { - Abc_Print( 1, "Networks are UNDECIDED. " ); + Abc_Print( 1, "Networks are UNDECIDED. " ); Abc_PrintTime( 1, "Time", Abc_Clock() - clkTotal ); } fflush( stdout ); diff --git a/src/proof/fra/fraCec.c b/src/proof/fra/fraCec.c index 130036a61..84f37930d 100644 --- a/src/proof/fra/fraCec.c +++ b/src/proof/fra/fraCec.c @@ -547,17 +547,17 @@ int Fra_FraigCecTop( Aig_Man_t * pMan1, Aig_Man_t * pMan2, int nConfLimit, int n // report the miter if ( RetValue == 1 ) { - printf( "Networks are equivalent. " ); + printf( "Networks are equivalent. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } else if ( RetValue == 0 ) { - printf( "Networks are NOT EQUIVALENT. " ); + printf( "Networks are NOT EQUIVALENT. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } else { - printf( "Networks are UNDECIDED. " ); + printf( "Networks are UNDECIDED. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } fflush( stdout ); diff --git a/src/proof/fra/fraSec.c b/src/proof/fra/fraSec.c index 06011d2e9..7e382fc89 100644 --- a/src/proof/fra/fraSec.c +++ b/src/proof/fra/fraSec.c @@ -606,7 +606,7 @@ finish: { if ( !pParSec->fSilent ) { - printf( "Networks are equivalent. " ); + printf( "Networks are equivalent. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } if ( pParSec->fReportSolution && !pParSec->fRecursive ) @@ -630,7 +630,7 @@ ABC_PRT( "Time", Abc_Clock() - clkTotal ); } if ( !pParSec->fSilent ) { - printf( "Networks are NOT EQUIVALENT. " ); + printf( "Networks are NOT EQUIVALENT. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } if ( pParSec->fReportSolution && !pParSec->fRecursive ) From 51f4dab475af1ffd22d23b5aeb8d7cf243739f75 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 24 Jan 2017 20:02:19 -0800 Subject: [PATCH 067/185] Adding features for invariant minimization. --- src/base/main/mainFrame.c | 4 - src/base/main/mainInt.h | 2 - src/base/wlc/wlcAbc.c | 155 ++++++++++--- src/base/wlc/wlcCom.c | 456 ++++++++++++++++++++++++++++---------- src/proof/pdr/pdrCore.c | 4 +- src/proof/pdr/pdrInv.c | 228 +++++++++++++++++++ src/proof/pdr/pdrUtil.c | 2 +- 7 files changed, 686 insertions(+), 165 deletions(-) diff --git a/src/base/main/mainFrame.c b/src/base/main/mainFrame.c index 05cb09c13..9647d020e 100644 --- a/src/base/main/mainFrame.c +++ b/src/base/main/mainFrame.c @@ -95,8 +95,6 @@ void Abc_FrameSetStatus( int Status ) { ABC_FREE( s_Globa void Abc_FrameSetManDsd( void * pMan ) { if (s_GlobalFrame->pManDsd && s_GlobalFrame->pManDsd != pMan) If_DsdManFree((If_DsdMan_t *)s_GlobalFrame->pManDsd, 0); s_GlobalFrame->pManDsd = pMan; } void Abc_FrameSetManDsd2( void * pMan ) { if (s_GlobalFrame->pManDsd2 && s_GlobalFrame->pManDsd2 != pMan) If_DsdManFree((If_DsdMan_t *)s_GlobalFrame->pManDsd2, 0); s_GlobalFrame->pManDsd2 = pMan; } void Abc_FrameSetInv( Vec_Int_t * vInv ) { Vec_IntFreeP(&s_GlobalFrame->pAbcWlcInv); s_GlobalFrame->pAbcWlcInv = vInv; } -void Abc_FrameSetCnf( Vec_Int_t * vCnf ) { Vec_IntFreeP(&s_GlobalFrame->pAbcWlcCnf); s_GlobalFrame->pAbcWlcCnf = vCnf; } -void Abc_FrameSetStr( Vec_Str_t * vStr ) { Vec_StrFreeP(&s_GlobalFrame->pAbcWlcStr); s_GlobalFrame->pAbcWlcStr = vStr; } void Abc_FrameSetJsonStrs( Abc_Nam_t * pStrs ) { Abc_NamDeref( s_GlobalFrame->pJsonStrs ); s_GlobalFrame->pJsonStrs = pStrs; } void Abc_FrameSetJsonObjs( Vec_Wec_t * vObjs ) { Vec_WecFreeP(&s_GlobalFrame->vJsonObjs ); s_GlobalFrame->vJsonObjs = vObjs; } @@ -227,8 +225,6 @@ void Abc_FrameDeallocate( Abc_Frame_t * p ) ABC_FREE( p->pCex2 ); ABC_FREE( p->pCex ); Vec_IntFreeP( &p->pAbcWlcInv ); - Vec_IntFreeP( &p->pAbcWlcCnf ); - Vec_StrFreeP( &p->pAbcWlcStr ); Abc_NamDeref( s_GlobalFrame->pJsonStrs ); Vec_WecFreeP(&s_GlobalFrame->vJsonObjs ); ABC_FREE( p ); diff --git a/src/base/main/mainInt.h b/src/base/main/mainInt.h index ff59b81a7..278a9191e 100644 --- a/src/base/main/mainInt.h +++ b/src/base/main/mainInt.h @@ -129,8 +129,6 @@ struct Abc_Frame_t_ void * pAbc85Delay; void * pAbcWlc; Vec_Int_t * pAbcWlcInv; - Vec_Int_t * pAbcWlcCnf; - Vec_Str_t * pAbcWlcStr; void * pAbcBac; void * pAbcCba; void * pAbcPla; diff --git a/src/base/wlc/wlcAbc.c b/src/base/wlc/wlcAbc.c index 0bf27f7b3..1a98fb71c 100644 --- a/src/base/wlc/wlcAbc.c +++ b/src/base/wlc/wlcAbc.c @@ -42,7 +42,7 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ) +void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vCounts, int fVerbose ) { Wlc_Obj_t * pObj; int i, k, nNum, nRange, nBits = 0; @@ -53,7 +53,7 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ) nRange = Wlc_ObjRange(pObj); for ( k = 0; k < nRange; k++ ) { - nNum = Vec_IntEntry(vInv, nBits + k); + nNum = Vec_IntEntry(vCounts, nBits + k); if ( nNum ) break; } @@ -65,7 +65,7 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ) printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg ); for ( k = 0; k < nRange; k++ ) { - nNum = Vec_IntEntry( vInv, nBits + k ); + nNum = Vec_IntEntry( vCounts, nBits + k ); if ( nNum == 0 ) continue; printf( " [%d] -> %d", k, nNum ); @@ -73,8 +73,8 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ) printf( "\n"); nBits += nRange; } - //printf( "%d %d\n", Vec_IntSize(vInv), nBits ); - assert( Vec_IntSize(vInv) == nBits ); + //printf( "%d %d\n", Vec_IntSize(vCounts), nBits ); + assert( Vec_IntSize(vCounts) == nBits ); } /**Function************************************************************* @@ -88,8 +88,14 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ) SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop, int fVerbose ) +Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv ) { + extern Vec_Int_t * Pdr_InvCounts( Vec_Int_t * vInv ); + extern Vec_Str_t * Pdr_InvPrintStr( Vec_Int_t * vInv, Vec_Int_t * vCounts ); + + Vec_Int_t * vCounts = Pdr_InvCounts( vInv ); + Vec_Str_t * vSop = Pdr_InvPrintStr( vInv, vCounts ); + Wlc_Obj_t * pObj; int i, k, nNum, nRange, nBits = 0; Abc_Ntk_t * pMainNtk = NULL; @@ -98,46 +104,69 @@ Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop, // start the network pMainNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 ); // duplicate the name and the spec - pMainNtk->pName = Extra_UtilStrsav(pNtk->pName); + pMainNtk->pName = Extra_UtilStrsav(pNtk ? pNtk->pName : "inv"); // create primary inputs - Wlc_NtkForEachCi( pNtk, pObj, i ) + if ( pNtk == NULL ) { - if ( pObj->Type != WLC_OBJ_FO ) - continue; - nRange = Wlc_ObjRange(pObj); - for ( k = 0; k < nRange; k++ ) + int Entry, nInputs = Abc_SopGetVarNum( Vec_StrArray(vSop) ); + Vec_IntForEachEntry( vCounts, Entry, i ) { - nNum = Vec_IntEntry(vInv, nBits + k); - if ( nNum ) - break; - } - if ( k == nRange ) - { - nBits += nRange; - continue; - } - //printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg ); - for ( k = 0; k < nRange; k++ ) - { - nNum = Vec_IntEntry( vInv, nBits + k ); - if ( nNum == 0 ) + if ( Entry == 0 ) continue; - //printf( " [%d] -> %d", k, nNum ); pMainObj = Abc_NtkCreatePi( pMainNtk ); - sprintf( Buffer, "%s[%d]", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), k ); + sprintf( Buffer, "pi%d", i ); Abc_ObjAssignName( pMainObj, Buffer, NULL ); - } - //printf( "\n"); - nBits += nRange; + if ( Abc_NtkPiNum(pMainNtk) != nInputs ) + { + printf( "Mismatch between number of inputs and the number of literals in the invariant.\n" ); + Abc_NtkDelete( pMainNtk ); + return NULL; + } } - //printf( "%d %d\n", Vec_IntSize(vInv), nBits ); - assert( Vec_IntSize(vInv) == nBits ); + else + { + Wlc_NtkForEachCi( pNtk, pObj, i ) + { + if ( pObj->Type != WLC_OBJ_FO ) + continue; + nRange = Wlc_ObjRange(pObj); + for ( k = 0; k < nRange; k++ ) + { + nNum = Vec_IntEntry(vCounts, nBits + k); + if ( nNum ) + break; + } + if ( k == nRange ) + { + nBits += nRange; + continue; + } + //printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg ); + for ( k = 0; k < nRange; k++ ) + { + nNum = Vec_IntEntry( vCounts, nBits + k ); + if ( nNum == 0 ) + continue; + //printf( " [%d] -> %d", k, nNum ); + pMainObj = Abc_NtkCreatePi( pMainNtk ); + sprintf( Buffer, "%s[%d]", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), k ); + Abc_ObjAssignName( pMainObj, Buffer, NULL ); + + } + //printf( "\n"); + nBits += nRange; + } + } + //printf( "%d %d\n", Vec_IntSize(vCounts), nBits ); + assert( pNtk == NULL || Vec_IntSize(vCounts) == nBits ); // create node pMainObj = Abc_NtkCreateNode( pMainNtk ); Abc_NtkForEachPi( pMainNtk, pMainTemp, i ) Abc_ObjAddFanin( pMainObj, pMainTemp ); pMainObj->pData = Abc_SopRegister( (Mem_Flex_t *)pMainNtk->pManFunc, Vec_StrArray(vSop) ); + Vec_IntFree( vCounts ); + Vec_StrFree( vSop ); // create PO pMainTemp = Abc_NtkCreatePo( pMainNtk ); Abc_ObjAddFanin( pMainTemp, pMainObj ); @@ -145,6 +174,66 @@ Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop, return pMainNtk; } +/**Function************************************************************* + + Synopsis [Translate current network into an interpolant.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, int nRegs ) +{ + Vec_Int_t * vRes = NULL; + if ( Abc_NtkPoNum(pNtk) != 1 ) + printf( "The number of outputs is other than 1.\n" ); + else if ( Abc_NtkNodeNum(pNtk) != 1 ) + printf( "The number of internal nodes is other than 1.\n" ); + else + { + Abc_Obj_t * pNode = Abc_ObjFanin0( Abc_NtkCo(pNtk, 0) ); + char * pName, * pCube, * pSop = (char *)pNode->pData; + Vec_Int_t * vFanins = Vec_IntAlloc( Abc_ObjFaninNum(pNode) ); + Abc_Obj_t * pFanin; int i, k, Value, nLits; + Abc_ObjForEachFanin( pNode, pFanin, i ) + { + assert( Abc_ObjIsCi(pFanin) ); + pName = Abc_ObjName(pFanin); + for ( k = (int)strlen(pName)-1; k >= 0; k-- ) + if ( pName[k] < '0' || pName[k] > '9' ) + break; + if ( k == (int)strlen(pName)-1 ) + { + printf( "Cannot read input name of fanin %d.\n", i ); + Value = i; + } + else + Value = atoi(pName + k + 1); + Vec_IntPush( vFanins, Value ); + } + assert( Vec_IntSize(vFanins) == Abc_ObjFaninNum(pNode) ); + vRes = Vec_IntAlloc( 1000 ); + Vec_IntPush( vRes, Abc_SopGetCubeNum(pSop) ); + Abc_SopForEachCube( pSop, Abc_ObjFaninNum(pNode), pCube ) + { + nLits = 0; + Abc_CubeForEachVar( pCube, Value, k ) + if ( Value != '-' ) + nLits++; + Vec_IntPush( vRes, nLits ); + Abc_CubeForEachVar( pCube, Value, k ) + if ( Value != '-' ) + Vec_IntPush( vRes, Abc_Var2Lit(Vec_IntEntry(vFanins, k), (int)Value == '0') ); + } + Vec_IntPush( vRes, nRegs ); + Vec_IntFree( vFanins ); + } + return vRes; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index f3eb6dd7a..93614938a 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -32,18 +32,21 @@ static int Abc_CommandReadWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandPsInv ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandGetInv ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvPrint ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvCheck ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvGet ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvPut ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvMin ( Abc_Frame_t * pAbc, int argc, char ** argv ); + static inline Wlc_Ntk_t * Wlc_AbcGetNtk( Abc_Frame_t * pAbc ) { return (Wlc_Ntk_t *)pAbc->pAbcWlc; } static inline void Wlc_AbcFreeNtk( Abc_Frame_t * pAbc ) { if ( pAbc->pAbcWlc ) Wlc_NtkFree(Wlc_AbcGetNtk(pAbc)); } static inline void Wlc_AbcUpdateNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk ) { Wlc_AbcFreeNtk(pAbc); pAbc->pAbcWlc = pNtk; } static inline Vec_Int_t * Wlc_AbcGetInv( Abc_Frame_t * pAbc ) { return pAbc->pAbcWlcInv; } -static inline Vec_Int_t * Wlc_AbcGetCnf( Abc_Frame_t * pAbc ) { return pAbc->pAbcWlcCnf; } -static inline Vec_Str_t * Wlc_AbcGetStr( Abc_Frame_t * pAbc ) { return pAbc->pAbcWlcStr; } //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -66,10 +69,15 @@ void Wlc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Word level", "%write", Abc_CommandWriteWlc, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%psinv", Abc_CommandPsInv, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%getinv", Abc_CommandGetInv, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%test", Abc_CommandTest, 0 ); + + Cmd_CommandAdd( pAbc, "Word level", "inv_ps", Abc_CommandInvPs, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_print", Abc_CommandInvPrint, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_check", Abc_CommandInvCheck, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_get", Abc_CommandInvGet, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_put", Abc_CommandInvPut, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_min", Abc_CommandInvMin, 0 ); } /**Function******************************************************************** @@ -429,122 +437,6 @@ usage: return 1; } -/**Function******************************************************************** - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -******************************************************************************/ -int Abc_CommandPsInv( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - extern void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ); - Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); - int c, fVerbose = 0; - Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) - { - switch ( c ) - { - case 'v': - fVerbose ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - if ( pNtk == NULL ) - { - Abc_Print( 1, "Abc_CommandPsInv(): There is no current design.\n" ); - return 0; - } - if ( Wlc_AbcGetNtk(pAbc) == NULL ) - { - Abc_Print( 1, "Abc_CommandPsInv(): There is no saved invariant.\n" ); - return 0; - } - if ( Wlc_AbcGetInv(pAbc) == NULL ) - { - Abc_Print( 1, "Abc_CommandPsInv(): Invariant is not available.\n" ); - return 0; - } - Wlc_NtkPrintInvStats( pNtk, Wlc_AbcGetInv(pAbc), fVerbose ); - return 0; - usage: - Abc_Print( -2, "usage: %%psinv [-vh]\n" ); - Abc_Print( -2, "\t prints statistics for inductive invariant\n" ); - Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\n" ); - Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); - Abc_Print( -2, "\t-h : print the command usage\n"); - return 1; -} - -/**Function******************************************************************** - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -******************************************************************************/ -int Abc_CommandGetInv( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - extern Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop, int fVerbose ); - Abc_Ntk_t * pMainNtk; - Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); - int c, fVerbose = 0; - Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) - { - switch ( c ) - { - case 'v': - fVerbose ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - if ( pNtk == NULL ) - { - Abc_Print( 1, "Abc_CommandGetInv(): There is no current design.\n" ); - return 0; - } - if ( Wlc_AbcGetNtk(pAbc) == NULL ) - { - Abc_Print( 1, "Abc_CommandGetInv(): There is no saved invariant.\n" ); - return 0; - } - if ( Wlc_AbcGetInv(pAbc) == NULL ) - { - Abc_Print( 1, "Abc_CommandGetInv(): Invariant is not available.\n" ); - return 0; - } - // derive the network - pMainNtk = Wlc_NtkGetInv( pNtk, Wlc_AbcGetInv(pAbc), Wlc_AbcGetStr(pAbc), fVerbose ); - // replace the current network - Abc_FrameReplaceCurrentNetwork( pAbc, pMainNtk ); - return 0; - usage: - Abc_Print( -2, "usage: %%getinv [-vh]\n" ); - Abc_Print( -2, "\t places invariant found by PDR as the current network in the main-space\n" ); - Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\n" ); - Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); - Abc_Print( -2, "\t-h : print the command usage\n"); - return 1; -} - /**Function******************************************************************** Synopsis [] @@ -641,6 +533,326 @@ usage: return 1; } +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandInvPs( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Vec_Int_t * Pdr_InvCounts( Vec_Int_t * vInv ); + extern void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ); + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + Vec_Int_t * vCounts; + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandInvPs(): There is no current design.\n" ); + return 0; + } + if ( Wlc_AbcGetInv(pAbc) == NULL ) + { + Abc_Print( 1, "Abc_CommandInvPs(): Invariant is not available.\n" ); + return 0; + } + vCounts = Pdr_InvCounts( Wlc_AbcGetInv(pAbc) ); + Wlc_NtkPrintInvStats( pNtk, vCounts, fVerbose ); + Vec_IntFree( vCounts ); + return 0; +usage: + Abc_Print( -2, "usage: inv_ps [-vh]\n" ); + Abc_Print( -2, "\t prints statistics for inductive invariant\n" ); + Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandInvPrint( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Pdr_InvPrint( Vec_Int_t * vInv ); + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( Wlc_AbcGetInv(pAbc) == NULL ) + { + Abc_Print( 1, "Abc_CommandInvPs(): Invariant is not available.\n" ); + return 0; + } + Pdr_InvPrint( Wlc_AbcGetInv(pAbc) ); + return 0; +usage: + Abc_Print( -2, "usage: inv_print [-vh]\n" ); + Abc_Print( -2, "\t prints the current inductive invariant\n" ); + Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Vec_Int_t * Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ); + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( 1, "Abc_CommandInvMin(): There is no current design.\n" ); + return 0; + } + if ( Wlc_AbcGetInv(pAbc) == NULL ) + { + Abc_Print( 1, "Abc_CommandInvMin(): There is no saved invariant.\n" ); + return 0; + } + if ( Gia_ManRegNum(pAbc->pGia) != Vec_IntEntryLast(Wlc_AbcGetInv(pAbc)) ) + { + Abc_Print( 1, "Abc_CommandInvMin(): The number of flops in the invariant and in GIA should be the same.\n" ); + return 0; + } + Pdr_InvCheck( pAbc->pGia, Wlc_AbcGetInv(pAbc) ); + return 0; +usage: + Abc_Print( -2, "usage: inv_check [-vh]\n" ); + Abc_Print( -2, "\t checks that the invariant is indeed an inductive invariant\n" ); + Abc_Print( -2, "\t (AIG representing the design should be in the &-space)\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandInvGet( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv ); + Abc_Ntk_t * pMainNtk; + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( Wlc_AbcGetInv(pAbc) == NULL ) + { + Abc_Print( 1, "Abc_CommandInvGet(): Invariant is not available.\n" ); + return 0; + } + // derive the network + pMainNtk = Wlc_NtkGetInv( pNtk, Wlc_AbcGetInv(pAbc) ); + // replace the current network + if ( pMainNtk ) + Abc_FrameReplaceCurrentNetwork( pAbc, pMainNtk ); + return 0; +usage: + Abc_Print( -2, "usage: inv_get [-vh]\n" ); + Abc_Print( -2, "\t places invariant found by PDR as the current network in the main-space\n" ); + Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandInvPut( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, int nRegs ); + Vec_Int_t * vInv = NULL; + Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandInvPut(): There is no current design.\n" ); + return 0; + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( 1, "Abc_CommandInvPut(): There is no current AIG.\n" ); + return 0; + } + // derive the network + vInv = Wlc_NtkGetPut( pNtk, Gia_ManRegNum(pAbc->pGia) ); + if ( vInv ) + Abc_FrameSetInv( vInv ); + return 0; +usage: + Abc_Print( -2, "usage: inv_put [-vh]\n" ); + Abc_Print( -2, "\t inputs the current network in the main-space as an invariant\n" ); + Abc_Print( -2, "\t (AIG representing the design should be in the &-space)\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandInvMin( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ); + Vec_Int_t * vInv, * vInv2; + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( 1, "Abc_CommandInvMin(): There is no current design.\n" ); + return 0; + } + if ( Wlc_AbcGetInv(pAbc) == NULL ) + { + Abc_Print( 1, "Abc_CommandInvMin(): Invariant is not available.\n" ); + return 0; + } + vInv = Wlc_AbcGetInv(pAbc); + if ( Gia_ManRegNum(pAbc->pGia) != Vec_IntEntryLast(vInv) ) + { + Abc_Print( 1, "Abc_CommandInvMin(): The number of flops in the invariant and in GIA should be the same.\n" ); + return 0; + } + vInv2 = Pdr_InvMinimize( pAbc->pGia, vInv ); + if ( vInv2 ) + Abc_FrameSetInv( vInv2 ); + return 0; +usage: + Abc_Print( -2, "usage: inv_min [-vh]\n" ); + Abc_Print( -2, "\t minimizes the number of clauses in the current invariant\n" ); + Abc_Print( -2, "\t (AIG representing the design should be in the &-space)\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index 66cae36e8..c625e366d 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -923,9 +923,7 @@ int Pdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) if ( p->pPars->fDumpInv ) { char * pFileName = Extra_FileNameGenericAppend(p->pAig->pName, "_inv.pla"); - Abc_FrameSetCnf( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); - Abc_FrameSetStr( Pdr_ManDumpString(p) ); - Abc_FrameSetInv( Pdr_ManCountFlopsInv(p) ); + Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); Pdr_ManDumpClauses( p, pFileName, RetValue==1 ); } p->tTotal += Abc_Clock() - clk; diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index 02b90a360..f29b792cf 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -605,9 +605,237 @@ Vec_Int_t * Pdr_ManDeriveInfinityClauses( Pdr_Man_t * p, int fReduce ) //Vec_PtrFree( vCubes ); Vec_PtrFreeP( &p->vInfCubes ); p->vInfCubes = vCubes; + Vec_IntPush( vResult, Aig_ManRegNum(p->pAig) ); return vResult; } + + +/**Function************************************************************* + + Synopsis [Remove clauses while maintaining the invariant.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +#define Pdr_ForEachCube( pList, pCut, i ) for ( i = 0, pCut = pList + 1; i < pList[0]; i++, pCut += pCut[0] + 1 ) + +extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); + +Vec_Int_t * Pdr_InvMap( Vec_Int_t * vCounts ) +{ + int i, k = 0, Count; + Vec_Int_t * vMap = Vec_IntStart( Vec_IntSize(vCounts) ); + Vec_IntForEachEntry( vCounts, Count, i ) + if ( Count ) + Vec_IntWriteEntry( vMap, i, k++ ); + return vMap; +} +Vec_Int_t * Pdr_InvCounts( Vec_Int_t * vInv ) +{ + int i, k, * pCube, * pList = Vec_IntArray(vInv); + Vec_Int_t * vCounts = Vec_IntStart( Vec_IntEntryLast(vInv) ); + Pdr_ForEachCube( pList, pCube, i ) + for ( k = 0; k < pCube[0]; k++ ) + Vec_IntAddToEntry( vCounts, Abc_Lit2Var(pCube[k+1]), 1 ); + return vCounts; +} +int Pdr_InvUsedFlopNum( Vec_Int_t * vInv ) +{ + Vec_Int_t * vCounts = Pdr_InvCounts( vInv ); + int nZeros = Vec_IntCountZero( vCounts ); + Vec_IntFree( vCounts ); + return Vec_IntEntryLast(vInv) - nZeros; +} + +Vec_Str_t * Pdr_InvPrintStr( Vec_Int_t * vInv, Vec_Int_t * vCounts ) +{ + Vec_Str_t * vStr = Vec_StrAlloc( 1000 ); + Vec_Int_t * vMap = Pdr_InvMap( vCounts ); + int nVars = Vec_IntSize(vCounts) - Vec_IntCountZero(vCounts); + int i, k, * pCube, * pList = Vec_IntArray(vInv); + char * pBuffer = ABC_ALLOC( char, nVars ); + for ( i = 0; i < nVars; i++ ) + pBuffer[i] = '-'; + Pdr_ForEachCube( pList, pCube, i ) + { + for ( k = 0; k < pCube[0]; k++ ) + pBuffer[Vec_IntEntry(vMap, Abc_Lit2Var(pCube[k+1]))] = '0' + !Abc_LitIsCompl(pCube[k+1]); + for ( k = 0; k < nVars; k++ ) + Vec_StrPush( vStr, pBuffer[k] ); + Vec_StrPush( vStr, ' ' ); + Vec_StrPush( vStr, '1' ); + Vec_StrPush( vStr, '\n' ); + for ( k = 0; k < pCube[0]; k++ ) + pBuffer[Vec_IntEntry(vMap, Abc_Lit2Var(pCube[k+1]))] = '-'; + } + Vec_StrPush( vStr, '\0' ); + ABC_FREE( pBuffer ); + Vec_IntFree( vMap ); + return vStr; +} +void Pdr_InvPrint( Vec_Int_t * vInv ) +{ + Vec_Int_t * vCounts = Pdr_InvCounts( vInv ); + Vec_Str_t * vStr = Pdr_InvPrintStr( vInv, vCounts ); + printf( "Invariant contains %d clauses with %d literals and %d flops (out of %d).\n", Vec_IntEntry(vInv, 0), Vec_IntSize(vInv)-Vec_IntEntry(vInv, 0)-2, Pdr_InvUsedFlopNum(vInv), Vec_IntEntryLast(vInv) ); + printf( "%s", Vec_StrArray( vStr ) ); + Vec_IntFree( vCounts ); + Vec_StrFree( vStr ); +} + +void Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ) +{ + int nBTLimit = 0; + int i, k, status, nFailed = 0; + // create SAT solver + Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + // collect cubes + int * pCube, * pList = Vec_IntArray(vInv), nCubes = pList[0]; + // create variables + Vec_Int_t * vLits = Vec_IntAlloc(100); + int nVars = Gia_ManRegNum(p); + int iFoVarBeg = pCnf->nVars - Gia_ManRegNum(p); + int iFiVarBeg = 1 + Gia_ManPoNum(p); + assert( Gia_ManPoNum(p) == 1 ); + // add cubes + Pdr_ForEachCube( pList, pCube, i ) + { + // collect literals + Vec_IntClear( vLits ); + for ( k = 0; k < pCube[0]; k++ ) + Vec_IntPush( vLits, Abc_Var2Lit(iFoVarBeg + Abc_Lit2Var(pCube[k+1]), !Abc_LitIsCompl(pCube[k+1])) ); + // add it to the solver + status = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits) ); + assert( status == 1 ); + } + // iterate through cubes in the direct order + Pdr_ForEachCube( pList, pCube, i ) + { + // collect cube + Vec_IntClear( vLits ); + for ( k = 0; k < pCube[0]; k++ ) + Vec_IntPush( vLits, Abc_Var2Lit(iFiVarBeg + Abc_Lit2Var(pCube[k+1]), Abc_LitIsCompl(pCube[k+1])) ); + // check if this cube intersects with the complement of other cubes in the solver + // if it does not intersect, then it is redundant and can be skipped + status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 ); + if ( status == l_Undef ) // timeout + break; + if ( status == l_False ) // unsat -- correct + continue; + assert( status == l_True ); + nFailed++; + } + if ( nFailed ) + printf( "Invariant verification failed for %d clauses (out of %d).\n", nFailed, nCubes ); + else + printf( "Invariant verification passes.\n" ); + Cnf_DataFree( pCnf ); + sat_solver_delete( pSat ); + Vec_IntFree( vLits ); +} + +Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ) +{ + int nBTLimit = 0; + int n, i, k, status, nLits, fFailed = 0, fCannot = 0, nRemoved = 0; + Vec_Int_t * vRes = NULL; + // create SAT solver + Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + int * pCube, * pList = Vec_IntArray(vInv), nCubes = pList[0]; + // create variables + Vec_Int_t * vLits = Vec_IntAlloc(100); + Vec_Bit_t * vRemoved = Vec_BitStart( nCubes ); + int nVars = Gia_ManRegNum(p); + int iFoVarBeg = pCnf->nVars - Gia_ManRegNum(p); + int iFiVarBeg = 1 + Gia_ManPoNum(p); + int iAuxVarBeg = sat_solver_nvars(pSat); + assert( Gia_ManPoNum(p) == 1 ); + // allocate auxiliary variables + sat_solver_setnvars( pSat, sat_solver_nvars(pSat) + nCubes ); + // add clauses + Pdr_ForEachCube( pList, pCube, i ) + { + // collect literals + Vec_IntFill( vLits, 1, Abc_Var2Lit(iAuxVarBeg + i, 1) ); // neg aux literal + for ( k = 0; k < pCube[0]; k++ ) + Vec_IntPush( vLits, Abc_Var2Lit(iFoVarBeg + Abc_Lit2Var(pCube[k+1]), !Abc_LitIsCompl(pCube[k+1])) ); + // add it to the solver + status = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits) ); + assert( status == 1 ); + } + // iterate through clauses + Pdr_ForEachCube( pList, pCube, i ) + { + if ( Vec_BitEntry(vRemoved, i) ) + continue; + // collect aux literals for remaining clauses + Vec_IntClear( vLits ); + for ( k = 0; k < nCubes; k++ ) + if ( k != i && !Vec_BitEntry(vRemoved, k) ) // skip this cube and already removed cubes + Vec_IntPush( vLits, Abc_Var2Lit(iAuxVarBeg + k, 0) ); // pos aux literal + nLits = Vec_IntSize( vLits ); + // try removing other clauses + fCannot = 0; + Pdr_ForEachCube( pList, pCube, n ) + { + if ( Vec_BitEntry(vRemoved, n) || n == i ) + continue; + // collect cube + Vec_IntShrink( vLits, nLits ); + for ( k = 0; k < pCube[0]; k++ ) + Vec_IntPush( vLits, Abc_Var2Lit(iFiVarBeg + Abc_Lit2Var(pCube[k+1]), Abc_LitIsCompl(pCube[k+1])) ); + // check if this cube intersects with the complement of other cubes in the solver + // if it does not intersect, then it is redundant and can be skipped + status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 ); + if ( status == l_Undef ) // timeout + { + fFailed = 1; + break; + } + if ( status == l_False ) // unsat -- correct + continue; + assert( status == l_True ); + // cannot remove + fCannot = 1; + break; + } + if ( fFailed ) + break; + if ( fCannot ) + continue; + printf( "Removing clause %d.\n", i ); + Vec_BitWriteEntry( vRemoved, i, 1 ); + nRemoved++; + } + if ( nRemoved ) + printf( "Invariant minimization reduced %d clauses (out of %d).\n", nRemoved, nCubes ); + else + printf( "Invariant minimization did not change the invariant.\n" ); + // cleanup cover + if ( !fFailed && nRemoved > 0 ) // finished without timeout and removed some cubes + { + vRes = Vec_IntAlloc( 1000 ); + Vec_IntPush( vRes, nCubes-nRemoved ); + Pdr_ForEachCube( pList, pCube, i ) + if ( !Vec_BitEntry(vRemoved, i) ) + for ( k = 0; k <= pCube[0]; k++ ) + Vec_IntPush( vRes, pCube[k] ); + Vec_IntPush( vRes, Vec_IntEntryLast(vInv) ); + } + Cnf_DataFree( pCnf ); + sat_solver_delete( pSat ); + Vec_BitFree( vRemoved ); + Vec_IntFree( vLits ); + return vRes; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/pdr/pdrUtil.c b/src/proof/pdr/pdrUtil.c index 53a8a54ae..32e977727 100644 --- a/src/proof/pdr/pdrUtil.c +++ b/src/proof/pdr/pdrUtil.c @@ -284,7 +284,7 @@ void Pdr_SetPrintStr( Vec_Str_t * vStr, Pdr_Set_t * p, int nRegs, Vec_Int_t * vF } Vec_StrPushBuffer( vStr, pBuff, k ); Vec_StrPush( vStr, ' ' ); - Vec_StrPush( vStr, '0' ); + Vec_StrPush( vStr, '1' ); Vec_StrPush( vStr, '\n' ); ABC_FREE( pBuff ); } From 849f18076411a54c21e593e3bd9e72bf6d56883e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 24 Jan 2017 20:44:25 -0800 Subject: [PATCH 068/185] Adding features for invariant minimization. --- src/base/wlc/wlcAbc.c | 2 +- src/base/wlc/wlcCom.c | 28 ++++++++++----- src/proof/pdr/pdrInv.c | 81 ++++++++++++++++++++++++++++++++++++------ 3 files changed, 92 insertions(+), 19 deletions(-) diff --git a/src/base/wlc/wlcAbc.c b/src/base/wlc/wlcAbc.c index 1a98fb71c..1f10d7b05 100644 --- a/src/base/wlc/wlcAbc.c +++ b/src/base/wlc/wlcAbc.c @@ -176,7 +176,7 @@ Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv ) /**Function************************************************************* - Synopsis [Translate current network into an interpolant.] + Synopsis [Translate current network into an invariant.] Description [] diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 93614938a..85b3b35d1 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -646,8 +646,8 @@ usage: ******************************************************************************/ int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern Vec_Int_t * Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ); - int c, fVerbose = 0; + extern int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ); + int c, nFailed, fVerbose = 0; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) { @@ -677,7 +677,11 @@ int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandInvMin(): The number of flops in the invariant and in GIA should be the same.\n" ); return 0; } - Pdr_InvCheck( pAbc->pGia, Wlc_AbcGetInv(pAbc) ); + nFailed = Pdr_InvCheck( pAbc->pGia, Wlc_AbcGetInv(pAbc) ); + if ( nFailed ) + printf( "Invariant verification failed for %d clauses (out of %d).\n", nFailed, Vec_IntEntry(Wlc_AbcGetInv(pAbc),0) ); + else + printf( "Invariant verification passes.\n" ); return 0; usage: Abc_Print( -2, "usage: inv_check [-vh]\n" ); @@ -808,13 +812,17 @@ usage: int Abc_CommandInvMin( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ); + extern Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv ); Vec_Int_t * vInv, * vInv2; - int c, fVerbose = 0; + int c, fLits = 0, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "lvh" ) ) != EOF ) { switch ( c ) { + case 'l': + fLits ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -840,14 +848,18 @@ int Abc_CommandInvMin( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandInvMin(): The number of flops in the invariant and in GIA should be the same.\n" ); return 0; } - vInv2 = Pdr_InvMinimize( pAbc->pGia, vInv ); + if ( fLits ) + vInv2 = Pdr_InvMinimizeLits( pAbc->pGia, vInv ); + else + vInv2 = Pdr_InvMinimize( pAbc->pGia, vInv ); if ( vInv2 ) Abc_FrameSetInv( vInv2 ); return 0; usage: - Abc_Print( -2, "usage: inv_min [-vh]\n" ); - Abc_Print( -2, "\t minimizes the number of clauses in the current invariant\n" ); + Abc_Print( -2, "usage: inv_min [-lvh]\n" ); + Abc_Print( -2, "\t performs minimization of the current invariant\n" ); Abc_Print( -2, "\t (AIG representing the design should be in the &-space)\n" ); + Abc_Print( -2, "\t-l : toggle minimizing literals rather than clauses [default = %s]\n", fLits? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index f29b792cf..8cfc74503 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -688,7 +688,7 @@ void Pdr_InvPrint( Vec_Int_t * vInv ) Vec_StrFree( vStr ); } -void Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ) +int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ) { int nBTLimit = 0; int i, k, status, nFailed = 0; @@ -699,7 +699,6 @@ void Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ) int * pCube, * pList = Vec_IntArray(vInv), nCubes = pList[0]; // create variables Vec_Int_t * vLits = Vec_IntAlloc(100); - int nVars = Gia_ManRegNum(p); int iFoVarBeg = pCnf->nVars - Gia_ManRegNum(p); int iFiVarBeg = 1 + Gia_ManPoNum(p); assert( Gia_ManPoNum(p) == 1 ); @@ -709,7 +708,8 @@ void Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ) // collect literals Vec_IntClear( vLits ); for ( k = 0; k < pCube[0]; k++ ) - Vec_IntPush( vLits, Abc_Var2Lit(iFoVarBeg + Abc_Lit2Var(pCube[k+1]), !Abc_LitIsCompl(pCube[k+1])) ); + if ( pCube[k+1] != -1 ) + Vec_IntPush( vLits, Abc_Var2Lit(iFoVarBeg + Abc_Lit2Var(pCube[k+1]), !Abc_LitIsCompl(pCube[k+1])) ); // add it to the solver status = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits) ); assert( status == 1 ); @@ -720,7 +720,8 @@ void Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ) // collect cube Vec_IntClear( vLits ); for ( k = 0; k < pCube[0]; k++ ) - Vec_IntPush( vLits, Abc_Var2Lit(iFiVarBeg + Abc_Lit2Var(pCube[k+1]), Abc_LitIsCompl(pCube[k+1])) ); + if ( pCube[k+1] != -1 ) + Vec_IntPush( vLits, Abc_Var2Lit(iFiVarBeg + Abc_Lit2Var(pCube[k+1]), Abc_LitIsCompl(pCube[k+1])) ); // check if this cube intersects with the complement of other cubes in the solver // if it does not intersect, then it is redundant and can be skipped status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 ); @@ -731,18 +732,16 @@ void Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ) assert( status == l_True ); nFailed++; } - if ( nFailed ) - printf( "Invariant verification failed for %d clauses (out of %d).\n", nFailed, nCubes ); - else - printf( "Invariant verification passes.\n" ); Cnf_DataFree( pCnf ); sat_solver_delete( pSat ); Vec_IntFree( vLits ); + return nFailed; } Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ) { int nBTLimit = 0; + int fCheckProperty = 0; int n, i, k, status, nLits, fFailed = 0, fCannot = 0, nRemoved = 0; Vec_Int_t * vRes = NULL; // create SAT solver @@ -752,7 +751,6 @@ Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ) // create variables Vec_Int_t * vLits = Vec_IntAlloc(100); Vec_Bit_t * vRemoved = Vec_BitStart( nCubes ); - int nVars = Gia_ManRegNum(p); int iFoVarBeg = pCnf->nVars - Gia_ManRegNum(p); int iFiVarBeg = 1 + Gia_ManPoNum(p); int iAuxVarBeg = sat_solver_nvars(pSat); @@ -781,7 +779,26 @@ Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ) if ( k != i && !Vec_BitEntry(vRemoved, k) ) // skip this cube and already removed cubes Vec_IntPush( vLits, Abc_Var2Lit(iAuxVarBeg + k, 0) ); // pos aux literal nLits = Vec_IntSize( vLits ); - // try removing other clauses + + // check if the property still holds + if ( fCheckProperty ) + { + Vec_IntPush( vLits, Abc_Var2Lit(1, 0) ); + status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 ); + if ( status == l_Undef ) // timeout + { + fFailed = 1; + break; + } + if ( status == l_True ) // sat - property fails + { + //printf( "property fails if clause %d is removed\n", i ); + continue; + } + assert( status == l_False ); // unsat - property holds + } + + // check other clauses fCannot = 0; Pdr_ForEachCube( pList, pCube, n ) { @@ -836,6 +853,50 @@ Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ) return vRes; } +Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv ) +{ + Vec_Int_t * vRes = NULL; + int i, k, nLits = 0, * pCube, * pList = Vec_IntArray(vInv), nRemoved = 0; + Pdr_ForEachCube( pList, pCube, i ) + { + nLits += pCube[0]; + for ( k = 0; k < pCube[0]; k++ ) + { + int Save = pCube[k+1]; + pCube[k+1] = -1; + if ( Pdr_InvCheck(p, vInv) ) + { + pCube[k+1] = Save; + continue; + } + printf( "Removing lit %d from clause %d.\n", k, i ); + nRemoved++; + } + } + if ( nRemoved ) + printf( "Invariant minimization reduced %d literals (out of %d).\n", nRemoved, nLits ); + else + printf( "Invariant minimization did not change the invariant.\n" ); + if ( nRemoved > 0 ) // finished without timeout and removed some lits + { + vRes = Vec_IntAlloc( 1000 ); + Vec_IntPush( vRes, pList[0] ); + Pdr_ForEachCube( pList, pCube, i ) + { + int nLits = 0; + for ( k = 0; k < pCube[0]; k++ ) + if ( pCube[k+1] != -1 ) + nLits++; + Vec_IntPush( vRes, nLits ); + for ( k = 0; k < pCube[0]; k++ ) + if ( pCube[k+1] != -1 ) + Vec_IntPush( vRes, pCube[k+1] ); + } + Vec_IntPush( vRes, Vec_IntEntryLast(vInv) ); + } + return vRes; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// From 88e887d1a08649cec01d508c4c24c08911a29eea Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 24 Jan 2017 20:46:03 -0800 Subject: [PATCH 069/185] Fixing gcc compilation problem. --- src/sat/xsat/xsatHeap.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sat/xsat/xsatHeap.h b/src/sat/xsat/xsatHeap.h index 2e873e590..409ce4604 100644 --- a/src/sat/xsat/xsatHeap.h +++ b/src/sat/xsat/xsatHeap.h @@ -48,7 +48,7 @@ struct xSAT_Heap_t_ SeeAlso [] ***********************************************************************/ -inline int xSAT_HeapSize( xSAT_Heap_t * h ) +static inline int xSAT_HeapSize( xSAT_Heap_t * h ) { return Vec_IntSize( h->vHeap ); } @@ -64,7 +64,7 @@ inline int xSAT_HeapSize( xSAT_Heap_t * h ) SeeAlso [] ***********************************************************************/ -inline int xSAT_HeapInHeap( xSAT_Heap_t * h, int Var ) +static inline int xSAT_HeapInHeap( xSAT_Heap_t * h, int Var ) { return ( Var < Vec_IntSize( h->vIndices ) ) && ( Vec_IntEntry( h->vIndices, Var ) >= 0 ); } From c3dfec7467ee4d0dab6e031a92e046729f2cff00 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 24 Jan 2017 20:49:47 -0800 Subject: [PATCH 070/185] Fixing windows compilation problem. --- src/sat/xsat/xsatBQueue.h | 3 ++- src/sat/xsat/xsatSolver.c | 2 +- src/sat/xsat/xsatSolver.h | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sat/xsat/xsatBQueue.h b/src/sat/xsat/xsatBQueue.h index 560f75c0e..f75f36505 100644 --- a/src/sat/xsat/xsatBQueue.h +++ b/src/sat/xsat/xsatBQueue.h @@ -125,8 +125,9 @@ static inline void xSAT_BQueuePush( xSAT_BQueue_t * p, unsigned Value ) ***********************************************************************/ static inline int xSAT_BQueuePop( xSAT_BQueue_t * p ) { + int RetValue; assert( p->nSize >= 1 ); - int RetValue = p->pData[p->iFirst]; + RetValue = p->pData[p->iFirst]; p->nSum -= RetValue; p->iFirst = ( p->iFirst + 1 ) % p->nCap; p->nSize--; diff --git a/src/sat/xsat/xsatSolver.c b/src/sat/xsat/xsatSolver.c index 467f5f8d3..9a98eec00 100644 --- a/src/sat/xsat/xsatSolver.c +++ b/src/sat/xsat/xsatSolver.c @@ -334,7 +334,7 @@ int xSAT_SolverEnqueue( xSAT_Solver_t * s, int Lit, unsigned Reason ) { int Var = xSAT_Lit2Var( Lit ); - Vec_StrWriteEntry( s->vAssigns, Var, xSAT_LitSign( Lit ) ); + Vec_StrWriteEntry( s->vAssigns, Var, (char)xSAT_LitSign( Lit ) ); Vec_IntWriteEntry( s->vLevels, Var, xSAT_SolverDecisionLevel( s ) ); Vec_IntWriteEntry( s->vReasons, Var, ( int ) Reason ); Vec_IntPush( s->vTrail, Lit ); diff --git a/src/sat/xsat/xsatSolver.h b/src/sat/xsat/xsatSolver.h index bf8bf4197..36432e03d 100644 --- a/src/sat/xsat/xsatSolver.h +++ b/src/sat/xsat/xsatSolver.h @@ -143,7 +143,7 @@ struct xSAT_Solver_t_ int nAssignSimplify; /* Number of top-level assignments since last * execution of 'simplify()'. */ - int64_t nPropSimplify; /* Remaining number of propagations that must be + iword nPropSimplify; /* Remaining number of propagations that must be * made before next execution of 'simplify()'. */ /* Temporary data used by Search method */ From cf1106aba8d940a6d9d5f410b6773c24bdf0d393 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 24 Jan 2017 22:28:28 -0800 Subject: [PATCH 071/185] Adding features for invariant minimization. --- src/base/wlc/wlcCom.c | 16 ++++++++-------- src/proof/pdr/pdrInv.c | 43 ++++++++++++++++++++++++++---------------- 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 85b3b35d1..be9ba7f62 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -601,7 +601,7 @@ usage: ******************************************************************************/ int Abc_CommandInvPrint( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern void Pdr_InvPrint( Vec_Int_t * vInv ); + extern void Pdr_InvPrint( Vec_Int_t * vInv, int fVerbose ); int c, fVerbose = 0; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) @@ -622,7 +622,7 @@ int Abc_CommandInvPrint( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandInvPs(): Invariant is not available.\n" ); return 0; } - Pdr_InvPrint( Wlc_AbcGetInv(pAbc) ); + Pdr_InvPrint( Wlc_AbcGetInv(pAbc), fVerbose ); return 0; usage: Abc_Print( -2, "usage: inv_print [-vh]\n" ); @@ -646,7 +646,7 @@ usage: ******************************************************************************/ int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ); + extern int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ); int c, nFailed, fVerbose = 0; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) @@ -677,7 +677,7 @@ int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandInvMin(): The number of flops in the invariant and in GIA should be the same.\n" ); return 0; } - nFailed = Pdr_InvCheck( pAbc->pGia, Wlc_AbcGetInv(pAbc) ); + nFailed = Pdr_InvCheck( pAbc->pGia, Wlc_AbcGetInv(pAbc), fVerbose ); if ( nFailed ) printf( "Invariant verification failed for %d clauses (out of %d).\n", nFailed, Vec_IntEntry(Wlc_AbcGetInv(pAbc),0) ); else @@ -811,8 +811,8 @@ usage: ******************************************************************************/ int Abc_CommandInvMin( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ); - extern Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv ); + extern Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ); + extern Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ); Vec_Int_t * vInv, * vInv2; int c, fLits = 0, fVerbose = 0; Extra_UtilGetoptReset(); @@ -849,9 +849,9 @@ int Abc_CommandInvMin( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; } if ( fLits ) - vInv2 = Pdr_InvMinimizeLits( pAbc->pGia, vInv ); + vInv2 = Pdr_InvMinimizeLits( pAbc->pGia, vInv, fVerbose ); else - vInv2 = Pdr_InvMinimize( pAbc->pGia, vInv ); + vInv2 = Pdr_InvMinimize( pAbc->pGia, vInv, fVerbose ); if ( vInv2 ) Abc_FrameSetInv( vInv2 ); return 0; diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index 8cfc74503..19e6c90e8 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -678,17 +678,20 @@ Vec_Str_t * Pdr_InvPrintStr( Vec_Int_t * vInv, Vec_Int_t * vCounts ) Vec_IntFree( vMap ); return vStr; } -void Pdr_InvPrint( Vec_Int_t * vInv ) +void Pdr_InvPrint( Vec_Int_t * vInv, int fVerbose ) { - Vec_Int_t * vCounts = Pdr_InvCounts( vInv ); - Vec_Str_t * vStr = Pdr_InvPrintStr( vInv, vCounts ); printf( "Invariant contains %d clauses with %d literals and %d flops (out of %d).\n", Vec_IntEntry(vInv, 0), Vec_IntSize(vInv)-Vec_IntEntry(vInv, 0)-2, Pdr_InvUsedFlopNum(vInv), Vec_IntEntryLast(vInv) ); - printf( "%s", Vec_StrArray( vStr ) ); - Vec_IntFree( vCounts ); - Vec_StrFree( vStr ); + if ( fVerbose ) + { + Vec_Int_t * vCounts = Pdr_InvCounts( vInv ); + Vec_Str_t * vStr = Pdr_InvPrintStr( vInv, vCounts ); + printf( "%s", Vec_StrArray( vStr ) ); + Vec_IntFree( vCounts ); + Vec_StrFree( vStr ); + } } -int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ) +int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) { int nBTLimit = 0; int i, k, status, nFailed = 0; @@ -696,7 +699,7 @@ int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ) Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); // collect cubes - int * pCube, * pList = Vec_IntArray(vInv), nCubes = pList[0]; + int * pCube, * pList = Vec_IntArray(vInv); // create variables Vec_Int_t * vLits = Vec_IntAlloc(100); int iFoVarBeg = pCnf->nVars - Gia_ManRegNum(p); @@ -731,6 +734,8 @@ int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ) continue; assert( status == l_True ); nFailed++; + if ( fVerbose ) + printf( "Verification failed for clause %d.\n", i ); } Cnf_DataFree( pCnf ); sat_solver_delete( pSat ); @@ -738,10 +743,11 @@ int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ) return nFailed; } -Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ) +Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) { int nBTLimit = 0; - int fCheckProperty = 0; + int fCheckProperty = 1; + abctime clk = Abc_Clock(); int n, i, k, status, nLits, fFailed = 0, fCannot = 0, nRemoved = 0; Vec_Int_t * vRes = NULL; // create SAT solver @@ -827,14 +833,16 @@ Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ) break; if ( fCannot ) continue; + if ( fVerbose ) printf( "Removing clause %d.\n", i ); Vec_BitWriteEntry( vRemoved, i, 1 ); nRemoved++; } if ( nRemoved ) - printf( "Invariant minimization reduced %d clauses (out of %d).\n", nRemoved, nCubes ); + printf( "Invariant minimization reduced %d clauses (out of %d). ", nRemoved, nCubes ); else - printf( "Invariant minimization did not change the invariant.\n" ); + printf( "Invariant minimization did not change the invariant. " ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); // cleanup cover if ( !fFailed && nRemoved > 0 ) // finished without timeout and removed some cubes { @@ -853,9 +861,10 @@ Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ) return vRes; } -Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv ) +Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) { Vec_Int_t * vRes = NULL; + abctime clk = Abc_Clock(); int i, k, nLits = 0, * pCube, * pList = Vec_IntArray(vInv), nRemoved = 0; Pdr_ForEachCube( pList, pCube, i ) { @@ -864,19 +873,21 @@ Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv ) { int Save = pCube[k+1]; pCube[k+1] = -1; - if ( Pdr_InvCheck(p, vInv) ) + if ( Pdr_InvCheck(p, vInv, 0) ) { pCube[k+1] = Save; continue; } + if ( fVerbose ) printf( "Removing lit %d from clause %d.\n", k, i ); nRemoved++; } } if ( nRemoved ) - printf( "Invariant minimization reduced %d literals (out of %d).\n", nRemoved, nLits ); + printf( "Invariant minimization reduced %d literals (out of %d). ", nRemoved, nLits ); else - printf( "Invariant minimization did not change the invariant.\n" ); + printf( "Invariant minimization did not change the invariant. " ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); if ( nRemoved > 0 ) // finished without timeout and removed some lits { vRes = Vec_IntAlloc( 1000 ); From 3119e1e30f8a44eb6236792c69f8cca64c99f7a8 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 25 Jan 2017 13:56:16 -0800 Subject: [PATCH 072/185] Adding features for invariant minimization. --- src/base/wlc/wlcCom.c | 2 +- src/proof/pdr/pdrInv.c | 104 +++++++++++++++++++++++++++++------------ 2 files changed, 75 insertions(+), 31 deletions(-) diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index be9ba7f62..2828fea33 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -681,7 +681,7 @@ int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( nFailed ) printf( "Invariant verification failed for %d clauses (out of %d).\n", nFailed, Vec_IntEntry(Wlc_AbcGetInv(pAbc),0) ); else - printf( "Invariant verification passes.\n" ); + printf( "Invariant verification succeeded.\n" ); return 0; usage: Abc_Print( -2, "usage: inv_check [-vh]\n" ); diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index 19e6c90e8..bd32953a6 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -691,20 +691,17 @@ void Pdr_InvPrint( Vec_Int_t * vInv, int fVerbose ) } } -int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) +int Pdr_InvCheck_int( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose, sat_solver * pSat ) { int nBTLimit = 0; - int i, k, status, nFailed = 0; - // create SAT solver - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); - sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + int fCheckProperty = 1; + int i, k, status, nFailed = 0, nFailedOuts = 0; // collect cubes int * pCube, * pList = Vec_IntArray(vInv); // create variables Vec_Int_t * vLits = Vec_IntAlloc(100); - int iFoVarBeg = pCnf->nVars - Gia_ManRegNum(p); + int iFoVarBeg = sat_solver_nvars(pSat) - Gia_ManRegNum(p); int iFiVarBeg = 1 + Gia_ManPoNum(p); - assert( Gia_ManPoNum(p) == 1 ); // add cubes Pdr_ForEachCube( pList, pCube, i ) { @@ -713,10 +710,34 @@ int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) for ( k = 0; k < pCube[0]; k++ ) if ( pCube[k+1] != -1 ) Vec_IntPush( vLits, Abc_Var2Lit(iFoVarBeg + Abc_Lit2Var(pCube[k+1]), !Abc_LitIsCompl(pCube[k+1])) ); + if ( Vec_IntSize(vLits) == 0 ) + { + Vec_IntFree( vLits ); + return 1; + } // add it to the solver status = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits) ); assert( status == 1 ); } + // verify property output + if ( fCheckProperty ) + { + for ( i = 0; i < Gia_ManPoNum(p); i++ ) + { + Vec_IntFill( vLits, 1, Abc_Var2Lit(1+i, 0) ); + status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 ); + if ( status == l_Undef ) // timeout + break; + if ( status == l_True ) // sat - property fails + { + if ( fVerbose ) + printf( "Coverage check failed for output %d.\n", i ); + nFailedOuts++; + continue; + } + assert( status == l_False ); // unsat - property holds + } + } // iterate through cubes in the direct order Pdr_ForEachCube( pList, pCube, i ) { @@ -735,12 +756,22 @@ int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) assert( status == l_True ); nFailed++; if ( fVerbose ) - printf( "Verification failed for clause %d.\n", i ); + printf( "Inductiveness check failed for clause %d.\n", i ); } - Cnf_DataFree( pCnf ); - sat_solver_delete( pSat ); Vec_IntFree( vLits ); - return nFailed; + return nFailed + nFailedOuts; +} + +int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) +{ + int RetValue; + Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + assert( sat_solver_nvars(pSat) == pCnf->nVars ); + Cnf_DataFree( pCnf ); + RetValue = Pdr_InvCheck_int( p, vInv, fVerbose, pSat ); + sat_solver_delete( pSat ); + return RetValue; } Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) @@ -760,8 +791,8 @@ Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) int iFoVarBeg = pCnf->nVars - Gia_ManRegNum(p); int iFiVarBeg = 1 + Gia_ManPoNum(p); int iAuxVarBeg = sat_solver_nvars(pSat); - assert( Gia_ManPoNum(p) == 1 ); // allocate auxiliary variables + assert( sat_solver_nvars(pSat) == pCnf->nVars ); sat_solver_setnvars( pSat, sat_solver_nvars(pSat) + nCubes ); // add clauses Pdr_ForEachCube( pList, pCube, i ) @@ -785,25 +816,28 @@ Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) if ( k != i && !Vec_BitEntry(vRemoved, k) ) // skip this cube and already removed cubes Vec_IntPush( vLits, Abc_Var2Lit(iAuxVarBeg + k, 0) ); // pos aux literal nLits = Vec_IntSize( vLits ); - // check if the property still holds if ( fCheckProperty ) { - Vec_IntPush( vLits, Abc_Var2Lit(1, 0) ); - status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 ); - if ( status == l_Undef ) // timeout + for ( k = 0; k < Gia_ManPoNum(p); k++ ) { - fFailed = 1; + Vec_IntShrink( vLits, nLits ); + Vec_IntPush( vLits, Abc_Var2Lit(1+k, 0) ); + status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 ); + if ( status == l_Undef ) // timeout + { + fFailed = 1; + break; + } + if ( status == l_True ) // sat - property fails + break; + assert( status == l_False ); // unsat - property holds + } + if ( fFailed ) break; - } - if ( status == l_True ) // sat - property fails - { - //printf( "property fails if clause %d is removed\n", i ); + if ( k < Gia_ManPoNum(p) ) continue; - } - assert( status == l_False ); // unsat - property holds } - // check other clauses fCannot = 0; Pdr_ForEachCube( pList, pCube, n ) @@ -866,6 +900,9 @@ Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) Vec_Int_t * vRes = NULL; abctime clk = Abc_Clock(); int i, k, nLits = 0, * pCube, * pList = Vec_IntArray(vInv), nRemoved = 0; + Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + sat_solver * pSat; +// sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); Pdr_ForEachCube( pList, pCube, i ) { nLits += pCube[0]; @@ -873,16 +910,23 @@ Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) { int Save = pCube[k+1]; pCube[k+1] = -1; - if ( Pdr_InvCheck(p, vInv, 0) ) - { + //sat_solver_bookmark( pSat ); + pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + if ( Pdr_InvCheck_int(p, vInv, 0, pSat) ) pCube[k+1] = Save; - continue; + else + { + if ( fVerbose ) + printf( "Removing lit %d from clause %d.\n", k, i ); + nRemoved++; } - if ( fVerbose ) - printf( "Removing lit %d from clause %d.\n", k, i ); - nRemoved++; + sat_solver_delete( pSat ); + //sat_solver_rollback( pSat ); + //sat_solver_bookmark( pSat ); } } + Cnf_DataFree( pCnf ); + //sat_solver_delete( pSat ); if ( nRemoved ) printf( "Invariant minimization reduced %d literals (out of %d). ", nRemoved, nLits ); else From 32288c696493a223966ed334554f0a113d9134f0 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 25 Jan 2017 14:02:14 -0800 Subject: [PATCH 073/185] Adding features for invariant minimization. --- src/proof/pdr/pdrCore.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index c625e366d..b81a1a2a3 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -926,6 +926,8 @@ int Pdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); Pdr_ManDumpClauses( p, pFileName, RetValue==1 ); } + else if ( RetValue == 1 ) + Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); p->tTotal += Abc_Clock() - clk; Pdr_ManStop( p ); pPars->iFrame--; From a02bdebcc484ce18f388a7f172355da9cda9395e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 25 Jan 2017 14:58:06 -0800 Subject: [PATCH 074/185] Corner-case bug in MiniLUT. --- src/aig/gia/giaMini.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/aig/gia/giaMini.c b/src/aig/gia/giaMini.c index 4ee92cdda..67805d445 100644 --- a/src/aig/gia/giaMini.c +++ b/src/aig/gia/giaMini.c @@ -295,6 +295,7 @@ Mini_Lut_t * Gia_ManToMiniLut( Gia_Man_t * pGia ) word Truth; assert( Gia_ManHasMapping(pGia) ); LutSize = Gia_ManLutSizeMax( pGia ); + LutSize = Abc_MaxInt( LutSize, 2 ); assert( LutSize >= 2 ); // create the manager p = Mini_LutStart( LutSize ); From 636332c63e31d15112f89e89a4689351ed3b66ca Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 25 Jan 2017 22:27:46 -0800 Subject: [PATCH 075/185] Adding features for invariant minimization. --- src/proof/pdr/pdrInv.c | 16 ++- src/sat/bmc/bmcEnum.c | 225 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 238 insertions(+), 3 deletions(-) create mode 100644 src/sat/bmc/bmcEnum.c diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index bd32953a6..0d27ce7eb 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -691,7 +691,7 @@ void Pdr_InvPrint( Vec_Int_t * vInv, int fVerbose ) } } -int Pdr_InvCheck_int( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose, sat_solver * pSat ) +int Pdr_InvCheck_int( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose, sat_solver * pSat, int fSkip ) { int nBTLimit = 0; int fCheckProperty = 1; @@ -733,6 +733,11 @@ int Pdr_InvCheck_int( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose, sat_solver if ( fVerbose ) printf( "Coverage check failed for output %d.\n", i ); nFailedOuts++; + if ( fSkip ) + { + Vec_IntFree( vLits ); + return 1; + } continue; } assert( status == l_False ); // unsat - property holds @@ -755,6 +760,11 @@ int Pdr_InvCheck_int( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose, sat_solver continue; assert( status == l_True ); nFailed++; + if ( fSkip ) + { + Vec_IntFree( vLits ); + return 1; + } if ( fVerbose ) printf( "Inductiveness check failed for clause %d.\n", i ); } @@ -769,7 +779,7 @@ int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); assert( sat_solver_nvars(pSat) == pCnf->nVars ); Cnf_DataFree( pCnf ); - RetValue = Pdr_InvCheck_int( p, vInv, fVerbose, pSat ); + RetValue = Pdr_InvCheck_int( p, vInv, fVerbose, pSat, 0 ); sat_solver_delete( pSat ); return RetValue; } @@ -912,7 +922,7 @@ Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) pCube[k+1] = -1; //sat_solver_bookmark( pSat ); pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); - if ( Pdr_InvCheck_int(p, vInv, 0, pSat) ) + if ( Pdr_InvCheck_int(p, vInv, 0, pSat, 1) ) pCube[k+1] = Save; else { diff --git a/src/sat/bmc/bmcEnum.c b/src/sat/bmc/bmcEnum.c new file mode 100644 index 000000000..5fe2c1ed6 --- /dev/null +++ b/src/sat/bmc/bmcEnum.c @@ -0,0 +1,225 @@ +/**CFile**************************************************************** + + FileName [bmcEnum.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [SAT-based bounded model checking.] + + Synopsis [Enumeration.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: bmcEnum.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "bmc.h" +#include "sat/cnf/cnf.h" +#include "sat/bsat/satSolver.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDeriveOne( Gia_Man_t * p, Vec_Int_t * vValues ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; int i, fPhase0, fPhase1; + assert( Vec_IntSize(vValues) == Gia_ManCiNum(p) ); + // propagate forward + Gia_ManForEachCi( p, pObj, i ) + pObj->fPhase = Vec_IntEntry(vValues, i); + Gia_ManForEachAnd( p, pObj, i ) + { + fPhase0 = Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj); + fPhase1 = Gia_ObjPhase(Gia_ObjFanin1(pObj)) ^ Gia_ObjFaninC1(pObj); + pObj->fPhase = fPhase0 & fPhase1; + } + // propagate backward + Gia_ManCleanMark0(p); + Gia_ManForEachCo( p, pObj, i ) + Gia_ObjFanin0(pObj)->fMark0 = 1; + Gia_ManForEachAndReverse( p, pObj, i ) + { + if ( !pObj->fMark0 ) + continue; + fPhase0 = Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj); + fPhase1 = Gia_ObjPhase(Gia_ObjFanin1(pObj)) ^ Gia_ObjFaninC1(pObj); + if ( fPhase0 == fPhase1 ) + { + assert( (int)pObj->fPhase == fPhase0 ); + Gia_ObjFanin0(pObj)->fMark0 = 1; + Gia_ObjFanin1(pObj)->fMark0 = 1; + } + else if ( fPhase0 ) + { + assert( fPhase1 == 0 ); + assert( pObj->fPhase == 0 ); + Gia_ObjFanin1(pObj)->fMark0 = 1; + } + else if ( fPhase1 ) + { + assert( fPhase0 == 0 ); + assert( pObj->fPhase == 0 ); + Gia_ObjFanin0(pObj)->fMark0 = 1; + } + } + // create new + Gia_ManFillValue( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Abc_LitNotCond( Gia_ManAppendCi(pNew), !Vec_IntEntry(vValues, i) ); + Gia_ManForEachAnd( p, pObj, i ) + { + if ( !pObj->fMark0 ) + continue; + fPhase0 = Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj); + fPhase1 = Gia_ObjPhase(Gia_ObjFanin1(pObj)) ^ Gia_ObjFaninC1(pObj); + if ( fPhase0 == fPhase1 ) + { + assert( (int)pObj->fPhase == fPhase0 ); + if ( pObj->fPhase ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0(pObj)->Value, Gia_ObjFanin1(pObj)->Value ); + else + pObj->Value = Gia_ManAppendOr( pNew, Gia_ObjFanin0(pObj)->Value, Gia_ObjFanin1(pObj)->Value ); + } + else if ( fPhase0 ) + { + assert( fPhase1 == 0 ); + assert( pObj->fPhase == 0 ); + pObj->Value = Gia_ObjFanin1(pObj)->Value; + } + else if ( fPhase1 ) + { + assert( fPhase0 == 0 ); + assert( pObj->fPhase == 0 ); + pObj->Value = Gia_ObjFanin0(pObj)->Value; + } + } + Gia_ManForEachCo( p, pObj, i ) + Gia_ManAppendCo( pNew, Gia_ObjFanin0(pObj)->Value ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + Gia_ManCleanMark0(p); + return pNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDeriveOneTest2( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Vec_Int_t * vValues = Vec_IntStart( Gia_ManCiNum(p) ); + //Vec_IntFill( vValues, Gia_ManCiNum(p), 1 ); + pNew = Gia_ManDeriveOne( p, vValues ); + Vec_IntFree( vValues ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManDeriveOneTest( Gia_Man_t * p ) +{ + int fVerbose = 1; + Gia_Man_t * pNew; + Gia_Obj_t * pObj, * pRoot; + Vec_Int_t * vValues = Vec_IntStart( Gia_ManCiNum(p) ); + Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + int i, iVar, nIter, iPoVarBeg = pCnf->nVars - Gia_ManCiNum(p); + sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + Vec_Int_t * vLits = Vec_IntAlloc( 100 ); + Vec_IntPush( vLits, Abc_Var2Lit( 1, 1 ) ); + for ( nIter = 0; nIter < 10000; nIter++ ) + { + int status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), 0, 0, 0, 0 ); + if ( status == l_False ) + break; + // derive new set + assert( status == l_True ); + for ( i = 0; i < Gia_ManCiNum(p); i++ ) + { + Vec_IntWriteEntry( vValues, i, sat_solver_var_value(pSat, iPoVarBeg+i) ); + printf( "%d", sat_solver_var_value(pSat, iPoVarBeg+i) ); + } + printf( " : " ); + + pNew = Gia_ManDeriveOne( p, vValues ); + // assign variables + Gia_ManForEachCi( pNew, pObj, i ) + pObj->Value = iPoVarBeg+i; + iVar = sat_solver_nvars(pSat); + Gia_ManForEachAnd( pNew, pObj, i ) + pObj->Value = iVar++; + sat_solver_setnvars( pSat, iVar ); + // create new clauses + Gia_ManForEachAnd( pNew, pObj, i ) + sat_solver_add_and( pSat, pObj->Value, Gia_ObjFanin0(pObj)->Value, Gia_ObjFanin1(pObj)->Value, Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj), 0 ); + // add to the assumptions + pRoot = Gia_ManCo(pNew, 0); + Vec_IntPush( vLits, Abc_Var2Lit(Gia_ObjFanin0(pRoot)->Value, !Gia_ObjFaninC0(pRoot)) ); + if ( fVerbose ) + { + printf( "Iter = %5d : ", nIter ); + printf( "And = %4d ", Gia_ManAndNum(pNew) ); + printf( "\n" ); + } + Gia_ManStop( pNew ); + } + Vec_IntFree( vLits ); + Vec_IntFree( vValues ); + Cnf_DataFree( pCnf ); + sat_solver_delete( pSat ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + From 57286e8ab692d2df5df6e4077134b913229ba33f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 25 Jan 2017 22:29:51 -0800 Subject: [PATCH 076/185] Adding features for invariant minimization. --- src/proof/pdr/pdrInv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index 0d27ce7eb..8b04c53b4 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -759,14 +759,14 @@ int Pdr_InvCheck_int( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose, sat_solver if ( status == l_False ) // unsat -- correct continue; assert( status == l_True ); + if ( fVerbose ) + printf( "Inductiveness check failed for clause %d.\n", i ); nFailed++; if ( fSkip ) { Vec_IntFree( vLits ); return 1; } - if ( fVerbose ) - printf( "Inductiveness check failed for clause %d.\n", i ); } Vec_IntFree( vLits ); return nFailed + nFailedOuts; From 3c8c807ac16dbfc9b1960f77dd49fd244e3d718d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 26 Jan 2017 11:56:17 -0800 Subject: [PATCH 077/185] Improvements to SMT-LIB parser. --- src/base/wlc/wlc.h | 1 + src/base/wlc/wlcNtk.c | 6 +- src/base/wlc/wlcReadSmt.c | 334 ++++++++++++++++++++++++++++---------- 3 files changed, 250 insertions(+), 91 deletions(-) diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 1df3e5e94..6f64b47a2 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -140,6 +140,7 @@ struct Wlc_Ntk_t_ int nObjs[WLC_OBJ_NUMBER]; // counter of objects of each type int nAnds[WLC_OBJ_NUMBER]; // counter of AND gates after blasting int fSmtLib; // the network comes from an SMT-LIB file + int nAssert; // the number of asserts // memory for objects Wlc_Obj_t * pObjs; int iObj; diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index 6f396771e..a0799ba09 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -195,14 +195,14 @@ void Wlc_ObjAddFanins( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFanins ) { assert( pObj->nFanins == 0 ); pObj->nFanins = Vec_IntSize(vFanins); - if ( Wlc_ObjHasArray(pObj) ) - pObj->pFanins[0] = (int *)Mem_FlexEntryFetch( p->pMemFanin, Vec_IntSize(vFanins) * sizeof(int) ); - memcpy( Wlc_ObjFanins(pObj), Vec_IntArray(vFanins), sizeof(int) * Vec_IntSize(vFanins) ); // special treatment of CONST, SELECT and TABLE if ( pObj->Type == WLC_OBJ_CONST ) pObj->nFanins = 0; else if ( pObj->Type == WLC_OBJ_BIT_SELECT || pObj->Type == WLC_OBJ_TABLE ) pObj->nFanins = 1; + if ( Wlc_ObjHasArray(pObj) ) + pObj->pFanins[0] = (int *)Mem_FlexEntryFetch( p->pMemFanin, Vec_IntSize(vFanins) * sizeof(int) ); + memcpy( Wlc_ObjFanins(pObj), Vec_IntArray(vFanins), sizeof(int) * Vec_IntSize(vFanins) ); } void Wlc_NtkFree( Wlc_Ntk_t * p ) { diff --git a/src/base/wlc/wlcReadSmt.c b/src/base/wlc/wlcReadSmt.c index d07a54c44..61d0bca89 100644 --- a/src/base/wlc/wlcReadSmt.c +++ b/src/base/wlc/wlcReadSmt.c @@ -219,6 +219,8 @@ static inline int Smt_StrToType( char * pName, int * pfSigned ) Type = WLC_OBJ_ARI_REM, *pfSigned = 1; // 40: arithmetic remainder else if ( !strcmp(pName, "bvsmod") ) Type = WLC_OBJ_ARI_MODULUS, *pfSigned = 1; // 40: arithmetic modulus + else if ( !strcmp(pName, "=") ) + Type = WLC_OBJ_COMP_EQU; // 40: arithmetic modulus // else if ( !strcmp(pName, "") ) // Type = WLC_OBJ_ARI_POWER; // 41: arithmetic power else if ( !strcmp(pName, "bvneg") ) @@ -255,6 +257,8 @@ static inline int Smt_PrsReadType( Smt_Prs_t * p, int iSig, int * pfSigned, int } } +static inline int Smt_StrType( char * str ) { return Smt_StrToType(str, NULL); } + /**Function************************************************************* Synopsis [] @@ -274,20 +278,27 @@ static inline int Smt_PrsCreateNodeOld( Wlc_Ntk_t * pNtk, int Type, int fSigned, assert( Type > 0 ); assert( Range >= 0 ); assert( fSigned >= 0 ); - Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj), vFanins ); - if ( fSigned ) - Wlc_NtkObj(pNtk, iObj)->Signed = fSigned; - if ( Type == WLC_OBJ_SHIFT_RA ) - Wlc_NtkObj(pNtk, iObj)->Signed = 1; + + // add node's name if ( pName == NULL ) { sprintf( Buffer, "_n%d_", iObj ); pName = Buffer; } - // add node's name NameId = Abc_NamStrFindOrAdd( pNtk->pManName, pName, &fFound ); assert( !fFound ); assert( iObj == NameId ); + + Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj), vFanins ); + if ( fSigned ) + { + Wlc_NtkObj(pNtk, iObj)->Signed = fSigned; +// if ( Vec_IntSize(vFanins) > 0 ) +// Wlc_NtkObj(pNtk, Vec_IntEntry(vFanins, 0))->Signed = fSigned; +// if ( Vec_IntSize(vFanins) > 1 ) +// Wlc_NtkObj(pNtk, Vec_IntEntry(vFanins, 1))->Signed = fSigned; + } + return iObj; } static inline int Smt_PrsCreateNode( Wlc_Ntk_t * pNtk, int Type, int fSigned, int Range, Vec_Int_t * vFanins, char * pName ) @@ -302,8 +313,7 @@ static inline int Smt_PrsCreateNode( Wlc_Ntk_t * pNtk, int Type, int fSigned, in assert( Range >= 0 ); assert( fSigned >= 0 ); - // allow more than 2 fanins for specific operators - // if (Vec_IntSize(vFanins)<=2 || Type == WLC_OBJ_BIT_CONCAT || Type == WLC_OBJ_MUX ) + //if (Vec_IntSize(vFanins)<=2 || Type == WLC_OBJ_BIT_CONCAT || Type == WLC_OBJ_MUX ) // explicitely secify allowed multi operators if (Vec_IntSize(vFanins)<=2 || !( Type == WLC_OBJ_BIT_AND || // 16:`` bitwise AND @@ -362,17 +372,17 @@ FINISHED_WITH_FANINS: Vec_IntFree(v2Fanins); - // to deal with long shifts create extra bit select (ROTATE as well ??) + //added to deal with long shifts create extra bit select (ROTATE as well ??) // this is a temporary hack - // basically we keep only 32 bits. - // bits 0 - 30 are kept same as original - // bit 31 will be the reduction or of all bits from 31 to Range-1 + // basically we keep only 32 bits. + // bit[31] will be the copy of original MSB (sign bit, just in case) UPDATE: assume it is unsigned first???? + // bit[31] will be the reduction or of any bits from [31] to Range if (Type == WLC_OBJ_SHIFT_R || Type == WLC_OBJ_SHIFT_RA || Type == WLC_OBJ_SHIFT_L) { - int iFanin1 = Vec_IntEntry(vFanins,1); - int range1 = Wlc_ObjRange( Wlc_NtkObj(pNtk, iFanin1) ); - int iObj1, iObj2, iObj3; + int range1, iObj1, iObj2, iObj3; assert(Vec_IntSize(vFanins)>=2); + iFanin1 = Vec_IntEntry(vFanins,1); + range1 = Wlc_ObjRange( Wlc_NtkObj(pNtk, iFanin1) ); if (range1>32) { Vec_Int_t * newFanins = Vec_IntAlloc(10); @@ -389,6 +399,8 @@ FINISHED_WITH_FANINS: Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj1), newFanins ); + //printf("obj1: %d\n",iObj1); + // bit select of larger bits Vec_IntPop(newFanins); Vec_IntPop(newFanins); @@ -402,6 +414,7 @@ FINISHED_WITH_FANINS: assert( iObj2 == NameId ); Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj2), newFanins ); + //printf("obj2: %d\n",iObj2); // reduction or Vec_IntPop( newFanins ); @@ -416,6 +429,7 @@ FINISHED_WITH_FANINS: assert( iObj3 == NameId ); Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj3), newFanins ); + //printf("obj3: %d\n",iObj3); // concat all together Vec_IntWriteEntry( newFanins, 0, iObj3 ); @@ -429,6 +443,7 @@ FINISHED_WITH_FANINS: assert( iObj == NameId ); Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj), newFanins ); + //printf("obj: %d\n",iObj); // pushing the new node Vec_IntWriteEntry(vFanins, 1, iObj); @@ -461,34 +476,22 @@ FINISHED_WITH_FANINS: return iObj; } -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ static inline char * Smt_GetHexFromDecimalString(char * pStr) { int i,k=0, nDigits = strlen(pStr); int digit, carry = 0; - int metNonZeroBit; - int nBits; - char * hex; + int metNonZeroBit = 0; Vec_Int_t * decimal = Vec_IntAlloc(nDigits); Vec_Int_t * rev; + int nBits; + char * hex; for (i=0;i= '0' && pStr[0] <= '9' ) { + // added: sanity check for large constants + /* + Vec_Int_t * temp = Vec_IntAlloc(10); + int fullBits = -1; + Smt_GetBinaryFromDecimalString(pStr,temp,&fullBits); + Vec_IntFree(temp); + assert(fullBits < 32);*/ + + char * pHex = Smt_GetHexFromDecimalString(pStr); + + if ( nBits == -1 ) + nBits = strlen(pHex)*4; + + //printf("nbits: %d\n",nBits); + + Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 ); + nDigits = Abc_TtReadHexNumber( (word *)Vec_IntArray(vFanins), pHex ); + ABC_FREE( pHex ); + /* int w, nWords, Number = atoi( pStr ); if ( nBits == -1 ) @@ -589,15 +616,6 @@ static inline int Smt_PrsBuildConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits for ( w = 0; w < nWords; w++ ) Vec_IntPush( vFanins, w ? 0 : Number ); */ - - // convert decimal to hex to parse large constants - char * pHex = Smt_GetHexFromDecimalString(pStr); - - if ( nBits == -1 ) - nBits = strlen(pHex)*4; - - Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 ); - nDigits = Abc_TtReadHexNumber( (word *)Vec_IntArray(vFanins), pHex ); } else { @@ -648,12 +666,6 @@ int Smt_PrsBuildNode( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int RangeOut, // s3087 int fFound, iObj = Abc_NamStrFindOrAdd( pNtk->pManName, pStr, &fFound ); assert( fFound ); - // create buffer if the name of the fanin has different name - if ( pName && strcmp(pStr, pName) ) - { - Vec_IntFill( &p->vTempFans, 1, iObj ); - iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BUF, 0, RangeOut, &p->vTempFans, pName ); - } return iObj; } } @@ -804,13 +816,6 @@ Wlc_Ntk_t * Smt_PrsBuild( Smt_Prs_t * p ) // skip () Fan = Vec_IntEntry(vFans, 2); assert( !Smt_EntryIsName(Fan) ); - vFans2 = Smt_VecEntryNode(p, vFans, 2); - if ( Vec_IntSize(vFans2) > 0 ) - { - printf( "File parsing error: Uninterpreted functions are not supported.\n" ); - Wlc_NtkFree( pNtk ); pNtk = NULL; - goto finish; - } // check type (Bool or BitVec) Fan = Vec_IntEntry(vFans, 3); if ( Smt_EntryIsName(Fan) ) @@ -1006,6 +1011,14 @@ char * Smt_PrsGenName( Smt_Prs_t * p ) } int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, char * pName ) { + char suffix[100]; + sprintf(suffix,"_as%d",pNtk->nAssert); + + //char * prepStr = Abc_NamStr(p->pStrs, Abc_Lit2Var(iNode)); + //printf("prestr: %s\n",prepStr); + + //printf("inode: %d %d\n",iNode,Smt_EntryIsName(iNode)); + if ( Smt_EntryIsName(iNode) ) { char * pStr = Abc_NamStr(p->pStrs, Abc_Lit2Var(iNode)); @@ -1018,7 +1031,27 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, return Smt_PrsBuildConstant( pNtk, pStr, -1, pName ? pName : Smt_PrsGenName(p) ); else { - int fFound, iObj = Abc_NamStrFindOrAdd( pNtk->pManName, pStr, &fFound ); + int fFound, iObj; + // look either for global DECLARE-FUN variable or local LET + char * pStr_glb = (char *)malloc(strlen(pStr) + 4 +1); //glb + char * pStr_loc = (char *)malloc(strlen(pStr) + strlen(suffix) +1); + strcpy(pStr_glb,pStr); + strcat(pStr_glb,"_glb"); + strcpy(pStr_loc,pStr); + strcat(pStr_loc,suffix); + + fFound = Abc_NamStrFind( pNtk->pManName, pStr_glb ); + + if (fFound) + pStr = pStr_glb; + else + { + assert( Abc_NamStrFind( pNtk->pManName, pStr_loc )); + pStr = pStr_loc; + } + // FIXME: delete memory of pStr + + iObj = Abc_NamStrFindOrAdd( pNtk->pManName, pStr, &fFound ); assert( fFound ); // create buffer if the name of the fanin has different name if ( pName && strcmp(Wlc_ObjName(pNtk, iObj), pName) ) @@ -1026,9 +1059,11 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, Vec_IntFill( &p->vTempFans, 1, iObj ); iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BUF, 0, Wlc_ObjRange(Wlc_NtkObj(pNtk, iObj)), &p->vTempFans, pName ); } + ABC_FREE( pStr_glb ); + ABC_FREE( pStr_loc ); return iObj; } - } + } else { Vec_Int_t * vRoots, * vRoots1, * vFans3; @@ -1039,7 +1074,7 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, if ( Smt_EntryIsName(iRoot0) ) { char * pName2, * pStr0 = Abc_NamStr(p->pStrs, Abc_Lit2Var(iRoot0)); - if ( Abc_Lit2Var(iRoot0) == SMT_PRS_LET ) + if ( Abc_Lit2Var(iRoot0) == SMT_PRS_LET || Abc_Lit2Var(iRoot0) == SMT_PRS_DEFINE_FUN) //added define-fun is similar to let { // let ((s35550 (bvor s48 s35549))) assert( Vec_IntSize(vRoots) == 3 ); @@ -1051,6 +1086,7 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, // iterate through the parts Vec_IntForEachEntry( vRoots1, Fan, k ) { + char * temp; // s35550 (bvor s48 s35549) assert( !Smt_EntryIsName(Fan) ); vFans3 = Smt_EntryNode(p, Fan); @@ -1059,11 +1095,26 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, Fan3 = Vec_IntEntry(vFans3, 0); assert( Smt_EntryIsName(Fan3) ); pName2 = Smt_EntryName(p, Fan3); + // create a local name with suffix + if ( Abc_Lit2Var(iRoot0) == SMT_PRS_LET ) + { + temp = (char *)malloc(strlen(pName2) + strlen(suffix) + 1); + strcpy(temp, pName2); + strcat(temp,suffix); + } + else + { temp = (char *)malloc(strlen(pName2) + 4 + 1); + strcpy(temp, pName2); + strcat(temp,"_glb"); + } + // FIXME: need to delete memory of pName2 + pName2 = temp; // get function Fan3 = Vec_IntEntry(vFans3, 1); //assert( !Smt_EntryIsName(Fan3) ); // solve the problem iObj = Smt_PrsBuild2_rec( pNtk, p, Fan3, -1, pName2 ); // NULL ); //pName2 ); + ABC_FREE( temp ); if ( iObj == 0 ) return 0; // create buffer @@ -1133,7 +1184,6 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, int iObj = Abc_NamStrFind( pNtk->pManName, pStr0 ); if ( iObj ) return iObj; - Type0 = Smt_StrToType( pStr0, &fSigned ); if ( Type0 == 0 ) return 0; @@ -1151,7 +1201,6 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, } Vec_IntPush( vFanins, iObj ); } - // find range Range = 0; if ( Type0 >= WLC_OBJ_LOGIC_NOT && Type0 <= WLC_OBJ_REDUCT_XOR ) @@ -1197,7 +1246,7 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) Wlc_Ntk_t * pNtk; Vec_Int_t * vFansRoot, * vFans, * vFans2; Vec_Int_t * vAsserts = Vec_IntAlloc(100); - int i, Root, Fan, iObj, NameId, Range, Status, nBits = 0; + int i, Root, Fan, iObj, NameId, Range, nBits = 0; char * pName, * pRange; // start network and create primary inputs pNtk = Wlc_NtkAlloc( p->pName, 1000 ); @@ -1214,22 +1263,22 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) // create variables if ( Abc_Lit2Var(Fan) == SMT_PRS_DECLARE_FUN ) { + char * pName_glb; assert( Vec_IntSize(vFans) == 4 ); assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_DECLARE_FUN) ); // get name Fan = Vec_IntEntry(vFans, 1); assert( Smt_EntryIsName(Fan) ); pName = Smt_EntryName(p, Fan); + // added: giving a global suffix + pName_glb = (char *) malloc(strlen(pName) + 4 + 1); + strcpy(pName_glb,pName); + strcat(pName_glb,"_glb"); + // FIXME: delete memory of pName + pName = pName_glb; // skip () Fan = Vec_IntEntry(vFans, 2); assert( !Smt_EntryIsName(Fan) ); - vFans2 = Smt_VecEntryNode(p, vFans, 2); - if ( Vec_IntSize(vFans2) > 0 ) - { - printf( "File parsing error: Uninterpreted functions are not supported.\n" ); - Wlc_NtkFree( pNtk ); pNtk = NULL; - goto finish; - } // check type (Bool or BitVec) Fan = Vec_IntEntry(vFans, 3); if ( Smt_EntryIsName(Fan) ) @@ -1259,9 +1308,11 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) Vec_IntPush( &pNtk->vValues, nBits ); Vec_IntPush( &pNtk->vValues, Range ); nBits += Range; + ABC_FREE( pName_glb ); } // create constants - else if ( Abc_Lit2Var(Fan) == SMT_PRS_DEFINE_FUN ) + /* + else if ( Abc_Lit2Var(Fan) == SMT_PRS_DEFINE_FUN ) // added: we parse DEFINE_FUN in LET { assert( Vec_IntSize(vFans) == 5 ); assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_DEFINE_FUN) ); @@ -1269,6 +1320,14 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) Fan = Vec_IntEntry(vFans, 1); assert( Smt_EntryIsName(Fan) ); pName = Smt_EntryName(p, Fan); + + // added: giving a global suffix + char * pName_glb = (char *) malloc(strlen(pName) + 4 + 1); + strcpy(pName_glb,pName); + strcat(pName_glb,"_glb"); + // FIXME: delete memory of pName + pName = pName_glb; + // skip () Fan = Vec_IntEntry(vFans, 2); assert( !Smt_EntryIsName(Fan) ); @@ -1278,13 +1337,17 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) { // (define-fun s_2 () Bool false) assert( !strcmp("Bool", Smt_VecEntryName(p, vFans, 3)) ); - iObj = Smt_PrsBuild2_rec( pNtk, p, Vec_IntEntry(vFans, 4), -1, pName ); - if ( iObj == 0 ) - { - Wlc_NtkFree( pNtk ); pNtk = NULL; - goto finish; - } - continue; + Range = 1; + pValue = Smt_VecEntryName(p, vFans, 4); + + //printf("value: %s\n",pValue); + + if ( !strcmp("false", pValue) ) + pValue = "#b0"; + else if ( !strcmp("true", pValue) ) + pValue = "#b1"; + else assert( 0 ); + Status = Smt_PrsBuildConstant( pNtk, pValue, Range, pName ); } else { @@ -1292,6 +1355,74 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) // (define-fun s1 () (_ BitVec 8) (bvneg #x7f)) // get range Fan = Vec_IntEntry(vFans, 3); + + assert( !Smt_EntryIsName(Fan) ); + vFans2 = Smt_VecEntryNode(p, vFans, 3); + assert( Vec_IntSize(vFans2) == 3 ); + assert( !strcmp("_", Smt_VecEntryName(p, vFans2, 0)) ); + assert( !strcmp("BitVec", Smt_VecEntryName(p, vFans2, 1)) ); + // get range + Fan = Vec_IntEntry(vFans2, 2); + + assert( Smt_EntryIsName(Fan) ); + pRange = Smt_EntryName(p, Fan); + Range = atoi(pRange); + + // added: can parse functions too + Vec_Int_t * vFans3 = Smt_VecEntryNode(p, vFans, 4); + Fan = Vec_IntEntry(vFans3, 0); + + // get constant + //Fan = Vec_IntEntry(vFans, 4); + + //printf("fan3: %s\n",Fan); + //printf("fan0: %s\n",Smt_VecEntryName(p, vFans3, 0)); + //printf("fan1: %s\n",Smt_VecEntryName(p, vFans3, 1)); + //printf("fan2: %s\n",Smt_VecEntryName(p, vFans3, 2)); + //printf("fan3: %s\n",Smt_VecEntryName(p, vFans3, 3)); + + Status = Smt_PrsBuildNode( pNtk, p, Fan, Range, pName ); + } + if ( !Status ) + { + Wlc_NtkFree( pNtk ); pNtk = NULL; + goto finish; + } + } + */ + // added: new way to parse define-fun + // create constants + else if ( Abc_Lit2Var(Fan) == SMT_PRS_DEFINE_FUN ) + { + char * pName_glb; + // (define-fun def_16001 () Bool (or def_15999 def_16000)) + // (define-fun def_15990 () (_ BitVec 24) (concat def_15988 def_15989)) + assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_DEFINE_FUN) ); + assert( Vec_IntSize(vFans) == 5 ); // const or definition + + // get name + Fan = Vec_IntEntry(vFans, 1); + assert( Smt_EntryIsName(Fan) ); + pName = Smt_EntryName(p, Fan); + // added: giving a global suffix + pName_glb = (char *) malloc(strlen(pName) + 4 + 1); + strcpy(pName_glb,pName); + strcat(pName_glb,"_glb"); + // FIXME: delete memory of pName + pName = pName_glb; + + //get range + Fan = Vec_IntEntry(vFans, 3); + if ( Smt_EntryIsName(Fan) ) + { + // (define-fun s_2 () Bool false) + assert( !strcmp("Bool", Smt_VecEntryName(p, vFans, 3)) ); + Range = 1; + } + else + { + // (define-fun s702 () (_ BitVec 4) #xe) + // (define-fun s1 () (_ BitVec 8) (bvneg #x7f)) assert( !Smt_EntryIsName(Fan) ); vFans2 = Smt_VecEntryNode(p, vFans, 3); assert( Vec_IntSize(vFans2) == 3 ); @@ -1302,16 +1433,13 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) assert( Smt_EntryIsName(Fan) ); pRange = Smt_EntryName(p, Fan); Range = atoi(pRange); - // get constant - Fan = Vec_IntEntry(vFans, 4); - Status = Smt_PrsBuildNode( pNtk, p, Fan, Range, pName ); - } - if ( !Status ) - { - Wlc_NtkFree( pNtk ); pNtk = NULL; - goto finish; } + + iObj = Smt_PrsBuild2_rec( pNtk, p, Vec_IntEntry(vFans, 4), Range, pName ); + assert( iObj ); + ABC_FREE( pName_glb ); } + // collect assertion outputs else if ( Abc_Lit2Var(Fan) == SMT_PRS_ASSERT ) { @@ -1321,6 +1449,7 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) //(assert (not (= s0 #x00))) assert( Vec_IntSize(vFans) == 2 ); assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_ASSERT) ); + pNtk->nAssert++; // added iObj = Smt_PrsBuild2_rec( pNtk, p, Vec_IntEntry(vFans, 1), -1, NULL ); if ( iObj == 0 ) { @@ -1336,6 +1465,9 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) // build AND of asserts if ( Vec_IntSize(vAsserts) == 1 ) iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BUF, 0, 1, vAsserts, "miter" ); + // added: 0 asserts + else if ( Vec_IntSize(vAsserts) == 0 ) + iObj = Smt_PrsBuildConstant( pNtk, "#b1", 1, "miter" ); else { iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vAsserts), vAsserts, NULL ); @@ -1413,18 +1545,35 @@ static inline char * Smt_PrsLoadFile( char * pFileName, char ** ppLimit ) static inline int Smt_PrsRemoveComments( char * pBuffer, char * pLimit ) { char * pTemp; int nCount1 = 0, nCount2 = 0, fHaveBar = 0; + int backslash = 0; for ( pTemp = pBuffer; pTemp < pLimit; pTemp++ ) { if ( *pTemp == '(' ) - nCount1++; + { if ( !fHaveBar ) nCount1++; } else if ( *pTemp == ')' ) - nCount2++; + { if ( !fHaveBar ) nCount2++; } else if ( *pTemp == '|' ) fHaveBar ^= 1; else if ( *pTemp == ';' && !fHaveBar ) while ( *pTemp && *pTemp != '\n' ) *pTemp++ = ' '; + // added: hack to remove quotes + else if ( *pTemp == '\"' && *(pTemp-1) != '\\' && !fHaveBar ) + { + *pTemp++ = ' '; + while ( *pTemp && (*pTemp != '\"' || backslash)) + { + if (*pTemp == '\\') + backslash = 1; + else + backslash = 0; + *pTemp++ = ' '; + } + // remove the last quote symbol + *pTemp = ' '; + } } + if ( nCount1 != nCount2 ) printf( "The input SMTLIB file has different number of opening and closing parentheses (%d and %d).\n", nCount1, nCount2 ); else if ( nCount1 == 0 ) @@ -1455,7 +1604,6 @@ static inline void Smt_PrsFree( Smt_Prs_t * p ) Vec_IntErase( &p->vStack ); Vec_IntErase( &p->vTempFans ); //Vec_WecErase( &p->vDepth ); - Vec_WecErase( &p->vObjs ); ABC_FREE( p ); } @@ -1499,6 +1647,15 @@ void Smt_PrsReadLines( Smt_Prs_t * p ) for ( p->pCur = p->pBuffer; p->pCur < p->pLimit; p->pCur++ ) { Smt_PrsSkipSpaces( p ); + if ( *p->pCur == '|' ) + { + *p->pCur = ' '; + while ( *p->pCur && *p->pCur != '|' ) + *p->pCur++ = ' '; + if ( *p->pCur == '|' ) + *p->pCur = ' '; + continue; + } if ( *p->pCur == '(' ) { // add new node at this depth @@ -1524,12 +1681,13 @@ void Smt_PrsReadLines( Smt_Prs_t * p ) { // remove strange characters (this can lead to name clashes) int iToken; + /* commented out for SMT comp char * pTemp; if ( *pStart == '?' ) *pStart = '_'; for ( pTemp = pStart; pTemp < p->pCur; pTemp++ ) if ( *pTemp == '.' ) - *pTemp = '_'; + *pTemp = '_';*/ // create and save token for this string iToken = Abc_NamStrFindOrAddLim( p->pStrs, pStart, p->pCur--, NULL ); Vec_IntPush( Vec_WecEntry(&p->vObjs, Vec_IntEntryLast(&p->vStack)), Abc_Var2Lit(iToken, 1) ); From 7d82819d519595854c4e1b9dbf99d91e1d2ab9f9 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 26 Jan 2017 15:17:02 -0800 Subject: [PATCH 078/185] Adding visualization of word-level networks Wlc_Ntk_t. --- abclib.dsp | 4 + src/base/wlc/module.make | 1 + src/base/wlc/wlc.h | 12 +- src/base/wlc/wlcAbs.c | 4 +- src/base/wlc/wlcCom.c | 116 +++++++++++++ src/base/wlc/wlcNtk.c | 162 ++++++++++++++++++- src/base/wlc/wlcReadVer.c | 2 +- src/base/wlc/wlcShow.c | 331 ++++++++++++++++++++++++++++++++++++++ 8 files changed, 621 insertions(+), 11 deletions(-) create mode 100644 src/base/wlc/wlcShow.c diff --git a/abclib.dsp b/abclib.dsp index 170633e49..6da7e2a2c 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -799,6 +799,10 @@ SOURCE=.\src\base\wlc\wlcReadVer.c # End Source File # Begin Source File +SOURCE=.\src\base\wlc\wlcShow.c +# End Source File +# Begin Source File + SOURCE=.\src\base\wlc\wlcSim.c # End Source File # Begin Source File diff --git a/src/base/wlc/module.make b/src/base/wlc/module.make index 5a95a63f2..ae7899ec9 100644 --- a/src/base/wlc/module.make +++ b/src/base/wlc/module.make @@ -7,6 +7,7 @@ SRC += src/base/wlc/wlcAbs.c \ src/base/wlc/wlcReadSmt.c \ src/base/wlc/wlcReadVer.c \ src/base/wlc/wlcSim.c \ + src/base/wlc/wlcShow.c \ src/base/wlc/wlcStdin.c \ src/base/wlc/wlcWin.c \ src/base/wlc/wlcWriteVer.c diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 6f64b47a2..e4a818e56 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -157,6 +157,7 @@ struct Wlc_Ntk_t_ Vec_Int_t vTravIds; // trav IDs of the objects Vec_Int_t vCopies; // object first bits Vec_Int_t vBits; // object mapping into AIG nodes + Vec_Int_t vLevels; // object levels }; static inline int Wlc_NtkObjNum( Wlc_Ntk_t * p ) { return p->iObj - 1; } @@ -206,6 +207,8 @@ static inline int Wlc_ObjSign( Wlc_Obj_t * p ) static inline int * Wlc_ObjConstValue( Wlc_Obj_t * p ) { assert(p->Type == WLC_OBJ_CONST); return Wlc_ObjFanins(p); } static inline int Wlc_ObjTableId( Wlc_Obj_t * p ) { assert(p->Type == WLC_OBJ_TABLE); return p->Fanins[1]; } static inline word * Wlc_ObjTable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { return (word *)Vec_PtrEntry( p->vTables, Wlc_ObjTableId(pObj) ); } +static inline int Wlc_ObjLevelId( Wlc_Ntk_t * p, int iObj ) { return Vec_IntEntry( &p->vLevels, iObj ); } +static inline int Wlc_ObjLevel( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { return Wlc_ObjLevelId( p, Wlc_ObjId(p, pObj) ); } static inline void Wlc_NtkCleanCopy( Wlc_Ntk_t * p ) { Vec_IntFill( &p->vCopies, p->nObjsAlloc, 0 ); } static inline int Wlc_NtkHasCopy( Wlc_Ntk_t * p ) { return Vec_IntSize( &p->vCopies ) > 0; } @@ -230,6 +233,8 @@ static inline Wlc_Obj_t * Wlc_ObjFoToFi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) #define Wlc_NtkForEachObj( p, pObj, i ) \ for ( i = 1; (i < Wlc_NtkObjNumMax(p)) && (((pObj) = Wlc_NtkObj(p, i)), 1); i++ ) +#define Wlc_NtkForEachObjReverse( p, pObj, i ) \ + for ( i = Wlc_NtkObjNumMax(p) - 1; (i > 0) && (((pObj) = Wlc_NtkObj(p, i)), 1); i-- ) #define Wlc_NtkForEachObjVec( vVec, p, pObj, i ) \ for ( i = 0; (i < Vec_IntSize(vVec)) && (((pObj) = Wlc_NtkObj(p, Vec_IntEntry(vVec, i))), 1); i++ ) #define Wlc_NtkForEachPi( p, pPi, i ) \ @@ -266,6 +271,7 @@ extern Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int i /*=== wlcCom.c ========================================================*/ extern void Wlc_SetNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk ); /*=== wlcNtk.c ========================================================*/ +extern char * Wlc_ObjTypeName( Wlc_Obj_t * p ); extern Wlc_Ntk_t * Wlc_NtkAlloc( char * pName, int nObjsAlloc ); extern int Wlc_ObjAlloc( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg ); extern int Wlc_ObjCreate( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg, Vec_Int_t * vFanins ); @@ -275,12 +281,16 @@ extern char * Wlc_ObjName( Wlc_Ntk_t * p, int iObj ); extern void Wlc_ObjUpdateType( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, int Type ); extern void Wlc_ObjAddFanins( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFanins ); extern void Wlc_NtkFree( Wlc_Ntk_t * p ); +extern int Wlc_NtkCreateLevels( Wlc_Ntk_t * p ); +extern int Wlc_NtkCreateLevelsRev( Wlc_Ntk_t * p ); extern void Wlc_NtkPrintNode( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ); extern void Wlc_NtkPrintNodeArray( Wlc_Ntk_t * p, Vec_Int_t * vArray ); extern void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type ); extern void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose ); -extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p ); +extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked ); extern void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ); +extern void Wlc_NtkCleanMarks( Wlc_Ntk_t * p ); +extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iPo ); extern Wlc_Ntk_t * Wlc_NtkDupSingleNodes( Wlc_Ntk_t * p ); /*=== wlcReadSmt.c ========================================================*/ extern Wlc_Ntk_t * Wlc_ReadSmtBuffer( char * pFileName, char * pBuffer, char * pLimit, int fOldParser, int fPrintTree ); diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 73ff73280..368652d6c 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -173,7 +173,7 @@ Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit ) if ( vNodes != vNodesInit ) Vec_IntFree( vNodes ); // reconstruct topological order - pNew = Wlc_NtkDupDfs( p ); + pNew = Wlc_NtkDupDfs( p, 0 ); Wlc_NtkTransferNames( pNew, p ); return pNew; } @@ -278,7 +278,7 @@ Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * p, Vec_Int_t * vPairsInit ) if ( vPairs != vPairsInit ) Vec_IntFree( vPairs ); // reconstruct topological order - pNew = Wlc_NtkDupDfs( p ); + pNew = Wlc_NtkDupDfs( p, 0 ); Wlc_NtkTransferNames( pNew, p ); return pNew; } diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 2828fea33..316d28835 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -31,8 +31,10 @@ ABC_NAMESPACE_IMPL_START static int Abc_CommandReadWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandShow ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandInvPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -68,8 +70,10 @@ void Wlc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Word level", "%read", Abc_CommandReadWlc, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%write", Abc_CommandWriteWlc, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%cone", Abc_CommandCone, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%show", Abc_CommandShow, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%test", Abc_CommandTest, 0 ); Cmd_CommandAdd( pAbc, "Word level", "inv_ps", Abc_CommandInvPs, 0 ); @@ -332,6 +336,70 @@ usage: return 1; } +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + int c, iOutput = -1, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Ovh" ) ) != EOF ) + { + switch ( c ) + { + case 'O': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" ); + goto usage; + } + iOutput = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( iOutput < 0 ) + goto usage; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" ); + return 0; + } + if ( iOutput < 0 || iOutput >= Wlc_NtkPoNum(pNtk) ) + { + Abc_Print( 1, "Abc_CommandCone(): Illegal output index (%d) (should be 0 <= num < %d).\n", iOutput, Wlc_NtkPoNum(pNtk) ); + return 0; + } + printf( "Extracting output %d.\n", iOutput ); + Wlc_NtkMarkCone( pNtk, iOutput ); + pNtk = Wlc_NtkDupDfs( pNtk, 1 ); + Wlc_AbcUpdateNtk( pAbc, pNtk ); + return 0; +usage: + Abc_Print( -2, "usage: %%cone [-O num] [-vh]\n" ); + Abc_Print( -2, "\t extracts cone of the given word-level output\n" ); + Abc_Print( -2, "\t-O num : zero-based index of the word-level output to extract [default = %d]\n", iOutput ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function******************************************************************** Synopsis [] @@ -481,6 +549,54 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandShow( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Wlc_NtkShow( Wlc_Ntk_t * p, Vec_Int_t * vBold ); + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + int c, fVerbose = 0; + // set defaults + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( -1, "Empty network.\n" ); + return 1; + } + Wlc_NtkShow( pNtk, NULL ); + return 0; + +usage: + Abc_Print( -2, "usage: %%show [-h]\n" ); + Abc_Print( -2, " visualizes the network structure using DOT and GSVIEW\n" ); +#ifdef WIN32 + Abc_Print( -2, " \"dot.exe\" and \"gsview32.exe\" should be set in the paths\n" ); + Abc_Print( -2, " (\"gsview32.exe\" may be in \"C:\\Program Files\\Ghostgum\\gsview\\\")\n" ); +#endif + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function******************************************************************** Synopsis [] diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index a0799ba09..fa0074d3f 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -88,6 +88,8 @@ static char * Wlc_Names[WLC_OBJ_NUMBER+1] = { NULL // 54: unused }; +char * Wlc_ObjTypeName( Wlc_Obj_t * p ) { return Wlc_Names[p->Type]; } + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -224,6 +226,7 @@ void Wlc_NtkFree( Wlc_Ntk_t * p ) ABC_FREE( p->vValues.pArray ); ABC_FREE( p->vCopies.pArray ); ABC_FREE( p->vBits.pArray ); + ABC_FREE( p->vLevels.pArray ); ABC_FREE( p->pInits ); ABC_FREE( p->pObjs ); ABC_FREE( p->pName ); @@ -244,6 +247,81 @@ int Wlc_NtkMemUsage( Wlc_Ntk_t * p ) return Mem; } +/**Function************************************************************* + + Synopsis [Assigns object levels.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Wlc_NtkCreateLevels( Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; + int i, k, iFanin, Level, LevelMax = 0; + Vec_IntFill( &p->vLevels, Wlc_NtkObjNumMax(p), 0 ); + Wlc_NtkForEachObj( p, pObj, i ) + { + Level = 0; + Wlc_ObjForEachFanin( pObj, iFanin, k ) + Level = Abc_MaxInt( Level, Wlc_ObjLevelId(p, iFanin) + 1 ); + Vec_IntWriteEntry( &p->vLevels, i, Level ); + LevelMax = Abc_MaxInt( LevelMax, Level ); + } + return LevelMax; +} +int Wlc_NtkCreateLevelsRev( Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; + int i, k, iFanin, Level, LevelMax = 0; + Vec_IntFill( &p->vLevels, Wlc_NtkObjNumMax(p), 0 ); + Wlc_NtkForEachObjReverse( p, pObj, i ) + { + if ( Wlc_ObjIsCi(pObj) ) + continue; + Level = Wlc_ObjLevel(p, pObj) + 1; + Wlc_ObjForEachFanin( pObj, iFanin, k ) + Vec_IntUpdateEntry( &p->vLevels, iFanin, Level ); + LevelMax = Abc_MaxInt( LevelMax, Level ); + } + // reverse the values + Wlc_NtkForEachObj( p, pObj, i ) + Vec_IntWriteEntry( &p->vLevels, i, LevelMax - Wlc_ObjLevelId(p, i) ); + Wlc_NtkForEachCi( p, pObj, i ) + Vec_IntWriteEntry( &p->vLevels, Wlc_ObjId(p, pObj), 0 ); + return LevelMax; +} + +/**Function************************************************************* + + Synopsis [Collects statistics for each side of the miter.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkCollectStats( Wlc_Ntk_t * p, int nObjs[2][WLC_OBJ_NUMBER] ) +{ + Wlc_Obj_t * pObj; + int n, i; + if ( Wlc_NtkPoNum(p) != 2 ) + return; + for ( n = 0; n < 2; n++ ) + { + Wlc_NtkMarkCone( p, n ); + Wlc_NtkForEachObj( p, pObj, i ) + if ( pObj->Mark ) + nObjs[n][pObj->Type]++; + } + Wlc_NtkCleanMarks( p ); +} + /**Function************************************************************* Synopsis [Prints distribution of operator types.] @@ -300,11 +378,13 @@ void Wlc_NtkPrintDistribSortOne( Vec_Ptr_t * vTypes, Vec_Ptr_t * vOccurs, int Ty } void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) { + int nObjs[2][WLC_OBJ_NUMBER] = {{0}}; // counter of objects of each type Wlc_Obj_t * pObj, * pObjRange = NULL; int nCountRange = 0; Vec_Ptr_t * vTypes, * vOccurs; Vec_Int_t * vAnds = Vec_IntStart( WLC_OBJ_NUMBER ); word Sign; int i, k, s, s0, s1; + Wlc_NtkCollectStats( p, nObjs ); // allocate statistics arrays vTypes = Vec_PtrStart( WLC_OBJ_NUMBER ); vOccurs = Vec_PtrStart( WLC_OBJ_NUMBER ); @@ -435,28 +515,40 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) else if ( pObj->Type == WLC_OBJ_ARI_SQUARE ) Vec_IntAddToEntry( vAnds, WLC_OBJ_ARI_SQUARE, 5 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) * Wlc_ObjRange(Wlc_ObjFanin1(p, pObj)) ); } - if ( nCountRange ) + if ( nCountRange && Vec_IntSize(&p->vNameIds) > 0 ) { printf( "Warning: %d objects of the design have non-zero-based ranges.\n", nCountRange ); printf( "In particular, object %6d with name \"%s\" has range %d=[%d:%d]\n", Wlc_ObjId(p, pObjRange), Abc_NamStr(p->pManName, Wlc_ObjNameId(p, Wlc_ObjId(p, pObjRange))), Wlc_ObjRange(pObjRange), pObjRange->End, pObjRange->Beg ); } // print by occurrence - printf( "ID : name occurrence and2 (occurrence)=. ...\n" ); + printf( "ID : name occurrence%s and2 (occurrence)=. ...\n", Wlc_NtkPoNum(p) == 2 ? " Left Share Right":"" ); for ( i = 0; i < WLC_OBJ_NUMBER; i++ ) { Vec_Wrd_t * vType = (Vec_Wrd_t *)Vec_PtrEntry( vTypes, i ); Vec_Wrd_t * vOccur = (Vec_Wrd_t *)Vec_PtrEntry( vOccurs, i ); if ( p->nObjs[i] == 0 ) continue; - printf( "%2d : %-8s %6d%8d ", i, Wlc_Names[i], p->nObjs[i], Vec_IntEntry(vAnds, i) ); + printf( "%2d : %-8s %6d", i, Wlc_Names[i], p->nObjs[i] ); + if ( Wlc_NtkPoNum(p) == 2 ) + { + printf( " " ); + printf( "%6d", nObjs[0][i] ); + printf( "%6d", nObjs[0][i]+nObjs[1][i]-p->nObjs[i] ); + printf( "%6d", nObjs[1][i] ); + } + printf( "%8d ", Vec_IntEntry(vAnds, i) ); // sort by occurence Wlc_NtkPrintDistribSortOne( vTypes, vOccurs, i ); Vec_WrdForEachEntry( vType, Sign, k ) { Wlc_NtkPrintDistribFromSign( Sign, &s, &s0, &s1 ); if ( ((k % 6) == 5 && s1) || ((k % 8) == 7 && !s1) ) + { printf( "\n " ); + if ( Wlc_NtkPoNum(p) == 2 ) + printf( " " ); + } printf( "(%d)", (int)Vec_WrdEntry( vOccur, k ) ); printf( "%s%d", Abc_LitIsCompl(s)?"-":"", Abc_Lit2Var(s) ); if ( s0 ) @@ -623,7 +715,7 @@ void Wlc_NtkDupDfs_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * v Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins ); Wlc_ObjDup( pNew, p, iObj, vFanins ); } -Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p ) +Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked ) { Wlc_Ntk_t * pNew; Wlc_Obj_t * pObj; @@ -634,11 +726,14 @@ Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p ) pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc ); pNew->fSmtLib = p->fSmtLib; Wlc_NtkForEachCi( p, pObj, i ) - Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + if ( !fMarked || pObj->Mark ) + Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); Wlc_NtkForEachCo( p, pObj, i ) - Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + if ( !fMarked || pObj->Mark ) + Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins ); Wlc_NtkForEachCo( p, pObj, i ) - Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), pObj->fIsFi ); + if ( !fMarked || pObj->Mark ) + Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), pObj->fIsFi ); if ( p->vInits ) pNew->vInits = Vec_IntDup( p->vInits ); if ( p->pInits ) @@ -666,6 +761,59 @@ void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ) pNew->vTables = p->vTables; p->vTables = NULL; } +/**Function************************************************************* + + Synopsis [Select the cone of the given output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkCleanMarks( Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; + int i; + Wlc_NtkForEachObj( p, pObj, i ) + pObj->Mark = 0; +} +void Wlc_NtkMarkCone_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFlops ) +{ + int i, iFanin; + if ( pObj->Mark ) + return; + pObj->Mark = 1; + if ( Wlc_ObjIsCi(pObj) ) + { + if ( !Wlc_ObjIsPi(pObj) ) + Vec_IntPush( vFlops, Wlc_ObjCiId(pObj) ); + return; + } + Wlc_ObjForEachFanin( pObj, iFanin, i ) + Wlc_NtkMarkCone_rec( p, Wlc_NtkObj(p, iFanin), vFlops ); +} +void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iPo ) +{ + Vec_Int_t * vFlops; + Wlc_Obj_t * pObj; + int i, CiId, CoId; + Wlc_NtkCleanMarks( p ); + Wlc_NtkForEachPi( p, pObj, i ) + pObj->Mark = 1; + vFlops = Vec_IntAlloc( 100 ); + Wlc_NtkForEachPo( p, pObj, i ) + if ( i == iPo ) + Wlc_NtkMarkCone_rec( p, pObj, vFlops ); + Vec_IntForEachEntry( vFlops, CiId, i ) + { + CoId = Wlc_NtkPoNum(p) + CiId - Wlc_NtkPiNum(p); + Wlc_NtkMarkCone_rec( p, Wlc_NtkCo(p, CoId), vFlops ); + } + Vec_IntFree( vFlops ); +} + /**Function************************************************************* Synopsis [Duplicates the network by copying each node.] diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c index fa3efacd9..2959f4a1f 100644 --- a/src/base/wlc/wlcReadVer.c +++ b/src/base/wlc/wlcReadVer.c @@ -1265,7 +1265,7 @@ Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr ) if ( !Wlc_PrsDerive( p ) ) goto finish; // derive topological order - pNtk = Wlc_NtkDupDfs( p->pNtk ); + pNtk = Wlc_NtkDupDfs( p->pNtk, 0 ); Wlc_NtkTransferNames( pNtk, p->pNtk ); pNtk->pSpec = Abc_UtilStrsav( pFileName ); finish: diff --git a/src/base/wlc/wlcShow.c b/src/base/wlc/wlcShow.c new file mode 100644 index 000000000..dd25c7a31 --- /dev/null +++ b/src/base/wlc/wlcShow.c @@ -0,0 +1,331 @@ +/**CFile**************************************************************** + + FileName [wlcShow.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Verilog parser.] + + Synopsis [Parses several flavors of word-level Verilog.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - August 22, 2014.] + + Revision [$Id: wlcShow.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wlc.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + + +/**Function************************************************************* + + Synopsis [Writes the graph structure of WLC for DOT.] + + Description [Useful for graph visualization using tools such as GraphViz: + http://www.graphviz.org/] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) +{ + FILE * pFile; + Wlc_Obj_t * pNode; + int LevelMax, Prev, Level, i; + + if ( Wlc_NtkObjNum(p) > 500 ) + { + fprintf( stdout, "Cannot visualize WLC with more than %d nodes.\n", 500 ); + return; + } + if ( (pFile = fopen( pFileName, "w" )) == NULL ) + { + fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName ); + return; + } + + // mark the nodes + if ( vBold ) + Wlc_NtkForEachObjVec( vBold, p, pNode, i ) + pNode->Mark = 1; + + // compute levels + LevelMax = 1 + Wlc_NtkCreateLevelsRev( p ); + + // write the DOT header + fprintf( pFile, "# %s\n", "WLC structure generated by ABC" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "digraph WLC {\n" ); + fprintf( pFile, "size = \"7.5,10\";\n" ); +// fprintf( pFile, "ranksep = 0.5;\n" ); +// fprintf( pFile, "nodesep = 0.5;\n" ); + fprintf( pFile, "center = true;\n" ); +// fprintf( pFile, "orientation = landscape;\n" ); +// fprintf( pFile, "edge [fontsize = 10];\n" ); +// fprintf( pFile, "edge [dir = none];\n" ); + fprintf( pFile, "edge [dir = back];\n" ); + fprintf( pFile, "\n" ); + + // labels on the left of the picture + fprintf( pFile, "{\n" ); + fprintf( pFile, " node [shape = plaintext];\n" ); + fprintf( pFile, " edge [style = invis];\n" ); + fprintf( pFile, " LevelTitle1 [label=\"\"];\n" ); + fprintf( pFile, " LevelTitle2 [label=\"\"];\n" ); + // generate node names with labels + for ( Level = LevelMax; Level >= 0; Level-- ) + { + // the visible node name + fprintf( pFile, " Level%d", Level ); + fprintf( pFile, " [label = " ); + // label name + fprintf( pFile, "\"" ); + fprintf( pFile, "\"" ); + fprintf( pFile, "];\n" ); + } + + // genetate the sequence of visible/invisible nodes to mark levels + fprintf( pFile, " LevelTitle1 -> LevelTitle2 ->" ); + for ( Level = LevelMax; Level >= 0; Level-- ) + { + // the visible node name + fprintf( pFile, " Level%d", Level ); + // the connector + if ( Level != 0 ) + fprintf( pFile, " ->" ); + else + fprintf( pFile, ";" ); + } + fprintf( pFile, "\n" ); + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate title box on top + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + fprintf( pFile, " LevelTitle1;\n" ); + fprintf( pFile, " title1 [shape=plaintext,\n" ); + fprintf( pFile, " fontsize=20,\n" ); + fprintf( pFile, " fontname = \"Times-Roman\",\n" ); + fprintf( pFile, " label=\"" ); + fprintf( pFile, "%s", "WLC structure generated by ABC" ); + fprintf( pFile, "\\n" ); + fprintf( pFile, "Benchmark \\\"%s\\\". ", p->pName ); +// fprintf( pFile, "Time was %s. ", Extra_TimeStamp() ); + fprintf( pFile, "\"\n" ); + fprintf( pFile, " ];\n" ); + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate statistics box + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + fprintf( pFile, " LevelTitle2;\n" ); + fprintf( pFile, " title2 [shape=plaintext,\n" ); + fprintf( pFile, " fontsize=18,\n" ); + fprintf( pFile, " fontname = \"Times-Roman\",\n" ); + fprintf( pFile, " label=\"" ); + fprintf( pFile, "The word-level network contains %d nodes and spans %d levels.", Wlc_NtkObjNum(p)-Wlc_NtkPiNum(p)-Wlc_NtkPoNum(p)-Wlc_NtkFfNum(p), LevelMax-1 ); + fprintf( pFile, "\\n" ); + fprintf( pFile, "\"\n" ); + fprintf( pFile, " ];\n" ); + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate the COs + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + // the labeling node of this level + fprintf( pFile, " Level%d;\n", LevelMax ); + // generate the CO nodes + Wlc_NtkForEachCo( p, pNode, i ) + { + fprintf( pFile, " NodePo%d [label = \"%s %d\"", Wlc_ObjId(p, pNode), Wlc_ObjName(p, Wlc_ObjId(p, pNode)), Wlc_ObjRange(pNode) ); + fprintf( pFile, ", shape = %s", "invtriangle" ); + fprintf( pFile, ", color = coral, fillcolor = coral" ); + fprintf( pFile, "];\n" ); + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate nodes of each rank + for ( Level = LevelMax - 1; Level > 0; Level-- ) + { + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + // the labeling node of this level + fprintf( pFile, " Level%d;\n", Level ); + Wlc_NtkForEachObj( p, pNode, i ) + { + if ( (int)Wlc_ObjLevel(p, pNode) != Level ) + continue; + + if ( pNode->Type == WLC_OBJ_CONST ) + { + fprintf( pFile, " Node%d [label = \"0x", i ); + Abc_TtPrintHexArrayRev( pFile, (word *)Wlc_ObjConstValue(pNode), (Wlc_ObjRange(pNode) + 3) / 4 ); + fprintf( pFile, "\"" ); + } + else if ( pNode->Type == WLC_OBJ_BUF || pNode->Type == WLC_OBJ_MUX ) + fprintf( pFile, " Node%d [label = \"%d\"", i, Wlc_ObjRange(pNode) ); + else if ( pNode->Type >= WLC_OBJ_LOGIC_NOT && pNode->Type <= WLC_OBJ_COMP_MOREEQU ) + fprintf( pFile, " Node%d [label = \"%s\"", i, Wlc_ObjTypeName(pNode) ); + else + fprintf( pFile, " Node%d [label = \"%s %d\"", i, Wlc_ObjTypeName(pNode), Wlc_ObjRange(pNode) ); + + if ( pNode->Type == WLC_OBJ_ARI_MULTI ) + fprintf( pFile, ", shape = doublecircle" ); + else if ( pNode->Type >= WLC_OBJ_COMP_EQU && pNode->Type <= WLC_OBJ_COMP_MOREEQU ) + fprintf( pFile, ", shape = diamond" ); + else if ( pNode->Type == WLC_OBJ_BIT_SELECT || pNode->Type == WLC_OBJ_BIT_CONCAT ) + fprintf( pFile, ", shape = box" ); + else if ( pNode->Type == WLC_OBJ_BUF || pNode->Type == WLC_OBJ_BIT_ZEROPAD || pNode->Type == WLC_OBJ_BIT_SIGNEXT ) + fprintf( pFile, ", shape = triangle" ); + else if ( pNode->Type == WLC_OBJ_MUX ) + fprintf( pFile, ", shape = trapezium" ); + else + fprintf( pFile, ", shape = ellipse" ); + + if ( vBold ? pNode->Mark : ((pNode->Type >= WLC_OBJ_ARI_ADD && pNode->Type <= WLC_OBJ_ARI_SQUARE) || pNode->Type == WLC_OBJ_BIT_NOT) ) + fprintf( pFile, ", style = filled" ); + fprintf( pFile, "];\n" ); + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + } + + // generate the CI nodes + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + // the labeling node of this level + fprintf( pFile, " Level%d;\n", 0 ); + // generate the CI nodes + Wlc_NtkForEachCi( p, pNode, i ) + { + fprintf( pFile, " Node%d [label = \"%s %d\"", Wlc_ObjId(p, pNode), Wlc_ObjName(p, Wlc_ObjId(p, pNode)), Wlc_ObjRange(pNode) ); + fprintf( pFile, ", shape = %s", "triangle" ); + fprintf( pFile, ", color = coral, fillcolor = coral" ); + fprintf( pFile, "];\n" ); + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate invisible edges from the square down + fprintf( pFile, "title1 -> title2 [style = invis];\n" ); + Wlc_NtkForEachCo( p, pNode, i ) + fprintf( pFile, "title2 -> NodePo%d [style = invis];\n", Wlc_ObjId(p, pNode) ); + // generate invisible edges among the COs + Prev = -1; + Wlc_NtkForEachCo( p, pNode, i ) + { + if ( i > 0 ) + fprintf( pFile, "NodePo%d -> NodePo%d [style = invis];\n", Prev, Wlc_ObjId(p, pNode) ); + Prev = Wlc_ObjId(p, pNode); + } + // generate invisible edges among the CIs + Prev = -1; + Wlc_NtkForEachCi( p, pNode, i ) + { + if ( i > 0 ) + fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Wlc_ObjId(p, pNode) ); + Prev = Wlc_ObjId(p, pNode); + } + + // generate edges + Wlc_NtkForEachObj( p, pNode, i ) + { + int k, iFanin; + if ( Wlc_ObjIsCi(pNode) ) + continue; + if ( Wlc_ObjIsCo(pNode) ) + { + // generate the edge from this node to the next + fprintf( pFile, "NodePo%d", i ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", i ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", pNode->Signed? "dotted" : "bold" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + } + // generate the edge from this node to the next + Wlc_ObjForEachFanin( pNode, iFanin, k ) + { + fprintf( pFile, "Node%d", i ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", iFanin ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", Wlc_NtkObj(p, iFanin)->Signed? "dotted" : "bold" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + } + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + fclose( pFile ); + + // unmark nodes + if ( vBold ) + Wlc_NtkCleanMarks( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkShow( Wlc_Ntk_t * p, Vec_Int_t * vBold ) +{ + extern void Abc_ShowFile( char * FileNameDot ); + FILE * pFile; + char FileNameDot[200]; + sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(p->pName, ".dot") ); + // check that the file can be opened + if ( (pFile = fopen( FileNameDot, "w" )) == NULL ) + { + fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", FileNameDot ); + return; + } + fclose( pFile ); + // generate the file + Wlc_NtkDumpDot( p, FileNameDot, vBold ); + // visualize the file + Abc_ShowFile( FileNameDot ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + From 64d7119ddc7fb1720542b8071f490763466a5d31 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 26 Jan 2017 21:43:28 -0800 Subject: [PATCH 079/185] Adding visualization of word-level networks Wlc_Ntk_t. --- abcexe.dsp | 4 - src/base/wlc/wlc.h | 13 ++- src/base/wlc/wlcAbs.c | 6 +- src/base/wlc/wlcCom.c | 152 ++++++++++++++++++------- src/base/wlc/wlcNtk.c | 226 ++++++++++++++++++++++++++++++------- src/base/wlc/wlcReadVer.c | 5 +- src/base/wlc/wlcShow.c | 38 ++++--- src/base/wlc/wlcWriteVer.c | 2 +- 8 files changed, 329 insertions(+), 117 deletions(-) diff --git a/abcexe.dsp b/abcexe.dsp index 9ef992c07..9d5152fc2 100644 --- a/abcexe.dsp +++ b/abcexe.dsp @@ -88,10 +88,6 @@ LINK32=link.exe # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File -SOURCE=.\src\proof\acec\acecTree.c -# End Source File -# Begin Source File - SOURCE=.\src\base\main\main.c # End Source File # End Group diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index e4a818e56..b898078f2 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -221,7 +221,8 @@ static inline int Wlc_NtkHasNameId( Wlc_Ntk_t * p ) static inline void Wlc_ObjSetNameId( Wlc_Ntk_t * p, int iObj, int i ) { Vec_IntWriteEntry( &p->vNameIds, iObj, i ); } static inline int Wlc_ObjNameId( Wlc_Ntk_t * p, int iObj ) { return Vec_IntEntry( &p->vNameIds, iObj ); } -static inline Wlc_Obj_t * Wlc_ObjFoToFi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { assert( pObj->Type == WLC_OBJ_FO ); return Wlc_NtkCo(p, Wlc_NtkCoNum(p) - Wlc_NtkCiNum(p) + Wlc_ObjCiId(pObj)); } +static inline Wlc_Obj_t * Wlc_ObjFo2Fi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { assert( pObj->Type == WLC_OBJ_FO ); return Wlc_NtkCo(p, Wlc_NtkPoNum(p) + Wlc_ObjCiId(pObj) - Wlc_NtkPiNum(p)); } +static inline Wlc_Obj_t * Wlc_ObjCo2PoFo( Wlc_Ntk_t * p, int iCoId ) { return iCoId < Wlc_NtkPoNum(p) ? Wlc_NtkPo(p, iCoId) : Wlc_NtkCi(p, Wlc_NtkPiNum(p) + iCoId - Wlc_NtkPoNum(p)); } //////////////////////////////////////////////////////////////////////// /// MACRO DEFINITIONS /// @@ -283,15 +284,19 @@ extern void Wlc_ObjAddFanins( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int extern void Wlc_NtkFree( Wlc_Ntk_t * p ); extern int Wlc_NtkCreateLevels( Wlc_Ntk_t * p ); extern int Wlc_NtkCreateLevelsRev( Wlc_Ntk_t * p ); +extern int Wlc_NtkCountRealPis( Wlc_Ntk_t * p ); extern void Wlc_NtkPrintNode( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ); extern void Wlc_NtkPrintNodeArray( Wlc_Ntk_t * p, Vec_Int_t * vArray ); extern void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type ); -extern void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose ); -extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked ); +extern void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fTwoSides, int fVerbose ); extern void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ); +extern char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq ); +extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ); extern void Wlc_NtkCleanMarks( Wlc_Ntk_t * p ); -extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iPo ); +extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int fSeq ); +extern void Wlc_NtkProfileCones( Wlc_Ntk_t * p ); extern Wlc_Ntk_t * Wlc_NtkDupSingleNodes( Wlc_Ntk_t * p ); +extern void Wlc_NtkShortNames( Wlc_Ntk_t * p ); /*=== wlcReadSmt.c ========================================================*/ extern Wlc_Ntk_t * Wlc_ReadSmtBuffer( char * pFileName, char * pBuffer, char * pLimit, int fOldParser, int fPrintTree ); extern Wlc_Ntk_t * Wlc_ReadSmt( char * pFileName, int fOldParser, int fPrintTree ); diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 368652d6c..ce6b8de91 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -173,8 +173,7 @@ Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit ) if ( vNodes != vNodesInit ) Vec_IntFree( vNodes ); // reconstruct topological order - pNew = Wlc_NtkDupDfs( p, 0 ); - Wlc_NtkTransferNames( pNew, p ); + pNew = Wlc_NtkDupDfs( p, 0, 1 ); return pNew; } @@ -278,8 +277,7 @@ Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * p, Vec_Int_t * vPairsInit ) if ( vPairs != vPairsInit ) Vec_IntFree( vPairs ); // reconstruct topological order - pNew = Wlc_NtkDupDfs( p, 0 ); - Wlc_NtkTransferNames( pNew, p ); + pNew = Wlc_NtkDupDfs( p, 0, 1 ); return pNew; } diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 316d28835..9f36ad566 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -28,21 +28,22 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static int Abc_CommandReadWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandShow ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandReadWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandShortNames ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandShow ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandInvPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandInvPrint ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandInvCheck ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandInvGet ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandInvPut ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandInvMin ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvPrint ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvCheck ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvGet ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvPut ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvMin ( Abc_Frame_t * pAbc, int argc, char ** argv ); static inline Wlc_Ntk_t * Wlc_AbcGetNtk( Abc_Frame_t * pAbc ) { return (Wlc_Ntk_t *)pAbc->pAbcWlc; } static inline void Wlc_AbcFreeNtk( Abc_Frame_t * pAbc ) { if ( pAbc->pAbcWlc ) Wlc_NtkFree(Wlc_AbcGetNtk(pAbc)); } @@ -67,21 +68,22 @@ static inline Vec_Int_t * Wlc_AbcGetInv( Abc_Frame_t * pAbc ) ******************************************************************************/ void Wlc_Init( Abc_Frame_t * pAbc ) { - Cmd_CommandAdd( pAbc, "Word level", "%read", Abc_CommandReadWlc, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%write", Abc_CommandWriteWlc, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%cone", Abc_CommandCone, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%show", Abc_CommandShow, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%test", Abc_CommandTest, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%read", Abc_CommandReadWlc, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%write", Abc_CommandWriteWlc, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%cone", Abc_CommandCone, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%short_names", Abc_CommandShortNames, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%show", Abc_CommandShow, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%test", Abc_CommandTest, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "inv_ps", Abc_CommandInvPs, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "inv_print", Abc_CommandInvPrint, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "inv_check", Abc_CommandInvCheck, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "inv_get", Abc_CommandInvGet, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "inv_put", Abc_CommandInvPut, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "inv_min", Abc_CommandInvMin, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_ps", Abc_CommandInvPs, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_print", Abc_CommandInvPrint, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_check", Abc_CommandInvCheck, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_get", Abc_CommandInvGet, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_put", Abc_CommandInvPut, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_min", Abc_CommandInvMin, 0 ); } /**Function******************************************************************** @@ -287,15 +289,20 @@ usage: int Abc_CommandPs( Abc_Frame_t * pAbc, int argc, char ** argv ) { Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + int fShowCones = 0; int fShowMulti = 0; int fShowAdder = 0; int fDistrib = 0; + int fTwoSides = 0; int c, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "madvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "cmadtvh" ) ) != EOF ) { switch ( c ) { + case 'c': + fShowCones ^= 1; + break; case 'm': fShowMulti ^= 1; break; @@ -305,6 +312,9 @@ int Abc_CommandPs( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'd': fDistrib ^= 1; break; + case 't': + fTwoSides ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -319,19 +329,23 @@ int Abc_CommandPs( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandPs(): There is no current design.\n" ); return 0; } - Wlc_NtkPrintStats( pNtk, fDistrib, fVerbose ); + Wlc_NtkPrintStats( pNtk, fDistrib, fTwoSides, fVerbose ); + if ( fShowCones ) + Wlc_NtkProfileCones( pNtk ); if ( fShowMulti ) Wlc_NtkPrintNodes( pNtk, WLC_OBJ_ARI_MULTI ); if ( fShowAdder ) Wlc_NtkPrintNodes( pNtk, WLC_OBJ_ARI_ADD ); return 0; usage: - Abc_Print( -2, "usage: %%ps [-madvh]\n" ); + Abc_Print( -2, "usage: %%ps [-cmadtvh]\n" ); Abc_Print( -2, "\t prints statistics\n" ); - Abc_Print( -2, "\t-m : toggle printing multipliers [default = %s]\n", fShowMulti? "yes": "no" ); - Abc_Print( -2, "\t-a : toggle printing adders [default = %s]\n", fShowAdder? "yes": "no" ); - Abc_Print( -2, "\t-d : toggle printing distrubition [default = %s]\n", fDistrib? "yes": "no" ); - Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-c : toggle printing cones [default = %s]\n", fShowCones? "yes": "no" ); + Abc_Print( -2, "\t-m : toggle printing multipliers [default = %s]\n", fShowMulti? "yes": "no" ); + Abc_Print( -2, "\t-a : toggle printing adders [default = %s]\n", fShowAdder? "yes": "no" ); + Abc_Print( -2, "\t-d : toggle printing distrubition [default = %s]\n", fDistrib? "yes": "no" ); + Abc_Print( -2, "\t-t : toggle printing stats for LHS and RHS [default = %s]\n", fTwoSides? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } @@ -350,9 +364,10 @@ usage: int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) { Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); - int c, iOutput = -1, fVerbose = 0; + int c, iOutput = -1, fSeq = 0, fVerbose = 0; + char * pName; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Ovh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "Osvh" ) ) != EOF ) { switch ( c ) { @@ -367,6 +382,9 @@ int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( iOutput < 0 ) goto usage; break; + case 's': + fSeq ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -381,20 +399,24 @@ int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" ); return 0; } - if ( iOutput < 0 || iOutput >= Wlc_NtkPoNum(pNtk) ) + if ( iOutput < 0 || iOutput >= Wlc_NtkCoNum(pNtk) ) { - Abc_Print( 1, "Abc_CommandCone(): Illegal output index (%d) (should be 0 <= num < %d).\n", iOutput, Wlc_NtkPoNum(pNtk) ); + Abc_Print( 1, "Abc_CommandCone(): Illegal output index (%d) (should be 0 <= num < %d).\n", iOutput, Wlc_NtkCoNum(pNtk) ); return 0; } - printf( "Extracting output %d.\n", iOutput ); - Wlc_NtkMarkCone( pNtk, iOutput ); - pNtk = Wlc_NtkDupDfs( pNtk, 1 ); + printf( "Extracting output %d as a %s word-level network.\n", iOutput, fSeq ? "sequential" : "combinational" ); + pName = Wlc_NtkNewName( pNtk, iOutput, fSeq ); + Wlc_NtkMarkCone( pNtk, iOutput, fSeq ); + pNtk = Wlc_NtkDupDfs( pNtk, 1, fSeq ); + ABC_FREE( pNtk->pName ); + pNtk->pName = Abc_UtilStrsav( pName ); Wlc_AbcUpdateNtk( pAbc, pNtk ); return 0; usage: - Abc_Print( -2, "usage: %%cone [-O num] [-vh]\n" ); + Abc_Print( -2, "usage: %%cone [-O num] [-svh]\n" ); Abc_Print( -2, "\t extracts cone of the given word-level output\n" ); Abc_Print( -2, "\t-O num : zero-based index of the word-level output to extract [default = %d]\n", iOutput ); + Abc_Print( -2, "\t-s : toggle performing extracting sequential cones [default = %s]\n", fSeq? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; @@ -549,6 +571,50 @@ usage: return 1; } +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandShortNames( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandProfile(): There is no current design.\n" ); + return 0; + } + Wlc_NtkShortNames( pNtk ); + return 0; +usage: + Abc_Print( -2, "usage: %%short_names [-vh]\n" ); + Abc_Print( -2, "\t derives short names for all objects of the network\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* Synopsis [] diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index fa0074d3f..822c2eb54 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -314,13 +314,23 @@ void Wlc_NtkCollectStats( Wlc_Ntk_t * p, int nObjs[2][WLC_OBJ_NUMBER] ) return; for ( n = 0; n < 2; n++ ) { - Wlc_NtkMarkCone( p, n ); + Wlc_NtkMarkCone( p, n, 1 ); Wlc_NtkForEachObj( p, pObj, i ) if ( pObj->Mark ) nObjs[n][pObj->Type]++; } Wlc_NtkCleanMarks( p ); } +int Wlc_NtkCountRealPis( Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; + int i, Count = 0; + Wlc_NtkMarkCone( p, -1, 1 ); + Wlc_NtkForEachPi( p, pObj, i ) + Count += pObj->Mark; + Wlc_NtkCleanMarks( p ); + return Count; +} /**Function************************************************************* @@ -376,7 +386,7 @@ void Wlc_NtkPrintDistribSortOne( Vec_Ptr_t * vTypes, Vec_Ptr_t * vOccurs, int Ty Vec_WrdReverseOrder( vType ); Vec_WrdReverseOrder( vOccur ); } -void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) +void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fTwoSides, int fVerbose ) { int nObjs[2][WLC_OBJ_NUMBER] = {{0}}; // counter of objects of each type Wlc_Obj_t * pObj, * pObjRange = NULL; int nCountRange = 0; @@ -384,7 +394,10 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) Vec_Int_t * vAnds = Vec_IntStart( WLC_OBJ_NUMBER ); word Sign; int i, k, s, s0, s1; - Wlc_NtkCollectStats( p, nObjs ); + if ( Wlc_NtkPoNum(p) != 2 ) + fTwoSides = 0; + if ( fTwoSides ) + Wlc_NtkCollectStats( p, nObjs ); // allocate statistics arrays vTypes = Vec_PtrStart( WLC_OBJ_NUMBER ); vOccurs = Vec_PtrStart( WLC_OBJ_NUMBER ); @@ -489,11 +502,11 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) else if ( pObj->Type == WLC_OBJ_REDUCT_XOR ) Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_XOR, 3 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 3 ); else if ( pObj->Type == WLC_OBJ_REDUCT_NAND ) - Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NAND, Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 ); + Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NAND, Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 ); else if ( pObj->Type == WLC_OBJ_REDUCT_NOR ) - Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NOR, Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 ); + Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NOR, Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 ); else if ( pObj->Type == WLC_OBJ_REDUCT_NXOR ) - Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NXOR, 3 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 3 ); + Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NXOR, 3 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 3 ); else if ( pObj->Type == WLC_OBJ_ARI_ADD ) Vec_IntAddToEntry( vAnds, WLC_OBJ_ARI_ADD, 9 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) ); else if ( pObj->Type == WLC_OBJ_ARI_SUB ) @@ -522,7 +535,7 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) Abc_NamStr(p->pManName, Wlc_ObjNameId(p, Wlc_ObjId(p, pObjRange))), Wlc_ObjRange(pObjRange), pObjRange->End, pObjRange->Beg ); } // print by occurrence - printf( "ID : name occurrence%s and2 (occurrence)=. ...\n", Wlc_NtkPoNum(p) == 2 ? " Left Share Right":"" ); + printf( "ID : name occurrence%s and2 (occurrence)=. ...\n", fTwoSides ? " Left Share Right":"" ); for ( i = 0; i < WLC_OBJ_NUMBER; i++ ) { Vec_Wrd_t * vType = (Vec_Wrd_t *)Vec_PtrEntry( vTypes, i ); @@ -530,11 +543,12 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) if ( p->nObjs[i] == 0 ) continue; printf( "%2d : %-8s %6d", i, Wlc_Names[i], p->nObjs[i] ); - if ( Wlc_NtkPoNum(p) == 2 ) + if ( fTwoSides ) { + int nTotal = i == WLC_OBJ_PI ? Wlc_NtkCountRealPis(p) : p->nObjs[i]; printf( " " ); printf( "%6d", nObjs[0][i] ); - printf( "%6d", nObjs[0][i]+nObjs[1][i]-p->nObjs[i] ); + printf( "%6d", nObjs[0][i]+nObjs[1][i]-nTotal ); printf( "%6d", nObjs[1][i] ); } printf( "%8d ", Vec_IntEntry(vAnds, i) ); @@ -546,7 +560,7 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) if ( ((k % 6) == 5 && s1) || ((k % 8) == 7 && !s1) ) { printf( "\n " ); - if ( Wlc_NtkPoNum(p) == 2 ) + if ( fTwoSides ) printf( " " ); } printf( "(%d)", (int)Vec_WrdEntry( vOccur, k ) ); @@ -627,11 +641,11 @@ void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type ) Wlc_NtkPrintNode( p, pObj ); } } -void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose ) +void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fTwoSides, int fVerbose ) { int i; printf( "%-20s : ", p->pName ); - printf( "PI = %4d ", Wlc_NtkPiNum(p) ); + printf( "PI = %4d ", Wlc_NtkCountRealPis(p) ); //Wlc_NtkPiNum(p) ); printf( "PO = %4d ", Wlc_NtkPoNum(p) ); printf( "FF = %4d ", Wlc_NtkFfNum(p) ); printf( "Obj = %6d ", Wlc_NtkObjNum(p) ); @@ -639,7 +653,7 @@ void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose ) printf( "\n" ); if ( fDistrib ) { - Wlc_NtkPrintDistrib( p, fVerbose ); + Wlc_NtkPrintDistrib( p, fTwoSides, fVerbose ); return; } if ( !fVerbose ) @@ -656,6 +670,41 @@ void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose ) } } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ) +{ + int i; + assert( !Wlc_NtkHasCopy(pNew) && Wlc_NtkHasCopy(p) ); + assert( !Wlc_NtkHasNameId(pNew) && Wlc_NtkHasNameId(p) ); + assert( pNew->pManName == NULL && p->pManName != NULL ); + Wlc_NtkCleanNameId( pNew ); + for ( i = 0; i < p->nObjsAlloc; i++ ) + if ( Wlc_ObjCopy(p, i) && i < Vec_IntSize(&p->vNameIds) && Wlc_ObjNameId(p, i) ) + Wlc_ObjSetNameId( pNew, Wlc_ObjCopy(p, i), Wlc_ObjNameId(p, i) ); + pNew->pManName = p->pManName; + p->pManName = NULL; + Vec_IntErase( &p->vNameIds ); + // transfer table + pNew->pMemTable = p->pMemTable; p->pMemTable = NULL; + pNew->vTables = p->vTables; p->vTables = NULL; +} +char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq ) +{ + static char pBuffer[1000]; + sprintf( pBuffer, "%s_o%d_%s", p->pName, iCoId, fSeq ? "seq": "comb" ); + return pBuffer; +} + /**Function************************************************************* Synopsis [Duplicates the network in a topological order.] @@ -715,51 +764,43 @@ void Wlc_NtkDupDfs_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * v Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins ); Wlc_ObjDup( pNew, p, iObj, vFanins ); } -Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked ) +Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ) { Wlc_Ntk_t * pNew; Wlc_Obj_t * pObj; Vec_Int_t * vFanins; int i; - Wlc_NtkCleanCopy( p ); vFanins = Vec_IntAlloc( 100 ); + Wlc_NtkCleanCopy( p ); pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc ); pNew->fSmtLib = p->fSmtLib; Wlc_NtkForEachCi( p, pObj, i ) if ( !fMarked || pObj->Mark ) + { + unsigned Type = pObj->Type; + if ( !fSeq ) pObj->Type = WLC_OBJ_PI; Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + pObj->Type = Type; + } Wlc_NtkForEachCo( p, pObj, i ) if ( !fMarked || pObj->Mark ) Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins ); Wlc_NtkForEachCo( p, pObj, i ) if ( !fMarked || pObj->Mark ) - Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), pObj->fIsFi ); - if ( p->vInits ) - pNew->vInits = Vec_IntDup( p->vInits ); - if ( p->pInits ) - pNew->pInits = Abc_UtilStrsav( p->pInits ); + Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), fSeq ? pObj->fIsFi : 0 ); Vec_IntFree( vFanins ); + if ( !fMarked ) + { + if ( p->vInits ) + pNew->vInits = Vec_IntDup( p->vInits ); + if ( p->pInits ) + pNew->pInits = Abc_UtilStrsav( p->pInits ); + } if ( p->pSpec ) pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Wlc_NtkTransferNames( pNew, p ); return pNew; } -void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ) -{ - int i; - assert( !Wlc_NtkHasCopy(pNew) && Wlc_NtkHasCopy(p) ); - assert( !Wlc_NtkHasNameId(pNew) && Wlc_NtkHasNameId(p) ); - assert( pNew->pManName == NULL && p->pManName != NULL ); - Wlc_NtkCleanNameId( pNew ); - for ( i = 0; i < p->nObjsAlloc; i++ ) - if ( Wlc_ObjCopy(p, i) && i < Vec_IntSize(&p->vNameIds) && Wlc_ObjNameId(p, i) ) - Wlc_ObjSetNameId( pNew, Wlc_ObjCopy(p, i), Wlc_ObjNameId(p, i) ); - pNew->pManName = p->pManName; - p->pManName = NULL; - Vec_IntErase( &p->vNameIds ); - // transfer table - pNew->pMemTable = p->pMemTable; p->pMemTable = NULL; - pNew->vTables = p->vTables; p->vTables = NULL; -} /**Function************************************************************* @@ -779,6 +820,30 @@ void Wlc_NtkCleanMarks( Wlc_Ntk_t * p ) Wlc_NtkForEachObj( p, pObj, i ) pObj->Mark = 0; } +int Wlc_NtkCountMarked( Wlc_Ntk_t * p, int * pnPis, int * pnFos, int * pnAdders, int * pnMults ) +{ + Wlc_Obj_t * pObj; + int i, nNodes = 0; + *pnPis = *pnFos = *pnAdders = *pnMults = 0; + Wlc_NtkForEachObj( p, pObj, i ) + { + if ( !pObj->Mark ) + continue; + if ( Wlc_ObjIsPi(pObj) ) + (*pnPis)++; + else if ( Wlc_ObjIsCi(pObj) ) + (*pnFos)++; + else if ( pObj->Mark ) + { + nNodes++; + if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB ) + (*pnAdders)++; + else if ( pObj->Type == WLC_OBJ_ARI_MULTI ) + (*pnMults)++; + } + } + return nNodes; +} void Wlc_NtkMarkCone_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFlops ) { int i, iFanin; @@ -794,18 +859,19 @@ void Wlc_NtkMarkCone_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFlops ) Wlc_ObjForEachFanin( pObj, iFanin, i ) Wlc_NtkMarkCone_rec( p, Wlc_NtkObj(p, iFanin), vFlops ); } -void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iPo ) +void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int fSeq ) { Vec_Int_t * vFlops; Wlc_Obj_t * pObj; int i, CiId, CoId; Wlc_NtkCleanMarks( p ); - Wlc_NtkForEachPi( p, pObj, i ) - pObj->Mark = 1; +// Wlc_NtkForEachPi( p, pObj, i ) +// pObj->Mark = 1; vFlops = Vec_IntAlloc( 100 ); - Wlc_NtkForEachPo( p, pObj, i ) - if ( i == iPo ) + Wlc_NtkForEachCo( p, pObj, i ) + if ( iCoId == -1 || i == iCoId ) Wlc_NtkMarkCone_rec( p, pObj, vFlops ); + if ( fSeq ) Vec_IntForEachEntry( vFlops, CiId, i ) { CoId = Wlc_NtkPoNum(p) + CiId - Wlc_NtkPiNum(p); @@ -813,6 +879,24 @@ void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iPo ) } Vec_IntFree( vFlops ); } +void Wlc_NtkProfileCones( Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; + int i, nPis, nFos, nNodes, nAdders, nMults; + Wlc_NtkForEachCo( p, pObj, i ) + { + Wlc_NtkMarkCone( p, i, 0 ); + nNodes = Wlc_NtkCountMarked( p, &nPis, &nFos, &nAdders, &nMults ); + printf( "Cone %5d : ", i ); + printf( "PI = %4d ", nPis ); + printf( "FO = %4d ", nFos ); + printf( "Node = %6d ", nNodes ); + printf( "Add/Sub = %4d ", nAdders ); + printf( "Mult = %4d ", nMults ); + printf( "\n" ); + } + Wlc_NtkCleanMarks( p ); +} /**Function************************************************************* @@ -871,6 +955,64 @@ Wlc_Ntk_t * Wlc_NtkDupSingleNodes( Wlc_Ntk_t * p ) return pNew; } +/**Function************************************************************* + + Synopsis [Creates short names for all objects.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkShortNames( Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; + char pBuffer[100]; + int nDigits, NameId, fFound, i; + int nFlops = Wlc_NtkCoNum(p) - Wlc_NtkPoNum(p); + nDigits = Abc_Base10Log( nFlops ); + Wlc_NtkForEachCo( p, pObj, i ) + { + if ( Wlc_ObjIsPo(pObj) ) + continue; + sprintf( pBuffer, "%s%0*d", "fi", nDigits, i - Wlc_NtkPoNum(p) ); + NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound ); + Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId ); + } + Wlc_NtkForEachCi( p, pObj, i ) + { + if ( Wlc_ObjIsPi(pObj) ) + continue; + sprintf( pBuffer, "%s%0*d", "fo", nDigits, i - Wlc_NtkPiNum(p) ); + NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound ); + Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId ); + } + nDigits = Abc_Base10Log( Wlc_NtkPoNum(p) ); + Wlc_NtkForEachPo( p, pObj, i ) + { + sprintf( pBuffer, "%s%0*d", "po", nDigits, i ); + NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound ); + Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId ); + } + nDigits = Abc_Base10Log( Wlc_NtkPiNum(p) ); + Wlc_NtkForEachPi( p, pObj, i ) + { + sprintf( pBuffer, "%s%0*d", "pi", nDigits, i ); + NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound ); + Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId ); + } + nDigits = Abc_Base10Log( Wlc_NtkObjNum(p) ); + Wlc_NtkForEachObj( p, pObj, i ) + { + if ( Wlc_ObjIsCi(pObj) || Wlc_ObjIsCo(pObj) ) + continue; + sprintf( pBuffer, "%s%0*d", "n", nDigits, i ); + NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound ); + Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId ); + } +} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c index 2959f4a1f..e4a65ecfb 100644 --- a/src/base/wlc/wlcReadVer.c +++ b/src/base/wlc/wlcReadVer.c @@ -28,7 +28,7 @@ ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// // Word-level Verilog file parser -#define WLV_PRS_MAX_LINE 1000 +#define WLV_PRS_MAX_LINE 10000 typedef struct Wlc_Prs_t_ Wlc_Prs_t; struct Wlc_Prs_t_ @@ -1265,8 +1265,7 @@ Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr ) if ( !Wlc_PrsDerive( p ) ) goto finish; // derive topological order - pNtk = Wlc_NtkDupDfs( p->pNtk, 0 ); - Wlc_NtkTransferNames( pNtk, p->pNtk ); + pNtk = Wlc_NtkDupDfs( p->pNtk, 0, 1 ); pNtk->pSpec = Abc_UtilStrsav( pFileName ); finish: Wlc_PrsPrintErrorMessage( p ); diff --git a/src/base/wlc/wlcShow.c b/src/base/wlc/wlcShow.c index dd25c7a31..8ef21d298 100644 --- a/src/base/wlc/wlcShow.c +++ b/src/base/wlc/wlcShow.c @@ -143,7 +143,7 @@ void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) fprintf( pFile, " fontsize=18,\n" ); fprintf( pFile, " fontname = \"Times-Roman\",\n" ); fprintf( pFile, " label=\"" ); - fprintf( pFile, "The word-level network contains %d nodes and spans %d levels.", Wlc_NtkObjNum(p)-Wlc_NtkPiNum(p)-Wlc_NtkPoNum(p)-Wlc_NtkFfNum(p), LevelMax-1 ); + fprintf( pFile, "The word-level network contains %d nodes and spans %d levels.", Wlc_NtkObjNum(p)-Wlc_NtkCiNum(p), LevelMax-1 ); fprintf( pFile, "\\n" ); fprintf( pFile, "\"\n" ); fprintf( pFile, " ];\n" ); @@ -159,8 +159,9 @@ void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) // generate the CO nodes Wlc_NtkForEachCo( p, pNode, i ) { - fprintf( pFile, " NodePo%d [label = \"%s %d\"", Wlc_ObjId(p, pNode), Wlc_ObjName(p, Wlc_ObjId(p, pNode)), Wlc_ObjRange(pNode) ); - fprintf( pFile, ", shape = %s", "invtriangle" ); + pNode = Wlc_ObjCo2PoFo(p, i); + fprintf( pFile, " NodePo%d [label = \"%s_in %d\"", Wlc_ObjId(p, pNode), Wlc_ObjName(p, Wlc_ObjId(p, pNode)), Wlc_ObjRange(pNode) ); + fprintf( pFile, ", shape = %s", i < Wlc_NtkPoNum(p) ? "invtriangle" : "box" ); fprintf( pFile, ", color = coral, fillcolor = coral" ); fprintf( pFile, "];\n" ); } @@ -224,7 +225,7 @@ void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) Wlc_NtkForEachCi( p, pNode, i ) { fprintf( pFile, " Node%d [label = \"%s %d\"", Wlc_ObjId(p, pNode), Wlc_ObjName(p, Wlc_ObjId(p, pNode)), Wlc_ObjRange(pNode) ); - fprintf( pFile, ", shape = %s", "triangle" ); + fprintf( pFile, ", shape = %s", i < Wlc_NtkPiNum(p) ? "triangle" : "box" ); fprintf( pFile, ", color = coral, fillcolor = coral" ); fprintf( pFile, "];\n" ); } @@ -235,11 +236,15 @@ void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) // generate invisible edges from the square down fprintf( pFile, "title1 -> title2 [style = invis];\n" ); Wlc_NtkForEachCo( p, pNode, i ) + { + pNode = Wlc_ObjCo2PoFo( p, i ); fprintf( pFile, "title2 -> NodePo%d [style = invis];\n", Wlc_ObjId(p, pNode) ); + } // generate invisible edges among the COs Prev = -1; Wlc_NtkForEachCo( p, pNode, i ) { + pNode = Wlc_ObjCo2PoFo( p, i ); if ( i > 0 ) fprintf( pFile, "NodePo%d -> NodePo%d [style = invis];\n", Prev, Wlc_ObjId(p, pNode) ); Prev = Wlc_ObjId(p, pNode); @@ -254,22 +259,21 @@ void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) } // generate edges + Wlc_NtkForEachCo( p, pNode, i ) + { + fprintf( pFile, "NodePo%d", Wlc_ObjId(p, Wlc_ObjCo2PoFo(p, i)) ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", Wlc_ObjId(p, pNode) ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", pNode->Signed? "dotted" : "solid" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + } Wlc_NtkForEachObj( p, pNode, i ) { int k, iFanin; if ( Wlc_ObjIsCi(pNode) ) continue; - if ( Wlc_ObjIsCo(pNode) ) - { - // generate the edge from this node to the next - fprintf( pFile, "NodePo%d", i ); - fprintf( pFile, " -> " ); - fprintf( pFile, "Node%d", i ); - fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", pNode->Signed? "dotted" : "bold" ); - fprintf( pFile, "]" ); - fprintf( pFile, ";\n" ); - } // generate the edge from this node to the next Wlc_ObjForEachFanin( pNode, iFanin, k ) { @@ -277,7 +281,9 @@ void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", iFanin ); fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", Wlc_NtkObj(p, iFanin)->Signed? "dotted" : "bold" ); + fprintf( pFile, "style = %s", Wlc_NtkObj(p, iFanin)->Signed? "dotted" : "solid" ); + if ( pNode->Type == WLC_OBJ_MUX && k == 0 ) + fprintf( pFile, ", style = %s", "bold" ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); } diff --git a/src/base/wlc/wlcWriteVer.c b/src/base/wlc/wlcWriteVer.c index cf0e528f6..c4dee094b 100644 --- a/src/base/wlc/wlcWriteVer.c +++ b/src/base/wlc/wlcWriteVer.c @@ -409,7 +409,7 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops ) fprintf( pFile, " reg%d (", i ); fprintf( pFile, " .q( %s ),", Wlc_ObjName(p, Wlc_ObjId(p, pObj)) ); fprintf( pFile, " .qbar()," ); - fprintf( pFile, " .d( %s ),", Wlc_ObjName(p, Wlc_ObjId(p, Wlc_ObjFoToFi(p, pObj))) ); + fprintf( pFile, " .d( %s ),", Wlc_ObjName(p, Wlc_ObjId(p, Wlc_ObjFo2Fi(p, pObj))) ); fprintf( pFile, " .clk( %s ),", "1\'b0" ); fprintf( pFile, " .arst( %s ),", "1\'b0" ); if ( p->vInits ) From c2b805dc85fa3c6e96cac04fa1d8ea182e9aab62 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 26 Jan 2017 22:22:22 -0800 Subject: [PATCH 080/185] Adding visualization of word-level networks Wlc_Ntk_t. --- src/base/wlc/wlc.h | 2 +- src/base/wlc/wlcCom.c | 28 ++++++++++++++++++++++------ src/base/wlc/wlcNtk.c | 15 ++++++++------- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index b898078f2..d51b699c0 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -293,7 +293,7 @@ extern void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ); extern char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq ); extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ); extern void Wlc_NtkCleanMarks( Wlc_Ntk_t * p ); -extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int fSeq ); +extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int Range, int fSeq, int fAllPis ); extern void Wlc_NtkProfileCones( Wlc_Ntk_t * p ); extern Wlc_Ntk_t * Wlc_NtkDupSingleNodes( Wlc_Ntk_t * p ); extern void Wlc_NtkShortNames( Wlc_Ntk_t * p ); diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 9f36ad566..82321d3b4 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -364,10 +364,10 @@ usage: int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) { Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); - int c, iOutput = -1, fSeq = 0, fVerbose = 0; + int c, iOutput = -1, Range = 1, fAllPis = 0, fSeq = 0, fVerbose = 0; char * pName; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Osvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "ORisvh" ) ) != EOF ) { switch ( c ) { @@ -382,6 +382,20 @@ int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( iOutput < 0 ) goto usage; break; + case 'R': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-R\" should be followed by an integer.\n" ); + goto usage; + } + Range = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( Range < 0 ) + goto usage; + break; + case 'i': + fAllPis ^= 1; + break; case 's': fSeq ^= 1; break; @@ -406,16 +420,18 @@ int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) } printf( "Extracting output %d as a %s word-level network.\n", iOutput, fSeq ? "sequential" : "combinational" ); pName = Wlc_NtkNewName( pNtk, iOutput, fSeq ); - Wlc_NtkMarkCone( pNtk, iOutput, fSeq ); + Wlc_NtkMarkCone( pNtk, iOutput, Range, fSeq, fAllPis ); pNtk = Wlc_NtkDupDfs( pNtk, 1, fSeq ); ABC_FREE( pNtk->pName ); pNtk->pName = Abc_UtilStrsav( pName ); Wlc_AbcUpdateNtk( pAbc, pNtk ); return 0; usage: - Abc_Print( -2, "usage: %%cone [-O num] [-svh]\n" ); - Abc_Print( -2, "\t extracts cone of the given word-level output\n" ); - Abc_Print( -2, "\t-O num : zero-based index of the word-level output to extract [default = %d]\n", iOutput ); + Abc_Print( -2, "usage: %%cone [-OR num] [-isvh]\n" ); + Abc_Print( -2, "\t extracts logic cone of one or more word-level outputs\n" ); + Abc_Print( -2, "\t-O num : zero-based index of the first word-level output to extract [default = %d]\n", iOutput ); + Abc_Print( -2, "\t-R num : total number of word-level outputs to extract [default = %d]\n", Range ); + Abc_Print( -2, "\t-i : toggle using support composed of all primary inputs [default = %s]\n", fAllPis? "yes": "no" ); Abc_Print( -2, "\t-s : toggle performing extracting sequential cones [default = %s]\n", fSeq? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index 822c2eb54..bd00a570f 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -314,7 +314,7 @@ void Wlc_NtkCollectStats( Wlc_Ntk_t * p, int nObjs[2][WLC_OBJ_NUMBER] ) return; for ( n = 0; n < 2; n++ ) { - Wlc_NtkMarkCone( p, n, 1 ); + Wlc_NtkMarkCone( p, n, 1, 1, 0 ); Wlc_NtkForEachObj( p, pObj, i ) if ( pObj->Mark ) nObjs[n][pObj->Type]++; @@ -325,7 +325,7 @@ int Wlc_NtkCountRealPis( Wlc_Ntk_t * p ) { Wlc_Obj_t * pObj; int i, Count = 0; - Wlc_NtkMarkCone( p, -1, 1 ); + Wlc_NtkMarkCone( p, -1, -1, 1, 0 ); Wlc_NtkForEachPi( p, pObj, i ) Count += pObj->Mark; Wlc_NtkCleanMarks( p ); @@ -859,17 +859,18 @@ void Wlc_NtkMarkCone_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFlops ) Wlc_ObjForEachFanin( pObj, iFanin, i ) Wlc_NtkMarkCone_rec( p, Wlc_NtkObj(p, iFanin), vFlops ); } -void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int fSeq ) +void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int Range, int fSeq, int fAllPis ) { Vec_Int_t * vFlops; Wlc_Obj_t * pObj; int i, CiId, CoId; Wlc_NtkCleanMarks( p ); -// Wlc_NtkForEachPi( p, pObj, i ) -// pObj->Mark = 1; + if ( fAllPis ) + Wlc_NtkForEachPi( p, pObj, i ) + pObj->Mark = 1; vFlops = Vec_IntAlloc( 100 ); Wlc_NtkForEachCo( p, pObj, i ) - if ( iCoId == -1 || i == iCoId ) + if ( iCoId == -1 || (i >= iCoId && i < iCoId + Range) ) Wlc_NtkMarkCone_rec( p, pObj, vFlops ); if ( fSeq ) Vec_IntForEachEntry( vFlops, CiId, i ) @@ -885,7 +886,7 @@ void Wlc_NtkProfileCones( Wlc_Ntk_t * p ) int i, nPis, nFos, nNodes, nAdders, nMults; Wlc_NtkForEachCo( p, pObj, i ) { - Wlc_NtkMarkCone( p, i, 0 ); + Wlc_NtkMarkCone( p, i, 1, 0, 0 ); nNodes = Wlc_NtkCountMarked( p, &nPis, &nFos, &nAdders, &nMults ); printf( "Cone %5d : ", i ); printf( "PI = %4d ", nPis ); From f701a0c659c57b8aa452bed93143a45cf5dcfeb8 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 27 Jan 2017 10:48:56 -0800 Subject: [PATCH 081/185] Commenting out &mfs report message. --- src/aig/gia/giaMfs.c | 1 + src/base/wlc/wlcShow.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/aig/gia/giaMfs.c b/src/aig/gia/giaMfs.c index 3ff169781..3229e0d0d 100644 --- a/src/aig/gia/giaMfs.c +++ b/src/aig/gia/giaMfs.c @@ -451,6 +451,7 @@ Gia_Man_t * Gia_ManPerformMfs( Gia_Man_t * p, Sfm_Par_t * pPars ) nNodes = Sfm_NtkPerform( pNtk, pPars ); if ( nNodes == 0 ) { + if ( p->pManTime ) Abc_Print( 1, "The network is not changed by \"&mfs\".\n" ); pNew = Gia_ManDup( p ); pNew->vMapping = Vec_IntDup( p->vMapping ); diff --git a/src/base/wlc/wlcShow.c b/src/base/wlc/wlcShow.c index 8ef21d298..7914cd7a6 100644 --- a/src/base/wlc/wlcShow.c +++ b/src/base/wlc/wlcShow.c @@ -49,9 +49,9 @@ void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) Wlc_Obj_t * pNode; int LevelMax, Prev, Level, i; - if ( Wlc_NtkObjNum(p) > 500 ) + if ( Wlc_NtkObjNum(p) > 1000 ) { - fprintf( stdout, "Cannot visualize WLC with more than %d nodes.\n", 500 ); + fprintf( stdout, "Cannot visualize WLC with more than %d nodes.\n", 1000 ); return; } if ( (pFile = fopen( pFileName, "w" )) == NULL ) From 596276152c0933f4251c53206ff1d98533b45ab2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 27 Jan 2017 15:22:23 -0800 Subject: [PATCH 082/185] Fixing non-reproducability related to floating-point numbers. --- src/aig/gia/giaJf.c | 14 ++++++++------ src/aig/gia/giaLf.c | 11 ++++++----- src/aig/gia/giaMf.c | 7 ++++--- src/aig/gia/giaNf.c | 17 +++++++++-------- 4 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/aig/gia/giaJf.c b/src/aig/gia/giaJf.c index 2d75581d0..205ab4080 100644 --- a/src/aig/gia/giaJf.c +++ b/src/aig/gia/giaJf.c @@ -36,6 +36,7 @@ ABC_NAMESPACE_IMPL_START #define JF_LEAF_MAX 8 #define JF_WORD_MAX ((JF_LEAF_MAX > 6) ? 1 << (JF_LEAF_MAX-6) : 1) #define JF_CUT_MAX 16 +#define JF_EPSILON 0.005 typedef struct Jf_Cut_t_ Jf_Cut_t; struct Jf_Cut_t_ @@ -940,15 +941,16 @@ float Jf_CutCompareDelay( Jf_Cut_t * pOld, Jf_Cut_t * pNew ) { if ( pOld->Time != pNew->Time ) return pOld->Time - pNew->Time; if ( pOld->pCut[0] != pNew->pCut[0] ) return pOld->pCut[0] - pNew->pCut[0]; - if ( pOld->Flow != pNew->Flow ) return pOld->Flow - pNew->Flow; +// if ( pOld->Flow != pNew->Flow ) return pOld->Flow - pNew->Flow; + if ( pOld->Flow < pNew->Flow - JF_EPSILON ) return -1; + if ( pOld->Flow > pNew->Flow + JF_EPSILON ) return 1; return 0; } float Jf_CutCompareArea( Jf_Cut_t * pOld, Jf_Cut_t * pNew ) { -// float Epsilon = (float)0.001; -// if ( pOld->Flow > pNew->Flow + Epsilon ) return 1; -// if ( pOld->Flow < pNew->Flow - Epsilon ) return -1; - if ( pOld->Flow != pNew->Flow ) return pOld->Flow - pNew->Flow; +// if ( pOld->Flow != pNew->Flow ) return pOld->Flow - pNew->Flow; + if ( pOld->Flow < pNew->Flow - JF_EPSILON ) return -1; + if ( pOld->Flow > pNew->Flow + JF_EPSILON ) return 1; if ( pOld->pCut[0] != pNew->pCut[0] ) return pOld->pCut[0] - pNew->pCut[0]; if ( pOld->Time != pNew->Time ) return pOld->Time - pNew->Time; return 0; @@ -1367,7 +1369,7 @@ void Jf_ObjComputeBestCut( Jf_Man_t * p, Gia_Obj_t * pObj, int fEdge, int fEla ) if ( fEdge && !fEla ) Jf_CutSetCost(pCut, Jf_CutSize(pCut)); Area = fEla ? Jf_CutArea(p, pCut, fEdge) : Jf_CutFlow(p, pCut) + Jf_CutCost(pCut); - if ( pCutBest == NULL || AreaBest > Area || (AreaBest == Area && TimeBest > (Time = Jf_CutArr(p, pCut))) ) + if ( pCutBest == NULL || AreaBest > Area + JF_EPSILON || (AreaBest > Area - JF_EPSILON && TimeBest > (Time = Jf_CutArr(p, pCut))) ) pCutBest = pCut, AreaBest = Area, TimeBest = Time; } Vec_IntWriteEntry( &p->vArr, iObj, Jf_CutArr(p, pCutBest) ); diff --git a/src/aig/gia/giaLf.c b/src/aig/gia/giaLf.c index 7973966a3..2c216a9b1 100644 --- a/src/aig/gia/giaLf.c +++ b/src/aig/gia/giaLf.c @@ -36,6 +36,7 @@ ABC_NAMESPACE_IMPL_START #define LF_NO_LEAF 255 #define LF_CUT_WORDS (4+LF_LEAF_MAX/2) #define LF_TT_WORDS ((LF_LEAF_MAX > 6) ? 1 << (LF_LEAF_MAX-6) : 1) +#define LF_EPSILON 0.005 typedef struct Lf_Cut_t_ Lf_Cut_t; struct Lf_Cut_t_ @@ -847,16 +848,16 @@ static inline int Lf_CutCompareDelay( Lf_Cut_t * pCut0, Lf_Cut_t * pCut1 ) if ( pCut0->Delay > pCut1->Delay ) return 1; if ( pCut0->nLeaves < pCut1->nLeaves ) return -1; if ( pCut0->nLeaves > pCut1->nLeaves ) return 1; - if ( pCut0->Flow < pCut1->Flow ) return -1; - if ( pCut0->Flow > pCut1->Flow ) return 1; + if ( pCut0->Flow < pCut1->Flow - LF_EPSILON ) return -1; + if ( pCut0->Flow > pCut1->Flow + LF_EPSILON ) return 1; return 0; } static inline int Lf_CutCompareArea( Lf_Cut_t * pCut0, Lf_Cut_t * pCut1 ) { if ( pCut0->fLate < pCut1->fLate ) return -1; if ( pCut0->fLate > pCut1->fLate ) return 1; - if ( pCut0->Flow < pCut1->Flow ) return -1; - if ( pCut0->Flow > pCut1->Flow ) return 1; + if ( pCut0->Flow < pCut1->Flow - LF_EPSILON ) return -1; + if ( pCut0->Flow > pCut1->Flow + LF_EPSILON ) return 1; if ( pCut0->Delay < pCut1->Delay ) return -1; if ( pCut0->Delay > pCut1->Delay ) return 1; if ( pCut0->nLeaves < pCut1->nLeaves ) return -1; @@ -1304,7 +1305,7 @@ void Lf_ObjMergeOrder( Lf_Man_t * p, int iObj ) p->nCutEqual++; // area cut iCutUsed = 0; - if ( nCutsR > 1 && pCutsR[0]->Flow > pCutsR[1]->Flow )//&& !pCutsR[1]->fLate ) // can remove !fLate + if ( nCutsR > 1 && pCutsR[0]->Flow > pCutsR[1]->Flow + LF_EPSILON )//&& !pCutsR[1]->fLate ) // can remove !fLate { pBest->Cut[1].Handle = Lf_MemSaveCut(&p->vStoreNew, pCutsR[1], iObj); pBest->Delay[1] = pCutsR[1]->Delay; diff --git a/src/aig/gia/giaMf.c b/src/aig/gia/giaMf.c index 2ded34bd0..a500a8394 100644 --- a/src/aig/gia/giaMf.c +++ b/src/aig/gia/giaMf.c @@ -37,6 +37,7 @@ ABC_NAMESPACE_IMPL_START #define MF_NO_LEAF 31 #define MF_TT_WORDS ((MF_LEAF_MAX > 6) ? 1 << (MF_LEAF_MAX-6) : 1) #define MF_NO_FUNC 134217727 // (1<<27)-1 +#define MF_EPSILON 0.005 typedef struct Mf_Cut_t_ Mf_Cut_t; struct Mf_Cut_t_ @@ -920,8 +921,8 @@ static inline int Mf_SetLastCutContainsArea( Mf_Cut_t ** pCuts, int nCuts ) } static inline int Mf_CutCompareArea( Mf_Cut_t * pCut0, Mf_Cut_t * pCut1 ) { - if ( pCut0->Flow < pCut1->Flow ) return -1; - if ( pCut0->Flow > pCut1->Flow ) return 1; + if ( pCut0->Flow < pCut1->Flow - MF_EPSILON ) return -1; + if ( pCut0->Flow > pCut1->Flow + MF_EPSILON ) return 1; if ( pCut0->Delay < pCut1->Delay ) return -1; if ( pCut0->Delay > pCut1->Delay ) return 1; if ( pCut0->nLeaves < pCut1->nLeaves ) return -1; @@ -1544,7 +1545,7 @@ static inline void Mf_ObjComputeBestCut( Mf_Man_t * p, int iObj ) assert( !Mf_CutIsTriv(pCut, iObj) ); assert( Mf_CutSize(pCut) <= p->pPars->nLutSize ); Flow = p->fUseEla ? Mf_CutAreaDerefed(p, pCut) : Mf_CutFlow(p, pCut, &Time); - if ( pCutBest == NULL || FlowBest > Flow || (FlowBest == Flow && TimeBest > Time) ) + if ( pCutBest == NULL || FlowBest > Flow + MF_EPSILON || (FlowBest > Flow - MF_EPSILON && TimeBest > Time) ) pCutBest = pCut, FlowBest = Flow, TimeBest = Time; } assert( pCutBest != NULL ); diff --git a/src/aig/gia/giaNf.c b/src/aig/gia/giaNf.c index 6761b6175..6f1d0c8d1 100644 --- a/src/aig/gia/giaNf.c +++ b/src/aig/gia/giaNf.c @@ -41,6 +41,7 @@ ABC_NAMESPACE_IMPL_START #define NF_CUT_MAX 32 #define NF_NO_LEAF 31 #define NF_NO_FUNC 0x3FFFFFF +#define NF_EPSILON 0.001 typedef struct Nf_Cut_t_ Nf_Cut_t; struct Nf_Cut_t_ @@ -171,7 +172,7 @@ static inline int Nf_CfgCompl( Nf_Cfg_t Cfg, int i ) int Nf_StoCellIsDominated( Mio_Cell2_t * pCell, int * pFans, int * pProf ) { int k; - if ( pCell->AreaF < Abc_Int2Float(pProf[0]) ) + if ( pCell->AreaF + NF_EPSILON < Abc_Int2Float(pProf[0]) ) return 0; for ( k = 0; k < (int)pCell->nFanins; k++ ) if ( pCell->iDelays[Abc_Lit2Var(pFans[k])] < pProf[k+1] ) @@ -802,8 +803,8 @@ static inline int Nf_CutCompareArea( Nf_Cut_t * pCut0, Nf_Cut_t * pCut1 ) { if ( pCut0->Useless < pCut1->Useless ) return -1; if ( pCut0->Useless > pCut1->Useless ) return 1; - if ( pCut0->Flow < pCut1->Flow ) return -1; - if ( pCut0->Flow > pCut1->Flow ) return 1; + if ( pCut0->Flow < pCut1->Flow - NF_EPSILON ) return -1; + if ( pCut0->Flow > pCut1->Flow + NF_EPSILON ) return 1; if ( pCut0->Delay < pCut1->Delay ) return -1; if ( pCut0->Delay > pCut1->Delay ) return 1; if ( pCut0->nLeaves < pCut1->nLeaves ) return -1; @@ -1162,7 +1163,7 @@ void Nf_ManCutMatchOne( Nf_Man_t * p, int iObj, int * pCut, int * pCutSet ) pD->Cfg.fCompl = 0; } - if ( pA->F > AreaF ) + if ( pA->F > AreaF + NF_EPSILON ) { pA->D = Delay; pA->F = AreaF; @@ -1310,7 +1311,7 @@ void Nf_ManCutMatch( Nf_Man_t * p, int iObj ) } //assert( pAp->F < FLT_MAX || pAn->F < FLT_MAX ); // try replacing pos with neg - if ( pAp->D == SCL_INFINITY || (pAp->F > pAn->F + p->InvAreaF && pAn->D + p->InvDelayI <= Required[0]) ) + if ( pAp->D == SCL_INFINITY || (pAp->F > pAn->F + p->InvAreaF + NF_EPSILON && pAn->D + p->InvDelayI <= Required[0]) ) { assert( p->Iter > 0 ); *pAp = *pAn; @@ -1322,7 +1323,7 @@ void Nf_ManCutMatch( Nf_Man_t * p, int iObj ) //printf( "Using inverter to improve area at node %d in phase %d.\n", iObj, 1 ); } // try replacing neg with pos - else if ( pAn->D == SCL_INFINITY || (pAn->F > pAp->F + p->InvAreaF && pAp->D + p->InvDelayI <= Required[1]) ) + else if ( pAn->D == SCL_INFINITY || (pAn->F > pAp->F + p->InvAreaF + NF_EPSILON && pAp->D + p->InvDelayI <= Required[1]) ) { assert( p->Iter > 0 ); *pAn = *pAp; @@ -1778,7 +1779,7 @@ void Nf_ManElaBestMatchOne( Nf_Man_t * p, int iObj, int c, int * pCut, int * pCu pMb->Cfg = Nf_Int2Cfg(0); pMb->fBest = 1; // compare - if ( pRes->F > pMb->F || (pRes->F == pMb->F && pRes->D > pMb->D) ) + if ( pRes->F > pMb->F + NF_EPSILON || (pRes->F > pMb->F - NF_EPSILON && pRes->D > pMb->D) ) *pRes = *pMb; return; } @@ -1814,7 +1815,7 @@ void Nf_ManElaBestMatchOne( Nf_Man_t * p, int iObj, int c, int * pCut, int * pCu // compute area pMb->F = Scl_Int2Flt((int)Nf_MatchRefArea(p, iObj, c, pMb, Required)); // compare - if ( pRes->F > pMb->F || (pRes->F == pMb->F && pRes->D > pMb->D) ) + if ( pRes->F > pMb->F + NF_EPSILON || (pRes->F > pMb->F - NF_EPSILON && pRes->D > pMb->D) ) *pRes = *pMb; } } From ec6b765314f029ca9ddf5a2f3adc5b496d560f43 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 28 Jan 2017 11:46:47 -0800 Subject: [PATCH 083/185] Custom floating-point number. --- src/sat/xsat/xsatFloat.h | 213 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 src/sat/xsat/xsatFloat.h diff --git a/src/sat/xsat/xsatFloat.h b/src/sat/xsat/xsatFloat.h new file mode 100644 index 000000000..73b74ff72 --- /dev/null +++ b/src/sat/xsat/xsatFloat.h @@ -0,0 +1,213 @@ +/**CFile**************************************************************** + + FileName [xsatFloat.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [xSAT - A SAT solver written in C. + Read the license file for more info.] + + Synopsis [Floating point number implementation.] + + Author [Alan Mishchenko, Bruno Schmitt] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - January 28, 2017.] + + Revision [] + +***********************************************************************/ +#ifndef ABC__sat__xSAT__xsatFloat_h +#define ABC__sat__xSAT__xsatFloat_h + +#include "misc/util/abc_global.h" +#include "misc/vec/vecInt.h" + +ABC_NAMESPACE_HEADER_START + +//////////////////////////////////////////////////////////////////////// +/// STRUCTURE DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/* + The xFloat_t floating-point number is represented as a 32-bit unsigned int. + The number is (2^Exp)*Mnt, where Exp is a 16-bit exponent and Mnt is a + 16-bit mantissa. The decimal point is located between the MSB of Mnt, + which is always 1, and the remaining 15 digits of Mnt. + + Currently, only positive numbers are represented. + + The range of possible values is [1.0; 2^(2^16-1)*1.111111111111111] + that is, the smallest possible number is 1.0 and the largest possible + number is 2^(---16 ones---).(1.---15 ones---) + + Comparison of numbers can be done by comparing the underlying unsigned ints. + + Only addition, multiplication, and division by 2^n are currently implemented. +*/ + +typedef struct xFloat_t_ xFloat_t; +struct xFloat_t_ +{ + unsigned Mnt : 16; + unsigned Exp : 16; +}; + +static inline unsigned xSat_Float2Uint( xFloat_t f ) { union { xFloat_t f; unsigned u; } temp; temp.f = f; return temp.u; } +static inline xFloat_t xSat_Uint2Float( unsigned u ) { union { xFloat_t f; unsigned u; } temp; temp.u = u; return temp.f; } +static inline int xSat_LessThan( xFloat_t a, xFloat_t b ) { return a.Exp < b.Exp || (a.Exp == b.Exp && a.Mnt < b.Mnt); } +static inline int xSat_Equal( xFloat_t a, xFloat_t b ) { return a.Exp == b.Exp && a.Mnt == b.Mnt; } + +static inline xFloat_t xSat_FloatCreate( unsigned Exp, unsigned Mnt ) { xFloat_t res; res.Exp = Exp; res.Mnt = Mnt; return res; } + +static inline xFloat_t xSat_FloatCreateConst1() { return xSat_FloatCreate( 0, 1 << 15 ); } +static inline xFloat_t xSat_FloatCreateConst2() { return xSat_FloatCreate( 1, 1 << 15 ); } +static inline xFloat_t xSat_FloatCreateConst3() { return xSat_FloatCreate( 1, 3 << 14 ); } +static inline xFloat_t xSat_FloatCreateConst12() { return xSat_FloatCreate( 3, 3 << 14 ); } +static inline xFloat_t xSat_FloatCreateConst1point5() { return xSat_FloatCreate( 0, 3 << 14 ); } +static inline xFloat_t xSat_FloatCreateConst2point5() { return xSat_FloatCreate( 1, 5 << 13 ); } +static inline xFloat_t xSat_FloatCreateMaximum() { return xSat_Uint2Float( 0xFFFFFFFF ); } + +static inline float xSat_Float2Float( xFloat_t a ) { assert(a.Exp < 127); return Abc_Int2Float(((a.Exp + 127) << 23) | ((a.Mnt & 0x7FFF) << 8)); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Adding two floating-point numbers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xFloat_t xSat_FloatAdd( xFloat_t a, xFloat_t b ) +{ + unsigned Exp, Mnt; + if ( a.Exp < b.Exp ) + return xSat_FloatAdd(b, a); + assert( a.Exp >= b.Exp ); + // compute new mantissa + Mnt = a.Mnt + (b.Mnt >> (a.Exp - b.Exp)); + // compute new exponent + Exp = a.Exp; + // update exponent and mantissa if new MSB is created + if ( Mnt & 0xFFFF0000 ) // new MSB bit is created + Exp++, Mnt >>= 1; + // check overflow + if ( Exp & 0xFFFF0000 ) // overflow + return xSat_Uint2Float( 0xFFFFFFFF ); + assert( (Exp & 0xFFFF0000) == 0 ); + assert( (Mnt & 0xFFFF0000) == 0 ); + assert( Mnt & 0x00008000 ); + return xSat_FloatCreate( Exp, Mnt ); +} + +/**Function************************************************************* + + Synopsis [Multiplying two floating-point numbers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xFloat_t xSat_FloatMul( xFloat_t a, xFloat_t b ) +{ + unsigned Exp, Mnt; + if ( a.Exp < b.Exp ) + return xSat_FloatMul(b, a); + assert( a.Exp >= b.Exp ); + // compute new mantissa + Mnt = (a.Mnt * b.Mnt) >> 15; + // compute new exponent + Exp = a.Exp + b.Exp; + // update exponent and mantissa if new MSB is created + if ( Mnt & 0xFFFF0000 ) // new MSB bit is created + Exp++, Mnt >>= 1; + // check overflow + if ( Exp & 0xFFFF0000 ) // overflow + return xSat_Uint2Float( 0xFFFFFFFF ); + assert( (Exp & 0xFFFF0000) == 0 ); + assert( (Mnt & 0xFFFF0000) == 0 ); + assert( Mnt & 0x00008000 ); + return xSat_FloatCreate( Exp, Mnt ); +} + +/**Function************************************************************* + + Synopsis [Dividing floating point number by a degree of 2.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xFloat_t xSat_FloatDiv( xFloat_t a, unsigned Deg2 ) +{ + assert( Deg2 < 0xFFFF ); + if ( a.Exp >= Deg2 ) + return xSat_FloatCreate( a.Exp - Deg2, a.Mnt ); + return xSat_FloatCreateConst1(); // underflow +} + +/**Function************************************************************* + + Synopsis [Testing procedure.] + + Description [Helpful link https://www.h-schmidt.net/FloatConverter/IEEE754.html] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSat_FloatTest() +{ + xFloat_t c1 = xSat_FloatCreateConst1(); + xFloat_t c2 = xSat_FloatCreateConst2(); + xFloat_t c3 = xSat_FloatCreateConst3(); + xFloat_t c12 = xSat_FloatCreateConst12(); + xFloat_t c1p5 = xSat_FloatCreateConst1point5(); + xFloat_t c2p5 = xSat_FloatCreateConst2point5(); + + xFloat_t sum1 = xSat_FloatAdd(c1, c1p5); + xFloat_t mul1 = xSat_FloatMul(c2, c1p5); + + xFloat_t sum2 = xSat_FloatAdd(c1p5, c2p5); + xFloat_t mul2 = xSat_FloatMul(c1p5, c2p5); + +// float f1 = xSat_Float2Float(c1); +// Extra_PrintBinary( stdout, (int *)&c1, 32 ); printf( "\n" ); +// Extra_PrintBinary( stdout, (int *)&f1, 32 ); printf( "\n" ); + + printf( "1 = %f\n", xSat_Float2Float(c1) ); + printf( "2 = %f\n", xSat_Float2Float(c2) ); + printf( "3 = %f\n", xSat_Float2Float(c3) ); + printf( "12 = %f\n", xSat_Float2Float(c12) ); + printf( "1.5 = %f\n", xSat_Float2Float(c1p5) ); + printf( "2.5 = %f\n", xSat_Float2Float(c2p5) ); + + printf( "1.0 + 1.5 = %f\n", xSat_Float2Float(sum1) ); + printf( "2.0 * 1.5 = %f\n", xSat_Float2Float(mul1) ); + + printf( "1.5 + 2.5 = %f\n", xSat_Float2Float(sum2) ); + printf( "1.5 * 2.5 = %f\n", xSat_Float2Float(mul2) ); + printf( "12 / 2^2 = %f\n", xSat_Float2Float(xSat_FloatDiv(c12, 2)) ); + + assert( xSat_Equal(sum1, c2p5) ); + assert( xSat_Equal(mul1, c3) ); +} + +ABC_NAMESPACE_HEADER_END + +#endif From 782125c61e78d7f14e129667433b54e2fc434d50 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 28 Jan 2017 12:01:32 -0800 Subject: [PATCH 084/185] Custom floating-point number. --- src/sat/xsat/xsatFloat.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/sat/xsat/xsatFloat.h b/src/sat/xsat/xsatFloat.h index 73b74ff72..901497837 100644 --- a/src/sat/xsat/xsatFloat.h +++ b/src/sat/xsat/xsatFloat.h @@ -70,6 +70,7 @@ static inline xFloat_t xSat_FloatCreateConst2point5() { retur static inline xFloat_t xSat_FloatCreateMaximum() { return xSat_Uint2Float( 0xFFFFFFFF ); } static inline float xSat_Float2Float( xFloat_t a ) { assert(a.Exp < 127); return Abc_Int2Float(((a.Exp + 127) << 23) | ((a.Mnt & 0x7FFF) << 8)); } +static inline xFloat_t xSat_FloatFromFloat( float a ) { int A = Abc_Float2Int(a); assert(a >= 1.0); return xSat_FloatCreate((A >> 23)-127, 0x8000 | ((A >> 8) & 0x7FFF)); } //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -180,6 +181,13 @@ static inline void xSat_FloatTest() xFloat_t c1p5 = xSat_FloatCreateConst1point5(); xFloat_t c2p5 = xSat_FloatCreateConst2point5(); + xFloat_t c1_ = xSat_FloatFromFloat(1.0); + xFloat_t c2_ = xSat_FloatFromFloat(2.0); + xFloat_t c3_ = xSat_FloatFromFloat(3.0); + xFloat_t c12_ = xSat_FloatFromFloat(12.0); + xFloat_t c1p5_ = xSat_FloatFromFloat(1.5); + xFloat_t c2p5_ = xSat_FloatFromFloat(2.5); + xFloat_t sum1 = xSat_FloatAdd(c1, c1p5); xFloat_t mul1 = xSat_FloatMul(c2, c1p5); @@ -197,6 +205,13 @@ static inline void xSat_FloatTest() printf( "1.5 = %f\n", xSat_Float2Float(c1p5) ); printf( "2.5 = %f\n", xSat_Float2Float(c2p5) ); + printf( "Converted 1 = %f\n", xSat_Float2Float(c1_) ); + printf( "Converted 2 = %f\n", xSat_Float2Float(c2_) ); + printf( "Converted 3 = %f\n", xSat_Float2Float(c3_) ); + printf( "Converted 12 = %f\n", xSat_Float2Float(c12_) ); + printf( "Converted 1.5 = %f\n", xSat_Float2Float(c1p5_) ); + printf( "Converted 2.5 = %f\n", xSat_Float2Float(c2p5_) ); + printf( "1.0 + 1.5 = %f\n", xSat_Float2Float(sum1) ); printf( "2.0 * 1.5 = %f\n", xSat_Float2Float(mul1) ); From 9171bb32ad332d2b76e3c85ff64308065b89367d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 28 Jan 2017 17:04:22 -0800 Subject: [PATCH 085/185] Updates to arithmetic verification. --- abclib.dsp | 8 + src/proof/acec/acecInt.h | 9 + src/proof/acec/acecMult.c | 1 + src/proof/acec/acecTree.c | 12 +- src/proof/acec/acecXor.c | 407 +++++++++++++++++++++++++++++++++++++ src/proof/acec/module.make | 3 +- 6 files changed, 430 insertions(+), 10 deletions(-) create mode 100644 src/proof/acec/acecXor.c diff --git a/abclib.dsp b/abclib.dsp index 6da7e2a2c..cbed067a0 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -1963,6 +1963,10 @@ SOURCE=.\src\sat\xsat\xsatCnfReader.c # End Source File # Begin Source File +SOURCE=.\src\sat\xsat\xsatFloat.h +# End Source File +# Begin Source File + SOURCE=.\src\sat\xsat\xsatHeap.h # End Source File # Begin Source File @@ -5553,6 +5557,10 @@ SOURCE=.\src\proof\acec\acecTree.c SOURCE=.\src\proof\acec\acecUtil.c # End Source File +# Begin Source File + +SOURCE=.\src\proof\acec\acecXor.c +# End Source File # End Group # End Group # End Group diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index b8ec24554..47a32e78d 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -56,6 +56,12 @@ struct Acec_Box_t_ /// MACRO DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +static inline int Acec_SignBit( Vec_Int_t * vAdds, int iBox, int b ) { return (Vec_IntEntry(vAdds, 6*iBox+5) >> b) & 1; } +static inline int Acec_SignBit2( Vec_Int_t * vAdds, int iBox, int b ) { return (Vec_IntEntry(vAdds, 6*iBox+5) >> (16+b)) & 1; } + +static inline void Acec_SignSetBit( Vec_Int_t * vAdds, int iBox, int b, int v ) { if ( v ) *Vec_IntEntryP(vAdds, 6*iBox+5) |= (1 << b); } +static inline void Acec_SignSetBit2( Vec_Int_t * vAdds, int iBox, int b, int v ) { if ( v ) *Vec_IntEntryP(vAdds, 6*iBox+5) |= (1 << (16+b)); } + //////////////////////////////////////////////////////////////////////// /// ITERATORS /// //////////////////////////////////////////////////////////////////////// @@ -75,11 +81,14 @@ extern void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] ); extern Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ); /*=== acecTree.c ========================================================*/ extern void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ); +extern void Acec_TreePrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds ); extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fFilterIn, int fFilterOut, int fVerbose ); extern void Acec_BoxFreeP( Acec_Box_t ** ppBox ); /*=== acecUtil.c ========================================================*/ extern void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose ); extern Vec_Int_t * Gia_PolynCollectLastXor( Gia_Man_t * pGia, int fVerbose ); +/*=== acecUtil.c ========================================================*/ +extern Acec_Box_t * Acec_DetectXorTrees( Gia_Man_t * p, int fVerbose ); diff --git a/src/proof/acec/acecMult.c b/src/proof/acec/acecMult.c index d868c3995..ba9405ac2 100644 --- a/src/proof/acec/acecMult.c +++ b/src/proof/acec/acecMult.c @@ -499,6 +499,7 @@ Vec_Int_t * Acec_MultFindPPs( Gia_Man_t * p ) { if ( Truth == Saved[i] || Truth == ~Saved[i] ) { + //printf( "*** Node %d is PP with support %d.\n", iObj, Vec_IntSize(vSupp) ); Acec_MultFindPPs_rec( p, iObj, vBold ); nProds++; break; diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index 2461c89bd..330a5d587 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -27,12 +27,6 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static inline int Acec_SignBit( Vec_Int_t * vAdds, int iBox, int b ) { return (Vec_IntEntry(vAdds, 6*iBox+5) >> b) & 1; } -static inline int Acec_SignBit2( Vec_Int_t * vAdds, int iBox, int b ) { return (Vec_IntEntry(vAdds, 6*iBox+5) >> (16+b)) & 1; } - -static inline void Acec_SignSetBit( Vec_Int_t * vAdds, int iBox, int b, int v ) { if ( v ) *Vec_IntEntryP(vAdds, 6*iBox+5) |= (1 << b); } -static inline void Acec_SignSetBit2( Vec_Int_t * vAdds, int iBox, int b, int v ) { if ( v ) *Vec_IntEntryP(vAdds, 6*iBox+5) |= (1 << (16+b)); } - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -558,7 +552,7 @@ void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ) printf( " }\n" ); } } -void Acec_PrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds ) +void Acec_TreePrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds ) { printf( "Adders:\n" ); Acec_PrintAdders( pBox->vAdds, vAdds ); @@ -703,7 +697,7 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) printf( "Processing tree %d: Ranks = %d. Adders = %d. Leaves = %d. Roots = %d.\n", i, Vec_WecSize(pBox->vAdds), Vec_WecSizeSize(pBox->vAdds), Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); - Acec_PrintBox( pBox, vAdds ); + Acec_TreePrintBox( pBox, vAdds ); Acec_BoxFreeP( &pBox ); } @@ -737,7 +731,7 @@ Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fFilterIn, 0, Vec_WecSize(pBox->vAdds), Vec_WecSizeSize(pBox->vAdds), Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); if ( pBox && fVerbose ) - Acec_PrintBox( pBox, vAdds ); + Acec_TreePrintBox( pBox, vAdds ); //Acec_PrintAdders( pBox0->vAdds, vAdds ); //Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); Vec_WecFreeP( &vTrees ); diff --git a/src/proof/acec/acecXor.c b/src/proof/acec/acecXor.c new file mode 100644 index 000000000..ae5aeff76 --- /dev/null +++ b/src/proof/acec/acecXor.c @@ -0,0 +1,407 @@ +/**CFile**************************************************************** + + FileName [acecXor.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [CEC for arithmetic circuits.] + + Synopsis [Detection of XOR trees.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: acecXor.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "acecInt.h" +#include "misc/vec/vecWec.h" +#include "misc/extra/extra.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Acec_OrderXorRoots( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vXorRoots, Vec_Wec_t * vXorTrees, Vec_Int_t * vMap ) +{ + Vec_Int_t * vOrder = Vec_IntAlloc( Vec_WecSize(vXorTrees) ); + Vec_Int_t * vReMap = Vec_IntStartFull( Vec_WecSize(vXorTrees) ); + int i, k, Entry, This; + // iterate through adders and for each try mark the next one + for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) + { + int Node = Vec_IntEntry(vAdds, 6*i+4); + if ( Vec_IntEntry(vMap, Node) == -1 ) + continue; + for ( k = 0; k < 3; k++ ) + { + int Fanin = Vec_IntEntry(vAdds, 6*i+k); + if ( Vec_IntEntry(vMap, Fanin) == -1 ) + continue; + //printf( "%4d: %2d -> %2d\n", Node, Vec_IntEntry(vMap, Node), Vec_IntEntry(vMap, Fanin) ); + Vec_IntWriteEntry( vReMap, Vec_IntEntry(vMap, Node), Vec_IntEntry(vMap, Fanin) ); + } + } +//Vec_IntPrint( vReMap ); + // find reodering + Vec_IntForEachEntry( vReMap, Entry, i ) + if ( Entry == -1 && Vec_IntFind(vReMap, i) >= 0 ) + break; + assert( i < Vec_IntSize(vReMap) ); + while ( 1 ) + { + Vec_IntPush( vOrder, Vec_IntEntry(vXorRoots, i) ); + Entry = i; + Vec_IntForEachEntry( vReMap, This, i ) + if ( This == Entry ) + break; + if ( i == Vec_IntSize(vReMap) ) + break; + } + Vec_IntFree( vReMap ); +//Vec_IntPrint( vOrder ); + return vOrder; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +// marks nodes appearing as fanins to XORs +Vec_Bit_t * Acec_MapXorIns( Gia_Man_t * p, Vec_Int_t * vXors ) +{ + Vec_Bit_t * vMap = Vec_BitStart( Gia_ManObjNum(p) ); int i; + for ( i = 0; 4*i < Vec_IntSize(vXors); i++ ) + { + Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i+1), 1 ); + Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i+2), 1 ); + Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i+3), 1 ); + } + return vMap; +} +// marks nodes having XOR cuts +Vec_Bit_t * Acec_MapXorOuts( Gia_Man_t * p, Vec_Int_t * vXors ) +{ + Vec_Bit_t * vMap = Vec_BitStart( Gia_ManObjNum(p) ); int i; + for ( i = 0; 4*i < Vec_IntSize(vXors); i++ ) + Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i), 1 ); + return vMap; +} +// marks nodes appearing as outputs of MAJs +Vec_Bit_t * Acec_MapMajOuts( Gia_Man_t * p, Vec_Int_t * vAdds ) +{ + Vec_Bit_t * vMap = Vec_BitStart( Gia_ManObjNum(p) ); int i; + for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) + Vec_BitWriteEntry( vMap, Vec_IntEntry(vAdds, 6*i+4), 1 ); + return vMap; +} +// maps MAJ outputs into their FAs and HAs +Vec_Int_t * Acec_MapMajOutsToAdds( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vXorOuts, Vec_Int_t * vMapRank ) +{ + Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); int i; + for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) + { + int Xor = Vec_IntEntry(vAdds, 6*i+3); + int Maj = Vec_IntEntry(vAdds, 6*i+4); + if ( Vec_IntEntry(vMap, Maj) >= 0 ) + { + int i2 = Vec_IntEntry(vMap, Maj); + int Xor2 = Vec_IntEntry(vAdds, 6*i2+3); + int Maj2 = Vec_IntEntry(vAdds, 6*i2+4); + printf( "*** Node %d has two MAJ adder drivers: %d%s (%d rank %d) and %d%s (%d rank %d).\n", + Maj, + i, Vec_IntEntry(vAdds, 6*i+2) ? "":"*", Vec_BitEntry(vXorOuts, Xor), Vec_IntEntry(vMapRank, Xor), + i2, Vec_IntEntry(vAdds, 6*i2+2) ? "":"*", Vec_BitEntry(vXorOuts, Xor2), Vec_IntEntry(vMapRank, Xor2) ); + } + Vec_IntWriteEntry( vMap, Vec_IntEntry(vAdds, 6*i+4), i ); + } + return vMap; +} +// collects XOR roots (XOR nodes not appearing as fanins of other XORs) +Vec_Int_t * Acec_FindXorRoots( Gia_Man_t * p, Vec_Int_t * vXors ) +{ + Vec_Bit_t * vMapXorIns = Acec_MapXorIns( p, vXors ); + Vec_Int_t * vXorRoots = Vec_IntAlloc( 100 ); int i; + for ( i = 0; 4*i < Vec_IntSize(vXors); i++ ) + if ( !Vec_BitEntry(vMapXorIns, Vec_IntEntry(vXors, 4*i)) ) + Vec_IntPushUniqueOrder( vXorRoots, Vec_IntEntry(vXors, 4*i) ); + Vec_BitFree( vMapXorIns ); +//Vec_IntRemove( vXorRoots, 54 ); + return vXorRoots; +} +// collects XOR trees belonging to each of XOR roots +Vec_Wec_t * Acec_FindXorTrees( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vXorRoots, Vec_Int_t ** pvMap ) +{ + Vec_Int_t * vDoubles = Vec_IntAlloc( 100 ); + Vec_Wec_t * vXorTrees = Vec_WecStart( Vec_IntSize(vXorRoots) ); + Vec_Int_t * vLevel; + int i, k, Entry; + // map roots into their classes + Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); + Vec_IntForEachEntry( vXorRoots, Entry, i ) + { + Vec_IntWriteEntry( vMap, Entry, i ); + Vec_WecPush( vXorTrees, i, Entry ); + } + // map nodes into their classes + for ( i = Vec_IntSize(vXors)/4 - 1; i >= 0; i-- ) + { + int Root = Vec_IntEntry( vXors, 4*i ); + int Repr = Vec_IntEntry( vMap, Root ); + //assert( Repr != -1 ); + if ( Repr == -1 ) + continue; + for ( k = 1; k < 4; k++ ) + { + int Node = Vec_IntEntry( vXors, 4*i+k ); + if ( Node == 0 ) + continue; + Entry = Vec_IntEntry( vMap, Node ); + if ( Entry == Repr ) + continue; + if ( Entry == -1 ) + { + Vec_IntWriteEntry( vMap, Node, Repr ); + Vec_WecPush( vXorTrees, Repr, Node ); + continue; + } + //printf( "Node %d belongs to Tree %d and Tree %d.\n", Node, Entry, Repr ); + Vec_IntPushUnique( Vec_WecEntry(vXorTrees, Entry), Node ); + Vec_IntPush( vDoubles, Node ); + } + } + // clean map + Vec_IntForEachEntry( vDoubles, Entry, i ) + Vec_IntWriteEntry( vMap, Entry, -1 ); + Vec_IntFree( vDoubles ); + // sort nodes + Vec_WecForEachLevel( vXorTrees, vLevel, i ) + Vec_IntSort( vLevel, 0 ); + if ( pvMap ) + *pvMap = vMap; + else + Vec_IntFree( vMap ); + return vXorTrees; +} +// collects leaves of each XOR tree +Vec_Wec_t * Acec_FindXorLeaves( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vAdds, Vec_Wec_t * vXorTrees, Vec_Int_t * vMap, Vec_Wec_t ** pvAddBoxes ) +{ + Vec_Bit_t * vMapXorOuts = Acec_MapXorOuts( p, vXors ); + Vec_Int_t * vMapMajOuts = Acec_MapMajOutsToAdds( p, vAdds, vMapXorOuts, vMap ); + Vec_Wec_t * vXorLeaves = Vec_WecStart( Vec_WecSize(vXorTrees) ); + int i, k; + if ( pvAddBoxes ) + *pvAddBoxes = Vec_WecStart( Vec_WecSize(vXorTrees) ); + // collect leaves + for ( i = 0; 4*i < Vec_IntSize(vXors); i++ ) + { + int Xor = Vec_IntEntry(vXors, 4*i); + for ( k = 1; k < 4; k++ ) + { + int Node = Vec_IntEntry(vXors, 4*i+k); + if ( Node == 0 ) + continue; + if ( Vec_BitEntry(vMapXorOuts, Node) || Vec_IntEntry(vMap, Xor) == -1 ) + continue; + if ( Vec_IntEntry(vMapMajOuts, Node) == -1 ) // no maj driver + Vec_WecPush( vXorLeaves, Vec_IntEntry(vMap, Xor), Node ); + else if ( pvAddBoxes && Vec_IntEntry(vMap, Xor) > 0 ) // save adder box + Vec_WecPush( *pvAddBoxes, Vec_IntEntry(vMap, Xor)-1, Vec_IntEntry(vMapMajOuts, Node) ); + } + } +/* + if ( pvAddBoxes ) + { + Vec_Int_t * vLevel; + //Vec_WecPrint( *pvAddBoxes, 0 ); + Vec_WecForEachLevelReverse( *pvAddBoxes, vLevel, i ) + if ( Vec_IntSize(vLevel) > 0 ) + break; + Vec_WecShrink( *pvAddBoxes, i+1 ); + //Vec_WecPrint( *pvAddBoxes, 0 ); + } +*/ + Vec_BitFree( vMapXorOuts ); + Vec_IntFree( vMapMajOuts ); + return vXorLeaves; +} + +Acec_Box_t * Acec_FindBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vAddBoxes, Vec_Wec_t * vXorTrees, Vec_Wec_t * vXorLeaves ) +{ + extern Vec_Int_t * Acec_TreeCarryMap( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ); + extern void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, int Node, int fPhase, Vec_Bit_t * vVisit ); + extern void Acec_TreeVerifyPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ); + extern void Acec_TreeVerifyPhases2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ); + + int MaxRank = Vec_WecSize( vAddBoxes ); + Vec_Bit_t * vVisit = Vec_BitStart( Vec_IntSize(vAdds)/6 ); + Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel, * vLevel2, * vMap; + int i, j, k, Box, Node; + + Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 ); + pBox->pGia = p; + pBox->vAdds = vAddBoxes; // Vec_WecDup( vAddBoxes ); + pBox->vLeafLits = Vec_WecStart( MaxRank + 0 ); + pBox->vRootLits = Vec_WecStart( MaxRank + 0 ); + + assert( Vec_WecSize(vAddBoxes) == Vec_WecSize(vXorTrees) ); + assert( Vec_WecSize(vAddBoxes) == Vec_WecSize(vXorLeaves) ); + + // collect boxes; mark inputs/outputs + Vec_WecForEachLevel( pBox->vAdds, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + { + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 ); + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 ); + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 ); + } + // sort each level + Vec_WecForEachLevel( pBox->vAdds, vLevel, i ) + Vec_IntSort( vLevel, 0 ); + + // set phases starting from roots + vMap = Acec_TreeCarryMap( p, vAdds, pBox->vAdds ); + Vec_WecForEachLevelReverse( pBox->vAdds, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+4) ) ) + { + //printf( "Pushing phase of output %d of box %d\n", Vec_IntEntry(vAdds, 6*Box+4), Box ); + Acec_TreePhases_rec( p, vAdds, vMap, Vec_IntEntry(vAdds, 6*Box+4), Vec_IntEntry(vAdds, 6*Box+2) != 0, vVisit ); + } + Acec_TreeVerifyPhases( p, vAdds, pBox->vAdds ); + Acec_TreeVerifyPhases2( p, vAdds, pBox->vAdds ); + Vec_BitFree( vVisit ); + Vec_IntFree( vMap ); + + // collect inputs/outputs + Vec_BitWriteEntry( vIsRoot, 0, 1 ); + Vec_WecForEachLevel( pBox->vAdds, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, j ) + { + for ( k = 0; k < 3; k++ ) + if ( !Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) ) + Vec_WecPush( pBox->vLeafLits, i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) ); + for ( k = 3; k < 5; k++ ) + if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) ) + Vec_WecPush( pBox->vRootLits, k == 4 ? i + 1 : i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) ); + if ( Vec_IntEntry(vAdds, 6*Box+2) == 0 && Acec_SignBit2(vAdds, Box, 2) ) + Vec_WecPush( pBox->vLeafLits, i, 1 ); + } + Vec_BitFree( vIsLeaf ); + Vec_BitFree( vIsRoot ); + + // collect last bit + vLevel = Vec_WecEntry( pBox->vLeafLits, Vec_WecSize(pBox->vLeafLits)-1 ); + vLevel2 = Vec_WecEntry( vXorLeaves, Vec_WecSize(vXorLeaves)-1 ); + if ( Vec_IntSize(vLevel) == 0 && Vec_IntSize(vLevel2) > 0 ) + { + Vec_IntForEachEntry( vLevel2, Node, k ) + Vec_IntPush( vLevel, Abc_Var2Lit(Node, 0) ); + } + vLevel = Vec_WecEntry( pBox->vRootLits, Vec_WecSize(pBox->vRootLits)-1 ); + vLevel2 = Vec_WecEntry( vXorTrees, Vec_WecSize(vXorTrees)-1 ); + Vec_IntClear( vLevel ); + if ( Vec_IntSize(vLevel) == 0 && Vec_IntSize(vLevel2) > 0 ) + { + Vec_IntPush( vLevel, Abc_Var2Lit(Vec_IntEntryLast(vLevel2), 0) ); + } + + // sort each level + Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i ) + Vec_IntSort( vLevel, 0 ); + Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) + Vec_IntSort( vLevel, 1 ); + return pBox; +} + +Acec_Box_t * Acec_DetectXorTrees( Gia_Man_t * p, int fVerbose ) +{ + abctime clk = Abc_Clock(); + Acec_Box_t * pBox = NULL; + Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( p, &vXors, 0 ); + Vec_Int_t * vMap, * vXorRootsNew; + Vec_Int_t * vXorRoots = Acec_FindXorRoots( p, vXors ); + Vec_Wec_t * vXorTrees = Acec_FindXorTrees( p, vXors, vXorRoots, &vMap ); + Vec_Wec_t * vXorLeaves, * vAddBoxes = NULL; + + //Ree_ManPrintAdders( vAdds, 1 ); + printf( "Detected %d full-adders and %d half-adders. Found %d XOR-cuts. ", Ree_ManCountFadds(vAdds), Vec_IntSize(vAdds)/6-Ree_ManCountFadds(vAdds), Vec_IntSize(vXors)/4 ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + +// printf( "XOR roots: \n" ); +// Vec_IntPrint( vXorRoots ); +// Vec_WecPrint( vXorTrees, 0 ); + + vXorRootsNew = Acec_OrderXorRoots( p, vAdds, vXorRoots, vXorTrees, vMap ); + Vec_IntFree( vXorRoots ); + Vec_WecFree( vXorTrees ); + Vec_IntFree( vMap ); + + vXorRoots = vXorRootsNew; vXorRootsNew = NULL; + vXorTrees = Acec_FindXorTrees( p, vXors, vXorRoots, &vMap ); + vXorLeaves = Acec_FindXorLeaves( p, vXors, vAdds, vXorTrees, vMap, &vAddBoxes ); + + printf( "XOR roots: \n" ); + Vec_IntPrint( vXorRoots ); + printf( "XOR leaves: \n" ); + Vec_WecPrint( vXorLeaves, 0 ); + printf( "Adder boxes: \n" ); + Vec_WecPrint( vAddBoxes, 0 ); + + pBox = Acec_FindBox( p, vAdds, vAddBoxes, vXorTrees, vXorLeaves ); + + Acec_TreePrintBox( pBox, vAdds ); + + Vec_IntFree( vXorRoots ); + Vec_WecFree( vXorTrees ); + Vec_WecFree( vXorLeaves ); + //Vec_WecFree( vAddBoxes ); + + Vec_IntFree( vMap ); + Vec_IntFree( vXors ); + Vec_IntFree( vAdds ); + + return pBox; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/acec/module.make b/src/proof/acec/module.make index dbf86ac2a..f4c69892a 100644 --- a/src/proof/acec/module.make +++ b/src/proof/acec/module.make @@ -14,4 +14,5 @@ SRC += src/proof/acec/acecCl.c \ src/proof/acec/acecPolyn.c \ src/proof/acec/acecSt.c \ src/proof/acec/acecTree.c \ - src/proof/acec/acecUtil.c + src/proof/acec/acecUtil.c \ + src/proof/acec/acecXor.c From e9566a1e3db178a6111d227439354fcbb935ffa7 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 29 Jan 2017 13:37:29 -0800 Subject: [PATCH 086/185] Updates to arithmetic verification. --- src/base/wlc/wlcReadVer.c | 1 + src/proof/acec/acecCore.c | 18 ++- src/proof/acec/acecInt.h | 2 +- src/proof/acec/acecTree.c | 37 +++++- src/proof/acec/acecXor.c | 268 +++++++++++++++++--------------------- 5 files changed, 168 insertions(+), 158 deletions(-) diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c index e4a65ecfb..16de49430 100644 --- a/src/base/wlc/wlcReadVer.c +++ b/src/base/wlc/wlcReadVer.c @@ -429,6 +429,7 @@ char * Wlc_PrsConvertInitValues( Wlc_Ntk_t * p ) Vec_Str_t * vStr = Vec_StrAlloc( 1000 ); Vec_IntForEachEntry( p->vInits, Value, i ) { + char * pname = Wlc_ObjName( p, Value ); if ( Value < 0 ) { for ( k = 0; k < -Value; k++ ) diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index a23417042..1a575fbe9 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -319,7 +319,7 @@ void Vec_IntInsertOrder( Vec_Int_t * vLits, Vec_Int_t * vClasses, int Lit, int C void Acec_MoveDuplicates( Vec_Wec_t * vLits, Vec_Wec_t * vClasses ) { Vec_Int_t * vLevel1, * vLevel2; - int i, k, Prev, This, Entry; + int i, k, Prev, This, Entry, Counter = 0; Vec_WecForEachLevel( vLits, vLevel1, i ) { if ( i == Vec_WecSize(vLits) - 1 ) @@ -347,8 +347,10 @@ void Acec_MoveDuplicates( Vec_Wec_t * vLits, Vec_Wec_t * vClasses ) assert( Vec_IntSize(vLevel1) == Vec_IntSize(vLevel2) ); assert( Vec_IntSize(Vec_WecEntry(vLits, i+1)) == Vec_IntSize(Vec_WecEntry(vClasses, i+1)) ); + Counter++; } } + printf( "Moved %d pairs of PPs to normalize the matrix.\n", Counter ); } void Acec_MatchCheckShift( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Vec_Wec_t * vLits0, Vec_Wec_t * vLits1, Vec_Int_t * vMap0, Vec_Int_t * vMap1, Vec_Wec_t * vRoots0, Vec_Wec_t * vRoots1 ) @@ -490,12 +492,14 @@ int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) Gia_Man_t * pMiter; Gia_Man_t * pGia0n = pGia0, * pGia1n = pGia1; Cec_ParCec_t ParsCec, * pCecPars = &ParsCec; - Vec_Bit_t * vIgnore0 = pPars->fBooth ? Acec_BoothFindPPG(pGia0) : NULL; - Vec_Bit_t * vIgnore1 = pPars->fBooth ? Acec_BoothFindPPG(pGia1) : NULL; - Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0, vIgnore0, 0, 0, pPars->fVerbose ); - Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1, vIgnore1, 0, 0, pPars->fVerbose ); - Vec_BitFreeP( &vIgnore0 ); - Vec_BitFreeP( &vIgnore1 ); +// Vec_Bit_t * vIgnore0 = pPars->fBooth ? Acec_BoothFindPPG(pGia0) : NULL; +// Vec_Bit_t * vIgnore1 = pPars->fBooth ? Acec_BoothFindPPG(pGia1) : NULL; +// Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0, vIgnore0, 0, 0, pPars->fVerbose ); +// Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1, vIgnore1, 0, 0, pPars->fVerbose ); +// Vec_BitFreeP( &vIgnore0 ); +// Vec_BitFreeP( &vIgnore1 ); + Acec_Box_t * pBox0 = Acec_ProduceBox( pGia0, pPars->fVerbose ); + Acec_Box_t * pBox1 = Acec_ProduceBox( pGia1, pPars->fVerbose ); if ( pBox0 == NULL || pBox1 == NULL ) // cannot match printf( "Cannot find arithmetic boxes in both LHS and RHS. Trying regular CEC.\n" ); else if ( !Acec_MatchBoxes( pBox0, pBox1 ) ) // cannot find matching diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index 47a32e78d..381ab8d13 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -88,7 +88,7 @@ extern void Acec_BoxFreeP( Acec_Box_t ** ppBox ); extern void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose ); extern Vec_Int_t * Gia_PolynCollectLastXor( Gia_Man_t * pGia, int fVerbose ); /*=== acecUtil.c ========================================================*/ -extern Acec_Box_t * Acec_DetectXorTrees( Gia_Man_t * p, int fVerbose ); +extern Acec_Box_t * Acec_ProduceBox( Gia_Man_t * p, int fVerbose ); diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index 330a5d587..ab17d7b9c 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -333,6 +333,37 @@ void Acec_TreeVerifyPhases2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxe Vec_BitFree( vPhase ); Vec_BitFree( vRoots ); } +void Acec_TreeVerifyConnections( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ) +{ + Vec_Int_t * vCounts = Vec_IntStartFull( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; + int i, k, n, Box; + // mark outputs + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + { + Vec_IntWriteEntry( vCounts, Vec_IntEntry( vAdds, 6*Box+3 ), 0 ); + Vec_IntWriteEntry( vCounts, Vec_IntEntry( vAdds, 6*Box+4 ), 0 ); + } + // count fanouts + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + for ( n = 0; n < 3; n++ ) + if ( Vec_IntEntry( vCounts, Vec_IntEntry(vAdds, 6*Box+n) ) != -1 ) + Vec_IntAddToEntry( vCounts, Vec_IntEntry(vAdds, 6*Box+n), 1 ); + // print out + printf( "The adder tree has %d internal cut points. ", Vec_IntCountLarger(vCounts, -1) ); + if ( Vec_IntCountLarger(vCounts, 1) == 0 ) + printf( "There is no internal fanouts.\n" ); + else + { + printf( "These %d points have more than one fanout:\n", Vec_IntCountLarger(vCounts, 1) ); + Vec_IntForEachEntry( vCounts, Box, i ) + if ( Box > 1 ) + printf( "Node %d(lev %d) has fanout %d.\n", i, Gia_ObjLevelId(p, i), Box ); + } + Vec_IntFree( vCounts ); +} /**Function************************************************************* @@ -534,7 +565,7 @@ void Acec_TreeFindTreesTest( Gia_Man_t * p ) SideEffects [] SeeAlso [] - +` ***********************************************************************/ void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ) { @@ -560,6 +591,10 @@ void Acec_TreePrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds ) Vec_WecPrintLits( pBox->vLeafLits ); printf( "Outputs:\n" ); Vec_WecPrintLits( pBox->vRootLits ); +// printf( "Node %d has level %d.\n", 3715, Gia_ObjLevelId(pBox->pGia, 3715) ); +// printf( "Node %d has level %d.\n", 167, Gia_ObjLevelId(pBox->pGia, 167) ); +// printf( "Node %d has level %d.\n", 278, Gia_ObjLevelId(pBox->pGia, 278) ); +// printf( "Node %d has level %d.\n", 597, Gia_ObjLevelId(pBox->pGia, 597) ); } int Acec_CreateBoxMaxRank( Vec_Int_t * vTree ) diff --git a/src/proof/acec/acecXor.c b/src/proof/acec/acecXor.c index ae5aeff76..acbde1a00 100644 --- a/src/proof/acec/acecXor.c +++ b/src/proof/acec/acecXor.c @@ -44,43 +44,43 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -Vec_Int_t * Acec_OrderXorRoots( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vXorRoots, Vec_Wec_t * vXorTrees, Vec_Int_t * vMap ) +Vec_Int_t * Acec_OrderTreeRoots( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vXorRoots, Vec_Int_t * vRanks ) { - Vec_Int_t * vOrder = Vec_IntAlloc( Vec_WecSize(vXorTrees) ); - Vec_Int_t * vReMap = Vec_IntStartFull( Vec_WecSize(vXorTrees) ); + Vec_Int_t * vOrder = Vec_IntAlloc( Vec_IntSize(vXorRoots) ); + Vec_Int_t * vMove = Vec_IntStartFull( Vec_IntSize(vXorRoots) ); int i, k, Entry, This; // iterate through adders and for each try mark the next one for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) { int Node = Vec_IntEntry(vAdds, 6*i+4); - if ( Vec_IntEntry(vMap, Node) == -1 ) + if ( Vec_IntEntry(vRanks, Node) == -1 ) continue; for ( k = 0; k < 3; k++ ) { int Fanin = Vec_IntEntry(vAdds, 6*i+k); - if ( Vec_IntEntry(vMap, Fanin) == -1 ) + if ( Vec_IntEntry(vRanks, Fanin) == -1 ) continue; - //printf( "%4d: %2d -> %2d\n", Node, Vec_IntEntry(vMap, Node), Vec_IntEntry(vMap, Fanin) ); - Vec_IntWriteEntry( vReMap, Vec_IntEntry(vMap, Node), Vec_IntEntry(vMap, Fanin) ); + //printf( "%4d: %2d -> %2d\n", Node, Vec_IntEntry(vRanks, Node), Vec_IntEntry(vRanks, Fanin) ); + Vec_IntWriteEntry( vMove, Vec_IntEntry(vRanks, Node), Vec_IntEntry(vRanks, Fanin) ); } } -//Vec_IntPrint( vReMap ); +//Vec_IntPrint( vMove ); // find reodering - Vec_IntForEachEntry( vReMap, Entry, i ) - if ( Entry == -1 && Vec_IntFind(vReMap, i) >= 0 ) + Vec_IntForEachEntry( vMove, Entry, i ) + if ( Entry == -1 && Vec_IntFind(vMove, i) >= 0 ) break; - assert( i < Vec_IntSize(vReMap) ); + assert( i < Vec_IntSize(vMove) ); while ( 1 ) { Vec_IntPush( vOrder, Vec_IntEntry(vXorRoots, i) ); Entry = i; - Vec_IntForEachEntry( vReMap, This, i ) + Vec_IntForEachEntry( vMove, This, i ) if ( This == Entry ) break; - if ( i == Vec_IntSize(vReMap) ) + if ( i == Vec_IntSize(vMove) ) break; } - Vec_IntFree( vReMap ); + Vec_IntFree( vMove ); //Vec_IntPrint( vOrder ); return vOrder; } @@ -96,6 +96,40 @@ Vec_Int_t * Acec_OrderXorRoots( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vX SeeAlso [] ***********************************************************************/ +// marks XOR outputs +Vec_Bit_t * Acec_MapXorOuts( Gia_Man_t * p, Vec_Int_t * vXors ) +{ + Vec_Bit_t * vMap = Vec_BitStart( Gia_ManObjNum(p) ); int i; + for ( i = 0; 4*i < Vec_IntSize(vXors); i++ ) + Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i), 1 ); + return vMap; +} +// marks XOR outputs participating in trees +Vec_Bit_t * Acec_MapXorOuts2( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vRanks ) +{ + Vec_Bit_t * vMap = Vec_BitStart( Gia_ManObjNum(p) ); int i; + for ( i = 0; 4*i < Vec_IntSize(vXors); i++ ) + if ( Vec_IntEntry(vRanks, Vec_IntEntry(vXors, 4*i)) != -1 ) + Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i), 1 ); + return vMap; +} +// marks MAJ outputs +Vec_Bit_t * Acec_MapMajOuts( Gia_Man_t * p, Vec_Int_t * vAdds ) +{ + Vec_Bit_t * vMap = Vec_BitStart( Gia_ManObjNum(p) ); int i; + for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) + Vec_BitWriteEntry( vMap, Vec_IntEntry(vAdds, 6*i+4), 1 ); + return vMap; +} +// marks MAJ outputs participating in trees +Vec_Int_t * Acec_MapMajOuts2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vRanks ) +{ + Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); int i; + for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) + if ( Vec_IntEntry(vRanks, Vec_IntEntry(vAdds, 6*i+4)) != -1 ) + Vec_IntWriteEntry( vMap, Vec_IntEntry(vAdds, 6*i+4), i ); + return vMap; +} // marks nodes appearing as fanins to XORs Vec_Bit_t * Acec_MapXorIns( Gia_Man_t * p, Vec_Int_t * vXors ) { @@ -108,44 +142,6 @@ Vec_Bit_t * Acec_MapXorIns( Gia_Man_t * p, Vec_Int_t * vXors ) } return vMap; } -// marks nodes having XOR cuts -Vec_Bit_t * Acec_MapXorOuts( Gia_Man_t * p, Vec_Int_t * vXors ) -{ - Vec_Bit_t * vMap = Vec_BitStart( Gia_ManObjNum(p) ); int i; - for ( i = 0; 4*i < Vec_IntSize(vXors); i++ ) - Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i), 1 ); - return vMap; -} -// marks nodes appearing as outputs of MAJs -Vec_Bit_t * Acec_MapMajOuts( Gia_Man_t * p, Vec_Int_t * vAdds ) -{ - Vec_Bit_t * vMap = Vec_BitStart( Gia_ManObjNum(p) ); int i; - for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) - Vec_BitWriteEntry( vMap, Vec_IntEntry(vAdds, 6*i+4), 1 ); - return vMap; -} -// maps MAJ outputs into their FAs and HAs -Vec_Int_t * Acec_MapMajOutsToAdds( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vXorOuts, Vec_Int_t * vMapRank ) -{ - Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); int i; - for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) - { - int Xor = Vec_IntEntry(vAdds, 6*i+3); - int Maj = Vec_IntEntry(vAdds, 6*i+4); - if ( Vec_IntEntry(vMap, Maj) >= 0 ) - { - int i2 = Vec_IntEntry(vMap, Maj); - int Xor2 = Vec_IntEntry(vAdds, 6*i2+3); - int Maj2 = Vec_IntEntry(vAdds, 6*i2+4); - printf( "*** Node %d has two MAJ adder drivers: %d%s (%d rank %d) and %d%s (%d rank %d).\n", - Maj, - i, Vec_IntEntry(vAdds, 6*i+2) ? "":"*", Vec_BitEntry(vXorOuts, Xor), Vec_IntEntry(vMapRank, Xor), - i2, Vec_IntEntry(vAdds, 6*i2+2) ? "":"*", Vec_BitEntry(vXorOuts, Xor2), Vec_IntEntry(vMapRank, Xor2) ); - } - Vec_IntWriteEntry( vMap, Vec_IntEntry(vAdds, 6*i+4), i ); - } - return vMap; -} // collects XOR roots (XOR nodes not appearing as fanins of other XORs) Vec_Int_t * Acec_FindXorRoots( Gia_Man_t * p, Vec_Int_t * vXors ) { @@ -159,103 +155,83 @@ Vec_Int_t * Acec_FindXorRoots( Gia_Man_t * p, Vec_Int_t * vXors ) return vXorRoots; } // collects XOR trees belonging to each of XOR roots -Vec_Wec_t * Acec_FindXorTrees( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vXorRoots, Vec_Int_t ** pvMap ) +Vec_Int_t * Acec_RankTrees( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vXorRoots ) { Vec_Int_t * vDoubles = Vec_IntAlloc( 100 ); - Vec_Wec_t * vXorTrees = Vec_WecStart( Vec_IntSize(vXorRoots) ); - Vec_Int_t * vLevel; int i, k, Entry; - // map roots into their classes - Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); + // map roots into their ranks + Vec_Int_t * vRanks = Vec_IntStartFull( Gia_ManObjNum(p) ); Vec_IntForEachEntry( vXorRoots, Entry, i ) - { - Vec_IntWriteEntry( vMap, Entry, i ); - Vec_WecPush( vXorTrees, i, Entry ); - } - // map nodes into their classes + Vec_IntWriteEntry( vRanks, Entry, i ); + // map nodes into their ranks for ( i = Vec_IntSize(vXors)/4 - 1; i >= 0; i-- ) { int Root = Vec_IntEntry( vXors, 4*i ); - int Repr = Vec_IntEntry( vMap, Root ); - //assert( Repr != -1 ); - if ( Repr == -1 ) + int Rank = Vec_IntEntry( vRanks, Root ); + // skip XORs that are not part of any tree + if ( Rank == -1 ) continue; + // iterate through XOR inputs for ( k = 1; k < 4; k++ ) { int Node = Vec_IntEntry( vXors, 4*i+k ); - if ( Node == 0 ) + if ( Node == 0 ) // HA continue; - Entry = Vec_IntEntry( vMap, Node ); - if ( Entry == Repr ) + Entry = Vec_IntEntry( vRanks, Node ); + if ( Entry == Rank ) // the same tree continue; if ( Entry == -1 ) - { - Vec_IntWriteEntry( vMap, Node, Repr ); - Vec_WecPush( vXorTrees, Repr, Node ); - continue; - } - //printf( "Node %d belongs to Tree %d and Tree %d.\n", Node, Entry, Repr ); - Vec_IntPushUnique( Vec_WecEntry(vXorTrees, Entry), Node ); - Vec_IntPush( vDoubles, Node ); + Vec_IntWriteEntry( vRanks, Node, Rank ); + else + Vec_IntPush( vDoubles, Node ); + //if ( Entry != -1 ) + //printf( "Xor node %d belongs to Tree %d and Tree %d.\n", Node, Entry, Rank ); } } - // clean map + // remove duplicated entries Vec_IntForEachEntry( vDoubles, Entry, i ) - Vec_IntWriteEntry( vMap, Entry, -1 ); + Vec_IntWriteEntry( vRanks, Entry, -1 ); Vec_IntFree( vDoubles ); - // sort nodes - Vec_WecForEachLevel( vXorTrees, vLevel, i ) - Vec_IntSort( vLevel, 0 ); - if ( pvMap ) - *pvMap = vMap; - else - Vec_IntFree( vMap ); - return vXorTrees; + return vRanks; } // collects leaves of each XOR tree -Vec_Wec_t * Acec_FindXorLeaves( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vAdds, Vec_Wec_t * vXorTrees, Vec_Int_t * vMap, Vec_Wec_t ** pvAddBoxes ) +Vec_Wec_t * Acec_FindXorLeaves( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vAdds, Vec_Int_t * vXorRoots, Vec_Int_t * vRanks, Vec_Wec_t ** pvAddBoxes ) { - Vec_Bit_t * vMapXorOuts = Acec_MapXorOuts( p, vXors ); - Vec_Int_t * vMapMajOuts = Acec_MapMajOutsToAdds( p, vAdds, vMapXorOuts, vMap ); - Vec_Wec_t * vXorLeaves = Vec_WecStart( Vec_WecSize(vXorTrees) ); + Vec_Bit_t * vMapXors = Acec_MapXorOuts2( p, vXors, vRanks ); + Vec_Int_t * vMapMajs = Acec_MapMajOuts2( p, vAdds, vRanks ); + Vec_Wec_t * vXorLeaves = Vec_WecStart( Vec_IntSize(vXorRoots) ); + Vec_Wec_t * vAddBoxes = Vec_WecStart( Vec_IntSize(vXorRoots) ); int i, k; - if ( pvAddBoxes ) - *pvAddBoxes = Vec_WecStart( Vec_WecSize(vXorTrees) ); - // collect leaves for ( i = 0; 4*i < Vec_IntSize(vXors); i++ ) { int Xor = Vec_IntEntry(vXors, 4*i); + int Rank = Vec_IntEntry(vRanks, Xor); + if ( Rank == -1 ) + continue; for ( k = 1; k < 4; k++ ) { - int Node = Vec_IntEntry(vXors, 4*i+k); - if ( Node == 0 ) + int Fanin = Vec_IntEntry(vXors, 4*i+k); + if ( Fanin == 0 ) continue; - if ( Vec_BitEntry(vMapXorOuts, Node) || Vec_IntEntry(vMap, Xor) == -1 ) + if ( Vec_BitEntry(vMapXors, Fanin) ) + { + assert( Rank == Vec_IntEntry(vRanks, Fanin) ); continue; - if ( Vec_IntEntry(vMapMajOuts, Node) == -1 ) // no maj driver - Vec_WecPush( vXorLeaves, Vec_IntEntry(vMap, Xor), Node ); - else if ( pvAddBoxes && Vec_IntEntry(vMap, Xor) > 0 ) // save adder box - Vec_WecPush( *pvAddBoxes, Vec_IntEntry(vMap, Xor)-1, Vec_IntEntry(vMapMajOuts, Node) ); + } + if ( Vec_IntEntry(vMapMajs, Fanin) == -1 ) // no adder driving this input + Vec_WecPush( vXorLeaves, Rank, Fanin ); + else if ( Vec_IntEntry(vRanks, Xor) > 0 ) // save adder box + Vec_WecPush( vAddBoxes, Rank-1, Vec_IntEntry(vMapMajs, Fanin) ); } } -/* + Vec_BitFree( vMapXors ); + Vec_IntFree( vMapMajs ); if ( pvAddBoxes ) - { - Vec_Int_t * vLevel; - //Vec_WecPrint( *pvAddBoxes, 0 ); - Vec_WecForEachLevelReverse( *pvAddBoxes, vLevel, i ) - if ( Vec_IntSize(vLevel) > 0 ) - break; - Vec_WecShrink( *pvAddBoxes, i+1 ); - //Vec_WecPrint( *pvAddBoxes, 0 ); - } -*/ - Vec_BitFree( vMapXorOuts ); - Vec_IntFree( vMapMajOuts ); + *pvAddBoxes = vAddBoxes; return vXorLeaves; } -Acec_Box_t * Acec_FindBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vAddBoxes, Vec_Wec_t * vXorTrees, Vec_Wec_t * vXorLeaves ) +Acec_Box_t * Acec_FindBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vAddBoxes, Vec_Wec_t * vXorLeaves, Vec_Int_t * vXorRoots ) { extern Vec_Int_t * Acec_TreeCarryMap( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ); extern void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, int Node, int fPhase, Vec_Bit_t * vVisit ); @@ -275,8 +251,8 @@ Acec_Box_t * Acec_FindBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vAddBox pBox->vLeafLits = Vec_WecStart( MaxRank + 0 ); pBox->vRootLits = Vec_WecStart( MaxRank + 0 ); - assert( Vec_WecSize(vAddBoxes) == Vec_WecSize(vXorTrees) ); assert( Vec_WecSize(vAddBoxes) == Vec_WecSize(vXorLeaves) ); + assert( Vec_WecSize(vAddBoxes) == Vec_IntSize(vXorRoots) ); // collect boxes; mark inputs/outputs Vec_WecForEachLevel( pBox->vAdds, vLevel, i ) @@ -332,12 +308,7 @@ Acec_Box_t * Acec_FindBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vAddBox Vec_IntPush( vLevel, Abc_Var2Lit(Node, 0) ); } vLevel = Vec_WecEntry( pBox->vRootLits, Vec_WecSize(pBox->vRootLits)-1 ); - vLevel2 = Vec_WecEntry( vXorTrees, Vec_WecSize(vXorTrees)-1 ); - Vec_IntClear( vLevel ); - if ( Vec_IntSize(vLevel) == 0 && Vec_IntSize(vLevel2) > 0 ) - { - Vec_IntPush( vLevel, Abc_Var2Lit(Vec_IntEntryLast(vLevel2), 0) ); - } + Vec_IntFill( vLevel, 1, Abc_Var2Lit(Vec_IntEntryLast(vXorRoots), 0) ); // sort each level Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i ) @@ -347,50 +318,49 @@ Acec_Box_t * Acec_FindBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vAddBox return pBox; } -Acec_Box_t * Acec_DetectXorTrees( Gia_Man_t * p, int fVerbose ) +Acec_Box_t * Acec_ProduceBox( Gia_Man_t * p, int fVerbose ) { + extern void Acec_TreeVerifyConnections( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ); + abctime clk = Abc_Clock(); Acec_Box_t * pBox = NULL; Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( p, &vXors, 0 ); - Vec_Int_t * vMap, * vXorRootsNew; - Vec_Int_t * vXorRoots = Acec_FindXorRoots( p, vXors ); - Vec_Wec_t * vXorTrees = Acec_FindXorTrees( p, vXors, vXorRoots, &vMap ); + Vec_Int_t * vTemp, * vXorRoots = Acec_FindXorRoots( p, vXors ); + Vec_Int_t * vRanks = Acec_RankTrees( p, vXors, vXorRoots ); Vec_Wec_t * vXorLeaves, * vAddBoxes = NULL; + Gia_ManLevelNum(p); + //Ree_ManPrintAdders( vAdds, 1 ); printf( "Detected %d full-adders and %d half-adders. Found %d XOR-cuts. ", Ree_ManCountFadds(vAdds), Vec_IntSize(vAdds)/6-Ree_ManCountFadds(vAdds), Vec_IntSize(vXors)/4 ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); -// printf( "XOR roots: \n" ); -// Vec_IntPrint( vXorRoots ); -// Vec_WecPrint( vXorTrees, 0 ); + vXorRoots = Acec_OrderTreeRoots( p, vAdds, vTemp = vXorRoots, vRanks ); + Vec_IntFree( vTemp ); + Vec_IntFree( vRanks ); - vXorRootsNew = Acec_OrderXorRoots( p, vAdds, vXorRoots, vXorTrees, vMap ); - Vec_IntFree( vXorRoots ); - Vec_WecFree( vXorTrees ); - Vec_IntFree( vMap ); + vRanks = Acec_RankTrees( p, vXors, vXorRoots ); + vXorLeaves = Acec_FindXorLeaves( p, vXors, vAdds, vXorRoots, vRanks, &vAddBoxes ); + Vec_IntFree( vRanks ); - vXorRoots = vXorRootsNew; vXorRootsNew = NULL; - vXorTrees = Acec_FindXorTrees( p, vXors, vXorRoots, &vMap ); - vXorLeaves = Acec_FindXorLeaves( p, vXors, vAdds, vXorTrees, vMap, &vAddBoxes ); + //printf( "XOR roots after reordering: \n" ); + //Vec_IntPrint( vXorRoots ); + //printf( "XOR leaves: \n" ); + //Vec_WecPrint( vXorLeaves, 0 ); + //printf( "Adder boxes: \n" ); + //Vec_WecPrint( vAddBoxes, 0 ); - printf( "XOR roots: \n" ); - Vec_IntPrint( vXorRoots ); - printf( "XOR leaves: \n" ); - Vec_WecPrint( vXorLeaves, 0 ); - printf( "Adder boxes: \n" ); - Vec_WecPrint( vAddBoxes, 0 ); + Acec_TreeVerifyConnections( p, vAdds, vAddBoxes ); - pBox = Acec_FindBox( p, vAdds, vAddBoxes, vXorTrees, vXorLeaves ); - - Acec_TreePrintBox( pBox, vAdds ); - - Vec_IntFree( vXorRoots ); - Vec_WecFree( vXorTrees ); - Vec_WecFree( vXorLeaves ); + pBox = Acec_FindBox( p, vAdds, vAddBoxes, vXorLeaves, vXorRoots ); //Vec_WecFree( vAddBoxes ); - Vec_IntFree( vMap ); + if ( fVerbose ) + Acec_TreePrintBox( pBox, vAdds ); + + Vec_IntFree( vXorRoots ); + Vec_WecFree( vXorLeaves ); + Vec_IntFree( vXors ); Vec_IntFree( vAdds ); From 3020d57ea67f7f897c93524b9c3025767db3933b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 29 Jan 2017 13:39:35 -0800 Subject: [PATCH 087/185] Commenting out debug code. --- src/base/wlc/wlcReadVer.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c index 16de49430..e4a65ecfb 100644 --- a/src/base/wlc/wlcReadVer.c +++ b/src/base/wlc/wlcReadVer.c @@ -429,7 +429,6 @@ char * Wlc_PrsConvertInitValues( Wlc_Ntk_t * p ) Vec_Str_t * vStr = Vec_StrAlloc( 1000 ); Vec_IntForEachEntry( p->vInits, Value, i ) { - char * pname = Wlc_ObjName( p, Value ); if ( Value < 0 ) { for ( k = 0; k < -Value; k++ ) From e21c7d72f3f43f38e5af10a38602de6f6ce9a20e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 30 Jan 2017 08:39:26 -0800 Subject: [PATCH 088/185] Updates to arithmetic verification. --- abclib.dsp | 4 + src/aig/gia/giaUtil.c | 4 +- src/base/io/io.c | 2 +- src/proof/acec/acecInt.h | 1 + src/proof/acec/acecMult.c | 66 +++++++++ src/proof/acec/acecStruct.c | 271 ++++++++++++++++++++++++++++++++++++ src/proof/acec/acecXor.c | 67 ++++++++- 7 files changed, 407 insertions(+), 8 deletions(-) create mode 100644 src/proof/acec/acecStruct.c diff --git a/abclib.dsp b/abclib.dsp index cbed067a0..f578fb778 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -5551,6 +5551,10 @@ SOURCE=.\src\proof\acec\acecSt.c # End Source File # Begin Source File +SOURCE=.\src\proof\acec\acecStruct.c +# End Source File +# Begin Source File + SOURCE=.\src\proof\acec\acecTree.c # End Source File # Begin Source File diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index eccdbc733..c7af642ec 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -937,8 +937,8 @@ int Gia_ObjRecognizeExor( Gia_Obj_t * pObj, Gia_Obj_t ** ppFan0, Gia_Obj_t ** pp return 0; if ( Gia_ObjFaninC0(p0) == Gia_ObjFaninC0(p1) || Gia_ObjFaninC1(p0) == Gia_ObjFaninC1(p1) ) return 0; - *ppFan0 = Gia_ObjChild0(p0); - *ppFan1 = Gia_ObjChild1(p0); + if ( ppFan0 ) *ppFan0 = Gia_ObjChild0(p0); + if ( ppFan1 ) *ppFan1 = Gia_ObjChild1(p0); return 1; } diff --git a/src/base/io/io.c b/src/base/io/io.c index 093eccca2..4cec01575 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -2150,7 +2150,7 @@ int IoCommandWriteCnf2( Abc_Frame_t * pAbc, int argc, char **argv ) extern void Mf_ManDumpCnf( Gia_Man_t * p, char * pFileName, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); FILE * pFile; char * pFileName; - int nLutSize = 6; + int nLutSize = 8; int fNewAlgo = 1; int fCnfObjIds = 0; int fAddOrCla = 1; diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index 381ab8d13..c4c8061e1 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -76,6 +76,7 @@ extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdd /*=== acecMult.c ========================================================*/ extern Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits ); extern Vec_Bit_t * Acec_BoothFindPPG( Gia_Man_t * p ); +extern Vec_Bit_t * Acec_MultMarkPPs( Gia_Man_t * p ); /*=== acecNorm.c ========================================================*/ extern void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] ); extern Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ); diff --git a/src/proof/acec/acecMult.c b/src/proof/acec/acecMult.c index ba9405ac2..c63fdde2b 100644 --- a/src/proof/acec/acecMult.c +++ b/src/proof/acec/acecMult.c @@ -433,6 +433,72 @@ Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec return vInputs; } +/**Function************************************************************* + + Synopsis [Mark nodes whose function is exactly that of a Booth PP.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Bit_t * Acec_MultMarkPPs( Gia_Man_t * p ) +{ + word Saved[32] = { + ABC_CONST(0xF335ACC0F335ACC0), + ABC_CONST(0x35C035C035C035C0), + ABC_CONST(0xD728D728D728D728), + ABC_CONST(0xFD80FD80FD80FD80), + ABC_CONST(0xACC0ACC0ACC0ACC0), + ABC_CONST(0x7878787878787878), + ABC_CONST(0x2828282828282828), + ABC_CONST(0xD0D0D0D0D0D0D0D0), + ABC_CONST(0x8080808080808080), + ABC_CONST(0x8888888888888888), + ABC_CONST(0xAAAAAAAAAAAAAAAA), + ABC_CONST(0x5555555555555555), + + ABC_CONST(0xD5A8D5A8D5A8D5A8), + ABC_CONST(0x2A572A572A572A57), + ABC_CONST(0xF3C0F3C0F3C0F3C0), + ABC_CONST(0x5858585858585858), + ABC_CONST(0xA7A7A7A7A7A7A7A7), + ABC_CONST(0x2727272727272727), + ABC_CONST(0xD8D8D8D8D8D8D8D8) + }; + + Vec_Bit_t * vRes = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); + Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); + int i, iObj, nProds = 0; + Gia_ManCleanMark0(p); + Gia_ManForEachAndId( p, iObj ) + { + word Truth = Gia_ObjComputeTruth6Cis( p, Abc_Var2Lit(iObj, 0), vSupp, vTemp ); + if ( Vec_IntSize(vSupp) > 6 ) + continue; + vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize ); + if ( Vec_IntSize(vSupp) > 5 ) + continue; + for ( i = 0; i < 32 && Saved[i]; i++ ) + { + if ( Truth == Saved[i] || Truth == ~Saved[i] ) + { + Vec_BitWriteEntry( vRes, iObj, 1 ); + nProds++; + break; + } + } + } + Gia_ManCleanMark0(p); + printf( "Collected %d pps.\n", nProds ); + Vec_IntFree( vSupp ); + Vec_WrdFree( vTemp ); + return vRes; +} + /**Function************************************************************* Synopsis [] diff --git a/src/proof/acec/acecStruct.c b/src/proof/acec/acecStruct.c new file mode 100644 index 000000000..6702e13be --- /dev/null +++ b/src/proof/acec/acecStruct.c @@ -0,0 +1,271 @@ +/**CFile**************************************************************** + + FileName [acecStruct.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [CEC for arithmetic circuits.] + + Synopsis [Core procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: acecStruct.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "acecInt.h" +#include "misc/vec/vecWec.h" +#include "misc/extra/extra.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Acec_StructDetectXorRoots( Gia_Man_t * p ) +{ + Vec_Int_t * vXors = Vec_IntAlloc( 100 ); + Vec_Bit_t * vXorIns = Vec_BitStart( Gia_ManObjNum(p) ); + Gia_Obj_t * pFan0, * pFan1, * pObj; + int i, k = 0, Entry; + Gia_ManForEachAnd( p, pObj, i ) + { + if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) ) + continue; + Vec_IntPush( vXors, i ); + Vec_BitWriteEntry( vXorIns, Gia_ObjId(p, Gia_Regular(pFan0)), 1 ); + Vec_BitWriteEntry( vXorIns, Gia_ObjId(p, Gia_Regular(pFan1)), 1 ); + } + // collect XORs that not inputs of other XORs + Vec_IntForEachEntry( vXors, Entry, i ) + if ( !Vec_BitEntry(vXorIns, Entry) ) + Vec_IntWriteEntry( vXors, k++, Entry ); + Vec_IntShrink( vXors, k ); + Vec_BitFree( vXorIns ); + return vXors; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Acec_StructAssignRanks( Gia_Man_t * p, Vec_Int_t * vXorRoots ) +{ + Vec_Int_t * vDoubles = Vec_IntAlloc( 100 ); + Gia_Obj_t * pFan0, * pFan1, * pObj; + int i, k, Fanins[2], Entry, Rank; + // map roots into their ranks + Vec_Int_t * vRanks = Vec_IntStartFull( Gia_ManObjNum(p) ); + Vec_IntForEachEntry( vXorRoots, Entry, i ) + Vec_IntWriteEntry( vRanks, Entry, i ); + // map nodes into their ranks + Gia_ManForEachAndReverse( p, pObj, i ) + { + if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) ) + continue; + Rank = Vec_IntEntry( vRanks, i ); + // skip XORs that are not part of any tree + if ( Rank == -1 ) + continue; + // iterate through XOR inputs + Fanins[0] = Gia_ObjId(p, Gia_Regular(pFan0)); + Fanins[1] = Gia_ObjId(p, Gia_Regular(pFan1)); + for ( k = 0; k < 2; k++ ) + { + Entry = Vec_IntEntry( vRanks, Fanins[k] ); + if ( Entry == Rank ) // the same tree -- allow fanout in this tree + continue; + if ( Entry == -1 ) + Vec_IntWriteEntry( vRanks, Fanins[k], Rank ); + else + Vec_IntPush( vDoubles, Fanins[k] ); + if ( Entry != -1 && Gia_ObjIsAnd(Gia_ManObj(p, Fanins[k]))) + printf( "Xor node %d belongs to Tree %d and Tree %d.\n", Fanins[k], Entry, Rank ); + } + } + // remove duplicated entries + Vec_IntForEachEntry( vDoubles, Entry, i ) + Vec_IntWriteEntry( vRanks, Entry, -1 ); + Vec_IntFree( vDoubles ); + return vRanks; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Wec_t * Acec_FindTreeLeaves( Gia_Man_t * p, Vec_Int_t * vXorRoots, Vec_Int_t * vRanks ) +{ + Vec_Bit_t * vMapXors = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Wec_t * vTreeLeaves = Vec_WecStart( Vec_IntSize(vXorRoots) ); + Gia_Obj_t * pFan0, * pFan1, * pObj; + int i, k, Fanins[2], Rank; + Gia_ManForEachAnd( p, pObj, i ) + { + if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) ) + continue; + Vec_BitWriteEntry( vMapXors, i, 1 ); + Rank = Vec_IntEntry( vRanks, i ); + // skip XORs that are not part of any tree + if ( Rank == -1 ) + continue; + // iterate through XOR inputs + Fanins[0] = Gia_ObjId(p, Gia_Regular(pFan0)); + Fanins[1] = Gia_ObjId(p, Gia_Regular(pFan1)); + for ( k = 0; k < 2; k++ ) + { + if ( Vec_BitEntry(vMapXors, Fanins[k]) ) + { + assert( Rank == Vec_IntEntry(vRanks, Fanins[k]) ); + continue; + } + Vec_WecPush( vTreeLeaves, Rank, Fanins[k] ); + } + } + Vec_BitFree( vMapXors ); + return vTreeLeaves; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Acec_FindShadows( Gia_Man_t * p, Vec_Int_t * vRanks ) +{ + Vec_Int_t * vShadows = Vec_IntDup( vRanks ); + Gia_Obj_t * pObj; int i, Shad0, Shad1; + Gia_ManForEachCi( p, pObj, i ) + Vec_IntWriteEntry( vShadows, Gia_ObjId(p, pObj), -1 ); + Gia_ManForEachAnd( p, pObj, i ) + { + if ( Vec_IntEntry(vShadows, i) >= 0 ) + continue; + Shad0 = Vec_IntEntry(vShadows, Gia_ObjFaninId0(pObj, i)); + Shad1 = Vec_IntEntry(vShadows, Gia_ObjFaninId1(pObj, i)); + if ( Shad0 == Shad1 && Shad0 != -1 ) + Vec_IntWriteEntry(vShadows, i, Shad0); + } + return vShadows; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_CollectSupp_rec( Gia_Man_t * p, int iNode, int Rank, Vec_Int_t * vRanks ) +{ + Gia_Obj_t * pObj; + int nSize; + if ( Gia_ObjIsTravIdCurrentId(p, iNode) ) + return 0; + Gia_ObjSetTravIdCurrentId(p, iNode); + pObj = Gia_ManObj(p, iNode); + assert( Gia_ObjIsAnd(pObj) ); + if ( Vec_IntEntry(vRanks, iNode) == Rank ) + return 1; + nSize = Acec_CollectSupp_rec( p, Gia_ObjFaninId0(pObj, iNode), Rank, vRanks ); + nSize += Acec_CollectSupp_rec( p, Gia_ObjFaninId1(pObj, iNode), Rank, vRanks ); + return nSize; +} +Vec_Wec_t * Acec_FindNexts( Gia_Man_t * p, Vec_Int_t * vRanks, Vec_Int_t * vShadows, Vec_Wec_t * vTreeLeaves ) +{ + Vec_Wec_t * vNexts = Vec_WecStart( Vec_WecSize(vTreeLeaves) ); + Vec_Int_t * vTree; + int i, k, Node, Fanins[2], Shad0, Shad1, Rank, nSupp; + Vec_WecForEachLevel( vTreeLeaves, vTree, i ) + Vec_IntForEachEntry( vTree, Node, k ) + { + Gia_Obj_t * pObj = Gia_ManObj(p, Node); + if ( !Gia_ObjIsAnd(pObj) ) + continue; + Fanins[0] = Gia_ObjFaninId0(pObj, Node); + Fanins[1] = Gia_ObjFaninId1(pObj, Node); + Shad0 = Vec_IntEntry(vShadows, Fanins[0]); + Shad1 = Vec_IntEntry(vShadows, Fanins[1]); + if ( Shad0 != Shad1 || Shad0 == -1 ) + continue; + // check support size of Node in terms of the shadow of its fanins + Rank = Vec_IntEntry( vRanks, Node ); + assert( Rank != Shad0 ); + Gia_ManIncrementTravId( p ); + nSupp = Acec_CollectSupp_rec( p, Node, Shad0, vRanks ); + assert( nSupp > 1 ); + if ( nSupp > 3 ) + continue; + Vec_IntPushUniqueOrder( Vec_WecEntry(vNexts, Shad0), Rank ); + } + return vNexts; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_StructTest( Gia_Man_t * p ) +{ +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/acec/acecXor.c b/src/proof/acec/acecXor.c index acbde1a00..71e0b7b39 100644 --- a/src/proof/acec/acecXor.c +++ b/src/proof/acec/acecXor.c @@ -33,6 +33,35 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_CheckXors( Gia_Man_t * p, Vec_Int_t * vXors ) +{ + Gia_Obj_t * pFan0, * pFan1; + Vec_Int_t * vCount2 = Vec_IntAlloc( Gia_ManObjNum(p) ); + int i, Entry, Count = 0; + for ( i = 0; 4*i < Vec_IntSize(vXors); i++ ) + if ( Vec_IntEntry(vXors, 4*i+3) == 0 ) + Vec_IntAddToEntry( vCount2, Vec_IntEntry(vXors, 4*i), 1 ); + Vec_IntForEachEntry( vCount2, Entry, i ) + if ( Entry > 1 ) + printf( "*** Obj %d has %d two-input XOR cuts.\n", i, Entry ), Count++; + else if ( Entry == 1 && Gia_ObjRecognizeExor(Gia_ManObj(p, i), &pFan0, &pFan1) ) + printf( "*** Obj %d cannot be recognized as XOR.\n", i ); + if ( Count == 0 ) + printf( "*** There no multiple two-input XOR cuts.\n" ); + Vec_IntFree( vCount2 ); +} + /**Function************************************************************* Synopsis [] @@ -151,7 +180,6 @@ Vec_Int_t * Acec_FindXorRoots( Gia_Man_t * p, Vec_Int_t * vXors ) if ( !Vec_BitEntry(vMapXorIns, Vec_IntEntry(vXors, 4*i)) ) Vec_IntPushUniqueOrder( vXorRoots, Vec_IntEntry(vXors, 4*i) ); Vec_BitFree( vMapXorIns ); -//Vec_IntRemove( vXorRoots, 54 ); return vXorRoots; } // collects XOR trees belonging to each of XOR roots @@ -184,8 +212,9 @@ Vec_Int_t * Acec_RankTrees( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vXorRo Vec_IntWriteEntry( vRanks, Node, Rank ); else Vec_IntPush( vDoubles, Node ); - //if ( Entry != -1 ) - //printf( "Xor node %d belongs to Tree %d and Tree %d.\n", Node, Entry, Rank ); + + if ( Entry != -1 && Gia_ObjIsAnd(Gia_ManObj(p, Node))) + printf( "Xor node %d belongs to Tree %d and Tree %d.\n", Node, Entry, Rank ); } } // remove duplicated entries @@ -211,6 +240,7 @@ Vec_Wec_t * Acec_FindXorLeaves( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vA for ( k = 1; k < 4; k++ ) { int Fanin = Vec_IntEntry(vXors, 4*i+k); + //int RankFanin = Vec_IntEntry(vRanks, Fanin); if ( Fanin == 0 ) continue; if ( Vec_BitEntry(vMapXors, Fanin) ) @@ -218,6 +248,8 @@ Vec_Wec_t * Acec_FindXorLeaves( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vA assert( Rank == Vec_IntEntry(vRanks, Fanin) ); continue; } +// if ( Vec_BitEntry(vMapXors, Fanin) && Rank == RankFanin ) +// continue; if ( Vec_IntEntry(vMapMajs, Fanin) == -1 ) // no adder driving this input Vec_WecPush( vXorLeaves, Rank, Fanin ); else if ( Vec_IntEntry(vRanks, Xor) > 0 ) // save adder box @@ -230,7 +262,26 @@ Vec_Wec_t * Acec_FindXorLeaves( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vA *pvAddBoxes = vAddBoxes; return vXorLeaves; } +void Acec_CheckBoothPPs( Gia_Man_t * p, Vec_Wec_t * vLitLeaves ) +{ + Vec_Bit_t * vMarked = Acec_MultMarkPPs( p ); + Vec_Int_t * vLevel; + int i, k, iLit; + Vec_WecForEachLevel( vLitLeaves, vLevel, i ) + { + int CountPI = 0, CountB = 0, CountNB = 0; + Vec_IntForEachEntry( vLevel, iLit, k ) + if ( !Gia_ObjIsAnd(Gia_ManObj(p, Abc_Lit2Var(iLit))) ) + CountPI++; + else if ( Vec_BitEntry( vMarked, Abc_Lit2Var(iLit) ) ) + CountB++; + else + CountNB++; + printf( "Rank %2d : Lits = %5d PI = %d Booth = %5d Non-Booth = %5d\n", i, Vec_IntSize(vLevel), CountPI, CountB, CountNB ); + } + Vec_BitFree( vMarked ); +} Acec_Box_t * Acec_FindBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vAddBoxes, Vec_Wec_t * vXorLeaves, Vec_Int_t * vXorRoots ) { extern Vec_Int_t * Acec_TreeCarryMap( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ); @@ -315,6 +366,8 @@ Acec_Box_t * Acec_FindBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vAddBox Vec_IntSort( vLevel, 0 ); Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) Vec_IntSort( vLevel, 1 ); + + //Acec_CheckBoothPPs( p, pBox->vLeafLits ); return pBox; } @@ -331,9 +384,13 @@ Acec_Box_t * Acec_ProduceBox( Gia_Man_t * p, int fVerbose ) Gia_ManLevelNum(p); + //Acec_CheckXors( p, vXors ); + //Ree_ManPrintAdders( vAdds, 1 ); - printf( "Detected %d full-adders and %d half-adders. Found %d XOR-cuts. ", Ree_ManCountFadds(vAdds), Vec_IntSize(vAdds)/6-Ree_ManCountFadds(vAdds), Vec_IntSize(vXors)/4 ); - Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + if ( fVerbose ) + printf( "Detected %d full-adders and %d half-adders. Found %d XOR-cuts. ", Ree_ManCountFadds(vAdds), Vec_IntSize(vAdds)/6-Ree_ManCountFadds(vAdds), Vec_IntSize(vXors)/4 ); + if ( fVerbose ) + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); vXorRoots = Acec_OrderTreeRoots( p, vAdds, vTemp = vXorRoots, vRanks ); Vec_IntFree( vTemp ); From 452a19f70c692372ef694af7f00ea38bf546cf01 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 30 Jan 2017 18:30:59 -0800 Subject: [PATCH 089/185] Improvements to SMT-LIB parser (bug fixes). --- src/base/wlc/wlcReadSmt.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/base/wlc/wlcReadSmt.c b/src/base/wlc/wlcReadSmt.c index 61d0bca89..69a01ab07 100644 --- a/src/base/wlc/wlcReadSmt.c +++ b/src/base/wlc/wlcReadSmt.c @@ -48,6 +48,9 @@ struct Smt_Prs_t_ char ErrorStr[1000]; }; +//#define SMT_GLO_SUFFIX "_glb" +#define SMT_GLO_SUFFIX "" + // parser name types typedef enum { SMT_PRS_NONE = 0, @@ -634,7 +637,10 @@ static inline int Smt_PrsBuildConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits if ( pStr[2+i] == '1' ) Abc_InfoSetBit( (unsigned *)Vec_IntArray(vFanins), nBits-1-i ); else if ( pStr[2+i] != '0' ) + { + Vec_IntFree( vFanins ); return 0; + } } else if ( pStr[1] == 'x' ) // hexadecimal { @@ -643,9 +649,16 @@ static inline int Smt_PrsBuildConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 ); nDigits = Abc_TtReadHexNumber( (word *)Vec_IntArray(vFanins), pStr+2 ); if ( nDigits != (nBits + 3)/4 ) + { + Vec_IntFree( vFanins ); return 0; + } + } + else + { + Vec_IntFree( vFanins ); + return 0; } - else return 0; // create constant node iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_CONST, 0, nBits, vFanins, pName ); Vec_IntFree( vFanins ); @@ -1036,7 +1049,7 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, char * pStr_glb = (char *)malloc(strlen(pStr) + 4 +1); //glb char * pStr_loc = (char *)malloc(strlen(pStr) + strlen(suffix) +1); strcpy(pStr_glb,pStr); - strcat(pStr_glb,"_glb"); + strcat(pStr_glb,SMT_GLO_SUFFIX); strcpy(pStr_loc,pStr); strcat(pStr_loc,suffix); @@ -1105,7 +1118,7 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, else { temp = (char *)malloc(strlen(pName2) + 4 + 1); strcpy(temp, pName2); - strcat(temp,"_glb"); + strcat(temp,SMT_GLO_SUFFIX); } // FIXME: need to delete memory of pName2 pName2 = temp; @@ -1273,7 +1286,7 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) // added: giving a global suffix pName_glb = (char *) malloc(strlen(pName) + 4 + 1); strcpy(pName_glb,pName); - strcat(pName_glb,"_glb"); + strcat(pName_glb,SMT_GLO_SUFFIX); // FIXME: delete memory of pName pName = pName_glb; // skip () @@ -1324,7 +1337,7 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) // added: giving a global suffix char * pName_glb = (char *) malloc(strlen(pName) + 4 + 1); strcpy(pName_glb,pName); - strcat(pName_glb,"_glb"); + strcat(pName_glb,SMT_GLO_SUFFIX); // FIXME: delete memory of pName pName = pName_glb; @@ -1407,7 +1420,7 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) // added: giving a global suffix pName_glb = (char *) malloc(strlen(pName) + 4 + 1); strcpy(pName_glb,pName); - strcat(pName_glb,"_glb"); + strcat(pName_glb,SMT_GLO_SUFFIX); // FIXME: delete memory of pName pName = pName_glb; @@ -1604,6 +1617,7 @@ static inline void Smt_PrsFree( Smt_Prs_t * p ) Vec_IntErase( &p->vStack ); Vec_IntErase( &p->vTempFans ); //Vec_WecErase( &p->vDepth ); + Vec_WecErase( &p->vObjs ); ABC_FREE( p ); } @@ -1634,6 +1648,7 @@ static inline void Smt_PrsSkipNonSpaces( Smt_Prs_t * p ) } void Smt_PrsReadLines( Smt_Prs_t * p ) { + int fFirstTime = 1; assert( Vec_IntSize(&p->vStack) == 0 ); //assert( Vec_WecSize(&p->vDepth) == 0 ); assert( Vec_WecSize(&p->vObjs) == 0 ); @@ -1647,8 +1662,9 @@ void Smt_PrsReadLines( Smt_Prs_t * p ) for ( p->pCur = p->pBuffer; p->pCur < p->pLimit; p->pCur++ ) { Smt_PrsSkipSpaces( p ); - if ( *p->pCur == '|' ) + if ( fFirstTime && *p->pCur == '|' ) { + fFirstTime = 0; *p->pCur = ' '; while ( *p->pCur && *p->pCur != '|' ) *p->pCur++ = ' '; From dc7445e435a56503a7e8e9e3889ef79ae89c4794 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 31 Jan 2017 11:09:38 -0800 Subject: [PATCH 090/185] Typo. --- src/map/scl/scl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/map/scl/scl.c b/src/map/scl/scl.c index bd6d1cea8..9d4653a7d 100644 --- a/src/map/scl/scl.c +++ b/src/map/scl/scl.c @@ -259,7 +259,7 @@ usage: fprintf( pAbc->Err, "\t-d : toggle dumping the parsed library into file \"*_temp.lib\" [default = %s]\n", fDump? "yes": "no" ); fprintf( pAbc->Err, "\t-n : toggle replacing gate/pin names by short strings [default = %s]\n", fShortNames? "yes": "no" ); fprintf( pAbc->Err, "\t-v : toggle writing verbose information [default = %s]\n", fVerbose? "yes": "no" ); - fprintf( pAbc->Err, "\t-v : toggle writing information about skipped gates [default = %s]\n", fVeryVerbose? "yes": "no" ); + fprintf( pAbc->Err, "\t-w : toggle writing information about skipped gates [default = %s]\n", fVeryVerbose? "yes": "no" ); fprintf( pAbc->Err, "\t-h : prints the command summary\n" ); fprintf( pAbc->Err, "\t : the name of a file to read\n" ); return 1; From a226496bf9174b5d50df5a438e1ee52770492f4d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 31 Jan 2017 19:53:57 -0800 Subject: [PATCH 091/185] Adding API for generating a monitor of a set of internal signals in a sequential logic network. --- src/base/abc/abcUtil.c | 154 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c index dd3a75b7c..77b55bb3e 100644 --- a/src/base/abc/abcUtil.c +++ b/src/base/abc/abcUtil.c @@ -2933,6 +2933,160 @@ void Abc_NtkTransferPhases( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk ) Vec_IntWriteEntry( pNtkNew->vPhases, Abc_ObjId( (Abc_Obj_t *)pObj->pCopy ), Vec_IntEntry(pNtk->vPhases, i) ); } +/**Function************************************************************* + + Synopsis [Starts a new network using existing network as a model.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkDeriveWithOnePo( Abc_Ntk_t * pNtk, Vec_Int_t * vNodeIds, Vec_Int_t * vNodeValues ) +{ + int fCopyNames = 1; + Abc_Ntk_t * pNtkNew; + Abc_Obj_t * pObj, * pFanin, * pObjNew, * pOutputNew; + Vec_Ptr_t * vFanins = Vec_PtrAlloc( 100 ); + int i, k, Id, Value; + // start the network + pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 ); + // duplicate the name and the spec + pNtkNew->pName = Extra_UtilStrsav(pNtk->pName); + pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec); + // clean the node copy fields + Abc_NtkCleanCopy( pNtk ); + // map the constant nodes + if ( Abc_NtkIsStrash(pNtk) && Abc_NtkIsStrash(pNtkNew) ) + Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew); + // clone CIs/CIs/boxes + Abc_NtkForEachPi( pNtk, pObj, i ) + Abc_NtkDupObj( pNtkNew, pObj, fCopyNames ); + //Abc_NtkForEachPo( pNtk, pObj, i ) + // Abc_NtkDupObj( pNtkNew, pObj, fCopyNames ); + // create one PO + pObjNew = Abc_NtkCreateObj( pNtkNew, ABC_OBJ_PO ); + Abc_ObjAssignName( pObjNew, "monitor", NULL ); + // create boxes + Abc_NtkForEachBox( pNtk, pObj, i ) + Abc_NtkDupBox( pNtkNew, pObj, fCopyNames ); + + // duplicate nodes (CIs/COs/latches are already duplicated) + Abc_NtkForEachObj( pNtk, pObj, i ) + if ( pObj->pCopy == NULL && !Abc_ObjIsPo(pObj) ) + Abc_NtkDupObj(pNtkNew, pObj, 0); + // reconnect all objects except boxes (they are already connected) and POs (they will be connected later) + Abc_NtkForEachObj( pNtk, pObj, i ) + if ( !Abc_ObjIsPo(pObj) && !Abc_ObjIsBox(pObj) && !Abc_ObjIsBo(pObj) ) + Abc_ObjForEachFanin( pObj, pFanin, k ) + Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); + + // AND nodes (with interters if needed) + pOutputNew = NULL; + Vec_IntForEachEntryTwo( vNodeIds, vNodeValues, Id, Value, i ) + { + pObjNew = Abc_NtkObj( pNtk, Id )->pCopy; + if ( Value == 0 ) // negative polarity - add inverter + pObjNew = Abc_NtkCreateNodeInv( pNtkNew, pObjNew ); + if ( pOutputNew == NULL ) + pOutputNew = pObjNew; + else + { + Vec_PtrFillTwo( vFanins, 2, pOutputNew, pObjNew ); + pOutputNew = Abc_NtkCreateNodeAnd( pNtkNew, vFanins ); + } + } + Vec_PtrFree( vFanins ); + // create the only POs, which is the AND of the corresponding nodes + Abc_ObjAddFanin( Abc_NtkPo(pNtkNew, 0), pOutputNew ); + + // check that the CI/CO/latches are copied correctly + assert( Abc_NtkPoNum(pNtkNew) == 1 ); + assert( Abc_NtkCiNum(pNtkNew) == Abc_NtkCiNum(pNtk) ); + assert( Abc_NtkLatchNum(pNtkNew) == Abc_NtkLatchNum(pNtk) ); + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Derives the AIG representing a property.] + + Description [Given is a sequential logic network (Abc_Ntk_t) and + an array of nodes (vector of object IDs) and their values (vector of 0s or 1s). + This procedure creates a sequential AIG (Abc_Ntk_t), which can be given to a + sequential model checker (in particular "pdr") to prove that the given + combination of values never appears at the intenal nodes of the network, + or produce a counter-example showing that it can appear.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkCreatePropertyMonitor( Abc_Ntk_t * p, Vec_Int_t * vNodeIds, Vec_Int_t * vNodeValues ) +{ + Abc_Ntk_t * pMonitor, * pStrashed, * pResult; + // sequential cleanup parameters + int fLatchConst = 1; + int fLatchEqual = 1; + int fSaveNames = 1; + int fUseMvSweep = 0; + int nFramesSymb = 1; + int nFramesSatur = 512; + int fVerbose = 0; + int fVeryVerbose = 0; + // expecting sequential logic network + assert( Abc_NtkIsLogic(p) ); + assert( Abc_NtkLatchNum(p) > 0 ); + assert( Vec_IntSize(vNodeIds) > 0 ); + assert( Vec_IntSize(vNodeIds) == Vec_IntSize(vNodeValues) ); + // derive ABC network whose only output is 1 iff the given nodes have the given values + pMonitor = Abc_NtkDeriveWithOnePo( p, vNodeIds, vNodeValues ); + // perform structural hashing + pStrashed = Abc_NtkStrash( pMonitor, 0, 1, 0 ); + Abc_NtkDelete( pMonitor ); + // it is a good idea to run sequential cleanup before giving the network to PDR + pResult = Abc_NtkDarLatchSweep( pStrashed, fLatchConst, fLatchEqual, fSaveNames, fUseMvSweep, nFramesSymb, nFramesSatur, fVerbose, fVeryVerbose ); + Abc_NtkDelete( pStrashed ); + return pResult; +} + +/**Function************************************************************* + + Synopsis [Testbench.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkCreatePropertyMonitorTest( Abc_Ntk_t * p ) +{ + Abc_Ntk_t * pNtk; + Vec_Int_t * vNodeIds = Vec_IntAlloc( 100 ); + Vec_Int_t * vNodeValues = Vec_IntAlloc( 100 ); + + // this test will only work for the network, which has nodes with internal IDs such as these + Vec_IntPush( vNodeIds, 90 ); + Vec_IntPush( vNodeIds, 80 ); + Vec_IntPush( vNodeIds, 100 ); + + Vec_IntPush( vNodeValues, 1 ); + Vec_IntPush( vNodeValues, 0 ); + Vec_IntPush( vNodeValues, 1 ); + + pNtk = Abc_NtkCreatePropertyMonitor( p, vNodeIds, vNodeValues ); + + Vec_IntFree( vNodeIds ); + Vec_IntFree( vNodeValues ); + + return pNtk; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// From f14ee271abe8d38a6dad8789d4b4dbc207fe23c4 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 2 Feb 2017 12:44:54 -0800 Subject: [PATCH 092/185] Reordering if-statements in the xsat solver. --- src/sat/xsat/xsatSolver.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/sat/xsat/xsatSolver.c b/src/sat/xsat/xsatSolver.c index 9a98eec00..9807e1b70 100644 --- a/src/sat/xsat/xsatSolver.c +++ b/src/sat/xsat/xsatSolver.c @@ -680,12 +680,10 @@ unsigned xSAT_SolverPropagate( xSAT_Solver_t* s ) nProp++; for ( i = begin; i < end; i++ ) { - if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( i->Blocker ) ) == xSAT_LitSign( xSAT_NegLit( i->Blocker ) ) ) - { - return i->CRef; - } - else if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( i->Blocker ) ) == VarX ) + if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( i->Blocker ) ) == VarX ) xSAT_SolverEnqueue( s, i->Blocker, i->CRef ); + else if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( i->Blocker ) ) == xSAT_LitSign( xSAT_NegLit( i->Blocker ) ) ) + return i->CRef; } ws = xSAT_VecWatchListEntry( s->vWatches, p ); From e91abd6307e15d9d4a4985146025e12ae6780cff Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 2 Feb 2017 16:03:40 -0800 Subject: [PATCH 093/185] Improvements to inductive generalization in IC3/PDR by Zyad Hassan. --- src/base/abci/abc.c | 35 +++++- src/proof/pdr/pdr.h | 3 + src/proof/pdr/pdrCore.c | 255 ++++++++++++++++++++++++++++++++++++++- src/proof/pdr/pdrInt.h | 4 + src/proof/pdr/pdrSat.c | 6 +- src/proof/pdr/pdrTsim.c | 4 +- src/proof/pdr/pdrUtil.c | 79 ++++++++++++ src/sat/bsat/satSolver.c | 120 ++++++++++++++++++ src/sat/bsat/satSolver.h | 2 + 9 files changed, 495 insertions(+), 13 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 806a5de79..7ff404b05 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26008,7 +26008,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Pdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGaxrmsipdegovwzh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmsipdegoncvwzh" ) ) != EOF ) { switch ( c ) { @@ -26100,6 +26100,17 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nTimeOutGap < 0 ) goto usage; break; + case 'S': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nRandomSeed = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nRandomSeed < 0 ) + goto usage; + break; case 'a': pPars->fSolveAll ^= 1; break; @@ -26133,6 +26144,12 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'o': pPars->fUsePropOut ^= 1; break; + case 'n': + pPars->fSkipDown ^= 1; + break; + case 'c': + pPars->fCtgs ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; @@ -26174,9 +26191,9 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: pdr [-MFCDRTHG ] [-axrmsipdegovwzh]\n" ); + Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmsipdegoncvwzh]\n" ); Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); - Abc_Print( -2, "\t pioneered by Aaron Bradley (http://ecee.colorado.edu/~bradleya/ic3/)\n" ); + Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); Abc_Print( -2, "\t-M num : limit on unused vars to trigger SAT solver recycling [default = %d]\n", pPars->nRecycle ); Abc_Print( -2, "\t-F num : limit on timeframes explored to stop computation [default = %d]\n", pPars->nFrameMax ); @@ -26186,6 +26203,7 @@ usage: Abc_Print( -2, "\t-T num : runtime limit, in seconds (0 = no limit) [default = %d]\n", pPars->nTimeOut ); Abc_Print( -2, "\t-H num : runtime limit per output, in miliseconds (with \"-a\") [default = %d]\n", pPars->nTimeOutOne ); Abc_Print( -2, "\t-G num : runtime gap since the last CEX (0 = no limit) [default = %d]\n", pPars->nTimeOutGap ); + Abc_Print( -2, "\t-S num : * value to seed the SAT solver with [default = %d]\n", pPars->nRandomSeed ); Abc_Print( -2, "\t-a : toggle solving all outputs even if one of them is SAT [default = %s]\n", pPars->fSolveAll? "yes": "no" ); Abc_Print( -2, "\t-x : toggle storing CEXes when solving all outputs [default = %s]\n", pPars->fStoreCex? "yes": "no" ); Abc_Print( -2, "\t-r : toggle using more effort in generalization [default = %s]\n", pPars->fTwoRounds? "yes": "no" ); @@ -26197,10 +26215,19 @@ usage: Abc_Print( -2, "\t-e : toggle using only support variables in the invariant [default = %s]\n", pPars->fUseSupp? "yes": "no" ); Abc_Print( -2, "\t-g : toggle skipping expensive generalization step [default = %s]\n", pPars->fSkipGeneral? "yes": "no" ); Abc_Print( -2, "\t-o : toggle using property output as inductive hypothesis [default = %s]\n", pPars->fUsePropOut? "yes": "no" ); + Abc_Print( -2, "\t-n : * toggle skipping \'down\' in generalization [default = %s]\n", pPars->fSkipDown? "yes": "no" ); + Abc_Print( -2, "\t-c : * toggle handling CTGs in \'down\' [default = %s]\n", pPars->fCtgs? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-w : toggle printing detailed stats default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); Abc_Print( -2, "\t-z : toggle suppressing report about solved outputs [default = %s]\n", pPars->fNotVerbose? "yes": "no" ); - Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "\t-h : print the command usage\n\n"); + Abc_Print( -2, "\t* Implementation of switches -S, -n, and -c is contributed by Zyad Hassan.\n"); + Abc_Print( -2, "\t The theory and experiments supporting this work can be found in the following paper:\n"); + Abc_Print( -2, "\t Zyad Hassan, Aaron R. Bradley, Fabio Somenzi, \"Better Generalization in IC3\", FMCAD 2013.\n"); + Abc_Print( -2, "\t (http://www.cs.utexas.edu/users/hunt/FMCAD/FMCAD13/papers/85-Better-Generalization-IC3.pdf)\n"); + + + return 1; } diff --git a/src/proof/pdr/pdr.h b/src/proof/pdr/pdr.h index 529a161f9..b73a54df9 100644 --- a/src/proof/pdr/pdr.h +++ b/src/proof/pdr/pdr.h @@ -49,6 +49,7 @@ struct Pdr_Par_t_ int nTimeOut; // timeout in seconds int nTimeOutGap; // approximate timeout in seconds since the last change int nTimeOutOne; // approximate timeout in seconds per one output + int nRandomSeed; // value to seed the SAT solver with int fTwoRounds; // use two rounds for generalization int fMonoCnf; // monolythic CNF int fDumpInv; // dump inductive invariant @@ -57,6 +58,8 @@ struct Pdr_Par_t_ int fShiftStart; // allows clause pushing to start from an intermediate frame int fReuseProofOblig; // reuses proof-obligationgs in the last timeframe int fSkipGeneral; // skips expensive generalization step + int fSkipDown; // skips the application of down + int fCtgs; // handle CTGs in down int fVerbose; // verbose output` int fVeryVerbose; // very verbose output int fNotVerbose; // not printing line by line progress diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index b81a1a2a3..71a61c813 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -20,6 +20,7 @@ #include "pdrInt.h" #include "base/main/main.h" +#include "misc/hash/hash.h" ABC_NAMESPACE_IMPL_START @@ -57,7 +58,10 @@ void Pdr_ManSetDefaultParams( Pdr_Par_t * pPars ) pPars->nConfLimit = 0; // limit on SAT solver conflicts pPars->nConfGenLimit = 0; // limit on SAT solver conflicts during generalization pPars->nRestLimit = 0; // limit on the number of proof-obligations + pPars->nRandomSeed = 91648253; // value to seed the SAT solver with pPars->fTwoRounds = 0; // use two rounds for generalization + pPars->fSkipDown = 1; // apply down in generalization + pPars->fCtgs = 0; // handle CTGs in down pPars->fMonoCnf = 0; // monolythic CNF pPars->fDumpInv = 0; // dump inductive invariant pPars->fUseSupp = 1; // using support variables in the invariant @@ -294,6 +298,190 @@ int * Pdr_ManSortByPriority( Pdr_Man_t * p, Pdr_Set_t * pCube ) } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int ZPdr_ManSimpleMic( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube ) +{ + int * pOrder; + int i, j, n, Lit, RetValue; + Pdr_Set_t * pCubeTmp; + // perform generalization + if ( p->pPars->fSkipGeneral ) + return 0; + + // sort literals by their occurences + pOrder = Pdr_ManSortByPriority( p, *ppCube ); + // try removing literals + for ( j = 0; j < (*ppCube)->nLits; j++ ) + { + // use ordering + // i = j; + i = pOrder[j]; + + assert( (*ppCube)->Lits[i] != -1 ); + // check init state + if ( Pdr_SetIsInit(*ppCube, i) ) + continue; + // try removing this literal + Lit = (*ppCube)->Lits[i]; (*ppCube)->Lits[i] = -1; + RetValue = Pdr_ManCheckCube( p, k, *ppCube, NULL, p->pPars->nConfLimit, 0 ); + if ( RetValue == -1 ) + return -1; + (*ppCube)->Lits[i] = Lit; + if ( RetValue == 0 ) + continue; + + // remove j-th entry + for ( n = j; n < (*ppCube)->nLits-1; n++ ) + pOrder[n] = pOrder[n+1]; + j--; + + // success - update the cube + *ppCube = Pdr_SetCreateFrom( pCubeTmp = *ppCube, i ); + Pdr_SetDeref( pCubeTmp ); + assert( (*ppCube)->nLits > 0 ); + i--; + + // get the ordering by decreasing priorit + pOrder = Pdr_ManSortByPriority( p, *ppCube ); + } + return 0; +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, Hash_Int_t * keep, Pdr_Set_t * pIndCube, int * added ) +{ + int RetValue = 0, CtgRetValue, i, ctgAttempts, l, micResult; + int kMax = Vec_PtrSize(p->vSolvers)-1; + Pdr_Set_t * pCubeTmp, * pCubeMin, * pCtg; + while ( RetValue == 0 ) + { + ctgAttempts = 0; + while ( p->pPars->fCtgs && RetValue == 0 && k > 1 && ctgAttempts < 3 ) + { + pCtg = Pdr_SetDup ( pPred ); + //Check CTG for inductiveness + if ( Pdr_SetIsInit( pCtg, -1 ) ) + { + Pdr_SetDeref( pCtg ); + break; + } + if (*added == 0) + { + for ( i = 1; i <= k; i++ ) + Pdr_ManSolverAddClause( p, i, pIndCube); + *added = 1; + } + ctgAttempts++; + CtgRetValue = Pdr_ManCheckCube ( p, k-1, pCtg, NULL, p->pPars->nConfLimit, 0 ); + if ( CtgRetValue != 1 ) + { + Pdr_SetDeref( pCtg ); + break; + } + pCubeMin = Pdr_ManReduceClause( p, k-1, pCtg ); + if ( pCubeMin == NULL ) + pCubeMin = Pdr_SetDup ( pCtg ); + + for ( l = k; l < kMax; l++ ) + if ( !Pdr_ManCheckCube( p, l, pCubeMin, NULL, 0, 0 ) ) + break; + micResult = ZPdr_ManSimpleMic( p, l-1, &pCubeMin ); + assert ( micResult != -1 ); + + // add new clause + if ( p->pPars->fVeryVerbose ) + { + Abc_Print( 1, "Adding cube " ); + Pdr_SetPrint( stdout, pCubeMin, Aig_ManRegNum(p->pAig), NULL ); + Abc_Print( 1, " to frame %d.\n", l ); + } + // set priority flops + for ( i = 0; i < pCubeMin->nLits; i++ ) + { + assert( pCubeMin->Lits[i] >= 0 ); + assert( (pCubeMin->Lits[i] / 2) < Aig_ManRegNum(p->pAig) ); + Vec_IntAddToEntry( p->vPrio, pCubeMin->Lits[i] / 2, 1 ); + } + + Vec_VecPush( p->vClauses, l, pCubeMin ); // consume ref + p->nCubes++; + // add clause + for ( i = 1; i <= l; i++ ) + Pdr_ManSolverAddClause( p, i, pCubeMin ); + RetValue = Pdr_ManCheckCube ( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0 ); + assert( RetValue >= 0 ); + Pdr_SetDeref( pCtg ); + if ( RetValue == 1 ) + { + //printf ("IT'S A ONE\n"); + return 1; + } + } + + //join + if ( p->pPars->fVeryVerbose ) + { + printf("Cube:\n"); + ZPdr_SetPrint( *ppCube ); + printf("\nPred:\n"); + ZPdr_SetPrint( pPred ); + } + *ppCube = ZPdr_SetIntersection( pCubeTmp = *ppCube, pPred, keep ); + Pdr_SetDeref( pCubeTmp ); + Pdr_SetDeref( pPred ); + if ( *ppCube == NULL ) + return 0; + if ( p->pPars->fVeryVerbose ) + { + printf("Intersection:\n"); + ZPdr_SetPrint( *ppCube ); + } + if ( Pdr_SetIsInit( *ppCube, -1 ) ) + { + if ( p->pPars->fVeryVerbose ) + printf ("Failed initiation\n"); + return 0; + } + RetValue = Pdr_ManCheckCube ( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0 ); + if ( RetValue == -1 ) + return -1; + if ( RetValue == 1 ) + { + //printf ("*********IT'S A ONE\n"); + break; + } + if ( RetValue == 0 && (*ppCube)->nLits == 1) + { + Pdr_SetDeref( pPred ); // fixed memory leak + // A workaround for the incomplete assignment returned by the SAT + // solver + return 0; + } + } + return 1; +} /**Function************************************************************* Synopsis [Returns 1 if the state could be blocked.] @@ -307,10 +495,12 @@ int * Pdr_ManSortByPriority( Pdr_Man_t * p, Pdr_Set_t * pCube ) ***********************************************************************/ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPred, Pdr_Set_t ** ppCubeMin ) { - Pdr_Set_t * pCubeMin, * pCubeTmp = NULL; + Pdr_Set_t * pCubeMin, * pCubeTmp = NULL, * pPred = NULL, * pCubeCpy = NULL; int i, j, n, Lit, RetValue; abctime clk = Abc_Clock(); int * pOrder; + int added = 0; + Hash_Int_t * keep = NULL; // if there is no induction, return *ppCubeMin = NULL; RetValue = Pdr_ManCheckCube( p, k, pCube, ppPred, p->pPars->nConfLimit, 0 ); @@ -318,9 +508,11 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP return -1; if ( RetValue == 0 ) { - p->tGeneral += Abc_Clock() - clk; + p->tGeneral += clock() - clk; return 0; } + + keep = p->pPars->fSkipDown ? NULL : Hash_IntAlloc( 1 ); // reduce clause using assumptions // pCubeMin = Pdr_SetDup( pCube ); @@ -340,13 +532,22 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP // i = j; i = pOrder[j]; - // check init state assert( pCubeMin->Lits[i] != -1 ); + if ( keep && Hash_IntExists( keep, pCubeMin->Lits[i] ) ) + { + //printf("Undroppable\n"); + continue; + } + + // check init state if ( Pdr_SetIsInit(pCubeMin, i) ) continue; // try removing this literal - Lit = pCubeMin->Lits[i]; pCubeMin->Lits[i] = -1; - RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 1 ); + Lit = pCubeMin->Lits[i]; pCubeMin->Lits[i] = -1; + if ( p->pPars->fSkipDown ) + RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 1 ); + else + RetValue = Pdr_ManCheckCube( p, k, pCubeMin, &pPred, p->pPars->nConfLimit, 1 ); if ( RetValue == -1 ) { Pdr_SetDeref( pCubeMin ); @@ -354,7 +555,39 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP } pCubeMin->Lits[i] = Lit; if ( RetValue == 0 ) + { + if ( p->pPars->fSkipDown ) + continue; + pCubeCpy = Pdr_SetCreateFrom ( pCubeMin, i ); + RetValue = ZPdr_ManDown ( p, k, &pCubeCpy, pPred, keep, pCubeMin, &added ); + if ( p->pPars->fCtgs ) + //CTG handling code messes up with the internal order array + pOrder = Pdr_ManSortByPriority( p, pCubeMin ); + if ( RetValue == -1 ) + { + Pdr_SetDeref( pCubeMin ); + Pdr_SetDeref( pCubeCpy ); + Pdr_SetDeref( pPred ); + return -1; + } + if ( RetValue == 0 ) + { + if ( keep ) + Hash_IntWriteEntry( keep, pCubeMin->Lits[i], 0 ); + if ( pCubeCpy ) + Pdr_SetDeref( pCubeCpy ); continue; + } + //Inductive subclause + added = 0; + Pdr_SetDeref( pCubeMin ); + pCubeMin = pCubeCpy; + assert( pCubeMin->nLits > 0 ); + pOrder = Pdr_ManSortByPriority( p, pCubeMin ); + j = -1; + continue; + } + added = 0; // remove j-th entry for ( n = j; n < pCubeMin->nLits-1; n++ ) @@ -383,7 +616,7 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP if ( Pdr_SetIsInit(pCubeMin, i) ) continue; // try removing this literal - Lit = pCubeMin->Lits[i]; pCubeMin->Lits[i] = -1; + Lit = pCubeMin->Lits[i]; pCubeMin->Lits[i] = -1; RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 0 ); if ( RetValue == -1 ) { @@ -411,8 +644,18 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP } assert( ppCubeMin != NULL ); + if ( p->pPars->fVeryVerbose ) + { + printf("Cube:\n"); + for ( i = 0; i < pCubeMin->nLits; i++) + { + printf ("%d ", pCubeMin->Lits[i]); + } + printf("\n"); + } *ppCubeMin = pCubeMin; p->tGeneral += Abc_Clock() - clk; + if ( keep ) Hash_IntFree( keep ); return 1; } diff --git a/src/proof/pdr/pdrInt.h b/src/proof/pdr/pdrInt.h index 6a08a1508..9c1e9840a 100644 --- a/src/proof/pdr/pdrInt.h +++ b/src/proof/pdr/pdrInt.h @@ -30,6 +30,7 @@ #include "sat/cnf/cnf.h" #include "sat/bsat/satSolver.h" #include "pdr.h" +#include "misc/hash/hashInt.h" ABC_NAMESPACE_HEADER_START @@ -196,10 +197,13 @@ extern Pdr_Set_t * Pdr_SetCreateSubset( Pdr_Set_t * pSet, int * pLits, int n extern Pdr_Set_t * Pdr_SetDup( Pdr_Set_t * pSet ); extern Pdr_Set_t * Pdr_SetRef( Pdr_Set_t * p ); extern void Pdr_SetDeref( Pdr_Set_t * p ); +extern Pdr_Set_t * ZPdr_SetIntersection( Pdr_Set_t * p1, Pdr_Set_t * p2, Hash_Int_t * keep ); extern int Pdr_SetContains( Pdr_Set_t * pOld, Pdr_Set_t * pNew ); extern int Pdr_SetContainsSimple( Pdr_Set_t * pOld, Pdr_Set_t * pNew ); extern int Pdr_SetIsInit( Pdr_Set_t * p, int iRemove ); +extern int ZPdr_SetIsInit( Pdr_Set_t * p ); extern void Pdr_SetPrint( FILE * pFile, Pdr_Set_t * p, int nRegs, Vec_Int_t * vFlopCounts ); +extern void ZPdr_SetPrint( Pdr_Set_t * p ); extern void Pdr_SetPrintStr( Vec_Str_t * vStr, Pdr_Set_t * p, int nRegs, Vec_Int_t * vFlopCounts ); extern int Pdr_SetCompare( Pdr_Set_t ** pp1, Pdr_Set_t ** pp2 ); extern Pdr_Obl_t * Pdr_OblStart( int k, int prio, Pdr_Set_t * pState, Pdr_Obl_t * pNext ); diff --git a/src/proof/pdr/pdrSat.c b/src/proof/pdr/pdrSat.c index 2e6130aa7..eb94a8263 100644 --- a/src/proof/pdr/pdrSat.c +++ b/src/proof/pdr/pdrSat.c @@ -51,7 +51,8 @@ sat_solver * Pdr_ManCreateSolver( Pdr_Man_t * p, int k ) assert( Vec_VecSize(p->vClauses) == k ); assert( Vec_IntSize(p->vActVars) == k ); // create new solver - pSat = sat_solver_new(); +// pSat = sat_solver_new(); + pSat = zsat_solver_new_seed(p->pPars->nRandomSeed); pSat = Pdr_ManNewSolver( pSat, p, k, (int)(k == 0) ); Vec_PtrPush( p->vSolvers, pSat ); Vec_VecExpand( p->vClauses, k ); @@ -86,7 +87,8 @@ sat_solver * Pdr_ManFetchSolver( Pdr_Man_t * p, int k ) p->nStarts++; // sat_solver_delete( pSat ); // pSat = sat_solver_new(); - sat_solver_restart( pSat ); +// sat_solver_restart( pSat ); + zsat_solver_restart_seed( pSat, p->pPars->nRandomSeed ); // create new SAT solver pSat = Pdr_ManNewSolver( pSat, p, k, (int)(k == 0) ); // write new SAT solver diff --git a/src/proof/pdr/pdrTsim.c b/src/proof/pdr/pdrTsim.c index 32d1c8573..37f846679 100644 --- a/src/proof/pdr/pdrTsim.c +++ b/src/proof/pdr/pdrTsim.c @@ -476,7 +476,9 @@ Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, vCi2Rem ); assert( Vec_IntSize(vRes) > 0 ); p->tTsim += Abc_Clock() - clk; pRes = Pdr_SetCreate( vRes, vPiLits ); - assert( k == 0 || !Pdr_SetIsInit(pRes, -1) ); + //ZH: Disabled assertion because this invariant doesn't hold with down + //because of the join operation which can bring in initial states + //assert( k == 0 || !Pdr_SetIsInit(pRes, -1) ); return pRes; } diff --git a/src/proof/pdr/pdrUtil.c b/src/proof/pdr/pdrUtil.c index 32e977727..8fb83fd25 100644 --- a/src/proof/pdr/pdrUtil.c +++ b/src/proof/pdr/pdrUtil.c @@ -249,6 +249,85 @@ void Pdr_SetPrint( FILE * pFile, Pdr_Set_t * p, int nRegs, Vec_Int_t * vFlopCoun ABC_FREE( pBuff ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void ZPdr_SetPrint( Pdr_Set_t * p ) +{ + int i; + for ( i = 0; i < p->nLits; i++) + printf ("%d ", p->Lits[i]); + printf ("\n"); + +} + +/**Function************************************************************* + + Synopsis [Return the intersection of p1 and p2.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Pdr_Set_t * ZPdr_SetIntersection( Pdr_Set_t * p1, Pdr_Set_t * p2, Hash_Int_t * keep ) +{ + Pdr_Set_t * pIntersection; + Vec_Int_t * vCommonLits, * vPiLits; + int i, j, nLits; + nLits = p1->nLits; + if ( p2->nLits < nLits ) + nLits = p2->nLits; + vCommonLits = Vec_IntAlloc( nLits ); + vPiLits = Vec_IntAlloc( 1 ); + for ( i = 0, j = 0; i < p1->nLits && j < p2->nLits; ) + { + if ( p1->Lits[i] > p2->Lits[j] ) + { + if ( Hash_IntExists( keep, p2->Lits[j] ) ) + { + //about to drop a literal that should not be dropped + Vec_IntFree( vCommonLits ); + Vec_IntFree( vPiLits ); + return NULL; + } + j++; + } + else if ( p1->Lits[i] < p2->Lits[j] ) + { + if ( Hash_IntExists( keep, p1->Lits[i] ) ) + { + //about to drop a literal that should not be dropped + Vec_IntFree( vCommonLits ); + Vec_IntFree( vPiLits ); + return NULL; + } + i++; + } + else + { + Vec_IntPush( vCommonLits, p1->Lits[i] ); + i++; + j++; + } + } + pIntersection = Pdr_SetCreate( vCommonLits, vPiLits ); + Vec_IntFree( vCommonLits ); + Vec_IntFree( vPiLits ); + return pIntersection; +} + + /**Function************************************************************* Synopsis [] diff --git a/src/sat/bsat/satSolver.c b/src/sat/bsat/satSolver.c index 88a05093a..3295fc6fe 100644 --- a/src/sat/bsat/satSolver.c +++ b/src/sat/bsat/satSolver.c @@ -1085,6 +1085,77 @@ sat_solver* sat_solver_new(void) return s; } +sat_solver* zsat_solver_new_seed(double seed) +{ + sat_solver* s = (sat_solver*)ABC_CALLOC( char, sizeof(sat_solver)); + +// Vec_SetAlloc_(&s->Mem, 15); + Sat_MemAlloc_(&s->Mem, 15); + s->hLearnts = -1; + s->hBinary = Sat_MemAppend( &s->Mem, NULL, 2, 0, 0 ); + s->binary = clause_read( s, s->hBinary ); + + s->nLearntStart = LEARNT_MAX_START_DEFAULT; // starting learned clause limit + s->nLearntDelta = LEARNT_MAX_INCRE_DEFAULT; // delta of learned clause limit + s->nLearntRatio = LEARNT_MAX_RATIO_DEFAULT; // ratio of learned clause limit + s->nLearntMax = s->nLearntStart; + + // initialize vectors + veci_new(&s->order); + veci_new(&s->trail_lim); + veci_new(&s->tagged); +// veci_new(&s->learned); + veci_new(&s->act_clas); + veci_new(&s->stack); +// veci_new(&s->model); + veci_new(&s->act_vars); + veci_new(&s->unit_lits); + veci_new(&s->temp_clause); + veci_new(&s->conf_final); + + // initialize arrays + s->wlists = 0; + s->activity = 0; + s->orderpos = 0; + s->reasons = 0; + s->trail = 0; + + // initialize other vars + s->size = 0; + s->cap = 0; + s->qhead = 0; + s->qtail = 0; +#ifdef USE_FLOAT_ACTIVITY + s->var_inc = 1; + s->cla_inc = 1; + s->var_decay = (float)(1 / 0.95 ); + s->cla_decay = (float)(1 / 0.999); +#else + s->var_inc = (1 << 5); + s->cla_inc = (1 << 11); +#endif + s->root_level = 0; +// s->simpdb_assigns = 0; +// s->simpdb_props = 0; + s->random_seed = seed; + s->progress_estimate = 0; +// s->binary = (clause*)ABC_ALLOC( char, sizeof(clause) + sizeof(lit)*2); +// s->binary->size_learnt = (2 << 1); + s->verbosity = 0; + + s->stats.starts = 0; + s->stats.decisions = 0; + s->stats.propagations = 0; + s->stats.inspects = 0; + s->stats.conflicts = 0; + s->stats.clauses = 0; + s->stats.clauses_literals = 0; + s->stats.learnts = 0; + s->stats.learnts_literals = 0; + s->stats.tot_literals = 0; + return s; +} + void sat_solver_setnvars(sat_solver* s,int n) { int var; @@ -1248,6 +1319,55 @@ void sat_solver_restart( sat_solver* s ) s->stats.tot_literals = 0; } +void zsat_solver_restart_seed( sat_solver* s, double seed ) +{ + int i; + Sat_MemRestart( &s->Mem ); + s->hLearnts = -1; + s->hBinary = Sat_MemAppend( &s->Mem, NULL, 2, 0, 0 ); + s->binary = clause_read( s, s->hBinary ); + + veci_resize(&s->act_clas, 0); + veci_resize(&s->trail_lim, 0); + veci_resize(&s->order, 0); + for ( i = 0; i < s->size*2; i++ ) + s->wlists[i].size = 0; + + s->nDBreduces = 0; + + // initialize other vars + s->size = 0; +// s->cap = 0; + s->qhead = 0; + s->qtail = 0; +#ifdef USE_FLOAT_ACTIVITY + s->var_inc = 1; + s->cla_inc = 1; + s->var_decay = (float)(1 / 0.95 ); + s->cla_decay = (float)(1 / 0.999 ); +#else + s->var_inc = (1 << 5); + s->cla_inc = (1 << 11); +#endif + s->root_level = 0; +// s->simpdb_assigns = 0; +// s->simpdb_props = 0; + s->random_seed = seed; + s->progress_estimate = 0; + s->verbosity = 0; + + s->stats.starts = 0; + s->stats.decisions = 0; + s->stats.propagations = 0; + s->stats.inspects = 0; + s->stats.conflicts = 0; + s->stats.clauses = 0; + s->stats.clauses_literals = 0; + s->stats.learnts = 0; + s->stats.learnts_literals = 0; + s->stats.tot_literals = 0; +} + // returns memory in bytes used by the SAT solver double sat_solver_memory( sat_solver* s ) { diff --git a/src/sat/bsat/satSolver.h b/src/sat/bsat/satSolver.h index 162b91e52..6ed611e15 100644 --- a/src/sat/bsat/satSolver.h +++ b/src/sat/bsat/satSolver.h @@ -42,6 +42,7 @@ struct sat_solver_t; typedef struct sat_solver_t sat_solver; extern sat_solver* sat_solver_new(void); +extern sat_solver* zsat_solver_new_seed(double seed); extern void sat_solver_delete(sat_solver* s); extern int sat_solver_addclause(sat_solver* s, lit* begin, lit* end); @@ -54,6 +55,7 @@ extern int sat_solver_push(sat_solver* s, int p); extern void sat_solver_pop(sat_solver* s); extern void sat_solver_set_resource_limits(sat_solver* s, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, ABC_INT64_T nConfLimitGlobal, ABC_INT64_T nInsLimitGlobal); extern void sat_solver_restart( sat_solver* s ); +extern void zsat_solver_restart_seed( sat_solver* s, double seed ); extern void sat_solver_rollback( sat_solver* s ); extern int sat_solver_nvars(sat_solver* s); From 6d088bc440fb6b7a5b3eb2c9ea7b9950a1698166 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 3 Feb 2017 17:02:36 -0800 Subject: [PATCH 094/185] Enabling new X-valued simulation in 'pdr'. --- abclib.dsp | 4 + src/base/abci/abc.c | 8 +- src/proof/pdr/module.make | 1 + src/proof/pdr/pdr.h | 1 + src/proof/pdr/pdrCore.c | 1 + src/proof/pdr/pdrInt.h | 8 + src/proof/pdr/pdrMan.c | 4 + src/proof/pdr/pdrSat.c | 9 +- src/proof/pdr/pdrTsim.c | 4 +- src/proof/pdr/pdrTsim2.c | 389 ++++++++++++++++++++++++++++++++++++++ 10 files changed, 424 insertions(+), 5 deletions(-) create mode 100644 src/proof/pdr/pdrTsim2.c diff --git a/abclib.dsp b/abclib.dsp index f578fb778..d6b769668 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -5263,6 +5263,10 @@ SOURCE=.\src\proof\pdr\pdrTsim.c # End Source File # Begin Source File +SOURCE=.\src\proof\pdr\pdrTsim2.c +# End Source File +# Begin Source File + SOURCE=.\src\proof\pdr\pdrUtil.c # End Source File # End Group diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 7ff404b05..b8a0a301a 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26008,7 +26008,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Pdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmsipdegoncvwzh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmusipdegoncvwzh" ) ) != EOF ) { switch ( c ) { @@ -26123,6 +26123,9 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'm': pPars->fMonoCnf ^= 1; break; + case 'u': + pPars->fNewXSim ^= 1; + break; case 's': pPars->fShortest ^= 1; break; @@ -26191,7 +26194,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmsipdegoncvwzh]\n" ); + Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmusipdegoncvwzh]\n" ); Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); @@ -26208,6 +26211,7 @@ usage: Abc_Print( -2, "\t-x : toggle storing CEXes when solving all outputs [default = %s]\n", pPars->fStoreCex? "yes": "no" ); Abc_Print( -2, "\t-r : toggle using more effort in generalization [default = %s]\n", pPars->fTwoRounds? "yes": "no" ); Abc_Print( -2, "\t-m : toggle using monolythic CNF computation [default = %s]\n", pPars->fMonoCnf? "yes": "no" ); + Abc_Print( -2, "\t-u : toggle updated X-valued simulation [default = %s]\n", pPars->fNewXSim? "yes": "no" ); Abc_Print( -2, "\t-s : toggle creating only shortest counter-examples [default = %s]\n", pPars->fShortest? "yes": "no" ); Abc_Print( -2, "\t-i : toggle clause pushing from an intermediate timeframe [default = %s]\n", pPars->fShiftStart? "yes": "no" ); Abc_Print( -2, "\t-p : toggle reusing proof-obligations in the last timeframe [default = %s]\n", pPars->fReuseProofOblig? "yes": "no" ); diff --git a/src/proof/pdr/module.make b/src/proof/pdr/module.make index 5bee83f81..2967aeb83 100644 --- a/src/proof/pdr/module.make +++ b/src/proof/pdr/module.make @@ -4,4 +4,5 @@ SRC += src/proof/pdr/pdrCnf.c \ src/proof/pdr/pdrMan.c \ src/proof/pdr/pdrSat.c \ src/proof/pdr/pdrTsim.c \ + src/proof/pdr/pdrTsim2.c \ src/proof/pdr/pdrUtil.c diff --git a/src/proof/pdr/pdr.h b/src/proof/pdr/pdr.h index b73a54df9..9f9ef238d 100644 --- a/src/proof/pdr/pdr.h +++ b/src/proof/pdr/pdr.h @@ -52,6 +52,7 @@ struct Pdr_Par_t_ int nRandomSeed; // value to seed the SAT solver with int fTwoRounds; // use two rounds for generalization int fMonoCnf; // monolythic CNF + int fNewXSim; // updated X-valued simulation int fDumpInv; // dump inductive invariant int fUseSupp; // use support in the invariant int fShortest; // forces bug traces to be shortest diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index 71a61c813..38792ef89 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -63,6 +63,7 @@ void Pdr_ManSetDefaultParams( Pdr_Par_t * pPars ) pPars->fSkipDown = 1; // apply down in generalization pPars->fCtgs = 0; // handle CTGs in down pPars->fMonoCnf = 0; // monolythic CNF + pPars->fNewXSim = 0; // updated X-valued simulation pPars->fDumpInv = 0; // dump inductive invariant pPars->fUseSupp = 1; // using support variables in the invariant pPars->fShortest = 0; // forces bug traces to be shortest diff --git a/src/proof/pdr/pdrInt.h b/src/proof/pdr/pdrInt.h index 9c1e9840a..f47c08a9a 100644 --- a/src/proof/pdr/pdrInt.h +++ b/src/proof/pdr/pdrInt.h @@ -42,6 +42,8 @@ ABC_NAMESPACE_HEADER_START /// BASIC TYPES /// //////////////////////////////////////////////////////////////////////// +typedef struct Txs_Man_t_ Txs_Man_t; + typedef struct Pdr_Set_t_ Pdr_Set_t; struct Pdr_Set_t_ { @@ -87,6 +89,8 @@ struct Pdr_Man_t_ int * pOrder; // ordering of the lits Vec_Int_t * vActVars; // the counter of activation variables int iUseFrame; // the first used frame + // terminary simulation + Txs_Man_t * pTxs; // internal use Vec_Int_t * vPrio; // priority flops Vec_Int_t * vLits; // array of literals @@ -189,6 +193,10 @@ extern int Pdr_ManCheckCubeCs( Pdr_Man_t * p, int k, Pdr_Set_t * pCu extern int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPred, int nConfLimit, int fTryConf ); /*=== pdrTsim.c ==========================================================*/ extern Pdr_Set_t * Pdr_ManTernarySim( Pdr_Man_t * p, int k, Pdr_Set_t * pCube ); +/*=== pdrTsim2.c ==========================================================*/ +extern Txs_Man_t * Txs_ManStart( Pdr_Man_t * pMan, Aig_Man_t * pAig, Vec_Int_t * vPrio ); +extern void Txs_ManStop( Txs_Man_t * ); +extern Pdr_Set_t * Txs_ManTernarySim( Txs_Man_t * p, int k, Pdr_Set_t * pCube ); /*=== pdrUtil.c ==========================================================*/ extern Pdr_Set_t * Pdr_SetAlloc( int nSize ); extern Pdr_Set_t * Pdr_SetCreate( Vec_Int_t * vLits, Vec_Int_t * vPiLits ); diff --git a/src/proof/pdr/pdrMan.c b/src/proof/pdr/pdrMan.c index b58c479bb..eb12e3418 100644 --- a/src/proof/pdr/pdrMan.c +++ b/src/proof/pdr/pdrMan.c @@ -70,6 +70,8 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio p->vSuppLits= Vec_IntAlloc( 100 ); // support literals p->pCubeJust= Pdr_SetAlloc( Saig_ManRegNum(pAig) ); p->pCnfMan = Cnf_ManStart(); + // ternary simulation + p->pTxs = Txs_ManStart( p, pAig, p->vPrio ); // additional AIG data-members if ( pAig->pFanData == NULL ) Aig_ManFanoutStart( pAig ); @@ -150,6 +152,8 @@ void Pdr_ManStop( Pdr_Man_t * p ) Vec_WecFreeP( &p->vVLits ); // CNF manager Cnf_ManStop( p->pCnfMan ); + // terminary simulation + Txs_ManStop( p->pTxs ); // internal use Vec_IntFreeP( &p->vPrio ); // priority flops Vec_IntFree( p->vLits ); // array of literals diff --git a/src/proof/pdr/pdrSat.c b/src/proof/pdr/pdrSat.c index eb94a8263..49b0448a0 100644 --- a/src/proof/pdr/pdrSat.c +++ b/src/proof/pdr/pdrSat.c @@ -377,7 +377,14 @@ int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPr p->tSatSat += clk; p->nCallsS++; if ( ppPred ) - *ppPred = Pdr_ManTernarySim( p, k, pCube ); + { + abctime clk = Abc_Clock(); + if ( p->pPars->fNewXSim ) + *ppPred = Txs_ManTernarySim( p->pTxs, k, pCube ); + else + *ppPred = Pdr_ManTernarySim( p, k, pCube ); + p->tTsim += Abc_Clock() - clk; + } RetValue = 0; } diff --git a/src/proof/pdr/pdrTsim.c b/src/proof/pdr/pdrTsim.c index 37f846679..43f2ddb0b 100644 --- a/src/proof/pdr/pdrTsim.c +++ b/src/proof/pdr/pdrTsim.c @@ -364,7 +364,7 @@ Pdr_Set_t * Pdr_ManTernarySim( Pdr_Man_t * p, int k, Pdr_Set_t * pCube ) Vec_Int_t * vRes = p->vRes; // final result (flop literals) Aig_Obj_t * pObj; int i, Entry, RetValue; - abctime clk = Abc_Clock(); + //abctime clk = Abc_Clock(); // collect CO objects Vec_IntClear( vCoObjs ); @@ -474,7 +474,7 @@ Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, vCi2Rem ); // derive the set of resulting registers Pdr_ManDeriveResult( p->pAig, vCiObjs, vCiVals, vCi2Rem, vRes, vPiLits ); assert( Vec_IntSize(vRes) > 0 ); - p->tTsim += Abc_Clock() - clk; + //p->tTsim += Abc_Clock() - clk; pRes = Pdr_SetCreate( vRes, vPiLits ); //ZH: Disabled assertion because this invariant doesn't hold with down //because of the join operation which can bring in initial states diff --git a/src/proof/pdr/pdrTsim2.c b/src/proof/pdr/pdrTsim2.c new file mode 100644 index 000000000..82e9a56c7 --- /dev/null +++ b/src/proof/pdr/pdrTsim2.c @@ -0,0 +1,389 @@ +/**CFile**************************************************************** + + FileName [pdrTsim.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Property driven reachability.] + + Synopsis [Improved ternary simulation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - November 20, 2010.] + + Revision [$Id: pdrTsim.c,v 1.00 2010/11/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "pdrInt.h" +#include "aig/gia/giaAig.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +struct Txs_Man_t_ +{ + Gia_Man_t * pGia; // user's AIG + Vec_Int_t * vPrio; // priority of each flop + Vec_Int_t * vCiObjs; // cone leaves (CI obj IDs) + Vec_Int_t * vCoObjs; // cone roots (CO obj IDs) + Vec_Int_t * vCiVals; // cone leaf values (0/1 CI values) + Vec_Int_t * vCoVals; // cone root values (0/1 CO values) + Vec_Int_t * vNodes; // cone nodes (node obj IDs) + Vec_Int_t * vPiLits; // resulting array of PI literals + Vec_Int_t * vFfLits; // resulting array of flop literals + Pdr_Man_t * pMan; // calling manager +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Start and stop the ternary simulation engine.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Txs_Man_t * Txs_ManStart( Pdr_Man_t * pMan, Aig_Man_t * pAig, Vec_Int_t * vPrio ) +{ + Txs_Man_t * p; +// Aig_Obj_t * pObj; +// int i; + assert( Vec_IntSize(vPrio) == Aig_ManRegNum(pAig) ); + p = ABC_CALLOC( Txs_Man_t, 1 ); + p->pGia = Gia_ManFromAigSimple(pAig); // user's AIG +// Aig_ManForEachObj( pAig, pObj, i ) +// assert( i == 0 || pObj->iData == Abc_Var2Lit(i, 0) ); + p->vPrio = vPrio; // priority of each flop + p->vCiObjs = Vec_IntAlloc( 100 ); // cone leaves (CI obj IDs) + p->vCoObjs = Vec_IntAlloc( 100 ); // cone roots (CO obj IDs) + p->vCiVals = Vec_IntAlloc( 100 ); // cone leaf values (0/1 CI values) + p->vCoVals = Vec_IntAlloc( 100 ); // cone root values (0/1 CO values) + p->vNodes = Vec_IntAlloc( 100 ); // cone nodes (node obj IDs) + p->vPiLits = Vec_IntAlloc( 100 ); // resulting array of PI literals + p->vFfLits = Vec_IntAlloc( 100 ); // resulting array of flop literals + p->pMan = pMan; // calling manager + return p; +} +void Txs_ManStop( Txs_Man_t * p ) +{ + Gia_ManStop( p->pGia ); + Vec_IntFree( p->vCiObjs ); + Vec_IntFree( p->vCoObjs ); + Vec_IntFree( p->vCiVals ); + Vec_IntFree( p->vCoVals ); + Vec_IntFree( p->vNodes ); + Vec_IntFree( p->vPiLits ); + Vec_IntFree( p->vFfLits ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Marks the TFI cone and collects CIs and nodes.] + + Description [For this procedure to work Value should not be ~0 + at the beginning.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Txs_ManCollectCone_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vCiObjs, Vec_Int_t * vNodes ) +{ + if ( !~pObj->Value ) + return; + pObj->Value = ~0; + if ( Gia_ObjIsCi(pObj) ) + { + Vec_IntPush( vCiObjs, Gia_ObjId(p, pObj) ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + Txs_ManCollectCone_rec( p, Gia_ObjFanin0(pObj), vCiObjs, vNodes ); + Txs_ManCollectCone_rec( p, Gia_ObjFanin1(pObj), vCiObjs, vNodes ); + Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); +} +void Txs_ManCollectCone( Gia_Man_t * p, Vec_Int_t * vCoObjs, Vec_Int_t * vCiObjs, Vec_Int_t * vNodes ) +{ + Gia_Obj_t * pObj; int i; +// printf( "Collecting cones for clause with %d literals.\n", Vec_IntSize(vCoObjs) ); + Vec_IntClear( vCiObjs ); + Vec_IntClear( vNodes ); + Gia_ManConst0(p)->Value = ~0; + Gia_ManForEachObjVec( vCoObjs, p, pObj, i ) + Txs_ManCollectCone_rec( p, Gia_ObjFanin0(pObj), vCiObjs, vNodes ); +} + +/**Function************************************************************* + + Synopsis [Propagate values and assign priority.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Txs_ManForwardPass( Gia_Man_t * p, + Vec_Int_t * vPrio, Vec_Int_t * vCiObjs, Vec_Int_t * vCiVals, + Vec_Int_t * vNodes, Vec_Int_t * vCoObjs, Vec_Int_t * vCoVals ) +{ + Gia_Obj_t * pObj, * pFan0, * pFan1; int i; + pObj = Gia_ManConst0(p); + pObj->fMark0 = 0; + pObj->fMark1 = 0; + Gia_ManForEachObjVec( vCiObjs, p, pObj, i ) + { + pObj->fMark0 = Vec_IntEntry(vCiVals, i); + pObj->fMark1 = 0; + pObj->Value = Gia_ObjIsPi(p, pObj) ? 0x7FFFFFFF : Vec_IntEntry(vPrio, Gia_ObjCioId(pObj)-Gia_ManPiNum(p)); + assert( ~pObj->Value ); + } + Gia_ManForEachObjVec( vNodes, p, pObj, i ) + { + pFan0 = Gia_ObjFanin0(pObj); + pFan1 = Gia_ObjFanin1(pObj); + pObj->fMark0 = (pFan0->fMark0 ^ Gia_ObjFaninC0(pObj)) & (pFan1->fMark0 ^ Gia_ObjFaninC1(pObj)); + pObj->fMark1 = 0; + if ( pObj->fMark0 ) + pObj->Value = Abc_MinInt( pFan0->Value, pFan1->Value ); + else if ( pFan0->fMark0 ) + pObj->Value = pFan1->Value; + else if ( pFan1->fMark0 ) + pObj->Value = pFan0->Value; + else // if ( pFan0->fMark0 == 0 && pFan1->fMark0 == 0 ) + pObj->Value = Abc_MaxInt( pFan0->Value, pFan1->Value ); + assert( ~pObj->Value ); + } + Gia_ManForEachObjVec( vCoObjs, p, pObj, i ) + { + pFan0 = Gia_ObjFanin0(pObj); + pObj->fMark0 = (pFan0->fMark0 ^ Gia_ObjFaninC0(pObj)); + pFan0->fMark1 = 1; + assert( (int)pObj->fMark0 == Vec_IntEntry(vCoVals, i) ); + } +} + +/**Function************************************************************* + + Synopsis [Propagate requirements and collect results.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Txs_ObjIsJust( Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + Gia_Obj_t * pFan0 = Gia_ObjFanin0(pObj); + Gia_Obj_t * pFan1 = Gia_ObjFanin1(pObj); + int value0 = pFan0->fMark0 ^ Gia_ObjFaninC0(pObj); + int value1 = pFan1->fMark0 ^ Gia_ObjFaninC1(pObj); + assert( Gia_ObjIsAnd(pObj) ); + if ( pObj->fMark0 ) + return pFan0->fMark1 && pFan1->fMark1; + assert( !pObj->fMark0 ); + assert( !value0 || !value1 ); + if ( value0 ) + return pFan1->fMark1; + if ( value1 ) + return pFan0->fMark1; + assert( !value0 && !value1 ); + return pFan0->fMark1 || pFan1->fMark1 || Gia_ObjIsPi(p, pFan0) || Gia_ObjIsPi(p, pFan1); +} +void Txs_ManBackwardPass( Gia_Man_t * p, Vec_Int_t * vCiObjs, Vec_Int_t * vNodes, Vec_Int_t * vPiLits, Vec_Int_t * vFfLits ) +{ + Gia_Obj_t * pObj, * pFan0, * pFan1; int i, value0, value1; + Gia_ManForEachObjVecReverse( vNodes, p, pObj, i ) + { + if ( !pObj->fMark1 ) + continue; + pFan0 = Gia_ObjFanin0(pObj); + pFan1 = Gia_ObjFanin1(pObj); + if ( pObj->fMark0 ) + { + pFan0->fMark1 = 1; + pFan1->fMark1 = 1; + continue; + } + value0 = pFan0->fMark0 ^ Gia_ObjFaninC0(pObj); + value1 = pFan1->fMark0 ^ Gia_ObjFaninC1(pObj); + assert( !value0 || !value1 ); + if ( value0 ) + pFan1->fMark1 = 1; + else if ( value1 ) + pFan0->fMark1 = 1; + else // if ( !value0 && !value1 ) + { + if ( pFan0->fMark1 || pFan1->fMark1 ) + continue; + if ( Gia_ObjIsPi(p, pFan0) ) + pFan0->fMark1 = 1; + else if ( Gia_ObjIsPi(p, pFan1) ) + pFan1->fMark1 = 1; + else if ( Gia_ObjIsAnd(pFan0) && Txs_ObjIsJust(p, pFan0) ) + pFan0->fMark1 = 1; + else if ( Gia_ObjIsAnd(pFan1) && Txs_ObjIsJust(p, pFan1) ) + pFan1->fMark1 = 1; + else + { + if ( pFan0->Value >= pFan1->Value ) + pFan0->fMark1 = 1; + else + pFan1->fMark1 = 1; + } + } + } + Vec_IntClear( vPiLits ); + Vec_IntClear( vFfLits ); + Gia_ManForEachObjVec( vCiObjs, p, pObj, i ) + { + if ( !pObj->fMark1 ) + continue; + if ( Gia_ObjIsPi(p, pObj) ) + Vec_IntPush( vPiLits, Abc_Var2Lit(Gia_ObjCioId(pObj), !pObj->fMark0) ); + else + Vec_IntPush( vFfLits, Abc_Var2Lit(Gia_ObjCioId(pObj)-Gia_ManPiNum(p), !pObj->fMark0) ); + } + assert( Vec_IntSize(vFfLits) > 0 ); +} + +/**Function************************************************************* + + Synopsis [Verify the result.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Txs_ManVerify( Gia_Man_t * p, Vec_Int_t * vCiObjs, Vec_Int_t * vNodes, Vec_Int_t * vPiLits, Vec_Int_t * vFfLits, Vec_Int_t * vCoObjs, Vec_Int_t * vCoVals ) +{ + Gia_Obj_t * pObj; + int i, iLit; + Gia_ObjTerSimSet0( Gia_ManConst0(p) ); + Gia_ManForEachObjVec( vCiObjs, p, pObj, i ) + Gia_ObjTerSimSetX( pObj ); + Vec_IntForEachEntry( vPiLits, iLit, i ) + { + pObj = Gia_ManPi( p, Abc_Lit2Var(iLit) ); + assert( Gia_ObjTerSimGetX(pObj) ); + if ( Abc_LitIsCompl(iLit) ) + Gia_ObjTerSimSet0( pObj ); + else + Gia_ObjTerSimSet1( pObj ); + } + Vec_IntForEachEntry( vFfLits, iLit, i ) + { + pObj = Gia_ManCi( p, Gia_ManPiNum(p) + Abc_Lit2Var(iLit) ); + assert( Gia_ObjTerSimGetX(pObj) ); + if ( Abc_LitIsCompl(iLit) ) + Gia_ObjTerSimSet0( pObj ); + else + Gia_ObjTerSimSet1( pObj ); + } + Gia_ManForEachObjVec( vNodes, p, pObj, i ) + Gia_ObjTerSimAnd( pObj ); + Gia_ManForEachObjVec( vCoObjs, p, pObj, i ) + { + Gia_ObjTerSimCo( pObj ); + if ( Vec_IntEntry(vCoVals, i) ) + assert( Gia_ObjTerSimGet1(pObj) ); + else + assert( Gia_ObjTerSimGet0(pObj) ); + } +} + +/**Function************************************************************* + + Synopsis [Shrinks values using ternary simulation.] + + Description [The cube contains the set of flop index literals which, + when converted into a clause and applied to the combinational outputs, + led to a satisfiable SAT run in frame k (values stored in the SAT solver). + If the cube is NULL, it is assumed that the first property output was + asserted and failed. + The resulting array is a set of flop index literals that asserts the COs. + Priority contains 0 for i-th entry if the i-th FF is desirable to remove.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Pdr_Set_t * Txs_ManTernarySim( Txs_Man_t * p, int k, Pdr_Set_t * pCube ) +{ + Pdr_Set_t * pRes; + Gia_Obj_t * pObj; + // collect CO objects + Vec_IntClear( p->vCoObjs ); + if ( pCube == NULL ) // the target is the property output + { + pObj = Gia_ManCo(p->pGia, p->pMan->iOutCur); + Vec_IntPush( p->vCoObjs, Gia_ObjId(p->pGia, pObj) ); + } + else // the target is the cube + { + int i; + for ( i = 0; i < pCube->nLits; i++ ) + { + if ( pCube->Lits[i] == -1 ) + continue; + pObj = Gia_ManCo(p->pGia, Gia_ManPoNum(p->pGia) + Abc_Lit2Var(pCube->Lits[i])); + Vec_IntPush( p->vCoObjs, Gia_ObjId(p->pGia, pObj) ); + } + } +if ( 0 ) +{ +Abc_Print( 1, "Trying to justify cube " ); +if ( pCube ) + Pdr_SetPrint( stdout, pCube, Gia_ManRegNum(p->pGia), NULL ); +else + Abc_Print( 1, "" ); +Abc_Print( 1, " in frame %d.\n", k ); +} + + // collect CI objects + Txs_ManCollectCone( p->pGia, p->vCoObjs, p->vCiObjs, p->vNodes ); + // collect values + Pdr_ManCollectValues( p->pMan, k, p->vCiObjs, p->vCiVals ); + Pdr_ManCollectValues( p->pMan, k, p->vCoObjs, p->vCoVals ); + + // perform two passes + Txs_ManForwardPass( p->pGia, p->vPrio, p->vCiObjs, p->vCiVals, p->vNodes, p->vCoObjs, p->vCoVals ); + Txs_ManBackwardPass( p->pGia, p->vCiObjs, p->vNodes, p->vPiLits, p->vFfLits ); + Txs_ManVerify( p->pGia, p->vCiObjs, p->vNodes, p->vPiLits, p->vFfLits, p->vCoObjs, p->vCoVals ); + + // derive the final set + pRes = Pdr_SetCreate( p->vFfLits, p->vPiLits ); + //ZH: Disabled assertion because this invariant doesn't hold with down + //because of the join operation which can bring in initial states + //assert( k == 0 || !Pdr_SetIsInit(pRes, -1) ); + return pRes; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END From a2cebd3e205751bf6e01d509c9568926069b6ab5 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 3 Feb 2017 17:32:44 -0800 Subject: [PATCH 095/185] Removing dead code in 'pdr'. --- src/proof/pdr/pdrInt.h | 3 --- src/proof/pdr/pdrMan.c | 4 --- src/proof/pdr/pdrSat.c | 18 ------------- src/proof/pdr/pdrUtil.c | 56 ----------------------------------------- 4 files changed, 81 deletions(-) diff --git a/src/proof/pdr/pdrInt.h b/src/proof/pdr/pdrInt.h index f47c08a9a..89b6f0d0f 100644 --- a/src/proof/pdr/pdrInt.h +++ b/src/proof/pdr/pdrInt.h @@ -103,8 +103,6 @@ struct Pdr_Man_t_ Vec_Int_t * vVisits; // intermediate Vec_Int_t * vCi2Rem; // CIs to be removed Vec_Int_t * vRes; // final result - Vec_Int_t * vSuppLits; // support literals - Pdr_Set_t * pCubeJust; // justification abctime * pTime4Outs;// timeout per output Vec_Ptr_t * vInfCubes; // infinity clauses/cubes // statistics @@ -224,7 +222,6 @@ extern void Pdr_QueueClean( Pdr_Man_t * p ); extern void Pdr_QueuePush( Pdr_Man_t * p, Pdr_Obl_t * pObl ); extern void Pdr_QueuePrint( Pdr_Man_t * p ); extern void Pdr_QueueStop( Pdr_Man_t * p ); -extern int Pdr_ManCubeJust( Pdr_Man_t * p, int k, Pdr_Set_t * pCube ); ABC_NAMESPACE_HEADER_END diff --git a/src/proof/pdr/pdrMan.c b/src/proof/pdr/pdrMan.c index eb12e3418..31446290a 100644 --- a/src/proof/pdr/pdrMan.c +++ b/src/proof/pdr/pdrMan.c @@ -67,8 +67,6 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio p->vVisits = Vec_IntAlloc( 100 ); // intermediate p->vCi2Rem = Vec_IntAlloc( 100 ); // CIs to be removed p->vRes = Vec_IntAlloc( 100 ); // final result - p->vSuppLits= Vec_IntAlloc( 100 ); // support literals - p->pCubeJust= Pdr_SetAlloc( Saig_ManRegNum(pAig) ); p->pCnfMan = Cnf_ManStart(); // ternary simulation p->pTxs = Txs_ManStart( p, pAig, p->vPrio ); @@ -166,9 +164,7 @@ void Pdr_ManStop( Pdr_Man_t * p ) Vec_IntFree( p->vVisits ); // intermediate Vec_IntFree( p->vCi2Rem ); // CIs to be removed Vec_IntFree( p->vRes ); // final result - Vec_IntFree( p->vSuppLits ); // support literals Vec_PtrFreeP( &p->vInfCubes ); - ABC_FREE( p->pCubeJust ); ABC_FREE( p->pTime4Outs ); if ( p->vCexes ) Vec_PtrFreeFree( p->vCexes ); diff --git a/src/proof/pdr/pdrSat.c b/src/proof/pdr/pdrSat.c index 49b0448a0..936a8f908 100644 --- a/src/proof/pdr/pdrSat.c +++ b/src/proof/pdr/pdrSat.c @@ -342,24 +342,6 @@ int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPr else return -1; } -/* - if ( RetValue == l_True ) - { - int RetValue2 = Pdr_ManCubeJust( p, k, pCube ); - if ( RetValue2 ) - p->nCasesSS++; - else - p->nCasesSU++; - } - else - { - int RetValue2 = Pdr_ManCubeJust( p, k, pCube ); - if ( RetValue2 ) - p->nCasesUS++; - else - p->nCasesUU++; - } -*/ } clk = Abc_Clock() - clk; p->tSat += clk; diff --git a/src/proof/pdr/pdrUtil.c b/src/proof/pdr/pdrUtil.c index 8fb83fd25..986697ac7 100644 --- a/src/proof/pdr/pdrUtil.c +++ b/src/proof/pdr/pdrUtil.c @@ -753,8 +753,6 @@ int Pdr_NtkFindSatAssign_rec( Aig_Man_t * pAig, Aig_Obj_t * pNode, int Value, Pd pNode->fMarkA = Value; if ( Aig_ObjIsCi(pNode) ) { -// if ( vSuppLits ) -// Vec_IntPush( vSuppLits, Abc_Var2Lit( Aig_ObjCioId(pNode), !Value ) ); if ( Saig_ObjIsLo(pAig, pNode) ) { // pCube->Lits[pCube->nLits++] = Abc_Var2Lit( Aig_ObjCioId(pNode) - Saig_ManPiNum(pAig), !Value ); @@ -793,60 +791,6 @@ int Pdr_NtkFindSatAssign_rec( Aig_Man_t * pAig, Aig_Obj_t * pNode, int Value, Pd return Pdr_NtkFindSatAssign_rec(pAig, Aig_ObjFanin0(pNode), Aig_ObjFaninC0(pNode), pCube, Heur); } -/**Function************************************************************* - - Synopsis [Returns 1 if SAT assignment is found; 0 otherwise.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Pdr_ManCubeJust( Pdr_Man_t * p, int k, Pdr_Set_t * pCube ) -{ - Aig_Obj_t * pNode; - int i, v, fCompl; -// return 0; - for ( i = 0; i < 4; i++ ) - { - // derive new assignment - p->pCubeJust->nLits = 0; - p->pCubeJust->Sign = 0; - Aig_ManIncrementTravId( p->pAig ); - for ( v = 0; v < pCube->nLits; v++ ) - { - if ( pCube->Lits[v] == -1 ) - continue; - pNode = Saig_ManLi( p->pAig, lit_var(pCube->Lits[v]) ); - fCompl = lit_sign(pCube->Lits[v]) ^ Aig_ObjFaninC0(pNode); - if ( !Pdr_NtkFindSatAssign_rec( p->pAig, Aig_ObjFanin0(pNode), !fCompl, p->pCubeJust, i ) ) - break; - } - if ( v < pCube->nLits ) - continue; - // figure this out!!! - if ( p->pCubeJust->nLits == 0 ) - continue; - // successfully derived new assignment - Vec_IntSelectSort( p->pCubeJust->Lits, p->pCubeJust->nLits ); - // check assignment against this cube - if ( Pdr_SetContainsSimple( p->pCubeJust, pCube ) ) - continue; -//printf( "\n" ); -//Pdr_SetPrint( stdout, pCube, Saig_ManRegNum(p->pAig), NULL ); printf( "\n" ); -//Pdr_SetPrint( stdout, p->pCubeJust, Saig_ManRegNum(p->pAig), NULL ); printf( "\n" ); - // check assignment against the clauses - if ( Pdr_ManCheckContainment( p, k, p->pCubeJust ) ) - continue; - // find good assignment - return 1; - } - return 0; -} - - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// From 45bf0369a84f9fdc55dd8cdc6227bdfd7c146dee Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 3 Feb 2017 19:51:53 -0800 Subject: [PATCH 096/185] Adding structural flop priority heuristics in 'pdr'. --- src/base/abci/abc.c | 8 ++- src/proof/pdr/pdr.h | 1 + src/proof/pdr/pdrCore.c | 106 +++++++++++++++++-------------------- src/proof/pdr/pdrInt.h | 3 ++ src/proof/pdr/pdrInv.c | 2 + src/proof/pdr/pdrMan.c | 102 ++++++++++++++++++++++++++++++++++-- src/proof/pdr/pdrSat.c | 2 + src/proof/pdr/pdrTsim.c | 112 ++++++++++++++++++++-------------------- 8 files changed, 214 insertions(+), 122 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index b8a0a301a..319525cfd 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26008,7 +26008,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Pdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmusipdegoncvwzh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmuysipdegoncvwzh" ) ) != EOF ) { switch ( c ) { @@ -26126,6 +26126,9 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'u': pPars->fNewXSim ^= 1; break; + case 'y': + pPars->fFlopPrio ^= 1; + break; case 's': pPars->fShortest ^= 1; break; @@ -26194,7 +26197,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmusipdegoncvwzh]\n" ); + Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmuysipdegoncvwzh]\n" ); Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); @@ -26212,6 +26215,7 @@ usage: Abc_Print( -2, "\t-r : toggle using more effort in generalization [default = %s]\n", pPars->fTwoRounds? "yes": "no" ); Abc_Print( -2, "\t-m : toggle using monolythic CNF computation [default = %s]\n", pPars->fMonoCnf? "yes": "no" ); Abc_Print( -2, "\t-u : toggle updated X-valued simulation [default = %s]\n", pPars->fNewXSim? "yes": "no" ); + Abc_Print( -2, "\t-y : toggle using structural flop priorities [default = %s]\n", pPars->fFlopPrio? "yes": "no" ); Abc_Print( -2, "\t-s : toggle creating only shortest counter-examples [default = %s]\n", pPars->fShortest? "yes": "no" ); Abc_Print( -2, "\t-i : toggle clause pushing from an intermediate timeframe [default = %s]\n", pPars->fShiftStart? "yes": "no" ); Abc_Print( -2, "\t-p : toggle reusing proof-obligations in the last timeframe [default = %s]\n", pPars->fReuseProofOblig? "yes": "no" ); diff --git a/src/proof/pdr/pdr.h b/src/proof/pdr/pdr.h index 9f9ef238d..18b059c6e 100644 --- a/src/proof/pdr/pdr.h +++ b/src/proof/pdr/pdr.h @@ -53,6 +53,7 @@ struct Pdr_Par_t_ int fTwoRounds; // use two rounds for generalization int fMonoCnf; // monolythic CNF int fNewXSim; // updated X-valued simulation + int fFlopPrio; // use structural flop priorities int fDumpInv; // dump inductive invariant int fUseSupp; // use support in the invariant int fShortest; // forces bug traces to be shortest diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index 38792ef89..cfc79d852 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -63,6 +63,7 @@ void Pdr_ManSetDefaultParams( Pdr_Par_t * pPars ) pPars->fSkipDown = 1; // apply down in generalization pPars->fCtgs = 0; // handle CTGs in down pPars->fMonoCnf = 0; // monolythic CNF + pPars->fFlopPrio = 0; // use structural flop priorities pPars->fNewXSim = 0; // updated X-valued simulation pPars->fDumpInv = 0; // dump inductive invariant pPars->fUseSupp = 1; // using support variables in the invariant @@ -313,7 +314,7 @@ int * Pdr_ManSortByPriority( Pdr_Man_t * p, Pdr_Set_t * pCube ) int ZPdr_ManSimpleMic( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube ) { int * pOrder; - int i, j, n, Lit, RetValue; + int i, j, Lit, RetValue; Pdr_Set_t * pCubeTmp; // perform generalization if ( p->pPars->fSkipGeneral ) @@ -341,19 +342,14 @@ int ZPdr_ManSimpleMic( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube ) if ( RetValue == 0 ) continue; - // remove j-th entry - for ( n = j; n < (*ppCube)->nLits-1; n++ ) - pOrder[n] = pOrder[n+1]; - j--; - // success - update the cube *ppCube = Pdr_SetCreateFrom( pCubeTmp = *ppCube, i ); Pdr_SetDeref( pCubeTmp ); assert( (*ppCube)->nLits > 0 ); - i--; - // get the ordering by decreasing priorit + // get the ordering by decreasing priority pOrder = Pdr_ManSortByPriority( p, *ppCube ); + j--; } return 0; } @@ -423,7 +419,7 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, { assert( pCubeMin->Lits[i] >= 0 ); assert( (pCubeMin->Lits[i] / 2) < Aig_ManRegNum(p->pAig) ); - Vec_IntAddToEntry( p->vPrio, pCubeMin->Lits[i] / 2, 1 ); + Vec_IntAddToEntry( p->vPrio, pCubeMin->Lits[i] / 2, 1 << p->nPrioShift ); } Vec_VecPush( p->vClauses, l, pCubeMin ); // consume ref @@ -456,14 +452,14 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, return 0; if ( p->pPars->fVeryVerbose ) { - printf("Intersection:\n"); - ZPdr_SetPrint( *ppCube ); + printf("Intersection:\n"); + ZPdr_SetPrint( *ppCube ); } if ( Pdr_SetIsInit( *ppCube, -1 ) ) { - if ( p->pPars->fVeryVerbose ) - printf ("Failed initiation\n"); - return 0; + if ( p->pPars->fVeryVerbose ) + printf ("Failed initiation\n"); + return 0; } RetValue = Pdr_ManCheckCube ( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0 ); if ( RetValue == -1 ) @@ -497,7 +493,7 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPred, Pdr_Set_t ** ppCubeMin ) { Pdr_Set_t * pCubeMin, * pCubeTmp = NULL, * pPred = NULL, * pCubeCpy = NULL; - int i, j, n, Lit, RetValue; + int i, j, Lit, RetValue; abctime clk = Abc_Clock(); int * pOrder; int added = 0; @@ -546,9 +542,9 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP // try removing this literal Lit = pCubeMin->Lits[i]; pCubeMin->Lits[i] = -1; if ( p->pPars->fSkipDown ) - RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 1 ); + RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 1 ); else - RetValue = Pdr_ManCheckCube( p, k, pCubeMin, &pPred, p->pPars->nConfLimit, 1 ); + RetValue = Pdr_ManCheckCube( p, k, pCubeMin, &pPred, p->pPars->nConfLimit, 1 ); if ( RetValue == -1 ) { Pdr_SetDeref( pCubeMin ); @@ -557,52 +553,47 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP pCubeMin->Lits[i] = Lit; if ( RetValue == 0 ) { - if ( p->pPars->fSkipDown ) - continue; - pCubeCpy = Pdr_SetCreateFrom ( pCubeMin, i ); - RetValue = ZPdr_ManDown ( p, k, &pCubeCpy, pPred, keep, pCubeMin, &added ); - if ( p->pPars->fCtgs ) - //CTG handling code messes up with the internal order array + if ( p->pPars->fSkipDown ) + continue; + pCubeCpy = Pdr_SetCreateFrom ( pCubeMin, i ); + RetValue = ZPdr_ManDown ( p, k, &pCubeCpy, pPred, keep, pCubeMin, &added ); + if ( p->pPars->fCtgs ) + //CTG handling code messes up with the internal order array + pOrder = Pdr_ManSortByPriority( p, pCubeMin ); + if ( RetValue == -1 ) + { + Pdr_SetDeref( pCubeMin ); + Pdr_SetDeref( pCubeCpy ); + Pdr_SetDeref( pPred ); + return -1; + } + if ( RetValue == 0 ) + { + if ( keep ) + Hash_IntWriteEntry( keep, pCubeMin->Lits[i], 0 ); + if ( pCubeCpy ) + Pdr_SetDeref( pCubeCpy ); + continue; + } + //Inductive subclause + added = 0; + Pdr_SetDeref( pCubeMin ); + pCubeMin = pCubeCpy; + assert( pCubeMin->nLits > 0 ); pOrder = Pdr_ManSortByPriority( p, pCubeMin ); - if ( RetValue == -1 ) - { - Pdr_SetDeref( pCubeMin ); - Pdr_SetDeref( pCubeCpy ); - Pdr_SetDeref( pPred ); - return -1; - } - if ( RetValue == 0 ) - { - if ( keep ) - Hash_IntWriteEntry( keep, pCubeMin->Lits[i], 0 ); - if ( pCubeCpy ) - Pdr_SetDeref( pCubeCpy ); + j = -1; continue; - } - //Inductive subclause - added = 0; - Pdr_SetDeref( pCubeMin ); - pCubeMin = pCubeCpy; - assert( pCubeMin->nLits > 0 ); - pOrder = Pdr_ManSortByPriority( p, pCubeMin ); - j = -1; - continue; } added = 0; - // remove j-th entry - for ( n = j; n < pCubeMin->nLits-1; n++ ) - pOrder[n] = pOrder[n+1]; - j--; - // success - update the cube pCubeMin = Pdr_SetCreateFrom( pCubeTmp = pCubeMin, i ); Pdr_SetDeref( pCubeTmp ); assert( pCubeMin->nLits > 0 ); - i--; - // get the ordering by decreasing priorit + // get the ordering by decreasing priority pOrder = Pdr_ManSortByPriority( p, pCubeMin ); + j--; } if ( p->pPars->fTwoRounds ) @@ -628,19 +619,14 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP if ( RetValue == 0 ) continue; - // remove j-th entry - for ( n = j; n < pCubeMin->nLits-1; n++ ) - pOrder[n] = pOrder[n+1]; - j--; - // success - update the cube pCubeMin = Pdr_SetCreateFrom( pCubeTmp = pCubeMin, i ); Pdr_SetDeref( pCubeTmp ); assert( pCubeMin->nLits > 0 ); - i--; - // get the ordering by decreasing priorit + // get the ordering by decreasing priority pOrder = Pdr_ManSortByPriority( p, pCubeMin ); + j--; } } @@ -762,7 +748,7 @@ int Pdr_ManBlockCube( Pdr_Man_t * p, Pdr_Set_t * pCube ) { assert( pCubeMin->Lits[i] >= 0 ); assert( (pCubeMin->Lits[i] / 2) < Aig_ManRegNum(p->pAig) ); - Vec_IntAddToEntry( p->vPrio, pCubeMin->Lits[i] / 2, 1 ); + Vec_IntAddToEntry( p->vPrio, pCubeMin->Lits[i] / 2, 1 << p->nPrioShift ); } Vec_VecPush( p->vClauses, k, pCubeMin ); // consume ref p->nCubes++; diff --git a/src/proof/pdr/pdrInt.h b/src/proof/pdr/pdrInt.h index 89b6f0d0f..dae20f0cd 100644 --- a/src/proof/pdr/pdrInt.h +++ b/src/proof/pdr/pdrInt.h @@ -82,6 +82,7 @@ struct Pdr_Man_t_ Vec_Wec_t * vVLits; // CNF literals // data representation int iOutCur; // current output + int nPrioShift;// priority shift Vec_Ptr_t * vCexes; // counter-examples for each output Vec_Ptr_t * vSolvers; // SAT solvers Vec_Vec_t * vClauses; // clauses by timeframe @@ -121,6 +122,8 @@ struct Pdr_Man_t_ int nQueCur; int nQueMax; int nQueLim; + int nXsimRuns; + int nXsimLits; // runtime abctime timeToStop; abctime timeToStopOne; diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index 8b04c53b4..16d98a36a 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -467,6 +467,8 @@ void Pdr_ManReportInvariant( Pdr_Man_t * p ) Vec_Ptr_t * vCubes; int kStart = Pdr_ManFindInvariantStart( p ); vCubes = Pdr_ManCollectCubes( p, kStart ); +// Abc_Print( 1, "Invariant F[%d] : %d clauses with %d flops (out of %d) (%.2f)\n", +// kStart, Vec_PtrSize(vCubes), Pdr_ManCountVariables(p, kStart), Aig_ManRegNum(p->pAig), 1.0*p->nXsimLits/p->nXsimRuns ); Abc_Print( 1, "Invariant F[%d] : %d clauses with %d flops (out of %d)\n", kStart, Vec_PtrSize(vCubes), Pdr_ManCountVariables(p, kStart), Aig_ManRegNum(p->pAig) ); Vec_PtrFree( vCubes ); diff --git a/src/proof/pdr/pdrMan.c b/src/proof/pdr/pdrMan.c index 31446290a..6fe4c28de 100644 --- a/src/proof/pdr/pdrMan.c +++ b/src/proof/pdr/pdrMan.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "pdrInt.h" +#include "aig/gia/giaAig.h" ABC_NAMESPACE_IMPL_START @@ -31,6 +32,94 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [Structural analysis.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Pdr_ManDeriveFlopPriorities2( Gia_Man_t * p, int fMuxCtrls, int * pnPrioShift ) +{ + Vec_Int_t * vRes = NULL; + Gia_Obj_t * pObj; + int MaxEntry = 0; + int i, * pPerm; + // create flop costs + Vec_Int_t * vCosts = Vec_IntStart( Gia_ManRegNum(p) ); + Gia_ManCreateRefs(p); + Gia_ManForEachRo( p, pObj, i ) + { + Vec_IntWriteEntry( vCosts, i, Gia_ObjRefNum(p, pObj) ); + MaxEntry = Abc_MaxInt( MaxEntry, Gia_ObjRefNum(p, pObj) ); + } + MaxEntry++; + ABC_FREE( p->pRefs ); + // add costs due to MUX inputs + if ( fMuxCtrls ) + { + int fVerbose = 0; + Vec_Bit_t * vCtrls = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Bit_t * vDatas = Vec_BitStart( Gia_ManObjNum(p) ); + Gia_Obj_t * pCtrl, * pData1, * pData0; + int nCtrls = 0, nDatas = 0, nBoth = 0; + Gia_ManForEachAnd( p, pObj, i ) + { + if ( !Gia_ObjIsMuxType(pObj) ) + continue; + pCtrl = Gia_ObjRecognizeMux( pObj, &pData1, &pData0 ); + pCtrl = Gia_Regular(pCtrl); + pData1 = Gia_Regular(pData1); + pData0 = Gia_Regular(pData0); + Vec_BitWriteEntry( vCtrls, Gia_ObjId(p, pCtrl), 1 ); + Vec_BitWriteEntry( vDatas, Gia_ObjId(p, pData1), 1 ); + Vec_BitWriteEntry( vDatas, Gia_ObjId(p, pData0), 1 ); + } + Gia_ManForEachRo( p, pObj, i ) + if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) ) + Vec_IntAddToEntry( vCosts, i, 2*MaxEntry ); + //else if ( Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) ) + // Vec_IntAddToEntry( vCosts, i, MaxEntry ); + MaxEntry *= 3; + // print out + if ( fVerbose ) + { + Gia_ManForEachRo( p, pObj, i ) + { + if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) ) + nCtrls++; + if ( Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) ) + nDatas++; + if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) && Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) ) + nBoth++; + } + printf( "%10s : Flops = %5d. Ctrls = %5d. Datas = %5d. Both = %5d.\n", Gia_ManName(p), Gia_ManRegNum(p), nCtrls, nDatas, nBoth ); + } + Vec_BitFree( vCtrls ); + Vec_BitFree( vDatas ); + } + *pnPrioShift = 1 + Abc_Base2Log( MaxEntry ); + // create ordering based on costs + pPerm = Abc_MergeSortCost( Vec_IntArray(vCosts), Vec_IntSize(vCosts) ); + vRes = Vec_IntAllocArray( pPerm, Vec_IntSize(vCosts) ); + Vec_IntFree( vCosts ); + vCosts = Vec_IntInvert( vRes, -1 ); + Vec_IntFree( vRes ); +//Vec_IntPrint( vCosts ); + return vCosts; +} +Vec_Int_t * Pdr_ManDeriveFlopPriorities( Aig_Man_t * pAig, int fMuxCtrls, int * pnPrioShift ) +{ + Gia_Man_t * pGia = Gia_ManFromAigSimple(pAig); + Vec_Int_t * vRes = Pdr_ManDeriveFlopPriorities2(pGia, fMuxCtrls, pnPrioShift); + Gia_ManStop( pGia ); + return vRes; +} + /**Function************************************************************* Synopsis [Creates manager.] @@ -56,7 +145,13 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio if ( !p->pPars->fMonoCnf ) p->vVLits = Vec_WecStart( 1+Abc_MaxInt(1, Aig_ManLevels(pAig)) ); // internal use - p->vPrio = vPrioInit ? vPrioInit : Vec_IntStart( Aig_ManRegNum(pAig) ); // priority flops + p->nPrioShift = 0; + if ( vPrioInit ) + p->vPrio = vPrioInit; + else if ( pPars->fFlopPrio ) + p->vPrio = Pdr_ManDeriveFlopPriorities(pAig, 0, &p->nPrioShift); + else + p->vPrio = Vec_IntStart( Aig_ManRegNum(pAig) ); p->vLits = Vec_IntAlloc( 100 ); // array of literals p->vCiObjs = Vec_IntAlloc( 100 ); // cone leaves p->vCoObjs = Vec_IntAlloc( 100 ); // cone roots @@ -69,7 +164,7 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio p->vRes = Vec_IntAlloc( 100 ); // final result p->pCnfMan = Cnf_ManStart(); // ternary simulation - p->pTxs = Txs_ManStart( p, pAig, p->vPrio ); + p->pTxs = pPars->fNewXSim ? Txs_ManStart( p, pAig, p->vPrio ) : NULL; // additional AIG data-members if ( pAig->pFanData == NULL ) Aig_ManFanoutStart( pAig ); @@ -151,7 +246,8 @@ void Pdr_ManStop( Pdr_Man_t * p ) // CNF manager Cnf_ManStop( p->pCnfMan ); // terminary simulation - Txs_ManStop( p->pTxs ); + if ( p->pPars->fNewXSim ) + Txs_ManStop( p->pTxs ); // internal use Vec_IntFreeP( &p->vPrio ); // priority flops Vec_IntFree( p->vLits ); // array of literals diff --git a/src/proof/pdr/pdrSat.c b/src/proof/pdr/pdrSat.c index 936a8f908..b9403e6fb 100644 --- a/src/proof/pdr/pdrSat.c +++ b/src/proof/pdr/pdrSat.c @@ -366,6 +366,8 @@ int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPr else *ppPred = Pdr_ManTernarySim( p, k, pCube ); p->tTsim += Abc_Clock() - clk; + p->nXsimLits += (*ppPred)->nLits; + p->nXsimRuns++; } RetValue = 0; } diff --git a/src/proof/pdr/pdrTsim.c b/src/proof/pdr/pdrTsim.c index 43f2ddb0b..0bcb6e0c1 100644 --- a/src/proof/pdr/pdrTsim.c +++ b/src/proof/pdr/pdrTsim.c @@ -404,67 +404,65 @@ Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, NULL ); RetValue = Pdr_ManSimDataInit( p->pAig, vCiObjs, vCiVals, vNodes, vCoObjs, vCoVals, NULL ); assert( RetValue ); -#if 1 - // try removing high-priority flops - Vec_IntClear( vCi2Rem ); - Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i ) + // iteratively remove flops + if ( p->pPars->fFlopPrio ) { - if ( !Saig_ObjIsLo( p->pAig, pObj ) ) - continue; - Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig); - if ( vPrio != NULL && Vec_IntEntry( vPrio, Entry ) != 0 ) - continue; - Vec_IntClear( vUndo ); - if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) ) - Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) ); - else - Pdr_ManExtendUndo( p->pAig, vUndo ); + // collect flops and sort them by priority + Vec_IntClear( vRes ); + Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i ) + { + if ( !Saig_ObjIsLo( p->pAig, pObj ) ) + continue; + Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig); + Vec_IntPush( vRes, Entry ); + } + Vec_IntSelectSortCost( Vec_IntArray(vRes), Vec_IntSize(vRes), vPrio ); + + // try removing flops starting from low-priority to high-priority + Vec_IntClear( vCi2Rem ); + Vec_IntForEachEntry( vRes, Entry, i ) + { + pObj = Aig_ManCi( p->pAig, Saig_ManPiNum(p->pAig) + Entry ); + assert( Saig_ObjIsLo( p->pAig, pObj ) ); + Vec_IntClear( vUndo ); + if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) ) + Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) ); + else + Pdr_ManExtendUndo( p->pAig, vUndo ); + } } - // try removing low-priority flops - Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i ) + else { - if ( !Saig_ObjIsLo( p->pAig, pObj ) ) - continue; - Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig); - if ( vPrio == NULL || Vec_IntEntry( vPrio, Entry ) == 0 ) - continue; - Vec_IntClear( vUndo ); - if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) ) - Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) ); - else - Pdr_ManExtendUndo( p->pAig, vUndo ); + // try removing low-priority flops first + Vec_IntClear( vCi2Rem ); + Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i ) + { + if ( !Saig_ObjIsLo( p->pAig, pObj ) ) + continue; + Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig); + if ( vPrio != NULL && Vec_IntEntry( vPrio, Entry ) != 0 ) + continue; + Vec_IntClear( vUndo ); + if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) ) + Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) ); + else + Pdr_ManExtendUndo( p->pAig, vUndo ); + } + // try removing high-priority flops next + Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i ) + { + if ( !Saig_ObjIsLo( p->pAig, pObj ) ) + continue; + Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig); + if ( vPrio == NULL || Vec_IntEntry( vPrio, Entry ) == 0 ) + continue; + Vec_IntClear( vUndo ); + if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) ) + Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) ); + else + Pdr_ManExtendUndo( p->pAig, vUndo ); + } } -#else - // try removing low-priority flops - Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i ) - { - if ( !Saig_ObjIsLo( p->pAig, pObj ) ) - continue; - Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig); - if ( vPrio == NULL || Vec_IntEntry( vPrio, Entry ) == 0 ) - continue; - Vec_IntClear( vUndo ); - if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) ) - Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) ); - else - Pdr_ManExtendUndo( p->pAig, vUndo ); - } - // try removing high-priority flops - Vec_IntClear( vCi2Rem ); - Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i ) - { - if ( !Saig_ObjIsLo( p->pAig, pObj ) ) - continue; - Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig); - if ( vPrio != NULL && Vec_IntEntry( vPrio, Entry ) != 0 ) - continue; - Vec_IntClear( vUndo ); - if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) ) - Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) ); - else - Pdr_ManExtendUndo( p->pAig, vUndo ); - } -#endif if ( p->pPars->fVeryVerbose ) Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, vCi2Rem ); From 2c4c464ab0a0f5a7ff91dd3abb1c39dbadefa1de Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 3 Feb 2017 21:31:40 -0800 Subject: [PATCH 097/185] Adding structural flop priority heuristics in 'pdr' (bug fix). --- src/proof/pdr/pdrMan.c | 135 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 126 insertions(+), 9 deletions(-) diff --git a/src/proof/pdr/pdrMan.c b/src/proof/pdr/pdrMan.c index 6fe4c28de..f682e9464 100644 --- a/src/proof/pdr/pdrMan.c +++ b/src/proof/pdr/pdrMan.c @@ -43,15 +43,134 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -Vec_Int_t * Pdr_ManDeriveFlopPriorities2( Gia_Man_t * p, int fMuxCtrls, int * pnPrioShift ) +Vec_Int_t * Pdr_ManDeriveFlopPriorities3( Gia_Man_t * p, int fMuxCtrls ) { + int fDiscount = 0; + Vec_Wec_t * vLevels; + Vec_Int_t * vRes, * vLevel, * vCosts; + Gia_Obj_t * pObj, * pCtrl, * pData0, * pData1; + int i, k, Entry, MaxEntry = 0; + Gia_ManCreateRefs(p); + // discount references + if ( fDiscount ) + Gia_ManForEachAnd( p, pObj, i ) + { + if ( !Gia_ObjIsMuxType(pObj) ) + continue; + pCtrl = Gia_Regular(Gia_ObjRecognizeMux(pObj, &pData1, &pData0)); + pData0 = Gia_Regular(pData0); + pData1 = Gia_Regular(pData1); + p->pRefs[Gia_ObjId(p, pCtrl)]--; + if ( pData0 == pData1 ) + p->pRefs[Gia_ObjId(p, pData0)]--; + } + // create flop costs + vCosts = Vec_IntAlloc( Gia_ManRegNum(p) ); + Gia_ManForEachRo( p, pObj, i ) + { + Vec_IntPush( vCosts, Gia_ObjRefNum(p, pObj) ); + MaxEntry = Abc_MaxInt( MaxEntry, Gia_ObjRefNum(p, pObj) ); + //printf( "%d(%d) ", i, Gia_ObjRefNum(p, pObj) ); + } + //printf( "\n" ); + MaxEntry++; + // add costs due to MUX inputs + if ( fMuxCtrls ) + { + int fVerbose = 0; + Vec_Bit_t * vCtrls = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Bit_t * vDatas = Vec_BitStart( Gia_ManObjNum(p) ); + Gia_Obj_t * pCtrl, * pData1, * pData0; + int nCtrls = 0, nDatas = 0, nBoth = 0; + Gia_ManForEachAnd( p, pObj, i ) + { + if ( !Gia_ObjIsMuxType(pObj) ) + continue; + pCtrl = Gia_ObjRecognizeMux( pObj, &pData1, &pData0 ); + pCtrl = Gia_Regular(pCtrl); + pData1 = Gia_Regular(pData1); + pData0 = Gia_Regular(pData0); + Vec_BitWriteEntry( vCtrls, Gia_ObjId(p, pCtrl), 1 ); + Vec_BitWriteEntry( vDatas, Gia_ObjId(p, pData1), 1 ); + Vec_BitWriteEntry( vDatas, Gia_ObjId(p, pData0), 1 ); + } + Gia_ManForEachRo( p, pObj, i ) + if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) ) + Vec_IntAddToEntry( vCosts, i, MaxEntry ); + //else if ( Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) ) + // Vec_IntAddToEntry( vCosts, i, MaxEntry ); + MaxEntry = 2*MaxEntry + 1; + // print out + if ( fVerbose ) + { + Gia_ManForEachRo( p, pObj, i ) + { + if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) ) + nCtrls++; + if ( Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) ) + nDatas++; + if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) && Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) ) + nBoth++; + } + printf( "%10s : Flops = %5d. Ctrls = %5d. Datas = %5d. Both = %5d.\n", Gia_ManName(p), Gia_ManRegNum(p), nCtrls, nDatas, nBoth ); + } + Vec_BitFree( vCtrls ); + Vec_BitFree( vDatas ); + } + // create levelized structure + vLevels = Vec_WecStart( MaxEntry ); + Vec_IntForEachEntry( vCosts, Entry, i ) + Vec_WecPush( vLevels, Entry, i ); + // collect in this order + MaxEntry = 0; + vRes = Vec_IntStart( Gia_ManRegNum(p) ); + Vec_WecForEachLevel( vLevels, vLevel, i ) + Vec_IntForEachEntry( vLevel, Entry, k ) + Vec_IntWriteEntry( vRes, Entry, MaxEntry++ ); + //printf( "%d ", Gia_ObjRefNum(p, Gia_ManCi(p, Gia_ManPiNum(p)+Entry)) ); + //printf( "\n" ); + assert( MaxEntry == Gia_ManRegNum(p) ); + Vec_WecFree( vLevels ); + Vec_IntFree( vCosts ); + ABC_FREE( p->pRefs ); +//Vec_IntPrint( vRes ); + return vRes; +} + +/**Function************************************************************* + + Synopsis [Structural analysis.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Pdr_ManDeriveFlopPriorities2( Gia_Man_t * p, int fMuxCtrls ) +{ + int fDiscount = 0; Vec_Int_t * vRes = NULL; - Gia_Obj_t * pObj; + Gia_Obj_t * pObj, * pCtrl, * pData0, * pData1; int MaxEntry = 0; int i, * pPerm; // create flop costs Vec_Int_t * vCosts = Vec_IntStart( Gia_ManRegNum(p) ); Gia_ManCreateRefs(p); + // discount references + if ( fDiscount ) + Gia_ManForEachAnd( p, pObj, i ) + { + if ( !Gia_ObjIsMuxType(pObj) ) + continue; + pCtrl = Gia_Regular(Gia_ObjRecognizeMux(pObj, &pData1, &pData0)); + pData0 = Gia_Regular(pData0); + pData1 = Gia_Regular(pData1); + p->pRefs[Gia_ObjId(p, pCtrl)]--; + if ( pData0 == pData1 ) + p->pRefs[Gia_ObjId(p, pData0)]--; + } Gia_ManForEachRo( p, pObj, i ) { Vec_IntWriteEntry( vCosts, i, Gia_ObjRefNum(p, pObj) ); @@ -81,10 +200,9 @@ Vec_Int_t * Pdr_ManDeriveFlopPriorities2( Gia_Man_t * p, int fMuxCtrls, int * pn } Gia_ManForEachRo( p, pObj, i ) if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) ) - Vec_IntAddToEntry( vCosts, i, 2*MaxEntry ); + Vec_IntAddToEntry( vCosts, i, MaxEntry ); //else if ( Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) ) // Vec_IntAddToEntry( vCosts, i, MaxEntry ); - MaxEntry *= 3; // print out if ( fVerbose ) { @@ -102,7 +220,6 @@ Vec_Int_t * Pdr_ManDeriveFlopPriorities2( Gia_Man_t * p, int fMuxCtrls, int * pn Vec_BitFree( vCtrls ); Vec_BitFree( vDatas ); } - *pnPrioShift = 1 + Abc_Base2Log( MaxEntry ); // create ordering based on costs pPerm = Abc_MergeSortCost( Vec_IntArray(vCosts), Vec_IntSize(vCosts) ); vRes = Vec_IntAllocArray( pPerm, Vec_IntSize(vCosts) ); @@ -112,10 +229,10 @@ Vec_Int_t * Pdr_ManDeriveFlopPriorities2( Gia_Man_t * p, int fMuxCtrls, int * pn //Vec_IntPrint( vCosts ); return vCosts; } -Vec_Int_t * Pdr_ManDeriveFlopPriorities( Aig_Man_t * pAig, int fMuxCtrls, int * pnPrioShift ) +Vec_Int_t * Pdr_ManDeriveFlopPriorities( Aig_Man_t * pAig, int fMuxCtrls ) { Gia_Man_t * pGia = Gia_ManFromAigSimple(pAig); - Vec_Int_t * vRes = Pdr_ManDeriveFlopPriorities2(pGia, fMuxCtrls, pnPrioShift); + Vec_Int_t * vRes = Pdr_ManDeriveFlopPriorities2(pGia, fMuxCtrls); Gia_ManStop( pGia ); return vRes; } @@ -145,11 +262,11 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio if ( !p->pPars->fMonoCnf ) p->vVLits = Vec_WecStart( 1+Abc_MaxInt(1, Aig_ManLevels(pAig)) ); // internal use - p->nPrioShift = 0; + p->nPrioShift = Abc_Base2Log(Aig_ManRegNum(pAig)); if ( vPrioInit ) p->vPrio = vPrioInit; else if ( pPars->fFlopPrio ) - p->vPrio = Pdr_ManDeriveFlopPriorities(pAig, 0, &p->nPrioShift); + p->vPrio = Pdr_ManDeriveFlopPriorities(pAig, 1); else p->vPrio = Vec_IntStart( Aig_ManRegNum(pAig) ); p->vLits = Vec_IntAlloc( 100 ); // array of literals From afcbb09717b9b76b6895dee66d42b9f9be0160e2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 5 Feb 2017 10:43:07 -0800 Subject: [PATCH 098/185] Corner-case bug-fix in library preprocessor for standard-cell mapping. --- src/map/mio/mioUtils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/map/mio/mioUtils.c b/src/map/mio/mioUtils.c index 7572b27c1..428eb92b2 100644 --- a/src/map/mio/mioUtils.c +++ b/src/map/mio/mioUtils.c @@ -569,7 +569,7 @@ Mio_Cell_t * Mio_CollectRootsNew( Mio_Library_t * pLib, int nInputs, int * pnGat if ( ppCells[3].pName == NULL ) { printf( "Error: Cannot find inverter gate in the library.\n" ); return NULL; } // sort by delay - if ( iCell > 1 ) + if ( iCell > 5 ) { qsort( (void *)(ppCells + 4), iCell - 4, sizeof(Mio_Cell_t), (int (*)(const void *, const void *)) Mio_AreaCompare ); @@ -726,7 +726,7 @@ Mio_Cell2_t * Mio_CollectRootsNew2( Mio_Library_t * pLib, int nInputs, int * pnG if ( ppCells[3].pName == NULL ) { printf( "Error: Cannot find inverter gate in the library.\n" ); return NULL; } // sort by delay - if ( iCell > 1 ) + if ( iCell > 5 ) { qsort( (void *)(ppCells + 4), iCell - 4, sizeof(Mio_Cell2_t), (int (*)(const void *, const void *)) Mio_AreaCompare2 ); From 8b6de217f6476649763ba95a0acf18fcea69557a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 5 Feb 2017 11:08:44 -0800 Subject: [PATCH 099/185] Compiler warnings. --- src/proof/pdr/pdrMan.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/proof/pdr/pdrMan.c b/src/proof/pdr/pdrMan.c index f682e9464..13e0b23cb 100644 --- a/src/proof/pdr/pdrMan.c +++ b/src/proof/pdr/pdrMan.c @@ -53,16 +53,18 @@ Vec_Int_t * Pdr_ManDeriveFlopPriorities3( Gia_Man_t * p, int fMuxCtrls ) Gia_ManCreateRefs(p); // discount references if ( fDiscount ) - Gia_ManForEachAnd( p, pObj, i ) { - if ( !Gia_ObjIsMuxType(pObj) ) - continue; - pCtrl = Gia_Regular(Gia_ObjRecognizeMux(pObj, &pData1, &pData0)); - pData0 = Gia_Regular(pData0); - pData1 = Gia_Regular(pData1); - p->pRefs[Gia_ObjId(p, pCtrl)]--; - if ( pData0 == pData1 ) - p->pRefs[Gia_ObjId(p, pData0)]--; + Gia_ManForEachAnd( p, pObj, i ) + { + if ( !Gia_ObjIsMuxType(pObj) ) + continue; + pCtrl = Gia_Regular(Gia_ObjRecognizeMux(pObj, &pData1, &pData0)); + pData0 = Gia_Regular(pData0); + pData1 = Gia_Regular(pData1); + p->pRefs[Gia_ObjId(p, pCtrl)]--; + if ( pData0 == pData1 ) + p->pRefs[Gia_ObjId(p, pData0)]--; + } } // create flop costs vCosts = Vec_IntAlloc( Gia_ManRegNum(p) ); @@ -160,16 +162,18 @@ Vec_Int_t * Pdr_ManDeriveFlopPriorities2( Gia_Man_t * p, int fMuxCtrls ) Gia_ManCreateRefs(p); // discount references if ( fDiscount ) - Gia_ManForEachAnd( p, pObj, i ) { - if ( !Gia_ObjIsMuxType(pObj) ) - continue; - pCtrl = Gia_Regular(Gia_ObjRecognizeMux(pObj, &pData1, &pData0)); - pData0 = Gia_Regular(pData0); - pData1 = Gia_Regular(pData1); - p->pRefs[Gia_ObjId(p, pCtrl)]--; - if ( pData0 == pData1 ) - p->pRefs[Gia_ObjId(p, pData0)]--; + Gia_ManForEachAnd( p, pObj, i ) + { + if ( !Gia_ObjIsMuxType(pObj) ) + continue; + pCtrl = Gia_Regular(Gia_ObjRecognizeMux(pObj, &pData1, &pData0)); + pData0 = Gia_Regular(pData0); + pData1 = Gia_Regular(pData1); + p->pRefs[Gia_ObjId(p, pCtrl)]--; + if ( pData0 == pData1 ) + p->pRefs[Gia_ObjId(p, pData0)]--; + } } Gia_ManForEachRo( p, pObj, i ) { From f34029dd09a3ddb5ec726ef5ae541e2342544cd9 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 5 Feb 2017 12:28:34 -0800 Subject: [PATCH 100/185] Improvements in AIG visualization. --- src/aig/gia/giaShow.c | 27 +++++++++++++++------------ src/base/io/ioWriteDot.c | 4 ++-- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index 4deebd7a1..3ca31d553 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -290,7 +290,7 @@ void Gia_ShowPath( Gia_Man_t * p, char * pFileName ) fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", Gia_ObjFaninId0p(p, pNode) ); fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", "bold" ); + fprintf( pFile, "style = %s", "solid" ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); } @@ -308,7 +308,7 @@ void Gia_ShowPath( Gia_Man_t * p, char * pFileName ) fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", iFan ); fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", "bold" ); + fprintf( pFile, "style = %s", "solid" ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); } @@ -583,7 +583,7 @@ void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold ) fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", Gia_ObjFaninId0(pNode, i) ); fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", Gia_ObjFaninC0(pNode)? "dotted" : "bold" ); + fprintf( pFile, "style = %s", Gia_ObjFaninC0(pNode)? "dotted" : "solid" ); // if ( Gia_NtkIsSeq(pNode->p) && Seq_ObjFaninL0(pNode) > 0 ) // fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,0) ); fprintf( pFile, "]" ); @@ -595,7 +595,7 @@ void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold ) fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", Gia_ObjFaninId1(pNode, i) ); fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", Gia_ObjFaninC1(pNode)? "dotted" : "bold" ); + fprintf( pFile, "style = %s", Gia_ObjFaninC1(pNode)? "dotted" : "solid" ); // if ( Gia_NtkIsSeq(pNode->p) && Seq_ObjFaninL1(pNode) > 0 ) // fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,1) ); fprintf( pFile, "]" ); @@ -624,7 +624,7 @@ void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold ) fprintf( pFile, "Node%d", pPrev->Id ); fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", pTemp->Id ); - fprintf( pFile, " [style = %s]", Gia_IsComplement(pTemp->pEquiv)? "dotted" : "bold" ); + fprintf( pFile, " [style = %s]", Gia_IsComplement(pTemp->pEquiv)? "dotted" : "solid" ); fprintf( pFile, ";\n" ); pPrev = pTemp; } @@ -632,7 +632,7 @@ void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold ) fprintf( pFile, "Node%d", pPrev->Id ); fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", pNode->Id ); - fprintf( pFile, " [style = %s]", Gia_IsComplement(pPrev->pEquiv)? "dotted" : "bold" ); + fprintf( pFile, " [style = %s]", Gia_IsComplement(pPrev->pEquiv)? "dotted" : "solid" ); fprintf( pFile, ";\n" ); } */ @@ -920,7 +920,7 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_In fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Gia_ObjFaninId0(pNode, iNode)) ); fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", Gia_ObjFaninC0(pNode)? "dotted" : "bold" ); + fprintf( pFile, "style = %s", Gia_ObjFaninC0(pNode)? "dotted" : "solid" ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); } @@ -933,11 +933,13 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_In for ( k = 0; k < 3; k++ ) if ( Vec_IntEntry(vAdds, 6*iBox+k) ) { + int iBox2 = Vec_IntEntry(vMapAdds, Vec_IntEntry(vAdds, 6*iBox+k)); + int fXor2 = iBox2 >= 0 ? (int)(Vec_IntEntry(vAdds, 6*iBox2+3) == Vec_IntEntry(vAdds, 6*iBox+k)) : 0; fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, iNode) ); fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Vec_IntEntry(vAdds, 6*iBox+k)) ); fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", 0? "dotted" : "bold" ); + fprintf( pFile, "style = %s", fXor2? "bold" : "solid" ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); } @@ -949,11 +951,12 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_In for ( k = 1; k < 4; k++ ) if ( Vec_IntEntry(vXors, 4*iXor+k) ) { + int iXor2 = Vec_IntEntry(vMapXors, Vec_IntEntry(vXors, 4*iXor+k)); fprintf( pFile, "Node%d", iNode ); fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Vec_IntEntry(vXors, 4*iXor+k)) ); fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", 0? "dotted" : "bold" ); + fprintf( pFile, "style = %s", iXor2 >= 0? "bold" : "solid" ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); } @@ -964,7 +967,7 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_In fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Gia_ObjFaninId0(pNode, iNode)) ); fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", Gia_ObjFaninC0(pNode)? "dotted" : "bold" ); + fprintf( pFile, "style = %s", Gia_ObjFaninC0(pNode)? "dotted" : "solid" ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); if ( !Gia_ObjIsAnd(pNode) ) @@ -974,7 +977,7 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_In fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Gia_ObjFaninId1(pNode, iNode)) ); fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", Gia_ObjFaninC1(pNode)? "dotted" : "bold" ); + fprintf( pFile, "style = %s", Gia_ObjFaninC1(pNode)? "dotted" : "solid" ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); @@ -985,7 +988,7 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_In fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Gia_ObjFaninId2(p, iNode)) ); fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", Gia_ObjFaninC2(p, pNode)? "dotted" : "bold" ); + fprintf( pFile, "style = %s", Gia_ObjFaninC2(p, pNode)? "dotted" : "solid" ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); } diff --git a/src/base/io/ioWriteDot.c b/src/base/io/ioWriteDot.c index 3431c7611..d9687c6e5 100644 --- a/src/base/io/ioWriteDot.c +++ b/src/base/io/ioWriteDot.c @@ -394,7 +394,7 @@ void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho fprintf( pFile, "Node%d", pNode->Id ); fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", pFanin->Id ); - fprintf( pFile, " [style = %s", fCompl? "dotted" : "bold" ); + fprintf( pFile, " [style = %s", fCompl? "dotted" : "solid" ); // fprintf( pFile, ", label = \"%c\"", 'a' + k ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); @@ -764,7 +764,7 @@ void Io_WriteDotSeq( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho fprintf( pFile, "Node%d", pNode->Id ); fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", pFanin->Id ); - fprintf( pFile, " [style = %s", fCompl? "dotted" : "bold" ); + fprintf( pFile, " [style = %s", fCompl? "dotted" : "solid" ); // fprintf( pFile, ", label = \"%c\"", 'a' + k ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); From 89e8e50069b62afa021bfd16b340d56cd5b4c113 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 6 Feb 2017 00:21:28 -0800 Subject: [PATCH 101/185] Improving new X-valued simulation in 'pdr'. --- src/proof/pdr/pdrInv.c | 8 +- src/proof/pdr/pdrMan.c | 4 +- src/proof/pdr/pdrTsim2.c | 177 +++++++++++++++++++++++++++++++++++++-- src/sat/bmc/bmcCexCare.c | 31 ++++++- 4 files changed, 203 insertions(+), 17 deletions(-) diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index 16d98a36a..8130d0a3a 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -467,10 +467,10 @@ void Pdr_ManReportInvariant( Pdr_Man_t * p ) Vec_Ptr_t * vCubes; int kStart = Pdr_ManFindInvariantStart( p ); vCubes = Pdr_ManCollectCubes( p, kStart ); -// Abc_Print( 1, "Invariant F[%d] : %d clauses with %d flops (out of %d) (%.2f)\n", -// kStart, Vec_PtrSize(vCubes), Pdr_ManCountVariables(p, kStart), Aig_ManRegNum(p->pAig), 1.0*p->nXsimLits/p->nXsimRuns ); - Abc_Print( 1, "Invariant F[%d] : %d clauses with %d flops (out of %d)\n", - kStart, Vec_PtrSize(vCubes), Pdr_ManCountVariables(p, kStart), Aig_ManRegNum(p->pAig) ); + Abc_Print( 1, "Invariant F[%d] : %d clauses with %d flops (out of %d) (%.2f)\n", + kStart, Vec_PtrSize(vCubes), Pdr_ManCountVariables(p, kStart), Aig_ManRegNum(p->pAig), 1.0*p->nXsimLits/p->nXsimRuns ); +// Abc_Print( 1, "Invariant F[%d] : %d clauses with %d flops (out of %d)\n", +// kStart, Vec_PtrSize(vCubes), Pdr_ManCountVariables(p, kStart), Aig_ManRegNum(p->pAig) ); Vec_PtrFree( vCubes ); } diff --git a/src/proof/pdr/pdrMan.c b/src/proof/pdr/pdrMan.c index 13e0b23cb..f9a14a07c 100644 --- a/src/proof/pdr/pdrMan.c +++ b/src/proof/pdr/pdrMan.c @@ -271,7 +271,9 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio p->vPrio = vPrioInit; else if ( pPars->fFlopPrio ) p->vPrio = Pdr_ManDeriveFlopPriorities(pAig, 1); - else + else if ( p->pPars->fNewXSim ) + p->vPrio = Vec_IntStartNatural( Aig_ManRegNum(pAig) ); + else p->vPrio = Vec_IntStart( Aig_ManRegNum(pAig) ); p->vLits = Vec_IntAlloc( 100 ); // array of literals p->vCiObjs = Vec_IntAlloc( 100 ); // cone leaves diff --git a/src/proof/pdr/pdrTsim2.c b/src/proof/pdr/pdrTsim2.c index 82e9a56c7..8a86eeccb 100644 --- a/src/proof/pdr/pdrTsim2.c +++ b/src/proof/pdr/pdrTsim2.c @@ -36,6 +36,7 @@ struct Txs_Man_t_ Vec_Int_t * vCiVals; // cone leaf values (0/1 CI values) Vec_Int_t * vCoVals; // cone root values (0/1 CO values) Vec_Int_t * vNodes; // cone nodes (node obj IDs) + Vec_Int_t * vTemp; // cone nodes (node obj IDs) Vec_Int_t * vPiLits; // resulting array of PI literals Vec_Int_t * vFfLits; // resulting array of flop literals Pdr_Man_t * pMan; // calling manager @@ -72,6 +73,7 @@ Txs_Man_t * Txs_ManStart( Pdr_Man_t * pMan, Aig_Man_t * pAig, Vec_Int_t * vPrio p->vCiVals = Vec_IntAlloc( 100 ); // cone leaf values (0/1 CI values) p->vCoVals = Vec_IntAlloc( 100 ); // cone root values (0/1 CO values) p->vNodes = Vec_IntAlloc( 100 ); // cone nodes (node obj IDs) + p->vTemp = Vec_IntAlloc( 100 ); // cone nodes (node obj IDs) p->vPiLits = Vec_IntAlloc( 100 ); // resulting array of PI literals p->vFfLits = Vec_IntAlloc( 100 ); // resulting array of flop literals p->pMan = pMan; // calling manager @@ -85,6 +87,7 @@ void Txs_ManStop( Txs_Man_t * p ) Vec_IntFree( p->vCiVals ); Vec_IntFree( p->vCoVals ); Vec_IntFree( p->vNodes ); + Vec_IntFree( p->vTemp ); Vec_IntFree( p->vPiLits ); Vec_IntFree( p->vFfLits ); ABC_FREE( p ); @@ -143,7 +146,8 @@ void Txs_ManForwardPass( Gia_Man_t * p, Vec_Int_t * vPrio, Vec_Int_t * vCiObjs, Vec_Int_t * vCiVals, Vec_Int_t * vNodes, Vec_Int_t * vCoObjs, Vec_Int_t * vCoVals ) { - Gia_Obj_t * pObj, * pFan0, * pFan1; int i; + Gia_Obj_t * pObj, * pFan0, * pFan1; + int i, value0, value1; pObj = Gia_ManConst0(p); pObj->fMark0 = 0; pObj->fMark1 = 0; @@ -158,15 +162,17 @@ void Txs_ManForwardPass( Gia_Man_t * p, { pFan0 = Gia_ObjFanin0(pObj); pFan1 = Gia_ObjFanin1(pObj); - pObj->fMark0 = (pFan0->fMark0 ^ Gia_ObjFaninC0(pObj)) & (pFan1->fMark0 ^ Gia_ObjFaninC1(pObj)); + value0 = pFan0->fMark0 ^ Gia_ObjFaninC0(pObj); + value1 = pFan1->fMark0 ^ Gia_ObjFaninC1(pObj); + pObj->fMark0 = value0 && value1; pObj->fMark1 = 0; if ( pObj->fMark0 ) pObj->Value = Abc_MinInt( pFan0->Value, pFan1->Value ); - else if ( pFan0->fMark0 ) + else if ( value0 ) pObj->Value = pFan1->Value; - else if ( pFan1->fMark0 ) + else if ( value1 ) pObj->Value = pFan0->Value; - else // if ( pFan0->fMark0 == 0 && pFan1->fMark0 == 0 ) + else // if ( value0 == 0 && value1 == 0 ) pObj->Value = Abc_MaxInt( pFan0->Value, pFan1->Value ); assert( ~pObj->Value ); } @@ -202,9 +208,9 @@ static inline int Txs_ObjIsJust( Gia_Man_t * p, Gia_Obj_t * pObj ) assert( !pObj->fMark0 ); assert( !value0 || !value1 ); if ( value0 ) - return pFan1->fMark1; + return pFan1->fMark1 || Gia_ObjIsPi(p, pFan1); if ( value1 ) - return pFan0->fMark1; + return pFan0->fMark1 || Gia_ObjIsPi(p, pFan0); assert( !value0 && !value1 ); return pFan0->fMark1 || pFan1->fMark1 || Gia_ObjIsPi(p, pFan0) || Gia_ObjIsPi(p, pFan1); } @@ -215,6 +221,7 @@ void Txs_ManBackwardPass( Gia_Man_t * p, Vec_Int_t * vCiObjs, Vec_Int_t * vNodes { if ( !pObj->fMark1 ) continue; + pObj->fMark1 = 0; pFan0 = Gia_ObjFanin0(pObj); pFan1 = Gia_ObjFanin1(pObj); if ( pObj->fMark0 ) @@ -265,6 +272,156 @@ void Txs_ManBackwardPass( Gia_Man_t * p, Vec_Int_t * vCiObjs, Vec_Int_t * vNodes assert( Vec_IntSize(vFfLits) > 0 ); } +/**Function************************************************************* + + Synopsis [Collects justification path.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Txs_ManSelectJustPath( Gia_Man_t * p, Vec_Int_t * vNodes, Vec_Int_t * vCoObjs, Vec_Int_t * vRes ) +{ + Gia_Obj_t * pObj, * pFan0, * pFan1; + int i, value0, value1; + // mark CO drivers + Gia_ManForEachObjVec( vCoObjs, p, pObj, i ) + Gia_ObjFanin0(pObj)->fMark1 = 1; + // collect just paths + Vec_IntClear( vRes ); + Gia_ManForEachObjVecReverse( vNodes, p, pObj, i ) + { + if ( !pObj->fMark1 ) + continue; + pObj->fMark1 = 0; + Vec_IntPush( vRes, Gia_ObjId(p, pObj) ); + pFan0 = Gia_ObjFanin0(pObj); + pFan1 = Gia_ObjFanin1(pObj); + if ( pObj->fMark0 ) + { + pFan0->fMark1 = 1; + pFan1->fMark1 = 1; + continue; + } + value0 = pFan0->fMark0 ^ Gia_ObjFaninC0(pObj); + value1 = pFan1->fMark0 ^ Gia_ObjFaninC1(pObj); + assert( !value0 || !value1 ); + if ( value0 ) + pFan1->fMark1 = 1; + else if ( value1 ) + pFan0->fMark1 = 1; + else // if ( !value0 && !value1 ) + { + pFan0->fMark1 = 1; + pFan1->fMark1 = 1; + } + } + Vec_IntReverseOrder( vRes ); +} +void Txs_ManCollectJustPis( Gia_Man_t * p, Vec_Int_t * vCiObjs, Vec_Int_t * vPiLits ) +{ + Gia_Obj_t * pObj; int i; + Vec_IntClear( vPiLits ); + Gia_ManForEachObjVec( vCiObjs, p, pObj, i ) + if ( pObj->fMark1 && Gia_ObjIsPi(p, pObj) ) + Vec_IntPush( vPiLits, Abc_Var2Lit(Gia_ObjCioId(pObj), !pObj->fMark0) ); +} +void Txs_ManInitPrio( Gia_Man_t * p, Vec_Int_t * vCiObjs ) +{ + Gia_Obj_t * pObj; int i; + Gia_ManConst0(p)->Value = 0x7FFFFFFF; + Gia_ManForEachObjVec( vCiObjs, p, pObj, i ) + pObj->Value = Gia_ObjIsPi(p, pObj) ? 0x7FFFFFFF : Gia_ObjCioId(pObj) - Gia_ManPiNum(p); +} +void Txs_ManPropagatePrio( Gia_Man_t * p, Vec_Int_t * vNodes, Vec_Int_t * vPrio ) +{ + Gia_Obj_t * pObj, * pFan0, * pFan1; + int i, value0, value1; + Gia_ManForEachObjVec( vNodes, p, pObj, i ) + { + pFan0 = Gia_ObjFanin0(pObj); + pFan1 = Gia_ObjFanin1(pObj); + if ( pObj->fMark0 ) + { +// pObj->Value = Abc_MinInt( pFan0->Value, pFan1->Value ); + if ( pFan0->Value == 0x7FFFFFFF ) + pObj->Value = pFan1->Value; + else if ( pFan1->Value == 0x7FFFFFFF ) + pObj->Value = pFan0->Value; + else if ( Vec_IntEntry(vPrio, pFan0->Value) < Vec_IntEntry(vPrio, pFan1->Value) ) + pObj->Value = pFan0->Value; + else + pObj->Value = pFan1->Value; + continue; + } + value0 = pFan0->fMark0 ^ Gia_ObjFaninC0(pObj); + value1 = pFan1->fMark0 ^ Gia_ObjFaninC1(pObj); + assert( !value0 || !value1 ); + if ( value0 ) + pObj->Value = pFan1->Value; + else if ( value1 ) + pObj->Value = pFan0->Value; + else // if ( value0 == 0 && value1 == 0 ) + { +// pObj->Value = Abc_MaxInt( pFan0->Value, pFan1->Value ); + if ( pFan0->Value == 0x7FFFFFFF || pFan1->Value == 0x7FFFFFFF ) + pObj->Value = 0x7FFFFFFF; + else if ( Vec_IntEntry(vPrio, pFan0->Value) >= Vec_IntEntry(vPrio, pFan1->Value) ) + pObj->Value = pFan0->Value; + else + pObj->Value = pFan1->Value; + } + assert( ~pObj->Value ); + } +} +int Txs_ManFindMinId( Gia_Man_t * p, Vec_Int_t * vCoObjs, Vec_Int_t * vPrio ) +{ + Gia_Obj_t * pObj; int i, iMinId = -1; + Gia_ManForEachObjVec( vCoObjs, p, pObj, i ) + if ( Gia_ObjFanin0(pObj)->Value != 0x7FFFFFFF ) + { + if ( iMinId == -1 || Vec_IntEntry(vPrio, iMinId) > Vec_IntEntry(vPrio, Gia_ObjFanin0(pObj)->Value) ) + iMinId = Gia_ObjFanin0(pObj)->Value; + } + return iMinId; +} +void Txs_ManFindCiReduction( Gia_Man_t * p, + Vec_Int_t * vPrio, Vec_Int_t * vCiObjs, + Vec_Int_t * vNodes, Vec_Int_t * vCoObjs, + Vec_Int_t * vPiLits, Vec_Int_t * vFfLits, Vec_Int_t * vTemp ) +{ + Gia_Obj_t * pObj; + int iPrioCi; + // propagate PI influence + Txs_ManSelectJustPath( p, vNodes, vCoObjs, vTemp ); + Txs_ManCollectJustPis( p, vCiObjs, vPiLits ); +// printf( "%d -> %d ", Vec_IntSize(vNodes), Vec_IntSize(vTemp) ); + // iteratively detect and remove smallest IDs + Vec_IntClear( vFfLits ); + Txs_ManInitPrio( p, vCiObjs ); + while ( 1 ) + { + Txs_ManPropagatePrio( p, vTemp, vPrio ); + iPrioCi = Txs_ManFindMinId( p, vCoObjs, vPrio ); + if ( iPrioCi == -1 ) + break; + pObj = Gia_ManCi( p, Gia_ManPiNum(p)+iPrioCi ); + Vec_IntPush( vFfLits, Abc_Var2Lit(iPrioCi, !pObj->fMark0) ); + pObj->Value = 0x7FFFFFFF; + } +} +void Txs_ManPrintFlopLits( Vec_Int_t * vFfLits, Vec_Int_t * vPrio ) +{ + int i, Entry; + printf( "%3d : ", Vec_IntSize(vFfLits) ); + Vec_IntForEachEntry( vFfLits, Entry, i ) + printf( "%s%d(%d) ", Abc_LitIsCompl(Entry)? "+":"-", Abc_Lit2Var(Entry), Vec_IntEntry(vPrio, Abc_Lit2Var(Entry)) ); + printf( "\n" ); +} + /**Function************************************************************* Synopsis [Verify the result.] @@ -332,6 +489,7 @@ void Txs_ManVerify( Gia_Man_t * p, Vec_Int_t * vCiObjs, Vec_Int_t * vNodes, Vec_ ***********************************************************************/ Pdr_Set_t * Txs_ManTernarySim( Txs_Man_t * p, int k, Pdr_Set_t * pCube ) { + int fTryNew = 1; Pdr_Set_t * pRes; Gia_Obj_t * pObj; // collect CO objects @@ -370,7 +528,10 @@ Abc_Print( 1, " in frame %d.\n", k ); // perform two passes Txs_ManForwardPass( p->pGia, p->vPrio, p->vCiObjs, p->vCiVals, p->vNodes, p->vCoObjs, p->vCoVals ); - Txs_ManBackwardPass( p->pGia, p->vCiObjs, p->vNodes, p->vPiLits, p->vFfLits ); + if ( fTryNew ) + Txs_ManFindCiReduction( p->pGia, p->vPrio, p->vCiObjs, p->vNodes, p->vCoObjs, p->vPiLits, p->vFfLits, p->vTemp ); + else + Txs_ManBackwardPass( p->pGia, p->vCiObjs, p->vNodes, p->vPiLits, p->vFfLits ); Txs_ManVerify( p->pGia, p->vCiObjs, p->vNodes, p->vPiLits, p->vFfLits, p->vCoObjs, p->vCoVals ); // derive the final set diff --git a/src/sat/bmc/bmcCexCare.c b/src/sat/bmc/bmcCexCare.c index 21fea4293..a6613891f 100644 --- a/src/sat/bmc/bmcCexCare.c +++ b/src/sat/bmc/bmcCexCare.c @@ -158,7 +158,7 @@ void Bmc_CexCarePropagateFwd( Gia_Man_t * p, Abc_Cex_t * pCex, int fGrow, Vec_In SeeAlso [] ***********************************************************************/ -void Bmc_CexCarePropagateBwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, Abc_Cex_t * pCexMin ) +void Bmc_CexCarePropagateBwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, int fGrow, Abc_Cex_t * pCexMin ) { Gia_Obj_t * pObj; int i, Phase0, Phase1; @@ -184,10 +184,33 @@ void Bmc_CexCarePropagateBwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, Abc_Cex Gia_ObjFanin0(pObj)->fPhase = 1; else // if ( !Phase0 && !Phase1 ) { - if ( Abc_Lit2Var(Gia_ObjFanin0(pObj)->Value) <= Abc_Lit2Var(Gia_ObjFanin1(pObj)->Value) ) + if ( Gia_ObjFanin0(pObj)->fPhase || Gia_ObjFanin1(pObj)->fPhase ) + continue; + if ( Gia_ObjIsPi(p, Gia_ObjFanin0(pObj)) ) Gia_ObjFanin0(pObj)->fPhase = 1; - else + else if ( Gia_ObjIsPi(p, Gia_ObjFanin1(pObj)) ) Gia_ObjFanin1(pObj)->fPhase = 1; +// else if ( Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) && Txs_ObjIsJust(p, Gia_ObjFanin0(pObj)) ) +// Gia_ObjFanin0(pObj)->fPhase = 1; +// else if ( Gia_ObjIsAnd(Gia_ObjFanin1(pObj)) && Txs_ObjIsJust(p, Gia_ObjFanin1(pObj)) ) +// Gia_ObjFanin1(pObj)->fPhase = 1; + else + { + if ( fGrow & 1 ) + { + if ( Abc_Lit2Var(Gia_ObjFanin0(pObj)->Value) >= Abc_Lit2Var(Gia_ObjFanin1(pObj)->Value) ) + Gia_ObjFanin0(pObj)->fPhase = 1; + else + Gia_ObjFanin1(pObj)->fPhase = 1; + } + else + { + if ( Abc_Lit2Var(Gia_ObjFanin0(pObj)->Value) <= Abc_Lit2Var(Gia_ObjFanin1(pObj)->Value) ) + Gia_ObjFanin0(pObj)->fPhase = 1; + else + Gia_ObjFanin1(pObj)->fPhase = 1; + } + } } } Gia_ManForEachPi( p, pObj, i ) @@ -210,7 +233,7 @@ Abc_Cex_t * Bmc_CexCarePropagateBwd( Gia_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t Gia_ManForEachRo( p, pObj, i ) pObj->Value = Vec_IntEntry( vPrios, f * pCex->nRegs + i ); Bmc_CexCarePropagateFwdOne( p, pCex, f, fGrow ); - Bmc_CexCarePropagateBwdOne( p, pCex, f, pCexMin ); + Bmc_CexCarePropagateBwdOne( p, pCex, f, fGrow, pCexMin ); Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) pObjRi->fPhase = pObjRo->fPhase; } From aed9a87282bcb7937fd74e078d30ed74786abc75 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 6 Feb 2017 00:54:18 -0800 Subject: [PATCH 102/185] Adding specialized flop ordering before generalization in 'pdr'. --- src/base/abci/abc.c | 8 ++++++-- src/proof/pdr/pdr.h | 1 + src/proof/pdr/pdrCore.c | 32 +++++++++++++++++++++++++++++++- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 319525cfd..008adbae7 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26008,7 +26008,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Pdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmuysipdegoncvwzh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmuyfsipdegoncvwzh" ) ) != EOF ) { switch ( c ) { @@ -26129,6 +26129,9 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'y': pPars->fFlopPrio ^= 1; break; + case 'f': + pPars->fFlopOrder ^= 1; + break; case 's': pPars->fShortest ^= 1; break; @@ -26197,7 +26200,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmuysipdegoncvwzh]\n" ); + Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmuyfsipdegoncvwzh]\n" ); Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); @@ -26216,6 +26219,7 @@ usage: Abc_Print( -2, "\t-m : toggle using monolythic CNF computation [default = %s]\n", pPars->fMonoCnf? "yes": "no" ); Abc_Print( -2, "\t-u : toggle updated X-valued simulation [default = %s]\n", pPars->fNewXSim? "yes": "no" ); Abc_Print( -2, "\t-y : toggle using structural flop priorities [default = %s]\n", pPars->fFlopPrio? "yes": "no" ); + Abc_Print( -2, "\t-f : toggle ordering flops by cost before generalization [default = %s]\n", pPars->fFlopOrder? "yes": "no" ); Abc_Print( -2, "\t-s : toggle creating only shortest counter-examples [default = %s]\n", pPars->fShortest? "yes": "no" ); Abc_Print( -2, "\t-i : toggle clause pushing from an intermediate timeframe [default = %s]\n", pPars->fShiftStart? "yes": "no" ); Abc_Print( -2, "\t-p : toggle reusing proof-obligations in the last timeframe [default = %s]\n", pPars->fReuseProofOblig? "yes": "no" ); diff --git a/src/proof/pdr/pdr.h b/src/proof/pdr/pdr.h index 18b059c6e..66990bfb0 100644 --- a/src/proof/pdr/pdr.h +++ b/src/proof/pdr/pdr.h @@ -54,6 +54,7 @@ struct Pdr_Par_t_ int fMonoCnf; // monolythic CNF int fNewXSim; // updated X-valued simulation int fFlopPrio; // use structural flop priorities + int fFlopOrder; // order flops for 'analyze_final' during generalization int fDumpInv; // dump inductive invariant int fUseSupp; // use support in the invariant int fShortest; // forces bug traces to be shortest diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index cfc79d852..74a15e40d 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -63,8 +63,9 @@ void Pdr_ManSetDefaultParams( Pdr_Par_t * pPars ) pPars->fSkipDown = 1; // apply down in generalization pPars->fCtgs = 0; // handle CTGs in down pPars->fMonoCnf = 0; // monolythic CNF - pPars->fFlopPrio = 0; // use structural flop priorities pPars->fNewXSim = 0; // updated X-valued simulation + pPars->fFlopPrio = 0; // use structural flop priorities + pPars->fFlopOrder = 0; // order flops for 'analyze_final' during generalization pPars->fDumpInv = 0; // dump inductive invariant pPars->fUseSupp = 1; // using support variables in the invariant pPars->fShortest = 0; // forces bug traces to be shortest @@ -479,6 +480,31 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, } return 1; } + +/**Function************************************************************* + + Synopsis [Specialized sorting of flops based on cost.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_IntSelectSortCostReverseLit( int * pArray, int nSize, Vec_Int_t * vCosts ) +{ + int i, j, best_i; + for ( i = 0; i < nSize-1; i++ ) + { + best_i = i; + for ( j = i+1; j < nSize; j++ ) + if ( Vec_IntEntry(vCosts, Abc_Lit2Var(pArray[j])) > Vec_IntEntry(vCosts, Abc_Lit2Var(pArray[best_i])) ) + best_i = j; + ABC_SWAP( int, pArray[i], pArray[best_i] ); + } +} + /**Function************************************************************* Synopsis [Returns 1 if the state could be blocked.] @@ -500,7 +526,11 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP Hash_Int_t * keep = NULL; // if there is no induction, return *ppCubeMin = NULL; + if ( p->pPars->fFlopOrder ) + Vec_IntSelectSortCostReverseLit( pCube->Lits, pCube->nLits, p->vPrio ); RetValue = Pdr_ManCheckCube( p, k, pCube, ppPred, p->pPars->nConfLimit, 0 ); + if ( p->pPars->fFlopOrder ) + Vec_IntSelectSort( pCube->Lits, pCube->nLits ); if ( RetValue == -1 ) return -1; if ( RetValue == 0 ) From cac3967b52ae44fae3962ee9eba456221e0efda3 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Mon, 6 Feb 2017 11:34:52 -0800 Subject: [PATCH 103/185] =?UTF-8?q?Adding=20a=20new=20SAT=20solver=20to=20?= =?UTF-8?q?ABC.=20(Satoko)=20The=20command=20is=20=E2=80=98satoko=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 2 +- src/base/abci/abc.c | 82 +++- src/sat/satoko/LICENSE | 22 + src/sat/satoko/act_clause.h | 80 ++++ src/sat/satoko/act_var.h | 84 ++++ src/sat/satoko/cdb.h | 100 ++++ src/sat/satoko/clause.h | 63 +++ src/sat/satoko/cnf_reader.c | 156 ++++++ src/sat/satoko/module.make | 3 + src/sat/satoko/satoko.h | 85 ++++ src/sat/satoko/solver.c | 704 ++++++++++++++++++++++++++++ src/sat/satoko/solver.h | 242 ++++++++++ src/sat/satoko/solver_api.c | 310 ++++++++++++ src/sat/satoko/types.h | 50 ++ src/sat/satoko/utils/b_queue.h | 81 ++++ src/sat/satoko/utils/heap.h | 181 +++++++ src/sat/satoko/utils/mem.h | 23 + src/sat/satoko/utils/misc.h | 37 ++ src/sat/satoko/utils/sort.h | 65 +++ src/sat/satoko/utils/vec/vec_char.h | 259 ++++++++++ src/sat/satoko/utils/vec/vec_dble.h | 246 ++++++++++ src/sat/satoko/utils/vec/vec_int.h | 240 ++++++++++ src/sat/satoko/utils/vec/vec_uint.h | 268 +++++++++++ src/sat/satoko/watch_list.h | 152 ++++++ 24 files changed, 3533 insertions(+), 2 deletions(-) create mode 100644 src/sat/satoko/LICENSE create mode 100644 src/sat/satoko/act_clause.h create mode 100644 src/sat/satoko/act_var.h create mode 100644 src/sat/satoko/cdb.h create mode 100644 src/sat/satoko/clause.h create mode 100644 src/sat/satoko/cnf_reader.c create mode 100644 src/sat/satoko/module.make create mode 100644 src/sat/satoko/satoko.h create mode 100644 src/sat/satoko/solver.c create mode 100644 src/sat/satoko/solver.h create mode 100644 src/sat/satoko/solver_api.c create mode 100644 src/sat/satoko/types.h create mode 100644 src/sat/satoko/utils/b_queue.h create mode 100644 src/sat/satoko/utils/heap.h create mode 100755 src/sat/satoko/utils/mem.h create mode 100755 src/sat/satoko/utils/misc.h create mode 100644 src/sat/satoko/utils/sort.h create mode 100644 src/sat/satoko/utils/vec/vec_char.h create mode 100755 src/sat/satoko/utils/vec/vec_dble.h create mode 100755 src/sat/satoko/utils/vec/vec_int.h create mode 100755 src/sat/satoko/utils/vec/vec_uint.h create mode 100644 src/sat/satoko/watch_list.h diff --git a/Makefile b/Makefile index d45978a9d..4142e1b28 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ MODULES := \ src/opt/cut src/opt/fxu src/opt/fxch src/opt/rwr src/opt/mfs src/opt/sim \ src/opt/ret src/opt/fret src/opt/res src/opt/lpk src/opt/nwk src/opt/rwt \ src/opt/cgt src/opt/csw src/opt/dar src/opt/dau src/opt/dsc src/opt/sfm src/opt/sbd \ - src/sat/bsat src/sat/xsat src/sat/csat src/sat/msat src/sat/psat src/sat/cnf src/sat/bmc \ + src/sat/bsat src/sat/xsat src/sat/satoko src/sat/csat src/sat/msat src/sat/psat src/sat/cnf src/sat/bmc \ src/bool/bdc src/bool/deco src/bool/dec src/bool/kit src/bool/lucky \ src/bool/rsb src/bool/rpo \ src/proof/pdr src/proof/abs src/proof/live src/proof/ssc src/proof/int \ diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 008adbae7..efb82fcc2 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -43,6 +43,7 @@ #include "map/amap/amap.h" #include "opt/ret/retInt.h" #include "sat/xsat/xsat.h" +#include "sat/satoko/satoko.h" #include "sat/cnf/cnf.h" #include "proof/cec/cec.h" #include "proof/acec/acec.h" @@ -308,6 +309,7 @@ static int Abc_CommandDSec ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandDSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandXSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandSatoko ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandIProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -956,6 +958,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Verification", "sat", Abc_CommandSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "dsat", Abc_CommandDSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "xsat", Abc_CommandXSat, 0 ); + Cmd_CommandAdd( pAbc, "Verification", "satoko", Abc_CommandSatoko, 0 ); Cmd_CommandAdd( pAbc, "Verification", "psat", Abc_CommandPSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "prove", Abc_CommandProve, 1 ); Cmd_CommandAdd( pAbc, "Verification", "iprove", Abc_CommandIProve, 1 ); @@ -23302,6 +23305,83 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandSatoko( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + abctime clk; + int c; + satoko_opts_t opts; + + satoko_default_opts(&opts); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Chv" ) ) != EOF ) + { + switch ( c ) + { + case 'C': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); + goto usage; + } + opts.conf_limit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.conf_limit < 0 ) + goto usage; + break; + case 'h': + goto usage; + case 'v': + opts.verbose ^= 1; + break; + + default: + goto usage; + } + } + + if ( argc == globalUtilOptind + 1 ) + { + char * pFileName = argv[globalUtilOptind]; + satoko_t * p; + int status; + + satoko_parse_dimacs( pFileName, &p ); + satoko_configure(p, &opts); + + clk = Abc_Clock(); + status = satoko_solve( p ); + + if ( status == SATOKO_UNDEC ) + Abc_Print( 1, "UNDECIDED " ); + else if ( status == SATOKO_SAT ) + Abc_Print( 1, "SATISFIABLE " ); + else + Abc_Print( 1, "UNSATISFIABLE " ); + + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + + satoko_destroy( p ); + return 0; + } + +usage: + Abc_Print( -2, "usage: satoko [-CILDE num] [-hv].cnf\n" ); + Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", opts.conf_limit ); + Abc_Print( -2, "\t-v : prints verbose information [default = %s]\n", opts.verbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} /**Function************************************************************* Synopsis [] @@ -26238,7 +26318,7 @@ usage: Abc_Print( -2, "\t Zyad Hassan, Aaron R. Bradley, Fabio Somenzi, \"Better Generalization in IC3\", FMCAD 2013.\n"); Abc_Print( -2, "\t (http://www.cs.utexas.edu/users/hunt/FMCAD/FMCAD13/papers/85-Better-Generalization-IC3.pdf)\n"); - + return 1; } diff --git a/src/sat/satoko/LICENSE b/src/sat/satoko/LICENSE new file mode 100644 index 000000000..519381371 --- /dev/null +++ b/src/sat/satoko/LICENSE @@ -0,0 +1,22 @@ +Copyright 2017, Bruno Schmitt - UC Berkeley / UFRGS (bruno@oschmitt.com) + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/sat/satoko/act_clause.h b/src/sat/satoko/act_clause.h new file mode 100644 index 000000000..5a2fda2b7 --- /dev/null +++ b/src/sat/satoko/act_clause.h @@ -0,0 +1,80 @@ +//===--- act_var.h ----------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__act_clause_h +#define satoko__act_clause_h + +#include "solver.h" +#include "types.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +#ifdef SATOKO_ACT_CLAUSE_FLOAT + +/** Re-scale the activity value for all clauses. + */ +static inline void clause_act_rescale(solver_t *s) +{ + unsigned i, cref; + struct clause *clause; + + vec_uint_foreach(s->learnts, cref, i) { + clause = clause_read(s, cref); + clause->data[clause->size].act *= 1e-20; + } + s->clause_act_inc *= 1e-20; +} + +/** Increment the activity value of one clause ('clause') + */ +static inline void clause_act_bump(solver_t *s, struct clause *clause) +{ + clause->data[clause->size].act += s->clause_act_inc; + if (clause->data[clause->size].act > 1e20) + clause_act_rescale(s); +} + +/** Increment the value by which clauses activity values are incremented + */ +static inline void clause_act_decay(solver_t *s) +{ + s->clause_act_inc *= (1 / s->opts.clause_decay); +} + +#else /* SATOKO_ACT_CLAUSE_FLOAT */ + +static inline void clause_act_rescale(solver_t *s) +{ + unsigned i, cref; + struct clause *clause; + + vec_uint_foreach(s->learnts, cref, i) { + clause = clause_read(s, cref); + clause->data[clause->size].act >>= 14; + } + s->clause_act_inc >>= 14; + s->clause_act_inc = mkt_uint_max(s->clause_act_inc, (1 << 10)); +} + +static inline void clause_act_bump(solver_t *s, struct clause *clause) +{ + clause->data[clause->size].act += s->clause_act_inc; + if (clause->data[clause->size].act & 0x80000000) + clause_act_rescale(s); +} + +static inline void clause_act_decay(solver_t *s) +{ + s->clause_act_inc += (s->clause_act_inc >> 10); +} + +#endif /* SATOKO_ACT_CLAUSE_FLOAT */ + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__act_clause_h */ diff --git a/src/sat/satoko/act_var.h b/src/sat/satoko/act_var.h new file mode 100644 index 000000000..161e9d9a4 --- /dev/null +++ b/src/sat/satoko/act_var.h @@ -0,0 +1,84 @@ +//===--- act_var.h ----------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__act_var_h +#define satoko__act_var_h + +#include "solver.h" +#include "types.h" +#include "utils/heap.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +#ifdef SATOKO_ACT_VAR_DBLE +/** Re-scale the activity value for all variables. + */ +static inline void var_act_rescale(solver_t *s) +{ + unsigned i; + double *activity = vec_dble_data(s->activity); + + for (i = 0; i < vec_dble_size(s->activity); i++) + activity[i] *= 1e-100; + s->var_act_inc *= 1e-100; +} + +/** Increment the activity value of one variable ('var') + */ +static inline void var_act_bump(solver_t *s, unsigned var) +{ + double *activity = vec_dble_data(s->activity); + + activity[var] += s->var_act_inc; + if (activity[var] > 1e100) + var_act_rescale(s); + if (heap_in_heap(s->var_order, var)) + heap_decrease(s->var_order, var); +} + +/** Increment the value by which variables activity values are incremented + */ +static inline void var_act_decay(solver_t *s) +{ + s->var_act_inc *= (1 / s->opts.var_decay); +} + +#else /* SATOKO_ACT_VAR_DBLE */ + +static inline void var_act_rescale(solver_t *s) +{ + unsigned i; + unsigned *activity = vec_uint_data(s->activity); + + for (i = 0; i < vec_uint_size(s->activity); i++) + activity[i] >>= 19; + s->var_act_inc >>= 19; + s->var_act_inc = mkt_uint_max(s->var_act_inc, (1 << 5)); +} + +static inline void var_act_bump(solver_t *s, unsigned var) +{ + unsigned *activity = vec_uint_data(s->activity); + + activity[var] += s->var_act_inc; + if (activity[var] & 0x80000000) + var_act_rescale(s); + if (heap_in_heap(s->var_order, var)) + heap_decrease(s->var_order, var); +} + +static inline void var_act_decay(solver_t *s) +{ + s->var_act_inc += (s->var_act_inc >> 4); +} + +#endif /* SATOKO_ACT_VAR_DBLE */ + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__act_var_h */ diff --git a/src/sat/satoko/cdb.h b/src/sat/satoko/cdb.h new file mode 100644 index 000000000..28686ff27 --- /dev/null +++ b/src/sat/satoko/cdb.h @@ -0,0 +1,100 @@ +//===--- cdb.h --------------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__cdb_h +#define satoko__cdb_h + +#include "clause.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +/* Clauses DB data structure */ +struct cdb { + unsigned size; + unsigned cap; + unsigned wasted; + unsigned *data; +}; + +//===------------------------------------------------------------------------=== +// Clause DB API +//===------------------------------------------------------------------------=== +static inline struct clause *cdb_handler(struct cdb *p, unsigned cref) +{ + return cref != 0xFFFFFFFF ? (struct clause *)(p->data + cref) : NULL; +} + +static inline unsigned cdb_cref(struct cdb *p, unsigned *clause) +{ + return (unsigned)(clause - &(p->data[0])); +} + +static inline void cdb_grow(struct cdb *p, unsigned cap) +{ + unsigned prev_cap = p->cap; + + if (p->cap >= cap) + return; + while (p->cap < cap) { + unsigned delta = ((p->cap >> 1) + (p->cap >> 3) + 2) & (unsigned)(~1); + p->cap += delta; + assert(p->cap >= prev_cap); + } + assert(p->cap > 0); + p->data = satoko_realloc(unsigned, p->data, p->cap); +} + +static inline struct cdb *cdb_alloc(unsigned cap) +{ + struct cdb *p = satoko_calloc(struct cdb, 1); + if (cap <= 0) + cap = 1024 * 1024; + cdb_grow(p, cap); + return p; +} + +static inline void cdb_free(struct cdb *p) +{ + satoko_free(p->data); + satoko_free(p); +} + +static inline unsigned cdb_append(struct cdb *p, unsigned size) +{ + unsigned prev_size; + assert(size > 0); + cdb_grow(p, p->size + size); + prev_size = p->size; + p->size += size; + assert(p->size > prev_size); + return prev_size; +} + +static inline void cdb_remove(struct cdb *p, struct clause *clause) +{ + p->wasted += clause->size; +} + +static inline unsigned cdb_capacity(struct cdb *p) +{ + return p->cap; +} + +static inline unsigned cdb_size(struct cdb *p) +{ + return p->size; +} + +static inline unsigned cdb_wasted(struct cdb *p) +{ + return p->wasted; +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__cdb_h */ diff --git a/src/sat/satoko/clause.h b/src/sat/satoko/clause.h new file mode 100644 index 000000000..2be18cd6a --- /dev/null +++ b/src/sat/satoko/clause.h @@ -0,0 +1,63 @@ +//===--- clause.h -----------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__clause_h +#define satoko__clause_h + +#include "types.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +struct clause { + unsigned f_learnt : 1; + unsigned f_mark : 1; + unsigned f_reallocd : 1; + unsigned f_deletable : 1; + unsigned lbd : 28; + unsigned size; + union { + unsigned lit; + clause_act_t act; + } data[0]; +}; + +//===------------------------------------------------------------------------=== +// Clause API +//===------------------------------------------------------------------------=== +static inline int clause_compare(const void *p1, const void *p2) +{ + const struct clause *c1 = (const struct clause *)p1; + const struct clause *c2 = (const struct clause *)p2; + + if (c1->size > 2 && c2->size == 2) + return 1; + if (c1->size == 2 && c2->size > 2) + return 0; + if (c1->size == 2 && c2->size == 2) + return 0; + + if (c1->lbd > c2->lbd) + return 1; + if (c1->lbd < c2->lbd) + return 0; + + return c1->data[c1->size].act < c2->data[c2->size].act; +} + +static inline void clause_print(struct clause *clause) +{ + unsigned i; + printf("{ "); + for (i = 0; i < clause->size; i++) + printf("%u ", clause->data[i].lit); + printf("}\n"); +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__clause_h */ diff --git a/src/sat/satoko/cnf_reader.c b/src/sat/satoko/cnf_reader.c new file mode 100644 index 000000000..5e4b92f92 --- /dev/null +++ b/src/sat/satoko/cnf_reader.c @@ -0,0 +1,156 @@ +//===--- cnf_reader.h -------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#include +#include +#include +#include +#include + +#include "satoko.h" +#include "solver.h" +#include "utils/mem.h" +#include "utils/vec/vec_uint.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_IMPL_START + +/** Read the file into an internal buffer. + * + * This function will receive a file name. The return data is a string ended + * with '\0'. + * + */ +static char * file_open(const char *fname) +{ + FILE *file = fopen(fname, "rb"); + char *buffer; + int sz_file; + int ret; + + if (file == NULL) { + printf("Couldn't open file: %s\n", fname); + return NULL; + } + fseek(file, 0, SEEK_END); + sz_file = ftell(file); + rewind(file); + buffer = satoko_alloc(char, sz_file + 3); + ret = fread(buffer, sz_file, 1, file); + buffer[sz_file + 0] = '\n'; + buffer[sz_file + 1] = '\0'; + return buffer; +} + +static void skip_spaces(char **pos) +{ + assert(pos != NULL); + for (; isspace(**pos); (*pos)++); +} + +static void skip_line(char **pos) +{ + assert(pos != NULL); + for(; **pos != '\n' && **pos != '\r' && **pos != EOF; (*pos)++); + if (**pos != EOF) + (*pos)++; + return; +} + +static int read_int(char **token) +{ + int value = 0; + int neg = 0; + + skip_spaces(token); + if (**token == '-') { + neg = 1; + (*token)++; + } else if (**token == '+') + (*token)++; + + if (!isdigit(**token)) { + printf("Parsing error. Unexpected char: %c.\n", **token); + exit(EXIT_FAILURE); + } + while (isdigit(**token)) { + value = (value * 10) + (**token - '0'); + (*token)++; + } + return neg ? -value : value; +} + +static void read_clause(char **token, vec_uint_t *lits) +{ + int var; + unsigned sign; + + vec_uint_clear(lits); + while (1) { + var = read_int(token); + if (var == 0) + break; + sign = (var > 0); + var = abs(var) - 1; + vec_uint_push_back(lits, var2lit((unsigned) var, !sign)); + } +} + +/** Start the solver and reads the DIMAC file. + * + * Returns false upon immediate conflict. + */ +int satoko_parse_dimacs(char *fname, satoko_t **solver) +{ + satoko_t *p = NULL; + vec_uint_t *lits = NULL; + int n_var; + int n_clause; + char *buffer = file_open(fname); + char *token; + + if (buffer == NULL) + return -1; + + token = buffer; + while (1) { + skip_spaces(&token); + if (*token == 0) + break; + else if (*token == 'c') + skip_line(&token); + else if (*token == 'p') { + token++; + skip_spaces(&token); + for(; !isspace(*token); token++); /* skip 'cnf' */ + + n_var = read_int(&token); + n_clause = read_int(&token); + skip_line(&token); + lits = vec_uint_alloc((unsigned) n_var); + p = satoko_create(); + } else { + if (lits == NULL) { + printf("There is no parameter line.\n"); + satoko_free(buffer); + return -1; + } + read_clause(&token, lits); + if (!satoko_add_clause(p, vec_uint_data(lits), vec_uint_size(lits))) { + vec_uint_print(lits); + return 0; + } + } + } + vec_uint_free(lits); + satoko_free(buffer); + *solver = p; + return satoko_simplify(p); +} + +ABC_NAMESPACE_IMPL_END diff --git a/src/sat/satoko/module.make b/src/sat/satoko/module.make new file mode 100644 index 000000000..512094ee3 --- /dev/null +++ b/src/sat/satoko/module.make @@ -0,0 +1,3 @@ +SRC += src/sat/satoko/solver.c \ + src/sat/satoko/solver_api.c \ + src/sat/satoko/cnf_reader.c diff --git a/src/sat/satoko/satoko.h b/src/sat/satoko/satoko.h new file mode 100644 index 000000000..49c7837e4 --- /dev/null +++ b/src/sat/satoko/satoko.h @@ -0,0 +1,85 @@ +//===--- satoko.h -----------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__satoko_h +#define satoko__satoko_h + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +/** Return valeus */ +enum { + SATOKO_ERR = 0, + SATOKO_OK = 1 +}; + +enum { + SATOKO_UNDEC = 0, /* Undecided */ + SATOKO_SAT = 1, + SATOKO_UNSAT = -1 +}; + +struct solver_t_; +typedef struct solver_t_ satoko_t; + +typedef struct satoko_opts satoko_opts_t; +struct satoko_opts { + /* Limits */ + long long conf_limit; /* Limit on the n.of conflicts */ + long long prop_limit; /* Limit on the n.of implications */ + + /* Constants used for restart heuristic */ + double f_rst; /* Used to force a restart */ + double b_rst; /* Used to block a restart */ + unsigned fst_block_rst; /* Lower bound n.of conflicts for start blocking restarts */ + unsigned sz_lbd_bqueue; /* Size of the moving avarege queue for LBD (force restart) */ + unsigned sz_trail_bqueue; /* Size of the moving avarege queue for Trail size (block restart) */ + + /* Constants used for clause database reduction heuristic */ + unsigned n_conf_fst_reduce; /* N.of conflicts before first reduction */ + unsigned inc_reduce; /* Increment to reduce */ + unsigned inc_special_reduce; /* Special increment to reduce */ + unsigned lbd_freeze_clause; + + /* VSIDS heuristic */ + float clause_decay; + double var_decay; + + /* Binary resolution */ + unsigned clause_max_sz_bin_resol; + unsigned clause_min_lbd_bin_resol; + float garbage_max_ratio; + char verbose; +}; + +//===------------------------------------------------------------------------=== +extern satoko_t *satoko_create(void); +extern void satoko_destroy(satoko_t *); +extern void satoko_default_opts(satoko_opts_t *); +extern void satoko_configure(satoko_t *, satoko_opts_t *); +extern int satoko_parse_dimacs(char *, satoko_t **); +extern void satoko_add_variable(satoko_t *, char); +extern int satoko_add_clause(satoko_t *, unsigned *, unsigned); +extern void satoko_assump_push(satoko_t *s, unsigned); +extern void satoko_assump_pop(satoko_t *s); +extern int satoko_simplify(satoko_t *); +extern int satoko_solve(satoko_t *); + +/* If problem is unsatisfiable under assumptions, this function is used to + * obtain the final conflict clause expressed in the assumptions. + * + * - It receives as inputs the solver and a pointer to a array where clause + * will be copied. The memory is allocated by the solver, but must be freed by + * the caller. + * - The return value is either the size of the array or -1 in case the final + * conflict cluase was not generated. + */ +extern int satoko_final_conflict(satoko_t *, unsigned *); + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__satoko_h */ diff --git a/src/sat/satoko/solver.c b/src/sat/satoko/solver.c new file mode 100644 index 000000000..b2861badc --- /dev/null +++ b/src/sat/satoko/solver.c @@ -0,0 +1,704 @@ +//===--- solver.c -----------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#include +#include +#include +#include + +#include "act_clause.h" +#include "act_var.h" +#include "solver.h" +#include "utils/heap.h" +#include "utils/mem.h" +#include "utils/sort.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_IMPL_START + +//===------------------------------------------------------------------------=== +// Lit funtions +//===------------------------------------------------------------------------=== +/** + * A literal is said to be redundant in a given clause if and only if all + * variables in its reason are either present in that clause or (recursevely) + * redundant. + */ +static inline int lit_is_removable(solver_t* s, unsigned lit, unsigned min_level) +{ + unsigned top = vec_uint_size(s->tagged); + + assert(lit_reason(s, lit) != UNDEF); + vec_uint_clear(s->stack); + vec_uint_push_back(s->stack, lit2var(lit)); + while (vec_uint_size(s->stack)) { + unsigned i; + unsigned var = vec_uint_pop_back(s->stack); + struct clause *c = clause_read(s, var_reason(s, var)); + unsigned *lits = &(c->data[0].lit); + + assert(var_reason(s, var) != UNDEF); + if (c->size == 2 && lit_value(s, lits[0]) == LIT_FALSE) { + assert(lit_value(s, lits[1]) == LIT_TRUE); + mkt_swap(unsigned, lits[0], lits[1]); + } + + /* Check scan the literals of the reason clause. + * The first literal is skiped because is the literal itself. */ + for (i = 1; i < c->size; i++) { + var = lit2var(lits[i]); + + /* Check if the variable has already been seen or if it + * was assinged a value at the decision level 0. In a + * positive case, there is no need to look any further */ + if (vec_char_at(s->seen, var) || var_dlevel(s, var) == 0) + continue; + + /* If the variable has a reason clause and if it was + * assingned at a 'possible' level, then we need to + * check if it is recursively redundant, otherwise the + * literal being checked is not redundant */ + if (var_reason(s, var) != UNDEF && ((1 << (var_dlevel(s, var) & 31)) & min_level)) { + vec_uint_push_back(s->stack, var); + vec_uint_push_back(s->tagged, var); + vec_char_assign(s->seen, var, 1); + } else { + vec_uint_foreach_start(s->tagged, var, i, top) + vec_char_assign(s->seen, var, 0); + vec_uint_shrink(s->tagged, top); + return 0; + } + } + } + return 1; +} + +//===------------------------------------------------------------------------=== +// Clause functions +//===------------------------------------------------------------------------=== +/* Calculate clause LBD (Literal Block Distance): + * - It's the number of variables in the final conflict clause that come from + * different decision levels + */ +static inline unsigned clause_clac_lbd(solver_t *s, unsigned *lits, unsigned size) +{ + unsigned i; + unsigned lbd = 0; + + s->cur_stamp++; + for (i = 0; i < size; i++) { + unsigned level = lit_dlevel(s, lits[i]); + if (vec_uint_at(s->stamps, level) != s->cur_stamp) { + vec_uint_assign(s->stamps, level, s->cur_stamp); + lbd++; + } + } + return lbd; +} + +static inline void clause_bin_resolution(solver_t *s, vec_uint_t *clause_lits) +{ + unsigned *lits = vec_uint_data(clause_lits); + unsigned counter, sz, i; + unsigned lit; + unsigned neg_lit = lit_neg(lits[0]); + struct watcher *w; + + s->cur_stamp++; + vec_uint_foreach(clause_lits, lit, i) + vec_uint_assign(s->stamps, lit2var(lit), s->cur_stamp); + + counter = 0; + watch_list_foreach(s->bin_watches, w, neg_lit) { + unsigned imp_lit = w->blocker; + if (vec_uint_at(s->stamps, lit2var(imp_lit)) == s->cur_stamp && + lit_value(s, imp_lit) == LIT_TRUE) { + counter++; + vec_uint_assign(s->stamps, lit2var(imp_lit), (s->cur_stamp - 1)); + } + } + if (counter > 0) { + sz = vec_uint_size(clause_lits) - 1; + for (i = 1; i < vec_uint_size(clause_lits) - counter; i++) + if (vec_uint_at(s->stamps, lit2var(lits[i])) != s->cur_stamp) { + mkt_swap(unsigned, lits[i], lits[sz]); + i--; + sz--; + } + vec_uint_shrink(clause_lits, vec_uint_size(clause_lits) - counter); + } +} + +static inline void clause_minimize(solver_t *s, vec_uint_t *clause_lits) +{ + unsigned i, j; + unsigned *lits = vec_uint_data(clause_lits); + unsigned min_level = 0; + unsigned clause_size; + + for (i = 1; i < vec_uint_size(clause_lits); i++) { + unsigned level = lit_dlevel(s, lits[i]); + min_level |= 1 << (level & 31); + } + + /* Remove reduntant literals */ + vec_uint_foreach(clause_lits, i, j) + vec_uint_push_back(s->tagged, lit2var(i)); + for (i = j = 1; i < vec_uint_size(clause_lits); i++) + if (lit_reason(s, lits[i]) == UNDEF || !lit_is_removable(s, lits[i], min_level)) + lits[j++] = lits[i]; + vec_uint_shrink(clause_lits, j); + + /* Binary Resolution */ + clause_size = vec_uint_size(clause_lits); + if (clause_size <= s->opts.clause_max_sz_bin_resol && + clause_clac_lbd(s, lits, clause_size) <= s->opts.clause_min_lbd_bin_resol) + clause_bin_resolution(s, clause_lits); +} + +static inline void clause_realloc(struct cdb *dest, struct cdb *src, unsigned *cref) +{ + unsigned new_cref; + struct clause *new_clause; + struct clause *old_clause = cdb_handler(src, *cref); + + if (old_clause->f_reallocd) { + *cref = (unsigned) old_clause->size; + return; + } + new_cref = cdb_append(dest, 3 + old_clause->f_learnt + old_clause->size); + new_clause = cdb_handler(dest, new_cref); + memcpy(new_clause, old_clause, (3 + old_clause->f_learnt + old_clause->size) * 4); + old_clause->f_reallocd = 1; + old_clause->size = (unsigned) new_cref; + *cref = new_cref; +} + +//===------------------------------------------------------------------------=== +// Solver internal functions +//===------------------------------------------------------------------------=== +static inline unsigned solver_decide(solver_t *s) +{ + unsigned next_var = UNDEF; + + while (next_var == UNDEF || var_value(s, next_var) != VAR_UNASSING) { + if (heap_size(s->var_order) == 0) { + next_var = UNDEF; + return UNDEF; + } else + next_var = heap_remove_min(s->var_order); + } + return var2lit(next_var, vec_char_at(s->polarity, next_var)); +} + +static inline void solver_new_decision(solver_t *s, unsigned lit) +{ + assert(var_value(s, lit2var(lit)) == VAR_UNASSING); + vec_uint_push_back(s->trail_lim, vec_uint_size(s->trail)); + solver_enqueue(s, lit, UNDEF); +} + +/* Calculate Backtrack Level from the learnt clause */ +static inline unsigned solver_calc_bt_level(solver_t *s, vec_uint_t *learnt) +{ + unsigned i, tmp; + unsigned i_max = 1; + unsigned *lits = vec_uint_data(learnt); + unsigned max = lit_dlevel(s, lits[1]); + + if (vec_uint_size(learnt) == 1) + return 0; + for (i = 2; i < vec_uint_size(learnt); i++) { + if (lit_dlevel(s, lits[i]) > max) { + max = lit_dlevel(s, lits[i]); + i_max = i; + } + } + tmp = lits[1]; + lits[1] = lits[i_max]; + lits[i_max] = tmp; + return lit_dlevel(s, lits[1]); +} + +/** + * Most books and papers explain conflict analysis and the calculation of the + * 1UIP (first Unique Implication Point) using an implication graph. This + * function, however, do not explicity constructs the graph! It inspects the + * trail in reverse and figure out which literals should be added to the + * to-be-learnt clause using the reasons of each assignment. + * + * cur_lit: current literal being analyzed. + * n_paths: number of unprocessed paths from conlfict node to the current + * literal being analyzed (cur_lit). + * + * This functions performs a backward BFS (breadth-first search) for 1UIP node. + * The trail works as the BFS queue. The counter of unprocessed but seen + * variables (n_paths) allows us to identify when 'cur_lit' is the closest + * cause of conflict. + * + * When 'n_paths' reaches zero it means there are no unprocessed reverse paths + * back from the conflict node to 'cur_lit' - meaning it is the 1UIP decision + * variable. + * + */ +static inline void solver_analyze(solver_t *s, unsigned cref, vec_uint_t *learnt, + unsigned *bt_level, unsigned *lbd) +{ + unsigned i; + unsigned *trail = vec_uint_data(s->trail); + unsigned idx = vec_uint_size(s->trail) - 1; + unsigned n_paths = 0; + unsigned p = UNDEF; + unsigned var; + + vec_uint_push_back(learnt, UNDEF); + do { + struct clause *clause; + unsigned *lits; + unsigned j; + + assert(cref != UNDEF); + clause = clause_read(s, cref); + lits = &(clause->data[0].lit); + + if (p != UNDEF && clause->size == 2 && lit_value(s, lits[0]) == LIT_FALSE) { + assert(lit_value(s, lits[1]) == LIT_TRUE); + mkt_swap(unsigned, lits[0], lits[1] ); + } + + if (clause->f_learnt) + clause_act_bump(s, clause); + + if (clause->f_learnt && clause->lbd > 2) { + unsigned n_levels = clause_clac_lbd(s, lits, clause->size); + if (n_levels + 1 < clause->lbd) { + if (clause->lbd <= s->opts.lbd_freeze_clause) + clause->f_deletable = 0; + clause->lbd = n_levels; + } + } + + for (j = (p == UNDEF ? 0 : 1); j < clause->size; j++) { + var = lit2var(lits[j]); + if (vec_char_at(s->seen, var) || var_dlevel(s, var) == 0) + continue; + vec_char_assign(s->seen, var, 1); + var_act_bump(s, var); + if (var_dlevel(s, var) == solver_dlevel(s)) { + n_paths++; + if (var_reason(s, var) != UNDEF && clause_read(s, var_reason(s, var))->f_learnt) + vec_uint_push_back(s->last_dlevel, var); + } else + vec_uint_push_back(learnt, lits[j]); + } + + while (!vec_char_at(s->seen, lit2var(trail[idx--]))); + + p = trail[idx + 1]; + cref = lit_reason(s, p); + vec_char_assign(s->seen, lit2var(p), 0); + n_paths--; + } while (n_paths > 0); + + vec_uint_data(learnt)[0] = lit_neg(p); + clause_minimize(s, learnt); + *bt_level = solver_calc_bt_level(s, learnt); + *lbd = clause_clac_lbd(s, vec_uint_data(learnt), vec_uint_size(learnt)); + + if (vec_uint_size( s->last_dlevel) > 0) { + vec_uint_foreach(s->last_dlevel, var, i) { + if (clause_read(s, var_reason(s, var))->lbd < *lbd) + var_act_bump(s, var); + } + vec_uint_clear(s->last_dlevel); + } + vec_uint_foreach(s->tagged, var, i) + vec_char_assign(s->seen, var, 0); + vec_uint_clear(s->tagged); +} + +static inline int solver_rst(solver_t *s) +{ + return b_queue_is_valid(s->bq_lbd) && + (((long long)b_queue_avg(s->bq_lbd) * s->opts.f_rst) > (s->sum_lbd / s->stats.n_conflicts)); +} + +static inline int solver_block_rst(solver_t *s) +{ + return s->stats.n_conflicts > s->opts.fst_block_rst && + b_queue_is_valid(s->bq_lbd) && + (vec_uint_size(s->trail) > (s->opts.b_rst * (long long)b_queue_avg(s->bq_trail))); +} + +static inline void solver_handle_conflict(solver_t *s, unsigned confl_cref) +{ + unsigned bt_level; + unsigned lbd; + unsigned cref; + + vec_uint_clear(s->temp_lits); + solver_analyze(s, confl_cref, s->temp_lits, &bt_level, &lbd); + s->sum_lbd += lbd; + b_queue_push(s->bq_lbd, lbd); + solver_cancel_until(s, bt_level); + cref = UNDEF; + if (vec_uint_size(s->temp_lits) > 1) { + cref = solver_clause_create(s, s->temp_lits, 1); + clause_watch(s, cref); + } + solver_enqueue(s, vec_uint_at(s->temp_lits, 0), cref); + var_act_decay(s); + clause_act_decay(s); +} + +static inline void solver_analyze_final(solver_t *s, unsigned lit) +{ + unsigned i; + + vec_uint_push_back(s->final_conflict, lit); + if (solver_dlevel(s) == 0) + return; + vec_char_assign(s->seen, lit2var(lit), 1); + for (i = vec_uint_size(s->trail) - 1; i <= vec_uint_at(s->trail_lim, 0); i--) { + unsigned var = lit2var(vec_uint_at(s->trail, i)); + + if (vec_char_at(s->seen, var)) { + unsigned reason = var_reason(s, var); + if (reason == UNDEF) { + assert(var_dlevel(s, var) > 0); + vec_uint_push_back(s->final_conflict, lit_neg(vec_uint_at(s->trail, i))); + } else { + unsigned j; + struct clause *clause = clause_read(s, reason); + for (j = (clause->size == 2 ? 0 : 1); j < clause->size; j++) { + if (lit_dlevel(s, clause->data[j].lit) > 0) + vec_char_assign(s->seen, lit2var(clause->data[j].lit), 1); + } + } + vec_char_assign(s->seen, var, 0); + } + } + vec_char_assign(s->seen, lit2var(lit), 0); +} + +static inline void solver_garbage_collect(solver_t *s) +{ + unsigned i; + unsigned *array; + struct cdb *new_cdb = cdb_alloc(cdb_capacity(s->all_clauses) - cdb_wasted(s->all_clauses)); + + for (i = 0; i < 2 * vec_char_size(s->assigns); i++) { + struct watcher *w; + watch_list_foreach(s->watches, w, i) + clause_realloc(new_cdb, s->all_clauses, &(w->cref)); + watch_list_foreach(s->bin_watches, w, i) + clause_realloc(new_cdb, s->all_clauses, &(w->cref)); + } + + for (i = 0; i < vec_uint_size(s->trail); i++) + if (lit_reason(s, vec_uint_at(s->trail, i)) != UNDEF) + clause_realloc(new_cdb, s->all_clauses, &(vec_uint_data(s->reasons)[lit2var(vec_uint_at(s->trail, i))])); + + array = vec_uint_data(s->learnts); + for (i = 0; i < vec_uint_size(s->learnts); i++) + clause_realloc(new_cdb, s->all_clauses, &(array[i])); + + array = vec_uint_data(s->originals); + for (i = 0; i < vec_uint_size(s->originals); i++) + clause_realloc(new_cdb, s->all_clauses, &(array[i])); + + cdb_free(s->all_clauses); + s->all_clauses = new_cdb; +} + +static inline void solver_reduce_cdb(solver_t *s) +{ + unsigned i, limit; + unsigned n_learnts = vec_uint_size(s->learnts); + unsigned cref; + struct clause *clause; + struct clause **learnts_cls; + + learnts_cls = satoko_alloc(struct clause *, n_learnts); + vec_uint_foreach(s->learnts, cref, i) + learnts_cls[i] = clause_read(s, cref); + + limit = n_learnts / 2; + + satoko_sort((void *)learnts_cls, n_learnts, + (int (*)(const void *, const void *)) clause_compare); + + if (learnts_cls[n_learnts / 2]->lbd <= 3) + s->RC2 += s->opts.inc_special_reduce; + if (learnts_cls[n_learnts - 1]->lbd <= 6) + s->RC2 += s->opts.inc_special_reduce; + + vec_uint_clear(s->learnts); + for (i = 0; i < n_learnts; i++) { + clause = learnts_cls[i]; + cref = cdb_cref(s->all_clauses, (unsigned *)clause); + assert(clause->f_mark == 0); + if (clause->f_deletable && clause->lbd > 2 && clause->size > 2 && lit_reason(s, clause->data[0].lit) != cref && (i < limit)) { + clause->f_mark = 1; + s->stats.n_learnt_lits -= clause->size; + clause_unwatch(s, cref); + cdb_remove(s->all_clauses, clause); + } else { + if (!clause->f_deletable) + limit++; + clause->f_deletable = 1; + vec_uint_push_back(s->learnts, cref); + } + } + satoko_free(learnts_cls); + + if (s->opts.verbose) { + printf("reduceDB: Keeping %7d out of %7d clauses (%5.2f %%) \n", + vec_uint_size(s->learnts), n_learnts, + 100.0 * vec_uint_size(s->learnts) / n_learnts); + fflush(stdout); + } + if (cdb_wasted(s->all_clauses) > cdb_size(s->all_clauses) * s->opts.garbage_max_ratio) + solver_garbage_collect(s); +} + +//===------------------------------------------------------------------------=== +// Solver external functions +//===------------------------------------------------------------------------=== +unsigned solver_clause_create(solver_t *s, vec_uint_t *lits, unsigned f_learnt) +{ + struct clause *clause; + unsigned cref; + unsigned n_words; + + assert(vec_uint_size(lits) > 1); + assert(f_learnt == 0 || f_learnt == 1); + + n_words = 3 + f_learnt + vec_uint_size(lits); + cref = cdb_append(s->all_clauses, n_words); + clause = clause_read(s, cref); + clause->f_learnt = f_learnt; + clause->f_mark = 0; + clause->f_reallocd = 0; + clause->f_deletable = f_learnt; + clause->size = vec_uint_size(lits); + memcpy(&(clause->data[0].lit), vec_uint_data(lits), sizeof(unsigned) * vec_uint_size(lits)); + + if (f_learnt) { + vec_uint_push_back(s->learnts, cref); + clause->lbd = clause_clac_lbd(s, vec_uint_data(lits), vec_uint_size(lits)); + clause->data[clause->size].act = 0; + s->stats.n_learnt_lits += vec_uint_size(lits); + clause_act_bump(s, clause); + } else { + vec_uint_push_back(s->originals, cref); + s->stats.n_original_lits += vec_uint_size(lits); + } + return cref; +} + +void solver_cancel_until(solver_t * s, unsigned level) +{ + int i; + + if (solver_dlevel(s) <= level) + return; + for (i = (int) vec_uint_size(s->trail) - 1; i >= (int) vec_uint_at(s->trail_lim, level); i--) { + unsigned var = lit2var(vec_uint_at(s->trail, (unsigned) i)); + + vec_char_assign(s->assigns, var, VAR_UNASSING); + vec_uint_assign(s->reasons, var, UNDEF); + vec_char_assign(s->polarity, var, lit_polarity(vec_uint_at(s->trail, (unsigned) i))); + if (!heap_in_heap(s->var_order, var)) + heap_insert(s->var_order, var); + } + s->i_qhead = vec_uint_at(s->trail_lim, level); + vec_uint_shrink(s->trail, vec_uint_at(s->trail_lim, level)); + vec_uint_shrink(s->trail_lim, level); +} + +unsigned solver_propagate(solver_t *s) +{ + unsigned conf_cref = UNDEF; + unsigned *lits; + unsigned neg_lit; + unsigned n_propagations = 0; + + while (s->i_qhead < vec_uint_size(s->trail)) { + unsigned p = vec_uint_at(s->trail, s->i_qhead++); + struct watch_list *ws; + struct watcher *begin; + struct watcher *end; + struct watcher *i, *j; + + n_propagations++; + watch_list_foreach(s->bin_watches, i, p) { + if (var_value(s, lit2var(i->blocker)) == VAR_UNASSING) + solver_enqueue(s, i->blocker, i->cref); + else if (lit_value(s, i->blocker) == LIT_FALSE) + return i->cref; + } + + ws = vec_wl_at(s->watches, p); + begin = watch_list_array(ws); + end = begin + watch_list_size(ws); + for (i = j = begin; i < end;) { + struct clause *clause; + struct watcher w; + + if (lit_value(s, i->blocker) == LIT_TRUE) { + *j++ = *i++; + continue; + } + + clause = clause_read(s, i->cref); + lits = &(clause->data[0].lit); + + // Make sure the false literal is data[1]: + neg_lit = lit_neg(p); + if (lits[0] == neg_lit) + mkt_swap(unsigned, lits[0], lits[1]); + assert(lits[1] == neg_lit); + + w.cref = i->cref; + w.blocker = lits[0]; + + /* If 0th watch is true, then clause is already satisfied. */ + if (lits[0] != i->blocker && lit_value(s, lits[0]) == LIT_TRUE) + *j++ = w; + else { + /* Look for new watch */ + unsigned k; + for (k = 2; k < clause->size; k++) { + if (lit_value(s, lits[k]) != LIT_FALSE) { + lits[1] = lits[k]; + lits[k] = neg_lit; + watch_list_push(vec_wl_at(s->watches, lit_neg(lits[1])), w); + goto next; + } + } + + *j++ = w; + + /* Clause becomes unit under this assignment */ + if (lit_value(s, lits[0]) == LIT_FALSE) { + conf_cref = i->cref; + s->i_qhead = vec_uint_size(s->trail); + i++; + // Copy the remaining watches: + while (i < end) + *j++ = *i++; + } else + solver_enqueue(s, lits[0], i->cref); + } + next: + i++; + } + + s->stats.n_inspects += j - watch_list_array(ws); + watch_list_shrink(ws, j - watch_list_array(ws)); + } + s->stats.n_propagations += n_propagations; + s->n_props_simplify -= n_propagations; + return conf_cref; +} + +char solver_search(solver_t *s) +{ + s->stats.n_starts++; + while (1) { + unsigned confl_cref = solver_propagate(s); + if (confl_cref != UNDEF) { + s->stats.n_conflicts++; + if (solver_dlevel(s) == 0) + return SATOKO_UNSAT; + /* Restart heuristic */ + b_queue_push(s->bq_trail, vec_uint_size(s->trail)); + if (solver_block_rst(s)) + b_queue_clean(s->bq_lbd); + solver_handle_conflict(s, confl_cref); + } else { + /* No conflict */ + unsigned next_lit; + + if (solver_rst(s)) { + b_queue_clean(s->bq_lbd); + solver_cancel_until(s, 0); + return SATOKO_UNDEC; + } + if (solver_dlevel(s) == 0) + satoko_simplify(s); + + /* Reduce the set of learnt clauses */ + if (s->stats.n_conflicts >= s->n_confl_bfr_reduce) { + s->RC1 = (s->stats.n_conflicts / s->RC2) + 1; + solver_reduce_cdb(s); + s->RC2 += s->opts.inc_reduce; + s->n_confl_bfr_reduce = s->RC1 * s->RC2; + } + + /* Make decisions based on user assumptions */ + next_lit = UNDEF; + while (solver_dlevel(s) < vec_uint_size(s->assumptions)) { + unsigned lit = vec_uint_at(s->assumptions, solver_dlevel(s)); + if (lit_value(s, lit) == LIT_TRUE) { + vec_uint_push_back(s->trail_lim, vec_uint_size(s->trail)); + } else if (lit_value(s, lit) == LIT_FALSE) { + solver_analyze_final(s, lit_neg(lit)); + return SATOKO_UNSAT; + } else { + next_lit = lit; + break; + } + + } + if (next_lit == UNDEF) { + s->stats.n_decisions++; + next_lit = solver_decide(s); + if (next_lit == UNDEF) + return SATOKO_SAT; + } + solver_new_decision(s, next_lit); + } + } +} + +//===------------------------------------------------------------------------=== +// Debug procedure +//===------------------------------------------------------------------------=== +void solver_debug_check(solver_t *s, int result) +{ + unsigned cref, i; + unsigned *array; + + printf("Checking for trail(%u) inconsistencies...", vec_uint_size(s->trail)); + array = vec_uint_data(s->trail); + for (i = 1; i < vec_uint_size(s->trail); i++) + if (array[i - 1] == lit_neg(array[i])) { + printf("Inconsistent trail: %u %u\n", array[i - 1], array[i]); + return; + } + printf(" TRAIL OK\n"); + + printf("Checking clauses... \n"); + vec_uint_foreach(s->originals, cref, i) { + unsigned j; + struct clause *clause = clause_read(s, cref); + for (j = 0; j < clause->size; j++) { + if (vec_uint_find(s->trail, clause->data[j].lit)) { + break; + } + } + if (result == SATOKO_SAT && j == clause->size) { + printf("FOUND UNSAT CLAUSE!!!!\n"); + clause_print(clause); + } + } +} + +ABC_NAMESPACE_IMPL_END diff --git a/src/sat/satoko/solver.h b/src/sat/satoko/solver.h new file mode 100644 index 000000000..65b86c681 --- /dev/null +++ b/src/sat/satoko/solver.h @@ -0,0 +1,242 @@ +//===--- solver.h -----------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__solver_h +#define satoko__solver_h + +#include +#include +#include +#include + +#include "clause.h" +#include "cdb.h" +#include "satoko.h" +#include "types.h" +#include "watch_list.h" +#include "utils/b_queue.h" +#include "utils/heap.h" +#include "utils/mem.h" +#include "utils/misc.h" +#include "utils/vec/vec_char.h" +#include "utils/vec/vec_dble.h" +#include "utils/vec/vec_uint.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +enum { + LIT_FALSE = 1, + LIT_TRUE = 0, + VAR_UNASSING = 3 +}; + +#define UNDEF 0xFFFFFFFF + +struct satoko_stats { + unsigned n_starts; + unsigned n_reduce_db; + + long long n_decisions; + long long n_propagations; + long long n_inspects; + long long n_conflicts; + + long long n_original_lits; + long long n_learnt_lits; +}; + +typedef struct solver_t_ solver_t; +struct solver_t_ { + /* User data */ + vec_uint_t *assumptions; + vec_uint_t *final_conflict; + + /* Clauses Database */ + struct cdb *all_clauses; + vec_uint_t *learnts; + vec_uint_t *originals; + vec_wl_t *watches; + vec_wl_t *bin_watches; + + /* Activity heuristic */ + act_t var_act_inc; /* Amount to bump next variable with. */ + clause_act_t clause_act_inc; /* Amount to bump next clause with. */ + + /* Variable Information */ + vec_act_t *activity; /* A heuristic measurement of the activity of a variable. */ + heap_t *var_order; + vec_uint_t *levels; /* Decision level of the current assignment */ + vec_uint_t *reasons; /* Reason (clause) of the current assignment */ + vec_char_t *assigns; + vec_char_t *polarity; + + /* Assignments */ + vec_uint_t *trail; + vec_uint_t *trail_lim; /* Separator indices for different decision levels in 'trail'. */ + unsigned i_qhead; /* Head of propagation queue (as index into the trail). */ + unsigned n_assigns_simplify; /* Number of top-level assignments since + last execution of 'simplify()'. */ + long long n_props_simplify; /* Remaining number of propagations that + must be made before next execution of + 'simplify()'. */ + + /* Temporary data used by Search method */ + b_queue_t *bq_trail; + b_queue_t *bq_lbd; + long RC1; + long RC2; + unsigned n_confl_bfr_reduce; + float sum_lbd; + + /* Temporary data used by Analyze */ + vec_uint_t *temp_lits; + vec_char_t *seen; + vec_uint_t *tagged; /* Stack */ + vec_uint_t *stack; + vec_uint_t *last_dlevel; + + /* Misc temporary */ + vec_uint_t *stamps; /* Multipurpose stamp used to calculate LBD and + * clauses minimization with binary resolution */ + unsigned cur_stamp; /* Used for marking literals and levels of interest */ + + struct satoko_stats stats; + struct satoko_opts opts; +}; + +//===------------------------------------------------------------------------=== +extern unsigned solver_clause_create(solver_t *, vec_uint_t *, unsigned); +extern char solver_search(solver_t *); +extern void solver_cancel_until(solver_t *, unsigned); +extern unsigned solver_propagate(solver_t *); +extern void solver_debug_check(solver_t *, int); + +//===------------------------------------------------------------------------=== +// Inline var/lit functions +//===------------------------------------------------------------------------=== +static inline unsigned var2lit(unsigned var, char polarity) +{ + return var + var + ((unsigned) polarity != 0); +} + +static inline unsigned lit2var(unsigned lit) +{ + return lit >> 1; +} +//===------------------------------------------------------------------------=== +// Inline var functions +//===------------------------------------------------------------------------=== +static inline char var_value(solver_t *s, unsigned var) +{ + return vec_char_at(s->assigns, var); +} + +static inline unsigned var_dlevel(solver_t *s, unsigned var) +{ + return vec_uint_at(s->levels, var); +} + +static inline unsigned var_reason(solver_t *s, unsigned var) +{ + return vec_uint_at(s->reasons, var); +} +//===------------------------------------------------------------------------=== +// Inline lit functions +//===------------------------------------------------------------------------=== +static inline unsigned lit_neg(unsigned lit) +{ + return lit ^ 1; +} + +static inline char lit_polarity(unsigned lit) +{ + return (char)(lit & 1); +} + +static inline char lit_value(solver_t *s, unsigned lit) +{ + return lit_polarity(lit) ^ vec_char_at(s->assigns, lit2var(lit)); +} + +static inline unsigned lit_dlevel(solver_t *s, unsigned lit) +{ + return vec_uint_at(s->levels, lit2var(lit)); +} + +static inline unsigned lit_reason(solver_t *s, unsigned lit) +{ + return vec_uint_at(s->reasons, lit2var(lit)); +} +//===------------------------------------------------------------------------=== +// Inline solver minor functions +//===------------------------------------------------------------------------=== +static inline unsigned solver_check_limits(solver_t *s) +{ + return (s->opts.conf_limit == 0 || s->opts.conf_limit >= s->stats.n_conflicts) && + (s->opts.prop_limit == 0 || s->opts.prop_limit >= s->stats.n_propagations); +} + +/** Returns current decision level */ +static inline unsigned solver_dlevel(solver_t *s) +{ + return vec_uint_size(s->trail_lim); +} + +static inline int solver_enqueue(solver_t *s, unsigned lit, unsigned reason) +{ + unsigned var = lit2var(lit); + + vec_char_assign(s->assigns, var, lit_polarity(lit)); + vec_uint_assign(s->levels, var, solver_dlevel(s)); + vec_uint_assign(s->reasons, var, reason); + vec_uint_push_back(s->trail, lit); + return SATOKO_OK; +} + +//===------------------------------------------------------------------------=== +// Inline clause functions +//===------------------------------------------------------------------------=== +static inline struct clause *clause_read(solver_t *s, unsigned cref) +{ + return cdb_handler(s->all_clauses, cref); +} + +static inline void clause_watch(solver_t *s, unsigned cref) +{ + struct clause *clause = cdb_handler(s->all_clauses, cref); + struct watcher w1; + struct watcher w2; + + w1.cref = cref; + w2.cref = cref; + w1.blocker = clause->data[1].lit; + w2.blocker = clause->data[0].lit; + if (clause->size == 2) { + watch_list_push(vec_wl_at(s->bin_watches, lit_neg(clause->data[0].lit)), w1); + watch_list_push(vec_wl_at(s->bin_watches, lit_neg(clause->data[1].lit)), w2); + } else { + watch_list_push(vec_wl_at(s->watches, lit_neg(clause->data[0].lit)), w1); + watch_list_push(vec_wl_at(s->watches, lit_neg(clause->data[1].lit)), w2); + } +} + +static inline void clause_unwatch(solver_t *s, unsigned cref) +{ + struct clause *clause = cdb_handler(s->all_clauses, cref); + if (clause->size == 2) { + watch_list_remove(vec_wl_at(s->bin_watches, lit_neg(clause->data[0].lit)), cref); + watch_list_remove(vec_wl_at(s->bin_watches, lit_neg(clause->data[1].lit)), cref); + } else { + watch_list_remove(vec_wl_at(s->watches, lit_neg(clause->data[0].lit)), cref); + watch_list_remove(vec_wl_at(s->watches, lit_neg(clause->data[1].lit)), cref); + } +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__solver_h */ diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c new file mode 100644 index 000000000..db9a267b5 --- /dev/null +++ b/src/sat/satoko/solver_api.c @@ -0,0 +1,310 @@ +//===--- solver_api.h -------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#include +#include +#include +#include + +#include "act_var.h" +#include "utils/misc.h" +#include "solver.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_IMPL_START + +//===------------------------------------------------------------------------=== +// Satoko internal functions +//===------------------------------------------------------------------------=== +static inline void solver_rebuild_order(solver_t *s) +{ + unsigned var; + vec_uint_t *vars = vec_uint_alloc(vec_char_size(s->assigns)); + + for (var = 0; var < vec_char_size(s->assigns); var++) + if (var_value(s, var) == VAR_UNASSING) + vec_uint_push_back(vars, var); + heap_build(s->var_order, vars); + vec_uint_free(vars); +} + +static inline int clause_is_satisfied(solver_t *s, struct clause *clause) +{ + unsigned i; + unsigned *lits = &(clause->data[0].lit); + for (i = 0; i < clause->size; i++) + if (lit_value(s, lits[i]) == LIT_TRUE) + return SATOKO_OK; + return SATOKO_ERR; +} + +static inline void print_opts(solver_t *s) +{ + printf( "+-[ BLACK MAGIC - PARAMETERS ]-+\n"); + printf( "| |\n"); + printf( "|--> Restarts heuristic |\n"); + printf( "| * LBD Queue = %6d |\n", s->opts.sz_lbd_bqueue); + printf( "| * Trail Queue = %6d |\n", s->opts.sz_trail_bqueue); + printf( "| * f_rst = %6.2f |\n", s->opts.f_rst); + printf( "| * b_rst = %6.2f |\n", s->opts.b_rst); + printf( "| |\n"); + printf( "|--> Clause DB reduction: |\n"); + printf( "| * First = %6d |\n", s->opts.n_conf_fst_reduce); + printf( "| * Inc = %6d |\n", s->opts.inc_reduce); + printf( "| * Special Inc = %6d |\n", s->opts.inc_special_reduce); + printf( "| * Protected (LBD) < %2d |\n", s->opts.lbd_freeze_clause); + printf( "| |\n"); + printf( "|--> Binary resolution: |\n"); + printf( "| * Clause size < %3d |\n", s->opts.clause_max_sz_bin_resol); + printf( "| * Clause lbd < %3d |\n", s->opts.clause_min_lbd_bin_resol); + printf( "+------------------------------+\n\n"); +} + +static inline void print_stats(solver_t *s) +{ + printf("starts : %10d\n", s->stats.n_starts); + printf("conflicts : %10lld\n", s->stats.n_conflicts); + printf("decisions : %10lld\n", s->stats.n_decisions); + printf("propagations : %10lld\n", s->stats.n_propagations); +} + +//===------------------------------------------------------------------------=== +// Satoko external functions +//===------------------------------------------------------------------------=== +solver_t * satoko_create() +{ + solver_t *s = satoko_calloc(solver_t, 1); + + satoko_default_opts(&s->opts); + /* User data */ + s->assumptions = vec_uint_alloc(0); + s->final_conflict = vec_uint_alloc(0); + /* Clauses Database */ + s->all_clauses = cdb_alloc(0); + s->originals = vec_uint_alloc(0); + s->learnts = vec_uint_alloc(0); + s->watches = vec_wl_alloc(0); + s->bin_watches = vec_wl_alloc(0); + /* Activity heuristic */ + s->var_act_inc = VAR_ACT_INIT_INC; + s->clause_act_inc = CLAUSE_ACT_INIT_INC; + /* Variable Information */ + s->activity = vec_act_alloc(0); + s->var_order = heap_alloc(s->activity); + s->levels = vec_uint_alloc(0); + s->reasons = vec_uint_alloc(0); + s->assigns = vec_char_alloc(0); + s->polarity = vec_char_alloc(0); + /* Assignments */ + s->trail = vec_uint_alloc(0); + s->trail_lim = vec_uint_alloc(0); + /* Temporary data used by Search method */ + s->bq_trail = b_queue_alloc(s->opts.sz_trail_bqueue); + s->bq_lbd = b_queue_alloc(s->opts.sz_lbd_bqueue); + s->n_confl_bfr_reduce = s->opts.n_conf_fst_reduce; + s->RC1 = 1; + s->RC2 = s->opts.n_conf_fst_reduce; + /* Temporary data used by Analyze */ + s->temp_lits = vec_uint_alloc(0); + s->seen = vec_char_alloc(0); + s->tagged = vec_uint_alloc(0); + s->stack = vec_uint_alloc(0); + s->last_dlevel = vec_uint_alloc(0); + /* Misc temporary */ + s->stamps = vec_uint_alloc(0); + return s; +} + +void satoko_destroy(solver_t *s) +{ + vec_uint_free(s->assumptions); + vec_uint_free(s->final_conflict); + cdb_free(s->all_clauses); + vec_uint_free(s->originals); + vec_uint_free(s->learnts); + vec_wl_free(s->watches); + vec_wl_free(s->bin_watches); + vec_act_free(s->activity); + heap_free(s->var_order); + vec_uint_free(s->levels); + vec_uint_free(s->reasons); + vec_char_free(s->assigns); + vec_char_free(s->polarity); + vec_uint_free(s->trail); + vec_uint_free(s->trail_lim); + b_queue_free(s->bq_lbd); + b_queue_free(s->bq_trail); + vec_uint_free(s->temp_lits); + vec_char_free(s->seen); + vec_uint_free(s->tagged); + vec_uint_free(s->stack); + vec_uint_free(s->last_dlevel); + vec_uint_free(s->stamps); + satoko_free(s); +} + +void satoko_default_opts(satoko_opts_t *opts) +{ + opts->verbose = 0; + /* Limits */ + opts->conf_limit = 0; + opts->prop_limit = 0; + /* Constants used for restart heuristic */ + opts->f_rst = 0.8; + opts->b_rst = 1.4; + opts->fst_block_rst = 10000; + opts->sz_lbd_bqueue = 50; + opts->sz_trail_bqueue = 5000; + /* Constants used for clause database reduction heuristic */ + opts->n_conf_fst_reduce = 2000; + opts->inc_reduce = 300; + opts->inc_special_reduce = 1000; + opts->lbd_freeze_clause = 30; + /* VSIDS heuristic */ + opts->var_decay = 0.95; + opts->clause_decay = 0.995; + /* Binary resolution */ + opts->clause_max_sz_bin_resol = 30; + opts->clause_min_lbd_bin_resol = 6; + + opts->garbage_max_ratio = 0.3; +} + +/** + * TODO: sanity check on configuration options + */ +void satoko_configure(satoko_t *s, satoko_opts_t *user_opts) +{ + assert(user_opts); + memcpy(&s->opts, user_opts, sizeof(satoko_opts_t)); +} + +int satoko_simplify(solver_t * s) +{ + unsigned i, j = 0; + unsigned cref; + + assert(solver_dlevel(s) == 0); + if (solver_propagate(s) != UNDEF) + return SATOKO_ERR; + if (s->n_assigns_simplify == vec_uint_size(s->trail) || s->n_props_simplify > 0) + return SATOKO_OK; + + vec_uint_foreach(s->originals, cref, i) { + struct clause *clause = clause_read(s, cref); + + if (clause_is_satisfied(s, clause)) { + clause->f_mark = 1; + s->stats.n_original_lits -= clause->size; + clause_unwatch(s, cref); + } else + vec_uint_assign(s->originals, j++, cref); + } + vec_uint_shrink(s->originals, j); + solver_rebuild_order(s); + s->n_assigns_simplify = vec_uint_size(s->trail); + s->n_props_simplify = s->stats.n_original_lits + s->stats.n_learnt_lits; + return SATOKO_OK; +} + +void satoko_add_variable(solver_t *s, char sign) +{ + unsigned var = vec_act_size(s->activity); + vec_wl_push(s->bin_watches); + vec_wl_push(s->bin_watches); + vec_wl_push(s->watches); + vec_wl_push(s->watches); + vec_act_push_back(s->activity, 0); + vec_uint_push_back(s->levels, 0); + vec_char_push_back(s->assigns, VAR_UNASSING); + vec_char_push_back(s->polarity, sign); + vec_uint_push_back(s->reasons, UNDEF); + vec_uint_push_back(s->stamps, 0); + vec_char_push_back(s->seen, 0); + heap_insert(s->var_order, var); +} + +int satoko_add_clause(solver_t *s, unsigned *lits, unsigned size) +{ + unsigned i, j; + unsigned prev_lit; + unsigned max_var; + unsigned cref; + + qsort((void *) lits, size, sizeof(unsigned), mkt_uint_compare); + max_var = lit2var(lits[size - 1]); + while (max_var >= vec_act_size(s->activity)) + satoko_add_variable(s, LIT_FALSE); + + vec_uint_clear(s->temp_lits); + j = 0; + prev_lit = UNDEF; + for (i = 0; i < size; i++) { + if (lits[i] == lit_neg(prev_lit) || lit_value(s, lits[i]) == LIT_TRUE) + return SATOKO_OK; + else if (lits[i] != prev_lit && var_value(s, lit2var(lits[i])) == VAR_UNASSING) { + prev_lit = lits[i]; + vec_uint_push_back(s->temp_lits, lits[i]); + } + } + + if (vec_uint_size(s->temp_lits) == 0) + return SATOKO_ERR; + if (vec_uint_size(s->temp_lits) == 1) { + solver_enqueue(s, vec_uint_at(s->temp_lits, 0), UNDEF); + return (solver_propagate(s) == UNDEF); + } + + cref = solver_clause_create(s, s->temp_lits, 0); + clause_watch(s, cref); + return SATOKO_OK; +} + +void satoko_assump_push(solver_t *s, unsigned lit) +{ + vec_uint_push_back(s->assumptions, lit); +} + +void satoko_assump_pop(solver_t *s) +{ + assert(vec_uint_size(s->assumptions) > 0); + vec_uint_pop_back(s->assumptions); + solver_cancel_until(s, vec_uint_size(s->assumptions)); +} + +int satoko_solve(solver_t *s) +{ + char status = SATOKO_UNDEC; + + assert(s); + if (s->opts.verbose) + print_opts(s); + + while (status == SATOKO_UNDEC) { + status = solver_search(s); + if (solver_check_limits(s) == 0) + break; + } + if (s->opts.verbose) + print_stats(s); + solver_cancel_until(s, vec_uint_size(s->assumptions)); + return status; +} + +int satoko_final_conflict(solver_t *s, unsigned *out) +{ + if (vec_uint_size(s->final_conflict) == 0) + return -1; + out = satoko_alloc(unsigned, vec_uint_size(s->final_conflict)); + memcpy(out, vec_uint_data(s->final_conflict), + sizeof(unsigned) * vec_uint_size(s->final_conflict)); + return vec_uint_size(s->final_conflict); + +} + +ABC_NAMESPACE_IMPL_END diff --git a/src/sat/satoko/types.h b/src/sat/satoko/types.h new file mode 100644 index 000000000..2811c2c65 --- /dev/null +++ b/src/sat/satoko/types.h @@ -0,0 +1,50 @@ +//===--- types.h ------------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__types_h +#define satoko__types_h + +#include "utils/vec/vec_dble.h" +#include "utils/vec/vec_uint.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +#define SATOKO_ACT_VAR_DBLE +#define SATOKO_ACT_CLAUSE_FLOAT + +#ifdef SATOKO_ACT_VAR_DBLE + #define VAR_ACT_INIT_INC 1.0 + typedef double act_t; + typedef vec_dble_t vec_act_t ; + #define vec_act_alloc(size) vec_dble_alloc(size) + #define vec_act_free(vec) vec_dble_free(vec) + #define vec_act_size(vec) vec_dble_size(vec) + #define vec_act_at(vec, idx) vec_dble_at(vec, idx) + #define vec_act_push_back(vec, value) vec_dble_push_back(vec, value) +#else + #define VAR_ACT_INIT_INC (1 << 5) + typedef unsigned act_t; + typedef vec_uint_t vec_act_t; + #define vec_act_alloc(size) vec_uint_alloc(size) + #define vec_act_free(vec) vec_uint_free(vec) + #define vec_act_size(vec) vec_uint_size(vec) + #define vec_act_at(vec, idx) vec_uint_at(vec, idx) + #define vec_act_push_back(vec, value) vec_uint_push_back(vec, value) +#endif /* SATOKO_ACT_VAR_DBLE */ + +#ifdef SATOKO_ACT_CLAUSE_FLOAT + #define CLAUSE_ACT_INIT_INC 1.0 + typedef float clause_act_t; +#else + #define CLAUSE_ACT_INIT_INC (1 << 11) + typedef unsigned clause_act_t; +#endif /* SATOKO_ACT_CLAUSE_FLOAT */ + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__types_h */ diff --git a/src/sat/satoko/utils/b_queue.h b/src/sat/satoko/utils/b_queue.h new file mode 100644 index 000000000..926edf290 --- /dev/null +++ b/src/sat/satoko/utils/b_queue.h @@ -0,0 +1,81 @@ +//===--- b_queue.h ----------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__utils__b_queue_h +#define satoko__utils__b_queue_h + +#include "mem.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +/* Bounded Queue */ +typedef struct b_queue_t_ b_queue_t; +struct b_queue_t_ { + unsigned size; + unsigned cap; + unsigned i_first; + unsigned i_empty; + unsigned long long sum; + unsigned *data; +}; + +//===------------------------------------------------------------------------=== +// Bounded Queue API +//===------------------------------------------------------------------------=== +static inline b_queue_t *b_queue_alloc(unsigned cap) +{ + b_queue_t *p = satoko_calloc(b_queue_t, 1); + p->cap = cap; + p->data = satoko_calloc(unsigned, cap); + return p; +} + +static inline void b_queue_free(b_queue_t *p) +{ + satoko_free(p->data); + satoko_free(p); +} + +static inline void b_queue_push(b_queue_t *p, unsigned Value) +{ + if (p->size == p->cap) { + assert(p->i_first == p->i_empty); + p->sum -= p->data[p->i_first]; + p->i_first = (p->i_first + 1) % p->cap; + } else + p->size++; + + p->sum += Value; + p->data[p->i_empty] = Value; + if ((++p->i_empty) == p->cap) { + p->i_empty = 0; + p->i_first = 0; + } +} + +static inline unsigned b_queue_avg(b_queue_t *p) +{ + return (unsigned)(p->sum / ((unsigned long long) p->size)); +} + +static inline unsigned b_queue_is_valid(b_queue_t *p) +{ + return (p->cap == p->size); +} + +static inline void b_queue_clean(b_queue_t *p) +{ + p->i_first = 0; + p->i_empty = 0; + p->size = 0; + p->sum = 0; +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__utils__b_queue_h */ diff --git a/src/sat/satoko/utils/heap.h b/src/sat/satoko/utils/heap.h new file mode 100644 index 000000000..e1611e95a --- /dev/null +++ b/src/sat/satoko/utils/heap.h @@ -0,0 +1,181 @@ +//===--- heap.h ----------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__utils__heap_h +#define satoko__utils__heap_h + +#include "mem.h" +#include "../types.h" +#include "vec/vec_dble.h" +#include "vec/vec_int.h" +#include "vec/vec_uint.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +typedef struct heap_t_ heap_t; +struct heap_t_ { + vec_int_t *indices; + vec_uint_t *data; + vec_act_t *weights; +}; +//===------------------------------------------------------------------------=== +// Heap internal functions +//===------------------------------------------------------------------------=== +static inline unsigned left(unsigned i) { return 2 * i + 1; } +static inline unsigned right(unsigned i) { return (i + 1) * 2; } +static inline unsigned parent(unsigned i) { return (i - 1) >> 1; } + +static inline int compare(heap_t *p, unsigned x, unsigned y) +{ + return vec_act_at(p->weights, x) > vec_act_at(p->weights, y); +} + +static inline void heap_percolate_up(heap_t *h, unsigned i) +{ + unsigned x = vec_uint_at(h->data, i); + unsigned p = parent(i); + + while (i != 0 && compare(h, x, vec_uint_at(h->data, p))) { + vec_uint_assign(h->data, i, vec_uint_at(h->data, p)); + vec_int_assign(h->indices, vec_uint_at(h->data, p), (int) i); + i = p; + p = parent(p); + } + vec_uint_assign(h->data, i, x); + vec_int_assign(h->indices, x, (int) i); +} + +static inline void heap_percolate_down(heap_t *h, unsigned i) +{ + unsigned x = vec_uint_at(h->data, i); + + while (left(i) < vec_uint_size(h->data)) { + unsigned child = right(i) < vec_uint_size(h->data) && + compare(h, vec_uint_at(h->data, right(i)), vec_uint_at(h->data, left(i))) + ? right(i) + : left(i); + + if (!compare(h, vec_uint_at(h->data, child), x)) + break; + + vec_uint_assign(h->data, i, vec_uint_at(h->data, child)); + vec_int_assign(h->indices, vec_uint_at(h->data, i), (int) i); + i = child; + } + vec_uint_assign(h->data, i, x); + vec_int_assign(h->indices, x, (int) i); +} + +//===------------------------------------------------------------------------=== +// Heap API +//===------------------------------------------------------------------------=== +static inline heap_t *heap_alloc(vec_act_t *weights) +{ + heap_t *p = satoko_alloc(heap_t, 1); + p->weights = weights; + p->indices = vec_int_alloc(0); + p->data = vec_uint_alloc(0); + return p; +} + +static inline void heap_free(heap_t *p) +{ + vec_int_free(p->indices); + vec_uint_free(p->data); + satoko_free(p); +} + +static inline unsigned heap_size(heap_t *p) +{ + return vec_uint_size(p->data); +} + +static inline int heap_in_heap(heap_t *p, unsigned entry) +{ + return (entry < vec_int_size(p->indices)) && + (vec_int_at(p->indices, entry) >= 0); +} + +static inline void heap_increase(heap_t *p, unsigned entry) +{ + assert(heap_in_heap(p, entry)); + heap_percolate_down(p, (unsigned) vec_int_at(p->indices, entry)); +} + +static inline void heap_decrease(heap_t *p, unsigned entry) +{ + assert(heap_in_heap(p, entry)); + heap_percolate_up(p, (unsigned) vec_int_at(p->indices, entry)); +} + +static inline void heap_insert(heap_t *p, unsigned entry) +{ + if (vec_int_size(p->indices) < entry + 1) { + unsigned old_size = vec_int_size(p->indices); + unsigned i; + int e; + vec_int_resize(p->indices, entry + 1); + vec_int_foreach_start(p->indices, e, i, old_size) + vec_int_assign(p->indices, i, -1); + } + assert(!heap_in_heap(p, entry)); + vec_int_assign(p->indices, entry, (int) vec_uint_size(p->data)); + vec_uint_push_back(p->data, entry); + heap_percolate_up(p, (unsigned) vec_int_at(p->indices, entry)); +} + +static inline void heap_update(heap_t *p, unsigned i) +{ + if (!heap_in_heap(p, i)) + heap_insert(p, i); + else { + heap_percolate_up(p, (unsigned) vec_int_at(p->indices, i)); + heap_percolate_down(p, (unsigned) vec_int_at(p->indices, i)); + } +} + +static inline void heap_build(heap_t *p, vec_uint_t *entries) +{ + int i; + unsigned j, entry; + + vec_uint_foreach(p->data, entry, j) + vec_int_assign(p->indices, entry, -1); + vec_uint_clear(p->data); + vec_uint_foreach(entries, entry, j) { + vec_int_assign(p->indices, entry, (int) j); + vec_uint_push_back(p->data, entry); + } + for ((i = vec_uint_size(p->data) / 2 - 1); i >= 0; i--) + heap_percolate_down(p, (unsigned) i); +} + +static inline void heap_clear(heap_t *p) +{ + unsigned i; + int entry; + vec_int_foreach(p->indices, entry, i) + vec_int_assign(p->indices, i, -1); + vec_uint_clear(p->data); +} + +static inline unsigned heap_remove_min(heap_t *p) +{ + unsigned x = vec_uint_at(p->data, 0); + vec_uint_assign(p->data, 0, vec_uint_at(p->data, vec_uint_size(p->data) - 1)); + vec_int_assign(p->indices, vec_uint_at(p->data, 0), 0); + vec_int_assign(p->indices, x, -1); + vec_uint_pop_back(p->data); + if (vec_uint_size(p->data) > 1) + heap_percolate_down(p, 0); + return x; +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__utils__heap_h */ diff --git a/src/sat/satoko/utils/mem.h b/src/sat/satoko/utils/mem.h new file mode 100755 index 000000000..5ff9873d4 --- /dev/null +++ b/src/sat/satoko/utils/mem.h @@ -0,0 +1,23 @@ +//===--- mem.h --------------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__utils__mem_h +#define satoko__utils__mem_h + +#include + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +#define satoko_alloc(type, n_elements) ((type *) malloc((n_elements) * sizeof(type))) +#define satoko_calloc(type, n_elements) ((type *) calloc((n_elements), sizeof(type))) +#define satoko_realloc(type, ptr, n_elements) ((type *) realloc(ptr, (n_elements) * sizeof(type))) +#define satoko_free(p) do { free(p); p = NULL; } while(0) + +ABC_NAMESPACE_HEADER_END +#endif diff --git a/src/sat/satoko/utils/misc.h b/src/sat/satoko/utils/misc.h new file mode 100755 index 000000000..aa8bcb8c4 --- /dev/null +++ b/src/sat/satoko/utils/misc.h @@ -0,0 +1,37 @@ +//===--- misc.h -------------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__utils__misc_h +#define satoko__utils__misc_h + +#include + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +#define mkt_swap(type, a, b) { type t = a; a = b; b = t; } + +static inline unsigned mkt_uint_max(unsigned a, unsigned b) +{ + return a > b ? a : b; +} + +static inline int mkt_uint_compare(const void *p1, const void *p2) +{ + const unsigned pp1 = *(const unsigned *)p1; + const unsigned pp2 = *(const unsigned *)p2; + + if (pp1 < pp2) + return -1; + if (pp1 > pp2) + return 1; + return 0; +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__utils__misc_h */ diff --git a/src/sat/satoko/utils/sort.h b/src/sat/satoko/utils/sort.h new file mode 100644 index 000000000..285f4b912 --- /dev/null +++ b/src/sat/satoko/utils/sort.h @@ -0,0 +1,65 @@ +//===--- sort.h -------------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__utils__sort_h +#define satoko__utils__sort_h + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +static inline void select_sort(void **data, unsigned size, + int (*comp_fn)(const void *, const void *)) +{ + unsigned i, j, i_best; + void *temp; + + for (i = 0; i < (size - 1); i++) { + i_best = i; + for (j = i + 1; j < size; j++) { + if (comp_fn(data[j], data[i_best])) + i_best = j; + } + temp = data[i]; + data[i] = data[i_best]; + data[i_best] = temp; + } +} + +static void satoko_sort(void **data, unsigned size, + int (*comp_fn)(const void *, const void *)) +{ + if (size <= 15) + select_sort(data, size, comp_fn); + else { + void *pivot = data[size / 2]; + void *temp; + unsigned j = size; + int i = -1; + + for (;;) { + do { + i++; + } while (comp_fn(data[i], pivot)); + do { + j--; + } while (comp_fn(pivot, data[j])); + + if ((unsigned) i >= j) + break; + + temp = data[i]; + data[i] = data[j]; + data[j] = temp; + } + satoko_sort(data, (unsigned) i, comp_fn); + satoko_sort(data + i, (size - (unsigned) i), comp_fn); + } +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__utils__sort_h */ diff --git a/src/sat/satoko/utils/vec/vec_char.h b/src/sat/satoko/utils/vec/vec_char.h new file mode 100644 index 000000000..fe88797a5 --- /dev/null +++ b/src/sat/satoko/utils/vec/vec_char.h @@ -0,0 +1,259 @@ +//===--- vec_char.h ---------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__utils__vec__vec_char_h +#define satoko__utils__vec__vec_char_h + +#include +#include +#include + +#include "../mem.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +typedef struct vec_char_t_ vec_char_t; +struct vec_char_t_ { + unsigned cap; + unsigned size; + char *data; +}; + +//===------------------------------------------------------------------------=== +// Vector Macros +//===------------------------------------------------------------------------=== +#define vec_char_foreach(vec, entry, i) \ + for (i = 0; (i < vec_char_size(vec)) && (((entry) = vec_char_at(vec, i)), 1); i++) + +#define vec_char_foreach_start(vec, entry, i, start) \ + for (i = start; (i < vec_char_size(vec)) && (((entry) = vec_char_at(vec, i)), 1); i++) + +#define vec_char_foreach_stop(vec, entry, i, stop) \ + for (i = 0; (i < stop) && (((entry) = vec_char_at(vec, i)), 1); i++) + +//===------------------------------------------------------------------------=== +// Vector API +//===------------------------------------------------------------------------=== +static inline vec_char_t * vec_char_alloc(unsigned cap) +{ + vec_char_t *p = satoko_alloc(vec_char_t, 1); + + if (cap > 0 && cap < 16) + cap = 16; + p->size = 0; + p->cap = cap; + p->data = p->cap ? satoko_alloc(char, p->cap) : NULL; + return p; +} + +static inline vec_char_t * vec_char_alloc_exact(unsigned cap) +{ + vec_char_t *p = satoko_alloc(vec_char_t, 1); + + cap = 0; + p->size = 0; + p->cap = cap; + p->data = p->cap ? satoko_alloc(char, p->cap ) : NULL; + return p; +} + +static inline vec_char_t * vec_char_init(unsigned size, char value) +{ + vec_char_t *p = satoko_alloc(vec_char_t, 1); + + p->cap = size; + p->size = size; + p->data = p->cap ? satoko_alloc(char, p->cap) : NULL; + memset(p->data, value, sizeof(char) * p->size); + return p; +} + +static inline void vec_char_free(vec_char_t *p) +{ + if (p->data != NULL) + satoko_free(p->data); + satoko_free(p); +} + +static inline unsigned vec_char_size(vec_char_t *p) +{ + return p->size; +} + +static inline void vec_char_resize(vec_char_t *p, unsigned new_size) +{ + p->size = new_size; + if (p->cap >= new_size) + return; + p->data = satoko_realloc(char, p->data, new_size); + assert(p->data != NULL); + p->cap = new_size; +} + +static inline void vec_char_shrink(vec_char_t *p, unsigned new_size) +{ + assert(p->cap > new_size); + p->size = new_size; +} + +static inline void vec_char_reserve(vec_char_t *p, unsigned new_cap) +{ + if (p->cap >= new_cap) + return; + p->data = satoko_realloc(char, p->data, new_cap); + assert(p->data != NULL); + p->cap = new_cap; +} + +static inline unsigned vec_char_capacity(vec_char_t *p) +{ + return p->cap; +} + +static inline int vec_char_empty(vec_char_t *p) +{ + return p->size ? 0 : 1; +} + +static inline void vec_char_erase(vec_char_t *p) +{ + satoko_free(p->data); + p->size = 0; + p->cap = 0; +} + +static inline char vec_char_at(vec_char_t *p, unsigned idx) +{ + assert(idx >= 0 && idx < p->size); + return p->data[idx]; +} + +static inline char * vec_char_at_ptr(vec_char_t *p, unsigned idx) +{ + assert(idx >= 0 && idx < p->size); + return p->data + idx; +} + +static inline char * vec_char_data(vec_char_t *p) +{ + assert(p); + return p->data; +} + +static inline void vec_char_duplicate(vec_char_t *dest, const vec_char_t *src) +{ + assert(dest != NULL && src != NULL); + vec_char_resize(dest, src->cap); + memcpy(dest->data, src->data, sizeof(char) * src->cap); + dest->size = src->size; +} + +static inline void vec_char_copy(vec_char_t *dest, const vec_char_t *src) +{ + assert(dest != NULL && src != NULL); + vec_char_resize(dest, src->size); + memcpy(dest->data, src->data, sizeof(char) * src->size); + dest->size = src->size; +} + +static inline void vec_char_push_back(vec_char_t *p, char value) +{ + if (p->size == p->cap) { + if (p->cap < 16) + vec_char_reserve(p, 16); + else + vec_char_reserve(p, 2 * p->cap); + } + p->data[p->size] = value; + p->size++; +} + +static inline char vec_char_pop_back(vec_char_t *p) +{ + assert(p && p->size); + return p->data[--p->size]; +} + +static inline void vec_char_assign(vec_char_t *p, unsigned idx, char value) +{ + assert((idx >= 0) && (idx < vec_char_size(p))); + p->data[idx] = value; +} + +static inline void vec_char_insert(vec_char_t *p, unsigned idx, char value) +{ + assert((idx >= 0) && (idx < vec_char_size(p))); + vec_char_push_back(p, 0); + memmove(p->data + idx + 1, p->data + idx, (p->size - idx - 2) * sizeof(char)); + p->data[idx] = value; +} + +static inline void vec_char_drop(vec_char_t *p, unsigned idx) +{ + assert((idx >= 0) && (idx < vec_char_size(p))); + memmove(p->data + idx, p->data + idx + 1, (p->size - idx - 1) * sizeof(char)); + p->size -= 1; +} + +static inline void vec_char_clear(vec_char_t *p) +{ + p->size = 0; +} + +static inline int vec_char_asc_compare(const void *p1, const void *p2) +{ + const char *pp1 = (const char *)p1; + const char *pp2 = (const char *)p2; + + if (*pp1 < *pp2) + return -1; + if (*pp1 > *pp2) + return 1; + return 0; +} + +static inline int vec_char_desc_compare(const void *p1, const void *p2) +{ + const char *pp1 = (const char *)p1; + const char *pp2 = (const char *)p2; + + if (*pp1 > *pp2) + return -1; + if (*pp1 < *pp2) + return 1; + return 0; +} + +static inline void vec_char_sort(vec_char_t *p, int ascending) +{ + if (ascending) + qsort((void *) p->data, p->size, sizeof(char), + (int (*)(const void *, const void *)) vec_char_asc_compare); + else + qsort((void*) p->data, p->size, sizeof(char), + (int (*)(const void *, const void *)) vec_char_desc_compare); +} + + +static inline long vec_char_memory(vec_char_t *p) +{ + return p == NULL ? 0 : sizeof(char) * p->cap + sizeof(vec_char_t); +} + +static inline void vec_char_print(vec_char_t* p) +{ + assert(p != NULL); + fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap); + for (unsigned i = 0; i < p->size; i++) + fprintf(stdout, " %d", p->data[i]); + fprintf(stdout, " }\n"); +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__utils__vec__vec_char_h */ diff --git a/src/sat/satoko/utils/vec/vec_dble.h b/src/sat/satoko/utils/vec/vec_dble.h new file mode 100755 index 000000000..50281c2a5 --- /dev/null +++ b/src/sat/satoko/utils/vec/vec_dble.h @@ -0,0 +1,246 @@ +//===--- vec_int.h ----------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__utils__vec__vec_dble_h +#define satoko__utils__vec__vec_dble_h + +#include +#include +#include + +#include "../mem.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +typedef struct vec_dble_t_ vec_dble_t; +struct vec_dble_t_ { + unsigned cap; + unsigned size; + double *data; +}; + +//===------------------------------------------------------------------------=== +// Vector Macros +//===------------------------------------------------------------------------=== +#define vec_dble_foreach(vec, entry, i) \ + for (i = 0; (i < vec->size) && (((entry) = vec_dble_at(vec, i)), 1); i++) + +#define vec_dble_foreach_start(vec, entry, i, start) \ + for (i = start; (i < vec_dble_size(vec)) && (((entry) = vec_dble_at(vec, i)), 1); i++) + +#define vec_dble_foreach_stop(vec, entry, i, stop) \ + for (i = 0; (i < stop) && (((entry) = vec_dble_at(vec, i)), 1); i++) + +//===------------------------------------------------------------------------=== +// Vector API +//===------------------------------------------------------------------------=== +static inline vec_dble_t *vec_dble_alloc(unsigned cap) +{ + vec_dble_t* p = satoko_alloc(vec_dble_t, 1); + + if (cap > 0 && cap < 16) + cap = 16; + p->size = 0; + p->cap = cap; + p->data = p->cap ? satoko_alloc(double, p->cap) : NULL; + return p; +} + +static inline vec_dble_t *vec_dble_alloc_exact(unsigned cap) +{ + vec_dble_t* p = satoko_alloc(vec_dble_t, 1); + + p->size = 0; + p->cap = cap; + p->data = p->cap ? satoko_alloc(double, p->cap) : NULL; + return p; +} + +static inline vec_dble_t *vec_dble_init(unsigned size, double value) +{ + vec_dble_t* p = satoko_alloc(vec_dble_t, 1); + + p->cap = size; + p->size = size; + p->data = p->cap ? satoko_alloc(double, p->cap) : NULL; + memset(p->data, value, sizeof(double) * p->size); + return p; +} + +static inline void vec_dble_free(vec_dble_t *p) +{ + if (p->data != NULL) + satoko_free(p->data); + satoko_free(p); +} + +static inline unsigned vec_dble_size(vec_dble_t *p) +{ + return p->size; +} + +static inline void vec_dble_resize(vec_dble_t *p, unsigned new_size) +{ + p->size = new_size; + if (p->cap >= new_size) + return; + p->data = satoko_realloc(double, p->data, new_size); + assert(p->data != NULL); + p->cap = new_size; +} + +static inline void vec_dble_reserve(vec_dble_t *p, unsigned new_cap) +{ + if (p->cap >= new_cap) + return; + p->data = satoko_realloc(double, p->data, new_cap); + assert(p->data != NULL); + p->cap = new_cap; +} + +static inline unsigned vec_dble_capacity(vec_dble_t *p) +{ + return p->cap; +} + +static inline int vec_dble_empty(vec_dble_t *p) +{ + return p->size ? 0 : 1; +} + +static inline void vec_dble_erase(vec_dble_t *p) +{ + satoko_free(p->data); + p->size = 0; + p->cap = 0; +} + +static inline double vec_dble_at(vec_dble_t *p, unsigned i) +{ + assert(i >= 0 && i < p->size); + return p->data[i]; +} + +static inline double *vec_dble_at_ptr(vec_dble_t *p, unsigned i) +{ + assert(i >= 0 && i < p->size); + return p->data + i; +} + +static inline double *vec_dble_data(vec_dble_t *p) +{ + assert(p); + return p->data; +} + +static inline void vec_dble_duplicate(vec_dble_t *dest, const vec_dble_t *src) +{ + assert(dest != NULL && src != NULL); + vec_dble_resize(dest, src->cap); + memcpy(dest->data, src->data, sizeof(double) * src->cap); + dest->size = src->size; +} + +static inline void vec_dble_copy(vec_dble_t *dest, const vec_dble_t *src) +{ + assert(dest != NULL && src != NULL); + vec_dble_resize(dest, src->size); + memcpy(dest->data, src->data, sizeof(double) * src->size); + dest->size = src->size; +} + +static inline void vec_dble_push_back(vec_dble_t *p, double value) +{ + if (p->size == p->cap) { + if (p->cap < 16) + vec_dble_reserve(p, 16); + else + vec_dble_reserve(p, 2 * p->cap); + } + p->data[p->size] = value; + p->size++; +} + +static inline void vec_dble_assign(vec_dble_t *p, unsigned i, double value) +{ + assert((i >= 0) && (i < vec_dble_size(p))); + p->data[i] = value; +} + +static inline void vec_dble_insert(vec_dble_t *p, unsigned i, double value) +{ + assert((i >= 0) && (i < vec_dble_size(p))); + vec_dble_push_back(p, 0); + memmove(p->data + i + 1, p->data + i, (p->size - i - 2) * sizeof(double)); + p->data[i] = value; +} + +static inline void vec_dble_drop(vec_dble_t *p, unsigned i) +{ + assert((i >= 0) && (i < vec_dble_size(p))); + memmove(p->data + i, p->data + i + 1, (p->size - i - 1) * sizeof(double)); + p->size -= 1; +} + +static inline void vec_dble_clear(vec_dble_t *p) +{ + p->size = 0; +} + +static inline int vec_dble_asc_compare(const void *p1, const void *p2) +{ + const double *pp1 = (const double *) p1; + const double *pp2 = (const double *) p2; + + if (*pp1 < *pp2) + return -1; + if (*pp1 > *pp2) + return 1; + return 0; +} + +static inline int vec_dble_desc_compare(const void* p1, const void* p2) +{ + const double *pp1 = (const double *) p1; + const double *pp2 = (const double *) p2; + + if (*pp1 > *pp2) + return -1; + if (*pp1 < *pp2) + return 1; + return 0; +} + +static inline void vec_dble_sort(vec_dble_t* p, int ascending) +{ + if (ascending) + qsort((void *) p->data, p->size, sizeof(double), + (int (*)(const void*, const void*)) vec_dble_asc_compare); + else + qsort((void *) p->data, p->size, sizeof(double), + (int (*)(const void*, const void*)) vec_dble_desc_compare); +} + +static inline long vec_dble_memory(vec_dble_t *p) +{ + return p == NULL ? 0 : sizeof(double) * p->cap + sizeof(vec_dble_t); +} + +static inline void vec_dble_print(vec_dble_t *p) +{ + unsigned i; + assert(p != NULL); + fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap); + for (i = 0; i < p->size; i++) + fprintf(stdout, " %f", p->data[i]); + fprintf(stdout, " }\n"); +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__utils__vec__vec_dble_h */ diff --git a/src/sat/satoko/utils/vec/vec_int.h b/src/sat/satoko/utils/vec/vec_int.h new file mode 100755 index 000000000..75c5d1343 --- /dev/null +++ b/src/sat/satoko/utils/vec/vec_int.h @@ -0,0 +1,240 @@ +//===--- vec_int.h ----------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__utils__vec__vec_int_h +#define satoko__utils__vec__vec_int_h + +#include +#include +#include + +#include "../mem.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +typedef struct vec_int_t_ vec_int_t; +struct vec_int_t_ { + unsigned cap; + unsigned size; + int *data; +}; + +//===------------------------------------------------------------------------=== +// Vector Macros +//===------------------------------------------------------------------------=== +#define vec_int_foreach(vec, entry, i) \ + for (i = 0; (i < vec->size) && (((entry) = vec_int_at(vec, i)), 1); i++) + +#define vec_int_foreach_start(vec, entry, i, start) \ + for (i = start; (i < vec_int_size(vec)) && (((entry) = vec_int_at(vec, i)), 1); i++) + +#define vec_int_foreach_stop(vec, entry, i, stop) \ + for (i = 0; (i < stop) && (((entry) = vec_int_at(vec, i)), 1); i++) + +//===------------------------------------------------------------------------=== +// Vector API +//===------------------------------------------------------------------------=== +static inline vec_int_t *vec_int_alloc(unsigned cap) +{ + vec_int_t* p = satoko_alloc(vec_int_t, 1); + + if (cap > 0 && cap < 16) + cap = 16; + p->size = 0; + p->cap = cap; + p->data = p->cap ? satoko_alloc(int, p->cap) : NULL; + return p; +} + +static inline vec_int_t *vec_int_alloc_exact(unsigned cap) +{ + vec_int_t* p = satoko_alloc(vec_int_t, 1); + + p->size = 0; + p->cap = cap; + p->data = p->cap ? satoko_alloc(int, p->cap) : NULL; + return p; +} + +static inline vec_int_t *vec_int_init(unsigned size, int value) +{ + vec_int_t* p = satoko_alloc(vec_int_t, 1); + + p->cap = size; + p->size = size; + p->data = p->cap ? satoko_alloc(int, p->cap) : NULL; + memset(p->data, value, sizeof(int) * p->size); + return p; +} + +static inline void vec_int_free(vec_int_t *p) +{ + if (p->data != NULL) + satoko_free(p->data); + satoko_free(p); +} + +static inline unsigned vec_int_size(vec_int_t *p) +{ + return p->size; +} + +static inline void vec_int_resize(vec_int_t *p, unsigned new_size) +{ + p->size = new_size; + if (p->cap >= new_size) + return; + p->data = satoko_realloc(int, p->data, new_size); + assert(p->data != NULL); + p->cap = new_size; +} + +static inline void vec_int_reserve(vec_int_t *p, unsigned new_cap) +{ + if (p->cap >= new_cap) + return; + p->data = satoko_realloc(int, p->data, new_cap); + assert(p->data != NULL); + p->cap = new_cap; +} + +static inline unsigned vec_int_capacity(vec_int_t *p) +{ + return p->cap; +} + +static inline int vec_int_empty(vec_int_t *p) +{ + return p->size ? 0 : 1; +} + +static inline void vec_int_erase(vec_int_t *p) +{ + satoko_free(p->data); + p->size = 0; + p->cap = 0; +} + +static inline int vec_int_at(vec_int_t *p, unsigned i) +{ + assert(i >= 0 && i < p->size); + return p->data[i]; +} + +static inline int *vec_int_at_ptr(vec_int_t *p, unsigned i) +{ + assert(i >= 0 && i < p->size); + return p->data + i; +} + +static inline void vec_int_duplicate(vec_int_t *dest, const vec_int_t *src) +{ + assert(dest != NULL && src != NULL); + vec_int_resize(dest, src->cap); + memcpy(dest->data, src->data, sizeof(int) * src->cap); + dest->size = src->size; +} + +static inline void vec_int_copy(vec_int_t *dest, const vec_int_t *src) +{ + assert(dest != NULL && src != NULL); + vec_int_resize(dest, src->size); + memcpy(dest->data, src->data, sizeof(int) * src->size); + dest->size = src->size; +} + +static inline void vec_int_push_back(vec_int_t *p, int value) +{ + if (p->size == p->cap) { + if (p->cap < 16) + vec_int_reserve(p, 16); + else + vec_int_reserve(p, 2 * p->cap); + } + p->data[p->size] = value; + p->size++; +} + +static inline void vec_int_assign(vec_int_t *p, unsigned i, int value) +{ + assert((i >= 0) && (i < vec_int_size(p))); + p->data[i] = value; +} + +static inline void vec_int_insert(vec_int_t *p, unsigned i, int value) +{ + assert((i >= 0) && (i < vec_int_size(p))); + vec_int_push_back(p, 0); + memmove(p->data + i + 1, p->data + i, (p->size - i - 2) * sizeof(int)); + p->data[i] = value; +} + +static inline void vec_int_drop(vec_int_t *p, unsigned i) +{ + assert((i >= 0) && (i < vec_int_size(p))); + memmove(p->data + i, p->data + i + 1, (p->size - i - 1) * sizeof(int)); + p->size -= 1; +} + +static inline void vec_int_clear(vec_int_t *p) +{ + p->size = 0; +} + +static inline int vec_int_asc_compare(const void *p1, const void *p2) +{ + const int *pp1 = (const int *) p1; + const int *pp2 = (const int *) p2; + + if (*pp1 < *pp2) + return -1; + if (*pp1 > *pp2) + return 1; + return 0; +} + +static inline int vec_int_desc_compare(const void* p1, const void* p2) +{ + const int *pp1 = (const int *) p1; + const int *pp2 = (const int *) p2; + + if (*pp1 > *pp2) + return -1; + if (*pp1 < *pp2) + return 1; + return 0; +} + +static inline void vec_int_sort(vec_int_t* p, int ascending) +{ + if (ascending) + qsort((void *) p->data, p->size, sizeof(int), + (int (*)(const void*, const void*)) vec_int_asc_compare); + else + qsort((void *) p->data, p->size, sizeof(int), + (int (*)(const void*, const void*)) vec_int_desc_compare); +} + +static inline long vec_int_memory(vec_int_t *p) +{ + return p == NULL ? 0 : sizeof(int) * p->cap + sizeof(vec_int_t); +} + +static inline void vec_int_print(vec_int_t *p) +{ + unsigned i; + assert(p != NULL); + fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap); + for (i = 0; i < p->size; i++) + fprintf(stdout, " %d", p->data[i]); + fprintf(stdout, " }\n"); +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__utils__vec__vec_int_h */ diff --git a/src/sat/satoko/utils/vec/vec_uint.h b/src/sat/satoko/utils/vec/vec_uint.h new file mode 100755 index 000000000..e6719ca30 --- /dev/null +++ b/src/sat/satoko/utils/vec/vec_uint.h @@ -0,0 +1,268 @@ +//===--- vec_uint.h ---------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__utils__vec__vec_uint_h +#define satoko__utils__vec__vec_uint_h + +#include +#include +#include + +#include "../mem.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +typedef struct vec_uint_t_ vec_uint_t; +struct vec_uint_t_ { + unsigned cap; + unsigned size; + unsigned* data; +}; + +//===------------------------------------------------------------------------=== +// Vector Macros +//===------------------------------------------------------------------------=== +#define vec_uint_foreach(vec, entry, i) \ + for (i = 0; (i < vec_uint_size(vec)) && (((entry) = vec_uint_at(vec, i)), 1); i++) + +#define vec_uint_foreach_start(vec, entry, i, start) \ + for (i = start; (i < vec_uint_size(vec)) && (((entry) = vec_uint_at(vec, i)), 1); i++) + +#define vec_uint_foreach_stop(vec, entry, i, stop) \ + for (i = 0; (i < stop) && (((entry) = vec_uint_at(vec, i)), 1); i++) + +//===------------------------------------------------------------------------=== +// Vector API +//===------------------------------------------------------------------------=== +static inline vec_uint_t * vec_uint_alloc(unsigned cap) +{ + vec_uint_t *p = satoko_alloc(vec_uint_t, 1); + + if (cap > 0 && cap < 16) + cap = 16; + p->size = 0; + p->cap = cap; + p->data = p->cap ? satoko_alloc(unsigned, p->cap) : NULL; + return p; +} + +static inline vec_uint_t * vec_uint_alloc_exact(unsigned cap) +{ + vec_uint_t *p = satoko_alloc(vec_uint_t, 1); + + cap = 0; + p->size = 0; + p->cap = cap; + p->data = p->cap ? satoko_alloc(unsigned, p->cap ) : NULL; + return p; +} + +static inline vec_uint_t * vec_uint_init(unsigned size, unsigned value) +{ + vec_uint_t *p = satoko_alloc(vec_uint_t, 1); + + p->cap = size; + p->size = size; + p->data = p->cap ? satoko_alloc(unsigned, p->cap ) : NULL; + memset(p->data, value, sizeof(unsigned) * p->size); + return p; +} + +static inline void vec_uint_free(vec_uint_t *p) +{ + if (p->data != NULL) + satoko_free(p->data); + satoko_free(p); +} + +static inline unsigned vec_uint_size(vec_uint_t *p) +{ + return p->size; +} + +static inline void vec_uint_resize(vec_uint_t *p, unsigned new_size) +{ + p->size = new_size; + if (p->cap >= new_size) + return; + p->data = satoko_realloc(unsigned, p->data, new_size); + assert(p->data != NULL); + p->cap = new_size; +} + +static inline void vec_uint_shrink(vec_uint_t *p, unsigned new_size) +{ + assert(p->cap >= new_size); + p->size = new_size; +} + +static inline void vec_uint_reserve(vec_uint_t *p, unsigned new_cap) +{ + if (p->cap >= new_cap) + return; + p->data = satoko_realloc(unsigned, p->data, new_cap); + assert(p->data != NULL); + p->cap = new_cap; +} + +static inline unsigned vec_uint_capacity(vec_uint_t *p) +{ + return p->cap; +} + +static inline int vec_uint_empty(vec_uint_t *p) +{ + return p->size ? 0 : 1; +} + +static inline void vec_uint_erase(vec_uint_t *p) +{ + satoko_free(p->data); + p->size = 0; + p->cap = 0; +} + +static inline unsigned vec_uint_at(vec_uint_t *p, unsigned idx) +{ + assert(idx >= 0 && idx < p->size); + return p->data[idx]; +} + +static inline unsigned * vec_uint_at_ptr(vec_uint_t *p, unsigned idx) +{ + assert(idx >= 0 && idx < p->size); + return p->data + idx; +} + +static inline unsigned vec_uint_find(vec_uint_t *p, unsigned entry) +{ + unsigned i; + for (i = 0; i < p->size; i++) + if (p->data[i] == entry) + return 1; + return 0; +} + +static inline unsigned * vec_uint_data(vec_uint_t *p) +{ + assert(p); + return p->data; +} + +static inline void vec_uint_duplicate(vec_uint_t *dest, const vec_uint_t *src) +{ + assert(dest != NULL && src != NULL); + vec_uint_resize(dest, src->cap); + memcpy(dest->data, src->data, sizeof(unsigned) * src->cap); + dest->size = src->size; +} + +static inline void vec_uint_copy(vec_uint_t *dest, const vec_uint_t *src) +{ + assert(dest != NULL && src != NULL); + vec_uint_resize(dest, src->size); + memcpy(dest->data, src->data, sizeof(unsigned) * src->size); + dest->size = src->size; +} + +static inline void vec_uint_push_back(vec_uint_t *p, unsigned value) +{ + if (p->size == p->cap) { + if (p->cap < 16) + vec_uint_reserve(p, 16); + else + vec_uint_reserve(p, 2 * p->cap); + } + p->data[p->size] = value; + p->size++; +} + +static inline unsigned vec_uint_pop_back(vec_uint_t *p) +{ + assert(p && p->size); + return p->data[--p->size]; +} + +static inline void vec_uint_assign(vec_uint_t *p, unsigned idx, unsigned value) +{ + assert((idx >= 0) && (idx < vec_uint_size(p))); + p->data[idx] = value; +} + +static inline void vec_uint_insert(vec_uint_t *p, unsigned idx, unsigned value) +{ + assert((idx >= 0) && (idx < vec_uint_size(p))); + vec_uint_push_back(p, 0); + memmove(p->data + idx + 1, p->data + idx, (p->size - idx - 2) * sizeof(unsigned)); + p->data[idx] = value; +} + +static inline void vec_uint_drop(vec_uint_t *p, unsigned idx) +{ + assert((idx >= 0) && (idx < vec_uint_size(p))); + memmove(p->data + idx, p->data + idx + 1, (p->size - idx - 1) * sizeof(unsigned)); + p->size -= 1; +} + +static inline void vec_uint_clear(vec_uint_t *p) +{ + p->size = 0; +} + +static inline int vec_uint_asc_compare(const void *p1, const void *p2) +{ + const unsigned *pp1 = (const unsigned *) p1; + const unsigned *pp2 = (const unsigned *) p2; + + if ( *pp1 < *pp2 ) + return -1; + if ( *pp1 > *pp2 ) + return 1; + return 0; +} + +static inline int vec_uint_desc_compare(const void *p1, const void *p2) +{ + const unsigned *pp1 = (const unsigned *) p1; + const unsigned *pp2 = (const unsigned *) p2; + + if ( *pp1 > *pp2 ) + return -1; + if ( *pp1 < *pp2 ) + return 1; + return 0; +} + +static inline void vec_uint_sort(vec_uint_t *p, int ascending) +{ + if (ascending) + qsort((void *) p->data, p->size, sizeof(unsigned), + (int (*)(const void *, const void *)) vec_uint_asc_compare); + else + qsort((void*) p->data, p->size, sizeof(unsigned), + (int (*)(const void *, const void *)) vec_uint_desc_compare); +} + +static inline long vec_uint_memory(vec_uint_t *p) +{ + return p == NULL ? 0 : sizeof(unsigned) * p->cap + sizeof(vec_uint_t); +} + +static inline void vec_uint_print(vec_uint_t* p) +{ + unsigned i; + assert(p != NULL); + fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap); + for (i = 0; i < p->size; i++) + fprintf(stdout, " %u", p->data[i]); + fprintf(stdout, " }\n"); +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__utils__vec__vec_uint_h */ diff --git a/src/sat/satoko/watch_list.h b/src/sat/satoko/watch_list.h new file mode 100644 index 000000000..f492904a7 --- /dev/null +++ b/src/sat/satoko/watch_list.h @@ -0,0 +1,152 @@ +//===--- watch_list.h -------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__watch_list_h +#define satoko__watch_list_h + +#include "utils/mem.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +struct watcher { + unsigned cref; + unsigned blocker; +}; + +struct watch_list { + unsigned cap; + unsigned size; + struct watcher *watchers; +}; + +typedef struct vec_wl_t_ vec_wl_t; +struct vec_wl_t_ { + unsigned cap; + unsigned size; + struct watch_list *watch_lists; +}; + +//===------------------------------------------------------------------------=== +// Watch list Macros +//===------------------------------------------------------------------------=== +#define watch_list_foreach(vec, watch, lit) \ + for (watch = watch_list_array(vec_wl_at(vec, lit)); \ + watch < watch_list_array(vec_wl_at(vec, lit)) + watch_list_size(vec_wl_at(vec, lit)); \ + watch++) + +//===------------------------------------------------------------------------=== +// Watch list API +//===------------------------------------------------------------------------=== +static inline void watch_list_free(struct watch_list *wl) +{ + if (wl->watchers) + satoko_free(wl->watchers); +} + +static inline unsigned watch_list_size(struct watch_list *wl) +{ + return wl->size; +} + +static inline void watch_list_shrink(struct watch_list *wl, unsigned size) +{ + assert(size <= wl->size); + wl->size = size; +} + +static inline void watch_list_push(struct watch_list *wl, struct watcher w) +{ + assert(wl); + if (wl->size == wl->cap) { + unsigned new_size = (wl->cap < 4) ? 4 : (wl->cap / 2) * 3; + struct watcher *watchers = + satoko_realloc(struct watcher, wl->watchers, new_size); + if (watchers == NULL) { + printf("Failed to realloc memory from %.1f MB to %.1f " + "MB.\n", + 1.0 * wl->cap / (1 << 20), + 1.0 * new_size / (1 << 20)); + fflush(stdout); + return; + } + wl->watchers = watchers; + wl->cap = new_size; + } + wl->watchers[wl->size++] = w; +} + +static inline struct watcher *watch_list_array(struct watch_list *wl) +{ + return wl->watchers; +} + +static inline void watch_list_remove(struct watch_list *wl, unsigned cref) +{ + struct watcher *watchers = watch_list_array(wl); + unsigned i; + for (i = 0; watchers[i].cref != cref; i++); + assert(i < watch_list_size(wl)); + memmove((wl->watchers + i), (wl->watchers + i + 1), + (wl->size - i - 1) * sizeof(struct watcher)); + wl->size -= 1; +} + +static inline vec_wl_t *vec_wl_alloc(unsigned cap) +{ + vec_wl_t *vec_wl = satoko_alloc(vec_wl_t, 1); + + if (cap == 0) + vec_wl->cap = 4; + else + vec_wl->cap = cap; + vec_wl->size = 0; + vec_wl->watch_lists = satoko_calloc( + struct watch_list, sizeof(struct watch_list) * vec_wl->cap); + return vec_wl; +} + +static inline void vec_wl_free(vec_wl_t *vec_wl) +{ + for (unsigned i = 0; i < vec_wl->size; i++) + watch_list_free(vec_wl->watch_lists + i); + satoko_free(vec_wl->watch_lists); + satoko_free(vec_wl); +} + +static inline void vec_wl_push(vec_wl_t *vec_wl) +{ + if (vec_wl->size == vec_wl->cap) { + unsigned new_size = + (vec_wl->cap < 4) ? vec_wl->cap * 2 : (vec_wl->cap / 2) * 3; + + vec_wl->watch_lists = satoko_realloc( + struct watch_list, vec_wl->watch_lists, new_size); + memset(vec_wl->watch_lists + vec_wl->cap, 0, + sizeof(struct watch_list) * (new_size - vec_wl->cap)); + if (vec_wl->watch_lists == NULL) { + printf("failed to realloc memory from %.1f mb to %.1f " + "mb.\n", + 1.0 * vec_wl->cap / (1 << 20), + 1.0 * new_size / (1 << 20)); + fflush(stdout); + } + vec_wl->cap = new_size; + } + vec_wl->size++; +} + +static inline struct watch_list *vec_wl_at(vec_wl_t *vec_wl, unsigned idx) +{ + assert(idx < vec_wl->cap); + assert(idx < vec_wl->size); + return vec_wl->watch_lists + idx; +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__watch_list_h */ From 495a34e3ce1a0a0ac664748c991be437dd1c7ea7 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 6 Feb 2017 18:53:35 -0800 Subject: [PATCH 104/185] Fixing compilation problem in 'dsc' package. --- src/opt/dsc/dsc.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/opt/dsc/dsc.c b/src/opt/dsc/dsc.c index ce180fe3b..7ddeeed99 100644 --- a/src/opt/dsc/dsc.c +++ b/src/opt/dsc/dsc.c @@ -51,14 +51,14 @@ struct Dsc_node_t_ /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -inline void xorInPlace( word * pOut, word * pIn2, int nWords) +static inline void xorInPlace( word * pOut, word * pIn2, int nWords) { int w; for ( w = 0; w < nWords; w++ ) pOut[w] ^= pIn2[w]; } -void dsc_debug_node(Dsc_node_t * pNode, int nVars, const int TRUTH_WORDS) { +static inline void dsc_debug_node(Dsc_node_t * pNode, int nVars, const int TRUTH_WORDS) { int i; printf("Node:\t%s\n",pNode->exp); printf("\tneg cof:\t");Abc_TtPrintHexRev(stdout, pNode->pNegCof, nVars); @@ -75,7 +75,7 @@ void dsc_debug_node(Dsc_node_t * pNode, int nVars, const int TRUTH_WORDS) { printf("\n"); } -inline int dsc_and_test(Dsc_node_t *ni, Dsc_node_t *nj, const int TRUTH_WORDS, int* ci, int* cj) { +static inline int dsc_and_test(Dsc_node_t *ni, Dsc_node_t *nj, const int TRUTH_WORDS, int* ci, int* cj) { if (Abc_TtEqual(ni->pNegCof, nj->pNegCof, TRUTH_WORDS)) {*ci=1; *cj=1; return 1;} else if (Abc_TtEqual(ni->pNegCof, nj->pPosCof, TRUTH_WORDS)) {*ci=1; *cj=0; return 1;} else if (Abc_TtEqual(ni->pPosCof, nj->pNegCof, TRUTH_WORDS)) {*ci=0; *cj=1; return 1;} @@ -83,11 +83,11 @@ inline int dsc_and_test(Dsc_node_t *ni, Dsc_node_t *nj, const int TRUTH_WORDS, i return 0; } -inline int dsc_xor_test(Dsc_node_t *ni, Dsc_node_t *nj, const int TRUTH_WORDS) { +static inline int dsc_xor_test(Dsc_node_t *ni, Dsc_node_t *nj, const int TRUTH_WORDS) { return Abc_TtEqual(ni->pBoolDiff, nj->pBoolDiff, TRUTH_WORDS); } -void concat(char* target, char begin, char end, char* s1, int s1Polarity, char* s2, int s2Polarity) { +static inline void concat(char* target, char begin, char end, char* s1, int s1Polarity, char* s2, int s2Polarity) { *target++ = begin; //s1 if (!s1Polarity) @@ -104,7 +104,7 @@ void concat(char* target, char begin, char end, char* s1, int s1Polarity, char* *target = '\0'; } -void cubeCofactor(word * const pTruth, const unsigned int * const cubeCof, const int TRUTH_WORDS) { +static inline void cubeCofactor(word * const pTruth, const unsigned int * const cubeCof, const int TRUTH_WORDS) { int size = cubeCof[0]; int i; for (i = 1; i <= size; i++) { @@ -117,7 +117,7 @@ void cubeCofactor(word * const pTruth, const unsigned int * const cubeCof, const } } -void merge(unsigned int * const pOut, const unsigned int * const pIn) { +static inline void merge(unsigned int * const pOut, const unsigned int * const pIn) { const int elementsToCopy = pIn[0]; int i, j; for (i = pOut[0]+1, j = 1; j <= elementsToCopy; i++, j++) { From 0fb4442a8208ccc36067db034c12a840095c0911 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Mon, 6 Feb 2017 19:50:57 -0800 Subject: [PATCH 105/185] Small changes to support old compilers. --- src/base/abci/abc.c | 2 +- src/sat/satoko/satoko.h | 4 ++-- src/sat/satoko/solver.c | 4 ++-- src/sat/satoko/solver.h | 36 ++++++++++++++--------------- src/sat/satoko/solver_api.c | 12 +++++----- src/sat/satoko/utils/b_queue.h | 4 ++-- src/sat/satoko/utils/misc.h | 2 -- src/sat/satoko/utils/vec/vec_char.h | 3 ++- src/sat/satoko/watch_list.h | 3 ++- 9 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index efb82fcc2..65974acb2 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -23357,7 +23357,7 @@ int Abc_CommandSatoko( Abc_Frame_t * pAbc, int argc, char ** argv ) int status; satoko_parse_dimacs( pFileName, &p ); - satoko_configure(p, &opts); + satoko_configure(p, &opts); clk = Abc_Clock(); status = satoko_solve( p ); diff --git a/src/sat/satoko/satoko.h b/src/sat/satoko/satoko.h index 49c7837e4..55790714a 100644 --- a/src/sat/satoko/satoko.h +++ b/src/sat/satoko/satoko.h @@ -30,8 +30,8 @@ typedef struct solver_t_ satoko_t; typedef struct satoko_opts satoko_opts_t; struct satoko_opts { /* Limits */ - long long conf_limit; /* Limit on the n.of conflicts */ - long long prop_limit; /* Limit on the n.of implications */ + long conf_limit; /* Limit on the n.of conflicts */ + long prop_limit; /* Limit on the n.of implications */ /* Constants used for restart heuristic */ double f_rst; /* Used to force a restart */ diff --git a/src/sat/satoko/solver.c b/src/sat/satoko/solver.c index b2861badc..8c06bbe8b 100644 --- a/src/sat/satoko/solver.c +++ b/src/sat/satoko/solver.c @@ -325,14 +325,14 @@ static inline void solver_analyze(solver_t *s, unsigned cref, vec_uint_t *learnt static inline int solver_rst(solver_t *s) { return b_queue_is_valid(s->bq_lbd) && - (((long long)b_queue_avg(s->bq_lbd) * s->opts.f_rst) > (s->sum_lbd / s->stats.n_conflicts)); + (((long)b_queue_avg(s->bq_lbd) * s->opts.f_rst) > (s->sum_lbd / s->stats.n_conflicts)); } static inline int solver_block_rst(solver_t *s) { return s->stats.n_conflicts > s->opts.fst_block_rst && b_queue_is_valid(s->bq_lbd) && - (vec_uint_size(s->trail) > (s->opts.b_rst * (long long)b_queue_avg(s->bq_trail))); + ((long)vec_uint_size(s->trail) > (s->opts.b_rst * (long)b_queue_avg(s->bq_trail))); } static inline void solver_handle_conflict(solver_t *s, unsigned confl_cref) diff --git a/src/sat/satoko/solver.h b/src/sat/satoko/solver.h index 65b86c681..fe1d1ef59 100644 --- a/src/sat/satoko/solver.h +++ b/src/sat/satoko/solver.h @@ -42,13 +42,13 @@ struct satoko_stats { unsigned n_starts; unsigned n_reduce_db; - long long n_decisions; - long long n_propagations; - long long n_inspects; - long long n_conflicts; + long n_decisions; + long n_propagations; + long n_inspects; + long n_conflicts; - long long n_original_lits; - long long n_learnt_lits; + long n_original_lits; + long n_learnt_lits; }; typedef struct solver_t_ solver_t; @@ -82,17 +82,9 @@ struct solver_t_ { unsigned i_qhead; /* Head of propagation queue (as index into the trail). */ unsigned n_assigns_simplify; /* Number of top-level assignments since last execution of 'simplify()'. */ - long long n_props_simplify; /* Remaining number of propagations that - must be made before next execution of - 'simplify()'. */ - - /* Temporary data used by Search method */ - b_queue_t *bq_trail; - b_queue_t *bq_lbd; - long RC1; - long RC2; - unsigned n_confl_bfr_reduce; - float sum_lbd; + long n_props_simplify; /* Remaining number of propagations that + must be made before next execution of + 'simplify()'. */ /* Temporary data used by Analyze */ vec_uint_t *temp_lits; @@ -101,10 +93,18 @@ struct solver_t_ { vec_uint_t *stack; vec_uint_t *last_dlevel; + /* Temporary data used by Search method */ + b_queue_t *bq_trail; + b_queue_t *bq_lbd; + long RC1; + long RC2; + long n_confl_bfr_reduce; + float sum_lbd; + /* Misc temporary */ + unsigned cur_stamp; /* Used for marking literals and levels of interest */ vec_uint_t *stamps; /* Multipurpose stamp used to calculate LBD and * clauses minimization with binary resolution */ - unsigned cur_stamp; /* Used for marking literals and levels of interest */ struct satoko_stats stats; struct satoko_opts opts; diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c index db9a267b5..e041cc62e 100644 --- a/src/sat/satoko/solver_api.c +++ b/src/sat/satoko/solver_api.c @@ -68,9 +68,9 @@ static inline void print_opts(solver_t *s) static inline void print_stats(solver_t *s) { printf("starts : %10d\n", s->stats.n_starts); - printf("conflicts : %10lld\n", s->stats.n_conflicts); - printf("decisions : %10lld\n", s->stats.n_decisions); - printf("propagations : %10lld\n", s->stats.n_propagations); + printf("conflicts : %10ld\n", s->stats.n_conflicts); + printf("decisions : %10ld\n", s->stats.n_decisions); + printf("propagations : %10ld\n", s->stats.n_propagations); } //===------------------------------------------------------------------------=== @@ -166,13 +166,13 @@ void satoko_default_opts(satoko_opts_t *opts) opts->inc_special_reduce = 1000; opts->lbd_freeze_clause = 30; /* VSIDS heuristic */ - opts->var_decay = 0.95; - opts->clause_decay = 0.995; + opts->var_decay = (act_t) 0.95; + opts->clause_decay = (clause_act_t) 0.995; /* Binary resolution */ opts->clause_max_sz_bin_resol = 30; opts->clause_min_lbd_bin_resol = 6; - opts->garbage_max_ratio = 0.3; + opts->garbage_max_ratio = (float) 0.3; } /** diff --git a/src/sat/satoko/utils/b_queue.h b/src/sat/satoko/utils/b_queue.h index 926edf290..b9b626768 100644 --- a/src/sat/satoko/utils/b_queue.h +++ b/src/sat/satoko/utils/b_queue.h @@ -21,7 +21,7 @@ struct b_queue_t_ { unsigned cap; unsigned i_first; unsigned i_empty; - unsigned long long sum; + unsigned long sum; unsigned *data; }; @@ -61,7 +61,7 @@ static inline void b_queue_push(b_queue_t *p, unsigned Value) static inline unsigned b_queue_avg(b_queue_t *p) { - return (unsigned)(p->sum / ((unsigned long long) p->size)); + return (unsigned)(p->sum / ((unsigned long) p->size)); } static inline unsigned b_queue_is_valid(b_queue_t *p) diff --git a/src/sat/satoko/utils/misc.h b/src/sat/satoko/utils/misc.h index aa8bcb8c4..481e23b71 100755 --- a/src/sat/satoko/utils/misc.h +++ b/src/sat/satoko/utils/misc.h @@ -9,8 +9,6 @@ #ifndef satoko__utils__misc_h #define satoko__utils__misc_h -#include - #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START diff --git a/src/sat/satoko/utils/vec/vec_char.h b/src/sat/satoko/utils/vec/vec_char.h index fe88797a5..7d5732ec0 100644 --- a/src/sat/satoko/utils/vec/vec_char.h +++ b/src/sat/satoko/utils/vec/vec_char.h @@ -248,9 +248,10 @@ static inline long vec_char_memory(vec_char_t *p) static inline void vec_char_print(vec_char_t* p) { + unsigned i; assert(p != NULL); fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap); - for (unsigned i = 0; i < p->size; i++) + for (i = 0; i < p->size; i++) fprintf(stdout, " %d", p->data[i]); fprintf(stdout, " }\n"); } diff --git a/src/sat/satoko/watch_list.h b/src/sat/satoko/watch_list.h index f492904a7..ef1c1a075 100644 --- a/src/sat/satoko/watch_list.h +++ b/src/sat/satoko/watch_list.h @@ -113,7 +113,8 @@ static inline vec_wl_t *vec_wl_alloc(unsigned cap) static inline void vec_wl_free(vec_wl_t *vec_wl) { - for (unsigned i = 0; i < vec_wl->size; i++) + unsigned i; + for (i = 0; i < vec_wl->size; i++) watch_list_free(vec_wl->watch_lists + i); satoko_free(vec_wl->watch_lists); satoko_free(vec_wl); From 542f84d2fb059a0779ee1878ee3c1cc2fdbad2df Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 6 Feb 2017 20:54:41 -0800 Subject: [PATCH 106/185] Small changes to compile satoko on Windows. --- abclib.dsp | 84 +++++++++++++++++++++++++++++++++++++ src/sat/satoko/act_clause.h | 4 +- src/sat/satoko/cnf_reader.c | 2 +- src/sat/satoko/solver.c | 2 +- 4 files changed, 88 insertions(+), 4 deletions(-) diff --git a/abclib.dsp b/abclib.dsp index d6b769668..12636df50 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -1994,6 +1994,90 @@ SOURCE=.\src\sat\xsat\xsatUtils.h SOURCE=.\src\sat\xsat\xsatWatchList.h # End Source File # End Group +# Begin Group "satoko" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\sat\satoko\act_clause.h +# End Source File +# Begin Source File + +SOURCE=.\src\sat\satoko\act_var.h +# End Source File +# Begin Source File + +SOURCE=.\src\sat\satoko\utils\b_queue.h +# End Source File +# Begin Source File + +SOURCE=.\src\sat\satoko\cdb.h +# End Source File +# Begin Source File + +SOURCE=.\src\sat\satoko\clause.h +# End Source File +# Begin Source File + +SOURCE=.\src\sat\satoko\cnf_reader.c +# End Source File +# Begin Source File + +SOURCE=.\src\sat\satoko\utils\heap.h +# End Source File +# Begin Source File + +SOURCE=.\src\sat\satoko\utils\mem.h +# End Source File +# Begin Source File + +SOURCE=.\src\sat\satoko\utils\misc.h +# End Source File +# Begin Source File + +SOURCE=.\src\sat\satoko\satoko.h +# End Source File +# Begin Source File + +SOURCE=.\src\sat\satoko\solver.c +# End Source File +# Begin Source File + +SOURCE=.\src\sat\satoko\solver.h +# End Source File +# Begin Source File + +SOURCE=.\src\sat\satoko\solver_api.c +# End Source File +# Begin Source File + +SOURCE=.\src\sat\satoko\utils\sort.h +# End Source File +# Begin Source File + +SOURCE=.\src\sat\satoko\types.h +# End Source File +# Begin Source File + +SOURCE=.\src\sat\satoko\utils\vec\vec_char.h +# End Source File +# Begin Source File + +SOURCE=.\src\sat\satoko\utils\vec\vec_dble.h +# End Source File +# Begin Source File + +SOURCE=.\src\sat\satoko\utils\vec\vec_int.h +# End Source File +# Begin Source File + +SOURCE=.\src\sat\satoko\utils\vec\vec_uint.h +# End Source File +# Begin Source File + +SOURCE=.\src\sat\satoko\watch_list.h +# End Source File +# End Group # End Group # Begin Group "opt" diff --git a/src/sat/satoko/act_clause.h b/src/sat/satoko/act_clause.h index 5a2fda2b7..2e80a1e67 100644 --- a/src/sat/satoko/act_clause.h +++ b/src/sat/satoko/act_clause.h @@ -26,9 +26,9 @@ static inline void clause_act_rescale(solver_t *s) vec_uint_foreach(s->learnts, cref, i) { clause = clause_read(s, cref); - clause->data[clause->size].act *= 1e-20; + clause->data[clause->size].act *= (float)1e-20; } - s->clause_act_inc *= 1e-20; + s->clause_act_inc *= (float)1e-20; } /** Increment the activity value of one clause ('clause') diff --git a/src/sat/satoko/cnf_reader.c b/src/sat/satoko/cnf_reader.c index 5e4b92f92..9fbbda65a 100644 --- a/src/sat/satoko/cnf_reader.c +++ b/src/sat/satoko/cnf_reader.c @@ -97,7 +97,7 @@ static void read_clause(char **token, vec_uint_t *lits) break; sign = (var > 0); var = abs(var) - 1; - vec_uint_push_back(lits, var2lit((unsigned) var, !sign)); + vec_uint_push_back(lits, var2lit((unsigned) var, (char)!sign)); } } diff --git a/src/sat/satoko/solver.c b/src/sat/satoko/solver.c index 8c06bbe8b..a4114e543 100644 --- a/src/sat/satoko/solver.c +++ b/src/sat/satoko/solver.c @@ -330,7 +330,7 @@ static inline int solver_rst(solver_t *s) static inline int solver_block_rst(solver_t *s) { - return s->stats.n_conflicts > s->opts.fst_block_rst && + return s->stats.n_conflicts > (int)s->opts.fst_block_rst && b_queue_is_valid(s->bq_lbd) && ((long)vec_uint_size(s->trail) > (s->opts.b_rst * (long)b_queue_avg(s->bq_trail))); } From 44dbf992a7e32f3e09a789b95222a18ed54f8f5b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 6 Feb 2017 23:28:00 -0800 Subject: [PATCH 107/185] Re-introducing floating-point activity in the SAT solver. --- src/sat/bsat/satSolver.c | 174 ++++++++++++++++++++++++++++++--------- src/sat/bsat/satSolver.h | 36 ++++++++ 2 files changed, 171 insertions(+), 39 deletions(-) diff --git a/src/sat/bsat/satSolver.c b/src/sat/bsat/satSolver.c index 3295fc6fe..73d0cf360 100644 --- a/src/sat/bsat/satSolver.c +++ b/src/sat/bsat/satSolver.c @@ -145,12 +145,22 @@ static inline void order_update(sat_solver* s, int v) // updateorder assert(s->orderpos[v] != -1); +#ifdef USE_FLOAT_ACTIVITY_NEW + while (i != 0 && xSat_LessThan(s->activity[heap[parent]], s->activity[x]) ){ + heap[i] = heap[parent]; + orderpos[heap[i]] = i; + i = parent; + parent = (i - 1) / 2; + } +#else while (i != 0 && s->activity[x] > s->activity[heap[parent]]){ heap[i] = heap[parent]; orderpos[heap[i]] = i; i = parent; parent = (i - 1) / 2; } +#endif + heap[i] = x; orderpos[x] = i; } @@ -192,11 +202,21 @@ static inline int order_select(sat_solver* s, float random_var_freq) // selectv int i = 0; int child = 1; while (child < size){ + +#ifdef USE_FLOAT_ACTIVITY_NEW + if (child+1 < size && xSat_LessThan(s->activity[heap[child]], s->activity[heap[child+1]]) ) + child++; + assert(child < size); + if ( !xSat_LessThan(s->activity[x], s->activity[heap[child]]) ) + break; +#else if (child+1 < size && s->activity[heap[child]] < s->activity[heap[child+1]]) child++; assert(child < size); if (s->activity[x] >= s->activity[heap[child]]) break; +#endif + heap[i] = heap[child]; orderpos[heap[i]] = i; i = child; @@ -213,6 +233,7 @@ static inline int order_select(sat_solver* s, float random_var_freq) // selectv void sat_solver_set_var_activity(sat_solver* s, int * pVars, int nVars) { +#ifndef USE_FLOAT_ACTIVITY_NEW int i; for (i = 0; i < s->size; i++) s->activity[i] = 0; @@ -223,6 +244,7 @@ void sat_solver_set_var_activity(sat_solver* s, int * pVars, int nVars) s->activity[iVar] = nVars-i; order_update( s, iVar ); } +#endif } //================================================================================================= @@ -230,6 +252,46 @@ void sat_solver_set_var_activity(sat_solver* s, int * pVars, int nVars) #ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + +static inline void act_var_rescale(sat_solver* s) { + xFloat_t * activity = s->activity; + int i; + for (i = 0; i < s->size; i++) + activity[i] = xSat_FloatDiv( activity[i], 1<<10 ); // activity[i] / 2^1024 + s->var_inc = xSat_FloatDiv( s->var_inc, 1<<10 ); +} +static inline void act_clause_rescale(sat_solver* s) { + xFloat_t* activity = (xFloat_t *)veci_begin(&s->act_clas); + int i; + for (i = 0; i < veci_size(&s->act_clas); i++) + activity[i] = xSat_FloatDiv( activity[i], 1<<10 ); // activity[i] / 2^1024 + s->cla_inc = xSat_FloatDiv( s->cla_inc, 1<<10 ); +} +static inline void act_var_bump(sat_solver* s, int v) { + s->activity[v] = xSat_FloatAdd( s->activity[v], s->var_inc ); + if ( xSat_LessThan(xSat_FloatCreate(1 << 12, 1 << 15), s->activity[v]) ) // 2^4096 < s->activity[v] + act_var_rescale(s); + if (s->orderpos[v] != -1) + order_update(s,v); +} +static inline void act_var_bump_global(sat_solver* s, int v) { + assert(0); +} +static inline void act_var_bump_factor(sat_solver* s, int v) { + assert(0); +} +static inline void act_clause_bump(sat_solver* s, clause *c) { + xFloat_t* act = (xFloat_t *)veci_begin(&s->act_clas) + c->lits[c->size]; + *act = xSat_FloatAdd( *act, s->cla_inc ); + if ( xSat_LessThan(xSat_FloatCreate(1 << 12, 1 << 15), *act) ) // 2^4096 < *act + act_clause_rescale(s); +} +static inline void act_var_decay(sat_solver* s) { s->var_inc = xSat_FloatMul(s->var_inc, s->var_decay); } +static inline void act_clause_decay(sat_solver* s) { s->cla_inc = xSat_FloatMul(s->cla_inc, s->cla_decay); } + +#else + static inline void act_var_rescale(sat_solver* s) { double* activity = s->activity; int i; @@ -238,18 +300,11 @@ static inline void act_var_rescale(sat_solver* s) { s->var_inc *= 1e-100; } static inline void act_clause_rescale(sat_solver* s) { -// static abctime Total = 0; - clause** cs = (clause**)veci_begin(&s->learnts); - int i;//, clk = Abc_Clock(); - for (i = 0; i < veci_size(&s->learnts); i++){ - float a = clause_activity(cs[i]); - clause_setactivity(cs[i], a * (float)1e-20); - } + float* activity = (float *)veci_begin(&s->act_clas); + int i; + for (i = 0; i < veci_size(&s->act_clas); i++) + activity[i] *= (float)1e-20; s->cla_inc *= (float)1e-20; - - Total += Abc_Clock() - clk; -// printf( "Rescaling... Cla inc = %10.3f Conf = %10d ", s->cla_inc, s->stats.conflicts ); -// Abc_PrintTime( 1, "Time", Total ); } static inline void act_var_bump(sat_solver* s, int v) { s->activity[v] += s->var_inc; @@ -259,31 +314,22 @@ static inline void act_var_bump(sat_solver* s, int v) { order_update(s,v); } static inline void act_var_bump_global(sat_solver* s, int v) { - if ( !s->pGlobalVars ) - return; - s->activity[v] += (s->var_inc * 3.0 * s->pGlobalVars[v]); - if (s->activity[v] > 1e100) - act_var_rescale(s); - if (s->orderpos[v] != -1) - order_update(s,v); + assert(0); } static inline void act_var_bump_factor(sat_solver* s, int v) { - if ( !s->factors ) - return; - s->activity[v] += (s->var_inc * s->factors[v]); - if (s->activity[v] > 1e100) - act_var_rescale(s); - if (s->orderpos[v] != -1) - order_update(s,v); + assert(0); } static inline void act_clause_bump(sat_solver* s, clause *c) { - float a = clause_activity(c) + s->cla_inc; - clause_setactivity(c,a); - if (a > 1e20) act_clause_rescale(s); + float* act = (float *)veci_begin(&s->act_clas) + c->lits[c->size]; + *act += s->cla_inc; + if (*act > 1e20) + act_clause_rescale(s); } static inline void act_var_decay(sat_solver* s) { s->var_inc *= s->var_decay; } static inline void act_clause_decay(sat_solver* s) { s->cla_inc *= s->cla_decay; } +#endif + #else static inline void act_var_rescale(sat_solver* s) { @@ -296,17 +342,12 @@ static inline void act_var_rescale(sat_solver* s) { } static inline void act_clause_rescale(sat_solver* s) { - static abctime Total = 0; - abctime clk = Abc_Clock(); unsigned* activity = (unsigned *)veci_begin(&s->act_clas); int i; for (i = 0; i < veci_size(&s->act_clas); i++) activity[i] >>= 14; s->cla_inc >>= 14; s->cla_inc = Abc_MaxInt( s->cla_inc, (1<<10) ); - Total += Abc_Clock() - clk; -// printf( "Rescaling... Cla inc = %5d Conf = %10d ", s->cla_inc, s->stats.conflicts ); -// Abc_PrintTime( 1, "Time", Total ); } static inline void act_var_bump(sat_solver* s, int v) { @@ -447,7 +488,15 @@ int sat_solver_clause_new(sat_solver* s, lit* begin, lit* end, int learnt) assert( clause_id(c) == veci_size(&s->act_clas) ); // veci_push(&s->learned, h); // act_clause_bump(s,clause_read(s, h)); +#ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + veci_push(&s->act_clas, xSat_Float2Uint(xSat_FloatCreateConst1())); +#else + veci_push(&s->act_clas, 0); +#endif +#else veci_push(&s->act_clas, (1<<10)); +#endif s->stats.learnts++; s->stats.learnts_literals += size; } @@ -1055,10 +1104,17 @@ sat_solver* sat_solver_new(void) s->qhead = 0; s->qtail = 0; #ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + s->var_inc = xSat_FloatCreateConst1(); + s->cla_inc = xSat_FloatCreateConst1(); + s->var_decay = xSat_FloatFromFloat( (float)(1 / 0.95) ); + s->cla_decay = xSat_FloatFromFloat( (float)(1 / 0.999) ); +#else s->var_inc = 1; s->cla_inc = 1; s->var_decay = (float)(1 / 0.95 ); s->cla_decay = (float)(1 / 0.999); +#endif #else s->var_inc = (1 << 5); s->cla_inc = (1 << 11); @@ -1126,10 +1182,17 @@ sat_solver* zsat_solver_new_seed(double seed) s->qhead = 0; s->qtail = 0; #ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + s->var_inc = xSat_FloatCreateConst1(); + s->cla_inc = xSat_FloatCreateConst1(); + s->var_decay = xSat_FloatFromFloat( (float)(1 / 0.95) ); + s->cla_decay = xSat_FloatFromFloat( (float)(1 / 0.999) ); +#else s->var_inc = 1; s->cla_inc = 1; s->var_decay = (float)(1 / 0.95 ); s->cla_decay = (float)(1 / 0.999); +#endif #else s->var_inc = (1 << 5); s->cla_inc = (1 << 11); @@ -1174,7 +1237,11 @@ void sat_solver_setnvars(sat_solver* s,int n) s->tags = ABC_REALLOC(char, s->tags, s->cap); s->loads = ABC_REALLOC(char, s->loads, s->cap); #ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + s->activity = ABC_REALLOC(xFloat_t, s->activity, s->cap); +#else s->activity = ABC_REALLOC(double, s->activity, s->cap); +#endif #else s->activity = ABC_REALLOC(unsigned, s->activity, s->cap); s->activity2 = ABC_REALLOC(unsigned, s->activity2,s->cap); @@ -1198,7 +1265,11 @@ void sat_solver_setnvars(sat_solver* s,int n) if ( s->wlists[2*var+1].ptr == NULL ) veci_new(&s->wlists[2*var+1]); #ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + s->activity[var] = xSat_FloatCreateConst1(); +#else s->activity[var] = 0; +#endif #else s->activity[var] = (1<<10); #endif @@ -1292,10 +1363,17 @@ void sat_solver_restart( sat_solver* s ) s->qhead = 0; s->qtail = 0; #ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + s->var_inc = xSat_FloatCreateConst1(); + s->cla_inc = xSat_FloatCreateConst1(); + s->var_decay = xSat_FloatFromFloat( (float)(1 / 0.95) ); + s->cla_decay = xSat_FloatFromFloat( (float)(1 / 0.999) ); +#else s->var_inc = 1; s->cla_inc = 1; - s->var_decay = (float)(1 / 0.95 ); - s->cla_decay = (float)(1 / 0.999 ); + s->var_decay = (float)(1 / 0.95 ); + s->cla_decay = (float)(1 / 0.999); +#endif #else s->var_inc = (1 << 5); s->cla_inc = (1 << 11); @@ -1341,10 +1419,17 @@ void zsat_solver_restart_seed( sat_solver* s, double seed ) s->qhead = 0; s->qtail = 0; #ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + s->var_inc = xSat_FloatCreateConst1(); + s->cla_inc = xSat_FloatCreateConst1(); + s->var_decay = xSat_FloatFromFloat( (float)(1 / 0.95) ); + s->cla_decay = xSat_FloatFromFloat( (float)(1 / 0.999) ); +#else s->var_inc = 1; s->cla_inc = 1; - s->var_decay = (float)(1 / 0.95 ); - s->cla_decay = (float)(1 / 0.999 ); + s->var_decay = (float)(1 / 0.95 ); + s->cla_decay = (float)(1 / 0.999); +#endif #else s->var_inc = (1 << 5); s->cla_inc = (1 << 11); @@ -1382,7 +1467,11 @@ double sat_solver_memory( sat_solver* s ) Mem += s->cap * sizeof(char); // ABC_FREE(s->tags ); Mem += s->cap * sizeof(char); // ABC_FREE(s->loads ); #ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + Mem += s->cap * sizeof(xFloat_t); // ABC_FREE(s->activity ); +#else Mem += s->cap * sizeof(double); // ABC_FREE(s->activity ); +#endif #else Mem += s->cap * sizeof(unsigned); // ABC_FREE(s->activity ); if ( s->activity2 ) @@ -1600,10 +1689,17 @@ void sat_solver_rollback( sat_solver* s ) s->qhead = 0; s->qtail = 0; #ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + s->var_inc = xSat_FloatCreateConst1(); + s->cla_inc = xSat_FloatCreateConst1(); + s->var_decay = xSat_FloatFromFloat( (float)(1 / 0.95) ); + s->cla_decay = xSat_FloatFromFloat( (float)(1 / 0.999) ); +#else s->var_inc = 1; s->cla_inc = 1; - s->var_decay = (float)(1 / 0.95 ); - s->cla_decay = (float)(1 / 0.999 ); + s->var_decay = (float)(1 / 0.95 ); + s->cla_decay = (float)(1 / 0.999); +#endif #else s->var_inc = (1 << 5); s->cla_inc = (1 << 11); diff --git a/src/sat/bsat/satSolver.h b/src/sat/bsat/satSolver.h index 6ed611e15..226d8c7ad 100644 --- a/src/sat/bsat/satSolver.h +++ b/src/sat/bsat/satSolver.h @@ -30,10 +30,12 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include "satVec.h" #include "satClause.h" +#include "sat/xsat/xsatFloat.h" ABC_NAMESPACE_HEADER_START //#define USE_FLOAT_ACTIVITY +//#define USE_FLOAT_ACTIVITY_NEW //================================================================================================= // Public interface: @@ -117,11 +119,23 @@ struct sat_solver_t // activities #ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + xFloat_t var_inc; // Amount to bump next variable with. + xFloat_t var_inc2; // Amount to bump next variable with. + xFloat_t var_decay; // INVERSE decay factor for variable activity: stores 1/decay. + xFloat_t cla_inc; // Amount to bump next clause with. + xFloat_t cla_decay; // INVERSE decay factor for clause activity: stores 1/decay. + xFloat_t* activity; // A heuristic measurement of the activity of a variable. + xFloat_t* activity2; // backup variable activity +#else double var_inc; // Amount to bump next variable with. + double var_inc2; // Amount to bump next variable with. double var_decay; // INVERSE decay factor for variable activity: stores 1/decay. float cla_inc; // Amount to bump next clause with. float cla_decay; // INVERSE decay factor for clause activity: stores 1/decay. double* activity; // A heuristic measurement of the activity of a variable. + double* activity2; // A heuristic measurement of the activity of a variable. +#endif #else int var_inc; // Amount to bump next variable with. int var_inc2; // Amount to bump next variable with. @@ -218,9 +232,21 @@ static int sat_solver_var_literal( sat_solver* s, int v ) static void sat_solver_act_var_clear(sat_solver* s) { int i; +#ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + for (i = 0; i < s->size; i++) + s->activity[i] = xSat_FloatCreateConst1(); + s->var_inc = xSat_FloatCreateConst1(); +#else for (i = 0; i < s->size; i++) s->activity[i] = 0; s->var_inc = 1; +#endif +#else + for (i = 0; i < s->size; i++) + s->activity[i] = 0; + s->var_inc = (1 << 5); +#endif } static void sat_solver_compress(sat_solver* s) { @@ -286,8 +312,18 @@ static inline void sat_solver_bookmark(sat_solver* s) Sat_MemBookMark( &s->Mem ); if ( s->activity2 ) { +#ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + s->var_inc2 = s->var_inc; + memcpy( s->activity2, s->activity, sizeof(xFloat_t) * s->iVarPivot ); +#else + s->var_inc2 = s->var_inc; + memcpy( s->activity2, s->activity, sizeof(double) * s->iVarPivot ); +#endif +#else s->var_inc2 = s->var_inc; memcpy( s->activity2, s->activity, sizeof(unsigned) * s->iVarPivot ); +#endif } } static inline void sat_solver_set_pivot_variables( sat_solver* s, int * pPivots, int nPivots ) From 80f5070dbe270f7b1e90df07c5f52c46f0c0c969 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 7 Feb 2017 02:05:03 -0800 Subject: [PATCH 108/185] Re-introducing floating-point activity in the SAT solver. --- src/sat/bsat/satSolver.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/sat/bsat/satSolver.c b/src/sat/bsat/satSolver.c index 73d0cf360..1a2a393db 100644 --- a/src/sat/bsat/satSolver.c +++ b/src/sat/bsat/satSolver.c @@ -492,7 +492,7 @@ int sat_solver_clause_new(sat_solver* s, lit* begin, lit* end, int learnt) #ifdef USE_FLOAT_ACTIVITY_NEW veci_push(&s->act_clas, xSat_Float2Uint(xSat_FloatCreateConst1())); #else - veci_push(&s->act_clas, 0); + veci_push(&s->act_clas, s->cla_inc); #endif #else veci_push(&s->act_clas, (1<<10)); @@ -1532,8 +1532,16 @@ void sat_solver_reducedb(sat_solver* s) Sat_MemForEachLearned( pMem, c, i, k ) { Id = clause_id(c); - pSortValues[Id] = (((7 - Abc_MinInt(c->lbd, 7)) << 28) | (act_clas[Id] >> 4)); // pSortValues[Id] = act[Id]; +#ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + pSortValues[Id] = ((7 - Abc_MinInt(c->lbd, 7)) << 28) | (act_clas[Id] >> 4); +#else + pSortValues[Id] = ((7 - Abc_MinInt(c->lbd, 7)) << 28);// | (act_clas[Id] >> 4); +#endif +#else + pSortValues[Id] = ((7 - Abc_MinInt(c->lbd, 7)) << 28) | (act_clas[Id] >> 4); +#endif assert( pSortValues[Id] >= 0 ); } @@ -1639,7 +1647,15 @@ void sat_solver_rollback( sat_solver* s ) if ( s->activity2 ) { s->var_inc = s->var_inc2; +#ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + memcpy( s->activity, s->activity2, sizeof(xFloat_t) * s->iVarPivot ); +#else + memcpy( s->activity, s->activity2, sizeof(double) * s->iVarPivot ); +#endif +#else memcpy( s->activity, s->activity2, sizeof(unsigned) * s->iVarPivot ); +#endif } veci_resize(&s->order, 0); for ( i = 0; i < s->iVarPivot; i++ ) From de4bf41c53665ca8389d74b15be24ab407e8ff65 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 8 Feb 2017 14:10:08 -0800 Subject: [PATCH 109/185] New command &satoko. --- abclib.dsp | 4 ++ src/aig/gia/giaSatoko.c | 126 ++++++++++++++++++++++++++++++++++++++++ src/aig/gia/module.make | 1 + src/base/abci/abc.c | 73 ++++++++++++++++++++++- src/base/wlc/wlcShow.c | 4 +- 5 files changed, 204 insertions(+), 4 deletions(-) create mode 100644 src/aig/gia/giaSatoko.c diff --git a/abclib.dsp b/abclib.dsp index 12636df50..5f0bfc7aa 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -4639,6 +4639,10 @@ SOURCE=.\src\aig\gia\giaSatMap.c # End Source File # Begin Source File +SOURCE=.\src\aig\gia\giaSatoko.c +# End Source File +# Begin Source File + SOURCE=.\src\aig\gia\giaScl.c # End Source File # Begin Source File diff --git a/src/aig/gia/giaSatoko.c b/src/aig/gia/giaSatoko.c new file mode 100644 index 000000000..62bc7713a --- /dev/null +++ b/src/aig/gia/giaSatoko.c @@ -0,0 +1,126 @@ +/**CFile**************************************************************** + + FileName [giaSatoko.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Interface to Satoko solver.] + + Author [Alan Mishchenko, Bruno Schmitt] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaSatoko.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "sat/cnf/cnf.h" +#include "sat/satoko/satoko.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +satoko_t * Gia_ManCreateSatoko( Gia_Man_t * p ) +{ + satoko_t * pSat = satoko_create(); + Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 1, 0 ); + int i, status; + //sat_solver_setnvars( pSat, p->nVars ); + for ( i = 0; i < pCnf->nClauses; i++ ) + { + if ( !satoko_add_clause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1]-pCnf->pClauses[i] ) ) + { + Cnf_DataFree( pCnf ); + satoko_destroy( pSat ); + return NULL; + } + } + Cnf_DataFree( pCnf ); + status = satoko_simplify(pSat); + if ( status == SATOKO_OK ) + return pSat; + satoko_destroy( pSat ); + return NULL; +} +void Gia_ManCallSatokoOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput ) +{ + abctime clk = Abc_Clock(); + satoko_t * pSat; + int status; + + pSat = Gia_ManCreateSatoko( p ); + if ( pSat ) + { + satoko_configure(pSat, opts); + status = satoko_solve( pSat ); + satoko_destroy( pSat ); + } + else + status = SATOKO_UNSAT; + + if ( iOutput >= 0 ) + Abc_Print( 1, "Output %6d : ", iOutput ); + else + Abc_Print( 1, "Total: " ); + + if ( status == SATOKO_UNDEC ) + Abc_Print( 1, "UNDECIDED " ); + else if ( status == SATOKO_SAT ) + Abc_Print( 1, "SATISFIABLE " ); + else + Abc_Print( 1, "UNSATISFIABLE " ); + + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); +} +void Gia_ManCallSatoko( Gia_Man_t * p, satoko_opts_t * opts, int fSplit ) +{ + if ( fSplit ) + { + Gia_Man_t * pOne; + Gia_Obj_t * pRoot; + int i; + Gia_ManForEachCo( p, pRoot, i ) + { + pOne = Gia_ManDupDfsCone( p, pRoot ); + Gia_ManCallSatokoOne( pOne, opts, i ); + Gia_ManStop( pOne ); + } + return; + } + Gia_ManCallSatokoOne( p, opts, -1 ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index 0066bfd2a..0ddf98331 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -59,6 +59,7 @@ SRC += src/aig/gia/giaAig.c \ src/aig/gia/giaSatLE.c \ src/aig/gia/giaSatLut.c \ src/aig/gia/giaSatMap.c \ + src/aig/gia/giaSatoko.c \ src/aig/gia/giaScl.c \ src/aig/gia/giaScript.c \ src/aig/gia/giaShow.c \ diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 65974acb2..1ecc5e681 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -310,6 +310,7 @@ static int Abc_CommandSat ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandDSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandXSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandSatoko ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Satoko ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandIProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -959,6 +960,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Verification", "dsat", Abc_CommandDSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "xsat", Abc_CommandXSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "satoko", Abc_CommandSatoko, 0 ); + Cmd_CommandAdd( pAbc, "Verification", "&satoko", Abc_CommandAbc9Satoko, 0 ); Cmd_CommandAdd( pAbc, "Verification", "psat", Abc_CommandPSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "prove", Abc_CommandProve, 1 ); Cmd_CommandAdd( pAbc, "Verification", "iprove", Abc_CommandIProve, 1 ); @@ -23356,11 +23358,12 @@ int Abc_CommandSatoko( Abc_Frame_t * pAbc, int argc, char ** argv ) satoko_t * p; int status; - satoko_parse_dimacs( pFileName, &p ); + status = satoko_parse_dimacs( pFileName, &p ); satoko_configure(p, &opts); clk = Abc_Clock(); - status = satoko_solve( p ); + if ( status == SATOKO_OK ) + status = satoko_solve( p ); if ( status == SATOKO_UNDEC ) Abc_Print( 1, "UNDECIDED " ); @@ -23382,6 +23385,72 @@ usage: Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9Satoko( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Gia_ManCallSatoko( Gia_Man_t * p, satoko_opts_t * opts, int fSplit ); + int c, fSplit = 0; + + satoko_opts_t opts; + satoko_default_opts(&opts); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Csvh" ) ) != EOF ) + { + switch ( c ) + { + case 'C': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); + goto usage; + } + opts.conf_limit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.conf_limit < 0 ) + goto usage; + break; + case 's': + fSplit ^= 1; + break; + case 'v': + opts.verbose ^= 1; + break; + case 'h': + goto usage; + + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9Satoko(): There is no AIG.\n" ); + return 1; + } + Gia_ManCallSatoko( pAbc->pGia, &opts, fSplit ); + return 0; + +usage: + Abc_Print( -2, "usage: &satoko [-C num] [-svh]\n" ); + Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", opts.conf_limit ); + Abc_Print( -2, "\t-s : split multi-output miter into individual outputs [default = %s]\n", fSplit? "yes": "no" ); + Abc_Print( -2, "\t-v : prints verbose information [default = %s]\n", opts.verbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* Synopsis [] diff --git a/src/base/wlc/wlcShow.c b/src/base/wlc/wlcShow.c index 7914cd7a6..1601d6023 100644 --- a/src/base/wlc/wlcShow.c +++ b/src/base/wlc/wlcShow.c @@ -49,9 +49,9 @@ void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) Wlc_Obj_t * pNode; int LevelMax, Prev, Level, i; - if ( Wlc_NtkObjNum(p) > 1000 ) + if ( Wlc_NtkObjNum(p) > 2000 ) { - fprintf( stdout, "Cannot visualize WLC with more than %d nodes.\n", 1000 ); + fprintf( stdout, "Cannot visualize WLC with more than %d nodes.\n", 2000 ); return; } if ( (pFile = fopen( pFileName, "w" )) == NULL ) From cf24a0eb0c630e19bf1d81622fc05327371c63cf Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 8 Feb 2017 14:12:49 -0800 Subject: [PATCH 110/185] Compiler warning. --- src/aig/gia/giaSatoko.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aig/gia/giaSatoko.c b/src/aig/gia/giaSatoko.c index 62bc7713a..5506c7e47 100644 --- a/src/aig/gia/giaSatoko.c +++ b/src/aig/gia/giaSatoko.c @@ -54,7 +54,7 @@ satoko_t * Gia_ManCreateSatoko( Gia_Man_t * p ) //sat_solver_setnvars( pSat, p->nVars ); for ( i = 0; i < pCnf->nClauses; i++ ) { - if ( !satoko_add_clause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1]-pCnf->pClauses[i] ) ) + if ( !satoko_add_clause( pSat, (unsigned *)pCnf->pClauses[i], pCnf->pClauses[i+1]-pCnf->pClauses[i] ) ) { Cnf_DataFree( pCnf ); satoko_destroy( pSat ); From 77e2b1ff53bd806a681c9a887cd5b026681d271b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 8 Feb 2017 18:57:16 -0800 Subject: [PATCH 111/185] Autotuner for 'satoko'. --- abclib.dsp | 4 + src/aig/gia/giaSatoko.c | 8 +- src/base/abci/abc.c | 27 +- src/base/cmd/cmd.c | 114 +++++++ src/base/cmd/cmdAuto.c | 522 +++++++++++++++++++++++++++++++++ src/base/cmd/module.make | 1 + src/misc/extra/extraUtilUtil.c | 54 ++-- 7 files changed, 702 insertions(+), 28 deletions(-) create mode 100644 src/base/cmd/cmdAuto.c diff --git a/abclib.dsp b/abclib.dsp index 5f0bfc7aa..321a6d716 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -523,6 +523,10 @@ SOURCE=.\src\base\cmd\cmdApi.c # End Source File # Begin Source File +SOURCE=.\src\base\cmd\cmdAuto.c +# End Source File +# Begin Source File + SOURCE=.\src\base\cmd\cmdFlag.c # End Source File # Begin Source File diff --git a/src/aig/gia/giaSatoko.c b/src/aig/gia/giaSatoko.c index 5506c7e47..fc8e5c28b 100644 --- a/src/aig/gia/giaSatoko.c +++ b/src/aig/gia/giaSatoko.c @@ -21,6 +21,7 @@ #include "gia.h" #include "sat/cnf/cnf.h" #include "sat/satoko/satoko.h" +#include "sat/satoko/solver.h" ABC_NAMESPACE_IMPL_START @@ -68,17 +69,19 @@ satoko_t * Gia_ManCreateSatoko( Gia_Man_t * p ) satoko_destroy( pSat ); return NULL; } -void Gia_ManCallSatokoOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput ) +int Gia_ManCallSatokoOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput ) { abctime clk = Abc_Clock(); satoko_t * pSat; - int status; + int status, Cost = 0; + pSat = Gia_ManCreateSatoko( p ); if ( pSat ) { satoko_configure(pSat, opts); status = satoko_solve( pSat ); + Cost = (unsigned)pSat->stats.n_conflicts; satoko_destroy( pSat ); } else @@ -97,6 +100,7 @@ void Gia_ManCallSatokoOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput ) Abc_Print( 1, "UNSATISFIABLE " ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + return Cost; } void Gia_ManCallSatoko( Gia_Man_t * p, satoko_opts_t * opts, int fSplit ) { diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 1ecc5e681..38a555d8e 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -16782,7 +16782,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) If_ManSetDefaultPars( pPars ); pPars->pLutLib = (If_LibLut_t *)Abc_FrameReadLibLut(); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGRNTXYDEWSqaflepmrsdbgxyuojiktncvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "K:CFAGRNTXYDEWSqaflepmrsdbgxyuojiktncvh" ) ) != EOF ) { switch ( c ) { @@ -38135,9 +38135,9 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv ) { Gia_Man_t * pTemp; Vec_Int_t * vPos; - int c, iOutNum = -1, nOutRange = 1, iPartNum = -1, nLevelMax = 0, nTimeWindow = 0, fUseAllCis = 0, fVerbose = 0; + int c, iOutNum = -1, nOutRange = 1, iPartNum = -1, nLevelMax = 0, nTimeWindow = 0, fUseAllCis = 0, fExtractAll = 0, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "ORPLWavh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "ORPLWaevh" ) ) != EOF ) { switch ( c ) { @@ -38199,6 +38199,9 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'a': fUseAllCis ^= 1; break; + case 'e': + fExtractAll ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -38213,6 +38216,21 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandAbc9Cone(): There is no AIG.\n" ); return 1; } + if ( fExtractAll ) + { + char Buffer[1000]; + Gia_Obj_t * pObj; + int i, nDigits = Abc_Base10Log(Gia_ManPoNum(pAbc->pGia)); + Gia_ManForEachPo( pAbc->pGia, pObj, i ) + { + Gia_Man_t * pOne = Gia_ManDupDfsCone( pAbc->pGia, pObj ); + sprintf( Buffer, "%s_%0*d.aig", Extra_FileNameGeneric(pAbc->pGia->pSpec), nDigits, i ); + Gia_AigerWrite( pOne, Buffer, 0, 0 ); + Gia_ManStop( pOne ); + } + printf( "Dumped all outputs into individual AIGER files.\n" ); + return 0; + } if ( nLevelMax || nTimeWindow ) { if ( nLevelMax && nTimeWindow ) @@ -38260,7 +38278,7 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &cone [-ORPLW num] [-avh]\n" ); + Abc_Print( -2, "usage: &cone [-ORPLW num] [-aevh]\n" ); Abc_Print( -2, "\t extracting multi-output sequential logic cones\n" ); Abc_Print( -2, "\t-O num : the index of first PO to extract [default = %d]\n", iOutNum ); Abc_Print( -2, "\t-R num : (optional) the number of outputs to extract [default = %d]\n", nOutRange ); @@ -38268,6 +38286,7 @@ usage: Abc_Print( -2, "\t-L num : (optional) extract cones with higher level [default = %d]\n", nLevelMax ); Abc_Print( -2, "\t-W num : (optional) extract cones falling into this window [default = %d]\n", nTimeWindow ); Abc_Print( -2, "\t-a : toggle keeping all CIs or structral support only [default = %s]\n", fUseAllCis? "all": "structural" ); + Abc_Print( -2, "\t-e : toggle writing all outputs into individual files [default = %s]\n", fExtractAll? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c index ab037139a..ec4a0c860 100644 --- a/src/base/cmd/cmd.c +++ b/src/base/cmd/cmd.c @@ -60,6 +60,7 @@ static int CmdCommandSis ( Abc_Frame_t * pAbc, int argc, char ** argv static int CmdCommandMvsis ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int CmdCommandCapo ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int CmdCommandStarter ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int CmdCommandAutoTuner ( Abc_Frame_t * pAbc, int argc, char ** argv ); extern int Cmd_CommandAbcLoadPlugIn( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -110,6 +111,7 @@ void Cmd_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Various", "mvsis", CmdCommandMvsis, 1 ); Cmd_CommandAdd( pAbc, "Various", "capo", CmdCommandCapo, 0 ); Cmd_CommandAdd( pAbc, "Various", "starter", CmdCommandStarter, 0 ); + Cmd_CommandAdd( pAbc, "Various", "autotuner", CmdCommandAutoTuner, 0 ); Cmd_CommandAdd( pAbc, "Various", "load_plugin", Cmd_CommandAbcLoadPlugIn, 0 ); } @@ -2457,6 +2459,118 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int CmdCommandAutoTuner( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Cmd_RunAutoTuner( char * pConfig, char * pFileList, int nCores ); + FILE * pFile; + char * pFileConf = NULL; + char * pFileList = NULL; + char * pFileName; + int c, nCores = 3; + int fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "NCFvh" ) ) != EOF ) + { + switch ( c ) + { + case 'N': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" ); + goto usage; + } + nCores = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nCores < 0 ) + goto usage; + break; + case 'C': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-C\" should be followed by a string (possibly in quotes).\n" ); + goto usage; + } + pFileConf = argv[globalUtilOptind]; + globalUtilOptind++; + break; + case 'F': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-F\" should be followed by a string (possibly in quotes).\n" ); + goto usage; + } + pFileList = argv[globalUtilOptind]; + globalUtilOptind++; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pFileConf == NULL ) + { + Abc_Print( -2, "File containing configuration for autotuning is not given.\n" ); + return 1; + } + if ( pFileList == NULL ) + { + Abc_Print( -2, "File contining list of files for autotuning is not given.\n" ); + return 1; + } + // get the input file name + pFileName = pFileConf; + if ( (pFile = Io_FileOpen( pFileName, "open_path", "rb", 0 )) == NULL ) +// if ( (pFile = fopen( pFileName, "rb" )) == NULL ) + { + Abc_Print( -2, "Cannot open configuration file \"%s\". ", pFileName ); + if (( pFileName = Extra_FileGetSimilarName( pFileName, ".c", ".s", ".scr", ".script", NULL ) )) + Abc_Print( -2, "Did you mean \"%s\"?", pFileName ); + Abc_Print( -2, "\n" ); + return 1; + } + fclose( pFile ); + // get the input file name + pFileName = pFileList; + if ( (pFile = Io_FileOpen( pFileName, "open_path", "rb", 0 )) == NULL ) +// if ( (pFile = fopen( pFileName, "rb" )) == NULL ) + { + Abc_Print( -2, "Cannot open the file list \"%s\". ", pFileName ); + if (( pFileName = Extra_FileGetSimilarName( pFileName, ".c", ".s", ".scr", ".script", NULL ) )) + Abc_Print( -2, "Did you mean \"%s\"?", pFileName ); + Abc_Print( -2, "\n" ); + return 1; + } + fclose( pFile ); + // run commands + Cmd_RunAutoTuner( pFileConf, pFileList, nCores ); + return 0; + +usage: + Abc_Print( -2, "usage: autotuner [-N num] [-C file] [-F file] [-vh]\n" ); + Abc_Print( -2, "\t runs command lines listed in concurrently on CPUs\n" ); + Abc_Print( -2, "\t-N num : the number of concurrent jobs including the controler [default = %d]\n", nCores ); + Abc_Print( -2, "\t-C cmd : configuration file for autotuning\n" ); + Abc_Print( -2, "\t-F cmd : list of files to be used for autotuning\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function******************************************************************** Synopsis [Print the version string.] diff --git a/src/base/cmd/cmdAuto.c b/src/base/cmd/cmdAuto.c new file mode 100644 index 000000000..28b209fad --- /dev/null +++ b/src/base/cmd/cmdAuto.c @@ -0,0 +1,522 @@ +/**CFile**************************************************************** + + FileName [cmdAuto.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Command processing package.] + + Synopsis [Autotuner.] + + Author [Alan Mishchenko, Bruno Schmitt] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cmdAuto.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include +#include +#include +#include +#include "misc/util/abc_global.h" +#include "misc/extra/extra.h" +#include "aig/gia/gia.h" +#include "sat/satoko/satoko.h" + +#ifdef ABC_USE_PTHREADS + +#ifdef _WIN32 +#include "../lib/pthread.h" +#else +#include +#include +#endif + +#endif + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define CMD_AUTO_LINE_MAX 1000 // max number of chars in the string +#define CMD_AUTO_ARG_MAX 100 // max number of arguments in the call + +extern int Gia_ManCallSatokoOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Printing option structure.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cmd_RunAutoTunerPrintOptions( satoko_opts_t * pOpts ) +{ + printf( "-C %d ", pOpts->conf_limit ); + printf( "-V %.3f ", pOpts->var_decay ); + printf( "-W %.3f ", pOpts->clause_decay ); + if ( pOpts->verbose ) + printf( "-v", pOpts->verbose ); + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [The main evaluation procedure for an array of AIGs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cmd_RunAutoTunerEvalSimple( Vec_Ptr_t * vAigs, satoko_opts_t * pOpts ) +{ + Gia_Man_t * pGia; + int i, TotalCost = 0; + //printf( "Tuning with options: " ); + //Cmd_RunAutoTunerPrintOptions( pOpts ); + Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, i ) + TotalCost += Gia_ManCallSatokoOne( pGia, pOpts, -1 ); + return TotalCost; +} + +/**Function************************************************************* + + Synopsis [The main evaluation procedure for the set of AIGs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +#ifndef ABC_USE_PTHREADS + +int Cmd_RunAutoTunerEval( Vec_Ptr_t * vAigs, satoko_opts_t * pOpts, int nCores ) +{ + return Cmd_RunAutoTunerEvalSimple( vAigs, pOpts ); +} + +#else // pthreads are used + + +#define CMD_THR_MAX 100 +typedef struct Cmd_AutoData_t_ +{ + Gia_Man_t * pGia; + satoko_opts_t * pOpts; + int iThread; + int nTimeOut; + int fWorking; + int Result; +} Cmd_AutoData_t; + +void * Cmd_RunAutoTunerEvalWorkerThread( void * pArg ) +{ + Cmd_AutoData_t * pThData = (Cmd_AutoData_t *)pArg; + volatile int * pPlace = &pThData->fWorking; + while ( 1 ) + { + while ( *pPlace == 0 ); + assert( pThData->fWorking ); + if ( pThData->pGia == NULL ) // kills itself when there is nothing to do + { + pthread_exit( NULL ); + assert( 0 ); + return NULL; + } + pThData->Result = Gia_ManCallSatokoOne( pThData->pGia, pThData->pOpts, -1 ); + pThData->fWorking = 0; + } + assert( 0 ); + return NULL; +} +int Cmd_RunAutoTunerEval( Vec_Ptr_t * vAigs, satoko_opts_t * pOpts, int nProcs ) +{ + abctime clkTotal = Abc_Clock(); + Cmd_AutoData_t ThData[CMD_THR_MAX]; + pthread_t WorkerThread[CMD_THR_MAX]; + int i, status, fWorkToDo = 1, TotalCost = 0; + Vec_Ptr_t * vStack; + if ( nProcs == 1 ) + return Cmd_RunAutoTunerEvalSimple( vAigs, pOpts ); + // subtract manager thread + nProcs--; + assert( nProcs >= 1 && nProcs <= CMD_THR_MAX ); + // start threads + for ( i = 0; i < nProcs; i++ ) + { + ThData[i].pGia = NULL; + ThData[i].pOpts = pOpts; + ThData[i].iThread = i; + ThData[i].nTimeOut = -1; + ThData[i].fWorking = 0; + ThData[i].Result = -1; + status = pthread_create( WorkerThread + i, NULL,Cmd_RunAutoTunerEvalWorkerThread, (void *)(ThData + i) ); assert( status == 0 ); + } + // look at the threads + vStack = Vec_PtrDup(vAigs); + while ( fWorkToDo ) + { + fWorkToDo = (int)(Vec_PtrSize(vStack) > 0); + for ( i = 0; i < nProcs; i++ ) + { + // check if this thread is working + if ( ThData[i].fWorking ) + { + fWorkToDo = 1; + continue; + } + // check if this thread has recently finished + if ( ThData[i].pGia != NULL ) + { + assert( ThData[i].Result >= 0 ); + TotalCost += ThData[i].Result; + ThData[i].pGia = NULL; + } + if ( Vec_PtrSize(vStack) == 0 ) + continue; + // give this thread a new job + assert( ThData[i].pGia == NULL ); + ThData[i].pGia = (Gia_Man_t *)Vec_PtrPop( vStack ); + ThData[i].fWorking = 1; + } + } + Vec_PtrFree( vStack ); + // stop threads + for ( i = 0; i < nProcs; i++ ) + { + assert( !ThData[i].fWorking ); + // stop + ThData[i].pGia = NULL; + ThData[i].fWorking = 1; + } + return TotalCost; +} + +#endif // pthreads are used + + +/**Function************************************************************* + + Synopsis [Derives all possible param stucts according to the config file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Cmd_DeriveConvertIntoString( int argc, char ** argv ) +{ + char pBuffer[CMD_AUTO_LINE_MAX] = {0}; + int i; + for ( i = 0; i < argc; i++ ) + { + strcat( pBuffer, argv[i] ); + strcat( pBuffer, " " ); + } + return Abc_UtilStrsav(pBuffer); +} +satoko_opts_t * Cmd_DeriveOptionFromSettings( int argc, char ** argv ) +{ + int c; + satoko_opts_t opts, * pOpts; + satoko_default_opts(&opts); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "CVWhv" ) ) != EOF ) + { + switch ( c ) + { + case 'C': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); + return NULL; + } + opts.conf_limit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.conf_limit < 0 ) + return NULL; + break; + case 'V': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-V\" should be followed by an integer.\n" ); + return NULL; + } + opts.var_decay = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.var_decay < 0 ) + return NULL; + break; + case 'W': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-W\" should be followed by an integer.\n" ); + return NULL; + } + opts.clause_decay = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.clause_decay < 0 ) + return NULL; + break; + case 'v': + opts.verbose ^= 1; + break; + default: + return NULL; + } + } + // return a copy of this parameter structure + pOpts = ABC_ALLOC( satoko_opts_t, 1 ); + memcpy( pOpts, &opts, sizeof(satoko_opts_t) ); + return pOpts; +} +void Cmf_CreateOptions_rec( Vec_Wec_t * vPars, int iPar, char Argv[CMD_AUTO_ARG_MAX][20], int Argc, Vec_Ptr_t * vOpts ) +{ + Vec_Int_t * vLine; + int Symb, Num, i; + assert( Argc <= CMD_AUTO_ARG_MAX ); + if ( Vec_WecSize(vPars) == iPar ) + { + satoko_opts_t * pOpts; + char * pArgv[CMD_AUTO_ARG_MAX]; + for ( i = 0; i < Argc; i++ ) + pArgv[i] = Argv[i]; + pOpts = Cmd_DeriveOptionFromSettings( Argc, pArgv ); + if ( pOpts == NULL ) + printf( "Cannot parse command line options...\n" ); + else + { + Vec_PtrPush( vOpts, pOpts ); + Vec_PtrPush( vOpts, Cmd_DeriveConvertIntoString(Argc, pArgv) ); + printf( "Adding settings %s\n", (char *)Vec_PtrEntryLast(vOpts) ); + } + return; + } + vLine = Vec_WecEntry( vPars, iPar ); + // consider binary option + if ( Vec_IntSize(vLine) == 2 ) + { + Symb = Vec_IntEntry( vLine, 0 ); + Num = Vec_IntEntry( vLine, 1 ); + assert( Abc_Int2Float(Num) == -1.0 ); + // create one setting without this option + Cmf_CreateOptions_rec( vPars, iPar+1, Argv, Argc, vOpts ); + // create another setting with this option + sprintf( Argv[Argc], "-%c", Symb ); + Cmf_CreateOptions_rec( vPars, iPar+1, Argv, Argc+1, vOpts ); + return; + } + // consider numeric option + Vec_IntForEachEntryDouble( vLine, Symb, Num, i ) + { + float NumF = Abc_Int2Float(Num); + // create setting with this option + assert( NumF >= 0 ); + sprintf( Argv[Argc], "-%c", Symb ); + if ( NumF == (float)(int)NumF ) + sprintf( Argv[Argc+1], "%d", (int)NumF ); + else + sprintf( Argv[Argc+1], "%.3f", NumF ); + Cmf_CreateOptions_rec( vPars, iPar+1, Argv, Argc+2, vOpts ); + } +} +Vec_Ptr_t * Cmf_CreateOptions( Vec_Wec_t * vPars ) +{ + char Argv[CMD_AUTO_ARG_MAX][20]; + int Symb, Num, i, Argc = 0; + Vec_Ptr_t * vOpts = Vec_PtrAlloc( 100 ); + Vec_Int_t * vLine = Vec_WecEntry( vPars, 0 ); + printf( "Creating all possible settings to be used by the autotuner:\n" ); + sprintf( Argv[Argc++], "autotuner" ); + Vec_IntForEachEntryDouble( vLine, Symb, Num, i ) + { + float NumF = Abc_Int2Float(Num); + sprintf( Argv[Argc++], "-%c", Symb ); + if ( NumF < 0.0 ) + continue; + if ( NumF == (float)(int)NumF ) + sprintf( Argv[Argc++], "%d", (int)NumF ); + else + sprintf( Argv[Argc++], "%.3f", NumF ); + } + Cmf_CreateOptions_rec( vPars, 1, Argv, Argc, vOpts ); + printf( "Finished creating %d settings.\n\n", Vec_PtrSize(vOpts)/2 ); + return vOpts; +} + + +/**Function************************************************************* + + Synopsis [Parses config file and derives AIGs listed in file list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Cmf_IsSpace( char p ) { return p == ' ' || p == '\t' || p == '\n' || p == '\r'; } +static inline Cmf_IsLowerCaseChar( char p ) { return p >= 'a' && p <= 'z'; } +static inline Cmf_IsUpperCaseChar( char p ) { return p >= 'A' && p <= 'Z'; } +static inline Cmf_IsDigit( char p ) { return (p >= '0' && p <= '9') || p == '.'; } + +Vec_Wec_t * Cmd_ReadParamChoices( char * pConfig ) +{ + Vec_Wec_t * vPars; + Vec_Int_t * vLine; + char * pThis, pBuffer[CMD_AUTO_LINE_MAX]; + FILE * pFile = fopen( pConfig, "rb" ); + if ( pFile == NULL ) + { printf( "File containing list of files \"%s\" cannot be opened.\n", pConfig ); return NULL; } + vPars = Vec_WecAlloc( 100 ); + while ( fgets( pBuffer, CMD_AUTO_LINE_MAX, pFile ) != NULL ) + { + // get the command from the file + if ( Cmf_IsSpace(pBuffer[0]) || pBuffer[0] == '#') + continue; + // skip trailing spaces + while ( Cmf_IsSpace(pBuffer[strlen(pBuffer)-1]) ) + pBuffer[strlen(pBuffer)-1] = 0; + // read the line + vLine = Vec_WecPushLevel( vPars ); + for ( pThis = pBuffer; *pThis; ) + { + if ( Cmf_IsLowerCaseChar(*pThis) ) + { + Vec_IntPushTwo( vLine, (int)*pThis, Abc_Float2Int((float)-1.0) ); + pThis++; + while ( Cmf_IsSpace(*pThis) ) + pThis++; + continue; + } + if ( Cmf_IsUpperCaseChar(*pThis) ) + { + char Param = *pThis++; + if ( !Cmf_IsDigit(*pThis) ) + { printf( "Upper-case character (%c) should be followed by a number without space in line \"%s\".\n", Param, pBuffer ); return NULL; } + Vec_IntPushTwo( vLine, (int)Param, Abc_Float2Int(atof(pThis)) ); + while ( Cmf_IsDigit(*pThis) ) + pThis++; + while ( Cmf_IsSpace(*pThis) ) + pThis++; + continue; + } + printf( "Expecting a leading lower-case or upper-case digit in line \"%s\".\n", pBuffer ); + return NULL; + } + } + fclose( pFile ); + return vPars; +} +Vec_Ptr_t * Cmd_ReadFiles( char * pFileList ) +{ + Gia_Man_t * pGia; + Vec_Ptr_t * vAigs; + char pBuffer[CMD_AUTO_LINE_MAX]; + FILE * pFile = fopen( pFileList, "rb" ); + if ( pFile == NULL ) + { printf( "File containing list of files \"%s\" cannot be opened.\n", pFileList ); return NULL; } + vAigs = Vec_PtrAlloc( 100 ); + while ( fgets( pBuffer, CMD_AUTO_LINE_MAX, pFile ) != NULL ) + { + // get the command from the file + if ( Cmf_IsSpace(pBuffer[0]) || pBuffer[0] == '#') + continue; + // skip trailing spaces + while ( Cmf_IsSpace(pBuffer[strlen(pBuffer)-1]) ) + pBuffer[strlen(pBuffer)-1] = 0; + // read the file + pGia = Gia_AigerRead( pBuffer, 0, 0, 0 ); + if ( pGia == NULL ) + { + printf( "Cannot read AIG from file \"%s\".\n", pBuffer ); + continue; + } + Vec_PtrPush( vAigs, pGia ); + } + fclose( pFile ); + return vAigs; +} + +/**Function************************************************************* + + Synopsis [Autotuner for SAT solver "satoko".] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cmd_RunAutoTuner( char * pConfig, char * pFileList, int nCores ) +{ + abctime clk = Abc_Clock(); + Vec_Wec_t * vPars = Cmd_ReadParamChoices( pConfig ); + Vec_Ptr_t * vAigs = Cmd_ReadFiles( pFileList ); + Vec_Ptr_t * vOpts = vPars ? Cmf_CreateOptions( vPars ) : NULL; + int i; char * pString, * pStringBest = NULL; + satoko_opts_t * pOpts, * pOptsBest = NULL; + int Result, ResultBest = 0x7FFFFFFF; + Gia_Man_t * pGia; + // iterate through all possible option settings + if ( vAigs && vOpts ) + { + Vec_PtrForEachEntryDouble( satoko_opts_t *, char *, vOpts, pOpts, pString, i ) + { + abctime clk = Abc_Clock(); + printf( "Evaluating options %20s... ", pString ); + Result = Cmd_RunAutoTunerEval( vAigs, pOpts, nCores ); + printf( "Cost = %6d. ", Result ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + if ( ResultBest > Result ) + { + ResultBest = Result; + pStringBest = pString; + pOptsBest = pOpts; + } + } + printf( "The best options are: %20s ", pStringBest ); + printf( "Best cost = %6d. ", ResultBest ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + } + // cleanup + if ( vPars ) Vec_WecFree( vPars ); + if ( vOpts ) Vec_PtrFreeFree( vOpts ); + if ( vAigs ) + { + Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, i ) + Gia_ManStop( pGia ); + Vec_PtrFree( vAigs ); + } +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/cmd/module.make b/src/base/cmd/module.make index b09ffa819..1042fbb0c 100644 --- a/src/base/cmd/module.make +++ b/src/base/cmd/module.make @@ -1,6 +1,7 @@ SRC += src/base/cmd/cmd.c \ src/base/cmd/cmdAlias.c \ src/base/cmd/cmdApi.c \ + src/base/cmd/cmdAuto.c \ src/base/cmd/cmdFlag.c \ src/base/cmd/cmdHist.c \ src/base/cmd/cmdLoad.c \ diff --git a/src/misc/extra/extraUtilUtil.c b/src/misc/extra/extraUtilUtil.c index 253d9e3ce..2f0f4559b 100644 --- a/src/misc/extra/extraUtilUtil.c +++ b/src/misc/extra/extraUtilUtil.c @@ -102,35 +102,45 @@ int Extra_UtilGetopt( int argc, char *argv[], const char *optstring ) globalUtilOptarg = NULL; - if (pScanStr == NULL || *pScanStr == '\0') { - if (globalUtilOptind == 0) globalUtilOptind++; - if (globalUtilOptind >= argc) return EOF; - place = argv[globalUtilOptind]; - if (place[0] != '-' || place[1] == '\0') return EOF; - globalUtilOptind++; - if (place[1] == '-' && place[2] == '\0') return EOF; - pScanStr = place+1; + if (pScanStr == NULL || *pScanStr == '\0') + { + if (globalUtilOptind == 0) + globalUtilOptind++; + if (globalUtilOptind >= argc) + return EOF; + place = argv[globalUtilOptind]; + if (place[0] != '-' || place[1] == '\0') + return EOF; + globalUtilOptind++; + if (place[1] == '-' && place[2] == '\0') + return EOF; + pScanStr = place+1; } c = *pScanStr++; place = strchr(optstring, c); if (place == NULL || c == ':') { - (void) fprintf(stderr, "%s: unknown option %c\n", argv[0], c); - return '?'; - } - if (*++place == ':') { - if (*pScanStr != '\0') { - globalUtilOptarg = pScanStr; - pScanStr = NULL; - } else { - if (globalUtilOptind >= argc) { - (void) fprintf(stderr, "%s: %c requires an argument\n", - argv[0], c); + (void) fprintf(stderr, "%s: unknown option %c\n", argv[0], c); return '?'; - } - globalUtilOptarg = argv[globalUtilOptind]; - globalUtilOptind++; } + if (*++place == ':') + { + if (*pScanStr != '\0') + { + globalUtilOptarg = pScanStr; + pScanStr = NULL; + } + else + { + if (globalUtilOptind >= argc) + { + (void) fprintf(stderr, "%s: %c requires an argument\n", + argv[0], c); + return '?'; + } + globalUtilOptarg = argv[globalUtilOptind]; + globalUtilOptind++; + } } return c; } From 1e62fb4a92b49639b8ee554a8fb6aafde428daf8 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 8 Feb 2017 18:59:07 -0800 Subject: [PATCH 112/185] Compiler warning. --- src/base/cmd/cmdAuto.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/base/cmd/cmdAuto.c b/src/base/cmd/cmdAuto.c index 28b209fad..e029f6d2d 100644 --- a/src/base/cmd/cmdAuto.c +++ b/src/base/cmd/cmdAuto.c @@ -66,11 +66,11 @@ extern int Gia_ManCallSatokoOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutpu ***********************************************************************/ void Cmd_RunAutoTunerPrintOptions( satoko_opts_t * pOpts ) { - printf( "-C %d ", pOpts->conf_limit ); + printf( "-C %d ", (int)pOpts->conf_limit ); printf( "-V %.3f ", pOpts->var_decay ); printf( "-W %.3f ", pOpts->clause_decay ); if ( pOpts->verbose ) - printf( "-v", pOpts->verbose ); + printf( "-v" ); printf( "\n" ); } @@ -150,7 +150,6 @@ void * Cmd_RunAutoTunerEvalWorkerThread( void * pArg ) } int Cmd_RunAutoTunerEval( Vec_Ptr_t * vAigs, satoko_opts_t * pOpts, int nProcs ) { - abctime clkTotal = Abc_Clock(); Cmd_AutoData_t ThData[CMD_THR_MAX]; pthread_t WorkerThread[CMD_THR_MAX]; int i, status, fWorkToDo = 1, TotalCost = 0; @@ -377,10 +376,10 @@ Vec_Ptr_t * Cmf_CreateOptions( Vec_Wec_t * vPars ) SeeAlso [] ***********************************************************************/ -static inline Cmf_IsSpace( char p ) { return p == ' ' || p == '\t' || p == '\n' || p == '\r'; } -static inline Cmf_IsLowerCaseChar( char p ) { return p >= 'a' && p <= 'z'; } -static inline Cmf_IsUpperCaseChar( char p ) { return p >= 'A' && p <= 'Z'; } -static inline Cmf_IsDigit( char p ) { return (p >= '0' && p <= '9') || p == '.'; } +static inline int Cmf_IsSpace( char p ) { return p == ' ' || p == '\t' || p == '\n' || p == '\r'; } +static inline int Cmf_IsLowerCaseChar( char p ) { return p >= 'a' && p <= 'z'; } +static inline int Cmf_IsUpperCaseChar( char p ) { return p >= 'A' && p <= 'Z'; } +static inline int Cmf_IsDigit( char p ) { return (p >= '0' && p <= '9') || p == '.'; } Vec_Wec_t * Cmd_ReadParamChoices( char * pConfig ) { From 778ea6bb8ac56a716f457932fbc1a211692f238c Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 8 Feb 2017 19:07:21 -0800 Subject: [PATCH 113/185] Editing output messages. --- src/base/cmd/cmdAuto.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/base/cmd/cmdAuto.c b/src/base/cmd/cmdAuto.c index e029f6d2d..7d0cc8afc 100644 --- a/src/base/cmd/cmdAuto.c +++ b/src/base/cmd/cmdAuto.c @@ -486,7 +486,7 @@ void Cmd_RunAutoTuner( char * pConfig, char * pFileList, int nCores ) Vec_PtrForEachEntryDouble( satoko_opts_t *, char *, vOpts, pOpts, pString, i ) { abctime clk = Abc_Clock(); - printf( "Evaluating options %20s... ", pString ); + printf( "Evaluating settings: %20s... \n", pString ); Result = Cmd_RunAutoTunerEval( vAigs, pOpts, nCores ); printf( "Cost = %6d. ", Result ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); @@ -497,9 +497,9 @@ void Cmd_RunAutoTuner( char * pConfig, char * pFileList, int nCores ) pOptsBest = pOpts; } } - printf( "The best options are: %20s ", pStringBest ); + printf( "The best settings are: %20s \n", pStringBest ); printf( "Best cost = %6d. ", ResultBest ); - Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + Abc_PrintTime( 1, "Total time", Abc_Clock() - clk ); } // cleanup if ( vPars ) Vec_WecFree( vPars ); From 2a9902eec7287735db933a8d55f7f7458aa9d939 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 8 Feb 2017 19:10:15 -0800 Subject: [PATCH 114/185] Accidental change. --- src/base/abci/abc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 38a555d8e..26e9c0f8e 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -16782,7 +16782,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) If_ManSetDefaultPars( pPars ); pPars->pLutLib = (If_LibLut_t *)Abc_FrameReadLibLut(); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "K:CFAGRNTXYDEWSqaflepmrsdbgxyuojiktncvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGRNTXYDEWSqaflepmrsdbgxyuojiktncvh" ) ) != EOF ) { switch ( c ) { From 040b88a7c6bc437f6f9dc792510d5d905b516eb5 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 8 Feb 2017 19:12:57 -0800 Subject: [PATCH 115/185] Editing output messages. --- src/base/cmd/cmd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c index ec4a0c860..853f57109 100644 --- a/src/base/cmd/cmd.c +++ b/src/base/cmd/cmd.c @@ -2562,10 +2562,10 @@ int CmdCommandAutoTuner( Abc_Frame_t * pAbc, int argc, char ** argv ) usage: Abc_Print( -2, "usage: autotuner [-N num] [-C file] [-F file] [-vh]\n" ); - Abc_Print( -2, "\t runs command lines listed in concurrently on CPUs\n" ); + Abc_Print( -2, "\t performs autotuning\n" ); Abc_Print( -2, "\t-N num : the number of concurrent jobs including the controler [default = %d]\n", nCores ); - Abc_Print( -2, "\t-C cmd : configuration file for autotuning\n" ); - Abc_Print( -2, "\t-F cmd : list of files to be used for autotuning\n" ); + Abc_Print( -2, "\t-C cmd : configuration file with settings for autotuning\n" ); + Abc_Print( -2, "\t-F cmd : list of AIGER files to be used for autotuning\n" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; From 871899dceac294f2b76c055a42d87176224028f2 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Thu, 9 Feb 2017 05:17:50 -0800 Subject: [PATCH 116/185] =?UTF-8?q?-=20Adding=20a=20compile=20time=20optio?= =?UTF-8?q?n=20to=20use=20floats=20for=20var=20activity=20(now=20it=20can?= =?UTF-8?q?=20be=20either=20=E2=80=98double=E2=80=99,=20=E2=80=98float?= =?UTF-8?q?=E2=80=99=20or=20=E2=80=98unsigned=E2=80=99=20(default))=20-=20?= =?UTF-8?q?Adding=20vector=20of=20=E2=80=98float=E2=80=99=20-=20Adding=20a?= =?UTF-8?q?n=20option=20to=20configure=20the=20ratio=20of=20learnt=20claus?= =?UTF-8?q?es=20to=20be=20kept=20in=20clause=20database=20at=20each=20redu?= =?UTF-8?q?ction=20(0=20means=20no=20reduction).=20-=20Other=20small=20cha?= =?UTF-8?q?nges.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sat/satoko/act_clause.h | 5 +- src/sat/satoko/act_var.h | 29 ++-- src/sat/satoko/satoko.h | 4 +- src/sat/satoko/solver.c | 15 +- src/sat/satoko/solver_api.c | 7 +- src/sat/satoko/types.h | 22 ++- src/sat/satoko/utils/misc.h | 6 +- src/sat/satoko/utils/vec/vec_flt.h | 246 +++++++++++++++++++++++++++++ 8 files changed, 300 insertions(+), 34 deletions(-) create mode 100644 src/sat/satoko/utils/vec/vec_flt.h diff --git a/src/sat/satoko/act_clause.h b/src/sat/satoko/act_clause.h index 2e80a1e67..1465e5ee0 100644 --- a/src/sat/satoko/act_clause.h +++ b/src/sat/satoko/act_clause.h @@ -56,10 +56,9 @@ static inline void clause_act_rescale(solver_t *s) vec_uint_foreach(s->learnts, cref, i) { clause = clause_read(s, cref); - clause->data[clause->size].act >>= 14; + clause->data[clause->size].act >>= 10; } - s->clause_act_inc >>= 14; - s->clause_act_inc = mkt_uint_max(s->clause_act_inc, (1 << 10)); + s->clause_act_inc = stk_uint_max((s->clause_act_inc >> 10), (1 << 11)); } static inline void clause_act_bump(solver_t *s, struct clause *clause) diff --git a/src/sat/satoko/act_var.h b/src/sat/satoko/act_var.h index 161e9d9a4..aa8a76abe 100644 --- a/src/sat/satoko/act_var.h +++ b/src/sat/satoko/act_var.h @@ -16,27 +16,27 @@ #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START -#ifdef SATOKO_ACT_VAR_DBLE +#if defined SATOKO_ACT_VAR_DBLE || defined SATOKO_ACT_VAR_FLOAT /** Re-scale the activity value for all variables. */ static inline void var_act_rescale(solver_t *s) { unsigned i; - double *activity = vec_dble_data(s->activity); + act_t *activity = vec_act_data(s->activity); - for (i = 0; i < vec_dble_size(s->activity); i++) - activity[i] *= 1e-100; - s->var_act_inc *= 1e-100; + for (i = 0; i < vec_act_size(s->activity); i++) + activity[i] *= VAR_ACT_RESCALE; + s->var_act_inc *= VAR_ACT_RESCALE; } /** Increment the activity value of one variable ('var') */ static inline void var_act_bump(solver_t *s, unsigned var) { - double *activity = vec_dble_data(s->activity); + act_t *activity = vec_act_data(s->activity); activity[var] += s->var_act_inc; - if (activity[var] > 1e100) + if (activity[var] > VAR_ACT_LIMIT) var_act_rescale(s); if (heap_in_heap(s->var_order, var)) heap_decrease(s->var_order, var); @@ -49,25 +49,24 @@ static inline void var_act_decay(solver_t *s) s->var_act_inc *= (1 / s->opts.var_decay); } -#else /* SATOKO_ACT_VAR_DBLE */ +#else static inline void var_act_rescale(solver_t *s) { unsigned i; - unsigned *activity = vec_uint_data(s->activity); + act_t *activity = vec_act_data(s->activity); - for (i = 0; i < vec_uint_size(s->activity); i++) + for (i = 0; i < vec_act_size(s->activity); i++) activity[i] >>= 19; - s->var_act_inc >>= 19; - s->var_act_inc = mkt_uint_max(s->var_act_inc, (1 << 5)); + s->var_act_inc = stk_uint_max((s->var_act_inc >> 19), (1 << 5)); } static inline void var_act_bump(solver_t *s, unsigned var) { - unsigned *activity = vec_uint_data(s->activity); + act_t *activity = vec_act_data(s->activity); activity[var] += s->var_act_inc; - if (activity[var] & 0x80000000) + if (activity[var] & 0xF0000000) var_act_rescale(s); if (heap_in_heap(s->var_order, var)) heap_decrease(s->var_order, var); @@ -78,7 +77,7 @@ static inline void var_act_decay(solver_t *s) s->var_act_inc += (s->var_act_inc >> 4); } -#endif /* SATOKO_ACT_VAR_DBLE */ +#endif /* SATOKO_ACT_VAR_DBLE || SATOKO_ACT_VAR_FLOAT */ ABC_NAMESPACE_HEADER_END #endif /* satoko__act_var_h */ diff --git a/src/sat/satoko/satoko.h b/src/sat/satoko/satoko.h index 55790714a..fb07c6f9f 100644 --- a/src/sat/satoko/satoko.h +++ b/src/sat/satoko/satoko.h @@ -9,6 +9,7 @@ #ifndef satoko__satoko_h #define satoko__satoko_h +#include "types.h" #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START @@ -45,10 +46,11 @@ struct satoko_opts { unsigned inc_reduce; /* Increment to reduce */ unsigned inc_special_reduce; /* Special increment to reduce */ unsigned lbd_freeze_clause; + float learnt_ratio; /* Percentage of learned clauses to remove */ /* VSIDS heuristic */ float clause_decay; - double var_decay; + act_t var_decay; /* Binary resolution */ unsigned clause_max_sz_bin_resol; diff --git a/src/sat/satoko/solver.c b/src/sat/satoko/solver.c index a4114e543..cdd3141e5 100644 --- a/src/sat/satoko/solver.c +++ b/src/sat/satoko/solver.c @@ -45,7 +45,7 @@ static inline int lit_is_removable(solver_t* s, unsigned lit, unsigned min_level assert(var_reason(s, var) != UNDEF); if (c->size == 2 && lit_value(s, lits[0]) == LIT_FALSE) { assert(lit_value(s, lits[1]) == LIT_TRUE); - mkt_swap(unsigned, lits[0], lits[1]); + stk_swap(unsigned, lits[0], lits[1]); } /* Check scan the literals of the reason clause. @@ -126,7 +126,7 @@ static inline void clause_bin_resolution(solver_t *s, vec_uint_t *clause_lits) sz = vec_uint_size(clause_lits) - 1; for (i = 1; i < vec_uint_size(clause_lits) - counter; i++) if (vec_uint_at(s->stamps, lit2var(lits[i])) != s->cur_stamp) { - mkt_swap(unsigned, lits[i], lits[sz]); + stk_swap(unsigned, lits[i], lits[sz]); i--; sz--; } @@ -268,7 +268,7 @@ static inline void solver_analyze(solver_t *s, unsigned cref, vec_uint_t *learnt if (p != UNDEF && clause->size == 2 && lit_value(s, lits[0]) == LIT_FALSE) { assert(lit_value(s, lits[1]) == LIT_TRUE); - mkt_swap(unsigned, lits[0], lits[1] ); + stk_swap(unsigned, lits[0], lits[1] ); } if (clause->f_learnt) @@ -310,7 +310,7 @@ static inline void solver_analyze(solver_t *s, unsigned cref, vec_uint_t *learnt *bt_level = solver_calc_bt_level(s, learnt); *lbd = clause_clac_lbd(s, vec_uint_data(learnt), vec_uint_size(learnt)); - if (vec_uint_size( s->last_dlevel) > 0) { + if (vec_uint_size(s->last_dlevel) > 0) { vec_uint_foreach(s->last_dlevel, var, i) { if (clause_read(s, var_reason(s, var))->lbd < *lbd) var_act_bump(s, var); @@ -428,7 +428,7 @@ static inline void solver_reduce_cdb(solver_t *s) vec_uint_foreach(s->learnts, cref, i) learnts_cls[i] = clause_read(s, cref); - limit = n_learnts / 2; + limit = (unsigned)(n_learnts * s->opts.learnt_ratio); satoko_sort((void *)learnts_cls, n_learnts, (int (*)(const void *, const void *)) clause_compare); @@ -562,7 +562,7 @@ unsigned solver_propagate(solver_t *s) // Make sure the false literal is data[1]: neg_lit = lit_neg(p); if (lits[0] == neg_lit) - mkt_swap(unsigned, lits[0], lits[1]); + stk_swap(unsigned, lits[0], lits[1]); assert(lits[1] == neg_lit); w.cref = i->cref; @@ -635,7 +635,8 @@ char solver_search(solver_t *s) satoko_simplify(s); /* Reduce the set of learnt clauses */ - if (s->stats.n_conflicts >= s->n_confl_bfr_reduce) { + if (s->opts.learnt_ratio && + s->stats.n_conflicts >= s->n_confl_bfr_reduce) { s->RC1 = (s->stats.n_conflicts / s->RC2) + 1; solver_reduce_cdb(s); s->RC2 += s->opts.inc_reduce; diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c index e041cc62e..980cc160d 100644 --- a/src/sat/satoko/solver_api.c +++ b/src/sat/satoko/solver_api.c @@ -165,6 +165,7 @@ void satoko_default_opts(satoko_opts_t *opts) opts->inc_reduce = 300; opts->inc_special_reduce = 1000; opts->lbd_freeze_clause = 30; + opts->learnt_ratio = 0.5; /* VSIDS heuristic */ opts->var_decay = (act_t) 0.95; opts->clause_decay = (clause_act_t) 0.995; @@ -187,7 +188,7 @@ void satoko_configure(satoko_t *s, satoko_opts_t *user_opts) int satoko_simplify(solver_t * s) { unsigned i, j = 0; - unsigned cref; + unsigned cref; assert(solver_dlevel(s) == 0); if (solver_propagate(s) != UNDEF) @@ -198,7 +199,7 @@ int satoko_simplify(solver_t * s) vec_uint_foreach(s->originals, cref, i) { struct clause *clause = clause_read(s, cref); - if (clause_is_satisfied(s, clause)) { + if (clause_is_satisfied(s, clause)) { clause->f_mark = 1; s->stats.n_original_lits -= clause->size; clause_unwatch(s, cref); @@ -236,7 +237,7 @@ int satoko_add_clause(solver_t *s, unsigned *lits, unsigned size) unsigned max_var; unsigned cref; - qsort((void *) lits, size, sizeof(unsigned), mkt_uint_compare); + qsort((void *) lits, size, sizeof(unsigned), stk_uint_compare); max_var = lit2var(lits[size - 1]); while (max_var >= vec_act_size(s->activity)) satoko_add_variable(s, LIT_FALSE); diff --git a/src/sat/satoko/types.h b/src/sat/satoko/types.h index 2811c2c65..ee9363bc3 100644 --- a/src/sat/satoko/types.h +++ b/src/sat/satoko/types.h @@ -10,23 +10,40 @@ #define satoko__types_h #include "utils/vec/vec_dble.h" +#include "utils/vec/vec_flt.h" #include "utils/vec/vec_uint.h" #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START -#define SATOKO_ACT_VAR_DBLE -#define SATOKO_ACT_CLAUSE_FLOAT +// #define SATOKO_ACT_VAR_DBLE +// #define SATOKO_ACT_VAR_FLOAT +// #define SATOKO_ACT_CLAUSE_FLOAT #ifdef SATOKO_ACT_VAR_DBLE #define VAR_ACT_INIT_INC 1.0 + #define VAR_ACT_LIMIT (double)1e100 + #define VAR_ACT_RESCALE (double)1e-100 typedef double act_t; typedef vec_dble_t vec_act_t ; #define vec_act_alloc(size) vec_dble_alloc(size) #define vec_act_free(vec) vec_dble_free(vec) #define vec_act_size(vec) vec_dble_size(vec) + #define vec_act_data(vec) vec_dble_data(vec) #define vec_act_at(vec, idx) vec_dble_at(vec, idx) #define vec_act_push_back(vec, value) vec_dble_push_back(vec, value) +#elif defined(SATOKO_ACT_VAR_FLOAT) + #define VAR_ACT_INIT_INC 1.0 + #define VAR_ACT_LIMIT (float)1e20 + #define VAR_ACT_RESCALE (float)1e-20 + typedef float act_t; + typedef vec_flt_t vec_act_t ; + #define vec_act_alloc(size) vec_flt_alloc(size) + #define vec_act_free(vec) vec_flt_free(vec) + #define vec_act_size(vec) vec_flt_size(vec) + #define vec_act_data(vec) vec_flt_data(vec) + #define vec_act_at(vec, idx) vec_flt_at(vec, idx) + #define vec_act_push_back(vec, value) vec_flt_push_back(vec, value) #else #define VAR_ACT_INIT_INC (1 << 5) typedef unsigned act_t; @@ -34,6 +51,7 @@ ABC_NAMESPACE_HEADER_START #define vec_act_alloc(size) vec_uint_alloc(size) #define vec_act_free(vec) vec_uint_free(vec) #define vec_act_size(vec) vec_uint_size(vec) + #define vec_act_data(vec) vec_uint_data(vec) #define vec_act_at(vec, idx) vec_uint_at(vec, idx) #define vec_act_push_back(vec, value) vec_uint_push_back(vec, value) #endif /* SATOKO_ACT_VAR_DBLE */ diff --git a/src/sat/satoko/utils/misc.h b/src/sat/satoko/utils/misc.h index 481e23b71..7205a0969 100755 --- a/src/sat/satoko/utils/misc.h +++ b/src/sat/satoko/utils/misc.h @@ -12,14 +12,14 @@ #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START -#define mkt_swap(type, a, b) { type t = a; a = b; b = t; } +#define stk_swap(type, a, b) { type t = a; a = b; b = t; } -static inline unsigned mkt_uint_max(unsigned a, unsigned b) +static inline unsigned stk_uint_max(unsigned a, unsigned b) { return a > b ? a : b; } -static inline int mkt_uint_compare(const void *p1, const void *p2) +static inline int stk_uint_compare(const void *p1, const void *p2) { const unsigned pp1 = *(const unsigned *)p1; const unsigned pp2 = *(const unsigned *)p2; diff --git a/src/sat/satoko/utils/vec/vec_flt.h b/src/sat/satoko/utils/vec/vec_flt.h new file mode 100644 index 000000000..d7c896d99 --- /dev/null +++ b/src/sat/satoko/utils/vec/vec_flt.h @@ -0,0 +1,246 @@ +//===--- vec_int.h ----------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__utils__vec__vec_flt_h +#define satoko__utils__vec__vec_flt_h + +#include +#include +#include + +#include "../mem.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +typedef struct vec_flt_t_ vec_flt_t; +struct vec_flt_t_ { + unsigned cap; + unsigned size; + float *data; +}; + +//===------------------------------------------------------------------------=== +// Vector Macros +//===------------------------------------------------------------------------=== +#define vec_flt_foreach(vec, entry, i) \ + for (i = 0; (i < vec->size) && (((entry) = vec_flt_at(vec, i)), 1); i++) + +#define vec_flt_foreach_start(vec, entry, i, start) \ + for (i = start; (i < vec_flt_size(vec)) && (((entry) = vec_flt_at(vec, i)), 1); i++) + +#define vec_flt_foreach_stop(vec, entry, i, stop) \ + for (i = 0; (i < stop) && (((entry) = vec_flt_at(vec, i)), 1); i++) + +//===------------------------------------------------------------------------=== +// Vector API +//===------------------------------------------------------------------------=== +static inline vec_flt_t *vec_flt_alloc(unsigned cap) +{ + vec_flt_t* p = satoko_alloc(vec_flt_t, 1); + + if (cap > 0 && cap < 16) + cap = 16; + p->size = 0; + p->cap = cap; + p->data = p->cap ? satoko_alloc(float, p->cap) : NULL; + return p; +} + +static inline vec_flt_t *vec_flt_alloc_exact(unsigned cap) +{ + vec_flt_t* p = satoko_alloc(vec_flt_t, 1); + + p->size = 0; + p->cap = cap; + p->data = p->cap ? satoko_alloc(float, p->cap) : NULL; + return p; +} + +static inline vec_flt_t *vec_flt_init(unsigned size, float value) +{ + vec_flt_t* p = satoko_alloc(vec_flt_t, 1); + + p->cap = size; + p->size = size; + p->data = p->cap ? satoko_alloc(float, p->cap) : NULL; + memset(p->data, value, sizeof(float) * p->size); + return p; +} + +static inline void vec_flt_free(vec_flt_t *p) +{ + if (p->data != NULL) + satoko_free(p->data); + satoko_free(p); +} + +static inline unsigned vec_flt_size(vec_flt_t *p) +{ + return p->size; +} + +static inline void vec_flt_resize(vec_flt_t *p, unsigned new_size) +{ + p->size = new_size; + if (p->cap >= new_size) + return; + p->data = satoko_realloc(float, p->data, new_size); + assert(p->data != NULL); + p->cap = new_size; +} + +static inline void vec_flt_reserve(vec_flt_t *p, unsigned new_cap) +{ + if (p->cap >= new_cap) + return; + p->data = satoko_realloc(float, p->data, new_cap); + assert(p->data != NULL); + p->cap = new_cap; +} + +static inline unsigned vec_flt_capacity(vec_flt_t *p) +{ + return p->cap; +} + +static inline int vec_flt_empty(vec_flt_t *p) +{ + return p->size ? 0 : 1; +} + +static inline void vec_flt_erase(vec_flt_t *p) +{ + satoko_free(p->data); + p->size = 0; + p->cap = 0; +} + +static inline float vec_flt_at(vec_flt_t *p, unsigned i) +{ + assert(i >= 0 && i < p->size); + return p->data[i]; +} + +static inline float *vec_flt_at_ptr(vec_flt_t *p, unsigned i) +{ + assert(i >= 0 && i < p->size); + return p->data + i; +} + +static inline float *vec_flt_data(vec_flt_t *p) +{ + assert(p); + return p->data; +} + +static inline void vec_flt_duplicate(vec_flt_t *dest, const vec_flt_t *src) +{ + assert(dest != NULL && src != NULL); + vec_flt_resize(dest, src->cap); + memcpy(dest->data, src->data, sizeof(float) * src->cap); + dest->size = src->size; +} + +static inline void vec_flt_copy(vec_flt_t *dest, const vec_flt_t *src) +{ + assert(dest != NULL && src != NULL); + vec_flt_resize(dest, src->size); + memcpy(dest->data, src->data, sizeof(float) * src->size); + dest->size = src->size; +} + +static inline void vec_flt_push_back(vec_flt_t *p, float value) +{ + if (p->size == p->cap) { + if (p->cap < 16) + vec_flt_reserve(p, 16); + else + vec_flt_reserve(p, 2 * p->cap); + } + p->data[p->size] = value; + p->size++; +} + +static inline void vec_flt_assign(vec_flt_t *p, unsigned i, float value) +{ + assert((i >= 0) && (i < vec_flt_size(p))); + p->data[i] = value; +} + +static inline void vec_flt_insert(vec_flt_t *p, unsigned i, float value) +{ + assert((i >= 0) && (i < vec_flt_size(p))); + vec_flt_push_back(p, 0); + memmove(p->data + i + 1, p->data + i, (p->size - i - 2) * sizeof(float)); + p->data[i] = value; +} + +static inline void vec_flt_drop(vec_flt_t *p, unsigned i) +{ + assert((i >= 0) && (i < vec_flt_size(p))); + memmove(p->data + i, p->data + i + 1, (p->size - i - 1) * sizeof(float)); + p->size -= 1; +} + +static inline void vec_flt_clear(vec_flt_t *p) +{ + p->size = 0; +} + +static inline int vec_flt_asc_compare(const void *p1, const void *p2) +{ + const float *pp1 = (const float *) p1; + const float *pp2 = (const float *) p2; + + if (*pp1 < *pp2) + return -1; + if (*pp1 > *pp2) + return 1; + return 0; +} + +static inline int vec_flt_desc_compare(const void* p1, const void* p2) +{ + const float *pp1 = (const float *) p1; + const float *pp2 = (const float *) p2; + + if (*pp1 > *pp2) + return -1; + if (*pp1 < *pp2) + return 1; + return 0; +} + +static inline void vec_flt_sort(vec_flt_t* p, int ascending) +{ + if (ascending) + qsort((void *) p->data, p->size, sizeof(float), + (int (*)(const void*, const void*)) vec_flt_asc_compare); + else + qsort((void *) p->data, p->size, sizeof(float), + (int (*)(const void*, const void*)) vec_flt_desc_compare); +} + +static inline long vec_flt_memory(vec_flt_t *p) +{ + return p == NULL ? 0 : sizeof(float) * p->cap + sizeof(vec_flt_t); +} + +static inline void vec_flt_print(vec_flt_t *p) +{ + unsigned i; + assert(p != NULL); + fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap); + for (i = 0; i < p->size; i++) + fprintf(stdout, " %f", p->data[i]); + fprintf(stdout, " }\n"); +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__utils__vec__vec_flt_h */ From e20ef654d99d5cf1f0f73466b931d53833f6a1eb Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 9 Feb 2017 13:31:07 -0800 Subject: [PATCH 117/185] Word-level abstraction. --- abclib.dsp | 8 ++ src/base/wlc/module.make | 1 + src/base/wlc/wlc.h | 15 ++- src/base/wlc/wlcAbs.c | 4 +- src/base/wlc/wlcAbs2.c | 186 ++++++++++++++++++++++++++++++++++++++ src/base/wlc/wlcCom.c | 99 +++++++++++++++++++- src/base/wlc/wlcNtk.c | 86 ++++++++++++++++-- src/base/wlc/wlcReadVer.c | 2 +- 8 files changed, 387 insertions(+), 14 deletions(-) create mode 100644 src/base/wlc/wlcAbs2.c diff --git a/abclib.dsp b/abclib.dsp index 321a6d716..f2fcf619b 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -779,6 +779,10 @@ SOURCE=.\src\base\wlc\wlcAbs.c # End Source File # Begin Source File +SOURCE=.\src\base\wlc\wlcAbs2.c +# End Source File +# Begin Source File + SOURCE=.\src\base\wlc\wlcBlast.c # End Source File # Begin Source File @@ -2071,6 +2075,10 @@ SOURCE=.\src\sat\satoko\utils\vec\vec_dble.h # End Source File # Begin Source File +SOURCE=.\src\sat\satoko\utils\vec\vec_flt.h +# End Source File +# Begin Source File + SOURCE=.\src\sat\satoko\utils\vec\vec_int.h # End Source File # Begin Source File diff --git a/src/base/wlc/module.make b/src/base/wlc/module.make index ae7899ec9..3485bd4d1 100644 --- a/src/base/wlc/module.make +++ b/src/base/wlc/module.make @@ -1,4 +1,5 @@ SRC += src/base/wlc/wlcAbs.c \ + src/base/wlc/wlcAbs2.c \ src/base/wlc/wlcAbc.c \ src/base/wlc/wlcBlast.c \ src/base/wlc/wlcCom.c \ diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index d51b699c0..0a17cfe60 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -160,6 +160,16 @@ struct Wlc_Ntk_t_ Vec_Int_t vLevels; // object levels }; +typedef struct Wlc_Par_t_ Wlc_Par_t; +struct Wlc_Par_t_ +{ + int nBitsAdd; // adder bit-width + int nBitsMul; // multiplier bit-widht + int nBitsMux; // MUX bit-width + int nBitsFlop; // flop bit-width + int fVerbose; // verbose output` +}; + static inline int Wlc_NtkObjNum( Wlc_Ntk_t * p ) { return p->iObj - 1; } static inline int Wlc_NtkObjNumMax( Wlc_Ntk_t * p ) { return p->iObj; } static inline int Wlc_NtkPiNum( Wlc_Ntk_t * p ) { return Vec_IntSize(&p->vPis); } @@ -267,6 +277,9 @@ extern Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p ); extern Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p ); extern Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * pNtk, Vec_Int_t * vNodes ); extern Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * pNtk, Vec_Int_t * vPairs ); +/*=== wlcAbs2.c ========================================================*/ +extern void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ); +extern Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcBlast.c ========================================================*/ extern Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, int nRange, int fGiaSimple, int fAddOutputs, int fBooth ); /*=== wlcCom.c ========================================================*/ @@ -291,7 +304,7 @@ extern void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type ); extern void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fTwoSides, int fVerbose ); extern void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ); extern char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq ); -extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ); +extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq, Vec_Int_t * vPisNew ); extern void Wlc_NtkCleanMarks( Wlc_Ntk_t * p ); extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int Range, int fSeq, int fAllPis ); extern void Wlc_NtkProfileCones( Wlc_Ntk_t * p ); diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index ce6b8de91..8662e5093 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -173,7 +173,7 @@ Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit ) if ( vNodes != vNodesInit ) Vec_IntFree( vNodes ); // reconstruct topological order - pNew = Wlc_NtkDupDfs( p, 0, 1 ); + pNew = Wlc_NtkDupDfs( p, 0, 1, NULL ); return pNew; } @@ -277,7 +277,7 @@ Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * p, Vec_Int_t * vPairsInit ) if ( vPairs != vPairsInit ) Vec_IntFree( vPairs ); // reconstruct topological order - pNew = Wlc_NtkDupDfs( p, 0, 1 ); + pNew = Wlc_NtkDupDfs( p, 0, 1, NULL ); return pNew; } diff --git a/src/base/wlc/wlcAbs2.c b/src/base/wlc/wlcAbs2.c new file mode 100644 index 000000000..9da59f423 --- /dev/null +++ b/src/base/wlc/wlcAbs2.c @@ -0,0 +1,186 @@ +/**CFile**************************************************************** + + FileName [wlcAbs2.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Verilog parser.] + + Synopsis [Abstraction for word-level networks.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - August 22, 2014.] + + Revision [$Id: wlcAbs2.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wlc.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Wabs_Par_t_ Wabs_Par_t; +struct Wabs_Par_t_ +{ + Wlc_Ntk_t * pNtk; + Wlc_Par_t * pPars; + Vec_Bit_t * vLeaves; +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ) +{ + memset( pPars, 0, sizeof(Wlc_Par_t) ); + pPars->nBitsAdd = 16; // adder bit-width + pPars->nBitsMul = 8; // multiplier bit-widht + pPars->nBitsMux = 32; // MUX bit-width + pPars->nBitsFlop = 32; // flop bit-width + pPars->fVerbose = 0; // verbose output` +} + +/**Function************************************************************* + + Synopsis [Mark operators that meet the criteria.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) +{ + Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) ); + Wlc_Obj_t * pObj; int i; + Wlc_NtkForEachObj( p, pObj, i ) + { + if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || pObj->Type == WLC_OBJ_ARI_MINUS ) + { + if ( Wlc_ObjRange(pObj) >= pPars->nBitsAdd ) + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ); + continue; + } + if ( pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_DIVIDE || pObj->Type == WLC_OBJ_ARI_REM || pObj->Type == WLC_OBJ_ARI_MODULUS ) + { + if ( Wlc_ObjRange(pObj) >= pPars->nBitsMul ) + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ); + continue; + } + if ( pObj->Type == WLC_OBJ_MUX ) + { + if ( Wlc_ObjRange(pObj) >= pPars->nBitsMux ) + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ); + continue; + } + if ( Wlc_ObjIsCi(pObj) && !Wlc_ObjIsPi(pObj) ) + { + if ( Wlc_ObjRange(pObj) >= pPars->nBitsFlop ) + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ); + continue; + } + } + return vLeaves; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vFlops, Vec_Int_t * vPisNew ) +{ + int i, iFanin; + if ( pObj->Mark ) + return; + pObj->Mark = 1; + if ( Vec_BitEntry(vLeaves, Wlc_ObjId(p, pObj)) ) + { + Vec_IntPush( vPisNew, Wlc_ObjId(p, pObj) ); + return; + } + if ( Wlc_ObjIsCi(pObj) ) + { + if ( !Wlc_ObjIsPi(pObj) ) + Vec_IntPush( vFlops, Wlc_ObjCiId(pObj) ); + return; + } + Wlc_ObjForEachFanin( pObj, iFanin, i ) + Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkObj(p, iFanin), vLeaves, vFlops, vPisNew ); +} + +Vec_Int_t * Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves ) +{ + Vec_Int_t * vFlops; + Vec_Int_t * vPisNew; + Wlc_Obj_t * pObj; + int i, CiId, CoId; + Wlc_NtkCleanMarks( p ); + vFlops = Vec_IntAlloc( 100 ); + vPisNew = Vec_IntAlloc( 100 ); + Wlc_NtkForEachCo( p, pObj, i ) + Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vFlops, vPisNew ); + Vec_IntForEachEntry( vFlops, CiId, i ) + { + CoId = Wlc_NtkPoNum(p) + CiId - Wlc_NtkPiNum(p); + Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkCo(p, CoId), vLeaves, vFlops, vPisNew ); + } + Vec_IntFree( vFlops ); + return vPisNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) +{ + Vec_Bit_t * vLeaves = Wlc_NtkAbsMarkOpers( p, pPars ); + Vec_Int_t * vPisNew = Wlc_NtkAbsMarkNodes( p, vLeaves ); + Wlc_Ntk_t * pNtkNew = Wlc_NtkDupDfs( p, 1, 1, vPisNew ); + Vec_IntFree( vPisNew ); + Vec_BitFree( vLeaves ); + return pNtkNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 82321d3b4..3bbe843fd 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -32,6 +32,7 @@ static int Abc_CommandReadWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ) static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandShortNames ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -72,6 +73,7 @@ void Wlc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Word level", "%write", Abc_CommandWriteWlc, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%cone", Abc_CommandCone, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%abs", Abc_CommandAbs, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%short_names", Abc_CommandShortNames, 0 ); @@ -421,7 +423,7 @@ int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) printf( "Extracting output %d as a %s word-level network.\n", iOutput, fSeq ? "sequential" : "combinational" ); pName = Wlc_NtkNewName( pNtk, iOutput, fSeq ); Wlc_NtkMarkCone( pNtk, iOutput, Range, fSeq, fAllPis ); - pNtk = Wlc_NtkDupDfs( pNtk, 1, fSeq ); + pNtk = Wlc_NtkDupDfs( pNtk, 1, fSeq, NULL ); ABC_FREE( pNtk->pName ); pNtk->pName = Abc_UtilStrsav( pName ); Wlc_AbcUpdateNtk( pAbc, pNtk ); @@ -438,6 +440,101 @@ usage: return 1; } +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + Wlc_Par_t Pars, * pPars = &Pars; + int c; + Wlc_ManSetDefaultParams( pPars ); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFvh" ) ) != EOF ) + { + switch ( c ) + { + case 'A': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-A\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsAdd = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsAdd < 0 ) + goto usage; + break; + case 'M': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsMul = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsMul < 0 ) + goto usage; + break; + case 'X': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsMux = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsMux < 0 ) + goto usage; + break; + case 'F': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsFlop = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsFlop < 0 ) + goto usage; + break; + case 'v': + pPars->fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" ); + return 0; + } + pNtk = Wlc_NtkAbs( pNtk, pPars ); + Wlc_AbcUpdateNtk( pAbc, pNtk ); + return 0; +usage: + Abc_Print( -2, "usage: %%abs [-AMXF num] [-vh]\n" ); + Abc_Print( -2, "\t abstraction for word-level networks\n" ); + Abc_Print( -2, "\t-A num : minimum bit-width of an adder/subtractor to abstract [default = %d]\n", pPars->nBitsAdd ); + Abc_Print( -2, "\t-M num : minimum bit-width of a multiplier to abstract [default = %d]\n", pPars->nBitsMul ); + Abc_Print( -2, "\t-X num : minimum bit-width of a MUX operator to abstract [default = %d]\n", pPars->nBitsMux ); + Abc_Print( -2, "\t-F num : minimum bit-width of a flip-flop to abstract [default = %d]\n", pPars->nBitsFlop ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function******************************************************************** Synopsis [] diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index bd00a570f..6eab44427 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -705,6 +705,45 @@ char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq ) return pBuffer; } +/**Function************************************************************* + + Synopsis [Reduce init vector.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Wlc_ReduceMarkedInitVec( Wlc_Ntk_t * p, Vec_Int_t * vInit ) +{ + Vec_Int_t * vInitNew = Vec_IntDup( vInit ); + Wlc_Obj_t * pObj; int i, k = 0; + assert( Vec_IntSize(vInit) == Wlc_NtkCiNum(p) - Wlc_NtkPiNum(p) ); + Wlc_NtkForEachCi( p, pObj, i ) + if ( !Wlc_ObjIsPi(pObj) && pObj->Mark ) + Vec_IntWriteEntry( vInitNew, k++, Vec_IntEntry(vInit, i) ); + Vec_IntShrink( vInitNew, k ); + return vInitNew; +} +char * Wlc_ReduceMarkedInitStr( Wlc_Ntk_t * p, char * pInit ) +{ + char * pInitNew = Abc_UtilStrsav( pInit ); + Wlc_Obj_t * pObj; int i, b, nBits = 0, k = 0; + Wlc_NtkForEachCi( p, pObj, i ) + { + if ( !Wlc_ObjIsPi(pObj) && pObj->Mark ) + for ( b = 0; b < Wlc_ObjRange(pObj); b++ ) + pInitNew[k++] = pInitNew[nBits+b]; + if ( !Wlc_ObjIsPi(pObj) ) + nBits += Wlc_ObjRange(pObj); + } + pInitNew[k] = '\0'; + assert( nBits == (int)strlen(pInit) ); + return pInitNew; +} + /**Function************************************************************* Synopsis [Duplicates the network in a topological order.] @@ -764,7 +803,7 @@ void Wlc_NtkDupDfs_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * v Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins ); Wlc_ObjDup( pNew, p, iObj, vFanins ); } -Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ) +Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq, Vec_Int_t * vPisNew ) { Wlc_Ntk_t * pNew; Wlc_Obj_t * pObj; @@ -774,14 +813,33 @@ Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ) Wlc_NtkCleanCopy( p ); pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc ); pNew->fSmtLib = p->fSmtLib; - Wlc_NtkForEachCi( p, pObj, i ) - if ( !fMarked || pObj->Mark ) + if ( vPisNew ) + { + // duplicate marked PIs + Wlc_NtkForEachPi( p, pObj, i ) + if ( pObj->Mark ) + Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + // duplicated additional PIs + Wlc_NtkForEachObjVec( vPisNew, p, pObj, i ) { unsigned Type = pObj->Type; - if ( !fSeq ) pObj->Type = WLC_OBJ_PI; + assert( !Wlc_ObjIsPi(pObj) ); + pObj->Type = WLC_OBJ_PI; Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); pObj->Type = Type; } + } + else + { + Wlc_NtkForEachCi( p, pObj, i ) + if ( !fMarked || pObj->Mark ) + { + unsigned Type = pObj->Type; + if ( !fSeq ) pObj->Type = WLC_OBJ_PI; + Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + pObj->Type = Type; + } + } Wlc_NtkForEachCo( p, pObj, i ) if ( !fMarked || pObj->Mark ) Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins ); @@ -789,12 +847,22 @@ Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ) if ( !fMarked || pObj->Mark ) Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), fSeq ? pObj->fIsFi : 0 ); Vec_IntFree( vFanins ); - if ( !fMarked ) + if ( fSeq ) { - if ( p->vInits ) - pNew->vInits = Vec_IntDup( p->vInits ); - if ( p->pInits ) - pNew->pInits = Abc_UtilStrsav( p->pInits ); + if ( fMarked ) + { + if ( p->vInits ) + pNew->vInits = Wlc_ReduceMarkedInitVec( p, p->vInits ); + if ( p->pInits ) + pNew->pInits = Wlc_ReduceMarkedInitStr( p, p->pInits ); + } + else + { + if ( p->vInits ) + pNew->vInits = Vec_IntDup( p->vInits ); + if ( p->pInits ) + pNew->pInits = Abc_UtilStrsav( p->pInits ); + } } if ( p->pSpec ) pNew->pSpec = Abc_UtilStrsav( p->pSpec ); diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c index e4a65ecfb..f7546b5b6 100644 --- a/src/base/wlc/wlcReadVer.c +++ b/src/base/wlc/wlcReadVer.c @@ -1265,7 +1265,7 @@ Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr ) if ( !Wlc_PrsDerive( p ) ) goto finish; // derive topological order - pNtk = Wlc_NtkDupDfs( p->pNtk, 0, 1 ); + pNtk = Wlc_NtkDupDfs( p->pNtk, 0, 1, NULL ); pNtk->pSpec = Abc_UtilStrsav( pFileName ); finish: Wlc_PrsPrintErrorMessage( p ); From 32712ec9abb3f27e3bd00690838b054f5bdc0f77 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 9 Feb 2017 14:17:19 -0800 Subject: [PATCH 118/185] Making sure 'inv_out' can match flops by name. --- src/base/wlc/wlcAbc.c | 54 ++++++++++++++++++++++++++++++++--------- src/base/wlc/wlcBlast.c | 11 +++++---- src/base/wlc/wlcCom.c | 4 +-- src/proof/pdr/pdrInv.c | 2 ++ 4 files changed, 53 insertions(+), 18 deletions(-) diff --git a/src/base/wlc/wlcAbc.c b/src/base/wlc/wlcAbc.c index 1f10d7b05..e19aaaecb 100644 --- a/src/base/wlc/wlcAbc.c +++ b/src/base/wlc/wlcAbc.c @@ -185,8 +185,9 @@ Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv ) SeeAlso [] ***********************************************************************/ -Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, int nRegs ) +Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, Gia_Man_t * pGia ) { + int nRegs = Gia_ManRegNum(pGia); Vec_Int_t * vRes = NULL; if ( Abc_NtkPoNum(pNtk) != 1 ) printf( "The number of outputs is other than 1.\n" ); @@ -194,26 +195,57 @@ Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, int nRegs ) printf( "The number of internal nodes is other than 1.\n" ); else { - Abc_Obj_t * pNode = Abc_ObjFanin0( Abc_NtkCo(pNtk, 0) ); + Abc_Nam_t * pNames = NULL; + Abc_Obj_t * pFanin, * pNode = Abc_ObjFanin0( Abc_NtkCo(pNtk, 0) ); char * pName, * pCube, * pSop = (char *)pNode->pData; Vec_Int_t * vFanins = Vec_IntAlloc( Abc_ObjFaninNum(pNode) ); - Abc_Obj_t * pFanin; int i, k, Value, nLits; + int i, k, Value, nLits, Counter = 0; + if ( pGia->vNamesIn ) + { + // hash the names + pNames = Abc_NamStart( 100, 16 ); + Vec_PtrForEachEntry( char *, pGia->vNamesIn, pName, i ) + { + Value = Abc_NamStrFindOrAdd( pNames, pName, NULL ); + assert( Value == i+1 ); + //printf( "%s(%d) ", pName, i ); + } + //printf( "\n" ); + } Abc_ObjForEachFanin( pNode, pFanin, i ) { assert( Abc_ObjIsCi(pFanin) ); pName = Abc_ObjName(pFanin); - for ( k = (int)strlen(pName)-1; k >= 0; k-- ) - if ( pName[k] < '0' || pName[k] > '9' ) - break; - if ( k == (int)strlen(pName)-1 ) + if ( pNames ) { - printf( "Cannot read input name of fanin %d.\n", i ); - Value = i; + Value = Abc_NamStrFind(pNames, pName) - 1; + if ( Value == -1 ) + { + if ( Counter++ == 0 ) + printf( "Cannot read input name \"%s\" of fanin %d.\n", pName, i ); + Value = i; + } + } + else + { + for ( k = (int)strlen(pName)-1; k >= 0; k-- ) + if ( pName[k] < '0' || pName[k] > '9' ) + break; + if ( k == (int)strlen(pName)-1 ) + { + if ( Counter++ == 0 ) + printf( "Cannot read input name \"%s\" of fanin %d.\n", pName, i ); + Value = i; + } + else + Value = atoi(pName + k + 1); } - else - Value = atoi(pName + k + 1); Vec_IntPush( vFanins, Value ); } + if ( Counter ) + printf( "Cannot read names for %d inputs of the invariant.\n", Counter ); + if ( pNames ) + Abc_NamStop( pNames ); assert( Vec_IntSize(vFanins) == Abc_ObjFaninNum(pNode) ); vRes = Vec_IntAlloc( 1000 ); Vec_IntPush( vRes, Abc_SopGetCubeNum(pSop) ); diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index b49c2dd7b..67d7c9025 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -872,6 +872,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in { int fVerbose = 0; int fUseOldMultiplierBlasting = 0; + int fSkipBitRange = 0; Tim_Man_t * pManTime = NULL; Gia_Man_t * pTemp, * pNew, * pExtra = NULL; Wlc_Obj_t * pObj; @@ -1448,7 +1449,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in { char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj)); nRange = Wlc_ObjRange( pObj ); - if ( nRange == 1 ) + if ( fSkipBitRange && nRange == 1 ) Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(pName) ); else for ( k = 0; k < nRange; k++ ) @@ -1475,7 +1476,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in { char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj)); nRange = Wlc_ObjRange( pObj ); - if ( nRange == 1 ) + if ( fSkipBitRange && nRange == 1 ) Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(pName) ); else for ( k = 0; k < nRange; k++ ) @@ -1498,7 +1499,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in { char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj)); nRange = Wlc_ObjRange( pObj ); - if ( nRange == 1 ) + if ( fSkipBitRange && nRange == 1 ) Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) ); else for ( k = 0; k < nRange; k++ ) @@ -1513,7 +1514,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in { char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj)); nRange = Wlc_ObjRange( pObj ); - if ( nRange == 1 ) + if ( fSkipBitRange && nRange == 1 ) Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) ); else for ( k = 0; k < nRange; k++ ) @@ -1532,7 +1533,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in { char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj)); nRange = Wlc_ObjRange( pObj ); - if ( nRange == 1 ) + if ( fSkipBitRange && nRange == 1 ) Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) ); else for ( k = 0; k < nRange; k++ ) diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 3bbe843fd..cc69c636e 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -1051,7 +1051,7 @@ usage: ******************************************************************************/ int Abc_CommandInvPut( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, int nRegs ); + extern Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, Gia_Man_t * pGia ); Vec_Int_t * vInv = NULL; Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); int c, fVerbose = 0; @@ -1080,7 +1080,7 @@ int Abc_CommandInvPut( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; } // derive the network - vInv = Wlc_NtkGetPut( pNtk, Gia_ManRegNum(pAbc->pGia) ); + vInv = Wlc_NtkGetPut( pNtk, pAbc->pGia ); if ( vInv ) Abc_FrameSetInv( vInv ); return 0; diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index 8130d0a3a..95adb10c3 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -756,6 +756,8 @@ int Pdr_InvCheck_int( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose, sat_solver // check if this cube intersects with the complement of other cubes in the solver // if it does not intersect, then it is redundant and can be skipped status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 ); + if ( status != l_True && fVerbose ) + printf( "Finished checking clause %d (out of %d)...\r", i, pList[0] ); if ( status == l_Undef ) // timeout break; if ( status == l_False ) // unsat -- correct From 2fe17c1f4bf2a4df4076ad2fee336f568c52786f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 9 Feb 2017 14:30:10 -0800 Subject: [PATCH 119/185] Word-level abstraction. --- src/base/cmd/cmdAuto.c | 4 ++-- src/base/wlc/wlcAbc.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/base/cmd/cmdAuto.c b/src/base/cmd/cmdAuto.c index 7d0cc8afc..35f155fa4 100644 --- a/src/base/cmd/cmdAuto.c +++ b/src/base/cmd/cmdAuto.c @@ -67,8 +67,8 @@ extern int Gia_ManCallSatokoOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutpu void Cmd_RunAutoTunerPrintOptions( satoko_opts_t * pOpts ) { printf( "-C %d ", (int)pOpts->conf_limit ); - printf( "-V %.3f ", pOpts->var_decay ); - printf( "-W %.3f ", pOpts->clause_decay ); + printf( "-V %.3f ", (float)pOpts->var_decay ); + printf( "-W %.3f ", (float)pOpts->clause_decay ); if ( pOpts->verbose ) printf( "-v" ); printf( "\n" ); diff --git a/src/base/wlc/wlcAbc.c b/src/base/wlc/wlcAbc.c index e19aaaecb..1836f4ed3 100644 --- a/src/base/wlc/wlcAbc.c +++ b/src/base/wlc/wlcAbc.c @@ -218,8 +218,8 @@ Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, Gia_Man_t * pGia ) pName = Abc_ObjName(pFanin); if ( pNames ) { - Value = Abc_NamStrFind(pNames, pName) - 1; - if ( Value == -1 ) + Value = Abc_NamStrFind(pNames, pName) - 1 - Gia_ManPiNum(pGia); + if ( Value < 0 ) { if ( Counter++ == 0 ) printf( "Cannot read input name \"%s\" of fanin %d.\n", pName, i ); From 7a2984bbe9e2d9e76851c0ce440e08f6788fcb70 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 9 Feb 2017 16:38:08 -0800 Subject: [PATCH 120/185] Word-level abstraction. --- src/base/wlc/wlc.h | 3 +- src/base/wlc/wlcAbs.c | 4 +- src/base/wlc/wlcAbs2.c | 76 +++++++++++++++++------------- src/base/wlc/wlcCom.c | 8 ++-- src/base/wlc/wlcNtk.c | 98 ++++++++++++++++++++++++++++----------- src/base/wlc/wlcReadVer.c | 2 +- 6 files changed, 125 insertions(+), 66 deletions(-) diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 0a17cfe60..21ba73a30 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -304,7 +304,8 @@ extern void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type ); extern void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fTwoSides, int fVerbose ); extern void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ); extern char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq ); -extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq, Vec_Int_t * vPisNew ); +extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ); +extern Wlc_Ntk_t * Wlc_NtkDupDfsAbs( Wlc_Ntk_t * p, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ); extern void Wlc_NtkCleanMarks( Wlc_Ntk_t * p ); extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int Range, int fSeq, int fAllPis ); extern void Wlc_NtkProfileCones( Wlc_Ntk_t * p ); diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 8662e5093..ce6b8de91 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -173,7 +173,7 @@ Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit ) if ( vNodes != vNodesInit ) Vec_IntFree( vNodes ); // reconstruct topological order - pNew = Wlc_NtkDupDfs( p, 0, 1, NULL ); + pNew = Wlc_NtkDupDfs( p, 0, 1 ); return pNew; } @@ -277,7 +277,7 @@ Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * p, Vec_Int_t * vPairsInit ) if ( vPairs != vPairsInit ) Vec_IntFree( vPairs ); // reconstruct topological order - pNew = Wlc_NtkDupDfs( p, 0, 1, NULL ); + pNew = Wlc_NtkDupDfs( p, 0, 1 ); return pNew; } diff --git a/src/base/wlc/wlcAbs2.c b/src/base/wlc/wlcAbs2.c index 9da59f423..f5a7b46da 100644 --- a/src/base/wlc/wlcAbs2.c +++ b/src/base/wlc/wlcAbs2.c @@ -52,11 +52,11 @@ struct Wabs_Par_t_ void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ) { memset( pPars, 0, sizeof(Wlc_Par_t) ); - pPars->nBitsAdd = 16; // adder bit-width - pPars->nBitsMul = 8; // multiplier bit-widht - pPars->nBitsMux = 32; // MUX bit-width - pPars->nBitsFlop = 32; // flop bit-width - pPars->fVerbose = 0; // verbose output` + pPars->nBitsAdd = ABC_INFINITY; // adder bit-width + pPars->nBitsMul = ABC_INFINITY; // multiplier bit-widht + pPars->nBitsMux = ABC_INFINITY; // MUX bit-width + pPars->nBitsFlop = ABC_INFINITY; // flop bit-width + pPars->fVerbose = 0; // verbose output` } /**Function************************************************************* @@ -73,40 +73,41 @@ void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ) Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) { Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) ); - Wlc_Obj_t * pObj; int i; + Wlc_Obj_t * pObj; int i, Count[4] = {0}; Wlc_NtkForEachObj( p, pObj, i ) { if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || pObj->Type == WLC_OBJ_ARI_MINUS ) { if ( Wlc_ObjRange(pObj) >= pPars->nBitsAdd ) - Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ); + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[0]++; continue; } if ( pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_DIVIDE || pObj->Type == WLC_OBJ_ARI_REM || pObj->Type == WLC_OBJ_ARI_MODULUS ) { if ( Wlc_ObjRange(pObj) >= pPars->nBitsMul ) - Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ); + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[1]++; continue; } if ( pObj->Type == WLC_OBJ_MUX ) { if ( Wlc_ObjRange(pObj) >= pPars->nBitsMux ) - Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ); + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[2]++; continue; } if ( Wlc_ObjIsCi(pObj) && !Wlc_ObjIsPi(pObj) ) { if ( Wlc_ObjRange(pObj) >= pPars->nBitsFlop ) - Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ); + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[3]++; continue; } } + printf( "Abstraction engine marked %d adds/subs, %d muls/divs, %d muxes, and %d flops to be abstracted away.\n", Count[0], Count[1], Count[2], Count[3] ); return vLeaves; } /**Function************************************************************* - Synopsis [] + Synopsis [Marks nodes to be included in the abstracted network.] Description [] @@ -115,7 +116,7 @@ Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) SeeAlso [] ***********************************************************************/ -void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vFlops, Vec_Int_t * vPisNew ) +void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) { int i, iFanin; if ( pObj->Mark ) @@ -123,42 +124,45 @@ void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeav pObj->Mark = 1; if ( Vec_BitEntry(vLeaves, Wlc_ObjId(p, pObj)) ) { + assert( !Wlc_ObjIsPi(pObj) ); Vec_IntPush( vPisNew, Wlc_ObjId(p, pObj) ); return; } if ( Wlc_ObjIsCi(pObj) ) { - if ( !Wlc_ObjIsPi(pObj) ) - Vec_IntPush( vFlops, Wlc_ObjCiId(pObj) ); + if ( Wlc_ObjIsPi(pObj) ) + Vec_IntPush( vPisOld, Wlc_ObjId(p, pObj) ); + else + Vec_IntPush( vFlops, Wlc_ObjId(p, pObj) ); return; } Wlc_ObjForEachFanin( pObj, iFanin, i ) - Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkObj(p, iFanin), vLeaves, vFlops, vPisNew ); + Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkObj(p, iFanin), vLeaves, vPisOld, vPisNew, vFlops ); } -Vec_Int_t * Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves ) +void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) { - Vec_Int_t * vFlops; - Vec_Int_t * vPisNew; Wlc_Obj_t * pObj; - int i, CiId, CoId; + int i, Count = 0; Wlc_NtkCleanMarks( p ); - vFlops = Vec_IntAlloc( 100 ); - vPisNew = Vec_IntAlloc( 100 ); Wlc_NtkForEachCo( p, pObj, i ) - Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vFlops, vPisNew ); - Vec_IntForEachEntry( vFlops, CiId, i ) - { - CoId = Wlc_NtkPoNum(p) + CiId - Wlc_NtkPiNum(p); - Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkCo(p, CoId), vLeaves, vFlops, vPisNew ); - } - Vec_IntFree( vFlops ); - return vPisNew; + Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vPisOld, vPisNew, vFlops ); + Wlc_NtkForEachObjVec( vFlops, p, pObj, i ) + Wlc_NtkAbsMarkNodes_rec( p, Wlc_ObjFo2Fi(p, pObj), vLeaves, vPisOld, vPisNew, vFlops ); + Wlc_NtkForEachObj( p, pObj, i ) + Count += pObj->Mark; +// printf( "Collected %d old PIs, %d new PIs, %d flops, and %d other objects.\n", +// Vec_IntSize(vPisOld), Vec_IntSize(vPisNew), Vec_IntSize(vFlops), +// Count - Vec_IntSize(vPisOld) - Vec_IntSize(vPisNew) - Vec_IntSize(vFlops) ); + Vec_IntSort( vPisOld, 0 ); + Vec_IntSort( vPisNew, 0 ); + Vec_IntSort( vFlops, 0 ); + Wlc_NtkCleanMarks( p ); } /**Function************************************************************* - Synopsis [] + Synopsis [Derive abstraction based on the parameter values.] Description [] @@ -169,11 +173,17 @@ Vec_Int_t * Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves ) ***********************************************************************/ Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) { + Wlc_Ntk_t * pNtkNew = NULL; + Vec_Int_t * vPisOld = Vec_IntAlloc( 100 ); + Vec_Int_t * vPisNew = Vec_IntAlloc( 100 ); + Vec_Int_t * vFlops = Vec_IntAlloc( 100 ); Vec_Bit_t * vLeaves = Wlc_NtkAbsMarkOpers( p, pPars ); - Vec_Int_t * vPisNew = Wlc_NtkAbsMarkNodes( p, vLeaves ); - Wlc_Ntk_t * pNtkNew = Wlc_NtkDupDfs( p, 1, 1, vPisNew ); - Vec_IntFree( vPisNew ); + Wlc_NtkAbsMarkNodes( p, vLeaves, vPisOld, vPisNew, vFlops ); Vec_BitFree( vLeaves ); + pNtkNew = Wlc_NtkDupDfsAbs( p, vPisOld, vPisNew, vFlops ); + Vec_IntFree( vPisOld ); + Vec_IntFree( vPisNew ); + Vec_IntFree( vFlops ); return pNtkNew; } diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index cc69c636e..346a90768 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -423,7 +423,7 @@ int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) printf( "Extracting output %d as a %s word-level network.\n", iOutput, fSeq ? "sequential" : "combinational" ); pName = Wlc_NtkNewName( pNtk, iOutput, fSeq ); Wlc_NtkMarkCone( pNtk, iOutput, Range, fSeq, fAllPis ); - pNtk = Wlc_NtkDupDfs( pNtk, 1, fSeq, NULL ); + pNtk = Wlc_NtkDupDfs( pNtk, 1, fSeq ); ABC_FREE( pNtk->pName ); pNtk->pName = Abc_UtilStrsav( pName ); Wlc_AbcUpdateNtk( pAbc, pNtk ); @@ -941,6 +941,7 @@ usage: ******************************************************************************/ int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) { + abctime clk = Abc_Clock(); extern int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ); int c, nFailed, fVerbose = 0; Extra_UtilGetoptReset(); @@ -974,9 +975,10 @@ int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) } nFailed = Pdr_InvCheck( pAbc->pGia, Wlc_AbcGetInv(pAbc), fVerbose ); if ( nFailed ) - printf( "Invariant verification failed for %d clauses (out of %d).\n", nFailed, Vec_IntEntry(Wlc_AbcGetInv(pAbc),0) ); + printf( "Invariant verification failed for %d clauses (out of %d). ", nFailed, Vec_IntEntry(Wlc_AbcGetInv(pAbc),0) ); else - printf( "Invariant verification succeeded.\n" ); + printf( "Invariant verification succeeded. " ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); return 0; usage: Abc_Print( -2, "usage: inv_check [-vh]\n" ); diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index 6eab44427..86b0c17e7 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -648,7 +648,7 @@ void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fTwoSides, int fVerbose printf( "PI = %4d ", Wlc_NtkCountRealPis(p) ); //Wlc_NtkPiNum(p) ); printf( "PO = %4d ", Wlc_NtkPoNum(p) ); printf( "FF = %4d ", Wlc_NtkFfNum(p) ); - printf( "Obj = %6d ", Wlc_NtkObjNum(p) ); + printf( "Obj = %6d ", Wlc_NtkObjNum(p) - Wlc_NtkPiNum(p) - Wlc_NtkPoNum(p) - Wlc_NtkFfNum(p) ); printf( "Mem = %.3f MB", 1.0*Wlc_NtkMemUsage(p)/(1<<20) ); printf( "\n" ); if ( fDistrib ) @@ -723,7 +723,7 @@ Vec_Int_t * Wlc_ReduceMarkedInitVec( Wlc_Ntk_t * p, Vec_Int_t * vInit ) assert( Vec_IntSize(vInit) == Wlc_NtkCiNum(p) - Wlc_NtkPiNum(p) ); Wlc_NtkForEachCi( p, pObj, i ) if ( !Wlc_ObjIsPi(pObj) && pObj->Mark ) - Vec_IntWriteEntry( vInitNew, k++, Vec_IntEntry(vInit, i) ); + Vec_IntWriteEntry( vInitNew, k++, Vec_IntEntry(vInit, i - Wlc_NtkPiNum(p)) ); Vec_IntShrink( vInitNew, k ); return vInitNew; } @@ -803,7 +803,7 @@ void Wlc_NtkDupDfs_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * v Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins ); Wlc_ObjDup( pNew, p, iObj, vFanins ); } -Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq, Vec_Int_t * vPisNew ) +Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ) { Wlc_Ntk_t * pNew; Wlc_Obj_t * pObj; @@ -813,33 +813,14 @@ Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq, Vec_Int_t * vPi Wlc_NtkCleanCopy( p ); pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc ); pNew->fSmtLib = p->fSmtLib; - if ( vPisNew ) - { - // duplicate marked PIs - Wlc_NtkForEachPi( p, pObj, i ) - if ( pObj->Mark ) - Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); - // duplicated additional PIs - Wlc_NtkForEachObjVec( vPisNew, p, pObj, i ) + Wlc_NtkForEachCi( p, pObj, i ) + if ( !fMarked || pObj->Mark ) { unsigned Type = pObj->Type; - assert( !Wlc_ObjIsPi(pObj) ); - pObj->Type = WLC_OBJ_PI; + if ( !fSeq ) pObj->Type = WLC_OBJ_PI; Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); pObj->Type = Type; } - } - else - { - Wlc_NtkForEachCi( p, pObj, i ) - if ( !fMarked || pObj->Mark ) - { - unsigned Type = pObj->Type; - if ( !fSeq ) pObj->Type = WLC_OBJ_PI; - Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); - pObj->Type = Type; - } - } Wlc_NtkForEachCo( p, pObj, i ) if ( !fMarked || pObj->Mark ) Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins ); @@ -865,7 +846,72 @@ Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq, Vec_Int_t * vPi } } if ( p->pSpec ) - pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Wlc_NtkTransferNames( pNew, p ); + return pNew; +} +Wlc_Ntk_t * Wlc_NtkDupDfsAbs( Wlc_Ntk_t * p, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) +{ + Wlc_Ntk_t * pNew; + Wlc_Obj_t * pObj; + Vec_Int_t * vFanins; + int i; + Wlc_NtkCleanCopy( p ); + pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc ); + pNew->fSmtLib = p->fSmtLib; + + // duplicate marked PIs + vFanins = Vec_IntAlloc( 100 ); + Wlc_NtkForEachObjVec( vPisOld, p, pObj, i ) + { + assert( Wlc_ObjIsPi(pObj) ); + Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + } + // duplicate additional PIs + Wlc_NtkForEachObjVec( vPisNew, p, pObj, i ) + { + unsigned Type = pObj->Type; + int nFanins = Wlc_ObjFaninNum(pObj); + assert( !Wlc_ObjIsPi(pObj) ); + pObj->Type = WLC_OBJ_PI; + pObj->nFanins = 0; + Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + pObj->Type = Type; + pObj->nFanins = (unsigned)nFanins; + } + // duplicate flop outputs + Wlc_NtkForEachObjVec( vFlops, p, pObj, i ) + { + assert( !Wlc_ObjIsPi(pObj) && Wlc_ObjIsCi(pObj) ); + Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + } + + // duplicate logic cones of primary outputs + Wlc_NtkForEachPo( p, pObj, i ) + Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + // duplidate logic cone of flop inputs + Wlc_NtkForEachObjVec( vFlops, p, pObj, i ) + Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, Wlc_ObjFo2Fi(p, pObj)), vFanins ); + + // duplicate POs + Wlc_NtkForEachPo( p, pObj, i ) + Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), 0 ); + // duplicate flop inputs + Wlc_NtkForEachObjVec( vFlops, p, pObj, i ) + Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, Wlc_ObjFo2Fi(p, pObj)), 1 ); + Vec_IntFree( vFanins ); + + // mark flop outputs + Wlc_NtkForEachObjVec( vFlops, p, pObj, i ) + pObj->Mark = 1; + if ( p->vInits ) + pNew->vInits = Wlc_ReduceMarkedInitVec( p, p->vInits ); + if ( p->pInits ) + pNew->pInits = Wlc_ReduceMarkedInitStr( p, p->pInits ); + Wlc_NtkCleanMarks( p ); + + if ( p->pSpec ) + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); Wlc_NtkTransferNames( pNew, p ); return pNew; } diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c index f7546b5b6..e4a65ecfb 100644 --- a/src/base/wlc/wlcReadVer.c +++ b/src/base/wlc/wlcReadVer.c @@ -1265,7 +1265,7 @@ Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr ) if ( !Wlc_PrsDerive( p ) ) goto finish; // derive topological order - pNtk = Wlc_NtkDupDfs( p->pNtk, 0, 1, NULL ); + pNtk = Wlc_NtkDupDfs( p->pNtk, 0, 1 ); pNtk->pSpec = Abc_UtilStrsav( pFileName ); finish: Wlc_PrsPrintErrorMessage( p ); From 4e6978f242c867f060075f19796a64a986d722da Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 9 Feb 2017 18:05:55 -0800 Subject: [PATCH 121/185] Profiling CEX minimization. --- src/sat/bmc/bmcCexCare.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/sat/bmc/bmcCexCare.c b/src/sat/bmc/bmcCexCare.c index a6613891f..8ca916c33 100644 --- a/src/sat/bmc/bmcCexCare.c +++ b/src/sat/bmc/bmcCexCare.c @@ -251,6 +251,20 @@ Abc_Cex_t * Bmc_CexCarePropagateBwd( Gia_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t SeeAlso [] ***********************************************************************/ +Abc_Cex_t * Bmc_CexCareTotal( Abc_Cex_t ** pCexes, int nCexes ) +{ + int i, k, nWords = Abc_BitWordNum( pCexes[0]->nBits ); + Abc_Cex_t * pCexMin = Abc_CexAlloc( pCexes[0]->nRegs, pCexes[0]->nPis, pCexes[0]->iFrame + 1 ); + pCexMin->iPo = pCexes[0]->iPo; + pCexMin->iFrame = pCexes[0]->iFrame; + for ( i = 0; i < nWords; i++ ) + { + pCexMin->pData[i] = pCexes[0]->pData[i]; + for ( k = 1; k < nCexes; k++ ) + pCexMin->pData[i] &= pCexes[k]->pData[i]; + } + return pCexMin; +} Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, Abc_Cex_t * pCex, int fCheck, int fVerbose ) { int nTryCexes = 4; // belongs to range [1;4] @@ -314,15 +328,19 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, Abc_Cex_t * pCex, int fCheck, pCexBest = pCexMin[k]; } } + if ( fVerbose ) + { + Abc_Cex_t * pTotal = Bmc_CexCareTotal( pCexMin, nTryCexes ); + printf( "Final : " ); + Bmc_CexPrint( pCexBest, Gia_ManPiNum(p), 0 ); + printf( "Total : " ); + Bmc_CexPrint( pTotal, Gia_ManPiNum(p), 0 ); + Abc_CexFreeP( &pTotal ); + } for ( k = 0; k < nTryCexes; k++ ) if ( pCexBest != pCexMin[k] ) Abc_CexFreeP( &pCexMin[k] ); // verify and return - if ( fVerbose ) - { - printf( "Final : " ); - Bmc_CexPrint( pCexBest, Gia_ManPiNum(p), 0 ); - } if ( !Bmc_CexVerify( p, pCex, pCexBest ) ) printf( "Counter-example verification has failed.\n" ); else if ( fCheck ) From d335ee096e902844b9a94076e8ce5855f74d9bde Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 10 Feb 2017 11:05:00 -0800 Subject: [PATCH 122/185] Standardizing the use of new CNF generator. Adding CNF variable connectivity information. --- src/aig/gia/gia.h | 2 ++ src/aig/gia/giaMf.c | 58 +++++++++++++++++++++++++++++++------ src/aig/gia/giaQbf.c | 12 ++++---- src/aig/gia/giaSatoko.c | 4 +-- src/base/abci/abcCollapse.c | 4 +-- src/base/abci/abcDetect.c | 3 +- src/proof/cec/cecCec.c | 3 +- src/proof/pdr/pdrInv.c | 8 ++--- src/sat/bmc/bmcBmcAnd.c | 3 +- src/sat/bmc/bmcChain.c | 3 +- src/sat/bmc/bmcClp.c | 10 +++---- src/sat/bmc/bmcEnum.c | 4 +-- src/sat/bmc/bmcExpand.c | 4 +-- src/sat/bmc/bmcFault.c | 2 +- src/sat/bmc/bmcFx.c | 6 ++-- src/sat/bmc/bmcGen.c | 4 +-- src/sat/bmc/bmcICheck.c | 3 +- 17 files changed, 76 insertions(+), 57 deletions(-) diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 3bc97e6b0..6677e0ad2 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -311,6 +311,7 @@ struct Jf_Par_t_ int fGenCnf; int fCnfObjIds; int fAddOrCla; + int fCnfMapping; int fPureAig; int fDoAverage; int fCutHashing; @@ -1405,6 +1406,7 @@ extern int Gia_MmStepReadMemUsage( Gia_MmStep_t * p ); /*=== giaMf.c ===========================================================*/ extern void Mf_ManSetDefaultPars( Jf_Par_t * pPars ); extern Gia_Man_t * Mf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars ); +extern void * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fMapping, int fVerbose ); /*=== giaMini.c ===========================================================*/ extern Gia_Man_t * Gia_ManReadMiniAig( char * pFileName ); extern void Gia_ManWriteMiniAig( Gia_Man_t * pGia, char * pFileName ); diff --git a/src/aig/gia/giaMf.c b/src/aig/gia/giaMf.c index a500a8394..24c1e6a04 100644 --- a/src/aig/gia/giaMf.c +++ b/src/aig/gia/giaMf.c @@ -388,6 +388,8 @@ Cnf_Dat_t * Mf_ManDeriveCnf( Mf_Man_t * p, int fCnfObjIds, int fAddOrCla ) Gia_ManForEachCoId( p->pGia, Id, i ) pCnf->pClauses[0][iLit++] = Abc_Var2Lit(pCnfIds[Id], 0); } + if ( p->pPars->fCnfMapping ) + pCnf->vMapping = Vec_IntStart( nVars ); // add clauses for the COs Gia_ManForEachCo( p->pGia, pObj, i ) { @@ -401,6 +403,14 @@ Cnf_Dat_t * Mf_ManDeriveCnf( Mf_Man_t * p, int fCnfObjIds, int fAddOrCla ) pCnf->pClauses[iCla++] = pCnf->pClauses[0] + iLit; pCnf->pClauses[0][iLit++] = Abc_Var2Lit(pCnfIds[Id], 1); pCnf->pClauses[0][iLit++] = Abc_Var2Lit(pCnfIds[DriId], Gia_ObjFaninC0(pObj)); + // generate mapping + if ( pCnf->vMapping ) + { + Vec_IntWriteEntry( pCnf->vMapping, pCnfIds[Id], Vec_IntSize(pCnf->vMapping) ); + Vec_IntPush( pCnf->vMapping, 1 ); + Vec_IntPush( pCnf->vMapping, pCnfIds[DriId] ); + Vec_IntPush( pCnf->vMapping, Gia_ObjFaninC0(pObj) ? 0x55555555 : 0xAAAAAAAA ); + } } // add clauses for the mapping Gia_ManForEachAndReverseId( p->pGia, Id ) @@ -427,6 +437,35 @@ Cnf_Dat_t * Mf_ManDeriveCnf( Mf_Man_t * p, int fCnfObjIds, int fAddOrCla ) if ( Mf_CubeLit(pCubes[c], k) ) pCnf->pClauses[0][iLit++] = Abc_Var2Lit( pFanins[k], Mf_CubeLit(pCubes[c], k) == 2 ); } + // generate mapping + if ( pCnf->vMapping ) + { + word pTruth[4], * pTruthP = Vec_MemReadEntry(p->vTtMem, iFunc); + assert( p->pPars->nLutSize <= 8 ); + Abc_TtCopy( pTruth, pTruthP, Abc_Truth6WordNum(p->pPars->nLutSize), Abc_LitIsCompl(iFunc) ); + assert( pCnfIds[Id] >= 0 && pCnfIds[Id] < nVars ); + Vec_IntWriteEntry( pCnf->vMapping, pCnfIds[Id], Vec_IntSize(pCnf->vMapping) ); + Vec_IntPush( pCnf->vMapping, Mf_CutSize(pCut) ); + for ( k = 0; k < Mf_CutSize(pCut); k++ ) + Vec_IntPush( pCnf->vMapping, pCnfIds[pCut[k+1]] ); + Vec_IntPush( pCnf->vMapping, (unsigned)pTruth[0] ); + if ( Mf_CutSize(pCut) >= 6 ) + { + Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[0] >> 32) ); + if ( Mf_CutSize(pCut) >= 7 ) + { + Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[1]) ); + Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[1] >> 32) ); + } + if ( Mf_CutSize(pCut) >= 8 ) + { + Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[2]) ); + Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[2] >> 32) ); + Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[3]) ); + Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[3] >> 32) ); + } + } + } } // constant clause pCnf->pClauses[iCla++] = pCnf->pClauses[0] + iLit; @@ -1636,28 +1675,29 @@ Gia_Man_t * Mf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars ) SeeAlso [] ***********************************************************************/ -Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ) +void * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fMapping, int fVerbose ) { Gia_Man_t * pNew; Jf_Par_t Pars, * pPars = &Pars; assert( nLutSize >= 3 && nLutSize <= 8 ); Mf_ManSetDefaultPars( pPars ); - pPars->fGenCnf = 1; - pPars->fCoarsen = !fCnfObjIds; - pPars->nLutSize = nLutSize; - pPars->fCnfObjIds = fCnfObjIds; - pPars->fAddOrCla = fAddOrCla; - pPars->fVerbose = fVerbose; + pPars->fGenCnf = 1; + pPars->fCoarsen = !fCnfObjIds; + pPars->nLutSize = nLutSize; + pPars->fCnfObjIds = fCnfObjIds; + pPars->fAddOrCla = fAddOrCla; + pPars->fCnfMapping = fMapping; + pPars->fVerbose = fVerbose; pNew = Mf_ManPerformMapping( pGia, pPars ); Gia_ManStopP( &pNew ); // Cnf_DataPrint( (Cnf_Dat_t *)pGia->pData, 1 ); - return (Cnf_Dat_t*)pGia->pData; + return pGia->pData; } void Mf_ManDumpCnf( Gia_Man_t * p, char * pFileName, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ) { abctime clk = Abc_Clock(); Cnf_Dat_t * pCnf; - pCnf = Mf_ManGenerateCnf( p, nLutSize, fCnfObjIds, fAddOrCla, fVerbose ); + pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, nLutSize, fCnfObjIds, fAddOrCla, 0, fVerbose ); Cnf_DataWriteIntoFile( pCnf, pFileName, 0, NULL, NULL ); // if ( fVerbose ) { diff --git a/src/aig/gia/giaQbf.c b/src/aig/gia/giaQbf.c index 4ca0bac33..2dfd83fca 100644 --- a/src/aig/gia/giaQbf.c +++ b/src/aig/gia/giaQbf.c @@ -48,8 +48,6 @@ struct Qbf_Man_t_ abctime clkSat; // SAT solver time }; -extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -192,7 +190,7 @@ int Gia_ManSatEnum( Gia_Man_t * pGia, int nConfLimit, int nTimeOut, int fVerbose int i, iLit, iParVarBeg, Iter; int nSolutions = 0, RetValue = 0; abctime clkStart = Abc_Clock(); - pCnf = Mf_ManGenerateCnf( pGia, 8, 0, 1, 0 ); + pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pGia, 8, 0, 1, 0, 0 ); pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); iParVarBeg = pCnf->nVars - Gia_ManPiNum(pGia);// - 1; Cnf_DataFree( pCnf ); @@ -247,7 +245,7 @@ void Gia_QbfDumpFile( Gia_Man_t * pGia, int nPars ) { // original problem: \exists p \forall x \exists y. M(p,x,y) // negated problem: \forall p \exists x \exists y. !M(p,x,y) - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( pGia, 8, 0, 1, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pGia, 8, 0, 1, 0, 0 ); Vec_Int_t * vVarMap, * vForAlls, * vExists; Gia_Obj_t * pObj; char * pFileName; @@ -291,7 +289,7 @@ Qbf_Man_t * Gia_QbfAlloc( Gia_Man_t * pGia, int nPars, int fVerbose ) Qbf_Man_t * p; Cnf_Dat_t * pCnf; Gia_ObjFlipFaninC0( Gia_ManPo(pGia, 0) ); - pCnf = Mf_ManGenerateCnf( pGia, 8, 0, 1, 0 ); + pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pGia, 8, 0, 1, 0, 0 ); Gia_ObjFlipFaninC0( Gia_ManPo(pGia, 0) ); p = ABC_CALLOC( Qbf_Man_t, 1 ); p->clkStart = Abc_Clock(); @@ -426,7 +424,7 @@ Gia_Man_t * Gia_QbfCofactor( Gia_Man_t * p, int nPars, Vec_Int_t * vValues, Vec_ /* int Gia_QbfAddCofactor( Qbf_Man_t * p, Gia_Man_t * pCof ) { - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( pCof, 8, 0, 1, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pCof, 8, 0, 1, 0, 0 ); int i, iFirstVar = sat_solver_nvars(p->pSatSyn) + pCnf->nVars - Gia_ManPiNum(pCof);// - 1; pCnf->pMan = NULL; Cnf_DataLift( pCnf, sat_solver_nvars(p->pSatSyn) ); @@ -459,7 +457,7 @@ void Cnf_SpecialDataLift( Cnf_Dat_t * p, int nVarsPlus, int firstPiVar, int last int Gia_QbfAddCofactor( Qbf_Man_t * p, Gia_Man_t * pCof ) { - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( pCof, 8, 0, 1, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pCof, 8, 0, 1, 0, 0 ); int i, useold = 0; int iFirstVar = useold ? sat_solver_nvars(p->pSatSyn) + pCnf->nVars - Gia_ManPiNum(pCof) : pCnf->nVars - Gia_ManPiNum(pCof); //-1 pCnf->pMan = NULL; diff --git a/src/aig/gia/giaSatoko.c b/src/aig/gia/giaSatoko.c index fc8e5c28b..db81bd854 100644 --- a/src/aig/gia/giaSatoko.c +++ b/src/aig/gia/giaSatoko.c @@ -30,8 +30,6 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -50,7 +48,7 @@ extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfOb satoko_t * Gia_ManCreateSatoko( Gia_Man_t * p ) { satoko_t * pSat = satoko_create(); - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 1, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 1, 0, 0 ); int i, status; //sat_solver_setnvars( pSat, p->nVars ); for ( i = 0; i < pCnf->nClauses; i++ ) diff --git a/src/base/abci/abcCollapse.c b/src/base/abci/abcCollapse.c index 8c2b3b393..1542c25a5 100644 --- a/src/base/abci/abcCollapse.c +++ b/src/base/abci/abcCollapse.c @@ -537,8 +537,6 @@ extern Vec_Wec_t * Gia_ManCreateCoSupps( Gia_Man_t * p, int fVerbose ); extern int Gia_ManCoLargestSupp( Gia_Man_t * p, Vec_Wec_t * vSupps ); extern Vec_Wec_t * Gia_ManIsoStrashReduceInt( Gia_Man_t * p, Vec_Wec_t * vSupps, int fVerbose ); -extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - /**Function************************************************************* Synopsis [Derives GIA for the network.] @@ -802,7 +800,7 @@ Vec_Ptr_t * Abc_GiaDeriveSops( Abc_Ntk_t * pNtkNew, Gia_Man_t * p, Vec_Wec_t * v if ( fCnfShared ) { vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); - pCnf = Mf_ManGenerateCnf( p, 8, 1, 0, 0 ); + pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 1, 0, 0, 0 ); } vSopsRepr = Vec_PtrStart( Vec_IntSize(vReprs) ); pProgress = Extra_ProgressBarStart( stdout, Vec_IntSize(vReprs) ); diff --git a/src/base/abci/abcDetect.c b/src/base/abci/abcDetect.c index 8b8bba64b..7adbed5db 100644 --- a/src/base/abci/abcDetect.c +++ b/src/base/abci/abcDetect.c @@ -901,8 +901,7 @@ Vec_Int_t * Abc_NtkFinCheckPair( Abc_Ntk_t * pNtk, Vec_Int_t * vTypes, Vec_Int_t } else { - extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( pGia, 8, 0, 1, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pGia, 8, 0, 1, 0, 0 ); sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); if ( pSat == NULL ) { diff --git a/src/proof/cec/cecCec.c b/src/proof/cec/cecCec.c index f7e45c57a..be6df65fa 100644 --- a/src/proof/cec/cecCec.c +++ b/src/proof/cec/cecCec.c @@ -225,8 +225,7 @@ int Cec_ManHandleSpecialCases( Gia_Man_t * p, Cec_ParCec_t * pPars ) ***********************************************************************/ int Cec_ManVerifyNaive( Gia_Man_t * p, Cec_ParCec_t * pPars ) { - extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); Gia_Obj_t * pObj0, * pObj1; abctime clkStart = Abc_Clock(); diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index 95adb10c3..fe759fffe 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -626,8 +626,6 @@ Vec_Int_t * Pdr_ManDeriveInfinityClauses( Pdr_Man_t * p, int fReduce ) ***********************************************************************/ #define Pdr_ForEachCube( pList, pCut, i ) for ( i = 0, pCut = pList + 1; i < pList[0]; i++, pCut += pCut[0] + 1 ) -extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - Vec_Int_t * Pdr_InvMap( Vec_Int_t * vCounts ) { int i, k = 0, Count; @@ -779,7 +777,7 @@ int Pdr_InvCheck_int( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose, sat_solver int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) { int RetValue; - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); assert( sat_solver_nvars(pSat) == pCnf->nVars ); Cnf_DataFree( pCnf ); @@ -796,7 +794,7 @@ Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) int n, i, k, status, nLits, fFailed = 0, fCannot = 0, nRemoved = 0; Vec_Int_t * vRes = NULL; // create SAT solver - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); int * pCube, * pList = Vec_IntArray(vInv), nCubes = pList[0]; // create variables @@ -914,7 +912,7 @@ Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) Vec_Int_t * vRes = NULL; abctime clk = Abc_Clock(); int i, k, nLits = 0, * pCube, * pList = Vec_IntArray(vInv), nRemoved = 0; - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); sat_solver * pSat; // sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); Pdr_ForEachCube( pList, pCube, i ) diff --git a/src/sat/bmc/bmcBmcAnd.c b/src/sat/bmc/bmcBmcAnd.c index 8087046a6..3490d34f6 100644 --- a/src/sat/bmc/bmcBmcAnd.c +++ b/src/sat/bmc/bmcBmcAnd.c @@ -986,8 +986,7 @@ int Gia_ManBmcPerformInt( Gia_Man_t * pGia, Bmc_AndPar_t * pPars ) { // p->pFrames = Jf_ManDeriveCnf( pTemp = p->pFrames, 1 ); Gia_ManStop( pTemp ); // p->pCnf = (Cnf_Dat_t *)p->pFrames->pData; p->pFrames->pData = NULL; - extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - p->pCnf = Mf_ManGenerateCnf( p->pFrames, pPars->nLutSize, 1, 0, pPars->fVerbose ); + p->pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p->pFrames, pPars->nLutSize, 1, 0, 0, pPars->fVerbose ); } Vec_IntFillExtra( p->vId2Var, Gia_ManObjNum(p->pFrames), 0 ); // create clauses for constant node diff --git a/src/sat/bmc/bmcChain.c b/src/sat/bmc/bmcChain.c index 324c7f6d2..5af54306a 100644 --- a/src/sat/bmc/bmcChain.c +++ b/src/sat/bmc/bmcChain.c @@ -185,10 +185,9 @@ Gia_Man_t * Gia_ManDupPosAndPropagateInit( Gia_Man_t * p ) } sat_solver * Gia_ManDeriveSatSolver( Gia_Man_t * p, Vec_Int_t * vSatIds ) { -// extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); sat_solver * pSat; Aig_Man_t * pAig = Gia_ManToAigSimple( p ); -// Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); +// Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); Cnf_Dat_t * pCnf = Cnf_Derive( pAig, Aig_ManCoNum(pAig) ); // save SAT vars for the primary inputs if ( vSatIds ) diff --git a/src/sat/bmc/bmcClp.c b/src/sat/bmc/bmcClp.c index 8a69fe566..cfc608b14 100644 --- a/src/sat/bmc/bmcClp.c +++ b/src/sat/bmc/bmcClp.c @@ -30,8 +30,6 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -651,7 +649,7 @@ Vec_Str_t * Bmc_CollapseOneInt2( Gia_Man_t * p, int nCubeLim, int nBTLimit, int int iOut = 0, iLit, iVar, status, n, Count, Start; // create SAT solver - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); sat_solver * pSat[3] = { (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0), (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0), @@ -841,7 +839,7 @@ Vec_Str_t * Bmc_CollapseOneOld( Gia_Man_t * p, int nCubeLim, int nBTLimit, int f { int fVeryVerbose = fVerbose; int nVars = Gia_ManCiNum(p); - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); sat_solver * pSat[2] = { (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0), (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0) }; sat_solver * pSatClean[2] = { (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0), (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0) }; Vec_Str_t * vSop[2] = { Vec_StrAlloc(1000), Vec_StrAlloc(1000) }, * vRes = NULL; @@ -1173,7 +1171,7 @@ cleanup: } Vec_Str_t * Bmc_CollapseOne3( Gia_Man_t * p, int nCubeLim, int nBTLimit, int fCanon, int fReverse, int fVerbose ) { - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); sat_solver * pSat0 = (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0); sat_solver * pSat1 = (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0); sat_solver * pSat2 = (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0); @@ -1507,7 +1505,7 @@ cleanup: } Vec_Str_t * Bmc_CollapseOne( Gia_Man_t * p, int nCubeLim, int nBTLimit, int fCanon, int fReverse, int fVerbose ) { - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0); Vec_Str_t * vSop = Bmc_CollapseOne_int( pSat, Gia_ManCiNum(p), nCubeLim, nBTLimit, fCanon, fReverse, fVerbose ); sat_solver_delete( pSat ); diff --git a/src/sat/bmc/bmcEnum.c b/src/sat/bmc/bmcEnum.c index 5fe2c1ed6..45aeb2b30 100644 --- a/src/sat/bmc/bmcEnum.c +++ b/src/sat/bmc/bmcEnum.c @@ -29,8 +29,6 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -169,7 +167,7 @@ void Gia_ManDeriveOneTest( Gia_Man_t * p ) Gia_Man_t * pNew; Gia_Obj_t * pObj, * pRoot; Vec_Int_t * vValues = Vec_IntStart( Gia_ManCiNum(p) ); - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); int i, iVar, nIter, iPoVarBeg = pCnf->nVars - Gia_ManCiNum(p); sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); Vec_Int_t * vLits = Vec_IntAlloc( 100 ); diff --git a/src/sat/bmc/bmcExpand.c b/src/sat/bmc/bmcExpand.c index f3ec999ed..6c7a59884 100644 --- a/src/sat/bmc/bmcExpand.c +++ b/src/sat/bmc/bmcExpand.c @@ -33,8 +33,6 @@ ABC_NAMESPACE_IMPL_START // iterator thought the cubes #define Bmc_SopForEachCube( pSop, nVars, pCube ) for ( pCube = (pSop); *pCube; pCube += (nVars) + 3 ) -extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -93,7 +91,7 @@ int Abc_ObjExpandCubes( Vec_Str_t * vSop, Gia_Man_t * p, int nVars ) int fReverse = 0; Vec_Int_t * vVars = Vec_IntAlloc( nVars ); - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0); int v, n, iLit, status, nCubesNew, iCiVarBeg = sat_solver_nvars(pSat) - nVars; diff --git a/src/sat/bmc/bmcFault.c b/src/sat/bmc/bmcFault.c index 8dc2a57fe..71eef2c46 100644 --- a/src/sat/bmc/bmcFault.c +++ b/src/sat/bmc/bmcFault.c @@ -280,7 +280,7 @@ static inline Cnf_Dat_t * Cnf_DeriveGiaRemapped( Gia_Man_t * p ) pCnf = Cnf_Derive( pAig, Aig_ManCoNum(pAig) ); Aig_ManStop( pAig ); return pCnf; -// return Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); +// return (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); } /**Function************************************************************* diff --git a/src/sat/bmc/bmcFx.c b/src/sat/bmc/bmcFx.c index 9cd37c882..15ea4f050 100644 --- a/src/sat/bmc/bmcFx.c +++ b/src/sat/bmc/bmcFx.c @@ -30,8 +30,6 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -598,7 +596,7 @@ int Bmc_FxCompute( Gia_Man_t * p ) extern Gia_Man_t * Gia_ManDupOnsetOffset( Gia_Man_t * p ); Gia_Man_t * p2 = Gia_ManDupOnsetOffset( p ); // create SAT solver - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p2, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p2, 8, 0, 0, 0, 0 ); sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); // compute parameters int nOuts = Gia_ManCoNum(p); @@ -674,7 +672,7 @@ int Bmc_FxComputeOne( Gia_Man_t * p, int nIterMax, int nDiv2Add ) { int Extra = 1000; // create SAT solver - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); // compute parameters int nCiVars = Gia_ManCiNum(p); // PI count diff --git a/src/sat/bmc/bmcGen.c b/src/sat/bmc/bmcGen.c index 74af1b78a..5d84ce87b 100644 --- a/src/sat/bmc/bmcGen.c +++ b/src/sat/bmc/bmcGen.c @@ -29,8 +29,6 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -131,7 +129,7 @@ void Gia_ManMoFindSimulate( Gia_Man_t * p, int nWords ) int Gia_ManTestSatEnum( Gia_Man_t * p ) { abctime clk = Abc_Clock(), clk2, clkTotal = 0; - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0); int i, v, status, iLit, nWords = 1, iOutVar = 1, Count = 0; Vec_Int_t * vVars = Vec_IntAlloc( 1000 ); diff --git a/src/sat/bmc/bmcICheck.c b/src/sat/bmc/bmcICheck.c index a779b1ed2..8d8c7c6b6 100644 --- a/src/sat/bmc/bmcICheck.c +++ b/src/sat/bmc/bmcICheck.c @@ -392,11 +392,10 @@ int Bmc_PerformISearchOne( Gia_Man_t * p, int nFramesMax, int nTimeOut, int fRev pCnf = Cnf_DeriveGiaRemapped( pMiter ); else { - extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); //pMiter = Jf_ManDeriveCnf( pTemp = pMiter, 0 ); //Gia_ManStop( pTemp ); //pCnf = (Cnf_Dat_t *)pMiter->pData; pMiter->pData = NULL; - pCnf = Mf_ManGenerateCnf( pMiter, 8, 0, 0, 0 ); + pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pMiter, 8, 0, 0, 0, 0 ); } /* // collect positive literals From f2d096c9f04acf95e959842d63b6febf2f8eb786 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 10 Feb 2017 13:20:20 -0800 Subject: [PATCH 123/185] Improving CEX minimization. --- src/base/io/io.c | 2 +- src/misc/util/utilCex.c | 25 ++- src/sat/bmc/bmc.h | 4 +- src/sat/bmc/bmcCexCare.c | 329 ++++++++++++++++++++++++-------------- src/sat/bmc/bmcCexTools.c | 6 +- 5 files changed, 229 insertions(+), 137 deletions(-) diff --git a/src/base/io/io.c b/src/base/io/io.c index 4cec01575..c2cf15d48 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -2420,7 +2420,7 @@ int IoCommandWriteCex( Abc_Frame_t * pAbc, int argc, char **argv ) Bmc_CexCareVerify( pAig, pCex, pCare, fVerbose ); } else - pCare = Bmc_CexCareMinimize( pAig, pCex, fCheckCex, fVerbose ); + pCare = Bmc_CexCareMinimize( pAig, 0, pCex, fCheckCex, fVerbose ); Aig_ManStop( pAig ); } // output flop values (unaffected by the minimization) diff --git a/src/misc/util/utilCex.c b/src/misc/util/utilCex.c index 3acd7f777..59107dc93 100644 --- a/src/misc/util/utilCex.c +++ b/src/misc/util/utilCex.c @@ -272,9 +272,9 @@ void Abc_CexPrintStats( Abc_Cex_t * p ) p->iPo, p->iFrame, p->nRegs, p->nPis, p->nBits, Counter, 100.0 * Counter / (p->nBits - p->nRegs) ); } -void Abc_CexPrintStatsInputs( Abc_Cex_t * p, int nInputs ) +void Abc_CexPrintStatsInputs( Abc_Cex_t * p, int nRealPis ) { - int k, Counter = 0, Counter2 = 0; + int k, Counter = 0, CounterPi = 0, CounterPpi = 0; if ( p == NULL ) { printf( "The counter example is NULL.\n" ); @@ -285,16 +285,27 @@ void Abc_CexPrintStatsInputs( Abc_Cex_t * p, int nInputs ) printf( "The counter example is present but not available (pointer has value \"1\").\n" ); return; } + assert( nRealPis <= p->nPis ); for ( k = 0; k < p->nBits; k++ ) { Counter += Abc_InfoHasBit(p->pData, k); - if ( (k - p->nRegs) % p->nPis < nInputs ) - Counter2 += Abc_InfoHasBit(p->pData, k); + if ( nRealPis == p->nPis ) + continue; + if ( (k - p->nRegs) % p->nPis < nRealPis ) + CounterPi += Abc_InfoHasBit(p->pData, k); + else + CounterPpi += Abc_InfoHasBit(p->pData, k); } - printf( "CEX: Po =%4d Frame =%4d FF = %d PI = %d Bit =%8d 1s =%8d (%5.2f %%) 1sIn =%8d (%5.2f %%)\n", + printf( "CEX: Po =%4d Fr =%4d FF = %d PI = %d Bit =%7d 1 =%8d (%5.2f %%)", p->iPo, p->iFrame, p->nRegs, p->nPis, p->nBits, - Counter, 100.0 * Counter / (p->nBits - p->nRegs), - Counter2, 100.0 * Counter2 / (p->nBits - p->nRegs - (p->iFrame + 1) * (p->nPis - nInputs)) ); + Counter, 100.0 * Counter / ((p->iFrame + 1) * p->nPis ) ); + if ( nRealPis < p->nPis ) + { + printf( " 1pi =%8d (%5.2f %%) 1ppi =%8d (%5.2f %%)", + CounterPi, 100.0 * CounterPi / ((p->iFrame + 1) * nRealPis ), + CounterPpi, 100.0 * CounterPpi / ((p->iFrame + 1) * (p->nPis - nRealPis)) ); + } + printf( "\n" ); } /**Function************************************************************* diff --git a/src/sat/bmc/bmc.h b/src/sat/bmc/bmc.h index 305382531..7820ebe6d 100644 --- a/src/sat/bmc/bmc.h +++ b/src/sat/bmc/bmc.h @@ -164,7 +164,7 @@ extern int Saig_ManBmcScalable( Aig_Man_t * pAig, Saig_ParBmc_t * extern int Gia_ManBmcPerform( Gia_Man_t * p, Bmc_AndPar_t * pPars ); /*=== bmcCexCare.c ==========================================================*/ extern Abc_Cex_t * Bmc_CexCareExtendToObjects( Gia_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t * pCexCare ); -extern Abc_Cex_t * Bmc_CexCareMinimize( Aig_Man_t * p, Abc_Cex_t * pCex, int fCheck, int fVerbose ); +extern Abc_Cex_t * Bmc_CexCareMinimize( Aig_Man_t * p, int nPPis, Abc_Cex_t * pCex, int fCheck, int fVerbose ); extern void Bmc_CexCareVerify( Aig_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t * pCexMin, int fVerbose ); /*=== bmcCexCut.c ==========================================================*/ extern Gia_Man_t * Bmc_GiaTargetStates( Gia_Man_t * p, Abc_Cex_t * pCex, int iFrBeg, int iFrEnd, int fCombOnly, int fGenAll, int fAllFrames, int fVerbose ); @@ -172,7 +172,7 @@ extern Aig_Man_t * Bmc_AigTargetStates( Aig_Man_t * p, Abc_Cex_t * pCex, i /*=== bmcCexMin.c ==========================================================*/ extern Abc_Cex_t * Saig_ManCexMinPerform( Aig_Man_t * pAig, Abc_Cex_t * pCex ); /*=== bmcCexTool.c ==========================================================*/ -extern void Bmc_CexPrint( Abc_Cex_t * pCex, int nInputs, int fVerbose ); +extern void Bmc_CexPrint( Abc_Cex_t * pCex, int nRealPis, int fVerbose ); extern int Bmc_CexVerify( Gia_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t * pCexCare ); /*=== bmcICheck.c ==========================================================*/ extern void Bmc_PerformICheck( Gia_Man_t * p, int nFramesMax, int nTimeOut, int fEmpty, int fVerbose ); diff --git a/src/sat/bmc/bmcCexCare.c b/src/sat/bmc/bmcCexCare.c index 8ca916c33..9c0a30d3c 100644 --- a/src/sat/bmc/bmcCexCare.c +++ b/src/sat/bmc/bmcCexCare.c @@ -86,67 +86,6 @@ Abc_Cex_t * Bmc_CexCareExtendToObjects( Gia_Man_t * p, Abc_Cex_t * pCex, Abc_Cex return pNew; } -/**Function************************************************************* - - Synopsis [Backward propagation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Bmc_CexCarePropagateFwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, int fGrow ) -{ - Gia_Obj_t * pObj; - int Prio, Prio0, Prio1; - int i, Phase0, Phase1; - if ( (fGrow & 2) ) - { - Gia_ManForEachPi( p, pObj, i ) - pObj->Value = Abc_Var2Lit( f * pCex->nPis + (pCex->nPis-1-i) + 1, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i) ); - } - else - { - Gia_ManForEachPi( p, pObj, i ) - pObj->Value = Abc_Var2Lit( f * pCex->nPis + i + 1, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i) ); - } - Gia_ManForEachAnd( p, pObj, i ) - { - Prio0 = Abc_Lit2Var(Gia_ObjFanin0(pObj)->Value); - Prio1 = Abc_Lit2Var(Gia_ObjFanin1(pObj)->Value); - Phase0 = Abc_LitIsCompl(Gia_ObjFanin0(pObj)->Value) ^ Gia_ObjFaninC0(pObj); - Phase1 = Abc_LitIsCompl(Gia_ObjFanin1(pObj)->Value) ^ Gia_ObjFaninC1(pObj); - if ( Phase0 && Phase1 ) - Prio = (fGrow & 1) ? Abc_MinInt(Prio0, Prio1) : Abc_MaxInt(Prio0, Prio1); - else if ( Phase0 && !Phase1 ) - Prio = Prio1; - else if ( !Phase0 && Phase1 ) - Prio = Prio0; - else // if ( !Phase0 && !Phase1 ) - Prio = (fGrow & 1) ? Abc_MaxInt(Prio0, Prio1) : Abc_MinInt(Prio0, Prio1); - pObj->Value = Abc_Var2Lit( Prio, Phase0 & Phase1 ); - } - Gia_ManForEachCo( p, pObj, i ) - pObj->Value = Abc_LitNotCond( Gia_ObjFanin0(pObj)->Value, Gia_ObjFaninC0(pObj) ); -} -void Bmc_CexCarePropagateFwd( Gia_Man_t * p, Abc_Cex_t * pCex, int fGrow, Vec_Int_t * vPrios ) -{ - Gia_Obj_t * pObj, * pObjRo, * pObjRi; - int f, i; - Gia_ManConst0( p )->Value = 0; - Gia_ManForEachRi( p, pObj, i ) - pObj->Value = 0; - Vec_IntClear( vPrios ); - for ( f = 0; f <= pCex->iFrame; f++ ) - { - Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) - Vec_IntPush( vPrios, (pObjRo->Value = pObjRi->Value) ); - Bmc_CexCarePropagateFwdOne( p, pCex, f, fGrow ); - } -} - /**Function************************************************************* Synopsis [Forward propagation.] @@ -158,11 +97,66 @@ void Bmc_CexCarePropagateFwd( Gia_Man_t * p, Abc_Cex_t * pCex, int fGrow, Vec_In SeeAlso [] ***********************************************************************/ -void Bmc_CexCarePropagateBwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, int fGrow, Abc_Cex_t * pCexMin ) +void Bmc_CexCarePropagateFwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, Vec_Int_t * vPriosIn ) { Gia_Obj_t * pObj; + int Prio, Prio0, Prio1; int i, Phase0, Phase1; - Gia_ManForEachCand( p, pObj, i ) + assert( Vec_IntSize(vPriosIn) == pCex->nPis * (pCex->iFrame + 1) ); + Gia_ManForEachPi( p, pObj, i ) + pObj->Value = Vec_IntEntry( vPriosIn, f * pCex->nPis + i ); + Gia_ManForEachAnd( p, pObj, i ) + { + Prio0 = Abc_Lit2Var(Gia_ObjFanin0(pObj)->Value); + Prio1 = Abc_Lit2Var(Gia_ObjFanin1(pObj)->Value); + Phase0 = Abc_LitIsCompl(Gia_ObjFanin0(pObj)->Value) ^ Gia_ObjFaninC0(pObj); + Phase1 = Abc_LitIsCompl(Gia_ObjFanin1(pObj)->Value) ^ Gia_ObjFaninC1(pObj); + if ( Phase0 && Phase1 ) + Prio = Abc_MinInt(Prio0, Prio1); + else if ( Phase0 ) + Prio = Prio1; + else if ( Phase1 ) + Prio = Prio0; + else // if ( !Phase0 && !Phase1 ) + Prio = Abc_MaxInt(Prio0, Prio1); + pObj->Value = Abc_Var2Lit( Prio, Phase0 && Phase1 ); + pObj->fPhase = 0; + } + Gia_ManForEachCo( p, pObj, i ) + pObj->Value = Abc_LitNotCond( Gia_ObjFanin0(pObj)->Value, Gia_ObjFaninC0(pObj) ); +} +void Bmc_CexCarePropagateFwd( Gia_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vPriosIn, Vec_Int_t * vPriosFf ) +{ + Gia_Obj_t * pObjRo, * pObjRi; + int i, f, ValueMax = Abc_Var2Lit( pCex->nPis * (pCex->iFrame + 1), 0 ); + Gia_ManConst0( p )->Value = ValueMax; + Gia_ManForEachRi( p, pObjRi, i ) + pObjRi->Value = ValueMax; + Vec_IntClear( vPriosFf ); + for ( f = 0; f <= pCex->iFrame; f++ ) + { + Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) + Vec_IntPush( vPriosFf, (pObjRo->Value = pObjRi->Value) ); + Bmc_CexCarePropagateFwdOne( p, pCex, f, vPriosIn ); + } +} + +/**Function************************************************************* + + Synopsis [Backward propagation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bmc_CexCarePropagateBwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, Abc_Cex_t * pCexMin ) +{ + Gia_Obj_t * pObj, * pFan0, * pFan1; + int i, Phase0, Phase1; + Gia_ManForEachCi( p, pObj, i ) pObj->fPhase = 0; Gia_ManForEachCo( p, pObj, i ) if ( pObj->fPhase ) @@ -171,45 +165,37 @@ void Bmc_CexCarePropagateBwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, int fGr { if ( !pObj->fPhase ) continue; - Phase0 = Abc_LitIsCompl(Gia_ObjFanin0(pObj)->Value) ^ Gia_ObjFaninC0(pObj); - Phase1 = Abc_LitIsCompl(Gia_ObjFanin1(pObj)->Value) ^ Gia_ObjFaninC1(pObj); + pFan0 = Gia_ObjFanin0(pObj); + pFan1 = Gia_ObjFanin1(pObj); + Phase0 = Abc_LitIsCompl(pFan0->Value) ^ Gia_ObjFaninC0(pObj); + Phase1 = Abc_LitIsCompl(pFan1->Value) ^ Gia_ObjFaninC1(pObj); if ( Phase0 && Phase1 ) { - Gia_ObjFanin0(pObj)->fPhase = 1; - Gia_ObjFanin1(pObj)->fPhase = 1; + pFan0->fPhase = 1; + pFan1->fPhase = 1; } - else if ( Phase0 && !Phase1 ) - Gia_ObjFanin1(pObj)->fPhase = 1; - else if ( !Phase0 && Phase1 ) - Gia_ObjFanin0(pObj)->fPhase = 1; + else if ( Phase0 ) + pFan1->fPhase = 1; + else if ( Phase1 ) + pFan0->fPhase = 1; else // if ( !Phase0 && !Phase1 ) { - if ( Gia_ObjFanin0(pObj)->fPhase || Gia_ObjFanin1(pObj)->fPhase ) + if ( pFan0->fPhase || pFan1->fPhase ) continue; - if ( Gia_ObjIsPi(p, Gia_ObjFanin0(pObj)) ) - Gia_ObjFanin0(pObj)->fPhase = 1; - else if ( Gia_ObjIsPi(p, Gia_ObjFanin1(pObj)) ) - Gia_ObjFanin1(pObj)->fPhase = 1; -// else if ( Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) && Txs_ObjIsJust(p, Gia_ObjFanin0(pObj)) ) -// Gia_ObjFanin0(pObj)->fPhase = 1; -// else if ( Gia_ObjIsAnd(Gia_ObjFanin1(pObj)) && Txs_ObjIsJust(p, Gia_ObjFanin1(pObj)) ) -// Gia_ObjFanin1(pObj)->fPhase = 1; + if ( Gia_ObjIsPi(p, pFan0) ) + pFan0->fPhase = 1; + else if ( Gia_ObjIsPi(p, pFan1) ) + pFan1->fPhase = 1; +// else if ( Gia_ObjIsAnd(pFan0) && Txs_ObjIsJust(p, pFan0) ) +// pFan0->fPhase = 1; +// else if ( Gia_ObjIsAnd(pFan1) && Txs_ObjIsJust(p, pFan1) ) +// pFan1->fPhase = 1; else { - if ( fGrow & 1 ) - { - if ( Abc_Lit2Var(Gia_ObjFanin0(pObj)->Value) >= Abc_Lit2Var(Gia_ObjFanin1(pObj)->Value) ) - Gia_ObjFanin0(pObj)->fPhase = 1; - else - Gia_ObjFanin1(pObj)->fPhase = 1; - } + if ( Abc_Lit2Var(pFan0->Value) > Abc_Lit2Var(pFan1->Value) ) + pFan0->fPhase = 1; else - { - if ( Abc_Lit2Var(Gia_ObjFanin0(pObj)->Value) <= Abc_Lit2Var(Gia_ObjFanin1(pObj)->Value) ) - Gia_ObjFanin0(pObj)->fPhase = 1; - else - Gia_ObjFanin1(pObj)->fPhase = 1; - } + pFan1->fPhase = 1; } } } @@ -217,23 +203,23 @@ void Bmc_CexCarePropagateBwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, int fGr if ( pObj->fPhase ) Abc_InfoSetBit( pCexMin->pData, pCexMin->nRegs + pCexMin->nPis * f + i ); } -Abc_Cex_t * Bmc_CexCarePropagateBwd( Gia_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vPrios, int fGrow ) +Abc_Cex_t * Bmc_CexCarePropagateBwd( Gia_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vPriosIn, Vec_Int_t * vPriosFf ) { Abc_Cex_t * pCexMin; - Gia_Obj_t * pObj, * pObjRo, * pObjRi; + Gia_Obj_t * pObjRo, * pObjRi; int f, i; pCexMin = Abc_CexAlloc( pCex->nRegs, pCex->nPis, pCex->iFrame + 1 ); pCexMin->iPo = pCex->iPo; pCexMin->iFrame = pCex->iFrame; - Gia_ManForEachCo( p, pObj, i ) - pObj->fPhase = 0; + Gia_ManForEachCo( p, pObjRi, i ) + pObjRi->fPhase = 0; for ( f = pCex->iFrame; f >= 0; f-- ) { Gia_ManPo(p, pCex->iPo)->fPhase = (int)(f == pCex->iFrame); - Gia_ManForEachRo( p, pObj, i ) - pObj->Value = Vec_IntEntry( vPrios, f * pCex->nRegs + i ); - Bmc_CexCarePropagateFwdOne( p, pCex, f, fGrow ); - Bmc_CexCarePropagateBwdOne( p, pCex, f, fGrow, pCexMin ); + Gia_ManForEachRo( p, pObjRo, i ) + pObjRo->Value = Vec_IntEntry( vPriosFf, f * pCex->nRegs + i ); + Bmc_CexCarePropagateFwdOne( p, pCex, f, vPriosIn ); + Bmc_CexCarePropagateBwdOne( p, pCex, f, pCexMin ); Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) pObjRi->fPhase = pObjRo->fPhase; } @@ -265,12 +251,12 @@ Abc_Cex_t * Bmc_CexCareTotal( Abc_Cex_t ** pCexes, int nCexes ) } return pCexMin; } -Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, Abc_Cex_t * pCex, int fCheck, int fVerbose ) +Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nPPis, Abc_Cex_t * pCex, int fCheck, int fVerbose ) { int nTryCexes = 4; // belongs to range [1;4] Abc_Cex_t * pCexBest, * pCexMin[4] = {NULL}; - int k, nOnesBest, nOnesCur; - Vec_Int_t * vPrios; + int k, f, i, nOnesBest, nOnesCur, Counter = 0; + Vec_Int_t * vPriosIn, * vPriosFf; if ( pCex->nPis != Gia_ManPiNum(p) ) { printf( "Given CEX does to have same number of inputs as the AIG.\n" ); @@ -292,30 +278,118 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, Abc_Cex_t * pCex, int fCheck, if ( fVerbose ) { printf( "Original : " ); - Bmc_CexPrint( pCex, Gia_ManPiNum(p), 0 ); + Bmc_CexPrint( pCex, Gia_ManPiNum(p) - nPPis, 0 ); } - vPrios = Vec_IntAlloc( pCex->nRegs * (pCex->iFrame + 1) ); + vPriosIn = Vec_IntAlloc( pCex->nPis * (pCex->iFrame + 1) ); + vPriosFf = Vec_IntAlloc( pCex->nRegs * (pCex->iFrame + 1) ); for ( k = 0; k < nTryCexes; k++ ) { - Bmc_CexCarePropagateFwd(p, pCex, k, vPrios ); - assert( Vec_IntSize(vPrios) == pCex->nRegs * (pCex->iFrame + 1) ); + Counter = 0; + Vec_IntFill( vPriosIn, pCex->nPis * (pCex->iFrame + 1), 0 ); +/* + if ( k == 0 ) + { + for ( f = 0; f <= pCex->iFrame; f++ ) + for ( i = nPPis; i < Gia_ManPiNum(p); i++ ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + for ( f = 0; f <= pCex->iFrame; f++ ) + for ( i = 0; i < nPPis; i++ ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + } + else if ( k == 1 ) + { + for ( f = pCex->iFrame; f >= 0; f-- ) + for ( i = nPPis; i < Gia_ManPiNum(p); i++ ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + for ( f = pCex->iFrame; f >= 0; f-- ) + for ( i = 0; i < nPPis; i++ ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + } + else if ( k == 2 ) + { + for ( f = 0; f <= pCex->iFrame; f++ ) + for ( i = Gia_ManPiNum(p) - 1; i >= nPPis; i-- ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + for ( f = 0; f <= pCex->iFrame; f++ ) + for ( i = nPPis - 1; i >= 0; i-- ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + } + else if ( k == 3 ) + { + for ( f = pCex->iFrame; f >= 0; f-- ) + for ( i = Gia_ManPiNum(p) - 1; i >= nPPis; i-- ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + for ( f = pCex->iFrame; f >= 0; f-- ) + for ( i = nPPis - 1; i >= 0; i-- ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + } + else assert( 0 ); +*/ + if ( k == 0 ) + { + for ( f = pCex->iFrame; f >= 0; f-- ) + for ( i = nPPis; i < Gia_ManPiNum(p); i++ ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + for ( f = pCex->iFrame; f >= 0; f-- ) + for ( i = 0; i < nPPis; i++ ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + } + else if ( k == 1 ) + { + for ( f = pCex->iFrame; f >= 0; f-- ) + for ( i = nPPis; i < Gia_ManPiNum(p); i++ ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + for ( f = pCex->iFrame; f >= 0; f-- ) + for ( i = nPPis - 1; i >= 0; i-- ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + } + else if ( k == 2 ) + { + for ( f = pCex->iFrame; f >= 0; f-- ) + for ( i = Gia_ManPiNum(p) - 1; i >= nPPis; i-- ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + for ( f = pCex->iFrame; f >= 0; f-- ) + for ( i = 0; i < nPPis; i++ ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + } + else if ( k == 3 ) + { + for ( f = pCex->iFrame; f >= 0; f-- ) + for ( i = Gia_ManPiNum(p) - 1; i >= nPPis; i-- ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + for ( f = pCex->iFrame; f >= 0; f-- ) + for ( i = nPPis - 1; i >= 0; i-- ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + } + else assert( 0 ); + + assert( Counter == pCex->nPis * (pCex->iFrame + 1) ); + Bmc_CexCarePropagateFwd( p, pCex, vPriosIn, vPriosFf ); + assert( Vec_IntSize(vPriosFf) == pCex->nRegs * (pCex->iFrame + 1) ); if ( !Abc_LitIsCompl(Gia_ManPo(p, pCex->iPo)->Value) ) { printf( "Counter-example is invalid.\n" ); - Vec_IntFree( vPrios ); + Vec_IntFree( vPriosIn ); + Vec_IntFree( vPriosFf ); return NULL; } - pCexMin[k] = Bmc_CexCarePropagateBwd( p, pCex, vPrios, k ); + pCexMin[k] = Bmc_CexCarePropagateBwd( p, pCex, vPriosIn, vPriosFf ); if ( fVerbose ) { - if ( (k & 1) ) - printf( "Decrease : " ); - else - printf( "Increase : " ); - Bmc_CexPrint( pCexMin[k], Gia_ManPiNum(p), 0 ); + if ( k == 0 ) + printf( "PiUp FrUp: " ); + else if ( k == 1 ) + printf( "PiUp FrDn: " ); + else if ( k == 2 ) + printf( "PiDn FrUp: " ); + else if ( k == 3 ) + printf( "PiDn FrDn: " ); + else assert( 0 ); + Bmc_CexPrint( pCexMin[k], Gia_ManPiNum(p) - nPPis, 0 ); } } - Vec_IntFree( vPrios ); + Vec_IntFree( vPriosIn ); + Vec_IntFree( vPriosFf ); // select the best one pCexBest = pCexMin[0]; nOnesBest = Abc_CexCountOnes(pCexMin[0]); @@ -330,12 +404,12 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, Abc_Cex_t * pCex, int fCheck, } if ( fVerbose ) { - Abc_Cex_t * pTotal = Bmc_CexCareTotal( pCexMin, nTryCexes ); + //Abc_Cex_t * pTotal = Bmc_CexCareTotal( pCexMin, nTryCexes ); printf( "Final : " ); - Bmc_CexPrint( pCexBest, Gia_ManPiNum(p), 0 ); - printf( "Total : " ); - Bmc_CexPrint( pTotal, Gia_ManPiNum(p), 0 ); - Abc_CexFreeP( &pTotal ); + Bmc_CexPrint( pCexBest, Gia_ManPiNum(p) - nPPis, 0 ); + //printf( "Total : " ); + //Bmc_CexPrint( pTotal, Gia_ManPiNum(p) - nPPis, 0 ); + //Abc_CexFreeP( &pTotal ); } for ( k = 0; k < nTryCexes; k++ ) if ( pCexBest != pCexMin[k] ) @@ -347,10 +421,10 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, Abc_Cex_t * pCex, int fCheck, printf( "Counter-example verification succeeded.\n" ); return pCexBest; } -Abc_Cex_t * Bmc_CexCareMinimize( Aig_Man_t * p, Abc_Cex_t * pCex, int fCheck, int fVerbose ) +Abc_Cex_t * Bmc_CexCareMinimize( Aig_Man_t * p, int nPPis, Abc_Cex_t * pCex, int fCheck, int fVerbose ) { Gia_Man_t * pGia = Gia_ManFromAigSimple( p ); - Abc_Cex_t * pCexMin = Bmc_CexCareMinimizeAig( pGia, pCex, fCheck, fVerbose ); + Abc_Cex_t * pCexMin = Bmc_CexCareMinimizeAig( pGia, nPPis, pCex, fCheck, fVerbose ); Gia_ManStop( pGia ); return pCexMin; } @@ -382,7 +456,14 @@ void Bmc_CexCareVerify( Aig_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t * pCexMin, in printf( "Counter-example verification succeeded.\n" ); Gia_ManStop( pGia ); } - +/* + { + Aig_Man_t * pAig = Abc_NtkToDar( pNtk, 0, 1 ); + Abc_Cex_t * pCex = Bmc_CexCareMinimize( pAig, 3*Saig_ManPiNum(pAig)/4, pAbc->pCex, 1, 1 ); + Aig_ManStop( pAig ); + Abc_CexFree( pCex ); + } +*/ //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/sat/bmc/bmcCexTools.c b/src/sat/bmc/bmcCexTools.c index 1c0d798ca..9c80b2781 100644 --- a/src/sat/bmc/bmcCexTools.c +++ b/src/sat/bmc/bmcCexTools.c @@ -304,10 +304,10 @@ void Bmc_CexBuildNetworkTest( Gia_Man_t * p, Abc_Cex_t * pCex ) SeeAlso [] ***********************************************************************/ -void Bmc_CexPrint( Abc_Cex_t * pCex, int nInputs, int fVerbose ) +void Bmc_CexPrint( Abc_Cex_t * pCex, int nRealPis, int fVerbose ) { int i, k, Count, iBit = pCex->nRegs; - Abc_CexPrintStatsInputs( pCex, nInputs ); + Abc_CexPrintStatsInputs( pCex, nRealPis ); if ( !fVerbose ) return; @@ -315,7 +315,7 @@ void Bmc_CexPrint( Abc_Cex_t * pCex, int nInputs, int fVerbose ) { Count = 0; printf( "%3d : ", i ); - for ( k = 0; k < nInputs; k++ ) + for ( k = 0; k < nRealPis; k++ ) { Count += Abc_InfoHasBit(pCex->pData, iBit); printf( "%d", Abc_InfoHasBit(pCex->pData, iBit++) ); From fce2b16a602dcdd3bef8529e51f9a06c2aaf1fec Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 10 Feb 2017 13:31:29 -0800 Subject: [PATCH 124/185] Re-introducing floating-point activity in the SAT solver. --- src/base/abci/abc.c | 8 ++++++-- src/proof/pdr/pdr.h | 1 + src/proof/pdr/pdrInt.h | 1 + src/proof/pdr/pdrMan.c | 3 +++ 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 26e9c0f8e..72fcafe2b 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26157,7 +26157,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Pdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmuyfsipdegoncvwzh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmuyfsipdegonctvwzh" ) ) != EOF ) { switch ( c ) { @@ -26308,6 +26308,9 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'c': pPars->fCtgs ^= 1; break; + case 't': + pPars->fUseAbs ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; @@ -26349,7 +26352,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmuyfsipdegoncvwzh]\n" ); + Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmuyfsipdegonctvwzh]\n" ); Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); @@ -26378,6 +26381,7 @@ usage: Abc_Print( -2, "\t-o : toggle using property output as inductive hypothesis [default = %s]\n", pPars->fUsePropOut? "yes": "no" ); Abc_Print( -2, "\t-n : * toggle skipping \'down\' in generalization [default = %s]\n", pPars->fSkipDown? "yes": "no" ); Abc_Print( -2, "\t-c : * toggle handling CTGs in \'down\' [default = %s]\n", pPars->fCtgs? "yes": "no" ); + Abc_Print( -2, "\t-t : toggle using abstraction [default = %s]\n", pPars->fUseAbs? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-w : toggle printing detailed stats default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); Abc_Print( -2, "\t-z : toggle suppressing report about solved outputs [default = %s]\n", pPars->fNotVerbose? "yes": "no" ); diff --git a/src/proof/pdr/pdr.h b/src/proof/pdr/pdr.h index 66990bfb0..333975882 100644 --- a/src/proof/pdr/pdr.h +++ b/src/proof/pdr/pdr.h @@ -63,6 +63,7 @@ struct Pdr_Par_t_ int fSkipGeneral; // skips expensive generalization step int fSkipDown; // skips the application of down int fCtgs; // handle CTGs in down + int fUseAbs; // use abstraction int fVerbose; // verbose output` int fVeryVerbose; // very verbose output int fNotVerbose; // not printing line by line progress diff --git a/src/proof/pdr/pdrInt.h b/src/proof/pdr/pdrInt.h index dae20f0cd..fb6717003 100644 --- a/src/proof/pdr/pdrInt.h +++ b/src/proof/pdr/pdrInt.h @@ -90,6 +90,7 @@ struct Pdr_Man_t_ int * pOrder; // ordering of the lits Vec_Int_t * vActVars; // the counter of activation variables int iUseFrame; // the first used frame + Vec_Int_t * vAbs; // abstraction (mapping abstracted flop ID into its PPIs number) // terminary simulation Txs_Man_t * pTxs; // internal use diff --git a/src/proof/pdr/pdrMan.c b/src/proof/pdr/pdrMan.c index f9a14a07c..b2df5e016 100644 --- a/src/proof/pdr/pdrMan.c +++ b/src/proof/pdr/pdrMan.c @@ -286,6 +286,8 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio p->vCi2Rem = Vec_IntAlloc( 100 ); // CIs to be removed p->vRes = Vec_IntAlloc( 100 ); // final result p->pCnfMan = Cnf_ManStart(); + if ( p->vAbs ) + p->vAbs = Vec_IntStart( Aig_ManRegNum(pAig) ); // ternary simulation p->pTxs = pPars->fNewXSim ? Txs_ManStart( p, pAig, p->vPrio ) : NULL; // additional AIG data-members @@ -368,6 +370,7 @@ void Pdr_ManStop( Pdr_Man_t * p ) Vec_WecFreeP( &p->vVLits ); // CNF manager Cnf_ManStop( p->pCnfMan ); + Vec_IntFreeP( &p->vAbs ); // terminary simulation if ( p->pPars->fNewXSim ) Txs_ManStop( p->pTxs ); From 342d2d9f5cd3f89289d84e2dc695516ec959e252 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Fri, 10 Feb 2017 17:26:45 -0800 Subject: [PATCH 125/185] New fixed point data type. Expose all options to command line. Expose search statistics to users. --- src/base/abci/abc.c | 218 ++++++++++++++++++++++++++++++++++- src/sat/satoko/act_var.h | 38 +++++- src/sat/satoko/satoko.h | 27 ++++- src/sat/satoko/solver.h | 13 --- src/sat/satoko/solver_api.c | 11 +- src/sat/satoko/types.h | 32 ++--- src/sat/satoko/utils/fixed.h | 67 +++++++++++ 7 files changed, 363 insertions(+), 43 deletions(-) create mode 100644 src/sat/satoko/utils/fixed.h diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 26e9c0f8e..ea0ed3770 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -23326,7 +23326,11 @@ int Abc_CommandSatoko( Abc_Frame_t * pAbc, int argc, char ** argv ) satoko_default_opts(&opts); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Chv" ) ) != EOF ) +#ifdef SATOKO_ACT_VAR_FIXED + while ( ( c = Extra_UtilGetopt( argc, argv, "CPDEFGHIJKLMNOQRSTUhv" ) ) != EOF ) +#else + while ( ( c = Extra_UtilGetopt( argc, argv, "CPDEFGHIJKLMNOQRShv" ) ) != EOF ) +#endif { switch ( c ) { @@ -23341,6 +23345,184 @@ int Abc_CommandSatoko( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( opts.conf_limit < 0 ) goto usage; break; + case 'P': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-P\" should be followed by an integer.\n" ); + goto usage; + } + opts.prop_limit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.prop_limit < 0 ) + goto usage; + break; + case 'D': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-D\" should be followed by an float.\n" ); + goto usage; + } + opts.f_rst = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.f_rst < 0 ) + goto usage; + break; + case 'E': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-E\" should be followed by an float.\n" ); + goto usage; + } + opts.b_rst = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.b_rst < 0 ) + goto usage; + break; + case 'F': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" ); + goto usage; + } + opts.fst_block_rst = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'G': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-G\" should be followed by an integer.\n" ); + goto usage; + } + opts.sz_lbd_bqueue = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'H': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-H\" should be followed by an integer.\n" ); + goto usage; + } + opts.sz_trail_bqueue = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'I': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); + goto usage; + } + opts.n_conf_fst_reduce = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'J': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-J\" should be followed by an integer.\n" ); + goto usage; + } + opts.inc_reduce = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'K': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-K\" should be followed by an integer.\n" ); + goto usage; + } + opts.inc_special_reduce = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'L': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-L\" should be followed by an integer.\n" ); + goto usage; + } + opts.lbd_freeze_clause = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'M': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + goto usage; + } + opts.learnt_ratio = atof(argv[globalUtilOptind]) / 100; + globalUtilOptind++; + if ( opts.learnt_ratio < 0 ) + goto usage; + break; + case 'N': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + goto usage; + } + opts.garbage_max_ratio = atof(argv[globalUtilOptind]) / 100; + globalUtilOptind++; + if ( opts.garbage_max_ratio < 0 ) + goto usage; + break; + case 'O': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" ); + goto usage; + } + opts.clause_max_sz_bin_resol = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'Q': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" ); + goto usage; + } + opts.clause_min_lbd_bin_resol = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'R': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-R\" should be followed by an float.\n" ); + goto usage; + } + opts.clause_decay = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.clause_decay < 0 ) + goto usage; + break; + case 'S': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-S\" should be followed by an float.\n" ); + goto usage; + } + opts.var_decay = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.var_decay < 0 ) + goto usage; + break; +#ifdef SATOKO_ACT_VAR_FIXED + case 'T': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-T\" should be followed by an float.\n" ); + goto usage; + } + opts.var_act_limit = (unsigned)strtol(argv[globalUtilOptind], NULL, 16); + globalUtilOptind++; + break; + case 'U': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-U\" should be followed by an float.\n" ); + goto usage; + } + opts.var_act_rescale = (unsigned)strtol(argv[globalUtilOptind], NULL, 16); + globalUtilOptind++; + break; +#endif case 'h': goto usage; case 'v': @@ -23379,9 +23561,37 @@ int Abc_CommandSatoko( Abc_Frame_t * pAbc, int argc, char ** argv ) } usage: - Abc_Print( -2, "usage: satoko [-CILDE num] [-hv].cnf\n" ); +#ifdef SATOKO_ACT_VAR_FIXED + Abc_Print( -2, "usage: satoko [-CPDEFGHIJKLMNOQRSTU num] [-hv].cnf\n" ); +#else + Abc_Print( -2, "usage: satoko [-CPDEFGHIJKLMNOQRS num] [-hv].cnf\n" ); +#endif Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", opts.conf_limit ); - Abc_Print( -2, "\t-v : prints verbose information [default = %s]\n", opts.verbose? "yes": "no" ); + Abc_Print( -2, "\t-P num : limit on the number of propagations [default = %d]\n", opts.conf_limit ); + Abc_Print( -2, "\n\tConstants used for restart heuristic:\n"); + Abc_Print( -2, "\t-D num : Constant value used by restart heuristics in forcing restarts [default = %f]\n", opts.f_rst ); + Abc_Print( -2, "\t-E num : Constant value used by restart heuristics in blocking restarts [default = %f]\n", opts.b_rst ); + Abc_Print( -2, "\t-F num : Lower bound n.of conflicts for start blocking restarts [default = %d]\n", opts.fst_block_rst ); + Abc_Print( -2, "\t-G num : Size of the moving avarege queue for LBD (force restart) [default = %d]\n", opts.sz_lbd_bqueue ); + Abc_Print( -2, "\t-H num : Size of the moving avarege queue for Trail size (block restart) [default = %d]\n", opts.sz_trail_bqueue ); + Abc_Print( -2, "\n\tConstants used for clause database reduction heuristic:\n"); + Abc_Print( -2, "\t-I num : N.of conflicts before first clause databese reduction [default = %d]\n", opts.n_conf_fst_reduce ); + Abc_Print( -2, "\t-J num : Increment to reduce [default = %d]\n", opts.inc_reduce ); + Abc_Print( -2, "\t-K num : Special increment to reduce [default = %d]\n", opts.inc_special_reduce ); + Abc_Print( -2, "\t-L num : Protecs clauses from deletion for one turn if its LBD is lower [default = %d]\n", opts.lbd_freeze_clause ); + Abc_Print( -2, "\t-M num : Percentage of learned clauses to remove [default = %d]\n", ( int )( 100 * opts.learnt_ratio ) ); + Abc_Print( -2, "\t-N num : Max percentage of garbage in clause database [default = %d]\n", ( int )( 100 * opts.garbage_max_ratio ) ); + Abc_Print( -2, "\n\tConstants used for binary resolution (clause minimization):\n"); + Abc_Print( -2, "\t-O num : Max clause size for binary resolution [default = %d]\n", opts.clause_max_sz_bin_resol ); + Abc_Print( -2, "\t-Q num : Min clause LBD for binary resolution [default = %d]\n", opts.clause_min_lbd_bin_resol ); + Abc_Print( -2, "\n\tConstants used for branching (VSIDS heuristic):\n"); + Abc_Print( -2, "\t-R num : Clause activity decay factor (when using float clause activity) [default = %f]\n", opts.clause_decay ); + Abc_Print( -2, "\t-S num : Varibale activity decay factor [default = %f]\n", opts.var_decay ); +#ifdef SATOKO_ACT_VAR_FIXED + Abc_Print( -2, "\t-T num : Variable activity limit valeu [default = 0x%08X]\n", opts.var_act_limit ); + Abc_Print( -2, "\t-U num : Variable activity re-scale factor [default = 0x%08X]\n", opts.var_act_rescale ); +#endif + Abc_Print( -2, "\n\t-v : prints verbose information [default = %s]\n", opts.verbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } @@ -38219,7 +38429,7 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( fExtractAll ) { char Buffer[1000]; - Gia_Obj_t * pObj; + Gia_Obj_t * pObj; int i, nDigits = Abc_Base10Log(Gia_ManPoNum(pAbc->pGia)); Gia_ManForEachPo( pAbc->pGia, pObj, i ) { diff --git a/src/sat/satoko/act_var.h b/src/sat/satoko/act_var.h index aa8a76abe..b1fdb756a 100644 --- a/src/sat/satoko/act_var.h +++ b/src/sat/satoko/act_var.h @@ -16,7 +16,7 @@ #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START -#if defined SATOKO_ACT_VAR_DBLE || defined SATOKO_ACT_VAR_FLOAT +#if defined SATOKO_ACT_VAR_DBLE /** Re-scale the activity value for all variables. */ static inline void var_act_rescale(solver_t *s) @@ -25,8 +25,8 @@ static inline void var_act_rescale(solver_t *s) act_t *activity = vec_act_data(s->activity); for (i = 0; i < vec_act_size(s->activity); i++) - activity[i] *= VAR_ACT_RESCALE; - s->var_act_inc *= VAR_ACT_RESCALE; + activity[i] *= s->opts.var_act_rescale; + s->var_act_inc *= s->opts.var_act_rescale; } /** Increment the activity value of one variable ('var') @@ -36,7 +36,7 @@ static inline void var_act_bump(solver_t *s, unsigned var) act_t *activity = vec_act_data(s->activity); activity[var] += s->var_act_inc; - if (activity[var] > VAR_ACT_LIMIT) + if (activity[var] > s->opts.var_act_limit) var_act_rescale(s); if (heap_in_heap(s->var_order, var)) heap_decrease(s->var_order, var); @@ -49,6 +49,34 @@ static inline void var_act_decay(solver_t *s) s->var_act_inc *= (1 / s->opts.var_decay); } +#elif defined(SATOKO_ACT_VAR_FIXED) + +static inline void var_act_rescale(solver_t *s) +{ + unsigned i; + act_t *activity = (act_t *)vec_act_data(s->activity); + + for (i = 0; i < vec_act_size(s->activity); i++) + activity[i] = fixed_mult(activity[i], VAR_ACT_RESCALE); + s->var_act_inc = fixed_mult(s->var_act_inc, VAR_ACT_RESCALE); +} + +static inline void var_act_bump(solver_t *s, unsigned var) +{ + act_t *activity = (act_t *)vec_act_data(s->activity); + + activity[var] = fixed_add(activity[var], s->var_act_inc); + if (activity[var] > VAR_ACT_LIMIT) + var_act_rescale(s); + if (heap_in_heap(s->var_order, var)) + heap_decrease(s->var_order, var); +} + +static inline void var_act_decay(solver_t *s) +{ + s->var_act_inc = fixed_mult(s->var_act_inc, dble2fixed(1 / s->opts.var_decay)); +} + #else static inline void var_act_rescale(solver_t *s) @@ -77,7 +105,7 @@ static inline void var_act_decay(solver_t *s) s->var_act_inc += (s->var_act_inc >> 4); } -#endif /* SATOKO_ACT_VAR_DBLE || SATOKO_ACT_VAR_FLOAT */ +#endif /* SATOKO_ACT_VAR_DBLE || SATOKO_ACT_VAR_FIXED */ ABC_NAMESPACE_HEADER_END #endif /* satoko__act_var_h */ diff --git a/src/sat/satoko/satoko.h b/src/sat/satoko/satoko.h index fb07c6f9f..363fe2fd3 100644 --- a/src/sat/satoko/satoko.h +++ b/src/sat/satoko/satoko.h @@ -32,7 +32,7 @@ typedef struct satoko_opts satoko_opts_t; struct satoko_opts { /* Limits */ long conf_limit; /* Limit on the n.of conflicts */ - long prop_limit; /* Limit on the n.of implications */ + long prop_limit; /* Limit on the n.of propagations */ /* Constants used for restart heuristic */ double f_rst; /* Used to force a restart */ @@ -42,7 +42,7 @@ struct satoko_opts { unsigned sz_trail_bqueue; /* Size of the moving avarege queue for Trail size (block restart) */ /* Constants used for clause database reduction heuristic */ - unsigned n_conf_fst_reduce; /* N.of conflicts before first reduction */ + unsigned n_conf_fst_reduce; /* N.of conflicts before first clause databese reduction */ unsigned inc_reduce; /* Increment to reduce */ unsigned inc_special_reduce; /* Special increment to reduce */ unsigned lbd_freeze_clause; @@ -50,7 +50,9 @@ struct satoko_opts { /* VSIDS heuristic */ float clause_decay; - act_t var_decay; + double var_decay; + act_t var_act_limit; + act_t var_act_rescale; /* Binary resolution */ unsigned clause_max_sz_bin_resol; @@ -59,6 +61,21 @@ struct satoko_opts { char verbose; }; +typedef struct satoko_stats satoko_stats_t; +struct satoko_stats { + unsigned n_starts; + unsigned n_reduce_db; + + long n_decisions; + long n_propagations; + long n_inspects; + long n_conflicts; + + long n_original_lits; + long n_learnt_lits; +}; + + //===------------------------------------------------------------------------=== extern satoko_t *satoko_create(void); extern void satoko_destroy(satoko_t *); @@ -81,7 +98,9 @@ extern int satoko_solve(satoko_t *); * - The return value is either the size of the array or -1 in case the final * conflict cluase was not generated. */ -extern int satoko_final_conflict(satoko_t *, unsigned *); +extern int satoko_final_conflict(satoko_t *, unsigned *); + +extern satoko_stats_t satoko_stats(satoko_t *); ABC_NAMESPACE_HEADER_END #endif /* satoko__satoko_h */ diff --git a/src/sat/satoko/solver.h b/src/sat/satoko/solver.h index fe1d1ef59..a46b0c9dc 100644 --- a/src/sat/satoko/solver.h +++ b/src/sat/satoko/solver.h @@ -38,19 +38,6 @@ enum { #define UNDEF 0xFFFFFFFF -struct satoko_stats { - unsigned n_starts; - unsigned n_reduce_db; - - long n_decisions; - long n_propagations; - long n_inspects; - long n_conflicts; - - long n_original_lits; - long n_learnt_lits; -}; - typedef struct solver_t_ solver_t; struct solver_t_ { /* User data */ diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c index 980cc160d..ccab7685f 100644 --- a/src/sat/satoko/solver_api.c +++ b/src/sat/satoko/solver_api.c @@ -12,8 +12,8 @@ #include #include "act_var.h" -#include "utils/misc.h" #include "solver.h" +#include "utils/misc.h" #include "misc/util/abc_global.h" ABC_NAMESPACE_IMPL_START @@ -167,7 +167,9 @@ void satoko_default_opts(satoko_opts_t *opts) opts->lbd_freeze_clause = 30; opts->learnt_ratio = 0.5; /* VSIDS heuristic */ - opts->var_decay = (act_t) 0.95; + opts->var_act_limit = VAR_ACT_LIMIT; + opts->var_act_rescale = VAR_ACT_RESCALE; + opts->var_decay = VAR_ACT_DECAY; opts->clause_decay = (clause_act_t) 0.995; /* Binary resolution */ opts->clause_max_sz_bin_resol = 30; @@ -308,4 +310,9 @@ int satoko_final_conflict(solver_t *s, unsigned *out) } +satoko_stats_t satoko_stats(satoko_t *s) +{ + return s->stats; +} + ABC_NAMESPACE_IMPL_END diff --git a/src/sat/satoko/types.h b/src/sat/satoko/types.h index ee9363bc3..7865ab0ee 100644 --- a/src/sat/satoko/types.h +++ b/src/sat/satoko/types.h @@ -9,21 +9,22 @@ #ifndef satoko__types_h #define satoko__types_h +#include "utils/fixed.h" #include "utils/vec/vec_dble.h" -#include "utils/vec/vec_flt.h" #include "utils/vec/vec_uint.h" #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START -// #define SATOKO_ACT_VAR_DBLE -// #define SATOKO_ACT_VAR_FLOAT +#define SATOKO_ACT_VAR_DBLE +// #define SATOKO_ACT_VAR_FIXED // #define SATOKO_ACT_CLAUSE_FLOAT #ifdef SATOKO_ACT_VAR_DBLE #define VAR_ACT_INIT_INC 1.0 #define VAR_ACT_LIMIT (double)1e100 #define VAR_ACT_RESCALE (double)1e-100 + #define VAR_ACT_DECAY (double)0.95 typedef double act_t; typedef vec_dble_t vec_act_t ; #define vec_act_alloc(size) vec_dble_alloc(size) @@ -32,18 +33,19 @@ ABC_NAMESPACE_HEADER_START #define vec_act_data(vec) vec_dble_data(vec) #define vec_act_at(vec, idx) vec_dble_at(vec, idx) #define vec_act_push_back(vec, value) vec_dble_push_back(vec, value) -#elif defined(SATOKO_ACT_VAR_FLOAT) - #define VAR_ACT_INIT_INC 1.0 - #define VAR_ACT_LIMIT (float)1e20 - #define VAR_ACT_RESCALE (float)1e-20 - typedef float act_t; - typedef vec_flt_t vec_act_t ; - #define vec_act_alloc(size) vec_flt_alloc(size) - #define vec_act_free(vec) vec_flt_free(vec) - #define vec_act_size(vec) vec_flt_size(vec) - #define vec_act_data(vec) vec_flt_data(vec) - #define vec_act_at(vec, idx) vec_flt_at(vec, idx) - #define vec_act_push_back(vec, value) vec_flt_push_back(vec, value) +#elif defined(SATOKO_ACT_VAR_FIXED) + #define VAR_ACT_INIT_INC FIXED_ONE + #define VAR_ACT_LIMIT (fixed_t)0xDFFFFFFF + #define VAR_ACT_RESCALE (fixed_t)0x00000012 + #define VAR_ACT_DECAY (double)0.96 + typedef fixed_t act_t; + typedef vec_uint_t vec_act_t; + #define vec_act_alloc(size) vec_uint_alloc(size) + #define vec_act_free(vec) vec_uint_free(vec) + #define vec_act_size(vec) vec_uint_size(vec) + #define vec_act_data(vec) vec_uint_data(vec) + #define vec_act_at(vec, idx) vec_uint_at(vec, idx) + #define vec_act_push_back(vec, value) vec_uint_push_back(vec, value) #else #define VAR_ACT_INIT_INC (1 << 5) typedef unsigned act_t; diff --git a/src/sat/satoko/utils/fixed.h b/src/sat/satoko/utils/fixed.h new file mode 100644 index 000000000..91fc9b79c --- /dev/null +++ b/src/sat/satoko/utils/fixed.h @@ -0,0 +1,67 @@ +//===--- sort.h -------------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__utils__fixed_h +#define satoko__utils__fixed_h + +#include "misc.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +typedef unsigned fixed_t; +static const int FIXED_W_BITS = 16; /* */ +static const int FIXED_F_BITS = 32 - FIXED_W_BITS; +static const int FIXED_F_MASK = (1 << FIXED_F_BITS) - 1; +static const fixed_t FIXED_MAX = 0xFFFFFFFF; +static const fixed_t FIXED_MIN = 0x00000000; +static const fixed_t FIXED_ONE = (1 << FIXED_F_BITS); + +/* Conversion functions */ +static inline fixed_t uint2fixed(unsigned a) { return a * FIXED_ONE; } +static inline unsigned fixed2uint(fixed_t a) +{ + return (a + (FIXED_ONE >> 1)) / FIXED_ONE; +} + +static inline float fixed2float(fixed_t a) { return (float)a / FIXED_ONE; } +static inline fixed_t float2fixed(float a) +{ + float temp = a * FIXED_ONE; + temp += (temp >= 0) ? 0.5f : -0.5f; + return (fixed_t)temp; +} + +static inline double fixed2dble(fixed_t a) { return (double)a / FIXED_ONE; } +static inline fixed_t dble2fixed(double a) +{ + double temp = a * FIXED_ONE; + temp += (temp >= 0) ? 0.5f : -0.5f; + return (fixed_t)temp; +} + +static inline fixed_t fixed_add(fixed_t a, fixed_t b) { return (a + b); } +static inline fixed_t fixed_mult(fixed_t a, fixed_t b) +{ + unsigned hi_a = (a >> FIXED_F_BITS), lo_a = (a & FIXED_F_MASK); + unsigned hi_b = (b >> FIXED_F_BITS), lo_b = (b & FIXED_F_MASK); + unsigned lo_ab = lo_a * lo_b; + unsigned ab_ab = (hi_a * lo_b) + (lo_a * hi_b); + unsigned hi_ret = (hi_a * hi_b) + (ab_ab >> FIXED_F_BITS); + unsigned lo_ret = lo_ab + (ab_ab << FIXED_W_BITS); + + /* Carry */ + if (lo_ret < lo_ab) + hi_ret++; + + return (hi_ret << FIXED_F_BITS) | (lo_ret >> FIXED_W_BITS); +} + +ABC_NAMESPACE_HEADER_END + +#endif /* satoko__utils__fixed_h */ From 8bff9aa1cd118028db47d886254dc4c76c516166 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 10 Feb 2017 17:36:20 -0800 Subject: [PATCH 126/185] Adding PDR with abstraction. --- src/aig/gia/giaDup.c | 74 ++++++++++++++++++++++ src/base/io/io.c | 2 +- src/proof/pdr/pdrCore.c | 132 +++++++++++++++++++++++---------------- src/proof/pdr/pdrInt.h | 10 ++- src/proof/pdr/pdrInv.c | 1 + src/proof/pdr/pdrMan.c | 113 +++++++++++++++++++++++++++++---- src/proof/pdr/pdrTsim.c | 36 ++++++++++- src/sat/bmc/bmc.h | 3 +- src/sat/bmc/bmcCexCare.c | 62 +++++++++--------- 9 files changed, 330 insertions(+), 103 deletions(-) diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index b0ba3472e..2a0fe6e38 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -220,6 +220,80 @@ Gia_Man_t * Gia_ManDupOrderDfs( Gia_Man_t * p ) return pNew; } +/**Function************************************************************* + + Synopsis [Duplicates AIG while putting objects in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupAbs( Gia_Man_t * p, Vec_Int_t * vMapPpi2Ff, Vec_Int_t * vMapFf2Ppi ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int k, Flop, Used; + assert( Vec_IntSize(vMapFf2Ppi) == Vec_IntSize(vMapPpi2Ff) + Vec_IntCountEntry(vMapFf2Ppi, -1) ); + Gia_ManFillValue( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManConst0(p)->Value = 0; + // create inputs + Gia_ManForEachPi( p, pObj, k ) + pObj->Value = Gia_ManAppendCi(pNew); + Vec_IntForEachEntry( vMapPpi2Ff, Flop, k ) + { + pObj = Gia_ManCi( p, Gia_ManPiNum(p) + Flop ); + pObj->Value = Gia_ManAppendCi(pNew); + } + Vec_IntForEachEntry( vMapFf2Ppi, Used, Flop ) + { + if ( Used >= 0 ) + { + assert( pObj->Value != ~0 ); + continue; + } + pObj = Gia_ManCi( p, Gia_ManPiNum(p) + Flop ); + assert( pObj->Value == ~0 ); + pObj->Value = Gia_ManAppendCi(pNew); + } + Gia_ManForEachCi( p, pObj, k ) + assert( pObj->Value != ~0 ); + // create nodes + Gia_ManForEachPo( p, pObj, k ) + Gia_ManDupOrderDfs_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Vec_IntForEachEntry( vMapFf2Ppi, Used, Flop ) + { + if ( Used >= 0 ) + continue; + pObj = Gia_ManCi( p, Gia_ManPiNum(p) + Flop ); + pObj = Gia_ObjRoToRi( p, pObj ); + Gia_ManDupOrderDfs_rec( pNew, p, Gia_ObjFanin0(pObj) ); + } + // create outputs + Gia_ManForEachPo( p, pObj, k ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Vec_IntForEachEntry( vMapFf2Ppi, Used, Flop ) + { + if ( Used >= 0 ) + continue; + pObj = Gia_ManCi( p, Gia_ManPiNum(p) + Flop ); + pObj = Gia_ObjRoToRi( p, pObj ); + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) - Vec_IntSize(vMapPpi2Ff) ); + assert( Gia_ManPiNum(pNew) == Gia_ManPiNum(p) + Vec_IntSize(vMapPpi2Ff) ); + assert( Gia_ManCiNum(pNew) == Gia_ManCiNum(p) ); + assert( Gia_ManPoNum(pNew) == Gia_ManPoNum(p) ); + assert( Gia_ManCoNum(pNew) == Gia_ManCoNum(p) - Vec_IntSize(vMapPpi2Ff) ); + return pNew; +} + + /**Function************************************************************* Synopsis [Duplicates AIG while putting objects in the DFS order.] diff --git a/src/base/io/io.c b/src/base/io/io.c index c2cf15d48..2e1ae5911 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -2420,7 +2420,7 @@ int IoCommandWriteCex( Abc_Frame_t * pAbc, int argc, char **argv ) Bmc_CexCareVerify( pAig, pCex, pCare, fVerbose ); } else - pCare = Bmc_CexCareMinimize( pAig, 0, pCex, fCheckCex, fVerbose ); + pCare = Bmc_CexCareMinimize( pAig, Saig_ManPiNum(pAig), pCex, 4, fCheckCex, fVerbose ); Aig_ManStop( pAig ); } // output flop values (unaffected by the minimization) diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index 74a15e40d..47f0ac8bc 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -420,6 +420,8 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, { assert( pCubeMin->Lits[i] >= 0 ); assert( (pCubeMin->Lits[i] / 2) < Aig_ManRegNum(p->pAig) ); + if ( (Vec_IntEntry(p->vPrio, pCubeMin->Lits[i] / 2) >> p->nPrioShift) == 0 ) + p->nAbsFlops++; Vec_IntAddToEntry( p->vPrio, pCubeMin->Lits[i] / 2, 1 << p->nPrioShift ); } @@ -778,6 +780,8 @@ int Pdr_ManBlockCube( Pdr_Man_t * p, Pdr_Set_t * pCube ) { assert( pCubeMin->Lits[i] >= 0 ); assert( (pCubeMin->Lits[i] / 2) < Aig_ManRegNum(p->pAig) ); + if ( (Vec_IntEntry(p->vPrio, pCubeMin->Lits[i] / 2) >> p->nPrioShift) == 0 ) + p->nAbsFlops++; Vec_IntAddToEntry( p->vPrio, pCubeMin->Lits[i] / 2, 1 << p->nPrioShift ); } Vec_VecPush( p->vClauses, k, pCubeMin ); // consume ref @@ -837,29 +841,43 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) Pdr_Set_t * pCube = NULL; Aig_Obj_t * pObj; Abc_Cex_t * pCexNew; - int k, RetValue = -1; + int iFrame, RetValue = -1; int nOutDigits = Abc_Base10Log( Saig_ManPoNum(p->pAig) ); abctime clkStart = Abc_Clock(), clkOne = 0; p->timeToStop = p->pPars->nTimeOut ? p->pPars->nTimeOut * CLOCKS_PER_SEC + Abc_Clock(): 0; assert( Vec_PtrSize(p->vSolvers) == 0 ); // in the multi-output mode, mark trivial POs (those fed by const0) as solved if ( p->pPars->fSolveAll ) - Saig_ManForEachPo( p->pAig, pObj, k ) + Saig_ManForEachPo( p->pAig, pObj, iFrame ) if ( Aig_ObjChild0(pObj) == Aig_ManConst0(p->pAig) ) { - Vec_IntWriteEntry( p->pPars->vOutMap, k, 1 ); // unsat + Vec_IntWriteEntry( p->pPars->vOutMap, iFrame, 1 ); // unsat p->pPars->nProveOuts++; if ( p->pPars->fUseBridge ) - Gia_ManToBridgeResult( stdout, 1, NULL, k ); + Gia_ManToBridgeResult( stdout, 1, NULL, iFrame ); } // create the first timeframe p->pPars->timeLastSolved = Abc_Clock(); - Pdr_ManCreateSolver( p, (k = 0) ); + Pdr_ManCreateSolver( p, (iFrame = 0) ); while ( 1 ) { - p->nFrames = k; - assert( k == Vec_PtrSize(p->vSolvers)-1 ); - p->iUseFrame = Abc_MaxInt(k, 1); + if ( p->pPars->fUseAbs && iFrame == 2 ) + { + int i, Prio, Num = Saig_ManPiNum(p->pAig); + assert( p->vAbsFlops == NULL ); + p->vAbsFlops = Vec_IntStart( Saig_ManRegNum(p->pAig) ); + p->vMapFf2Ppi = Vec_IntStartFull( Saig_ManRegNum(p->pAig) ); + p->vMapPpi2Ff = Vec_IntAlloc( 100 ); + Vec_IntForEachEntry( p->vPrio, Prio, i ) + if ( Prio >> p->nPrioShift ) + Vec_IntWriteEntry( p->vAbsFlops, i, 1 ); + } + if ( p->pPars->fUseAbs && p->vAbsFlops ) + printf( "Starting frame %d with %d flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops) ); + + p->nFrames = iFrame; + assert( iFrame == Vec_PtrSize(p->vSolvers)-1 ); + p->iUseFrame = Abc_MaxInt(iFrame, 1); Saig_ManForEachPo( p->pAig, pObj, p->iOutCur ) { // skip disproved outputs @@ -876,16 +894,16 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) { if ( !p->pPars->fSolveAll ) { - pCexNew = Abc_CexMakeTriv( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), k*Saig_ManPoNum(p->pAig)+p->iOutCur ); + pCexNew = Abc_CexMakeTriv( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), iFrame*Saig_ManPoNum(p->pAig)+p->iOutCur ); p->pAig->pSeqModel = pCexNew; return 0; // SAT } - pCexNew = (p->pPars->fUseBridge || p->pPars->fStoreCex) ? Abc_CexMakeTriv( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), k*Saig_ManPoNum(p->pAig)+p->iOutCur ) : (Abc_Cex_t *)(ABC_PTRINT_T)1; + pCexNew = (p->pPars->fUseBridge || p->pPars->fStoreCex) ? Abc_CexMakeTriv( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), iFrame*Saig_ManPoNum(p->pAig)+p->iOutCur ) : (Abc_Cex_t *)(ABC_PTRINT_T)1; p->pPars->nFailOuts++; if ( p->pPars->vOutMap ) Vec_IntWriteEntry( p->pPars->vOutMap, p->iOutCur, 0 ); if ( !p->pPars->fNotVerbose ) Abc_Print( 1, "Output %*d was trivially asserted in frame %2d (solved %*d out of %*d outputs).\n", - nOutDigits, p->iOutCur, k, nOutDigits, p->pPars->nFailOuts, nOutDigits, Saig_ManPoNum(p->pAig) ); + nOutDigits, p->iOutCur, iFrame, nOutDigits, p->pPars->nFailOuts, nOutDigits, Saig_ManPoNum(p->pAig) ); assert( Vec_PtrEntry(p->vCexes, p->iOutCur) == NULL ); if ( p->pPars->fUseBridge ) Gia_ManToBridgeResult( stdout, 0, pCexNew, pCexNew->iPo ); @@ -895,8 +913,8 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) if ( p->pPars->fVerbose ) Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); if ( !p->pPars->fSilent ) - Abc_Print( 1, "Quitting due to callback on fail.\n" ); - p->pPars->iFrame = k; + Abc_Print( 1, "Quitting due to callback on fail in frame %d.\n", iFrame ); + p->pPars->iFrame = iFrame; return -1; } if ( p->pPars->nFailOuts + p->pPars->nDropOuts == Saig_ManPoNum(p->pAig) ) @@ -918,11 +936,11 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) if ( p->pPars->fVerbose ) Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); if ( !p->pPars->fSilent ) - Abc_Print( 1, "Reached gap timeout (%d seconds).\n", p->pPars->nTimeOutGap ); - p->pPars->iFrame = k; + Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame ); + p->pPars->iFrame = iFrame; return -1; } - RetValue = Pdr_ManCheckCube( p, k, NULL, &pCube, p->pPars->nConfLimit, 0 ); + RetValue = Pdr_ManCheckCube( p, iFrame, NULL, &pCube, p->pPars->nConfLimit, 0 ); if ( RetValue == 1 ) break; if ( RetValue == -1 ) @@ -930,9 +948,9 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) if ( p->pPars->fVerbose ) Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); if ( p->timeToStop && Abc_Clock() > p->timeToStop ) - Abc_Print( 1, "Reached timeout (%d seconds).\n", p->pPars->nTimeOut ); + Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame ); else if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC ) - Abc_Print( 1, "Reached gap timeout (%d seconds).\n", p->pPars->nTimeOutGap ); + Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame ); else if ( p->timeToStopOne && Abc_Clock() > p->timeToStopOne ) { Pdr_QueueClean( p ); @@ -940,10 +958,10 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) break; // keep solving } else if ( p->pPars->nConfLimit ) - Abc_Print( 1, "Reached conflict limit (%d).\n", p->pPars->nConfLimit ); + Abc_Print( 1, "Reached conflict limit (%d) in frame %d.\n", p->pPars->nConfLimit, iFrame ); else if ( p->pPars->fVerbose ) - Abc_Print( 1, "Computation cancelled by the callback.\n" ); - p->pPars->iFrame = k; + Abc_Print( 1, "Computation cancelled by the callback in frame %d.\n", iFrame ); + p->pPars->iFrame = iFrame; return -1; } if ( RetValue == 0 ) @@ -954,9 +972,9 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) if ( p->pPars->fVerbose ) Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); if ( p->timeToStop && Abc_Clock() > p->timeToStop ) - Abc_Print( 1, "Reached timeout (%d seconds).\n", p->pPars->nTimeOut ); + Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame ); else if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC ) - Abc_Print( 1, "Reached gap timeout (%d seconds).\n", p->pPars->nTimeOutGap ); + Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame ); else if ( p->timeToStopOne && Abc_Clock() > p->timeToStopOne ) { Pdr_QueueClean( p ); @@ -964,25 +982,33 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) break; // keep solving } else if ( p->pPars->nConfLimit ) - Abc_Print( 1, "Reached conflict limit (%d).\n", p->pPars->nConfLimit ); + Abc_Print( 1, "Reached conflict limit (%d) in frame %d.\n", p->pPars->nConfLimit, iFrame ); else if ( p->pPars->fVerbose ) - Abc_Print( 1, "Computation cancelled by the callback.\n" ); - p->pPars->iFrame = k; + Abc_Print( 1, "Computation cancelled by the callback in frame %d.\n", iFrame ); + p->pPars->iFrame = iFrame; return -1; } if ( RetValue == 0 ) { if ( fPrintClauses ) { - Abc_Print( 1, "*** Clauses after frame %d:\n", k ); + Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame ); Pdr_ManPrintClauses( p, 0 ); } if ( p->pPars->fVerbose ) Pdr_ManPrintProgress( p, !p->pPars->fSolveAll, Abc_Clock() - clkStart ); - p->pPars->iFrame = k; + p->pPars->iFrame = iFrame; if ( !p->pPars->fSolveAll ) { - p->pAig->pSeqModel = Pdr_ManDeriveCex(p); + Abc_Cex_t * pCex = Pdr_ManDeriveCexAbs(p); + if ( pCex == NULL ) + { + assert( p->pPars->fUseAbs ); + Pdr_QueueClean( p ); + pCube = NULL; + break; // keep solving + } + p->pAig->pSeqModel = pCex; return 0; // SAT } p->pPars->nFailOuts++; @@ -997,13 +1023,13 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) if ( p->pPars->fVerbose ) Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); if ( !p->pPars->fSilent ) - Abc_Print( 1, "Quitting due to callback on fail.\n" ); - p->pPars->iFrame = k; + Abc_Print( 1, "Quitting due to callback on fail in frame %d.\n", iFrame ); + p->pPars->iFrame = iFrame; return -1; } if ( !p->pPars->fNotVerbose ) Abc_Print( 1, "Output %*d was asserted in frame %2d (%2d) (solved %*d out of %*d outputs).\n", - nOutDigits, p->iOutCur, k, k, nOutDigits, p->pPars->nFailOuts, nOutDigits, Saig_ManPoNum(p->pAig) ); + nOutDigits, p->iOutCur, iFrame, iFrame, nOutDigits, p->pPars->nFailOuts, nOutDigits, Saig_ManPoNum(p->pAig) ); if ( p->pPars->nFailOuts == Saig_ManPoNum(p->pAig) ) return 0; // all SAT Pdr_QueueClean( p ); @@ -1025,7 +1051,7 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) if ( p->pPars->vOutMap ) Vec_IntWriteEntry( p->pPars->vOutMap, p->iOutCur, -1 ); if ( !p->pPars->fNotVerbose ) - Abc_Print( 1, "Timing out on output %*d.\n", nOutDigits, p->iOutCur ); + Abc_Print( 1, "Timing out on output %*d in frame %d.\n", nOutDigits, p->iOutCur, iFrame ); } p->timeToStopOne = 0; } @@ -1036,11 +1062,11 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) // open a new timeframe p->nQueLim = p->pPars->nRestLimit; assert( pCube == NULL ); - Pdr_ManSetPropertyOutput( p, k ); - Pdr_ManCreateSolver( p, ++k ); + Pdr_ManSetPropertyOutput( p, iFrame ); + Pdr_ManCreateSolver( p, ++iFrame ); if ( fPrintClauses ) { - Abc_Print( 1, "*** Clauses after frame %d:\n", k ); + Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame ); Pdr_ManPrintClauses( p, 0 ); } // push clauses into this timeframe @@ -1052,11 +1078,11 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) if ( !p->pPars->fSilent ) { if ( p->timeToStop && Abc_Clock() > p->timeToStop ) - Abc_Print( 1, "Reached timeout (%d seconds).\n", p->pPars->nTimeOut ); + Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame ); else - Abc_Print( 1, "Reached conflict limit (%d).\n", p->pPars->nConfLimit ); + Abc_Print( 1, "Reached conflict limit (%d) in frame.\n", p->pPars->nConfLimit, iFrame ); } - p->pPars->iFrame = k; + p->pPars->iFrame = iFrame; return -1; } if ( RetValue ) @@ -1067,17 +1093,17 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) Pdr_ManReportInvariant( p ); if ( !p->pPars->fSilent ) Pdr_ManVerifyInvariant( p ); - p->pPars->iFrame = k; + p->pPars->iFrame = iFrame; // count the number of UNSAT outputs p->pPars->nProveOuts = Saig_ManPoNum(p->pAig) - p->pPars->nFailOuts - p->pPars->nDropOuts; // convert previously 'unknown' into 'unsat' if ( p->pPars->vOutMap ) - for ( k = 0; k < Saig_ManPoNum(p->pAig); k++ ) - if ( Vec_IntEntry(p->pPars->vOutMap, k) == -2 ) // unknown + for ( iFrame = 0; iFrame < Saig_ManPoNum(p->pAig); iFrame++ ) + if ( Vec_IntEntry(p->pPars->vOutMap, iFrame) == -2 ) // unknown { - Vec_IntWriteEntry( p->pPars->vOutMap, k, 1 ); // unsat + Vec_IntWriteEntry( p->pPars->vOutMap, iFrame, 1 ); // unsat if ( p->pPars->fUseBridge ) - Gia_ManToBridgeResult( stdout, 1, NULL, k ); + Gia_ManToBridgeResult( stdout, 1, NULL, iFrame ); } if ( p->pPars->nProveOuts == Saig_ManPoNum(p->pAig) ) return 1; // UNSAT @@ -1091,44 +1117,44 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) // check termination if ( p->pPars->pFuncStop && p->pPars->pFuncStop(p->pPars->RunId) ) { - p->pPars->iFrame = k; + p->pPars->iFrame = iFrame; return -1; } if ( p->timeToStop && Abc_Clock() > p->timeToStop ) { if ( fPrintClauses ) { - Abc_Print( 1, "*** Clauses after frame %d:\n", k ); + Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame ); Pdr_ManPrintClauses( p, 0 ); } if ( p->pPars->fVerbose ) Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); if ( !p->pPars->fSilent ) - Abc_Print( 1, "Reached timeout (%d seconds).\n", p->pPars->nTimeOut ); - p->pPars->iFrame = k; + Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame ); + p->pPars->iFrame = iFrame; return -1; } if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC ) { if ( fPrintClauses ) { - Abc_Print( 1, "*** Clauses after frame %d:\n", k ); + Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame ); Pdr_ManPrintClauses( p, 0 ); } if ( p->pPars->fVerbose ) Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); if ( !p->pPars->fSilent ) - Abc_Print( 1, "Reached gap timeout (%d seconds).\n", p->pPars->nTimeOutGap ); - p->pPars->iFrame = k; + Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame ); + p->pPars->iFrame = iFrame; return -1; } - if ( p->pPars->nFrameMax && k >= p->pPars->nFrameMax ) + if ( p->pPars->nFrameMax && iFrame >= p->pPars->nFrameMax ) { if ( p->pPars->fVerbose ) Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); if ( !p->pPars->fSilent ) Abc_Print( 1, "Reached limit on the number of timeframes (%d).\n", p->pPars->nFrameMax ); - p->pPars->iFrame = k; + p->pPars->iFrame = iFrame; return -1; } } diff --git a/src/proof/pdr/pdrInt.h b/src/proof/pdr/pdrInt.h index fb6717003..2ee4ae095 100644 --- a/src/proof/pdr/pdrInt.h +++ b/src/proof/pdr/pdrInt.h @@ -31,6 +31,7 @@ #include "sat/bsat/satSolver.h" #include "pdr.h" #include "misc/hash/hashInt.h" +#include "aig/gia/giaAig.h" ABC_NAMESPACE_HEADER_START @@ -71,6 +72,7 @@ struct Pdr_Man_t_ // input problem Pdr_Par_t * pPars; // parameters Aig_Man_t * pAig; // user's AIG + Gia_Man_t * pGia; // user's AIG // static CNF representation Cnf_Man_t * pCnfMan; // CNF manager Cnf_Dat_t * pCnf1; // CNF for this AIG @@ -90,7 +92,10 @@ struct Pdr_Man_t_ int * pOrder; // ordering of the lits Vec_Int_t * vActVars; // the counter of activation variables int iUseFrame; // the first used frame - Vec_Int_t * vAbs; // abstraction (mapping abstracted flop ID into its PPIs number) + int nAbsFlops; // the number of flops used + Vec_Int_t * vAbsFlops; // flops currently used + Vec_Int_t * vMapFf2Ppi; + Vec_Int_t * vMapPpi2Ff; // terminary simulation Txs_Man_t * pTxs; // internal use @@ -161,8 +166,6 @@ static inline abctime Pdr_ManTimeLimit( Pdr_Man_t * p ) /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -/*=== pdrCex.c ==========================================================*/ -extern Abc_Cex_t * Pdr_ManDeriveCex( Pdr_Man_t * p ); /*=== pdrCnf.c ==========================================================*/ extern int Pdr_ObjSatVar( Pdr_Man_t * p, int k, int Pol, Aig_Obj_t * pObj ); extern int Pdr_ObjRegNum( Pdr_Man_t * p, int k, int iSatVar ); @@ -183,6 +186,7 @@ extern Vec_Int_t * Pdr_ManDeriveInfinityClauses( Pdr_Man_t * p, int fReduce extern Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrioInit ); extern void Pdr_ManStop( Pdr_Man_t * p ); extern Abc_Cex_t * Pdr_ManDeriveCex( Pdr_Man_t * p ); +extern Abc_Cex_t * Pdr_ManDeriveCexAbs( Pdr_Man_t * p ); /*=== pdrSat.c ==========================================================*/ extern sat_solver * Pdr_ManCreateSolver( Pdr_Man_t * p, int k ); extern sat_solver * Pdr_ManFetchSolver( Pdr_Man_t * p, int k ); diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index fe759fffe..7a8a66d62 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -81,6 +81,7 @@ void Pdr_ManPrintProgress( Pdr_Man_t * p, int fClose, abctime Time ) for ( i = ThisSize; i < 70; i++ ) Abc_Print( 1, " " ); Abc_Print( 1, "%6d", p->nQueMax ); + Abc_Print( 1, "%6d", p->nAbsFlops ); Abc_Print( 1, "%10.2f sec", 1.0*Time/CLOCKS_PER_SEC ); if ( p->pPars->fSolveAll ) Abc_Print( 1, " CEX =%4d", p->pPars->nFailOuts ); diff --git a/src/proof/pdr/pdrMan.c b/src/proof/pdr/pdrMan.c index b2df5e016..e2807c920 100644 --- a/src/proof/pdr/pdrMan.c +++ b/src/proof/pdr/pdrMan.c @@ -19,7 +19,7 @@ ***********************************************************************/ #include "pdrInt.h" -#include "aig/gia/giaAig.h" +#include "sat/bmc/bmc.h" ABC_NAMESPACE_IMPL_START @@ -233,13 +233,6 @@ Vec_Int_t * Pdr_ManDeriveFlopPriorities2( Gia_Man_t * p, int fMuxCtrls ) //Vec_IntPrint( vCosts ); return vCosts; } -Vec_Int_t * Pdr_ManDeriveFlopPriorities( Aig_Man_t * pAig, int fMuxCtrls ) -{ - Gia_Man_t * pGia = Gia_ManFromAigSimple(pAig); - Vec_Int_t * vRes = Pdr_ManDeriveFlopPriorities2(pGia, fMuxCtrls); - Gia_ManStop( pGia ); - return vRes; -} /**Function************************************************************* @@ -258,6 +251,7 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio p = ABC_CALLOC( Pdr_Man_t, 1 ); p->pPars = pPars; p->pAig = pAig; + p->pGia = (pPars->fFlopPrio || p->pPars->fNewXSim || p->pPars->fUseAbs) ? Gia_ManFromAigSimple(pAig) : NULL; p->vSolvers = Vec_PtrAlloc( 0 ); p->vClauses = Vec_VecAlloc( 0 ); p->pQueue = NULL; @@ -270,7 +264,7 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio if ( vPrioInit ) p->vPrio = vPrioInit; else if ( pPars->fFlopPrio ) - p->vPrio = Pdr_ManDeriveFlopPriorities(pAig, 1); + p->vPrio = Pdr_ManDeriveFlopPriorities2(p->pGia, 1); else if ( p->pPars->fNewXSim ) p->vPrio = Vec_IntStartNatural( Aig_ManRegNum(pAig) ); else @@ -286,8 +280,6 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio p->vCi2Rem = Vec_IntAlloc( 100 ); // CIs to be removed p->vRes = Vec_IntAlloc( 100 ); // final result p->pCnfMan = Cnf_ManStart(); - if ( p->vAbs ) - p->vAbs = Vec_IntStart( Aig_ManRegNum(pAig) ); // ternary simulation p->pTxs = pPars->fNewXSim ? Txs_ManStart( p, pAig, p->vPrio ) : NULL; // additional AIG data-members @@ -328,6 +320,7 @@ void Pdr_ManStop( Pdr_Man_t * p ) Pdr_Set_t * pCla; sat_solver * pSat; int i, k; + Gia_ManStopP( &p->pGia ); Aig_ManCleanMarkAB( p->pAig ); if ( p->pPars->fVerbose ) { @@ -370,7 +363,9 @@ void Pdr_ManStop( Pdr_Man_t * p ) Vec_WecFreeP( &p->vVLits ); // CNF manager Cnf_ManStop( p->pCnfMan ); - Vec_IntFreeP( &p->vAbs ); + Vec_IntFreeP( &p->vAbsFlops ); + Vec_IntFreeP( &p->vMapFf2Ppi ); + Vec_IntFreeP( &p->vMapPpi2Ff ); // terminary simulation if ( p->pPars->fNewXSim ) Txs_ManStop( p->pTxs ); @@ -419,7 +414,6 @@ Abc_Cex_t * Pdr_ManDeriveCex( Pdr_Man_t * p ) nFrames++; // create the counter-example pCex = Abc_CexAlloc( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), nFrames ); -// pCex->iPo = (p->pPars->iOutput==-1)? 0 : p->pPars->iOutput; pCex->iPo = p->iOutCur; pCex->iFrame = nFrames-1; for ( pObl = p->pQueue, f = 0; pObl; pObl = pObl->pNext, f++ ) @@ -428,6 +422,8 @@ Abc_Cex_t * Pdr_ManDeriveCex( Pdr_Man_t * p ) Lit = pObl->pState->Lits[i]; if ( lit_sign(Lit) ) continue; + if ( lit_var(Lit) >= pCex->nPis ) // allows PPI literals to be thrown away + continue; assert( lit_var(Lit) < pCex->nPis ); Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + lit_var(Lit) ); } @@ -437,6 +433,97 @@ Abc_Cex_t * Pdr_ManDeriveCex( Pdr_Man_t * p ) return pCex; } +/**Function************************************************************* + + Synopsis [Derives counter-example when abstraction is used.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Pdr_ManDeriveCexAbs( Pdr_Man_t * p ) +{ + extern Gia_Man_t * Gia_ManDupAbs( Gia_Man_t * p, Vec_Int_t * vMapPpi2Ff, Vec_Int_t * vMapFf2Ppi ); + + Gia_Man_t * pAbs; + Abc_Cex_t * pCex, * pCexCare; + Pdr_Obl_t * pObl; + int i, f, Lit, Flop, nFrames = 0; + int nPis = Saig_ManPiNum(p->pAig); + int nFfRefined = 0; + if ( !p->pPars->fUseAbs ) + return Pdr_ManDeriveCex(p); + // restore previous map + Vec_IntForEachEntry( p->vMapPpi2Ff, Flop, i ) + { + assert( Vec_IntEntry( p->vMapFf2Ppi, Flop ) == i ); + Vec_IntWriteEntry( p->vMapFf2Ppi, Flop, -1 ); + } + Vec_IntClear( p->vMapPpi2Ff ); + // count the number of frames + for ( pObl = p->pQueue; pObl; pObl = pObl->pNext ) + { + for ( i = pObl->pState->nLits; i < pObl->pState->nTotal; i++ ) + { + Lit = pObl->pState->Lits[i]; + if ( lit_var(Lit) < nPis ) // PI literal + continue; + Flop = lit_var(Lit) - nPis; + if ( Vec_IntEntry(p->vMapFf2Ppi, Flop) >= 0 ) // already used PPI literal + continue; + Vec_IntWriteEntry( p->vMapFf2Ppi, Flop, Vec_IntSize(p->vMapPpi2Ff) ); + Vec_IntPush( p->vMapPpi2Ff, Flop ); + } + nFrames++; + } + if ( Vec_IntSize(p->vMapPpi2Ff) == 0 ) // no PPIs -- this is a real CEX + return Pdr_ManDeriveCex(p); + // create the counter-example + pCex = Abc_CexAlloc( Aig_ManRegNum(p->pAig) - Vec_IntSize(p->vMapPpi2Ff), Saig_ManPiNum(p->pAig) + Vec_IntSize(p->vMapPpi2Ff), nFrames ); + pCex->iPo = p->iOutCur; + pCex->iFrame = nFrames-1; + for ( pObl = p->pQueue, f = 0; pObl; pObl = pObl->pNext, f++ ) + for ( i = pObl->pState->nLits; i < pObl->pState->nTotal; i++ ) + { + Lit = pObl->pState->Lits[i]; + if ( lit_sign(Lit) ) + continue; + if ( lit_var(Lit) < nPis ) // PI literal + Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + lit_var(Lit) ); + else + { + int iPPI = nPis + Vec_IntEntry(p->vMapFf2Ppi, lit_var(Lit) - nPis); + assert( iPPI < pCex->nPis ); + Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + iPPI ); + } + } + assert( f == nFrames ); + // perform CEX minimization + pAbs = Gia_ManDupAbs( p->pGia, p->vMapPpi2Ff, p->vMapFf2Ppi ); + pCexCare = Bmc_CexCareMinimizeAig( pAbs, nPis, pCex, 1, 1, 1 ); + Gia_ManStop( pAbs ); + assert( pCexCare->nPis == pCex->nPis ); + Abc_CexFree( pCex ); + // detect care PPIs + for ( f = 0; f < nFrames; f++ ) + { + for ( i = nPis; i < pCexCare->nPis; i++ ) + if ( Abc_InfoHasBit(pCexCare->pData, pCexCare->nRegs + pCexCare->nPis * f + i) ) + { + if ( Vec_IntEntry(p->vAbsFlops, Vec_IntEntry(p->vMapPpi2Ff, i-nPis)) == 0 ) // currently abstracted + Vec_IntWriteEntry( p->vAbsFlops, Vec_IntEntry(p->vMapPpi2Ff, i-nPis), 1 ), nFfRefined++; + } + } + Abc_CexFree( pCexCare ); + if ( nFfRefined == 0 ) // no refinement -- this is a real CEX + return Pdr_ManDeriveCex(p); + printf( "CEX-based refinement refined %d flops.\n", nFfRefined ); + return NULL; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/pdr/pdrTsim.c b/src/proof/pdr/pdrTsim.c index 0bcb6e0c1..1cff03c79 100644 --- a/src/proof/pdr/pdrTsim.c +++ b/src/proof/pdr/pdrTsim.c @@ -440,7 +440,7 @@ Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, NULL ); if ( !Saig_ObjIsLo( p->pAig, pObj ) ) continue; Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig); - if ( vPrio != NULL && Vec_IntEntry( vPrio, Entry ) != 0 ) + if ( Vec_IntEntry(vPrio, Entry) ) continue; Vec_IntClear( vUndo ); if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) ) @@ -454,7 +454,7 @@ Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, NULL ); if ( !Saig_ObjIsLo( p->pAig, pObj ) ) continue; Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig); - if ( vPrio == NULL || Vec_IntEntry( vPrio, Entry ) == 0 ) + if ( !Vec_IntEntry(vPrio, Entry) ) continue; Vec_IntClear( vUndo ); if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) ) @@ -473,7 +473,39 @@ Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, vCi2Rem ); Pdr_ManDeriveResult( p->pAig, vCiObjs, vCiVals, vCi2Rem, vRes, vPiLits ); assert( Vec_IntSize(vRes) > 0 ); //p->tTsim += Abc_Clock() - clk; + // move abstracted literals from flops to inputs + if ( p->pPars->fUseAbs && p->vAbsFlops ) + { + int i, iLit, k = 0, fAllNegs = 1; + Vec_IntForEachEntry( vRes, iLit, i ) + { + if ( Vec_IntEntry(p->vAbsFlops, Abc_Lit2Var(iLit)) ) // used flop + { + Vec_IntWriteEntry( vRes, k++, iLit ); + fAllNegs &= Abc_LitIsCompl(iLit); + } + else + Vec_IntPush( vPiLits, 2*Saig_ManPiNum(p->pAig) + iLit ); + } + Vec_IntShrink( vRes, k ); + if ( fAllNegs ) // insert any positive literal + { + Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i ) + { + if ( !Saig_ObjIsLo( p->pAig, pObj ) ) + continue; + if ( Vec_IntEntry(vCiVals, i) ) + { + Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig); + Vec_IntPush( vRes, Abc_Var2Lit(Entry, 0) ); + break; + } + } + } + } pRes = Pdr_SetCreate( vRes, vPiLits ); + assert( k == 0 || !Pdr_SetIsInit(pRes, -1) ); + //ZH: Disabled assertion because this invariant doesn't hold with down //because of the join operation which can bring in initial states //assert( k == 0 || !Pdr_SetIsInit(pRes, -1) ); diff --git a/src/sat/bmc/bmc.h b/src/sat/bmc/bmc.h index 7820ebe6d..a3f353c2c 100644 --- a/src/sat/bmc/bmc.h +++ b/src/sat/bmc/bmc.h @@ -164,7 +164,8 @@ extern int Saig_ManBmcScalable( Aig_Man_t * pAig, Saig_ParBmc_t * extern int Gia_ManBmcPerform( Gia_Man_t * p, Bmc_AndPar_t * pPars ); /*=== bmcCexCare.c ==========================================================*/ extern Abc_Cex_t * Bmc_CexCareExtendToObjects( Gia_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t * pCexCare ); -extern Abc_Cex_t * Bmc_CexCareMinimize( Aig_Man_t * p, int nPPis, Abc_Cex_t * pCex, int fCheck, int fVerbose ); +extern Abc_Cex_t * Bmc_CexCareMinimize( Aig_Man_t * p, int nRealPis, Abc_Cex_t * pCex, int nTryCexes, int fCheck, int fVerbose ); +extern Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nRealPis, Abc_Cex_t * pCex, int nTryCexes, int fCheck, int fVerbose ); extern void Bmc_CexCareVerify( Aig_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t * pCexMin, int fVerbose ); /*=== bmcCexCut.c ==========================================================*/ extern Gia_Man_t * Bmc_GiaTargetStates( Gia_Man_t * p, Abc_Cex_t * pCex, int iFrBeg, int iFrEnd, int fCombOnly, int fGenAll, int fAllFrames, int fVerbose ); diff --git a/src/sat/bmc/bmcCexCare.c b/src/sat/bmc/bmcCexCare.c index 9c0a30d3c..cc3e85ea5 100644 --- a/src/sat/bmc/bmcCexCare.c +++ b/src/sat/bmc/bmcCexCare.c @@ -251,9 +251,9 @@ Abc_Cex_t * Bmc_CexCareTotal( Abc_Cex_t ** pCexes, int nCexes ) } return pCexMin; } -Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nPPis, Abc_Cex_t * pCex, int fCheck, int fVerbose ) +Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nRealPis, Abc_Cex_t * pCex, int nTryCexes, int fCheck, int fVerbose ) { - int nTryCexes = 4; // belongs to range [1;4] + //int nTryCexes = 4; // belongs to range [1;4] Abc_Cex_t * pCexBest, * pCexMin[4] = {NULL}; int k, f, i, nOnesBest, nOnesCur, Counter = 0; Vec_Int_t * vPriosIn, * vPriosFf; @@ -278,7 +278,7 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nPPis, Abc_Cex_t * pCex, if ( fVerbose ) { printf( "Original : " ); - Bmc_CexPrint( pCex, Gia_ManPiNum(p) - nPPis, 0 ); + Bmc_CexPrint( pCex, nRealPis, 0 ); } vPriosIn = Vec_IntAlloc( pCex->nPis * (pCex->iFrame + 1) ); vPriosFf = Vec_IntAlloc( pCex->nRegs * (pCex->iFrame + 1) ); @@ -290,37 +290,37 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nPPis, Abc_Cex_t * pCex, if ( k == 0 ) { for ( f = 0; f <= pCex->iFrame; f++ ) - for ( i = nPPis; i < Gia_ManPiNum(p); i++ ) + for ( i = nRealPis; i < Gia_ManPiNum(p); i++ ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); for ( f = 0; f <= pCex->iFrame; f++ ) - for ( i = 0; i < nPPis; i++ ) + for ( i = 0; i < nRealPis; i++ ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); } else if ( k == 1 ) { for ( f = pCex->iFrame; f >= 0; f-- ) - for ( i = nPPis; i < Gia_ManPiNum(p); i++ ) + for ( i = nRealPis; i < Gia_ManPiNum(p); i++ ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); for ( f = pCex->iFrame; f >= 0; f-- ) - for ( i = 0; i < nPPis; i++ ) + for ( i = 0; i < nRealPis; i++ ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); } else if ( k == 2 ) { for ( f = 0; f <= pCex->iFrame; f++ ) - for ( i = Gia_ManPiNum(p) - 1; i >= nPPis; i-- ) + for ( i = Gia_ManPiNum(p) - 1; i >= nRealPis; i-- ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); for ( f = 0; f <= pCex->iFrame; f++ ) - for ( i = nPPis - 1; i >= 0; i-- ) + for ( i = nRealPis - 1; i >= 0; i-- ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); } else if ( k == 3 ) { for ( f = pCex->iFrame; f >= 0; f-- ) - for ( i = Gia_ManPiNum(p) - 1; i >= nPPis; i-- ) + for ( i = Gia_ManPiNum(p) - 1; i >= nRealPis; i-- ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); for ( f = pCex->iFrame; f >= 0; f-- ) - for ( i = nPPis - 1; i >= 0; i-- ) + for ( i = nRealPis - 1; i >= 0; i-- ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); } else assert( 0 ); @@ -328,37 +328,37 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nPPis, Abc_Cex_t * pCex, if ( k == 0 ) { for ( f = pCex->iFrame; f >= 0; f-- ) - for ( i = nPPis; i < Gia_ManPiNum(p); i++ ) + for ( i = Gia_ManPiNum(p) - 1; i >= nRealPis; i-- ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); for ( f = pCex->iFrame; f >= 0; f-- ) - for ( i = 0; i < nPPis; i++ ) + for ( i = nRealPis - 1; i >= 0; i-- ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); } else if ( k == 1 ) { for ( f = pCex->iFrame; f >= 0; f-- ) - for ( i = nPPis; i < Gia_ManPiNum(p); i++ ) + for ( i = Gia_ManPiNum(p) - 1; i >= nRealPis; i-- ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); for ( f = pCex->iFrame; f >= 0; f-- ) - for ( i = nPPis - 1; i >= 0; i-- ) + for ( i = 0; i < nRealPis; i++ ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); } else if ( k == 2 ) { for ( f = pCex->iFrame; f >= 0; f-- ) - for ( i = Gia_ManPiNum(p) - 1; i >= nPPis; i-- ) + for ( i = nRealPis; i < Gia_ManPiNum(p); i++ ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); for ( f = pCex->iFrame; f >= 0; f-- ) - for ( i = 0; i < nPPis; i++ ) + for ( i = nRealPis - 1; i >= 0; i-- ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); } else if ( k == 3 ) { for ( f = pCex->iFrame; f >= 0; f-- ) - for ( i = Gia_ManPiNum(p) - 1; i >= nPPis; i-- ) + for ( i = nRealPis; i < Gia_ManPiNum(p); i++ ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); for ( f = pCex->iFrame; f >= 0; f-- ) - for ( i = nPPis - 1; i >= 0; i-- ) + for ( i = 0; i < nRealPis; i++ ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); } else assert( 0 ); @@ -377,15 +377,15 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nPPis, Abc_Cex_t * pCex, if ( fVerbose ) { if ( k == 0 ) - printf( "PiUp FrUp: " ); + printf( "PI- PPI-: " ); else if ( k == 1 ) - printf( "PiUp FrDn: " ); + printf( "PI+ PPI-: " ); else if ( k == 2 ) - printf( "PiDn FrUp: " ); + printf( "PI- PPI+: " ); else if ( k == 3 ) - printf( "PiDn FrDn: " ); + printf( "PI+ PPI+: " ); else assert( 0 ); - Bmc_CexPrint( pCexMin[k], Gia_ManPiNum(p) - nPPis, 0 ); + Bmc_CexPrint( pCexMin[k], nRealPis, 0 ); } } Vec_IntFree( vPriosIn ); @@ -395,6 +395,8 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nPPis, Abc_Cex_t * pCex, nOnesBest = Abc_CexCountOnes(pCexMin[0]); for ( k = 1; k < nTryCexes; k++ ) { + if ( pCexMin[k] == NULL ) + continue; nOnesCur = Abc_CexCountOnes(pCexMin[k]); if ( nOnesBest > nOnesCur ) { @@ -406,13 +408,13 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nPPis, Abc_Cex_t * pCex, { //Abc_Cex_t * pTotal = Bmc_CexCareTotal( pCexMin, nTryCexes ); printf( "Final : " ); - Bmc_CexPrint( pCexBest, Gia_ManPiNum(p) - nPPis, 0 ); + Bmc_CexPrint( pCexBest, nRealPis, 0 ); //printf( "Total : " ); - //Bmc_CexPrint( pTotal, Gia_ManPiNum(p) - nPPis, 0 ); + //Bmc_CexPrint( pTotal, nRealPis, 0 ); //Abc_CexFreeP( &pTotal ); } for ( k = 0; k < nTryCexes; k++ ) - if ( pCexBest != pCexMin[k] ) + if ( pCexMin[k] && pCexBest != pCexMin[k] ) Abc_CexFreeP( &pCexMin[k] ); // verify and return if ( !Bmc_CexVerify( p, pCex, pCexBest ) ) @@ -421,10 +423,10 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nPPis, Abc_Cex_t * pCex, printf( "Counter-example verification succeeded.\n" ); return pCexBest; } -Abc_Cex_t * Bmc_CexCareMinimize( Aig_Man_t * p, int nPPis, Abc_Cex_t * pCex, int fCheck, int fVerbose ) +Abc_Cex_t * Bmc_CexCareMinimize( Aig_Man_t * p, int nRealPis, Abc_Cex_t * pCex, int nTryCexes, int fCheck, int fVerbose ) { Gia_Man_t * pGia = Gia_ManFromAigSimple( p ); - Abc_Cex_t * pCexMin = Bmc_CexCareMinimizeAig( pGia, nPPis, pCex, fCheck, fVerbose ); + Abc_Cex_t * pCexMin = Bmc_CexCareMinimizeAig( pGia, nRealPis, pCex, nTryCexes, fCheck, fVerbose ); Gia_ManStop( pGia ); return pCexMin; } @@ -459,7 +461,7 @@ void Bmc_CexCareVerify( Aig_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t * pCexMin, in /* { Aig_Man_t * pAig = Abc_NtkToDar( pNtk, 0, 1 ); - Abc_Cex_t * pCex = Bmc_CexCareMinimize( pAig, 3*Saig_ManPiNum(pAig)/4, pAbc->pCex, 1, 1 ); + Abc_Cex_t * pCex = Bmc_CexCareMinimize( pAig, 3*Saig_ManPiNum(pAig)/4, 4, pAbc->pCex, 1, 1 ); Aig_ManStop( pAig ); Abc_CexFree( pCex ); } From 1bdbea66120292d821fc594b9a6637135bde6244 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 10 Feb 2017 17:40:34 -0800 Subject: [PATCH 127/185] Compiler warnings. --- src/aig/gia/giaDup.c | 2 +- src/proof/pdr/pdrCore.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 2a0fe6e38..56d1d29d5 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -252,12 +252,12 @@ Gia_Man_t * Gia_ManDupAbs( Gia_Man_t * p, Vec_Int_t * vMapPpi2Ff, Vec_Int_t * vM } Vec_IntForEachEntry( vMapFf2Ppi, Used, Flop ) { + pObj = Gia_ManCi( p, Gia_ManPiNum(p) + Flop ); if ( Used >= 0 ) { assert( pObj->Value != ~0 ); continue; } - pObj = Gia_ManCi( p, Gia_ManPiNum(p) + Flop ); assert( pObj->Value == ~0 ); pObj->Value = Gia_ManAppendCi(pNew); } diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index 47f0ac8bc..fb35269d8 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -863,7 +863,7 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) { if ( p->pPars->fUseAbs && iFrame == 2 ) { - int i, Prio, Num = Saig_ManPiNum(p->pAig); + int i, Prio; assert( p->vAbsFlops == NULL ); p->vAbsFlops = Vec_IntStart( Saig_ManRegNum(p->pAig) ); p->vMapFf2Ppi = Vec_IntStartFull( Saig_ManRegNum(p->pAig) ); From d4b491d849c32195408b0fcc3e5eb42085186824 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 10 Feb 2017 17:51:42 -0800 Subject: [PATCH 128/185] Changes to compile on Windows. --- abclib.dsp | 4 ++++ src/sat/satoko/utils/fixed.h | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/abclib.dsp b/abclib.dsp index f2fcf619b..853076350 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -2031,6 +2031,10 @@ SOURCE=.\src\sat\satoko\cnf_reader.c # End Source File # Begin Source File +SOURCE=.\src\sat\satoko\utils\fixed.h +# End Source File +# Begin Source File + SOURCE=.\src\sat\satoko\utils\heap.h # End Source File # Begin Source File diff --git a/src/sat/satoko/utils/fixed.h b/src/sat/satoko/utils/fixed.h index 91fc9b79c..bddd1bb48 100644 --- a/src/sat/satoko/utils/fixed.h +++ b/src/sat/satoko/utils/fixed.h @@ -16,11 +16,11 @@ ABC_NAMESPACE_HEADER_START typedef unsigned fixed_t; static const int FIXED_W_BITS = 16; /* */ -static const int FIXED_F_BITS = 32 - FIXED_W_BITS; -static const int FIXED_F_MASK = (1 << FIXED_F_BITS) - 1; +static const int FIXED_F_BITS = 16;//32 - FIXED_W_BITS; +static const int FIXED_F_MASK = 0xFFFF; //(1 << FIXED_F_BITS) - 1; static const fixed_t FIXED_MAX = 0xFFFFFFFF; static const fixed_t FIXED_MIN = 0x00000000; -static const fixed_t FIXED_ONE = (1 << FIXED_F_BITS); +static const fixed_t FIXED_ONE = 0x10000;//(1 << FIXED_F_BITS); /* Conversion functions */ static inline fixed_t uint2fixed(unsigned a) { return a * FIXED_ONE; } From 5d717256d3b856d8f29c4a5e442af624f0b0bb69 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 10 Feb 2017 18:14:06 -0800 Subject: [PATCH 129/185] Updates to the autotuner. --- src/base/abci/abc.c | 220 ++--------------------------------------- src/base/cmd/cmdAuto.c | 209 ++++++++++++++++++++++++++++++++++----- src/sat/satoko/types.h | 2 +- 3 files changed, 197 insertions(+), 234 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 933f97786..f10be02b9 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -23320,222 +23320,22 @@ usage: ***********************************************************************/ int Abc_CommandSatoko( Abc_Frame_t * pAbc, int argc, char ** argv ) { - abctime clk; - int c; - satoko_opts_t opts; + extern satoko_opts_t * Cmd_DeriveOptionFromSettings( int argc, char ** argv ); + // create default options + satoko_opts_t opts, * popts; satoko_default_opts(&opts); - Extra_UtilGetoptReset(); -#ifdef SATOKO_ACT_VAR_FIXED - while ( ( c = Extra_UtilGetopt( argc, argv, "CPDEFGHIJKLMNOQRSTUhv" ) ) != EOF ) -#else - while ( ( c = Extra_UtilGetopt( argc, argv, "CPDEFGHIJKLMNOQRShv" ) ) != EOF ) -#endif - { - switch ( c ) - { - case 'C': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); - goto usage; - } - opts.conf_limit = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( opts.conf_limit < 0 ) - goto usage; - break; - case 'P': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-P\" should be followed by an integer.\n" ); - goto usage; - } - opts.prop_limit = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( opts.prop_limit < 0 ) - goto usage; - break; - case 'D': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-D\" should be followed by an float.\n" ); - goto usage; - } - opts.f_rst = atof(argv[globalUtilOptind]); - globalUtilOptind++; - if ( opts.f_rst < 0 ) - goto usage; - break; - case 'E': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-E\" should be followed by an float.\n" ); - goto usage; - } - opts.b_rst = atof(argv[globalUtilOptind]); - globalUtilOptind++; - if ( opts.b_rst < 0 ) - goto usage; - break; - case 'F': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" ); - goto usage; - } - opts.fst_block_rst = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'G': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-G\" should be followed by an integer.\n" ); - goto usage; - } - opts.sz_lbd_bqueue = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'H': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-H\" should be followed by an integer.\n" ); - goto usage; - } - opts.sz_trail_bqueue = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'I': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); - goto usage; - } - opts.n_conf_fst_reduce = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'J': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-J\" should be followed by an integer.\n" ); - goto usage; - } - opts.inc_reduce = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'K': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-K\" should be followed by an integer.\n" ); - goto usage; - } - opts.inc_special_reduce = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'L': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-L\" should be followed by an integer.\n" ); - goto usage; - } - opts.lbd_freeze_clause = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'M': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); - goto usage; - } - opts.learnt_ratio = atof(argv[globalUtilOptind]) / 100; - globalUtilOptind++; - if ( opts.learnt_ratio < 0 ) - goto usage; - break; - case 'N': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); - goto usage; - } - opts.garbage_max_ratio = atof(argv[globalUtilOptind]) / 100; - globalUtilOptind++; - if ( opts.garbage_max_ratio < 0 ) - goto usage; - break; - case 'O': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" ); - goto usage; - } - opts.clause_max_sz_bin_resol = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'Q': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" ); - goto usage; - } - opts.clause_min_lbd_bin_resol = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'R': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-R\" should be followed by an float.\n" ); - goto usage; - } - opts.clause_decay = atof(argv[globalUtilOptind]); - globalUtilOptind++; - if ( opts.clause_decay < 0 ) - goto usage; - break; - case 'S': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-S\" should be followed by an float.\n" ); - goto usage; - } - opts.var_decay = atof(argv[globalUtilOptind]); - globalUtilOptind++; - if ( opts.var_decay < 0 ) - goto usage; - break; -#ifdef SATOKO_ACT_VAR_FIXED - case 'T': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-T\" should be followed by an float.\n" ); - goto usage; - } - opts.var_act_limit = (unsigned)strtol(argv[globalUtilOptind], NULL, 16); - globalUtilOptind++; - break; - case 'U': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-U\" should be followed by an float.\n" ); - goto usage; - } - opts.var_act_rescale = (unsigned)strtol(argv[globalUtilOptind], NULL, 16); - globalUtilOptind++; - break; -#endif - case 'h': - goto usage; - case 'v': - opts.verbose ^= 1; - break; - default: - goto usage; - } - } + // override default options + popts = Cmd_DeriveOptionFromSettings( argc, argv ); + if ( popts == NULL ) + goto usage; + memcpy( &opts, popts, sizeof(satoko_opts_t) ); + ABC_FREE( popts ); if ( argc == globalUtilOptind + 1 ) { + abctime clk; char * pFileName = argv[globalUtilOptind]; satoko_t * p; int status; diff --git a/src/base/cmd/cmdAuto.c b/src/base/cmd/cmdAuto.c index 35f155fa4..e279b19d1 100644 --- a/src/base/cmd/cmdAuto.c +++ b/src/base/cmd/cmdAuto.c @@ -241,7 +241,11 @@ satoko_opts_t * Cmd_DeriveOptionFromSettings( int argc, char ** argv ) satoko_opts_t opts, * pOpts; satoko_default_opts(&opts); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "CVWhv" ) ) != EOF ) +#ifdef SATOKO_ACT_VAR_FIXED + while ( ( c = Extra_UtilGetopt( argc, argv, "CPDEFGHIJKLMNOQRSTUhv" ) ) != EOF ) +#else + while ( ( c = Extra_UtilGetopt( argc, argv, "CPDEFGHIJKLMNOQRShv" ) ) != EOF ) +#endif { switch ( c ) { @@ -256,31 +260,190 @@ satoko_opts_t * Cmd_DeriveOptionFromSettings( int argc, char ** argv ) if ( opts.conf_limit < 0 ) return NULL; break; - case 'V': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-V\" should be followed by an integer.\n" ); - return NULL; - } - opts.var_decay = atof(argv[globalUtilOptind]); - globalUtilOptind++; - if ( opts.var_decay < 0 ) - return NULL; - break; - case 'W': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-W\" should be followed by an integer.\n" ); - return NULL; - } - opts.clause_decay = atof(argv[globalUtilOptind]); - globalUtilOptind++; - if ( opts.clause_decay < 0 ) - return NULL; - break; + case 'P': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-P\" should be followed by an integer.\n" ); + return NULL; + } + opts.prop_limit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.prop_limit < 0 ) + return NULL; + break; + case 'D': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-D\" should be followed by an float.\n" ); + return NULL; + } + opts.f_rst = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.f_rst < 0 ) + return NULL; + break; + case 'E': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-E\" should be followed by an float.\n" ); + return NULL; + } + opts.b_rst = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.b_rst < 0 ) + return NULL; + break; + case 'F': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" ); + return NULL; + } + opts.fst_block_rst = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'G': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-G\" should be followed by an integer.\n" ); + return NULL; + } + opts.sz_lbd_bqueue = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'H': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-H\" should be followed by an integer.\n" ); + return NULL; + } + opts.sz_trail_bqueue = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'I': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); + return NULL; + } + opts.n_conf_fst_reduce = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'J': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-J\" should be followed by an integer.\n" ); + return NULL; + } + opts.inc_reduce = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'K': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-K\" should be followed by an integer.\n" ); + return NULL; + } + opts.inc_special_reduce = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'L': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-L\" should be followed by an integer.\n" ); + return NULL; + } + opts.lbd_freeze_clause = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'M': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + return NULL; + } + opts.learnt_ratio = atof(argv[globalUtilOptind]) / 100; + globalUtilOptind++; + if ( opts.learnt_ratio < 0 ) + return NULL; + break; + case 'N': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + return NULL; + } + opts.garbage_max_ratio = atof(argv[globalUtilOptind]) / 100; + globalUtilOptind++; + if ( opts.garbage_max_ratio < 0 ) + return NULL; + break; + case 'O': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" ); + return NULL; + } + opts.clause_max_sz_bin_resol = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'Q': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" ); + return NULL; + } + opts.clause_min_lbd_bin_resol = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'R': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-R\" should be followed by an float.\n" ); + return NULL; + } + opts.clause_decay = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.clause_decay < 0 ) + return NULL; + break; + case 'S': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-S\" should be followed by an float.\n" ); + return NULL; + } + opts.var_decay = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.var_decay < 0 ) + return NULL; + break; +#ifdef SATOKO_ACT_VAR_FIXED + case 'T': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-T\" should be followed by an float.\n" ); + return NULL; + } + opts.var_act_limit = (unsigned)strtol(argv[globalUtilOptind], NULL, 16); + globalUtilOptind++; + break; + case 'U': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-U\" should be followed by an float.\n" ); + return NULL; + } + opts.var_act_rescale = (unsigned)strtol(argv[globalUtilOptind], NULL, 16); + globalUtilOptind++; + break; +#endif + case 'h': + return NULL; case 'v': opts.verbose ^= 1; break; + default: return NULL; } diff --git a/src/sat/satoko/types.h b/src/sat/satoko/types.h index 7865ab0ee..5d5d4b989 100644 --- a/src/sat/satoko/types.h +++ b/src/sat/satoko/types.h @@ -18,7 +18,7 @@ ABC_NAMESPACE_HEADER_START #define SATOKO_ACT_VAR_DBLE // #define SATOKO_ACT_VAR_FIXED -// #define SATOKO_ACT_CLAUSE_FLOAT +#define SATOKO_ACT_CLAUSE_FLOAT #ifdef SATOKO_ACT_VAR_DBLE #define VAR_ACT_INIT_INC 1.0 From dd96bb7477fc568ef8fc8d86d330af22c8fa2f26 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 10 Feb 2017 18:53:39 -0800 Subject: [PATCH 130/185] Adding PDR with abstraction. --- src/proof/pdr/pdrCore.c | 13 ++++++++----- src/proof/pdr/pdrInt.h | 3 +++ src/proof/pdr/pdrInv.c | 8 +++++--- src/proof/pdr/pdrMan.c | 11 +++++++---- src/proof/pdr/pdrTsim.c | 17 ++++++++++++++++- 5 files changed, 39 insertions(+), 13 deletions(-) diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index fb35269d8..5aa689f57 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -861,7 +861,8 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) Pdr_ManCreateSolver( p, (iFrame = 0) ); while ( 1 ) { - if ( p->pPars->fUseAbs && iFrame == 2 ) + int fRefined = 0; + if ( p->pPars->fUseAbs && iFrame == 3 ) { int i, Prio; assert( p->vAbsFlops == NULL ); @@ -872,9 +873,8 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) if ( Prio >> p->nPrioShift ) Vec_IntWriteEntry( p->vAbsFlops, i, 1 ); } - if ( p->pPars->fUseAbs && p->vAbsFlops ) - printf( "Starting frame %d with %d flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops) ); - + //if ( p->pPars->fUseAbs && p->vAbsFlops ) + // printf( "Starting frame %d with %d flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops) ); p->nFrames = iFrame; assert( iFrame == Vec_PtrSize(p->vSolvers)-1 ); p->iUseFrame = Abc_MaxInt(iFrame, 1); @@ -1000,12 +1000,15 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) p->pPars->iFrame = iFrame; if ( !p->pPars->fSolveAll ) { + abctime clk = Abc_Clock(); Abc_Cex_t * pCex = Pdr_ManDeriveCexAbs(p); + p->tAbs += Abc_Clock() - clk; if ( pCex == NULL ) { assert( p->pPars->fUseAbs ); Pdr_QueueClean( p ); pCube = NULL; + fRefined = 1; break; // keep solving } p->pAig->pSeqModel = pCex; @@ -1058,7 +1061,7 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) } if ( p->pPars->fVerbose ) - Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + Pdr_ManPrintProgress( p, !fRefined, Abc_Clock() - clkStart ); // open a new timeframe p->nQueLim = p->pPars->nRestLimit; assert( pCube == NULL ); diff --git a/src/proof/pdr/pdrInt.h b/src/proof/pdr/pdrInt.h index 2ee4ae095..a6d249e89 100644 --- a/src/proof/pdr/pdrInt.h +++ b/src/proof/pdr/pdrInt.h @@ -96,6 +96,8 @@ struct Pdr_Man_t_ Vec_Int_t * vAbsFlops; // flops currently used Vec_Int_t * vMapFf2Ppi; Vec_Int_t * vMapPpi2Ff; + int nCexes; + int nCexesTotal; // terminary simulation Txs_Man_t * pTxs; // internal use @@ -142,6 +144,7 @@ struct Pdr_Man_t_ abctime tTsim; abctime tContain; abctime tCnf; + abctime tAbs; abctime tTotal; }; diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index 7a8a66d62..e3233a3a9 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -80,8 +80,10 @@ void Pdr_ManPrintProgress( Pdr_Man_t * p, int fClose, abctime Time ) } for ( i = ThisSize; i < 70; i++ ) Abc_Print( 1, " " ); - Abc_Print( 1, "%6d", p->nQueMax ); - Abc_Print( 1, "%6d", p->nAbsFlops ); + Abc_Print( 1, "%5d", p->nQueMax ); + Abc_Print( 1, "%5d", p->vAbsFlops ? Vec_IntCountPositive(p->vAbsFlops) : p->nAbsFlops ); + if ( p->pPars->fUseAbs ) + Abc_Print( 1, "%5d", p->nCexes ); Abc_Print( 1, "%10.2f sec", 1.0*Time/CLOCKS_PER_SEC ); if ( p->pPars->fSolveAll ) Abc_Print( 1, " CEX =%4d", p->pPars->nFailOuts ); @@ -89,7 +91,7 @@ void Pdr_ManPrintProgress( Pdr_Man_t * p, int fClose, abctime Time ) Abc_Print( 1, " T/O =%3d", p->pPars->nDropOuts ); Abc_Print( 1, "%s", fClose ? "\n":"\r" ); if ( fClose ) - p->nQueMax = 0; + p->nQueMax = 0, p->nCexes = 0; fflush( stdout ); } diff --git a/src/proof/pdr/pdrMan.c b/src/proof/pdr/pdrMan.c index e2807c920..c19041eed 100644 --- a/src/proof/pdr/pdrMan.c +++ b/src/proof/pdr/pdrMan.c @@ -324,8 +324,8 @@ void Pdr_ManStop( Pdr_Man_t * p ) Aig_ManCleanMarkAB( p->pAig ); if ( p->pPars->fVerbose ) { - Abc_Print( 1, "Block =%5d Oblig =%6d Clause =%6d Call =%6d (sat=%.1f%%) Start =%4d\n", - p->nBlocks, p->nObligs, p->nCubes, p->nCalls, 100.0 * p->nCallsS / p->nCalls, p->nStarts ); + Abc_Print( 1, "Block =%5d Oblig =%6d Clause =%6d Call =%6d (sat=%.1f%%) Cex =%4d Start =%4d\n", + p->nBlocks, p->nObligs, p->nCubes, p->nCalls, 100.0 * p->nCallsS / p->nCalls, p->nCexesTotal, p->nStarts ); ABC_PRTP( "SAT solving", p->tSat, p->tTotal ); ABC_PRTP( " unsat ", p->tSatUnsat, p->tTotal ); ABC_PRTP( " sat ", p->tSatSat, p->tTotal ); @@ -334,6 +334,7 @@ void Pdr_ManStop( Pdr_Man_t * p ) ABC_PRTP( "Ternary sim", p->tTsim, p->tTotal ); ABC_PRTP( "Containment", p->tContain, p->tTotal ); ABC_PRTP( "CNF compute", p->tCnf, p->tTotal ); + ABC_PRTP( "Refinement ", p->tAbs, p->tTotal ); ABC_PRTP( "TOTAL ", p->tTotal, p->tTotal ); fflush( stdout ); } @@ -503,7 +504,7 @@ Abc_Cex_t * Pdr_ManDeriveCexAbs( Pdr_Man_t * p ) assert( f == nFrames ); // perform CEX minimization pAbs = Gia_ManDupAbs( p->pGia, p->vMapPpi2Ff, p->vMapFf2Ppi ); - pCexCare = Bmc_CexCareMinimizeAig( pAbs, nPis, pCex, 1, 1, 1 ); + pCexCare = Bmc_CexCareMinimizeAig( pAbs, nPis, pCex, 1, 0, 0 ); Gia_ManStop( pAbs ); assert( pCexCare->nPis == pCex->nPis ); Abc_CexFree( pCex ); @@ -520,7 +521,9 @@ Abc_Cex_t * Pdr_ManDeriveCexAbs( Pdr_Man_t * p ) Abc_CexFree( pCexCare ); if ( nFfRefined == 0 ) // no refinement -- this is a real CEX return Pdr_ManDeriveCex(p); - printf( "CEX-based refinement refined %d flops.\n", nFfRefined ); + //printf( "CEX-based refinement refined %d flops.\n", nFfRefined ); + p->nCexesTotal++; + p->nCexes++; return NULL; } diff --git a/src/proof/pdr/pdrTsim.c b/src/proof/pdr/pdrTsim.c index 1cff03c79..283a0e1dd 100644 --- a/src/proof/pdr/pdrTsim.c +++ b/src/proof/pdr/pdrTsim.c @@ -476,7 +476,7 @@ Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, vCi2Rem ); // move abstracted literals from flops to inputs if ( p->pPars->fUseAbs && p->vAbsFlops ) { - int i, iLit, k = 0, fAllNegs = 1; + int i, iLit, Used, k = 0, fAllNegs = 1; Vec_IntForEachEntry( vRes, iLit, i ) { if ( Vec_IntEntry(p->vAbsFlops, Abc_Lit2Var(iLit)) ) // used flop @@ -501,6 +501,21 @@ Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, vCi2Rem ); break; } } + // add any flop that is not in the cone + if ( i == Vec_IntSize(vCiObjs) ) + { + Vec_IntForEachEntry( p->vAbsFlops, Used, i ) + { + if ( !Used ) + continue; + if ( Vec_IntFind( vRes, Abc_Var2Lit(i, 1) ) >= 0 ) + continue; + Vec_IntPush( vRes, Abc_Var2Lit(i, 0) ); + //Vec_IntPrint( vRes ); + break; + } + assert( i < Vec_IntSize(p->vAbsFlops) ); + } } } pRes = Pdr_SetCreate( vRes, vPiLits ); From 8333cb807fbe6773df8285591e75f35d519b6e81 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 11 Feb 2017 10:55:34 -0800 Subject: [PATCH 131/185] Platform-independent double. --- src/sat/xsat/xsatDouble.h | 226 ++++++++++++++++++++++++++++++++++++++ src/sat/xsat/xsatFloat.h | 1 - 2 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 src/sat/xsat/xsatDouble.h diff --git a/src/sat/xsat/xsatDouble.h b/src/sat/xsat/xsatDouble.h new file mode 100644 index 000000000..d90e8c05b --- /dev/null +++ b/src/sat/xsat/xsatDouble.h @@ -0,0 +1,226 @@ +/**CFile**************************************************************** + + FileName [xdouble.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [] + + Synopsis [Double floating point number implementation.] + + Author [Alan Mishchenko, Bruno Schmitt] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - February 11, 2017.] + + Revision [] + +***********************************************************************/ + +#ifndef ABC__sat__Xdbl__Xdbl_h +#define ABC__sat__Xdbl__Xdbl_h + +#include "misc/util/abc_global.h" + +ABC_NAMESPACE_HEADER_START + +//////////////////////////////////////////////////////////////////////// +/// STRUCTURE DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/* + The xdbl floating-point number is represented as a 64-bit unsigned int. + The number is (2^Exp)*Mnt, where Exp is a 16-bit exponent and Mnt is a + 48-bit mantissa. The decimal point is located between the MSB of Mnt, + which is always 1, and the remaining 15 digits of Mnt. + + Currently, only positive numbers are represented. + + The range of possible values is [1.0; 2^(2^16-1)*1.111111111111111] + that is, the smallest possible number is 1.0 and the largest possible + number is 2^(---16 ones---).(1.---47 ones---) + + Comparison of numbers can be done by comparing the underlying unsigned ints. + + Only addition, multiplication, and division by 2^n are currently implemented. +*/ + +static inline word Abc_Dbl2Word( double Dbl ) { union { word x; double y; } v; v.y = Dbl; return v.x; } +static inline double Abc_Word2Dbl( word Num ) { union { word x; double y; } v; v.x = Num; return v.y; } + + +typedef word xdbl; + +static inline word Xdbl_Exp( xdbl a ) { return a >> 48; } +static inline word Xdbl_Mnt( xdbl a ) { return (a << 16) >> 16; } + +static inline xdbl Xdbl_Create( word Exp, word Mnt ) { assert(!(Exp>>16) && (Mnt>>47)==(word)1); return (Exp<<48) | Mnt; } + +static inline xdbl Xdbl_Const1() { return Xdbl_Create( (word)0, (word)1 << 47 ); } +static inline xdbl Xdbl_Const2() { return Xdbl_Create( (word)1, (word)1 << 47 ); } +static inline xdbl Xdbl_Const3() { return Xdbl_Create( (word)1, (word)3 << 46 ); } +static inline xdbl Xdbl_Const12() { return Xdbl_Create( (word)3, (word)3 << 46 ); } +static inline xdbl Xdbl_Const1point5() { return Xdbl_Create( (word)0, (word)3 << 46 ); } +static inline xdbl Xdbl_Const2point5() { return Xdbl_Create( (word)1, (word)5 << 45 ); } +static inline xdbl Xdbl_Maximum() { return ~(word)0; } + +static inline double Xdbl_ToDouble( xdbl a ) { assert(Xdbl_Exp(a) < 1023); return Abc_Word2Dbl(((Xdbl_Exp(a) + 1023) << 52) | (((a<<17)>>17) << 5)); } +static inline xdbl Xdbl_FromDouble( double a ) { word A = Abc_Dbl2Word(a); assert(a >= 1.0); return Xdbl_Create((A >> 52)-1023, (((word)1) << 47) | ((A << 12) >> 17)); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Adding two floating-point numbers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xdbl Xdbl_Add( xdbl a, xdbl b ) +{ + word Exp, Mnt; + if ( a < b ) a ^= b, b ^= a, a ^= b; + assert( a >= b ); + Mnt = Xdbl_Mnt(a) + (Xdbl_Mnt(b) >> (Xdbl_Exp(a) - Xdbl_Exp(b))); + Exp = Xdbl_Exp(a); + if ( Mnt >> 48 ) // new MSB is created + Exp++, Mnt >>= 1; + if ( Exp >> 16 ) // overflow + return Xdbl_Maximum(); + return Xdbl_Create( Exp, Mnt ); +} + +/**Function************************************************************* + + Synopsis [Multiplying two floating-point numbers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xdbl Xdbl_Mul( xdbl a, xdbl b ) +{ + word Exp, Mnt, MntA, MntB, MntAh, MntBh, MntAl, MntBl; + if ( a < b ) a ^= b, b ^= a, a ^= b; + assert( a >= b ); + MntA = Xdbl_Mnt(a); + MntB = Xdbl_Mnt(b); + MntAh = MntA>>32; + MntBh = MntB>>32; + MntAl = (MntA<<32)>>32; + MntBl = (MntB<<32)>>32; + Mnt = ((MntAh * MntBh) << 17) + ((MntAl * MntBl) >> 47) + ((MntAl * MntBh) >> 15) + ((MntAh * MntBl) >> 15); + Exp = Xdbl_Exp(a) + Xdbl_Exp(b); + if ( Mnt >> 48 ) // new MSB is created + Exp++, Mnt >>= 1; + if ( Exp >> 16 ) // overflow + return Xdbl_Maximum(); + return Xdbl_Create( Exp, Mnt ); +} + +/**Function************************************************************* + + Synopsis [Dividing floating point number by a degree of 2.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xdbl Xdbl_Div( xdbl a, unsigned Deg2 ) +{ + if ( Xdbl_Exp(a) >= (word)Deg2 ) + return Xdbl_Create( Xdbl_Exp(a) - Deg2, Xdbl_Mnt(a) ); + return Xdbl_Const1(); // underflow +} + +/**Function************************************************************* + + Synopsis [Testing procedure.] + + Description [Helpful link https://www.h-schmidt.net/FloatConverter/IEEE754.html] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Xdbl_Test() +{ + xdbl c1 = Xdbl_Const1(); + xdbl c2 = Xdbl_Const2(); + xdbl c3 = Xdbl_Const3(); + xdbl c12 = Xdbl_Const12(); + xdbl c1p5 = Xdbl_Const1point5(); + xdbl c2p5 = Xdbl_Const2point5(); + + xdbl c1_ = Xdbl_FromDouble(1.0); + xdbl c2_ = Xdbl_FromDouble(2.0); + xdbl c3_ = Xdbl_FromDouble(3.0); + xdbl c12_ = Xdbl_FromDouble(12.0); + xdbl c1p5_ = Xdbl_FromDouble(1.5); + xdbl c2p5_ = Xdbl_FromDouble(2.5); + + xdbl sum1 = Xdbl_Add(c1, c1p5); + xdbl mul1 = Xdbl_Mul(c2, c1p5); + + xdbl sum2 = Xdbl_Add(c1p5, c2p5); + xdbl mul2 = Xdbl_Mul(c1p5, c2p5); + + xdbl a = Xdbl_FromDouble(1.2929725); + xdbl b = Xdbl_FromDouble(10.28828287); + xdbl ab = Xdbl_Mul(a, b); + + xdbl ten100 = Xdbl_FromDouble( 1e100 ); + xdbl ten100_ = ABC_CONST(0x014c924d692ca61b); + + assert( ten100 == ten100_ ); + +// float f1 = Xdbl_ToDouble(c1); +// Extra_PrintBinary( stdout, (int *)&c1, 32 ); printf( "\n" ); +// Extra_PrintBinary( stdout, (int *)&f1, 32 ); printf( "\n" ); + + printf( "1 = %lf\n", Xdbl_ToDouble(c1) ); + printf( "2 = %lf\n", Xdbl_ToDouble(c2) ); + printf( "3 = %lf\n", Xdbl_ToDouble(c3) ); + printf( "12 = %lf\n", Xdbl_ToDouble(c12) ); + printf( "1.5 = %lf\n", Xdbl_ToDouble(c1p5) ); + printf( "2.5 = %lf\n", Xdbl_ToDouble(c2p5) ); + + printf( "Converted 1 = %lf\n", Xdbl_ToDouble(c1_) ); + printf( "Converted 2 = %lf\n", Xdbl_ToDouble(c2_) ); + printf( "Converted 3 = %lf\n", Xdbl_ToDouble(c3_) ); + printf( "Converted 12 = %lf\n", Xdbl_ToDouble(c12_) ); + printf( "Converted 1.5 = %lf\n", Xdbl_ToDouble(c1p5_) ); + printf( "Converted 2.5 = %lf\n", Xdbl_ToDouble(c2p5_) ); + + printf( "1.0 + 1.5 = %lf\n", Xdbl_ToDouble(sum1) ); + printf( "2.0 * 1.5 = %lf\n", Xdbl_ToDouble(mul1) ); + + printf( "1.5 + 2.5 = %lf\n", Xdbl_ToDouble(sum2) ); + printf( "1.5 * 2.5 = %lf\n", Xdbl_ToDouble(mul2) ); + printf( "12 / 2^2 = %lf\n", Xdbl_ToDouble(Xdbl_Div(c12, 2)) ); + + printf( "12 / 2^2 = %lf\n", Xdbl_ToDouble(Xdbl_Div(c12, 2)) ); + + printf( "%.16lf * %.16lf = %.16lf (%.16lf)\n", Xdbl_ToDouble(a), Xdbl_ToDouble(b), Xdbl_ToDouble(ab), 1.2929725 * 10.28828287 ); + + assert( sum1 == c2p5 ); + assert( mul1 == c3 ); +} + +ABC_NAMESPACE_HEADER_END + +#endif diff --git a/src/sat/xsat/xsatFloat.h b/src/sat/xsat/xsatFloat.h index 901497837..fb451a945 100644 --- a/src/sat/xsat/xsatFloat.h +++ b/src/sat/xsat/xsatFloat.h @@ -22,7 +22,6 @@ #define ABC__sat__xSAT__xsatFloat_h #include "misc/util/abc_global.h" -#include "misc/vec/vecInt.h" ABC_NAMESPACE_HEADER_START From ab2d3acac99620aef7d5b1c48eb59ee33bb2b584 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Sat, 11 Feb 2017 13:28:22 -0800 Subject: [PATCH 132/185] New implementation of a software floating point implementation (sdbl) for consistency across different platforms and compilers. Removing useless files and compile time options related to variable activity data type (it can only be sdbl). --- src/sat/satoko/act_clause.h | 36 ---- src/sat/satoko/act_var.h | 70 +------- src/sat/satoko/satoko.h | 5 +- src/sat/satoko/solver.h | 2 +- src/sat/satoko/solver_api.c | 6 +- src/sat/satoko/types.h | 67 ++------ src/sat/satoko/utils/fixed.h | 67 -------- src/sat/satoko/utils/heap.h | 2 +- src/sat/satoko/utils/sdbl.h | 133 +++++++++++++++ src/sat/satoko/utils/vec/vec_dble.h | 246 --------------------------- src/sat/satoko/utils/vec/vec_sdbl.h | 247 ++++++++++++++++++++++++++++ 11 files changed, 412 insertions(+), 469 deletions(-) delete mode 100644 src/sat/satoko/utils/fixed.h create mode 100644 src/sat/satoko/utils/sdbl.h delete mode 100755 src/sat/satoko/utils/vec/vec_dble.h create mode 100755 src/sat/satoko/utils/vec/vec_sdbl.h diff --git a/src/sat/satoko/act_clause.h b/src/sat/satoko/act_clause.h index 1465e5ee0..ade5e5692 100644 --- a/src/sat/satoko/act_clause.h +++ b/src/sat/satoko/act_clause.h @@ -15,40 +15,6 @@ #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START -#ifdef SATOKO_ACT_CLAUSE_FLOAT - -/** Re-scale the activity value for all clauses. - */ -static inline void clause_act_rescale(solver_t *s) -{ - unsigned i, cref; - struct clause *clause; - - vec_uint_foreach(s->learnts, cref, i) { - clause = clause_read(s, cref); - clause->data[clause->size].act *= (float)1e-20; - } - s->clause_act_inc *= (float)1e-20; -} - -/** Increment the activity value of one clause ('clause') - */ -static inline void clause_act_bump(solver_t *s, struct clause *clause) -{ - clause->data[clause->size].act += s->clause_act_inc; - if (clause->data[clause->size].act > 1e20) - clause_act_rescale(s); -} - -/** Increment the value by which clauses activity values are incremented - */ -static inline void clause_act_decay(solver_t *s) -{ - s->clause_act_inc *= (1 / s->opts.clause_decay); -} - -#else /* SATOKO_ACT_CLAUSE_FLOAT */ - static inline void clause_act_rescale(solver_t *s) { unsigned i, cref; @@ -73,7 +39,5 @@ static inline void clause_act_decay(solver_t *s) s->clause_act_inc += (s->clause_act_inc >> 10); } -#endif /* SATOKO_ACT_CLAUSE_FLOAT */ - ABC_NAMESPACE_HEADER_END #endif /* satoko__act_clause_h */ diff --git a/src/sat/satoko/act_var.h b/src/sat/satoko/act_var.h index b1fdb756a..6b0ff98ab 100644 --- a/src/sat/satoko/act_var.h +++ b/src/sat/satoko/act_var.h @@ -12,11 +12,11 @@ #include "solver.h" #include "types.h" #include "utils/heap.h" +#include "utils/sdbl.h" #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START -#if defined SATOKO_ACT_VAR_DBLE /** Re-scale the activity value for all variables. */ static inline void var_act_rescale(solver_t *s) @@ -24,9 +24,9 @@ static inline void var_act_rescale(solver_t *s) unsigned i; act_t *activity = vec_act_data(s->activity); - for (i = 0; i < vec_act_size(s->activity); i++) - activity[i] *= s->opts.var_act_rescale; - s->var_act_inc *= s->opts.var_act_rescale; + for (i = 0; i < vec_sdbl_size(s->activity); i++) + activity[i] = sdbl_div(activity[i], s->opts.var_act_rescale); + s->var_act_inc = sdbl_div(s->var_act_inc, s->opts.var_act_rescale); } /** Increment the activity value of one variable ('var') @@ -35,7 +35,7 @@ static inline void var_act_bump(solver_t *s, unsigned var) { act_t *activity = vec_act_data(s->activity); - activity[var] += s->var_act_inc; + activity[var] = sdbl_add(activity[var], s->var_act_inc); if (activity[var] > s->opts.var_act_limit) var_act_rescale(s); if (heap_in_heap(s->var_order, var)) @@ -46,66 +46,8 @@ static inline void var_act_bump(solver_t *s, unsigned var) */ static inline void var_act_decay(solver_t *s) { - s->var_act_inc *= (1 / s->opts.var_decay); + s->var_act_inc = sdbl_mult(s->var_act_inc, double2sdbl(1 /s->opts.var_decay)); } -#elif defined(SATOKO_ACT_VAR_FIXED) - -static inline void var_act_rescale(solver_t *s) -{ - unsigned i; - act_t *activity = (act_t *)vec_act_data(s->activity); - - for (i = 0; i < vec_act_size(s->activity); i++) - activity[i] = fixed_mult(activity[i], VAR_ACT_RESCALE); - s->var_act_inc = fixed_mult(s->var_act_inc, VAR_ACT_RESCALE); -} - -static inline void var_act_bump(solver_t *s, unsigned var) -{ - act_t *activity = (act_t *)vec_act_data(s->activity); - - activity[var] = fixed_add(activity[var], s->var_act_inc); - if (activity[var] > VAR_ACT_LIMIT) - var_act_rescale(s); - if (heap_in_heap(s->var_order, var)) - heap_decrease(s->var_order, var); -} - -static inline void var_act_decay(solver_t *s) -{ - s->var_act_inc = fixed_mult(s->var_act_inc, dble2fixed(1 / s->opts.var_decay)); -} - -#else - -static inline void var_act_rescale(solver_t *s) -{ - unsigned i; - act_t *activity = vec_act_data(s->activity); - - for (i = 0; i < vec_act_size(s->activity); i++) - activity[i] >>= 19; - s->var_act_inc = stk_uint_max((s->var_act_inc >> 19), (1 << 5)); -} - -static inline void var_act_bump(solver_t *s, unsigned var) -{ - act_t *activity = vec_act_data(s->activity); - - activity[var] += s->var_act_inc; - if (activity[var] & 0xF0000000) - var_act_rescale(s); - if (heap_in_heap(s->var_order, var)) - heap_decrease(s->var_order, var); -} - -static inline void var_act_decay(solver_t *s) -{ - s->var_act_inc += (s->var_act_inc >> 4); -} - -#endif /* SATOKO_ACT_VAR_DBLE || SATOKO_ACT_VAR_FIXED */ - ABC_NAMESPACE_HEADER_END #endif /* satoko__act_var_h */ diff --git a/src/sat/satoko/satoko.h b/src/sat/satoko/satoko.h index 363fe2fd3..e3134b77a 100644 --- a/src/sat/satoko/satoko.h +++ b/src/sat/satoko/satoko.h @@ -49,10 +49,11 @@ struct satoko_opts { float learnt_ratio; /* Percentage of learned clauses to remove */ /* VSIDS heuristic */ - float clause_decay; double var_decay; + float clause_decay; + unsigned var_act_rescale; act_t var_act_limit; - act_t var_act_rescale; + /* Binary resolution */ unsigned clause_max_sz_bin_resol; diff --git a/src/sat/satoko/solver.h b/src/sat/satoko/solver.h index a46b0c9dc..849d738a6 100644 --- a/src/sat/satoko/solver.h +++ b/src/sat/satoko/solver.h @@ -24,7 +24,7 @@ #include "utils/mem.h" #include "utils/misc.h" #include "utils/vec/vec_char.h" -#include "utils/vec/vec_dble.h" +#include "utils/vec/vec_sdbl.h" #include "utils/vec/vec_uint.h" #include "misc/util/abc_global.h" diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c index ccab7685f..f3f3d781d 100644 --- a/src/sat/satoko/solver_api.c +++ b/src/sat/satoko/solver_api.c @@ -169,7 +169,7 @@ void satoko_default_opts(satoko_opts_t *opts) /* VSIDS heuristic */ opts->var_act_limit = VAR_ACT_LIMIT; opts->var_act_rescale = VAR_ACT_RESCALE; - opts->var_decay = VAR_ACT_DECAY; + opts->var_decay = 0.95; opts->clause_decay = (clause_act_t) 0.995; /* Binary resolution */ opts->clause_max_sz_bin_resol = 30; @@ -222,7 +222,9 @@ void satoko_add_variable(solver_t *s, char sign) vec_wl_push(s->bin_watches); vec_wl_push(s->watches); vec_wl_push(s->watches); - vec_act_push_back(s->activity, 0); + /* Variable activity are initialized with the lowest possible value + * which in satoko double implementation (SDBL) is the constant 1 */ + vec_act_push_back(s->activity, SDBL_CONST1); vec_uint_push_back(s->levels, 0); vec_char_push_back(s->assigns, VAR_UNASSING); vec_char_push_back(s->polarity, sign); diff --git a/src/sat/satoko/types.h b/src/sat/satoko/types.h index 5d5d4b989..d51aed4c0 100644 --- a/src/sat/satoko/types.h +++ b/src/sat/satoko/types.h @@ -9,62 +9,29 @@ #ifndef satoko__types_h #define satoko__types_h -#include "utils/fixed.h" -#include "utils/vec/vec_dble.h" -#include "utils/vec/vec_uint.h" +#include "utils/sdbl.h" +#include "utils/vec/vec_sdbl.h" #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START -#define SATOKO_ACT_VAR_DBLE -// #define SATOKO_ACT_VAR_FIXED -#define SATOKO_ACT_CLAUSE_FLOAT +/* In Satoko ABC version this file is useless */ -#ifdef SATOKO_ACT_VAR_DBLE - #define VAR_ACT_INIT_INC 1.0 - #define VAR_ACT_LIMIT (double)1e100 - #define VAR_ACT_RESCALE (double)1e-100 - #define VAR_ACT_DECAY (double)0.95 - typedef double act_t; - typedef vec_dble_t vec_act_t ; - #define vec_act_alloc(size) vec_dble_alloc(size) - #define vec_act_free(vec) vec_dble_free(vec) - #define vec_act_size(vec) vec_dble_size(vec) - #define vec_act_data(vec) vec_dble_data(vec) - #define vec_act_at(vec, idx) vec_dble_at(vec, idx) - #define vec_act_push_back(vec, value) vec_dble_push_back(vec, value) -#elif defined(SATOKO_ACT_VAR_FIXED) - #define VAR_ACT_INIT_INC FIXED_ONE - #define VAR_ACT_LIMIT (fixed_t)0xDFFFFFFF - #define VAR_ACT_RESCALE (fixed_t)0x00000012 - #define VAR_ACT_DECAY (double)0.96 - typedef fixed_t act_t; - typedef vec_uint_t vec_act_t; - #define vec_act_alloc(size) vec_uint_alloc(size) - #define vec_act_free(vec) vec_uint_free(vec) - #define vec_act_size(vec) vec_uint_size(vec) - #define vec_act_data(vec) vec_uint_data(vec) - #define vec_act_at(vec, idx) vec_uint_at(vec, idx) - #define vec_act_push_back(vec, value) vec_uint_push_back(vec, value) -#else - #define VAR_ACT_INIT_INC (1 << 5) - typedef unsigned act_t; - typedef vec_uint_t vec_act_t; - #define vec_act_alloc(size) vec_uint_alloc(size) - #define vec_act_free(vec) vec_uint_free(vec) - #define vec_act_size(vec) vec_uint_size(vec) - #define vec_act_data(vec) vec_uint_data(vec) - #define vec_act_at(vec, idx) vec_uint_at(vec, idx) - #define vec_act_push_back(vec, value) vec_uint_push_back(vec, value) -#endif /* SATOKO_ACT_VAR_DBLE */ +#define VAR_ACT_INIT_INC SDBL_CONST1 +#define VAR_ACT_LIMIT ABC_CONST(0x014c924d692ca61b) +#define VAR_ACT_RESCALE 200 +typedef sdbl_t act_t; +typedef vec_sdbl_t vec_act_t ; +#define vec_act_alloc(size) vec_sdbl_alloc(size) +#define vec_act_free(vec) vec_sdbl_free(vec) +#define vec_act_size(vec) vec_sdbl_size(vec) +#define vec_act_data(vec) vec_sdbl_data(vec) +#define vec_act_at(vec, idx) vec_sdbl_at(vec, idx) +#define vec_act_push_back(vec, value) vec_sdbl_push_back(vec, value) -#ifdef SATOKO_ACT_CLAUSE_FLOAT - #define CLAUSE_ACT_INIT_INC 1.0 - typedef float clause_act_t; -#else - #define CLAUSE_ACT_INIT_INC (1 << 11) - typedef unsigned clause_act_t; -#endif /* SATOKO_ACT_CLAUSE_FLOAT */ + +#define CLAUSE_ACT_INIT_INC (1 << 11) +typedef unsigned clause_act_t; ABC_NAMESPACE_HEADER_END #endif /* satoko__types_h */ diff --git a/src/sat/satoko/utils/fixed.h b/src/sat/satoko/utils/fixed.h deleted file mode 100644 index bddd1bb48..000000000 --- a/src/sat/satoko/utils/fixed.h +++ /dev/null @@ -1,67 +0,0 @@ -//===--- sort.h -------------------------------------------------------------=== -// -// satoko: Satisfiability solver -// -// This file is distributed under the BSD 2-Clause License. -// See LICENSE for details. -// -//===------------------------------------------------------------------------=== -#ifndef satoko__utils__fixed_h -#define satoko__utils__fixed_h - -#include "misc.h" - -#include "misc/util/abc_global.h" -ABC_NAMESPACE_HEADER_START - -typedef unsigned fixed_t; -static const int FIXED_W_BITS = 16; /* */ -static const int FIXED_F_BITS = 16;//32 - FIXED_W_BITS; -static const int FIXED_F_MASK = 0xFFFF; //(1 << FIXED_F_BITS) - 1; -static const fixed_t FIXED_MAX = 0xFFFFFFFF; -static const fixed_t FIXED_MIN = 0x00000000; -static const fixed_t FIXED_ONE = 0x10000;//(1 << FIXED_F_BITS); - -/* Conversion functions */ -static inline fixed_t uint2fixed(unsigned a) { return a * FIXED_ONE; } -static inline unsigned fixed2uint(fixed_t a) -{ - return (a + (FIXED_ONE >> 1)) / FIXED_ONE; -} - -static inline float fixed2float(fixed_t a) { return (float)a / FIXED_ONE; } -static inline fixed_t float2fixed(float a) -{ - float temp = a * FIXED_ONE; - temp += (temp >= 0) ? 0.5f : -0.5f; - return (fixed_t)temp; -} - -static inline double fixed2dble(fixed_t a) { return (double)a / FIXED_ONE; } -static inline fixed_t dble2fixed(double a) -{ - double temp = a * FIXED_ONE; - temp += (temp >= 0) ? 0.5f : -0.5f; - return (fixed_t)temp; -} - -static inline fixed_t fixed_add(fixed_t a, fixed_t b) { return (a + b); } -static inline fixed_t fixed_mult(fixed_t a, fixed_t b) -{ - unsigned hi_a = (a >> FIXED_F_BITS), lo_a = (a & FIXED_F_MASK); - unsigned hi_b = (b >> FIXED_F_BITS), lo_b = (b & FIXED_F_MASK); - unsigned lo_ab = lo_a * lo_b; - unsigned ab_ab = (hi_a * lo_b) + (lo_a * hi_b); - unsigned hi_ret = (hi_a * hi_b) + (ab_ab >> FIXED_F_BITS); - unsigned lo_ret = lo_ab + (ab_ab << FIXED_W_BITS); - - /* Carry */ - if (lo_ret < lo_ab) - hi_ret++; - - return (hi_ret << FIXED_F_BITS) | (lo_ret >> FIXED_W_BITS); -} - -ABC_NAMESPACE_HEADER_END - -#endif /* satoko__utils__fixed_h */ diff --git a/src/sat/satoko/utils/heap.h b/src/sat/satoko/utils/heap.h index e1611e95a..8b1d8f4b7 100644 --- a/src/sat/satoko/utils/heap.h +++ b/src/sat/satoko/utils/heap.h @@ -11,7 +11,7 @@ #include "mem.h" #include "../types.h" -#include "vec/vec_dble.h" +#include "vec/vec_sdbl.h" #include "vec/vec_int.h" #include "vec/vec_uint.h" diff --git a/src/sat/satoko/utils/sdbl.h b/src/sat/satoko/utils/sdbl.h new file mode 100644 index 000000000..9f90ba021 --- /dev/null +++ b/src/sat/satoko/utils/sdbl.h @@ -0,0 +1,133 @@ +//===--- sdbl.h -------------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +// by Alan Mishchenko +#ifndef satoko__utils__sdbl_h +#define satoko__utils__sdbl_h + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START +/* + The sdbl_t floating-point number is represented as a 64-bit unsigned int. + The number is (2^expt)*mnt, where expt is a 16-bit exponent and mnt is a + 48-bit mantissa. The decimal point is located between the MSB of mnt, + which is always 1, and the remaining 15 digits of mnt. + + Currently, only positive numbers are represented. + + The range of possible values is [1.0; 2^(2^16-1)*1.111111111111111] + that is, the smallest possible number is 1.0 and the largest possible + number is 2^(---16 ones---).(1.---47 ones---) + + Comparison of numbers can be done by comparing the underlying unsigned ints. + + Only addition, multiplication, and division by 2^n are currently implemented. +*/ + +typedef word sdbl_t; + +static sdbl_t SDBL_CONST1 = ABC_CONST(0x0000800000000000); +static sdbl_t SDBL_MAX = ~(sdbl_t)(0); + +union ui64_dbl { word ui64; double dbl; }; + +static inline word sdbl_exp(sdbl_t a) { return a >> 48; } +static inline word sdbl_mnt(sdbl_t a) { return (a << 16) >> 16; } + +static inline double sdbl2double(sdbl_t a) { + union ui64_dbl temp; + assert(sdbl_exp(a) < 1023); + temp.ui64 = ((sdbl_exp(a) + 1023) << 52) | (((a << 17) >> 17) << 5); + return temp.dbl; +} + +static inline sdbl_t double2sdbl(double value) +{ + union ui64_dbl temp; + sdbl_t expt, mnt; + assert(value >= 1.0); + temp.dbl = value; + expt = (temp.ui64 >> 52) - 1023; + mnt = SDBL_CONST1 | ((temp.ui64 << 12) >> 17); + return (expt << 48) + mnt; +} + +static inline sdbl_t sdbl_add(sdbl_t a, sdbl_t b) +{ + sdbl_t expt, mnt; + if (a < b) { + a ^= b; + b ^= a; + a ^= b; + } + assert(a >= b); + expt = sdbl_exp(a); + mnt = sdbl_mnt(a) + (sdbl_mnt(b) >> (sdbl_exp(a) - sdbl_exp(b))); + /* Check for carry */ + if (mnt >> 48) { + expt++; + mnt >>= 1; + } + if (expt >> 16) /* overflow */ + return SDBL_MAX; + return (expt << 48) + mnt; +} + +static inline sdbl_t sdbl_mult(sdbl_t a, sdbl_t b) +{ + sdbl_t expt, mnt; + sdbl_t a_mnt, a_mnt_hi, a_mnt_lo; + sdbl_t b_mnt, b_mnt_hi, b_mnt_lo; + if (a < b) { + a ^= b; + b ^= a; + a ^= b; + } + assert( a >= b ); + a_mnt = sdbl_mnt(a); + b_mnt = sdbl_mnt(b); + a_mnt_hi = a_mnt>>32; + b_mnt_hi = b_mnt>>32; + a_mnt_lo = (a_mnt<<32)>>32; + b_mnt_lo = (b_mnt<<32)>>32; + mnt = ((a_mnt_hi * b_mnt_hi) << 17) + + ((a_mnt_lo * b_mnt_lo) >> 47) + + ((a_mnt_lo * b_mnt_hi) >> 15) + + ((a_mnt_hi * b_mnt_lo) >> 15); + expt = sdbl_exp(a) + sdbl_exp(b); + /* Check for carry */ + if (mnt >> 48) { + expt++; + mnt >>= 1; + } + if (expt >> 16) /* overflow */ + return SDBL_MAX; + return (expt << 48) + mnt; +} + +static inline sdbl_t sdbl_div(sdbl_t a, unsigned deg2) +{ + if (sdbl_exp(a) >= (word)deg2) + return ((sdbl_exp(a) - deg2) << 48) + sdbl_mnt(a); + return SDBL_CONST1; +} + +static inline void sdbl_test() +{ + sdbl_t ten100_ = ABC_CONST(0x014c924d692ca61b); + printf("%f\n", sdbl2double(ten100_)); + printf("%016lX\n", double2sdbl(1 /0.95)); + printf("%016lX\n", SDBL_CONST1); + printf("%f\n", sdbl2double(SDBL_CONST1)); + printf("%f\n", sdbl2double(ABC_CONST(0x000086BCA1AF286B))); + +} + +ABC_NAMESPACE_HEADER_END + +#endif /* satoko__utils__sdbl_h */ diff --git a/src/sat/satoko/utils/vec/vec_dble.h b/src/sat/satoko/utils/vec/vec_dble.h deleted file mode 100755 index 50281c2a5..000000000 --- a/src/sat/satoko/utils/vec/vec_dble.h +++ /dev/null @@ -1,246 +0,0 @@ -//===--- vec_int.h ----------------------------------------------------------=== -// -// satoko: Satisfiability solver -// -// This file is distributed under the BSD 2-Clause License. -// See LICENSE for details. -// -//===------------------------------------------------------------------------=== -#ifndef satoko__utils__vec__vec_dble_h -#define satoko__utils__vec__vec_dble_h - -#include -#include -#include - -#include "../mem.h" - -#include "misc/util/abc_global.h" -ABC_NAMESPACE_HEADER_START - -typedef struct vec_dble_t_ vec_dble_t; -struct vec_dble_t_ { - unsigned cap; - unsigned size; - double *data; -}; - -//===------------------------------------------------------------------------=== -// Vector Macros -//===------------------------------------------------------------------------=== -#define vec_dble_foreach(vec, entry, i) \ - for (i = 0; (i < vec->size) && (((entry) = vec_dble_at(vec, i)), 1); i++) - -#define vec_dble_foreach_start(vec, entry, i, start) \ - for (i = start; (i < vec_dble_size(vec)) && (((entry) = vec_dble_at(vec, i)), 1); i++) - -#define vec_dble_foreach_stop(vec, entry, i, stop) \ - for (i = 0; (i < stop) && (((entry) = vec_dble_at(vec, i)), 1); i++) - -//===------------------------------------------------------------------------=== -// Vector API -//===------------------------------------------------------------------------=== -static inline vec_dble_t *vec_dble_alloc(unsigned cap) -{ - vec_dble_t* p = satoko_alloc(vec_dble_t, 1); - - if (cap > 0 && cap < 16) - cap = 16; - p->size = 0; - p->cap = cap; - p->data = p->cap ? satoko_alloc(double, p->cap) : NULL; - return p; -} - -static inline vec_dble_t *vec_dble_alloc_exact(unsigned cap) -{ - vec_dble_t* p = satoko_alloc(vec_dble_t, 1); - - p->size = 0; - p->cap = cap; - p->data = p->cap ? satoko_alloc(double, p->cap) : NULL; - return p; -} - -static inline vec_dble_t *vec_dble_init(unsigned size, double value) -{ - vec_dble_t* p = satoko_alloc(vec_dble_t, 1); - - p->cap = size; - p->size = size; - p->data = p->cap ? satoko_alloc(double, p->cap) : NULL; - memset(p->data, value, sizeof(double) * p->size); - return p; -} - -static inline void vec_dble_free(vec_dble_t *p) -{ - if (p->data != NULL) - satoko_free(p->data); - satoko_free(p); -} - -static inline unsigned vec_dble_size(vec_dble_t *p) -{ - return p->size; -} - -static inline void vec_dble_resize(vec_dble_t *p, unsigned new_size) -{ - p->size = new_size; - if (p->cap >= new_size) - return; - p->data = satoko_realloc(double, p->data, new_size); - assert(p->data != NULL); - p->cap = new_size; -} - -static inline void vec_dble_reserve(vec_dble_t *p, unsigned new_cap) -{ - if (p->cap >= new_cap) - return; - p->data = satoko_realloc(double, p->data, new_cap); - assert(p->data != NULL); - p->cap = new_cap; -} - -static inline unsigned vec_dble_capacity(vec_dble_t *p) -{ - return p->cap; -} - -static inline int vec_dble_empty(vec_dble_t *p) -{ - return p->size ? 0 : 1; -} - -static inline void vec_dble_erase(vec_dble_t *p) -{ - satoko_free(p->data); - p->size = 0; - p->cap = 0; -} - -static inline double vec_dble_at(vec_dble_t *p, unsigned i) -{ - assert(i >= 0 && i < p->size); - return p->data[i]; -} - -static inline double *vec_dble_at_ptr(vec_dble_t *p, unsigned i) -{ - assert(i >= 0 && i < p->size); - return p->data + i; -} - -static inline double *vec_dble_data(vec_dble_t *p) -{ - assert(p); - return p->data; -} - -static inline void vec_dble_duplicate(vec_dble_t *dest, const vec_dble_t *src) -{ - assert(dest != NULL && src != NULL); - vec_dble_resize(dest, src->cap); - memcpy(dest->data, src->data, sizeof(double) * src->cap); - dest->size = src->size; -} - -static inline void vec_dble_copy(vec_dble_t *dest, const vec_dble_t *src) -{ - assert(dest != NULL && src != NULL); - vec_dble_resize(dest, src->size); - memcpy(dest->data, src->data, sizeof(double) * src->size); - dest->size = src->size; -} - -static inline void vec_dble_push_back(vec_dble_t *p, double value) -{ - if (p->size == p->cap) { - if (p->cap < 16) - vec_dble_reserve(p, 16); - else - vec_dble_reserve(p, 2 * p->cap); - } - p->data[p->size] = value; - p->size++; -} - -static inline void vec_dble_assign(vec_dble_t *p, unsigned i, double value) -{ - assert((i >= 0) && (i < vec_dble_size(p))); - p->data[i] = value; -} - -static inline void vec_dble_insert(vec_dble_t *p, unsigned i, double value) -{ - assert((i >= 0) && (i < vec_dble_size(p))); - vec_dble_push_back(p, 0); - memmove(p->data + i + 1, p->data + i, (p->size - i - 2) * sizeof(double)); - p->data[i] = value; -} - -static inline void vec_dble_drop(vec_dble_t *p, unsigned i) -{ - assert((i >= 0) && (i < vec_dble_size(p))); - memmove(p->data + i, p->data + i + 1, (p->size - i - 1) * sizeof(double)); - p->size -= 1; -} - -static inline void vec_dble_clear(vec_dble_t *p) -{ - p->size = 0; -} - -static inline int vec_dble_asc_compare(const void *p1, const void *p2) -{ - const double *pp1 = (const double *) p1; - const double *pp2 = (const double *) p2; - - if (*pp1 < *pp2) - return -1; - if (*pp1 > *pp2) - return 1; - return 0; -} - -static inline int vec_dble_desc_compare(const void* p1, const void* p2) -{ - const double *pp1 = (const double *) p1; - const double *pp2 = (const double *) p2; - - if (*pp1 > *pp2) - return -1; - if (*pp1 < *pp2) - return 1; - return 0; -} - -static inline void vec_dble_sort(vec_dble_t* p, int ascending) -{ - if (ascending) - qsort((void *) p->data, p->size, sizeof(double), - (int (*)(const void*, const void*)) vec_dble_asc_compare); - else - qsort((void *) p->data, p->size, sizeof(double), - (int (*)(const void*, const void*)) vec_dble_desc_compare); -} - -static inline long vec_dble_memory(vec_dble_t *p) -{ - return p == NULL ? 0 : sizeof(double) * p->cap + sizeof(vec_dble_t); -} - -static inline void vec_dble_print(vec_dble_t *p) -{ - unsigned i; - assert(p != NULL); - fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap); - for (i = 0; i < p->size; i++) - fprintf(stdout, " %f", p->data[i]); - fprintf(stdout, " }\n"); -} - -ABC_NAMESPACE_HEADER_END -#endif /* satoko__utils__vec__vec_dble_h */ diff --git a/src/sat/satoko/utils/vec/vec_sdbl.h b/src/sat/satoko/utils/vec/vec_sdbl.h new file mode 100755 index 000000000..aefd687a4 --- /dev/null +++ b/src/sat/satoko/utils/vec/vec_sdbl.h @@ -0,0 +1,247 @@ +//===--- vec_int.h ----------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__utils__vec__vec_sdbl_h +#define satoko__utils__vec__vec_sdbl_h + +#include +#include +#include + +#include "../mem.h" +#include "../sdbl.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +typedef struct vec_sdbl_t_ vec_sdbl_t; +struct vec_sdbl_t_ { + unsigned cap; + unsigned size; + sdbl_t *data; +}; + +//===------------------------------------------------------------------------=== +// Vector Macros +//===------------------------------------------------------------------------=== +#define vec_sdbl_foreach(vec, entry, i) \ + for (i = 0; (i < vec->size) && (((entry) = vec_sdbl_at(vec, i)), 1); i++) + +#define vec_sdbl_foreach_start(vec, entry, i, start) \ + for (i = start; (i < vec_sdbl_size(vec)) && (((entry) = vec_sdbl_at(vec, i)), 1); i++) + +#define vec_sdbl_foreach_stop(vec, entry, i, stop) \ + for (i = 0; (i < stop) && (((entry) = vec_sdbl_at(vec, i)), 1); i++) + +//===------------------------------------------------------------------------=== +// Vector API +//===------------------------------------------------------------------------=== +static inline vec_sdbl_t *vec_sdbl_alloc(unsigned cap) +{ + vec_sdbl_t* p = satoko_alloc(vec_sdbl_t, 1); + + if (cap > 0 && cap < 16) + cap = 16; + p->size = 0; + p->cap = cap; + p->data = p->cap ? satoko_alloc(sdbl_t, p->cap) : NULL; + return p; +} + +static inline vec_sdbl_t *vec_sdbl_alloc_exact(unsigned cap) +{ + vec_sdbl_t* p = satoko_alloc(vec_sdbl_t, 1); + + p->size = 0; + p->cap = cap; + p->data = p->cap ? satoko_alloc(sdbl_t, p->cap) : NULL; + return p; +} + +static inline vec_sdbl_t *vec_sdbl_init(unsigned size, sdbl_t value) +{ + vec_sdbl_t* p = satoko_alloc(vec_sdbl_t, 1); + + p->cap = size; + p->size = size; + p->data = p->cap ? satoko_alloc(sdbl_t, p->cap) : NULL; + memset(p->data, value, sizeof(sdbl_t) * p->size); + return p; +} + +static inline void vec_sdbl_free(vec_sdbl_t *p) +{ + if (p->data != NULL) + satoko_free(p->data); + satoko_free(p); +} + +static inline unsigned vec_sdbl_size(vec_sdbl_t *p) +{ + return p->size; +} + +static inline void vec_sdbl_resize(vec_sdbl_t *p, unsigned new_size) +{ + p->size = new_size; + if (p->cap >= new_size) + return; + p->data = satoko_realloc(sdbl_t, p->data, new_size); + assert(p->data != NULL); + p->cap = new_size; +} + +static inline void vec_sdbl_reserve(vec_sdbl_t *p, unsigned new_cap) +{ + if (p->cap >= new_cap) + return; + p->data = satoko_realloc(sdbl_t, p->data, new_cap); + assert(p->data != NULL); + p->cap = new_cap; +} + +static inline unsigned vec_sdbl_capacity(vec_sdbl_t *p) +{ + return p->cap; +} + +static inline int vec_sdbl_empty(vec_sdbl_t *p) +{ + return p->size ? 0 : 1; +} + +static inline void vec_sdbl_erase(vec_sdbl_t *p) +{ + satoko_free(p->data); + p->size = 0; + p->cap = 0; +} + +static inline sdbl_t vec_sdbl_at(vec_sdbl_t *p, unsigned i) +{ + assert(i >= 0 && i < p->size); + return p->data[i]; +} + +static inline sdbl_t *vec_sdbl_at_ptr(vec_sdbl_t *p, unsigned i) +{ + assert(i >= 0 && i < p->size); + return p->data + i; +} + +static inline sdbl_t *vec_sdbl_data(vec_sdbl_t *p) +{ + assert(p); + return p->data; +} + +static inline void vec_sdbl_duplicate(vec_sdbl_t *dest, const vec_sdbl_t *src) +{ + assert(dest != NULL && src != NULL); + vec_sdbl_resize(dest, src->cap); + memcpy(dest->data, src->data, sizeof(sdbl_t) * src->cap); + dest->size = src->size; +} + +static inline void vec_sdbl_copy(vec_sdbl_t *dest, const vec_sdbl_t *src) +{ + assert(dest != NULL && src != NULL); + vec_sdbl_resize(dest, src->size); + memcpy(dest->data, src->data, sizeof(sdbl_t) * src->size); + dest->size = src->size; +} + +static inline void vec_sdbl_push_back(vec_sdbl_t *p, sdbl_t value) +{ + if (p->size == p->cap) { + if (p->cap < 16) + vec_sdbl_reserve(p, 16); + else + vec_sdbl_reserve(p, 2 * p->cap); + } + p->data[p->size] = value; + p->size++; +} + +static inline void vec_sdbl_assign(vec_sdbl_t *p, unsigned i, sdbl_t value) +{ + assert((i >= 0) && (i < vec_sdbl_size(p))); + p->data[i] = value; +} + +static inline void vec_sdbl_insert(vec_sdbl_t *p, unsigned i, sdbl_t value) +{ + assert((i >= 0) && (i < vec_sdbl_size(p))); + vec_sdbl_push_back(p, 0); + memmove(p->data + i + 1, p->data + i, (p->size - i - 2) * sizeof(sdbl_t)); + p->data[i] = value; +} + +static inline void vec_sdbl_drop(vec_sdbl_t *p, unsigned i) +{ + assert((i >= 0) && (i < vec_sdbl_size(p))); + memmove(p->data + i, p->data + i + 1, (p->size - i - 1) * sizeof(sdbl_t)); + p->size -= 1; +} + +static inline void vec_sdbl_clear(vec_sdbl_t *p) +{ + p->size = 0; +} + +static inline int vec_sdbl_asc_compare(const void *p1, const void *p2) +{ + const sdbl_t *pp1 = (const sdbl_t *) p1; + const sdbl_t *pp2 = (const sdbl_t *) p2; + + if (*pp1 < *pp2) + return -1; + if (*pp1 > *pp2) + return 1; + return 0; +} + +static inline int vec_sdbl_desc_compare(const void* p1, const void* p2) +{ + const sdbl_t *pp1 = (const sdbl_t *) p1; + const sdbl_t *pp2 = (const sdbl_t *) p2; + + if (*pp1 > *pp2) + return -1; + if (*pp1 < *pp2) + return 1; + return 0; +} + +static inline void vec_sdbl_sort(vec_sdbl_t* p, int ascending) +{ + if (ascending) + qsort((void *) p->data, p->size, sizeof(sdbl_t), + (int (*)(const void*, const void*)) vec_sdbl_asc_compare); + else + qsort((void *) p->data, p->size, sizeof(sdbl_t), + (int (*)(const void*, const void*)) vec_sdbl_desc_compare); +} + +static inline long vec_sdbl_memory(vec_sdbl_t *p) +{ + return p == NULL ? 0 : sizeof(sdbl_t) * p->cap + sizeof(vec_sdbl_t); +} + +static inline void vec_sdbl_print(vec_sdbl_t *p) +{ + unsigned i; + assert(p != NULL); + fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap); + for (i = 0; i < p->size; i++) + fprintf(stdout, " %f", sdbl2double(p->data[i])); + fprintf(stdout, " }\n"); +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__utils__vec__vec_sdbl_h */ From 45f4d6c7e8678e140b363f3114b5393ed1f29681 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 11 Feb 2017 13:55:41 -0800 Subject: [PATCH 133/185] Movinng custom floating-point implementations, etc. --- abclib.dsp | 24 +++++++++---------- src/misc/util/abc_global.h | 2 ++ .../xsatDouble.h => misc/util/utilDouble.h} | 6 +---- .../xsatFloat.h => misc/util/utilFloat.h} | 5 ++-- src/sat/bsat/satSolver.h | 3 ++- 5 files changed, 19 insertions(+), 21 deletions(-) rename src/{sat/xsat/xsatDouble.h => misc/util/utilDouble.h} (96%) rename src/{sat/xsat/xsatFloat.h => misc/util/utilFloat.h} (98%) diff --git a/abclib.dsp b/abclib.dsp index 853076350..f9cc2f502 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -1971,10 +1971,6 @@ SOURCE=.\src\sat\xsat\xsatCnfReader.c # End Source File # Begin Source File -SOURCE=.\src\sat\xsat\xsatFloat.h -# End Source File -# Begin Source File - SOURCE=.\src\sat\xsat\xsatHeap.h # End Source File # Begin Source File @@ -2031,10 +2027,6 @@ SOURCE=.\src\sat\satoko\cnf_reader.c # End Source File # Begin Source File -SOURCE=.\src\sat\satoko\utils\fixed.h -# End Source File -# Begin Source File - SOURCE=.\src\sat\satoko\utils\heap.h # End Source File # Begin Source File @@ -2051,6 +2043,10 @@ SOURCE=.\src\sat\satoko\satoko.h # End Source File # Begin Source File +SOURCE=.\src\sat\satoko\utils\sdbl.h +# End Source File +# Begin Source File + SOURCE=.\src\sat\satoko\solver.c # End Source File # Begin Source File @@ -2075,10 +2071,6 @@ SOURCE=.\src\sat\satoko\utils\vec\vec_char.h # End Source File # Begin Source File -SOURCE=.\src\sat\satoko\utils\vec\vec_dble.h -# End Source File -# Begin Source File - SOURCE=.\src\sat\satoko\utils\vec\vec_flt.h # End Source File # Begin Source File @@ -3659,10 +3651,18 @@ SOURCE=.\src\misc\util\utilColor.c # End Source File # Begin Source File +SOURCE=.\src\misc\util\utilDouble.h +# End Source File +# Begin Source File + SOURCE=.\src\misc\util\utilFile.c # End Source File # Begin Source File +SOURCE=.\src\misc\util\utilFloat.h +# End Source File +# Begin Source File + SOURCE=.\src\misc\util\utilIsop.c # End Source File # Begin Source File diff --git a/src/misc/util/abc_global.h b/src/misc/util/abc_global.h index 00d5d5148..9e9068169 100644 --- a/src/misc/util/abc_global.h +++ b/src/misc/util/abc_global.h @@ -225,6 +225,8 @@ static inline double Abc_MinDouble( double a, double b ) { return a < b ? static inline int Abc_Float2Int( float Val ) { union { int x; float y; } v; v.y = Val; return v.x; } static inline float Abc_Int2Float( int Num ) { union { int x; float y; } v; v.x = Num; return v.y; } +static inline word Abc_Dbl2Word( double Dbl ) { union { word x; double y; } v; v.y = Dbl; return v.x; } +static inline double Abc_Word2Dbl( word Num ) { union { word x; double y; } v; v.x = Num; return v.y; } static inline int Abc_Base2Log( unsigned n ) { int r; if ( n < 2 ) return n; for ( r = 0, n--; n; n >>= 1, r++ ) {}; return r; } static inline int Abc_Base10Log( unsigned n ) { int r; if ( n < 2 ) return n; for ( r = 0, n--; n; n /= 10, r++ ) {}; return r; } static inline int Abc_Base16Log( unsigned n ) { int r; if ( n < 2 ) return n; for ( r = 0, n--; n; n /= 16, r++ ) {}; return r; } diff --git a/src/sat/xsat/xsatDouble.h b/src/misc/util/utilDouble.h similarity index 96% rename from src/sat/xsat/xsatDouble.h rename to src/misc/util/utilDouble.h index d90e8c05b..0d0237818 100644 --- a/src/sat/xsat/xsatDouble.h +++ b/src/misc/util/utilDouble.h @@ -1,6 +1,6 @@ /**CFile**************************************************************** - FileName [xdouble.h] + FileName [utilDouble.h] SystemName [ABC: Logic synthesis and verification system.] @@ -46,10 +46,6 @@ ABC_NAMESPACE_HEADER_START Only addition, multiplication, and division by 2^n are currently implemented. */ -static inline word Abc_Dbl2Word( double Dbl ) { union { word x; double y; } v; v.y = Dbl; return v.x; } -static inline double Abc_Word2Dbl( word Num ) { union { word x; double y; } v; v.x = Num; return v.y; } - - typedef word xdbl; static inline word Xdbl_Exp( xdbl a ) { return a >> 48; } diff --git a/src/sat/xsat/xsatFloat.h b/src/misc/util/utilFloat.h similarity index 98% rename from src/sat/xsat/xsatFloat.h rename to src/misc/util/utilFloat.h index fb451a945..f0739a922 100644 --- a/src/sat/xsat/xsatFloat.h +++ b/src/misc/util/utilFloat.h @@ -1,11 +1,10 @@ /**CFile**************************************************************** - FileName [xsatFloat.h] + FileName [utilFloat.h] SystemName [ABC: Logic synthesis and verification system.] - PackageName [xSAT - A SAT solver written in C. - Read the license file for more info.] + PackageName [] Synopsis [Floating point number implementation.] diff --git a/src/sat/bsat/satSolver.h b/src/sat/bsat/satSolver.h index 226d8c7ad..21f24fcb1 100644 --- a/src/sat/bsat/satSolver.h +++ b/src/sat/bsat/satSolver.h @@ -30,7 +30,8 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include "satVec.h" #include "satClause.h" -#include "sat/xsat/xsatFloat.h" +#include "misc/util/utilFloat.h" +#include "misc/util/utilDouble.h" ABC_NAMESPACE_HEADER_START From f6193c0d45406e863e7efe3e092e0284d86adb9b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 11 Feb 2017 15:38:50 -0800 Subject: [PATCH 134/185] Updates to variable activity in the SAT solver. --- src/sat/bsat/satSolver.c | 481 ++++++++++++++++----------------------- src/sat/bsat/satSolver.h | 87 +++---- 2 files changed, 225 insertions(+), 343 deletions(-) diff --git a/src/sat/bsat/satSolver.c b/src/sat/bsat/satSolver.c index 1a2a393db..efe8efa66 100644 --- a/src/sat/bsat/satSolver.c +++ b/src/sat/bsat/satSolver.c @@ -145,21 +145,12 @@ static inline void order_update(sat_solver* s, int v) // updateorder assert(s->orderpos[v] != -1); -#ifdef USE_FLOAT_ACTIVITY_NEW - while (i != 0 && xSat_LessThan(s->activity[heap[parent]], s->activity[x]) ){ - heap[i] = heap[parent]; - orderpos[heap[i]] = i; - i = parent; - parent = (i - 1) / 2; - } -#else while (i != 0 && s->activity[x] > s->activity[heap[parent]]){ heap[i] = heap[parent]; orderpos[heap[i]] = i; i = parent; parent = (i - 1) / 2; } -#endif heap[i] = x; orderpos[x] = i; @@ -203,19 +194,11 @@ static inline int order_select(sat_solver* s, float random_var_freq) // selectv int child = 1; while (child < size){ -#ifdef USE_FLOAT_ACTIVITY_NEW - if (child+1 < size && xSat_LessThan(s->activity[heap[child]], s->activity[heap[child+1]]) ) - child++; - assert(child < size); - if ( !xSat_LessThan(s->activity[x], s->activity[heap[child]]) ) - break; -#else if (child+1 < size && s->activity[heap[child]] < s->activity[heap[child+1]]) child++; assert(child < size); if (s->activity[x] >= s->activity[heap[child]]) break; -#endif heap[i] = heap[child]; orderpos[heap[i]] = i; @@ -233,160 +216,180 @@ static inline int order_select(sat_solver* s, float random_var_freq) // selectv void sat_solver_set_var_activity(sat_solver* s, int * pVars, int nVars) { -#ifndef USE_FLOAT_ACTIVITY_NEW int i; + assert( s->VarActType == 1 ); for (i = 0; i < s->size; i++) s->activity[i] = 0; - s->var_inc = 1; + s->var_inc = Abc_Dbl2Word(1); for ( i = 0; i < nVars; i++ ) { int iVar = pVars ? pVars[i] : i; - s->activity[iVar] = nVars-i; + s->activity[iVar] = Abc_Dbl2Word(nVars-i); order_update( s, iVar ); } -#endif } //================================================================================================= -// Activity functions: +// variable activities -#ifdef USE_FLOAT_ACTIVITY +static inline void solver_init_activities(sat_solver* s) +{ + // variable activities + s->VarActType = 0; + if ( s->VarActType == 0 ) + { + s->var_inc = (1 << 5); + s->var_decay = -1; + } + else if ( s->VarActType == 1 ) + { + s->var_inc = Abc_Dbl2Word(1.0); + s->var_decay = Abc_Dbl2Word(1.0 / 0.95); + } + else if ( s->VarActType == 2 ) + { + s->var_inc = Xdbl_FromDouble(1.0); + s->var_decay = Xdbl_FromDouble(1.0 / 0.950); + } + else assert(0); -#ifdef USE_FLOAT_ACTIVITY_NEW + // clause activities + s->ClaActType = 0; + if ( s->ClaActType == 0 ) + { + s->cla_inc = (1 << 11); + s->cla_decay = -1; + } + else + { + s->cla_inc = 1; + s->cla_decay = (float)(1 / 0.999); + } +} -static inline void act_var_rescale(sat_solver* s) { - xFloat_t * activity = s->activity; - int i; - for (i = 0; i < s->size; i++) - activity[i] = xSat_FloatDiv( activity[i], 1<<10 ); // activity[i] / 2^1024 - s->var_inc = xSat_FloatDiv( s->var_inc, 1<<10 ); +static inline void act_var_rescale(sat_solver* s) +{ + if ( s->VarActType == 0 ) + { + word* activity = s->activity; + int i; + for (i = 0; i < s->size; i++) + activity[i] >>= 19; + s->var_inc >>= 19; + s->var_inc = Abc_MaxInt( (unsigned)s->var_inc, (1<<4) ); + } + else if ( s->VarActType == 1 ) + { + double* activity = (double*)s->activity; + int i; + for (i = 0; i < s->size; i++) + activity[i] *= 1e-100; + s->var_inc = Abc_Dbl2Word( Abc_Word2Dbl(s->var_inc) * 1e-100 ); + //printf( "Rescaling var activity...\n" ); + } + else if ( s->VarActType == 2 ) + { + xdbl * activity = s->activity; + int i; + for (i = 0; i < s->size; i++) + activity[i] = Xdbl_Div( activity[i], 200 ); // activity[i] / 2^200 + s->var_inc = Xdbl_Div( s->var_inc, 200 ); + } + else assert(0); } -static inline void act_clause_rescale(sat_solver* s) { - xFloat_t* activity = (xFloat_t *)veci_begin(&s->act_clas); - int i; - for (i = 0; i < veci_size(&s->act_clas); i++) - activity[i] = xSat_FloatDiv( activity[i], 1<<10 ); // activity[i] / 2^1024 - s->cla_inc = xSat_FloatDiv( s->cla_inc, 1<<10 ); +static inline void act_var_bump(sat_solver* s, int v) +{ + if ( s->VarActType == 0 ) + { + s->activity[v] += s->var_inc; + if ((unsigned)s->activity[v] & 0x80000000) + act_var_rescale(s); + if (s->orderpos[v] != -1) + order_update(s,v); + } + else if ( s->VarActType == 1 ) + { + double act = Abc_Word2Dbl(s->activity[v]) + Abc_Word2Dbl(s->var_inc); + s->activity[v] = Abc_Dbl2Word(act); + if (act > 1e100) + act_var_rescale(s); + if (s->orderpos[v] != -1) + order_update(s,v); + } + else if ( s->VarActType == 2 ) + { + s->activity[v] = Xdbl_Add( s->activity[v], s->var_inc ); + if (s->activity[v] > ABC_CONST(0x014c924d692ca61b)) + act_var_rescale(s); + if (s->orderpos[v] != -1) + order_update(s,v); + } + else assert(0); } -static inline void act_var_bump(sat_solver* s, int v) { - s->activity[v] = xSat_FloatAdd( s->activity[v], s->var_inc ); - if ( xSat_LessThan(xSat_FloatCreate(1 << 12, 1 << 15), s->activity[v]) ) // 2^4096 < s->activity[v] - act_var_rescale(s); - if (s->orderpos[v] != -1) - order_update(s,v); -} -static inline void act_var_bump_global(sat_solver* s, int v) { +static inline void act_var_bump_global(sat_solver* s, int v) +{ assert(0); } -static inline void act_var_bump_factor(sat_solver* s, int v) { +static inline void act_var_bump_factor(sat_solver* s, int v) +{ assert(0); } -static inline void act_clause_bump(sat_solver* s, clause *c) { - xFloat_t* act = (xFloat_t *)veci_begin(&s->act_clas) + c->lits[c->size]; - *act = xSat_FloatAdd( *act, s->cla_inc ); - if ( xSat_LessThan(xSat_FloatCreate(1 << 12, 1 << 15), *act) ) // 2^4096 < *act - act_clause_rescale(s); -} -static inline void act_var_decay(sat_solver* s) { s->var_inc = xSat_FloatMul(s->var_inc, s->var_decay); } -static inline void act_clause_decay(sat_solver* s) { s->cla_inc = xSat_FloatMul(s->cla_inc, s->cla_decay); } - -#else - -static inline void act_var_rescale(sat_solver* s) { - double* activity = s->activity; - int i; - for (i = 0; i < s->size; i++) - activity[i] *= 1e-100; - s->var_inc *= 1e-100; -} -static inline void act_clause_rescale(sat_solver* s) { - float* activity = (float *)veci_begin(&s->act_clas); - int i; - for (i = 0; i < veci_size(&s->act_clas); i++) - activity[i] *= (float)1e-20; - s->cla_inc *= (float)1e-20; -} -static inline void act_var_bump(sat_solver* s, int v) { - s->activity[v] += s->var_inc; - if (s->activity[v] > 1e100) - act_var_rescale(s); - if (s->orderpos[v] != -1) - order_update(s,v); -} -static inline void act_var_bump_global(sat_solver* s, int v) { - assert(0); -} -static inline void act_var_bump_factor(sat_solver* s, int v) { - assert(0); -} -static inline void act_clause_bump(sat_solver* s, clause *c) { - float* act = (float *)veci_begin(&s->act_clas) + c->lits[c->size]; - *act += s->cla_inc; - if (*act > 1e20) - act_clause_rescale(s); -} -static inline void act_var_decay(sat_solver* s) { s->var_inc *= s->var_decay; } -static inline void act_clause_decay(sat_solver* s) { s->cla_inc *= s->cla_decay; } - -#endif - -#else - -static inline void act_var_rescale(sat_solver* s) { - unsigned* activity = s->activity; - int i; - for (i = 0; i < s->size; i++) - activity[i] >>= 19; - s->var_inc >>= 19; - s->var_inc = Abc_MaxInt( s->var_inc, (1<<4) ); +static inline void act_var_decay(sat_solver* s) +{ + if ( s->VarActType == 0 ) + s->var_inc += (s->var_inc >> 4); + else if ( s->VarActType == 1 ) + s->var_inc = Abc_Dbl2Word( Abc_Word2Dbl(s->var_inc) * Abc_Word2Dbl(s->var_decay) ); + else if ( s->VarActType == 2 ) + s->var_inc = Xdbl_Mul(s->var_inc, s->var_decay); + else assert(0); } -static inline void act_clause_rescale(sat_solver* s) { - unsigned* activity = (unsigned *)veci_begin(&s->act_clas); - int i; - for (i = 0; i < veci_size(&s->act_clas); i++) - activity[i] >>= 14; - s->cla_inc >>= 14; - s->cla_inc = Abc_MaxInt( s->cla_inc, (1<<10) ); +// clause activities +static inline void act_clause_rescale(sat_solver* s) +{ + if ( s->ClaActType == 0 ) + { + unsigned* activity = (unsigned *)veci_begin(&s->act_clas); + int i; + for (i = 0; i < veci_size(&s->act_clas); i++) + activity[i] >>= 14; + s->cla_inc >>= 14; + s->cla_inc = Abc_MaxInt( s->cla_inc, (1<<10) ); + } + else + { + float* activity = (float *)veci_begin(&s->act_clas); + int i; + for (i = 0; i < veci_size(&s->act_clas); i++) + activity[i] *= (float)1e-20; + s->cla_inc *= (float)1e-20; + } } - -static inline void act_var_bump(sat_solver* s, int v) { - s->activity[v] += s->var_inc; - if (s->activity[v] & 0x80000000) - act_var_rescale(s); - if (s->orderpos[v] != -1) - order_update(s,v); +static inline void act_clause_bump(sat_solver* s, clause *c) +{ + if ( s->ClaActType == 0 ) + { + unsigned* act = (unsigned *)veci_begin(&s->act_clas) + c->lits[c->size]; + *act += s->cla_inc; + if ( *act & 0x80000000 ) + act_clause_rescale(s); + } + else + { + float* act = (float *)veci_begin(&s->act_clas) + c->lits[c->size]; + *act += s->cla_inc; + if (*act > 1e20) + act_clause_rescale(s); + } } -static inline void act_var_bump_global(sat_solver* s, int v) { - if ( !s->pGlobalVars ) - return; - s->activity[v] += (int)(s->var_inc * 3 * s->pGlobalVars[v]); - if (s->activity[v] & 0x80000000) - act_var_rescale(s); - if (s->orderpos[v] != -1) - order_update(s,v); +static inline void act_clause_decay(sat_solver* s) +{ + if ( s->ClaActType == 0 ) + s->cla_inc += (s->cla_inc >> 10); + else + s->cla_inc *= s->cla_decay; } -static inline void act_var_bump_factor(sat_solver* s, int v) { - if ( !s->factors ) - return; - s->activity[v] += (int)(s->var_inc * s->factors[v]); - if (s->activity[v] & 0x80000000) - act_var_rescale(s); - if (s->orderpos[v] != -1) - order_update(s,v); -} - -static inline void act_clause_bump(sat_solver* s, clause*c) { - unsigned* act = (unsigned *)veci_begin(&s->act_clas) + c->lits[c->size]; - *act += s->cla_inc; - if ( *act & 0x80000000 ) - act_clause_rescale(s); -} - -static inline void act_var_decay(sat_solver* s) { s->var_inc += (s->var_inc >> 4); } -static inline void act_clause_decay(sat_solver* s) { s->cla_inc += (s->cla_inc >> 10); } - -#endif //================================================================================================= @@ -488,15 +491,10 @@ int sat_solver_clause_new(sat_solver* s, lit* begin, lit* end, int learnt) assert( clause_id(c) == veci_size(&s->act_clas) ); // veci_push(&s->learned, h); // act_clause_bump(s,clause_read(s, h)); -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - veci_push(&s->act_clas, xSat_Float2Uint(xSat_FloatCreateConst1())); -#else - veci_push(&s->act_clas, s->cla_inc); -#endif -#else - veci_push(&s->act_clas, (1<<10)); -#endif + if ( s->ClaActType == 0 ) + veci_push(&s->act_clas, (1<<10)); + else + veci_push(&s->act_clas, s->cla_inc); s->stats.learnts++; s->stats.learnts_literals += size; } @@ -1086,7 +1084,6 @@ sat_solver* sat_solver_new(void) veci_new(&s->act_clas); veci_new(&s->stack); // veci_new(&s->model); - veci_new(&s->act_vars); veci_new(&s->unit_lits); veci_new(&s->temp_clause); veci_new(&s->conf_final); @@ -1103,22 +1100,10 @@ sat_solver* sat_solver_new(void) s->cap = 0; s->qhead = 0; s->qtail = 0; -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - s->var_inc = xSat_FloatCreateConst1(); - s->cla_inc = xSat_FloatCreateConst1(); - s->var_decay = xSat_FloatFromFloat( (float)(1 / 0.95) ); - s->cla_decay = xSat_FloatFromFloat( (float)(1 / 0.999) ); -#else - s->var_inc = 1; - s->cla_inc = 1; - s->var_decay = (float)(1 / 0.95 ); - s->cla_decay = (float)(1 / 0.999); -#endif -#else - s->var_inc = (1 << 5); - s->cla_inc = (1 << 11); -#endif + + solver_init_activities(s); + veci_new(&s->act_vars); + s->root_level = 0; // s->simpdb_assigns = 0; // s->simpdb_props = 0; @@ -1164,7 +1149,6 @@ sat_solver* zsat_solver_new_seed(double seed) veci_new(&s->act_clas); veci_new(&s->stack); // veci_new(&s->model); - veci_new(&s->act_vars); veci_new(&s->unit_lits); veci_new(&s->temp_clause); veci_new(&s->conf_final); @@ -1181,22 +1165,10 @@ sat_solver* zsat_solver_new_seed(double seed) s->cap = 0; s->qhead = 0; s->qtail = 0; -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - s->var_inc = xSat_FloatCreateConst1(); - s->cla_inc = xSat_FloatCreateConst1(); - s->var_decay = xSat_FloatFromFloat( (float)(1 / 0.95) ); - s->cla_decay = xSat_FloatFromFloat( (float)(1 / 0.999) ); -#else - s->var_inc = 1; - s->cla_inc = 1; - s->var_decay = (float)(1 / 0.95 ); - s->cla_decay = (float)(1 / 0.999); -#endif -#else - s->var_inc = (1 << 5); - s->cla_inc = (1 << 11); -#endif + + solver_init_activities(s); + veci_new(&s->act_vars); + s->root_level = 0; // s->simpdb_assigns = 0; // s->simpdb_props = 0; @@ -1236,16 +1208,8 @@ void sat_solver_setnvars(sat_solver* s,int n) s->polarity = ABC_REALLOC(char, s->polarity, s->cap); s->tags = ABC_REALLOC(char, s->tags, s->cap); s->loads = ABC_REALLOC(char, s->loads, s->cap); -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - s->activity = ABC_REALLOC(xFloat_t, s->activity, s->cap); -#else - s->activity = ABC_REALLOC(double, s->activity, s->cap); -#endif -#else - s->activity = ABC_REALLOC(unsigned, s->activity, s->cap); - s->activity2 = ABC_REALLOC(unsigned, s->activity2,s->cap); -#endif + s->activity = ABC_REALLOC(word, s->activity, s->cap); + s->activity2 = ABC_REALLOC(word, s->activity2,s->cap); s->pFreqs = ABC_REALLOC(char, s->pFreqs, s->cap); if ( s->factors ) @@ -1264,15 +1228,15 @@ void sat_solver_setnvars(sat_solver* s,int n) veci_new(&s->wlists[2*var]); if ( s->wlists[2*var+1].ptr == NULL ) veci_new(&s->wlists[2*var+1]); -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - s->activity[var] = xSat_FloatCreateConst1(); -#else - s->activity[var] = 0; -#endif -#else - s->activity[var] = (1<<10); -#endif + + if ( s->VarActType == 0 ) + s->activity[var] = (1<<10); + else if ( s->VarActType == 1 ) + s->activity[var] = 0; + else if ( s->VarActType == 2 ) + s->activity[var] = Xdbl_Const1(); + else assert(0); + s->pFreqs[var] = 0; if ( s->factors ) s->factors [var] = 0; @@ -1349,7 +1313,6 @@ void sat_solver_restart( sat_solver* s ) s->hBinary = Sat_MemAppend( &s->Mem, NULL, 2, 0, 0 ); s->binary = clause_read( s, s->hBinary ); - veci_resize(&s->act_clas, 0); veci_resize(&s->trail_lim, 0); veci_resize(&s->order, 0); for ( i = 0; i < s->size*2; i++ ) @@ -1362,22 +1325,13 @@ void sat_solver_restart( sat_solver* s ) // s->cap = 0; s->qhead = 0; s->qtail = 0; -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - s->var_inc = xSat_FloatCreateConst1(); - s->cla_inc = xSat_FloatCreateConst1(); - s->var_decay = xSat_FloatFromFloat( (float)(1 / 0.95) ); - s->cla_decay = xSat_FloatFromFloat( (float)(1 / 0.999) ); -#else - s->var_inc = 1; - s->cla_inc = 1; - s->var_decay = (float)(1 / 0.95 ); - s->cla_decay = (float)(1 / 0.999); -#endif -#else - s->var_inc = (1 << 5); - s->cla_inc = (1 << 11); -#endif + + + // variable activities + solver_init_activities(s); + veci_resize(&s->act_clas, 0); + + s->root_level = 0; // s->simpdb_assigns = 0; // s->simpdb_props = 0; @@ -1405,7 +1359,6 @@ void zsat_solver_restart_seed( sat_solver* s, double seed ) s->hBinary = Sat_MemAppend( &s->Mem, NULL, 2, 0, 0 ); s->binary = clause_read( s, s->hBinary ); - veci_resize(&s->act_clas, 0); veci_resize(&s->trail_lim, 0); veci_resize(&s->order, 0); for ( i = 0; i < s->size*2; i++ ) @@ -1418,22 +1371,10 @@ void zsat_solver_restart_seed( sat_solver* s, double seed ) // s->cap = 0; s->qhead = 0; s->qtail = 0; -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - s->var_inc = xSat_FloatCreateConst1(); - s->cla_inc = xSat_FloatCreateConst1(); - s->var_decay = xSat_FloatFromFloat( (float)(1 / 0.95) ); - s->cla_decay = xSat_FloatFromFloat( (float)(1 / 0.999) ); -#else - s->var_inc = 1; - s->cla_inc = 1; - s->var_decay = (float)(1 / 0.95 ); - s->cla_decay = (float)(1 / 0.999); -#endif -#else - s->var_inc = (1 << 5); - s->cla_inc = (1 << 11); -#endif + + solver_init_activities(s); + veci_resize(&s->act_clas, 0); + s->root_level = 0; // s->simpdb_assigns = 0; // s->simpdb_props = 0; @@ -1466,17 +1407,9 @@ double sat_solver_memory( sat_solver* s ) Mem += s->cap * sizeof(char); // ABC_FREE(s->polarity ); Mem += s->cap * sizeof(char); // ABC_FREE(s->tags ); Mem += s->cap * sizeof(char); // ABC_FREE(s->loads ); -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - Mem += s->cap * sizeof(xFloat_t); // ABC_FREE(s->activity ); -#else - Mem += s->cap * sizeof(double); // ABC_FREE(s->activity ); -#endif -#else - Mem += s->cap * sizeof(unsigned); // ABC_FREE(s->activity ); + Mem += s->cap * sizeof(word); // ABC_FREE(s->activity ); if ( s->activity2 ) - Mem += s->cap * sizeof(unsigned); // ABC_FREE(s->activity2); -#endif + Mem += s->cap * sizeof(word); // ABC_FREE(s->activity ); if ( s->factors ) Mem += s->cap * sizeof(double); // ABC_FREE(s->factors ); Mem += s->cap * sizeof(int); // ABC_FREE(s->orderpos ); @@ -1523,7 +1456,7 @@ void sat_solver_reducedb(sat_solver* s) s->nDBreduces++; -// printf( "Calling reduceDB with %d learned clause limit.\n", s->nLearntMax ); + printf( "Calling reduceDB with %d learned clause limit.\n", s->nLearntMax ); s->nLearntMax = s->nLearntStart + s->nLearntDelta * s->nDBreduces; // return; @@ -1533,15 +1466,10 @@ void sat_solver_reducedb(sat_solver* s) { Id = clause_id(c); // pSortValues[Id] = act[Id]; -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - pSortValues[Id] = ((7 - Abc_MinInt(c->lbd, 7)) << 28) | (act_clas[Id] >> 4); -#else - pSortValues[Id] = ((7 - Abc_MinInt(c->lbd, 7)) << 28);// | (act_clas[Id] >> 4); -#endif -#else - pSortValues[Id] = ((7 - Abc_MinInt(c->lbd, 7)) << 28) | (act_clas[Id] >> 4); -#endif + if ( s->ClaActType == 0 ) + pSortValues[Id] = ((7 - Abc_MinInt(c->lbd, 7)) << 28) | (act_clas[Id] >> 4); + else + pSortValues[Id] = ((7 - Abc_MinInt(c->lbd, 7)) << 28);// | (act_clas[Id] >> 4); assert( pSortValues[Id] >= 0 ); } @@ -1647,15 +1575,7 @@ void sat_solver_rollback( sat_solver* s ) if ( s->activity2 ) { s->var_inc = s->var_inc2; -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - memcpy( s->activity, s->activity2, sizeof(xFloat_t) * s->iVarPivot ); -#else - memcpy( s->activity, s->activity2, sizeof(double) * s->iVarPivot ); -#endif -#else - memcpy( s->activity, s->activity2, sizeof(unsigned) * s->iVarPivot ); -#endif + memcpy( s->activity, s->activity2, sizeof(word) * s->iVarPivot ); } veci_resize(&s->order, 0); for ( i = 0; i < s->iVarPivot; i++ ) @@ -1704,22 +1624,9 @@ void sat_solver_rollback( sat_solver* s ) // s->cap = 0; s->qhead = 0; s->qtail = 0; -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - s->var_inc = xSat_FloatCreateConst1(); - s->cla_inc = xSat_FloatCreateConst1(); - s->var_decay = xSat_FloatFromFloat( (float)(1 / 0.95) ); - s->cla_decay = xSat_FloatFromFloat( (float)(1 / 0.999) ); -#else - s->var_inc = 1; - s->cla_inc = 1; - s->var_decay = (float)(1 / 0.95 ); - s->cla_decay = (float)(1 / 0.999); -#endif -#else - s->var_inc = (1 << 5); - s->cla_inc = (1 << 11); -#endif + + solver_init_activities(s); + s->root_level = 0; s->random_seed = 91648253; s->progress_estimate = 0; diff --git a/src/sat/bsat/satSolver.h b/src/sat/bsat/satSolver.h index 21f24fcb1..5a8483c1a 100644 --- a/src/sat/bsat/satSolver.h +++ b/src/sat/bsat/satSolver.h @@ -30,14 +30,10 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include "satVec.h" #include "satClause.h" -#include "misc/util/utilFloat.h" #include "misc/util/utilDouble.h" ABC_NAMESPACE_HEADER_START -//#define USE_FLOAT_ACTIVITY -//#define USE_FLOAT_ACTIVITY_NEW - //================================================================================================= // Public interface: @@ -111,7 +107,6 @@ struct sat_solver_t int hBinary; // the special binary clause clause * binary; veci* wlists; // watcher lists - veci act_clas; // contain clause activities // rollback int iVarPivot; // the pivot for variables @@ -119,31 +114,17 @@ struct sat_solver_t int hProofPivot; // the pivot for proof records // activities -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - xFloat_t var_inc; // Amount to bump next variable with. - xFloat_t var_inc2; // Amount to bump next variable with. - xFloat_t var_decay; // INVERSE decay factor for variable activity: stores 1/decay. - xFloat_t cla_inc; // Amount to bump next clause with. - xFloat_t cla_decay; // INVERSE decay factor for clause activity: stores 1/decay. - xFloat_t* activity; // A heuristic measurement of the activity of a variable. - xFloat_t* activity2; // backup variable activity -#else - double var_inc; // Amount to bump next variable with. - double var_inc2; // Amount to bump next variable with. - double var_decay; // INVERSE decay factor for variable activity: stores 1/decay. - float cla_inc; // Amount to bump next clause with. - float cla_decay; // INVERSE decay factor for clause activity: stores 1/decay. - double* activity; // A heuristic measurement of the activity of a variable. - double* activity2; // A heuristic measurement of the activity of a variable. -#endif -#else - int var_inc; // Amount to bump next variable with. - int var_inc2; // Amount to bump next variable with. - int cla_inc; // Amount to bump next clause with. - unsigned* activity; // A heuristic measurement of the activity of a variable. - unsigned* activity2; // backup variable activity -#endif + int VarActType; + int ClaActType; + word var_inc; // Amount to bump next variable with. + word var_inc2; // Amount to bump next variable with. + word var_decay; // INVERSE decay factor for variable activity: stores 1/decay. + word* activity; // A heuristic measurement of the activity of a variable. + word* activity2; // backup variable activity + unsigned cla_inc; // Amount to bump next clause with. + unsigned cla_decay; // INVERSE decay factor for clause activity: stores 1/decay. + veci act_clas; // contain clause activities + char * pFreqs; // how many times this variable was assigned a value int nVarUsed; @@ -233,21 +214,25 @@ static int sat_solver_var_literal( sat_solver* s, int v ) static void sat_solver_act_var_clear(sat_solver* s) { int i; -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - for (i = 0; i < s->size; i++) - s->activity[i] = xSat_FloatCreateConst1(); - s->var_inc = xSat_FloatCreateConst1(); -#else - for (i = 0; i < s->size; i++) - s->activity[i] = 0; - s->var_inc = 1; -#endif -#else - for (i = 0; i < s->size; i++) - s->activity[i] = 0; - s->var_inc = (1 << 5); -#endif + if ( s->VarActType == 0 ) + { + for (i = 0; i < s->size; i++) + s->activity[i] = (1 << 10); + s->var_inc = (1 << 5); + } + else if ( s->VarActType == 1 ) + { + for (i = 0; i < s->size; i++) + s->activity[i] = 0; + s->var_inc = 1; + } + else if ( s->VarActType == 2 ) + { + for (i = 0; i < s->size; i++) + s->activity[i] = Xdbl_Const1(); + s->var_inc = Xdbl_Const1(); + } + else assert(0); } static void sat_solver_compress(sat_solver* s) { @@ -313,18 +298,8 @@ static inline void sat_solver_bookmark(sat_solver* s) Sat_MemBookMark( &s->Mem ); if ( s->activity2 ) { -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW s->var_inc2 = s->var_inc; - memcpy( s->activity2, s->activity, sizeof(xFloat_t) * s->iVarPivot ); -#else - s->var_inc2 = s->var_inc; - memcpy( s->activity2, s->activity, sizeof(double) * s->iVarPivot ); -#endif -#else - s->var_inc2 = s->var_inc; - memcpy( s->activity2, s->activity, sizeof(unsigned) * s->iVarPivot ); -#endif + memcpy( s->activity2, s->activity, sizeof(word) * s->iVarPivot ); } } static inline void sat_solver_set_pivot_variables( sat_solver* s, int * pPivots, int nPivots ) From 7b7ebf91e458271b5979a3464b25faae5a5e4a6a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 11 Feb 2017 15:40:53 -0800 Subject: [PATCH 135/185] Compiler warning. --- src/aig/ivy/ivyFraig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aig/ivy/ivyFraig.c b/src/aig/ivy/ivyFraig.c index 059f4c0e0..d9887d740 100644 --- a/src/aig/ivy/ivyFraig.c +++ b/src/aig/ivy/ivyFraig.c @@ -2081,7 +2081,7 @@ void Ivy_FraigPrintActivity( Ivy_FraigMan_t * p ) { int i; for ( i = 0; i < p->nSatVars; i++ ) - printf( "%d %d ", i, p->pSat->activity[i] ); + printf( "%d %d ", i, (int)p->pSat->activity[i] ); printf( "\n" ); } From 2a5fa67d36393ab3ddb14e5bf542b0f29c8634e1 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 11 Feb 2017 17:28:37 -0800 Subject: [PATCH 136/185] Adding APIs to mark cones. Creating test-bench for incremental solving &satoko -i. --- src/aig/gia/giaSatoko.c | 145 +++++++++++++++++++++++++++--------- src/base/abci/abc.c | 14 ++-- src/base/cmd/cmdAuto.c | 6 +- src/sat/satoko/satoko.h | 2 + src/sat/satoko/solver.c | 16 +++- src/sat/satoko/solver.h | 23 ++++++ src/sat/satoko/solver_api.c | 27 ++++++- 7 files changed, 187 insertions(+), 46 deletions(-) diff --git a/src/aig/gia/giaSatoko.c b/src/aig/gia/giaSatoko.c index db81bd854..7cbc4184c 100644 --- a/src/aig/gia/giaSatoko.c +++ b/src/aig/gia/giaSatoko.c @@ -45,46 +45,59 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -satoko_t * Gia_ManCreateSatoko( Gia_Man_t * p ) +void Gia_ManCollectVars_rec( int Var, Vec_Int_t * vMapping, Vec_Int_t * vRes, Vec_Bit_t * vVisit ) +{ + int * pCut, i; + if ( Vec_BitEntry(vVisit, Var) ) + return; + Vec_BitWriteEntry(vVisit, Var, 1); + if ( Vec_IntEntry(vMapping, Var) ) // primary input or constant 0 + { + pCut = Vec_IntEntryP( vMapping, Vec_IntEntry(vMapping, Var) ); + for ( i = 1; i <= pCut[0]; i++ ) + Gia_ManCollectVars_rec( pCut[i], vMapping, vRes, vVisit ); + } + Vec_IntPush( vRes, Var ); +} +Vec_Int_t * Gia_ManCollectVars( int Root, Vec_Int_t * vMapping, int nVars ) +{ + Vec_Int_t * vRes = Vec_IntAlloc( 100 ); + Vec_Bit_t * vVisit = Vec_BitStart( nVars ); + assert( Vec_IntEntry(vMapping, Root) ); + Gia_ManCollectVars_rec( Root, vMapping, vRes, vVisit ); + Vec_BitFree( vVisit ); + return vRes; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +satoko_t * Gia_ManSatokoInit( Cnf_Dat_t * pCnf, satoko_opts_t * opts ) { satoko_t * pSat = satoko_create(); - Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 1, 0, 0 ); - int i, status; + int i; //sat_solver_setnvars( pSat, p->nVars ); for ( i = 0; i < pCnf->nClauses; i++ ) { if ( !satoko_add_clause( pSat, (unsigned *)pCnf->pClauses[i], pCnf->pClauses[i+1]-pCnf->pClauses[i] ) ) { - Cnf_DataFree( pCnf ); satoko_destroy( pSat ); return NULL; } } - Cnf_DataFree( pCnf ); - status = satoko_simplify(pSat); - if ( status == SATOKO_OK ) - return pSat; - satoko_destroy( pSat ); - return NULL; + satoko_configure(pSat, opts); + return pSat; } -int Gia_ManCallSatokoOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput ) +void Gia_ManSatokoReport( int iOutput, int status, abctime clk ) { - abctime clk = Abc_Clock(); - satoko_t * pSat; - int status, Cost = 0; - - - pSat = Gia_ManCreateSatoko( p ); - if ( pSat ) - { - satoko_configure(pSat, opts); - status = satoko_solve( pSat ); - Cost = (unsigned)pSat->stats.n_conflicts; - satoko_destroy( pSat ); - } - else - status = SATOKO_UNSAT; - if ( iOutput >= 0 ) Abc_Print( 1, "Output %6d : ", iOutput ); else @@ -97,25 +110,89 @@ int Gia_ManCallSatokoOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput ) else Abc_Print( 1, "UNSATISFIABLE " ); - Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + Abc_PrintTime( 1, "Time", clk ); +} +satoko_t * Gia_ManSatokoCreate( Gia_Man_t * p, satoko_opts_t * opts ) +{ + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 1, 0, 0 ); + satoko_t * pSat = Gia_ManSatokoInit( pCnf, opts ); + int status = pSat ? satoko_simplify(pSat) : SATOKO_OK; + Cnf_DataFree( pCnf ); + if ( status == SATOKO_OK ) + return pSat; + satoko_destroy( pSat ); + return NULL; +} +int Gia_ManSatokoCallOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput ) +{ + abctime clk = Abc_Clock(); + satoko_t * pSat; + int status, Cost = 0; + + pSat = Gia_ManSatokoCreate( p, opts ); + if ( pSat ) + { + status = satoko_solve( pSat ); + Cost = (unsigned)pSat->stats.n_conflicts; + satoko_destroy( pSat ); + } + else + status = SATOKO_UNSAT; + + Gia_ManSatokoReport( iOutput, status, Abc_Clock() - clk ); return Cost; } -void Gia_ManCallSatoko( Gia_Man_t * p, satoko_opts_t * opts, int fSplit ) +void Gia_ManSatokoCall( Gia_Man_t * p, satoko_opts_t * opts, int fSplit, int fIncrem ) { + int fUseCone = 1; + Gia_Man_t * pOne; + Gia_Obj_t * pRoot; + Vec_Int_t * vCone; + int i, iLit, status; + if ( fIncrem ) + { + abctime clk = Abc_Clock(); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, fUseCone, 0 ); + satoko_t * pSat = Gia_ManSatokoInit( pCnf, opts ); + Gia_ManForEachCo( p, pRoot, i ) + { + abctime clk = Abc_Clock(); + iLit = Abc_Var2Lit( i+1, 0 ); + satoko_assump_push( pSat, iLit ); + if ( fUseCone ) + { + vCone = Gia_ManCollectVars( i+1, pCnf->vMapping, pCnf->nVars ); + satoko_mark_cone( pSat, Vec_IntArray(vCone), Vec_IntSize(vCone) ); + printf( "Cone has %6d vars (out of %6d). ", Vec_IntSize(vCone), pCnf->nVars ); + status = satoko_solve( pSat ); + satoko_unmark_cone( pSat, Vec_IntArray(vCone), Vec_IntSize(vCone) ); + Vec_IntFree( vCone ); + } + else + { + status = satoko_solve( pSat ); + } + satoko_assump_pop( pSat ); + Gia_ManSatokoReport( i, status, Abc_Clock() - clk ); + } + Cnf_DataFree( pCnf ); + satoko_destroy( pSat ); + Abc_PrintTime( 1, "Total time", Abc_Clock() - clk ); + return; + } if ( fSplit ) { - Gia_Man_t * pOne; - Gia_Obj_t * pRoot; - int i; + abctime clk = Abc_Clock(); Gia_ManForEachCo( p, pRoot, i ) { pOne = Gia_ManDupDfsCone( p, pRoot ); - Gia_ManCallSatokoOne( pOne, opts, i ); + Gia_ManSatokoCallOne( pOne, opts, i ); Gia_ManStop( pOne ); } + Abc_PrintTime( 1, "Total time", Abc_Clock() - clk ); return; } - Gia_ManCallSatokoOne( p, opts, -1 ); + Gia_ManSatokoCallOne( p, opts, -1 ); } diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index f10be02b9..bb0b8c8dd 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -23410,13 +23410,13 @@ usage: ***********************************************************************/ int Abc_CommandAbc9Satoko( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern void Gia_ManCallSatoko( Gia_Man_t * p, satoko_opts_t * opts, int fSplit ); - int c, fSplit = 0; + extern void Gia_ManSatokoCall( Gia_Man_t * p, satoko_opts_t * opts, int fSplit, int fIncrem ); + int c, fSplit = 0, fIncrem = 0; satoko_opts_t opts; satoko_default_opts(&opts); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Csvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "Csivh" ) ) != EOF ) { switch ( c ) { @@ -23434,6 +23434,9 @@ int Abc_CommandAbc9Satoko( Abc_Frame_t * pAbc, int argc, char ** argv ) case 's': fSplit ^= 1; break; + case 'i': + fIncrem ^= 1; + break; case 'v': opts.verbose ^= 1; break; @@ -23449,13 +23452,14 @@ int Abc_CommandAbc9Satoko( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandAbc9Satoko(): There is no AIG.\n" ); return 1; } - Gia_ManCallSatoko( pAbc->pGia, &opts, fSplit ); + Gia_ManSatokoCall( pAbc->pGia, &opts, fSplit, fIncrem ); return 0; usage: - Abc_Print( -2, "usage: &satoko [-C num] [-svh]\n" ); + Abc_Print( -2, "usage: &satoko [-C num] [-sivh]\n" ); Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", opts.conf_limit ); Abc_Print( -2, "\t-s : split multi-output miter into individual outputs [default = %s]\n", fSplit? "yes": "no" ); + Abc_Print( -2, "\t-i : split multi-output miter and solve incrementally [default = %s]\n", fIncrem? "yes": "no" ); Abc_Print( -2, "\t-v : prints verbose information [default = %s]\n", opts.verbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; diff --git a/src/base/cmd/cmdAuto.c b/src/base/cmd/cmdAuto.c index e279b19d1..8151c2e53 100644 --- a/src/base/cmd/cmdAuto.c +++ b/src/base/cmd/cmdAuto.c @@ -47,7 +47,7 @@ ABC_NAMESPACE_IMPL_START #define CMD_AUTO_LINE_MAX 1000 // max number of chars in the string #define CMD_AUTO_ARG_MAX 100 // max number of arguments in the call -extern int Gia_ManCallSatokoOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput ); +extern int Gia_ManSatokoCallOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -92,7 +92,7 @@ int Cmd_RunAutoTunerEvalSimple( Vec_Ptr_t * vAigs, satoko_opts_t * pOpts ) //printf( "Tuning with options: " ); //Cmd_RunAutoTunerPrintOptions( pOpts ); Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, i ) - TotalCost += Gia_ManCallSatokoOne( pGia, pOpts, -1 ); + TotalCost += Gia_ManSatokoCallOne( pGia, pOpts, -1 ); return TotalCost; } @@ -142,7 +142,7 @@ void * Cmd_RunAutoTunerEvalWorkerThread( void * pArg ) assert( 0 ); return NULL; } - pThData->Result = Gia_ManCallSatokoOne( pThData->pGia, pThData->pOpts, -1 ); + pThData->Result = Gia_ManSatokoCallOne( pThData->pGia, pThData->pOpts, -1 ); pThData->fWorking = 0; } assert( 0 ); diff --git a/src/sat/satoko/satoko.h b/src/sat/satoko/satoko.h index e3134b77a..8d55a81c8 100644 --- a/src/sat/satoko/satoko.h +++ b/src/sat/satoko/satoko.h @@ -89,6 +89,8 @@ extern void satoko_assump_push(satoko_t *s, unsigned); extern void satoko_assump_pop(satoko_t *s); extern int satoko_simplify(satoko_t *); extern int satoko_solve(satoko_t *); +extern void satoko_mark_cone(satoko_t *s, int * pvars, int nvars); +extern void satoko_unmark_cone(satoko_t *s, int * pvars, int nvars); /* If problem is unsatisfiable under assumptions, this function is used to * obtain the final conflict clause expressed in the assumptions. diff --git a/src/sat/satoko/solver.c b/src/sat/satoko/solver.c index cdd3141e5..2abc9833b 100644 --- a/src/sat/satoko/solver.c +++ b/src/sat/satoko/solver.c @@ -190,14 +190,18 @@ static inline unsigned solver_decide(solver_t *s) if (heap_size(s->var_order) == 0) { next_var = UNDEF; return UNDEF; - } else - next_var = heap_remove_min(s->var_order); + } + next_var = heap_remove_min(s->var_order); + if (solver_has_marks(s) && !var_mark(s, next_var)) + next_var = UNDEF; } return var2lit(next_var, vec_char_at(s->polarity, next_var)); } static inline void solver_new_decision(solver_t *s, unsigned lit) { + if (solver_has_marks(s) && !var_mark(s, lit2var(lit))) + return; assert(var_value(s, lit2var(lit)) == VAR_UNASSING); vec_uint_push_back(s->trail_lim, vec_uint_size(s->trail)); solver_enqueue(s, lit, UNDEF); @@ -538,6 +542,8 @@ unsigned solver_propagate(solver_t *s) n_propagations++; watch_list_foreach(s->bin_watches, i, p) { + if (solver_has_marks(s) && !var_mark(s, lit2var(i->blocker))) + continue; if (var_value(s, lit2var(i->blocker)) == VAR_UNASSING) solver_enqueue(s, i->blocker, i->cref); else if (lit_value(s, i->blocker) == LIT_FALSE) @@ -551,6 +557,12 @@ unsigned solver_propagate(solver_t *s) struct clause *clause; struct watcher w; + if (solver_has_marks(s) && !var_mark(s, lit2var(i->blocker))) + { + *j++ = *i++; + continue; + } + if (lit_value(s, i->blocker) == LIT_TRUE) { *j++ = *i++; continue; diff --git a/src/sat/satoko/solver.h b/src/sat/satoko/solver.h index 849d738a6..01912a6e6 100644 --- a/src/sat/satoko/solver.h +++ b/src/sat/satoko/solver.h @@ -93,6 +93,9 @@ struct solver_t_ { vec_uint_t *stamps; /* Multipurpose stamp used to calculate LBD and * clauses minimization with binary resolution */ + /* Temporary data used for solving cones */ + vec_char_t *marks; + struct satoko_stats stats; struct satoko_opts opts; }; @@ -133,6 +136,18 @@ static inline unsigned var_reason(solver_t *s, unsigned var) { return vec_uint_at(s->reasons, var); } +static inline int var_mark(solver_t *s, unsigned var) +{ + return (int)vec_char_at(s->marks, var); +} +static inline void var_set_mark(solver_t *s, unsigned var) +{ + vec_char_assign(s->marks, var, 1); +} +static inline void var_clean_mark(solver_t *s, unsigned var) +{ + vec_char_assign(s->marks, var, 0); +} //===------------------------------------------------------------------------=== // Inline lit functions //===------------------------------------------------------------------------=== @@ -185,6 +200,14 @@ static inline int solver_enqueue(solver_t *s, unsigned lit, unsigned reason) vec_uint_push_back(s->trail, lit); return SATOKO_OK; } +static inline int solver_varnum(solver_t *s) +{ + return vec_char_size(s->assigns); +} +static inline int solver_has_marks(solver_t *s) +{ + return (int)(s->marks != NULL); +} //===------------------------------------------------------------------------=== // Inline clause functions diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c index f3f3d781d..b446fb054 100644 --- a/src/sat/satoko/solver_api.c +++ b/src/sat/satoko/solver_api.c @@ -145,11 +145,13 @@ void satoko_destroy(solver_t *s) vec_uint_free(s->stack); vec_uint_free(s->last_dlevel); vec_uint_free(s->stamps); + if (s->marks) vec_char_free(s->marks); satoko_free(s); } void satoko_default_opts(satoko_opts_t *opts) { + memset(opts, 0, sizeof(satoko_opts_t)); opts->verbose = 0; /* Limits */ opts->conf_limit = 0; @@ -232,6 +234,7 @@ void satoko_add_variable(solver_t *s, char sign) vec_uint_push_back(s->stamps, 0); vec_char_push_back(s->seen, 0); heap_insert(s->var_order, var); + if (s->marks) vec_char_push_back(s->marks, 0); } int satoko_add_clause(solver_t *s, unsigned *lits, unsigned size) @@ -287,8 +290,8 @@ int satoko_solve(solver_t *s) char status = SATOKO_UNDEC; assert(s); - if (s->opts.verbose) - print_opts(s); + //if (s->opts.verbose) + // print_opts(s); while (status == SATOKO_UNDEC) { status = solver_search(s); @@ -317,4 +320,24 @@ satoko_stats_t satoko_stats(satoko_t *s) return s->stats; } +void satoko_mark_cone(satoko_t *s, int * pvars, int nvars) +{ + int i; + if (!solver_has_marks(s)) + s->marks = vec_char_init(solver_varnum(s), 0); + for (i = 0; i < nvars; i++) + { + var_set_mark(s, pvars[i]); + if (!heap_in_heap(s->var_order, pvars[i])) + heap_insert(s->var_order, pvars[i]); + } +} +void satoko_unmark_cone(satoko_t *s, int * pvars, int nvars) +{ + int i; + assert(solver_has_marks(s)); + for (i = 0; i < nvars; i++) + var_clean_mark(s, pvars[i]); +} + ABC_NAMESPACE_IMPL_END From ae521b66019623fd6ed51d89bef8244650227876 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 11 Feb 2017 21:00:37 -0800 Subject: [PATCH 137/185] Adding PDR with abstraction. --- src/proof/pdr/pdrCore.c | 11 +++++++---- src/proof/pdr/pdrInv.c | 4 ++-- src/proof/pdr/pdrTsim.c | 37 ++----------------------------------- 3 files changed, 11 insertions(+), 41 deletions(-) diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index 5aa689f57..f77bc05f0 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -706,7 +706,7 @@ int Pdr_ManBlockCube( Pdr_Man_t * p, Pdr_Set_t * pCube ) { Counter++; pThis = Pdr_QueueHead( p ); - if ( pThis->iFrame == 0 ) + if ( pThis->iFrame == 0 || (p->pPars->fUseAbs && Pdr_SetIsInit(pThis->pState, -1)) ) return 0; // SAT if ( pThis->iFrame > kMax ) // finished this level return 1; @@ -862,7 +862,7 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) while ( 1 ) { int fRefined = 0; - if ( p->pPars->fUseAbs && iFrame == 3 ) + if ( p->pPars->fUseAbs && p->vAbsFlops == NULL && iFrame == 2 ) { int i, Prio; assert( p->vAbsFlops == NULL ); @@ -995,7 +995,7 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame ); Pdr_ManPrintClauses( p, 0 ); } - if ( p->pPars->fVerbose ) + if ( p->pPars->fVerbose && !p->pPars->fUseAbs ) Pdr_ManPrintProgress( p, !p->pPars->fSolveAll, Abc_Clock() - clkStart ); p->pPars->iFrame = iFrame; if ( !p->pPars->fSolveAll ) @@ -1043,6 +1043,8 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) Pdr_ManPrintProgress( p, 0, Abc_Clock() - clkStart ); } } + if ( fRefined ) + break; if ( p->pTime4Outs ) { abctime timeSince = Abc_Clock() - clkOne; @@ -1059,9 +1061,10 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) p->timeToStopOne = 0; } } - if ( p->pPars->fVerbose ) Pdr_ManPrintProgress( p, !fRefined, Abc_Clock() - clkStart ); + if ( fRefined ) + continue; // open a new timeframe p->nQueLim = p->pPars->nRestLimit; assert( pCube == NULL ); diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index e3233a3a9..554add9b3 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -470,8 +470,8 @@ void Pdr_ManReportInvariant( Pdr_Man_t * p ) Vec_Ptr_t * vCubes; int kStart = Pdr_ManFindInvariantStart( p ); vCubes = Pdr_ManCollectCubes( p, kStart ); - Abc_Print( 1, "Invariant F[%d] : %d clauses with %d flops (out of %d) (%.2f)\n", - kStart, Vec_PtrSize(vCubes), Pdr_ManCountVariables(p, kStart), Aig_ManRegNum(p->pAig), 1.0*p->nXsimLits/p->nXsimRuns ); + Abc_Print( 1, "Invariant F[%d] : %d clauses with %d flops (out of %d) (cex = %d, ave = %.2f)\n", + kStart, Vec_PtrSize(vCubes), Pdr_ManCountVariables(p, kStart), Aig_ManRegNum(p->pAig), p->nCexesTotal, 1.0*p->nXsimLits/p->nXsimRuns ); // Abc_Print( 1, "Invariant F[%d] : %d clauses with %d flops (out of %d)\n", // kStart, Vec_PtrSize(vCubes), Pdr_ManCountVariables(p, kStart), Aig_ManRegNum(p->pAig) ); Vec_PtrFree( vCubes ); diff --git a/src/proof/pdr/pdrTsim.c b/src/proof/pdr/pdrTsim.c index 283a0e1dd..acbf70f5b 100644 --- a/src/proof/pdr/pdrTsim.c +++ b/src/proof/pdr/pdrTsim.c @@ -473,54 +473,21 @@ Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, vCi2Rem ); Pdr_ManDeriveResult( p->pAig, vCiObjs, vCiVals, vCi2Rem, vRes, vPiLits ); assert( Vec_IntSize(vRes) > 0 ); //p->tTsim += Abc_Clock() - clk; + // move abstracted literals from flops to inputs if ( p->pPars->fUseAbs && p->vAbsFlops ) { - int i, iLit, Used, k = 0, fAllNegs = 1; + int i, iLit, k = 0; Vec_IntForEachEntry( vRes, iLit, i ) { if ( Vec_IntEntry(p->vAbsFlops, Abc_Lit2Var(iLit)) ) // used flop - { Vec_IntWriteEntry( vRes, k++, iLit ); - fAllNegs &= Abc_LitIsCompl(iLit); - } else Vec_IntPush( vPiLits, 2*Saig_ManPiNum(p->pAig) + iLit ); } Vec_IntShrink( vRes, k ); - if ( fAllNegs ) // insert any positive literal - { - Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i ) - { - if ( !Saig_ObjIsLo( p->pAig, pObj ) ) - continue; - if ( Vec_IntEntry(vCiVals, i) ) - { - Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig); - Vec_IntPush( vRes, Abc_Var2Lit(Entry, 0) ); - break; - } - } - // add any flop that is not in the cone - if ( i == Vec_IntSize(vCiObjs) ) - { - Vec_IntForEachEntry( p->vAbsFlops, Used, i ) - { - if ( !Used ) - continue; - if ( Vec_IntFind( vRes, Abc_Var2Lit(i, 1) ) >= 0 ) - continue; - Vec_IntPush( vRes, Abc_Var2Lit(i, 0) ); - //Vec_IntPrint( vRes ); - break; - } - assert( i < Vec_IntSize(p->vAbsFlops) ); - } - } } pRes = Pdr_SetCreate( vRes, vPiLits ); - assert( k == 0 || !Pdr_SetIsInit(pRes, -1) ); - //ZH: Disabled assertion because this invariant doesn't hold with down //because of the join operation which can bring in initial states //assert( k == 0 || !Pdr_SetIsInit(pRes, -1) ); From 4abb1ce8a45d115567a125c6b2b00d48f6776aff Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 11 Feb 2017 21:11:45 -0800 Subject: [PATCH 138/185] Commenting out uncommented message. --- src/sat/bsat/satSolver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sat/bsat/satSolver.c b/src/sat/bsat/satSolver.c index efe8efa66..37e0ea949 100644 --- a/src/sat/bsat/satSolver.c +++ b/src/sat/bsat/satSolver.c @@ -1456,7 +1456,7 @@ void sat_solver_reducedb(sat_solver* s) s->nDBreduces++; - printf( "Calling reduceDB with %d learned clause limit.\n", s->nLearntMax ); + //printf( "Calling reduceDB with %d learned clause limit.\n", s->nLearntMax ); s->nLearntMax = s->nLearntStart + s->nLearntDelta * s->nDBreduces; // return; From 3fb058a35562ceeafb2967f0991215ad47a23b0f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 11 Feb 2017 22:48:20 -0800 Subject: [PATCH 139/185] Adding PDR with abstraction. --- src/proof/pdr/pdrCore.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index f77bc05f0..568f76428 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -874,7 +874,7 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) Vec_IntWriteEntry( p->vAbsFlops, i, 1 ); } //if ( p->pPars->fUseAbs && p->vAbsFlops ) - // printf( "Starting frame %d with %d flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops) ); + // printf( "Starting frame %d with %d (%d) flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops), Vec_IntCountPositive(p->vPrio) ); p->nFrames = iFrame; assert( iFrame == Vec_PtrSize(p->vSolvers)-1 ); p->iUseFrame = Abc_MaxInt(iFrame, 1); @@ -1061,10 +1061,19 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) p->timeToStopOne = 0; } } + if ( p->pPars->fUseAbs && p->vAbsFlops && !fRefined ) + { + int i, Used; + Vec_IntForEachEntry( p->vAbsFlops, Used, i ) + if ( Used && (Vec_IntEntry(p->vPrio, i) >> p->nPrioShift) == 0 ) + Vec_IntWriteEntry( p->vAbsFlops, i, 0 ); + } if ( p->pPars->fVerbose ) Pdr_ManPrintProgress( p, !fRefined, Abc_Clock() - clkStart ); if ( fRefined ) continue; + //if ( p->pPars->fUseAbs && p->vAbsFlops ) + // printf( "Finished frame %d with %d (%d) flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops), Vec_IntCountPositive(p->vPrio) ); // open a new timeframe p->nQueLim = p->pPars->nRestLimit; assert( pCube == NULL ); From f4853496d7bc96ef134fb300f70f480307fa133b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 13 Feb 2017 01:02:03 -0800 Subject: [PATCH 140/185] Adding PDR with abstraction. --- src/proof/pdr/pdrCore.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index 568f76428..45dbfc9f1 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -862,16 +862,16 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) while ( 1 ) { int fRefined = 0; - if ( p->pPars->fUseAbs && p->vAbsFlops == NULL && iFrame == 2 ) + if ( p->pPars->fUseAbs && p->vAbsFlops == NULL && iFrame == 1 ) { - int i, Prio; +// int i, Prio; assert( p->vAbsFlops == NULL ); p->vAbsFlops = Vec_IntStart( Saig_ManRegNum(p->pAig) ); p->vMapFf2Ppi = Vec_IntStartFull( Saig_ManRegNum(p->pAig) ); p->vMapPpi2Ff = Vec_IntAlloc( 100 ); - Vec_IntForEachEntry( p->vPrio, Prio, i ) - if ( Prio >> p->nPrioShift ) - Vec_IntWriteEntry( p->vAbsFlops, i, 1 ); +// Vec_IntForEachEntry( p->vPrio, Prio, i ) +// if ( Prio >> p->nPrioShift ) +// Vec_IntWriteEntry( p->vAbsFlops, i, 1 ); } //if ( p->pPars->fUseAbs && p->vAbsFlops ) // printf( "Starting frame %d with %d (%d) flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops), Vec_IntCountPositive(p->vPrio) ); From 30037e06533b1c7291e32025ebb7c9a2e875e079 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Tue, 14 Feb 2017 14:43:44 -0800 Subject: [PATCH 141/185] - Small bug fix in var activity (improve performance) - New implementation of watcher lists. --- src/sat/satoko/solver.c | 14 ++++------ src/sat/satoko/solver.h | 20 ++++---------- src/sat/satoko/solver_api.c | 23 +++++++--------- src/sat/satoko/watch_list.h | 54 ++++++++++++++++++++++++------------- 4 files changed, 55 insertions(+), 56 deletions(-) diff --git a/src/sat/satoko/solver.c b/src/sat/satoko/solver.c index 2abc9833b..d2bf1b5e8 100644 --- a/src/sat/satoko/solver.c +++ b/src/sat/satoko/solver.c @@ -114,7 +114,7 @@ static inline void clause_bin_resolution(solver_t *s, vec_uint_t *clause_lits) vec_uint_assign(s->stamps, lit2var(lit), s->cur_stamp); counter = 0; - watch_list_foreach(s->bin_watches, w, neg_lit) { + watch_list_foreach_bin(s->watches, w, neg_lit) { unsigned imp_lit = w->blocker; if (vec_uint_at(s->stamps, lit2var(imp_lit)) == s->cur_stamp && lit_value(s, imp_lit) == LIT_TRUE) { @@ -400,8 +400,6 @@ static inline void solver_garbage_collect(solver_t *s) struct watcher *w; watch_list_foreach(s->watches, w, i) clause_realloc(new_cdb, s->all_clauses, &(w->cref)); - watch_list_foreach(s->bin_watches, w, i) - clause_realloc(new_cdb, s->all_clauses, &(w->cref)); } for (i = 0; i < vec_uint_size(s->trail); i++) @@ -541,7 +539,7 @@ unsigned solver_propagate(solver_t *s) struct watcher *i, *j; n_propagations++; - watch_list_foreach(s->bin_watches, i, p) { + watch_list_foreach_bin(s->watches, i, p) { if (solver_has_marks(s) && !var_mark(s, lit2var(i->blocker))) continue; if (var_value(s, lit2var(i->blocker)) == VAR_UNASSING) @@ -553,16 +551,14 @@ unsigned solver_propagate(solver_t *s) ws = vec_wl_at(s->watches, p); begin = watch_list_array(ws); end = begin + watch_list_size(ws); - for (i = j = begin; i < end;) { + for (i = j = begin + ws->n_bin; i < end;) { struct clause *clause; struct watcher w; - if (solver_has_marks(s) && !var_mark(s, lit2var(i->blocker))) - { + if (solver_has_marks(s) && !var_mark(s, lit2var(i->blocker))) { *j++ = *i++; continue; } - if (lit_value(s, i->blocker) == LIT_TRUE) { *j++ = *i++; continue; @@ -590,7 +586,7 @@ unsigned solver_propagate(solver_t *s) if (lit_value(s, lits[k]) != LIT_FALSE) { lits[1] = lits[k]; lits[k] = neg_lit; - watch_list_push(vec_wl_at(s->watches, lit_neg(lits[1])), w); + watch_list_push(vec_wl_at(s->watches, lit_neg(lits[1])), w, 0); goto next; } } diff --git a/src/sat/satoko/solver.h b/src/sat/satoko/solver.h index 01912a6e6..84c256895 100644 --- a/src/sat/satoko/solver.h +++ b/src/sat/satoko/solver.h @@ -49,7 +49,6 @@ struct solver_t_ { vec_uint_t *learnts; vec_uint_t *originals; vec_wl_t *watches; - vec_wl_t *bin_watches; /* Activity heuristic */ act_t var_act_inc; /* Amount to bump next variable with. */ @@ -200,6 +199,7 @@ static inline int solver_enqueue(solver_t *s, unsigned lit, unsigned reason) vec_uint_push_back(s->trail, lit); return SATOKO_OK; } + static inline int solver_varnum(solver_t *s) { return vec_char_size(s->assigns); @@ -227,25 +227,15 @@ static inline void clause_watch(solver_t *s, unsigned cref) w2.cref = cref; w1.blocker = clause->data[1].lit; w2.blocker = clause->data[0].lit; - if (clause->size == 2) { - watch_list_push(vec_wl_at(s->bin_watches, lit_neg(clause->data[0].lit)), w1); - watch_list_push(vec_wl_at(s->bin_watches, lit_neg(clause->data[1].lit)), w2); - } else { - watch_list_push(vec_wl_at(s->watches, lit_neg(clause->data[0].lit)), w1); - watch_list_push(vec_wl_at(s->watches, lit_neg(clause->data[1].lit)), w2); - } + watch_list_push(vec_wl_at(s->watches, lit_neg(clause->data[0].lit)), w1, (clause->size == 2)); + watch_list_push(vec_wl_at(s->watches, lit_neg(clause->data[1].lit)), w2, (clause->size == 2)); } static inline void clause_unwatch(solver_t *s, unsigned cref) { struct clause *clause = cdb_handler(s->all_clauses, cref); - if (clause->size == 2) { - watch_list_remove(vec_wl_at(s->bin_watches, lit_neg(clause->data[0].lit)), cref); - watch_list_remove(vec_wl_at(s->bin_watches, lit_neg(clause->data[1].lit)), cref); - } else { - watch_list_remove(vec_wl_at(s->watches, lit_neg(clause->data[0].lit)), cref); - watch_list_remove(vec_wl_at(s->watches, lit_neg(clause->data[1].lit)), cref); - } + watch_list_remove(vec_wl_at(s->watches, lit_neg(clause->data[0].lit)), cref, (clause->size == 2)); + watch_list_remove(vec_wl_at(s->watches, lit_neg(clause->data[1].lit)), cref, (clause->size == 2)); } ABC_NAMESPACE_HEADER_END diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c index b446fb054..65fab8378 100644 --- a/src/sat/satoko/solver_api.c +++ b/src/sat/satoko/solver_api.c @@ -89,7 +89,6 @@ solver_t * satoko_create() s->originals = vec_uint_alloc(0); s->learnts = vec_uint_alloc(0); s->watches = vec_wl_alloc(0); - s->bin_watches = vec_wl_alloc(0); /* Activity heuristic */ s->var_act_inc = VAR_ACT_INIT_INC; s->clause_act_inc = CLAUSE_ACT_INIT_INC; @@ -128,7 +127,6 @@ void satoko_destroy(solver_t *s) vec_uint_free(s->originals); vec_uint_free(s->learnts); vec_wl_free(s->watches); - vec_wl_free(s->bin_watches); vec_act_free(s->activity); heap_free(s->var_order); vec_uint_free(s->levels); @@ -145,7 +143,8 @@ void satoko_destroy(solver_t *s) vec_uint_free(s->stack); vec_uint_free(s->last_dlevel); vec_uint_free(s->stamps); - if (s->marks) vec_char_free(s->marks); + if (s->marks) + vec_char_free(s->marks); satoko_free(s); } @@ -220,13 +219,9 @@ int satoko_simplify(solver_t * s) void satoko_add_variable(solver_t *s, char sign) { unsigned var = vec_act_size(s->activity); - vec_wl_push(s->bin_watches); - vec_wl_push(s->bin_watches); vec_wl_push(s->watches); vec_wl_push(s->watches); - /* Variable activity are initialized with the lowest possible value - * which in satoko double implementation (SDBL) is the constant 1 */ - vec_act_push_back(s->activity, SDBL_CONST1); + vec_act_push_back(s->activity, 0); vec_uint_push_back(s->levels, 0); vec_char_push_back(s->assigns, VAR_UNASSING); vec_char_push_back(s->polarity, sign); @@ -320,23 +315,23 @@ satoko_stats_t satoko_stats(satoko_t *s) return s->stats; } -void satoko_mark_cone(satoko_t *s, int * pvars, int nvars) +void satoko_mark_cone(satoko_t *s, int * pvars, int n_vars) { int i; if (!solver_has_marks(s)) - s->marks = vec_char_init(solver_varnum(s), 0); - for (i = 0; i < nvars; i++) - { + s->marks = vec_char_init(solver_varnum(s), 0); + for (i = 0; i < n_vars; i++) { var_set_mark(s, pvars[i]); if (!heap_in_heap(s->var_order, pvars[i])) heap_insert(s->var_order, pvars[i]); } } -void satoko_unmark_cone(satoko_t *s, int * pvars, int nvars) + +void satoko_unmark_cone(satoko_t *s, int *pvars, int n_vars) { int i; assert(solver_has_marks(s)); - for (i = 0; i < nvars; i++) + for (i = 0; i < n_vars; i++) var_clean_mark(s, pvars[i]); } diff --git a/src/sat/satoko/watch_list.h b/src/sat/satoko/watch_list.h index ef1c1a075..96399a83a 100644 --- a/src/sat/satoko/watch_list.h +++ b/src/sat/satoko/watch_list.h @@ -10,6 +10,7 @@ #define satoko__watch_list_h #include "utils/mem.h" +#include "utils/misc.h" #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START @@ -22,6 +23,7 @@ struct watcher { struct watch_list { unsigned cap; unsigned size; + unsigned n_bin; struct watcher *watchers; }; @@ -40,6 +42,10 @@ struct vec_wl_t_ { watch < watch_list_array(vec_wl_at(vec, lit)) + watch_list_size(vec_wl_at(vec, lit)); \ watch++) +#define watch_list_foreach_bin(vec, watch, lit) \ + for (watch = watch_list_array(vec_wl_at(vec, lit)); \ + watch < watch_list_array(vec_wl_at(vec, lit)) + vec_wl_at(vec, lit)->n_bin; \ + watch++) //===------------------------------------------------------------------------=== // Watch list API //===------------------------------------------------------------------------=== @@ -60,25 +66,33 @@ static inline void watch_list_shrink(struct watch_list *wl, unsigned size) wl->size = size; } -static inline void watch_list_push(struct watch_list *wl, struct watcher w) +static inline void watch_list_grow(struct watch_list *wl) +{ + unsigned new_size = (wl->cap < 4) ? 4 : (wl->cap / 2) * 3; + struct watcher *watchers = + satoko_realloc(struct watcher, wl->watchers, new_size); + if (watchers == NULL) { + printf("Failed to realloc memory from %.1f MB to %.1f " + "MB.\n", + 1.0 * wl->cap / (1 << 20), + 1.0 * new_size / (1 << 20)); + fflush(stdout); + return; + } + wl->watchers = watchers; + wl->cap = new_size; +} + +static inline void watch_list_push(struct watch_list *wl, struct watcher w, unsigned is_bin) { assert(wl); - if (wl->size == wl->cap) { - unsigned new_size = (wl->cap < 4) ? 4 : (wl->cap / 2) * 3; - struct watcher *watchers = - satoko_realloc(struct watcher, wl->watchers, new_size); - if (watchers == NULL) { - printf("Failed to realloc memory from %.1f MB to %.1f " - "MB.\n", - 1.0 * wl->cap / (1 << 20), - 1.0 * new_size / (1 << 20)); - fflush(stdout); - return; - } - wl->watchers = watchers; - wl->cap = new_size; - } + if (wl->size == wl->cap) + watch_list_grow(wl); wl->watchers[wl->size++] = w; + if (is_bin && wl->size > wl->n_bin) { + stk_swap(struct watcher, wl->watchers[wl->n_bin], wl->watchers[wl->size - 1]); + wl->n_bin++; + } } static inline struct watcher *watch_list_array(struct watch_list *wl) @@ -86,11 +100,15 @@ static inline struct watcher *watch_list_array(struct watch_list *wl) return wl->watchers; } -static inline void watch_list_remove(struct watch_list *wl, unsigned cref) +static inline void watch_list_remove(struct watch_list *wl, unsigned cref, unsigned is_bin) { struct watcher *watchers = watch_list_array(wl); unsigned i; - for (i = 0; watchers[i].cref != cref; i++); + if (is_bin) { + for (i = 0; watchers[i].cref != cref; i++); + wl->n_bin--; + } else + for (i = wl->n_bin; watchers[i].cref != cref; i++); assert(i < watch_list_size(wl)); memmove((wl->watchers + i), (wl->watchers + i + 1), (wl->size - i - 1) * sizeof(struct watcher)); From cb1ab7030fcd6964d4feb7441bf594829583d5ba Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 14 Feb 2017 20:26:43 -0800 Subject: [PATCH 142/185] Experiments with simulation. --- src/proof/cec/cecSimBack.c | 194 +++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 src/proof/cec/cecSimBack.c diff --git a/src/proof/cec/cecSimBack.c b/src/proof/cec/cecSimBack.c new file mode 100644 index 000000000..c3d09ff59 --- /dev/null +++ b/src/proof/cec/cecSimBack.c @@ -0,0 +1,194 @@ +/**CFile**************************************************************** + + FileName [cecSimBack.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinational equivalence checking.] + + Synopsis [Backward simulation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecSimBack.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" +#include "aig/gia/giaAig.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ObjSatVerify( Gia_Man_t * p, Gia_Obj_t * pRoot, int Value ) +{ + Gia_Obj_t * pObj; + int i, RetValue = 1; + printf( "Obj = %4d Value = %d ", Gia_ObjId(p, pRoot), Value ); + Gia_ObjTerSimSet0( Gia_ManConst0(p) ); + Gia_ManForEachCi( p, pObj, i ) + if ( !Gia_ObjIsTravIdCurrent(p, pObj) ) + Gia_ObjTerSimSetX( pObj ), printf( "x" ); + else if ( pObj->fMark0 ) + Gia_ObjTerSimSet1( pObj ), printf( "1" ); + else + Gia_ObjTerSimSet0( pObj ), printf( "0" ); + printf( " " ); + Gia_ManForEachAnd( p, pObj, i ) + Gia_ObjTerSimAnd( pObj ); + if ( Value ? Gia_ObjTerSimGet1(pRoot) : Gia_ObjTerSimGet0(pRoot) ) + printf( "Verification successful.\n" ); + else + printf( "Verification failed.\n" ), RetValue = 0; + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Return 1 if pObj can have Value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +word Cec_ManCheckSat2_rec( Gia_Man_t * p, Gia_Obj_t * pObj, word Value, Vec_Wrd_t * vValues ) +{ + Gia_Obj_t * pFan0, * pFan1; + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return Value == (int)pObj->fMark0; + Gia_ObjSetTravIdCurrent(p, pObj); + pObj->fMark0 = Value; + if ( !Gia_ObjIsAnd(pObj) ) + return 1; + pFan0 = Gia_ObjFanin0(pObj); + pFan1 = Gia_ObjFanin1(pObj); + if ( Value ) + { + return Cec_ManCheckSat2_rec( p, pFan0, !Gia_ObjFaninC0(pObj), vValues ) && + Cec_ManCheckSat2_rec( p, pFan1, !Gia_ObjFaninC1(pObj), vValues ); + } + if ( Gia_ObjIsTravIdCurrent(p, pFan0) ) // already assigned + { + if ( Gia_ObjFaninC0(pObj) == (int)pFan0->fMark0 ) // justified + return 1; + return Cec_ManCheckSat2_rec( p, pFan1, Gia_ObjFaninC1(pObj), vValues ); + } + if ( Gia_ObjIsTravIdCurrent(p, pFan1) ) // already assigned + { + if ( Gia_ObjFaninC1(pObj) == (int)pFan1->fMark0 ) // justified + return 1; + return Cec_ManCheckSat2_rec( p, pFan0, Gia_ObjFaninC0(pObj), vValues ); + } + return Cec_ManCheckSat2_rec( p, pFan0, Gia_ObjFaninC0(pObj), vValues ); +} +word Cec_ManCheckSat2( Gia_Man_t * p, Gia_Obj_t * pObj, int Value, Vec_Wrd_t * vValues ) +{ + return 0; +} + +/**Function************************************************************* + + Synopsis [Return 1 if pObj can have Value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManCheckSat_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int Value ) +{ + Gia_Obj_t * pFan0, * pFan1; + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return Value == (int)pObj->fMark0; + Gia_ObjSetTravIdCurrent(p, pObj); + pObj->fMark0 = Value; + if ( !Gia_ObjIsAnd(pObj) ) + return 1; + pFan0 = Gia_ObjFanin0(pObj); + pFan1 = Gia_ObjFanin1(pObj); + if ( Value ) + { + return Cec_ManCheckSat_rec( p, pFan0, !Gia_ObjFaninC0(pObj) ) && + Cec_ManCheckSat_rec( p, pFan1, !Gia_ObjFaninC1(pObj) ); + } + if ( Gia_ObjIsTravIdCurrent(p, pFan0) ) // already assigned + { + if ( Gia_ObjFaninC0(pObj) == (int)pFan0->fMark0 ) // justified + return 1; + return Cec_ManCheckSat_rec( p, pFan1, Gia_ObjFaninC1(pObj) ); + } + if ( Gia_ObjIsTravIdCurrent(p, pFan1) ) // already assigned + { + if ( Gia_ObjFaninC1(pObj) == (int)pFan1->fMark0 ) // justified + return 1; + return Cec_ManCheckSat_rec( p, pFan0, Gia_ObjFaninC0(pObj) ); + } + return Cec_ManCheckSat_rec( p, pFan0, Gia_ObjFaninC0(pObj) ); +} +void Cec_ManSimBack( Gia_Man_t * p ) +{ + abctime clk = Abc_Clock(); + Vec_Wrd_t * vValues = Vec_WrdStart( Gia_ManObjNum(p) ); + Gia_Obj_t * pObj; + int i, Count = 0; + word Res; + Gia_ManSetPhase( p ); + //Gia_ManForEachAnd( p, pObj, i ) + // printf( "%d", pObj->fPhase ); + //printf( "\n" ); + //return; + + Gia_ManForEachAnd( p, pObj, i ) + { + Gia_ManIncrementTravId(p); + //Gia_ManCleanMark0( p ); + Res = Cec_ManCheckSat_rec( p, pObj, !pObj->fPhase ); + //if ( Res ) + // Cec_ObjSatVerify( p, pObj, !pObj->fPhase ); + + //Res = Cec_ManCheckSat2_rec( p, pObj, !pObj->fPhase ? ~(word)0 : 0, vValues ); + //if ( Res ) + // Cec_ObjSatVerify2( p, pObj, !pObj->fPhase, Res ); + + Count += (int)(Res > 0); + } + Vec_WrdFree( vValues ); + printf( "Obj = %6d. SAT = %6d. ", Gia_ManAndNum(p), Count ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + From 088aabc1023e6745bedeb16f9f8f01515c38e4b7 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Wed, 15 Feb 2017 17:02:32 -0800 Subject: [PATCH 143/185] - Small changes to the watch lists behavior. - Implementation of bookmark, unbookmark and rollback procedures. - Minor changes. --- src/sat/satoko/satoko.h | 7 ++-- src/sat/satoko/solver.c | 5 +-- src/sat/satoko/solver.h | 6 ++++ src/sat/satoko/solver_api.c | 56 ++++++++++++++++++++++++++++- src/sat/satoko/types.h | 1 + src/sat/satoko/utils/vec/vec_sdbl.h | 6 ++++ src/sat/satoko/watch_list.h | 22 ++++++++++++ 7 files changed, 98 insertions(+), 5 deletions(-) diff --git a/src/sat/satoko/satoko.h b/src/sat/satoko/satoko.h index 8d55a81c8..88070eace 100644 --- a/src/sat/satoko/satoko.h +++ b/src/sat/satoko/satoko.h @@ -89,9 +89,12 @@ extern void satoko_assump_push(satoko_t *s, unsigned); extern void satoko_assump_pop(satoko_t *s); extern int satoko_simplify(satoko_t *); extern int satoko_solve(satoko_t *); -extern void satoko_mark_cone(satoko_t *s, int * pvars, int nvars); -extern void satoko_unmark_cone(satoko_t *s, int * pvars, int nvars); +extern void satoko_mark_cone(satoko_t *, int *, int); +extern void satoko_unmark_cone(satoko_t *, int *, int); +extern void satoko_rollback(satoko_t *); +extern void satoko_bookmark(satoko_t *); +extern void satoko_unbookmark(satoko_t *); /* If problem is unsatisfiable under assumptions, this function is used to * obtain the final conflict clause expressed in the assumptions. * diff --git a/src/sat/satoko/solver.c b/src/sat/satoko/solver.c index d2bf1b5e8..21a4860d6 100644 --- a/src/sat/satoko/solver.c +++ b/src/sat/satoko/solver.c @@ -402,6 +402,7 @@ static inline void solver_garbage_collect(solver_t *s) clause_realloc(new_cdb, s->all_clauses, &(w->cref)); } + /* Update CREFS */ for (i = 0; i < vec_uint_size(s->trail); i++) if (lit_reason(s, vec_uint_at(s->trail, i)) != UNDEF) clause_realloc(new_cdb, s->all_clauses, &(vec_uint_data(s->reasons)[lit2var(vec_uint_at(s->trail, i))])); @@ -427,7 +428,7 @@ static inline void solver_reduce_cdb(solver_t *s) struct clause **learnts_cls; learnts_cls = satoko_alloc(struct clause *, n_learnts); - vec_uint_foreach(s->learnts, cref, i) + vec_uint_foreach_start(s->learnts, cref, i, s->book_cl_lrnt) learnts_cls[i] = clause_read(s, cref); limit = (unsigned)(n_learnts * s->opts.learnt_ratio); @@ -504,7 +505,7 @@ unsigned solver_clause_create(solver_t *s, vec_uint_t *lits, unsigned f_learnt) return cref; } -void solver_cancel_until(solver_t * s, unsigned level) +void solver_cancel_until(solver_t *s, unsigned level) { int i; diff --git a/src/sat/satoko/solver.h b/src/sat/satoko/solver.h index 84c256895..68cc97dcb 100644 --- a/src/sat/satoko/solver.h +++ b/src/sat/satoko/solver.h @@ -92,6 +92,12 @@ struct solver_t_ { vec_uint_t *stamps; /* Multipurpose stamp used to calculate LBD and * clauses minimization with binary resolution */ + /* Bookmark */ + unsigned book_cl_orig; /* Bookmark for orignal problem clauses vector */ + unsigned book_cl_lrnt; /* Bookmark for learnt clauses vector */ + unsigned book_vars; /* Bookmark number of variables */ + unsigned book_trail; /* Bookmark trail size */ + /* Temporary data used for solving cones */ vec_char_t *marks; diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c index 65fab8378..9cad0a144 100644 --- a/src/sat/satoko/solver_api.c +++ b/src/sat/satoko/solver_api.c @@ -229,7 +229,8 @@ void satoko_add_variable(solver_t *s, char sign) vec_uint_push_back(s->stamps, 0); vec_char_push_back(s->seen, 0); heap_insert(s->var_order, var); - if (s->marks) vec_char_push_back(s->marks, 0); + if (s->marks) + vec_char_push_back(s->marks, 0); } int satoko_add_clause(solver_t *s, unsigned *lits, unsigned size) @@ -315,6 +316,59 @@ satoko_stats_t satoko_stats(satoko_t *s) return s->stats; } +void satoko_bookmark(satoko_t *s) +{ + assert(solver_dlevel(s) == 0); + s->book_cl_orig = vec_uint_size(s->originals); + s->book_cl_lrnt = vec_uint_size(s->learnts); + s->book_vars = vec_char_size(s->assigns); + s->book_trail = vec_uint_size(s->trail); +} + +void satoko_unbookmark(satoko_t *s) +{ + s->book_cl_orig = 0; + s->book_cl_lrnt = 0; + s->book_vars = 0; + s->book_trail = 0; +} + +void satoko_rollback(satoko_t *s) +{ + unsigned i, cref; + unsigned n_originals = vec_uint_size(s->originals) - s->book_cl_orig; + unsigned n_learnts = vec_uint_size(s->learnts) - s->book_cl_lrnt; + struct clause **cl_to_remove; + + assert(solver_dlevel(s) == 0); + cl_to_remove = satoko_alloc(struct clause *, n_originals + n_learnts); + /* Mark clauses */ + vec_uint_foreach_start(s->originals, cref, i, s->book_cl_orig) + cl_to_remove[i] = clause_read(s, cref); + vec_uint_foreach_start(s->learnts, cref, i, s->book_cl_lrnt) + cl_to_remove[n_originals + i] = clause_read(s, cref); + for (i = 0; i < n_originals + n_learnts; i++) { + clause_unwatch(s, cdb_cref(s->all_clauses, (unsigned *)cl_to_remove[i])); + cl_to_remove[i]->f_mark = 1; + } + vec_uint_shrink(s->originals, s->book_cl_orig); + vec_uint_shrink(s->learnts, s->book_cl_lrnt); + /* Shrink variable related vectors */ + vec_act_shrink(s->activity, s->book_vars); + vec_uint_shrink(s->levels, s->book_vars); + vec_uint_shrink(s->reasons, s->book_vars); + vec_char_shrink(s->assigns, s->book_vars); + vec_char_shrink(s->polarity, s->book_vars); + solver_rebuild_order(s); + /* Rewind solver and cancel level 0 assignments to the trail */ + solver_cancel_until(s, 0); + vec_uint_shrink(s->trail, s->book_trail); + s->book_cl_orig = 0; + s->book_cl_lrnt = 0; + s->book_vars = 0; + s->book_trail = 0; +} + void satoko_mark_cone(satoko_t *s, int * pvars, int n_vars) { int i; diff --git a/src/sat/satoko/types.h b/src/sat/satoko/types.h index d51aed4c0..9c47ca7c8 100644 --- a/src/sat/satoko/types.h +++ b/src/sat/satoko/types.h @@ -26,6 +26,7 @@ typedef vec_sdbl_t vec_act_t ; #define vec_act_free(vec) vec_sdbl_free(vec) #define vec_act_size(vec) vec_sdbl_size(vec) #define vec_act_data(vec) vec_sdbl_data(vec) +#define vec_act_shrink(vec, size) vec_sdbl_shrink(vec, size) #define vec_act_at(vec, idx) vec_sdbl_at(vec, idx) #define vec_act_push_back(vec, value) vec_sdbl_push_back(vec, value) diff --git a/src/sat/satoko/utils/vec/vec_sdbl.h b/src/sat/satoko/utils/vec/vec_sdbl.h index aefd687a4..ec1c731cb 100755 --- a/src/sat/satoko/utils/vec/vec_sdbl.h +++ b/src/sat/satoko/utils/vec/vec_sdbl.h @@ -86,6 +86,12 @@ static inline unsigned vec_sdbl_size(vec_sdbl_t *p) return p->size; } +static inline void vec_sdbl_shrink(vec_sdbl_t *p, unsigned new_size) +{ + assert(new_size <= p->cap); + p->size = new_size; +} + static inline void vec_sdbl_resize(vec_sdbl_t *p, unsigned new_size) { p->size = new_size; diff --git a/src/sat/satoko/watch_list.h b/src/sat/satoko/watch_list.h index 96399a83a..49f419f27 100644 --- a/src/sat/satoko/watch_list.h +++ b/src/sat/satoko/watch_list.h @@ -100,6 +100,27 @@ static inline struct watcher *watch_list_array(struct watch_list *wl) return wl->watchers; } +/* TODO: I still have mixed feelings if this change should be done, keeping the + * old code commented after it. */ +static inline void watch_list_remove(struct watch_list *wl, unsigned cref, unsigned is_bin) +{ + struct watcher *watchers = watch_list_array(wl); + unsigned i; + if (is_bin) { + for (i = 0; watchers[i].cref != cref; i++); + assert(i < watch_list_size(wl)); + wl->n_bin--; + memmove((wl->watchers + i), (wl->watchers + i + 1), + (wl->size - i - 1) * sizeof(struct watcher)); + } else { + for (i = wl->n_bin; watchers[i].cref != cref; i++); + assert(i < watch_list_size(wl)); + stk_swap(struct watcher, wl->watchers[i], wl->watchers[wl->size - 1]); + } + wl->size -= 1; +} + +/* static inline void watch_list_remove(struct watch_list *wl, unsigned cref, unsigned is_bin) { struct watcher *watchers = watch_list_array(wl); @@ -114,6 +135,7 @@ static inline void watch_list_remove(struct watch_list *wl, unsigned cref, unsig (wl->size - i - 1) * sizeof(struct watcher)); wl->size -= 1; } +*/ static inline vec_wl_t *vec_wl_alloc(unsigned cap) { From ab387953ab3a50200384f5619cf999e3f729f28f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 15 Feb 2017 17:16:19 -0800 Subject: [PATCH 144/185] Word-level abstraction engine. --- abclib.dsp | 4 + src/aig/gia/gia.h | 1 + src/aig/gia/giaDup.c | 37 +++ src/base/abci/abc.c | 10 +- src/base/wlc/module.make | 1 + src/base/wlc/wlc.h | 25 +- src/base/wlc/wlcAbs.c | 534 ++++++++++++++++++++++++--------------- src/base/wlc/wlcAbs2.c | 298 +++++++++++++++++++--- src/base/wlc/wlcBlast.c | 2 +- src/base/wlc/wlcCom.c | 143 ++++++++++- src/base/wlc/wlcNtk.c | 91 ++++++- src/base/wlc/wlcUif.c | 290 +++++++++++++++++++++ src/proof/pdr/pdrInv.c | 13 +- src/proof/pdr/pdrMan.c | 2 +- 14 files changed, 1180 insertions(+), 271 deletions(-) create mode 100644 src/base/wlc/wlcUif.c diff --git a/abclib.dsp b/abclib.dsp index f9cc2f502..23c57506b 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -819,6 +819,10 @@ SOURCE=.\src\base\wlc\wlcStdin.c # End Source File # Begin Source File +SOURCE=.\src\base\wlc\wlcUif.c +# End Source File +# Begin Source File + SOURCE=.\src\base\wlc\wlcWin.c # End Source File # Begin Source File diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 6677e0ad2..c183432a4 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1229,6 +1229,7 @@ extern Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p, int fTrimCis, int f extern Gia_Man_t * Gia_ManDupOntop( Gia_Man_t * p, Gia_Man_t * p2 ); extern Gia_Man_t * Gia_ManDupWithNewPo( Gia_Man_t * p1, Gia_Man_t * p2 ); extern Gia_Man_t * Gia_ManDupDfsCiMap( Gia_Man_t * p, int * pCi2Lit, Vec_Int_t * vLits ); +extern Gia_Man_t * Gia_ManPermuteInputs( Gia_Man_t * p, int nPpis, int nExtra ); extern Gia_Man_t * Gia_ManDupDfsClasses( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupTopAnd( Gia_Man_t * p, int fVerbose ); extern Gia_Man_t * Gia_ManMiter( Gia_Man_t * pAig0, Gia_Man_t * pAig1, int nInsDup, int fDualOut, int fSeq, int fImplic, int fVerbose ); diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 56d1d29d5..ee709df49 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -2169,6 +2169,43 @@ Gia_Man_t * Gia_ManDupDfsCiMap( Gia_Man_t * p, int * pCi2Lit, Vec_Int_t * vLits return pNew; } +/**Function************************************************************* + + Synopsis [Permute inputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManPermuteInputs( Gia_Man_t * p, int nPpis, int nExtra ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManConst0(p)->Value = 0; + for ( i = 0; i < Gia_ManPiNum(p) - nPpis - nExtra; i++ ) // regular PIs + Gia_ManCi(p, i)->Value = Gia_ManAppendCi( pNew ); + for ( i = Gia_ManPiNum(p) - nExtra; i < Gia_ManPiNum(p); i++ ) // extra PIs due to DC values + Gia_ManCi(p, i)->Value = Gia_ManAppendCi( pNew ); + for ( i = Gia_ManPiNum(p) - nPpis - nExtra; i < Gia_ManPiNum(p) - nExtra; i++ ) // pseudo-PIs + Gia_ManCi(p, i)->Value = Gia_ManAppendCi( pNew ); + for ( i = Gia_ManPiNum(p); i < Gia_ManCiNum(p); i++ ) // flop outputs + Gia_ManCi(p, i)->Value = Gia_ManAppendCi( pNew ); + assert( Gia_ManCiNum(pNew) == Gia_ManCiNum(p) ); + Gia_ManForEachAnd( p, pObj, i ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachCo( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} + /**Function************************************************************* Synopsis [Duplicates AIG in the DFS order.] diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index bb0b8c8dd..af5d0ccfb 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26171,7 +26171,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Pdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmuyfsipdegonctvwzh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDQTHGSaxrmuyfsipdegonctvwzh" ) ) != EOF ) { switch ( c ) { @@ -26219,10 +26219,10 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nConfGenLimit < 0 ) goto usage; break; - case 'R': + case 'Q': if ( globalUtilOptind >= argc ) { - Abc_Print( -1, "Command line switch \"-R\" should be followed by an integer.\n" ); + Abc_Print( -1, "Command line switch \"-Q\" should be followed by an integer.\n" ); goto usage; } pPars->nRestLimit = atoi(argv[globalUtilOptind]); @@ -26366,7 +26366,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmuyfsipdegonctvwzh]\n" ); + Abc_Print( -2, "usage: pdr [-MFCDQTHGS ] [-axrmuyfsipdegonctvwzh]\n" ); Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); @@ -26374,7 +26374,7 @@ usage: Abc_Print( -2, "\t-F num : limit on timeframes explored to stop computation [default = %d]\n", pPars->nFrameMax ); Abc_Print( -2, "\t-C num : limit on conflicts in one SAT call (0 = no limit) [default = %d]\n", pPars->nConfLimit ); Abc_Print( -2, "\t-D num : limit on conflicts during ind-generalization (0 = no limit) [default = %d]\n",pPars->nConfGenLimit ); - Abc_Print( -2, "\t-R num : limit on proof obligations before a restart (0 = no limit) [default = %d]\n", pPars->nRestLimit ); + Abc_Print( -2, "\t-Q num : limit on proof obligations before a restart (0 = no limit) [default = %d]\n", pPars->nRestLimit ); Abc_Print( -2, "\t-T num : runtime limit, in seconds (0 = no limit) [default = %d]\n", pPars->nTimeOut ); Abc_Print( -2, "\t-H num : runtime limit per output, in miliseconds (with \"-a\") [default = %d]\n", pPars->nTimeOutOne ); Abc_Print( -2, "\t-G num : runtime gap since the last CEX (0 = no limit) [default = %d]\n", pPars->nTimeOutGap ); diff --git a/src/base/wlc/module.make b/src/base/wlc/module.make index 3485bd4d1..c4330264d 100644 --- a/src/base/wlc/module.make +++ b/src/base/wlc/module.make @@ -10,5 +10,6 @@ SRC += src/base/wlc/wlcAbs.c \ src/base/wlc/wlcSim.c \ src/base/wlc/wlcShow.c \ src/base/wlc/wlcStdin.c \ + src/base/wlc/wlcUif.c \ src/base/wlc/wlcWin.c \ src/base/wlc/wlcWriteVer.c diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 21ba73a30..91dc05730 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -158,6 +158,7 @@ struct Wlc_Ntk_t_ Vec_Int_t vCopies; // object first bits Vec_Int_t vBits; // object mapping into AIG nodes Vec_Int_t vLevels; // object levels + Vec_Int_t vRefs; // object reference counters }; typedef struct Wlc_Par_t_ Wlc_Par_t; @@ -167,7 +168,10 @@ struct Wlc_Par_t_ int nBitsMul; // multiplier bit-widht int nBitsMux; // MUX bit-width int nBitsFlop; // flop bit-width - int fVerbose; // verbose output` + int nIterMax; // the max number of iterations + int fXorOutput; // XOR outputs of word-level miter + int fVerbose; // verbose output + int fPdrVerbose; // verbose output }; static inline int Wlc_NtkObjNum( Wlc_Ntk_t * p ) { return p->iObj - 1; } @@ -272,19 +276,15 @@ static inline Wlc_Obj_t * Wlc_ObjCo2PoFo( Wlc_Ntk_t * p, int iCoId ) //////////////////////////////////////////////////////////////////////// /*=== wlcAbs.c ========================================================*/ -extern int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 ); -extern Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p ); -extern Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p ); -extern Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * pNtk, Vec_Int_t * vNodes ); -extern Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * pNtk, Vec_Int_t * vPairs ); +extern int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcAbs2.c ========================================================*/ -extern void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ); -extern Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); +extern int Wlc_NtkAbsCore2( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcBlast.c ========================================================*/ extern Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, int nRange, int fGiaSimple, int fAddOutputs, int fBooth ); /*=== wlcCom.c ========================================================*/ extern void Wlc_SetNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk ); /*=== wlcNtk.c ========================================================*/ +extern void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ); extern char * Wlc_ObjTypeName( Wlc_Obj_t * p ); extern Wlc_Ntk_t * Wlc_NtkAlloc( char * pName, int nObjsAlloc ); extern int Wlc_ObjAlloc( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg ); @@ -311,6 +311,9 @@ extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int Range, int extern void Wlc_NtkProfileCones( Wlc_Ntk_t * p ); extern Wlc_Ntk_t * Wlc_NtkDupSingleNodes( Wlc_Ntk_t * p ); extern void Wlc_NtkShortNames( Wlc_Ntk_t * p ); +extern int Wlc_NtkDcFlopNum( Wlc_Ntk_t * p ); +extern void Wlc_NtkSetRefs( Wlc_Ntk_t * p ); +extern int Wlc_NtkCountObjBits( Wlc_Ntk_t * p, Vec_Int_t * vPisNew ); /*=== wlcReadSmt.c ========================================================*/ extern Wlc_Ntk_t * Wlc_ReadSmtBuffer( char * pFileName, char * pBuffer, char * pLimit, int fOldParser, int fPrintTree ); extern Wlc_Ntk_t * Wlc_ReadSmt( char * pFileName, int fOldParser, int fPrintTree ); @@ -321,6 +324,12 @@ extern void Wlc_NtkDeleteSim( Vec_Ptr_t * p ); extern int Wlc_StdinProcessSmt( Abc_Frame_t * pAbc, char * pCmd ); /*=== wlcReadVer.c ========================================================*/ extern Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr ); +/*=== wlcUif.c ========================================================*/ +extern int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 ); +extern Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p ); +extern Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p ); +extern Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * pNtk, Vec_Int_t * vNodes ); +extern Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * pNtk, Vec_Int_t * vPairs ); /*=== wlcWin.c =============================================================*/ extern void Wlc_WinProfileArith( Wlc_Ntk_t * p ); /*=== wlcWriteVer.c ========================================================*/ diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index ce6b8de91..318df4dd4 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -1,6 +1,6 @@ /**CFile**************************************************************** - FileName [wlcAbs.c] + FileName [wlcAbs1.c] SystemName [ABC: Logic synthesis and verification system.] @@ -14,11 +14,14 @@ Date [Ver. 1.0. Started - August 22, 2014.] - Revision [$Id: wlcAbs.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + Revision [$Id: wlcAbs1.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] ***********************************************************************/ #include "wlc.h" +#include "proof/pdr/pdr.h" +#include "aig/gia/giaAig.h" +#include "sat/bmc/bmc.h" ABC_NAMESPACE_IMPL_START @@ -32,253 +35,370 @@ ABC_NAMESPACE_IMPL_START /**Function************************************************************* - Synopsis [Check if two objects have the same input/output signatures.] + Synopsis [Mark operators that meet the abstraction criteria.] - Description [] + Description [This procedure returns the array of objects (vLeaves) that + should be abstracted because of their high bit-width. It uses input array (vUnmark) + to not abstract those objects that have been refined in the previous rounds.] SideEffects [] SeeAlso [] ***********************************************************************/ -int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 ) +static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose ) { - Wlc_Obj_t * pFanin, * pFanin2; int k; - if ( Wlc_ObjRange(pObj) != Wlc_ObjRange(pObj2) ) - return 0; - if ( Wlc_ObjIsSigned(pObj) != Wlc_ObjIsSigned(pObj2) ) - return 0; - if ( Wlc_ObjFaninNum(pObj) != Wlc_ObjFaninNum(pObj2) ) - return 0; - for ( k = 0; k < Wlc_ObjFaninNum(pObj); k++ ) - { - pFanin = Wlc_ObjFanin(p, pObj, k); - pFanin2 = Wlc_ObjFanin(p, pObj2, k); - if ( Wlc_ObjRange(pFanin) != Wlc_ObjRange(pFanin2) ) - return 0; - if ( Wlc_ObjIsSigned(pFanin) != Wlc_ObjIsSigned(pFanin2) ) - return 0; - } - return 1; -} - -/**Function************************************************************* - - Synopsis [Collect IDs of the multipliers.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p ) -{ - Wlc_Obj_t * pObj; int i; - Vec_Int_t * vBoxIds = Vec_IntAlloc( 100 ); + Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) ); + Wlc_Obj_t * pObj; int i, Count[4] = {0}; Wlc_NtkForEachObj( p, pObj, i ) - if ( pObj->Type == WLC_OBJ_ARI_MULTI ) - Vec_IntPush( vBoxIds, i ); - if ( Vec_IntSize( vBoxIds ) > 0 ) - return vBoxIds; - Vec_IntFree( vBoxIds ); - return NULL; -} - -/**Function************************************************************* - - Synopsis [Returns all pairs of uifable multipliers.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p ) -{ - Vec_Int_t * vMultis = Wlc_NtkCollectMultipliers( p ); - Vec_Int_t * vPairs = Vec_IntAlloc( 2 ); - Wlc_Obj_t * pObj, * pObj2; int i, k; - // iterate through unique pairs - Wlc_NtkForEachObjVec( vMultis, p, pObj, i ) - Wlc_NtkForEachObjVec( vMultis, p, pObj2, k ) + { + if ( vUnmark && Vec_BitEntry(vUnmark, i) ) // not allow this object to be abstracted away + continue; + if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || pObj->Type == WLC_OBJ_ARI_MINUS ) { - if ( k == i ) - break; - if ( Wlc_NtkPairIsUifable( p, pObj, pObj2 ) ) - { - Vec_IntPush( vPairs, Wlc_ObjId(p, pObj) ); - Vec_IntPush( vPairs, Wlc_ObjId(p, pObj2) ); - } + if ( Wlc_ObjRange(pObj) >= pPars->nBitsAdd ) + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[0]++; + continue; } - Vec_IntFree( vMultis ); - if ( Vec_IntSize( vPairs ) > 0 ) - return vPairs; - Vec_IntFree( vPairs ); - return NULL; + if ( pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_DIVIDE || pObj->Type == WLC_OBJ_ARI_REM || pObj->Type == WLC_OBJ_ARI_MODULUS ) + { + if ( Wlc_ObjRange(pObj) >= pPars->nBitsMul ) + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[1]++; + continue; + } + if ( pObj->Type == WLC_OBJ_MUX ) + { + if ( Wlc_ObjRange(pObj) >= pPars->nBitsMux ) + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[2]++; + continue; + } + if ( Wlc_ObjIsCi(pObj) && !Wlc_ObjIsPi(pObj) ) + { + if ( Wlc_ObjRange(pObj) >= pPars->nBitsFlop ) + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[3]++; + continue; + } + } + if ( fVerbose ) + printf( "Abstraction engine marked %d adds/subs, %d muls/divs, %d muxes, and %d flops to be abstracted away.\n", Count[0], Count[1], Count[2], Count[3] ); + return vLeaves; } - - /**Function************************************************************* - Synopsis [Abstracts nodes by replacing their outputs with new PIs.] + Synopsis [Marks nodes to be included in the abstracted network.] - Description [If array is NULL, abstract all multipliers.] + Description [Marks all objects that will be included in the abstracted model. + Stops at the objects (vLeaves) that are abstracted away. Returns three arrays: + a subset of original PIs (vPisOld), a subset of pseudo-PIs (vPisNew) and the + set of flops present as flops in the abstracted network.] SideEffects [] SeeAlso [] ***********************************************************************/ -Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit ) +static void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) +{ + int i, iFanin; + if ( pObj->Mark ) + return; + pObj->Mark = 1; + if ( Vec_BitEntry(vLeaves, Wlc_ObjId(p, pObj)) ) + { + assert( !Wlc_ObjIsPi(pObj) ); + Vec_IntPush( vPisNew, Wlc_ObjId(p, pObj) ); + return; + } + if ( Wlc_ObjIsCi(pObj) ) + { + if ( Wlc_ObjIsPi(pObj) ) + Vec_IntPush( vPisOld, Wlc_ObjId(p, pObj) ); + else + Vec_IntPush( vFlops, Wlc_ObjId(p, pObj) ); + return; + } + Wlc_ObjForEachFanin( pObj, iFanin, i ) + Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkObj(p, iFanin), vLeaves, vPisOld, vPisNew, vFlops ); +} +static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) { - Vec_Int_t * vNodes = vNodesInit; - Wlc_Ntk_t * pNew; Wlc_Obj_t * pObj; - int i, k, iObj, iFanin; - // get multipliers if not given - if ( vNodes == NULL ) - vNodes = Wlc_NtkCollectMultipliers( p ); - if ( vNodes == NULL ) - return NULL; - // mark nodes - Wlc_NtkForEachObjVec( vNodes, p, pObj, i ) - pObj->Mark = 1; - // iterate through the nodes in the DFS order - Wlc_NtkCleanCopy( p ); + int i, Count = 0; + Wlc_NtkCleanMarks( p ); + Wlc_NtkForEachCo( p, pObj, i ) + Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vPisOld, vPisNew, vFlops ); + Wlc_NtkForEachObjVec( vFlops, p, pObj, i ) + Wlc_NtkAbsMarkNodes_rec( p, Wlc_ObjFo2Fi(p, pObj), vLeaves, vPisOld, vPisNew, vFlops ); Wlc_NtkForEachObj( p, pObj, i ) - { - if ( i == Vec_IntSize(&p->vCopies) ) - break; - if ( pObj->Mark ) { - // clean - pObj->Mark = 0; - // add fresh PI with the same number of bits - iObj = Wlc_ObjAlloc( p, WLC_OBJ_PI, Wlc_ObjIsSigned(pObj), Wlc_ObjRange(pObj) - 1, 0 ); - } - else { - // update fanins - Wlc_ObjForEachFanin( pObj, iFanin, k ) - Wlc_ObjFanins(pObj)[k] = Wlc_ObjCopy(p, iFanin); - // node to remain - iObj = i; - } - Wlc_ObjSetCopy( p, i, iObj ); - } - // POs do not change in this procedure - if ( vNodes != vNodesInit ) - Vec_IntFree( vNodes ); - // reconstruct topological order - pNew = Wlc_NtkDupDfs( p, 0, 1 ); - return pNew; + Count += pObj->Mark; +// printf( "Collected %d old PIs, %d new PIs, %d flops, and %d other objects.\n", +// Vec_IntSize(vPisOld), Vec_IntSize(vPisNew), Vec_IntSize(vFlops), +// Count - Vec_IntSize(vPisOld) - Vec_IntSize(vPisNew) - Vec_IntSize(vFlops) ); + Vec_IntSort( vPisOld, 0 ); + Vec_IntSort( vPisNew, 0 ); + Vec_IntSort( vFlops, 0 ); + Wlc_NtkCleanMarks( p ); } /**Function************************************************************* - Synopsis [Adds UIF constraints to node pairs and updates POs.] + Synopsis [Derive word-level abstracted model based on the parameter values.] - Description [] + Description [Retuns the word-level abstracted network and the set of pseudo-PIs + (vPisNew), which were created during abstraction. If the abstraction is + satisfiable, some of the pseudo-PIs will be un-abstracted. These pseudo-PIs + and their MFFC cones will be listed in the array (vUnmark), which will + force the abstraction to not stop at these pseudo-PIs in the future.] SideEffects [] SeeAlso [] ***********************************************************************/ -Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * p, Vec_Int_t * vPairsInit ) +static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose ) { - Vec_Int_t * vPairs = vPairsInit; - Wlc_Ntk_t * pNew; - Wlc_Obj_t * pObj, * pObj2; - Vec_Int_t * vUifConstrs, * vCompares, * vFanins; - int i, k, iObj, iObj2, iObjNew, iObjNew2; - int iFanin, iFanin2, iFaninNew; - // get multiplier pairs if not given - if ( vPairs == NULL ) - vPairs = Wlc_NtkFindUifableMultiplierPairs( p ); - if ( vPairs == NULL ) - return NULL; - // sanity checks - assert( Vec_IntSize(vPairs) > 0 && Vec_IntSize(vPairs) % 2 == 0 ); - // iterate through node pairs - vFanins = Vec_IntAlloc( 100 ); - vCompares = Vec_IntAlloc( 100 ); - vUifConstrs = Vec_IntAlloc( 100 ); - Vec_IntForEachEntryDouble( vPairs, iObj, iObj2, i ) - { - // get two nodes - pObj = Wlc_NtkObj( p, iObj ); - pObj2 = Wlc_NtkObj( p, iObj2 ); - assert( Wlc_NtkPairIsUifable(p, pObj, pObj2) ); - // create fanin comparator nodes - Vec_IntClear( vCompares ); - Wlc_ObjForEachFanin( pObj, iFanin, k ) - { - iFanin2 = Wlc_ObjFaninId( pObj2, k ); - Vec_IntFillTwo( vFanins, 2, iFanin, iFanin2 ); - iFaninNew = Wlc_ObjCreate( p, WLC_OBJ_COMP_NOTEQU, 0, 0, 0, vFanins ); - Vec_IntPush( vCompares, iFaninNew ); - // note that a pointer to Wlc_Obj_t (for example, pObj) can be invalidated after a call to - // Wlc_ObjCreate() due to a possible realloc of the internal array of objects... - pObj = Wlc_NtkObj( p, iObj ); - } - // concatenate fanin comparators - iObjNew = Wlc_ObjCreate( p, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vCompares) - 1, 0, vCompares ); - // create reduction-OR node - Vec_IntFill( vFanins, 1, iObjNew ); - iObjNew = Wlc_ObjCreate( p, WLC_OBJ_REDUCT_OR, 0, 0, 0, vFanins ); - // craete output comparator node - Vec_IntFillTwo( vFanins, 2, iObj, iObj2 ); - iObjNew2 = Wlc_ObjCreate( p, WLC_OBJ_COMP_EQU, 0, 0, 0, vFanins ); - // create implication node (iObjNew is already complemented above) - Vec_IntFillTwo( vFanins, 2, iObjNew, iObjNew2 ); - iObjNew = Wlc_ObjCreate( p, WLC_OBJ_LOGIC_OR, 0, 0, 0, vFanins ); - // save the constraint - Vec_IntPush( vUifConstrs, iObjNew ); - } - // derive the AND of the UIF contraints - assert( Vec_IntSize(vUifConstrs) > 0 ); - if ( Vec_IntSize(vUifConstrs) == 1 ) - iObjNew = Vec_IntEntry( vUifConstrs, 0 ); + Wlc_Ntk_t * pNtkNew = NULL; + Vec_Int_t * vPisOld = Vec_IntAlloc( 100 ); + Vec_Int_t * vPisNew = Vec_IntAlloc( 100 ); + Vec_Int_t * vFlops = Vec_IntAlloc( 100 ); + Vec_Bit_t * vLeaves = Wlc_NtkAbsMarkOpers( p, pPars, vUnmark, fVerbose ); + Wlc_NtkAbsMarkNodes( p, vLeaves, vPisOld, vPisNew, vFlops ); + Vec_BitFree( vLeaves ); + pNtkNew = Wlc_NtkDupDfsAbs( p, vPisOld, vPisNew, vFlops ); + Vec_IntFree( vPisOld ); + Vec_IntFree( vFlops ); + if ( pvPisNew ) + *pvPisNew = vPisNew; else + Vec_IntFree( vPisNew ); + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Find what objects need to be un-abstracted.] + + Description [Returns a subset of pseudo-PIs (vPisNew), which will be + prevented from being abstracted in the future rounds of abstraction. + The AIG manager (pGia) is a bit-level view of the abstracted model. + The counter-example (pCex) is used to find waht PPIs to refine.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static Vec_Int_t * Wlc_NtkAbsRefinement( Wlc_Ntk_t * p, Gia_Man_t * pGia, Abc_Cex_t * pCex, Vec_Int_t * vPisNew ) +{ + Vec_Int_t * vRefine = Vec_IntAlloc( 100 ); + Abc_Cex_t * pCexCare; + Wlc_Obj_t * pObj; + // count the number of bit-level PPIs and map them into word-level objects they were derived from + int f, i, b, nRealPis, nPpiBits = 0; + Vec_Int_t * vMap = Vec_IntStartFull( pCex->nPis ); + Wlc_NtkForEachObjVec( vPisNew, p, pObj, i ) + for ( b = 0; b < Wlc_ObjRange(pObj); b++ ) + Vec_IntWriteEntry( vMap, nPpiBits++, Wlc_ObjId(p, pObj) ); + // since PPIs are ordered last, the previous bits are real PIs + nRealPis = pCex->nPis - nPpiBits; + // find the care-set + pCexCare = Bmc_CexCareMinimizeAig( pGia, nRealPis, pCex, 1, 0, 0 ); + assert( pCexCare->nPis == pCex->nPis ); + // detect care PPIs + for ( f = 0; f <= pCexCare->iFrame; f++ ) + for ( i = nRealPis; i < pCexCare->nPis; i++ ) + if ( Abc_InfoHasBit(pCexCare->pData, pCexCare->nRegs + pCexCare->nPis * f + i) ) + Vec_IntPushUniqueOrder( vRefine, Vec_IntEntry(vMap, i-nRealPis) ); + Abc_CexFree( pCexCare ); + Vec_IntFree( vMap ); + if ( Vec_IntSize(vRefine) == 0 )// real CEX + Vec_IntFreeP( &vRefine ); + return vRefine; +} + +/**Function************************************************************* + + Synopsis [Mark MFFC cones of the un-abstracted objects.] + + Description [The MFFC cones of the objects in vRefine are traversed + and all their nodes are marked in vUnmark.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static int Wlc_NtkNodeDeref_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark ) +{ + int i, Fanin, Counter = 1; + if ( Wlc_ObjIsCi(pNode) ) + return 0; + Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 ); + Wlc_ObjForEachFanin( pNode, Fanin, i ) { - // concatenate - iObjNew = Wlc_ObjCreate( p, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vUifConstrs) - 1, 0, vUifConstrs ); - // create reduction-AND node - Vec_IntFill( vFanins, 1, iObjNew ); - iObjNew = Wlc_ObjCreate( p, WLC_OBJ_REDUCT_AND, 0, 0, 0, vFanins ); + Vec_IntAddToEntry( &p->vRefs, Fanin, -1 ); + if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 ) + Counter += Wlc_NtkNodeDeref_rec( p, Wlc_NtkObj(p, Fanin), vUnmark ); } - // update each PO to point to the new node - Wlc_NtkForEachPo( p, pObj, i ) + return Counter; +} +static int Wlc_NtkNodeRef_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode ) +{ + int i, Fanin, Counter = 1; + if ( Wlc_ObjIsCi(pNode) ) + return 0; + Wlc_ObjForEachFanin( pNode, Fanin, i ) { - iObj = Wlc_ObjId(p, pObj); - Vec_IntFillTwo( vFanins, 2, iObj, iObjNew ); - iObjNew = Wlc_ObjCreate( p, WLC_OBJ_LOGIC_AND, 0, 0, 0, vFanins ); - // note that a pointer to Wlc_Obj_t (for example, pObj) can be invalidated after a call to - // Wlc_ObjCreate() due to a possible realloc of the internal array of objects... - pObj = Wlc_NtkObj( p, iObj ); - // update PO/CO arrays - assert( Vec_IntEntry(&p->vPos, i) == iObj ); - assert( Vec_IntEntry(&p->vCos, i) == iObj ); - Vec_IntWriteEntry( &p->vPos, i, iObjNew ); - Vec_IntWriteEntry( &p->vCos, i, iObjNew ); - // transfer the PO attribute - Wlc_NtkObj(p, iObjNew)->fIsPo = 1; - assert( pObj->fIsPo ); - pObj->fIsPo = 0; + if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 ) + Counter += Wlc_NtkNodeRef_rec( p, Wlc_NtkObj(p, Fanin) ); + Vec_IntAddToEntry( &p->vRefs, Fanin, 1 ); } - // cleanup - Vec_IntFree( vUifConstrs ); - Vec_IntFree( vCompares ); - Vec_IntFree( vFanins ); - if ( vPairs != vPairsInit ) - Vec_IntFree( vPairs ); - // reconstruct topological order - pNew = Wlc_NtkDupDfs( p, 0, 1 ); - return pNew; + return Counter; +} +static int Wlc_NtkMarkMffc( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark ) +{ + int Count1, Count2; + // if this is a flop output, compute MFFC of the corresponding flop input + while ( Wlc_ObjIsCi(pNode) ) + { + Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 ); + pNode = Wlc_ObjFo2Fi(p, pNode); + } + assert( !Wlc_ObjIsCi(pNode) ); + // dereference the node (and set the bits in vUnmark) + Count1 = Wlc_NtkNodeDeref_rec( p, pNode, vUnmark ); + // reference it back + Count2 = Wlc_NtkNodeRef_rec( p, pNode ); + assert( Count1 == Count2 ); + return Count1; +} +static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec_Bit_t * vUnmark ) +{ + Wlc_Obj_t * pObj; int i, nNodes = 0; + if ( Vec_IntSize(&p->vRefs) == 0 ) + Wlc_NtkSetRefs( p ); + Wlc_NtkForEachObjVec( vRefine, p, pObj, i ) + nNodes += Wlc_NtkMarkMffc( p, pObj, vUnmark ); + return nNodes; +} + +/**Function************************************************************* + + Synopsis [Performs abstraction.] + + Description [Derives initial abstraction based on user-specified + parameter values, which tell what is the smallest bit-width of a + primitive that is being abstracted away. Currently only add/sub, + mul/div, mux, and flop are supported with individual parameters. + The second step is to refine the initial abstraction until the + point when the property is proved.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) +{ + abctime clk = Abc_Clock(); + int nIters, nNodes, nDcFlops, RetValue = -1; + // start the bitmap to mark objects that cannot be abstracted because of refinement + // currently, this bitmap is empty because abstraction begins without refinement + Vec_Bit_t * vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(p) ); + // set up parameters to run PDR + Pdr_Par_t PdrPars, * pPdrPars = &PdrPars; + Pdr_ManSetDefaultParams( pPdrPars ); + pPdrPars->fUseAbs = 1; // use 'pdr -t' (on-the-fly abstraction) + pPdrPars->fCtgs = 1; // use 'pdr -nc' (improved generalization) + pPdrPars->fSkipDown = 0; // use 'pdr -nc' (improved generalization) + //pPdrPars->nRestLimit = 500; // reset queue or proof-obligations when it gets larger than this + pPdrPars->fVerbose = pPars->fPdrVerbose; + // perform refinement iterations + for ( nIters = 1; nIters < pPars->nIterMax; nIters++ ) + { + Aig_Man_t * pAig; + Abc_Cex_t * pCex; + Vec_Int_t * vPisNew, * vRefine; + Gia_Man_t * pGia, * pTemp; + Wlc_Ntk_t * pAbs; + + if ( pPars->fVerbose ) + printf( "\nIteration %d:\n", nIters ); + + // get abstracted GIA and the set of pseudo-PIs (vPisNew) + pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, pPars->fVerbose ); + pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 ); + + // if the abstraction has flops with DC-init state, + // new PIs were introduced by bit-blasting at the end of the PI list + // here we move these variables to be *before* PPIs, because + // PPIs are supposed to be at the end of the PI list for refinement + nDcFlops = Wlc_NtkDcFlopNum(pAbs); + if ( nDcFlops > 0 ) // DC-init flops are present + { + pGia = Gia_ManPermuteInputs( pTemp = pGia, Wlc_NtkCountObjBits(p, vPisNew), nDcFlops ); + Gia_ManStop( pTemp ); + } + // if the word-level outputs have to be XORs, this is a place to do it + if ( pPars->fXorOutput ) + { + pGia = Gia_ManTransformMiter2( pTemp = pGia ); + Gia_ManStop( pTemp ); + } + if ( pPars->fVerbose ) + { + printf( "Derived abstraction with %d objects and %d PPIs. Bit-blasted AIG stats are:\n", Wlc_NtkObjNum(pAbs), Vec_IntSize(vPisNew) ); + Gia_ManPrintStats( pGia, NULL ); + } + Wlc_NtkFree( pAbs ); + + // try to prove abstracted GIA by converting it to AIG and calling PDR + pAig = Gia_ManToAigSimple( pGia ); + RetValue = Pdr_ManSolve( pAig, pPdrPars ); + pCex = pAig->pSeqModel; pAig->pSeqModel = NULL; + Aig_ManStop( pAig ); + + // consider outcomes + if ( pCex == NULL ) + { + assert( RetValue ); // proved or undecided + Gia_ManStop( pGia ); + Vec_IntFree( vPisNew ); + break; + } + + // perform refinement + vRefine = Wlc_NtkAbsRefinement( p, pGia, pCex, vPisNew ); + Gia_ManStop( pGia ); + Vec_IntFree( vPisNew ); + if ( vRefine == NULL ) // real CEX + { + Abc_CexFree( pCex ); // return CEX in the future + break; + } + + // update the set of objects to be un-abstracted + nNodes = Wlc_NtkRemoveFromAbstraction( p, vRefine, vUnmark ); + if ( pPars->fVerbose ) + printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs, whose MFFCs include %d objects.\n", pCex->iFrame, Vec_IntSize(vRefine), nNodes ); + Vec_IntFree( vRefine ); + Abc_CexFree( pCex ); + } + Vec_BitFree( vUnmark ); + // report the result + if ( pPars->fVerbose ) + printf( "\n" ); + printf( "Abstraction " ); + if ( RetValue == 0 ) + printf( "resulted in a real CEX" ); + else if ( RetValue == 1 ) + printf( "is successfully proved" ); + else + printf( "timed out" ); + printf( " after %d iterations. ", nIters ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + return RetValue; } //////////////////////////////////////////////////////////////////////// diff --git a/src/base/wlc/wlcAbs2.c b/src/base/wlc/wlcAbs2.c index f5a7b46da..9bccdf620 100644 --- a/src/base/wlc/wlcAbs2.c +++ b/src/base/wlc/wlcAbs2.c @@ -19,6 +19,9 @@ ***********************************************************************/ #include "wlc.h" +#include "proof/pdr/pdr.h" +#include "aig/gia/giaAig.h" +#include "sat/bmc/bmc.h" ABC_NAMESPACE_IMPL_START @@ -26,56 +29,31 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -typedef struct Wabs_Par_t_ Wabs_Par_t; -struct Wabs_Par_t_ -{ - Wlc_Ntk_t * pNtk; - Wlc_Par_t * pPars; - Vec_Bit_t * vLeaves; -}; - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* - Synopsis [] + Synopsis [Mark operators that meet the abstraction criteria.] - Description [] + Description [This procedure returns the array of objects (vLeaves) that + should be abstracted because of their high bit-width. It uses input array (vUnmark) + to not abstract those objects that have been refined in the previous rounds.] SideEffects [] SeeAlso [] ***********************************************************************/ -void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ) -{ - memset( pPars, 0, sizeof(Wlc_Par_t) ); - pPars->nBitsAdd = ABC_INFINITY; // adder bit-width - pPars->nBitsMul = ABC_INFINITY; // multiplier bit-widht - pPars->nBitsMux = ABC_INFINITY; // MUX bit-width - pPars->nBitsFlop = ABC_INFINITY; // flop bit-width - pPars->fVerbose = 0; // verbose output` -} - -/**Function************************************************************* - - Synopsis [Mark operators that meet the criteria.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) +static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose ) { Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) ); Wlc_Obj_t * pObj; int i, Count[4] = {0}; Wlc_NtkForEachObj( p, pObj, i ) { + if ( vUnmark && Vec_BitEntry(vUnmark, i) ) // not allow this object to be abstracted away + continue; if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || pObj->Type == WLC_OBJ_ARI_MINUS ) { if ( Wlc_ObjRange(pObj) >= pPars->nBitsAdd ) @@ -101,7 +79,8 @@ Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) continue; } } - printf( "Abstraction engine marked %d adds/subs, %d muls/divs, %d muxes, and %d flops to be abstracted away.\n", Count[0], Count[1], Count[2], Count[3] ); + if ( fVerbose ) + printf( "Abstraction engine marked %d adds/subs, %d muls/divs, %d muxes, and %d flops to be abstracted away.\n", Count[0], Count[1], Count[2], Count[3] ); return vLeaves; } @@ -109,14 +88,17 @@ Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) Synopsis [Marks nodes to be included in the abstracted network.] - Description [] + Description [Marks all objects that will be included in the abstracted model. + Stops at the objects (vLeaves) that are abstracted away. Returns three arrays: + a subset of original PIs (vPisOld), a subset of pseudo-PIs (vPisNew) and the + set of flops present as flops in the abstracted network.] SideEffects [] SeeAlso [] ***********************************************************************/ -void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) +static void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) { int i, iFanin; if ( pObj->Mark ) @@ -139,8 +121,7 @@ void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeav Wlc_ObjForEachFanin( pObj, iFanin, i ) Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkObj(p, iFanin), vLeaves, vPisOld, vPisNew, vFlops ); } - -void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) +static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) { Wlc_Obj_t * pObj; int i, Count = 0; @@ -162,31 +143,264 @@ void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOl /**Function************************************************************* - Synopsis [Derive abstraction based on the parameter values.] + Synopsis [Derive word-level abstracted model based on the parameter values.] - Description [] + Description [Retuns the word-level abstracted network and the set of pseudo-PIs + (vPisNew), which were created during abstraction. If the abstraction is + satisfiable, some of the pseudo-PIs will be un-abstracted. These pseudo-PIs + and their MFFC cones will be listed in the array (vUnmark), which will + force the abstraction to not stop at these pseudo-PIs in the future.] SideEffects [] SeeAlso [] ***********************************************************************/ -Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) +static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose ) { Wlc_Ntk_t * pNtkNew = NULL; Vec_Int_t * vPisOld = Vec_IntAlloc( 100 ); Vec_Int_t * vPisNew = Vec_IntAlloc( 100 ); Vec_Int_t * vFlops = Vec_IntAlloc( 100 ); - Vec_Bit_t * vLeaves = Wlc_NtkAbsMarkOpers( p, pPars ); + Vec_Bit_t * vLeaves = Wlc_NtkAbsMarkOpers( p, pPars, vUnmark, fVerbose ); Wlc_NtkAbsMarkNodes( p, vLeaves, vPisOld, vPisNew, vFlops ); Vec_BitFree( vLeaves ); pNtkNew = Wlc_NtkDupDfsAbs( p, vPisOld, vPisNew, vFlops ); Vec_IntFree( vPisOld ); - Vec_IntFree( vPisNew ); Vec_IntFree( vFlops ); + if ( pvPisNew ) + *pvPisNew = vPisNew; + else + Vec_IntFree( vPisNew ); return pNtkNew; } +/**Function************************************************************* + + Synopsis [Find what objects need to be un-abstracted.] + + Description [Returns a subset of pseudo-PIs (vPisNew), which will be + prevented from being abstracted in the future rounds of abstraction. + The AIG manager (pGia) is a bit-level view of the abstracted model. + The counter-example (pCex) is used to find waht PPIs to refine.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static Vec_Int_t * Wlc_NtkAbsRefinement( Wlc_Ntk_t * p, Gia_Man_t * pGia, Abc_Cex_t * pCex, Vec_Int_t * vPisNew ) +{ + Vec_Int_t * vRefine = Vec_IntAlloc( 100 ); + Abc_Cex_t * pCexCare; + Wlc_Obj_t * pObj; + // count the number of bit-level PPIs and map them into word-level objects they were derived from + int f, i, b, nRealPis, nPpiBits = 0; + Vec_Int_t * vMap = Vec_IntStartFull( pCex->nPis ); + Wlc_NtkForEachObjVec( vPisNew, p, pObj, i ) + for ( b = 0; b < Wlc_ObjRange(pObj); b++ ) + Vec_IntWriteEntry( vMap, nPpiBits++, Wlc_ObjId(p, pObj) ); + // since PPIs are ordered last, the previous bits are real PIs + nRealPis = pCex->nPis - nPpiBits; + // find the care-set + pCexCare = Bmc_CexCareMinimizeAig( pGia, nRealPis, pCex, 1, 0, 0 ); + assert( pCexCare->nPis == pCex->nPis ); + // detect care PPIs + for ( f = 0; f <= pCexCare->iFrame; f++ ) + for ( i = nRealPis; i < pCexCare->nPis; i++ ) + if ( Abc_InfoHasBit(pCexCare->pData, pCexCare->nRegs + pCexCare->nPis * f + i) ) + Vec_IntPushUniqueOrder( vRefine, Vec_IntEntry(vMap, i-nRealPis) ); + Abc_CexFree( pCexCare ); + Vec_IntFree( vMap ); + if ( Vec_IntSize(vRefine) == 0 )// real CEX + Vec_IntFreeP( &vRefine ); + return vRefine; +} + +/**Function************************************************************* + + Synopsis [Mark MFFC cones of the un-abstracted objects.] + + Description [The MFFC cones of the objects in vRefine are traversed + and all their nodes are marked in vUnmark.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static int Wlc_NtkNodeDeref_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark ) +{ + int i, Fanin, Counter = 1; + if ( Wlc_ObjIsCi(pNode) ) + return 0; + Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 ); + Wlc_ObjForEachFanin( pNode, Fanin, i ) + { + Vec_IntAddToEntry( &p->vRefs, Fanin, -1 ); + if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 ) + Counter += Wlc_NtkNodeDeref_rec( p, Wlc_NtkObj(p, Fanin), vUnmark ); + } + return Counter; +} +static int Wlc_NtkNodeRef_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode ) +{ + int i, Fanin, Counter = 1; + if ( Wlc_ObjIsCi(pNode) ) + return 0; + Wlc_ObjForEachFanin( pNode, Fanin, i ) + { + if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 ) + Counter += Wlc_NtkNodeRef_rec( p, Wlc_NtkObj(p, Fanin) ); + Vec_IntAddToEntry( &p->vRefs, Fanin, 1 ); + } + return Counter; +} +static int Wlc_NtkMarkMffc( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark ) +{ + int Count1, Count2; + // if this is a flop output, compute MFFC of the corresponding flop input + while ( Wlc_ObjIsCi(pNode) ) + { + Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 ); + pNode = Wlc_ObjFo2Fi(p, pNode); + } + assert( !Wlc_ObjIsCi(pNode) ); + // dereference the node (and set the bits in vUnmark) + Count1 = Wlc_NtkNodeDeref_rec( p, pNode, vUnmark ); + // reference it back + Count2 = Wlc_NtkNodeRef_rec( p, pNode ); + assert( Count1 == Count2 ); + return Count1; +} +static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec_Bit_t * vUnmark ) +{ + Wlc_Obj_t * pObj; int i, nNodes = 0; + if ( Vec_IntSize(&p->vRefs) == 0 ) + Wlc_NtkSetRefs( p ); + Wlc_NtkForEachObjVec( vRefine, p, pObj, i ) + nNodes += Wlc_NtkMarkMffc( p, pObj, vUnmark ); + return nNodes; +} + +/**Function************************************************************* + + Synopsis [Performs abstraction.] + + Description [Derives initial abstraction based on user-specified + parameter values, which tell what is the smallest bit-width of a + primitive that is being abstracted away. Currently only add/sub, + mul/div, mux, and flop are supported with individual parameters. + The second step is to refine the initial abstraction until the + point when the property is proved.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Wlc_NtkAbsCore2( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) +{ + abctime clk = Abc_Clock(); + int nIters, nNodes, nDcFlops, RetValue = -1; + // start the bitmap to mark objects that cannot be abstracted because of refinement + // currently, this bitmap is empty because abstraction begins without refinement + Vec_Bit_t * vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(p) ); + // set up parameters to run PDR + Pdr_Par_t PdrPars, * pPdrPars = &PdrPars; + Pdr_ManSetDefaultParams( pPdrPars ); + pPdrPars->fUseAbs = 1; // use 'pdr -t' (on-the-fly abstraction) + pPdrPars->fCtgs = 1; // use 'pdr -nc' (improved generalization) + pPdrPars->fSkipDown = 0; // use 'pdr -nc' (improved generalization) + //pPdrPars->nRestLimit = 500; // reset queue or proof-obligations when it gets larger than this + pPdrPars->fVerbose = pPars->fPdrVerbose; + // perform refinement iterations + for ( nIters = 1; nIters < pPars->nIterMax; nIters++ ) + { + Aig_Man_t * pAig; + Abc_Cex_t * pCex; + Vec_Int_t * vPisNew, * vRefine; + Gia_Man_t * pGia, * pTemp; + Wlc_Ntk_t * pAbs; + + if ( pPars->fVerbose ) + printf( "\nIteration %d:\n", nIters ); + + // get abstracted GIA and the set of pseudo-PIs (vPisNew) + pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, pPars->fVerbose ); + pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 ); + + // if the abstraction has flops with DC-init state, + // new PIs were introduced by bit-blasting at the end of the PI list + // here we move these variables to be *before* PPIs, because + // PPIs are supposed to be at the end of the PI list for refinement + nDcFlops = Wlc_NtkDcFlopNum(pAbs); + if ( nDcFlops > 0 ) // DC-init flops are present + { + pGia = Gia_ManPermuteInputs( pTemp = pGia, Wlc_NtkCountObjBits(p, vPisNew), nDcFlops ); + Gia_ManStop( pTemp ); + } + // if the word-level outputs have to be XORs, this is a place to do it + if ( pPars->fXorOutput ) + { + pGia = Gia_ManTransformMiter2( pTemp = pGia ); + Gia_ManStop( pTemp ); + } + if ( pPars->fVerbose ) + { + printf( "Derived abstraction with %d objects and %d PPIs. Bit-blasted AIG stats are:\n", Wlc_NtkObjNum(pAbs), Vec_IntSize(vPisNew) ); + Gia_ManPrintStats( pGia, NULL ); + } + Wlc_NtkFree( pAbs ); + + // try to prove abstracted GIA by converting it to AIG and calling PDR + pAig = Gia_ManToAigSimple( pGia ); + RetValue = Pdr_ManSolve( pAig, pPdrPars ); + pCex = pAig->pSeqModel; pAig->pSeqModel = NULL; + Aig_ManStop( pAig ); + + // consider outcomes + if ( pCex == NULL ) + { + assert( RetValue ); // proved or undecided + Gia_ManStop( pGia ); + Vec_IntFree( vPisNew ); + break; + } + + // perform refinement + vRefine = Wlc_NtkAbsRefinement( p, pGia, pCex, vPisNew ); + Gia_ManStop( pGia ); + Vec_IntFree( vPisNew ); + if ( vRefine == NULL ) // real CEX + { + Abc_CexFree( pCex ); // return CEX in the future + break; + } + + // update the set of objects to be un-abstracted + nNodes = Wlc_NtkRemoveFromAbstraction( p, vRefine, vUnmark ); + if ( pPars->fVerbose ) + printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs, whose MFFCs include %d objects.\n", pCex->iFrame, Vec_IntSize(vRefine), nNodes ); + Vec_IntFree( vRefine ); + Abc_CexFree( pCex ); + } + Vec_BitFree( vUnmark ); + // report the result + if ( pPars->fVerbose ) + printf( "\n" ); + printf( "Abstraction " ); + if ( RetValue == 0 ) + printf( "resulted in a real CEX" ); + else if ( RetValue == 1 ) + printf( "is successfully proved" ); + else + printf( "timed out" ); + printf( " after %d iterations. ", nIters ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + return RetValue; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index 67d7c9025..f4de8ee66 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -1418,7 +1418,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in } else { - pNew = Gia_ManDupZeroUndc( pTemp = pNew, p->pInits, fGiaSimple, 1 ); + pNew = Gia_ManDupZeroUndc( pTemp = pNew, p->pInits, fGiaSimple, 0 ); Gia_ManDupRemapLiterals( vBits, pTemp ); Gia_ManStop( pTemp ); } diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 346a90768..97717b090 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -33,6 +33,7 @@ static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ) static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbs ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbs2 ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandShortNames ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -74,6 +75,7 @@ void Wlc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%cone", Abc_CommandCone, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%abs", Abc_CommandAbs, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%abs2", Abc_CommandAbs2, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%short_names", Abc_CommandShortNames, 0 ); @@ -458,7 +460,7 @@ int Abc_CommandAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Wlc_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIxvwh" ) ) != EOF ) { switch ( c ) { @@ -506,9 +508,26 @@ int Abc_CommandAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nBitsFlop < 0 ) goto usage; break; + case 'I': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nIterMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nIterMax < 0 ) + goto usage; + break; + case 'x': + pPars->fXorOutput ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; + case 'w': + pPars->fPdrVerbose ^= 1; + break; case 'h': goto usage; default: @@ -520,17 +539,133 @@ int Abc_CommandAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" ); return 0; } - pNtk = Wlc_NtkAbs( pNtk, pPars ); - Wlc_AbcUpdateNtk( pAbc, pNtk ); + Wlc_NtkAbsCore( pNtk, pPars ); return 0; usage: - Abc_Print( -2, "usage: %%abs [-AMXF num] [-vh]\n" ); + Abc_Print( -2, "usage: %%abs [-AMXFI num] [-xvwh]\n" ); Abc_Print( -2, "\t abstraction for word-level networks\n" ); Abc_Print( -2, "\t-A num : minimum bit-width of an adder/subtractor to abstract [default = %d]\n", pPars->nBitsAdd ); Abc_Print( -2, "\t-M num : minimum bit-width of a multiplier to abstract [default = %d]\n", pPars->nBitsMul ); Abc_Print( -2, "\t-X num : minimum bit-width of a MUX operator to abstract [default = %d]\n", pPars->nBitsMux ); Abc_Print( -2, "\t-F num : minimum bit-width of a flip-flop to abstract [default = %d]\n", pPars->nBitsFlop ); + Abc_Print( -2, "\t-I num : maximum number of CEGAR iterations [default = %d]\n", pPars->nIterMax ); + Abc_Print( -2, "\t-x : toggle XORing outputs of word-level miter [default = %s]\n", pPars->fXorOutput? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-w : toggle printing verbose PDR output [default = %s]\n", pPars->fPdrVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandAbs2( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + Wlc_Par_t Pars, * pPars = &Pars; + int c; + Wlc_ManSetDefaultParams( pPars ); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIxvwh" ) ) != EOF ) + { + switch ( c ) + { + case 'A': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-A\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsAdd = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsAdd < 0 ) + goto usage; + break; + case 'M': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsMul = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsMul < 0 ) + goto usage; + break; + case 'X': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsMux = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsMux < 0 ) + goto usage; + break; + case 'F': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsFlop = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsFlop < 0 ) + goto usage; + break; + case 'I': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nIterMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nIterMax < 0 ) + goto usage; + break; + case 'x': + pPars->fXorOutput ^= 1; + break; + case 'v': + pPars->fVerbose ^= 1; + break; + case 'w': + pPars->fPdrVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" ); + return 0; + } + Wlc_NtkAbsCore2( pNtk, pPars ); + return 0; +usage: + Abc_Print( -2, "usage: %%abs2 [-AMXFI num] [-xvwh]\n" ); + Abc_Print( -2, "\t abstraction for word-level networks\n" ); + Abc_Print( -2, "\t-A num : minimum bit-width of an adder/subtractor to abstract [default = %d]\n", pPars->nBitsAdd ); + Abc_Print( -2, "\t-M num : minimum bit-width of a multiplier to abstract [default = %d]\n", pPars->nBitsMul ); + Abc_Print( -2, "\t-X num : minimum bit-width of a MUX operator to abstract [default = %d]\n", pPars->nBitsMux ); + Abc_Print( -2, "\t-F num : minimum bit-width of a flip-flop to abstract [default = %d]\n", pPars->nBitsFlop ); + Abc_Print( -2, "\t-I num : maximum number of CEGAR iterations [default = %d]\n", pPars->nIterMax ); + Abc_Print( -2, "\t-x : toggle XORing outputs of word-level miter [default = %s]\n", pPars->fXorOutput? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-w : toggle printing verbose PDR output [default = %s]\n", pPars->fPdrVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index 86b0c17e7..e6ab0739c 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -94,6 +94,30 @@ char * Wlc_ObjTypeName( Wlc_Obj_t * p ) { return Wlc_Names[p->Type]; } /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ) +{ + memset( pPars, 0, sizeof(Wlc_Par_t) ); + pPars->nBitsAdd = ABC_INFINITY; // adder bit-width + pPars->nBitsMul = ABC_INFINITY; // multiplier bit-widht + pPars->nBitsMux = ABC_INFINITY; // MUX bit-width + pPars->nBitsFlop = ABC_INFINITY; // flop bit-width + pPars->nIterMax = 1000; // the max number of iterations + pPars->fXorOutput = 1; // XOR outputs of word-level miter + pPars->fVerbose = 0; // verbose output` + pPars->fPdrVerbose = 0; // show verbose PDR output +} + /**Function************************************************************* Synopsis [Working with models.] @@ -227,6 +251,7 @@ void Wlc_NtkFree( Wlc_Ntk_t * p ) ABC_FREE( p->vCopies.pArray ); ABC_FREE( p->vBits.pArray ); ABC_FREE( p->vLevels.pArray ); + ABC_FREE( p->vRefs.pArray ); ABC_FREE( p->pInits ); ABC_FREE( p->pObjs ); ABC_FREE( p->pName ); @@ -912,7 +937,7 @@ Wlc_Ntk_t * Wlc_NtkDupDfsAbs( Wlc_Ntk_t * p, Vec_Int_t * vPisOld, Vec_Int_t * vP if ( p->pSpec ) pNew->pSpec = Abc_UtilStrsav( p->pSpec ); - Wlc_NtkTransferNames( pNew, p ); + //Wlc_NtkTransferNames( pNew, p ); return pNew; } @@ -1129,6 +1154,70 @@ void Wlc_NtkShortNames( Wlc_Ntk_t * p ) } } +/**Function************************************************************* + + Synopsis [Count the number of flops initialized to DC value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Wlc_NtkDcFlopNum( Wlc_Ntk_t * p ) +{ + int i, nFlops, Count = 0; + if ( p->pInits == NULL ) + return 0; + nFlops = strlen(p->pInits); + for ( i = 0; i < nFlops; i++ ) + Count += (p->pInits[i] == 'x' || p->pInits[i] == 'X'); + return Count; +} + +/**Function************************************************************* + + Synopsis [Create references.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkSetRefs( Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; int i, k, Fanin; + Vec_IntFill( &p->vRefs, Wlc_NtkObjNumMax(p), 0 ); + Wlc_NtkForEachObj( p, pObj, i ) + Wlc_ObjForEachFanin( pObj, Fanin, k ) + Vec_IntAddToEntry( &p->vRefs, Fanin, 1 ); + Wlc_NtkForEachCo( p, pObj, i ) + Vec_IntAddToEntry( &p->vRefs, Wlc_ObjId(p, pObj), 1 ); +} + +/**Function************************************************************* + + Synopsis [This procedure simply count the number of PPI bits.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Wlc_NtkCountObjBits( Wlc_Ntk_t * p, Vec_Int_t * vPisNew ) +{ + Wlc_Obj_t * pObj; + int i, Count = 0; + Wlc_NtkForEachObjVec( vPisNew, p, pObj, i ) + Count += Wlc_ObjRange(pObj); + return Count; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/wlc/wlcUif.c b/src/base/wlc/wlcUif.c new file mode 100644 index 000000000..78451c17b --- /dev/null +++ b/src/base/wlc/wlcUif.c @@ -0,0 +1,290 @@ +/**CFile**************************************************************** + + FileName [wlcUif.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Verilog parser.] + + Synopsis [Abstraction for word-level networks.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - August 22, 2014.] + + Revision [$Id: wlcUif.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wlc.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Check if two objects have the same input/output signatures.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 ) +{ + Wlc_Obj_t * pFanin, * pFanin2; int k; + if ( Wlc_ObjRange(pObj) != Wlc_ObjRange(pObj2) ) + return 0; + if ( Wlc_ObjIsSigned(pObj) != Wlc_ObjIsSigned(pObj2) ) + return 0; + if ( Wlc_ObjFaninNum(pObj) != Wlc_ObjFaninNum(pObj2) ) + return 0; + for ( k = 0; k < Wlc_ObjFaninNum(pObj); k++ ) + { + pFanin = Wlc_ObjFanin(p, pObj, k); + pFanin2 = Wlc_ObjFanin(p, pObj2, k); + if ( Wlc_ObjRange(pFanin) != Wlc_ObjRange(pFanin2) ) + return 0; + if ( Wlc_ObjIsSigned(pFanin) != Wlc_ObjIsSigned(pFanin2) ) + return 0; + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Collect IDs of the multipliers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; int i; + Vec_Int_t * vBoxIds = Vec_IntAlloc( 100 ); + Wlc_NtkForEachObj( p, pObj, i ) + if ( pObj->Type == WLC_OBJ_ARI_MULTI ) + Vec_IntPush( vBoxIds, i ); + if ( Vec_IntSize( vBoxIds ) > 0 ) + return vBoxIds; + Vec_IntFree( vBoxIds ); + return NULL; +} + +/**Function************************************************************* + + Synopsis [Returns all pairs of uifable multipliers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p ) +{ + Vec_Int_t * vMultis = Wlc_NtkCollectMultipliers( p ); + Vec_Int_t * vPairs = Vec_IntAlloc( 2 ); + Wlc_Obj_t * pObj, * pObj2; int i, k; + // iterate through unique pairs + Wlc_NtkForEachObjVec( vMultis, p, pObj, i ) + Wlc_NtkForEachObjVec( vMultis, p, pObj2, k ) + { + if ( k == i ) + break; + if ( Wlc_NtkPairIsUifable( p, pObj, pObj2 ) ) + { + Vec_IntPush( vPairs, Wlc_ObjId(p, pObj) ); + Vec_IntPush( vPairs, Wlc_ObjId(p, pObj2) ); + } + } + Vec_IntFree( vMultis ); + if ( Vec_IntSize( vPairs ) > 0 ) + return vPairs; + Vec_IntFree( vPairs ); + return NULL; +} + + + +/**Function************************************************************* + + Synopsis [Abstracts nodes by replacing their outputs with new PIs.] + + Description [If array is NULL, abstract all multipliers.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit ) +{ + Vec_Int_t * vNodes = vNodesInit; + Wlc_Ntk_t * pNew; + Wlc_Obj_t * pObj; + int i, k, iObj, iFanin; + // get multipliers if not given + if ( vNodes == NULL ) + vNodes = Wlc_NtkCollectMultipliers( p ); + if ( vNodes == NULL ) + return NULL; + // mark nodes + Wlc_NtkForEachObjVec( vNodes, p, pObj, i ) + pObj->Mark = 1; + // iterate through the nodes in the DFS order + Wlc_NtkCleanCopy( p ); + Wlc_NtkForEachObj( p, pObj, i ) + { + if ( i == Vec_IntSize(&p->vCopies) ) + break; + if ( pObj->Mark ) { + // clean + pObj->Mark = 0; + // add fresh PI with the same number of bits + iObj = Wlc_ObjAlloc( p, WLC_OBJ_PI, Wlc_ObjIsSigned(pObj), Wlc_ObjRange(pObj) - 1, 0 ); + } + else { + // update fanins + Wlc_ObjForEachFanin( pObj, iFanin, k ) + Wlc_ObjFanins(pObj)[k] = Wlc_ObjCopy(p, iFanin); + // node to remain + iObj = i; + } + Wlc_ObjSetCopy( p, i, iObj ); + } + // POs do not change in this procedure + if ( vNodes != vNodesInit ) + Vec_IntFree( vNodes ); + // reconstruct topological order + pNew = Wlc_NtkDupDfs( p, 0, 1 ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Adds UIF constraints to node pairs and updates POs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * p, Vec_Int_t * vPairsInit ) +{ + Vec_Int_t * vPairs = vPairsInit; + Wlc_Ntk_t * pNew; + Wlc_Obj_t * pObj, * pObj2; + Vec_Int_t * vUifConstrs, * vCompares, * vFanins; + int i, k, iObj, iObj2, iObjNew, iObjNew2; + int iFanin, iFanin2, iFaninNew; + // get multiplier pairs if not given + if ( vPairs == NULL ) + vPairs = Wlc_NtkFindUifableMultiplierPairs( p ); + if ( vPairs == NULL ) + return NULL; + // sanity checks + assert( Vec_IntSize(vPairs) > 0 && Vec_IntSize(vPairs) % 2 == 0 ); + // iterate through node pairs + vFanins = Vec_IntAlloc( 100 ); + vCompares = Vec_IntAlloc( 100 ); + vUifConstrs = Vec_IntAlloc( 100 ); + Vec_IntForEachEntryDouble( vPairs, iObj, iObj2, i ) + { + // get two nodes + pObj = Wlc_NtkObj( p, iObj ); + pObj2 = Wlc_NtkObj( p, iObj2 ); + assert( Wlc_NtkPairIsUifable(p, pObj, pObj2) ); + // create fanin comparator nodes + Vec_IntClear( vCompares ); + Wlc_ObjForEachFanin( pObj, iFanin, k ) + { + iFanin2 = Wlc_ObjFaninId( pObj2, k ); + Vec_IntFillTwo( vFanins, 2, iFanin, iFanin2 ); + iFaninNew = Wlc_ObjCreate( p, WLC_OBJ_COMP_NOTEQU, 0, 0, 0, vFanins ); + Vec_IntPush( vCompares, iFaninNew ); + // note that a pointer to Wlc_Obj_t (for example, pObj) can be invalidated after a call to + // Wlc_ObjCreate() due to a possible realloc of the internal array of objects... + pObj = Wlc_NtkObj( p, iObj ); + } + // concatenate fanin comparators + iObjNew = Wlc_ObjCreate( p, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vCompares) - 1, 0, vCompares ); + // create reduction-OR node + Vec_IntFill( vFanins, 1, iObjNew ); + iObjNew = Wlc_ObjCreate( p, WLC_OBJ_REDUCT_OR, 0, 0, 0, vFanins ); + // craete output comparator node + Vec_IntFillTwo( vFanins, 2, iObj, iObj2 ); + iObjNew2 = Wlc_ObjCreate( p, WLC_OBJ_COMP_EQU, 0, 0, 0, vFanins ); + // create implication node (iObjNew is already complemented above) + Vec_IntFillTwo( vFanins, 2, iObjNew, iObjNew2 ); + iObjNew = Wlc_ObjCreate( p, WLC_OBJ_LOGIC_OR, 0, 0, 0, vFanins ); + // save the constraint + Vec_IntPush( vUifConstrs, iObjNew ); + } + // derive the AND of the UIF contraints + assert( Vec_IntSize(vUifConstrs) > 0 ); + if ( Vec_IntSize(vUifConstrs) == 1 ) + iObjNew = Vec_IntEntry( vUifConstrs, 0 ); + else + { + // concatenate + iObjNew = Wlc_ObjCreate( p, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vUifConstrs) - 1, 0, vUifConstrs ); + // create reduction-AND node + Vec_IntFill( vFanins, 1, iObjNew ); + iObjNew = Wlc_ObjCreate( p, WLC_OBJ_REDUCT_AND, 0, 0, 0, vFanins ); + } + // update each PO to point to the new node + Wlc_NtkForEachPo( p, pObj, i ) + { + iObj = Wlc_ObjId(p, pObj); + Vec_IntFillTwo( vFanins, 2, iObj, iObjNew ); + iObjNew = Wlc_ObjCreate( p, WLC_OBJ_LOGIC_AND, 0, 0, 0, vFanins ); + // note that a pointer to Wlc_Obj_t (for example, pObj) can be invalidated after a call to + // Wlc_ObjCreate() due to a possible realloc of the internal array of objects... + pObj = Wlc_NtkObj( p, iObj ); + // update PO/CO arrays + assert( Vec_IntEntry(&p->vPos, i) == iObj ); + assert( Vec_IntEntry(&p->vCos, i) == iObj ); + Vec_IntWriteEntry( &p->vPos, i, iObjNew ); + Vec_IntWriteEntry( &p->vCos, i, iObjNew ); + // transfer the PO attribute + Wlc_NtkObj(p, iObjNew)->fIsPo = 1; + assert( pObj->fIsPo ); + pObj->fIsPo = 0; + } + // cleanup + Vec_IntFree( vUifConstrs ); + Vec_IntFree( vCompares ); + Vec_IntFree( vFanins ); + if ( vPairs != vPairsInit ) + Vec_IntFree( vPairs ); + // reconstruct topological order + pNew = Wlc_NtkDupDfs( p, 0, 1 ); + return pNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index 554add9b3..baade033d 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -50,7 +50,16 @@ void Pdr_ManPrintProgress( Pdr_Man_t * p, int fClose, abctime Time ) Vec_Ptr_t * vVec; int i, ThisSize, Length, LengthStart; if ( Vec_PtrSize(p->vSolvers) < 2 ) + { + printf( "Frame " ); + printf( "Clauses " ); + printf( "Max Queue " ); + printf( "Flops " ); + printf( "Cex " ); + printf( "Time" ); + printf( "\n" ); return; + } if ( Abc_FrameIsBatchMode() && !fClose ) return; // count the total length of the printout @@ -81,9 +90,9 @@ void Pdr_ManPrintProgress( Pdr_Man_t * p, int fClose, abctime Time ) for ( i = ThisSize; i < 70; i++ ) Abc_Print( 1, " " ); Abc_Print( 1, "%5d", p->nQueMax ); - Abc_Print( 1, "%5d", p->vAbsFlops ? Vec_IntCountPositive(p->vAbsFlops) : p->nAbsFlops ); + Abc_Print( 1, "%6d", p->vAbsFlops ? Vec_IntCountPositive(p->vAbsFlops) : p->nAbsFlops ); if ( p->pPars->fUseAbs ) - Abc_Print( 1, "%5d", p->nCexes ); + Abc_Print( 1, "%4d", p->nCexes ); Abc_Print( 1, "%10.2f sec", 1.0*Time/CLOCKS_PER_SEC ); if ( p->pPars->fSolveAll ) Abc_Print( 1, " CEX =%4d", p->pPars->nFailOuts ); diff --git a/src/proof/pdr/pdrMan.c b/src/proof/pdr/pdrMan.c index c19041eed..abe8c0a8d 100644 --- a/src/proof/pdr/pdrMan.c +++ b/src/proof/pdr/pdrMan.c @@ -455,7 +455,7 @@ Abc_Cex_t * Pdr_ManDeriveCexAbs( Pdr_Man_t * p ) int i, f, Lit, Flop, nFrames = 0; int nPis = Saig_ManPiNum(p->pAig); int nFfRefined = 0; - if ( !p->pPars->fUseAbs ) + if ( !p->pPars->fUseAbs || !p->vMapPpi2Ff ) return Pdr_ManDeriveCex(p); // restore previous map Vec_IntForEachEntry( p->vMapPpi2Ff, Flop, i ) From bcc6d2686ffe6c0edce08d1470801f2f8e642bff Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 15 Feb 2017 19:12:47 -0800 Subject: [PATCH 145/185] Fixing missing sat_solver APIs in 'iprove'. --- src/sat/bsat/satSolver.c | 43 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/src/sat/bsat/satSolver.c b/src/sat/bsat/satSolver.c index 37e0ea949..f753e0a54 100644 --- a/src/sat/bsat/satSolver.c +++ b/src/sat/bsat/satSolver.c @@ -328,12 +328,49 @@ static inline void act_var_bump(sat_solver* s, int v) } static inline void act_var_bump_global(sat_solver* s, int v) { - assert(0); + if ( !s->pGlobalVars ) + return; + if ( s->VarActType == 0 ) + { + s->activity[v] += (int)((unsigned)s->var_inc * 3 * s->pGlobalVars[v]); + if (s->activity[v] & 0x80000000) + act_var_rescale(s); + if (s->orderpos[v] != -1) + order_update(s,v); + } + else if ( s->VarActType == 1 ) + { + s->activity[v] += (unsigned)(Abc_Word2Dbl(s->var_inc) * 3.0 * s->pGlobalVars[v]); + if (Abc_Word2Dbl(s->activity[v]) > 1e100) + act_var_rescale(s); + if (s->orderpos[v] != -1) + order_update(s,v); + } + else assert( 0 ); } static inline void act_var_bump_factor(sat_solver* s, int v) { - assert(0); + if ( !s->factors ) + return; + if ( s->VarActType == 0 ) + { + s->activity[v] += (int)((unsigned)s->var_inc * (float)s->factors[v]); + if (s->activity[v] & 0x80000000) + act_var_rescale(s); + if (s->orderpos[v] != -1) + order_update(s,v); + } + else if ( s->VarActType == 1 ) + { + s->activity[v] += (unsigned)(Abc_Word2Dbl(s->var_inc) * s->factors[v]); + if (Abc_Word2Dbl(s->activity[v]) > 1e100) + act_var_rescale(s); + if (s->orderpos[v] != -1) + order_update(s,v); + } + else assert( 0 ); } + static inline void act_var_decay(sat_solver* s) { if ( s->VarActType == 0 ) @@ -1234,7 +1271,7 @@ void sat_solver_setnvars(sat_solver* s,int n) else if ( s->VarActType == 1 ) s->activity[var] = 0; else if ( s->VarActType == 2 ) - s->activity[var] = Xdbl_Const1(); + s->activity[var] = 0; else assert(0); s->pFreqs[var] = 0; From c7b68c5e3f547679b524ec5e0dcb85cc3735deef Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 16 Feb 2017 10:03:34 -0800 Subject: [PATCH 146/185] Promising modification of the generalization procedure in 'pdr'. --- src/base/abci/abc.c | 8 ++++++-- src/proof/pdr/pdr.h | 1 + src/proof/pdr/pdrCore.c | 37 ++++++++++++++++++++++++------------- src/proof/pdr/pdrInt.h | 2 +- src/proof/pdr/pdrSat.c | 4 ++-- 5 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index af5d0ccfb..44e4bc166 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26171,7 +26171,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Pdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDQTHGSaxrmuyfsipdegonctvwzh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDQTHGSaxrmuyfsipdegjonctvwzh" ) ) != EOF ) { switch ( c ) { @@ -26313,6 +26313,9 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'g': pPars->fSkipGeneral ^= 1; break; + case 'j': + pPars->fSimpleGeneral ^= 1; + break; case 'o': pPars->fUsePropOut ^= 1; break; @@ -26366,7 +26369,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: pdr [-MFCDQTHGS ] [-axrmuyfsipdegonctvwzh]\n" ); + Abc_Print( -2, "usage: pdr [-MFCDQTHGS ] [-axrmuyfsipdegjonctvwzh]\n" ); Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); @@ -26392,6 +26395,7 @@ usage: Abc_Print( -2, "\t-d : toggle dumping invariant (valid if init state is all-0) [default = %s]\n", pPars->fDumpInv? "yes": "no" ); Abc_Print( -2, "\t-e : toggle using only support variables in the invariant [default = %s]\n", pPars->fUseSupp? "yes": "no" ); Abc_Print( -2, "\t-g : toggle skipping expensive generalization step [default = %s]\n", pPars->fSkipGeneral? "yes": "no" ); + Abc_Print( -2, "\t-j : toggle using simplified generalization step [default = %s]\n", pPars->fSimpleGeneral? "yes": "no" ); Abc_Print( -2, "\t-o : toggle using property output as inductive hypothesis [default = %s]\n", pPars->fUsePropOut? "yes": "no" ); Abc_Print( -2, "\t-n : * toggle skipping \'down\' in generalization [default = %s]\n", pPars->fSkipDown? "yes": "no" ); Abc_Print( -2, "\t-c : * toggle handling CTGs in \'down\' [default = %s]\n", pPars->fCtgs? "yes": "no" ); diff --git a/src/proof/pdr/pdr.h b/src/proof/pdr/pdr.h index 333975882..534e8e4b8 100644 --- a/src/proof/pdr/pdr.h +++ b/src/proof/pdr/pdr.h @@ -60,6 +60,7 @@ struct Pdr_Par_t_ int fShortest; // forces bug traces to be shortest int fShiftStart; // allows clause pushing to start from an intermediate frame int fReuseProofOblig; // reuses proof-obligationgs in the last timeframe + int fSimpleGeneral; // simplified generalization int fSkipGeneral; // skips expensive generalization step int fSkipDown; // skips the application of down int fCtgs; // handle CTGs in down diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index 45dbfc9f1..58735f283 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -125,7 +125,7 @@ Pdr_Set_t * Pdr_ManReduceClause( Pdr_Man_t * p, int k, Pdr_Set_t * pCube ) // make sure the cube works { int RetValue; - RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, 0, 0 ); + RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, 0, 0, 1 ); assert( RetValue ); } */ @@ -172,7 +172,7 @@ int Pdr_ManPushClauses( Pdr_Man_t * p ) } // check if the clause can be moved to the next frame - RetValue2 = Pdr_ManCheckCube( p, k, pCubeK, NULL, 0, 0 ); + RetValue2 = Pdr_ManCheckCube( p, k, pCubeK, NULL, 0, 0, 1 ); if ( RetValue2 == -1 ) return -1; if ( !RetValue2 ) @@ -336,7 +336,7 @@ int ZPdr_ManSimpleMic( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube ) continue; // try removing this literal Lit = (*ppCube)->Lits[i]; (*ppCube)->Lits[i] = -1; - RetValue = Pdr_ManCheckCube( p, k, *ppCube, NULL, p->pPars->nConfLimit, 0 ); + RetValue = Pdr_ManCheckCube( p, k, *ppCube, NULL, p->pPars->nConfLimit, 0, 1 ); if ( RetValue == -1 ) return -1; (*ppCube)->Lits[i] = Lit; @@ -392,7 +392,7 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, *added = 1; } ctgAttempts++; - CtgRetValue = Pdr_ManCheckCube ( p, k-1, pCtg, NULL, p->pPars->nConfLimit, 0 ); + CtgRetValue = Pdr_ManCheckCube ( p, k-1, pCtg, NULL, p->pPars->nConfLimit, 0, 1 ); if ( CtgRetValue != 1 ) { Pdr_SetDeref( pCtg ); @@ -403,7 +403,7 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, pCubeMin = Pdr_SetDup ( pCtg ); for ( l = k; l < kMax; l++ ) - if ( !Pdr_ManCheckCube( p, l, pCubeMin, NULL, 0, 0 ) ) + if ( !Pdr_ManCheckCube( p, l, pCubeMin, NULL, 0, 0, 1 ) ) break; micResult = ZPdr_ManSimpleMic( p, l-1, &pCubeMin ); assert ( micResult != -1 ); @@ -430,7 +430,7 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, // add clause for ( i = 1; i <= l; i++ ) Pdr_ManSolverAddClause( p, i, pCubeMin ); - RetValue = Pdr_ManCheckCube ( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0 ); + RetValue = Pdr_ManCheckCube ( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0, 1 ); assert( RetValue >= 0 ); Pdr_SetDeref( pCtg ); if ( RetValue == 1 ) @@ -464,7 +464,7 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, printf ("Failed initiation\n"); return 0; } - RetValue = Pdr_ManCheckCube ( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0 ); + RetValue = Pdr_ManCheckCube ( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0, 1 ); if ( RetValue == -1 ) return -1; if ( RetValue == 1 ) @@ -530,7 +530,7 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP *ppCubeMin = NULL; if ( p->pPars->fFlopOrder ) Vec_IntSelectSortCostReverseLit( pCube->Lits, pCube->nLits, p->vPrio ); - RetValue = Pdr_ManCheckCube( p, k, pCube, ppPred, p->pPars->nConfLimit, 0 ); + RetValue = Pdr_ManCheckCube( p, k, pCube, ppPred, p->pPars->nConfLimit, 0, 1 ); if ( p->pPars->fFlopOrder ) Vec_IntSelectSort( pCube->Lits, pCube->nLits ); if ( RetValue == -1 ) @@ -552,6 +552,16 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP // perform generalization if ( !p->pPars->fSkipGeneral ) { + // assume the unminimized cube + if ( p->pPars->fSimpleGeneral ) + { + sat_solver * pSat = Pdr_ManFetchSolver( p, k ); + Vec_Int_t * vLits1 = Pdr_ManCubeToLits( p, k, pCubeMin, 1, 0 ); + int RetValue1 = sat_solver_addclause( pSat, Vec_IntArray(vLits1), Vec_IntArray(vLits1) + Vec_IntSize(vLits1) ); + assert( RetValue1 == 1 ); + sat_solver_compress( pSat ); + } + // sort literals by their occurences pOrder = Pdr_ManSortByPriority( p, pCubeMin ); // try removing literals @@ -571,12 +581,13 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP // check init state if ( Pdr_SetIsInit(pCubeMin, i) ) continue; + // try removing this literal Lit = pCubeMin->Lits[i]; pCubeMin->Lits[i] = -1; if ( p->pPars->fSkipDown ) - RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 1 ); + RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 1, !p->pPars->fSimpleGeneral ); else - RetValue = Pdr_ManCheckCube( p, k, pCubeMin, &pPred, p->pPars->nConfLimit, 1 ); + RetValue = Pdr_ManCheckCube( p, k, pCubeMin, &pPred, p->pPars->nConfLimit, 1, !p->pPars->fSimpleGeneral ); if ( RetValue == -1 ) { Pdr_SetDeref( pCubeMin ); @@ -641,7 +652,7 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP continue; // try removing this literal Lit = pCubeMin->Lits[i]; pCubeMin->Lits[i] = -1; - RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 0 ); + RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 0, 1 ); if ( RetValue == -1 ) { Pdr_SetDeref( pCubeMin ); @@ -759,7 +770,7 @@ int Pdr_ManBlockCube( Pdr_Man_t * p, Pdr_Set_t * pCube ) assert( pPred == NULL ); for ( k = pThis->iFrame; k < kMax; k++ ) { - RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, 0, 0 ); + RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, 0, 0, 1 ); if ( RetValue == -1 ) { Pdr_OblDeref( pThis ); @@ -940,7 +951,7 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) p->pPars->iFrame = iFrame; return -1; } - RetValue = Pdr_ManCheckCube( p, iFrame, NULL, &pCube, p->pPars->nConfLimit, 0 ); + RetValue = Pdr_ManCheckCube( p, iFrame, NULL, &pCube, p->pPars->nConfLimit, 0, 1 ); if ( RetValue == 1 ) break; if ( RetValue == -1 ) diff --git a/src/proof/pdr/pdrInt.h b/src/proof/pdr/pdrInt.h index a6d249e89..e5b043396 100644 --- a/src/proof/pdr/pdrInt.h +++ b/src/proof/pdr/pdrInt.h @@ -199,7 +199,7 @@ extern Vec_Int_t * Pdr_ManLitsToCube( Pdr_Man_t * p, int k, int * pArray, in extern void Pdr_ManSolverAddClause( Pdr_Man_t * p, int k, Pdr_Set_t * pCube ); extern void Pdr_ManCollectValues( Pdr_Man_t * p, int k, Vec_Int_t * vObjIds, Vec_Int_t * vValues ); extern int Pdr_ManCheckCubeCs( Pdr_Man_t * p, int k, Pdr_Set_t * pCube ); -extern int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPred, int nConfLimit, int fTryConf ); +extern int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPred, int nConfLimit, int fTryConf, int fUseLit ); /*=== pdrTsim.c ==========================================================*/ extern Pdr_Set_t * Pdr_ManTernarySim( Pdr_Man_t * p, int k, Pdr_Set_t * pCube ); /*=== pdrTsim2.c ==========================================================*/ diff --git a/src/proof/pdr/pdrSat.c b/src/proof/pdr/pdrSat.c index b9403e6fb..ab582d9e5 100644 --- a/src/proof/pdr/pdrSat.c +++ b/src/proof/pdr/pdrSat.c @@ -287,9 +287,9 @@ int Pdr_ManCheckCubeCs( Pdr_Man_t * p, int k, Pdr_Set_t * pCube ) SeeAlso [] ***********************************************************************/ -int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPred, int nConfLimit, int fTryConf ) +int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPred, int nConfLimit, int fTryConf, int fUseLit ) { - int fUseLit = 1; + //int fUseLit = 0; int fLitUsed = 0; sat_solver * pSat; Vec_Int_t * vLits; From 408ce468152257ddbcbce697f26e5246618fd38b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 16 Feb 2017 10:28:39 -0800 Subject: [PATCH 147/185] Fixing memory leak in 'pdr'. --- src/proof/pdr/pdrCore.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index 58735f283..40e86727e 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -378,7 +378,7 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, ctgAttempts = 0; while ( p->pPars->fCtgs && RetValue == 0 && k > 1 && ctgAttempts < 3 ) { - pCtg = Pdr_SetDup ( pPred ); + pCtg = Pdr_SetDup( pPred ); //Check CTG for inductiveness if ( Pdr_SetIsInit( pCtg, -1 ) ) { @@ -392,7 +392,7 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, *added = 1; } ctgAttempts++; - CtgRetValue = Pdr_ManCheckCube ( p, k-1, pCtg, NULL, p->pPars->nConfLimit, 0, 1 ); + CtgRetValue = Pdr_ManCheckCube( p, k-1, pCtg, NULL, p->pPars->nConfLimit, 0, 1 ); if ( CtgRetValue != 1 ) { Pdr_SetDeref( pCtg ); @@ -430,7 +430,8 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, // add clause for ( i = 1; i <= l; i++ ) Pdr_ManSolverAddClause( p, i, pCubeMin ); - RetValue = Pdr_ManCheckCube ( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0, 1 ); + Pdr_SetDeref( pPred ); + RetValue = Pdr_ManCheckCube( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0, 1 ); assert( RetValue >= 0 ); Pdr_SetDeref( pCtg ); if ( RetValue == 1 ) @@ -464,7 +465,7 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, printf ("Failed initiation\n"); return 0; } - RetValue = Pdr_ManCheckCube ( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0, 1 ); + RetValue = Pdr_ManCheckCube( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0, 1 ); if ( RetValue == -1 ) return -1; if ( RetValue == 1 ) @@ -598,8 +599,8 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP { if ( p->pPars->fSkipDown ) continue; - pCubeCpy = Pdr_SetCreateFrom ( pCubeMin, i ); - RetValue = ZPdr_ManDown ( p, k, &pCubeCpy, pPred, keep, pCubeMin, &added ); + pCubeCpy = Pdr_SetCreateFrom( pCubeMin, i ); + RetValue = ZPdr_ManDown( p, k, &pCubeCpy, pPred, keep, pCubeMin, &added ); if ( p->pPars->fCtgs ) //CTG handling code messes up with the internal order array pOrder = Pdr_ManSortByPriority( p, pCubeMin ); From 61b665ac8d3f107eb8ddf01f4cb816ddc3df21b0 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 16 Feb 2017 11:38:06 -0800 Subject: [PATCH 148/185] Experiment with graph constuction using ZDDs. --- src/bdd/extrab/extraBddMisc.c | 46 +++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/bdd/extrab/extraBddMisc.c b/src/bdd/extrab/extraBddMisc.c index a2ba40368..44170102e 100644 --- a/src/bdd/extrab/extraBddMisc.c +++ b/src/bdd/extrab/extraBddMisc.c @@ -2333,6 +2333,52 @@ void Extra_zddDumpPla( DdManager * dd, DdNode * F, int nVars, char * pFileName ) ABC_FREE( pCube ); } +/**Function************************************************************* + + Synopsis [Constructing ZDD of a graph.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Extra_GraphExperiment() +{ + int Edges[5][5] = { + {1, 3, 4}, + {1, 5}, + {2, 3, 5}, + {2, 4} + }; + int e, n; + + DdManager * dd = Cudd_Init( 0, 6, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); + + // create the edges + DdNode * zGraph, * zEdge, * zVar, * zTemp; + zGraph = DD_ZERO(dd); Cudd_Ref( zGraph ); + for ( e = 0; Edges[e][0]; e++ ) + { + zEdge = DD_ONE(dd); Cudd_Ref( zEdge ); + for ( n = 0; Edges[e][n]; n++ ) + { + zVar = cuddZddGetNode( dd, Edges[e][n], DD_ONE(dd), DD_ZERO(dd) ); Cudd_Ref( zVar ); + zEdge = Cudd_zddUnateProduct( dd, zTemp = zEdge, zVar ); Cudd_Ref( zEdge ); + Cudd_RecursiveDerefZdd( dd, zTemp ); + Cudd_RecursiveDerefZdd( dd, zVar ); + } + zGraph = Cudd_zddUnion( dd, zTemp = zGraph, zEdge ); Cudd_Ref( zGraph ); + Cudd_RecursiveDerefZdd( dd, zTemp ); + Cudd_RecursiveDerefZdd( dd, zEdge ); + } + + Cudd_zddPrintMinterm( dd, zGraph ); + + Cudd_RecursiveDerefZdd( dd, zGraph ); + Cudd_Quit(dd); +} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// From 632ca7ed11be3bd57ac1a730a9775658c17d9b53 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 16 Feb 2017 13:37:46 -0800 Subject: [PATCH 149/185] Promising alternative of CEX minimization in 'pdr'. --- src/base/abci/abc.c | 8 +++- src/proof/pdr/pdr.h | 1 + src/proof/pdr/pdrCore.c | 6 ++- src/proof/pdr/pdrMan.c | 87 +++++++++++++++++++++++------------------ 4 files changed, 61 insertions(+), 41 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 44e4bc166..52684f8cf 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26171,7 +26171,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Pdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDQTHGSaxrmuyfsipdegjonctvwzh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDQTHGSaxrmuyfsipdegjonctkvwzh" ) ) != EOF ) { switch ( c ) { @@ -26328,6 +26328,9 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) case 't': pPars->fUseAbs ^= 1; break; + case 'k': + pPars->fUseSimpleRef ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; @@ -26369,7 +26372,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: pdr [-MFCDQTHGS ] [-axrmuyfsipdegjonctvwzh]\n" ); + Abc_Print( -2, "usage: pdr [-MFCDQTHGS ] [-axrmuyfsipdegjonctkvwzh]\n" ); Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); @@ -26400,6 +26403,7 @@ usage: Abc_Print( -2, "\t-n : * toggle skipping \'down\' in generalization [default = %s]\n", pPars->fSkipDown? "yes": "no" ); Abc_Print( -2, "\t-c : * toggle handling CTGs in \'down\' [default = %s]\n", pPars->fCtgs? "yes": "no" ); Abc_Print( -2, "\t-t : toggle using abstraction [default = %s]\n", pPars->fUseAbs? "yes": "no" ); + Abc_Print( -2, "\t-k : toggle using simplified refinement [default = %s]\n", pPars->fUseSimpleRef? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-w : toggle printing detailed stats default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); Abc_Print( -2, "\t-z : toggle suppressing report about solved outputs [default = %s]\n", pPars->fNotVerbose? "yes": "no" ); diff --git a/src/proof/pdr/pdr.h b/src/proof/pdr/pdr.h index 534e8e4b8..51b046063 100644 --- a/src/proof/pdr/pdr.h +++ b/src/proof/pdr/pdr.h @@ -65,6 +65,7 @@ struct Pdr_Par_t_ int fSkipDown; // skips the application of down int fCtgs; // handle CTGs in down int fUseAbs; // use abstraction + int fUseSimpleRef; // simplified CEX refinement int fVerbose; // verbose output` int fVeryVerbose; // very verbose output int fNotVerbose; // not printing line by line progress diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index 40e86727e..efb4154f1 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -60,8 +60,6 @@ void Pdr_ManSetDefaultParams( Pdr_Par_t * pPars ) pPars->nRestLimit = 0; // limit on the number of proof-obligations pPars->nRandomSeed = 91648253; // value to seed the SAT solver with pPars->fTwoRounds = 0; // use two rounds for generalization - pPars->fSkipDown = 1; // apply down in generalization - pPars->fCtgs = 0; // handle CTGs in down pPars->fMonoCnf = 0; // monolythic CNF pPars->fNewXSim = 0; // updated X-valued simulation pPars->fFlopPrio = 0; // use structural flop priorities @@ -70,6 +68,10 @@ void Pdr_ManSetDefaultParams( Pdr_Par_t * pPars ) pPars->fUseSupp = 1; // using support variables in the invariant pPars->fShortest = 0; // forces bug traces to be shortest pPars->fUsePropOut = 1; // use property output + pPars->fSkipDown = 1; // apply down in generalization + pPars->fCtgs = 0; // handle CTGs in down + pPars->fUseAbs = 0; // use abstraction + pPars->fUseSimpleRef = 0; // simplified CEX refinement pPars->fVerbose = 0; // verbose output pPars->fVeryVerbose = 0; // very verbose output pPars->fNotVerbose = 0; // not printing line-by-line progress diff --git a/src/proof/pdr/pdrMan.c b/src/proof/pdr/pdrMan.c index abe8c0a8d..a076223b3 100644 --- a/src/proof/pdr/pdrMan.c +++ b/src/proof/pdr/pdrMan.c @@ -482,45 +482,58 @@ Abc_Cex_t * Pdr_ManDeriveCexAbs( Pdr_Man_t * p ) } if ( Vec_IntSize(p->vMapPpi2Ff) == 0 ) // no PPIs -- this is a real CEX return Pdr_ManDeriveCex(p); - // create the counter-example - pCex = Abc_CexAlloc( Aig_ManRegNum(p->pAig) - Vec_IntSize(p->vMapPpi2Ff), Saig_ManPiNum(p->pAig) + Vec_IntSize(p->vMapPpi2Ff), nFrames ); - pCex->iPo = p->iOutCur; - pCex->iFrame = nFrames-1; - for ( pObl = p->pQueue, f = 0; pObl; pObl = pObl->pNext, f++ ) - for ( i = pObl->pState->nLits; i < pObl->pState->nTotal; i++ ) - { - Lit = pObl->pState->Lits[i]; - if ( lit_sign(Lit) ) - continue; - if ( lit_var(Lit) < nPis ) // PI literal - Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + lit_var(Lit) ); - else - { - int iPPI = nPis + Vec_IntEntry(p->vMapFf2Ppi, lit_var(Lit) - nPis); - assert( iPPI < pCex->nPis ); - Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + iPPI ); - } - } - assert( f == nFrames ); - // perform CEX minimization - pAbs = Gia_ManDupAbs( p->pGia, p->vMapPpi2Ff, p->vMapFf2Ppi ); - pCexCare = Bmc_CexCareMinimizeAig( pAbs, nPis, pCex, 1, 0, 0 ); - Gia_ManStop( pAbs ); - assert( pCexCare->nPis == pCex->nPis ); - Abc_CexFree( pCex ); - // detect care PPIs - for ( f = 0; f < nFrames; f++ ) + if ( p->pPars->fUseSimpleRef ) { - for ( i = nPis; i < pCexCare->nPis; i++ ) - if ( Abc_InfoHasBit(pCexCare->pData, pCexCare->nRegs + pCexCare->nPis * f + i) ) - { - if ( Vec_IntEntry(p->vAbsFlops, Vec_IntEntry(p->vMapPpi2Ff, i-nPis)) == 0 ) // currently abstracted - Vec_IntWriteEntry( p->vAbsFlops, Vec_IntEntry(p->vMapPpi2Ff, i-nPis), 1 ), nFfRefined++; - } + // rely on ternary simulation to perform refinement + Vec_IntForEachEntry( p->vMapPpi2Ff, Flop, i ) + { + assert( Vec_IntEntry(p->vAbsFlops, Flop) == 0 ); + Vec_IntWriteEntry( p->vAbsFlops, Flop, 1 ); + nFfRefined++; + } + } + else + { + // create the counter-example + pCex = Abc_CexAlloc( Aig_ManRegNum(p->pAig) - Vec_IntSize(p->vMapPpi2Ff), Saig_ManPiNum(p->pAig) + Vec_IntSize(p->vMapPpi2Ff), nFrames ); + pCex->iPo = p->iOutCur; + pCex->iFrame = nFrames-1; + for ( pObl = p->pQueue, f = 0; pObl; pObl = pObl->pNext, f++ ) + for ( i = pObl->pState->nLits; i < pObl->pState->nTotal; i++ ) + { + Lit = pObl->pState->Lits[i]; + if ( lit_sign(Lit) ) + continue; + if ( lit_var(Lit) < nPis ) // PI literal + Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + lit_var(Lit) ); + else + { + int iPPI = nPis + Vec_IntEntry(p->vMapFf2Ppi, lit_var(Lit) - nPis); + assert( iPPI < pCex->nPis ); + Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + iPPI ); + } + } + assert( f == nFrames ); + // perform CEX minimization + pAbs = Gia_ManDupAbs( p->pGia, p->vMapPpi2Ff, p->vMapFf2Ppi ); + pCexCare = Bmc_CexCareMinimizeAig( pAbs, nPis, pCex, 1, 0, 0 ); + Gia_ManStop( pAbs ); + assert( pCexCare->nPis == pCex->nPis ); + Abc_CexFree( pCex ); + // detect care PPIs + for ( f = 0; f < nFrames; f++ ) + { + for ( i = nPis; i < pCexCare->nPis; i++ ) + if ( Abc_InfoHasBit(pCexCare->pData, pCexCare->nRegs + pCexCare->nPis * f + i) ) + { + if ( Vec_IntEntry(p->vAbsFlops, Vec_IntEntry(p->vMapPpi2Ff, i-nPis)) == 0 ) // currently abstracted + Vec_IntWriteEntry( p->vAbsFlops, Vec_IntEntry(p->vMapPpi2Ff, i-nPis), 1 ), nFfRefined++; + } + } + Abc_CexFree( pCexCare ); + if ( nFfRefined == 0 ) // no refinement -- this is a real CEX + return Pdr_ManDeriveCex(p); } - Abc_CexFree( pCexCare ); - if ( nFfRefined == 0 ) // no refinement -- this is a real CEX - return Pdr_ManDeriveCex(p); //printf( "CEX-based refinement refined %d flops.\n", nFfRefined ); p->nCexesTotal++; p->nCexes++; From 6d6bf8740d246b1478b636a1d300ede371bffabe Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 16 Feb 2017 13:57:36 -0800 Subject: [PATCH 150/185] Fixing missing sat_solver APIs in 'iprove'. --- src/sat/bsat/satSolver.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/sat/bsat/satSolver.c b/src/sat/bsat/satSolver.c index f753e0a54..df9ada8eb 100644 --- a/src/sat/bsat/satSolver.c +++ b/src/sat/bsat/satSolver.c @@ -328,11 +328,11 @@ static inline void act_var_bump(sat_solver* s, int v) } static inline void act_var_bump_global(sat_solver* s, int v) { - if ( !s->pGlobalVars ) + if ( !s->pGlobalVars || !s->pGlobalVars[v] ) return; if ( s->VarActType == 0 ) { - s->activity[v] += (int)((unsigned)s->var_inc * 3 * s->pGlobalVars[v]); + s->activity[v] += (int)((unsigned)s->var_inc * 3); if (s->activity[v] & 0x80000000) act_var_rescale(s); if (s->orderpos[v] != -1) @@ -340,8 +340,17 @@ static inline void act_var_bump_global(sat_solver* s, int v) } else if ( s->VarActType == 1 ) { - s->activity[v] += (unsigned)(Abc_Word2Dbl(s->var_inc) * 3.0 * s->pGlobalVars[v]); - if (Abc_Word2Dbl(s->activity[v]) > 1e100) + double act = Abc_Word2Dbl(s->activity[v]) + Abc_Word2Dbl(s->var_inc) * 3.0; + s->activity[v] = Abc_Dbl2Word(act); + if ( act > 1e100) + act_var_rescale(s); + if (s->orderpos[v] != -1) + order_update(s,v); + } + else if ( s->VarActType == 2 ) + { + s->activity[v] = Xdbl_Add( s->activity[v], Xdbl_Mul(s->var_inc, Xdbl_FromDouble(3.0)) ); + if (s->activity[v] > ABC_CONST(0x014c924d692ca61b)) act_var_rescale(s); if (s->orderpos[v] != -1) order_update(s,v); @@ -362,8 +371,17 @@ static inline void act_var_bump_factor(sat_solver* s, int v) } else if ( s->VarActType == 1 ) { - s->activity[v] += (unsigned)(Abc_Word2Dbl(s->var_inc) * s->factors[v]); - if (Abc_Word2Dbl(s->activity[v]) > 1e100) + double act = Abc_Word2Dbl(s->activity[v]) + Abc_Word2Dbl(s->var_inc) * s->factors[v]; + s->activity[v] = Abc_Dbl2Word(act); + if ( act > 1e100) + act_var_rescale(s); + if (s->orderpos[v] != -1) + order_update(s,v); + } + else if ( s->VarActType == 2 ) + { + s->activity[v] = Xdbl_Add( s->activity[v], Xdbl_Mul(s->var_inc, Xdbl_FromDouble(s->factors[v])) ); + if (s->activity[v] > ABC_CONST(0x014c924d692ca61b)) act_var_rescale(s); if (s->orderpos[v] != -1) order_update(s,v); From 378af9d94fc32232f638c784fb9cb9095f410bee Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 17 Feb 2017 14:09:58 -0800 Subject: [PATCH 151/185] Experiment with graph constuction using ZDDs. --- src/bdd/extrab/extraBddMisc.c | 203 ++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) diff --git a/src/bdd/extrab/extraBddMisc.c b/src/bdd/extrab/extraBddMisc.c index 44170102e..bc4d8a7ac 100644 --- a/src/bdd/extrab/extraBddMisc.c +++ b/src/bdd/extrab/extraBddMisc.c @@ -2379,6 +2379,209 @@ void Extra_GraphExperiment() Cudd_RecursiveDerefZdd( dd, zGraph ); Cudd_Quit(dd); } + + + + +/**Function******************************************************************** + + Synopsis [Performs the reordering-sensitive step of Extra_zddCombination().] + + Description [Generates in a bottom-up fashion ZDD for one combination + whose var values are given in the array VarValues. If necessary, + creates new variables on the fly.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +DdNode * extraZddCombination( + DdManager* dd, + int* VarValues, + int nVars ) +{ + int lev, index; + DdNode *zRes, *zTemp; + + /* transform the combination from the array VarValues into a ZDD cube. */ + zRes = dd->one; + cuddRef(zRes); + + /* go through levels starting bottom-up and create nodes + * if these variables are present in the comb + */ + for (lev = nVars - 1; lev >= 0; lev--) + { + index = (lev >= dd->sizeZ) ? lev : dd->invpermZ[lev]; + if (VarValues[index] == 1) + { + /* compose zRes with ZERO for the given ZDD variable */ + zRes = cuddZddGetNode( dd, index, zTemp = zRes, dd->zero ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zTemp ); + return NULL; + } + cuddRef( zRes ); + cuddDeref( zTemp ); + } + } + cuddDeref( zRes ); + return zRes; + +} /* end of extraZddCombination */ + +/**Function******************************************************************** + + Synopsis [Creates ZDD of the combination containing given variables.] + + Description [Creates ZDD of the combination containing given variables. + VarValues contains 1 for a variable that belongs to the + combination and 0 for a varible that does not belong. + nVars is number of ZDD variables in the array.] + + SideEffects [New ZDD variables are created if indices of the variables + present in the combination are larger than the currently + allocated number of ZDD variables.] + + SeeAlso [] + +******************************************************************************/ +DdNode * Extra_zddCombination( + DdManager *dd, + int* VarValues, + int nVars ) +{ + DdNode *res; + do { + dd->reordered = 0; + res = extraZddCombination(dd, VarValues, nVars); + } while (dd->reordered == 1); + return(res); + +} /* end of Extra_zddCombination */ + +/**Function******************************************************************** + + Synopsis [Generates a random set of combinations.] + + Description [Given a set of n elements, each of which is encoded using one + ZDD variable, this function generates a random set of k subsets + (combinations of elements) with density d. Assumes that k and n + are positive integers. Returns NULL if density is less than 0.0 + or more than 1.0.] + + SideEffects [Allocates new ZDD variables if their current number is less than n.] + + SeeAlso [] + +******************************************************************************/ +DdNode* Extra_zddRandomSet( + DdManager * dd, /* the DD manager */ + int n, /* the number of elements */ + int k, /* the number of combinations (subsets) */ + double d) /* average density of elements in combinations */ +{ + DdNode *Result, *TempComb, *Aux; + int c, v, Limit, *VarValues; + + /* sanity check the parameters */ + if ( n <= 0 || k <= 0 || d < 0.0 || d > 1.0 ) + return NULL; + + /* allocate temporary storage for variable values */ + VarValues = ABC_ALLOC( int, n ); + if (VarValues == NULL) + { + dd->errorCode = CUDD_MEMORY_OUT; + return NULL; + } + + /* start the new set */ + Result = dd->zero; + Cudd_Ref( Result ); + + /* seed random number generator */ + Cudd_Srandom( time(NULL) ); +// Cudd_Srandom( 4 ); + /* determine the limit below which var belongs to the combination */ + Limit = (int)(d * 2147483561.0); + + /* add combinations one by one */ + for ( c = 0; c < k; c++ ) + { + for ( v = 0; v < n; v++ ) + if ( Cudd_Random() <= Limit ) + VarValues[v] = 1; + else + VarValues[v] = 0; + + TempComb = Extra_zddCombination( dd, VarValues, n ); + Cudd_Ref( TempComb ); + + /* make sure that this combination is not already in the set */ + if ( c ) + { /* at least one combination is already included */ + + Aux = Cudd_zddDiff( dd, Result, TempComb ); + Cudd_Ref( Aux ); + if ( Aux != Result ) + { + Cudd_RecursiveDerefZdd( dd, Aux ); + Cudd_RecursiveDerefZdd( dd, TempComb ); + c--; + continue; + } + else + { /* Aux is the same node as Result */ + Cudd_Deref( Aux ); + } + } + + Result = Cudd_zddUnion( dd, Aux = Result, TempComb ); + Cudd_Ref( Result ); + Cudd_RecursiveDerefZdd( dd, Aux ); + Cudd_RecursiveDerefZdd( dd, TempComb ); + } + + ABC_FREE( VarValues ); + Cudd_Deref( Result ); + return Result; + +} /* end of Extra_zddRandomSet */ + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void Extra_ZddTest() +{ + int N = 64; + int K0 = 1000; + int i, Size; + DdManager * dd = Cudd_Init( 0, 32, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); + for ( i = 1; i <= 10; i++ ) + { + int K = K0 * i; + DdNode * zRandSet = Extra_zddRandomSet( dd, N, K, 0.5 ); Cudd_Ref(zRandSet); + Size = Cudd_zddDagSize(zRandSet); + //Cudd_zddPrintMinterm( dd, zRandSet ); + printf( "N = %5d K = %5d BddSize = %6d MemBdd = %8.3f MB MemBit = %8.3f MB Ratio = %8.3f %%\n", + N, K, Size, 20.0*Size/(1<<20), 0.125 * N * K /(1<<20), 100.0*(0.125 * N * K)/(20.0*Size) ); + Cudd_RecursiveDerefZdd( dd, zRandSet ); + } + Cudd_Quit(dd); +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// From bc010af4be920199d7f1e0bfe4a6d70dcbca042b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 17 Feb 2017 14:10:32 -0800 Subject: [PATCH 152/185] Promising modification of the generalization procedure in 'pdr'. --- src/proof/pdr/pdrCore.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index efb4154f1..501f9be67 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -637,6 +637,16 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP Pdr_SetDeref( pCubeTmp ); assert( pCubeMin->nLits > 0 ); + // assume the minimized cube + if ( p->pPars->fSimpleGeneral ) + { + sat_solver * pSat = Pdr_ManFetchSolver( p, k ); + Vec_Int_t * vLits1 = Pdr_ManCubeToLits( p, k, pCubeMin, 1, 0 ); + int RetValue1 = sat_solver_addclause( pSat, Vec_IntArray(vLits1), Vec_IntArray(vLits1) + Vec_IntSize(vLits1) ); + assert( RetValue1 == 1 ); + sat_solver_compress( pSat ); + } + // get the ordering by decreasing priority pOrder = Pdr_ManSortByPriority( p, pCubeMin ); j--; From 1d3ff5338a0c98f2319578b25f9695c3a326dd9d Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Fri, 17 Feb 2017 18:55:00 -0800 Subject: [PATCH 153/185] added ipdr --- src/base/abci/abc.c | 268 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 268 insertions(+) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 52684f8cf..af79a66d4 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -333,6 +333,7 @@ static int Abc_CommandBm2 ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandSaucy ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTestCex ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPdr ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandIPdr ( Abc_Frame_t * pAbc, int argc, char ** argv ); #ifdef ABC_USE_CUDD static int Abc_CommandReconcile ( Abc_Frame_t * pAbc, int argc, char ** argv ); #endif @@ -983,6 +984,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Verification", "saucy3", Abc_CommandSaucy, 1 ); Cmd_CommandAdd( pAbc, "Verification", "testcex", Abc_CommandTestCex, 0 ); Cmd_CommandAdd( pAbc, "Verification", "pdr", Abc_CommandPdr, 0 ); + Cmd_CommandAdd( pAbc, "Verification", "ipdr", Abc_CommandIPdr, 0 ); #ifdef ABC_USE_CUDD Cmd_CommandAdd( pAbc, "Verification", "reconcile", Abc_CommandReconcile, 1 ); #endif @@ -26415,6 +26417,272 @@ usage: + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandIPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern int Abc_NtkDarPdr( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ); + Pdr_Par_t Pars, * pPars = &Pars; + Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); + int c; + Pdr_ManSetDefaultParams( pPars ); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDQTHGSaxrmuyfsipdegjonctkvwzh" ) ) != EOF ) + { + switch ( c ) + { + case 'M': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nRecycle = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nRecycle < 0 ) + goto usage; + break; + case 'F': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nFrameMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nFrameMax < 0 ) + goto usage; + break; + case 'C': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nConfLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nConfLimit < 0 ) + goto usage; + break; + case 'D': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-D\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nConfGenLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nConfGenLimit < 0 ) + goto usage; + break; + case 'Q': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-Q\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nRestLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nRestLimit < 0 ) + goto usage; + break; + case 'T': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nTimeOut = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nTimeOut < 0 ) + goto usage; + break; + case 'H': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-H\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nTimeOutOne = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nTimeOutOne < 0 ) + goto usage; + break; + case 'G': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-G\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nTimeOutGap = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nTimeOutGap < 0 ) + goto usage; + break; + case 'S': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nRandomSeed = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nRandomSeed < 0 ) + goto usage; + break; + case 'a': + pPars->fSolveAll ^= 1; + break; + case 'x': + pPars->fStoreCex ^= 1; + break; + case 'r': + pPars->fTwoRounds ^= 1; + break; + case 'm': + pPars->fMonoCnf ^= 1; + break; + case 'u': + pPars->fNewXSim ^= 1; + break; + case 'y': + pPars->fFlopPrio ^= 1; + break; + case 'f': + pPars->fFlopOrder ^= 1; + break; + case 's': + pPars->fShortest ^= 1; + break; + case 'i': + pPars->fShiftStart ^= 1; + break; + case 'p': + pPars->fReuseProofOblig ^= 1; + break; + case 'd': + pPars->fDumpInv ^= 1; + break; + case 'e': + pPars->fUseSupp ^= 1; + break; + case 'g': + pPars->fSkipGeneral ^= 1; + break; + case 'j': + pPars->fSimpleGeneral ^= 1; + break; + case 'o': + pPars->fUsePropOut ^= 1; + break; + case 'n': + pPars->fSkipDown ^= 1; + break; + case 'c': + pPars->fCtgs ^= 1; + break; + case 't': + pPars->fUseAbs ^= 1; + break; + case 'k': + pPars->fUseSimpleRef ^= 1; + break; + case 'v': + pPars->fVerbose ^= 1; + break; + case 'w': + pPars->fVeryVerbose ^= 1; + break; + case 'z': + pPars->fNotVerbose ^= 1; + break; + case 'h': + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( -2, "There is no current network.\n"); + return 0; + } + if ( Abc_NtkLatchNum(pNtk) == 0 ) + { + Abc_Print( 0, "The current network is combinational.\n"); + return 0; + } + if ( !Abc_NtkIsStrash(pNtk) ) + { + Abc_Print( -2, "The current network is not an AIG (run \"strash\").\n"); + return 0; + } + // run the procedure + pPars->fUseBridge = pAbc->fBridgeMode; + pAbc->Status = Abc_NtkDarPdr( pNtk, pPars ); + pAbc->nFrames = pNtk->vSeqModelVec ? -1 : pPars->iFrame; + Abc_FrameReplacePoStatuses( pAbc, &pPars->vOutMap ); + if ( pNtk->vSeqModelVec ) + Abc_FrameReplaceCexVec( pAbc, &pNtk->vSeqModelVec ); + else + Abc_FrameReplaceCex( pAbc, &pNtk->pSeqModel ); + return 0; + +usage: + Abc_Print( -2, "usage: ipdr [-MFCDQTHGS ] [-axrmuyfsipdegjonctkvwzh]\n" ); + Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); + Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); + Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); + Abc_Print( -2, "\t-M num : limit on unused vars to trigger SAT solver recycling [default = %d]\n", pPars->nRecycle ); + Abc_Print( -2, "\t-F num : limit on timeframes explored to stop computation [default = %d]\n", pPars->nFrameMax ); + Abc_Print( -2, "\t-C num : limit on conflicts in one SAT call (0 = no limit) [default = %d]\n", pPars->nConfLimit ); + Abc_Print( -2, "\t-D num : limit on conflicts during ind-generalization (0 = no limit) [default = %d]\n",pPars->nConfGenLimit ); + Abc_Print( -2, "\t-Q num : limit on proof obligations before a restart (0 = no limit) [default = %d]\n", pPars->nRestLimit ); + Abc_Print( -2, "\t-T num : runtime limit, in seconds (0 = no limit) [default = %d]\n", pPars->nTimeOut ); + Abc_Print( -2, "\t-H num : runtime limit per output, in miliseconds (with \"-a\") [default = %d]\n", pPars->nTimeOutOne ); + Abc_Print( -2, "\t-G num : runtime gap since the last CEX (0 = no limit) [default = %d]\n", pPars->nTimeOutGap ); + Abc_Print( -2, "\t-S num : * value to seed the SAT solver with [default = %d]\n", pPars->nRandomSeed ); + Abc_Print( -2, "\t-a : toggle solving all outputs even if one of them is SAT [default = %s]\n", pPars->fSolveAll? "yes": "no" ); + Abc_Print( -2, "\t-x : toggle storing CEXes when solving all outputs [default = %s]\n", pPars->fStoreCex? "yes": "no" ); + Abc_Print( -2, "\t-r : toggle using more effort in generalization [default = %s]\n", pPars->fTwoRounds? "yes": "no" ); + Abc_Print( -2, "\t-m : toggle using monolythic CNF computation [default = %s]\n", pPars->fMonoCnf? "yes": "no" ); + Abc_Print( -2, "\t-u : toggle updated X-valued simulation [default = %s]\n", pPars->fNewXSim? "yes": "no" ); + Abc_Print( -2, "\t-y : toggle using structural flop priorities [default = %s]\n", pPars->fFlopPrio? "yes": "no" ); + Abc_Print( -2, "\t-f : toggle ordering flops by cost before generalization [default = %s]\n", pPars->fFlopOrder? "yes": "no" ); + Abc_Print( -2, "\t-s : toggle creating only shortest counter-examples [default = %s]\n", pPars->fShortest? "yes": "no" ); + Abc_Print( -2, "\t-i : toggle clause pushing from an intermediate timeframe [default = %s]\n", pPars->fShiftStart? "yes": "no" ); + Abc_Print( -2, "\t-p : toggle reusing proof-obligations in the last timeframe [default = %s]\n", pPars->fReuseProofOblig? "yes": "no" ); + Abc_Print( -2, "\t-d : toggle dumping invariant (valid if init state is all-0) [default = %s]\n", pPars->fDumpInv? "yes": "no" ); + Abc_Print( -2, "\t-e : toggle using only support variables in the invariant [default = %s]\n", pPars->fUseSupp? "yes": "no" ); + Abc_Print( -2, "\t-g : toggle skipping expensive generalization step [default = %s]\n", pPars->fSkipGeneral? "yes": "no" ); + Abc_Print( -2, "\t-j : toggle using simplified generalization step [default = %s]\n", pPars->fSimpleGeneral? "yes": "no" ); + Abc_Print( -2, "\t-o : toggle using property output as inductive hypothesis [default = %s]\n", pPars->fUsePropOut? "yes": "no" ); + Abc_Print( -2, "\t-n : * toggle skipping \'down\' in generalization [default = %s]\n", pPars->fSkipDown? "yes": "no" ); + Abc_Print( -2, "\t-c : * toggle handling CTGs in \'down\' [default = %s]\n", pPars->fCtgs? "yes": "no" ); + Abc_Print( -2, "\t-t : toggle using abstraction [default = %s]\n", pPars->fUseAbs? "yes": "no" ); + Abc_Print( -2, "\t-k : toggle using simplified refinement [default = %s]\n", pPars->fUseSimpleRef? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-w : toggle printing detailed stats default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); + Abc_Print( -2, "\t-z : toggle suppressing report about solved outputs [default = %s]\n", pPars->fNotVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n\n"); + Abc_Print( -2, "\t* Implementation of switches -S, -n, and -c is contributed by Zyad Hassan.\n"); + Abc_Print( -2, "\t The theory and experiments supporting this work can be found in the following paper:\n"); + Abc_Print( -2, "\t Zyad Hassan, Aaron R. Bradley, Fabio Somenzi, \"Better Generalization in IC3\", FMCAD 2013.\n"); + Abc_Print( -2, "\t (http://www.cs.utexas.edu/users/hunt/FMCAD/FMCAD13/papers/85-Better-Generalization-IC3.pdf)\n"); + + + return 1; } From 16fda0bd24f1d1e4bb6b39cd0f1a545fd096d6c3 Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sat, 18 Feb 2017 09:10:45 -0800 Subject: [PATCH 154/185] added a simple example; edited hgignore --- .hgignore | 5 +++++ fsm.v | 28 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 fsm.v diff --git a/.hgignore b/.hgignore index b5fedc7a5..f5d4784c8 100644 --- a/.hgignore +++ b/.hgignore @@ -52,9 +52,14 @@ build/ *.rej *.orig +tags + syntax: regexp ^libabc.a$ ^abc$ ^arch_flags$ + +^cmake +^cscope diff --git a/fsm.v b/fsm.v new file mode 100644 index 000000000..272c4a898 --- /dev/null +++ b/fsm.v @@ -0,0 +1,28 @@ +module fsm (out); +output out; + +wire [2:0] ns; +wire [2:0] cs; + +always @( ns or cs ) +begin +case (cs) + 0 : ns = 3'b010; + 1 : ns = 3'b001; + 2 : ns = 3'b000; + 3 : ns = 3'b101; + 4 : ns = 3'b001; + 5 : ns = 3'b111; + 6 : ns = 3'b001; + 7 : ns = 3'b110; +endcase +end + +assign out = cs == 3'b001; + +wire [2:0] const0 = 3'h0; + + +CPL_FF#3 ff3 ( .q(cs), .qbar(), .d(ns), .clk(), .arst(), .arstval(const0) ); + +endmodule From 196b3591830e9fbe0877411b8053233c11d0f4ce Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sat, 18 Feb 2017 09:51:54 -0800 Subject: [PATCH 155/185] started pdrIncr.c --- src/base/abci/abc.c | 2 ++ src/proof/pdr/module.make | 3 ++- src/proof/pdr/pdrIncr.c | 56 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 src/proof/pdr/pdrIncr.c diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index af79a66d4..0e3a1d3ad 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26434,6 +26434,7 @@ usage: int Abc_CommandIPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern int Abc_NtkDarPdr( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ); + extern int IPdr_ManSolve( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ); Pdr_Par_t Pars, * pPars = &Pars; Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); int c; @@ -26629,6 +26630,7 @@ int Abc_CommandIPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; } // run the procedure + IPdr_ManSolve( pNtk, pPars ); pPars->fUseBridge = pAbc->fBridgeMode; pAbc->Status = Abc_NtkDarPdr( pNtk, pPars ); pAbc->nFrames = pNtk->vSeqModelVec ? -1 : pPars->iFrame; diff --git a/src/proof/pdr/module.make b/src/proof/pdr/module.make index 2967aeb83..4c177a21b 100644 --- a/src/proof/pdr/module.make +++ b/src/proof/pdr/module.make @@ -5,4 +5,5 @@ SRC += src/proof/pdr/pdrCnf.c \ src/proof/pdr/pdrSat.c \ src/proof/pdr/pdrTsim.c \ src/proof/pdr/pdrTsim2.c \ - src/proof/pdr/pdrUtil.c + src/proof/pdr/pdrUtil.c \ + src/proof/pdr/pdrIncr.c diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c new file mode 100644 index 000000000..a23298704 --- /dev/null +++ b/src/proof/pdr/pdrIncr.c @@ -0,0 +1,56 @@ +/**CFile**************************************************************** + + FileName [pdrIncr.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Property driven reachability.] + + Synopsis [PDR with incremental solving.] + + Author [Yen-Sheng Ho, Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - Feb. 17, 2017.] + + Revision [$Id: pdrIncr.c$] + +***********************************************************************/ + +#include "pdrInt.h" +#include "base/main/main.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int IPdr_ManSolve( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ) +{ + return 0; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END From 91a0a0fc3b5dfd5aa71122106dbdacf6268e51fb Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sat, 18 Feb 2017 10:28:16 -0800 Subject: [PATCH 156/185] copied pdr_mansolve --- src/base/abci/abc.c | 3 +-- src/proof/pdr/pdrIncr.c | 41 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 0e3a1d3ad..f12e37274 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26630,9 +26630,8 @@ int Abc_CommandIPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; } // run the procedure - IPdr_ManSolve( pNtk, pPars ); pPars->fUseBridge = pAbc->fBridgeMode; - pAbc->Status = Abc_NtkDarPdr( pNtk, pPars ); + pAbc->Status = IPdr_ManSolve( pNtk, pPars ); pAbc->nFrames = pNtk->vSeqModelVec ? -1 : pPars->iFrame; Abc_FrameReplacePoStatuses( pAbc, &pPars->vOutMap ); if ( pNtk->vSeqModelVec ) diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c index a23298704..2276384c5 100644 --- a/src/proof/pdr/pdrIncr.c +++ b/src/proof/pdr/pdrIncr.c @@ -27,6 +27,7 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -45,7 +46,45 @@ ABC_NAMESPACE_IMPL_START ***********************************************************************/ int IPdr_ManSolve( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ) { - return 0; + int RetValue = -1; + abctime clk = Abc_Clock(); + Aig_Man_t * pMan; + pMan = Abc_NtkToDar( pNtk, 0, 1 ); + + RetValue = Pdr_ManSolve( pMan, pPars ); + + if ( RetValue == 1 ) + Abc_Print( 1, "Property proved. " ); + else + { + if ( RetValue == 0 ) + { + if ( pMan->pSeqModel == NULL ) + Abc_Print( 1, "Counter-example is not available.\n" ); + else + { + Abc_Print( 1, "Output %d of miter \"%s\" was asserted in frame %d. ", pMan->pSeqModel->iPo, pNtk->pName, pMan->pSeqModel->iFrame ); + if ( !Saig_ManVerifyCex( pMan, pMan->pSeqModel ) ) + Abc_Print( 1, "Counter-example verification has FAILED.\n" ); + } + } + else if ( RetValue == -1 ) + Abc_Print( 1, "Property UNDECIDED. " ); + else + assert( 0 ); + } + ABC_PRT( "Time", Abc_Clock() - clk ); + + + ABC_FREE( pNtk->pSeqModel ); + pNtk->pSeqModel = pMan->pSeqModel; + pMan->pSeqModel = NULL; + if ( pNtk->vSeqModelVec ) + Vec_PtrFreeFree( pNtk->vSeqModelVec ); + pNtk->vSeqModelVec = pMan->vSeqModelVec; + pMan->vSeqModelVec = NULL; + Aig_ManStop( pMan ); + return RetValue; } //////////////////////////////////////////////////////////////////////// From b93a80512941e5039e48a7b74e625d7d6f9f720a Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sat, 18 Feb 2017 12:43:03 -0800 Subject: [PATCH 157/185] copied some functions from pdr --- src/base/abci/abc.c | 4 +- src/proof/pdr/pdrIncr.c | 429 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 429 insertions(+), 4 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index f12e37274..0645c6e38 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26434,7 +26434,7 @@ usage: int Abc_CommandIPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern int Abc_NtkDarPdr( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ); - extern int IPdr_ManSolve( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ); + extern int Abc_NtkDarIPdr( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ); Pdr_Par_t Pars, * pPars = &Pars; Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); int c; @@ -26631,7 +26631,7 @@ int Abc_CommandIPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) } // run the procedure pPars->fUseBridge = pAbc->fBridgeMode; - pAbc->Status = IPdr_ManSolve( pNtk, pPars ); + pAbc->Status = Abc_NtkDarIPdr( pNtk, pPars ); pAbc->nFrames = pNtk->vSeqModelVec ? -1 : pPars->iFrame; Abc_FrameReplacePoStatuses( pAbc, &pPars->vOutMap ); if ( pNtk->vSeqModelVec ) diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c index 2276384c5..d33b45ac3 100644 --- a/src/proof/pdr/pdrIncr.c +++ b/src/proof/pdr/pdrIncr.c @@ -28,6 +28,11 @@ ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters ); +extern int Pdr_ManBlockCube( Pdr_Man_t * p, Pdr_Set_t * pCube ); +extern int Pdr_ManPushClauses( Pdr_Man_t * p ); +extern int Gia_ManToBridgeAbort( FILE * pFile, int Size, unsigned char * pBuffer ); +extern int Gia_ManToBridgeResult( FILE * pFile, int Result, Abc_Cex_t * pCex, int iPoProved ); + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -44,14 +49,434 @@ extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters ); SeeAlso [] ***********************************************************************/ -int IPdr_ManSolve( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ) +int IPdr_ManSolveInt( Pdr_Man_t * p ) +{ + int fPrintClauses = 0; + Pdr_Set_t * pCube = NULL; + Aig_Obj_t * pObj; + Abc_Cex_t * pCexNew; + int iFrame, RetValue = -1; + int nOutDigits = Abc_Base10Log( Saig_ManPoNum(p->pAig) ); + abctime clkStart = Abc_Clock(), clkOne = 0; + p->timeToStop = p->pPars->nTimeOut ? p->pPars->nTimeOut * CLOCKS_PER_SEC + Abc_Clock(): 0; + assert( Vec_PtrSize(p->vSolvers) == 0 ); + // in the multi-output mode, mark trivial POs (those fed by const0) as solved + if ( p->pPars->fSolveAll ) + Saig_ManForEachPo( p->pAig, pObj, iFrame ) + if ( Aig_ObjChild0(pObj) == Aig_ManConst0(p->pAig) ) + { + Vec_IntWriteEntry( p->pPars->vOutMap, iFrame, 1 ); // unsat + p->pPars->nProveOuts++; + if ( p->pPars->fUseBridge ) + Gia_ManToBridgeResult( stdout, 1, NULL, iFrame ); + } + // create the first timeframe + p->pPars->timeLastSolved = Abc_Clock(); + Pdr_ManCreateSolver( p, (iFrame = 0) ); + while ( 1 ) + { + int fRefined = 0; + if ( p->pPars->fUseAbs && p->vAbsFlops == NULL && iFrame == 1 ) + { +// int i, Prio; + assert( p->vAbsFlops == NULL ); + p->vAbsFlops = Vec_IntStart( Saig_ManRegNum(p->pAig) ); + p->vMapFf2Ppi = Vec_IntStartFull( Saig_ManRegNum(p->pAig) ); + p->vMapPpi2Ff = Vec_IntAlloc( 100 ); +// Vec_IntForEachEntry( p->vPrio, Prio, i ) +// if ( Prio >> p->nPrioShift ) +// Vec_IntWriteEntry( p->vAbsFlops, i, 1 ); + } + //if ( p->pPars->fUseAbs && p->vAbsFlops ) + // printf( "Starting frame %d with %d (%d) flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops), Vec_IntCountPositive(p->vPrio) ); + p->nFrames = iFrame; + assert( iFrame == Vec_PtrSize(p->vSolvers)-1 ); + p->iUseFrame = Abc_MaxInt(iFrame, 1); + Saig_ManForEachPo( p->pAig, pObj, p->iOutCur ) + { + // skip disproved outputs + if ( p->vCexes && Vec_PtrEntry(p->vCexes, p->iOutCur) ) + continue; + // skip output whose time has run out + if ( p->pTime4Outs && p->pTime4Outs[p->iOutCur] == 0 ) + continue; + // check if the output is trivially solved + if ( Aig_ObjChild0(pObj) == Aig_ManConst0(p->pAig) ) + continue; + // check if the output is trivially solved + if ( Aig_ObjChild0(pObj) == Aig_ManConst1(p->pAig) ) + { + if ( !p->pPars->fSolveAll ) + { + pCexNew = Abc_CexMakeTriv( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), iFrame*Saig_ManPoNum(p->pAig)+p->iOutCur ); + p->pAig->pSeqModel = pCexNew; + return 0; // SAT + } + pCexNew = (p->pPars->fUseBridge || p->pPars->fStoreCex) ? Abc_CexMakeTriv( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), iFrame*Saig_ManPoNum(p->pAig)+p->iOutCur ) : (Abc_Cex_t *)(ABC_PTRINT_T)1; + p->pPars->nFailOuts++; + if ( p->pPars->vOutMap ) Vec_IntWriteEntry( p->pPars->vOutMap, p->iOutCur, 0 ); + if ( !p->pPars->fNotVerbose ) + Abc_Print( 1, "Output %*d was trivially asserted in frame %2d (solved %*d out of %*d outputs).\n", + nOutDigits, p->iOutCur, iFrame, nOutDigits, p->pPars->nFailOuts, nOutDigits, Saig_ManPoNum(p->pAig) ); + assert( Vec_PtrEntry(p->vCexes, p->iOutCur) == NULL ); + if ( p->pPars->fUseBridge ) + Gia_ManToBridgeResult( stdout, 0, pCexNew, pCexNew->iPo ); + Vec_PtrWriteEntry( p->vCexes, p->iOutCur, pCexNew ); + if ( p->pPars->pFuncOnFail && p->pPars->pFuncOnFail(p->iOutCur, p->pPars->fStoreCex ? (Abc_Cex_t *)Vec_PtrEntry(p->vCexes, p->iOutCur) : NULL) ) + { + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + if ( !p->pPars->fSilent ) + Abc_Print( 1, "Quitting due to callback on fail in frame %d.\n", iFrame ); + p->pPars->iFrame = iFrame; + return -1; + } + if ( p->pPars->nFailOuts + p->pPars->nDropOuts == Saig_ManPoNum(p->pAig) ) + return p->pPars->nFailOuts ? 0 : -1; // SAT or UNDEC + p->pPars->timeLastSolved = Abc_Clock(); + continue; + } + // try to solve this output + if ( p->pTime4Outs ) + { + assert( p->pTime4Outs[p->iOutCur] > 0 ); + clkOne = Abc_Clock(); + p->timeToStopOne = p->pTime4Outs[p->iOutCur] + Abc_Clock(); + } + while ( 1 ) + { + if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC ) + { + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + if ( !p->pPars->fSilent ) + Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame ); + p->pPars->iFrame = iFrame; + return -1; + } + RetValue = Pdr_ManCheckCube( p, iFrame, NULL, &pCube, p->pPars->nConfLimit, 0, 1 ); + if ( RetValue == 1 ) + break; + if ( RetValue == -1 ) + { + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + if ( p->timeToStop && Abc_Clock() > p->timeToStop ) + Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame ); + else if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC ) + Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame ); + else if ( p->timeToStopOne && Abc_Clock() > p->timeToStopOne ) + { + Pdr_QueueClean( p ); + pCube = NULL; + break; // keep solving + } + else if ( p->pPars->nConfLimit ) + Abc_Print( 1, "Reached conflict limit (%d) in frame %d.\n", p->pPars->nConfLimit, iFrame ); + else if ( p->pPars->fVerbose ) + Abc_Print( 1, "Computation cancelled by the callback in frame %d.\n", iFrame ); + p->pPars->iFrame = iFrame; + return -1; + } + if ( RetValue == 0 ) + { + RetValue = Pdr_ManBlockCube( p, pCube ); + if ( RetValue == -1 ) + { + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + if ( p->timeToStop && Abc_Clock() > p->timeToStop ) + Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame ); + else if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC ) + Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame ); + else if ( p->timeToStopOne && Abc_Clock() > p->timeToStopOne ) + { + Pdr_QueueClean( p ); + pCube = NULL; + break; // keep solving + } + else if ( p->pPars->nConfLimit ) + Abc_Print( 1, "Reached conflict limit (%d) in frame %d.\n", p->pPars->nConfLimit, iFrame ); + else if ( p->pPars->fVerbose ) + Abc_Print( 1, "Computation cancelled by the callback in frame %d.\n", iFrame ); + p->pPars->iFrame = iFrame; + return -1; + } + if ( RetValue == 0 ) + { + if ( fPrintClauses ) + { + Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame ); + Pdr_ManPrintClauses( p, 0 ); + } + if ( p->pPars->fVerbose && !p->pPars->fUseAbs ) + Pdr_ManPrintProgress( p, !p->pPars->fSolveAll, Abc_Clock() - clkStart ); + p->pPars->iFrame = iFrame; + if ( !p->pPars->fSolveAll ) + { + abctime clk = Abc_Clock(); + Abc_Cex_t * pCex = Pdr_ManDeriveCexAbs(p); + p->tAbs += Abc_Clock() - clk; + if ( pCex == NULL ) + { + assert( p->pPars->fUseAbs ); + Pdr_QueueClean( p ); + pCube = NULL; + fRefined = 1; + break; // keep solving + } + p->pAig->pSeqModel = pCex; + return 0; // SAT + } + p->pPars->nFailOuts++; + pCexNew = (p->pPars->fUseBridge || p->pPars->fStoreCex) ? Pdr_ManDeriveCex(p) : (Abc_Cex_t *)(ABC_PTRINT_T)1; + if ( p->pPars->vOutMap ) Vec_IntWriteEntry( p->pPars->vOutMap, p->iOutCur, 0 ); + assert( Vec_PtrEntry(p->vCexes, p->iOutCur) == NULL ); + if ( p->pPars->fUseBridge ) + Gia_ManToBridgeResult( stdout, 0, pCexNew, pCexNew->iPo ); + Vec_PtrWriteEntry( p->vCexes, p->iOutCur, pCexNew ); + if ( p->pPars->pFuncOnFail && p->pPars->pFuncOnFail(p->iOutCur, p->pPars->fStoreCex ? (Abc_Cex_t *)Vec_PtrEntry(p->vCexes, p->iOutCur) : NULL) ) + { + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + if ( !p->pPars->fSilent ) + Abc_Print( 1, "Quitting due to callback on fail in frame %d.\n", iFrame ); + p->pPars->iFrame = iFrame; + return -1; + } + if ( !p->pPars->fNotVerbose ) + Abc_Print( 1, "Output %*d was asserted in frame %2d (%2d) (solved %*d out of %*d outputs).\n", + nOutDigits, p->iOutCur, iFrame, iFrame, nOutDigits, p->pPars->nFailOuts, nOutDigits, Saig_ManPoNum(p->pAig) ); + if ( p->pPars->nFailOuts == Saig_ManPoNum(p->pAig) ) + return 0; // all SAT + Pdr_QueueClean( p ); + pCube = NULL; + break; // keep solving + } + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, 0, Abc_Clock() - clkStart ); + } + } + if ( fRefined ) + break; + if ( p->pTime4Outs ) + { + abctime timeSince = Abc_Clock() - clkOne; + assert( p->pTime4Outs[p->iOutCur] > 0 ); + p->pTime4Outs[p->iOutCur] = (p->pTime4Outs[p->iOutCur] > timeSince) ? p->pTime4Outs[p->iOutCur] - timeSince : 0; + if ( p->pTime4Outs[p->iOutCur] == 0 && Vec_PtrEntry(p->vCexes, p->iOutCur) == NULL ) // undecided + { + p->pPars->nDropOuts++; + if ( p->pPars->vOutMap ) + Vec_IntWriteEntry( p->pPars->vOutMap, p->iOutCur, -1 ); + if ( !p->pPars->fNotVerbose ) + Abc_Print( 1, "Timing out on output %*d in frame %d.\n", nOutDigits, p->iOutCur, iFrame ); + } + p->timeToStopOne = 0; + } + } + if ( p->pPars->fUseAbs && p->vAbsFlops && !fRefined ) + { + int i, Used; + Vec_IntForEachEntry( p->vAbsFlops, Used, i ) + if ( Used && (Vec_IntEntry(p->vPrio, i) >> p->nPrioShift) == 0 ) + Vec_IntWriteEntry( p->vAbsFlops, i, 0 ); + } + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, !fRefined, Abc_Clock() - clkStart ); + if ( fRefined ) + continue; + //if ( p->pPars->fUseAbs && p->vAbsFlops ) + // printf( "Finished frame %d with %d (%d) flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops), Vec_IntCountPositive(p->vPrio) ); + // open a new timeframe + p->nQueLim = p->pPars->nRestLimit; + assert( pCube == NULL ); + Pdr_ManSetPropertyOutput( p, iFrame ); + Pdr_ManCreateSolver( p, ++iFrame ); + if ( fPrintClauses ) + { + Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame ); + Pdr_ManPrintClauses( p, 0 ); + } + // push clauses into this timeframe + RetValue = Pdr_ManPushClauses( p ); + if ( RetValue == -1 ) + { + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + if ( !p->pPars->fSilent ) + { + if ( p->timeToStop && Abc_Clock() > p->timeToStop ) + Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame ); + else + Abc_Print( 1, "Reached conflict limit (%d) in frame.\n", p->pPars->nConfLimit, iFrame ); + } + p->pPars->iFrame = iFrame; + return -1; + } + if ( RetValue ) + { + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + if ( !p->pPars->fSilent ) + Pdr_ManReportInvariant( p ); + if ( !p->pPars->fSilent ) + Pdr_ManVerifyInvariant( p ); + p->pPars->iFrame = iFrame; + // count the number of UNSAT outputs + p->pPars->nProveOuts = Saig_ManPoNum(p->pAig) - p->pPars->nFailOuts - p->pPars->nDropOuts; + // convert previously 'unknown' into 'unsat' + if ( p->pPars->vOutMap ) + for ( iFrame = 0; iFrame < Saig_ManPoNum(p->pAig); iFrame++ ) + if ( Vec_IntEntry(p->pPars->vOutMap, iFrame) == -2 ) // unknown + { + Vec_IntWriteEntry( p->pPars->vOutMap, iFrame, 1 ); // unsat + if ( p->pPars->fUseBridge ) + Gia_ManToBridgeResult( stdout, 1, NULL, iFrame ); + } + if ( p->pPars->nProveOuts == Saig_ManPoNum(p->pAig) ) + return 1; // UNSAT + if ( p->pPars->nFailOuts > 0 ) + return 0; // SAT + return -1; + } + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, 0, Abc_Clock() - clkStart ); + + // check termination + if ( p->pPars->pFuncStop && p->pPars->pFuncStop(p->pPars->RunId) ) + { + p->pPars->iFrame = iFrame; + return -1; + } + if ( p->timeToStop && Abc_Clock() > p->timeToStop ) + { + if ( fPrintClauses ) + { + Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame ); + Pdr_ManPrintClauses( p, 0 ); + } + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + if ( !p->pPars->fSilent ) + Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame ); + p->pPars->iFrame = iFrame; + return -1; + } + if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC ) + { + if ( fPrintClauses ) + { + Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame ); + Pdr_ManPrintClauses( p, 0 ); + } + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + if ( !p->pPars->fSilent ) + Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame ); + p->pPars->iFrame = iFrame; + return -1; + } + if ( p->pPars->nFrameMax && iFrame >= p->pPars->nFrameMax ) + { + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + if ( !p->pPars->fSilent ) + Abc_Print( 1, "Reached limit on the number of timeframes (%d).\n", p->pPars->nFrameMax ); + p->pPars->iFrame = iFrame; + return -1; + } + } + assert( 0 ); + return -1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int IPdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) +{ + Pdr_Man_t * p; + int k, RetValue; + abctime clk = Abc_Clock(); + if ( pPars->nTimeOutOne && !pPars->fSolveAll ) + pPars->nTimeOutOne = 0; + if ( pPars->nTimeOutOne && pPars->nTimeOut == 0 ) + pPars->nTimeOut = pPars->nTimeOutOne * Saig_ManPoNum(pAig) / 1000 + (int)((pPars->nTimeOutOne * Saig_ManPoNum(pAig) % 1000) > 0); + if ( pPars->fVerbose ) + { +// Abc_Print( 1, "Running PDR by Niklas Een (aka IC3 by Aaron Bradley) with these parameters:\n" ); + Abc_Print( 1, "VarMax = %d. FrameMax = %d. QueMax = %d. TimeMax = %d. ", + pPars->nRecycle, + pPars->nFrameMax, + pPars->nRestLimit, + pPars->nTimeOut ); + Abc_Print( 1, "MonoCNF = %s. SkipGen = %s. SolveAll = %s.\n", + pPars->fMonoCnf ? "yes" : "no", + pPars->fSkipGeneral ? "yes" : "no", + pPars->fSolveAll ? "yes" : "no" ); + } + ABC_FREE( pAig->pSeqModel ); + p = Pdr_ManStart( pAig, pPars, NULL ); + RetValue = IPdr_ManSolveInt( p ); + if ( RetValue == 0 ) + assert( pAig->pSeqModel != NULL || p->vCexes != NULL ); + if ( p->vCexes ) + { + assert( p->pAig->vSeqModelVec == NULL ); + p->pAig->vSeqModelVec = p->vCexes; + p->vCexes = NULL; + } + if ( p->pPars->fDumpInv ) + { + char * pFileName = Extra_FileNameGenericAppend(p->pAig->pName, "_inv.pla"); + Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); + Pdr_ManDumpClauses( p, pFileName, RetValue==1 ); + } + else if ( RetValue == 1 ) + Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); + p->tTotal += Abc_Clock() - clk; + Pdr_ManStop( p ); + pPars->iFrame--; + // convert all -2 (unknown) entries into -1 (undec) + if ( pPars->vOutMap ) + for ( k = 0; k < Saig_ManPoNum(pAig); k++ ) + if ( Vec_IntEntry(pPars->vOutMap, k) == -2 ) // unknown + Vec_IntWriteEntry( pPars->vOutMap, k, -1 ); // undec + if ( pPars->fUseBridge ) + Gia_ManToBridgeAbort( stdout, 7, (unsigned char *)"timeout" ); + return RetValue; +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkDarIPdr ( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ) { int RetValue = -1; abctime clk = Abc_Clock(); Aig_Man_t * pMan; pMan = Abc_NtkToDar( pNtk, 0, 1 ); - RetValue = Pdr_ManSolve( pMan, pPars ); + RetValue = IPdr_ManSolve( pMan, pPars ); if ( RetValue == 1 ) Abc_Print( 1, "Property proved. " ); From 429f52ce15d1c10e71d98d8c1388b93809a425e1 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 18 Feb 2017 14:20:10 -0800 Subject: [PATCH 158/185] Experiments with SAT sweeping. --- abclib.dsp | 4 + src/aig/gia/gia.h | 14 +- src/aig/gia/giaEquiv.c | 2 +- src/aig/gia/giaUtil.c | 19 + src/base/wlc/wlcSim.c | 22 +- src/misc/util/utilTruth.h | 16 + src/proof/cec/cecSat.c | 862 ++++++++++++++++++++++++++++++++++++ src/proof/cec/module.make | 1 + src/sat/bmc/bmcGen.c | 18 +- src/sat/satoko/satoko.h | 2 +- src/sat/satoko/solver_api.c | 4 +- 11 files changed, 936 insertions(+), 28 deletions(-) create mode 100644 src/proof/cec/cecSat.c diff --git a/abclib.dsp b/abclib.dsp index 23c57506b..99ade15e4 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -5027,6 +5027,10 @@ SOURCE=.\src\proof\cec\cecPat.c # End Source File # Begin Source File +SOURCE=.\src\proof\cec\cecSat.c +# End Source File +# Begin Source File + SOURCE=.\src\proof\cec\cecSeq.c # End Source File # Begin Source File diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index c183432a4..108048507 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -194,6 +194,7 @@ struct Gia_Man_t_ int MappedDelay; // delay after mapping // bit-parallel simulation int iPatsPi; + int nSimWords; Vec_Wrd_t * vSims; Vec_Wrd_t * vSimsPi; Vec_Int_t * vClassOld; @@ -982,24 +983,26 @@ static inline void Gia_ObjSetNext( Gia_Man_t * p, int Id, int Num ) { p static inline int Gia_ObjIsConst( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == 0; } static inline int Gia_ObjIsHead( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == GIA_VOID && Gia_ObjNext(p, Id) > 0; } -static inline int Gia_ObjIsNone( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == GIA_VOID && Gia_ObjNext(p, Id) == 0; } -static inline int Gia_ObjIsTail( Gia_Man_t * p, int Id ) { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) && Gia_ObjNext(p, Id) == 0; } +static inline int Gia_ObjIsNone( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == GIA_VOID && Gia_ObjNext(p, Id) <= 0; } +static inline int Gia_ObjIsTail( Gia_Man_t * p, int Id ) { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) && Gia_ObjNext(p, Id) <= 0; } static inline int Gia_ObjIsClass( Gia_Man_t * p, int Id ) { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) || Gia_ObjNext(p, Id) > 0; } static inline int Gia_ObjHasSameRepr( Gia_Man_t * p, int i, int k ) { assert( k ); return i? (Gia_ObjRepr(p, i) == Gia_ObjRepr(p, k) && Gia_ObjRepr(p, i) != GIA_VOID) : Gia_ObjRepr(p, k) == 0; } static inline int Gia_ObjIsFailedPair( Gia_Man_t * p, int i, int k ) { assert( k ); return i? (Gia_ObjFailed(p, i) || Gia_ObjFailed(p, k)) : Gia_ObjFailed(p, k); } -static inline int Gia_ClassIsPair( Gia_Man_t * p, int i ) { assert( Gia_ObjIsHead(p, i) ); assert( Gia_ObjNext(p, i) ); return Gia_ObjNext(p, Gia_ObjNext(p, i)) == 0; } +static inline int Gia_ClassIsPair( Gia_Man_t * p, int i ) { assert( Gia_ObjIsHead(p, i) ); assert( Gia_ObjNext(p, i) ); return Gia_ObjNext(p, Gia_ObjNext(p, i)) <= 0; } static inline void Gia_ClassUndoPair( Gia_Man_t * p, int i ) { assert( Gia_ClassIsPair(p,i) ); Gia_ObjSetRepr(p, Gia_ObjNext(p, i), GIA_VOID); Gia_ObjSetNext(p, i, 0); } #define Gia_ManForEachConst( p, i ) \ for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsConst(p, i) ) {} else #define Gia_ManForEachClass( p, i ) \ for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsHead(p, i) ) {} else +#define Gia_ManForEachClass0( p, i ) \ + for ( i = 0; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsHead(p, i) ) {} else #define Gia_ManForEachClassReverse( p, i ) \ for ( i = Gia_ManObjNum(p) - 1; i > 0; i-- ) if ( !Gia_ObjIsHead(p, i) ) {} else #define Gia_ClassForEachObj( p, i, iObj ) \ - for ( assert(Gia_ObjIsHead(p, i)), iObj = i; iObj; iObj = Gia_ObjNext(p, iObj) ) + for ( assert(Gia_ObjIsHead(p, i)), iObj = i; iObj > 0; iObj = Gia_ObjNext(p, iObj) ) #define Gia_ClassForEachObj1( p, i, iObj ) \ - for ( assert(Gia_ObjIsHead(p, i)), iObj = Gia_ObjNext(p, i); iObj; iObj = Gia_ObjNext(p, iObj) ) + for ( assert(Gia_ObjIsHead(p, i)), iObj = Gia_ObjNext(p, i); iObj > 0; iObj = Gia_ObjNext(p, iObj) ) static inline int Gia_ObjFoffsetId( Gia_Man_t * p, int Id ) { return Vec_IntEntry( p->vFanout, Id ); } @@ -1585,6 +1588,7 @@ extern void Gia_ManSwapPos( Gia_Man_t * p, int i ); extern Vec_Int_t * Gia_ManSaveValue( Gia_Man_t * p ); extern void Gia_ManLoadValue( Gia_Man_t * p, Vec_Int_t * vValues ); extern Vec_Int_t * Gia_ManFirstFanouts( Gia_Man_t * p ); +extern void Gia_ManDetectMuxes( Gia_Man_t * p ); /*=== giaCTas.c ===========================================================*/ typedef struct Tas_Man_t_ Tas_Man_t; diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c index 1b0bce07d..f41db8985 100644 --- a/src/aig/gia/giaEquiv.c +++ b/src/aig/gia/giaEquiv.c @@ -485,7 +485,7 @@ void Gia_ManEquivPrintClasses( Gia_Man_t * p, int fVerbose, float Mem ) if ( fVerbose ) { // int Ent; - Abc_Print( 1, "Const0 = " ); + Abc_Print( 1, "Const0 (%d) = ", Counter0 ); Gia_ManForEachConst( p, i ) Abc_Print( 1, "%d ", i ); Abc_Print( 1, "\n" ); diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index c7af642ec..d64c53fa2 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -2050,6 +2050,25 @@ void Gia_AigerWriteLut( Gia_Man_t * p, char * pFileName ) Vec_WrdFree( vTruths ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManDetectMuxes( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj, * pNodeT, * pNodeE; int i; + Gia_ManForEachObj( p, pObj, i ); + if ( Gia_ObjIsAnd(pObj) && Gia_ObjRecognizeMux(pObj, &pNodeT, &pNodeE) ) + pObj->fMark0 = 1; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/wlc/wlcSim.c b/src/base/wlc/wlcSim.c index 20ac8c61d..e2fcd1f8f 100644 --- a/src/base/wlc/wlcSim.c +++ b/src/base/wlc/wlcSim.c @@ -43,13 +43,13 @@ ABC_NAMESPACE_IMPL_START ***********************************************************************/ static inline word * Wlc_ObjSim( Gia_Man_t * p, int iObj ) { - return Vec_WrdEntryP( p->vSims, p->iPatsPi * iObj ); + return Vec_WrdEntryP( p->vSims, p->nSimWords * iObj ); } static inline void Wlc_ObjSimPi( Gia_Man_t * p, int iObj ) { int w; word * pSim = Wlc_ObjSim( p, iObj ); - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSim[w] = Gia_ManRandomW( 0 ); } static inline void Wlc_ObjSimRo( Gia_Man_t * p, int iObj ) @@ -57,7 +57,7 @@ static inline void Wlc_ObjSimRo( Gia_Man_t * p, int iObj ) int w; word * pSimRo = Wlc_ObjSim( p, iObj ); word * pSimRi = Wlc_ObjSim( p, Gia_ObjRoToRiId(p, iObj) ); - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSimRo[w] = pSimRi[w]; } static inline void Wlc_ObjSimCo( Gia_Man_t * p, int iObj ) @@ -67,10 +67,10 @@ static inline void Wlc_ObjSimCo( Gia_Man_t * p, int iObj ) word * pSimCo = Wlc_ObjSim( p, iObj ); word * pSimDri = Wlc_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) ); if ( Gia_ObjFaninC0(pObj) ) - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSimCo[w] = ~pSimDri[w]; else - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSimCo[w] = pSimDri[w]; } static inline void Wlc_ObjSimAnd( Gia_Man_t * p, int iObj ) @@ -81,16 +81,16 @@ static inline void Wlc_ObjSimAnd( Gia_Man_t * p, int iObj ) word * pSim0 = Wlc_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) ); word * pSim1 = Wlc_ObjSim( p, Gia_ObjFaninId1(pObj, iObj) ); if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSim[w] = ~pSim0[w] & ~pSim1[w]; else if ( Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) ) - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSim[w] = ~pSim0[w] & pSim1[w]; else if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSim[w] = pSim0[w] & ~pSim1[w]; else - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSim[w] = pSim0[w] & pSim1[w]; } @@ -135,7 +135,7 @@ Vec_Ptr_t * Wlc_NtkSimulate( Wlc_Ntk_t * p, Vec_Int_t * vNodes, int nWords, int // allocate simulation info for one timeframe Vec_WrdFreeP( &pGia->vSims ); pGia->vSims = Vec_WrdStart( Gia_ManObjNum(pGia) * nWords ); - pGia->iPatsPi = nWords; + pGia->nSimWords = nWords; // allocate resulting simulation info vRes = Vec_PtrAlloc( Vec_IntSize(vNodes) ); Wlc_NtkForEachObjVec( vNodes, p, pWlcObj, i ) @@ -188,7 +188,7 @@ Vec_Ptr_t * Wlc_NtkSimulate( Wlc_Ntk_t * p, Vec_Int_t * vNodes, int nWords, int printf( "Replaced %d dangling internal bits with constant 0.\n", Counter ); } Vec_WrdFreeP( &pGia->vSims ); - pGia->iPatsPi = 0; + pGia->nSimWords = 0; Gia_ManStop( pGia ); return vRes; } diff --git a/src/misc/util/utilTruth.h b/src/misc/util/utilTruth.h index d77ed64d6..e04ffbc95 100644 --- a/src/misc/util/utilTruth.h +++ b/src/misc/util/utilTruth.h @@ -1631,6 +1631,14 @@ static inline int Abc_TtFindFirstBit( word * pIn, int nVars ) return 64*w + Abc_Tt6FirstBit(pIn[w]); return -1; } +static inline int Abc_TtFindFirstBit2( word * pIn, int nWords ) +{ + int w; + for ( w = 0; w < nWords; w++ ) + if ( pIn[w] ) + return 64*w + Abc_Tt6FirstBit(pIn[w]); + return -1; +} static inline int Abc_TtFindFirstDiffBit( word * pIn1, word * pIn2, int nVars ) { int w, nWords = Abc_TtWordNum(nVars); @@ -1639,6 +1647,14 @@ static inline int Abc_TtFindFirstDiffBit( word * pIn1, word * pIn2, int nVars ) return 64*w + Abc_Tt6FirstBit(pIn1[w] ^ pIn2[w]); return -1; } +static inline int Abc_TtFindFirstDiffBit2( word * pIn1, word * pIn2, int nWords ) +{ + int w; + for ( w = 0; w < nWords; w++ ) + if ( pIn1[w] ^ pIn2[w] ) + return 64*w + Abc_Tt6FirstBit(pIn1[w] ^ pIn2[w]); + return -1; +} static inline int Abc_TtFindFirstZero( word * pIn, int nVars ) { int w, nWords = Abc_TtWordNum(nVars); diff --git a/src/proof/cec/cecSat.c b/src/proof/cec/cecSat.c new file mode 100644 index 000000000..9e85e49de --- /dev/null +++ b/src/proof/cec/cecSat.c @@ -0,0 +1,862 @@ +/**CFile**************************************************************** + + FileName [cecSat.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinational equivalence checking.] + + Synopsis [Detection of structural isomorphism.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "aig/gia/gia.h" +#include "misc/util/utilTruth.h" +#include "sat/satoko/satoko.h" +#include "sat/satoko/solver.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// sweeping manager +typedef struct Cec2_Par_t_ Cec2_Par_t; +struct Cec2_Par_t_ +{ + int nSimWords; // simulation words + int nSimRounds; // simulation rounds + int nConfLimit; // SAT solver conflict limit + int fIsMiter; // this is a miter + int fVeryVerbose; // verbose stats + int fVerbose; // verbose stats +}; + +// SAT solving manager +typedef struct Cec2_Man_t_ Cec2_Man_t; +struct Cec2_Man_t_ +{ + Cec2_Par_t * pPars; // parameters + Gia_Man_t * pAig; // user's AIG + Gia_Man_t * pNew; // internal AIG + // SAT solving + satoko_t * pSat; // SAT solver + Vec_Ptr_t * vFrontier; // CNF construction + Vec_Ptr_t * vFanins; // CNF construction + Vec_Wrd_t * vSims; // CI simulation info + Vec_Int_t * vNodesNew; // nodes + Vec_Int_t * vObjSatPairs; // nodes +}; + +static inline int Cec2_ObjSatId( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjCopyArray(p, Gia_ObjId(p, pObj)); } +static inline int Cec2_ObjSetSatId( Gia_Man_t * p, Gia_Obj_t * pObj, int Num ) { assert(Cec2_ObjSatId(p, pObj) == -1); Gia_ObjSetCopyArray(p, Gia_ObjId(p, pObj), Num); return Num; } +static inline void Cec2_ObjCleanSatId( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert(Cec2_ObjSatId(p, pObj) != -1); Gia_ObjSetCopyArray(p, Gia_ObjId(p, pObj), -1); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Sets parameter defaults.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec2_SetDefaultParams( Cec2_Par_t * p ) +{ + memset( p, 0, sizeof(Cec2_Par_t) ); + p->nSimWords = 8; // simulation words + p->nSimRounds = 4; // simulation rounds + p->nConfLimit = 1000; // conflict limit at a node + p->fIsMiter = 0; // this is a miter + p->fVeryVerbose = 0; // verbose stats + p->fVerbose = 1; // verbose stats +} + +/**Function************************************************************* + + Synopsis [Adds clauses to the solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec2_AddClausesMux( Gia_Man_t * p, Gia_Obj_t * pNode, satoko_t * pSat ) +{ + int fPolarFlip = 0; + Gia_Obj_t * pNodeI, * pNodeT, * pNodeE; + int pLits[4], RetValue, VarF, VarI, VarT, VarE, fCompT, fCompE; + + assert( !Gia_IsComplement( pNode ) ); + assert( pNode->fMark0 ); + // get nodes (I = if, T = then, E = else) + pNodeI = Gia_ObjRecognizeMux( pNode, &pNodeT, &pNodeE ); + // get the variable numbers + VarF = Cec2_ObjSatId(p, pNode); + VarI = Cec2_ObjSatId(p, pNodeI); + VarT = Cec2_ObjSatId(p, Gia_Regular(pNodeT)); + VarE = Cec2_ObjSatId(p, Gia_Regular(pNodeE)); + // get the complementation flags + fCompT = Gia_IsComplement(pNodeT); + fCompE = Gia_IsComplement(pNodeE); + + // f = ITE(i, t, e) + + // i' + t' + f + // i' + t + f' + // i + e' + f + // i + e + f' + + // create four clauses + pLits[0] = Abc_Var2Lit(VarI, 1); + pLits[1] = Abc_Var2Lit(VarT, 1^fCompT); + pLits[2] = Abc_Var2Lit(VarF, 0); + if ( fPolarFlip ) + { + if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( Gia_Regular(pNodeT)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] ); + } + RetValue = satoko_add_clause( pSat, pLits, 3 ); + assert( RetValue ); + pLits[0] = Abc_Var2Lit(VarI, 1); + pLits[1] = Abc_Var2Lit(VarT, 0^fCompT); + pLits[2] = Abc_Var2Lit(VarF, 1); + if ( fPolarFlip ) + { + if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( Gia_Regular(pNodeT)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] ); + } + RetValue = satoko_add_clause( pSat, pLits, 3 ); + assert( RetValue ); + pLits[0] = Abc_Var2Lit(VarI, 0); + pLits[1] = Abc_Var2Lit(VarE, 1^fCompE); + pLits[2] = Abc_Var2Lit(VarF, 0); + if ( fPolarFlip ) + { + if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] ); + } + RetValue = satoko_add_clause( pSat, pLits, 3 ); + assert( RetValue ); + pLits[0] = Abc_Var2Lit(VarI, 0); + pLits[1] = Abc_Var2Lit(VarE, 0^fCompE); + pLits[2] = Abc_Var2Lit(VarF, 1); + if ( fPolarFlip ) + { + if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] ); + } + RetValue = satoko_add_clause( pSat, pLits, 3 ); + assert( RetValue ); + + // two additional clauses + // t' & e' -> f' + // t & e -> f + + // t + e + f' + // t' + e' + f + + if ( VarT == VarE ) + { +// assert( fCompT == !fCompE ); + return; + } + + pLits[0] = Abc_Var2Lit(VarT, 0^fCompT); + pLits[1] = Abc_Var2Lit(VarE, 0^fCompE); + pLits[2] = Abc_Var2Lit(VarF, 1); + if ( fPolarFlip ) + { + if ( Gia_Regular(pNodeT)->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] ); + } + RetValue = satoko_add_clause( pSat, pLits, 3 ); + assert( RetValue ); + pLits[0] = Abc_Var2Lit(VarT, 1^fCompT); + pLits[1] = Abc_Var2Lit(VarE, 1^fCompE); + pLits[2] = Abc_Var2Lit(VarF, 0); + if ( fPolarFlip ) + { + if ( Gia_Regular(pNodeT)->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] ); + } + RetValue = satoko_add_clause( pSat, pLits, 3 ); + assert( RetValue ); +} +void Cec2_AddClausesSuper( Gia_Man_t * p, Gia_Obj_t * pNode, Vec_Ptr_t * vSuper, satoko_t * pSat ) +{ + int fPolarFlip = 0; + Gia_Obj_t * pFanin; + int * pLits, nLits, RetValue, i; + assert( !Gia_IsComplement(pNode) ); + assert( Gia_ObjIsAnd( pNode ) ); + // create storage for literals + nLits = Vec_PtrSize(vSuper) + 1; + pLits = ABC_ALLOC( int, nLits ); + // suppose AND-gate is A & B = C + // add !A => !C or A + !C + Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i ) + { + pLits[0] = Abc_Var2Lit(Cec2_ObjSatId(p, Gia_Regular(pFanin)), Gia_IsComplement(pFanin)); + pLits[1] = Abc_Var2Lit(Cec2_ObjSatId(p, pNode), 1); + if ( fPolarFlip ) + { + if ( Gia_Regular(pFanin)->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( pNode->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + } + RetValue = satoko_add_clause( pSat, pLits, 2 ); + assert( RetValue ); + } + // add A & B => C or !A + !B + C + Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i ) + { + pLits[i] = Abc_Var2Lit(Cec2_ObjSatId(p, Gia_Regular(pFanin)), !Gia_IsComplement(pFanin)); + if ( fPolarFlip ) + { + if ( Gia_Regular(pFanin)->fPhase ) pLits[i] = Abc_LitNot( pLits[i] ); + } + } + pLits[nLits-1] = Abc_Var2Lit(Cec2_ObjSatId(p, pNode), 0); + if ( fPolarFlip ) + { + if ( pNode->fPhase ) pLits[nLits-1] = Abc_LitNot( pLits[nLits-1] ); + } + RetValue = satoko_add_clause( pSat, pLits, nLits ); + assert( RetValue ); + ABC_FREE( pLits ); +} + +/**Function************************************************************* + + Synopsis [Adds clauses and returns CNF variable of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec2_CollectSuper_rec( Gia_Obj_t * pObj, Vec_Ptr_t * vSuper, int fFirst, int fUseMuxes ) +{ + // if the new node is complemented or a PI, another gate begins + if ( Gia_IsComplement(pObj) || Gia_ObjIsCi(pObj) || + (!fFirst && Gia_ObjValue(pObj) > 1) || + (fUseMuxes && pObj->fMark0) ) + { + Vec_PtrPushUnique( vSuper, pObj ); + return; + } + // go through the branches + Cec2_CollectSuper_rec( Gia_ObjChild0(pObj), vSuper, 0, fUseMuxes ); + Cec2_CollectSuper_rec( Gia_ObjChild1(pObj), vSuper, 0, fUseMuxes ); +} +void Cec2_CollectSuper( Gia_Obj_t * pObj, int fUseMuxes, Vec_Ptr_t * vSuper ) +{ + assert( !Gia_IsComplement(pObj) ); + assert( !Gia_ObjIsCi(pObj) ); + Vec_PtrClear( vSuper ); + Cec2_CollectSuper_rec( pObj, vSuper, 1, fUseMuxes ); +} +void Cec2_ObjAddToFrontier( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Ptr_t * vFrontier, satoko_t * pSat ) +{ + assert( !Gia_IsComplement(pObj) ); + assert( !Gia_ObjIsConst0(pObj) ); + if ( Cec2_ObjSatId(p, pObj) >= 0 ) + return; + assert( Cec2_ObjSatId(p, pObj) == -1 ); + Cec2_ObjSetSatId( p, pObj, satoko_add_variable(pSat, 0) ); + if ( Gia_ObjIsAnd(pObj) ) + Vec_PtrPush( vFrontier, pObj ); +} +int Cec2_ObjGetCnfVar( Cec2_Man_t * p, int iObj ) +{ + Gia_Obj_t * pNode, * pFanin; + Gia_Obj_t * pObj = Gia_ManObj(p->pNew, iObj); + int i, k, fUseMuxes = 1; + // quit if CNF is ready + if ( Cec2_ObjSatId(p->pNew,pObj) >= 0 ) + return Cec2_ObjSatId(p->pNew,pObj); + assert( iObj > 0 ); + if ( Gia_ObjIsCi(pObj) ) + return Cec2_ObjSetSatId( p->pNew, pObj, satoko_add_variable(p->pSat, 0) ); + assert( Gia_ObjIsAnd(pObj) ); + // start the frontier + Vec_PtrClear( p->vFrontier ); + Cec2_ObjAddToFrontier( p->pNew, pObj, p->vFrontier, p->pSat ); + // explore nodes in the frontier + Vec_PtrForEachEntry( Gia_Obj_t *, p->vFrontier, pNode, i ) + { + // create the supergate + assert( Cec2_ObjSatId(p->pNew,pNode) >= 0 ); + if ( fUseMuxes && pNode->fMark0 ) + { + Vec_PtrClear( p->vFanins ); + Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin0( Gia_ObjFanin0(pNode) ) ); + Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin0( Gia_ObjFanin1(pNode) ) ); + Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin1( Gia_ObjFanin0(pNode) ) ); + Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin1( Gia_ObjFanin1(pNode) ) ); + Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k ) + Cec2_ObjAddToFrontier( p->pNew, Gia_Regular(pFanin), p->vFrontier, p->pSat ); + Cec2_AddClausesMux( p->pNew, pNode, p->pSat ); + } + else + { + Cec2_CollectSuper( pNode, fUseMuxes, p->vFanins ); + Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k ) + Cec2_ObjAddToFrontier( p->pNew, Gia_Regular(pFanin), p->vFrontier, p->pSat ); + Cec2_AddClausesSuper( p->pNew, pNode, p->vFanins, p->pSat ); + } + assert( Vec_PtrSize(p->vFanins) > 1 ); + } + return Cec2_ObjSatId(p->pNew,pObj); +} + + + +/**Function************************************************************* + + Synopsis [Internal simulation APIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline word * Cec2_ObjSim( Gia_Man_t * p, int iObj ) +{ + return Vec_WrdEntryP( p->vSims, p->nSimWords * iObj ); +} +static inline void Cec2_ObjSimSetPiBit( Gia_Man_t * p, int iObj, int Bit ) +{ + word * pSim = Cec2_ObjSim( p, iObj ); + p->iPatsPi = (p->iPatsPi == 64 * p->nSimWords - 1) ? 1 : p->iPatsPi + 1; + assert( p->iPatsPi > 0 && p->iPatsPi < 64 * p->nSimWords ); + if ( Abc_InfoHasBit( (unsigned*)pSim, p->iPatsPi ) != Bit ) + Abc_InfoXorBit( (unsigned*)pSim, p->iPatsPi ); +} +static inline void Cec2_ObjSimRo( Gia_Man_t * p, int iObj ) +{ + int w; + word * pSimRo = Cec2_ObjSim( p, iObj ); + word * pSimRi = Cec2_ObjSim( p, Gia_ObjRoToRiId(p, iObj) ); + for ( w = 0; w < p->nSimWords; w++ ) + pSimRo[w] = pSimRi[w]; +} +static inline void Cec2_ObjSimCo( Gia_Man_t * p, int iObj ) +{ + int w; + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + word * pSimCo = Cec2_ObjSim( p, iObj ); + word * pSimDri = Cec2_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) ); + if ( Gia_ObjFaninC0(pObj) ) + for ( w = 0; w < p->nSimWords; w++ ) + pSimCo[w] = ~pSimDri[w]; + else + for ( w = 0; w < p->nSimWords; w++ ) + pSimCo[w] = pSimDri[w]; +} +static inline void Cec2_ObjSimAnd( Gia_Man_t * p, int iObj ) +{ + int w; + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + word * pSim = Cec2_ObjSim( p, iObj ); + word * pSim0 = Cec2_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) ); + word * pSim1 = Cec2_ObjSim( p, Gia_ObjFaninId1(pObj, iObj) ); + if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) + for ( w = 0; w < p->nSimWords; w++ ) + pSim[w] = ~pSim0[w] & ~pSim1[w]; + else if ( Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) ) + for ( w = 0; w < p->nSimWords; w++ ) + pSim[w] = ~pSim0[w] & pSim1[w]; + else if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) + for ( w = 0; w < p->nSimWords; w++ ) + pSim[w] = pSim0[w] & ~pSim1[w]; + else + for ( w = 0; w < p->nSimWords; w++ ) + pSim[w] = pSim0[w] & pSim1[w]; +} +static inline int Cec2_ObjSimEqual( Gia_Man_t * p, int iObj0, int iObj1 ) +{ + int w; + word * pSim0 = Cec2_ObjSim( p, iObj0 ); + word * pSim1 = Cec2_ObjSim( p, iObj1 ); + if ( (pSim0[0] & 1) == (pSim1[0] & 1) ) + { + for ( w = 0; w < p->nSimWords; w++ ) + if ( pSim0[w] != pSim1[w] ) + return 0; + return 1; + } + else + { + for ( w = 0; w < p->nSimWords; w++ ) + if ( pSim0[w] != ~pSim1[w] ) + return 0; + return 1; + } +} +static inline void Cec2_ObjSimPi( Gia_Man_t * p, int iObj ) +{ + int w; + word * pSim = Cec2_ObjSim( p, iObj ); + for ( w = 0; w < p->nSimWords; w++ ) + pSim[w] = Gia_ManRandomW( 0 ); + pSim[0] <<= 1; +} +void Cec2_ManSimulateCis( Gia_Man_t * p ) +{ + int i, Id; + Gia_ManForEachCiId( p, Id, i ) + Cec2_ObjSimPi( p, Id ); + p->iPatsPi = 1; +} +Abc_Cex_t * Cec2_ManDeriveCex( Gia_Man_t * p, int iOut, int iPat ) +{ + Abc_Cex_t * pCex; + int i, Id; + pCex = Abc_CexAlloc( 0, Gia_ManCiNum(p), 1 ); + pCex->iPo = iOut; + if ( iPat == -1 ) + return pCex; + Gia_ManForEachCiId( p, Id, i ) + if ( Abc_InfoHasBit((unsigned *)Cec2_ObjSim(p, Id), iPat) ) + Abc_InfoSetBit( pCex->pData, i ); + return pCex; +} +int Cec2_ManSimulateCos( Gia_Man_t * p ) +{ + int i, Id; + // check outputs and generate CEX if they fail + Gia_ManForEachCoId( p, Id, i ) + { + Cec2_ObjSimCo( p, Id ); + if ( Cec2_ObjSimEqual(p, Id, 0) ) + continue; + p->pCexSeq = Cec2_ManDeriveCex( p, i, Abc_TtFindFirstBit2(Cec2_ObjSim(p, Id), p->nSimWords) ); + return 0; + } + return 1; +} +void Cec2_ManSaveCis( Gia_Man_t * p ) +{ + int w, i, Id; + assert( p->vSimsPi != NULL ); + for ( w = 0; w < p->nSimWords; w++ ) + Gia_ManForEachCiId( p, Id, i ) + Vec_WrdPush( p->vSimsPi, Cec2_ObjSim(p, Id)[w] ); +} +void Cec2_ManSimulate( Gia_Man_t * p ) +{ + extern void Cec2_ManSimClassRefineOne( Gia_Man_t * p, int iRepr ); + Gia_Obj_t * pObj; int i; + Cec2_ManSaveCis( p ); + Gia_ManForEachAnd( p, pObj, i ) + Cec2_ObjSimAnd( p, i ); + if ( p->pReprs == NULL ) + return; + Gia_ManForEachClass0( p, i ) + Cec2_ManSimClassRefineOne( p, i ); +} +void Cec2_ManSimAlloc( Gia_Man_t * p, int nWords ) +{ + Vec_WrdFreeP( &p->vSims ); + Vec_WrdFreeP( &p->vSimsPi ); + p->vSims = Vec_WrdStart( Gia_ManObjNum(p) * nWords ); + p->vSimsPi = Vec_WrdAlloc( Gia_ManCiNum(p) * nWords * 4 ); // storage for CI patterns + p->nSimWords = nWords; +} + + +/**Function************************************************************* + + Synopsis [Computes hash key of the simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec2_ManSimHashKey( word * pSim, int nSims, int nTableSize ) +{ + static int s_Primes[16] = { + 1291, 1699, 1999, 2357, 2953, 3313, 3907, 4177, + 4831, 5147, 5647, 6343, 6899, 7103, 7873, 8147 }; + unsigned uHash = 0, * pSimU = (unsigned *)pSim; + int i, nSimsU = 2 * nSims; + if ( pSimU[0] & 1 ) + for ( i = 0; i < nSimsU; i++ ) + uHash ^= ~pSimU[i] * s_Primes[i & 0xf]; + else + for ( i = 0; i < nSimsU; i++ ) + uHash ^= pSimU[i] * s_Primes[i & 0xf]; + return (int)(uHash % nTableSize); + +} + +/**Function************************************************************* + + Synopsis [Creating initial equivalence classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec2_ManSimClassRefineOne( Gia_Man_t * p, int iRepr ) +{ + int iObj, iPrev = iRepr, iPrev2, iRepr2; + Gia_ClassForEachObj1( p, iRepr, iRepr2 ) + if ( Cec2_ObjSimEqual(p, iRepr, iRepr2) ) + iPrev = iRepr2; + else + break; + if ( iRepr2 <= 0 ) // no refinement + return; + // relink remaining nodes of the class + // nodes that are equal to iRepr, remain in the class of iRepr + // nodes that are not equal to iRepr, move to the class of iRepr2 + Gia_ObjSetRepr( p, iRepr2, GIA_VOID ); + iPrev2 = iRepr2; + for ( iObj = Gia_ObjNext(p, iRepr2); iObj > 0; iObj = Gia_ObjNext(p, iObj) ) + { + if ( Cec2_ObjSimEqual(p, iRepr, iObj) ) // remains with iRepr + { + Gia_ObjSetNext( p, iPrev, iObj ); + iPrev = iObj; + } + else // moves to iRepr2 + { + Gia_ObjSetRepr( p, iObj, iRepr2 ); + Gia_ObjSetNext( p, iPrev2, iObj ); + iPrev2 = iObj; + } + } + Gia_ObjSetNext( p, iPrev, -1 ); + Gia_ObjSetNext( p, iPrev2, -1 ); +} +void Cec2_ManCreateClasses( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int nWords = p->nSimWords; + int * pTable, nTableSize, i, Key; + // allocate representation + assert( p->pReprs == NULL ); + p->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p) ); + p->pNexts = ABC_FALLOC( int, Gia_ManObjNum(p) ); + // hash each node by its simulation info + nTableSize = Abc_PrimeCudd( Gia_ManObjNum(p) ); + pTable = ABC_FALLOC( int, nTableSize ); + Gia_ManForEachObj( p, pObj, i ) + { + p->pReprs[i].iRepr = GIA_VOID; + if ( Gia_ObjIsCo(pObj) ) + continue; + Key = Cec2_ManSimHashKey( Cec2_ObjSim(p, i), nWords, nTableSize ); + assert( Key >= 0 && Key < nTableSize ); + if ( pTable[Key] == -1 ) + pTable[Key] = i; + else + Gia_ObjSetRepr( p, i, pTable[Key] ); + } + // create classes + for ( i = Gia_ManObjNum(p) - 1; i >= 0; i-- ) + { + int iRepr = Gia_ObjRepr(p, i); + if ( iRepr == GIA_VOID ) + continue; + Gia_ObjSetNext( p, i, Gia_ObjNext(p, iRepr) ); + Gia_ObjSetNext( p, iRepr, i ); + } + ABC_FREE( pTable ); + Gia_ManForEachClass0( p, i ) + Cec2_ManSimClassRefineOne( p, i ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Cec2_Man_t * Cec2_ManCreate( Gia_Man_t * pAig, Cec2_Par_t * pPars ) +{ + Cec2_Man_t * p; + Gia_Obj_t * pObj; int i; + assert( Gia_ManRegNum(pAig) == 0 ); + p = ABC_CALLOC( Cec2_Man_t, 1 ); + memset( p, 0, sizeof(Cec2_Man_t) ); + p->pPars = pPars; + p->pAig = pAig; + // create new manager + p->pNew = Gia_ManStart( Gia_ManObjNum(pAig) ); + Gia_ManFillValue( pAig ); + Gia_ManConst0(pAig)->Value = 0; + Gia_ManForEachCi( pAig, pObj, i ) + pObj->Value = Gia_ManAppendCi( p->pNew ); + Gia_ManHashAlloc( p->pNew ); + Vec_IntFill( &p->pNew->vCopies, Gia_ManObjNum(p->pNew), -1 ); + // SAT solving + p->pSat = satoko_create(); + p->vFrontier = Vec_PtrAlloc( 1000 ); + p->vFanins = Vec_PtrAlloc( 100 ); + p->vNodesNew = Vec_IntAlloc( 100 ); + p->vObjSatPairs = Vec_IntAlloc( 100 ); + // remember pointer to the solver in the AIG manager + pAig->pData = p->pSat; + return p; +} +void Cec2_ManDestroy( Cec2_Man_t * p ) +{ + Vec_WrdFreeP( &p->pAig->vSims ); + //Vec_WrdFreeP( &p->pAig->vSimsPi ); + Gia_ManCleanMark01( p->pAig ); + satoko_destroy( p->pSat ); + Gia_ManStopP( &p->pNew ); + Vec_PtrFreeP( &p->vFrontier ); + Vec_PtrFreeP( &p->vFanins ); + Vec_IntFreeP( &p->vNodesNew ); + Vec_IntFreeP( &p->vObjSatPairs ); + ABC_FREE( p ); +} + + +/**Function************************************************************* + + Synopsis [Internal simulation APIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec2_ManCollect_rec( Cec2_Man_t * p, int iObj ) +{ + Gia_Obj_t * pObj; + if ( Gia_ObjIsTravIdCurrentId(p->pNew, iObj) ) + return; + Gia_ObjSetTravIdCurrentId(p->pNew, iObj); + pObj = Gia_ManObj( p->pNew, iObj ); + if ( Cec2_ObjSatId(p->pNew, pObj) >= 0 ) + Vec_IntPush( p->vNodesNew, iObj ); + if ( !iObj ) + return; + if ( Gia_ObjIsAnd(pObj) ) + { + Cec2_ManCollect_rec( p, Gia_ObjFaninId0(pObj, iObj) ); + Cec2_ManCollect_rec( p, Gia_ObjFaninId1(pObj, iObj) ); + } + else + { + assert( Cec2_ObjSatId(p->pNew, pObj) >= 0 ); + Vec_IntPushTwo( p->vObjSatPairs, Gia_ManCiIdToId(p->pAig, Gia_ObjCioId(pObj)), Cec2_ObjSatId(p->pNew, pObj) ); // SAT var + } +} +int Cec2_ManSolveTwo( Cec2_Man_t * p, int iObj0, int iObj1, int fPhase ) +{ + Gia_Obj_t * pObj; + int status, i, iVar0, iVar1; + if (iObj1 < iObj0) + iObj1 ^= iObj0, iObj0 ^= iObj1, iObj1 ^= iObj0; + assert( iObj0 < iObj1 ); + assert( solver_varnum(p->pSat) == 0 ); + if ( !iObj0 ) + Cec2_ObjSetSatId( p->pNew, Gia_ManConst0(p->pNew), satoko_add_variable(p->pSat, 0) ); + iVar0 = Cec2_ObjGetCnfVar( p, iObj0 ); + iVar1 = Cec2_ObjGetCnfVar( p, iObj1 ); + // collect inputs and internal nodes + Vec_IntClear( p->vNodesNew ); + Vec_IntClear( p->vObjSatPairs ); + Gia_ManIncrementTravId( p->pNew ); + Cec2_ManCollect_rec( p, iObj0 ); + Cec2_ManCollect_rec( p, iObj1 ); + // solve direct + satoko_assump_push( p->pSat, Abc_Var2Lit(iVar0, 1) ); + satoko_assump_push( p->pSat, Abc_Var2Lit(iVar1, fPhase) ); + status = satoko_solve( p->pSat ); + satoko_assump_pop( p->pSat ); + satoko_assump_pop( p->pSat ); + if ( status == SATOKO_UNSAT && iObj0 > 0 ) + { + // solve reverse + satoko_assump_push( p->pSat, Abc_Var2Lit(iVar0, 0) ); + satoko_assump_push( p->pSat, Abc_Var2Lit(iVar1, !fPhase) ); + status = satoko_solve( p->pSat ); + satoko_assump_pop( p->pSat ); + satoko_assump_pop( p->pSat ); + } + Gia_ManForEachObjVec( p->vNodesNew, p->pNew, pObj, i ) + Cec2_ObjCleanSatId( p->pNew, pObj ); + return status; +} +int Cec2_ManSweepNode( Cec2_Man_t * p, int iObj ) +{ + int i, IdAig, IdSat, status, RetValue = 1; + Gia_Obj_t * pObj = Gia_ManObj( p->pAig, iObj ); + Gia_Obj_t * pRepr = Gia_ObjReprObj( p->pAig, iObj ); + int fCompl = Abc_LitIsCompl(pObj->Value) ^ Abc_LitIsCompl(pRepr->Value) ^ pObj->fPhase ^ pRepr->fPhase; + status = Cec2_ManSolveTwo( p, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl ); + if ( status == SATOKO_SAT ) + { + Vec_IntForEachEntryDouble( p->vObjSatPairs, IdAig, IdSat, i ) + Cec2_ObjSimSetPiBit( p->pAig, IdAig, var_value(p->pSat, IdSat) == LIT_TRUE ); + RetValue = 0; + } + else if ( status == SATOKO_UNSAT ) + { + pObj->Value = Abc_LitNotCond( pRepr->Value, fCompl ); + Gia_ObjSetProved( p->pAig, iObj ); + } + else + { + assert( status == SATOKO_UNDEC ); + Gia_ObjSetFailed( p->pAig, iObj ); + assert( 0 ); + } + satoko_rollback( p->pSat ); + return RetValue; +} +int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) +{ + Cec2_Man_t * pMan; + Gia_Obj_t * pObj, * pRepr, * pObjNew; + int i, fDisproved = 1; + + // check if any output trivially fails under all-0 pattern + Gia_ManSetPhase( p ); + if ( pPars->fIsMiter ) + { + Gia_ManForEachCo( p, pObj, i ) + if ( pObj->fPhase ) + { + p->pCexSeq = Cec2_ManDeriveCex( p, i, -1 ); + return 0; + } + } + // simulate one round and create classes + Cec2_ManSimAlloc( p, pPars->nSimWords ); + Cec2_ManSimulateCis( p ); + Cec2_ManSimulate( p ); + if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected + return 0; + Cec2_ManCreateClasses( p ); + if ( pPars->fVerbose ) + Gia_ManEquivPrintClasses( p, pPars->fVeryVerbose, 0 ); + + // perform additinal simulation + for ( i = 0; i < pPars->nSimRounds; i++ ) + { + Cec2_ManSimulateCis( p ); + Cec2_ManSimulate( p ); + if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected + return 0; + if ( pPars->fVerbose ) + Gia_ManEquivPrintClasses( p, pPars->fVeryVerbose, 0 ); + } + // perform sweeping + pMan = Cec2_ManCreate( p, pPars ); + while ( fDisproved ) + { + fDisproved = 0; + Cec2_ManSimulateCis( p ); + Gia_ManForEachAnd( p, pObj, i ) + { + pObj->fMark1 = 0; + if ( ~pObj->Value ) // skip swept nodes + continue; + assert( !Gia_ObjProved(p, i) && !Gia_ObjFailed(p, i) ); + pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1 || Gia_ObjFanin1(pObj)->fMark1; + if ( pObj->fMark1 ) // skip nodes in the TFO of a disproved one + continue; + // duplicate the node + pObj->Value = Gia_ManHashAnd( pMan->pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + if ( Vec_IntSize(&pMan->pNew->vCopies) == Abc_Lit2Var(pObj->Value) ) + { + pObjNew = Gia_ManObj( pMan->pNew, Abc_Lit2Var(pObj->Value) ); + pObjNew->fMark0 = Gia_ObjIsMuxType( pObjNew ); + Vec_IntPush( &pMan->pNew->vCopies, -1 ); + } + assert( Vec_IntSize(&pMan->pNew->vCopies) == Gia_ManObjNum(pMan->pNew) ); + pRepr = Gia_ObjReprObj( p, i ); + if ( pRepr == NULL || pRepr->fMark1 ) + continue; + //if ( Gia_ObjIsConst0(pRepr) ) + // continue; + if ( Abc_Lit2Var(pObj->Value) == Abc_Lit2Var(pRepr->Value) ) + { + assert( (pObj->Value ^ pRepr->Value) == (pObj->fPhase ^ pRepr->fPhase) ); + Gia_ObjSetProved( p, i ); + continue; + } + if ( Cec2_ManSweepNode(pMan, i) ) + continue; + // mark nodes as disproved + pRepr->fMark1 = pObj->fMark1 = 1; + fDisproved = 1; + } + if ( fDisproved ) + { + Cec2_ManSimulate( p ); + if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected + break; + } + if ( pPars->fVerbose ) + Gia_ManEquivPrintClasses( p, pPars->fVeryVerbose, 0 ); + } + Cec2_ManDestroy( pMan ); + return p->pCexSeq ? 0 : 1; +} +void Cec2_ManSimulateTest( Gia_Man_t * p ) +{ + abctime clk = Abc_Clock(); + Cec2_Par_t Pars, * pPars = &Pars; + Cec2_SetDefaultParams( pPars ); + Cec2_ManPerformSweeping( p, pPars ); + Abc_PrintTime( 1, "SAT sweeping time", Abc_Clock() - clk ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/cec/module.make b/src/proof/cec/module.make index 82e0de748..38106e5ea 100644 --- a/src/proof/cec/module.make +++ b/src/proof/cec/module.make @@ -6,6 +6,7 @@ SRC += src/proof/cec/cecCec.c \ src/proof/cec/cecIso.c \ src/proof/cec/cecMan.c \ src/proof/cec/cecPat.c \ + src/proof/cec/cecSat.c \ src/proof/cec/cecSeq.c \ src/proof/cec/cecSolve.c \ src/proof/cec/cecSplit.c \ diff --git a/src/sat/bmc/bmcGen.c b/src/sat/bmc/bmcGen.c index 5d84ce87b..460c9fecf 100644 --- a/src/sat/bmc/bmcGen.c +++ b/src/sat/bmc/bmcGen.c @@ -46,13 +46,13 @@ ABC_NAMESPACE_IMPL_START ***********************************************************************/ static inline word * Gia_ManMoObj( Gia_Man_t * p, int iObj ) { - return Vec_WrdEntryP( p->vSims, iObj * p->iPatsPi ); + return Vec_WrdEntryP( p->vSims, iObj * p->nSimWords ); } static inline void Gia_ManMoSetCi( Gia_Man_t * p, int iObj ) { int w; word * pSims = Gia_ManMoObj( p, iObj ); - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSims[w] = Gia_ManRandomW( 0 ); } static inline void Gia_ManMoSimAnd( Gia_Man_t * p, int iObj ) @@ -65,19 +65,19 @@ static inline void Gia_ManMoSimAnd( Gia_Man_t * p, int iObj ) if ( Gia_ObjFaninC0(pObj) ) { if ( Gia_ObjFaninC1(pObj) ) - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSims[w] = ~(pSims0[w] | pSims1[w]); else - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSims[w] = ~pSims0[w] & pSims1[w]; } else { if ( Gia_ObjFaninC1(pObj) ) - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSims[w] = pSims0[w] & ~pSims1[w]; else - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSims[w] = pSims0[w] & pSims1[w]; } } @@ -89,12 +89,12 @@ static inline void Gia_ManMoSetCo( Gia_Man_t * p, int iObj ) word * pSims0 = Gia_ManMoObj( p, Gia_ObjFaninId0(pObj, iObj) ); if ( Gia_ObjFaninC0(pObj) ) { - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSims[w] = ~pSims0[w]; } else { - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSims[w] = pSims0[w]; } } @@ -102,7 +102,7 @@ void Gia_ManMoFindSimulate( Gia_Man_t * p, int nWords ) { int i, iObj; Gia_ManRandomW( 1 ); - p->iPatsPi = nWords; + p->nSimWords = nWords; if ( p->vSims ) Vec_WrdFill( p->vSims, nWords * Gia_ManObjNum(p), 0 ); else diff --git a/src/sat/satoko/satoko.h b/src/sat/satoko/satoko.h index 88070eace..7c2f37201 100644 --- a/src/sat/satoko/satoko.h +++ b/src/sat/satoko/satoko.h @@ -83,7 +83,7 @@ extern void satoko_destroy(satoko_t *); extern void satoko_default_opts(satoko_opts_t *); extern void satoko_configure(satoko_t *, satoko_opts_t *); extern int satoko_parse_dimacs(char *, satoko_t **); -extern void satoko_add_variable(satoko_t *, char); +extern int satoko_add_variable(satoko_t *, char); extern int satoko_add_clause(satoko_t *, unsigned *, unsigned); extern void satoko_assump_push(satoko_t *s, unsigned); extern void satoko_assump_pop(satoko_t *s); diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c index 9cad0a144..e03cc084a 100644 --- a/src/sat/satoko/solver_api.c +++ b/src/sat/satoko/solver_api.c @@ -216,7 +216,7 @@ int satoko_simplify(solver_t * s) return SATOKO_OK; } -void satoko_add_variable(solver_t *s, char sign) +int satoko_add_variable(solver_t *s, char sign) { unsigned var = vec_act_size(s->activity); vec_wl_push(s->watches); @@ -231,6 +231,7 @@ void satoko_add_variable(solver_t *s, char sign) heap_insert(s->var_order, var); if (s->marks) vec_char_push_back(s->marks, 0); + return var; } int satoko_add_clause(solver_t *s, unsigned *lits, unsigned size) @@ -351,6 +352,7 @@ void satoko_rollback(satoko_t *s) clause_unwatch(s, cdb_cref(s->all_clauses, (unsigned *)cl_to_remove[i])); cl_to_remove[i]->f_mark = 1; } + satoko_free(cl_to_remove); vec_uint_shrink(s->originals, s->book_cl_orig); vec_uint_shrink(s->learnts, s->book_cl_lrnt); /* Shrink variable related vectors */ From 316238d484c867c1114bd015c025dd0d1ce2bb1a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 18 Feb 2017 14:26:31 -0800 Subject: [PATCH 159/185] Compiler warnings. --- src/aig/gia/giaUtil.c | 2 +- src/sat/satoko/satoko.h | 4 ++-- src/sat/satoko/solver_api.c | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index d64c53fa2..d100b6c1e 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -2063,7 +2063,7 @@ void Gia_AigerWriteLut( Gia_Man_t * p, char * pFileName ) ***********************************************************************/ void Gia_ManDetectMuxes( Gia_Man_t * p ) { - Gia_Obj_t * pObj, * pNodeT, * pNodeE; int i; + Gia_Obj_t * pObj = NULL, * pNodeT, * pNodeE; int i; Gia_ManForEachObj( p, pObj, i ); if ( Gia_ObjIsAnd(pObj) && Gia_ObjRecognizeMux(pObj, &pNodeT, &pNodeE) ) pObj->fMark0 = 1; diff --git a/src/sat/satoko/satoko.h b/src/sat/satoko/satoko.h index 7c2f37201..2d3e056ef 100644 --- a/src/sat/satoko/satoko.h +++ b/src/sat/satoko/satoko.h @@ -84,8 +84,8 @@ extern void satoko_default_opts(satoko_opts_t *); extern void satoko_configure(satoko_t *, satoko_opts_t *); extern int satoko_parse_dimacs(char *, satoko_t **); extern int satoko_add_variable(satoko_t *, char); -extern int satoko_add_clause(satoko_t *, unsigned *, unsigned); -extern void satoko_assump_push(satoko_t *s, unsigned); +extern int satoko_add_clause(satoko_t *, int *, int); +extern void satoko_assump_push(satoko_t *s, int); extern void satoko_assump_pop(satoko_t *s); extern int satoko_simplify(satoko_t *); extern int satoko_solve(satoko_t *); diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c index e03cc084a..e4fd88b75 100644 --- a/src/sat/satoko/solver_api.c +++ b/src/sat/satoko/solver_api.c @@ -234,7 +234,7 @@ int satoko_add_variable(solver_t *s, char sign) return var; } -int satoko_add_clause(solver_t *s, unsigned *lits, unsigned size) +int satoko_add_clause(solver_t *s, int *lits, int size) { unsigned i, j; unsigned prev_lit; @@ -249,10 +249,10 @@ int satoko_add_clause(solver_t *s, unsigned *lits, unsigned size) vec_uint_clear(s->temp_lits); j = 0; prev_lit = UNDEF; - for (i = 0; i < size; i++) { - if (lits[i] == lit_neg(prev_lit) || lit_value(s, lits[i]) == LIT_TRUE) + for (i = 0; i < (unsigned)size; i++) { + if ((unsigned)lits[i] == lit_neg(prev_lit) || lit_value(s, lits[i]) == LIT_TRUE) return SATOKO_OK; - else if (lits[i] != prev_lit && var_value(s, lit2var(lits[i])) == VAR_UNASSING) { + else if ((unsigned)lits[i] != prev_lit && var_value(s, lit2var(lits[i])) == VAR_UNASSING) { prev_lit = lits[i]; vec_uint_push_back(s->temp_lits, lits[i]); } @@ -270,7 +270,7 @@ int satoko_add_clause(solver_t *s, unsigned *lits, unsigned size) return SATOKO_OK; } -void satoko_assump_push(solver_t *s, unsigned lit) +void satoko_assump_push(solver_t *s, int lit) { vec_uint_push_back(s->assumptions, lit); } From 131c1613a4ca77c063cd677d0086a3b426868b3b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 18 Feb 2017 14:29:04 -0800 Subject: [PATCH 160/185] Compiler warnings. --- src/aig/gia/giaSatoko.c | 2 +- src/sat/satoko/cnf_reader.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/aig/gia/giaSatoko.c b/src/aig/gia/giaSatoko.c index 7cbc4184c..5e04502df 100644 --- a/src/aig/gia/giaSatoko.c +++ b/src/aig/gia/giaSatoko.c @@ -87,7 +87,7 @@ satoko_t * Gia_ManSatokoInit( Cnf_Dat_t * pCnf, satoko_opts_t * opts ) //sat_solver_setnvars( pSat, p->nVars ); for ( i = 0; i < pCnf->nClauses; i++ ) { - if ( !satoko_add_clause( pSat, (unsigned *)pCnf->pClauses[i], pCnf->pClauses[i+1]-pCnf->pClauses[i] ) ) + if ( !satoko_add_clause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1]-pCnf->pClauses[i] ) ) { satoko_destroy( pSat ); return NULL; diff --git a/src/sat/satoko/cnf_reader.c b/src/sat/satoko/cnf_reader.c index 9fbbda65a..adb9a47bd 100644 --- a/src/sat/satoko/cnf_reader.c +++ b/src/sat/satoko/cnf_reader.c @@ -141,7 +141,7 @@ int satoko_parse_dimacs(char *fname, satoko_t **solver) return -1; } read_clause(&token, lits); - if (!satoko_add_clause(p, vec_uint_data(lits), vec_uint_size(lits))) { + if (!satoko_add_clause(p, (int*)vec_uint_data(lits), vec_uint_size(lits))) { vec_uint_print(lits); return 0; } From fdc0b471e5b9a20d4bf5f603f58369aba17326c3 Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sat, 18 Feb 2017 14:38:08 -0800 Subject: [PATCH 161/185] working on incremental pdr --- src/proof/pdr/pdrIncr.c | 149 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 146 insertions(+), 3 deletions(-) diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c index d33b45ac3..c4f384f5f 100644 --- a/src/proof/pdr/pdrIncr.c +++ b/src/proof/pdr/pdrIncr.c @@ -38,6 +38,121 @@ extern int Gia_ManToBridgeResult( FILE * pFile, int Result, Abc_Cex_t * pCex, in /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void IPdr_ManPrintClauses( Vec_Vec_t * vClauses, int kStart, int nRegs ) +{ + Vec_Ptr_t * vArrayK; + Pdr_Set_t * pCube; + int i, k, Counter = 0; + Vec_VecForEachLevelStart( vClauses, vArrayK, k, kStart ) + { + Vec_PtrSort( vArrayK, (int (*)(void))Pdr_SetCompare ); + Vec_PtrForEachEntry( Pdr_Set_t *, vArrayK, pCube, i ) + { + Abc_Print( 1, "C=%4d. F=%4d ", Counter++, k ); + Pdr_SetPrint( stdout, pCube, nRegs, NULL ); + Abc_Print( 1, "\n" ); + } + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Vec_t * IPdr_ManSaveClauses( Pdr_Man_t * p ) +{ + int i, k; + Vec_Vec_t * vClausesSaved; + Pdr_Set_t * pCla; + + // Note that the last frame is empty + vClausesSaved = Vec_VecStart(Vec_VecSize(p->vClauses)-1); + Vec_VecForEachEntryStartStop( Pdr_Set_t *, p->vClauses, pCla, i, k, 0, Vec_VecSize(vClausesSaved) ) + Vec_VecPush(vClausesSaved, i, Pdr_SetDup(pCla)); + + return vClausesSaved; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +sat_solver * IPdr_ManSetSolver( Pdr_Man_t * p, int k ) +{ + sat_solver * pSat; + Vec_Ptr_t * vArrayK; + Pdr_Set_t * pCube; + int i, j; + + assert( Vec_PtrSize(p->vSolvers) == k ); + assert( Vec_IntSize(p->vActVars) == k ); + + pSat = zsat_solver_new_seed(p->pPars->nRandomSeed); + pSat = Pdr_ManNewSolver( pSat, p, k, (int)(k == 0) ); + Vec_PtrPush( p->vSolvers, pSat ); + Vec_IntPush( p->vActVars, 0 ); + + // set the property output + Pdr_ManSetPropertyOutput( p, k ); + // add the clauses + Vec_VecForEachLevelStart( p->vClauses, vArrayK, i, k ) + Vec_PtrForEachEntry( Pdr_Set_t *, vArrayK, pCube, j ) + Pdr_ManSolverAddClause( p, k, pCube ); + return pSat; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses ) +{ + int i; + + assert(vClauses); + + Vec_VecFree(p->vClauses); + p->vClauses = vClauses; + + for ( i = 0; i < Vec_VecSize(p->vClauses); ++i ) + IPdr_ManSetSolver(p, i); + + return 0; +} + /**Function************************************************************* Synopsis [] @@ -59,7 +174,7 @@ int IPdr_ManSolveInt( Pdr_Man_t * p ) int nOutDigits = Abc_Base10Log( Saig_ManPoNum(p->pAig) ); abctime clkStart = Abc_Clock(), clkOne = 0; p->timeToStop = p->pPars->nTimeOut ? p->pPars->nTimeOut * CLOCKS_PER_SEC + Abc_Clock(): 0; - assert( Vec_PtrSize(p->vSolvers) == 0 ); + // assert( Vec_PtrSize(p->vSolvers) == 0 ); // in the multi-output mode, mark trivial POs (those fed by const0) as solved if ( p->pPars->fSolveAll ) Saig_ManForEachPo( p->pAig, pObj, iFrame ) @@ -72,7 +187,13 @@ int IPdr_ManSolveInt( Pdr_Man_t * p ) } // create the first timeframe p->pPars->timeLastSolved = Abc_Clock(); - Pdr_ManCreateSolver( p, (iFrame = 0) ); + + if ( Vec_VecSize(p->vClauses) == 0 ) + Pdr_ManCreateSolver( p, (iFrame = 0) ); + else { + iFrame = Vec_VecSize(p->vClauses); + Pdr_ManCreateSolver( p, iFrame ); + } while ( 1 ) { int fRefined = 0; @@ -406,6 +527,9 @@ int IPdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) { Pdr_Man_t * p; int k, RetValue; + int i, nRegs; + Vec_Vec_t * vClausesSaved; + abctime clk = Abc_Clock(); if ( pPars->nTimeOutOne && !pPars->fSolveAll ) pPars->nTimeOutOne = 0; @@ -444,6 +568,26 @@ int IPdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) else if ( RetValue == 1 ) Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); p->tTotal += Abc_Clock() - clk; + + if (pPars->iFrame == pPars->nFrameMax) + { + vClausesSaved = IPdr_ManSaveClauses(p); + nRegs = Aig_ManRegNum(p->pAig); + + Pdr_ManStop( p ); + + printf("PDR reached the max frame: %d\n", pPars->iFrame); + IPdr_ManPrintClauses(vClausesSaved, 0, nRegs); + + p = Pdr_ManStart( pAig, pPars, NULL ); + IPdr_ManRestore( p, vClausesSaved ); + + // Solve again + pPars->nFrameMax = pPars->nFrameMax + 1; + RetValue = IPdr_ManSolveInt(p); + IPdr_ManPrintClauses(p->vClauses, 0, nRegs); + } + Pdr_ManStop( p ); pPars->iFrame--; // convert all -2 (unknown) entries into -1 (undec) @@ -457,7 +601,6 @@ int IPdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) } - /**Function************************************************************* Synopsis [] From ac409b3152bf0bb6fd49c243ae635ca288d92b06 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Sat, 18 Feb 2017 15:24:56 -0800 Subject: [PATCH 162/185] Bug fix in analyze_final method. --- src/sat/satoko/solver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sat/satoko/solver.c b/src/sat/satoko/solver.c index 21a4860d6..6554f653d 100644 --- a/src/sat/satoko/solver.c +++ b/src/sat/satoko/solver.c @@ -362,13 +362,13 @@ static inline void solver_handle_conflict(solver_t *s, unsigned confl_cref) static inline void solver_analyze_final(solver_t *s, unsigned lit) { - unsigned i; + int i; vec_uint_push_back(s->final_conflict, lit); if (solver_dlevel(s) == 0) return; vec_char_assign(s->seen, lit2var(lit), 1); - for (i = vec_uint_size(s->trail) - 1; i <= vec_uint_at(s->trail_lim, 0); i--) { + for (i = (int) vec_uint_size(s->trail) - 1; i >= (int) vec_uint_at(s->trail_lim, 0); i--) { unsigned var = lit2var(vec_uint_at(s->trail, i)); if (vec_char_at(s->seen, var)) { From 3f0cb6318b14e286cd9054a0f771183d15ef3db6 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Sat, 18 Feb 2017 17:08:54 -0800 Subject: [PATCH 163/185] New function to retrieve polarity value of a variable. --- src/sat/satoko/solver.c | 2 +- src/sat/satoko/solver.h | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/sat/satoko/solver.c b/src/sat/satoko/solver.c index 6554f653d..3e5fc8ee9 100644 --- a/src/sat/satoko/solver.c +++ b/src/sat/satoko/solver.c @@ -195,7 +195,7 @@ static inline unsigned solver_decide(solver_t *s) if (solver_has_marks(s) && !var_mark(s, next_var)) next_var = UNDEF; } - return var2lit(next_var, vec_char_at(s->polarity, next_var)); + return var2lit(next_var, var_polarity(s, next_var)); } static inline void solver_new_decision(solver_t *s, unsigned lit) diff --git a/src/sat/satoko/solver.h b/src/sat/satoko/solver.h index 68cc97dcb..dcae8f6e7 100644 --- a/src/sat/satoko/solver.h +++ b/src/sat/satoko/solver.h @@ -132,6 +132,11 @@ static inline char var_value(solver_t *s, unsigned var) return vec_char_at(s->assigns, var); } +static inline char var_polarity(solver_t *s, unsigned var) +{ + return vec_char_at(s->polarity, var); +} + static inline unsigned var_dlevel(solver_t *s, unsigned var) { return vec_uint_at(s->levels, var); From 27caed8dc812db321730ee9451a2a0788ad0ab28 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 18 Feb 2017 20:20:50 -0800 Subject: [PATCH 164/185] Experiments with SAT sweeping. --- src/base/abci/abc.c | 2 +- src/proof/cec/cecSat.c | 119 +++++++++++++++++++++++++++++------- src/sat/satoko/solver.c | 1 + src/sat/satoko/solver_api.c | 9 +++ src/sat/satoko/watch_list.h | 2 +- 5 files changed, 108 insertions(+), 25 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 52684f8cf..4c37242d7 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -43019,7 +43019,7 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv ) // Jf_ManTestCnf( pAbc->pGia ); // Gia_ManCheckFalseTest( pAbc->pGia, nFrames ); // Gia_ParTest( pAbc->pGia, nWords, nProcs ); - +Cec2_ManSimulateTest( pAbc->pGia ); // printf( "\nThis command is currently disabled.\n\n" ); return 0; usage: diff --git a/src/proof/cec/cecSat.c b/src/proof/cec/cecSat.c index 9e85e49de..aba533184 100644 --- a/src/proof/cec/cecSat.c +++ b/src/proof/cec/cecSat.c @@ -55,6 +55,7 @@ struct Cec2_Man_t_ Vec_Wrd_t * vSims; // CI simulation info Vec_Int_t * vNodesNew; // nodes Vec_Int_t * vObjSatPairs; // nodes + Vec_Int_t * vCexTriples; // nodes }; static inline int Cec2_ObjSatId( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjCopyArray(p, Gia_ObjId(p, pObj)); } @@ -352,11 +353,9 @@ static inline word * Cec2_ObjSim( Gia_Man_t * p, int iObj ) { return Vec_WrdEntryP( p->vSims, p->nSimWords * iObj ); } -static inline void Cec2_ObjSimSetPiBit( Gia_Man_t * p, int iObj, int Bit ) +static inline void Cec2_ObjSimSetInputBit( Gia_Man_t * p, int iObj, int Bit ) { word * pSim = Cec2_ObjSim( p, iObj ); - p->iPatsPi = (p->iPatsPi == 64 * p->nSimWords - 1) ? 1 : p->iPatsPi + 1; - assert( p->iPatsPi > 0 && p->iPatsPi < 64 * p->nSimWords ); if ( Abc_InfoHasBit( (unsigned*)pSim, p->iPatsPi ) != Bit ) Abc_InfoXorBit( (unsigned*)pSim, p->iPatsPi ); } @@ -421,7 +420,7 @@ static inline int Cec2_ObjSimEqual( Gia_Man_t * p, int iObj0, int iObj1 ) return 1; } } -static inline void Cec2_ObjSimPi( Gia_Man_t * p, int iObj ) +static inline void Cec2_ObjSimCi( Gia_Man_t * p, int iObj ) { int w; word * pSim = Cec2_ObjSim( p, iObj ); @@ -433,7 +432,7 @@ void Cec2_ManSimulateCis( Gia_Man_t * p ) { int i, Id; Gia_ManForEachCiId( p, Id, i ) - Cec2_ObjSimPi( p, Id ); + Cec2_ObjSimCi( p, Id ); p->iPatsPi = 1; } Abc_Cex_t * Cec2_ManDeriveCex( Gia_Man_t * p, int iOut, int iPat ) @@ -471,15 +470,28 @@ void Cec2_ManSaveCis( Gia_Man_t * p ) Gia_ManForEachCiId( p, Id, i ) Vec_WrdPush( p->vSimsPi, Cec2_ObjSim(p, Id)[w] ); } -void Cec2_ManSimulate( Gia_Man_t * p ) +void Cec2_ManSimulate( Gia_Man_t * p, Vec_Int_t * vTriples ) { extern void Cec2_ManSimClassRefineOne( Gia_Man_t * p, int iRepr ); - Gia_Obj_t * pObj; int i; - Cec2_ManSaveCis( p ); + Gia_Obj_t * pObj; + int i, iRepr, iObj, Entry; + //Cec2_ManSaveCis( p ); Gia_ManForEachAnd( p, pObj, i ) Cec2_ObjSimAnd( p, i ); if ( p->pReprs == NULL ) return; + if ( vTriples ) + { + Vec_IntForEachEntryTriple( vTriples, iRepr, iObj, Entry, i ) + { + word * pSim0 = Cec2_ObjSim( p, iRepr ); + word * pSim1 = Cec2_ObjSim( p, iObj ); + int iPat = Abc_Lit2Var(Entry); + int fPhase = Abc_LitIsCompl(Entry); + if ( (fPhase ^ Abc_InfoHasBit((unsigned *)pSim0, iPat)) == Abc_InfoHasBit((unsigned *)pSim1, iPat) ) + printf( "ERROR: Pattern %d did not disprove pair %d and %d.\n", iPat, iRepr, iObj ); + } + } Gia_ManForEachClass0( p, i ) Cec2_ManSimClassRefineOne( p, i ); } @@ -570,7 +582,8 @@ void Cec2_ManCreateClasses( Gia_Man_t * p ) int nWords = p->nSimWords; int * pTable, nTableSize, i, Key; // allocate representation - assert( p->pReprs == NULL ); + ABC_FREE( p->pReprs ); + ABC_FREE( p->pNexts ); p->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p) ); p->pNexts = ABC_FALLOC( int, Gia_ManObjNum(p) ); // hash each node by its simulation info @@ -618,7 +631,7 @@ Cec2_Man_t * Cec2_ManCreate( Gia_Man_t * pAig, Cec2_Par_t * pPars ) { Cec2_Man_t * p; Gia_Obj_t * pObj; int i; - assert( Gia_ManRegNum(pAig) == 0 ); + //assert( Gia_ManRegNum(pAig) == 0 ); p = ABC_CALLOC( Cec2_Man_t, 1 ); memset( p, 0, sizeof(Cec2_Man_t) ); p->pPars = pPars; @@ -637,6 +650,7 @@ Cec2_Man_t * Cec2_ManCreate( Gia_Man_t * pAig, Cec2_Par_t * pPars ) p->vFanins = Vec_PtrAlloc( 100 ); p->vNodesNew = Vec_IntAlloc( 100 ); p->vObjSatPairs = Vec_IntAlloc( 100 ); + p->vCexTriples = Vec_IntAlloc( 100 ); // remember pointer to the solver in the AIG manager pAig->pData = p->pSat; return p; @@ -652,10 +666,51 @@ void Cec2_ManDestroy( Cec2_Man_t * p ) Vec_PtrFreeP( &p->vFanins ); Vec_IntFreeP( &p->vNodesNew ); Vec_IntFreeP( &p->vObjSatPairs ); + Vec_IntFreeP( &p->vCexTriples ); ABC_FREE( p ); } +/**Function************************************************************* + + Synopsis [Verify counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec2_ManVerify_rec( Gia_Man_t * p, int iObj, satoko_t * pSat ) +{ + int Value0, Value1; + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + if ( iObj == 0 ) return 0; + if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) + return pObj->fMark1; + Gia_ObjSetTravIdCurrentId(p, iObj); + if ( Gia_ObjIsCi(pObj) ) + return pObj->fMark1 = var_polarity(pSat, Cec2_ObjSatId(p, pObj)) == LIT_TRUE; + assert( Gia_ObjIsAnd(pObj) ); + Value0 = Cec2_ManVerify_rec( p, Gia_ObjFaninId0(pObj, iObj), pSat ) ^ Gia_ObjFaninC0(pObj); + Value1 = Cec2_ManVerify_rec( p, Gia_ObjFaninId1(pObj, iObj), pSat ) ^ Gia_ObjFaninC1(pObj); + return pObj->fMark1 = Value0 & Value1; +} +void Cec2_ManVerify( Gia_Man_t * p, int iObj0, int iObj1, int fPhase, satoko_t * pSat ) +{ +// int val0 = var_polarity(pSat, Cec2_ObjSatId(p, Gia_ManObj(p, iObj0))) == LIT_TRUE; +// int val1 = var_polarity(pSat, Cec2_ObjSatId(p, Gia_ManObj(p, iObj1))) == LIT_TRUE; + int Value0, Value1; + Gia_ManIncrementTravId( p ); + Value0 = Cec2_ManVerify_rec( p, iObj0, pSat ); + Value1 = Cec2_ManVerify_rec( p, iObj1, pSat ); + if ( (Value0 ^ Value1) == fPhase ) + printf( "CEX verification FAILED for obj %d and obj %d.\n", iObj0, iObj1 ); +// else +// printf( "CEX verification succeeded for obj %d and obj %d.\n", iObj0, iObj1 );; +} + /**Function************************************************************* Synopsis [Internal simulation APIs.] @@ -707,6 +762,7 @@ int Cec2_ManSolveTwo( Cec2_Man_t * p, int iObj0, int iObj1, int fPhase ) Gia_ManIncrementTravId( p->pNew ); Cec2_ManCollect_rec( p, iObj0 ); Cec2_ManCollect_rec( p, iObj1 ); +//printf( "%d ", Vec_IntSize(p->vNodesNew) ); // solve direct satoko_assump_push( p->pSat, Abc_Var2Lit(iVar0, 1) ); satoko_assump_push( p->pSat, Abc_Var2Lit(iVar1, fPhase) ); @@ -722,6 +778,8 @@ int Cec2_ManSolveTwo( Cec2_Man_t * p, int iObj0, int iObj1, int fPhase ) satoko_assump_pop( p->pSat ); satoko_assump_pop( p->pSat ); } + //if ( status == SATOKO_SAT ) + // Cec2_ManVerify( p->pNew, iObj0, iObj1, fPhase, p->pSat ); Gia_ManForEachObjVec( p->vNodesNew, p->pNew, pObj, i ) Cec2_ObjCleanSatId( p->pNew, pObj ); return status; @@ -735,8 +793,10 @@ int Cec2_ManSweepNode( Cec2_Man_t * p, int iObj ) status = Cec2_ManSolveTwo( p, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl ); if ( status == SATOKO_SAT ) { + p->pAig->iPatsPi = (p->pAig->iPatsPi == 64 * p->pAig->nSimWords - 1) ? 1 : p->pAig->iPatsPi + 1; + assert( p->pAig->iPatsPi > 0 && p->pAig->iPatsPi < 64 * p->pAig->nSimWords ); Vec_IntForEachEntryDouble( p->vObjSatPairs, IdAig, IdSat, i ) - Cec2_ObjSimSetPiBit( p->pAig, IdAig, var_value(p->pSat, IdSat) == LIT_TRUE ); + Cec2_ObjSimSetInputBit( p->pAig, IdAig, var_polarity(p->pSat, IdSat) == LIT_TRUE ); RetValue = 0; } else if ( status == SATOKO_UNSAT ) @@ -751,13 +811,14 @@ int Cec2_ManSweepNode( Cec2_Man_t * p, int iObj ) assert( 0 ); } satoko_rollback( p->pSat ); + p->pSat->stats.n_conflicts = 0; return RetValue; } int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) { Cec2_Man_t * pMan; Gia_Obj_t * pObj, * pRepr, * pObjNew; - int i, fDisproved = 1; + int i, Iter, fDisproved = 1; // check if any output trivially fails under all-0 pattern Gia_ManSetPhase( p ); @@ -770,10 +831,11 @@ int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) return 0; } } + // simulate one round and create classes Cec2_ManSimAlloc( p, pPars->nSimWords ); Cec2_ManSimulateCis( p ); - Cec2_ManSimulate( p ); + Cec2_ManSimulate( p, NULL ); if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected return 0; Cec2_ManCreateClasses( p ); @@ -784,7 +846,7 @@ int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) for ( i = 0; i < pPars->nSimRounds; i++ ) { Cec2_ManSimulateCis( p ); - Cec2_ManSimulate( p ); + Cec2_ManSimulate( p, NULL ); if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected return 0; if ( pPars->fVerbose ) @@ -792,33 +854,34 @@ int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) } // perform sweeping pMan = Cec2_ManCreate( p, pPars ); - while ( fDisproved ) + for ( Iter = 0; fDisproved; Iter++ ) { fDisproved = 0; Cec2_ManSimulateCis( p ); + Vec_IntClear( pMan->vCexTriples ); Gia_ManForEachAnd( p, pObj, i ) { - pObj->fMark1 = 0; - if ( ~pObj->Value ) // skip swept nodes - continue; - assert( !Gia_ObjProved(p, i) && !Gia_ObjFailed(p, i) ); pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1 || Gia_ObjFanin1(pObj)->fMark1; if ( pObj->fMark1 ) // skip nodes in the TFO of a disproved one continue; + if ( ~pObj->Value ) // skip swept nodes + continue; + if ( !~Gia_ObjFanin0(pObj)->Value || !~Gia_ObjFanin1(pObj)->Value ) // skip fanouts of non-swept nodes + continue; + assert( !Gia_ObjProved(p, i) && !Gia_ObjFailed(p, i) ); // duplicate the node pObj->Value = Gia_ManHashAnd( pMan->pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); if ( Vec_IntSize(&pMan->pNew->vCopies) == Abc_Lit2Var(pObj->Value) ) { pObjNew = Gia_ManObj( pMan->pNew, Abc_Lit2Var(pObj->Value) ); pObjNew->fMark0 = Gia_ObjIsMuxType( pObjNew ); + Gia_ObjSetPhase( pMan->pNew, pObjNew ); Vec_IntPush( &pMan->pNew->vCopies, -1 ); } assert( Vec_IntSize(&pMan->pNew->vCopies) == Gia_ManObjNum(pMan->pNew) ); pRepr = Gia_ObjReprObj( p, i ); if ( pRepr == NULL || pRepr->fMark1 ) continue; - //if ( Gia_ObjIsConst0(pRepr) ) - // continue; if ( Abc_Lit2Var(pObj->Value) == Abc_Lit2Var(pRepr->Value) ) { assert( (pObj->Value ^ pRepr->Value) == (pObj->fPhase ^ pRepr->fPhase) ); @@ -827,13 +890,20 @@ int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) } if ( Cec2_ManSweepNode(pMan, i) ) continue; + pObj->Value = ~0; + //Vec_IntPushThree( pMan->vCexTriples, Gia_ObjId(p, pRepr), i, Abc_Var2Lit(p->iPatsPi, pObj->fPhase ^ pRepr->fPhase) ); // mark nodes as disproved - pRepr->fMark1 = pObj->fMark1 = 1; fDisproved = 1; + if ( Iter > 5 ) + continue; + if ( Gia_ObjIsAnd(pRepr) ) + pRepr->fMark1 = 1; + pObj->fMark1 = 1; } if ( fDisproved ) { - Cec2_ManSimulate( p ); + //printf( "The number of pattern = %d.\n", p->iPatsPi ); + Cec2_ManSimulate( p, pMan->vCexTriples ); if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected break; } @@ -841,6 +911,7 @@ int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) Gia_ManEquivPrintClasses( p, pPars->fVeryVerbose, 0 ); } Cec2_ManDestroy( pMan ); + //Gia_ManEquivPrintClasses( p, 1, 0 ); return p->pCexSeq ? 0 : 1; } void Cec2_ManSimulateTest( Gia_Man_t * p ) @@ -848,6 +919,8 @@ void Cec2_ManSimulateTest( Gia_Man_t * p ) abctime clk = Abc_Clock(); Cec2_Par_t Pars, * pPars = &Pars; Cec2_SetDefaultParams( pPars ); +// Gia_ManComputeGiaEquivs( p, 100000, 0 ); +// Gia_ManEquivPrintClasses( p, 1, 0 ); Cec2_ManPerformSweeping( p, pPars ); Abc_PrintTime( 1, "SAT sweeping time", Abc_Clock() - clk ); } diff --git a/src/sat/satoko/solver.c b/src/sat/satoko/solver.c index 3e5fc8ee9..3738129bc 100644 --- a/src/sat/satoko/solver.c +++ b/src/sat/satoko/solver.c @@ -364,6 +364,7 @@ static inline void solver_analyze_final(solver_t *s, unsigned lit) { int i; + vec_uint_clear(s->final_conflict); vec_uint_push_back(s->final_conflict, lit); if (solver_dlevel(s) == 0) return; diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c index e4fd88b75..f758a1ef9 100644 --- a/src/sat/satoko/solver_api.c +++ b/src/sat/satoko/solver_api.c @@ -356,10 +356,15 @@ void satoko_rollback(satoko_t *s) vec_uint_shrink(s->originals, s->book_cl_orig); vec_uint_shrink(s->learnts, s->book_cl_lrnt); /* Shrink variable related vectors */ + for (i = s->book_vars; i < 2 * vec_char_size(s->assigns); i++) + vec_wl_at(s->watches, i)->size = 0; + s->watches->size = s->book_vars; vec_act_shrink(s->activity, s->book_vars); vec_uint_shrink(s->levels, s->book_vars); vec_uint_shrink(s->reasons, s->book_vars); + vec_uint_shrink(s->stamps, s->book_vars); vec_char_shrink(s->assigns, s->book_vars); + vec_char_shrink(s->seen, s->book_vars); vec_char_shrink(s->polarity, s->book_vars); solver_rebuild_order(s); /* Rewind solver and cancel level 0 assignments to the trail */ @@ -369,6 +374,10 @@ void satoko_rollback(satoko_t *s) s->book_cl_lrnt = 0; s->book_vars = 0; s->book_trail = 0; + if (!s->book_vars) { + s->all_clauses->size = 0; + s->all_clauses->wasted = 0; + } } void satoko_mark_cone(satoko_t *s, int * pvars, int n_vars) diff --git a/src/sat/satoko/watch_list.h b/src/sat/satoko/watch_list.h index 49f419f27..a36ab2bb9 100644 --- a/src/sat/satoko/watch_list.h +++ b/src/sat/satoko/watch_list.h @@ -154,7 +154,7 @@ static inline vec_wl_t *vec_wl_alloc(unsigned cap) static inline void vec_wl_free(vec_wl_t *vec_wl) { unsigned i; - for (i = 0; i < vec_wl->size; i++) + for (i = 0; i < vec_wl->cap; i++) watch_list_free(vec_wl->watch_lists + i); satoko_free(vec_wl->watch_lists); satoko_free(vec_wl); From fc0f3b8d0dbd15b57f2159a1119b1dcf5db0aa68 Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sat, 18 Feb 2017 21:22:26 -0800 Subject: [PATCH 165/185] working on incremental pdr --- src/proof/pdr/pdrIncr.c | 72 +++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c index c4f384f5f..aa07b6681 100644 --- a/src/proof/pdr/pdrIncr.c +++ b/src/proof/pdr/pdrIncr.c @@ -527,7 +527,6 @@ int IPdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) { Pdr_Man_t * p; int k, RetValue; - int i, nRegs; Vec_Vec_t * vClausesSaved; abctime clk = Abc_Clock(); @@ -549,46 +548,49 @@ int IPdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) pPars->fSolveAll ? "yes" : "no" ); } ABC_FREE( pAig->pSeqModel ); + + p = Pdr_ManStart( pAig, pPars, NULL ); - RetValue = IPdr_ManSolveInt( p ); - if ( RetValue == 0 ) - assert( pAig->pSeqModel != NULL || p->vCexes != NULL ); - if ( p->vCexes ) - { - assert( p->pAig->vSeqModelVec == NULL ); - p->pAig->vSeqModelVec = p->vCexes; - p->vCexes = NULL; - } - if ( p->pPars->fDumpInv ) - { - char * pFileName = Extra_FileNameGenericAppend(p->pAig->pName, "_inv.pla"); - Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); - Pdr_ManDumpClauses( p, pFileName, RetValue==1 ); - } - else if ( RetValue == 1 ) - Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); - p->tTotal += Abc_Clock() - clk; + while ( 1 ) { + RetValue = IPdr_ManSolveInt( p ); - if (pPars->iFrame == pPars->nFrameMax) - { - vClausesSaved = IPdr_ManSaveClauses(p); - nRegs = Aig_ManRegNum(p->pAig); + if ( RetValue == -1 && pPars->iFrame == pPars->nFrameMax) { + vClausesSaved = IPdr_ManSaveClauses( p ); + Pdr_ManStop( p ); + + p = Pdr_ManStart( pAig, pPars, NULL ); + IPdr_ManRestore( p, vClausesSaved ); + + pPars->nFrameMax = pPars->nFrameMax << 1; + + continue; + } + + if ( RetValue == 0 ) + assert( pAig->pSeqModel != NULL || p->vCexes != NULL ); + if ( p->vCexes ) + { + assert( p->pAig->vSeqModelVec == NULL ); + p->pAig->vSeqModelVec = p->vCexes; + p->vCexes = NULL; + } + if ( p->pPars->fDumpInv ) + { + char * pFileName = Extra_FileNameGenericAppend(p->pAig->pName, "_inv.pla"); + Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); + Pdr_ManDumpClauses( p, pFileName, RetValue==1 ); + } + else if ( RetValue == 1 ) + Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); + + p->tTotal += Abc_Clock() - clk; Pdr_ManStop( p ); - printf("PDR reached the max frame: %d\n", pPars->iFrame); - IPdr_ManPrintClauses(vClausesSaved, 0, nRegs); - - p = Pdr_ManStart( pAig, pPars, NULL ); - IPdr_ManRestore( p, vClausesSaved ); - - // Solve again - pPars->nFrameMax = pPars->nFrameMax + 1; - RetValue = IPdr_ManSolveInt(p); - IPdr_ManPrintClauses(p->vClauses, 0, nRegs); + break; } - - Pdr_ManStop( p ); + + pPars->iFrame--; // convert all -2 (unknown) entries into -1 (undec) if ( pPars->vOutMap ) From 24fdcecb2d034af4d7f7c26ec083f6baf1434018 Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sun, 19 Feb 2017 09:20:44 -0800 Subject: [PATCH 166/185] started %pdra --- src/base/wlc/wlcCom.c | 117 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 97717b090..6b542b94c 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -33,6 +33,7 @@ static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ) static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbs ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandPdrAbs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbs2 ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -75,6 +76,7 @@ void Wlc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%cone", Abc_CommandCone, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%abs", Abc_CommandAbs, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%pdra", Abc_CommandPdrAbs, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%abs2", Abc_CommandAbs2, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); @@ -442,6 +444,121 @@ usage: return 1; } +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + Wlc_Par_t Pars, * pPars = &Pars; + int c; + Wlc_ManSetDefaultParams( pPars ); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIxvwh" ) ) != EOF ) + { + switch ( c ) + { + case 'A': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-A\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsAdd = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsAdd < 0 ) + goto usage; + break; + case 'M': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsMul = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsMul < 0 ) + goto usage; + break; + case 'X': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsMux = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsMux < 0 ) + goto usage; + break; + case 'F': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsFlop = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsFlop < 0 ) + goto usage; + break; + case 'I': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nIterMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nIterMax < 0 ) + goto usage; + break; + case 'x': + pPars->fXorOutput ^= 1; + break; + case 'v': + pPars->fVerbose ^= 1; + break; + case 'w': + pPars->fPdrVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" ); + return 0; + } + Wlc_NtkAbsCore( pNtk, pPars ); + return 0; +usage: + Abc_Print( -2, "usage: %%pdra [-AMXFI num] [-xvwh]\n" ); + Abc_Print( -2, "\t abstraction for word-level networks\n" ); + Abc_Print( -2, "\t-A num : minimum bit-width of an adder/subtractor to abstract [default = %d]\n", pPars->nBitsAdd ); + Abc_Print( -2, "\t-M num : minimum bit-width of a multiplier to abstract [default = %d]\n", pPars->nBitsMul ); + Abc_Print( -2, "\t-X num : minimum bit-width of a MUX operator to abstract [default = %d]\n", pPars->nBitsMux ); + Abc_Print( -2, "\t-F num : minimum bit-width of a flip-flop to abstract [default = %d]\n", pPars->nBitsFlop ); + Abc_Print( -2, "\t-I num : maximum number of CEGAR iterations [default = %d]\n", pPars->nIterMax ); + Abc_Print( -2, "\t-x : toggle XORing outputs of word-level miter [default = %s]\n", pPars->fXorOutput? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-w : toggle printing verbose PDR output [default = %s]\n", pPars->fPdrVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + + /**Function******************************************************************** Synopsis [] From 6cf289dadd41354eb03ef1fa0a4d366ab5f62f8c Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sun, 19 Feb 2017 09:55:58 -0800 Subject: [PATCH 167/185] working on pdr with wla --- src/base/wlc/wlc.h | 1 + src/base/wlc/wlcAbs.c | 111 ++++++++++++++++++++++++++++++++++++++++ src/base/wlc/wlcCom.c | 2 +- src/proof/pdr/pdrIncr.c | 11 ++-- 4 files changed, 120 insertions(+), 5 deletions(-) diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 91dc05730..9ca569173 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -277,6 +277,7 @@ static inline Wlc_Obj_t * Wlc_ObjCo2PoFo( Wlc_Ntk_t * p, int iCoId ) /*=== wlcAbs.c ========================================================*/ extern int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); +extern int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcAbs2.c ========================================================*/ extern int Wlc_NtkAbsCore2( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcBlast.c ========================================================*/ diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 318df4dd4..cfd1155d3 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -283,6 +283,117 @@ static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec return nNodes; } +/**Function************************************************************* + + Synopsis [Performs PDR with word-level abstraction.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) +{ + abctime clk = Abc_Clock(); + int nIters, nNodes, nDcFlops, RetValue = -1; + // start the bitmap to mark objects that cannot be abstracted because of refinement + // currently, this bitmap is empty because abstraction begins without refinement + Vec_Bit_t * vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(p) ); + // set up parameters to run PDR + Pdr_Par_t PdrPars, * pPdrPars = &PdrPars; + Pdr_ManSetDefaultParams( pPdrPars ); + pPdrPars->fVerbose = pPars->fPdrVerbose; + + // perform refinement iterations + for ( nIters = 1; nIters < pPars->nIterMax; nIters++ ) + { + Aig_Man_t * pAig; + Abc_Cex_t * pCex; + Vec_Int_t * vPisNew, * vRefine; + Gia_Man_t * pGia, * pTemp; + Wlc_Ntk_t * pAbs; + + if ( pPars->fVerbose ) + printf( "\nIteration %d:\n", nIters ); + + // get abstracted GIA and the set of pseudo-PIs (vPisNew) + pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, pPars->fVerbose ); + pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 ); + + // if the abstraction has flops with DC-init state, + // new PIs were introduced by bit-blasting at the end of the PI list + // here we move these variables to be *before* PPIs, because + // PPIs are supposed to be at the end of the PI list for refinement + nDcFlops = Wlc_NtkDcFlopNum(pAbs); + if ( nDcFlops > 0 ) // DC-init flops are present + { + pGia = Gia_ManPermuteInputs( pTemp = pGia, Wlc_NtkCountObjBits(p, vPisNew), nDcFlops ); + Gia_ManStop( pTemp ); + } + // if the word-level outputs have to be XORs, this is a place to do it + if ( pPars->fXorOutput ) + { + pGia = Gia_ManTransformMiter2( pTemp = pGia ); + Gia_ManStop( pTemp ); + } + if ( pPars->fVerbose ) + { + printf( "Derived abstraction with %d objects and %d PPIs. Bit-blasted AIG stats are:\n", Wlc_NtkObjNum(pAbs), Vec_IntSize(vPisNew) ); + Gia_ManPrintStats( pGia, NULL ); + } + Wlc_NtkFree( pAbs ); + + // try to prove abstracted GIA by converting it to AIG and calling PDR + pAig = Gia_ManToAigSimple( pGia ); + RetValue = Pdr_ManSolve( pAig, pPdrPars ); + pCex = pAig->pSeqModel; pAig->pSeqModel = NULL; + Aig_ManStop( pAig ); + + // consider outcomes + if ( pCex == NULL ) + { + assert( RetValue ); // proved or undecided + Gia_ManStop( pGia ); + Vec_IntFree( vPisNew ); + break; + } + + // perform refinement + vRefine = Wlc_NtkAbsRefinement( p, pGia, pCex, vPisNew ); + Gia_ManStop( pGia ); + Vec_IntFree( vPisNew ); + if ( vRefine == NULL ) // real CEX + { + Abc_CexFree( pCex ); // return CEX in the future + break; + } + + // update the set of objects to be un-abstracted + nNodes = Wlc_NtkRemoveFromAbstraction( p, vRefine, vUnmark ); + if ( pPars->fVerbose ) + printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs, whose MFFCs include %d objects.\n", pCex->iFrame, Vec_IntSize(vRefine), nNodes ); + Vec_IntFree( vRefine ); + Abc_CexFree( pCex ); + } + + Vec_BitFree( vUnmark ); + // report the result + if ( pPars->fVerbose ) + printf( "\n" ); + printf( "Abstraction " ); + if ( RetValue == 0 ) + printf( "resulted in a real CEX" ); + else if ( RetValue == 1 ) + printf( "is successfully proved" ); + else + printf( "timed out" ); + printf( " after %d iterations. ", nIters ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + return RetValue; +} + /**Function************************************************************* Synopsis [Performs abstraction.] diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 6b542b94c..e980752b6 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -541,7 +541,7 @@ int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" ); return 0; } - Wlc_NtkAbsCore( pNtk, pPars ); + Wlc_NtkPdrAbs( pNtk, pPars ); return 0; usage: Abc_Print( -2, "usage: %%pdra [-AMXFI num] [-xvwh]\n" ); diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c index aa07b6681..2a7185772 100644 --- a/src/proof/pdr/pdrIncr.c +++ b/src/proof/pdr/pdrIncr.c @@ -77,14 +77,17 @@ void IPdr_ManPrintClauses( Vec_Vec_t * vClauses, int kStart, int nRegs ) SeeAlso [] ***********************************************************************/ -Vec_Vec_t * IPdr_ManSaveClauses( Pdr_Man_t * p ) +Vec_Vec_t * IPdr_ManSaveClauses( Pdr_Man_t * p, int fDropLast ) { int i, k; Vec_Vec_t * vClausesSaved; Pdr_Set_t * pCla; - // Note that the last frame is empty - vClausesSaved = Vec_VecStart(Vec_VecSize(p->vClauses)-1); + if ( fDropLast ) + vClausesSaved = Vec_VecStart( Vec_VecSize(p->vClauses)-1 ); + else + vClausesSaved = Vec_VecStart( Vec_VecSize(p->vClauses) ); + Vec_VecForEachEntryStartStop( Pdr_Set_t *, p->vClauses, pCla, i, k, 0, Vec_VecSize(vClausesSaved) ) Vec_VecPush(vClausesSaved, i, Pdr_SetDup(pCla)); @@ -555,7 +558,7 @@ int IPdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) RetValue = IPdr_ManSolveInt( p ); if ( RetValue == -1 && pPars->iFrame == pPars->nFrameMax) { - vClausesSaved = IPdr_ManSaveClauses( p ); + vClausesSaved = IPdr_ManSaveClauses( p, 1 ); Pdr_ManStop( p ); From 840f5d1ca8d8d51fa28c2ac3cd7bc9dd2e245f29 Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sun, 19 Feb 2017 10:22:15 -0800 Subject: [PATCH 168/185] working on pdr with wla --- src/base/wlc/wlcAbs.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index cfd1155d3..b6571e53d 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -20,6 +20,7 @@ #include "wlc.h" #include "proof/pdr/pdr.h" +#include "proof/pdr/pdrInt.h" #include "aig/gia/giaAig.h" #include "sat/bmc/bmc.h" @@ -29,6 +30,10 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +extern Vec_Vec_t * IPdr_ManSaveClauses( Pdr_Man_t * p, int fDropLast ); +extern int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses ); +extern int IPdr_ManSolveInt( Pdr_Man_t * p ); + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -297,6 +302,8 @@ static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) { abctime clk = Abc_Clock(); + Pdr_Man_t * pPdr; + Vec_Vec_t * vClauses = NULL; int nIters, nNodes, nDcFlops, RetValue = -1; // start the bitmap to mark objects that cannot be abstracted because of refinement // currently, this bitmap is empty because abstraction begins without refinement @@ -347,9 +354,14 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) // try to prove abstracted GIA by converting it to AIG and calling PDR pAig = Gia_ManToAigSimple( pGia ); - RetValue = Pdr_ManSolve( pAig, pPdrPars ); + + pPdr = Pdr_ManStart( pAig, pPdrPars, NULL ); + if (vClauses) + IPdr_ManRestore(pPdr, vClauses); + + RetValue = IPdr_ManSolveInt( pPdr ); + pCex = pAig->pSeqModel; pAig->pSeqModel = NULL; - Aig_ManStop( pAig ); // consider outcomes if ( pCex == NULL ) @@ -357,6 +369,8 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) assert( RetValue ); // proved or undecided Gia_ManStop( pGia ); Vec_IntFree( vPisNew ); + Pdr_ManStop( pPdr ); + Aig_ManStop( pAig ); break; } @@ -367,15 +381,22 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) if ( vRefine == NULL ) // real CEX { Abc_CexFree( pCex ); // return CEX in the future + Pdr_ManStop( pPdr ); + Aig_ManStop( pAig ); break; } + // spurious CEX, continue solving + vClauses = IPdr_ManSaveClauses( pPdr, 0 ); + Pdr_ManStop( pPdr ); + // update the set of objects to be un-abstracted nNodes = Wlc_NtkRemoveFromAbstraction( p, vRefine, vUnmark ); if ( pPars->fVerbose ) printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs, whose MFFCs include %d objects.\n", pCex->iFrame, Vec_IntSize(vRefine), nNodes ); Vec_IntFree( vRefine ); Abc_CexFree( pCex ); + Aig_ManStop( pAig ); } Vec_BitFree( vUnmark ); From 2732cbc1ee3b82fa7f609ef4c7156132058612dc Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sun, 19 Feb 2017 12:31:28 -0800 Subject: [PATCH 169/185] working on pdr with wla --- src/base/wlc/wlcAbs.c | 30 +++++++++++++++++++++++++----- src/proof/pdr/pdrIncr.c | 3 +++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index b6571e53d..342d667f1 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -133,6 +133,17 @@ static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * Wlc_NtkCleanMarks( p ); Wlc_NtkForEachCo( p, pObj, i ) Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vPisOld, vPisNew, vFlops ); + + + Vec_IntClear(vFlops); + Wlc_NtkForEachCi( p, pObj, i ) { + if ( !Wlc_ObjIsPi(pObj) ) { + Vec_IntPush( vFlops, Wlc_ObjId(p, pObj) ); + pObj->Mark = 1; + } + } + + Wlc_NtkForEachObjVec( vFlops, p, pObj, i ) Wlc_NtkAbsMarkNodes_rec( p, Wlc_ObjFo2Fi(p, pObj), vLeaves, vPisOld, vPisNew, vFlops ); Wlc_NtkForEachObj( p, pObj, i ) @@ -312,6 +323,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) Pdr_Par_t PdrPars, * pPdrPars = &PdrPars; Pdr_ManSetDefaultParams( pPdrPars ); pPdrPars->fVerbose = pPars->fPdrVerbose; + pPdrPars->fVeryVerbose = 1; // perform refinement iterations for ( nIters = 1; nIters < pPars->nIterMax; nIters++ ) @@ -356,8 +368,15 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) pAig = Gia_ManToAigSimple( pGia ); pPdr = Pdr_ManStart( pAig, pPdrPars, NULL ); - if (vClauses) - IPdr_ManRestore(pPdr, vClauses); + if ( vClauses ) { + if ( Vec_VecSize( vClauses) == 1 ) { + Vec_VecFree( vClauses ); + vClauses = NULL; + } else { + assert( Vec_VecSize( vClauses) >= 2 ); + IPdr_ManRestore(pPdr, vClauses); + } + } RetValue = IPdr_ManSolveInt( pPdr ); @@ -441,11 +460,12 @@ int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) // set up parameters to run PDR Pdr_Par_t PdrPars, * pPdrPars = &PdrPars; Pdr_ManSetDefaultParams( pPdrPars ); - pPdrPars->fUseAbs = 1; // use 'pdr -t' (on-the-fly abstraction) - pPdrPars->fCtgs = 1; // use 'pdr -nc' (improved generalization) - pPdrPars->fSkipDown = 0; // use 'pdr -nc' (improved generalization) + //pPdrPars->fUseAbs = 1; // use 'pdr -t' (on-the-fly abstraction) + //pPdrPars->fCtgs = 1; // use 'pdr -nc' (improved generalization) + //pPdrPars->fSkipDown = 0; // use 'pdr -nc' (improved generalization) //pPdrPars->nRestLimit = 500; // reset queue or proof-obligations when it gets larger than this pPdrPars->fVerbose = pPars->fPdrVerbose; + pPdrPars->fVeryVerbose = 1; // perform refinement iterations for ( nIters = 1; nIters < pPars->nIterMax; nIters++ ) { diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c index 2a7185772..b1f126f41 100644 --- a/src/proof/pdr/pdrIncr.c +++ b/src/proof/pdr/pdrIncr.c @@ -147,6 +147,9 @@ int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses ) assert(vClauses); + printf( "IPdr restore:\n" ); + IPdr_ManPrintClauses( vClauses, 0, Aig_ManRegNum( p->pAig ) ); + Vec_VecFree(p->vClauses); p->vClauses = vClauses; From 99fe7dfe2906cafad8fafc104b23e6ec8416ce4e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 19 Feb 2017 12:51:38 -0800 Subject: [PATCH 170/185] Experiments with SAT sweeping. --- src/proof/cec/cecSat.c | 89 +++++++++++++++++++++++++++++++++--------- 1 file changed, 71 insertions(+), 18 deletions(-) diff --git a/src/proof/cec/cecSat.c b/src/proof/cec/cecSat.c index aba533184..883975505 100644 --- a/src/proof/cec/cecSat.c +++ b/src/proof/cec/cecSat.c @@ -56,6 +56,17 @@ struct Cec2_Man_t_ Vec_Int_t * vNodesNew; // nodes Vec_Int_t * vObjSatPairs; // nodes Vec_Int_t * vCexTriples; // nodes + // statistics + int nSatSat; + int nSatUnsat; + int nSatUndec; + abctime timeSatSat; + abctime timeSatUnsat; + abctime timeSatUndec; + abctime timeSim; + abctime timeRefine; + abctime timeExtra; + abctime timeStart; }; static inline int Cec2_ObjSatId( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjCopyArray(p, Gia_ObjId(p, pObj)); } @@ -470,14 +481,16 @@ void Cec2_ManSaveCis( Gia_Man_t * p ) Gia_ManForEachCiId( p, Id, i ) Vec_WrdPush( p->vSimsPi, Cec2_ObjSim(p, Id)[w] ); } -void Cec2_ManSimulate( Gia_Man_t * p, Vec_Int_t * vTriples ) +void Cec2_ManSimulate( Gia_Man_t * p, Vec_Int_t * vTriples, Cec2_Man_t * pMan ) { extern void Cec2_ManSimClassRefineOne( Gia_Man_t * p, int iRepr ); + abctime clk = Abc_Clock(); Gia_Obj_t * pObj; int i, iRepr, iObj, Entry; //Cec2_ManSaveCis( p ); Gia_ManForEachAnd( p, pObj, i ) Cec2_ObjSimAnd( p, i ); + pMan->timeSim += Abc_Clock() - clk; if ( p->pReprs == NULL ) return; if ( vTriples ) @@ -492,8 +505,10 @@ void Cec2_ManSimulate( Gia_Man_t * p, Vec_Int_t * vTriples ) printf( "ERROR: Pattern %d did not disprove pair %d and %d.\n", iPat, iRepr, iObj ); } } + clk = Abc_Clock(); Gia_ManForEachClass0( p, i ) Cec2_ManSimClassRefineOne( p, i ); + pMan->timeRefine += Abc_Clock() - clk; } void Cec2_ManSimAlloc( Gia_Man_t * p, int nWords ) { @@ -576,8 +591,9 @@ void Cec2_ManSimClassRefineOne( Gia_Man_t * p, int iRepr ) Gia_ObjSetNext( p, iPrev, -1 ); Gia_ObjSetNext( p, iPrev2, -1 ); } -void Cec2_ManCreateClasses( Gia_Man_t * p ) +void Cec2_ManCreateClasses( Gia_Man_t * p, Cec2_Man_t * pMan ) { + abctime clk; Gia_Obj_t * pObj; int nWords = p->nSimWords; int * pTable, nTableSize, i, Key; @@ -611,8 +627,10 @@ void Cec2_ManCreateClasses( Gia_Man_t * p ) Gia_ObjSetNext( p, iRepr, i ); } ABC_FREE( pTable ); + clk = Abc_Clock(); Gia_ManForEachClass0( p, i ) Cec2_ManSimClassRefineOne( p, i ); + pMan->timeRefine += Abc_Clock() - clk; } @@ -634,6 +652,7 @@ Cec2_Man_t * Cec2_ManCreate( Gia_Man_t * pAig, Cec2_Par_t * pPars ) //assert( Gia_ManRegNum(pAig) == 0 ); p = ABC_CALLOC( Cec2_Man_t, 1 ); memset( p, 0, sizeof(Cec2_Man_t) ); + p->timeStart = Abc_Clock(); p->pPars = pPars; p->pAig = pAig; // create new manager @@ -657,6 +676,24 @@ Cec2_Man_t * Cec2_ManCreate( Gia_Man_t * pAig, Cec2_Par_t * pPars ) } void Cec2_ManDestroy( Cec2_Man_t * p ) { + if ( p->pPars->fVerbose ) + { + abctime timeTotal = Abc_Clock() - p->timeStart; + abctime timeSat = p->timeSatSat + p->timeSatUnsat + p->timeSatUndec; + abctime timeOther = timeTotal - timeSat - p->timeSim - p->timeRefine - p->timeExtra; +// Abc_Print( 1, "%d\n", p->Num ); + ABC_PRTP( "SAT solving", timeSat, timeTotal ); + ABC_PRTP( " sat ", p->timeSatSat, timeTotal ); + ABC_PRTP( " unsat ", p->timeSatUnsat, timeTotal ); + ABC_PRTP( " fail ", p->timeSatUndec, timeTotal ); + ABC_PRTP( "Simulation ", p->timeSim, timeTotal ); + ABC_PRTP( "Refinement ", p->timeRefine, timeTotal ); + ABC_PRTP( "Rollback ", p->timeExtra, timeTotal ); + ABC_PRTP( "Other ", timeOther, timeTotal ); + ABC_PRTP( "TOTAL ", timeTotal, timeTotal ); + fflush( stdout ); + } + Vec_WrdFreeP( &p->pAig->vSims ); //Vec_WrdFreeP( &p->pAig->vSimsPi ); Gia_ManCleanMark01( p->pAig ); @@ -784,8 +821,10 @@ int Cec2_ManSolveTwo( Cec2_Man_t * p, int iObj0, int iObj1, int fPhase ) Cec2_ObjCleanSatId( p->pNew, pObj ); return status; } + int Cec2_ManSweepNode( Cec2_Man_t * p, int iObj ) { + abctime clk = Abc_Clock(); int i, IdAig, IdSat, status, RetValue = 1; Gia_Obj_t * pObj = Gia_ManObj( p->pAig, iObj ); Gia_Obj_t * pRepr = Gia_ObjReprObj( p->pAig, iObj ); @@ -793,30 +832,47 @@ int Cec2_ManSweepNode( Cec2_Man_t * p, int iObj ) status = Cec2_ManSolveTwo( p, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl ); if ( status == SATOKO_SAT ) { + p->nSatSat++; p->pAig->iPatsPi = (p->pAig->iPatsPi == 64 * p->pAig->nSimWords - 1) ? 1 : p->pAig->iPatsPi + 1; assert( p->pAig->iPatsPi > 0 && p->pAig->iPatsPi < 64 * p->pAig->nSimWords ); Vec_IntForEachEntryDouble( p->vObjSatPairs, IdAig, IdSat, i ) Cec2_ObjSimSetInputBit( p->pAig, IdAig, var_polarity(p->pSat, IdSat) == LIT_TRUE ); RetValue = 0; + p->timeSatSat += Abc_Clock() - clk; } else if ( status == SATOKO_UNSAT ) { + p->nSatUnsat++; pObj->Value = Abc_LitNotCond( pRepr->Value, fCompl ); Gia_ObjSetProved( p->pAig, iObj ); + p->timeSatUnsat += Abc_Clock() - clk; } else { + p->nSatUndec++; assert( status == SATOKO_UNDEC ); Gia_ObjSetFailed( p->pAig, iObj ); assert( 0 ); + p->timeSatUndec += Abc_Clock() - clk; } + clk = Abc_Clock(); satoko_rollback( p->pSat ); + p->timeExtra += Abc_Clock() - clk; p->pSat->stats.n_conflicts = 0; return RetValue; } +void Cec2_ManPrintStats( Gia_Man_t * p, Cec2_Par_t * pPars, Cec2_Man_t * pMan ) +{ + if ( !pPars->fVerbose ) + return; + printf( "S =%5d ", pMan ? pMan->nSatSat : 0 ); + printf( "U =%5d ", pMan ? pMan->nSatUnsat : 0 ); + printf( "F =%5d ", pMan ? pMan->nSatUndec : 0 ); + Gia_ManEquivPrintClasses( p, pPars->fVeryVerbose, 0 ); +} int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) { - Cec2_Man_t * pMan; + Cec2_Man_t * pMan = Cec2_ManCreate( p, pPars ); Gia_Obj_t * pObj, * pRepr, * pObjNew; int i, Iter, fDisproved = 1; @@ -835,25 +891,23 @@ int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) // simulate one round and create classes Cec2_ManSimAlloc( p, pPars->nSimWords ); Cec2_ManSimulateCis( p ); - Cec2_ManSimulate( p, NULL ); + Cec2_ManSimulate( p, NULL, pMan ); if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected return 0; - Cec2_ManCreateClasses( p ); - if ( pPars->fVerbose ) - Gia_ManEquivPrintClasses( p, pPars->fVeryVerbose, 0 ); + Cec2_ManCreateClasses( p, pMan ); + Cec2_ManPrintStats( p, pPars, pMan ); // perform additinal simulation for ( i = 0; i < pPars->nSimRounds; i++ ) { Cec2_ManSimulateCis( p ); - Cec2_ManSimulate( p, NULL ); + Cec2_ManSimulate( p, NULL, pMan ); if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected return 0; - if ( pPars->fVerbose ) - Gia_ManEquivPrintClasses( p, pPars->fVeryVerbose, 0 ); + Cec2_ManPrintStats( p, pPars, pMan ); } // perform sweeping - pMan = Cec2_ManCreate( p, pPars ); + //pMan = Cec2_ManCreate( p, pPars ); for ( Iter = 0; fDisproved; Iter++ ) { fDisproved = 0; @@ -880,7 +934,7 @@ int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) } assert( Vec_IntSize(&pMan->pNew->vCopies) == Gia_ManObjNum(pMan->pNew) ); pRepr = Gia_ObjReprObj( p, i ); - if ( pRepr == NULL || pRepr->fMark1 ) + if ( pRepr == NULL || pRepr->fMark1 || !~pRepr->Value ) continue; if ( Abc_Lit2Var(pObj->Value) == Abc_Lit2Var(pRepr->Value) ) { @@ -894,7 +948,7 @@ int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) //Vec_IntPushThree( pMan->vCexTriples, Gia_ObjId(p, pRepr), i, Abc_Var2Lit(p->iPatsPi, pObj->fPhase ^ pRepr->fPhase) ); // mark nodes as disproved fDisproved = 1; - if ( Iter > 5 ) + //if ( Iter > 5 ) continue; if ( Gia_ObjIsAnd(pRepr) ) pRepr->fMark1 = 1; @@ -903,12 +957,11 @@ int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) if ( fDisproved ) { //printf( "The number of pattern = %d.\n", p->iPatsPi ); - Cec2_ManSimulate( p, pMan->vCexTriples ); + Cec2_ManSimulate( p, pMan->vCexTriples, pMan ); if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected break; } - if ( pPars->fVerbose ) - Gia_ManEquivPrintClasses( p, pPars->fVeryVerbose, 0 ); + Cec2_ManPrintStats( p, pPars, pMan ); } Cec2_ManDestroy( pMan ); //Gia_ManEquivPrintClasses( p, 1, 0 ); @@ -916,13 +969,13 @@ int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) } void Cec2_ManSimulateTest( Gia_Man_t * p ) { - abctime clk = Abc_Clock(); + //abctime clk = Abc_Clock(); Cec2_Par_t Pars, * pPars = &Pars; Cec2_SetDefaultParams( pPars ); // Gia_ManComputeGiaEquivs( p, 100000, 0 ); // Gia_ManEquivPrintClasses( p, 1, 0 ); Cec2_ManPerformSweeping( p, pPars ); - Abc_PrintTime( 1, "SAT sweeping time", Abc_Clock() - clk ); + //Abc_PrintTime( 1, "SAT sweeping time", Abc_Clock() - clk ); } From 68dd7806355a423af3ea400ab7c605bd3bf566d3 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Sun, 19 Feb 2017 15:34:21 -0800 Subject: [PATCH 171/185] Adding new command to reset Satoko. Small fixes in watching list data structure. --- src/sat/satoko/cdb.h | 6 +++++ src/sat/satoko/satoko.h | 2 ++ src/sat/satoko/solver_api.c | 48 +++++++++++++++++++++++++++++++++---- src/sat/satoko/types.h | 1 + src/sat/satoko/utils/heap.h | 5 +--- src/sat/satoko/watch_list.h | 10 ++++++++ 6 files changed, 63 insertions(+), 9 deletions(-) diff --git a/src/sat/satoko/cdb.h b/src/sat/satoko/cdb.h index 28686ff27..32b0bf93b 100644 --- a/src/sat/satoko/cdb.h +++ b/src/sat/satoko/cdb.h @@ -81,6 +81,12 @@ static inline void cdb_remove(struct cdb *p, struct clause *clause) p->wasted += clause->size; } +static inline void cdb_clear(struct cdb *p) +{ + p->wasted = 0; + p->size = 0; +} + static inline unsigned cdb_capacity(struct cdb *p) { return p->cap; diff --git a/src/sat/satoko/satoko.h b/src/sat/satoko/satoko.h index 2d3e056ef..a0c4d216d 100644 --- a/src/sat/satoko/satoko.h +++ b/src/sat/satoko/satoko.h @@ -80,6 +80,8 @@ struct satoko_stats { //===------------------------------------------------------------------------=== extern satoko_t *satoko_create(void); extern void satoko_destroy(satoko_t *); +extern void satoko_reset(satoko_t *); + extern void satoko_default_opts(satoko_opts_t *); extern void satoko_configure(satoko_t *, satoko_opts_t *); extern int satoko_parse_dimacs(char *, satoko_t **); diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c index f758a1ef9..90d04cfd7 100644 --- a/src/sat/satoko/solver_api.c +++ b/src/sat/satoko/solver_api.c @@ -334,6 +334,41 @@ void satoko_unbookmark(satoko_t *s) s->book_trail = 0; } +void satoko_reset(satoko_t *s) +{ + vec_uint_clear(s->assumptions); + vec_uint_clear(s->final_conflict); + cdb_clear(s->all_clauses); + vec_uint_clear(s->originals); + vec_uint_clear(s->learnts); + vec_wl_clean(s->watches); + vec_act_clear(s->activity); + heap_clear(s->var_order); + vec_uint_clear(s->levels); + vec_uint_clear(s->reasons); + vec_char_clear(s->assigns); + vec_char_clear(s->polarity); + vec_uint_clear(s->trail); + vec_uint_clear(s->trail_lim); + b_queue_clean(s->bq_lbd); + b_queue_clean(s->bq_trail); + vec_uint_clear(s->temp_lits); + vec_char_clear(s->seen); + vec_uint_clear(s->tagged); + vec_uint_clear(s->stack); + vec_uint_clear(s->last_dlevel); + vec_uint_clear(s->stamps); + s->var_act_inc = VAR_ACT_INIT_INC; + s->clause_act_inc = CLAUSE_ACT_INIT_INC; + s->n_confl_bfr_reduce = s->opts.n_conf_fst_reduce; + s->RC1 = 1; + s->RC2 = s->opts.n_conf_fst_reduce; + s->book_cl_orig = 0; + s->book_cl_lrnt = 0; + s->book_vars = 0; + s->book_trail = 0; +} + void satoko_rollback(satoko_t *s) { unsigned i, cref; @@ -342,6 +377,11 @@ void satoko_rollback(satoko_t *s) struct clause **cl_to_remove; assert(solver_dlevel(s) == 0); + if (!s->book_vars) { + satoko_reset(s); + return; + } + cl_to_remove = satoko_alloc(struct clause *, n_originals + n_learnts); /* Mark clauses */ vec_uint_foreach_start(s->originals, cref, i, s->book_cl_orig) @@ -356,8 +396,10 @@ void satoko_rollback(satoko_t *s) vec_uint_shrink(s->originals, s->book_cl_orig); vec_uint_shrink(s->learnts, s->book_cl_lrnt); /* Shrink variable related vectors */ - for (i = s->book_vars; i < 2 * vec_char_size(s->assigns); i++) + for (i = s->book_vars; i < 2 * vec_char_size(s->assigns); i++) { vec_wl_at(s->watches, i)->size = 0; + vec_wl_at(s->watches, i)->n_bin = 0; + } s->watches->size = s->book_vars; vec_act_shrink(s->activity, s->book_vars); vec_uint_shrink(s->levels, s->book_vars); @@ -374,10 +416,6 @@ void satoko_rollback(satoko_t *s) s->book_cl_lrnt = 0; s->book_vars = 0; s->book_trail = 0; - if (!s->book_vars) { - s->all_clauses->size = 0; - s->all_clauses->wasted = 0; - } } void satoko_mark_cone(satoko_t *s, int * pvars, int n_vars) diff --git a/src/sat/satoko/types.h b/src/sat/satoko/types.h index 9c47ca7c8..06c190ab8 100644 --- a/src/sat/satoko/types.h +++ b/src/sat/satoko/types.h @@ -26,6 +26,7 @@ typedef vec_sdbl_t vec_act_t ; #define vec_act_free(vec) vec_sdbl_free(vec) #define vec_act_size(vec) vec_sdbl_size(vec) #define vec_act_data(vec) vec_sdbl_data(vec) +#define vec_act_clear(vec) vec_sdbl_clear(vec) #define vec_act_shrink(vec, size) vec_sdbl_shrink(vec, size) #define vec_act_at(vec, idx) vec_sdbl_at(vec, idx) #define vec_act_push_back(vec, value) vec_sdbl_push_back(vec, value) diff --git a/src/sat/satoko/utils/heap.h b/src/sat/satoko/utils/heap.h index 8b1d8f4b7..391b8a7e4 100644 --- a/src/sat/satoko/utils/heap.h +++ b/src/sat/satoko/utils/heap.h @@ -158,10 +158,7 @@ static inline void heap_build(heap_t *p, vec_uint_t *entries) static inline void heap_clear(heap_t *p) { - unsigned i; - int entry; - vec_int_foreach(p->indices, entry, i) - vec_int_assign(p->indices, i, -1); + vec_int_clear(p->indices); vec_uint_clear(p->data); } diff --git a/src/sat/satoko/watch_list.h b/src/sat/satoko/watch_list.h index a36ab2bb9..1bcbf3b43 100644 --- a/src/sat/satoko/watch_list.h +++ b/src/sat/satoko/watch_list.h @@ -160,6 +160,16 @@ static inline void vec_wl_free(vec_wl_t *vec_wl) satoko_free(vec_wl); } +static inline void vec_wl_clean(vec_wl_t *vec_wl) +{ + unsigned i; + for (i = 0; i < vec_wl->size; i++) { + vec_wl->watch_lists[i].size = 0; + vec_wl->watch_lists[i].n_bin = 0; + } + vec_wl->size = 0; +} + static inline void vec_wl_push(vec_wl_t *vec_wl) { if (vec_wl->size == vec_wl->cap) { From 2d1792040a8c09a12d70413ceb99bd11bb145c2b Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sun, 19 Feb 2017 15:57:13 -0800 Subject: [PATCH 172/185] working on pdr with wla --- src/base/wlc/wlcAbs.c | 16 ++++++-------- src/proof/pdr/pdrIncr.c | 47 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 15 deletions(-) diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 342d667f1..8cc79722e 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -323,7 +323,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) Pdr_Par_t PdrPars, * pPdrPars = &PdrPars; Pdr_ManSetDefaultParams( pPdrPars ); pPdrPars->fVerbose = pPars->fPdrVerbose; - pPdrPars->fVeryVerbose = 1; + pPdrPars->fVeryVerbose = 0; // perform refinement iterations for ( nIters = 1; nIters < pPars->nIterMax; nIters++ ) @@ -368,14 +368,10 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) pAig = Gia_ManToAigSimple( pGia ); pPdr = Pdr_ManStart( pAig, pPdrPars, NULL ); + if ( vClauses ) { - if ( Vec_VecSize( vClauses) == 1 ) { - Vec_VecFree( vClauses ); - vClauses = NULL; - } else { - assert( Vec_VecSize( vClauses) >= 2 ); - IPdr_ManRestore(pPdr, vClauses); - } + assert( Vec_VecSize( vClauses) >= 2 ); + IPdr_ManRestore( pPdr, vClauses ); } RetValue = IPdr_ManSolveInt( pPdr ); @@ -406,7 +402,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) } // spurious CEX, continue solving - vClauses = IPdr_ManSaveClauses( pPdr, 0 ); + vClauses = IPdr_ManSaveClauses( pPdr, 1 ); Pdr_ManStop( pPdr ); // update the set of objects to be un-abstracted @@ -465,7 +461,7 @@ int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) //pPdrPars->fSkipDown = 0; // use 'pdr -nc' (improved generalization) //pPdrPars->nRestLimit = 500; // reset queue or proof-obligations when it gets larger than this pPdrPars->fVerbose = pPars->fPdrVerbose; - pPdrPars->fVeryVerbose = 1; + pPdrPars->fVeryVerbose = 0; // perform refinement iterations for ( nIters = 1; nIters < pPars->nIterMax; nIters++ ) { diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c index b1f126f41..4f66eeb41 100644 --- a/src/proof/pdr/pdrIncr.c +++ b/src/proof/pdr/pdrIncr.c @@ -66,6 +66,41 @@ void IPdr_ManPrintClauses( Vec_Vec_t * vClauses, int kStart, int nRegs ) } } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int IPdr_ManCheckClauses( Pdr_Man_t * p ) +{ + Pdr_Set_t * pCubeK; + Vec_Ptr_t * vArrayK; + int j, k, RetValue, kMax = Vec_PtrSize(p->vSolvers)-1; + int iStartFrame = 1; + + Vec_VecForEachLevelStartStop( p->vClauses, vArrayK, k, iStartFrame, kMax ) + { + Vec_PtrForEachEntry( Pdr_Set_t *, vArrayK, pCubeK, j ) + { + RetValue = Pdr_ManCheckCube( p, k, pCubeK, NULL, 0, 0, 1 ); + + if ( !RetValue ) { + printf( "Cube[%d][%d] not inductive!\n", k, j ); + } + + assert( RetValue == 1 ); + } + } + + return 1; +} + /**Function************************************************************* Synopsis [] @@ -83,6 +118,11 @@ Vec_Vec_t * IPdr_ManSaveClauses( Pdr_Man_t * p, int fDropLast ) Vec_Vec_t * vClausesSaved; Pdr_Set_t * pCla; + if ( Vec_VecSize( p->vClauses ) == 1 ) + return NULL; + if ( Vec_VecSize( p->vClauses ) == 2 && fDropLast ) + return NULL; + if ( fDropLast ) vClausesSaved = Vec_VecStart( Vec_VecSize(p->vClauses)-1 ); else @@ -147,9 +187,6 @@ int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses ) assert(vClauses); - printf( "IPdr restore:\n" ); - IPdr_ManPrintClauses( vClauses, 0, Aig_ManRegNum( p->pAig ) ); - Vec_VecFree(p->vClauses); p->vClauses = vClauses; @@ -197,8 +234,8 @@ int IPdr_ManSolveInt( Pdr_Man_t * p ) if ( Vec_VecSize(p->vClauses) == 0 ) Pdr_ManCreateSolver( p, (iFrame = 0) ); else { - iFrame = Vec_VecSize(p->vClauses); - Pdr_ManCreateSolver( p, iFrame ); + iFrame = Vec_VecSize(p->vClauses) - 1; + IPdr_ManCheckClauses( p ); } while ( 1 ) { From 1a66a5823a37123c099e63cb94bba1fd844487d1 Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sun, 19 Feb 2017 16:09:59 -0800 Subject: [PATCH 173/185] working on pdr with wla --- src/base/wlc/wlcAbs.c | 2 +- src/proof/pdr/pdrIncr.c | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 8cc79722e..47bd9a3f2 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -402,7 +402,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) } // spurious CEX, continue solving - vClauses = IPdr_ManSaveClauses( pPdr, 1 ); + vClauses = IPdr_ManSaveClauses( pPdr, 0 ); Pdr_ManStop( pPdr ); // update the set of objects to be un-abstracted diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c index 4f66eeb41..9f7dfd907 100644 --- a/src/proof/pdr/pdrIncr.c +++ b/src/proof/pdr/pdrIncr.c @@ -81,14 +81,16 @@ int IPdr_ManCheckClauses( Pdr_Man_t * p ) { Pdr_Set_t * pCubeK; Vec_Ptr_t * vArrayK; - int j, k, RetValue, kMax = Vec_PtrSize(p->vSolvers)-1; + int j, k, RetValue, kMax = Vec_PtrSize(p->vSolvers); int iStartFrame = 1; + int counter = 0; Vec_VecForEachLevelStartStop( p->vClauses, vArrayK, k, iStartFrame, kMax ) { Vec_PtrForEachEntry( Pdr_Set_t *, vArrayK, pCubeK, j ) { - RetValue = Pdr_ManCheckCube( p, k, pCubeK, NULL, 0, 0, 1 ); + ++counter; + RetValue = Pdr_ManCheckCube( p, k - 1, pCubeK, NULL, 0, 0, 1 ); if ( !RetValue ) { printf( "Cube[%d][%d] not inductive!\n", k, j ); @@ -97,6 +99,7 @@ int IPdr_ManCheckClauses( Pdr_Man_t * p ) assert( RetValue == 1 ); } } + printf( "XXX: Pass check clauses! %d frames and %d clauses checked\n", k, counter ); return 1; } From 25ecc3d42973cd832d78b00cbed188171892325d Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sun, 19 Feb 2017 19:57:44 -0800 Subject: [PATCH 174/185] fixed a tricky bug: property should not be assumed true in the last frame --- src/proof/pdr/pdrIncr.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c index 9f7dfd907..09a06a27c 100644 --- a/src/proof/pdr/pdrIncr.c +++ b/src/proof/pdr/pdrIncr.c @@ -99,7 +99,6 @@ int IPdr_ManCheckClauses( Pdr_Man_t * p ) assert( RetValue == 1 ); } } - printf( "XXX: Pass check clauses! %d frames and %d clauses checked\n", k, counter ); return 1; } @@ -149,7 +148,7 @@ Vec_Vec_t * IPdr_ManSaveClauses( Pdr_Man_t * p, int fDropLast ) SeeAlso [] ***********************************************************************/ -sat_solver * IPdr_ManSetSolver( Pdr_Man_t * p, int k ) +sat_solver * IPdr_ManSetSolver( Pdr_Man_t * p, int k, int nTotal ) { sat_solver * pSat; Vec_Ptr_t * vArrayK; @@ -165,7 +164,12 @@ sat_solver * IPdr_ManSetSolver( Pdr_Man_t * p, int k ) Vec_IntPush( p->vActVars, 0 ); // set the property output - Pdr_ManSetPropertyOutput( p, k ); + if ( k < nTotal - 1 ) + Pdr_ManSetPropertyOutput( p, k ); + + if (k == 0) + return pSat; + // add the clauses Vec_VecForEachLevelStart( p->vClauses, vArrayK, i, k ) Vec_PtrForEachEntry( Pdr_Set_t *, vArrayK, pCube, j ) @@ -194,7 +198,7 @@ int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses ) p->vClauses = vClauses; for ( i = 0; i < Vec_VecSize(p->vClauses); ++i ) - IPdr_ManSetSolver(p, i); + IPdr_ManSetSolver( p, i, Vec_VecSize( p->vClauses ) ); return 0; } From 222b3741a40af2913132ef385936b955bbc19b4d Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Mon, 20 Feb 2017 10:13:18 -0800 Subject: [PATCH 175/185] fixed time profiling in pdr --- src/base/wlc/wlcAbs.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 47bd9a3f2..902c060d9 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -313,6 +313,7 @@ static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) { abctime clk = Abc_Clock(); + abctime pdrClk; Pdr_Man_t * pPdr; Vec_Vec_t * vClauses = NULL; int nIters, nNodes, nDcFlops, RetValue = -1; @@ -368,6 +369,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) pAig = Gia_ManToAigSimple( pGia ); pPdr = Pdr_ManStart( pAig, pPdrPars, NULL ); + pdrClk = Abc_Clock(); if ( vClauses ) { assert( Vec_VecSize( vClauses) >= 2 ); @@ -375,6 +377,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) } RetValue = IPdr_ManSolveInt( pPdr ); + pPdr->tTotal += Abc_Clock() - pdrClk; pCex = pAig->pSeqModel; pAig->pSeqModel = NULL; @@ -403,6 +406,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) // spurious CEX, continue solving vClauses = IPdr_ManSaveClauses( pPdr, 0 ); + Pdr_ManStop( pPdr ); // update the set of objects to be un-abstracted From 19510bd38e46fd913bf6dc29393938e50fd717ee Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Mon, 20 Feb 2017 11:07:12 -0800 Subject: [PATCH 176/185] added datastructure for %pdra options --- src/base/wlc/wlc.h | 18 +++++++++++++++++- src/base/wlc/wlcAbs.c | 27 ++++++++++++++++++++++++++- src/base/wlc/wlcCom.c | 4 ++-- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 9ca569173..cf8bdab41 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -174,6 +174,21 @@ struct Wlc_Par_t_ int fPdrVerbose; // verbose output }; + +typedef struct WlcPdr_Par_t_ WlcPdr_Par_t; +struct WlcPdr_Par_t_ +{ + int nBitsAdd; // adder bit-width + int nBitsMul; // multiplier bit-widht + int nBitsMux; // MUX bit-width + int nBitsFlop; // flop bit-width + int nIterMax; // the max number of iterations + int fXorOutput; // XOR outputs of word-level miter + int fVerbose; // verbose output + int fPdrVerbose; // verbose output +}; + + static inline int Wlc_NtkObjNum( Wlc_Ntk_t * p ) { return p->iObj - 1; } static inline int Wlc_NtkObjNumMax( Wlc_Ntk_t * p ) { return p->iObj; } static inline int Wlc_NtkPiNum( Wlc_Ntk_t * p ) { return Vec_IntSize(&p->vPis); } @@ -277,7 +292,7 @@ static inline Wlc_Obj_t * Wlc_ObjCo2PoFo( Wlc_Ntk_t * p, int iCoId ) /*=== wlcAbs.c ========================================================*/ extern int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); -extern int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); +extern int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars ); /*=== wlcAbs2.c ========================================================*/ extern int Wlc_NtkAbsCore2( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcBlast.c ========================================================*/ @@ -286,6 +301,7 @@ extern Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int i extern void Wlc_SetNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk ); /*=== wlcNtk.c ========================================================*/ extern void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ); +extern void WlcPdr_ManSetDefaultParams( WlcPdr_Par_t * pPars ); extern char * Wlc_ObjTypeName( Wlc_Obj_t * p ); extern Wlc_Ntk_t * Wlc_NtkAlloc( char * pName, int nObjsAlloc ); extern int Wlc_ObjAlloc( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg ); diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 902c060d9..8fde7f569 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -38,6 +38,31 @@ extern int IPdr_ManSolveInt( Pdr_Man_t * p ); /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +void WlcPdr_ManSetDefaultParams( WlcPdr_Par_t * pPars ) +{ + memset( pPars, 0, sizeof(WlcPdr_Par_t) ); + pPars->nBitsAdd = ABC_INFINITY; // adder bit-width + pPars->nBitsMul = ABC_INFINITY; // multiplier bit-width + pPars->nBitsMux = ABC_INFINITY; // MUX bit-width + pPars->nBitsFlop = ABC_INFINITY; // flop bit-width + pPars->nIterMax = 1000; // the max number of iterations + pPars->fXorOutput = 1; // XOR outputs of word-level miter + pPars->fVerbose = 0; // verbose output + pPars->fPdrVerbose = 0; // show verbose PDR output +} + /**Function************************************************************* Synopsis [Mark operators that meet the abstraction criteria.] @@ -310,7 +335,7 @@ static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec SeeAlso [] ***********************************************************************/ -int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) +int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars ) { abctime clk = Abc_Clock(); abctime pdrClk; diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index e980752b6..d30b376e2 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -458,9 +458,9 @@ usage: int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) { Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); - Wlc_Par_t Pars, * pPars = &Pars; + WlcPdr_Par_t Pars, * pPars = &Pars; int c; - Wlc_ManSetDefaultParams( pPars ); + WlcPdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIxvwh" ) ) != EOF ) { From ac1eb60db9129110e7795614ad82d85cb74d854e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 20 Feb 2017 12:32:32 -0800 Subject: [PATCH 177/185] Experiments with SAT sweeping. --- src/base/abci/abc.c | 2 +- src/proof/cec/cecSat.c | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 4c37242d7..466af66a4 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -43019,7 +43019,7 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv ) // Jf_ManTestCnf( pAbc->pGia ); // Gia_ManCheckFalseTest( pAbc->pGia, nFrames ); // Gia_ParTest( pAbc->pGia, nWords, nProcs ); -Cec2_ManSimulateTest( pAbc->pGia ); +//Cec2_ManSimulateTest( pAbc->pGia ); // printf( "\nThis command is currently disabled.\n\n" ); return 0; usage: diff --git a/src/proof/cec/cecSat.c b/src/proof/cec/cecSat.c index 883975505..97bbb7d3c 100644 --- a/src/proof/cec/cecSat.c +++ b/src/proof/cec/cecSat.c @@ -37,6 +37,7 @@ struct Cec2_Par_t_ int nSimRounds; // simulation rounds int nConfLimit; // SAT solver conflict limit int fIsMiter; // this is a miter + int fUseCones; // use logic cones int fVeryVerbose; // verbose stats int fVerbose; // verbose stats }; @@ -54,6 +55,7 @@ struct Cec2_Man_t_ Vec_Ptr_t * vFanins; // CNF construction Vec_Wrd_t * vSims; // CI simulation info Vec_Int_t * vNodesNew; // nodes + Vec_Int_t * vSatVars; // nodes Vec_Int_t * vObjSatPairs; // nodes Vec_Int_t * vCexTriples; // nodes // statistics @@ -95,6 +97,7 @@ void Cec2_SetDefaultParams( Cec2_Par_t * p ) p->nSimRounds = 4; // simulation rounds p->nConfLimit = 1000; // conflict limit at a node p->fIsMiter = 0; // this is a miter + p->fUseCones = 1; // use logic cones p->fVeryVerbose = 0; // verbose stats p->fVerbose = 1; // verbose stats } @@ -668,6 +671,7 @@ Cec2_Man_t * Cec2_ManCreate( Gia_Man_t * pAig, Cec2_Par_t * pPars ) p->vFrontier = Vec_PtrAlloc( 1000 ); p->vFanins = Vec_PtrAlloc( 100 ); p->vNodesNew = Vec_IntAlloc( 100 ); + p->vSatVars = Vec_IntAlloc( 100 ); p->vObjSatPairs = Vec_IntAlloc( 100 ); p->vCexTriples = Vec_IntAlloc( 100 ); // remember pointer to the solver in the AIG manager @@ -702,6 +706,7 @@ void Cec2_ManDestroy( Cec2_Man_t * p ) Vec_PtrFreeP( &p->vFrontier ); Vec_PtrFreeP( &p->vFanins ); Vec_IntFreeP( &p->vNodesNew ); + Vec_IntFreeP( &p->vSatVars ); Vec_IntFreeP( &p->vObjSatPairs ); Vec_IntFreeP( &p->vCexTriples ); ABC_FREE( p ); @@ -767,7 +772,10 @@ void Cec2_ManCollect_rec( Cec2_Man_t * p, int iObj ) Gia_ObjSetTravIdCurrentId(p->pNew, iObj); pObj = Gia_ManObj( p->pNew, iObj ); if ( Cec2_ObjSatId(p->pNew, pObj) >= 0 ) + { Vec_IntPush( p->vNodesNew, iObj ); + Vec_IntPush( p->vSatVars, Cec2_ObjSatId(p->pNew, pObj) ); + } if ( !iObj ) return; if ( Gia_ObjIsAnd(pObj) ) @@ -788,19 +796,21 @@ int Cec2_ManSolveTwo( Cec2_Man_t * p, int iObj0, int iObj1, int fPhase ) if (iObj1 < iObj0) iObj1 ^= iObj0, iObj0 ^= iObj1, iObj1 ^= iObj0; assert( iObj0 < iObj1 ); - assert( solver_varnum(p->pSat) == 0 ); - if ( !iObj0 ) + assert( p->pPars->fUseCones || solver_varnum(p->pSat) == 0 ); + if ( !iObj0 && Cec2_ObjSatId(p->pNew, Gia_ManConst0(p->pNew)) == -1 ) Cec2_ObjSetSatId( p->pNew, Gia_ManConst0(p->pNew), satoko_add_variable(p->pSat, 0) ); iVar0 = Cec2_ObjGetCnfVar( p, iObj0 ); iVar1 = Cec2_ObjGetCnfVar( p, iObj1 ); // collect inputs and internal nodes Vec_IntClear( p->vNodesNew ); + Vec_IntClear( p->vSatVars ); Vec_IntClear( p->vObjSatPairs ); Gia_ManIncrementTravId( p->pNew ); Cec2_ManCollect_rec( p, iObj0 ); Cec2_ManCollect_rec( p, iObj1 ); //printf( "%d ", Vec_IntSize(p->vNodesNew) ); // solve direct + if ( p->pPars->fUseCones ) satoko_mark_cone( p->pSat, Vec_IntArray(p->vSatVars), Vec_IntSize(p->vSatVars) ); satoko_assump_push( p->pSat, Abc_Var2Lit(iVar0, 1) ); satoko_assump_push( p->pSat, Abc_Var2Lit(iVar1, fPhase) ); status = satoko_solve( p->pSat ); @@ -815,8 +825,11 @@ int Cec2_ManSolveTwo( Cec2_Man_t * p, int iObj0, int iObj1, int fPhase ) satoko_assump_pop( p->pSat ); satoko_assump_pop( p->pSat ); } + if ( p->pPars->fUseCones ) satoko_unmark_cone( p->pSat, Vec_IntArray(p->vSatVars), Vec_IntSize(p->vSatVars) ); //if ( status == SATOKO_SAT ) // Cec2_ManVerify( p->pNew, iObj0, iObj1, fPhase, p->pSat ); + if ( p->pPars->fUseCones ) + return status; Gia_ManForEachObjVec( p->vNodesNew, p->pNew, pObj, i ) Cec2_ObjCleanSatId( p->pNew, pObj ); return status; @@ -855,6 +868,8 @@ int Cec2_ManSweepNode( Cec2_Man_t * p, int iObj ) assert( 0 ); p->timeSatUndec += Abc_Clock() - clk; } + if ( p->pPars->fUseCones ) + return RetValue; clk = Abc_Clock(); satoko_rollback( p->pSat ); p->timeExtra += Abc_Clock() - clk; From 9f43c84501cf8c5a8ae74cc5bebea63dafc3a714 Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Mon, 20 Feb 2017 12:51:04 -0800 Subject: [PATCH 178/185] added options of checking and pushing to %pdra --- src/base/wlc/wlc.h | 2 ++ src/base/wlc/wlcAbs.c | 10 ++++++---- src/base/wlc/wlcCom.c | 12 ++++++++++-- src/proof/pdr/pdrIncr.c | 37 +++++++++++++++++++++++++++++++++---- 4 files changed, 51 insertions(+), 10 deletions(-) diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index cf8bdab41..9cb34bf3a 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -184,6 +184,8 @@ struct WlcPdr_Par_t_ int nBitsFlop; // flop bit-width int nIterMax; // the max number of iterations int fXorOutput; // XOR outputs of word-level miter + int fCheckClauses; // Check clauses in the reloaded trace + int fPushClauses; // Push clauses in the reloaded trace int fVerbose; // verbose output int fPdrVerbose; // verbose output }; diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 8fde7f569..fbaa1b8a7 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -32,7 +32,7 @@ ABC_NAMESPACE_IMPL_START extern Vec_Vec_t * IPdr_ManSaveClauses( Pdr_Man_t * p, int fDropLast ); extern int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses ); -extern int IPdr_ManSolveInt( Pdr_Man_t * p ); +extern int IPdr_ManSolveInt( Pdr_Man_t * p, int fCheckClauses, int fPushClauses ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -59,6 +59,8 @@ void WlcPdr_ManSetDefaultParams( WlcPdr_Par_t * pPars ) pPars->nBitsFlop = ABC_INFINITY; // flop bit-width pPars->nIterMax = 1000; // the max number of iterations pPars->fXorOutput = 1; // XOR outputs of word-level miter + pPars->fCheckClauses = 1; // Check clauses in the reloaded trace + pPars->fPushClauses = 0; // Push clauses in the reloaded trace pPars->fVerbose = 0; // verbose output pPars->fPdrVerbose = 0; // show verbose PDR output } @@ -76,7 +78,7 @@ void WlcPdr_ManSetDefaultParams( WlcPdr_Par_t * pPars ) SeeAlso [] ***********************************************************************/ -static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose ) +static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose ) { Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) ); Wlc_Obj_t * pObj; int i, Count[4] = {0}; @@ -197,7 +199,7 @@ static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * SeeAlso [] ***********************************************************************/ -static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose ) +static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose ) { Wlc_Ntk_t * pNtkNew = NULL; Vec_Int_t * vPisOld = Vec_IntAlloc( 100 ); @@ -401,7 +403,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars ) IPdr_ManRestore( pPdr, vClauses ); } - RetValue = IPdr_ManSolveInt( pPdr ); + RetValue = IPdr_ManSolveInt( pPdr, pPars->fCheckClauses, pPars->fPushClauses ); pPdr->tTotal += Abc_Clock() - pdrClk; pCex = pAig->pSeqModel; pAig->pSeqModel = NULL; diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index d30b376e2..7801abc66 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -462,7 +462,7 @@ int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; WlcPdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIxvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIcpxvwh" ) ) != EOF ) { switch ( c ) { @@ -524,6 +524,12 @@ int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'x': pPars->fXorOutput ^= 1; break; + case 'c': + pPars->fCheckClauses ^= 1; + break; + case 'p': + pPars->fPushClauses ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; @@ -544,7 +550,7 @@ int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) Wlc_NtkPdrAbs( pNtk, pPars ); return 0; usage: - Abc_Print( -2, "usage: %%pdra [-AMXFI num] [-xvwh]\n" ); + Abc_Print( -2, "usage: %%pdra [-AMXFI num] [-cpxvwh]\n" ); Abc_Print( -2, "\t abstraction for word-level networks\n" ); Abc_Print( -2, "\t-A num : minimum bit-width of an adder/subtractor to abstract [default = %d]\n", pPars->nBitsAdd ); Abc_Print( -2, "\t-M num : minimum bit-width of a multiplier to abstract [default = %d]\n", pPars->nBitsMul ); @@ -552,6 +558,8 @@ usage: Abc_Print( -2, "\t-F num : minimum bit-width of a flip-flop to abstract [default = %d]\n", pPars->nBitsFlop ); Abc_Print( -2, "\t-I num : maximum number of CEGAR iterations [default = %d]\n", pPars->nIterMax ); Abc_Print( -2, "\t-x : toggle XORing outputs of word-level miter [default = %s]\n", pPars->fXorOutput? "yes": "no" ); + Abc_Print( -2, "\t-c : toggle checking clauses in the reloaded trace [default = %s]\n", pPars->fCheckClauses? "yes": "no" ); + Abc_Print( -2, "\t-p : toggle pushing clauses in the reloaded trace [default = %s]\n", pPars->fPushClauses? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-w : toggle printing verbose PDR output [default = %s]\n", pPars->fPdrVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c index 09a06a27c..85403a7d1 100644 --- a/src/proof/pdr/pdrIncr.c +++ b/src/proof/pdr/pdrIncr.c @@ -68,7 +68,9 @@ void IPdr_ManPrintClauses( Vec_Vec_t * vClauses, int kStart, int nRegs ) /**Function************************************************************* - Synopsis [] + Synopsis [ Check if each cube c_k in frame k satisfies the query + R_{k-1} && T && !c_k && c_k' (must be UNSAT). + Return True if all cubes pass the check. ] Description [] @@ -214,7 +216,7 @@ int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses ) SeeAlso [] ***********************************************************************/ -int IPdr_ManSolveInt( Pdr_Man_t * p ) +int IPdr_ManSolveInt( Pdr_Man_t * p, int fCheckClauses, int fPushClauses ) { int fPrintClauses = 0; Pdr_Set_t * pCube = NULL; @@ -242,7 +244,34 @@ int IPdr_ManSolveInt( Pdr_Man_t * p ) Pdr_ManCreateSolver( p, (iFrame = 0) ); else { iFrame = Vec_VecSize(p->vClauses) - 1; - IPdr_ManCheckClauses( p ); + + if ( fCheckClauses ) + { + if ( p->pPars->fVerbose ) + Abc_Print( 1, "IPDR: Checking the reloaded length-%d trace...", iFrame + 1 ) ; + IPdr_ManCheckClauses( p ); + if ( p->pPars->fVerbose ) + Abc_Print( 1, " Passed!\n" ) ; + } + + if ( fPushClauses ) + { + p->iUseFrame = Abc_MaxInt(iFrame, 1); + + if ( p->pPars->fVerbose ) + { + Abc_Print( 1, "IPDR: Pushing the reloaded clauses. Before:\n" ); + Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + } + + RetValue = Pdr_ManPushClauses( p ); + + if ( p->pPars->fVerbose ) + { + Abc_Print( 1, "IPDR: Finished pushing. After:\n" ); + Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + } + } } while ( 1 ) { @@ -602,7 +631,7 @@ int IPdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) p = Pdr_ManStart( pAig, pPars, NULL ); while ( 1 ) { - RetValue = IPdr_ManSolveInt( p ); + RetValue = IPdr_ManSolveInt( p, 1, 0 ); if ( RetValue == -1 && pPars->iFrame == pPars->nFrameMax) { vClausesSaved = IPdr_ManSaveClauses( p, 1 ); From c5e9506f5d5a5303b9df453fce7f313147799276 Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Mon, 20 Feb 2017 12:58:20 -0800 Subject: [PATCH 179/185] small tweaks in %pdra -p --- src/proof/pdr/pdrIncr.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c index 85403a7d1..6de86c188 100644 --- a/src/proof/pdr/pdrIncr.c +++ b/src/proof/pdr/pdrIncr.c @@ -271,6 +271,13 @@ int IPdr_ManSolveInt( Pdr_Man_t * p, int fCheckClauses, int fPushClauses ) Abc_Print( 1, "IPDR: Finished pushing. After:\n" ); Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); } + + if ( RetValue ) + { + Pdr_ManReportInvariant( p ); + Pdr_ManVerifyInvariant( p ); + return 1; + } } } while ( 1 ) From 9d46d84b278acac3ca5983ddb7fbd41a9a4b926b Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Tue, 21 Feb 2017 18:37:06 -0300 Subject: [PATCH 180/185] Small tweak to rollback behavior. --- src/sat/satoko/solver.c | 3 +++ src/sat/satoko/solver.h | 1 + src/sat/satoko/solver_api.c | 4 ++++ 3 files changed, 8 insertions(+) diff --git a/src/sat/satoko/solver.c b/src/sat/satoko/solver.c index 3738129bc..af3dcffba 100644 --- a/src/sat/satoko/solver.c +++ b/src/sat/satoko/solver.c @@ -397,6 +397,9 @@ static inline void solver_garbage_collect(solver_t *s) unsigned *array; struct cdb *new_cdb = cdb_alloc(cdb_capacity(s->all_clauses) - cdb_wasted(s->all_clauses)); + if (s->book_cdb) + s->book_cdb = 0; + for (i = 0; i < 2 * vec_char_size(s->assigns); i++) { struct watcher *w; watch_list_foreach(s->watches, w, i) diff --git a/src/sat/satoko/solver.h b/src/sat/satoko/solver.h index dcae8f6e7..33f8ce885 100644 --- a/src/sat/satoko/solver.h +++ b/src/sat/satoko/solver.h @@ -95,6 +95,7 @@ struct solver_t_ { /* Bookmark */ unsigned book_cl_orig; /* Bookmark for orignal problem clauses vector */ unsigned book_cl_lrnt; /* Bookmark for learnt clauses vector */ + unsigned book_cdb; /* Bookmark clause database size */ unsigned book_vars; /* Bookmark number of variables */ unsigned book_trail; /* Bookmark trail size */ diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c index 90d04cfd7..3cb9f3d30 100644 --- a/src/sat/satoko/solver_api.c +++ b/src/sat/satoko/solver_api.c @@ -330,6 +330,7 @@ void satoko_unbookmark(satoko_t *s) { s->book_cl_orig = 0; s->book_cl_lrnt = 0; + s->book_cdb = 0; s->book_vars = 0; s->book_trail = 0; } @@ -365,6 +366,7 @@ void satoko_reset(satoko_t *s) s->RC2 = s->opts.n_conf_fst_reduce; s->book_cl_orig = 0; s->book_cl_lrnt = 0; + s->book_cdb = 0; s->book_vars = 0; s->book_trail = 0; } @@ -412,6 +414,8 @@ void satoko_rollback(satoko_t *s) /* Rewind solver and cancel level 0 assignments to the trail */ solver_cancel_until(s, 0); vec_uint_shrink(s->trail, s->book_trail); + if (s->book_cdb) + s->all_clauses->size = s->book_cdb; s->book_cl_orig = 0; s->book_cl_lrnt = 0; s->book_vars = 0; From 01e6beea8e617eb5ef4f9b621b009eded9498a1f Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Tue, 21 Feb 2017 20:06:13 -0800 Subject: [PATCH 181/185] clean up --- fsm.v | 28 ---------------------------- src/base/wlc/wlc.h | 18 +----------------- src/base/wlc/wlcAbs.c | 33 +++------------------------------ src/base/wlc/wlcCom.c | 4 ++-- src/base/wlc/wlcNtk.c | 2 ++ 5 files changed, 8 insertions(+), 77 deletions(-) delete mode 100644 fsm.v diff --git a/fsm.v b/fsm.v deleted file mode 100644 index 272c4a898..000000000 --- a/fsm.v +++ /dev/null @@ -1,28 +0,0 @@ -module fsm (out); -output out; - -wire [2:0] ns; -wire [2:0] cs; - -always @( ns or cs ) -begin -case (cs) - 0 : ns = 3'b010; - 1 : ns = 3'b001; - 2 : ns = 3'b000; - 3 : ns = 3'b101; - 4 : ns = 3'b001; - 5 : ns = 3'b111; - 6 : ns = 3'b001; - 7 : ns = 3'b110; -endcase -end - -assign out = cs == 3'b001; - -wire [2:0] const0 = 3'h0; - - -CPL_FF#3 ff3 ( .q(cs), .qbar(), .d(ns), .clk(), .arst(), .arstval(const0) ); - -endmodule diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 9cb34bf3a..686d9f009 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -163,20 +163,6 @@ struct Wlc_Ntk_t_ typedef struct Wlc_Par_t_ Wlc_Par_t; struct Wlc_Par_t_ -{ - int nBitsAdd; // adder bit-width - int nBitsMul; // multiplier bit-widht - int nBitsMux; // MUX bit-width - int nBitsFlop; // flop bit-width - int nIterMax; // the max number of iterations - int fXorOutput; // XOR outputs of word-level miter - int fVerbose; // verbose output - int fPdrVerbose; // verbose output -}; - - -typedef struct WlcPdr_Par_t_ WlcPdr_Par_t; -struct WlcPdr_Par_t_ { int nBitsAdd; // adder bit-width int nBitsMul; // multiplier bit-widht @@ -190,7 +176,6 @@ struct WlcPdr_Par_t_ int fPdrVerbose; // verbose output }; - static inline int Wlc_NtkObjNum( Wlc_Ntk_t * p ) { return p->iObj - 1; } static inline int Wlc_NtkObjNumMax( Wlc_Ntk_t * p ) { return p->iObj; } static inline int Wlc_NtkPiNum( Wlc_Ntk_t * p ) { return Vec_IntSize(&p->vPis); } @@ -294,7 +279,7 @@ static inline Wlc_Obj_t * Wlc_ObjCo2PoFo( Wlc_Ntk_t * p, int iCoId ) /*=== wlcAbs.c ========================================================*/ extern int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); -extern int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars ); +extern int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcAbs2.c ========================================================*/ extern int Wlc_NtkAbsCore2( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcBlast.c ========================================================*/ @@ -303,7 +288,6 @@ extern Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int i extern void Wlc_SetNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk ); /*=== wlcNtk.c ========================================================*/ extern void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ); -extern void WlcPdr_ManSetDefaultParams( WlcPdr_Par_t * pPars ); extern char * Wlc_ObjTypeName( Wlc_Obj_t * p ); extern Wlc_Ntk_t * Wlc_NtkAlloc( char * pName, int nObjsAlloc ); extern int Wlc_ObjAlloc( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg ); diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index fbaa1b8a7..1e5df918b 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -38,33 +38,6 @@ extern int IPdr_ManSolveInt( Pdr_Man_t * p, int fCheckClauses, int fPu /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -void WlcPdr_ManSetDefaultParams( WlcPdr_Par_t * pPars ) -{ - memset( pPars, 0, sizeof(WlcPdr_Par_t) ); - pPars->nBitsAdd = ABC_INFINITY; // adder bit-width - pPars->nBitsMul = ABC_INFINITY; // multiplier bit-width - pPars->nBitsMux = ABC_INFINITY; // MUX bit-width - pPars->nBitsFlop = ABC_INFINITY; // flop bit-width - pPars->nIterMax = 1000; // the max number of iterations - pPars->fXorOutput = 1; // XOR outputs of word-level miter - pPars->fCheckClauses = 1; // Check clauses in the reloaded trace - pPars->fPushClauses = 0; // Push clauses in the reloaded trace - pPars->fVerbose = 0; // verbose output - pPars->fPdrVerbose = 0; // show verbose PDR output -} - /**Function************************************************************* Synopsis [Mark operators that meet the abstraction criteria.] @@ -78,7 +51,7 @@ void WlcPdr_ManSetDefaultParams( WlcPdr_Par_t * pPars ) SeeAlso [] ***********************************************************************/ -static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose ) +static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose ) { Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) ); Wlc_Obj_t * pObj; int i, Count[4] = {0}; @@ -199,7 +172,7 @@ static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * SeeAlso [] ***********************************************************************/ -static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose ) +static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose ) { Wlc_Ntk_t * pNtkNew = NULL; Vec_Int_t * vPisOld = Vec_IntAlloc( 100 ); @@ -337,7 +310,7 @@ static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec SeeAlso [] ***********************************************************************/ -int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars ) +int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) { abctime clk = Abc_Clock(); abctime pdrClk; diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 7801abc66..df736e702 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -458,9 +458,9 @@ usage: int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) { Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); - WlcPdr_Par_t Pars, * pPars = &Pars; + Wlc_Par_t Pars, * pPars = &Pars; int c; - WlcPdr_ManSetDefaultParams( pPars ); + Wlc_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIcpxvwh" ) ) != EOF ) { diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index e6ab0739c..c8fc15a76 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -114,6 +114,8 @@ void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ) pPars->nBitsFlop = ABC_INFINITY; // flop bit-width pPars->nIterMax = 1000; // the max number of iterations pPars->fXorOutput = 1; // XOR outputs of word-level miter + pPars->fCheckClauses = 1; // Check clauses in the reloaded trace + pPars->fPushClauses = 0; // Push clauses in the reloaded trace pPars->fVerbose = 0; // verbose output` pPars->fPdrVerbose = 0; // show verbose PDR output } From fb2fbd70bd31eb08dd50c66788d5165697ca6925 Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Tue, 21 Feb 2017 20:10:11 -0800 Subject: [PATCH 182/185] clean up --- src/base/abci/abc.c | 269 -------------------------------------------- 1 file changed, 269 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 0645c6e38..52684f8cf 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -333,7 +333,6 @@ static int Abc_CommandBm2 ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandSaucy ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTestCex ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPdr ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandIPdr ( Abc_Frame_t * pAbc, int argc, char ** argv ); #ifdef ABC_USE_CUDD static int Abc_CommandReconcile ( Abc_Frame_t * pAbc, int argc, char ** argv ); #endif @@ -984,7 +983,6 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Verification", "saucy3", Abc_CommandSaucy, 1 ); Cmd_CommandAdd( pAbc, "Verification", "testcex", Abc_CommandTestCex, 0 ); Cmd_CommandAdd( pAbc, "Verification", "pdr", Abc_CommandPdr, 0 ); - Cmd_CommandAdd( pAbc, "Verification", "ipdr", Abc_CommandIPdr, 0 ); #ifdef ABC_USE_CUDD Cmd_CommandAdd( pAbc, "Verification", "reconcile", Abc_CommandReconcile, 1 ); #endif @@ -26417,273 +26415,6 @@ usage: - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandIPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - extern int Abc_NtkDarPdr( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ); - extern int Abc_NtkDarIPdr( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ); - Pdr_Par_t Pars, * pPars = &Pars; - Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); - int c; - Pdr_ManSetDefaultParams( pPars ); - Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDQTHGSaxrmuyfsipdegjonctkvwzh" ) ) != EOF ) - { - switch ( c ) - { - case 'M': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nRecycle = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nRecycle < 0 ) - goto usage; - break; - case 'F': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nFrameMax = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nFrameMax < 0 ) - goto usage; - break; - case 'C': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nConfLimit = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nConfLimit < 0 ) - goto usage; - break; - case 'D': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-D\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nConfGenLimit = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nConfGenLimit < 0 ) - goto usage; - break; - case 'Q': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-Q\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nRestLimit = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nRestLimit < 0 ) - goto usage; - break; - case 'T': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nTimeOut = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nTimeOut < 0 ) - goto usage; - break; - case 'H': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-H\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nTimeOutOne = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nTimeOutOne < 0 ) - goto usage; - break; - case 'G': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-G\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nTimeOutGap = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nTimeOutGap < 0 ) - goto usage; - break; - case 'S': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nRandomSeed = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nRandomSeed < 0 ) - goto usage; - break; - case 'a': - pPars->fSolveAll ^= 1; - break; - case 'x': - pPars->fStoreCex ^= 1; - break; - case 'r': - pPars->fTwoRounds ^= 1; - break; - case 'm': - pPars->fMonoCnf ^= 1; - break; - case 'u': - pPars->fNewXSim ^= 1; - break; - case 'y': - pPars->fFlopPrio ^= 1; - break; - case 'f': - pPars->fFlopOrder ^= 1; - break; - case 's': - pPars->fShortest ^= 1; - break; - case 'i': - pPars->fShiftStart ^= 1; - break; - case 'p': - pPars->fReuseProofOblig ^= 1; - break; - case 'd': - pPars->fDumpInv ^= 1; - break; - case 'e': - pPars->fUseSupp ^= 1; - break; - case 'g': - pPars->fSkipGeneral ^= 1; - break; - case 'j': - pPars->fSimpleGeneral ^= 1; - break; - case 'o': - pPars->fUsePropOut ^= 1; - break; - case 'n': - pPars->fSkipDown ^= 1; - break; - case 'c': - pPars->fCtgs ^= 1; - break; - case 't': - pPars->fUseAbs ^= 1; - break; - case 'k': - pPars->fUseSimpleRef ^= 1; - break; - case 'v': - pPars->fVerbose ^= 1; - break; - case 'w': - pPars->fVeryVerbose ^= 1; - break; - case 'z': - pPars->fNotVerbose ^= 1; - break; - case 'h': - default: - goto usage; - } - } - if ( pNtk == NULL ) - { - Abc_Print( -2, "There is no current network.\n"); - return 0; - } - if ( Abc_NtkLatchNum(pNtk) == 0 ) - { - Abc_Print( 0, "The current network is combinational.\n"); - return 0; - } - if ( !Abc_NtkIsStrash(pNtk) ) - { - Abc_Print( -2, "The current network is not an AIG (run \"strash\").\n"); - return 0; - } - // run the procedure - pPars->fUseBridge = pAbc->fBridgeMode; - pAbc->Status = Abc_NtkDarIPdr( pNtk, pPars ); - pAbc->nFrames = pNtk->vSeqModelVec ? -1 : pPars->iFrame; - Abc_FrameReplacePoStatuses( pAbc, &pPars->vOutMap ); - if ( pNtk->vSeqModelVec ) - Abc_FrameReplaceCexVec( pAbc, &pNtk->vSeqModelVec ); - else - Abc_FrameReplaceCex( pAbc, &pNtk->pSeqModel ); - return 0; - -usage: - Abc_Print( -2, "usage: ipdr [-MFCDQTHGS ] [-axrmuyfsipdegjonctkvwzh]\n" ); - Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); - Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); - Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); - Abc_Print( -2, "\t-M num : limit on unused vars to trigger SAT solver recycling [default = %d]\n", pPars->nRecycle ); - Abc_Print( -2, "\t-F num : limit on timeframes explored to stop computation [default = %d]\n", pPars->nFrameMax ); - Abc_Print( -2, "\t-C num : limit on conflicts in one SAT call (0 = no limit) [default = %d]\n", pPars->nConfLimit ); - Abc_Print( -2, "\t-D num : limit on conflicts during ind-generalization (0 = no limit) [default = %d]\n",pPars->nConfGenLimit ); - Abc_Print( -2, "\t-Q num : limit on proof obligations before a restart (0 = no limit) [default = %d]\n", pPars->nRestLimit ); - Abc_Print( -2, "\t-T num : runtime limit, in seconds (0 = no limit) [default = %d]\n", pPars->nTimeOut ); - Abc_Print( -2, "\t-H num : runtime limit per output, in miliseconds (with \"-a\") [default = %d]\n", pPars->nTimeOutOne ); - Abc_Print( -2, "\t-G num : runtime gap since the last CEX (0 = no limit) [default = %d]\n", pPars->nTimeOutGap ); - Abc_Print( -2, "\t-S num : * value to seed the SAT solver with [default = %d]\n", pPars->nRandomSeed ); - Abc_Print( -2, "\t-a : toggle solving all outputs even if one of them is SAT [default = %s]\n", pPars->fSolveAll? "yes": "no" ); - Abc_Print( -2, "\t-x : toggle storing CEXes when solving all outputs [default = %s]\n", pPars->fStoreCex? "yes": "no" ); - Abc_Print( -2, "\t-r : toggle using more effort in generalization [default = %s]\n", pPars->fTwoRounds? "yes": "no" ); - Abc_Print( -2, "\t-m : toggle using monolythic CNF computation [default = %s]\n", pPars->fMonoCnf? "yes": "no" ); - Abc_Print( -2, "\t-u : toggle updated X-valued simulation [default = %s]\n", pPars->fNewXSim? "yes": "no" ); - Abc_Print( -2, "\t-y : toggle using structural flop priorities [default = %s]\n", pPars->fFlopPrio? "yes": "no" ); - Abc_Print( -2, "\t-f : toggle ordering flops by cost before generalization [default = %s]\n", pPars->fFlopOrder? "yes": "no" ); - Abc_Print( -2, "\t-s : toggle creating only shortest counter-examples [default = %s]\n", pPars->fShortest? "yes": "no" ); - Abc_Print( -2, "\t-i : toggle clause pushing from an intermediate timeframe [default = %s]\n", pPars->fShiftStart? "yes": "no" ); - Abc_Print( -2, "\t-p : toggle reusing proof-obligations in the last timeframe [default = %s]\n", pPars->fReuseProofOblig? "yes": "no" ); - Abc_Print( -2, "\t-d : toggle dumping invariant (valid if init state is all-0) [default = %s]\n", pPars->fDumpInv? "yes": "no" ); - Abc_Print( -2, "\t-e : toggle using only support variables in the invariant [default = %s]\n", pPars->fUseSupp? "yes": "no" ); - Abc_Print( -2, "\t-g : toggle skipping expensive generalization step [default = %s]\n", pPars->fSkipGeneral? "yes": "no" ); - Abc_Print( -2, "\t-j : toggle using simplified generalization step [default = %s]\n", pPars->fSimpleGeneral? "yes": "no" ); - Abc_Print( -2, "\t-o : toggle using property output as inductive hypothesis [default = %s]\n", pPars->fUsePropOut? "yes": "no" ); - Abc_Print( -2, "\t-n : * toggle skipping \'down\' in generalization [default = %s]\n", pPars->fSkipDown? "yes": "no" ); - Abc_Print( -2, "\t-c : * toggle handling CTGs in \'down\' [default = %s]\n", pPars->fCtgs? "yes": "no" ); - Abc_Print( -2, "\t-t : toggle using abstraction [default = %s]\n", pPars->fUseAbs? "yes": "no" ); - Abc_Print( -2, "\t-k : toggle using simplified refinement [default = %s]\n", pPars->fUseSimpleRef? "yes": "no" ); - Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" ); - Abc_Print( -2, "\t-w : toggle printing detailed stats default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); - Abc_Print( -2, "\t-z : toggle suppressing report about solved outputs [default = %s]\n", pPars->fNotVerbose? "yes": "no" ); - Abc_Print( -2, "\t-h : print the command usage\n\n"); - Abc_Print( -2, "\t* Implementation of switches -S, -n, and -c is contributed by Zyad Hassan.\n"); - Abc_Print( -2, "\t The theory and experiments supporting this work can be found in the following paper:\n"); - Abc_Print( -2, "\t Zyad Hassan, Aaron R. Bradley, Fabio Somenzi, \"Better Generalization in IC3\", FMCAD 2013.\n"); - Abc_Print( -2, "\t (http://www.cs.utexas.edu/users/hunt/FMCAD/FMCAD13/papers/85-Better-Generalization-IC3.pdf)\n"); - - - return 1; } From 96ccd24e6e5e2489d165bc14ac81136255a7b1f8 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 21 Feb 2017 20:39:52 -0800 Subject: [PATCH 183/185] Changes to Visual Studio project file to support 'pdra'. --- abclib.dsp | 4 ++++ src/proof/pdr/module.make | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/abclib.dsp b/abclib.dsp index 99ade15e4..b852551d4 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -5355,6 +5355,10 @@ SOURCE=.\src\proof\pdr\pdrCore.c # End Source File # Begin Source File +SOURCE=.\src\proof\pdr\pdrIncr.c +# End Source File +# Begin Source File + SOURCE=.\src\proof\pdr\pdrInt.h # End Source File # Begin Source File diff --git a/src/proof/pdr/module.make b/src/proof/pdr/module.make index 4c177a21b..1dee93aa8 100644 --- a/src/proof/pdr/module.make +++ b/src/proof/pdr/module.make @@ -1,9 +1,9 @@ SRC += src/proof/pdr/pdrCnf.c \ src/proof/pdr/pdrCore.c \ + src/proof/pdr/pdrIncr.c \ src/proof/pdr/pdrInv.c \ src/proof/pdr/pdrMan.c \ src/proof/pdr/pdrSat.c \ src/proof/pdr/pdrTsim.c \ src/proof/pdr/pdrTsim2.c \ - src/proof/pdr/pdrUtil.c \ - src/proof/pdr/pdrIncr.c + src/proof/pdr/pdrUtil.c From 53b1d46b8d19e491679d9374c9758b09e2becf59 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 21 Feb 2017 22:20:03 -0800 Subject: [PATCH 184/185] Remapping flops in '%pdra. --- src/base/wlc/wlcAbs.c | 95 +++++++++++++++++++++++++++++++++++------ src/proof/pdr/pdrIncr.c | 13 +++++- 2 files changed, 94 insertions(+), 14 deletions(-) diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 1e5df918b..e33424f7d 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -1,6 +1,6 @@ /**CFile**************************************************************** - FileName [wlcAbs1.c] + FileName [wlcAbs.c] SystemName [ABC: Logic synthesis and verification system.] @@ -8,13 +8,13 @@ Synopsis [Abstraction for word-level networks.] - Author [Alan Mishchenko] + Author [Yen-Sheng Ho, Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - August 22, 2014.] - Revision [$Id: wlcAbs1.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + Revision [$Id: wlcAbs.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] ***********************************************************************/ @@ -31,7 +31,7 @@ ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// extern Vec_Vec_t * IPdr_ManSaveClauses( Pdr_Man_t * p, int fDropLast ); -extern int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses ); +extern int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses, Vec_Int_t * vMap ); extern int IPdr_ManSolveInt( Pdr_Man_t * p, int fCheckClauses, int fPushClauses ); //////////////////////////////////////////////////////////////////////// @@ -134,7 +134,7 @@ static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * Wlc_NtkForEachCo( p, pObj, i ) Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vPisOld, vPisNew, vFlops ); - +/* Vec_IntClear(vFlops); Wlc_NtkForEachCi( p, pObj, i ) { if ( !Wlc_ObjIsPi(pObj) ) { @@ -142,7 +142,7 @@ static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * pObj->Mark = 1; } } - +*/ Wlc_NtkForEachObjVec( vFlops, p, pObj, i ) Wlc_NtkAbsMarkNodes_rec( p, Wlc_ObjFo2Fi(p, pObj), vLeaves, vPisOld, vPisNew, vFlops ); @@ -172,7 +172,7 @@ static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * SeeAlso [] ***********************************************************************/ -static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose ) +static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, Vec_Int_t ** pvFlops, int fVerbose ) { Wlc_Ntk_t * pNtkNew = NULL; Vec_Int_t * vPisOld = Vec_IntAlloc( 100 ); @@ -183,7 +183,10 @@ static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUn Vec_BitFree( vLeaves ); pNtkNew = Wlc_NtkDupDfsAbs( p, vPisOld, vPisNew, vFlops ); Vec_IntFree( vPisOld ); - Vec_IntFree( vFlops ); + if ( pvFlops ) + *pvFlops = vFlops; + else + Vec_IntFree( vFlops ); if ( pvPisNew ) *pvPisNew = vPisNew; else @@ -299,6 +302,55 @@ static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec return nNodes; } +/**Function************************************************************* + + Synopsis [Computes the map for remapping flop IDs used in the clauses.] + + Description [Takes the original network (Wlc_Ntk_t) and the array of word-level + flops used in the old abstraction (vFfOld) and those used in the new abstraction + (vFfNew). Returns the integer map, which remaps every binary flop found + in the old abstraction into a binary flop found in the new abstraction.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Wlc_NtkFlopsRemap( Wlc_Ntk_t * p, Vec_Int_t * vFfOld, Vec_Int_t * vFfNew ) +{ + Vec_Int_t * vMap = Vec_IntAlloc( 1000 ); // the resulting map + Vec_Int_t * vMapFfNew2Bit1 = Vec_IntAlloc( 1000 ); // first binary bit of each new word-level flop + int i, b, iFfOld, iFfNew, iBit1New, nBits = 0; + // map object IDs of old flops into their flop indexes + Vec_Int_t * vMapFfObj2FfId = Vec_IntStartFull( Wlc_NtkObjNumMax(p) ); + Vec_IntForEachEntry( vFfNew, iFfNew, i ) + Vec_IntWriteEntry( vMapFfObj2FfId, iFfNew, i ); + // map each new flop index into its first bit + Vec_IntForEachEntry( vFfNew, iFfNew, i ) + { + Wlc_Obj_t * pObj = Wlc_NtkObj( p, iFfNew ); + int nRange = Wlc_ObjRange( pObj ); + Vec_IntPush( vMapFfNew2Bit1, nBits ); + nBits += nRange; + } + assert( Vec_IntSize(vMapFfNew2Bit1) == Vec_IntSize(vFfNew) ); + // remap old binary flops into new binary flops + Vec_IntForEachEntry( vFfOld, iFfOld, i ) + { + Wlc_Obj_t * pObj = Wlc_NtkObj( p, iFfOld ); + int nRange = Wlc_ObjRange( pObj ); + iFfNew = Vec_IntEntry( vMapFfObj2FfId, iFfOld ); + assert( iFfNew >= 0 ); // every old flop should be present in the new abstraction + // find the first bit of this new flop + iBit1New = Vec_IntEntry( vMapFfNew2Bit1, iFfNew ); + for ( b = 0; b < nRange; b++ ) + Vec_IntPush( vMap, iBit1New + b ); + } + Vec_IntFree( vMapFfNew2Bit1 ); + Vec_IntFree( vMapFfObj2FfId ); + return vMap; +} + /**Function************************************************************* Synopsis [Performs PDR with word-level abstraction.] @@ -316,7 +368,8 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) abctime pdrClk; Pdr_Man_t * pPdr; Vec_Vec_t * vClauses = NULL; - int nIters, nNodes, nDcFlops, RetValue = -1; + Vec_Int_t * vFfOld = NULL, * vFfNew = NULL, * vMap = NULL; + int nIters, nNodes, nDcFlops, RetValue = -1, nGiaFfNumOld = -1; // start the bitmap to mark objects that cannot be abstracted because of refinement // currently, this bitmap is empty because abstraction begins without refinement Vec_Bit_t * vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(p) ); @@ -339,9 +392,25 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) printf( "\nIteration %d:\n", nIters ); // get abstracted GIA and the set of pseudo-PIs (vPisNew) - pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, pPars->fVerbose ); + pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, &vFfNew, pPars->fVerbose ); pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 ); + // map old flops into new flops + if ( vFfOld ) + { + assert( nGiaFfNumOld >= 0 ); + vMap = Wlc_NtkFlopsRemap( p, vFfOld, vFfNew ); + //Vec_IntPrint( vMap ); + // if reset flop was added in the previous iteration, it will be added again in this iteration + // remap the last flop (reset flop) into the last flop (reset flop) of the current AIG + if ( Vec_IntSize(vMap) + 1 == nGiaFfNumOld ) + Vec_IntPush( vMap, Gia_ManRegNum(pGia)-1 ); + assert( Vec_IntSize(vMap) == nGiaFfNumOld ); + Vec_IntFreeP( &vFfOld ); + } + ABC_SWAP( Vec_Int_t *, vFfOld, vFfNew ); + nGiaFfNumOld = Gia_ManRegNum(pGia); + // if the abstraction has flops with DC-init state, // new PIs were introduced by bit-blasting at the end of the PI list // here we move these variables to be *before* PPIs, because @@ -373,8 +442,9 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) if ( vClauses ) { assert( Vec_VecSize( vClauses) >= 2 ); - IPdr_ManRestore( pPdr, vClauses ); + IPdr_ManRestore( pPdr, vClauses, vMap ); } + Vec_IntFreeP( &vMap ); RetValue = IPdr_ManSolveInt( pPdr, pPars->fCheckClauses, pPars->fPushClauses ); pPdr->tTotal += Abc_Clock() - pdrClk; @@ -418,6 +488,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) Aig_ManStop( pAig ); } + Vec_IntFreeP( &vFfOld ); Vec_BitFree( vUnmark ); // report the result if ( pPars->fVerbose ) @@ -479,7 +550,7 @@ int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) printf( "\nIteration %d:\n", nIters ); // get abstracted GIA and the set of pseudo-PIs (vPisNew) - pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, pPars->fVerbose ); + pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, NULL, pPars->fVerbose ); pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 ); // if the abstraction has flops with DC-init state, diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c index 6de86c188..3fcd3d312 100644 --- a/src/proof/pdr/pdrIncr.c +++ b/src/proof/pdr/pdrIncr.c @@ -190,7 +190,7 @@ sat_solver * IPdr_ManSetSolver( Pdr_Man_t * p, int k, int nTotal ) SeeAlso [] ***********************************************************************/ -int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses ) +int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses, Vec_Int_t * vMap ) { int i; @@ -199,6 +199,15 @@ int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses ) Vec_VecFree(p->vClauses); p->vClauses = vClauses; + // remap clause literals using mapping (old flop -> new flop) found in array vMap + if ( vMap ) + { + Pdr_Set_t * pSet; int j, k; + Vec_VecForEachEntry( Pdr_Set_t *, vClauses, pSet, i, j ) + for ( k = 0; k < pSet->nLits; k++ ) + pSet->Lits[k] = Abc_Lit2LitV( Vec_IntArray(vMap), pSet->Lits[k] ); + } + for ( i = 0; i < Vec_VecSize(p->vClauses); ++i ) IPdr_ManSetSolver( p, i, Vec_VecSize( p->vClauses ) ); @@ -646,7 +655,7 @@ int IPdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) Pdr_ManStop( p ); p = Pdr_ManStart( pAig, pPars, NULL ); - IPdr_ManRestore( p, vClausesSaved ); + IPdr_ManRestore( p, vClausesSaved, NULL ); pPars->nFrameMax = pPars->nFrameMax << 1; From dd8cc7e9a27e2bd962d612911c6fd9508c6c1e0d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 22 Feb 2017 13:03:53 -0800 Subject: [PATCH 185/185] Removing unused procedure. --- src/aig/gia/gia.h | 1 - src/aig/gia/giaUtil.c | 19 ------------------- 2 files changed, 20 deletions(-) diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 108048507..5ad87008c 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1588,7 +1588,6 @@ extern void Gia_ManSwapPos( Gia_Man_t * p, int i ); extern Vec_Int_t * Gia_ManSaveValue( Gia_Man_t * p ); extern void Gia_ManLoadValue( Gia_Man_t * p, Vec_Int_t * vValues ); extern Vec_Int_t * Gia_ManFirstFanouts( Gia_Man_t * p ); -extern void Gia_ManDetectMuxes( Gia_Man_t * p ); /*=== giaCTas.c ===========================================================*/ typedef struct Tas_Man_t_ Tas_Man_t; diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index d100b6c1e..c7af642ec 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -2050,25 +2050,6 @@ void Gia_AigerWriteLut( Gia_Man_t * p, char * pFileName ) Vec_WrdFree( vTruths ); } -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_ManDetectMuxes( Gia_Man_t * p ) -{ - Gia_Obj_t * pObj = NULL, * pNodeT, * pNodeE; int i; - Gia_ManForEachObj( p, pObj, i ); - if ( Gia_ObjIsAnd(pObj) && Gia_ObjRecognizeMux(pObj, &pNodeT, &pNodeE) ) - pObj->fMark0 = 1; -} - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// ////////////////////////////////////////////////////////////////////////