| /**CFile**************************************************************** |
| |
| FileName [wlcStdin.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [Verilog parser.] |
| |
| Synopsis [stdin processing for STM interface.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - August 22, 2014.] |
| |
| Revision [$Id: wlcStdin.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "wlc.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [Converts a bit-string into a number in a given radix.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Wlc_ComputeSum( char * pRes, char * pAdd, int nBits, int Radix ) |
| { |
| char Carry = 0; int i; |
| for ( i = 0; i < nBits; i++ ) |
| { |
| char Sum = pRes[i] + pAdd[i] + Carry; |
| if ( Sum >= Radix ) |
| { |
| Sum -= Radix; |
| Carry = 1; |
| } |
| else |
| Carry = 0; |
| assert( Sum >= 0 && Sum < Radix ); |
| pRes[i] = Sum; |
| } |
| assert( Carry == 0 ); |
| } |
| Vec_Str_t * Wlc_ConvertToRadix( unsigned * pBits, int Start, int nBits, int Radix ) |
| { |
| Vec_Str_t * vRes = Vec_StrStart( nBits ); |
| Vec_Str_t * vSum = Vec_StrStart( nBits ); |
| char * pRes = Vec_StrArray( vRes ); |
| char * pSum = Vec_StrArray( vSum ); int i; |
| assert( Radix >= 2 && Radix < 36 ); |
| pSum[0] = 1; |
| // compute number |
| for ( i = 0; i < nBits; i++ ) |
| { |
| if ( Abc_InfoHasBit(pBits, Start + i) ) |
| Wlc_ComputeSum( pRes, pSum, nBits, Radix ); |
| if ( i < nBits - 1 ) |
| Wlc_ComputeSum( pSum, pSum, nBits, Radix ); |
| } |
| Vec_StrFree( vSum ); |
| // remove zeros |
| for ( i = nBits - 1; i >= 0; i-- ) |
| if ( pRes[i] ) |
| break; |
| Vec_StrShrink( vRes, i+1 ); |
| // convert to chars |
| for ( ; i >= 0; i-- ) |
| { |
| if ( pRes[i] < 10 ) |
| pRes[i] += '0'; |
| else |
| pRes[i] += 'a' - 10; |
| } |
| Vec_StrReverseOrder( vRes ); |
| if ( Vec_StrSize(vRes) == 0 ) |
| Vec_StrPush( vRes, '0' ); |
| Vec_StrPush( vRes, '\0' ); |
| return vRes; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Report results.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Wlc_NtkReport( Wlc_Ntk_t * p, Abc_Cex_t * pCex, char * pName, int Radix ) |
| { |
| Vec_Str_t * vNum; |
| int i, NameId, Name, Start = -1, nBits = -1; |
| assert( pCex->nRegs == 0 ); |
| // get the name ID |
| NameId = Abc_NamStrFind( p->pManName, pName ); |
| if ( NameId <= 0 ) |
| { |
| printf( "Cannot find \"%s\" among nodes of the network.\n", pName ); |
| return; |
| } |
| // get the primary input |
| Vec_IntForEachEntryTriple( &p->vValues, Name, Start, nBits, i ) |
| if ( Name == NameId ) |
| break; |
| // find the PI |
| if ( i == Vec_IntSize(&p->vValues) ) |
| { |
| printf( "Cannot find \"%s\" among primary inputs of the network.\n", pName ); |
| return; |
| } |
| // print value |
| assert( Radix == 2 || Radix == 10 || Radix == 16 ); |
| vNum = Wlc_ConvertToRadix( pCex->pData, Start, nBits, Radix ); |
| printf( "((%s %s%s))\n", pName, Radix == 16 ? "#x" : (Radix == 2 ? "#b" : ""), Vec_StrArray(vNum) ); |
| Vec_StrFree( vNum ); |
| } |
| |
| /**Function******************************************************************** |
| |
| Synopsis [Reads stdin and stops when "(check-sat)" is observed.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ******************************************************************************/ |
| static inline int Wlc_StdinCollectStop( Vec_Str_t * vInput, char * pLine, int LineSize ) |
| { |
| char * pStr = Vec_StrArray(vInput) + Vec_StrSize(vInput) - LineSize; |
| if ( Vec_StrSize(vInput) < LineSize ) |
| return 0; |
| return !strncmp( pStr, pLine, LineSize ); |
| } |
| Vec_Str_t * Wlc_StdinCollectProblem( char * pDir ) |
| { |
| int c, DirSize = strlen(pDir); |
| Vec_Str_t * vInput = Vec_StrAlloc( 1000 ); |
| while ( (c = fgetc(stdin)) != EOF ) |
| { |
| Vec_StrPush( vInput, (char)c ); |
| if ( c == ')' && Wlc_StdinCollectStop(vInput, pDir, DirSize) ) |
| break; |
| } |
| Vec_StrPush( vInput, '\0' ); |
| return vInput; |
| } |
| Vec_Str_t * Wlc_StdinCollectQuery() |
| { |
| int c, Count = 0, fSomeInput = 0; |
| Vec_Str_t * vInput = Vec_StrAlloc( 1000 ); |
| while ( (c = fgetc(stdin)) != EOF ) |
| { |
| Vec_StrPush( vInput, (char)c ); |
| if ( c == '(' ) |
| Count++, fSomeInput = 1; |
| else if ( c == ')' ) |
| Count--; |
| if ( Count == 0 && fSomeInput ) |
| break; |
| } |
| if ( c == EOF ) |
| Vec_StrFreeP( &vInput ); |
| else |
| Vec_StrPush( vInput, '\0' ); |
| return vInput; |
| } |
| int Wlc_StdinProcessSmt( Abc_Frame_t * pAbc, char * pCmd ) |
| { |
| // collect stdin until (check-sat) |
| Vec_Str_t * vInput = Wlc_StdinCollectProblem( "(check-sat)" ); |
| // parse input |
| Wlc_Ntk_t * pNtk = Wlc_ReadSmtBuffer( "top", Vec_StrArray(vInput), Vec_StrArray(vInput) + Vec_StrSize(vInput), 0, 0 ); |
| Vec_StrFree( vInput ); |
| // install current network |
| Wlc_SetNtk( pAbc, pNtk ); |
| // execute command |
| if ( Cmd_CommandExecute(pAbc, pCmd) ) |
| { |
| Abc_Print( 1, "Something did not work out with the command \"%s\".\n", pCmd ); |
| return 0; |
| } |
| // solver finished |
| if ( Abc_FrameReadProbStatus(pAbc) == -1 ) |
| printf( "undecided\n" ); |
| else if ( Abc_FrameReadProbStatus(pAbc) == 1 ) |
| printf( "unsat\n" ); |
| else if ( Abc_FrameReadProbStatus(pAbc) == 0 ) |
| printf( "sat\n" ); |
| else assert( 0 ); |
| fflush( stdout ); |
| // wait for stdin for give directions |
| while ( (vInput = Wlc_StdinCollectQuery()) != NULL ) |
| { |
| char * pName = strtok( Vec_StrArray(vInput), " \n\t\r()" ); |
| // check directive |
| if ( strcmp(pName, "get-value") ) |
| { |
| Abc_Print( 1, "ABC is expecting \"get-value\" in a follow-up input of the satisfiable problem.\n" ); |
| Vec_StrFree( vInput ); |
| return 0; |
| } |
| // check status |
| if ( Abc_FrameReadProbStatus(pAbc) != 0 ) |
| { |
| Abc_Print( 1, "ABC received a follow-up input for a problem that is not known to be satisfiable.\n" ); |
| Vec_StrFree( vInput ); |
| return 0; |
| } |
| // get the variable number |
| pName = strtok( NULL, "() \n\t\r" ); |
| // get the counter-example |
| if ( Abc_FrameReadCex(pAbc) == NULL ) |
| { |
| Abc_Print( 1, "ABC does not have a counter-example available to process a \"get-value\" request.\n" ); |
| Vec_StrFree( vInput ); |
| return 0; |
| } |
| // report value of this variable |
| Wlc_NtkReport( (Wlc_Ntk_t *)pAbc->pAbcWlc, (Abc_Cex_t *)Abc_FrameReadCex(pAbc), pName, 16 ); |
| Vec_StrFree( vInput ); |
| fflush( stdout ); |
| } |
| return 1; |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |