diff options
| author | Alan Mishchenko <alanmi@berkeley.edu> | 2015-02-28 22:05:46 -0800 | 
|---|---|---|
| committer | Alan Mishchenko <alanmi@berkeley.edu> | 2015-02-28 22:05:46 -0800 | 
| commit | f27979fc8fd5663d2bc9d9bad3fcbed2acfc4e17 (patch) | |
| tree | 32cecbcbad6ecbce283584c9790c99cd81e32e09 | |
| parent | 2fcdd113162665234486485c6c150c3f5521b80c (diff) | |
| download | abc-f27979fc8fd5663d2bc9d9bad3fcbed2acfc4e17.tar.gz abc-f27979fc8fd5663d2bc9d9bad3fcbed2acfc4e17.tar.bz2 abc-f27979fc8fd5663d2bc9d9bad3fcbed2acfc4e17.zip | |
Improvements to the SMTLIB parser.
| -rw-r--r-- | src/base/wlc/wlcBlast.c | 4 | ||||
| -rw-r--r-- | src/base/wlc/wlcReadSmt.c | 1216 | 
2 files changed, 687 insertions, 533 deletions
| diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index 4a935f6b..a4e5459e 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -107,6 +107,8 @@ void Wlc_BlastShiftRight( Gia_Man_t * pNew, int * pNum, int nNum, int * pShift,      int * pRes = Wlc_VecCopy( vRes, pNum, nNum );      int Fill = fSticky ? pNum[nNum-1] : 0;      int i, j, fShort = 0; +    if ( nShift > 32 ) +        nShift = 32;      assert( nShift <= 32 );      for( i = 0; i < nShift; i++ )           for( j = 0; j < nNum - fSticky; j++ )  @@ -126,6 +128,8 @@ void Wlc_BlastShiftLeft( Gia_Man_t * pNew, int * pNum, int nNum, int * pShift, i      int * pRes = Wlc_VecCopy( vRes, pNum, nNum );      int Fill = fSticky ? pNum[0] : 0;      int i, j, fShort = 0; +    if ( nShift > 32 ) +        nShift = 32;      assert( nShift <= 32 );      for( i = 0; i < nShift; i++ )           for( j = nNum-1; j >= fSticky; j-- )  diff --git a/src/base/wlc/wlcReadSmt.c b/src/base/wlc/wlcReadSmt.c index 7093d79d..8143be6c 100644 --- a/src/base/wlc/wlcReadSmt.c +++ b/src/base/wlc/wlcReadSmt.c @@ -1,6 +1,6 @@  /**CFile**************************************************************** -  FileName    [wlcReadSmt.c] +  FileName    [wlcParse.c]    SystemName  [ABC: Logic synthesis and verification system.] @@ -14,11 +14,12 @@    Date        [Ver. 1.0. Started - August 22, 2014.] -  Revision    [$Id: wlcReadSmt.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] +  Revision    [$Id: wlcParse.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $]  ***********************************************************************/  #include "wlc.h" +#include "misc/vec/vecWec.h"  ABC_NAMESPACE_IMPL_START @@ -26,19 +27,9 @@ ABC_NAMESPACE_IMPL_START  ///                        DECLARATIONS                              ///  //////////////////////////////////////////////////////////////////////// -// parser name types -typedef enum {  -    PRS_SMT_NONE = 0,  -    PRS_SMT_INPUT,     -    PRS_SMT_CONST,     -    PRS_SMT_LET,    -    PRS_SMT_ASSERT, -    PRS_SMT_VALUE -} Prs_ManType_t;  -  // parser -typedef struct Prs_Smt_t_ Prs_Smt_t; -struct Prs_Smt_t_ +typedef struct Smt_Prs_t_ Smt_Prs_t; +struct Smt_Prs_t_  {      // input data      char *       pName;       // file name @@ -47,81 +38,77 @@ struct Prs_Smt_t_      char *       pCur;        // current position      Abc_Nam_t *  pStrs;       // string manager      // network structure -    Vec_Int_t    vData; -    Vec_Int_t    vValues; +    Vec_Int_t    vStack;      // current node on each level +    //Vec_Wec_t    vDepth;      // objects on each level +    Vec_Wec_t    vObjs;       // objects      // error handling -    char ErrorStr[1000];       +    char ErrorStr[1000];       }; - -// create error message -static inline int Prs_SmtErrorSet( Prs_Smt_t * p, char * pError, int Value ) +// parser name types +typedef enum {  +    SMT_PRS_NONE = 0,  +    SMT_PRS_SET_OPTION,     +    SMT_PRS_SET_LOGIC,     +    SMT_PRS_SET_INFO,     +    SMT_PRS_DEFINE_FUN, +    SMT_PRS_DECLARE_FUN,    +    SMT_PRS_ASSERT,    +    SMT_PRS_LET,    +    SMT_PRS_CHECK_SAT,    +    SMT_PRS_GET_VALUE,    +    SMT_PRS_EXIT, +    SMT_PRS_END +} Smt_LineType_t;  + +typedef struct Smt_Pair_t_ Smt_Pair_t; +struct Smt_Pair_t_  { -    assert( !p->ErrorStr[0] ); -    sprintf( p->ErrorStr, "%s", pError ); -    return Value; -} -// clear error message -static inline void Prs_SmtErrorClear( Prs_Smt_t * p ) +    Smt_LineType_t Type; +    char *         pName; +}; +static Smt_Pair_t s_Types[SMT_PRS_END] =  { -    p->ErrorStr[0] = '\0'; -} -// print error message -static inline int Prs_SmtErrorPrint( Prs_Smt_t * p ) +    { SMT_PRS_NONE,         NULL         }, +    { SMT_PRS_SET_OPTION,  "set-option"  }, +    { SMT_PRS_SET_LOGIC,   "set-logic"   }, +    { SMT_PRS_SET_INFO,    "set-info"    }, +    { SMT_PRS_DEFINE_FUN,  "define-fun"  }, +    { SMT_PRS_DECLARE_FUN, "declare-fun" }, +    { SMT_PRS_ASSERT,      "assert"      }, +    { SMT_PRS_LET,         "let"         }, +    { SMT_PRS_CHECK_SAT,   "check-sat"   }, +    { SMT_PRS_GET_VALUE,   "get-value"   }, +    { SMT_PRS_EXIT,        "exit"        } +}; +static inline char * Smt_GetTypeName( Smt_LineType_t Type )  { -    char * pThis; int iLine = 0; -    if ( !p->ErrorStr[0] ) return 1; -    for ( pThis = p->pBuffer; pThis < p->pCur; pThis++ ) -        iLine += (int)(*pThis == '\n'); -    printf( "Line %d: %s\n", iLine, p->ErrorStr ); -    return 0; +    Smt_LineType_t i; +    for ( i = 1; i < SMT_PRS_END; i++ ) +        if ( s_Types[i].Type == Type ) +            return s_Types[i].pName; +    return NULL;  } -static inline char * Prs_SmtLoadFile( char * pFileName, char ** ppLimit ) +static inline void Smt_AddTypes( Abc_Nam_t * p )  { -    char * pBuffer; -    int nFileSize, RetValue; -    FILE * pFile = fopen( pFileName, "rb" ); -    if ( pFile == NULL ) -    { -        printf( "Cannot open input file.\n" ); -        return NULL; -    } -    // 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 ); -    pBuffer[0] = '\n'; -    RetValue = fread( pBuffer+1, nFileSize, 1, pFile ); -    // terminate the string with '\0' -    pBuffer[nFileSize + 0] = '\n'; -    pBuffer[nFileSize + 1] = '\0'; -    *ppLimit = pBuffer + nFileSize + 2; -    return pBuffer; -} -static inline Prs_Smt_t * Prs_SmtAlloc( char * pFileName, char * pBuffer, char * pLimit ) -{ -    Prs_Smt_t * p; -    p = ABC_CALLOC( Prs_Smt_t, 1 ); -    p->pName   = pFileName; -    p->pBuffer = pBuffer; -    p->pLimit  = pLimit; -    p->pCur    = pBuffer; -    p->pStrs   = Abc_NamStart( 1000, 24 ); -    Vec_IntGrow ( &p->vData, 1000 ); -    return p; +    Smt_LineType_t Type; +    for ( Type = 1; Type < SMT_PRS_END; Type++ ) +        Abc_NamStrFindOrAdd( p, Smt_GetTypeName(Type), NULL ); +    assert( Abc_NamObjNumMax(p) == SMT_PRS_END );  } -static inline void Prs_SmtFree( Prs_Smt_t * p ) -{ -    if ( p->pStrs ) -        Abc_NamDeref( p->pStrs ); -    Vec_IntErase( &p->vData ); -    Vec_IntErase( &p->vValues ); -    ABC_FREE( p ); -} +static inline int         Smt_EntryIsName( int Fan )                          { return Abc_LitIsCompl(Fan);                                                         } +static inline int         Smt_EntryIsType( int Fan, Smt_LineType_t Type )     { assert(Smt_EntryIsName(Fan));  return Abc_Lit2Var(Fan) == Type;                     } +static inline char *      Smt_EntryName( Smt_Prs_t * p, int Fan )             { assert(Smt_EntryIsName(Fan));  return Abc_NamStr( p->pStrs, Abc_Lit2Var(Fan) );     } +static inline Vec_Int_t * Smt_EntryNode( Smt_Prs_t * p, int Fan )             { assert(!Smt_EntryIsName(Fan)); return Vec_WecEntry( &p->vObjs, Abc_Lit2Var(Fan) );  } + +static inline int         Smt_VecEntryIsType( Vec_Int_t * vFans, int i, Smt_LineType_t Type ) { return i < Vec_IntSize(vFans) && Smt_EntryIsName(Vec_IntEntry(vFans, i)) && Smt_EntryIsType(Vec_IntEntry(vFans, i), Type); } +static inline char *      Smt_VecEntryName( Smt_Prs_t * p, Vec_Int_t * vFans, int i )         { return Smt_EntryIsName(Vec_IntEntry(vFans, i)) ? Smt_EntryName(p, Vec_IntEntry(vFans, i)) : NULL;                          } +static inline Vec_Int_t * Smt_VecEntryNode( Smt_Prs_t * p, Vec_Int_t * vFans, int i )         { return Smt_EntryIsName(Vec_IntEntry(vFans, i)) ? NULL : Smt_EntryNode(p, Vec_IntEntry(vFans, i));                          } + +#define Smt_ManForEachDir( p, Type, vVec, i )                                                       \ +    for ( i = 0; (i < Vec_WecSize(&p->vObjs)) && (((vVec) = Vec_WecEntry(&p->vObjs, i)), 1); i++ )  \ +        if ( !Smt_VecEntryIsType(vVec, 0, Type) ) {} else  ////////////////////////////////////////////////////////////////////////  ///                     FUNCTION DEFINITIONS                         /// @@ -138,306 +125,7 @@ static inline void Prs_SmtFree( Prs_Smt_t * p )    SeeAlso     []  ***********************************************************************/ -static inline void Prs_SmtRemoveComments( Prs_Smt_t * p ) -{ -    char * pTemp; -    for ( pTemp = p->pBuffer; pTemp < p->pLimit; pTemp++ ) -        if ( *pTemp == ';' ) -            while ( *pTemp && *pTemp != '\n' ) -                *pTemp++ = ' '; -} -static inline void Prs_SmtSkipSpaces( Prs_Smt_t * p ) -{ -    while ( *p->pCur == ' ' || *p->pCur == '\t' || *p->pCur == '\r' || *p->pCur == '\n' ) -        p->pCur++; -} -static inline int Prs_SmtIsWord( Prs_Smt_t * p, char * pWord ) -{ -    Prs_SmtSkipSpaces( p ); -    if ( strncmp( p->pCur, pWord, strlen(pWord) ) ) -        return 0; -    p->pCur += strlen(pWord); -    Prs_SmtSkipSpaces( p ); -    return 1; -} -static inline char * Prs_SmtFindNextPar( Prs_Smt_t * p ) -{ -    char * pTemp; int Count = 1; -    for ( pTemp = p->pCur; pTemp < p->pLimit; pTemp++ ) -    { -        if ( *pTemp == '(' ) -            Count++; -        else if ( *pTemp == ')' ) -            Count--; -        if ( Count == 0 ) -            break; -    } -    assert( *pTemp == ')' ); -    return pTemp; -} -static inline int Prs_SmtParseLet( Prs_Smt_t * p, char * pLimit, int Type ) -{ -    char * pToken; -    assert( *pLimit == ')' ); -    *pLimit = 0; -    Vec_IntPush( &p->vData, 0 ); -    Vec_IntPush( &p->vData, Type ); -    pToken = strtok( p->pCur, " ()" ); -    while ( pToken ) -    { -        if ( pToken[0] != '_' && pToken[0] != '=' ) -            Vec_IntPush( &p->vData, Abc_NamStrFindOrAdd(p->pStrs, pToken, NULL) ); -        pToken = strtok( NULL, " ()" ); -    } -    assert( *pLimit == 0 ); -    *pLimit = ')'; -    p->pCur = pLimit; -    return 1; -} -static inline int Prs_SmtParseFun( Prs_Smt_t * p, char * pLimit, int Type ) -{ -    char * pToken; -    assert( *pLimit == ')' ); -    *pLimit = 0; -    Vec_IntPush( &p->vData, 0 ); -    Vec_IntPush( &p->vData, Type ); -    pToken = strtok( p->pCur, " ()" ); -    assert( pToken != NULL ); -    Vec_IntPush( &p->vData, Abc_NamStrFindOrAdd(p->pStrs, pToken, NULL) ); -    pToken = strtok( NULL, " ()" ); -    if ( pToken[0] == '_' ) -        pToken = strtok( NULL, " ()" ); -    if ( !strcmp(pToken, "Bool") ) -    { -        Vec_IntPush( &p->vData, Abc_NamStrFindOrAdd(p->pStrs, "1", NULL) ); -        pToken = strtok( NULL, " ()" ); -        if ( !strcmp(pToken, "false") ) -            Vec_IntPush( &p->vData, Abc_NamStrFindOrAdd(p->pStrs, "#b0", NULL) ); -        else if ( !strcmp(pToken, "true") ) -            Vec_IntPush( &p->vData, Abc_NamStrFindOrAdd(p->pStrs, "#b1", NULL) ); -        else assert( 0 ); -    } -    else if ( !strcmp(pToken, "BitVec") ) -    { -        pToken = strtok( NULL, " ()" ); -        Vec_IntPush( &p->vData, Abc_NamStrFindOrAdd(p->pStrs, pToken, NULL) ); -        pToken = strtok( NULL, " ()" ); -        if ( pToken ) -        { -            Vec_IntPush( &p->vData, Abc_NamStrFindOrAdd(p->pStrs, pToken, NULL) ); -            pToken = strtok( NULL, " ()" ); -            if ( pToken != NULL ) -                return Prs_SmtErrorSet(p, "Trailing symbols are not recognized.", 0); -        } -    } -    else  -        return Prs_SmtErrorSet(p, "Expecting either \"Bool\" or \"BitVec\".", 0); -    assert( *pLimit == 0 ); -    *pLimit = ')'; -    p->pCur = pLimit; -    return 1; -} -static inline int Prs_SmtParseValue( Prs_Smt_t * p, char * pLimit, int Type ) -{ -    char * pToken; -    assert( *pLimit == ')' ); -    *pLimit = 0; -    pToken = strtok( p->pCur, " ()" ); -    assert( pToken != NULL ); -    Vec_IntPush( &p->vValues, Abc_NamStrFindOrAdd(p->pStrs, pToken, NULL) ); -    pToken = strtok( NULL, " ()" ); -    assert( pToken == NULL ); -    assert( *pLimit == 0 ); -    *pLimit = ')'; -    p->pCur = pLimit; -    return 1; -} -int Prs_SmtReadLines( Prs_Smt_t * p ) -{ -    int fAssert = 0; -    Prs_SmtSkipSpaces( p ); -    while ( *p->pCur == '(' ) -    { -        p->pCur++; -        if ( Prs_SmtIsWord(p, "let") ) -        { -            assert( *p->pCur == '(' ); -            p->pCur++; -            if ( !Prs_SmtParseLet( p, Prs_SmtFindNextPar(p), PRS_SMT_LET ) ) -                return 0; -            assert( *p->pCur == ')' ); -            p->pCur++; -        } -        else if ( Prs_SmtIsWord(p, "declare-fun")  ) -        { -            if ( !Prs_SmtParseFun( p, Prs_SmtFindNextPar(p), PRS_SMT_INPUT ) ) -                return 0; -            assert( *p->pCur == ')' ); -            p->pCur++; -        } -        else if ( Prs_SmtIsWord(p, "define-fun") ) -        { -            if ( !Prs_SmtParseFun( p, Prs_SmtFindNextPar(p), PRS_SMT_CONST ) ) -                return 0; -            assert( *p->pCur == ')' ); -            p->pCur++; -        } -        else if ( Prs_SmtIsWord(p, "get-value") ) -        { -            if ( !Prs_SmtParseValue( p, Prs_SmtFindNextPar(p), PRS_SMT_VALUE ) ) -                return 0; -            assert( *p->pCur == ')' ); -            p->pCur++; -        } -        else if ( Prs_SmtIsWord(p, "assert") ) -            fAssert = 1; -        else if ( Prs_SmtIsWord(p, "check-sat") ) -            break; -        else if ( Prs_SmtIsWord(p, "set-option") || Prs_SmtIsWord(p, "set-logic") ) -            p->pCur = Prs_SmtFindNextPar(p) + 1; -//        else -            //return Prs_SmtErrorSet(p, "Unsupported directive.", 0); -        Prs_SmtSkipSpaces( p ); -        if ( *p->pCur != '(' && fAssert == 1 ) -        { -            fAssert = 0; -            // finish parsing assert -            if ( !Prs_SmtParseLet( p, Prs_SmtFindNextPar(p), PRS_SMT_ASSERT ) ) -                return 0; -            assert( *p->pCur == ')' ); -            Vec_IntPush( &p->vData, 0 ); -            // skip closing -            while ( *p->pCur == ')' ) -                p->pCur++; -            Prs_SmtSkipSpaces( p ); -        } -    } -    assert( fAssert == 0 ); -    return 1; -} - -/**Function************************************************************* - -  Synopsis    [] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -void Prs_SmtPrintParser( Prs_Smt_t * p ) -{ -    int Entry, i; -    Vec_IntForEachEntry( &p->vData, Entry, i ) -    { -        if ( Entry == 0 ) -        { -            printf( "\n" ); -            if ( i == Vec_IntSize(&p->vData) - 1 ) -                break; -            Entry = Vec_IntEntry(&p->vData, ++i); -            if ( Entry == PRS_SMT_INPUT ) -                printf( "declare-fun" ); -            else if ( Entry == PRS_SMT_CONST ) -                printf( "define-fun" ); -            else if ( Entry == PRS_SMT_LET ) -                printf( "let" ); -            else if ( Entry == PRS_SMT_ASSERT ) -                printf( "assert" ); -            else assert(0); -            continue; -        } -        printf( " %s", Abc_NamStr(p->pStrs, Entry) ); -    } -    Vec_IntForEachEntry( &p->vValues, Entry, i ) -        printf( "get-value %s\n", Abc_NamStr(p->pStrs, Entry) ); -} - - - -/**Function************************************************************* - -  Synopsis    [] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -static inline int Prs_SmtReadConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits, Vec_Int_t * vFanins, char * pName ) -{ -    char Buffer[100]; -    int i, nDigits, iObj, NameId, fFound; -    Vec_IntClear( vFanins ); -    if ( pStr[0] != '#' ) -    { -        // handle decimal number -        int Number = atoi( pStr ); -        nBits = Abc_Base2Log( Number+1 ); -        assert( nBits < 32 ); -        Vec_IntPush( vFanins, Number ); -    } -    else if ( pStr[1] == 'b' ) -    { -        if ( nBits == -1 ) -            nBits = strlen(pStr+2); -        Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 ); -        for ( i = 0; i < nBits; i++ ) -            if ( pStr[2+i] == '1' ) -                Abc_InfoSetBit( (unsigned *)Vec_IntArray(vFanins), nBits-1-i ); -            else if ( pStr[2+i] != '0' ) -                return 0; -    } -    else if ( pStr[1] == 'x' ) -    { -        if ( nBits == -1 ) -            nBits = strlen(pStr+2)*4; -        Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 ); -        nDigits = Abc_TtReadHexNumber( (word *)Vec_IntArray(vFanins), pStr+2 ); -        if ( nDigits != (nBits + 3)/4 ) -            assert( 0 ); -    } -    else return 0; -    // create constant node -    iObj = Wlc_ObjAlloc( pNtk, WLC_OBJ_CONST, 0, nBits-1, 0 ); -    Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj), vFanins ); -    // add node's name -    if ( pName == NULL ) -    { -        sprintf( Buffer, "_c%d_", iObj ); -        pName = Buffer; -    } -    NameId = Abc_NamStrFindOrAdd( pNtk->pManName, pName, &fFound ); -    assert( !fFound ); -    assert( iObj == NameId ); -    return NameId; -} -static inline int Prs_SmtReadName( Wlc_Ntk_t * pNtk, char * pStr, int nBits, Vec_Int_t * vFanins ) -{ -    if ( (pStr[0] >= '0' && pStr[0] <= '9') || pStr[0] == '#' ) -    { -        Vec_Int_t * vTemp = Vec_IntAlloc(0); -        int NameId = Prs_SmtReadConstant( pNtk, pStr, nBits, vTemp, NULL ); -        Vec_IntFree( vTemp ); -        if ( !NameId ) -            return 0; -        Vec_IntPush( vFanins, NameId ); -        return 1; -    } -    else -    { -        // read name -        int fFound, NameId = Abc_NamStrFindOrAdd( pNtk->pManName, pStr, &fFound ); -        assert( fFound ); -        Vec_IntPush( vFanins, NameId ); -        return 1; -    } -} -static inline int Prs_SmtStrToType( char * pName, int * pfSigned ) +static inline int Smt_StrToType( char * pName, int * pfSigned )  {      int Type = 0; *pfSigned = 0;      if ( !strcmp(pName, "ite") ) @@ -534,209 +222,670 @@ static inline int Prs_SmtStrToType( char * pName, int * pfSigned )      }      return Type;  } -static inline int Prs_SmtReadNode( Prs_Smt_t * p, Wlc_Ntk_t * pNtk, Vec_Int_t * vData, int i, Vec_Int_t * vFanins, int * pRange, int * pfSigned ) +static inline int Smt_PrsReadType( Smt_Prs_t * p, int iSig, int * pfSigned, int * Value1, int * Value2 )  { -    int Type, NameId; -    char * pName = Abc_NamStr( p->pStrs, Vec_IntEntry(vData, i) ); -    // read type -    Type = Prs_SmtStrToType( pName, pfSigned ); -    if ( Type == 0 ) -        return 0; -    *pRange = 0; -    Vec_IntClear( vFanins ); -    if ( Type == WLC_OBJ_COMP_EQU ) +    if ( Smt_EntryIsName(iSig) ) +        return Smt_StrToType( Smt_EntryName(p, iSig), pfSigned ); +    else      { -        *pRange = 1; -        Prs_SmtReadName( pNtk, Abc_NamStr(p->pStrs, Vec_IntEntry(vData, ++i)), -1, vFanins ); -        Prs_SmtReadName( pNtk, Abc_NamStr(p->pStrs, Vec_IntEntry(vData, ++i)), -1, vFanins ); -        return WLC_OBJ_COMP_EQU; +        Vec_Int_t * vFans = Smt_EntryNode( p, iSig ); +        char * pStr = Smt_VecEntryName( p, vFans, 0 );  int Type; +        assert( Vec_IntSize(vFans) >= 3 ); +        assert( !strcmp(pStr, "_") ); // special op +        *Value1 = *Value2 = -1; +        assert( pStr[0] != 'b' || pStr[1] != 'v' ); +        // read type +        Type = Smt_StrToType( Smt_VecEntryName(p, vFans, 1), pfSigned ); +        if ( Type == 0 ) +            return 0; +        *Value1 = atoi( Smt_VecEntryName(p, vFans, 2) ); +        if ( Vec_IntSize(vFans) > 3 ) +            *Value2 = atoi( Smt_VecEntryName(p, vFans, 3) ); +        return Type;      } -    else if ( Type == WLC_OBJ_LOGIC_NOT ) +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Smt_PrsCreateNode( Wlc_Ntk_t * pNtk, int Type, int fSigned, int Range, Vec_Int_t * vFanins, char * pName ) +{ +    char Buffer[100]; +    int NameId, fFound; +    int iObj = Wlc_ObjAlloc( pNtk, Type, fSigned, Range-1, 0 ); +    assert( Type > 0 ); +    assert( Range >= 0 ); +    assert( fSigned >= 0 ); +    Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj), vFanins ); +    if ( fSigned )      { -        pName = Abc_NamStr( p->pStrs, Vec_IntEntry(vData, ++i) ); -        if ( !strcmp(pName, "bvcomp") ) -        { -            *pRange = 1; -            Prs_SmtReadName( pNtk, Abc_NamStr(p->pStrs, Vec_IntEntry(vData, ++i)), -1, vFanins ); -            Prs_SmtReadName( pNtk, Abc_NamStr(p->pStrs, Vec_IntEntry(vData, ++i)), -1, vFanins ); -            return WLC_OBJ_COMP_NOTEQU;   // 26: compare equal -        } -        i--; +        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;      } -    else if ( Type == WLC_OBJ_BIT_SELECT ) +    if ( pName == NULL )      { -        int End, Beg; -        pName = Abc_NamStr( p->pStrs, Vec_IntEntry(vData, ++i) ); -        End = atoi( pName ); -        pName = Abc_NamStr( p->pStrs, Vec_IntEntry(vData, ++i) ); -        Beg = atoi( pName ); -        pName = Abc_NamStr( p->pStrs, Vec_IntEntry(vData, ++i) ); -        Prs_SmtReadName( pNtk, pName, -1, vFanins ); -        Vec_IntPush( vFanins, (End << 16) | Beg ); -        *pRange = End - Beg + 1; -        return WLC_OBJ_BIT_SELECT; +        sprintf( Buffer, "_n%d_", iObj ); +        pName = Buffer;      } -    while ( Vec_IntEntry(vData, ++i) ) -        Prs_SmtReadName( pNtk, Abc_NamStr(p->pStrs, Vec_IntEntry(vData, i)), -1, vFanins ); -    if ( Type == WLC_OBJ_ROTATE_R || Type == WLC_OBJ_ROTATE_L ) +    // add node's name +    NameId = Abc_NamStrFindOrAdd( pNtk->pManName, pName, &fFound ); +    assert( !fFound ); +    assert( iObj == NameId ); +    return iObj; +} +static inline int Smt_PrsBuildConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits, char * pName ) +{ +    int i, nDigits, iObj; +    Vec_Int_t * vFanins = Vec_IntAlloc( 10 ); +    if ( pStr[0] != '#' ) // decimal      { -        int * pArray = Vec_IntArray(vFanins); -        assert( Vec_IntSize(vFanins) == 2 ); -        ABC_SWAP( int, pArray[0], pArray[1] ); -    }     -    if ( Type >= WLC_OBJ_LOGIC_NOT && Type <= WLC_OBJ_REDUCT_XOR ) -        *pRange = 1; -    else if ( Type == WLC_OBJ_BIT_CONCAT ) +        int Number = atoi( pStr ); +        nBits = Abc_Base2Log( Number+1 ); +        assert( nBits < 32 ); +        Vec_IntPush( vFanins, Number ); +    } +    else if ( pStr[1] == 'b' ) // binary      { -        int k; -        Vec_IntForEachEntry( vFanins, NameId, k ) -            *pRange += Wlc_ObjRange( Wlc_NtkObj(pNtk, NameId) ); +        if ( nBits == -1 ) +            nBits = strlen(pStr+2); +        Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 ); +        for ( i = 0; i < nBits; i++ ) +            if ( pStr[2+i] == '1' ) +                Abc_InfoSetBit( (unsigned *)Vec_IntArray(vFanins), nBits-1-i ); +            else if ( pStr[2+i] != '0' ) +                return 0;      } -    else if ( Type == WLC_OBJ_MUX ) +    else if ( pStr[1] == 'x' ) // hexadecimal      { -        int * pArray = Vec_IntArray(vFanins); -        assert( Vec_IntSize(vFanins) == 3 ); -        ABC_SWAP( int, pArray[1], pArray[2] ); -        NameId = Vec_IntEntry(vFanins, 1); -        *pRange = Wlc_ObjRange( Wlc_NtkObj(pNtk, NameId) ); +        if ( nBits == -1 ) +            nBits = strlen(pStr+2)*4; +        Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 ); +        nDigits = Abc_TtReadHexNumber( (word *)Vec_IntArray(vFanins), pStr+2 ); +        if ( nDigits != (nBits + 3)/4 ) +            return 0;      } -    else // to determine range, look at the first argument +    else return 0; +    // create constant node +    iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_CONST, 0, nBits, vFanins, pName ); +    Vec_IntFree( vFanins ); +    return iObj; +} +int Smt_PrsBuildNode( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int RangeOut, char * pName ) +{ +    if ( Smt_EntryIsName(iNode) ) // name or constant      { -        NameId = Vec_IntEntry(vFanins, 0); -        *pRange = Wlc_ObjRange( Wlc_NtkObj(pNtk, NameId) ); +        char * pStr = Abc_NamStr(p->pStrs, Abc_Lit2Var(iNode)); +        if ( (pStr[0] >= '0' && pStr[0] <= '9') || pStr[0] == '#' ) +        {  +            // (_ BitVec 8) #x19 +            return Smt_PrsBuildConstant( pNtk, pStr, RangeOut, pName ); +        } +        else +        { +            // s3087 +            int fFound, iObj = Abc_NamStrFindOrAdd( pNtk->pManName, pStr, &fFound ); +            assert( fFound ); +            return iObj; +        } +    } +    else // node +    { +        Vec_Int_t * vFans = Smt_EntryNode( p, iNode ); +        char * pStr0 = Smt_VecEntryName( p, vFans, 0 ); +        char * pStr1 = Smt_VecEntryName( p, vFans, 1 ); +        if ( pStr0 && pStr1 && pStr0[0] == '_' && pStr1[0] == 'b' && pStr1[1] == 'v' ) +        { +            // (_ bv1 32) +            char * pStr2 = Smt_VecEntryName( p, vFans, 2 ); +            assert( Vec_IntSize(vFans) == 3 ); +            return Smt_PrsBuildConstant( pNtk, pStr2+2, atoi(pStr2), pName ); +        } +        else if ( pStr0 && pStr0[0] == '=' ) +        { +            assert( Vec_IntSize(vFans) == 3 ); +            iNode = Vec_IntEntry(vFans, 2); +            assert( Smt_EntryIsName(iNode) ); +            pStr0 = Smt_EntryName(p, iNode); +            // check the last one is "#b1" +            if ( !strcmp("#b1", pStr0) ) +            { +                iNode = Vec_IntEntry(vFans, 1); +                return Smt_PrsBuildNode( pNtk, p, iNode, -1, pName ); +            } +            else +            { +                Vec_Int_t * vFanins = Vec_IntAlloc( 2 ); +                // get the constant +                int iObj, iOper, iConst = Smt_PrsBuildConstant( pNtk, pStr0, -1, NULL ); +                // check the middle one is an operator +                iNode = Vec_IntEntry(vFans, 1); +                iOper = Smt_PrsBuildNode( pNtk, p, iNode, -1, pName ); +                // build comparator +                Vec_IntPushTwo( vFanins, iOper, iConst ); +                iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_COMP_EQU, 0, 1, vFanins, pName ); +                Vec_IntFree( vFanins ); +                return iObj; +            } +        } +        else +        { +            int i, Fan, NameId, iFanin, fSigned, Range, Value1 = -1, Value2 = -1; +            int Type = Smt_PrsReadType( p, Vec_IntEntry(vFans, 0), &fSigned, &Value1, &Value2 ); +            // collect fanins +            Vec_Int_t * vFanins = Vec_IntAlloc( 100 ); +            Vec_IntForEachEntryStart( vFans, Fan, i, 1 ) +            { +                iFanin = Smt_PrsBuildNode( pNtk, p, Fan, -1, NULL ); +                if ( iFanin == 0 ) +                { +                    Vec_IntFree( vFanins ); +                    return 0; +                } +                Vec_IntPush( vFanins, iFanin ); +            } +            // update specialized nodes +            assert( Type != WLC_OBJ_BIT_SIGNEXT && Type != WLC_OBJ_BIT_ZEROPAD ); +            if ( Type == WLC_OBJ_BIT_SELECT ) +            { +                assert( Value1 >= 0 && Value2 >= 0 && Value1 >= Value2 ); +                Vec_IntPush( vFanins, (Value1 << 16) | Value2 ); +            } +            else if ( Type == WLC_OBJ_ROTATE_R || Type == WLC_OBJ_ROTATE_L ) +            { +                char Buffer[10]; +                assert( Value1 >= 0 ); +                sprintf( Buffer, "%d", Value1 );  +                NameId = Smt_PrsBuildConstant( pNtk, Buffer, -1, NULL ); +                Vec_IntPush( vFanins, NameId ); +            } +            // find range +            Range = 0; +            if ( Type >= WLC_OBJ_LOGIC_NOT && Type <= WLC_OBJ_REDUCT_XOR ) +                Range = 1; +            else if ( Type == WLC_OBJ_BIT_SELECT ) +                Range = Value1 - Value2 + 1; +            else if ( Type == WLC_OBJ_BIT_CONCAT ) +            { +                Vec_IntForEachEntry( vFanins, NameId, i ) +                    Range += Wlc_ObjRange( Wlc_NtkObj(pNtk, NameId) ); +            } +            else if ( Type == WLC_OBJ_MUX ) +            { +                int * pArray = Vec_IntArray(vFanins); +                assert( Vec_IntSize(vFanins) == 3 ); +                ABC_SWAP( int, pArray[1], pArray[2] ); +                NameId = Vec_IntEntry(vFanins, 1); +                Range = Wlc_ObjRange( Wlc_NtkObj(pNtk, NameId) ); +            } +            else // to determine range, look at the first argument +            { +                NameId = Vec_IntEntry(vFanins, 0); +                Range = Wlc_ObjRange( Wlc_NtkObj(pNtk, NameId) ); +            } +            // create node +            assert( Range > 0 ); +            NameId = Smt_PrsCreateNode( pNtk, Type, fSigned, Range, vFanins, pName ); +            Vec_IntFree( vFanins ); +            return NameId; +        }      } -    return Type;  } -Wlc_Ntk_t * Prs_SmtBuild( Prs_Smt_t * p ) + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Wlc_Ntk_t * Smt_PrsBuild( Smt_Prs_t * p )  {      Wlc_Ntk_t * pNtk; -    char * pName, * pBits, * pConst; -    Vec_Int_t * vFanins = Vec_IntAlloc( 100 ); -    int i, iObj, Type, Entry, NameId, fFound, Range, fSigned, nBits = 0; +    Vec_Int_t * vFans, * vFans2, * vFans3;  +    Vec_Int_t * vAsserts = Vec_IntAlloc(100); +    char * pName, * pRange, * pValue; +    int i, k, Fan, Fan3, iObj, Status, Range, NameId, nBits = 0; +    // issue warnings about unknown dirs +    vFans = Vec_WecEntry( &p->vObjs, 0 ); +    Vec_IntForEachEntry( vFans, Fan, i ) +    { +        assert( !Smt_EntryIsName(Fan) ); +        vFans2 = Smt_VecEntryNode( p, vFans, i ); +        Fan = Vec_IntEntry(vFans2, 0); +        assert( Smt_EntryIsName(Fan) ); +        if ( Abc_Lit2Var(Fan) >= SMT_PRS_END ) +            printf( "Ignoring directive \"%s\".\n", Smt_EntryName(p, Fan) ); +    }      // start network and create primary inputs -    pNtk = Wlc_NtkAlloc( p->pName, Vec_IntCountEntry(&p->vData, 0) + 100 ); +    pNtk = Wlc_NtkAlloc( p->pName, 1000 );      pNtk->pManName = Abc_NamStart( 1000, 24 ); -    for ( i = 0; i < Vec_IntSize(&p->vData) - 1; ) +    Smt_ManForEachDir( p, SMT_PRS_DECLARE_FUN, vFans, i )      { -        assert( Vec_IntEntry(&p->vData, i) == 0 ); -        if ( Vec_IntEntry(&p->vData, ++i) == PRS_SMT_INPUT ) +        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); +        // skip () +        Fan = Vec_IntEntry(vFans, 2); +        assert( !Smt_EntryIsName(Fan) ); +        // check type (Bool or BitVec) +        Fan = Vec_IntEntry(vFans, 3); +        if ( Smt_EntryIsName(Fan) )           { -            pName = Abc_NamStr( p->pStrs, Vec_IntEntry(&p->vData, ++i) ); -            pBits = Abc_NamStr( p->pStrs, Vec_IntEntry(&p->vData, ++i) ); -            iObj = Wlc_ObjAlloc( pNtk, WLC_OBJ_PI, 0, atoi(pBits)-1, 0 ); -            NameId = Abc_NamStrFindOrAdd( pNtk->pManName, pName, &fFound ); -            assert( !fFound ); -            assert( iObj == NameId ); -            // save values -            Vec_IntPush( &pNtk->vValues, NameId ); -            Vec_IntPush( &pNtk->vValues, nBits ); -            Vec_IntPush( &pNtk->vValues, atoi(pBits) ); -            nBits += atoi(pBits); +            //(declare-fun s1 () Bool) +            assert( !strcmp("Bool", Smt_VecEntryName(p, vFans, 3)) ); +            Range = 1;          } -        while ( Vec_IntEntry(&p->vData, ++i) ); +        else +        { +            // (declare-fun s1 () (_ BitVec 64)) +            // get range +            Fan = Vec_IntEntry(vFans, 3); +            assert( !Smt_EntryIsName(Fan) ); +            vFans2 = Smt_EntryNode(p, Fan); +            assert( Vec_IntSize(vFans2) == 3 ); +            assert( !strcmp("_", Smt_VecEntryName(p, vFans2, 0)) ); +            assert( !strcmp("BitVec", Smt_VecEntryName(p, vFans2, 1)) ); +            Fan = Vec_IntEntry(vFans2, 2); +            assert( Smt_EntryIsName(Fan) ); +            pRange = Smt_EntryName(p, Fan); +            Range = atoi(pRange); +        } +        // create node +        iObj = Wlc_ObjAlloc( pNtk, WLC_OBJ_PI, 0, Range-1, 0 ); +        NameId = Abc_NamStrFindOrAdd( pNtk->pManName, pName, NULL ); +        assert( iObj == NameId ); +        // save values +        Vec_IntPush( &pNtk->vValues, NameId ); +        Vec_IntPush( &pNtk->vValues, nBits ); +        Vec_IntPush( &pNtk->vValues, Range ); +        nBits += Range;      } -    // create logic nodes -    for ( i = 0; i < Vec_IntSize(&p->vData) - 1; ) +    // create constants +    Smt_ManForEachDir( p, SMT_PRS_DEFINE_FUN, vFans, i )      { -        assert( Vec_IntEntry(&p->vData, i) == 0 ); -        Entry = Vec_IntEntry(&p->vData, ++i); -        if ( Entry == PRS_SMT_INPUT ) -        {} -        else if ( Entry == PRS_SMT_CONST ) +        assert( Vec_IntSize(vFans) == 5 ); +        assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_DEFINE_FUN) ); +        // get name +        Fan = Vec_IntEntry(vFans, 1); +        assert( Smt_EntryIsName(Fan) ); +        pName = Smt_EntryName(p, Fan); +        // skip () +        Fan = Vec_IntEntry(vFans, 2); +        assert( !Smt_EntryIsName(Fan) ); +        // check type (Bool or BitVec) +        Fan = Vec_IntEntry(vFans, 3); +        if ( Smt_EntryIsName(Fan) )           { -            pName  = Abc_NamStr( p->pStrs, Vec_IntEntry(&p->vData, ++i) ); -            pBits  = Abc_NamStr( p->pStrs, Vec_IntEntry(&p->vData, ++i) ); -            pConst = Abc_NamStr( p->pStrs, Vec_IntEntry(&p->vData, ++i) ); -            // create new node -            if ( !Prs_SmtReadConstant( pNtk, pConst, atoi(pBits), vFanins, pName ) ) -                return NULL; +            // (define-fun s_2 () Bool false) +            assert( !strcmp("Bool", Smt_VecEntryName(p, vFans, 3)) ); +            Range = 1; +            pValue = Smt_VecEntryName(p, vFans, 4); +            if ( !strcmp("false", pValue) ) +                pValue = "#b0"; +            else if ( !strcmp("true", pValue) ) +                pValue = "#b1"; +            else assert( 0 ); +            Status = Smt_PrsBuildConstant( pNtk, pValue, Range, pName );          } -        else if ( Entry == PRS_SMT_LET ) +        else          { -            pName = Abc_NamStr( p->pStrs, Vec_IntEntry(&p->vData, ++i) ); -            Type = Prs_SmtReadNode( p, pNtk, &p->vData, ++i, vFanins, &Range, &fSigned ); -            if ( Type == WLC_OBJ_NONE ) -                return NULL; -            assert( Range > 0 ); -            // create new node -            iObj = Wlc_ObjAlloc( pNtk, Type, 0, Range-1, 0 ); -            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; -            } -            // add node's name -            NameId = Abc_NamStrFindOrAdd( pNtk->pManName, pName, &fFound ); -            assert( !fFound ); -            assert( iObj == NameId ); +            // (define-fun s702 () (_ BitVec 4) #xe) +            // (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); +            // get constant +            Fan = Vec_IntEntry(vFans, 4); +            Status = Smt_PrsBuildNode( pNtk, p, Fan, Range, pName ); +        }         +        if ( !Status ) +        { +            Wlc_NtkFree( pNtk ); pNtk = NULL; +            goto finish;          } -        else if ( Entry == PRS_SMT_ASSERT ) +    } +    // process let-statements +    Smt_ManForEachDir( p, SMT_PRS_LET, vFans, i ) +    { +        // let ((s35550 (bvor s48 s35549))) +        assert( Vec_IntSize(vFans) == 3 ); +        assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_LET) ); +        // get parts +        Fan = Vec_IntEntry(vFans, 1); +        assert( !Smt_EntryIsName(Fan) ); +        vFans2 = Smt_EntryNode(p, Fan); +        if ( Smt_VecEntryIsType(vFans2, 0, SMT_PRS_LET) ) +            continue; +        // iterate through the parts +        Vec_IntForEachEntry( vFans2, Fan, k )          { -            Type = WLC_OBJ_BUF; -            Vec_IntClear( vFanins ); -            pName = Abc_NamStr( p->pStrs, Vec_IntEntry(&p->vData, ++i) ); -            if ( !strcmp(pName, "not") ) +            // s35550 (bvor s48 s35549) +            Fan = Vec_IntEntry(vFans2, 0); +            assert( !Smt_EntryIsName(Fan) ); +            vFans3 = Smt_EntryNode(p, Fan); +            // get the name +            Fan3 = Vec_IntEntry(vFans3, 0); +            assert( Smt_EntryIsName(Fan3) ); +            pName = Smt_EntryName(p, Fan3); +            // get function +            Fan3 = Vec_IntEntry(vFans3, 1); +            assert( !Smt_EntryIsName(Fan3) ); +            Status = Smt_PrsBuildNode( pNtk, p, Fan3, -1, pName ); +            if ( !Status )              { -                Type = WLC_OBJ_LOGIC_NOT; -                pName = Abc_NamStr( p->pStrs, Vec_IntEntry(&p->vData, ++i) ); -                Range = 1; +                Wlc_NtkFree( pNtk ); pNtk = NULL; +                goto finish;              } -            // add fanin -            NameId = Abc_NamStrFindOrAdd( pNtk->pManName, pName, &fFound ); -            assert( fFound ); -            Vec_IntPush( vFanins, NameId ); -            // find range -            if ( Type == WLC_OBJ_BUF ) +        } +    } +    // process assert-statements +    Vec_IntClear( vAsserts ); +    Smt_ManForEachDir( p, SMT_PRS_ASSERT, vFans, i ) +    { +        //(assert ; no quantifiers +        //   (let ((s2 (bvsge s0 s1))) +        //   (not s2))) +        //(assert (not (= s0 #x00))) +        assert( Vec_IntSize(vFans) == 2 ); +        assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_ASSERT) ); +        // get second directive +        Fan = Vec_IntEntry(vFans, 1); +        if ( !Smt_EntryIsName(Fan) ) +        { +            // find the final let-statement +            vFans2 = Smt_VecEntryNode(p, vFans, 1); +            while ( Smt_VecEntryIsType(vFans2, 0, SMT_PRS_LET) )              { -                // find range -                iObj = Vec_IntEntry(vFanins, 0); -                Range = Wlc_ObjRange( Wlc_NtkObj(pNtk, iObj) ); -                assert( Range == 1 ); +                Fan = Vec_IntEntry(vFans2, 2); +                if ( Smt_EntryIsName(Fan) ) +                    break; +                vFans2 = Smt_VecEntryNode(p, vFans2, 2);              } -            // create new node -            iObj = Wlc_ObjAlloc( pNtk, Type, 0, Range-1, 0 ); -            Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj), vFanins ); -            Wlc_ObjSetCo( pNtk, Wlc_NtkObj(pNtk, iObj), 0 ); -            // add node's name -            NameId = Abc_NamStrFindOrAdd( pNtk->pManName, "miter_output", &fFound ); -            assert( !fFound ); -            assert( iObj == NameId ); -            break;          } -        else assert( 0 ); -        while ( Vec_IntEntry(&p->vData, ++i) ); +        // find name or create node +        iObj = Smt_PrsBuildNode( pNtk, p, Fan, -1, NULL ); +        if ( !iObj ) +        { +            Wlc_NtkFree( pNtk ); pNtk = NULL; +            goto finish; +        } +        Vec_IntPush( vAsserts, iObj );      } -    Vec_IntFree( vFanins ); +    // build AND of asserts +    if ( Vec_IntSize(vAsserts) == 1 ) +        iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BUF, 0, 1, vAsserts, "miter_output" ); +    else +    { +        iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vAsserts), vAsserts, NULL ); +        Vec_IntFill( vAsserts, 1, iObj ); +        iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_REDUCT_AND, 0, 1, vAsserts, "miter_output" ); +    } +    Wlc_ObjSetCo( pNtk, Wlc_NtkObj(pNtk, iObj), 0 );      // create nameIDs -    vFanins = Vec_IntStartNatural( Wlc_NtkObjNumMax(pNtk) ); -    Vec_IntAppend( &pNtk->vNameIds, vFanins ); -    Vec_IntFree( vFanins ); +    vFans = Vec_IntStartNatural( Wlc_NtkObjNumMax(pNtk) ); +    Vec_IntAppend( &pNtk->vNameIds, vFans ); +    Vec_IntFree( vFans );      //Wlc_NtkReport( pNtk, NULL ); +finish: +    // cleanup +    Vec_IntFree(vAsserts);      return pNtk;  } + + + + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +// create error message +static inline int Smt_PrsErrorSet( Smt_Prs_t * p, char * pError, int Value ) +{ +    assert( !p->ErrorStr[0] ); +    sprintf( p->ErrorStr, "%s", pError ); +    return Value; +} +// print error message +static inline int Smt_PrsErrorPrint( Smt_Prs_t * p ) +{ +    char * pThis; int iLine = 0; +    if ( !p->ErrorStr[0] ) return 1; +    for ( pThis = p->pBuffer; pThis < p->pCur; pThis++ ) +        iLine += (int)(*pThis == '\n'); +    printf( "Line %d: %s\n", iLine, p->ErrorStr ); +    return 0; +} +static inline char * Smt_PrsLoadFile( char * pFileName, char ** ppLimit ) +{ +    char * pBuffer; +    int nFileSize, RetValue; +    FILE * pFile = fopen( pFileName, "rb" ); +    if ( pFile == NULL ) +    { +        printf( "Cannot open input file.\n" ); +        return NULL; +    } +    // 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 ); +    pBuffer[0] = '\n'; +    RetValue = fread( pBuffer+1, nFileSize, 1, pFile ); +    // terminate the string with '\0' +    pBuffer[nFileSize + 0] = '\n'; +    pBuffer[nFileSize + 1] = '\0'; +    *ppLimit = pBuffer + nFileSize + 2; +    return pBuffer; +} +static inline int Smt_PrsRemoveComments( char * pBuffer, char * pLimit ) +{ +    char * pTemp; int nCount1 = 0, nCount2 = 0; +    for ( pTemp = pBuffer; pTemp < pLimit; pTemp++ ) +    { +        if ( *pTemp == '(' ) +            nCount1++; +        else if ( *pTemp == ')' ) +            nCount2++; +        else if ( *pTemp == ';' ) +            while ( *pTemp && *pTemp != '\n' ) +                *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 ) +        printf( "The input SMTLIB file has no opening or closing parentheses.\n" ); +    return nCount1 == nCount2 ? nCount1 : 0; +} +static inline Smt_Prs_t * Smt_PrsAlloc( char * pFileName, char * pBuffer, char * pLimit, int nObjs ) +{ +    Smt_Prs_t * p; +    if ( nObjs == 0 ) +        return NULL; +    p = ABC_CALLOC( Smt_Prs_t, 1 ); +    p->pName   = pFileName; +    p->pBuffer = pBuffer; +    p->pLimit  = pLimit; +    p->pCur    = pBuffer; +    p->pStrs   = Abc_NamStart( 1000, 24 ); +    Smt_AddTypes( p->pStrs ); +    Vec_IntGrow( &p->vStack, 100 ); +    //Vec_WecGrow( &p->vDepth, 100 ); +    Vec_WecGrow( &p->vObjs, nObjs+1 ); +    return p; +} +static inline void Smt_PrsFree( Smt_Prs_t * p ) +{ +    if ( p->pStrs ) +        Abc_NamDeref( p->pStrs ); +    Vec_IntErase( &p->vStack ); +    //Vec_WecErase( &p->vDepth ); +    Vec_WecErase( &p->vObjs ); +    ABC_FREE( p ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Smt_PrsIsSpace( char c ) +{ +    return c == ' ' || c == '\t' || c == '\r' || c == '\n'; +} +static inline void Smt_PrsSkipSpaces( Smt_Prs_t * p ) +{ +    while ( Smt_PrsIsSpace(*p->pCur) ) +        p->pCur++; +} +static inline void Smt_PrsSkipNonSpaces( Smt_Prs_t * p ) +{ +    while ( p->pCur < p->pLimit && !Smt_PrsIsSpace(*p->pCur) && *p->pCur != '(' && *p->pCur != ')' ) +        p->pCur++; +} +void Smt_PrsReadLines( Smt_Prs_t * p ) +{ +    assert( Vec_IntSize(&p->vStack) == 0 ); +    //assert( Vec_WecSize(&p->vDepth) == 0 ); +    assert( Vec_WecSize(&p->vObjs) == 0 ); +    // add top node at level 0 +    //Vec_WecPushLevel( &p->vDepth ); +    //Vec_WecPush( &p->vDepth, Vec_IntSize(&p->vStack), Vec_WecSize(&p->vObjs) ); +    // add top node +    Vec_IntPush( &p->vStack, Vec_WecSize(&p->vObjs) ); +    Vec_WecPushLevel( &p->vObjs ); +    // add other nodes +    for ( p->pCur = p->pBuffer; p->pCur < p->pLimit; p->pCur++ ) +    { +        Smt_PrsSkipSpaces( p ); +        if ( *p->pCur == '(' ) +        { +            // add new node at this depth +            //assert( Vec_WecSize(&p->vDepth) >= Vec_IntSize(&p->vStack) ); +            //if ( Vec_WecSize(&p->vDepth) == Vec_IntSize(&p->vStack) ) +            //    Vec_WecPushLevel(&p->vDepth); +            //Vec_WecPush( &p->vDepth, Vec_IntSize(&p->vStack), Vec_WecSize(&p->vObjs) ); +            // add fanin to node on the previous level +            Vec_IntPush( Vec_WecEntry(&p->vObjs, Vec_IntEntryLast(&p->vStack)), Abc_Var2Lit(Vec_WecSize(&p->vObjs), 0) );             +            // add node to the stack +            Vec_IntPush( &p->vStack, Vec_WecSize(&p->vObjs) ); +            Vec_WecPushLevel( &p->vObjs ); +        } +        else if ( *p->pCur == ')' ) +        { +            Vec_IntPop( &p->vStack ); +        } +        else  // token +        { +            char * pStart = p->pCur;  +            Smt_PrsSkipNonSpaces( p ); +            if ( p->pCur < p->pLimit ) +            { +                // add fanin +                int iToken = Abc_NamStrFindOrAddLim( p->pStrs, pStart, p->pCur--, NULL ); +                Vec_IntPush( Vec_WecEntry(&p->vObjs, Vec_IntEntryLast(&p->vStack)), Abc_Var2Lit(iToken, 1) ); +            } +        } +    } +    assert( Vec_IntSize(&p->vStack) == 1 ); +    assert( Vec_WecSize(&p->vObjs) == Vec_WecCap(&p->vObjs) ); +} +void Smt_PrsPrintParser_rec( Smt_Prs_t * p, int iObj, int Depth ) +{ +    Vec_Int_t * vFans; int i, Fan; +    printf( "%*s(\n", Depth, "" ); +    vFans = Vec_WecEntry( &p->vObjs, iObj ); +    Vec_IntForEachEntry( vFans, Fan, i ) +    { +        if ( Abc_LitIsCompl(Fan) ) +        { +            printf( "%*s", Depth+2, "" ); +            printf( "%s\n", Abc_NamStr(p->pStrs, Abc_Lit2Var(Fan)) ); +        } +        else +            Smt_PrsPrintParser_rec( p, Abc_Lit2Var(Fan), Depth+4 ); +    } +    printf( "%*s)\n", Depth, "" ); +} +void Smt_PrsPrintParser( Smt_Prs_t * p ) +{ +//    Vec_WecPrint( &p->vDepth, 0 ); +    Smt_PrsPrintParser_rec( p, 0, 0 ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/  Wlc_Ntk_t * Wlc_ReadSmtBuffer( char * pFileName, char * pBuffer, char * pLimit )  {      Wlc_Ntk_t * pNtk = NULL; -    Prs_Smt_t * p = Prs_SmtAlloc( pFileName, pBuffer, pLimit ); +    int nCount = Smt_PrsRemoveComments( pBuffer, pLimit ); +    Smt_Prs_t * p = Smt_PrsAlloc( pFileName, pBuffer, pLimit, nCount );      if ( p == NULL )          return NULL; -    Prs_SmtRemoveComments( p ); -    Prs_SmtReadLines( p ); -    //Prs_SmtPrintParser( p ); -    if ( Prs_SmtErrorPrint(p) ) -        pNtk = Prs_SmtBuild( p ); -    Prs_SmtFree( p ); +    Smt_PrsReadLines( p ); +    //Smt_PrsPrintParser( p ); +    if ( Smt_PrsErrorPrint(p) ) +        pNtk = Smt_PrsBuild( p ); +    Smt_PrsFree( p );      return pNtk;  }  Wlc_Ntk_t * Wlc_ReadSmt( char * pFileName )  {      Wlc_Ntk_t * pNtk = NULL; -    char * pBuffer, * pLimit; -    pBuffer = Prs_SmtLoadFile( pFileName, &pLimit ); +    char * pBuffer, * pLimit;  +    pBuffer = Smt_PrsLoadFile( pFileName, &pLimit );      if ( pBuffer == NULL )          return NULL;      pNtk = Wlc_ReadSmtBuffer( pFileName, pBuffer, pLimit ); @@ -744,6 +893,7 @@ Wlc_Ntk_t * Wlc_ReadSmt( char * pFileName )      return pNtk;  } +  ////////////////////////////////////////////////////////////////////////  ///                       END OF FILE                                ///  //////////////////////////////////////////////////////////////////////// | 
