Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
abc
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
abc
Commits
f27979fc
Commit
f27979fc
authored
Feb 28, 2015
by
Alan Mishchenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improvements to the SMTLIB parser.
parent
2fcdd113
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
687 additions
and
533 deletions
+687
-533
src/base/wlc/wlcBlast.c
+4
-0
src/base/wlc/wlcReadSmt.c
+683
-533
No files found.
src/base/wlc/wlcBlast.c
View file @
f27979fc
...
...
@@ -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
--
)
...
...
src/base/wlc/wlcReadSmt.c
View file @
f27979fc
/**CFile****************************************************************
FileName [wlc
ReadSmt
.c]
FileName [wlc
Parse
.c]
SystemName [ABC: Logic synthesis and verification system.]
...
...
@@ -14,11 +14,12 @@
Date [Ver. 1.0. Started - August 22, 2014.]
Revision [$Id: wlc
ReadSmt
.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $]
Revision [$Id: wlc
Parse
.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
)
+
1
00
);
pNtk
=
Wlc_NtkAlloc
(
p
->
pName
,
10
00
);
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 node
s
for
(
i
=
0
;
i
<
Vec_IntSize
(
&
p
->
vData
)
-
1
;
)
// create
constant
s
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
i
Obj
=
Vec_IntEntry
(
vFanins
,
0
);
Range
=
Wlc_ObjRange
(
Wlc_NtkObj
(
pNtk
,
iObj
)
)
;
assert
(
Range
==
1
);
Fan
=
Vec_IntEntry
(
vFans2
,
2
);
i
f
(
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
vFan
in
s
=
Vec_IntStartNatural
(
Wlc_NtkObjNumMax
(
pNtk
)
);
Vec_IntAppend
(
&
pNtk
->
vNameIds
,
vFan
in
s
);
Vec_IntFree
(
vFan
in
s
);
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_Smt
LoadFile
(
pFileName
,
&
pLimit
);
char
*
pBuffer
,
*
pLimit
;
pBuffer
=
Smt_Prs
LoadFile
(
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 ///
////////////////////////////////////////////////////////////////////////
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment