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
429f52ce
Commit
429f52ce
authored
Feb 18, 2017
by
Alan Mishchenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Experiments with SAT sweeping.
parent
bc010af4
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
936 additions
and
28 deletions
+936
-28
abclib.dsp
+4
-0
src/aig/gia/gia.h
+9
-5
src/aig/gia/giaEquiv.c
+1
-1
src/aig/gia/giaUtil.c
+19
-0
src/base/wlc/wlcSim.c
+11
-11
src/misc/util/utilTruth.h
+16
-0
src/proof/cec/cecSat.c
+862
-0
src/proof/cec/module.make
+1
-0
src/sat/bmc/bmcGen.c
+9
-9
src/sat/satoko/satoko.h
+1
-1
src/sat/satoko/solver_api.c
+3
-1
No files found.
abclib.dsp
View file @
429f52ce
...
...
@@ -5027,6 +5027,10 @@ SOURCE=.\src\proof\cec\cecPat.c
# End Source File
# Begin Source File
SOURCE=.\src\proof\cec\cecSat.c
# End Source File
# Begin Source File
SOURCE=.\src\proof\cec\cecSeq.c
# End Source File
# Begin Source File
...
...
src/aig/gia/gia.h
View file @
429f52ce
...
...
@@ -194,6 +194,7 @@ struct Gia_Man_t_
int
MappedDelay
;
// delay after mapping
// bit-parallel simulation
int
iPatsPi
;
int
nSimWords
;
Vec_Wrd_t
*
vSims
;
Vec_Wrd_t
*
vSimsPi
;
Vec_Int_t
*
vClassOld
;
...
...
@@ -982,24 +983,26 @@ static inline void Gia_ObjSetNext( Gia_Man_t * p, int Id, int Num ) { p
static
inline
int
Gia_ObjIsConst
(
Gia_Man_t
*
p
,
int
Id
)
{
return
Gia_ObjRepr
(
p
,
Id
)
==
0
;
}
static
inline
int
Gia_ObjIsHead
(
Gia_Man_t
*
p
,
int
Id
)
{
return
Gia_ObjRepr
(
p
,
Id
)
==
GIA_VOID
&&
Gia_ObjNext
(
p
,
Id
)
>
0
;
}
static
inline
int
Gia_ObjIsNone
(
Gia_Man_t
*
p
,
int
Id
)
{
return
Gia_ObjRepr
(
p
,
Id
)
==
GIA_VOID
&&
Gia_ObjNext
(
p
,
Id
)
=
=
0
;
}
static
inline
int
Gia_ObjIsTail
(
Gia_Man_t
*
p
,
int
Id
)
{
return
(
Gia_ObjRepr
(
p
,
Id
)
>
0
&&
Gia_ObjRepr
(
p
,
Id
)
!=
GIA_VOID
)
&&
Gia_ObjNext
(
p
,
Id
)
=
=
0
;
}
static
inline
int
Gia_ObjIsNone
(
Gia_Man_t
*
p
,
int
Id
)
{
return
Gia_ObjRepr
(
p
,
Id
)
==
GIA_VOID
&&
Gia_ObjNext
(
p
,
Id
)
<
=
0
;
}
static
inline
int
Gia_ObjIsTail
(
Gia_Man_t
*
p
,
int
Id
)
{
return
(
Gia_ObjRepr
(
p
,
Id
)
>
0
&&
Gia_ObjRepr
(
p
,
Id
)
!=
GIA_VOID
)
&&
Gia_ObjNext
(
p
,
Id
)
<
=
0
;
}
static
inline
int
Gia_ObjIsClass
(
Gia_Man_t
*
p
,
int
Id
)
{
return
(
Gia_ObjRepr
(
p
,
Id
)
>
0
&&
Gia_ObjRepr
(
p
,
Id
)
!=
GIA_VOID
)
||
Gia_ObjNext
(
p
,
Id
)
>
0
;
}
static
inline
int
Gia_ObjHasSameRepr
(
Gia_Man_t
*
p
,
int
i
,
int
k
)
{
assert
(
k
);
return
i
?
(
Gia_ObjRepr
(
p
,
i
)
==
Gia_ObjRepr
(
p
,
k
)
&&
Gia_ObjRepr
(
p
,
i
)
!=
GIA_VOID
)
:
Gia_ObjRepr
(
p
,
k
)
==
0
;
}
static
inline
int
Gia_ObjIsFailedPair
(
Gia_Man_t
*
p
,
int
i
,
int
k
)
{
assert
(
k
);
return
i
?
(
Gia_ObjFailed
(
p
,
i
)
||
Gia_ObjFailed
(
p
,
k
))
:
Gia_ObjFailed
(
p
,
k
);
}
static
inline
int
Gia_ClassIsPair
(
Gia_Man_t
*
p
,
int
i
)
{
assert
(
Gia_ObjIsHead
(
p
,
i
)
);
assert
(
Gia_ObjNext
(
p
,
i
)
);
return
Gia_ObjNext
(
p
,
Gia_ObjNext
(
p
,
i
))
=
=
0
;
}
static
inline
int
Gia_ClassIsPair
(
Gia_Man_t
*
p
,
int
i
)
{
assert
(
Gia_ObjIsHead
(
p
,
i
)
);
assert
(
Gia_ObjNext
(
p
,
i
)
);
return
Gia_ObjNext
(
p
,
Gia_ObjNext
(
p
,
i
))
<
=
0
;
}
static
inline
void
Gia_ClassUndoPair
(
Gia_Man_t
*
p
,
int
i
)
{
assert
(
Gia_ClassIsPair
(
p
,
i
)
);
Gia_ObjSetRepr
(
p
,
Gia_ObjNext
(
p
,
i
),
GIA_VOID
);
Gia_ObjSetNext
(
p
,
i
,
0
);
}
#define Gia_ManForEachConst( p, i ) \
for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsConst(p, i) ) {} else
#define Gia_ManForEachClass( p, i ) \
for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsHead(p, i) ) {} else
#define Gia_ManForEachClass0( p, i ) \
for ( i = 0; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsHead(p, i) ) {} else
#define Gia_ManForEachClassReverse( p, i ) \
for ( i = Gia_ManObjNum(p) - 1; i > 0; i-- ) if ( !Gia_ObjIsHead(p, i) ) {} else
#define Gia_ClassForEachObj( p, i, iObj ) \
for ( assert(Gia_ObjIsHead(p, i)), iObj = i; iObj; iObj = Gia_ObjNext(p, iObj) )
for ( assert(Gia_ObjIsHead(p, i)), iObj = i; iObj
> 0
; iObj = Gia_ObjNext(p, iObj) )
#define Gia_ClassForEachObj1( p, i, iObj ) \
for ( assert(Gia_ObjIsHead(p, i)), iObj = Gia_ObjNext(p, i); iObj; iObj = Gia_ObjNext(p, iObj) )
for ( assert(Gia_ObjIsHead(p, i)), iObj = Gia_ObjNext(p, i); iObj
> 0
; iObj = Gia_ObjNext(p, iObj) )
static
inline
int
Gia_ObjFoffsetId
(
Gia_Man_t
*
p
,
int
Id
)
{
return
Vec_IntEntry
(
p
->
vFanout
,
Id
);
}
...
...
@@ -1585,6 +1588,7 @@ extern void Gia_ManSwapPos( Gia_Man_t * p, int i );
extern
Vec_Int_t
*
Gia_ManSaveValue
(
Gia_Man_t
*
p
);
extern
void
Gia_ManLoadValue
(
Gia_Man_t
*
p
,
Vec_Int_t
*
vValues
);
extern
Vec_Int_t
*
Gia_ManFirstFanouts
(
Gia_Man_t
*
p
);
extern
void
Gia_ManDetectMuxes
(
Gia_Man_t
*
p
);
/*=== giaCTas.c ===========================================================*/
typedef
struct
Tas_Man_t_
Tas_Man_t
;
...
...
src/aig/gia/giaEquiv.c
View file @
429f52ce
...
...
@@ -485,7 +485,7 @@ void Gia_ManEquivPrintClasses( Gia_Man_t * p, int fVerbose, float Mem )
if
(
fVerbose
)
{
// int Ent;
Abc_Print
(
1
,
"Const0
= "
);
Abc_Print
(
1
,
"Const0
(%d) = "
,
Counter0
);
Gia_ManForEachConst
(
p
,
i
)
Abc_Print
(
1
,
"%d "
,
i
);
Abc_Print
(
1
,
"
\n
"
);
...
...
src/aig/gia/giaUtil.c
View file @
429f52ce
...
...
@@ -2050,6 +2050,25 @@ void Gia_AigerWriteLut( Gia_Man_t * p, char * pFileName )
Vec_WrdFree
(
vTruths
);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Gia_ManDetectMuxes
(
Gia_Man_t
*
p
)
{
Gia_Obj_t
*
pObj
,
*
pNodeT
,
*
pNodeE
;
int
i
;
Gia_ManForEachObj
(
p
,
pObj
,
i
);
if
(
Gia_ObjIsAnd
(
pObj
)
&&
Gia_ObjRecognizeMux
(
pObj
,
&
pNodeT
,
&
pNodeE
)
)
pObj
->
fMark0
=
1
;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
...
...
src/base/wlc/wlcSim.c
View file @
429f52ce
...
...
@@ -43,13 +43,13 @@ ABC_NAMESPACE_IMPL_START
***********************************************************************/
static
inline
word
*
Wlc_ObjSim
(
Gia_Man_t
*
p
,
int
iObj
)
{
return
Vec_WrdEntryP
(
p
->
vSims
,
p
->
iPatsPi
*
iObj
);
return
Vec_WrdEntryP
(
p
->
vSims
,
p
->
nSimWords
*
iObj
);
}
static
inline
void
Wlc_ObjSimPi
(
Gia_Man_t
*
p
,
int
iObj
)
{
int
w
;
word
*
pSim
=
Wlc_ObjSim
(
p
,
iObj
);
for
(
w
=
0
;
w
<
p
->
iPatsPi
;
w
++
)
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
pSim
[
w
]
=
Gia_ManRandomW
(
0
);
}
static
inline
void
Wlc_ObjSimRo
(
Gia_Man_t
*
p
,
int
iObj
)
...
...
@@ -57,7 +57,7 @@ static inline void Wlc_ObjSimRo( Gia_Man_t * p, int iObj )
int
w
;
word
*
pSimRo
=
Wlc_ObjSim
(
p
,
iObj
);
word
*
pSimRi
=
Wlc_ObjSim
(
p
,
Gia_ObjRoToRiId
(
p
,
iObj
)
);
for
(
w
=
0
;
w
<
p
->
iPatsPi
;
w
++
)
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
pSimRo
[
w
]
=
pSimRi
[
w
];
}
static
inline
void
Wlc_ObjSimCo
(
Gia_Man_t
*
p
,
int
iObj
)
...
...
@@ -67,10 +67,10 @@ static inline void Wlc_ObjSimCo( Gia_Man_t * p, int iObj )
word
*
pSimCo
=
Wlc_ObjSim
(
p
,
iObj
);
word
*
pSimDri
=
Wlc_ObjSim
(
p
,
Gia_ObjFaninId0
(
pObj
,
iObj
)
);
if
(
Gia_ObjFaninC0
(
pObj
)
)
for
(
w
=
0
;
w
<
p
->
iPatsPi
;
w
++
)
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
pSimCo
[
w
]
=
~
pSimDri
[
w
];
else
for
(
w
=
0
;
w
<
p
->
iPatsPi
;
w
++
)
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
pSimCo
[
w
]
=
pSimDri
[
w
];
}
static
inline
void
Wlc_ObjSimAnd
(
Gia_Man_t
*
p
,
int
iObj
)
...
...
@@ -81,16 +81,16 @@ static inline void Wlc_ObjSimAnd( Gia_Man_t * p, int iObj )
word
*
pSim0
=
Wlc_ObjSim
(
p
,
Gia_ObjFaninId0
(
pObj
,
iObj
)
);
word
*
pSim1
=
Wlc_ObjSim
(
p
,
Gia_ObjFaninId1
(
pObj
,
iObj
)
);
if
(
Gia_ObjFaninC0
(
pObj
)
&&
Gia_ObjFaninC1
(
pObj
)
)
for
(
w
=
0
;
w
<
p
->
iPatsPi
;
w
++
)
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
pSim
[
w
]
=
~
pSim0
[
w
]
&
~
pSim1
[
w
];
else
if
(
Gia_ObjFaninC0
(
pObj
)
&&
!
Gia_ObjFaninC1
(
pObj
)
)
for
(
w
=
0
;
w
<
p
->
iPatsPi
;
w
++
)
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
pSim
[
w
]
=
~
pSim0
[
w
]
&
pSim1
[
w
];
else
if
(
!
Gia_ObjFaninC0
(
pObj
)
&&
Gia_ObjFaninC1
(
pObj
)
)
for
(
w
=
0
;
w
<
p
->
iPatsPi
;
w
++
)
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
pSim
[
w
]
=
pSim0
[
w
]
&
~
pSim1
[
w
];
else
for
(
w
=
0
;
w
<
p
->
iPatsPi
;
w
++
)
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
pSim
[
w
]
=
pSim0
[
w
]
&
pSim1
[
w
];
}
...
...
@@ -135,7 +135,7 @@ Vec_Ptr_t * Wlc_NtkSimulate( Wlc_Ntk_t * p, Vec_Int_t * vNodes, int nWords, int
// allocate simulation info for one timeframe
Vec_WrdFreeP
(
&
pGia
->
vSims
);
pGia
->
vSims
=
Vec_WrdStart
(
Gia_ManObjNum
(
pGia
)
*
nWords
);
pGia
->
iPatsPi
=
nWords
;
pGia
->
nSimWords
=
nWords
;
// allocate resulting simulation info
vRes
=
Vec_PtrAlloc
(
Vec_IntSize
(
vNodes
)
);
Wlc_NtkForEachObjVec
(
vNodes
,
p
,
pWlcObj
,
i
)
...
...
@@ -188,7 +188,7 @@ Vec_Ptr_t * Wlc_NtkSimulate( Wlc_Ntk_t * p, Vec_Int_t * vNodes, int nWords, int
printf
(
"Replaced %d dangling internal bits with constant 0.
\n
"
,
Counter
);
}
Vec_WrdFreeP
(
&
pGia
->
vSims
);
pGia
->
iPatsPi
=
0
;
pGia
->
nSimWords
=
0
;
Gia_ManStop
(
pGia
);
return
vRes
;
}
...
...
src/misc/util/utilTruth.h
View file @
429f52ce
...
...
@@ -1631,6 +1631,14 @@ static inline int Abc_TtFindFirstBit( word * pIn, int nVars )
return
64
*
w
+
Abc_Tt6FirstBit
(
pIn
[
w
]);
return
-
1
;
}
static
inline
int
Abc_TtFindFirstBit2
(
word
*
pIn
,
int
nWords
)
{
int
w
;
for
(
w
=
0
;
w
<
nWords
;
w
++
)
if
(
pIn
[
w
]
)
return
64
*
w
+
Abc_Tt6FirstBit
(
pIn
[
w
]);
return
-
1
;
}
static
inline
int
Abc_TtFindFirstDiffBit
(
word
*
pIn1
,
word
*
pIn2
,
int
nVars
)
{
int
w
,
nWords
=
Abc_TtWordNum
(
nVars
);
...
...
@@ -1639,6 +1647,14 @@ static inline int Abc_TtFindFirstDiffBit( word * pIn1, word * pIn2, int nVars )
return
64
*
w
+
Abc_Tt6FirstBit
(
pIn1
[
w
]
^
pIn2
[
w
]);
return
-
1
;
}
static
inline
int
Abc_TtFindFirstDiffBit2
(
word
*
pIn1
,
word
*
pIn2
,
int
nWords
)
{
int
w
;
for
(
w
=
0
;
w
<
nWords
;
w
++
)
if
(
pIn1
[
w
]
^
pIn2
[
w
]
)
return
64
*
w
+
Abc_Tt6FirstBit
(
pIn1
[
w
]
^
pIn2
[
w
]);
return
-
1
;
}
static
inline
int
Abc_TtFindFirstZero
(
word
*
pIn
,
int
nVars
)
{
int
w
,
nWords
=
Abc_TtWordNum
(
nVars
);
...
...
src/proof/cec/cecSat.c
0 → 100644
View file @
429f52ce
/**CFile****************************************************************
FileName [cecSat.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Combinational equivalence checking.]
Synopsis [Detection of structural isomorphism.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: cecSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "aig/gia/gia.h"
#include "misc/util/utilTruth.h"
#include "sat/satoko/satoko.h"
#include "sat/satoko/solver.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
// sweeping manager
typedef
struct
Cec2_Par_t_
Cec2_Par_t
;
struct
Cec2_Par_t_
{
int
nSimWords
;
// simulation words
int
nSimRounds
;
// simulation rounds
int
nConfLimit
;
// SAT solver conflict limit
int
fIsMiter
;
// this is a miter
int
fVeryVerbose
;
// verbose stats
int
fVerbose
;
// verbose stats
};
// SAT solving manager
typedef
struct
Cec2_Man_t_
Cec2_Man_t
;
struct
Cec2_Man_t_
{
Cec2_Par_t
*
pPars
;
// parameters
Gia_Man_t
*
pAig
;
// user's AIG
Gia_Man_t
*
pNew
;
// internal AIG
// SAT solving
satoko_t
*
pSat
;
// SAT solver
Vec_Ptr_t
*
vFrontier
;
// CNF construction
Vec_Ptr_t
*
vFanins
;
// CNF construction
Vec_Wrd_t
*
vSims
;
// CI simulation info
Vec_Int_t
*
vNodesNew
;
// nodes
Vec_Int_t
*
vObjSatPairs
;
// nodes
};
static
inline
int
Cec2_ObjSatId
(
Gia_Man_t
*
p
,
Gia_Obj_t
*
pObj
)
{
return
Gia_ObjCopyArray
(
p
,
Gia_ObjId
(
p
,
pObj
));
}
static
inline
int
Cec2_ObjSetSatId
(
Gia_Man_t
*
p
,
Gia_Obj_t
*
pObj
,
int
Num
)
{
assert
(
Cec2_ObjSatId
(
p
,
pObj
)
==
-
1
);
Gia_ObjSetCopyArray
(
p
,
Gia_ObjId
(
p
,
pObj
),
Num
);
return
Num
;
}
static
inline
void
Cec2_ObjCleanSatId
(
Gia_Man_t
*
p
,
Gia_Obj_t
*
pObj
)
{
assert
(
Cec2_ObjSatId
(
p
,
pObj
)
!=
-
1
);
Gia_ObjSetCopyArray
(
p
,
Gia_ObjId
(
p
,
pObj
),
-
1
);
}
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Sets parameter defaults.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Cec2_SetDefaultParams
(
Cec2_Par_t
*
p
)
{
memset
(
p
,
0
,
sizeof
(
Cec2_Par_t
)
);
p
->
nSimWords
=
8
;
// simulation words
p
->
nSimRounds
=
4
;
// simulation rounds
p
->
nConfLimit
=
1000
;
// conflict limit at a node
p
->
fIsMiter
=
0
;
// this is a miter
p
->
fVeryVerbose
=
0
;
// verbose stats
p
->
fVerbose
=
1
;
// verbose stats
}
/**Function*************************************************************
Synopsis [Adds clauses to the solver.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Cec2_AddClausesMux
(
Gia_Man_t
*
p
,
Gia_Obj_t
*
pNode
,
satoko_t
*
pSat
)
{
int
fPolarFlip
=
0
;
Gia_Obj_t
*
pNodeI
,
*
pNodeT
,
*
pNodeE
;
int
pLits
[
4
],
RetValue
,
VarF
,
VarI
,
VarT
,
VarE
,
fCompT
,
fCompE
;
assert
(
!
Gia_IsComplement
(
pNode
)
);
assert
(
pNode
->
fMark0
);
// get nodes (I = if, T = then, E = else)
pNodeI
=
Gia_ObjRecognizeMux
(
pNode
,
&
pNodeT
,
&
pNodeE
);
// get the variable numbers
VarF
=
Cec2_ObjSatId
(
p
,
pNode
);
VarI
=
Cec2_ObjSatId
(
p
,
pNodeI
);
VarT
=
Cec2_ObjSatId
(
p
,
Gia_Regular
(
pNodeT
));
VarE
=
Cec2_ObjSatId
(
p
,
Gia_Regular
(
pNodeE
));
// get the complementation flags
fCompT
=
Gia_IsComplement
(
pNodeT
);
fCompE
=
Gia_IsComplement
(
pNodeE
);
// f = ITE(i, t, e)
// i' + t' + f
// i' + t + f'
// i + e' + f
// i + e + f'
// create four clauses
pLits
[
0
]
=
Abc_Var2Lit
(
VarI
,
1
);
pLits
[
1
]
=
Abc_Var2Lit
(
VarT
,
1
^
fCompT
);
pLits
[
2
]
=
Abc_Var2Lit
(
VarF
,
0
);
if
(
fPolarFlip
)
{
if
(
pNodeI
->
fPhase
)
pLits
[
0
]
=
Abc_LitNot
(
pLits
[
0
]
);
if
(
Gia_Regular
(
pNodeT
)
->
fPhase
)
pLits
[
1
]
=
Abc_LitNot
(
pLits
[
1
]
);
if
(
pNode
->
fPhase
)
pLits
[
2
]
=
Abc_LitNot
(
pLits
[
2
]
);
}
RetValue
=
satoko_add_clause
(
pSat
,
pLits
,
3
);
assert
(
RetValue
);
pLits
[
0
]
=
Abc_Var2Lit
(
VarI
,
1
);
pLits
[
1
]
=
Abc_Var2Lit
(
VarT
,
0
^
fCompT
);
pLits
[
2
]
=
Abc_Var2Lit
(
VarF
,
1
);
if
(
fPolarFlip
)
{
if
(
pNodeI
->
fPhase
)
pLits
[
0
]
=
Abc_LitNot
(
pLits
[
0
]
);
if
(
Gia_Regular
(
pNodeT
)
->
fPhase
)
pLits
[
1
]
=
Abc_LitNot
(
pLits
[
1
]
);
if
(
pNode
->
fPhase
)
pLits
[
2
]
=
Abc_LitNot
(
pLits
[
2
]
);
}
RetValue
=
satoko_add_clause
(
pSat
,
pLits
,
3
);
assert
(
RetValue
);
pLits
[
0
]
=
Abc_Var2Lit
(
VarI
,
0
);
pLits
[
1
]
=
Abc_Var2Lit
(
VarE
,
1
^
fCompE
);
pLits
[
2
]
=
Abc_Var2Lit
(
VarF
,
0
);
if
(
fPolarFlip
)
{
if
(
pNodeI
->
fPhase
)
pLits
[
0
]
=
Abc_LitNot
(
pLits
[
0
]
);
if
(
Gia_Regular
(
pNodeE
)
->
fPhase
)
pLits
[
1
]
=
Abc_LitNot
(
pLits
[
1
]
);
if
(
pNode
->
fPhase
)
pLits
[
2
]
=
Abc_LitNot
(
pLits
[
2
]
);
}
RetValue
=
satoko_add_clause
(
pSat
,
pLits
,
3
);
assert
(
RetValue
);
pLits
[
0
]
=
Abc_Var2Lit
(
VarI
,
0
);
pLits
[
1
]
=
Abc_Var2Lit
(
VarE
,
0
^
fCompE
);
pLits
[
2
]
=
Abc_Var2Lit
(
VarF
,
1
);
if
(
fPolarFlip
)
{
if
(
pNodeI
->
fPhase
)
pLits
[
0
]
=
Abc_LitNot
(
pLits
[
0
]
);
if
(
Gia_Regular
(
pNodeE
)
->
fPhase
)
pLits
[
1
]
=
Abc_LitNot
(
pLits
[
1
]
);
if
(
pNode
->
fPhase
)
pLits
[
2
]
=
Abc_LitNot
(
pLits
[
2
]
);
}
RetValue
=
satoko_add_clause
(
pSat
,
pLits
,
3
);
assert
(
RetValue
);
// two additional clauses
// t' & e' -> f'
// t & e -> f
// t + e + f'
// t' + e' + f
if
(
VarT
==
VarE
)
{
// assert( fCompT == !fCompE );
return
;
}
pLits
[
0
]
=
Abc_Var2Lit
(
VarT
,
0
^
fCompT
);
pLits
[
1
]
=
Abc_Var2Lit
(
VarE
,
0
^
fCompE
);
pLits
[
2
]
=
Abc_Var2Lit
(
VarF
,
1
);
if
(
fPolarFlip
)
{
if
(
Gia_Regular
(
pNodeT
)
->
fPhase
)
pLits
[
0
]
=
Abc_LitNot
(
pLits
[
0
]
);
if
(
Gia_Regular
(
pNodeE
)
->
fPhase
)
pLits
[
1
]
=
Abc_LitNot
(
pLits
[
1
]
);
if
(
pNode
->
fPhase
)
pLits
[
2
]
=
Abc_LitNot
(
pLits
[
2
]
);
}
RetValue
=
satoko_add_clause
(
pSat
,
pLits
,
3
);
assert
(
RetValue
);
pLits
[
0
]
=
Abc_Var2Lit
(
VarT
,
1
^
fCompT
);
pLits
[
1
]
=
Abc_Var2Lit
(
VarE
,
1
^
fCompE
);
pLits
[
2
]
=
Abc_Var2Lit
(
VarF
,
0
);
if
(
fPolarFlip
)
{
if
(
Gia_Regular
(
pNodeT
)
->
fPhase
)
pLits
[
0
]
=
Abc_LitNot
(
pLits
[
0
]
);
if
(
Gia_Regular
(
pNodeE
)
->
fPhase
)
pLits
[
1
]
=
Abc_LitNot
(
pLits
[
1
]
);
if
(
pNode
->
fPhase
)
pLits
[
2
]
=
Abc_LitNot
(
pLits
[
2
]
);
}
RetValue
=
satoko_add_clause
(
pSat
,
pLits
,
3
);
assert
(
RetValue
);
}
void
Cec2_AddClausesSuper
(
Gia_Man_t
*
p
,
Gia_Obj_t
*
pNode
,
Vec_Ptr_t
*
vSuper
,
satoko_t
*
pSat
)
{
int
fPolarFlip
=
0
;
Gia_Obj_t
*
pFanin
;
int
*
pLits
,
nLits
,
RetValue
,
i
;
assert
(
!
Gia_IsComplement
(
pNode
)
);
assert
(
Gia_ObjIsAnd
(
pNode
)
);
// create storage for literals
nLits
=
Vec_PtrSize
(
vSuper
)
+
1
;
pLits
=
ABC_ALLOC
(
int
,
nLits
);
// suppose AND-gate is A & B = C
// add !A => !C or A + !C
Vec_PtrForEachEntry
(
Gia_Obj_t
*
,
vSuper
,
pFanin
,
i
)
{
pLits
[
0
]
=
Abc_Var2Lit
(
Cec2_ObjSatId
(
p
,
Gia_Regular
(
pFanin
)),
Gia_IsComplement
(
pFanin
));
pLits
[
1
]
=
Abc_Var2Lit
(
Cec2_ObjSatId
(
p
,
pNode
),
1
);
if
(
fPolarFlip
)
{
if
(
Gia_Regular
(
pFanin
)
->
fPhase
)
pLits
[
0
]
=
Abc_LitNot
(
pLits
[
0
]
);
if
(
pNode
->
fPhase
)
pLits
[
1
]
=
Abc_LitNot
(
pLits
[
1
]
);
}
RetValue
=
satoko_add_clause
(
pSat
,
pLits
,
2
);
assert
(
RetValue
);
}
// add A & B => C or !A + !B + C
Vec_PtrForEachEntry
(
Gia_Obj_t
*
,
vSuper
,
pFanin
,
i
)
{
pLits
[
i
]
=
Abc_Var2Lit
(
Cec2_ObjSatId
(
p
,
Gia_Regular
(
pFanin
)),
!
Gia_IsComplement
(
pFanin
));
if
(
fPolarFlip
)
{
if
(
Gia_Regular
(
pFanin
)
->
fPhase
)
pLits
[
i
]
=
Abc_LitNot
(
pLits
[
i
]
);
}
}
pLits
[
nLits
-
1
]
=
Abc_Var2Lit
(
Cec2_ObjSatId
(
p
,
pNode
),
0
);
if
(
fPolarFlip
)
{
if
(
pNode
->
fPhase
)
pLits
[
nLits
-
1
]
=
Abc_LitNot
(
pLits
[
nLits
-
1
]
);
}
RetValue
=
satoko_add_clause
(
pSat
,
pLits
,
nLits
);
assert
(
RetValue
);
ABC_FREE
(
pLits
);
}
/**Function*************************************************************
Synopsis [Adds clauses and returns CNF variable of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Cec2_CollectSuper_rec
(
Gia_Obj_t
*
pObj
,
Vec_Ptr_t
*
vSuper
,
int
fFirst
,
int
fUseMuxes
)
{
// if the new node is complemented or a PI, another gate begins
if
(
Gia_IsComplement
(
pObj
)
||
Gia_ObjIsCi
(
pObj
)
||
(
!
fFirst
&&
Gia_ObjValue
(
pObj
)
>
1
)
||
(
fUseMuxes
&&
pObj
->
fMark0
)
)
{
Vec_PtrPushUnique
(
vSuper
,
pObj
);
return
;
}
// go through the branches
Cec2_CollectSuper_rec
(
Gia_ObjChild0
(
pObj
),
vSuper
,
0
,
fUseMuxes
);
Cec2_CollectSuper_rec
(
Gia_ObjChild1
(
pObj
),
vSuper
,
0
,
fUseMuxes
);
}
void
Cec2_CollectSuper
(
Gia_Obj_t
*
pObj
,
int
fUseMuxes
,
Vec_Ptr_t
*
vSuper
)
{
assert
(
!
Gia_IsComplement
(
pObj
)
);
assert
(
!
Gia_ObjIsCi
(
pObj
)
);
Vec_PtrClear
(
vSuper
);
Cec2_CollectSuper_rec
(
pObj
,
vSuper
,
1
,
fUseMuxes
);
}
void
Cec2_ObjAddToFrontier
(
Gia_Man_t
*
p
,
Gia_Obj_t
*
pObj
,
Vec_Ptr_t
*
vFrontier
,
satoko_t
*
pSat
)
{
assert
(
!
Gia_IsComplement
(
pObj
)
);
assert
(
!
Gia_ObjIsConst0
(
pObj
)
);
if
(
Cec2_ObjSatId
(
p
,
pObj
)
>=
0
)
return
;
assert
(
Cec2_ObjSatId
(
p
,
pObj
)
==
-
1
);
Cec2_ObjSetSatId
(
p
,
pObj
,
satoko_add_variable
(
pSat
,
0
)
);
if
(
Gia_ObjIsAnd
(
pObj
)
)
Vec_PtrPush
(
vFrontier
,
pObj
);
}
int
Cec2_ObjGetCnfVar
(
Cec2_Man_t
*
p
,
int
iObj
)
{
Gia_Obj_t
*
pNode
,
*
pFanin
;
Gia_Obj_t
*
pObj
=
Gia_ManObj
(
p
->
pNew
,
iObj
);
int
i
,
k
,
fUseMuxes
=
1
;
// quit if CNF is ready
if
(
Cec2_ObjSatId
(
p
->
pNew
,
pObj
)
>=
0
)
return
Cec2_ObjSatId
(
p
->
pNew
,
pObj
);
assert
(
iObj
>
0
);
if
(
Gia_ObjIsCi
(
pObj
)
)
return
Cec2_ObjSetSatId
(
p
->
pNew
,
pObj
,
satoko_add_variable
(
p
->
pSat
,
0
)
);
assert
(
Gia_ObjIsAnd
(
pObj
)
);
// start the frontier
Vec_PtrClear
(
p
->
vFrontier
);
Cec2_ObjAddToFrontier
(
p
->
pNew
,
pObj
,
p
->
vFrontier
,
p
->
pSat
);
// explore nodes in the frontier
Vec_PtrForEachEntry
(
Gia_Obj_t
*
,
p
->
vFrontier
,
pNode
,
i
)
{
// create the supergate
assert
(
Cec2_ObjSatId
(
p
->
pNew
,
pNode
)
>=
0
);
if
(
fUseMuxes
&&
pNode
->
fMark0
)
{
Vec_PtrClear
(
p
->
vFanins
);
Vec_PtrPushUnique
(
p
->
vFanins
,
Gia_ObjFanin0
(
Gia_ObjFanin0
(
pNode
)
)
);
Vec_PtrPushUnique
(
p
->
vFanins
,
Gia_ObjFanin0
(
Gia_ObjFanin1
(
pNode
)
)
);
Vec_PtrPushUnique
(
p
->
vFanins
,
Gia_ObjFanin1
(
Gia_ObjFanin0
(
pNode
)
)
);
Vec_PtrPushUnique
(
p
->
vFanins
,
Gia_ObjFanin1
(
Gia_ObjFanin1
(
pNode
)
)
);
Vec_PtrForEachEntry
(
Gia_Obj_t
*
,
p
->
vFanins
,
pFanin
,
k
)
Cec2_ObjAddToFrontier
(
p
->
pNew
,
Gia_Regular
(
pFanin
),
p
->
vFrontier
,
p
->
pSat
);
Cec2_AddClausesMux
(
p
->
pNew
,
pNode
,
p
->
pSat
);
}
else
{
Cec2_CollectSuper
(
pNode
,
fUseMuxes
,
p
->
vFanins
);
Vec_PtrForEachEntry
(
Gia_Obj_t
*
,
p
->
vFanins
,
pFanin
,
k
)
Cec2_ObjAddToFrontier
(
p
->
pNew
,
Gia_Regular
(
pFanin
),
p
->
vFrontier
,
p
->
pSat
);
Cec2_AddClausesSuper
(
p
->
pNew
,
pNode
,
p
->
vFanins
,
p
->
pSat
);
}
assert
(
Vec_PtrSize
(
p
->
vFanins
)
>
1
);
}
return
Cec2_ObjSatId
(
p
->
pNew
,
pObj
);
}
/**Function*************************************************************
Synopsis [Internal simulation APIs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
word
*
Cec2_ObjSim
(
Gia_Man_t
*
p
,
int
iObj
)
{
return
Vec_WrdEntryP
(
p
->
vSims
,
p
->
nSimWords
*
iObj
);
}
static
inline
void
Cec2_ObjSimSetPiBit
(
Gia_Man_t
*
p
,
int
iObj
,
int
Bit
)
{
word
*
pSim
=
Cec2_ObjSim
(
p
,
iObj
);
p
->
iPatsPi
=
(
p
->
iPatsPi
==
64
*
p
->
nSimWords
-
1
)
?
1
:
p
->
iPatsPi
+
1
;
assert
(
p
->
iPatsPi
>
0
&&
p
->
iPatsPi
<
64
*
p
->
nSimWords
);
if
(
Abc_InfoHasBit
(
(
unsigned
*
)
pSim
,
p
->
iPatsPi
)
!=
Bit
)
Abc_InfoXorBit
(
(
unsigned
*
)
pSim
,
p
->
iPatsPi
);
}
static
inline
void
Cec2_ObjSimRo
(
Gia_Man_t
*
p
,
int
iObj
)
{
int
w
;
word
*
pSimRo
=
Cec2_ObjSim
(
p
,
iObj
);
word
*
pSimRi
=
Cec2_ObjSim
(
p
,
Gia_ObjRoToRiId
(
p
,
iObj
)
);
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
pSimRo
[
w
]
=
pSimRi
[
w
];
}
static
inline
void
Cec2_ObjSimCo
(
Gia_Man_t
*
p
,
int
iObj
)
{
int
w
;
Gia_Obj_t
*
pObj
=
Gia_ManObj
(
p
,
iObj
);
word
*
pSimCo
=
Cec2_ObjSim
(
p
,
iObj
);
word
*
pSimDri
=
Cec2_ObjSim
(
p
,
Gia_ObjFaninId0
(
pObj
,
iObj
)
);
if
(
Gia_ObjFaninC0
(
pObj
)
)
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
pSimCo
[
w
]
=
~
pSimDri
[
w
];
else
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
pSimCo
[
w
]
=
pSimDri
[
w
];
}
static
inline
void
Cec2_ObjSimAnd
(
Gia_Man_t
*
p
,
int
iObj
)
{
int
w
;
Gia_Obj_t
*
pObj
=
Gia_ManObj
(
p
,
iObj
);
word
*
pSim
=
Cec2_ObjSim
(
p
,
iObj
);
word
*
pSim0
=
Cec2_ObjSim
(
p
,
Gia_ObjFaninId0
(
pObj
,
iObj
)
);
word
*
pSim1
=
Cec2_ObjSim
(
p
,
Gia_ObjFaninId1
(
pObj
,
iObj
)
);
if
(
Gia_ObjFaninC0
(
pObj
)
&&
Gia_ObjFaninC1
(
pObj
)
)
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
pSim
[
w
]
=
~
pSim0
[
w
]
&
~
pSim1
[
w
];
else
if
(
Gia_ObjFaninC0
(
pObj
)
&&
!
Gia_ObjFaninC1
(
pObj
)
)
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
pSim
[
w
]
=
~
pSim0
[
w
]
&
pSim1
[
w
];
else
if
(
!
Gia_ObjFaninC0
(
pObj
)
&&
Gia_ObjFaninC1
(
pObj
)
)
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
pSim
[
w
]
=
pSim0
[
w
]
&
~
pSim1
[
w
];
else
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
pSim
[
w
]
=
pSim0
[
w
]
&
pSim1
[
w
];
}
static
inline
int
Cec2_ObjSimEqual
(
Gia_Man_t
*
p
,
int
iObj0
,
int
iObj1
)
{
int
w
;
word
*
pSim0
=
Cec2_ObjSim
(
p
,
iObj0
);
word
*
pSim1
=
Cec2_ObjSim
(
p
,
iObj1
);
if
(
(
pSim0
[
0
]
&
1
)
==
(
pSim1
[
0
]
&
1
)
)
{
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
if
(
pSim0
[
w
]
!=
pSim1
[
w
]
)
return
0
;
return
1
;
}
else
{
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
if
(
pSim0
[
w
]
!=
~
pSim1
[
w
]
)
return
0
;
return
1
;
}
}
static
inline
void
Cec2_ObjSimPi
(
Gia_Man_t
*
p
,
int
iObj
)
{
int
w
;
word
*
pSim
=
Cec2_ObjSim
(
p
,
iObj
);
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
pSim
[
w
]
=
Gia_ManRandomW
(
0
);
pSim
[
0
]
<<=
1
;
}
void
Cec2_ManSimulateCis
(
Gia_Man_t
*
p
)
{
int
i
,
Id
;
Gia_ManForEachCiId
(
p
,
Id
,
i
)
Cec2_ObjSimPi
(
p
,
Id
);
p
->
iPatsPi
=
1
;
}
Abc_Cex_t
*
Cec2_ManDeriveCex
(
Gia_Man_t
*
p
,
int
iOut
,
int
iPat
)
{
Abc_Cex_t
*
pCex
;
int
i
,
Id
;
pCex
=
Abc_CexAlloc
(
0
,
Gia_ManCiNum
(
p
),
1
);
pCex
->
iPo
=
iOut
;
if
(
iPat
==
-
1
)
return
pCex
;
Gia_ManForEachCiId
(
p
,
Id
,
i
)
if
(
Abc_InfoHasBit
((
unsigned
*
)
Cec2_ObjSim
(
p
,
Id
),
iPat
)
)
Abc_InfoSetBit
(
pCex
->
pData
,
i
);
return
pCex
;
}
int
Cec2_ManSimulateCos
(
Gia_Man_t
*
p
)
{
int
i
,
Id
;
// check outputs and generate CEX if they fail
Gia_ManForEachCoId
(
p
,
Id
,
i
)
{
Cec2_ObjSimCo
(
p
,
Id
);
if
(
Cec2_ObjSimEqual
(
p
,
Id
,
0
)
)
continue
;
p
->
pCexSeq
=
Cec2_ManDeriveCex
(
p
,
i
,
Abc_TtFindFirstBit2
(
Cec2_ObjSim
(
p
,
Id
),
p
->
nSimWords
)
);
return
0
;
}
return
1
;
}
void
Cec2_ManSaveCis
(
Gia_Man_t
*
p
)
{
int
w
,
i
,
Id
;
assert
(
p
->
vSimsPi
!=
NULL
);
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
Gia_ManForEachCiId
(
p
,
Id
,
i
)
Vec_WrdPush
(
p
->
vSimsPi
,
Cec2_ObjSim
(
p
,
Id
)[
w
]
);
}
void
Cec2_ManSimulate
(
Gia_Man_t
*
p
)
{
extern
void
Cec2_ManSimClassRefineOne
(
Gia_Man_t
*
p
,
int
iRepr
);
Gia_Obj_t
*
pObj
;
int
i
;
Cec2_ManSaveCis
(
p
);
Gia_ManForEachAnd
(
p
,
pObj
,
i
)
Cec2_ObjSimAnd
(
p
,
i
);
if
(
p
->
pReprs
==
NULL
)
return
;
Gia_ManForEachClass0
(
p
,
i
)
Cec2_ManSimClassRefineOne
(
p
,
i
);
}
void
Cec2_ManSimAlloc
(
Gia_Man_t
*
p
,
int
nWords
)
{
Vec_WrdFreeP
(
&
p
->
vSims
);
Vec_WrdFreeP
(
&
p
->
vSimsPi
);
p
->
vSims
=
Vec_WrdStart
(
Gia_ManObjNum
(
p
)
*
nWords
);
p
->
vSimsPi
=
Vec_WrdAlloc
(
Gia_ManCiNum
(
p
)
*
nWords
*
4
);
// storage for CI patterns
p
->
nSimWords
=
nWords
;
}
/**Function*************************************************************
Synopsis [Computes hash key of the simulation info.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
Cec2_ManSimHashKey
(
word
*
pSim
,
int
nSims
,
int
nTableSize
)
{
static
int
s_Primes
[
16
]
=
{
1291
,
1699
,
1999
,
2357
,
2953
,
3313
,
3907
,
4177
,
4831
,
5147
,
5647
,
6343
,
6899
,
7103
,
7873
,
8147
};
unsigned
uHash
=
0
,
*
pSimU
=
(
unsigned
*
)
pSim
;
int
i
,
nSimsU
=
2
*
nSims
;
if
(
pSimU
[
0
]
&
1
)
for
(
i
=
0
;
i
<
nSimsU
;
i
++
)
uHash
^=
~
pSimU
[
i
]
*
s_Primes
[
i
&
0xf
];
else
for
(
i
=
0
;
i
<
nSimsU
;
i
++
)
uHash
^=
pSimU
[
i
]
*
s_Primes
[
i
&
0xf
];
return
(
int
)(
uHash
%
nTableSize
);
}
/**Function*************************************************************
Synopsis [Creating initial equivalence classes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Cec2_ManSimClassRefineOne
(
Gia_Man_t
*
p
,
int
iRepr
)
{
int
iObj
,
iPrev
=
iRepr
,
iPrev2
,
iRepr2
;
Gia_ClassForEachObj1
(
p
,
iRepr
,
iRepr2
)
if
(
Cec2_ObjSimEqual
(
p
,
iRepr
,
iRepr2
)
)
iPrev
=
iRepr2
;
else
break
;
if
(
iRepr2
<=
0
)
// no refinement
return
;
// relink remaining nodes of the class
// nodes that are equal to iRepr, remain in the class of iRepr
// nodes that are not equal to iRepr, move to the class of iRepr2
Gia_ObjSetRepr
(
p
,
iRepr2
,
GIA_VOID
);
iPrev2
=
iRepr2
;
for
(
iObj
=
Gia_ObjNext
(
p
,
iRepr2
);
iObj
>
0
;
iObj
=
Gia_ObjNext
(
p
,
iObj
)
)
{
if
(
Cec2_ObjSimEqual
(
p
,
iRepr
,
iObj
)
)
// remains with iRepr
{
Gia_ObjSetNext
(
p
,
iPrev
,
iObj
);
iPrev
=
iObj
;
}
else
// moves to iRepr2
{
Gia_ObjSetRepr
(
p
,
iObj
,
iRepr2
);
Gia_ObjSetNext
(
p
,
iPrev2
,
iObj
);
iPrev2
=
iObj
;
}
}
Gia_ObjSetNext
(
p
,
iPrev
,
-
1
);
Gia_ObjSetNext
(
p
,
iPrev2
,
-
1
);
}
void
Cec2_ManCreateClasses
(
Gia_Man_t
*
p
)
{
Gia_Obj_t
*
pObj
;
int
nWords
=
p
->
nSimWords
;
int
*
pTable
,
nTableSize
,
i
,
Key
;
// allocate representation
assert
(
p
->
pReprs
==
NULL
);
p
->
pReprs
=
ABC_CALLOC
(
Gia_Rpr_t
,
Gia_ManObjNum
(
p
)
);
p
->
pNexts
=
ABC_FALLOC
(
int
,
Gia_ManObjNum
(
p
)
);
// hash each node by its simulation info
nTableSize
=
Abc_PrimeCudd
(
Gia_ManObjNum
(
p
)
);
pTable
=
ABC_FALLOC
(
int
,
nTableSize
);
Gia_ManForEachObj
(
p
,
pObj
,
i
)
{
p
->
pReprs
[
i
].
iRepr
=
GIA_VOID
;
if
(
Gia_ObjIsCo
(
pObj
)
)
continue
;
Key
=
Cec2_ManSimHashKey
(
Cec2_ObjSim
(
p
,
i
),
nWords
,
nTableSize
);
assert
(
Key
>=
0
&&
Key
<
nTableSize
);
if
(
pTable
[
Key
]
==
-
1
)
pTable
[
Key
]
=
i
;
else
Gia_ObjSetRepr
(
p
,
i
,
pTable
[
Key
]
);
}
// create classes
for
(
i
=
Gia_ManObjNum
(
p
)
-
1
;
i
>=
0
;
i
--
)
{
int
iRepr
=
Gia_ObjRepr
(
p
,
i
);
if
(
iRepr
==
GIA_VOID
)
continue
;
Gia_ObjSetNext
(
p
,
i
,
Gia_ObjNext
(
p
,
iRepr
)
);
Gia_ObjSetNext
(
p
,
iRepr
,
i
);
}
ABC_FREE
(
pTable
);
Gia_ManForEachClass0
(
p
,
i
)
Cec2_ManSimClassRefineOne
(
p
,
i
);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Cec2_Man_t
*
Cec2_ManCreate
(
Gia_Man_t
*
pAig
,
Cec2_Par_t
*
pPars
)
{
Cec2_Man_t
*
p
;
Gia_Obj_t
*
pObj
;
int
i
;
assert
(
Gia_ManRegNum
(
pAig
)
==
0
);
p
=
ABC_CALLOC
(
Cec2_Man_t
,
1
);
memset
(
p
,
0
,
sizeof
(
Cec2_Man_t
)
);
p
->
pPars
=
pPars
;
p
->
pAig
=
pAig
;
// create new manager
p
->
pNew
=
Gia_ManStart
(
Gia_ManObjNum
(
pAig
)
);
Gia_ManFillValue
(
pAig
);
Gia_ManConst0
(
pAig
)
->
Value
=
0
;
Gia_ManForEachCi
(
pAig
,
pObj
,
i
)
pObj
->
Value
=
Gia_ManAppendCi
(
p
->
pNew
);
Gia_ManHashAlloc
(
p
->
pNew
);
Vec_IntFill
(
&
p
->
pNew
->
vCopies
,
Gia_ManObjNum
(
p
->
pNew
),
-
1
);
// SAT solving
p
->
pSat
=
satoko_create
();
p
->
vFrontier
=
Vec_PtrAlloc
(
1000
);
p
->
vFanins
=
Vec_PtrAlloc
(
100
);
p
->
vNodesNew
=
Vec_IntAlloc
(
100
);
p
->
vObjSatPairs
=
Vec_IntAlloc
(
100
);
// remember pointer to the solver in the AIG manager
pAig
->
pData
=
p
->
pSat
;
return
p
;
}
void
Cec2_ManDestroy
(
Cec2_Man_t
*
p
)
{
Vec_WrdFreeP
(
&
p
->
pAig
->
vSims
);
//Vec_WrdFreeP( &p->pAig->vSimsPi );
Gia_ManCleanMark01
(
p
->
pAig
);
satoko_destroy
(
p
->
pSat
);
Gia_ManStopP
(
&
p
->
pNew
);
Vec_PtrFreeP
(
&
p
->
vFrontier
);
Vec_PtrFreeP
(
&
p
->
vFanins
);
Vec_IntFreeP
(
&
p
->
vNodesNew
);
Vec_IntFreeP
(
&
p
->
vObjSatPairs
);
ABC_FREE
(
p
);
}
/**Function*************************************************************
Synopsis [Internal simulation APIs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Cec2_ManCollect_rec
(
Cec2_Man_t
*
p
,
int
iObj
)
{
Gia_Obj_t
*
pObj
;
if
(
Gia_ObjIsTravIdCurrentId
(
p
->
pNew
,
iObj
)
)
return
;
Gia_ObjSetTravIdCurrentId
(
p
->
pNew
,
iObj
);
pObj
=
Gia_ManObj
(
p
->
pNew
,
iObj
);
if
(
Cec2_ObjSatId
(
p
->
pNew
,
pObj
)
>=
0
)
Vec_IntPush
(
p
->
vNodesNew
,
iObj
);
if
(
!
iObj
)
return
;
if
(
Gia_ObjIsAnd
(
pObj
)
)
{
Cec2_ManCollect_rec
(
p
,
Gia_ObjFaninId0
(
pObj
,
iObj
)
);
Cec2_ManCollect_rec
(
p
,
Gia_ObjFaninId1
(
pObj
,
iObj
)
);
}
else
{
assert
(
Cec2_ObjSatId
(
p
->
pNew
,
pObj
)
>=
0
);
Vec_IntPushTwo
(
p
->
vObjSatPairs
,
Gia_ManCiIdToId
(
p
->
pAig
,
Gia_ObjCioId
(
pObj
)),
Cec2_ObjSatId
(
p
->
pNew
,
pObj
)
);
// SAT var
}
}
int
Cec2_ManSolveTwo
(
Cec2_Man_t
*
p
,
int
iObj0
,
int
iObj1
,
int
fPhase
)
{
Gia_Obj_t
*
pObj
;
int
status
,
i
,
iVar0
,
iVar1
;
if
(
iObj1
<
iObj0
)
iObj1
^=
iObj0
,
iObj0
^=
iObj1
,
iObj1
^=
iObj0
;
assert
(
iObj0
<
iObj1
);
assert
(
solver_varnum
(
p
->
pSat
)
==
0
);
if
(
!
iObj0
)
Cec2_ObjSetSatId
(
p
->
pNew
,
Gia_ManConst0
(
p
->
pNew
),
satoko_add_variable
(
p
->
pSat
,
0
)
);
iVar0
=
Cec2_ObjGetCnfVar
(
p
,
iObj0
);
iVar1
=
Cec2_ObjGetCnfVar
(
p
,
iObj1
);
// collect inputs and internal nodes
Vec_IntClear
(
p
->
vNodesNew
);
Vec_IntClear
(
p
->
vObjSatPairs
);
Gia_ManIncrementTravId
(
p
->
pNew
);
Cec2_ManCollect_rec
(
p
,
iObj0
);
Cec2_ManCollect_rec
(
p
,
iObj1
);
// solve direct
satoko_assump_push
(
p
->
pSat
,
Abc_Var2Lit
(
iVar0
,
1
)
);
satoko_assump_push
(
p
->
pSat
,
Abc_Var2Lit
(
iVar1
,
fPhase
)
);
status
=
satoko_solve
(
p
->
pSat
);
satoko_assump_pop
(
p
->
pSat
);
satoko_assump_pop
(
p
->
pSat
);
if
(
status
==
SATOKO_UNSAT
&&
iObj0
>
0
)
{
// solve reverse
satoko_assump_push
(
p
->
pSat
,
Abc_Var2Lit
(
iVar0
,
0
)
);
satoko_assump_push
(
p
->
pSat
,
Abc_Var2Lit
(
iVar1
,
!
fPhase
)
);
status
=
satoko_solve
(
p
->
pSat
);
satoko_assump_pop
(
p
->
pSat
);
satoko_assump_pop
(
p
->
pSat
);
}
Gia_ManForEachObjVec
(
p
->
vNodesNew
,
p
->
pNew
,
pObj
,
i
)
Cec2_ObjCleanSatId
(
p
->
pNew
,
pObj
);
return
status
;
}
int
Cec2_ManSweepNode
(
Cec2_Man_t
*
p
,
int
iObj
)
{
int
i
,
IdAig
,
IdSat
,
status
,
RetValue
=
1
;
Gia_Obj_t
*
pObj
=
Gia_ManObj
(
p
->
pAig
,
iObj
);
Gia_Obj_t
*
pRepr
=
Gia_ObjReprObj
(
p
->
pAig
,
iObj
);
int
fCompl
=
Abc_LitIsCompl
(
pObj
->
Value
)
^
Abc_LitIsCompl
(
pRepr
->
Value
)
^
pObj
->
fPhase
^
pRepr
->
fPhase
;
status
=
Cec2_ManSolveTwo
(
p
,
Abc_Lit2Var
(
pRepr
->
Value
),
Abc_Lit2Var
(
pObj
->
Value
),
fCompl
);
if
(
status
==
SATOKO_SAT
)
{
Vec_IntForEachEntryDouble
(
p
->
vObjSatPairs
,
IdAig
,
IdSat
,
i
)
Cec2_ObjSimSetPiBit
(
p
->
pAig
,
IdAig
,
var_value
(
p
->
pSat
,
IdSat
)
==
LIT_TRUE
);
RetValue
=
0
;
}
else
if
(
status
==
SATOKO_UNSAT
)
{
pObj
->
Value
=
Abc_LitNotCond
(
pRepr
->
Value
,
fCompl
);
Gia_ObjSetProved
(
p
->
pAig
,
iObj
);
}
else
{
assert
(
status
==
SATOKO_UNDEC
);
Gia_ObjSetFailed
(
p
->
pAig
,
iObj
);
assert
(
0
);
}
satoko_rollback
(
p
->
pSat
);
return
RetValue
;
}
int
Cec2_ManPerformSweeping
(
Gia_Man_t
*
p
,
Cec2_Par_t
*
pPars
)
{
Cec2_Man_t
*
pMan
;
Gia_Obj_t
*
pObj
,
*
pRepr
,
*
pObjNew
;
int
i
,
fDisproved
=
1
;
// check if any output trivially fails under all-0 pattern
Gia_ManSetPhase
(
p
);
if
(
pPars
->
fIsMiter
)
{
Gia_ManForEachCo
(
p
,
pObj
,
i
)
if
(
pObj
->
fPhase
)
{
p
->
pCexSeq
=
Cec2_ManDeriveCex
(
p
,
i
,
-
1
);
return
0
;
}
}
// simulate one round and create classes
Cec2_ManSimAlloc
(
p
,
pPars
->
nSimWords
);
Cec2_ManSimulateCis
(
p
);
Cec2_ManSimulate
(
p
);
if
(
pPars
->
fIsMiter
&&
!
Cec2_ManSimulateCos
(
p
)
)
// cex detected
return
0
;
Cec2_ManCreateClasses
(
p
);
if
(
pPars
->
fVerbose
)
Gia_ManEquivPrintClasses
(
p
,
pPars
->
fVeryVerbose
,
0
);
// perform additinal simulation
for
(
i
=
0
;
i
<
pPars
->
nSimRounds
;
i
++
)
{
Cec2_ManSimulateCis
(
p
);
Cec2_ManSimulate
(
p
);
if
(
pPars
->
fIsMiter
&&
!
Cec2_ManSimulateCos
(
p
)
)
// cex detected
return
0
;
if
(
pPars
->
fVerbose
)
Gia_ManEquivPrintClasses
(
p
,
pPars
->
fVeryVerbose
,
0
);
}
// perform sweeping
pMan
=
Cec2_ManCreate
(
p
,
pPars
);
while
(
fDisproved
)
{
fDisproved
=
0
;
Cec2_ManSimulateCis
(
p
);
Gia_ManForEachAnd
(
p
,
pObj
,
i
)
{
pObj
->
fMark1
=
0
;
if
(
~
pObj
->
Value
)
// skip swept nodes
continue
;
assert
(
!
Gia_ObjProved
(
p
,
i
)
&&
!
Gia_ObjFailed
(
p
,
i
)
);
pObj
->
fMark1
=
Gia_ObjFanin0
(
pObj
)
->
fMark1
||
Gia_ObjFanin1
(
pObj
)
->
fMark1
;
if
(
pObj
->
fMark1
)
// skip nodes in the TFO of a disproved one
continue
;
// duplicate the node
pObj
->
Value
=
Gia_ManHashAnd
(
pMan
->
pNew
,
Gia_ObjFanin0Copy
(
pObj
),
Gia_ObjFanin1Copy
(
pObj
)
);
if
(
Vec_IntSize
(
&
pMan
->
pNew
->
vCopies
)
==
Abc_Lit2Var
(
pObj
->
Value
)
)
{
pObjNew
=
Gia_ManObj
(
pMan
->
pNew
,
Abc_Lit2Var
(
pObj
->
Value
)
);
pObjNew
->
fMark0
=
Gia_ObjIsMuxType
(
pObjNew
);
Vec_IntPush
(
&
pMan
->
pNew
->
vCopies
,
-
1
);
}
assert
(
Vec_IntSize
(
&
pMan
->
pNew
->
vCopies
)
==
Gia_ManObjNum
(
pMan
->
pNew
)
);
pRepr
=
Gia_ObjReprObj
(
p
,
i
);
if
(
pRepr
==
NULL
||
pRepr
->
fMark1
)
continue
;
//if ( Gia_ObjIsConst0(pRepr) )
// continue;
if
(
Abc_Lit2Var
(
pObj
->
Value
)
==
Abc_Lit2Var
(
pRepr
->
Value
)
)
{
assert
(
(
pObj
->
Value
^
pRepr
->
Value
)
==
(
pObj
->
fPhase
^
pRepr
->
fPhase
)
);
Gia_ObjSetProved
(
p
,
i
);
continue
;
}
if
(
Cec2_ManSweepNode
(
pMan
,
i
)
)
continue
;
// mark nodes as disproved
pRepr
->
fMark1
=
pObj
->
fMark1
=
1
;
fDisproved
=
1
;
}
if
(
fDisproved
)
{
Cec2_ManSimulate
(
p
);
if
(
pPars
->
fIsMiter
&&
!
Cec2_ManSimulateCos
(
p
)
)
// cex detected
break
;
}
if
(
pPars
->
fVerbose
)
Gia_ManEquivPrintClasses
(
p
,
pPars
->
fVeryVerbose
,
0
);
}
Cec2_ManDestroy
(
pMan
);
return
p
->
pCexSeq
?
0
:
1
;
}
void
Cec2_ManSimulateTest
(
Gia_Man_t
*
p
)
{
abctime
clk
=
Abc_Clock
();
Cec2_Par_t
Pars
,
*
pPars
=
&
Pars
;
Cec2_SetDefaultParams
(
pPars
);
Cec2_ManPerformSweeping
(
p
,
pPars
);
Abc_PrintTime
(
1
,
"SAT sweeping time"
,
Abc_Clock
()
-
clk
);
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END
src/proof/cec/module.make
View file @
429f52ce
...
...
@@ -6,6 +6,7 @@ SRC += src/proof/cec/cecCec.c \
src/proof/cec/cecIso.c
\
src/proof/cec/cecMan.c
\
src/proof/cec/cecPat.c
\
src/proof/cec/cecSat.c
\
src/proof/cec/cecSeq.c
\
src/proof/cec/cecSolve.c
\
src/proof/cec/cecSplit.c
\
...
...
src/sat/bmc/bmcGen.c
View file @
429f52ce
...
...
@@ -46,13 +46,13 @@ ABC_NAMESPACE_IMPL_START
***********************************************************************/
static
inline
word
*
Gia_ManMoObj
(
Gia_Man_t
*
p
,
int
iObj
)
{
return
Vec_WrdEntryP
(
p
->
vSims
,
iObj
*
p
->
iPatsPi
);
return
Vec_WrdEntryP
(
p
->
vSims
,
iObj
*
p
->
nSimWords
);
}
static
inline
void
Gia_ManMoSetCi
(
Gia_Man_t
*
p
,
int
iObj
)
{
int
w
;
word
*
pSims
=
Gia_ManMoObj
(
p
,
iObj
);
for
(
w
=
0
;
w
<
p
->
iPatsPi
;
w
++
)
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
pSims
[
w
]
=
Gia_ManRandomW
(
0
);
}
static
inline
void
Gia_ManMoSimAnd
(
Gia_Man_t
*
p
,
int
iObj
)
...
...
@@ -65,19 +65,19 @@ static inline void Gia_ManMoSimAnd( Gia_Man_t * p, int iObj )
if
(
Gia_ObjFaninC0
(
pObj
)
)
{
if
(
Gia_ObjFaninC1
(
pObj
)
)
for
(
w
=
0
;
w
<
p
->
iPatsPi
;
w
++
)
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
pSims
[
w
]
=
~
(
pSims0
[
w
]
|
pSims1
[
w
]);
else
for
(
w
=
0
;
w
<
p
->
iPatsPi
;
w
++
)
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
pSims
[
w
]
=
~
pSims0
[
w
]
&
pSims1
[
w
];
}
else
{
if
(
Gia_ObjFaninC1
(
pObj
)
)
for
(
w
=
0
;
w
<
p
->
iPatsPi
;
w
++
)
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
pSims
[
w
]
=
pSims0
[
w
]
&
~
pSims1
[
w
];
else
for
(
w
=
0
;
w
<
p
->
iPatsPi
;
w
++
)
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
pSims
[
w
]
=
pSims0
[
w
]
&
pSims1
[
w
];
}
}
...
...
@@ -89,12 +89,12 @@ static inline void Gia_ManMoSetCo( Gia_Man_t * p, int iObj )
word
*
pSims0
=
Gia_ManMoObj
(
p
,
Gia_ObjFaninId0
(
pObj
,
iObj
)
);
if
(
Gia_ObjFaninC0
(
pObj
)
)
{
for
(
w
=
0
;
w
<
p
->
iPatsPi
;
w
++
)
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
pSims
[
w
]
=
~
pSims0
[
w
];
}
else
{
for
(
w
=
0
;
w
<
p
->
iPatsPi
;
w
++
)
for
(
w
=
0
;
w
<
p
->
nSimWords
;
w
++
)
pSims
[
w
]
=
pSims0
[
w
];
}
}
...
...
@@ -102,7 +102,7 @@ void Gia_ManMoFindSimulate( Gia_Man_t * p, int nWords )
{
int
i
,
iObj
;
Gia_ManRandomW
(
1
);
p
->
iPatsPi
=
nWords
;
p
->
nSimWords
=
nWords
;
if
(
p
->
vSims
)
Vec_WrdFill
(
p
->
vSims
,
nWords
*
Gia_ManObjNum
(
p
),
0
);
else
...
...
src/sat/satoko/satoko.h
View file @
429f52ce
...
...
@@ -83,7 +83,7 @@ extern void satoko_destroy(satoko_t *);
extern
void
satoko_default_opts
(
satoko_opts_t
*
);
extern
void
satoko_configure
(
satoko_t
*
,
satoko_opts_t
*
);
extern
int
satoko_parse_dimacs
(
char
*
,
satoko_t
**
);
extern
void
satoko_add_variable
(
satoko_t
*
,
char
);
extern
int
satoko_add_variable
(
satoko_t
*
,
char
);
extern
int
satoko_add_clause
(
satoko_t
*
,
unsigned
*
,
unsigned
);
extern
void
satoko_assump_push
(
satoko_t
*
s
,
unsigned
);
extern
void
satoko_assump_pop
(
satoko_t
*
s
);
...
...
src/sat/satoko/solver_api.c
View file @
429f52ce
...
...
@@ -216,7 +216,7 @@ int satoko_simplify(solver_t * s)
return
SATOKO_OK
;
}
void
satoko_add_variable
(
solver_t
*
s
,
char
sign
)
int
satoko_add_variable
(
solver_t
*
s
,
char
sign
)
{
unsigned
var
=
vec_act_size
(
s
->
activity
);
vec_wl_push
(
s
->
watches
);
...
...
@@ -231,6 +231,7 @@ void satoko_add_variable(solver_t *s, char sign)
heap_insert
(
s
->
var_order
,
var
);
if
(
s
->
marks
)
vec_char_push_back
(
s
->
marks
,
0
);
return
var
;
}
int
satoko_add_clause
(
solver_t
*
s
,
unsigned
*
lits
,
unsigned
size
)
...
...
@@ -351,6 +352,7 @@ void satoko_rollback(satoko_t *s)
clause_unwatch
(
s
,
cdb_cref
(
s
->
all_clauses
,
(
unsigned
*
)
cl_to_remove
[
i
]));
cl_to_remove
[
i
]
->
f_mark
=
1
;
}
satoko_free
(
cl_to_remove
);
vec_uint_shrink
(
s
->
originals
,
s
->
book_cl_orig
);
vec_uint_shrink
(
s
->
learnts
,
s
->
book_cl_lrnt
);
/* Shrink variable related vectors */
...
...
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