23#pragma warning(disable : 4786)
43 typedef std::bitset<64>
bsw;
55 std::vector<std::vector<word> >
savedt;
75 for(
int i = 0; i <
nInputs; i++) {
80 virtual void Save(
unsigned i) {
81 if(
savedt.size() < i + 1) {
89 virtual void Load(
unsigned i) {
113 int index = index_lev >> (
lww - logwidth);
114 int pos = (index_lev % (1 << (
lww - logwidth))) << logwidth;
115 return (
t[index] >>
pos) &
ones[logwidth];
118 int IsEq(
int index1,
int index2,
int lev,
bool fCompl =
false) {
124 int nScopeSize = 1 << (logwidth -
lww);
125 for(
int i = 0; i < nScopeSize && (fEq || fCompl); i++) {
126 fEq &= (
t[nScopeSize * index1 + i] ==
t[nScopeSize * index2 + i]);
127 fCompl &= (
t[nScopeSize * index1 + i] ==
~t[nScopeSize * index2 + i]);
134 return 2 * fCompl + fEq;
137 bool Imply(
int index1,
int index2,
int lev) {
142 int nScopeSize = 1 << (logwidth -
lww);
143 for(
int i = 0; i < nScopeSize; i++) {
144 if(
t[nScopeSize * index1 + i] & ~
t[nScopeSize * index2 + i]) {
159 for(
int i = 0; i <
nInputs; i++) {
168 int nScopeSize = 1 << (logwidth -
lww);
171 for(
int i = 0; i < nScopeSize && (fZero || fOne); i++) {
177 return -2 ^ (int)fOne;
179 for(
unsigned j = 0; j <
vvIndices[lev].size(); j++) {
183 for(
int i = 0; i < nScopeSize && (fEq || fCompl); i++) {
184 fEq &= (
t[nScopeSize * index + i] ==
t[nScopeSize * index2 + i]);
185 fCompl &= (
t[nScopeSize * index + i] ==
~t[nScopeSize * index2 + i]);
188 return (j << 1) ^ (int)fCompl;
199 for(
unsigned j = 0; j <
vvIndices[lev].size(); j++) {
205 if(!(value2 ^
ones[logwidth])) {
233 for(
unsigned i = 0; i <
vvIndices[lev-1].size(); i++) {
245 for(
int i = 1; i <
nInputs; i++) {
254 for(
int i = lev; i < lev + 2; i++) {
266 for(
unsigned i = 0; i <
vvIndices[lev+1].size(); i++) {
268 if(
IsEq(index << 1, (index << 1) ^ 1, lev + 2)) {
278 std::vector<int>::iterator it0 = std::find(
vLevels.begin(),
vLevels.end(), lev);
279 std::vector<int>::iterator it1 = std::find(
vLevels.begin(),
vLevels.end(), lev + 1);
280 std::swap(*it0, *it1);
282 int nScopeSize = 1 << (
nInputs - lev - 2 -
lww);
283 for(
int i = nScopeSize; i <
nTotalSize; i += (nScopeSize << 2)) {
284 for(
int j = 0; j < nScopeSize; j++) {
285 std::swap(
t[i + j],
t[i + nScopeSize + j]);
290 t[i+1] ^=
t[i] >> (
ww / 2);
291 t[i] ^=
t[i+1] << (
ww / 2);
292 t[i+1] ^=
t[i] >> (
ww / 2);
306 if((index >> d) % 4 == 1) {
308 }
else if((index >> d) % 4 == 2) {
315 for(
int i = lev + 2; i <
nInputs; i++) {
316 for(
unsigned j = 0; j <
vvIndices[i].size(); j++) {
328 std::vector<int> vars(
nInputs);
333 std::vector<unsigned> vCounts(
nInputs);
339 while(j > 0 && vCounts[vars[j-1]] < vCounts[vars[j]]) {
340 std::swap(vars[j], vars[j-1]);
346 for(j = 0; j < vars.size(); j++) {
348 bool updated =
false;
350 for(
int i = lev; i <
nInputs - 1; i++) {
362 for(
int i = lev - 1; i >= 0; i--) {
379 void Reo(std::vector<int> vLevelsNew) {
380 for(
int i = 0; i <
nInputs; i++) {
381 int var = std::find(vLevelsNew.begin(), vLevelsNew.end(), i) - vLevelsNew.begin();
384 for(
int j = lev; j < i; j++) {
388 for(
int j = lev - 1; j >= i; j--) {
399 for(
int i = 0; i < nRound; i++) {
400 std::vector<int> vLevelsNew(
nInputs);
405 for(j =
nInputs - 1; j > 0; j--) {
407 std::swap(vLevelsNew[j], vLevelsNew[d]);
423 return vvNodes[lev][r >> 1] ^ (r & 1);
434 if(
Imply(index << 1, (index << 1) ^ 1, lev + 1)) {
436 }
else if(
Imply((index << 1) ^ 1, index << 1, lev + 1)) {
442 vvNodes[lev].push_back(node);
449 std::vector<std::vector<int> > vvNodes(
nInputs);
450 std::vector<int> vInputs(
nInputs);
457 Gia_ManAppendCo(pNew, node);
521 for(
unsigned i = 0; i <
vvIndices[lev-1].size(); i++) {
539 for(
int i = 1; i <
nInputs + 1; i++) {
546 if(cof0 < 0 && cof0 == cof1) {
549 bool fCompl = cof0 & 1;
554 int *place = Hash_Int2ManLookup(unique, cof0, cof1);
556 return (Hash_IntObjData2(unique, *place) << 1) ^ (int)fCompl;
559 Hash_Int2ManInsert(unique, cof0, cof1,
vvIndices[lev].size() - 1);
560 vChildrenLow.push_back(cof0);
561 vChildrenLow.push_back(cof1);
565 return ((
vvIndices[lev].size() - 1) << 1) ^ (int)fCompl;
571 std::vector<int> vChildrenHigh;
572 std::vector<int> vChildrenLow;
575 for(
unsigned i = 0; i <
vvIndices[lev].size(); i++) {
581 int cof00, cof01, cof10, cof11;
583 cof00 = -2 ^ (int)cof0c;
584 cof01 = -2 ^ (int)cof0c;
586 cof00 =
vvChildren[lev+1][cof0index+cof0index] ^ (int)cof0c;
587 cof01 =
vvChildren[lev+1][cof0index+cof0index+1] ^ (int)cof0c;
590 cof10 = -2 ^ (int)cof1c;
591 cof11 = -2 ^ (int)cof1c;
593 cof10 =
vvChildren[lev+1][cof1index+cof1index] ^ (int)cof1c;
594 cof11 =
vvChildren[lev+1][cof1index+cof1index+1] ^ (int)cof1c;
596 int newcof0 =
BDDRebuildOne(index << 1, cof00, cof10, lev + 1, unique, vChildrenLow);
597 int newcof1 =
BDDRebuildOne((index << 1) ^ 1, cof01, cof11, lev + 1, unique, vChildrenLow);
598 vChildrenHigh.push_back(newcof0);
599 vChildrenHigh.push_back(newcof1);
600 if(newcof0 == newcof1) {
604 Hash_IntManStop(unique);
612 std::vector<int>::iterator it0 = std::find(
vLevels.begin(),
vLevels.end(), lev);
613 std::vector<int>::iterator it1 = std::find(
vLevels.begin(),
vLevels.end(), lev + 1);
614 std::swap(*it0, *it1);
636 int index = index_lev >> (
lww - logwidth);
637 int pos = (index_lev % (1 << (
lww - logwidth))) << logwidth;
638 t[index] &= ~(
ones[logwidth] <<
pos);
642 void CopyFunc(
int index1,
int index2,
int lev,
bool fCompl) {
646 int nScopeSize = 1 << (logwidth -
lww);
649 for(
int i = 0; i < nScopeSize; i++) {
650 t[nScopeSize * index1 + i] = 0;
653 for(
int i = 0; i < nScopeSize; i++) {
654 t[nScopeSize * index1 + i] =
t[nScopeSize * index2 + i];
659 for(
int i = 0; i < nScopeSize; i++) {
660 t[nScopeSize * index1 + i] =
ones[
lww];
663 for(
int i = 0; i < nScopeSize; i++) {
664 t[nScopeSize * index1 + i] =
~t[nScopeSize * index2 + i];
685 int nScopeSize = 1 << (logwidth -
lww);
686 for(
int i = 0; i < nScopeSize; i++) {
687 count +=
bsw(
t[nScopeSize * index + i]).count();
692 bool majority = count > (1 << (logwidth - 1));
745 int nScopeSize = 1 << (
nInputs - lev - 2 -
lww);
746 for(
int i = nScopeSize; i <
nSize; i += (nScopeSize << 2)) {
747 for(
int j = 0; j < nScopeSize; j++) {
748 std::swap(
care[i + j],
care[i + nScopeSize + j]);
752 for(
int i = 0; i <
nSize; i += 2) {
758 for(
int i = 0; i <
nSize || (i == 0 && !
nSize); i++) {
777 int padding = i * (1 <<
nInputs);
787 int index = index_lev >> (
lww - logwidth);
788 int pos = (index_lev % (1 << (
lww - logwidth))) << logwidth;
797 int nScopeSize = 1 << (logwidth -
lww);
798 for(
int i = 0; i < nScopeSize; i++) {
803 word cvalue =
caret[nScopeSize * index2 + i];
804 t[nScopeSize * index1 + i] &= ~cvalue;
805 t[nScopeSize * index1 + i] |= cvalue &
value;
815 value1 &= cvalue ^ one;
816 value1 |= cvalue & value2;
821 bool IsDC(
int index,
int lev) {
824 for(
int i = 0; i < nScopeSize; i++) {
825 if(
caret[nScopeSize * index + i]) {
829 }
else if(
GetCare(index, lev)) {
835 int Include(
int index1,
int index2,
int lev,
bool fCompl) {
841 int nScopeSize = 1 << (logwidth -
lww);
842 for(
int i = 0; i < nScopeSize && (fEq || fCompl); i++) {
843 word cvalue =
caret[nScopeSize * index2 + i];
844 if(~
caret[nScopeSize * index1 + i] & cvalue) {
847 word value =
t[nScopeSize * index1 + i] ^
t[nScopeSize * index2 + i];
848 fEq &= !(
value & cvalue);
849 fCompl &= !(
~value & cvalue);
853 if((
GetCare(index1, lev) ^
ones[logwidth]) & cvalue) {
857 fEq &= !(
value & cvalue);
858 fCompl &= !((
value ^
ones[logwidth]) & cvalue);
860 return 2 * fCompl + fEq;
863 int Intersect(
int index1,
int index2,
int lev,
bool fCompl,
bool fEq =
true) {
868 int nScopeSize = 1 << (logwidth -
lww);
869 for(
int i = 0; i < nScopeSize && (fEq || fCompl); i++) {
870 word value =
t[nScopeSize * index1 + i] ^
t[nScopeSize * index2 + i];
871 word cvalue =
caret[nScopeSize * index1 + i] &
caret[nScopeSize * index2 + i];
872 fEq &= !(
value & cvalue);
873 fCompl &= !(
~value & cvalue);
878 fEq &= !(
value & cvalue);
879 fCompl &= !((
value ^
ones[logwidth]) & cvalue);
881 return 2 * fCompl + fEq;
889 int nScopeSize = 1 << (logwidth -
lww);
890 for(
int i = 0; i < nScopeSize; i++) {
891 caret[nScopeSize * index1 + i] |=
caret[nScopeSize * index2 + i];
895 int index = index1 >> (
lww - logwidth);
896 int pos = (index1 % (1 << (
lww - logwidth))) << logwidth;
901 void Merge(
int index1,
int index2,
int lev,
bool fCompl) {
903 vvMergedIndices[lev].push_back(std::make_pair((index1 << 1) ^ (
int)fCompl, index2));
919 for(
int i =
nInputs - 1; i >= 0; i--) {
921 CopyFunc((*it).second, (*it).first >> 1, i, (*it).first & 1);
951 for(i = lev; i <
nInputs; i++) {
958 for(i = 0; i < lev; i++) {
961 for(i = lev; i <
nInputs; i++) {
998 for(
int i = 1; i <
nInputs; i++) {
999 for(
unsigned j = 0; j <
vvIndices[i-1].size(); j++) {
1015 if(logwidth >
lww) {
1016 int nScopeSize = 1 << (logwidth -
lww);
1019 for(
int i = 0; i < nScopeSize && (fZero || fOne); i++) {
1021 word cvalue =
caret[nScopeSize * index + i];
1022 fZero &= !(
value & cvalue);
1023 fOne &= !(
~value & cvalue);
1026 return -2 ^ (int)fOne;
1028 for(
unsigned j = 0; j <
vvIndices[lev].size(); j++) {
1032 for(
int i = 0; i < nScopeSize && (fEq || fCompl); i++) {
1033 word value =
t[nScopeSize * index + i] ^
t[nScopeSize * index2 + i];
1034 word cvalue =
caret[nScopeSize * index + i] &
caret[nScopeSize * index2 + i];
1035 fEq &= !(
value & cvalue);
1036 fCompl &= !(
~value & cvalue);
1039 return (index2 << 1) ^ (int)!fEq;
1046 if(!(
value & cvalue)) {
1049 if(!((
value ^ one) & cvalue)) {
1052 for(
unsigned j = 0; j <
vvIndices[lev].size(); j++) {
1056 if(!(value2 & cvalue2)) {
1059 if(!((value2 ^ one) & cvalue2)) {
1060 return (index2 << 1) ^ 1;
1072 Merge(r >> 1, index, lev, r & 1);
1116 int i, g, k, nInputs;
1119 pNew->
pName = Abc_UtilStrsav(
p->pName );
1120 pNew->
pSpec = Abc_UtilStrsav(
p->pSpec );
1122 Gia_ManAppendCi( pNew );
1125 for ( g = 0; g < Gia_ManCoNum(
p); g += nOuts )
1128 nInputs = Vec_IntSize( vSupp );
1130 for ( k = 0; k < nOuts; k++ )
1132 pObj = Gia_ManCo(
p, g+k );
1135 for ( i = 0; i < tt.
nSize; i++ )
1136 tt.
t[i + tt.
nSize * k] = Gia_ObjFaninC0(pObj)? ~pTruth[i]: pTruth[i];
1139 i = k * (1 << nInputs);
1140 v = (Gia_ObjFaninC0(pObj)? ~pTruth[0]: pTruth[0]) & tt.
ones[nInputs];
1141 tt.
t[i / tt.
ww] |= v << (i % tt.
ww);
1149 Vec_IntFree( vSupp );
1164 word * pTruth, * pCare;
1165 int i, g, k, nInputs;
1166 Vec_Wrd_t * vSimI = Vec_WrdReadBin( pFileName, fVerbose );
1169 pNew->
pName = Abc_UtilStrsav(
p->pName );
1170 pNew->
pSpec = Abc_UtilStrsav(
p->pSpec );
1172 Gia_ManAppendCi( pNew );
1175 for ( g = 0; g < Gia_ManCoNum(
p); g += nOuts )
1178 nInputs = Vec_IntSize( vSupp );
1181 for ( k = 0; k < nOuts; k++ )
1183 pObj = Gia_ManCo(
p, g+k );
1185 Gia_ManAppendCo( pNew, pTruth[0] & 1 );
1187 Vec_IntFree( vSupp );
1191 for ( k = 0; k < nOuts; k++ )
1193 pObj = Gia_ManCo(
p, g+k );
1196 for ( i = 0; i < tt.
nSize; i++ )
1197 tt.
t[i + tt.
nSize * k] = Gia_ObjFaninC0(pObj)? ~pTruth[i]: pTruth[i];
1200 i = k * (1 << nInputs);
1201 v = (Gia_ObjFaninC0(pObj)? ~pTruth[0]: pTruth[0]) & tt.
ones[nInputs];
1202 tt.
t[i / tt.
ww] |= v << (i % tt.
ww);
1205 i = 1 << Vec_IntSize( vSupp );
1207 tt.
care[0] = pCare[0];
1208 for ( i = 1; i < tt.
nSize; i++ )
1209 tt.
care[i] = pCare[i];
1214 Vec_IntFree( vSupp );
1219 Vec_WrdFreeP( &vSimI );
#define ABC_CONST(number)
PARAMETERS ///.
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
ABC_NAMESPACE_IMPL_START typedef signed char value
std::vector< std::vector< word > > savedcare
void LoadIndices(unsigned i)
void CopyFuncMasked(int index1, int index2, int lev, bool fCompl)
bool IsDC(int index, int lev)
virtual void BDDRebuildByMerge(int lev)
void SaveIndices(unsigned i)
std::vector< std::vector< std::pair< int, int > > > vvMergedIndices
word GetCare(int index_lev, int lev)
int BDDBuildOne(int index, int lev)
std::vector< std::vector< std::vector< std::pair< int, int > > > > vvMergedIndicesSaved
std::vector< word > caret
void MergeCare(int index1, int index2, int lev)
int Intersect(int index1, int index2, int lev, bool fCompl, bool fEq=true)
std::vector< word > originalt
TruthTableCare(int nInputs, int nOutputs)
void Merge(int index1, int index2, int lev, bool fCompl)
void OptimizationStartup()
int Include(int index1, int index2, int lev, bool fCompl)
void BDDRebuildByMerge(int lev)
int BDDBuildOne(int index, int lev)
TruthTableLevelTSM(int nInputs, int nOutputs)
int BDDFindTSM(int index, int lev)
std::vector< std::vector< std::vector< int > > > vvChildrenSaved
TruthTableReo(int nInputs, int nOutputs)
virtual void BDDGenerateAig(Gia_Man_t *pNew, Vec_Int_t *vSupp)
int BDDRebuildOne(int index, int cof0, int cof1, int lev, Hash_IntMan_t *unique, std::vector< int > &vChildrenLow)
void LoadIndices(unsigned i)
std::vector< std::vector< int > > vvChildren
void SaveIndices(unsigned i)
void BDDBuildLevel(int lev)
void SetValue(int index_lev, int lev, word value)
void CopyFunc(int index1, int index2, int lev, bool fCompl)
void ShiftToMajority(int index, int lev)
TruthTableRewrite(int nInputs, int nOutputs)
virtual void BDDBuildStartup()
virtual void Swap(int lev)
static const word swapmask[]
std::vector< std::vector< int > > vvRedundantIndices
bool Imply(int index1, int index2, int lev)
std::vector< int > vLevels
virtual int BDDSwap(int lev)
void Reo(std::vector< int > vLevelsNew)
word GetValue(int index_lev, int lev)
virtual void BDDGenerateAig(Gia_Man_t *pNew, Vec_Int_t *vSupp)
int RandomSiftReo(int nRound)
int BDDGenerateAigRec(Gia_Man_t *pNew, std::vector< int > const &vInputs, std::vector< std::vector< int > > &vvNodes, int index, int lev)
std::vector< std::vector< int > > vLevelsSaved
std::vector< std::vector< std::vector< int > > > vvRedundantIndicesSaved
int BDDNodeCountLevel(int lev)
virtual void LoadIndices(unsigned i)
std::vector< std::vector< std::vector< int > > > vvIndicesSaved
virtual int BDDBuildOne(int index, int lev)
TruthTable(int nInputs, int nOutputs)
virtual void BDDBuildLevel(int lev)
void SwapIndex(int &index, int d)
virtual void Save(unsigned i)
virtual void SaveIndices(unsigned i)
std::vector< std::vector< int > > vvIndices
virtual void Load(unsigned i)
int BDDFind(int index, int lev)
virtual int BDDRebuild(int lev)
std::vector< std::vector< word > > savedt
int IsEq(int index1, int index2, int lev, bool fCompl=false)
Gia_Man_t * Gia_ManTtopt(Gia_Man_t *p, int nIns, int nOuts, int nRounds)
Gia_Man_t * Gia_ManTtoptCare(Gia_Man_t *p, int nIns, int nOuts, int nRounds, char *pFileName, int nRarity)
word * Gia_ObjComputeTruthTableCut(Gia_Man_t *p, Gia_Obj_t *pObj, Vec_Int_t *vLeaves)
void Gia_ManHashStart(Gia_Man_t *p)
void Gia_ManSetRegNum(Gia_Man_t *p, int nRegs)
Gia_Man_t * Gia_ManStart(int nObjsMax)
FUNCTION DEFINITIONS ///.
int Gia_ManHashOr(Gia_Man_t *p, int iLit0, int iLit1)
struct Gia_Obj_t_ Gia_Obj_t
struct Gia_Man_t_ Gia_Man_t
int Gia_ManHashMux(Gia_Man_t *p, int iCtrl, int iData1, int iData0)
void Gia_ObjComputeTruthTableStart(Gia_Man_t *p, int nVarsMax)
Vec_Int_t * Gia_ManCollectSuppNew(Gia_Man_t *p, int iOut, int nOuts)
void Gia_ObjComputeTruthTableStop(Gia_Man_t *p)
int Gia_ManHashAnd(Gia_Man_t *p, int iLit0, int iLit1)
word * Gia_ManCountFraction(Gia_Man_t *p, Vec_Wrd_t *vSimI, Vec_Int_t *vSupp, int Thresh, int fVerbose, int *pCare)
#define Gia_ManForEachCi(p, pObj, i)
void Gia_ManHashStop(Gia_Man_t *p)
int Gia_ManLevelNum(Gia_Man_t *p)
unsigned __int64 word
DECLARATIONS ///.
struct Hash_IntMan_t_ Hash_IntMan_t
typedefABC_NAMESPACE_HEADER_START struct Vec_Wrd_t_ Vec_Wrd_t
INCLUDES ///.