summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--abclib.dsp180
-rw-r--r--src/aig/gia/gia.c96
-rw-r--r--src/aig/gia/gia.h58
-rw-r--r--src/aig/gia/giaAig.c36
-rw-r--r--src/aig/gia/giaAiger.c281
-rw-r--r--src/aig/gia/giaCSat.c4
-rw-r--r--src/aig/gia/giaCSat3.c1365
-rw-r--r--src/aig/gia/giaCut.c149
-rw-r--r--src/aig/gia/giaDecs.c350
-rw-r--r--src/aig/gia/giaDeep.c120
-rw-r--r--src/aig/gia/giaDfs.c28
-rw-r--r--src/aig/gia/giaDup.c188
-rw-r--r--src/aig/gia/giaEmbed.c2
-rw-r--r--src/aig/gia/giaEquiv.c297
-rw-r--r--src/aig/gia/giaFanout.c83
-rw-r--r--src/aig/gia/giaFx.c6
-rw-r--r--src/aig/gia/giaGen.c461
-rw-r--r--src/aig/gia/giaHash.c322
-rw-r--r--src/aig/gia/giaIf.c82
-rw-r--r--src/aig/gia/giaIso.c6
-rw-r--r--src/aig/gia/giaIso2.c2
-rw-r--r--src/aig/gia/giaIso3.c91
-rw-r--r--src/aig/gia/giaMan.c99
-rw-r--r--src/aig/gia/giaMf.c238
-rw-r--r--src/aig/gia/giaMinLut.c1058
-rw-r--r--src/aig/gia/giaMinLut2.c1372
-rw-r--r--src/aig/gia/giaMini.c396
-rw-r--r--src/aig/gia/giaPat2.c1329
-rw-r--r--src/aig/gia/giaReshape1.c (renamed from src/aig/gia/giaSim5.c)18
-rw-r--r--src/aig/gia/giaReshape2.c (renamed from src/aig/gia/giaSim4.c)12
-rw-r--r--src/aig/gia/giaResub.c1767
-rw-r--r--src/aig/gia/giaResub2.c1558
-rw-r--r--src/aig/gia/giaResub3.c54
-rw-r--r--src/aig/gia/giaScript.c21
-rw-r--r--src/aig/gia/giaSim.c166
-rw-r--r--src/aig/gia/giaSimBase.c837
-rw-r--r--src/aig/gia/giaStoch.c448
-rw-r--r--src/aig/gia/giaStr.c26
-rw-r--r--src/aig/gia/giaSupps.c817
-rw-r--r--src/aig/gia/giaSweep.c25
-rw-r--r--src/aig/gia/giaTruth.c32
-rw-r--r--src/aig/gia/giaUtil.c803
-rw-r--r--src/aig/gia/module.make13
-rw-r--r--src/aig/hop/hopBalance.c2
-rw-r--r--src/aig/ivy/ivyBalance.c2
-rw-r--r--src/aig/ivy/ivyCutTrav.c2
-rw-r--r--src/aig/ivy/ivyRwrAlg.c2
-rw-r--r--src/aig/miniaig/abcOper.h26
-rw-r--r--src/aig/miniaig/minilut.h32
-rw-r--r--src/aig/miniaig/ndr.h85
-rw-r--r--src/aig/saig/saigConstr.c4
-rw-r--r--src/aig/saig/saigIso.c4
-rw-r--r--src/aig/saig/saigIsoFast.c2
-rw-r--r--src/aig/saig/saigIsoSlow.c8
-rw-r--r--src/aig/saig/saigWnd.c2
-rw-r--r--src/base/abc/abc.h7
-rw-r--r--src/base/abc/abcCheck.c4
-rw-r--r--src/base/abc/abcDfs.c4
-rw-r--r--src/base/abc/abcFanOrder.c4
-rw-r--r--src/base/abc/abcFunc.c13
-rw-r--r--src/base/abc/abcHie.c2
-rw-r--r--src/base/abc/abcHieNew.c4
-rw-r--r--src/base/abc/abcLatch.c15
-rw-r--r--src/base/abc/abcMinBase.c57
-rw-r--r--src/base/abc/abcNames.c11
-rw-r--r--src/base/abc/abcNtk.c9
-rw-r--r--src/base/abc/abcObj.c1
-rw-r--r--src/base/abc/abcShow.c6
-rw-r--r--src/base/abc/abcUtil.c11
-rw-r--r--src/base/abci/abc.c2113
-rw-r--r--src/base/abci/abcBalance.c2
-rw-r--r--src/base/abci/abcCollapse.c15
-rw-r--r--src/base/abci/abcDar.c39
-rw-r--r--src/base/abci/abcDress2.c29
-rw-r--r--src/base/abci/abcEspresso.c2
-rw-r--r--src/base/abci/abcExtract.c17
-rw-r--r--src/base/abci/abcFx.c2
-rw-r--r--src/base/abci/abcFxu.c2
-rw-r--r--src/base/abci/abcIf.c6
-rw-r--r--src/base/abci/abcIvy.c6
-rw-r--r--src/base/abci/abcLut.c160
-rw-r--r--src/base/abci/abcLutmin.c4
-rw-r--r--src/base/abci/abcMap.c6
-rw-r--r--src/base/abci/abcMffc.c2
-rw-r--r--src/base/abci/abcMiter.c4
-rw-r--r--src/base/abci/abcNpnSave.c2
-rw-r--r--src/base/abci/abcNtbdd.c42
-rw-r--r--src/base/abci/abcPrint.c11
-rw-r--r--src/base/abci/abcProve.c2
-rw-r--r--src/base/abci/abcReorder.c2
-rw-r--r--src/base/abci/abcStrash.c90
-rw-r--r--src/base/abci/abcSweep.c6
-rw-r--r--src/base/abci/abcTiming.c60
-rw-r--r--src/base/abci/abcUnreach.c2
-rw-r--r--src/base/abci/abcVerify.c3
-rw-r--r--src/base/acb/acb.h6
-rw-r--r--src/base/acb/acbFunc.c475
-rw-r--r--src/base/acb/acbTest.c611
-rw-r--r--src/base/acb/acbUtil.c300
-rw-r--r--src/base/cba/cbaNtk.c2
-rw-r--r--src/base/cmd/cmdHist.c3
-rw-r--r--src/base/io/io.c110
-rw-r--r--src/base/io/ioReadAiger.c9
-rw-r--r--src/base/io/ioReadBench.c4
-rw-r--r--src/base/io/ioReadBlif.c19
-rw-r--r--src/base/io/ioReadBlifMv.c9
-rw-r--r--src/base/io/ioUtil.c56
-rw-r--r--src/base/io/ioWriteBench.c2
-rw-r--r--src/base/io/ioWriteDot.c4
-rw-r--r--src/base/io/ioWriteVerilog.c256
-rw-r--r--src/base/main/abcapis.h3
-rw-r--r--src/base/main/main.h5
-rw-r--r--src/base/main/mainFrame.c8
-rw-r--r--src/base/main/mainInit.c5
-rw-r--r--src/base/main/mainInt.h2
-rw-r--r--src/base/main/mainUtils.c7
-rw-r--r--src/base/wlc/wlc.c440
-rw-r--r--src/base/wlc/wlc.h2
-rw-r--r--src/base/wlc/wlcAbc.c14
-rw-r--r--src/base/wlc/wlcAbs.c8
-rw-r--r--src/base/wlc/wlcBlast.c120
-rw-r--r--src/base/wlc/wlcCom.c61
-rw-r--r--src/base/wlc/wlcNdr.c15
-rw-r--r--src/base/wln/wln.h2
-rw-r--r--src/base/wln/wlnNdr.c10
-rw-r--r--src/base/wln/wlnRetime.c57
-rw-r--r--src/bdd/extrab/extraBddMisc.c2
-rw-r--r--src/bdd/llb/llb4Nonlin.c2
-rw-r--r--src/bool/bdc/bdc.h2
-rw-r--r--src/bool/bdc/bdcCore.c79
-rw-r--r--src/bool/kit/kit.h3
-rw-r--r--src/bool/kit/kitGraph.c28
-rw-r--r--src/bool/kit/kitHop.c101
-rw-r--r--src/map/if/ifCut.c24
-rw-r--r--src/map/if/ifMap.c5
-rw-r--r--src/map/if/ifTruth.c1
-rw-r--r--src/map/mio/mio.c22
-rw-r--r--src/map/mio/mio.h1
-rw-r--r--src/map/mio/mioUtils.c93
-rw-r--r--src/map/scl/scl.c15
-rw-r--r--src/map/scl/sclBufSize.c2
-rw-r--r--src/map/scl/sclBuffer.c2
-rw-r--r--src/misc/bzlib/decompress.c4
-rw-r--r--src/misc/extra/extra.h1
-rw-r--r--src/misc/extra/extraUtilFile.c14
-rw-r--r--src/misc/extra/extraUtilPrime.c2
-rw-r--r--src/misc/extra/extraUtilReader.c5
-rw-r--r--src/misc/mem/mem.c16
-rw-r--r--src/misc/mem/mem.h1
-rw-r--r--src/misc/util/abc_global.h11
-rw-r--r--src/misc/util/utilNam.c39
-rw-r--r--src/misc/util/utilNam.h2
-rw-r--r--src/misc/util/utilSort.c204
-rw-r--r--src/misc/util/utilTruth.h392
-rw-r--r--src/misc/vec/vecHsh.h4
-rw-r--r--src/misc/vec/vecInt.h271
-rw-r--r--src/misc/vec/vecPtr.h60
-rw-r--r--src/misc/vec/vecQue.h4
-rw-r--r--src/misc/vec/vecStr.h5
-rw-r--r--src/misc/vec/vecWec.h137
-rw-r--r--src/misc/vec/vecWrd.h227
-rw-r--r--src/opt/cgt/cgtAig.c2
-rw-r--r--src/opt/dar/darBalance.c8
-rw-r--r--src/opt/dar/darScript.c7
-rw-r--r--src/opt/dau/dauDsd.c8
-rw-r--r--src/opt/fxch/FxchSCHashTable.c4
-rw-r--r--src/opt/fxu/fxuReduce.c3
-rw-r--r--src/opt/mfs/mfsDiv.c2
-rw-r--r--src/opt/sbd/sbdCut2.c6
-rw-r--r--src/opt/sfm/sfm.h1
-rw-r--r--src/opt/sfm/sfmCore.c74
-rw-r--r--src/opt/sfm/sfmInt.h3
-rw-r--r--src/opt/sfm/sfmSat.c104
-rw-r--r--src/opt/sfm/sfmWin.c12
-rw-r--r--src/proof/abs/absVta.c4
-rw-r--r--src/proof/acec/acecFadds.c30
-rw-r--r--src/proof/cec/cec.h8
-rw-r--r--src/proof/cec/cecCec.c6
-rw-r--r--src/proof/cec/cecChoice.c25
-rw-r--r--src/proof/cec/cecClass.c33
-rw-r--r--src/proof/cec/cecCore.c32
-rw-r--r--src/proof/cec/cecCorr.c2
-rw-r--r--src/proof/cec/cecInt.h11
-rw-r--r--src/proof/cec/cecMan.c1
-rw-r--r--src/proof/cec/cecSatG2.c1921
-rw-r--r--src/proof/cec/cecSim.c360
-rw-r--r--src/proof/cec/cecSolve.c7
-rw-r--r--src/proof/cec/cecSolveG.c641
-rw-r--r--src/proof/cec/cecSweep.c3
-rw-r--r--src/proof/cec/module.make3
-rw-r--r--src/proof/dch/dch.h1
-rw-r--r--src/proof/dch/dchCore.c4
-rw-r--r--src/proof/dch/dchSimSat.c4
-rw-r--r--src/proof/fra/fraSec.c24
-rw-r--r--src/proof/int/int.h2
-rw-r--r--src/proof/pdr/pdrCore.c4
-rw-r--r--src/proof/pdr/pdrIncr.c4
-rw-r--r--src/proof/pdr/pdrInv.c6
-rw-r--r--src/sat/bsat/satSolver.h18
-rw-r--r--src/sat/glucose/AbcGlucose.cpp170
-rw-r--r--src/sat/glucose/AbcGlucose.h8
-rw-r--r--src/sat/glucose/Glucose.cpp2
-rw-r--r--src/sat/glucose/Solver.h12
-rw-r--r--src/sat/glucose/SolverTypes.h12
-rw-r--r--src/sat/glucose/Vec.h3
-rw-r--r--src/sat/glucose/stdint.h1628
-rw-r--r--src/sat/glucose2/AbcGlucose2.cpp1543
-rw-r--r--src/sat/glucose2/AbcGlucose2.h118
-rw-r--r--src/sat/glucose2/AbcGlucoseCmd2.cpp149
-rw-r--r--src/sat/glucose2/Alg.h88
-rw-r--r--src/sat/glucose2/Alloc.h136
-rw-r--r--src/sat/glucose2/BoundedQueue.h114
-rw-r--r--src/sat/glucose2/CGlucose.h7
-rw-r--r--src/sat/glucose2/CGlucoseCore.h620
-rw-r--r--src/sat/glucose2/Constants.h33
-rw-r--r--src/sat/glucose2/Dimacs.h93
-rw-r--r--src/sat/glucose2/Glucose2.cpp1749
-rw-r--r--src/sat/glucose2/Heap.h163
-rw-r--r--src/sat/glucose2/Heap2.h169
-rw-r--r--src/sat/glucose2/IntTypes.h49
-rw-r--r--src/sat/glucose2/Map.h197
-rw-r--r--src/sat/glucose2/Options.h392
-rw-r--r--src/sat/glucose2/Options2.cpp95
-rw-r--r--src/sat/glucose2/ParseUtils.h155
-rw-r--r--src/sat/glucose2/Queue.h73
-rw-r--r--src/sat/glucose2/SimpSolver.h230
-rw-r--r--src/sat/glucose2/SimpSolver2.cpp781
-rw-r--r--src/sat/glucose2/Solver.h653
-rw-r--r--src/sat/glucose2/SolverTypes.h450
-rw-r--r--src/sat/glucose2/Sort.h101
-rw-r--r--src/sat/glucose2/System.h73
-rw-r--r--src/sat/glucose2/System2.cpp116
-rw-r--r--src/sat/glucose2/Vec.h152
-rw-r--r--src/sat/glucose2/XAlloc.h53
-rw-r--r--src/sat/glucose2/license32
-rw-r--r--src/sat/glucose2/module.make6
-rw-r--r--src/sat/glucose2/pstdint.h919
-rw-r--r--src/sat/satoko/utils/sdbl.h4
239 files changed, 34757 insertions, 2631 deletions
diff --git a/Makefile b/Makefile
index ee4172f5..80d21649 100644
--- a/Makefile
+++ b/Makefile
@@ -27,7 +27,7 @@ MODULES := \
src/opt/cut src/opt/fxu src/opt/fxch src/opt/rwr src/opt/mfs src/opt/sim \
src/opt/ret src/opt/fret src/opt/res src/opt/lpk src/opt/nwk src/opt/rwt \
src/opt/cgt src/opt/csw src/opt/dar src/opt/dau src/opt/dsc src/opt/sfm src/opt/sbd \
- src/sat/bsat src/sat/xsat src/sat/satoko src/sat/csat src/sat/msat src/sat/psat src/sat/cnf src/sat/bmc src/sat/glucose \
+ src/sat/bsat src/sat/xsat src/sat/satoko src/sat/csat src/sat/msat src/sat/psat src/sat/cnf src/sat/bmc src/sat/glucose src/sat/glucose2 \
src/bool/bdc src/bool/deco src/bool/dec src/bool/kit src/bool/lucky \
src/bool/rsb src/bool/rpo \
src/proof/pdr src/proof/abs src/proof/live src/proof/ssc src/proof/int \
diff --git a/abclib.dsp b/abclib.dsp
index 2cbd831f..43b46871 100644
--- a/abclib.dsp
+++ b/abclib.dsp
@@ -2366,6 +2366,122 @@ SOURCE=.\src\sat\glucose\Vec.h
SOURCE=.\src\sat\glucose\XAlloc.h
# End Source File
# End Group
+# Begin Group "glucose2"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\AbcGlucose2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\AbcGlucose2.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\AbcGlucoseCmd2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\Alg.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\Alloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\BoundedQueue.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\CGlucose.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\CGlucoseCore.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\Constants.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\Dimacs.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\Glucose2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\Heap.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\IntTypes.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\Map.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\Options.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\Options2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\ParseUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\pstdint.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\Queue.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\SimpSolver.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\SimpSolver2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\Solver.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\SolverTypes.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\Sort.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\System.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\System2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\Vec.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\glucose2\XAlloc.h
+# End Source File
+# End Group
# End Group
# Begin Group "opt"
@@ -4787,6 +4903,10 @@ SOURCE=.\src\aig\gia\giaCSat2.c
# End Source File
# Begin Source File
+SOURCE=.\src\aig\gia\giaCSat3.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\aig\gia\giaCSatOld.c
# End Source File
# Begin Source File
@@ -4799,6 +4919,10 @@ SOURCE=.\src\aig\gia\giaCut.c
# End Source File
# Begin Source File
+SOURCE=.\src\aig\gia\giaDecs.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\aig\gia\giaDeep.c
# End Source File
# Begin Source File
@@ -4943,6 +5067,14 @@ SOURCE=.\src\aig\gia\giaMini.c
# End Source File
# Begin Source File
+SOURCE=.\src\aig\gia\giaMinLut.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\aig\gia\giaMinLut2.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\aig\gia\giaMuxes.c
# End Source File
# Begin Source File
@@ -4963,6 +5095,10 @@ SOURCE=.\src\aig\gia\giaPat.c
# End Source File
# Begin Source File
+SOURCE=.\src\aig\gia\giaPat2.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\aig\gia\giaPf.c
# End Source File
# Begin Source File
@@ -4971,10 +5107,26 @@ SOURCE=.\src\aig\gia\giaQbf.c
# End Source File
# Begin Source File
+SOURCE=.\src\aig\gia\giaReshape1.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\aig\gia\giaReshape2.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\aig\gia\giaResub.c
# End Source File
# Begin Source File
+SOURCE=.\src\aig\gia\giaResub2.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\aig\gia\giaResub3.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\aig\gia\giaRetime.c
# End Source File
# Begin Source File
@@ -5039,14 +5191,6 @@ SOURCE=.\src\aig\gia\giaSim2.c
# End Source File
# Begin Source File
-SOURCE=.\src\aig\gia\giaSim4.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\src\aig\gia\giaSim5.c
-# End Source File
-# Begin Source File
-
SOURCE=.\src\aig\gia\giaSimBase.c
# End Source File
# Begin Source File
@@ -5067,6 +5211,10 @@ SOURCE=.\src\aig\gia\giaStg.c
# End Source File
# Begin Source File
+SOURCE=.\src\aig\gia\giaStoch.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\aig\gia\giaStr.c
# End Source File
# Begin Source File
@@ -5079,6 +5227,10 @@ SOURCE=.\src\aig\gia\giaSupp.c
# End Source File
# Begin Source File
+SOURCE=.\src\aig\gia\giaSupps.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\aig\gia\giaSweep.c
# End Source File
# Begin Source File
@@ -5411,14 +5563,26 @@ SOURCE=.\src\proof\cec\cecSatG.c
# End Source File
# Begin Source File
+SOURCE=.\src\proof\cec\cecSatG2.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\proof\cec\cecSeq.c
# End Source File
# Begin Source File
+SOURCE=.\src\proof\cec\cecSim.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\proof\cec\cecSolve.c
# End Source File
# Begin Source File
+SOURCE=.\src\proof\cec\cecSolveG.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\proof\cec\cecSplit.c
# End Source File
# Begin Source File
diff --git a/src/aig/gia/gia.c b/src/aig/gia/gia.c
index 7947a60e..ed6e276a 100644
--- a/src/aig/gia/gia.c
+++ b/src/aig/gia/gia.c
@@ -19,6 +19,7 @@
***********************************************************************/
#include "gia.h"
+#include "misc/util/utilTruth.h"
ABC_NAMESPACE_IMPL_START
@@ -297,6 +298,101 @@ void Gia_ManStructExperiment( Gia_Man_t * p )
Vec_PtrFree( vGias );
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_EnumFirstUnused( int * pUsed, int nVars )
+{
+ int i;
+ for ( i = 0; i < nVars; i++ )
+ if ( pUsed[i] == 0 )
+ return i;
+ return -1;
+}
+void Gia_EnumPerms_rec( int * pUsed, int nVars, int * pPerm, int nPerm, int * pCount, FILE * pFile, int nLogVars )
+{
+ int i, k, New;
+ if ( nPerm == nVars )
+ {
+ if ( pFile )
+ {
+ for ( i = 0; i < nLogVars; i++ )
+ fprintf( pFile, "%c", '0' + ((*pCount) >> (nLogVars-1-i) & 1) );
+ fprintf( pFile, " " );
+ for ( i = 0; i < nVars; i++ )
+ for ( k = 0; k < nVars; k++ )
+ fprintf( pFile, "%c", '0' + (pPerm[i] == k) );
+ fprintf( pFile, "\n" );
+ }
+ else
+ {
+ if ( *pCount < 20 )
+ {
+ printf( "%5d : ", (*pCount) );
+ for ( i = 0; i < nVars; i += 2 )
+ printf( "%d %d ", pPerm[i], pPerm[i+1] );
+ printf( "\n" );
+ }
+ }
+ (*pCount)++;
+ return;
+ }
+ New = Gia_EnumFirstUnused( pUsed, nVars );
+ assert( New >= 0 );
+ pPerm[nPerm] = New;
+ assert( pUsed[New] == 0 );
+ pUsed[New] = 1;
+ // try remaining ones
+ for ( i = 0; i < nVars; i++ )
+ {
+ if ( pUsed[i] == 1 )
+ continue;
+ pPerm[nPerm+1] = i;
+ assert( pUsed[i] == 0 );
+ pUsed[i] = 1;
+ Gia_EnumPerms_rec( pUsed, nVars, pPerm, nPerm+2, pCount, pFile, nLogVars );
+ assert( pUsed[i] == 1 );
+ pUsed[i] = 0;
+ }
+ assert( pUsed[New] == 1 );
+ pUsed[New] = 0;
+}
+void Gia_EnumPerms( int nVars )
+{
+ int nLogVars = 0, Count = 0;
+ int * pUsed = ABC_CALLOC( int, nVars );
+ int * pPerm = ABC_CALLOC( int, nVars );
+ FILE * pFile = fopen( "pairset.pla", "wb" );
+ assert( nVars % 2 == 0 );
+
+ printf( "Printing sets of pairs for %d objects:\n", nVars );
+ Gia_EnumPerms_rec( pUsed, nVars, pPerm, 0, &Count, NULL, -1 );
+ if ( Count > 20 )
+ printf( "...\n" );
+ printf( "Finished enumerating %d sets of pairs.\n", Count );
+
+ nLogVars = Abc_Base2Log( Count );
+ printf( "Need %d variables to encode %d sets.\n", nLogVars, Count );
+ Count = 0;
+ fprintf( pFile, ".i %d\n", nLogVars );
+ fprintf( pFile, ".o %d\n", nVars*nVars );
+ Gia_EnumPerms_rec( pUsed, nVars, pPerm, 0, &Count, pFile, nLogVars );
+ fprintf( pFile, ".e\n" );
+ fclose( pFile );
+ printf( "Finished dumping file \"%s\".\n", "pairset.pla" );
+
+ ABC_FREE( pUsed );
+ ABC_FREE( pPerm );
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h
index ae9835ee..5548def6 100644
--- a/src/aig/gia/gia.h
+++ b/src/aig/gia/gia.h
@@ -171,6 +171,7 @@ struct Gia_Man_t_
Vec_Int_t * vCoReqs; // CO required times
Vec_Int_t * vCoArrs; // CO arrival times
Vec_Int_t * vCoAttrs; // CO attributes
+ Vec_Int_t * vWeights; // object attributes
int And2Delay; // delay of the AND gate
float DefInArrs; // default PI arrival times
float DefOutReqs; // default PO required times
@@ -179,6 +180,7 @@ struct Gia_Man_t_
int nTravIdsAlloc; // the number of trav IDs allocated
Vec_Ptr_t * vNamesIn; // the input names
Vec_Ptr_t * vNamesOut; // the output names
+ Vec_Ptr_t * vNamesNode; // the node names
Vec_Int_t * vUserPiIds; // numbers assigned to PIs by the user
Vec_Int_t * vUserPoIds; // numbers assigned to POs by the user
Vec_Int_t * vUserFfIds; // numbers assigned to FFs by the user
@@ -214,6 +216,8 @@ struct Gia_Man_t_
Vec_Wrd_t * vSimsPo;
Vec_Int_t * vClassOld;
Vec_Int_t * vClassNew;
+ Vec_Int_t * vPats;
+ Vec_Bit_t * vPolars;
// incremental simulation
int fIncrSim;
int iNextPi;
@@ -235,6 +239,7 @@ struct Gia_Man_t_
Vec_Wrd_t * vSuppWords; // support information
Vec_Int_t vCopiesTwo; // intermediate copies
Vec_Int_t vSuppVars; // used variables
+ Vec_Int_t vVarMap; // used variables
Gia_Dat_t * pUData;
};
@@ -339,6 +344,7 @@ struct Jf_Par_t_
int fCutMin;
int fFuncDsd;
int fGenCnf;
+ int fGenLit;
int fCnfObjIds;
int fAddOrCla;
int fCnfMapping;
@@ -477,6 +483,11 @@ static inline int Gia_ObjValue( Gia_Obj_t * pObj ) {
static inline void Gia_ObjSetValue( Gia_Obj_t * pObj, int i ) { pObj->Value = i; }
static inline int Gia_ObjPhase( Gia_Obj_t * pObj ) { return pObj->fPhase; }
static inline int Gia_ObjPhaseReal( Gia_Obj_t * pObj ) { return Gia_Regular(pObj)->fPhase ^ Gia_IsComplement(pObj); }
+static inline int Gia_ObjPhaseDiff( Gia_Man_t * p, int i, int k ) { return Gia_ManObj(p, i)->fPhase ^ Gia_ManObj(p, k)->fPhase; }
+static inline char * Gia_ObjCiName( Gia_Man_t * p, int i ) { return p->vNamesIn ? (char*)Vec_PtrEntry(p->vNamesIn, i) : NULL; }
+static inline char * Gia_ObjCoName( Gia_Man_t * p, int i ) { return p->vNamesOut ? (char*)Vec_PtrEntry(p->vNamesOut, i) : NULL; }
+static inline char * Gia_ObjName( Gia_Man_t * p, int i ) { return p->vNamesNode ? (char*)Vec_PtrEntry(p->vNamesNode, i) : NULL; }
+static inline char * Gia_ObjNameObj( Gia_Man_t * p, Gia_Obj_t * pObj ) { return p->vNamesNode ? (char*)Vec_PtrEntry(p->vNamesNode, Gia_ObjId(p, pObj)) : NULL; }
static inline int Gia_ObjIsTerm( Gia_Obj_t * pObj ) { return pObj->fTerm; }
static inline int Gia_ObjIsAndOrConst0( Gia_Obj_t * pObj ) { return!pObj->fTerm; }
@@ -538,6 +549,7 @@ static inline void Gia_ObjFlipFaninC0( Gia_Obj_t * pObj ) {
static inline int Gia_ObjFaninNum( Gia_Man_t * p, Gia_Obj_t * pObj ) { if ( Gia_ObjIsMux(p, pObj) ) return 3; if ( Gia_ObjIsAnd(pObj) ) return 2; if ( Gia_ObjIsCo(pObj) ) return 1; return 0; }
static inline int Gia_ObjWhatFanin( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanin ) { if ( Gia_ObjFanin0(pObj) == pFanin ) return 0; if ( Gia_ObjFanin1(pObj) == pFanin ) return 1; if ( Gia_ObjFanin2(p, pObj) == pFanin ) return 2; assert(0); return -1; }
+static inline int Gia_ManCoDriverId( Gia_Man_t * p, int iCoIndex ) { return Gia_ObjFaninId0p(p, Gia_ManCo(p, iCoIndex)); }
static inline int Gia_ManPoIsConst( Gia_Man_t * p, int iPoIndex ) { return Gia_ObjFaninId0p(p, Gia_ManPo(p, iPoIndex)) == 0; }
static inline int Gia_ManPoIsConst0( Gia_Man_t * p, int iPoIndex ) { return Gia_ManIsConst0Lit( Gia_ObjFaninLit0p(p, Gia_ManPo(p, iPoIndex)) ); }
static inline int Gia_ManPoIsConst1( Gia_Man_t * p, int iPoIndex ) { return Gia_ManIsConst1Lit( Gia_ObjFaninLit0p(p, Gia_ManPo(p, iPoIndex)) ); }
@@ -570,6 +582,7 @@ static inline int Gia_ObjPhaseRealLit( Gia_Man_t * p, int iLit ) {
static inline int Gia_ObjLevelId( Gia_Man_t * p, int Id ) { return Vec_IntGetEntry(p->vLevels, Id); }
static inline int Gia_ObjLevel( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjLevelId( p, Gia_ObjId(p,pObj) ); }
+static inline void Gia_ObjUpdateLevelId( Gia_Man_t * p, int Id, int l ) { Vec_IntSetEntry(p->vLevels, Id, Abc_MaxInt(Vec_IntEntry(p->vLevels, Id), l)); }
static inline void Gia_ObjSetLevelId( Gia_Man_t * p, int Id, int l ) { Vec_IntSetEntry(p->vLevels, Id, l); }
static inline void Gia_ObjSetLevel( Gia_Man_t * p, Gia_Obj_t * pObj, int l ) { Gia_ObjSetLevelId( p, Gia_ObjId(p,pObj), l ); }
static inline void Gia_ObjSetCoLevel( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjIsCo(pObj) ); Gia_ObjSetLevel( p, pObj, Gia_ObjLevel(p,Gia_ObjFanin0(pObj)) ); }
@@ -610,10 +623,14 @@ static inline void Gia_ObjSetTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * p
static inline void Gia_ObjSetTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); p->pTravIds[Gia_ObjId(p, pObj)] = p->nTravIds - 1; }
static inline int Gia_ObjIsTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); return (p->pTravIds[Gia_ObjId(p, pObj)] == p->nTravIds); }
static inline int Gia_ObjIsTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); return (p->pTravIds[Gia_ObjId(p, pObj)] == p->nTravIds - 1); }
+static inline int Gia_ObjUpdateTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { if ( Gia_ObjIsTravIdCurrent(p, pObj) ) return 1; Gia_ObjSetTravIdCurrent(p, pObj); return 0; }
+static inline int Gia_ObjUpdateTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { if ( Gia_ObjIsTravIdPrevious(p, pObj) ) return 1; Gia_ObjSetTravIdPrevious(p, pObj); return 0; }
static inline void Gia_ObjSetTravIdCurrentId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); p->pTravIds[Id] = p->nTravIds; }
static inline void Gia_ObjSetTravIdPreviousId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); p->pTravIds[Id] = p->nTravIds - 1; }
static inline int Gia_ObjIsTravIdCurrentId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); return (p->pTravIds[Id] == p->nTravIds); }
static inline int Gia_ObjIsTravIdPreviousId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); return (p->pTravIds[Id] == p->nTravIds - 1); }
+static inline int Gia_ObjUpdateTravIdCurrentId( Gia_Man_t * p, int Id ) { if ( Gia_ObjIsTravIdCurrentId(p, Id) ) return 1; Gia_ObjSetTravIdCurrentId(p, Id); return 0; }
+static inline int Gia_ObjUpdateTravIdPreviousId( Gia_Man_t * p, int Id ) { if ( Gia_ObjIsTravIdPreviousId(p, Id) ) return 1; Gia_ObjSetTravIdPreviousId(p, Id); return 0; }
static inline void Gia_ManTimeClean( Gia_Man_t * p ) { int i; assert( p->vTiming != NULL ); Vec_FltFill(p->vTiming, 3*Gia_ManObjNum(p), 0); for ( i = 0; i < Gia_ManObjNum(p); i++ ) Vec_FltWriteEntry( p->vTiming, 3*i+1, (float)(ABC_INFINITY) ); }
static inline void Gia_ManTimeStart( Gia_Man_t * p ) { assert( p->vTiming == NULL ); p->vTiming = Vec_FltAlloc(0); Gia_ManTimeClean( p ); }
@@ -1067,9 +1084,11 @@ static inline void Gia_ClassUndoPair( Gia_Man_t * p, int i ) { a
#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 > 0; iObj = Gia_ObjNext(p, iObj) )
+ for ( assert(Gia_ObjIsHead(p, i) && 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 > 0; iObj = Gia_ObjNext(p, iObj) )
+#define Gia_ClassForEachObjStart( p, i, iObj, Start ) \
+ for ( assert(Gia_ObjIsHead(p, i)), iObj = Gia_ObjNext(p, Start); iObj > 0; iObj = Gia_ObjNext(p, iObj) )
static inline int Gia_ObjFoffsetId( Gia_Man_t * p, int Id ) { return Vec_IntEntry( p->vFanout, Id ); }
@@ -1149,7 +1168,13 @@ static inline int Gia_ObjCellId( Gia_Man_t * p, int iLit ) { re
for ( i = 1; (i < p->nObjs) && ((pObj) = Gia_ManObj(p, i)); i++ )
#define Gia_ManForEachObjVec( vVec, p, pObj, i ) \
for ( i = 0; (i < Vec_IntSize(vVec)) && ((pObj) = Gia_ManObj(p, Vec_IntEntry(vVec,i))); i++ )
-#define Gia_ManForEachObjVecReverse( vVec, p, pObj, i ) \
+#define Gia_ManForEachObjVecStart( vVec, p, pObj, i, Start ) \
+ for ( i = Start; (i < Vec_IntSize(vVec)) && ((pObj) = Gia_ManObj(p, Vec_IntEntry(vVec,i))); i++ )
+#define Gia_ManForEachObjVecStop( vVec, p, pObj, i, Stop ) \
+ for ( i = 0; (i < Stop) && ((pObj) = Gia_ManObj(p, Vec_IntEntry(vVec,i))); i++ )
+#define Gia_ManForEachObjVecStartStop( vVec, p, pObj, i, Start, Stop ) \
+ for ( i = Start; (i < Stop) && ((pObj) = Gia_ManObj(p, Vec_IntEntry(vVec,i))); i++ )
+#define Gia_ManForEachObjVecReverse( vVec, p, pObj, i ) \
for ( i = Vec_IntSize(vVec) - 1; (i >= 0) && ((pObj) = Gia_ManObj(p, Vec_IntEntry(vVec,i))); i-- )
#define Gia_ManForEachObjVecLit( vVec, p, pObj, fCompl, i ) \
for ( i = 0; (i < Vec_IntSize(vVec)) && ((pObj) = Gia_ManObj(p, Abc_Lit2Var(Vec_IntEntry(vVec,i)))) && (((fCompl) = Abc_LitIsCompl(Vec_IntEntry(vVec,i))),1); i++ )
@@ -1245,7 +1270,7 @@ extern Cbs_Man_t * Cbs_ManAlloc( Gia_Man_t * pGia );
extern void Cbs_ManStop( Cbs_Man_t * p );
extern int Cbs_ManSolve( Cbs_Man_t * p, Gia_Obj_t * pObj );
extern int Cbs_ManSolve2( Cbs_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pObj2 );
-extern Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pGia, int nConfs, Vec_Str_t ** pvStatus, int fVerbose );
+extern Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pGia, int nConfs, Vec_Str_t ** pvStatus, int f0Proved, int fVerbose );
extern void Cbs_ManSetConflictNum( Cbs_Man_t * p, int Num );
extern Vec_Int_t * Cbs_ReadModel( Cbs_Man_t * p );
/*=== giaCTas.c ============================================================*/
@@ -1255,6 +1280,11 @@ extern void Gia_ManPrintFanio( Gia_Man_t * pGia, int nNodes );
extern Gia_Man_t * Gia_ManDupCof( Gia_Man_t * p, int iVar );
extern Gia_Man_t * Gia_ManDupCofAllInt( Gia_Man_t * p, Vec_Int_t * vSigs, int fVerbose );
extern Gia_Man_t * Gia_ManDupCofAll( Gia_Man_t * p, int nFanLim, int fVerbose );
+/*=== giaDecs.c ============================================================*/
+extern int Gia_ResubVarNum( Vec_Int_t * vResub );
+extern word Gia_ResubToTruth6( Vec_Int_t * vResub );
+extern int Gia_ManEvalSolutionOne( Gia_Man_t * p, Vec_Wrd_t * vSims, Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vSet, int nWords, int fVerbose );
+extern Vec_Int_t * Gia_ManDeriveSolutionOne( Gia_Man_t * p, Vec_Wrd_t * vSims, Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vSet, int nWords, int Type );
/*=== giaDfs.c ============================================================*/
extern void Gia_ManCollectCis( Gia_Man_t * p, int * pNodes, int nNodes, Vec_Int_t * vSupp );
extern void Gia_ManCollectAnds_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vNodes );
@@ -1264,6 +1294,7 @@ extern Vec_Int_t * Gia_ManCollectNodesCis( Gia_Man_t * p, int * pNodes,
extern int Gia_ManSuppSize( Gia_Man_t * p, int * pNodes, int nNodes );
extern int Gia_ManConeSize( Gia_Man_t * p, int * pNodes, int nNodes );
extern Vec_Vec_t * Gia_ManLevelize( Gia_Man_t * p );
+extern Vec_Wec_t * Gia_ManLevelizeR( Gia_Man_t * p );
extern Vec_Int_t * Gia_ManOrderReverse( Gia_Man_t * p );
extern void Gia_ManCollectTfi( Gia_Man_t * p, Vec_Int_t * vRoots, Vec_Int_t * vNodes );
extern void Gia_ManCollectTfo( Gia_Man_t * p, Vec_Int_t * vRoots, Vec_Int_t * vNodes );
@@ -1272,7 +1303,7 @@ extern void Gia_ManDupRemapLiterals( Vec_Int_t * vLits, Gia_Man_t
extern void Gia_ManDupRemapEquiv( Gia_Man_t * pNew, Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupOrderDfs( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupOrderDfsChoices( Gia_Man_t * p );
-extern Gia_Man_t * Gia_ManDupOrderDfsReverse( Gia_Man_t * p );
+extern Gia_Man_t * Gia_ManDupOrderDfsReverse( Gia_Man_t * p, int fRevFans, int fRevOuts );
extern Gia_Man_t * Gia_ManDupOutputGroup( Gia_Man_t * p, int iOutStart, int iOutStop );
extern Gia_Man_t * Gia_ManDupOutputVec( Gia_Man_t * p, Vec_Int_t * vOutPres );
extern Gia_Man_t * Gia_ManDupSelectedOutputs( Gia_Man_t * p, Vec_Int_t * vOutsLeft );
@@ -1298,6 +1329,7 @@ extern Gia_Man_t * Gia_ManDupMarked( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupTimes( Gia_Man_t * p, int nTimes );
extern Gia_Man_t * Gia_ManDupDfs( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupDfsOnePo( Gia_Man_t * p, int iPo );
+extern Gia_Man_t * Gia_ManDupDfsRehash( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupCofactorVar( Gia_Man_t * p, int iVar, int Value );
extern Gia_Man_t * Gia_ManDupCofactorObj( Gia_Man_t * p, int iObj, int Value );
extern Gia_Man_t * Gia_ManDupMux( int iVar, Gia_Man_t * pCof1, Gia_Man_t * pCof0 );
@@ -1397,6 +1429,7 @@ extern void Gia_ManFanoutStart( Gia_Man_t * p );
extern void Gia_ManFanoutStop( Gia_Man_t * p );
extern void Gia_ManStaticFanoutStart( Gia_Man_t * p );
extern void Gia_ManStaticFanoutStop( Gia_Man_t * p );
+extern void Gia_ManStaticMappingFanoutStart( Gia_Man_t * p );
/*=== giaForce.c =========================================================*/
extern void For_ManExperiment( Gia_Man_t * pGia, int nIters, int fClustered, int fVerbose );
/*=== giaFrames.c =========================================================*/
@@ -1480,7 +1513,7 @@ extern void Gia_ManPrintStatsMiter( Gia_Man_t * p, int fVerbose )
extern void Gia_ManSetRegNum( Gia_Man_t * p, int nRegs );
extern void Gia_ManReportImprovement( Gia_Man_t * p, Gia_Man_t * pNew );
extern void Gia_ManPrintNpnClasses( Gia_Man_t * p );
-extern void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs );
+extern void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs );
/*=== giaMem.c ===========================================================*/
extern Gia_MmFixed_t * Gia_MmFixedStart( int nEntrySize, int nEntriesMax );
extern void Gia_MmFixedStop( Gia_MmFixed_t * p, int fVerbose );
@@ -1504,7 +1537,7 @@ extern void Mf_ManSetDefaultPars( Jf_Par_t * pPars );
extern Gia_Man_t * Mf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars );
extern void * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fMapping, int fVerbose );
/*=== giaMini.c ===========================================================*/
-extern Gia_Man_t * Gia_ManReadMiniAig( char * pFileName );
+extern Gia_Man_t * Gia_ManReadMiniAig( char * pFileName, int fGiaSimple );
extern void Gia_ManWriteMiniAig( Gia_Man_t * pGia, char * pFileName );
extern Gia_Man_t * Gia_ManReadMiniLut( char * pFileName );
extern void Gia_ManWriteMiniLut( Gia_Man_t * pGia, char * pFileName );
@@ -1557,6 +1590,15 @@ extern void Gia_ManIncrSimStart( Gia_Man_t * p, int nWords, int n
extern void Gia_ManIncrSimSet( Gia_Man_t * p, Vec_Int_t * vObjLits );
extern int Gia_ManIncrSimCheckOver( Gia_Man_t * p, int iLit0, int iLit1 );
extern int Gia_ManIncrSimCheckEqual( Gia_Man_t * p, int iLit0, int iLit1 );
+/*=== giaSimBase.c ============================================================*/
+extern Vec_Wrd_t * Gia_ManSimPatSim( Gia_Man_t * p );
+extern Vec_Wrd_t * Gia_ManSimPatSimOut( Gia_Man_t * pGia, Vec_Wrd_t * vSimsPi, int fOuts );
+extern void Gia_ManSim2ArrayOne( Vec_Wrd_t * vSimsPi, Vec_Int_t * vRes );
+extern Vec_Wec_t * Gia_ManSim2Array( Vec_Ptr_t * vSims );
+extern Vec_Wrd_t * Gia_ManArray2SimOne( Vec_Int_t * vRes );
+extern Vec_Ptr_t * Gia_ManArray2Sim( Vec_Wec_t * vRes );
+extern void Gia_ManPtrWrdDumpBin( char * pFileName, Vec_Ptr_t * p, int fVerbose );
+extern Vec_Ptr_t * Gia_ManPtrWrdReadBin( char * pFileName, int fVerbose );
/*=== giaSpeedup.c ============================================================*/
extern float Gia_ManDelayTraceLut( Gia_Man_t * p );
extern float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose );
@@ -1668,6 +1710,7 @@ extern void Gia_ManSetPhase1( Gia_Man_t * p );
extern void Gia_ManCleanPhase( Gia_Man_t * p );
extern int Gia_ManCheckCoPhase( Gia_Man_t * p );
extern int Gia_ManLevelNum( Gia_Man_t * p );
+extern int Gia_ManLevelRNum( Gia_Man_t * p );
extern Vec_Int_t * Gia_ManGetCiLevels( Gia_Man_t * p );
extern int Gia_ManSetLevels( Gia_Man_t * p, Vec_Int_t * vCiLevels );
extern Vec_Int_t * Gia_ManReverseLevel( Gia_Man_t * p );
@@ -1682,7 +1725,9 @@ extern int Gia_ObjRecognizeExor( Gia_Obj_t * pObj, Gia_Obj_t **
extern Gia_Obj_t * Gia_ObjRecognizeMux( Gia_Obj_t * pNode, Gia_Obj_t ** ppNodeT, Gia_Obj_t ** ppNodeE );
extern int Gia_ObjRecognizeMuxLits( Gia_Man_t * p, Gia_Obj_t * pNode, int * iLitT, int * iLitE );
extern int Gia_NodeMffcSize( Gia_Man_t * p, Gia_Obj_t * pNode );
+extern int Gia_NodeMffcSizeMark( Gia_Man_t * p, Gia_Obj_t * pNode );
extern int Gia_NodeMffcSizeSupp( Gia_Man_t * p, Gia_Obj_t * pNode, Vec_Int_t * vSupp );
+extern int Gia_NodeMffcMapping( Gia_Man_t * p );
extern int Gia_ManHasDangling( Gia_Man_t * p );
extern int Gia_ManMarkDangling( Gia_Man_t * p );
extern Vec_Int_t * Gia_ManGetDangling( Gia_Man_t * p );
@@ -1704,6 +1749,7 @@ extern int Gia_ManCheckSuppOverlap( Gia_Man_t * p, int iNode1, i
extern int Gia_ManCountPisWithFanout( Gia_Man_t * p );
extern int Gia_ManCountPosWithNonZeroDrivers( Gia_Man_t * p );
extern void Gia_ManUpdateCopy( Vec_Int_t * vCopy, Gia_Man_t * p );
+extern Vec_Int_t * Gia_ManComputeDistance( Gia_Man_t * p, int iObj, Vec_Int_t * vObjs, int fVerbose );
/*=== giaCTas.c ===========================================================*/
typedef struct Tas_Man_t_ Tas_Man_t;
diff --git a/src/aig/gia/giaAig.c b/src/aig/gia/giaAig.c
index dfd4a467..91a9c600 100644
--- a/src/aig/gia/giaAig.c
+++ b/src/aig/gia/giaAig.c
@@ -102,6 +102,41 @@ Gia_Man_t * Gia_ManFromAig( Aig_Man_t * p )
/**Function*************************************************************
+ Synopsis [Checks integrity of choice nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManCheckChoices_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( !pObj || !Gia_ObjIsAnd(pObj) || pObj->fPhase )
+ return;
+ pObj->fPhase = 1;
+ Gia_ManCheckChoices_rec( p, Gia_ObjFanin0(pObj) );
+ Gia_ManCheckChoices_rec( p, Gia_ObjFanin1(pObj) );
+ Gia_ManCheckChoices_rec( p, Gia_ObjSiblObj(p, Gia_ObjId(p, pObj)) );
+}
+void Gia_ManCheckChoices( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i, fFound = 0;
+ Gia_ManCleanPhase( p );
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManCheckChoices_rec( p, Gia_ObjFanin0(pObj) );
+ Gia_ManForEachAnd( p, pObj, i )
+ if ( !pObj->fPhase )
+ printf( "Object %d is dangling.\n", i ), fFound = 1;
+ if ( !fFound )
+ printf( "There are no dangling objects.\n" );
+ Gia_ManCleanPhase( p );
+}
+
+/**Function*************************************************************
+
Synopsis [Duplicates AIG in the DFS order.]
Description []
@@ -155,6 +190,7 @@ Gia_Man_t * Gia_ManFromAigChoices( Aig_Man_t * p )
Gia_ManAppendCo( pNew, Gia_ObjChild0Copy(pObj) );
Gia_ManSetRegNum( pNew, Aig_ManRegNum(p) );
//assert( Gia_ManObjNum(pNew) == Aig_ManObjNum(p) );
+ //Gia_ManCheckChoices( pNew );
return pNew;
}
diff --git a/src/aig/gia/giaAiger.c b/src/aig/gia/giaAiger.c
index c9ad28db..aafe311b 100644
--- a/src/aig/gia/giaAiger.c
+++ b/src/aig/gia/giaAiger.c
@@ -176,6 +176,7 @@ Vec_Str_t * Gia_AigerWriteLiterals( Vec_Int_t * vLits )
Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSimple, int fSkipStrash, int fCheck )
{
Gia_Man_t * pNew, * pTemp;
+ Vec_Ptr_t * vNamesIn = NULL, * vNamesOut = NULL, * vNamesRegIn = NULL, * vNamesRegOut = NULL, * vNamesNode = NULL;
Vec_Int_t * vLits = NULL, * vPoTypes = NULL;
Vec_Int_t * vNodes, * vDrivers, * vInits = NULL;
int iObj, iNode0, iNode1, fHieOnly = 0;
@@ -377,6 +378,101 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
pCur = pSymbols;
if ( pCur < (unsigned char *)pContents + nFileSize && *pCur != 'c' )
{
+ int fReadNames = 1;
+ if ( fReadNames )
+ {
+ int fError = 0;
+ while ( !fError && pCur < (unsigned char *)pContents + nFileSize && *pCur != 'c' )
+ {
+ int iTerm;
+ char * pType = (char *)pCur;
+ char * pName = NULL;
+ // check terminal type
+ if ( *pCur != 'i' && *pCur != 'o' && *pCur != 'l' && *pCur != 'n' )
+ {
+ fError = 1;
+ break;
+ }
+ // get terminal number
+ iTerm = atoi( (char *)++pCur ); while ( *pCur++ != ' ' );
+ // skip spaces
+ while ( *pCur == ' ' )
+ pCur++;
+ // skip till the end of line
+ for ( pName = (char *)pCur; *pCur && *pCur != '\n'; pCur++ );
+ if ( *pCur == '\n' )
+ *pCur = 0;
+ // save the name
+ if ( *pType == 'i' )
+ {
+ if ( vNamesIn == NULL )
+ vNamesIn = Vec_PtrAlloc( nInputs + nLatches );
+ if ( Vec_PtrSize(vNamesIn) != iTerm )
+ {
+ fError = 1;
+ break;
+ }
+ Vec_PtrPush( vNamesIn, Abc_UtilStrsav(pName) );
+ }
+ else if ( *pType == 'o' )
+ {
+ if ( vNamesOut == NULL )
+ vNamesOut = Vec_PtrAlloc( nOutputs + nLatches );
+ if ( Vec_PtrSize(vNamesOut) != iTerm )
+ {
+ fError = 1;
+ break;
+ }
+ Vec_PtrPush( vNamesOut, Abc_UtilStrsav(pName) );
+ }
+ else if ( *pType == 'l' )
+ {
+ char Buffer[1000];
+ assert( strlen(pName) < 995 );
+ sprintf( Buffer, "%s_in", pName );
+ if ( vNamesRegIn == NULL )
+ vNamesRegIn = Vec_PtrAlloc( nLatches );
+ if ( vNamesRegOut == NULL )
+ vNamesRegOut = Vec_PtrAlloc( nLatches );
+ if ( Vec_PtrSize(vNamesRegIn) != iTerm )
+ {
+ fError = 1;
+ break;
+ }
+ Vec_PtrPush( vNamesRegIn, Abc_UtilStrsav(Buffer) );
+ Vec_PtrPush( vNamesRegOut, Abc_UtilStrsav(pName) );
+ }
+ else if ( *pType == 'n' )
+ {
+ if ( Vec_IntSize(&pNew->vHTable) != 0 )
+ {
+ printf( "Structural hashing should be disabled to read internal nodes names.\n" );
+ fError = 1;
+ break;
+ }
+ if ( vNamesNode == NULL )
+ vNamesNode = Vec_PtrStart( Gia_ManObjNum(pNew) );
+ Vec_PtrWriteEntry( vNamesNode, iTerm, Abc_UtilStrsav(pName) );
+ }
+ else
+ {
+ fError = 1;
+ break;
+ }
+ pCur++;
+ }
+ if ( fError )
+ {
+ printf( "Error occurred when reading signal names. Signal names ignored.\n" );
+ if ( vNamesIn ) Vec_PtrFreeFree( vNamesIn ), vNamesIn = NULL;
+ if ( vNamesOut ) Vec_PtrFreeFree( vNamesOut ), vNamesOut = NULL;
+ if ( vNamesRegIn ) Vec_PtrFreeFree( vNamesRegIn ), vNamesRegIn = NULL;
+ if ( vNamesRegOut ) Vec_PtrFreeFree( vNamesRegOut ), vNamesRegOut = NULL;
+ if ( vNamesNode ) Vec_PtrFreeFree( vNamesNode ), vNamesNode = NULL;
+ }
+ }
+ else
+ {
int fBreakUsed = 0;
unsigned char * pCurOld = pCur;
pNew->vUserPiIds = Vec_IntStartFull( nInputs );
@@ -505,6 +601,7 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
}
Vec_IntFree( vPoNames );
}
+ }
}
@@ -636,6 +733,7 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
pCur++;
if ( (*pCur >= 'a' && *pCur <= 'z') || (*pCur >= 'A' && *pCur <= 'Z') || (*pCur >= '0' && *pCur <= '9') )
{
+ ABC_FREE( pNew->pName );
pNew->pName = Abc_UtilStrsav( (char *)pCur ); pCur += strlen(pNew->pName) + 1;
}
else
@@ -866,6 +964,39 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
Abc_Print( 0, "Structural hashing enabled while reading AIGER invalidated the mapping. Consider using \"&r -s\".\n" );
Vec_IntFreeP( &pNew->vMapping );
}
+ if ( vNamesIn && Gia_ManPiNum(pNew) != Vec_PtrSize(vNamesIn) )
+ Abc_Print( 0, "The number of inputs does not match the number of input names.\n" );
+ else if ( vNamesOut && Gia_ManPoNum(pNew) != Vec_PtrSize(vNamesOut) )
+ Abc_Print( 0, "The number of output does not match the number of output names.\n" );
+ else if ( vNamesRegOut && Gia_ManRegNum(pNew) != Vec_PtrSize(vNamesRegOut) )
+ Abc_Print( 0, "The number of inputs does not match the number of flop names.\n" );
+ else if ( vNamesIn && vNamesOut )
+ {
+ pNew->vNamesIn = vNamesIn; vNamesIn = NULL;
+ pNew->vNamesOut = vNamesOut; vNamesOut = NULL;
+ if ( vNamesRegOut )
+ {
+ Vec_PtrAppend( pNew->vNamesIn, vNamesRegOut );
+ Vec_PtrClear( vNamesRegOut );
+ Vec_PtrFree( vNamesRegOut );
+ vNamesRegOut = NULL;
+ }
+ if ( vNamesRegIn )
+ {
+ Vec_PtrAppend( pNew->vNamesOut, vNamesRegIn );
+ Vec_PtrClear( vNamesRegIn );
+ Vec_PtrFree( vNamesRegIn );
+ vNamesRegIn = NULL;
+ }
+ }
+ if ( vNamesNode && Gia_ManObjNum(pNew) != Vec_PtrSize(vNamesNode) )
+ Abc_Print( 0, "The size of the node name array does not match the number of objects. Names are not entered.\n" );
+ else if ( vNamesNode )
+ pNew->vNamesNode = vNamesNode, vNamesNode = NULL;
+ if ( vNamesIn ) Vec_PtrFreeFree( vNamesIn );
+ if ( vNamesOut ) Vec_PtrFreeFree( vNamesOut );
+ if ( vNamesRegIn ) Vec_PtrFreeFree( vNamesRegIn );
+ if ( vNamesRegOut ) Vec_PtrFreeFree( vNamesRegOut );
return pNew;
}
@@ -1197,6 +1328,14 @@ void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
Gia_ManForEachPo( p, pObj, i )
fprintf( pFile, "o%d %s\n", i, (char *)Vec_PtrEntry(p->vNamesOut, i) );
}
+ if ( p->vNamesNode && Vec_PtrSize(p->vNamesNode) != Gia_ManObjNum(p) )
+ Abc_Print( 0, "The size of the node name array does not match the number of objects. Names are not written.\n" );
+ else if ( p->vNamesNode )
+ {
+ Gia_ManForEachAnd( p, pObj, i )
+ if ( Vec_PtrEntry(p->vNamesNode, i) )
+ fprintf( pFile, "n%d %s\n", i, (char *)Vec_PtrEntry(p->vNamesNode, i) );
+ }
// write the comment
if ( fWriteNewLine )
@@ -1477,6 +1616,148 @@ void Gia_AigerWriteSimple( Gia_Man_t * pInit, char * pFileName )
fclose( pFile );
}
+
+
+/**Function*************************************************************
+
+ Synopsis [Simple AIGER reader/writer.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline unsigned Aiger_ReadUnsigned( FILE * pFile )
+{
+ unsigned x = 0, i = 0;
+ unsigned char ch;
+ while ((ch = fgetc(pFile)) & 0x80)
+ x |= (ch & 0x7f) << (7 * i++);
+ return x | (ch << (7 * i));
+}
+static inline void Aiger_WriteUnsigned( FILE * pFile, unsigned x )
+{
+ unsigned char ch;
+ while (x & ~0x7f)
+ {
+ ch = (x & 0x7f) | 0x80;
+ fputc( ch, pFile );
+ x >>= 7;
+ }
+ ch = x;
+ fputc( ch, pFile );
+}
+int * Aiger_Read( char * pFileName, int * pnObjs, int * pnIns, int * pnLats, int * pnOuts, int * pnAnds )
+{
+ int i, Temp, Value = 0, nTotal, nObjs, nIns, nLats, nOuts, nAnds, * pObjs;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ fprintf( stdout, "Aiger_Read(): Cannot open the output file \"%s\".\n", pFileName );
+ return NULL;
+ }
+ if ( fgetc(pFile) != 'a' || fgetc(pFile) != 'i' || fgetc(pFile) != 'g' )
+ {
+ fprintf( stdout, "Aiger_Read(): Can only read binary AIGER.\n" );
+ fclose( pFile );
+ return NULL;
+ }
+ if ( fscanf(pFile, "%d %d %d %d %d", &nTotal, &nIns, &nLats, &nOuts, &nAnds) != 5 )
+ {
+ fprintf( stdout, "Aiger_Read(): Cannot read the header line.\n" );
+ fclose( pFile );
+ return NULL;
+ }
+ if ( nTotal != nIns + nLats + nAnds )
+ {
+ fprintf( stdout, "The number of objects does not match.\n" );
+ fclose( pFile );
+ return NULL;
+ }
+ nObjs = 1 + nIns + 2*nLats + nOuts + nAnds;
+ pObjs = ABC_CALLOC( int, nObjs * 2 );
+ // read flop input literals
+ for ( i = 0; i < nLats; i++ )
+ {
+ while ( fgetc(pFile) != '\n' );
+ Value += fscanf( pFile, "%d", &Temp );
+ pObjs[2*(nObjs-nLats+i)+0] = Temp;
+ pObjs[2*(nObjs-nLats+i)+1] = Temp;
+ }
+ // read output literals
+ for ( i = 0; i < nOuts; i++ )
+ {
+ while ( fgetc(pFile) != '\n' );
+ Value += fscanf( pFile, "%d", &Temp );
+ pObjs[2*(nObjs-nOuts-nLats+i)+0] = Temp;
+ pObjs[2*(nObjs-nOuts-nLats+i)+1] = Temp;
+ }
+ assert( Value == nLats + nOuts );
+ // read the binary part
+ while ( fgetc(pFile) != '\n' );
+ for ( i = 0; i < nAnds; i++ )
+ {
+ int uLit = 2*(1 + nIns + nLats + i);
+ int uLit1 = uLit - Aiger_ReadUnsigned( pFile );
+ int uLit0 = uLit1 - Aiger_ReadUnsigned( pFile );
+ pObjs[2*(1+nIns+nLats+i)+0] = uLit0;
+ pObjs[2*(1+nIns+nLats+i)+1] = uLit1;
+ }
+ fclose( pFile );
+ if ( pnObjs ) *pnObjs = nObjs;
+ if ( pnIns ) *pnIns = nIns;
+ if ( pnLats ) *pnLats = nLats;
+ if ( pnOuts ) *pnOuts = nOuts;
+ if ( pnAnds ) *pnAnds = nAnds;
+ return pObjs;
+}
+void Aiger_Write( char * pFileName, int * pObjs, int nObjs, int nIns, int nLats, int nOuts, int nAnds )
+{
+ FILE * pFile = fopen( pFileName, "wb" ); int i;
+ if ( pFile == NULL )
+ {
+ fprintf( stdout, "Aiger_Write(): Cannot open the output file \"%s\".\n", pFileName );
+ return;
+ }
+ fprintf( pFile, "aig %d %d %d %d %d\n", nIns + nLats + nAnds, nIns, nLats, nOuts, nAnds );
+ for ( i = 0; i < nLats; i++ )
+ fprintf( pFile, "%d\n", pObjs[2*(nObjs-nLats+i)+0] );
+ for ( i = 0; i < nOuts; i++ )
+ fprintf( pFile, "%d\n", pObjs[2*(nObjs-nOuts-nLats+i)+0] );
+ for ( i = 0; i < nAnds; i++ )
+ {
+ int uLit = 2*(1 + nIns + nLats + i);
+ int uLit0 = pObjs[2*(1+nIns+nLats+i)+0];
+ int uLit1 = pObjs[2*(1+nIns+nLats+i)+1];
+ Aiger_WriteUnsigned( pFile, uLit - uLit1 );
+ Aiger_WriteUnsigned( pFile, uLit1 - uLit0 );
+ }
+ fprintf( pFile, "c\n" );
+ fclose( pFile );
+}
+void Aiger_Test( char * pFileNameIn, char * pFileNameOut )
+{
+ int nObjs, nIns, nLats, nOuts, nAnds, * pObjs = Aiger_Read( pFileNameIn, &nObjs, &nIns, &nLats, &nOuts, &nAnds );
+ if ( pObjs == NULL )
+ return;
+ printf( "Read input file \"%s\".\n", pFileNameIn );
+ Aiger_Write( pFileNameOut, pObjs, nObjs, nIns, nLats, nOuts, nAnds );
+ printf( "Written output file \"%s\".\n", pFileNameOut );
+ ABC_FREE( pObjs );
+}
+
+/*
+int main( int argc, char ** argv )
+{
+ if ( argc != 3 )
+ return 0;
+ Aiger_Test( argv[1], argv[2] );
+ return 1;
+}
+*/
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaCSat.c b/src/aig/gia/giaCSat.c
index 503961d4..67b62655 100644
--- a/src/aig/gia/giaCSat.c
+++ b/src/aig/gia/giaCSat.c
@@ -1034,7 +1034,7 @@ void Cbs_ManSatPrintStats( Cbs_Man_t * p )
SeeAlso []
***********************************************************************/
-Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int fVerbose )
+Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int f0Proved, int fVerbose )
{
extern void Gia_ManCollectTest( Gia_Man_t * pAig );
extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out );
@@ -1105,6 +1105,8 @@ Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
}
if ( status == 1 )
{
+ if ( f0Proved )
+ Gia_ManPatchCoDriver( pAig, i, 0 );
p->nSatUnsat++;
p->nConfUnsat += p->Pars.nBTThis;
p->timeSatUnsat += Abc_Clock() - clk;
diff --git a/src/aig/gia/giaCSat3.c b/src/aig/gia/giaCSat3.c
new file mode 100644
index 00000000..c34c84ca
--- /dev/null
+++ b/src/aig/gia/giaCSat3.c
@@ -0,0 +1,1365 @@
+/**CFile****************************************************************
+
+ FileName [giaCSat.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [A simple circuit-based solver.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaCSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Cbs3_Par_t_ Cbs3_Par_t;
+struct Cbs3_Par_t_
+{
+ // conflict limits
+ int nBTLimit; // limit on the number of conflicts
+ int nJustLimit; // limit on the size of justification queue
+ int nRestLimit; // limit on the number of restarts
+ // current parameters
+ int nBTThis; // number of conflicts
+ int nJustThis; // max size of the frontier
+ int nBTTotal; // total number of conflicts
+ int nJustTotal; // total size of the frontier
+ // other
+ int fVerbose;
+};
+
+typedef struct Cbs3_Que_t_ Cbs3_Que_t;
+struct Cbs3_Que_t_
+{
+ int iHead; // beginning of the queue
+ int iTail; // end of the queue
+ int nSize; // allocated size
+ int * pData; // nodes stored in the queue
+};
+
+typedef struct Cbs3_Man_t_ Cbs3_Man_t;
+struct Cbs3_Man_t_
+{
+ Cbs3_Par_t Pars; // parameters
+ Gia_Man_t * pAig; // AIG manager
+ Cbs3_Que_t pProp; // propagation queue
+ Cbs3_Que_t pJust; // justification queue
+ Cbs3_Que_t pClauses; // clause queue
+ Vec_Int_t * vModel; // satisfying assignment
+ Vec_Int_t * vTemp; // temporary storage
+ // circuit structure
+ int nVars;
+ int nVarsAlloc;
+ int var_inc;
+ Vec_Int_t vMap;
+ Vec_Int_t vRef;
+ Vec_Int_t vFans;
+ Vec_Wec_t vImps;
+ // internal data
+ Vec_Str_t vAssign;
+ Vec_Str_t vMark;
+ Vec_Int_t vLevReason;
+ Vec_Int_t vActs;
+ Vec_Int_t vWatches;
+ Vec_Int_t vWatchUpds;
+ // SAT calls statistics
+ int nSatUnsat; // the number of proofs
+ int nSatSat; // the number of failure
+ int nSatUndec; // the number of timeouts
+ int nSatTotal; // the number of calls
+ // conflicts
+ int nConfUnsat; // conflicts in unsat problems
+ int nConfSat; // conflicts in sat problems
+ int nConfUndec; // conflicts in undec problems
+ // runtime stats
+ abctime timeJFront;
+ abctime timeSatLoad; // SAT solver loading time
+ abctime timeSatUnsat; // unsat
+ abctime timeSatSat; // sat
+ abctime timeSatUndec; // undecided
+ abctime timeTotal; // total runtime
+ // other statistics
+ int nPropCalls[3];
+ int nFails[2];
+ int nClauseConf;
+ int nDecs;
+};
+
+static inline int Cbs3_VarUnused( Cbs3_Man_t * p, int iVar ) { return Vec_IntEntry(&p->vLevReason, 3*iVar) == -1; }
+static inline void Cbs3_VarSetUnused( Cbs3_Man_t * p, int iVar ) { Vec_IntWriteEntry(&p->vLevReason, 3*iVar, -1); }
+
+static inline int Cbs3_VarMark0( Cbs3_Man_t * p, int iVar ) { return Vec_StrEntry(&p->vMark, iVar); }
+static inline void Cbs3_VarSetMark0( Cbs3_Man_t * p, int iVar, int Value ) { Vec_StrWriteEntry(&p->vMark, iVar, (char)Value); }
+
+static inline int Cbs3_VarIsAssigned( Cbs3_Man_t * p, int iVar ) { return Vec_StrEntry(&p->vAssign, iVar) < 2; }
+static inline void Cbs3_VarUnassign( Cbs3_Man_t * p, int iVar ) { assert( Cbs3_VarIsAssigned(p, iVar)); Vec_StrWriteEntry(&p->vAssign, iVar, (char)(2+Vec_StrEntry(&p->vAssign, iVar))); Cbs3_VarSetUnused(p, iVar); }
+
+static inline int Cbs3_VarValue( Cbs3_Man_t * p, int iVar ) { return Vec_StrEntry(&p->vAssign, iVar); }
+static inline void Cbs3_VarSetValue( Cbs3_Man_t * p, int iVar, int v ) { assert( !Cbs3_VarIsAssigned(p, iVar)); Vec_StrWriteEntry(&p->vAssign, iVar, (char)v); }
+
+static inline int Cbs3_VarLit0( Cbs3_Man_t * p, int iVar ) { return Vec_IntEntry( &p->vFans, Abc_Var2Lit(iVar, 0) ); }
+static inline int Cbs3_VarLit1( Cbs3_Man_t * p, int iVar ) { return Vec_IntEntry( &p->vFans, Abc_Var2Lit(iVar, 1) ); }
+static inline int Cbs3_VarIsPi( Cbs3_Man_t * p, int iVar ) { return Vec_IntEntry( &p->vFans, Abc_Var2Lit(iVar, 0) ) == 0; }
+static inline int Cbs3_VarIsJust( Cbs3_Man_t * p, int iVar ) { int * pLits = Vec_IntEntryP(&p->vFans, Abc_Var2Lit(iVar, 0)); return pLits[0] > 0 && Cbs3_VarValue(p, Abc_Lit2Var(pLits[0])) >= 2 && Cbs3_VarValue(p, Abc_Lit2Var(pLits[1])) >= 2; }
+
+static inline int Cbs3_VarDecLevel( Cbs3_Man_t * p, int iVar ) { assert( !Cbs3_VarUnused(p, iVar) ); return Vec_IntEntry(&p->vLevReason, 3*iVar); }
+static inline int Cbs3_VarReason0( Cbs3_Man_t * p, int iVar ) { assert( !Cbs3_VarUnused(p, iVar) ); return Vec_IntEntry(&p->vLevReason, 3*iVar+1); }
+static inline int Cbs3_VarReason1( Cbs3_Man_t * p, int iVar ) { assert( !Cbs3_VarUnused(p, iVar) ); return Vec_IntEntry(&p->vLevReason, 3*iVar+2); }
+static inline int * Cbs3_VarReasonP( Cbs3_Man_t * p, int iVar ) { assert( !Cbs3_VarUnused(p, iVar) ); return Vec_IntEntryP(&p->vLevReason, 3*iVar+1); }
+static inline int Cbs3_ClauseDecLevel( Cbs3_Man_t * p, int hClause ) { return Cbs3_VarDecLevel( p, p->pClauses.pData[hClause] ); }
+
+static inline int Cbs3_ClauseSize( Cbs3_Man_t * p, int hClause ) { return p->pClauses.pData[hClause]; }
+static inline int * Cbs3_ClauseLits( Cbs3_Man_t * p, int hClause ) { return p->pClauses.pData+hClause+1; }
+static inline int Cbs3_ClauseLit( Cbs3_Man_t * p, int hClause, int i ) { return p->pClauses.pData[hClause+1+i]; }
+static inline int * Cbs3_ClauseNext1p( Cbs3_Man_t * p, int hClause ) { return p->pClauses.pData+hClause+Cbs3_ClauseSize(p, hClause)+2; }
+
+static inline void Cbs3_ClauseSetSize( Cbs3_Man_t * p, int hClause, int x ) { p->pClauses.pData[hClause] = x; }
+static inline void Cbs3_ClauseSetLit( Cbs3_Man_t * p, int hClause, int i, int x ) { p->pClauses.pData[hClause+i+1] = x; }
+static inline void Cbs3_ClauseSetNext( Cbs3_Man_t * p, int hClause, int n, int x ){ p->pClauses.pData[hClause+Cbs3_ClauseSize(p, hClause)+1+n] = x; }
+
+
+#define Cbs3_QueForEachEntry( Que, iObj, i ) \
+ for ( i = (Que).iHead; (i < (Que).iTail) && ((iObj) = (Que).pData[i]); i++ )
+
+#define Cbs3_ClauseForEachEntry( p, hClause, iObj, i ) \
+ for ( i = 1; i <= Cbs3_ClauseSize(p, hClause) && (iObj = (p)->pClauses.pData[hClause+i]); i++ )
+#define Cbs3_ClauseForEachEntry1( p, hClause, iObj, i ) \
+ for ( i = 2; i <= Cbs3_ClauseSize(p, hClause) && (iObj = (p)->pClauses.pData[hClause+i]); i++ )
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Sets default values of the parameters.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cbs3_SetDefaultParams( Cbs3_Par_t * pPars )
+{
+ memset( pPars, 0, sizeof(Cbs3_Par_t) );
+ pPars->nBTLimit = 1000; // limit on the number of conflicts
+ pPars->nJustLimit = 500; // limit on the size of justification queue
+ pPars->nRestLimit = 10; // limit on the number of restarts
+ pPars->fVerbose = 1; // print detailed statistics
+}
+void Cbs3_ManSetConflictNum( Cbs3_Man_t * p, int Num )
+{
+ p->Pars.nBTLimit = Num;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Cbs3_Man_t * Cbs3_ManAlloc( Gia_Man_t * pGia )
+{
+ Cbs3_Man_t * p;
+ p = ABC_CALLOC( Cbs3_Man_t, 1 );
+ p->pProp.nSize = p->pJust.nSize = p->pClauses.nSize = 10000;
+ p->pProp.pData = ABC_ALLOC( int, p->pProp.nSize );
+ p->pJust.pData = ABC_ALLOC( int, p->pJust.nSize );
+ p->pClauses.pData = ABC_ALLOC( int, p->pClauses.nSize );
+ p->pClauses.iHead = p->pClauses.iTail = 1;
+ p->vModel = Vec_IntAlloc( 1000 );
+ p->vTemp = Vec_IntAlloc( 1000 );
+ p->pAig = pGia;
+ Cbs3_SetDefaultParams( &p->Pars );
+ // circuit structure
+ Vec_IntPush( &p->vMap, -1 );
+ Vec_IntPush( &p->vRef, -1 );
+ Vec_IntPushTwo( &p->vFans, -1, -1 );
+ Vec_WecPushLevel( &p->vImps );
+ Vec_WecPushLevel( &p->vImps );
+ p->nVars = 1;
+ // internal data
+ p->nVarsAlloc = 1000;
+ Vec_StrFill( &p->vAssign, p->nVarsAlloc, 2 );
+ Vec_StrFill( &p->vMark, p->nVarsAlloc, 0 );
+ Vec_IntFill( &p->vLevReason, 3*p->nVarsAlloc, -1 );
+ Vec_IntFill( &p->vActs, p->nVarsAlloc, 0 );
+ Vec_IntFill( &p->vWatches, 2*p->nVarsAlloc, 0 );
+ Vec_IntGrow( &p->vWatchUpds, 1000 );
+ return p;
+}
+static inline void Cbs3_ManReset( Cbs3_Man_t * p )
+{
+ assert( p->nVars == Vec_IntSize(&p->vMap) );
+ Vec_IntShrink( &p->vMap, 1 );
+ Vec_IntShrink( &p->vRef, 1 );
+ Vec_IntShrink( &p->vFans, 2 );
+ Vec_WecShrink( &p->vImps, 2 );
+ p->nVars = 1;
+}
+static inline void Cbs3_ManGrow( Cbs3_Man_t * p )
+{
+ if ( p->nVarsAlloc < p->nVars )
+ {
+ p->nVarsAlloc = 2*p->nVars;
+ Vec_StrFill( &p->vAssign, p->nVarsAlloc, 2 );
+ Vec_StrFill( &p->vMark, p->nVarsAlloc, 0 );
+ Vec_IntFill( &p->vLevReason, 3*p->nVarsAlloc, -1 );
+ Vec_IntFill( &p->vActs, p->nVarsAlloc, 0 );
+ Vec_IntFill( &p->vWatches, 2*p->nVarsAlloc, 0 );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cbs3_ManStop( Cbs3_Man_t * p )
+{
+ // circuit structure
+ Vec_IntErase( &p->vMap );
+ Vec_IntErase( &p->vRef );
+ Vec_IntErase( &p->vFans );
+ Vec_WecErase( &p->vImps );
+ // internal data
+ Vec_StrErase( &p->vAssign );
+ Vec_StrErase( &p->vMark );
+ Vec_IntErase( &p->vLevReason );
+ Vec_IntErase( &p->vActs );
+ Vec_IntErase( &p->vWatches );
+ Vec_IntErase( &p->vWatchUpds );
+ Vec_IntFree( p->vModel );
+ Vec_IntFree( p->vTemp );
+ ABC_FREE( p->pClauses.pData );
+ ABC_FREE( p->pProp.pData );
+ ABC_FREE( p->pJust.pData );
+ ABC_FREE( p );
+}
+int Cbs3_ManMemory( Cbs3_Man_t * p )
+{
+ int nMem = sizeof(Cbs3_Man_t);
+ nMem += (int)Vec_IntMemory( &p->vMap );
+ nMem += (int)Vec_IntMemory( &p->vRef );
+ nMem += (int)Vec_IntMemory( &p->vFans );
+ nMem += (int)Vec_WecMemory( &p->vImps );
+ nMem += (int)Vec_StrMemory( &p->vAssign );
+ nMem += (int)Vec_StrMemory( &p->vMark );
+ nMem += (int)Vec_IntMemory( &p->vActs );
+ nMem += (int)Vec_IntMemory( &p->vWatches );
+ nMem += (int)Vec_IntMemory( &p->vWatchUpds );
+ nMem += (int)Vec_IntMemory( p->vModel );
+ nMem += (int)Vec_IntMemory( p->vTemp );
+ nMem += 4*p->pClauses.nSize;
+ nMem += 4*p->pProp.nSize;
+ nMem += 4*p->pJust.nSize;
+ return nMem;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns satisfying assignment.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Cbs3_ReadModel( Cbs3_Man_t * p )
+{
+ return p->vModel;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Activity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+//#define USE_ACTIVITY
+
+#ifdef USE_ACTIVITY
+static inline void Cbs3_ActReset( Cbs3_Man_t * p )
+{
+ int i, * pAct = Vec_IntArray(&p->vActs);
+ for ( i = 0; i < p->nVars; i++ )
+ pAct[i] = (1 << 10);
+ p->var_inc = (1 << 5);
+}
+static inline void Cbs3_ActRescale( Cbs3_Man_t * p )
+{
+ int i, * pAct = Vec_IntArray(&p->vActs);
+ for ( i = 0; i < p->nVars; i++ )
+ pAct[i] >>= 19;
+ p->var_inc >>= 19;
+ p->var_inc = Abc_MaxInt( (unsigned)p->var_inc, (1<<5) );
+}
+static inline void Cbs3_ActBumpVar( Cbs3_Man_t * p, int iVar )
+{
+ int * pAct = Vec_IntArray(&p->vActs);
+ pAct[iVar] += p->var_inc;
+ if ((unsigned)pAct[iVar] & 0x80000000)
+ Cbs3_ActRescale(p);
+}
+static inline void Cbs3_ActDecay( Cbs3_Man_t * p )
+{
+ p->var_inc += (p->var_inc >> 4);
+}
+#else
+static inline void Cbs3_ActReset( Cbs3_Man_t * p ) {}
+static inline void Cbs3_ActRescale( Cbs3_Man_t * p ) {}
+static inline void Cbs3_ActBumpVar( Cbs3_Man_t * p, int iVar ) {}
+static inline void Cbs3_ActDecay( Cbs3_Man_t * p ) {}
+#endif
+
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if the solver is out of limits.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cbs3_ManCheckLimits( Cbs3_Man_t * p )
+{
+ p->nFails[0] += p->Pars.nJustThis > p->Pars.nJustLimit;
+ p->nFails[1] += p->Pars.nBTThis > p->Pars.nBTLimit;
+ return p->Pars.nJustThis > p->Pars.nJustLimit || p->Pars.nBTThis > p->Pars.nBTLimit;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Saves the satisfying assignment as an array of literals.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Cbs3_ManSaveModel( Cbs3_Man_t * p, Vec_Int_t * vCex )
+{
+ int i, iLit;
+ Vec_IntClear( vCex );
+ p->pProp.iHead = 0;
+ Cbs3_QueForEachEntry( p->pProp, iLit, i )
+ if ( Cbs3_VarIsPi(p, Abc_Lit2Var(iLit)) )
+ Vec_IntPush( vCex, Abc_Lit2LitV(Vec_IntArray(&p->vMap), iLit)-2 );
+}
+static inline void Cbs3_ManSaveModelAll( Cbs3_Man_t * p, Vec_Int_t * vCex )
+{
+ int i, iLit;
+ Vec_IntClear( vCex );
+ p->pProp.iHead = 0;
+ Cbs3_QueForEachEntry( p->pProp, iLit, i )
+ {
+ int iVar = Abc_Lit2Var(iLit);
+ Vec_IntPush( vCex, Abc_Var2Lit(iVar, !Cbs3_VarValue(p, iVar)) );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cbs3_QueIsEmpty( Cbs3_Que_t * p )
+{
+ return p->iHead == p->iTail;
+}
+static inline int Cbs3_QueSize( Cbs3_Que_t * p )
+{
+ return p->iTail - p->iHead;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Cbs3_QuePush( Cbs3_Que_t * p, int iObj )
+{
+ if ( p->iTail == p->nSize )
+ {
+ p->nSize *= 2;
+ p->pData = ABC_REALLOC( int, p->pData, p->nSize );
+ }
+ p->pData[p->iTail++] = iObj;
+}
+static inline void Cbs3_QueGrow( Cbs3_Que_t * p, int Plus )
+{
+ if ( p->iTail + Plus > p->nSize )
+ {
+ p->nSize *= 2;
+ p->pData = ABC_REALLOC( int, p->pData, p->nSize );
+ }
+ assert( p->iTail + Plus <= p->nSize );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if the object in the queue.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cbs3_QueHasNode( Cbs3_Que_t * p, int iObj )
+{
+ int i, iTemp;
+ Cbs3_QueForEachEntry( *p, iTemp, i )
+ if ( iTemp == iObj )
+ return 1;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Cbs3_QueStore( Cbs3_Que_t * p, int * piHeadOld, int * piTailOld )
+{
+ int i;
+ *piHeadOld = p->iHead;
+ *piTailOld = p->iTail;
+ for ( i = *piHeadOld; i < *piTailOld; i++ )
+ Cbs3_QuePush( p, p->pData[i] );
+ p->iHead = *piTailOld;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Cbs3_QueRestore( Cbs3_Que_t * p, int iHeadOld, int iTailOld )
+{
+ p->iHead = iHeadOld;
+ p->iTail = iTailOld;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find variable with the highest ID.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cbs3_ManDecide( Cbs3_Man_t * p )
+{
+ int i, iObj, iObjMax = 0;
+#ifdef USE_ACTIVITY
+ Cbs3_QueForEachEntry( p->pJust, iObj, i )
+ if ( iObjMax == 0 ||
+ Vec_IntEntry(&p->vActs, iObjMax) < Vec_IntEntry(&p->vActs, iObj) ||
+ (Vec_IntEntry(&p->vActs, iObjMax) == Vec_IntEntry(&p->vActs, iObj) && Vec_IntEntry(&p->vMap, iObjMax) < Vec_IntEntry(&p->vMap, iObj)) )
+ iObjMax = iObj;
+#else
+ Cbs3_QueForEachEntry( p->pJust, iObj, i )
+// if ( iObjMax == 0 || iObjMax < iObj )
+ if ( iObjMax == 0 || Vec_IntEntry(&p->vMap, iObjMax) < Vec_IntEntry(&p->vMap, iObj) )
+ iObjMax = iObj;
+#endif
+ return iObjMax;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Cbs3_ManCancelUntil( Cbs3_Man_t * p, int iBound )
+{
+ int i, iLit;
+ assert( iBound <= p->pProp.iTail );
+ p->pProp.iHead = iBound;
+ Cbs3_QueForEachEntry( p->pProp, iLit, i )
+ Cbs3_VarUnassign( p, Abc_Lit2Var(iLit) );
+ p->pProp.iTail = iBound;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Assigns the variables a value.]
+
+ Description [Returns 1 if conflict; 0 if no conflict.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Cbs3_ManAssign( Cbs3_Man_t * p, int iLit, int Level, int iRes0, int iRes1 )
+{
+ int iObj = Abc_Lit2Var(iLit);
+ assert( Cbs3_VarUnused(p, iObj) );
+ assert( !Cbs3_VarIsAssigned(p, iObj) );
+ Cbs3_VarSetValue( p, iObj, !Abc_LitIsCompl(iLit) );
+ Cbs3_QuePush( &p->pProp, iLit );
+ Vec_IntWriteEntry( &p->vLevReason, 3*iObj, Level );
+ Vec_IntWriteEntry( &p->vLevReason, 3*iObj+1, iRes0 );
+ Vec_IntWriteEntry( &p->vLevReason, 3*iObj+2, iRes1 );
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Prints conflict clause.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Cbs3_ManPrintClause( Cbs3_Man_t * p, int Level, int hClause )
+{
+ int i, iLit;
+ assert( Cbs3_QueIsEmpty( &p->pClauses ) );
+ printf( "Level %2d : ", Level );
+ Cbs3_ClauseForEachEntry( p, hClause, iLit, i )
+ printf( "%c%d ", Abc_LitIsCompl(iLit) ? '-':'+', Abc_Lit2Var(iLit) );
+// printf( "%d=%d(%d) ", iObj, Cbs3_VarValue(p, Abc_Lit2Var(iLit)), Cbs3_VarDecLevel(p, Abc_Lit2Var(iLit)) );
+ printf( "\n" );
+}
+static inline void Cbs3_ManPrintCube( Cbs3_Man_t * p, int Level, int hClause )
+{
+ int i, iObj;
+ assert( Cbs3_QueIsEmpty( &p->pClauses ) );
+ printf( "Level %2d : ", Level );
+ Cbs3_ClauseForEachEntry( p, hClause, iObj, i )
+ printf( "%c%d ", Cbs3_VarValue(p, iObj)? '+':'-', iObj );
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Finalized the clause.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Cbs3_ManCleanWatch( Cbs3_Man_t * p )
+{
+ int i, iLit;
+ Vec_IntForEachEntry( &p->vWatchUpds, iLit, i )
+ Vec_IntWriteEntry( &p->vWatches, iLit, 0 );
+ Vec_IntClear( &p->vWatchUpds );
+ //Vec_IntForEachEntry( &p->vWatches, iLit, i )
+ // assert( iLit == 0 );
+}
+static inline void Cbs3_ManWatchClause( Cbs3_Man_t * p, int hClause, int Lit )
+{
+ int * pLits = Cbs3_ClauseLits( p, hClause );
+ int * pPlace = Vec_IntEntryP( &p->vWatches, Abc_LitNot(Lit) );
+ if ( *pPlace == 0 )
+ Vec_IntPush( &p->vWatchUpds, Abc_LitNot(Lit) );
+/*
+ if ( pClause->pLits[0] == Lit )
+ pClause->pNext0 = p->pWatches[lit_neg(Lit)];
+ else
+ {
+ assert( pClause->pLits[1] == Lit );
+ pClause->pNext1 = p->pWatches[lit_neg(Lit)];
+ }
+ p->pWatches[lit_neg(Lit)] = pClause;
+*/
+ assert( Lit == pLits[0] || Lit == pLits[1] );
+ Cbs3_ClauseSetNext( p, hClause, Lit == pLits[1], *pPlace );
+ *pPlace = hClause;
+}
+static inline int Cbs3_QueFinish( Cbs3_Man_t * p, int Level )
+{
+ Cbs3_Que_t * pQue = &(p->pClauses);
+ int i, iObj, hClauseC, hClause = pQue->iHead, Size = pQue->iTail - pQue->iHead - 1;
+ assert( pQue->iHead+1 < pQue->iTail );
+ Cbs3_ClauseSetSize( p, pQue->iHead, Size );
+ hClauseC = pQue->iHead = pQue->iTail;
+ //printf( "Adding cube: " ); Cbs3_ManPrintCube(p, Level, hClause);
+ if ( Size == 1 )
+ return hClause;
+ // create watched clause
+ pQue->iHead = hClause;
+ Cbs3_QueForEachEntry( p->pClauses, iObj, i )
+ {
+ if ( i == hClauseC )
+ break;
+ else if ( i == hClause ) // nlits
+ Cbs3_QuePush( pQue, iObj );
+ else // literals
+ Cbs3_QuePush( pQue, Abc_Var2Lit(iObj, Cbs3_VarValue(p, iObj)) ); // complement
+ }
+ Cbs3_QuePush( pQue, 0 ); // next0
+ Cbs3_QuePush( pQue, 0 ); // next1
+ pQue->iHead = pQue->iTail;
+ Cbs3_ManWatchClause( p, hClauseC, Cbs3_ClauseLit(p, hClauseC, 0) );
+ Cbs3_ManWatchClause( p, hClauseC, Cbs3_ClauseLit(p, hClauseC, 1) );
+ //printf( "Adding clause %d: ", hClauseC ); Cbs3_ManPrintClause(p, Level, hClauseC);
+ Cbs3_ActDecay( p );
+ return hClause;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns conflict clause.]
+
+ Description [Performs conflict analysis.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cbs3_ManDeriveReason( Cbs3_Man_t * p, int Level )
+{
+ Cbs3_Que_t * pQue = &(p->pClauses);
+ int i, k, iObj, iLitLevel, * pReason;
+ assert( pQue->pData[pQue->iHead] == 0 );
+ assert( pQue->pData[pQue->iHead+1] == 0 );
+ assert( pQue->iHead + 2 < pQue->iTail );
+ //for ( i = pQue->iHead + 2; i < pQue->iTail; i++ )
+ // assert( !Cbs3_VarMark0(p, pQue->pData[i]) );
+ // compact literals
+ Vec_IntClear( p->vTemp );
+ for ( i = k = pQue->iHead + 2; i < pQue->iTail; i++ )
+ {
+ iObj = pQue->pData[i];
+ if ( Cbs3_VarMark0(p, iObj) ) // unassigned - seen again
+ continue;
+ //if ( Vec_IntEntry(&p->vActivity, iObj) == 0 )
+ // Vec_IntPush( &p->vActStore, iObj );
+ //Vec_IntAddToEntry( &p->vActivity, iObj, 1 );
+ // assigned - seen first time
+ Cbs3_VarSetMark0(p, iObj, 1);
+ Cbs3_ActBumpVar(p, iObj);
+ Vec_IntPush( p->vTemp, iObj );
+ // check decision level
+ iLitLevel = Cbs3_VarDecLevel( p, iObj );
+ if ( iLitLevel < Level )
+ {
+ pQue->pData[k++] = iObj;
+ continue;
+ }
+ assert( iLitLevel == Level );
+ pReason = Cbs3_VarReasonP( p, iObj );
+ if ( pReason[0] == 0 && pReason[1] == 0 ) // no reason
+ {
+ assert( pQue->pData[pQue->iHead+1] == 0 );
+ pQue->pData[pQue->iHead+1] = iObj;
+ }
+ else if ( pReason[0] != 0 ) // circuit reason
+ {
+ Cbs3_QuePush( pQue, pReason[0] );
+ if ( pReason[1] )
+ Cbs3_QuePush( pQue, pReason[1] );
+ }
+ else // clause reason
+ {
+ int i, * pLits, nLits = Cbs3_ClauseSize( p, pReason[1] );
+ assert( pReason[1] );
+ Cbs3_QueGrow( pQue, nLits );
+ pLits = Cbs3_ClauseLits( p, pReason[1] );
+ assert( iObj == Abc_Lit2Var(pLits[0]) );
+ for ( i = 1; i < nLits; i++ )
+ Cbs3_QuePush( pQue, Abc_Lit2Var(pLits[i]) );
+ }
+ }
+ assert( pQue->pData[pQue->iHead] == 0 );
+ assert( pQue->pData[pQue->iHead+1] != 0 );
+ pQue->iTail = k;
+ // clear the marks
+ Vec_IntForEachEntry( p->vTemp, iObj, i )
+ Cbs3_VarSetMark0(p, iObj, 0);
+ return Cbs3_QueFinish( p, Level );
+}
+static inline int Cbs3_ManAnalyze( Cbs3_Man_t * p, int Level, int iVar, int iFan0, int iFan1 )
+{
+ Cbs3_Que_t * pQue = &(p->pClauses);
+ assert( Cbs3_VarIsAssigned(p, iVar) );
+ assert( Cbs3_QueIsEmpty( pQue ) );
+ Cbs3_QuePush( pQue, 0 );
+ Cbs3_QuePush( pQue, 0 );
+ if ( iFan0 ) // circuit conflict
+ {
+ assert( Cbs3_VarIsAssigned(p, iFan0) );
+ assert( iFan1 == 0 || Cbs3_VarIsAssigned(p, iFan1) );
+ Cbs3_QuePush( pQue, iVar );
+ Cbs3_QuePush( pQue, iFan0 );
+ if ( iFan1 )
+ Cbs3_QuePush( pQue, iFan1 );
+ }
+ else // clause conflict
+ {
+ int i, * pLits, nLits = Cbs3_ClauseSize( p, iFan1 );
+ assert( iFan1 );
+ Cbs3_QueGrow( pQue, nLits );
+ pLits = Cbs3_ClauseLits( p, iFan1 );
+ assert( iVar == Abc_Lit2Var(pLits[0]) );
+ assert( Cbs3_VarValue(p, iVar) == Abc_LitIsCompl(pLits[0]) );
+ for ( i = 0; i < nLits; i++ )
+ Cbs3_QuePush( pQue, Abc_Lit2Var(pLits[i]) );
+ }
+ return Cbs3_ManDeriveReason( p, Level );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Propagate one assignment.]
+
+ Description [Returns handle of the conflict clause, if conflict occurs.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cbs3_ManPropagateClauses( Cbs3_Man_t * p, int Level, int Lit )
+{
+ int i, Value, Cur, LitF = Abc_LitNot(Lit);
+ int * pPrev = Vec_IntEntryP( &p->vWatches, Lit );
+ //for ( pCur = p->pWatches[Lit]; pCur; pCur = *ppPrev )
+ for ( Cur = *pPrev; Cur; Cur = *pPrev )
+ {
+ int nLits = Cbs3_ClauseSize( p, Cur );
+ int * pLits = Cbs3_ClauseLits( p, Cur );
+ p->nPropCalls[1]++;
+//printf( " Watching literal %c%d on level %d.\n", Abc_LitIsCompl(Lit) ? '-':'+', Abc_Lit2Var(Lit), Level );
+ // make sure the false literal is in the second literal of the clause
+ //if ( pCur->pLits[0] == LitF )
+ if ( pLits[0] == LitF )
+ {
+ //pCur->pLits[0] = pCur->pLits[1];
+ pLits[0] = pLits[1];
+ //pCur->pLits[1] = LitF;
+ pLits[1] = LitF;
+ //pTemp = pCur->pNext0;
+ //pCur->pNext0 = pCur->pNext1;
+ //pCur->pNext1 = pTemp;
+ ABC_SWAP( int, pLits[nLits], pLits[nLits+1] );
+ }
+ //assert( pCur->pLits[1] == LitF );
+ assert( pLits[1] == LitF );
+
+ // if the first literal is true, the clause is satisfied
+ //if ( pCur->pLits[0] == p->pAssigns[lit_var(pCur->pLits[0])] )
+ if ( Cbs3_VarValue(p, Abc_Lit2Var(pLits[0])) == !Abc_LitIsCompl(pLits[0]) )
+ {
+ //ppPrev = &pCur->pNext1;
+ pPrev = Cbs3_ClauseNext1p(p, Cur);
+ continue;
+ }
+
+ // look for a new literal to watch
+ for ( i = 2; i < nLits; i++ )
+ {
+ // skip the case when the literal is false
+ //if ( lit_neg(pCur->pLits[i]) == p->pAssigns[lit_var(pCur->pLits[i])] )
+ if ( Cbs3_VarValue(p, Abc_Lit2Var(pLits[i])) == Abc_LitIsCompl(pLits[i]) )
+ continue;
+ // the literal is either true or unassigned - watch it
+ //pCur->pLits[1] = pCur->pLits[i];
+ //pCur->pLits[i] = LitF;
+ pLits[1] = pLits[i];
+ pLits[i] = LitF;
+ // remove this clause from the watch list of Lit
+ //*ppPrev = pCur->pNext1;
+ *pPrev = *Cbs3_ClauseNext1p(p, Cur);
+ // add this clause to the watch list of pCur->pLits[i] (now it is pCur->pLits[1])
+ //Intb_ManWatchClause( p, pCur, pCur->pLits[1] );
+ Cbs3_ManWatchClause( p, Cur, Cbs3_ClauseLit(p, Cur, 1) );
+ break;
+ }
+ if ( i < nLits ) // found new watch
+ continue;
+
+ // clause is unit - enqueue new implication
+ //if ( Inta_ManEnqueue(p, pCur->pLits[0], pCur) )
+ //{
+ // ppPrev = &pCur->pNext1;
+ // continue;
+ //}
+
+ // clause is unit - enqueue new implication
+ Value = Cbs3_VarValue(p, Abc_Lit2Var(pLits[0]));
+ if ( Value >= 2 ) // unassigned
+ {
+ Cbs3_ManAssign( p, pLits[0], Level, 0, Cur );
+ pPrev = Cbs3_ClauseNext1p(p, Cur);
+ continue;
+ }
+
+ // conflict detected - return the conflict clause
+ //return pCur;
+ if ( Value == Abc_LitIsCompl(pLits[0]) )
+ {
+ p->nClauseConf++;
+ return Cbs3_ManAnalyze( p, Level, Abc_Lit2Var(pLits[0]), 0, Cur );
+ }
+ }
+ return 0;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs resolution of two clauses.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cbs3_ManResolve( Cbs3_Man_t * p, int Level, int hClause0, int hClause1 )
+{
+ Cbs3_Que_t * pQue = &(p->pClauses);
+ int i, iObj, LevelMax = -1, LevelCur;
+ assert( pQue->pData[hClause0+1] != 0 );
+ assert( pQue->pData[hClause0+1] == pQue->pData[hClause1+1] );
+ //Cbs3_ClauseForEachEntry1( p, hClause0, iObj, i )
+ // assert( !Cbs3_VarMark0(p, iObj) );
+ //Cbs3_ClauseForEachEntry1( p, hClause1, iObj, i )
+ // assert( !Cbs3_VarMark0(p, iObj) );
+ assert( Cbs3_QueIsEmpty( pQue ) );
+ Cbs3_QuePush( pQue, 0 );
+ Cbs3_QuePush( pQue, 0 );
+// for ( i = hClause0 + 1; (iObj = pQue->pData[i]); i++ )
+ Cbs3_ClauseForEachEntry1( p, hClause0, iObj, i )
+ {
+ if ( Cbs3_VarMark0(p, iObj) ) // unassigned - seen again
+ continue;
+ //if ( Vec_IntEntry(&p->vActivity, iObj) == 0 )
+ // Vec_IntPush( &p->vActStore, iObj );
+ //Vec_IntAddToEntry( &p->vActivity, iObj, 1 );
+ // assigned - seen first time
+ Cbs3_VarSetMark0(p, iObj, 1);
+ Cbs3_ActBumpVar(p, iObj);
+ Cbs3_QuePush( pQue, iObj );
+ LevelCur = Cbs3_VarDecLevel( p, iObj );
+ if ( LevelMax < LevelCur )
+ LevelMax = LevelCur;
+ }
+// for ( i = hClause1 + 1; (iObj = pQue->pData[i]); i++ )
+ Cbs3_ClauseForEachEntry1( p, hClause1, iObj, i )
+ {
+ if ( Cbs3_VarMark0(p, iObj) ) // unassigned - seen again
+ continue;
+ //if ( Vec_IntEntry(&p->vActivity, iObj) == 0 )
+ // Vec_IntPush( &p->vActStore, iObj );
+ //Vec_IntAddToEntry( &p->vActivity, iObj, 1 );
+ // assigned - seen first time
+ Cbs3_VarSetMark0(p, iObj, 1);
+ Cbs3_ActBumpVar(p, iObj);
+ Cbs3_QuePush( pQue, iObj );
+ LevelCur = Cbs3_VarDecLevel( p, iObj );
+ if ( LevelMax < LevelCur )
+ LevelMax = LevelCur;
+ }
+ for ( i = pQue->iHead + 2; i < pQue->iTail; i++ )
+ Cbs3_VarSetMark0(p, pQue->pData[i], 0);
+ return Cbs3_ManDeriveReason( p, LevelMax );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Propagates a variable.]
+
+ Description [Returns clause handle if conflict; 0 if no conflict.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cbs3_ManUpdateJFrontier( Cbs3_Man_t * p )
+{
+ //abctime clk = Abc_Clock();
+ int iVar, iLit, i, k = p->pJust.iTail;
+ Cbs3_QueGrow( &p->pJust, Cbs3_QueSize(&p->pJust) + Cbs3_QueSize(&p->pProp) );
+ Cbs3_QueForEachEntry( p->pJust, iVar, i )
+ if ( Cbs3_VarIsJust(p, iVar) )
+ p->pJust.pData[k++] = iVar;
+ Cbs3_QueForEachEntry( p->pProp, iLit, i )
+ if ( Cbs3_VarIsJust(p, Abc_Lit2Var(iLit)) )
+ p->pJust.pData[k++] = Abc_Lit2Var(iLit);
+ p->pJust.iHead = p->pJust.iTail;
+ p->pJust.iTail = k;
+ //p->timeJFront += Abc_Clock() - clk;
+}
+int Cbs3_ManPropagateNew( Cbs3_Man_t * p, int Level )
+{
+ int i, k, iLit, hClause, nLits, * pLits;
+ p->nPropCalls[0]++;
+ Cbs3_QueForEachEntry( p->pProp, iLit, i )
+ {
+ if ( (hClause = Cbs3_ManPropagateClauses(p, Level, iLit)) )
+ return hClause;
+ p->nPropCalls[2]++;
+ nLits = Vec_IntSize(Vec_WecEntry(&p->vImps, iLit));
+ pLits = Vec_IntArray(Vec_WecEntry(&p->vImps, iLit));
+ for ( k = 0; k < nLits; k += 2 )
+ {
+ int Value0 = Cbs3_VarValue(p, Abc_Lit2Var(pLits[k]));
+ int Value1 = pLits[k+1] ? Cbs3_VarValue(p, Abc_Lit2Var(pLits[k+1])) : -1;
+ if ( Value1 == -1 || Value1 == Abc_LitIsCompl(pLits[k+1]) ) // pLits[k+1] is false
+ {
+ if ( Value0 >= 2 ) // pLits[k] is unassigned
+ Cbs3_ManAssign( p, pLits[k], Level, Abc_Lit2Var(iLit), Abc_Lit2Var(pLits[k+1]) );
+ else if ( Value0 == Abc_LitIsCompl(pLits[k]) ) // pLits[k] is false
+ return Cbs3_ManAnalyze( p, Level, Abc_Lit2Var(iLit), Abc_Lit2Var(pLits[k]), Abc_Lit2Var(pLits[k+1]) );
+ }
+ if ( Value1 != -1 && Value0 == Abc_LitIsCompl(pLits[k]) ) // pLits[k] is false
+ {
+ if ( Value1 >= 2 ) // pLits[k+1] is unassigned
+ Cbs3_ManAssign( p, pLits[k+1], Level, Abc_Lit2Var(iLit), Abc_Lit2Var(pLits[k]) );
+ else if ( Value1 == Abc_LitIsCompl(pLits[k+1]) ) // pLits[k+1] is false
+ return Cbs3_ManAnalyze( p, Level, Abc_Lit2Var(iLit), Abc_Lit2Var(pLits[k]), Abc_Lit2Var(pLits[k+1]) );
+ }
+ }
+ }
+ Cbs3_ManUpdateJFrontier( p );
+ // finalize propagation queue
+ p->pProp.iHead = p->pProp.iTail;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Solve the problem recursively.]
+
+ Description [Returns learnt clause if unsat, NULL if sat or undecided.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cbs3_ManSolve2_rec( Cbs3_Man_t * p, int Level )
+{
+ Cbs3_Que_t * pQue = &(p->pClauses);
+ int iPropHead, iJustHead, iJustTail;
+ int hClause, hLearn0, hLearn1, iVar, iDecLit;
+ int nRef0, nRef1;
+ // propagate assignments
+ assert( !Cbs3_QueIsEmpty(&p->pProp) );
+ //if ( (hClause = Cbs3_ManPropagate( p, Level )) )
+ if ( (hClause = Cbs3_ManPropagateNew( p, Level )) )
+ return hClause;
+ // check for satisfying assignment
+ assert( Cbs3_QueIsEmpty(&p->pProp) );
+ if ( Cbs3_QueIsEmpty(&p->pJust) )
+ return 0;
+ // quit using resource limits
+ p->Pars.nJustThis = Abc_MaxInt( p->Pars.nJustThis, p->pJust.iTail - p->pJust.iHead );
+ if ( Cbs3_ManCheckLimits( p ) )
+ return 0;
+ // remember the state before branching
+ iPropHead = p->pProp.iHead;
+ iJustHead = p->pJust.iHead;
+ iJustTail = p->pJust.iTail;
+ // find the decision variable
+ p->nDecs++;
+ iVar = Cbs3_ManDecide( p );
+ assert( !Cbs3_VarIsPi(p, iVar) );
+ assert( Cbs3_VarIsJust(p, iVar) );
+ // chose decision variable using fanout count
+ nRef0 = Vec_IntEntry(&p->vRef, Abc_Lit2Var(Cbs3_VarLit0(p, iVar)));
+ nRef1 = Vec_IntEntry(&p->vRef, Abc_Lit2Var(Cbs3_VarLit1(p, iVar)));
+// if ( nRef0 >= nRef1 || (nRef0 == nRef1) && (Abc_Random(0) & 1) )
+ if ( nRef0 >= nRef1 )
+ iDecLit = Abc_LitNot(Cbs3_VarLit0(p, iVar));
+ else
+ iDecLit = Abc_LitNot(Cbs3_VarLit1(p, iVar));
+ // decide on first fanin
+ Cbs3_ManAssign( p, iDecLit, Level+1, 0, 0 );
+ if ( !(hLearn0 = Cbs3_ManSolve2_rec( p, Level+1 )) )
+ return 0;
+ if ( pQue->pData[hLearn0+1] != Abc_Lit2Var(iDecLit) )
+ return hLearn0;
+ Cbs3_ManCancelUntil( p, iPropHead );
+ Cbs3_QueRestore( &p->pJust, iJustHead, iJustTail );
+ // decide on second fanin
+ Cbs3_ManAssign( p, Abc_LitNot(iDecLit), Level+1, 0, 0 );
+ if ( !(hLearn1 = Cbs3_ManSolve2_rec( p, Level+1 )) )
+ return 0;
+ if ( pQue->pData[hLearn1+1] != Abc_Lit2Var(iDecLit) )
+ return hLearn1;
+ hClause = Cbs3_ManResolve( p, Level, hLearn0, hLearn1 );
+ p->Pars.nBTThis++;
+ return hClause;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Looking for a satisfying assignment of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cbs3_ManSolveInt( Cbs3_Man_t * p, int iLit )
+{
+ int RetValue = 0;
+ assert( !p->pProp.iHead && !p->pProp.iTail );
+ assert( !p->pJust.iHead && !p->pJust.iTail );
+ p->Pars.nBTThis = p->Pars.nJustThis = 0;
+ Cbs3_ManAssign( p, iLit, 0, 0, 0 );
+ if ( !Cbs3_ManSolve2_rec(p, 0) && !Cbs3_ManCheckLimits(p) )
+ Cbs3_ManSaveModel( p, p->vModel );
+ else
+ RetValue = 1;
+ Cbs3_ManCancelUntil( p, 0 );
+ p->pJust.iHead = p->pJust.iTail = 0;
+ p->Pars.nBTTotal += p->Pars.nBTThis;
+ p->Pars.nJustTotal = Abc_MaxInt( p->Pars.nJustTotal, p->Pars.nJustThis );
+ if ( Cbs3_ManCheckLimits( p ) )
+ RetValue = -1;
+ return RetValue;
+}
+int Cbs3_ManSolve( Cbs3_Man_t * p, int iLit, int nRestarts )
+{
+ int i, RetValue = -1;
+ assert( p->pClauses.iHead == 1 && p->pClauses.iTail == 1 );
+ for ( i = 0; i < nRestarts; i++ )
+ if ( (RetValue = Cbs3_ManSolveInt(p, iLit)) != -1 )
+ break;
+ Cbs3_ManCleanWatch( p );
+ p->pClauses.iHead = p->pClauses.iTail = 1;
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints statistics of the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cbs3_ManSatPrintStats( Cbs3_Man_t * p )
+{
+ printf( "CO = %8d ", Gia_ManCoNum(p->pAig) );
+ printf( "AND = %8d ", Gia_ManAndNum(p->pAig) );
+ printf( "Conf = %6d ", p->Pars.nBTLimit );
+ printf( "Restart = %2d ", p->Pars.nRestLimit );
+ printf( "JustMax = %5d ", p->Pars.nJustLimit );
+ printf( "\n" );
+ printf( "Unsat calls %6d (%6.2f %%) Ave conf = %8.1f ",
+ p->nSatUnsat, p->nSatTotal? 100.0*p->nSatUnsat/p->nSatTotal :0.0, p->nSatUnsat? 1.0*p->nConfUnsat/p->nSatUnsat :0.0 );
+ ABC_PRTP( "Time", p->timeSatUnsat, p->timeTotal );
+ printf( "Sat calls %6d (%6.2f %%) Ave conf = %8.1f ",
+ p->nSatSat, p->nSatTotal? 100.0*p->nSatSat/p->nSatTotal :0.0, p->nSatSat? 1.0*p->nConfSat/p->nSatSat : 0.0 );
+ ABC_PRTP( "Time", p->timeSatSat, p->timeTotal );
+ printf( "Undef calls %6d (%6.2f %%) Ave conf = %8.1f ",
+ p->nSatUndec, p->nSatTotal? 100.0*p->nSatUndec/p->nSatTotal :0.0, p->nSatUndec? 1.0*p->nConfUndec/p->nSatUndec : 0.0 );
+ ABC_PRTP( "Time", p->timeSatUndec, p->timeTotal );
+ ABC_PRT( "Total time", p->timeTotal );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cbs3_ManAddVar( Cbs3_Man_t * p, int iGiaObj )
+{
+ assert( Vec_IntSize(&p->vMap) == p->nVars );
+ Vec_IntPush( &p->vMap, iGiaObj );
+ Vec_IntPush( &p->vRef, Gia_ObjRefNumId(p->pAig, iGiaObj) );
+ Vec_IntPushTwo( &p->vFans, 0, 0 );
+ Vec_WecPushLevel(&p->vImps);
+ Vec_WecPushLevel(&p->vImps);
+ return Abc_Var2Lit( p->nVars++, 0 );
+}
+static inline void Cbs3_ManAddConstr( Cbs3_Man_t * p, int x, int x0, int x1 )
+{
+ Vec_WecPushTwo( &p->vImps, x , x0, 0 ); // ~x + x0
+ Vec_WecPushTwo( &p->vImps, x , x1, 0 ); // ~x + x1
+ Vec_WecPushTwo( &p->vImps, 1^x0, 1^x , 0 ); // ~x + x0
+ Vec_WecPushTwo( &p->vImps, 1^x1, 1^x , 0 ); // ~x + x1
+ Vec_WecPushTwo( &p->vImps, 1^x , 1^x0, 1^x1 ); // x + ~x0 + ~x1
+ Vec_WecPushTwo( &p->vImps, x0, x , 1^x1 ); // x + ~x0 + ~x1
+ Vec_WecPushTwo( &p->vImps, x1, x , 1^x0 ); // x + ~x0 + ~x1
+}
+static inline void Cbs3_ManAddAnd( Cbs3_Man_t * p, int x, int x0, int x1 )
+{
+ assert( x > 0 && x0 > 0 && x1 > 0 );
+ Vec_IntWriteEntry( &p->vFans, x, x0 );
+ Vec_IntWriteEntry( &p->vFans, x+1, x1 );
+ Cbs3_ManAddConstr( p, x, x0, x1 );
+}
+static inline int Cbs3_ManToSolver1_rec( Cbs3_Man_t * pSol, Gia_Man_t * p, int iObj, int Depth )
+{
+ Gia_Obj_t * pObj = Gia_ManObj(p, iObj); int Lit0, Lit1;
+ if ( Gia_ObjUpdateTravIdCurrentId(p, iObj) )
+ return pObj->Value;
+ pObj->Value = Cbs3_ManAddVar( pSol, iObj );
+ if ( Gia_ObjIsCi(pObj) || Depth == 0 )
+ return pObj->Value;
+ assert( Gia_ObjIsAnd(pObj) );
+ Lit0 = Cbs3_ManToSolver1_rec( pSol, p, Gia_ObjFaninId0(pObj, iObj), Depth - Gia_ObjFaninC0(pObj) );
+ Lit1 = Cbs3_ManToSolver1_rec( pSol, p, Gia_ObjFaninId1(pObj, iObj), Depth - Gia_ObjFaninC1(pObj) );
+ Cbs3_ManAddAnd( pSol, pObj->Value, Lit0 ^ Gia_ObjFaninC0(pObj), Lit1 ^ Gia_ObjFaninC1(pObj) );
+ return pObj->Value;
+}
+static inline int Cbs3_ManToSolver1( Cbs3_Man_t * pSol, Gia_Man_t * p, Gia_Obj_t * pRoot, int nRestarts, int Depth )
+{
+ //abctime clk = Abc_Clock();
+ assert( Gia_ObjIsCo(pRoot) );
+ Cbs3_ManReset( pSol );
+ Gia_ManIncrementTravId( p );
+ Cbs3_ManToSolver1_rec( pSol, p, Gia_ObjFaninId0p(p, pRoot), Depth );
+ Cbs3_ManGrow( pSol );
+ Cbs3_ActReset( pSol );
+ //pSol->timeSatLoad += Abc_Clock() - clk;
+ return Cbs3_ManSolve( pSol, Gia_ObjFanin0Copy(pRoot), nRestarts );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Cbs3_ManPrepare( Cbs3_Man_t * p )
+{
+ int x, x0, x1;
+ Vec_WecInit( &p->vImps, Abc_Var2Lit(p->nVars, 0) );
+ Vec_IntForEachEntryDoubleStart( &p->vFans, x0, x1, x, 2 )
+ if ( x0 ) Cbs3_ManAddConstr( p, x, x0, x1 );
+}
+static inline int Cbs3_ManAddNode( Cbs3_Man_t * p, int iGiaObj, int iLit0, int iLit1 )
+{
+ assert( Vec_IntSize(&p->vMap) == p->nVars );
+ Vec_IntPush( &p->vMap, iGiaObj );
+ Vec_IntPush( &p->vRef, Gia_ObjRefNumId(p->pAig, iGiaObj) );
+ Vec_IntPushTwo( &p->vFans, iLit0, iLit1 );
+ return Abc_Var2Lit( p->nVars++, 0 );
+}
+static inline int Cbs3_ManToSolver2_rec( Cbs3_Man_t * pSol, Gia_Man_t * p, int iObj, int Depth )
+{
+ Gia_Obj_t * pObj = Gia_ManObj(p, iObj); int Lit0, Lit1;
+ if ( Gia_ObjUpdateTravIdCurrentId(p, iObj) )
+ return pObj->Value;
+ if ( Gia_ObjIsCi(pObj) || Depth == 0 )
+ return pObj->Value = Cbs3_ManAddNode(pSol, iObj, 0, 0);
+ assert( Gia_ObjIsAnd(pObj) );
+ Lit0 = Cbs3_ManToSolver2_rec( pSol, p, Gia_ObjFaninId0(pObj, iObj), Depth - Gia_ObjFaninC0(pObj) );
+ Lit1 = Cbs3_ManToSolver2_rec( pSol, p, Gia_ObjFaninId1(pObj, iObj), Depth - Gia_ObjFaninC1(pObj) );
+ return pObj->Value = Cbs3_ManAddNode(pSol, iObj, Lit0 ^ Gia_ObjFaninC0(pObj), Lit1 ^ Gia_ObjFaninC1(pObj));
+}
+static inline int Cbs3_ManToSolver2( Cbs3_Man_t * pSol, Gia_Man_t * p, Gia_Obj_t * pRoot, int nRestarts, int Depth )
+{
+ //abctime clk = Abc_Clock();
+ assert( Gia_ObjIsCo(pRoot) );
+ Cbs3_ManReset( pSol );
+ Gia_ManIncrementTravId( p );
+ Cbs3_ManToSolver2_rec( pSol, p, Gia_ObjFaninId0p(p, pRoot), Depth );
+ Cbs3_ManGrow( pSol );
+ Cbs3_ManPrepare( pSol );
+ Cbs3_ActReset( pSol );
+ //pSol->timeSatLoad += Abc_Clock() - clk;
+ return Cbs3_ManSolve( pSol, Gia_ObjFanin0Copy(pRoot), nRestarts );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Procedure to test the new SAT solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Cbs3_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, int nRestarts, Vec_Str_t ** pvStatus, int fVerbose )
+{
+ extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out );
+ Cbs3_Man_t * p;
+ Vec_Int_t * vCex, * vVisit, * vCexStore;
+ Vec_Str_t * vStatus;
+ Gia_Obj_t * pRoot;
+ int i, status; // 1 = unsat, 0 = sat, -1 = undec
+ abctime clk, clkTotal = Abc_Clock();
+ //assert( Gia_ManRegNum(pAig) == 0 );
+ Gia_ManCreateRefs( pAig );
+ //Gia_ManLevelNum( pAig );
+ // create logic network
+ p = Cbs3_ManAlloc( pAig );
+ p->Pars.nBTLimit = nConfs;
+ p->Pars.nRestLimit = nRestarts;
+ // create resulting data-structures
+ vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) );
+ vCexStore = Vec_IntAlloc( 10000 );
+ vVisit = Vec_IntAlloc( 100 );
+ vCex = Cbs3_ReadModel( p );
+ // solve for each output
+ Gia_ManForEachCo( pAig, pRoot, i )
+ {
+ if ( Gia_ObjIsConst0(Gia_ObjFanin0(pRoot)) )
+ {
+ Vec_IntClear( vCex );
+ Vec_StrPush( vStatus, (char)(!Gia_ObjFaninC0(pRoot)) );
+ if ( Gia_ObjFaninC0(pRoot) ) // const1
+ Cec_ManSatAddToStore( vCexStore, vCex, i ); // trivial counter-example
+ continue;
+ }
+ clk = Abc_Clock();
+ status = Cbs3_ManToSolver2( p, pAig, pRoot, p->Pars.nRestLimit, 10000 );
+ Vec_StrPush( vStatus, (char)status );
+ if ( status == -1 )
+ {
+ p->nSatUndec++;
+ p->nConfUndec += p->Pars.nBTThis;
+ Cec_ManSatAddToStore( vCexStore, NULL, i ); // timeout
+ p->timeSatUndec += Abc_Clock() - clk;
+ continue;
+ }
+ if ( status == 1 )
+ {
+ p->nSatUnsat++;
+ p->nConfUnsat += p->Pars.nBTThis;
+ p->timeSatUnsat += Abc_Clock() - clk;
+ continue;
+ }
+ p->nSatSat++;
+ p->nConfSat += p->Pars.nBTThis;
+ //Gia_SatVerifyPattern( pAig, pRoot, vCex, vVisit );
+ Cec_ManSatAddToStore( vCexStore, vCex, i );
+ p->timeSatSat += Abc_Clock() - clk;
+ }
+ Vec_IntFree( vVisit );
+ p->nSatTotal = Gia_ManPoNum(pAig);
+ p->timeTotal = Abc_Clock() - clkTotal;
+ if ( fVerbose )
+ Cbs3_ManSatPrintStats( p );
+ if ( fVerbose )
+ {
+ printf( "Prop1 = %d. Prop2 = %d. Prop3 = %d. ClaConf = %d. FailJ = %d. FailC = %d. ", p->nPropCalls[0], p->nPropCalls[1], p->nPropCalls[2], p->nClauseConf, p->nFails[0], p->nFails[1] );
+ printf( "Mem usage %.2f MB.\n", 1.0*Cbs3_ManMemory(p)/(1<<20) );
+ //Abc_PrintTime( 1, "JFront", p->timeJFront );
+ //Abc_PrintTime( 1, "Loading", p->timeSatLoad );
+ //printf( "Decisions = %d.\n", p->nDecs );
+ }
+ Cbs3_ManStop( p );
+ *pvStatus = vStatus;
+ return vCexStore;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaCut.c b/src/aig/gia/giaCut.c
index f70f0fc0..7ee795b6 100644
--- a/src/aig/gia/giaCut.c
+++ b/src/aig/gia/giaCut.c
@@ -602,10 +602,10 @@ void Gia_StoRefObj( Gia_Sto_t * p, int iObj )
}
void Gia_StoComputeCuts( Gia_Man_t * pGia )
{
- int nCutSize = 6;
- int nCutNum = 25;
- int fCutMin = 1;
- int fTruthMin = 1;
+ int nCutSize = 8;
+ int nCutNum = 6;
+ int fCutMin = 0;
+ int fTruthMin = 0;
int fVerbose = 1;
Gia_Sto_t * p = Gia_StoAlloc( pGia, nCutSize, nCutNum, fCutMin, fTruthMin, fVerbose );
Gia_Obj_t * pObj; int i, iObj;
@@ -637,6 +637,147 @@ void Gia_StoComputeCuts( Gia_Man_t * pGia )
Gia_StoFree( p );
}
+
+/**Function*************************************************************
+
+ Synopsis [Extract a given number of cuts.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_StoSelectOneCut( Vec_Wec_t * vCuts, int iObj, Vec_Int_t * vCut, int nCutSizeMin )
+{
+ Vec_Int_t * vThis = Vec_WecEntry( vCuts, iObj );
+ int i, v, * pCut, * pList = Vec_IntArray( vThis );
+ if ( pList == NULL )
+ return 0;
+ Vec_IntClear( vCut );
+ Sdb_ForEachCut( pList, pCut, i )
+ {
+ if ( pCut[0] < nCutSizeMin )
+ continue;
+ for ( v = 0; v <= pCut[0]; v++ )
+ Vec_IntPush( vCut, pCut[v] );
+ return 1;
+ }
+ return 0;
+}
+Vec_Wec_t * Gia_ManSelectCuts( Vec_Wec_t * vCuts, int nCuts, int nCutSizeMin )
+{
+ Vec_Wec_t * vCutsSel = Vec_WecStart( nCuts );
+ int i; srand( time(NULL) );
+ for ( i = 0; i < nCuts; i++ )
+ while ( !Gia_StoSelectOneCut(vCuts, (rand() | (rand() << 15)) % Vec_WecSize(vCuts), Vec_WecEntry(vCutsSel, i), nCutSizeMin) );
+ return vCutsSel;
+}
+Vec_Wec_t * Gia_ManExtractCuts( Gia_Man_t * pGia, int nCutSize0, int nCuts0, int fVerbose0 )
+{
+ int nCutSize = nCutSize0;
+ int nCutNum = 6;
+ int fCutMin = 0;
+ int fTruthMin = 0;
+ int fVerbose = fVerbose0;
+ Vec_Wec_t * vCutsSel;
+ Gia_Sto_t * p = Gia_StoAlloc( pGia, nCutSize, nCutNum, fCutMin, fTruthMin, fVerbose );
+ Gia_Obj_t * pObj; int i, iObj;
+ assert( nCutSize <= GIA_MAX_CUTSIZE );
+ assert( nCutNum < GIA_MAX_CUTNUM );
+ // prepare references
+ Gia_ManForEachObj( p->pGia, pObj, iObj )
+ Gia_StoRefObj( p, iObj );
+ // compute cuts
+ Gia_StoComputeCutsConst0( p, 0 );
+ Gia_ManForEachCiId( p->pGia, iObj, i )
+ Gia_StoComputeCutsCi( p, iObj );
+ Gia_ManForEachAnd( p->pGia, pObj, iObj )
+ Gia_StoComputeCutsNode( p, iObj );
+ if ( p->fVerbose )
+ {
+ printf( "Running cut computation with CutSize = %d CutNum = %d CutMin = %s TruthMin = %s\n",
+ p->nCutSize, p->nCutNum, p->fCutMin ? "yes":"no", p->fTruthMin ? "yes":"no" );
+ printf( "CutPair = %.0f ", p->CutCount[0] );
+ printf( "Merge = %.0f (%.2f %%) ", p->CutCount[1], 100.0*p->CutCount[1]/p->CutCount[0] );
+ printf( "Eval = %.0f (%.2f %%) ", p->CutCount[2], 100.0*p->CutCount[2]/p->CutCount[0] );
+ printf( "Cut = %.0f (%.2f %%) ", p->CutCount[3], 100.0*p->CutCount[3]/p->CutCount[0] );
+ printf( "Cut/Node = %.2f ", p->CutCount[3] / Gia_ManAndNum(p->pGia) );
+ printf( "\n" );
+ printf( "The number of nodes with cut count over the limit (%d cuts) = %d nodes (out of %d). ",
+ p->nCutNum, p->nCutsOver, Gia_ManAndNum(pGia) );
+ Abc_PrintTime( 0, "Time", Abc_Clock() - p->clkStart );
+ }
+ vCutsSel = Gia_ManSelectCuts( p->vCuts, nCuts0, nCutSize0-1 );
+ Gia_StoFree( p );
+ return vCutsSel;
+}
+void Gia_ManCreateWins( Gia_Man_t * pGia, Vec_Wec_t * vCuts )
+{
+ Gia_Obj_t * pObj;
+ Vec_Wec_t * vWins = Vec_WecStart( Gia_ManObjNum(pGia) );
+ Vec_Int_t * vTemp = Vec_IntAlloc( 100 );
+ Vec_Int_t * vCut; int i, k, Obj, Cut;
+ Vec_WecForEachLevel( vCuts, vCut, i )
+ Vec_IntForEachEntryStart( vCut, Obj, k, 1 )
+ Vec_IntPush( Vec_WecEntry(vWins, Obj), i );
+ Gia_ManForEachAnd( pGia, pObj, Obj )
+ {
+ Vec_Int_t * vWin = Vec_WecEntry(vWins, Obj);
+ Vec_Int_t * vWin0 = Vec_WecEntry(vWins, Gia_ObjFaninId0(pObj, Obj));
+ Vec_Int_t * vWin1 = Vec_WecEntry(vWins, Gia_ObjFaninId1(pObj, Obj));
+ Vec_IntTwoFindCommon( vWin0, vWin1, vTemp );
+ Vec_IntForEachEntry( vTemp, Cut, k )
+ {
+ Vec_IntPushUniqueOrder( vWin, Cut );
+ Vec_IntPush( Vec_WecEntry(vCuts, Cut), Obj );
+ }
+ }
+ Vec_WecFree( vWins );
+ Vec_IntFree( vTemp );
+}
+void Gia_ManPrintWins( Vec_Wec_t * vCuts )
+{
+ Vec_Int_t * vCut; int i, k, Obj;
+ Vec_WecForEachLevel( vCuts, vCut, i )
+ {
+ int nInputs = Vec_IntEntry(vCut, 0);
+ printf( "Cut %5d : ", i );
+ printf( "Supp = %d ", nInputs );
+ printf( "Nodes = %d ", Vec_IntSize(vCut) - 1 - nInputs );
+ Vec_IntForEachEntryStartStop( vCut, Obj, k, 1, nInputs+1 )
+ printf( "%d ", Obj );
+ printf( " " );
+ Vec_IntForEachEntryStart( vCut, Obj, k, nInputs+1 )
+ printf( "%d ", Obj );
+ printf( "\n" );
+ }
+}
+void Gia_ManPrintWinStats( Vec_Wec_t * vCuts )
+{
+ Vec_Int_t * vCut; int i, nInputs = 0, nNodes = 0;
+ Vec_WecForEachLevel( vCuts, vCut, i )
+ {
+ nInputs += Vec_IntEntry(vCut, 0);
+ nNodes += Vec_IntSize(vCut) - 1 - Vec_IntEntry(vCut, 0);
+ }
+ printf( "Computed %d windows with average support %.3f and average volume %.3f.\n",
+ Vec_WecSize(vCuts), 1.0*nInputs/Vec_WecSize(vCuts), 1.0*nNodes/Vec_WecSize(vCuts) );
+}
+void Gia_ManExtractTest( Gia_Man_t * pGia )
+{
+ extern Vec_Wec_t * Gia_ManExtractCuts2( Gia_Man_t * p, int nCutSize, int nCuts, int fVerbose );
+ Vec_Wec_t * vCutsSel = Gia_ManExtractCuts2( pGia, 8, 10000, 1 );
+ //Vec_Wec_t * vCutsSel = Gia_ManExtractCuts( pGia, 8, 10000, 1 );
+ abctime clk = Abc_Clock();
+ Gia_ManCreateWins( pGia, vCutsSel );
+ //Gia_ManPrintWins( vCutsSel );
+ Gia_ManPrintWinStats( vCutsSel );
+ Vec_WecFree( vCutsSel );
+ Abc_PrintTime( 0, "Creating windows", Abc_Clock() - clk );
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaDecs.c b/src/aig/gia/giaDecs.c
new file mode 100644
index 00000000..343891d5
--- /dev/null
+++ b/src/aig/gia/giaDecs.c
@@ -0,0 +1,350 @@
+/**CFile****************************************************************
+
+ FileName [giaDecs.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Calling various decomposition engines.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaDecs.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "aig/gia/gia.h"
+#include "misc/util/utilTruth.h"
+#include "misc/extra/extra.h"
+#include "bool/bdc/bdc.h"
+#include "bool/kit/kit.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+extern void Extra_BitMatrixTransposeP( Vec_Wrd_t * vSimsIn, int nWordsIn, Vec_Wrd_t * vSimsOut, int nWordsOut );
+extern Vec_Int_t * Gia_ManResubOne( Vec_Ptr_t * vDivs, int nWords, int nLimit, int nDivsMax, int iChoice, int fUseXor, int fDebug, int fVerbose, word * pFunc, int Depth );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ResubVarNum( Vec_Int_t * vResub )
+{
+ if ( Vec_IntSize(vResub) == 1 )
+ return Vec_IntEntryLast(vResub) >= 2;
+ return Vec_IntEntryLast(vResub)/2 - Vec_IntSize(vResub)/2 - 1;
+}
+word Gia_ResubToTruth6_rec( Vec_Int_t * vResub, int iNode, int nVars )
+{
+ assert( iNode >= 0 && nVars <= 6 );
+ if ( iNode < nVars )
+ return s_Truths6[iNode];
+ else
+ {
+ int iLit0 = Vec_IntEntry( vResub, Abc_Var2Lit(iNode-nVars, 0) );
+ int iLit1 = Vec_IntEntry( vResub, Abc_Var2Lit(iNode-nVars, 1) );
+ word Res0 = Gia_ResubToTruth6_rec( vResub, Abc_Lit2Var(iLit0)-2, nVars );
+ word Res1 = Gia_ResubToTruth6_rec( vResub, Abc_Lit2Var(iLit1)-2, nVars );
+ Res0 = Abc_LitIsCompl(iLit0) ? ~Res0 : Res0;
+ Res1 = Abc_LitIsCompl(iLit1) ? ~Res1 : Res1;
+ return iLit0 > iLit1 ? Res0 ^ Res1 : Res0 & Res1;
+ }
+}
+word Gia_ResubToTruth6( Vec_Int_t * vResub )
+{
+ word Res;
+ int iRoot = Vec_IntEntryLast(vResub);
+ if ( iRoot < 2 )
+ return iRoot ? ~(word)0 : 0;
+ assert( iRoot != 2 && iRoot != 3 );
+ Res = Gia_ResubToTruth6_rec( vResub, Abc_Lit2Var(iRoot)-2, Gia_ResubVarNum(vResub) );
+ return Abc_LitIsCompl(iRoot) ? ~Res : Res;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Wrd_t * Gia_ManDeriveTruths( Gia_Man_t * p, Vec_Wrd_t * vSims, Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vSet, int nWords )
+{
+ int nTtWords = Abc_Truth6WordNum(Vec_IntSize(vSet));
+ int nFuncs = Vec_WrdSize(vIsfs) / 2 / nWords;
+ Vec_Wrd_t * vRes = Vec_WrdStart( 2 * nFuncs * nTtWords );
+ Vec_Wrd_t * vIn = Vec_WrdStart( 64*nWords ), * vOut;
+ int i, f, m, iObj; word Func;
+ assert( Vec_IntSize(vSet) <= 64 );
+ Vec_IntForEachEntry( vSet, iObj, i )
+ Abc_TtCopy( Vec_WrdEntryP(vIn, i*nWords), Vec_WrdEntryP(vSims, Vec_IntEntry(vCands, iObj)*nWords), nWords, 0 );
+ vOut = Vec_WrdStart( Vec_WrdSize(vIn) );
+ Extra_BitMatrixTransposeP( vIn, nWords, vOut, 1 );
+ for ( f = 0; f < nFuncs; f++ )
+ {
+ word * pIsf[2] = { Vec_WrdEntryP(vIsfs, (2*f+0)*nWords),
+ Vec_WrdEntryP(vIsfs, (2*f+1)*nWords) };
+ word * pTruth[2] = { Vec_WrdEntryP(vRes, (2*f+0)*nTtWords),
+ Vec_WrdEntryP(vRes, (2*f+1)*nTtWords) };
+ for ( m = 0; m < 64*nWords; m++ )
+ {
+ int iMint = (int)Vec_WrdEntry(vOut, m);
+ int Value0 = Abc_TtGetBit( pIsf[0], m );
+ int Value1 = Abc_TtGetBit( pIsf[1], m );
+ if ( !Value0 && !Value1 )
+ continue;
+ if ( Value0 && Value1 )
+ printf( "Internal error: Onset and Offset overlap.\n" );
+ assert( !Value0 || !Value1 );
+ Abc_TtSetBit( pTruth[Value1], iMint );
+ }
+ if ( Abc_TtCountOnesVecMask(pTruth[0], pTruth[1], nTtWords, 0) )
+ printf( "Verification for function %d failed for %d minterm pairs.\n", f,
+ Abc_TtCountOnesVecMask(pTruth[0], pTruth[1], nTtWords, 0) );
+ }
+ if ( Vec_IntSize(vSet) < 6 )
+ Vec_WrdForEachEntry( vRes, Func, i )
+ Vec_WrdWriteEntry( vRes, i, Abc_Tt6Stretch(Func, Vec_IntSize(vSet)) );
+ Vec_WrdFree( vIn );
+ Vec_WrdFree( vOut );
+ return vRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManCountResub( Vec_Wrd_t * vTruths, int nVars, int fVerbose )
+{
+ Vec_Int_t * vResub; int nNodes;
+ int nTtWords = Abc_Truth6WordNum(nVars);
+ int v, nFuncs = Vec_WrdSize(vTruths) / 2 / nTtWords;
+ Vec_Wrd_t * vElems = Vec_WrdStartTruthTables( nVars );
+ Vec_Ptr_t * vDivs = Vec_PtrAlloc( 2 + nVars );
+ assert( Vec_WrdSize(vElems) == nTtWords * nVars );
+ assert( nFuncs == 1 );
+ Vec_PtrPush( vDivs, Vec_WrdEntryP(vTruths, (2*0+0)*nTtWords) );
+ Vec_PtrPush( vDivs, Vec_WrdEntryP(vTruths, (2*0+1)*nTtWords) );
+ for ( v = 0; v < nVars; v++ )
+ Vec_PtrPush( vDivs, Vec_WrdEntryP(vElems, v*nTtWords) );
+ vResub = Gia_ManResubOne( vDivs, nTtWords, 30, 100, 0, 0, 0, fVerbose, NULL, 0 );
+ Vec_PtrFree( vDivs );
+ Vec_WrdFree( vElems );
+ nNodes = Vec_IntSize(vResub) ? Vec_IntSize(vResub)/2 : 999;
+ Vec_IntFree( vResub );
+ return nNodes;
+}
+Vec_Int_t * Gia_ManDeriveResub( Vec_Wrd_t * vTruths, int nVars )
+{
+ Vec_Int_t * vResub;
+ int nTtWords = Abc_Truth6WordNum(nVars);
+ int v, nFuncs = Vec_WrdSize(vTruths) / 2 / nTtWords;
+ Vec_Wrd_t * vElems = Vec_WrdStartTruthTables( nVars );
+ Vec_Ptr_t * vDivs = Vec_PtrAlloc( 2 + nVars );
+ assert( Vec_WrdSize(vElems) == nTtWords * nVars );
+ assert( nFuncs == 1 );
+ Vec_PtrPush( vDivs, Vec_WrdEntryP(vTruths, (2*0+0)*nTtWords) );
+ Vec_PtrPush( vDivs, Vec_WrdEntryP(vTruths, (2*0+1)*nTtWords) );
+ for ( v = 0; v < nVars; v++ )
+ Vec_PtrPush( vDivs, Vec_WrdEntryP(vElems, v*nTtWords) );
+ vResub = Gia_ManResubOne( vDivs, nTtWords, 30, 100, 0, 0, 0, 0, NULL, 0 );
+ Vec_PtrFree( vDivs );
+ Vec_WrdFree( vElems );
+ return vResub;
+}
+
+int Gia_ManCountBidec( Vec_Wrd_t * vTruths, int nVars, int fVerbose )
+{
+ int nNodes, nTtWords = Abc_Truth6WordNum(nVars);
+ word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords),
+ Vec_WrdEntryP(vTruths, 1*nTtWords) };
+ Abc_TtOr( pTruth[0], pTruth[0], pTruth[1], nTtWords );
+ nNodes = Bdc_ManBidecNodeNum( pTruth[1], pTruth[0], nVars, fVerbose );
+ Abc_TtSharp( pTruth[0], pTruth[0], pTruth[1], nTtWords );
+ return nNodes;
+}
+Vec_Int_t * Gia_ManDeriveBidec( Vec_Wrd_t * vTruths, int nVars )
+{
+ Vec_Int_t * vRes = NULL;
+ int nTtWords = Abc_Truth6WordNum(nVars);
+ word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords),
+ Vec_WrdEntryP(vTruths, 1*nTtWords) };
+ Abc_TtOr( pTruth[0], pTruth[0], pTruth[1], nTtWords );
+ vRes = Bdc_ManBidecResub( pTruth[1], pTruth[0], nVars );
+ Abc_TtSharp( pTruth[0], pTruth[0], pTruth[1], nTtWords );
+ return vRes;
+}
+
+int Gia_ManCountIsop( Vec_Wrd_t * vTruths, int nVars, int fVerbose )
+{
+ int nTtWords = Abc_Truth6WordNum(nVars);
+ word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords),
+ Vec_WrdEntryP(vTruths, 1*nTtWords) };
+ int nNodes = Kit_IsopNodeNum( (unsigned *)pTruth[0], (unsigned *)pTruth[1], nVars, NULL );
+ return nNodes;
+}
+Vec_Int_t * Gia_ManDeriveIsop( Vec_Wrd_t * vTruths, int nVars )
+{
+ Vec_Int_t * vRes = NULL;
+ int nTtWords = Abc_Truth6WordNum(nVars);
+ word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords),
+ Vec_WrdEntryP(vTruths, 1*nTtWords) };
+ vRes = Kit_IsopResub( (unsigned *)pTruth[0], (unsigned *)pTruth[1], nVars, NULL );
+ return vRes;
+}
+
+int Gia_ManCountBdd( Vec_Wrd_t * vTruths, int nVars, int fVerbose )
+{
+ extern Gia_Man_t * Gia_TryPermOptNew( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose );
+ int nTtWords = Abc_Truth6WordNum(nVars);
+ word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords),
+ Vec_WrdEntryP(vTruths, 1*nTtWords) };
+ Gia_Man_t * pGia; int nNodes;
+
+ Abc_TtOr( pTruth[1], pTruth[1], pTruth[0], nTtWords );
+ Abc_TtNot( pTruth[0], nTtWords );
+ pGia = Gia_TryPermOptNew( pTruth[0], nVars, 1, nTtWords, 50, 0 );
+ Abc_TtNot( pTruth[0], nTtWords );
+ Abc_TtSharp( pTruth[1], pTruth[1], pTruth[0], nTtWords );
+
+ nNodes = Gia_ManAndNum(pGia);
+ Gia_ManStop( pGia );
+ return nNodes;
+}
+Vec_Int_t * Gia_ManDeriveBdd( Vec_Wrd_t * vTruths, int nVars )
+{
+ extern Vec_Int_t * Gia_ManToGates( Gia_Man_t * p );
+ Vec_Int_t * vRes = NULL;
+ extern Gia_Man_t * Gia_TryPermOptNew( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose );
+ int nTtWords = Abc_Truth6WordNum(nVars);
+ word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords),
+ Vec_WrdEntryP(vTruths, 1*nTtWords) };
+ Gia_Man_t * pGia;
+
+ Abc_TtOr( pTruth[1], pTruth[1], pTruth[0], nTtWords );
+ Abc_TtNot( pTruth[0], nTtWords );
+ pGia = Gia_TryPermOptNew( pTruth[0], nVars, 1, nTtWords, 50, 0 );
+ Abc_TtNot( pTruth[0], nTtWords );
+ Abc_TtSharp( pTruth[1], pTruth[1], pTruth[0], nTtWords );
+
+ vRes = Gia_ManToGates( pGia );
+ Gia_ManStop( pGia );
+ return vRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManEvalSolutionOne( Gia_Man_t * p, Vec_Wrd_t * vSims, Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vSet, int nWords, int fVerbose )
+{
+ Vec_Wrd_t * vTruths = Gia_ManDeriveTruths( p, vSims, vIsfs, vCands, vSet, nWords );
+ int nTtWords = Vec_WrdSize(vTruths)/2, nVars = Vec_IntSize(vSet);
+ word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords),
+ Vec_WrdEntryP(vTruths, 1*nTtWords) };
+ int nNodesResub = Gia_ManCountResub( vTruths, nVars, 0 );
+ int nNodesBidec = nVars > 2 ? Gia_ManCountBidec( vTruths, nVars, 0 ) : 999;
+ int nNodesIsop = nVars > 2 ? Gia_ManCountIsop( vTruths, nVars, 0 ) : 999;
+ int nNodesBdd = nVars > 2 ? Gia_ManCountBdd( vTruths, nVars, 0 ) : 999;
+ int nNodesMin = Abc_MinInt( Abc_MinInt(nNodesResub, nNodesBidec), Abc_MinInt(nNodesIsop, nNodesBdd) );
+ if ( fVerbose )
+ {
+ printf( "Size = %2d ", nVars );
+ printf( "Resub =%3d ", nNodesResub );
+ printf( "Bidec =%3d ", nNodesBidec );
+ printf( "Isop =%3d ", nNodesIsop );
+ printf( "Bdd =%3d ", nNodesBdd );
+ Abc_TtIsfPrint( pTruth[0], pTruth[1], nTtWords );
+ if ( nVars <= 6 )
+ {
+ printf( " " );
+ Extra_PrintHex( stdout, (unsigned*)pTruth[0], nVars );
+ printf( " " );
+ Extra_PrintHex( stdout, (unsigned*)pTruth[1], nVars );
+ }
+ printf( "\n" );
+ }
+ Vec_WrdFree( vTruths );
+ if ( nNodesMin > 500 )
+ return -1;
+ if ( nNodesMin == nNodesResub )
+ return (nNodesMin << 2) | 0;
+ if ( nNodesMin == nNodesBidec )
+ return (nNodesMin << 2) | 1;
+ if ( nNodesMin == nNodesIsop )
+ return (nNodesMin << 2) | 2;
+ if ( nNodesMin == nNodesBdd )
+ return (nNodesMin << 2) | 3;
+ return -1;
+}
+Vec_Int_t * Gia_ManDeriveSolutionOne( Gia_Man_t * p, Vec_Wrd_t * vSims, Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vSet, int nWords, int Type )
+{
+ Vec_Int_t * vRes = NULL;
+ Vec_Wrd_t * vTruths = Gia_ManDeriveTruths( p, vSims, vIsfs, vCands, vSet, nWords );
+ int nTtWords = Vec_WrdSize(vTruths)/2, nVars = Vec_IntSize(vSet);
+ word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords),
+ Vec_WrdEntryP(vTruths, 1*nTtWords) };
+ if ( Type == 0 )
+ vRes = Gia_ManDeriveResub( vTruths, nVars );
+ else if ( Type == 1 )
+ vRes = Gia_ManDeriveBidec( vTruths, nVars );
+ else if ( Type == 2 )
+ vRes = Gia_ManDeriveIsop( vTruths, nVars );
+ else if ( Type == 3 )
+ vRes = Gia_ManDeriveBdd( vTruths, nVars );
+ if ( vRes && Gia_ResubVarNum(vRes) <= 6 )
+ {
+ word Func = Gia_ResubToTruth6( vRes );
+ assert( !(Func & pTruth[0][0]) );
+ assert( !(pTruth[1][0] & ~Func) );
+ }
+ Vec_WrdFree( vTruths );
+ return vRes;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaDeep.c b/src/aig/gia/giaDeep.c
index f8b2930e..815a546e 100644
--- a/src/aig/gia/giaDeep.c
+++ b/src/aig/gia/giaDeep.c
@@ -19,14 +19,14 @@
***********************************************************************/
#include "gia.h"
+#include "base/main/main.h"
+#include "base/cmd/cmd.h"
ABC_NAMESPACE_IMPL_START
-
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@@ -43,9 +43,121 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
-Gia_Man_t * Gia_ManDeepSyn( Gia_Man_t * pGia, int TimeOut, int nAnds, int Seed, int fVerbose )
+Gia_Man_t * Gia_ManDeepSynOne( int nNoImpr, int TimeOut, int nAnds, int Seed, int fUseTwo, int fVerbose )
+{
+ abctime nTimeToStop = TimeOut ? Abc_Clock() + TimeOut * CLOCKS_PER_SEC : 0;
+ abctime clkStart = Abc_Clock();
+ int s, i, IterMax = 100000, nAndsMin = -1, iIterLast = -1;
+ Gia_Man_t * pTemp = Abc_FrameReadGia(Abc_FrameGetGlobalFrame());
+ Gia_Man_t * pNew = Gia_ManDup( pTemp );
+ Abc_Random(1);
+ for ( s = 0; s < 10+Seed; s++ )
+ Abc_Random(0);
+ for ( i = 0; i < IterMax; i++ )
+ {
+ unsigned Rand = Abc_Random(0);
+ int fDch = Rand & 1;
+ //int fCom = (Rand >> 1) & 3;
+ int fCom = (Rand >> 1) & 1;
+ int fFx = (Rand >> 2) & 1;
+ int KLut = fUseTwo ? 2 + (i % 5) : 3 + (i % 4);
+ int fChange = 0;
+ char Command[1000];
+ char * pComp = NULL;
+ if ( fCom == 3 )
+ pComp = "; &put; compress2rs; compress2rs; compress2rs; &get";
+ else if ( fCom == 2 )
+ pComp = "; &put; compress2rs; compress2rs; &get";
+ else if ( fCom == 1 )
+ pComp = "; &put; compress2rs; &get";
+ else if ( fCom == 0 )
+ pComp = "; &dc2";
+ sprintf( Command, "&dch%s; &if -a -K %d; &mfs -e -W 20 -L 20%s%s",
+ fDch ? " -f" : "", KLut, fFx ? "; &fx; &st" : "", pComp );
+ if ( Abc_FrameIsBatchMode() )
+ {
+ if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) )
+ {
+ Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command );
+ return NULL;
+ }
+ }
+ else
+ {
+ Abc_FrameSetBatchMode( 1 );
+ if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) )
+ {
+ Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command );
+ return NULL;
+ }
+ Abc_FrameSetBatchMode( 0 );
+ }
+ pTemp = Abc_FrameReadGia(Abc_FrameGetGlobalFrame());
+ if ( Gia_ManAndNum(pNew) > Gia_ManAndNum(pTemp) )
+ {
+ Gia_ManStop( pNew );
+ pNew = Gia_ManDup( pTemp );
+ fChange = 1;
+ iIterLast = i;
+ }
+ else if ( Gia_ManAndNum(pNew) + Gia_ManAndNum(pNew)/10 < Gia_ManAndNum(pTemp) )
+ {
+ //printf( "Updating\n" );
+ //Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), Gia_ManDup(pNew) );
+ }
+ if ( fChange && fVerbose )
+ {
+ printf( "Iter %6d : ", i );
+ printf( "Time %8.2f sec : ", (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC );
+ printf( "And = %6d ", Gia_ManAndNum(pNew) );
+ printf( "Lev = %3d ", Gia_ManLevelNum(pNew) );
+ if ( fChange )
+ printf( "<== best : " );
+ else if ( fVerbose )
+ printf( " " );
+ printf( "%s", Command );
+ printf( "\n" );
+ }
+ if ( nTimeToStop && Abc_Clock() > nTimeToStop )
+ {
+ printf( "Runtime limit (%d sec) is reached after %d iterations.\n", TimeOut, i );
+ break;
+ }
+ if ( i - iIterLast > nNoImpr )
+ {
+ printf( "Completed %d iterations without improvement in %.2f seconds.\n",
+ nNoImpr, (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC );
+ break;
+ }
+ }
+ if ( i == IterMax )
+ printf( "Iteration limit (%d iters) is reached after %.2f seconds.\n", IterMax, (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC );
+ else if ( nAnds && nAndsMin <= nAnds )
+ printf( "Quality goal (%d nodes <= %d nodes) is achieved after %d iterations and %.2f seconds.\n",
+ nAndsMin, nAnds, i, (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC );
+ return pNew;
+}
+Gia_Man_t * Gia_ManDeepSyn( Gia_Man_t * pGia, int nIters, int nNoImpr, int TimeOut, int nAnds, int Seed, int fUseTwo, int fVerbose )
{
- return NULL;
+ Gia_Man_t * pInit = Gia_ManDup(pGia);
+ Gia_Man_t * pBest = Gia_ManDup(pGia);
+ Gia_Man_t * pThis;
+ int i;
+ for ( i = 0; i < nIters; i++ )
+ {
+ Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), Gia_ManDup(pInit) );
+ pThis = Gia_ManDeepSynOne( nNoImpr, TimeOut, nAnds, Seed+i, fUseTwo, fVerbose );
+ if ( Gia_ManAndNum(pBest) > Gia_ManAndNum(pThis) )
+ {
+ Gia_ManStop( pBest );
+ pBest = pThis;
+ }
+ else
+ Gia_ManStop( pThis );
+
+ }
+ Gia_ManStop( pInit );
+ return pBest;
}
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaDfs.c b/src/aig/gia/giaDfs.c
index 5cfe3b44..7ed59b9a 100644
--- a/src/aig/gia/giaDfs.c
+++ b/src/aig/gia/giaDfs.c
@@ -418,6 +418,34 @@ Vec_Vec_t * Gia_ManLevelize( Gia_Man_t * p )
/**Function*************************************************************
+ Synopsis [Levelizes the nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Wec_t * Gia_ManLevelizeR( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ Vec_Wec_t * vLevels;
+ int nLevels, Level, i;
+ nLevels = Gia_ManLevelRNum( p );
+ vLevels = Vec_WecStart( nLevels + 1 );
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ if ( i == 0 || (!Gia_ObjIsCo(pObj) && !Gia_ObjLevel(p, pObj)) )
+ continue;
+ Level = Gia_ObjLevel( p, pObj );
+ assert( Level <= nLevels );
+ Vec_WecPush( vLevels, Level, i );
+ }
+ return vLevels;
+}
+/**Function*************************************************************
+
Synopsis [Computes reverse topological order.]
Description [Assumes that levels are already assigned.
diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c
index 4f448c40..b3fcd295 100644
--- a/src/aig/gia/giaDup.c
+++ b/src/aig/gia/giaDup.c
@@ -466,7 +466,16 @@ Gia_Man_t * Gia_ManDupOrderDfsChoices( Gia_Man_t * p )
SeeAlso []
***********************************************************************/
-Gia_Man_t * Gia_ManDupOrderDfsReverse( Gia_Man_t * p )
+int Gia_ManDupOrderDfs2_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( ~pObj->Value )
+ return pObj->Value;
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManDupOrderDfs2_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ Gia_ManDupOrderDfs2_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ return pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+Gia_Man_t * Gia_ManDupOrderDfsReverse( Gia_Man_t * p, int fRevFans, int fRevOuts )
{
Gia_Man_t * pNew;
Gia_Obj_t * pObj;
@@ -476,12 +485,28 @@ Gia_Man_t * Gia_ManDupOrderDfsReverse( Gia_Man_t * p )
pNew->pName = Abc_UtilStrsav( p->pName );
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
Gia_ManConst0(p)->Value = 0;
- Gia_ManForEachCoReverse( p, pObj, i )
- Gia_ManDupOrderDfs_rec( pNew, p, pObj );
Gia_ManForEachCi( p, pObj, i )
- if ( !~pObj->Value )
- pObj->Value = Gia_ManAppendCi(pNew);
- assert( Gia_ManCiNum(pNew) == Gia_ManCiNum(p) );
+ pObj->Value = Gia_ManAppendCi(pNew);
+ if ( fRevOuts )
+ {
+ if ( fRevFans )
+ Gia_ManForEachCoReverse( p, pObj, i )
+ Gia_ManDupOrderDfs2_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ else
+ Gia_ManForEachCoReverse( p, pObj, i )
+ Gia_ManDupOrderDfs_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ }
+ else
+ {
+ if ( fRevFans )
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManDupOrderDfs2_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ else
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManDupOrderDfs_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ }
+ Gia_ManForEachCo( p, pObj, i )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
Gia_ManDupRemapCis( pNew, p );
Gia_ManDupRemapCos( pNew, p );
Gia_ManDupRemapEquiv( pNew, p );
@@ -1327,7 +1352,7 @@ Gia_Man_t * Gia_ManDupMarked( Gia_Man_t * p )
{
Gia_Obj_t * pRepr;
pNew->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(pNew) );
- for ( i = 0; i < Gia_ManObjNum(p); i++ )
+ for ( i = 0; i < Gia_ManObjNum(pNew); i++ )
Gia_ObjSetRepr( pNew, i, GIA_VOID );
Gia_ManForEachObj1( p, pObj, i )
{
@@ -1585,6 +1610,52 @@ Gia_Man_t * Gia_ManDupDfsOnePo( Gia_Man_t * p, int iPo )
/**Function*************************************************************
+ Synopsis [Duplicates the AIG in the DFS order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManDupDfsRehash_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( ~pObj->Value )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManDupDfsRehash_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Gia_ManDupDfsRehash_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+Gia_Man_t * Gia_ManDupDfsRehash( Gia_Man_t * p )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj;
+ int i;
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManFillValue( p );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ManHashAlloc( pNew );
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManDupDfsRehash_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Gia_ManForEachCo( p, pObj, i )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ pNew->nConstrs = p->nConstrs;
+ if ( p->pCexSeq )
+ pNew->pCexSeq = Abc_CexDup( p->pCexSeq, Gia_ManRegNum(p) );
+ return pNew;
+}
+
+/**Function*************************************************************
+
Synopsis [Cofactors w.r.t. a primary input variable.]
Description []
@@ -2295,6 +2366,31 @@ Gia_Man_t * Gia_ManDupTrimmed2( Gia_Man_t * p )
assert( !Gia_ManHasDangling( pNew ) );
return pNew;
}
+Gia_Man_t * Gia_ManDupTrimmed3( Gia_Man_t * p )
+{
+ Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) );
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj;
+ int i;
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManFillValue( p );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ManForEachAnd( p, pObj, i )
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ // mark duplicated POs
+ Gia_ManForEachPo( p, pObj, i )
+ Vec_IntWriteEntry( vMap, Gia_ObjFaninId0p(p, pObj), i );
+ Gia_ManForEachPo( p, pObj, i )
+ if ( Vec_IntEntry(vMap, Gia_ObjFaninId0p(p, pObj)) == i )
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Vec_IntFree( vMap );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ return pNew;
+}
/**Function*************************************************************
@@ -2916,6 +3012,44 @@ Vec_Ptr_t * Gia_ManMiterNames( Vec_Ptr_t * p, int nOuts )
/**Function*************************************************************
+ Synopsis [Pair-wise miter.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManPairWiseMiter( Gia_Man_t * p )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj, * pObj2;
+ int i, k, iLit;
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManHashAlloc( pNew );
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ Gia_ManForEachAnd( p, pObj, i )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ Gia_ManForEachPo( p, pObj, i )
+ Gia_ManForEachPo( p, pObj2, k )
+ {
+ if ( i >= k )
+ continue;
+ iLit = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin0Copy(pObj2) );
+ Gia_ManAppendCo( pNew, iLit );
+ }
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+/**Function*************************************************************
+
Synopsis [Transforms the circuit into a regular miter.]
Description []
@@ -3448,7 +3582,7 @@ Gia_Man_t * Gia_ManDupCones( Gia_Man_t * p, int * pPos, int nPos, int fTrimPis )
Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) );
Vec_PtrForEachEntry( Gia_Obj_t *, vRoots, pObj, i )
Gia_ManDupCones_rec( p, pObj, vLeaves, vNodes, vRoots );
- Vec_PtrSort( vLeaves, (int (*)(void))Gia_ObjCompareByCioId );
+ Vec_PtrSort( vLeaves, (int (*)(const void *, const void *))Gia_ObjCompareByCioId );
// start the new manager
// Gia_ManFillValue( p );
@@ -3460,6 +3594,8 @@ Gia_Man_t * Gia_ManDupCones( Gia_Man_t * p, int * pPos, int nPos, int fTrimPis )
// create PIs
if ( fTrimPis )
{
+ Gia_ManForEachPi( p, pObj, i )
+ pObj->Value = ~0;
Vec_PtrForEachEntry( Gia_Obj_t *, vLeaves, pObj, i )
pObj->Value = Gia_ManAppendCi( pNew );
}
@@ -3508,7 +3644,7 @@ Gia_Man_t * Gia_ManDupAndCones( Gia_Man_t * p, int * pAnds, int nAnds, int fTrim
Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) );
Vec_PtrForEachEntry( Gia_Obj_t *, vRoots, pObj, i )
Gia_ManDupCones_rec( p, pObj, vLeaves, vNodes, vRoots );
- Vec_PtrSort( vLeaves, (int (*)(void))Gia_ObjCompareByCioId );
+ Vec_PtrSort( vLeaves, (int (*)(const void *, const void *))Gia_ObjCompareByCioId );
// start the new manager
// Gia_ManFillValue( p );
@@ -4245,7 +4381,7 @@ Gia_Man_t * Gia_ManDupDemiter( Gia_Man_t * p, int fVerbose )
vSuperPtr = Vec_PtrAlloc( Vec_IntSize(vSuper) );
Vec_IntForEachEntry( vSuper, iLit, i )
Vec_PtrPush( vSuperPtr, Gia_Lit2Obj(p, iLit) );
- Vec_PtrSort( vSuperPtr, (int (*)(void))Gia_ManSortByValue );
+ Vec_PtrSort( vSuperPtr, (int (*)(const void *, const void *))Gia_ManSortByValue );
// create new manager
pNew = Gia_ManStart( Gia_ManObjNum(p) );
pNew->pName = Abc_UtilStrsav( p->pName );
@@ -4899,6 +5035,38 @@ Gia_Man_t * Gia_ManDupReplaceCut( Gia_Man_t * p )
return pNew;
}
+/**Function*************************************************************
+
+ Synopsis [Duplicate AIG by creating a cut between logic fed by PIs]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManDupAddPis( Gia_Man_t * p, int nMulti )
+{
+ Gia_Man_t * pNew; int i, k;
+ Gia_Obj_t * pObj;
+ pNew = Gia_ManStart( Gia_ManObjNum(p) + Gia_ManCiNum(p) * nMulti );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ {
+ pObj->Value = Gia_ManAppendCi(pNew);
+ for ( k = 1; k < nMulti; k++ )
+ Gia_ManAppendCi(pNew);
+ }
+ Gia_ManForEachAnd( p, pObj, i )
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ Gia_ManForEachCo( p, pObj, i )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ assert( Gia_ManCiNum(pNew) == nMulti * Gia_ManCiNum(p) );
+ return pNew;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaEmbed.c b/src/aig/gia/giaEmbed.c
index b646a311..28d28483 100644
--- a/src/aig/gia/giaEmbed.c
+++ b/src/aig/gia/giaEmbed.c
@@ -32,7 +32,7 @@ ABC_NAMESPACE_IMPL_START
http://www.emis.de/journals/JGAA/accepted/2004/HarelKoren2004.8.2.pdf
Iterative refinement is described in the paper: F. A. Aloul, I. L. Markov, and K. A. Sakallah.
- "FORCE: A Fast and Easy-To-Implement Variable-Ordering Heuristic", Proc. GLSVLSI’03.
+ "FORCE: A Fast and Easy-To-Implement Variable-Ordering Heuristic", Proc. GLSVLSI 03.
http://www.eecs.umich.edu/~imarkov/pubs/conf/glsvlsi03-force.pdf
*/
diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c
index 03b9b819..5c82b260 100644
--- a/src/aig/gia/giaEquiv.c
+++ b/src/aig/gia/giaEquiv.c
@@ -269,6 +269,7 @@ int * Gia_ManDeriveNexts( Gia_Man_t * p )
pTails[i] = i;
for ( i = 0; i < Gia_ManObjNum(p); i++ )
{
+ //if ( p->pReprs[i].iRepr == GIA_VOID )
if ( !p->pReprs[i].iRepr || p->pReprs[i].iRepr == GIA_VOID )
continue;
pNexts[ pTails[p->pReprs[i].iRepr] ] = i;
@@ -480,8 +481,10 @@ void Gia_ManEquivPrintClasses( Gia_Man_t * p, int fVerbose, float Mem )
}
CounterX -= Gia_ManCoNum(p);
nLits = Gia_ManCiNum(p) + Gia_ManAndNum(p) - Counter - CounterX;
- Abc_Print( 1, "cst =%8d cls =%7d lit =%8d unused =%8d proof =%6d mem =%5.2f MB\n",
- Counter0, Counter, nLits, CounterX, Proved, (Mem == 0.0) ? 8.0*Gia_ManObjNum(p)/(1<<20) : Mem );
+// Abc_Print( 1, "cst =%8d cls =%7d lit =%8d unused =%8d proof =%6d mem =%5.2f MB\n",
+// Counter0, Counter, nLits, CounterX, Proved, (Mem == 0.0) ? 8.0*Gia_ManObjNum(p)/(1<<20) : Mem );
+ Abc_Print( 1, "cst =%8d cls =%7d lit =%8d unused =%8d proof =%6d\n",
+ Counter0, Counter, nLits, CounterX, Proved );
assert( Gia_ManEquivCheckLits( p, nLits ) );
if ( fVerbose )
{
@@ -1985,7 +1988,7 @@ Gia_Man_t * Gia_ManEquivToChoices( Gia_Man_t * p, int nSnapshots )
pNew->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p) );
pNew->pNexts = ABC_CALLOC( int, Gia_ManObjNum(p) );
for ( i = 0; i < Gia_ManObjNum(p); i++ )
- Gia_ObjSetRepr( pNew, i, GIA_VOID );
+ pNew->pReprs[i].iRepr = GIA_VOID;
Gia_ManFillValue( p );
Gia_ManConst0(p)->Value = 0;
Gia_ManForEachCi( p, pObj, i )
@@ -2587,6 +2590,294 @@ void Gia_ManFilterEquivsUsingLatches( Gia_Man_t * pGia, int fFlopsOnly, int fFlo
Abc_Print( 1, "The number of literals: Before = %d. After = %d.\n", iLitsOld, iLitsNew );
}
+/**Function*************************************************************
+
+ Synopsis [Changing node order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManChangeOrder_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( ~pObj->Value )
+ return pObj->Value;
+ if ( Gia_ObjIsCi(pObj) )
+ return pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ManChangeOrder_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ if ( Gia_ObjIsCo(pObj) )
+ return pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Gia_ManChangeOrder_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ return pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+Gia_Man_t * Gia_ManChangeOrder( Gia_Man_t * p )
+{
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj;
+ int i, k;
+ Gia_ManFillValue( p );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ManForEachClass( p, i )
+ Gia_ClassForEachObj( p, i, k )
+ Gia_ManChangeOrder_rec( pNew, p, Gia_ManObj(p, k) );
+ Gia_ManForEachConst( p, k )
+ Gia_ManChangeOrder_rec( pNew, p, Gia_ManObj(p, k) );
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManChangeOrder_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Gia_ManForEachCo( p, pObj, i )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ assert( Gia_ManObjNum(pNew) == Gia_ManObjNum(p) );
+ return pNew;
+}
+void Gia_ManTransferEquivs( Gia_Man_t * p, Gia_Man_t * pNew )
+{
+ Vec_Int_t * vClass;
+ int i, k, iNode, iRepr;
+ assert( Gia_ManObjNum(p) == Gia_ManObjNum(pNew) );
+ assert( p->pReprs != NULL );
+ assert( p->pNexts != NULL );
+ assert( pNew->pReprs == NULL );
+ assert( pNew->pNexts == NULL );
+ // start representatives
+ pNew->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(pNew) );
+ for ( i = 0; i < Gia_ManObjNum(pNew); i++ )
+ Gia_ObjSetRepr( pNew, i, GIA_VOID );
+ // iterate over constant candidates
+ Gia_ManForEachConst( p, i )
+ Gia_ObjSetRepr( pNew, Abc_Lit2Var(Gia_ManObj(p, i)->Value), 0 );
+ // iterate over class candidates
+ vClass = Vec_IntAlloc( 100 );
+ Gia_ManForEachClass( p, i )
+ {
+ Vec_IntClear( vClass );
+ Gia_ClassForEachObj( p, i, k )
+ Vec_IntPushUnique( vClass, Abc_Lit2Var(Gia_ManObj(p, k)->Value) );
+ assert( Vec_IntSize( vClass ) > 1 );
+ Vec_IntSort( vClass, 0 );
+ iRepr = Vec_IntEntry( vClass, 0 );
+ Vec_IntForEachEntryStart( vClass, iNode, k, 1 )
+ Gia_ObjSetRepr( pNew, iNode, iRepr );
+ }
+ Vec_IntFree( vClass );
+ pNew->pNexts = Gia_ManDeriveNexts( pNew );
+}
+void Gia_ManTransferTest( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj; int i;
+ Gia_Rpr_t * pReprs = p->pReprs; // representatives (for CIs and ANDs)
+ int * pNexts = p->pNexts; // next nodes in the equivalence classes
+ Gia_Man_t * pNew = Gia_ManChangeOrder(p);
+ //Gia_ManEquivPrintClasses( p, 1, 0 );
+ assert( Gia_ManObjNum(p) == Gia_ManObjNum(pNew) );
+ Gia_ManTransferEquivs( p, pNew );
+ p->pReprs = NULL;
+ p->pNexts = NULL;
+ // make new point to old
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ assert( !Abc_LitIsCompl(pObj->Value) );
+ Gia_ManObj(pNew, Abc_Lit2Var(pObj->Value))->Value = Abc_Var2Lit(i, 0);
+ }
+ Gia_ManTransferEquivs( pNew, p );
+ //Gia_ManEquivPrintClasses( p, 1, 0 );
+ for ( i = 0; i < Gia_ManObjNum(p); i++ )
+ pReprs[i].fProved = 0;
+ //printf( "%5d : %5d %5d %5d %5d\n", i, *(int*)&p->pReprs[i], *(int*)&pReprs[i], (int)p->pNexts[i], (int)pNexts[i] );
+ if ( memcmp(p->pReprs, pReprs, sizeof(int)*Gia_ManObjNum(p)) )
+ printf( "Verification of reprs failed.\n" );
+ else
+ printf( "Verification of reprs succeeded.\n" );
+ if ( memcmp(p->pNexts, pNexts, sizeof(int)*Gia_ManObjNum(p)) )
+ printf( "Verification of nexts failed.\n" );
+ else
+ printf( "Verification of nexts succeeded.\n" );
+ ABC_FREE( pNew->pReprs );
+ ABC_FREE( pNew->pNexts );
+ ABC_FREE( pReprs );
+ ABC_FREE( pNexts );
+ Gia_ManStop( pNew );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Converting AIG after SAT sweeping into AIG with choices.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec4_ManMarkIndependentClasses_rec( Gia_Man_t * p, int iObj )
+{
+ Gia_Obj_t * pObj;
+ assert( iObj > 0 );
+ if ( Gia_ObjIsTravIdPreviousId(p, iObj) ) // failed
+ return 0;
+ if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) // passed
+ return 1;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ pObj = Gia_ManObj( p, iObj );
+ if ( Gia_ObjIsCi(pObj) )
+ return 1;
+ assert( Gia_ObjIsAnd(pObj) );
+ if ( Cec4_ManMarkIndependentClasses_rec( p, Gia_ObjFaninId0(pObj, iObj) ) &&
+ Cec4_ManMarkIndependentClasses_rec( p, Gia_ObjFaninId1(pObj, iObj) ) )
+ return 1;
+ Gia_ObjSetTravIdPreviousId(p, iObj);
+ return 0;
+}
+int Cec4_ManMarkIndependentClasses( Gia_Man_t * p, Gia_Man_t * pNew )
+{
+ int iObjNew, iRepr, iObj, Res, fHaveChoices = 0;
+ Gia_ManCleanMark01(p);
+ Gia_ManForEachClass( p, iRepr )
+ {
+ Gia_ManIncrementTravId( pNew );
+ Gia_ManIncrementTravId( pNew );
+ iObjNew = Abc_Lit2Var( Gia_ManObj(p, iRepr)->Value );
+ Res = Cec4_ManMarkIndependentClasses_rec( pNew, iObjNew );
+ assert( Res == 1 );
+ Gia_ObjSetTravIdPreviousId( pNew, iObjNew );
+ p->pReprs[iRepr].fColorA = 1;
+ Gia_ClassForEachObj1( p, iRepr, iObj )
+ {
+ assert( p->pReprs[iObj].iRepr == (unsigned)iRepr );
+ iObjNew = Abc_Lit2Var( Gia_ManObj(p, iObj)->Value );
+ if ( Cec4_ManMarkIndependentClasses_rec( pNew, iObjNew ) )
+ {
+ p->pReprs[iObj].fColorA = 1;
+ fHaveChoices = 1;
+ }
+ Gia_ObjSetTravIdPreviousId( pNew, iObjNew );
+ }
+ }
+ return fHaveChoices;
+}
+int Cec4_ManSatSolverAnd_rec( Gia_Man_t * pCho, Gia_Man_t * p, Gia_Man_t * pNew, int iObj )
+{
+ return 0;
+}
+int Cec4_ManSatSolverChoices_rec( Gia_Man_t * pCho, Gia_Man_t * p, Gia_Man_t * pNew, int iObj )
+{
+ if ( !Gia_ObjIsClass(p, iObj) )
+ return Cec4_ManSatSolverAnd_rec( pCho, p, pNew, iObj );
+ else
+ {
+ Vec_Int_t * vLits = Vec_IntAlloc( 100 );
+ int i, iHead, iNext, iRepr = Gia_ObjIsHead(p, iObj) ? iObj : Gia_ObjRepr(p, iObj);
+ Gia_ClassForEachObj( p, iRepr, iObj )
+ if ( p->pReprs[iObj].fColorA )
+ Vec_IntPush( vLits, Cec4_ManSatSolverAnd_rec( pCho, p, pNew, iObj ) );
+ Vec_IntSort( vLits, 1 );
+ iHead = Abc_Lit2Var( Vec_IntEntry(vLits, 0) );
+ if ( Vec_IntSize(vLits) > 1 )
+ {
+ Vec_IntForEachEntryStart( vLits, iNext, i, 1 )
+ {
+ pCho->pSibls[iHead] = Abc_Lit2Var(iNext);
+ iHead = Abc_Lit2Var(iNext);
+ }
+ }
+ return Abc_LitNotCond( Vec_IntEntry(vLits, 0), Gia_ManObj(p, iHead)->fPhase );
+ }
+}
+Gia_Man_t * Cec4_ManSatSolverChoices( Gia_Man_t * p, Gia_Man_t * pNew )
+{
+ Gia_Man_t * pCho;
+ Gia_Obj_t * pObj;
+ int i, DriverId;
+ // mark topologically dependent equivalent nodes
+ if ( !Cec4_ManMarkIndependentClasses( p, pNew ) )
+ return Gia_ManDup( pNew );
+ // rebuild AIG in a different order with choices
+ pCho = Gia_ManStart( Gia_ManObjNum(pNew) );
+ pCho->pName = Abc_UtilStrsav( p->pName );
+ pCho->pSpec = Abc_UtilStrsav( p->pSpec );
+ pCho->pSibls = ABC_CALLOC( int, Gia_ManObjNum(pNew) );
+ Gia_ManFillValue(pNew);
+ Gia_ManConst0(pNew)->Value = 0;
+ for ( i = 0; i < Gia_ManCiNum(pNew); i++ )
+ Gia_ManCi(pNew, i)->Value = Gia_ManAppendCi( pCho );
+ Gia_ManForEachCoDriverId( p, DriverId, i )
+ Cec4_ManSatSolverChoices_rec( pCho, p, pNew, DriverId );
+ Gia_ManForEachCo( pNew, pObj, i )
+ pObj->Value = Gia_ManAppendCo( pCho, Gia_ObjFanin0Copy(pObj) );
+ Gia_ManSetRegNum( pCho, Gia_ManRegNum(p) );
+ return pCho;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Converting AIG after SAT sweeping into AIG with choices.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManCombSpecReduce( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj, * pRepr; int i, iLit;
+ Vec_Int_t * vXors = Vec_IntAlloc( 100 );
+ Gia_Man_t * pTemp, * pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ assert( p->pReprs && p->pNexts );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManLevelNum(p);
+ Gia_ManSetPhase(p);
+ Gia_ManFillValue(p);
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ Gia_ManHashAlloc( pNew );
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ pRepr = Gia_ObjReprObj( p, i );
+ if ( pRepr && Abc_Lit2Var(pObj->Value) != Abc_Lit2Var(pRepr->Value) )
+ {
+ //if ( Gia_ObjLevel(p, pRepr) > Gia_ObjLevel(p, pObj) + 50 )
+ //printf( "%d %d ", Gia_ObjLevel(p, pRepr), Gia_ObjLevel(p, pObj) );
+ iLit = Abc_LitNotCond( pRepr->Value, pObj->fPhase ^ pRepr->fPhase );
+ Vec_IntPush( vXors, Gia_ManHashXor( pNew, pObj->Value, iLit ) );
+ pObj->Value = iLit;
+ }
+ }
+ Gia_ManHashStop( pNew );
+ if ( Vec_IntSize(vXors) == 0 )
+ Vec_IntPush( vXors, 0 );
+ Vec_IntForEachEntry( vXors, iLit, i )
+ Gia_ManAppendCo( pNew, iLit );
+ Vec_IntFree( vXors );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+void Gia_ManCombSpecReduceTest( Gia_Man_t * p, char * pFileName )
+{
+ Gia_Man_t * pSrm = Gia_ManCombSpecReduce( p );
+ if ( pFileName == NULL )
+ pFileName = "test.aig";
+ Gia_AigerWrite( pSrm, pFileName, 0, 0, 0 );
+ Abc_Print( 1, "Speculatively reduced model was written into file \"%s\".\n", pFileName );
+ Gia_ManStop( pSrm );
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaFanout.c b/src/aig/gia/giaFanout.c
index 44e79ba2..8b104e9b 100644
--- a/src/aig/gia/giaFanout.c
+++ b/src/aig/gia/giaFanout.c
@@ -283,6 +283,89 @@ void Gia_ManStaticFanoutStart( Gia_Man_t * p )
Vec_IntFree( vCounts );
}
+
+/**Function*************************************************************
+
+ Synopsis [Compute the map of all edges.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ManStartMappingFanoutMap( Gia_Man_t * p, Vec_Int_t * vFanoutNums )
+{
+ Gia_Obj_t * pObj;
+ int i, iOffset = Gia_ManObjNum(p);
+ Vec_Int_t * vEdgeMap = Vec_IntAlloc( 2 * iOffset );
+ Vec_IntFill( vEdgeMap, iOffset, 0 );
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ if ( Vec_IntEntry(vFanoutNums, i) == 0 )
+ continue;
+ Vec_IntWriteEntry( vEdgeMap, i, iOffset );
+ iOffset += Vec_IntEntry( vFanoutNums, i );
+ Vec_IntFillExtra( vEdgeMap, iOffset, 0 );
+ }
+ //printf( "Fanout map is %.2fx larger than AIG manager.\n", 1.0*Vec_IntSize(vEdgeMap)/Gia_ManObjNum(p) );
+ return vEdgeMap;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates static fanout.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManStaticMappingFanoutStart( Gia_Man_t * p )
+{
+ Vec_Int_t * vCounts;
+ int * pRefsOld;
+ Gia_Obj_t * pObj, * pFanin;
+ int i, k, iFan, iFanout;
+ assert( p->vFanoutNums == NULL );
+ assert( p->vFanout == NULL );
+ // recompute reference counters
+ pRefsOld = p->pLutRefs; p->pLutRefs = NULL;
+ Gia_ManSetLutRefs(p);
+ p->vFanoutNums = Vec_IntAllocArray( p->pLutRefs, Gia_ManObjNum(p) );
+ p->pLutRefs = pRefsOld;
+ // start the fanout maps
+ p->vFanout = Gia_ManStartMappingFanoutMap( p, p->vFanoutNums );
+ // incrementally add fanouts
+ vCounts = Vec_IntStart( Gia_ManObjNum(p) );
+ Gia_ManForEachLut( p, i )
+ {
+ pObj = Gia_ManObj( p, i );
+ Gia_LutForEachFanin( p, i, iFan, k )
+ {
+ pFanin = Gia_ManObj( p, iFan );
+ iFanout = Vec_IntEntry( vCounts, iFan );
+ Gia_ObjSetFanout( p, pFanin, iFanout, pObj );
+ Vec_IntAddToEntry( vCounts, iFan, 1 );
+ }
+ }
+ Gia_ManForEachCo( p, pObj, i )
+ {
+ iFan = Gia_ObjFaninId0p(p, pObj);
+ pFanin = Gia_ManObj( p, iFan );
+ iFanout = Vec_IntEntry( vCounts, iFan );
+ Gia_ObjSetFanout( p, pFanin, iFanout, pObj );
+ Vec_IntAddToEntry( vCounts, iFan, 1 );
+ }
+ // double-check the current number of fanouts added
+ Gia_ManForEachObj( p, pObj, i )
+ assert( Vec_IntEntry(vCounts, i) == Gia_ObjFanoutNum(p, pObj) );
+ Vec_IntFree( vCounts );
+}
+
/**Function*************************************************************
Synopsis [Deallocates static fanout.]
diff --git a/src/aig/gia/giaFx.c b/src/aig/gia/giaFx.c
index c6eae6c7..032ae5fc 100644
--- a/src/aig/gia/giaFx.c
+++ b/src/aig/gia/giaFx.c
@@ -460,7 +460,11 @@ Gia_Man_t * Gia_ManPerformFx( Gia_Man_t * p, int nNewNodesMax, int LitCountMax,
Vec_Wec_t * vCubes;
Vec_Str_t * vCompl;
if ( Gia_ManAndNum(p) == 0 )
- return Gia_ManDup(p);
+ {
+ pNew = Gia_ManDup(p);
+ Gia_ManTransferTiming( pNew, p );
+ return pNew;
+ }
// abctime clk;
assert( Gia_ManHasMapping(p) );
// collect information
diff --git a/src/aig/gia/giaGen.c b/src/aig/gia/giaGen.c
index 94d561cc..cb56ef64 100644
--- a/src/aig/gia/giaGen.c
+++ b/src/aig/gia/giaGen.c
@@ -20,6 +20,7 @@
#include "gia.h"
#include "misc/util/utilTruth.h"
+#include "misc/extra/extra.h"
ABC_NAMESPACE_IMPL_START
@@ -35,6 +36,64 @@ ABC_NAMESPACE_IMPL_START
/**Function*************************************************************
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_DeriveAig( Vec_Wrd_t * vSims, Vec_Str_t * vSimsOut )
+{
+ int nInputs = 32*32*24;
+ int nWords = nInputs/64;
+ int nExamps = 64;
+ int i, e, iLitOut[10] = {0};
+ Gia_Man_t * pNew;
+ assert( Vec_WrdSize(vSims) % nInputs == 0 );
+ pNew = Gia_ManStart( nInputs * nExamps + 10000 );
+ for ( i = 0; i < nInputs; i++ )
+ Gia_ManAppendCi( pNew );
+ Gia_ManHashStart( pNew );
+ for ( e = 0; e < nExamps; e++ )
+ {
+ int Class = Vec_StrEntry( vSimsOut, e );
+ int This = 1;
+ word * pSim = Vec_WrdEntryP( vSims, e*nWords );
+ for ( i = 0; i < nInputs; i++ )
+ This = Gia_ManHashAnd( pNew, This, Abc_Var2Lit(i+1, !Abc_TtGetBit(pSim, i)) );
+ assert( Class >= 0 && Class <= 9 );
+ iLitOut[Class] = Gia_ManHashOr( pNew, iLitOut[Class], This );
+ //printf( "Finished example %d\n", e );
+ }
+ for ( i = 0; i < 10; i++ )
+ Gia_ManAppendCo( pNew, iLitOut[i] );
+ //pNew = Gia_ManCleanup( pTemp = pNew );
+ //Gia_ManStop( pTemp );
+ return pNew;
+}
+void Gia_DeriveAigTest()
+{
+ extern int Gia_ManReadCifar10File( char * pFileName, Vec_Wrd_t ** pvSimsIn, Vec_Str_t ** pvSimsOut, int * pnExamples );
+ char pFileName[100] = "test";
+ Vec_Wrd_t * vSimsIn;
+ Vec_Str_t * vSimsOut;
+ int nExamples = 0;
+ int nInputs = Gia_ManReadCifar10File( pFileName, &vSimsIn, &vSimsOut, &nExamples );
+ Gia_Man_t * pThis = Gia_DeriveAig( vSimsIn, vSimsOut );
+ Gia_AigerWrite( pThis, "examples64.aig", 0, 0, 0 );
+ printf( "Dumped file \"%s\".\n", "examples64.aig" );
+ Gia_ManStop( pThis );
+ Vec_WrdFree( vSimsIn );
+ Vec_StrFree( vSimsOut );
+ nInputs = 0;
+}
+
+
+/**Function*************************************************************
+
Synopsis [Populate internal simulation info.]
Description []
@@ -136,6 +195,38 @@ int Gia_ManSimulateWordsInit( Gia_Man_t * p, Vec_Wrd_t * vSimsIn )
return 1;
}
+Vec_Wrd_t * Gia_ManSimulateWordsOut( Gia_Man_t * p, Vec_Wrd_t * vSimsIn )
+{
+ Gia_Obj_t * pObj; int i, Id;
+ int nWords = Vec_WrdSize(vSimsIn) / Gia_ManCiNum(p);
+ Vec_Wrd_t * vSimsOut = Vec_WrdStart( nWords * Gia_ManCoNum(p) );
+ assert( Vec_WrdSize(vSimsIn) == nWords * Gia_ManCiNum(p) );
+ // allocate simulation info for one timeframe
+ Vec_WrdFreeP( &p->vSims );
+ p->vSims = Vec_WrdStart( Gia_ManObjNum(p) * nWords );
+ p->nSimWords = nWords;
+ // set input sim info
+ Gia_ManForEachCiId( p, Id, i )
+ memcpy( Vec_WrdEntryP(p->vSims, Id*nWords), Vec_WrdEntryP(vSimsIn, i*nWords), sizeof(word)*nWords );
+ // perform simulation
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ if ( Gia_ObjIsAnd(pObj) )
+ Gia_ManObjSimAnd( p, i );
+ else if ( Gia_ObjIsCi(pObj) )
+ continue;
+ else if ( Gia_ObjIsCo(pObj) )
+ Gia_ManObjSimPo( p, i );
+ else assert( 0 );
+ }
+ // set output sim info
+ Gia_ManForEachCoId( p, Id, i )
+ memcpy( Vec_WrdEntryP(vSimsOut, i*nWords), Vec_WrdEntryP(p->vSims, Id*nWords), sizeof(word)*nWords );
+ Vec_WrdFreeP( &p->vSims );
+ p->nSimWords = -1;
+ return vSimsOut;
+}
+
/**Function*************************************************************
Synopsis [Dump data files.]
@@ -443,6 +534,224 @@ void Gia_ManCompareValues( Gia_Man_t * p, Vec_Wrd_t * vSimsIn, Vec_Int_t * vValu
SeeAlso []
***********************************************************************/
+void Gia_ManReadSimFile( char * pFileName, int * pnIns, int * pnOuts, int * pnPats, Vec_Wrd_t ** pvSimsIn, Vec_Wrd_t ** pvSimsOut )
+{
+ char * pTemp, pBuffer[1000];
+ Vec_Wrd_t * vSimsIn = NULL, * vSimsOut = NULL;
+ int i, iPat = 0, nWordsI, nWordsO, nIns = -1, nOuts = -1, nPats = -1;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return;
+ }
+ while ( fgets( pBuffer, 1000, pFile ) != NULL )
+ {
+ pTemp = pBuffer;
+ if ( pTemp[0] == '\0' || pTemp[0] == '#' || pTemp[0] == ' ' )
+ continue;
+ if ( pTemp[0] != '.' )
+ break;
+ if ( pTemp[1] == 'i' )
+ nIns = atoi(pTemp+2);
+ else if ( pTemp[1] == 'o' )
+ nOuts = atoi(pTemp+2);
+ else if ( pTemp[1] == 'p' )
+ {
+ if ( atoi(pTemp+2) % 64 == 0 )
+ printf( "Expecting the number of patterns divisible by 64.\n" );
+ nPats = atoi(pTemp+2) / 64;
+ }
+ }
+ if ( nIns == -1 || nOuts == -1 || nPats == -1 )
+ {
+ printf( "Some of the parameters (inputs, outputs, patterns) is not specified.\n" );
+ fclose( pFile );
+ return;
+ }
+ nWordsI = (nIns + 63) / 64;
+ nWordsO = (nOuts + 63) / 64;
+
+ vSimsIn = Vec_WrdStart( nPats * nWordsI );
+ vSimsOut = Vec_WrdStart( nPats * nWordsO );
+ rewind(pFile);
+ while ( fgets( pBuffer, 1000, pFile ) != NULL )
+ {
+ if ( pTemp[0] == '\0' || pTemp[0] == '.' )
+ continue;
+ for ( i = 0, pTemp = pBuffer; *pTemp != '\n'; pTemp++ )
+ if ( *pTemp == '0' || *pTemp == '1' )
+ {
+ if ( *pTemp == '1' )
+ {
+ if ( i < nIns )
+ Abc_TtSetBit( Vec_WrdEntryP(vSimsIn, nWordsI*iPat), i );
+ else
+ Abc_TtSetBit( Vec_WrdEntryP(vSimsOut, nWordsO*iPat), i-nIns );
+ }
+ i++;
+ }
+ iPat++;
+ }
+ if ( iPat != nPats )
+ printf( "The number of patterns does not match.\n" );
+ fclose( pFile );
+ *pnIns = nIns;
+ *pnOuts = nOuts;
+ *pnPats = nPats;
+ *pvSimsIn = vSimsIn;
+ *pvSimsOut = vSimsOut;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManReadBinaryFile( char * pFileName, Vec_Wrd_t ** pvSimsIn, Vec_Str_t ** pvSimsOut )
+{
+ extern void Extra_BitMatrixTransposeP( Vec_Wrd_t * vSimsIn, int nWordsIn, Vec_Wrd_t * vSimsOut, int nWordsOut );
+ int nFileSize = Extra_FileSize( pFileName );
+ int nExamples = 1 << 16;
+ int nInputs = nFileSize / nExamples - 1;
+ int nWords = (8*nInputs + 63)/64, i;
+ char * pContents = Extra_FileReadContents( pFileName );
+ Vec_Wrd_t * vSimsIn = Vec_WrdStart( nExamples * nWords );
+ Vec_Wrd_t * vSimsIn2 = Vec_WrdStart( nExamples * nWords );
+ Vec_Str_t * vSimsOut = Vec_StrAlloc( nExamples );
+ assert( nFileSize % nExamples == 0 );
+ for ( i = 0; i < nExamples; i++ )
+ {
+ memcpy( (void *)Vec_WrdEntryP(vSimsIn, i*nWords), (void *)(pContents + i*(nInputs+1)), nInputs );
+ Vec_StrPush( vSimsOut, pContents[i*(nInputs+1) + nInputs] );
+ }
+ Extra_BitMatrixTransposeP( vSimsIn, nWords, vSimsIn2, nExamples/64 );
+ Vec_WrdShrink( vSimsIn2, 8*nInputs * nExamples/64 );
+ Vec_WrdFree( vSimsIn );
+ *pvSimsIn = vSimsIn2;
+ *pvSimsOut = vSimsOut;
+ ABC_FREE( pContents );
+ return nInputs;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSimLogStats2( Gia_Man_t * p, char * pDumpFile, int Total, int nPositives, float ErrorTotal, float GuessTotal )
+{
+ FILE * pTable = fopen( pDumpFile, "wb" );
+ fprintf( pTable, "{\n" );
+ fprintf( pTable, " \"name\" : \"%s\",\n", p->pName );
+ fprintf( pTable, " \"input\" : %d,\n", Gia_ManCiNum(p) );
+ fprintf( pTable, " \"output\" : %d,\n", Gia_ManCoNum(p) );
+ fprintf( pTable, " \"and\" : %d,\n", Gia_ManAndNum(p) );
+ fprintf( pTable, " \"level\" : %d,\n", Gia_ManLevelNum(p) );
+ fprintf( pTable, " \"total\" : %d,\n", Total );
+ fprintf( pTable, " \"positive\" : %d,\n", nPositives );
+ fprintf( pTable, " \"error\" : %e,\n", ErrorTotal );
+ fprintf( pTable, " \"guess\" : %e\n", GuessTotal );
+ fprintf( pTable, "}\n" );
+ fclose( pTable );
+}
+int Gia_ManGetExampleValue( word ** ppSims, int nSims, int iExample )
+{
+ int o, Sign = 0, ValueSim = 0;
+ for ( o = 0; o < nSims; o++ )
+ if ( (Sign = Abc_TtGetBit(ppSims[o], iExample)) )
+ ValueSim |= (1 << o);
+ if ( Sign )
+ ValueSim |= ~0 << nSims;
+ return ValueSim;
+}
+void Gia_ManCompareValues2( int nInputs, Gia_Man_t * p, Vec_Wrd_t * vSimsIn, Vec_Str_t * vValues, char * pDumpFile )
+{
+ float Error1, ErrorTotal = 0, Guess1, GuessTotal = 0;
+ int i, o, nPositives = 0, nWords = Vec_WrdSize(vSimsIn) / Gia_ManCiNum(p);
+ word ** ppSims = ABC_CALLOC( word *, Gia_ManCoNum(p) );
+ Gia_Obj_t * pObj;
+ assert( nWords == (1<<10) );
+ assert( Vec_WrdSize(vSimsIn) % Gia_ManCiNum(p) == 0 );
+ assert( Vec_StrSize(vValues) == (1 << 16) );
+ assert( nWords*64 == (1 << 16) );
+ // simulate examples given in vSimsIn
+ Gia_ManSimulateWordsInit( p, vSimsIn );
+ // collect simulation info for the outputs
+ assert( p->nSimWords == nWords );
+ Gia_ManForEachCo( p, pObj, o )
+ ppSims[o] = Gia_ManObjSim( p, Gia_ObjId(p, pObj) );
+ // compare the output for each example
+ for ( i = 0; i < nWords*64; i++ )
+ {
+ int ValueGold = (int)Vec_StrEntry( vValues, i );
+ int ValueImpl = Gia_ManGetExampleValue( ppSims, Gia_ManCoNum(p), i );
+ // compute error for this example
+ Error1 = (float)(ValueGold - ValueImpl)/256;
+ ErrorTotal += Error1 * Error1;
+ // compute error of zero-output
+ Guess1 = ValueGold > 0 ? Abc_AbsInt(ValueImpl) : 0;
+ GuessTotal += Guess1 * Guess1;
+ // count positive values (disregard negative values due to Leaky ReLU)
+ nPositives += (int)(ValueGold > 0);
+ }
+ ABC_FREE( ppSims );
+ printf( "Total = %6d. Positive = %6d. (%6.2f %%) Errors = %e. Guess = %e. (%6.2f %%)\n",
+ Vec_StrSize(vValues), nPositives, 100.0*nPositives/Vec_StrSize(vValues),
+ ErrorTotal, GuessTotal, 100.0*ErrorTotal/GuessTotal );
+ if ( pDumpFile == NULL )
+ return;
+ Gia_ManSimLogStats2( p, pDumpFile, Vec_StrSize(vValues), nPositives, ErrorTotal, GuessTotal );
+ printf( "Finished dumping statistics into file \"%s\".\n", pDumpFile );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManTestWordFileUnused( Gia_Man_t * p, char * pFileName, char * pDumpFile )
+{
+ Vec_Wrd_t * vSimsIn;
+ Vec_Str_t * vSimsOut;
+ int nInputs = Gia_ManReadBinaryFile( pFileName, &vSimsIn, &vSimsOut );
+ if ( Gia_ManCiNum(p) == 8*nInputs )
+ Gia_ManCompareValues2( nInputs, p, vSimsIn, vSimsOut, pDumpFile );
+ else
+ printf( "The number of inputs in the AIG (%d) and in the file (%d) does not match.\n", Gia_ManCiNum(p), 8*nInputs );
+ Vec_WrdFree( vSimsIn );
+ Vec_StrFree( vSimsOut );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
void Gia_ManTestOneFile( Gia_Man_t * p, char * pFileName, char * pDumpFile )
{
Vec_Wrd_t * vSimsIn;
@@ -463,6 +772,158 @@ void Gia_ManTestOneFile( Gia_Man_t * p, char * pFileName, char * pDumpFile )
Vec_IntFree( vValues );
}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManReadCifar10File( char * pFileName, Vec_Wrd_t ** pvSimsIn, Vec_Str_t ** pvSimsOut, int * pnExamples )
+{
+ int nPixels = 32*32*3;
+ int nFileSize = Extra_FileSize( pFileName );
+ int nExamples = nFileSize / (nPixels + 1);
+ int nWordsIn = nPixels / 8;
+ int nWordsOut = (nExamples + 63) / 64; int e;
+ if ( nFileSize % (nPixels + 1) )
+ {
+ printf( "The input file \"%s\" with image data does not appear to be in CIFAR10 format.\n", pFileName );
+ return 0;
+ }
+ else
+ {
+ Vec_Wrd_t * vSimsIn = Vec_WrdStart( 64 * nWordsOut * nWordsIn );
+ Vec_Str_t * vSimsOut = Vec_StrAlloc( 64 * nWordsOut );
+ unsigned char * pBuffer = ABC_ALLOC( unsigned char, nFileSize );
+ FILE * pFile = fopen( pFileName, "rb" );
+ int Value = fread( pBuffer, 1, nFileSize, pFile );
+ fclose( pFile );
+ assert( Value == nFileSize );
+ printf( "Successfully read %5.2f MB (%d images) from file \"%s\".\n", (float)nFileSize/(1<<20), nExamples, pFileName );
+ for ( e = 0; e < nExamples; e++ )
+ {
+ Vec_StrPush( vSimsOut, (char)pBuffer[e*(nPixels + 1)] );
+ memcpy( Vec_WrdEntryP(vSimsIn, e*nWordsIn), pBuffer + e*(nPixels + 1) + 1, nPixels );
+ }
+ ABC_FREE( pBuffer );
+ for ( ; e < 64 * nWordsOut; e++ )
+ Vec_StrPush( vSimsOut, (char)0 );
+ memset( Vec_WrdEntryP(vSimsIn, nExamples*nWordsIn), 0, (64*nWordsOut - nExamples)*nWordsIn );
+ *pvSimsIn = vSimsIn;
+ *pvSimsOut = vSimsOut;
+ *pnExamples = nExamples;
+ return 8*nPixels;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManSimulateBatch( Gia_Man_t * p, Vec_Wrd_t * vSimsIn, Vec_Str_t * vSimsOut, Vec_Str_t * vSimsOut2, int b, int Limit )
+{
+ Gia_Obj_t * pObj;
+ word * ppSims[10];
+ int i, o, Count = 0;
+ assert( Gia_ManCiNum(p) == Vec_WrdSize(vSimsIn) );
+ assert( Gia_ManCoNum(p) == 10 );
+ Gia_ManSimulateWordsInit( p, vSimsIn );
+ Gia_ManForEachCo( p, pObj, o )
+ ppSims[o] = Gia_ManObjSim( p, Gia_ObjId(p, pObj) );
+ for ( i = 0; i < Limit; i++ )
+ {
+ int Value = 0;
+ for ( o = 0; o < 10; o++ )
+ if ( Abc_TtGetBit(ppSims[o], i) )
+ {
+ Value = o;
+ break;
+ }
+ Vec_StrPush( vSimsOut, (char)Value );
+ Count += Value == (int)Vec_StrEntry( vSimsOut2, 64*b+i );
+ }
+ return Count;
+}
+Vec_Str_t * Gia_ManSimulateAll( Gia_Man_t * p, Vec_Wrd_t * vSimsIn, Vec_Str_t * vSimsOut, int nExamples, int fVerbose )
+{
+ extern void Extra_BitMatrixTransposeP( Vec_Wrd_t * vSimsIn, int nWordsIn, Vec_Wrd_t * vSimsOut, int nWordsOut );
+ Vec_Str_t * vRes = Vec_StrAlloc( 100 ); int b, Count;
+ int nWordsIn = 32*32*24/64; // one image
+ int nWordsOut = Vec_WrdSize(vSimsIn)/(nWordsIn*64);
+ assert( Vec_WrdSize(vSimsIn) % nWordsIn == 0 );
+ for ( b = 0; b < nWordsOut; b++ )
+ {
+ int Limit = b == nWordsOut-1 ? nExamples-b*64 : 64;
+ Vec_Wrd_t * vSimsIn1 = Vec_WrdStart( nWordsIn*64 );
+ Vec_Wrd_t * vSimsIn2 = Vec_WrdStart( nWordsIn*64 );
+ memcpy( Vec_WrdArray(vSimsIn1), Vec_WrdEntryP(vSimsIn, b*nWordsIn*64), sizeof(word)*nWordsIn*64 );
+ Extra_BitMatrixTransposeP( vSimsIn1, nWordsIn, vSimsIn2, 1 );
+ Vec_WrdFree( vSimsIn1 );
+ Count = Gia_ManSimulateBatch( p, vSimsIn2, vRes, vSimsOut, b, Limit );
+ Vec_WrdFree( vSimsIn2 );
+ if ( fVerbose )
+ printf( "Finished simulating word %4d (out of %4d). Correct = %2d. (Limit = %2d.)\n", b, nWordsOut, Count, Limit );
+ }
+ assert( Vec_StrSize(vRes) == nExamples );
+ return vRes;
+}
+void Gia_ManCompareCifar10Values( Gia_Man_t * p, Vec_Str_t * vRes, Vec_Str_t * vSimsOut, char * pDumpFile, int nExamples )
+{
+ int i, Guess = (nExamples+9)/10, Count = 0;
+ for ( i = 0; i < nExamples; i++ )
+ {
+ char ValueReal = Vec_StrEntry(vRes, i);
+ char ValueGold = Vec_StrEntry(vSimsOut, i);
+ if ( ValueReal == ValueGold )
+ Count++;
+ }
+ printf( "Summary: Total = %6d. Errors = %6d. Correct = %6d. (%6.2f %%) Naive guess = %6d. (%6.2f %%)\n",
+ nExamples, nExamples - Count,
+ Count, 100.0*Count/nExamples,
+ Guess, 100.0*Guess/nExamples);
+ if ( pDumpFile == NULL )
+ return;
+ Gia_ManSimLogStats( p, pDumpFile, nExamples, Count, Guess );
+ printf( "Finished dumping statistics into file \"%s\".\n", pDumpFile );
+}
+void Gia_ManTestWordFile( Gia_Man_t * p, char * pFileName, char * pDumpFile, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ Vec_Wrd_t * vSimsIn;
+ Vec_Str_t * vSimsOut;
+ int i, nExamples = 0;
+ int nInputs = Gia_ManReadCifar10File( pFileName, &vSimsIn, &vSimsOut, &nExamples );
+ char * pKnownFileNames[3] = {"small.aig", "medium.aig", "large.aig"};
+ int pLimitFileSizes[3] = {10000, 100000, 1000000};
+ for ( i = 0; i < 3; i++ )
+ if ( p->pSpec && !strncmp(p->pSpec, pKnownFileNames[i], 5) && Gia_ManAndNum(p) > pLimitFileSizes[i] )
+ printf( "Warning: The input file \"%s\" contains more than %d internal and-nodes.\n", pKnownFileNames[i], pLimitFileSizes[i] );
+ if ( nInputs == Gia_ManCiNum(p) )
+ {
+ Vec_Str_t * vRes = Gia_ManSimulateAll( p, vSimsIn, vSimsOut, nExamples, fVerbose );
+ Gia_ManCompareCifar10Values( p, vRes, vSimsOut, pDumpFile, nExamples );
+ Vec_StrFree( vRes );
+ }
+ else
+ printf( "The primary input counts in the AIG (%d) and in the image data (%d) do not match.\n", Gia_ManCiNum(p), nInputs );
+ Vec_WrdFree( vSimsIn );
+ Vec_StrFree( vSimsOut );
+ Abc_PrintTime( 1, "Total checking time", Abc_Clock() - clk );
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaHash.c b/src/aig/gia/giaHash.c
index 64e39613..063cfd31 100644
--- a/src/aig/gia/giaHash.c
+++ b/src/aig/gia/giaHash.c
@@ -814,6 +814,328 @@ int Gia_ManHashDualMiter( Gia_Man_t * p, Vec_Int_t * vOuts )
return iRes;
}
+
+
+/**Function*************************************************************
+
+ Synopsis [Create multi-input tree.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int * Gia_ManCollectLiterals( int nVars )
+{
+ int i, * pRes = ABC_CALLOC( int, nVars );
+ for ( i = 0; i < nVars; i++ )
+ pRes[i] = Abc_Var2Lit( i+1, 0 );
+ return pRes;
+}
+int * Gia_ManGenZero( int nBits )
+{
+ return ABC_CALLOC( int, nBits );
+}
+int * Gia_ManGenPerm( int nBits )
+{
+ int i, * pRes = ABC_CALLOC( int, nBits );
+ srand( time(NULL) );
+ for ( i = 0; i < nBits; i++ )
+ pRes[i] = i;
+ for ( i = 0; i < nBits; i++ )
+ {
+ int iPerm = rand() % nBits;
+ ABC_SWAP( int, pRes[i], pRes[iPerm] );
+ }
+ return pRes;
+}
+int * Gia_ManGenPerm2( int nBits )
+{
+ int i, * pRes = ABC_CALLOC( int, nBits );
+ srand( time(NULL) );
+ for ( i = 0; i < nBits; i++ )
+ pRes[i] = rand() % nBits;
+ return pRes;
+}
+int Gia_ManMultiCheck( int * pPerm, int nPerm )
+{
+ int i;
+ for ( i = 1; i < nPerm; i++ )
+ if ( pPerm[i-1] <= pPerm[i] )
+ return 0;
+ return 1;
+}
+int Gia_ManMultiInputPerm( Gia_Man_t * pNew, int * pVars, int nVars, int * pPerm, int fOr, int fXor )
+{
+ int fPrint = 1;
+ int i, iLit;
+ if ( fPrint )
+ {
+ for ( i = 0; i < nVars; i++ )
+ printf( "%d ", pPerm[i] );
+ printf( "\n" );
+ }
+ while ( 1 )
+ {
+ for ( i = 1; i < nVars; i++ )
+ if ( pPerm[i-1] >= pPerm[i] )
+ break;
+ if ( i == nVars )
+ break;
+ assert( pPerm[i-1] >= pPerm[i] );
+ if ( pPerm[i-1] > pPerm[i] )
+ {
+ ABC_SWAP( int, pPerm[i-1], pPerm[i] );
+ ABC_SWAP( int, pVars[i-1], pVars[i] );
+ }
+ else
+ {
+ assert( pPerm[i-1] == pPerm[i] );
+ pPerm[i-1]++;
+ if ( fXor )
+ pVars[i-1] = Gia_ManHashXor( pNew, pVars[i-1], pVars[i] );
+ else if ( fOr )
+ pVars[i-1] = Gia_ManHashOr( pNew, pVars[i-1], pVars[i] );
+ else
+ pVars[i-1] = Gia_ManHashAnd( pNew, pVars[i-1], pVars[i] );
+ for ( i = i+1; i < nVars; i++ )
+ {
+ pPerm[i-1] = pPerm[i];
+ pVars[i-1] = pVars[i];
+ }
+ nVars--;
+ }
+ if ( fPrint )
+ {
+ for ( i = 0; i < nVars; i++ )
+ printf( "%d ", pPerm[i] );
+ printf( "\n" );
+ }
+ }
+ iLit = pVars[0];
+ for ( i = 1; i < nVars; i++ )
+ if ( fXor )
+ iLit = Gia_ManHashXor( pNew, iLit, pVars[i] );
+ else if ( fOr )
+ iLit = Gia_ManHashOr( pNew, iLit, pVars[i] );
+ else
+ iLit = Gia_ManHashAnd( pNew, iLit, pVars[i] );
+ return iLit;
+}
+Gia_Man_t * Gia_ManMultiInputTest( int nBits )
+{
+ Gia_Man_t * pNew;
+ int i, iRes, * pPerm;
+ int * pMulti = Gia_ManCollectLiterals( nBits );
+ pNew = Gia_ManStart( 1000 );
+ pNew->pName = Abc_UtilStrsav( "multi" );
+ for ( i = 0; i < nBits; i++ )
+ Gia_ManAppendCi( pNew );
+ Gia_ManHashAlloc( pNew );
+ pPerm = Gia_ManGenPerm2( nBits );
+ //pPerm = Gia_ManGenZero( nBits );
+ iRes = Gia_ManMultiInputPerm( pNew, pMulti, nBits, pPerm, 0, 0 );
+ Gia_ManAppendCo( pNew, iRes );
+ ABC_FREE( pPerm );
+ ABC_FREE( pMulti );
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Create MUX tree.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManCube( Gia_Man_t * pNew, int Vars, int nVars, int * pLits )
+{
+ int i, iLit = 1;
+ for ( i = 0; i < nVars; i++ )
+ iLit = Gia_ManHashAnd( pNew, iLit, Abc_LitNotCond(pLits[i], !((Vars >> i) & 1)) );
+ return iLit;
+}
+int Gia_ManMuxTree_rec( Gia_Man_t * pNew, int * pCtrl, int nCtrl, int * pData )
+{
+ int iLit0, iLit1;
+ if ( nCtrl == 0 )
+ return pData[0];
+ iLit0 = Gia_ManMuxTree_rec( pNew, pCtrl, nCtrl-1, pData );
+ iLit1 = Gia_ManMuxTree_rec( pNew, pCtrl, nCtrl-1, pData + (1<<(nCtrl-1)) );
+ return Gia_ManHashMux( pNew, pCtrl[nCtrl-1], iLit1, iLit0 );
+}
+void Gia_ManUsePerm( int * pTree, int nBits, int * pPerm )
+{
+ int fPrint = 0;
+ int i, k, m, nVars = nBits + (1 << nBits);
+ if ( fPrint )
+ {
+ for ( i = 0; i < nVars; i++ )
+ printf( "%d ", pPerm[i] );
+ printf( "\n" );
+ }
+ for ( i = 0; i < nBits; i++ )
+ {
+ for ( k = i+1; k < nBits; k++ )
+ if ( pPerm[i] > pPerm[k] )
+ break;
+ if ( k == nBits )
+ break;
+ assert( pPerm[i] > pPerm[k] );
+ ABC_SWAP( int, pPerm[i], pPerm[k] );
+ ABC_SWAP( int, pTree[i], pTree[k] );
+ for ( m = 0; m < (1 << nBits); m++ )
+ if ( ((m >> i) & 1) && !((m >> k) & 1) )
+ {
+ ABC_SWAP( int, pTree[nBits+m], pTree[nBits+(m^(1<<i)^(1<<k))] );
+ ABC_SWAP( int, pPerm[nBits+m], pPerm[nBits+(m^(1<<i)^(1<<k))] );
+ }
+ }
+ if ( fPrint )
+ {
+ for ( i = 0; i < nVars; i++ )
+ printf( "%d ", pPerm[i] );
+ printf( "\n" );
+ }
+}
+int Gia_ManFindCond( int * pLits, int nBits, int iLate1, int iLate2 )
+{
+ int i;
+ assert( iLate1 != iLate2 );
+ for ( i = 0; i < nBits; i++ )
+ if ( (((iLate1 ^ iLate2) >> i) & 1) )
+ return Abc_LitNotCond( pLits[i], (iLate1 >> i) & 1 );
+ return -1;
+}
+int Gia_ManLatest( int * pPerm, int nVars, int iPrev1, int iPrev2, int iPrev3 )
+{
+ int i, Value = -1, iLate = -1;
+ for ( i = 0; i < nVars; i++ )
+ if ( Value < pPerm[i] && i != iPrev1 && i != iPrev2 && i != iPrev3 )
+ {
+ Value = pPerm[i];
+ iLate = i;
+ }
+ return iLate;
+}
+int Gia_ManEarliest( int * pPerm, int nVars )
+{
+ int i, Value = ABC_INFINITY, iLate = -1;
+ for ( i = 0; i < nVars; i++ )
+ if ( Value > pPerm[i] )
+ {
+ Value = pPerm[i];
+ iLate = i;
+ }
+ return iLate;
+}
+int Gia_ManDecompOne( Gia_Man_t * pNew, int * pTree, int nBits, int * pPerm, int iLate )
+{
+ int iRes, iData;
+ assert( iLate >= 0 && iLate < (1<<nBits) );
+ iData = pTree[nBits+iLate];
+ pTree[nBits+iLate] = pTree[nBits+(iLate^1)];
+ iRes = Gia_ManMuxTree_rec( pNew, pTree, nBits, pTree+nBits );
+ return Gia_ManHashMux( pNew, Gia_ManCube(pNew, iLate, nBits, pTree), iData, iRes );
+}
+int Gia_ManDecompTwo( Gia_Man_t * pNew, int * pTree, int nBits, int * pPerm, int iLate1, int iLate2 )
+{
+ int iRes, iData1, iData2, iData, iCond, iCond2;
+ assert( iLate1 != iLate2 );
+ assert( iLate1 >= 0 && iLate1 < (1<<nBits) );
+ assert( iLate2 >= 0 && iLate2 < (1<<nBits) );
+ iData1 = pTree[nBits+iLate1];
+ iData2 = pTree[nBits+iLate2];
+ pTree[nBits+iLate1] = pTree[nBits+(iLate1^1)];
+ pTree[nBits+iLate2] = pTree[nBits+(iLate2^1)];
+ iRes = Gia_ManMuxTree_rec( pNew, pTree, nBits, pTree+nBits );
+ iCond = Gia_ManHashOr( pNew, Gia_ManCube(pNew, iLate1, nBits, pTree), Gia_ManCube(pNew, iLate2, nBits, pTree) );
+ iCond2 = Gia_ManFindCond( pTree, nBits, iLate1, iLate2 );
+ iData = Gia_ManHashMux( pNew, iCond2, iData2, iData1 );
+ return Gia_ManHashMux( pNew, iCond, iData, iRes );
+}
+int Gia_ManDecompThree( Gia_Man_t * pNew, int * pTree, int nBits, int * pPerm, int iLate1, int iLate2, int iLate3 )
+{
+ int iRes, iData1, iData2, iData3, iCube1, iCube2, iCube3, iCtrl0, iCtrl1, iMux10, iMux11;
+ assert( iLate1 != iLate2 );
+ assert( iLate1 != iLate3 );
+ assert( iLate2 != iLate3 );
+ assert( iLate1 >= 0 && iLate1 < (1<<nBits) );
+ assert( iLate2 >= 0 && iLate2 < (1<<nBits) );
+ assert( iLate3 >= 0 && iLate3 < (1<<nBits) );
+ iData1 = pTree[nBits+iLate1];
+ iData2 = pTree[nBits+iLate2];
+ iData3 = pTree[nBits+iLate3];
+ pTree[nBits+iLate1] = pTree[nBits+(iLate1^1)];
+ pTree[nBits+iLate2] = pTree[nBits+(iLate2^1)];
+ pTree[nBits+iLate3] = pTree[nBits+(iLate3^1)];
+ iRes = Gia_ManMuxTree_rec( pNew, pTree, nBits, pTree+nBits );
+ iCube1 = Gia_ManCube( pNew, iLate1, nBits, pTree );
+ iCube2 = Gia_ManCube( pNew, iLate2, nBits, pTree );
+ iCube3 = Gia_ManCube( pNew, iLate3, nBits, pTree );
+ iCtrl0 = Gia_ManHashOr( pNew, iCube1, iCube3 );
+ iCtrl1 = Gia_ManHashOr( pNew, iCube2, iCube3 );
+ iMux10 = Gia_ManHashMux( pNew, iCtrl0, iData1, iRes );
+ iMux11 = Gia_ManHashMux( pNew, iCtrl0, iData3, iData2 );
+ return Gia_ManHashMux( pNew, iCtrl1, iMux11, iMux10 );
+}
+int Gia_ManDecomp( Gia_Man_t * pNew, int * pTree, int nBits, int * pPerm )
+{
+ if ( nBits == 2 )
+ return Gia_ManMuxTree_rec( pNew, pTree, nBits, pTree+nBits );
+ else
+ {
+ int iBase = Gia_ManEarliest( pPerm+nBits, 1<<nBits ), BaseValue = pPerm[nBits+iBase];
+ int iLate1 = Gia_ManLatest( pPerm+nBits, 1<<nBits, -1, -1, -1 );
+ int iLate2 = Gia_ManLatest( pPerm+nBits, 1<<nBits, iLate1, -1, -1 );
+ int iLate3 = Gia_ManLatest( pPerm+nBits, 1<<nBits, iLate1, iLate2, -1 );
+ int iLate4 = Gia_ManLatest( pPerm+nBits, 1<<nBits, iLate1, iLate2, iLate3 );
+ if ( 0 )
+ {
+ int i;
+ for ( i = 0; i < (1<<nBits); i++ )
+ printf( "%d ", pPerm[nBits+i] );
+ printf( "\n" );
+ }
+ if ( pPerm[nBits+iLate1] > BaseValue && pPerm[nBits+iLate2] > BaseValue && pPerm[nBits+iLate3] > BaseValue && pPerm[nBits+iLate4] == BaseValue )
+ return Gia_ManDecompThree( pNew, pTree, nBits, pPerm, iLate1, iLate2, iLate3 );
+ if ( pPerm[nBits+iLate1] > BaseValue && pPerm[nBits+iLate2] > BaseValue && pPerm[nBits+iLate3] == BaseValue )
+ return Gia_ManDecompTwo( pNew, pTree, nBits, pPerm, iLate1, iLate2 );
+ if ( pPerm[nBits+iLate1] > BaseValue && pPerm[nBits+iLate2] == BaseValue )
+ return Gia_ManDecompOne( pNew, pTree, nBits, pPerm, iLate1 );
+ return Gia_ManMuxTree_rec( pNew, pTree, nBits, pTree+nBits );
+ }
+}
+Gia_Man_t * Gia_ManMuxTreeTest( int nBits )
+{
+ Gia_Man_t * pNew;
+ int i, iLit, nVars = nBits + (1 << nBits);
+ int * pPerm, * pTree = Gia_ManCollectLiterals( nVars );
+ pNew = Gia_ManStart( 1000 );
+ pNew->pName = Abc_UtilStrsav( "mux_tree" );
+ for ( i = 0; i < nVars; i++ )
+ Gia_ManAppendCi( pNew );
+ Gia_ManHashAlloc( pNew );
+ pPerm = Gia_ManGenPerm( nVars );
+ //pPerm = Gia_ManGenZero( nVars );
+ pPerm[nBits+1] = 100;
+ pPerm[nBits+5] = 100;
+ pPerm[nBits+4] = 100;
+ Gia_ManUsePerm( pTree, nBits, pPerm );
+ iLit = Gia_ManDecomp( pNew, pTree, nBits, pPerm );
+ Gia_ManAppendCo( pNew, iLit );
+ ABC_FREE( pPerm );
+ ABC_FREE( pTree );
+ return pNew;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c
index 37ca6d4b..ae87277a 100644
--- a/src/aig/gia/giaIf.c
+++ b/src/aig/gia/giaIf.c
@@ -39,6 +39,8 @@ ABC_NAMESPACE_IMPL_START
extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash );
extern int Abc_RecToGia3( Gia_Man_t * pMan, If_Man_t * pIfMan, If_Cut_t * pCut, Vec_Int_t * vLeaves, int fHash );
+extern void Gia_ManPrintGetMuxFanins( Gia_Man_t * p, Gia_Obj_t * pObj, int * pFanins );
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -200,6 +202,7 @@ int Gia_ManLutLevel( Gia_Man_t * p, int ** ppLevels )
***********************************************************************/
void Gia_ManLutParams( Gia_Man_t * p, int * pnCurLuts, int * pnCurEdges, int * pnCurLevels )
{
+ int fDisable2Lut = 1;
if ( p->pManTime && Tim_ManBoxNum((Tim_Man_t *)p->pManTime) )
{
int i;
@@ -219,20 +222,37 @@ void Gia_ManLutParams( Gia_Man_t * p, int * pnCurLuts, int * pnCurEdges, int * p
int * pLevels = ABC_CALLOC( int, Gia_ManObjNum(p) );
*pnCurLuts = 0;
*pnCurEdges = 0;
+ *pnCurLevels = 0;
Gia_ManForEachLut( p, i )
{
- int Level = 0;
+ if ( Gia_ObjLutIsMux(p, i) && !(fDisable2Lut && Gia_ObjLutSize(p, i) == 2) )
+ {
+ int pFanins[3];
+ if ( Gia_ObjLutSize(p, i) == 3 )
+ {
+ Gia_ManPrintGetMuxFanins( p, Gia_ManObj(p, i), pFanins );
+ pLevels[i] = Abc_MaxInt( pLevels[i], pLevels[pFanins[0]]+1 );
+ pLevels[i] = Abc_MaxInt( pLevels[i], pLevels[pFanins[1]] );
+ pLevels[i] = Abc_MaxInt( pLevels[i], pLevels[pFanins[2]] );
+ }
+ else if ( Gia_ObjLutSize(p, i) == 2 )
+ {
+ pObj = Gia_ManObj( p, i );
+ pLevels[i] = Abc_MaxInt( pLevels[i], pLevels[Gia_ObjFaninId0(pObj, i)] );
+ pLevels[i] = Abc_MaxInt( pLevels[i], pLevels[Gia_ObjFaninId1(pObj, i)] );
+ }
+ *pnCurLevels = Abc_MaxInt( *pnCurLevels, pLevels[i] );
+ (*pnCurEdges)++;
+ //nMuxF++;
+ continue;
+ }
(*pnCurLuts)++;
(*pnCurEdges) += Gia_ObjLutSize(p, i);
Gia_LutForEachFanin( p, i, iFan, k )
- if ( Level < pLevels[iFan] )
- Level = pLevels[iFan];
- pLevels[i] = Level + 1;
+ pLevels[i] = Abc_MaxInt( pLevels[i], pLevels[iFan] );
+ pLevels[i]++;
+ *pnCurLevels = Abc_MaxInt( *pnCurLevels, pLevels[i] );
}
- *pnCurLevels = 0;
- Gia_ManForEachCo( p, pObj, k )
- if ( *pnCurLevels < pLevels[Gia_ObjFaninId0p(p, pObj)] )
- *pnCurLevels = pLevels[Gia_ObjFaninId0p(p, pObj)];
ABC_FREE( pLevels );
}
}
@@ -452,6 +472,7 @@ int Gia_ManCountDupLut( Gia_Man_t * p )
void Gia_ManPrintMappingStats( Gia_Man_t * p, char * pDumpFile )
{
+ int fDisable2Lut = 1;
Gia_Obj_t * pObj;
int * pLevels;
int i, k, iFan, nLutSize = 0, nLuts = 0, nFanins = 0, LevelMax = 0, Ave = 0, nMuxF = 0;
@@ -460,7 +481,7 @@ void Gia_ManPrintMappingStats( Gia_Man_t * p, char * pDumpFile )
pLevels = ABC_CALLOC( int, Gia_ManObjNum(p) );
Gia_ManForEachLut( p, i )
{
- if ( Gia_ObjLutIsMux(p, i) )
+ if ( Gia_ObjLutIsMux(p, i) && !(fDisable2Lut && Gia_ObjLutSize(p, i) == 2) )
{
int pFanins[3];
if ( Gia_ObjLutSize(p, i) == 3 )
@@ -756,6 +777,43 @@ int Gia_ManChoiceLevel( Gia_Man_t * p )
}
+/**Function*************************************************************
+
+ Synopsis [Checks integrity of choice nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void If_ManCheckChoices_rec( If_Man_t * pIfMan, If_Obj_t * pIfObj )
+{
+ if ( !pIfObj || pIfObj->Type != IF_AND || pIfObj->fDriver )
+ return;
+ pIfObj->fDriver = 1;
+ If_ManCheckChoices_rec( pIfMan, If_ObjFanin0(pIfObj) );
+ If_ManCheckChoices_rec( pIfMan, If_ObjFanin1(pIfObj) );
+ If_ManCheckChoices_rec( pIfMan, pIfObj->pEquiv );
+}
+void If_ManCheckChoices( If_Man_t * pIfMan )
+{
+ If_Obj_t * pIfObj;
+ int i, fFound = 0;
+ If_ManForEachObj( pIfMan, pIfObj, i )
+ pIfObj->fDriver = 0;
+ If_ManForEachCo( pIfMan, pIfObj, i )
+ If_ManCheckChoices_rec( pIfMan, If_ObjFanin0(pIfObj) );
+ If_ManForEachNode( pIfMan, pIfObj, i )
+ if ( !pIfObj->fDriver )
+ printf( "Object %d is dangling.\n", i ), fFound = 1;
+ if ( !fFound )
+ printf( "There are no dangling objects.\n" );
+ If_ManForEachObj( pIfMan, pIfObj, i )
+ pIfObj->fDriver = 0;
+}
+
/**Function*************************************************************
@@ -824,6 +882,7 @@ If_Man_t * Gia_ManToIf( Gia_Man_t * p, If_Par_t * pPars )
}
if ( Gia_ManHasChoices(p) )
Gia_ManCleanMark0( p );
+ //If_ManCheckChoices( pIfMan );
return pIfMan;
}
@@ -1987,6 +2046,7 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
pFile = fopen( Buffer, "wb" );
if ( pFile == NULL )
{
+ Vec_StrFree( vConfigsStr );
printf( "Cannot open file \"%s\".\n", Buffer );
return pNew;
}
@@ -2162,10 +2222,11 @@ void Gia_ManTransferTiming( Gia_Man_t * p, Gia_Man_t * pGia )
p->DefOutReqs = pGia->DefOutReqs;
p->And2Delay = pGia->And2Delay;
}
- if ( pGia->vNamesIn || pGia->vNamesOut )
+ if ( pGia->vNamesIn || pGia->vNamesOut || pGia->vNamesNode )
{
p->vNamesIn = pGia->vNamesIn; pGia->vNamesIn = NULL;
p->vNamesOut = pGia->vNamesOut; pGia->vNamesOut = NULL;
+ p->vNamesNode = pGia->vNamesNode; pGia->vNamesNode = NULL;
}
if ( pGia->vConfigs || pGia->pCellStr )
{
@@ -2357,6 +2418,7 @@ Gia_Man_t * Gia_ManPerformMappingInt( Gia_Man_t * p, If_Par_t * pPars )
// transfer name
assert( pNew->pName == NULL );
pNew->pName = Abc_UtilStrsav( p->pName );
+ ABC_FREE( pNew->pSpec );
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
// print delay trace
diff --git a/src/aig/gia/giaIso.c b/src/aig/gia/giaIso.c
index 76419e93..fcfa3448 100644
--- a/src/aig/gia/giaIso.c
+++ b/src/aig/gia/giaIso.c
@@ -894,7 +894,7 @@ void Gia_ManFindCaninicalOrder( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAn
Vec_PtrClear( vTemp );
Gia_ManForEachPi( p, pObj, i )
Vec_PtrPush( vTemp, pObj );
- Vec_PtrSort( vTemp, (int (*)(void))Gia_ObjCompareByValue );
+ Vec_PtrSort( vTemp, (int (*)(const void *, const void *))Gia_ObjCompareByValue );
// create the result
Vec_PtrForEachEntry( Gia_Obj_t *, vTemp, pObj, i )
Vec_IntPush( vCis, Gia_ObjId(p, pObj) );
@@ -917,7 +917,7 @@ void Gia_ManFindCaninicalOrder( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAn
pObj->Value = Abc_Var2Lit( Gia_ObjFanin0(pObj)->Value, Gia_ObjFaninC0(pObj) );
Vec_PtrPush( vTemp, pObj );
}
- Vec_PtrSort( vTemp, (int (*)(void))Gia_ObjCompareByValue );
+ Vec_PtrSort( vTemp, (int (*)(const void *, const void *))Gia_ObjCompareByValue );
Vec_PtrForEachEntry( Gia_Obj_t *, vTemp, pObj, i )
Vec_IntPush( vCos, Gia_ObjId(p, pObj) );
}
@@ -926,7 +926,7 @@ void Gia_ManFindCaninicalOrder( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAn
Vec_PtrClear( vTemp );
Gia_ManForEachRo( p, pObj, i )
Vec_PtrPush( vTemp, pObj );
- Vec_PtrSort( vTemp, (int (*)(void))Gia_ObjCompareByValue );
+ Vec_PtrSort( vTemp, (int (*)(const void *, const void *))Gia_ObjCompareByValue );
// create the result
Vec_PtrForEachEntry( Gia_Obj_t *, vTemp, pObj, i )
{
diff --git a/src/aig/gia/giaIso2.c b/src/aig/gia/giaIso2.c
index 576b118f..22b1d09e 100644
--- a/src/aig/gia/giaIso2.c
+++ b/src/aig/gia/giaIso2.c
@@ -328,7 +328,7 @@ int Gia_Iso2ManUniqify( Gia_Iso2Man_t * p )
}
Vec_IntShrink( p->vTied, k );
// sort singletons
- Vec_PtrSort( p->vSingles, (int (*)(void))Gia_ObjCompareByValue2 );
+ Vec_PtrSort( p->vSingles, (int (*)(const void *, const void *))Gia_ObjCompareByValue2 );
// add them to unique and increment signature
Vec_PtrForEachEntry( Gia_Obj_t *, p->vSingles, pObj, i )
{
diff --git a/src/aig/gia/giaIso3.c b/src/aig/gia/giaIso3.c
index a88a0569..8bea4bbf 100644
--- a/src/aig/gia/giaIso3.c
+++ b/src/aig/gia/giaIso3.c
@@ -158,6 +158,97 @@ void Gia_Iso3Test( Gia_Man_t * p )
Vec_IntFreeP( &vSign );
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Wec_t * Gia_Iso4Gia( Gia_Man_t * p )
+{
+ Vec_Wec_t * vLevs = Gia_ManLevelizeR( p );
+ Vec_Int_t * vLevel; int l;
+ Abc_Random( 1 );
+ Vec_WecForEachLevel( vLevs, vLevel, l )
+ {
+ Gia_Obj_t * pObj; int i;
+ int RandC[2] = { Abc_Random(0), Abc_Random(0) };
+ if ( l == 0 )
+ {
+ Gia_ManForEachObjVec( vLevel, p, pObj, i )
+ {
+ assert( Gia_ObjIsCo(pObj) );
+ pObj->Value = Abc_Random(0);
+ Gia_ObjFanin0(pObj)->Value += pObj->Value + RandC[Gia_ObjFaninC0(pObj)];
+ }
+ }
+ else
+ {
+ Gia_ManForEachObjVec( vLevel, p, pObj, i ) if ( Gia_ObjIsAnd(pObj) )
+ {
+ Gia_ObjFanin0(pObj)->Value += pObj->Value + RandC[Gia_ObjFaninC0(pObj)];
+ Gia_ObjFanin1(pObj)->Value += pObj->Value + RandC[Gia_ObjFaninC1(pObj)];
+ }
+ }
+ }
+ return vLevs;
+}
+void Gia_Iso4Test( Gia_Man_t * p )
+{
+ Vec_Wec_t * vLevs = Gia_Iso4Gia( p );
+ Vec_Int_t * vLevel; int l;
+ Vec_WecForEachLevel( vLevs, vLevel, l )
+ {
+ Gia_Obj_t * pObj; int i;
+ printf( "Level %d\n", l );
+ Gia_ManForEachObjVec( vLevel, p, pObj, i )
+ printf( "Obj = %5d. Value = %08x.\n", Gia_ObjId(p, pObj), pObj->Value );
+ }
+ Vec_WecFree( vLevs );
+}
+Vec_Int_t * Gia_IsoCollectData( Gia_Man_t * p, Vec_Int_t * vObjs )
+{
+ Gia_Obj_t * pObj; int i;
+ Vec_Int_t * vData = Vec_IntAlloc( Vec_IntSize(vObjs) );
+ Gia_ManForEachObjVec( vObjs, p, pObj, i )
+ Vec_IntPush( vData, pObj->Value );
+ return vData;
+}
+void Gia_IsoCompareVecs( Gia_Man_t * pGia0, Vec_Wec_t * vLevs0, Gia_Man_t * pGia1, Vec_Wec_t * vLevs1 )
+{
+ int i, Common, nLevels = Abc_MinInt( Vec_WecSize(vLevs0), Vec_WecSize(vLevs1) );
+ Gia_ManPrintStats( pGia0, NULL );
+ Gia_ManPrintStats( pGia1, NULL );
+ printf( "Printing %d shared levels:\n", nLevels );
+ for ( i = 0; i < nLevels; i++ )
+ {
+ Vec_Int_t * vLev0 = Vec_WecEntry(vLevs0, i);
+ Vec_Int_t * vLev1 = Vec_WecEntry(vLevs1, i);
+ Vec_Int_t * vData0 = Gia_IsoCollectData( pGia0, vLev0 );
+ Vec_Int_t * vData1 = Gia_IsoCollectData( pGia1, vLev1 );
+ Vec_IntSort( vData0, 0 );
+ Vec_IntSort( vData1, 0 );
+ Common = Vec_IntTwoCountCommon( vData0, vData1 );
+ printf( "Level = %3d. One = %6d. Two = %6d. Common = %6d.\n",
+ i, Vec_IntSize(vData0)-Common, Vec_IntSize(vData1)-Common, Common );
+ Vec_IntFree( vData0 );
+ Vec_IntFree( vData1 );
+ }
+}
+void Gia_Iso4TestTwo( Gia_Man_t * pGia0, Gia_Man_t * pGia1 )
+{
+ Vec_Wec_t * vLevs0 = Gia_Iso4Gia( pGia0 );
+ Vec_Wec_t * vLevs1 = Gia_Iso4Gia( pGia1 );
+ Gia_IsoCompareVecs( pGia0, vLevs0, pGia1, vLevs1 );
+ Vec_WecFree( vLevs0 );
+ Vec_WecFree( vLevs1 );
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c
index 4ca9bfa4..a40673a7 100644
--- a/src/aig/gia/giaMan.c
+++ b/src/aig/gia/giaMan.c
@@ -81,8 +81,6 @@ Gia_Man_t * Gia_ManStart( int nObjsMax )
***********************************************************************/
void Gia_ManStop( Gia_Man_t * p )
{
- extern void Gia_DatFree( Gia_Dat_t * p );
- Gia_DatFree( p->pUData );
if ( p->vSeqModelVec )
Vec_PtrFreeFree( p->vSeqModelVec );
Gia_ManStaticFanoutStop( p );
@@ -90,11 +88,14 @@ void Gia_ManStop( Gia_Man_t * p )
assert( p->pManTime == NULL );
Vec_PtrFreeFree( p->vNamesIn );
Vec_PtrFreeFree( p->vNamesOut );
+ Vec_PtrFreeFree( p->vNamesNode );
Vec_IntFreeP( &p->vSwitching );
Vec_IntFreeP( &p->vSuper );
Vec_IntFreeP( &p->vStore );
Vec_IntFreeP( &p->vClassNew );
Vec_IntFreeP( &p->vClassOld );
+ Vec_IntFreeP( &p->vPats );
+ Vec_BitFreeP( &p->vPolars );
Vec_WrdFreeP( &p->vSims );
Vec_WrdFreeP( &p->vSimsT );
Vec_WrdFreeP( &p->vSimsPi );
@@ -129,6 +130,7 @@ void Gia_ManStop( Gia_Man_t * p )
Vec_IntFreeP( &p->vVar2Obj );
Vec_IntErase( &p->vCopiesTwo );
Vec_IntErase( &p->vSuppVars );
+ Vec_IntErase( &p->vVarMap );
Vec_WrdFreeP( &p->vSuppWords );
Vec_IntFreeP( &p->vTtNums );
Vec_IntFreeP( &p->vTtNodes );
@@ -147,6 +149,7 @@ void Gia_ManStop( Gia_Man_t * p )
Vec_IntFreeP( &p->vCoReqs );
Vec_IntFreeP( &p->vCoArrs );
Vec_IntFreeP( &p->vCoAttrs );
+ Vec_IntFreeP( &p->vWeights );
Gia_ManStopP( &p->pAigExtra );
Vec_IntFree( p->vCis );
Vec_IntFree( p->vCos );
@@ -201,6 +204,7 @@ double Gia_ManMemory( Gia_Man_t * p )
Memory += Vec_FltMemory( p->vOutReqs );
Memory += Vec_PtrMemory( p->vNamesIn );
Memory += Vec_PtrMemory( p->vNamesOut );
+ Memory += Vec_PtrMemory( p->vNamesNode );
return Memory;
}
@@ -582,7 +586,7 @@ void Gia_ManPrintStats( Gia_Man_t * p, Gps_Par_t * pPars )
Gia_ManPrintMappingStats( p, pPars ? pPars->pDumpFile : NULL );
else if ( pPars && pPars->pDumpFile )
Gia_ManLogAigStats( p, pPars->pDumpFile );
- if ( pPars && pPars->fNpn && Gia_ManHasMapping(p) && Gia_ManLutSizeMax(p) <= 4 )
+ if ( pPars && pPars->fNpn && Gia_ManHasMapping(p) )
Gia_ManPrintNpnClasses( p );
if ( p->vPacking )
Gia_ManPrintPackingStats( p );
@@ -1269,13 +1273,14 @@ void Gia_ManWriteNames( FILE * pFile, char c, int n, Vec_Ptr_t * vNames, int Sta
fFirst = 0;
}
}
-void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs )
+void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs )
{
FILE * pFile;
Gia_Obj_t * pObj;
Vec_Bit_t * vInvs, * vUsed;
- int nDigits = Abc_Base10Log( Gia_ManObjNum(p) );
- int nDigits2 = Abc_Base10Log( Gia_ManPiNum(p) );
+ int nDigits = Abc_Base10Log( Gia_ManObjNum(p) );
+ int nDigitsI = Abc_Base10Log( Gia_ManPiNum(p) );
+ int nDigitsO = Abc_Base10Log( Gia_ManPoNum(p) );
int i, k, iObj;
if ( Gia_ManRegNum(p) )
{
@@ -1300,20 +1305,63 @@ void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs )
fprintf( pFile, "%c", p->pName[i] );
else
fprintf( pFile, "_" );
- fprintf( pFile, " (\n " );
- Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 4, 4, NULL );
- fprintf( pFile, ",\n " );
- Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 4, 4, NULL );
- fprintf( pFile, "\n );\n\n" );
+ if ( fVerBufs )
+ {
+ fprintf( pFile, " (\n " );
+ Gia_ManWriteNames( pFile, 'a', Gia_ManPiNum(p), NULL, 4, 4, NULL );
+ fprintf( pFile, ",\n " );
+
+ Gia_ManWriteNames( pFile, 'y', Gia_ManPoNum(p), NULL, 4, 4, NULL );
+ fprintf( pFile, "\n );\n\n" );
+
+ fprintf( pFile, " input " );
+ Gia_ManWriteNames( pFile, 'a', Gia_ManPiNum(p), NULL, 8, 4, NULL );
+ fprintf( pFile, ";\n\n" );
+
+ fprintf( pFile, " output " );
+ Gia_ManWriteNames( pFile, 'y', Gia_ManPoNum(p), NULL, 9, 4, NULL );
+ fprintf( pFile, ";\n\n" );
+
+ fprintf( pFile, " wire " );
+ Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 8, 4, NULL );
+ fprintf( pFile, ";\n\n" );
- fprintf( pFile, " input " );
- Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 8, 4, NULL );
- fprintf( pFile, ";\n\n" );
+ fprintf( pFile, " wire " );
+ Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 9, 4, NULL );
+ fprintf( pFile, ";\n\n" );
- fprintf( pFile, " output " );
- Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 9, 4, NULL );
- fprintf( pFile, ";\n\n" );
+ Gia_ManForEachPi( p, pObj, i )
+ {
+ fprintf( pFile, " buf ( %s,", Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigitsI) );
+ fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(NULL, 'a', i, nDigitsI) );
+ }
+ fprintf( pFile, "\n" );
+
+ Gia_ManForEachPo( p, pObj, i )
+ {
+ fprintf( pFile, " buf ( %s,", Gia_ObjGetDumpName(NULL, 'y', i, nDigitsO) );
+ fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(p->vNamesOut, 'z', i, nDigitsO) );
+ }
+ fprintf( pFile, "\n" );
+ }
+ else
+ {
+ fprintf( pFile, " (\n " );
+ Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 4, 4, NULL );
+ fprintf( pFile, ",\n " );
+
+ Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 4, 4, NULL );
+ fprintf( pFile, "\n );\n\n" );
+
+ fprintf( pFile, " input " );
+ Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 8, 4, NULL );
+ fprintf( pFile, ";\n\n" );
+
+ fprintf( pFile, " output " );
+ Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 9, 4, NULL );
+ fprintf( pFile, ";\n\n" );
+ }
if ( Vec_BitCount(vUsed) )
{
@@ -1337,7 +1385,7 @@ void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs )
fprintf( pFile, ";\n\n" );
Vec_IntForEachEntry( vObjs, iObj, i )
{
- fprintf( pFile, " buf( %s,", Gia_ObjGetDumpName(NULL, 'n', iObj, nDigits) );
+ fprintf( pFile, " buf ( %s,", Gia_ObjGetDumpName(NULL, 'n', iObj, nDigits) );
fprintf( pFile, " t_%d );\n", i );
}
fprintf( pFile, "\n" );
@@ -1348,13 +1396,13 @@ void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs )
{
if ( Vec_BitEntry(vUsed, Gia_ObjId(p, pObj)) )
{
- fprintf( pFile, " buf( %s,", Gia_ObjGetDumpName(NULL, 'n', Gia_ObjId(p, pObj), nDigits) );
- fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigits2) );
+ fprintf( pFile, " buf ( %s,", Gia_ObjGetDumpName(NULL, 'n', Gia_ObjId(p, pObj), nDigits) );
+ fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigitsI) );
}
if ( Vec_BitEntry(vInvs, Gia_ObjId(p, pObj)) )
{
- fprintf( pFile, " not( %s,", Gia_ObjGetDumpName(NULL, 'i', Gia_ObjId(p, pObj), nDigits) );
- fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigits2) );
+ fprintf( pFile, " not ( %s,", Gia_ObjGetDumpName(NULL, 'i', Gia_ObjId(p, pObj), nDigits) );
+ fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigitsI) );
}
}
@@ -1373,20 +1421,19 @@ void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs )
}
if ( !fSkip )
{
- fprintf( pFile, " and( %s,", Gia_ObjGetDumpName(NULL, 'n', i, nDigits) );
+ fprintf( pFile, " and ( %s,", Gia_ObjGetDumpName(NULL, 'n', i, nDigits) );
fprintf( pFile, " %s,", Gia_ObjGetDumpName(NULL, (char)(Gia_ObjFaninC0(pObj)? 'i':'n'), Gia_ObjFaninId0(pObj, i), nDigits) );
fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(NULL, (char)(Gia_ObjFaninC1(pObj)? 'i':'n'), Gia_ObjFaninId1(pObj, i), nDigits) );
}
if ( Vec_BitEntry(vInvs, i) )
{
- fprintf( pFile, " not( %s,", Gia_ObjGetDumpName(NULL, 'i', i, nDigits) );
+ fprintf( pFile, " not ( %s,", Gia_ObjGetDumpName(NULL, 'i', i, nDigits) );
fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(NULL, 'n', i, nDigits) );
}
}
// output drivers
fprintf( pFile, "\n" );
- nDigits2 = Abc_Base10Log( Gia_ManPoNum(p) );
Gia_ManForEachPo( p, pObj, i )
{
/*
@@ -1396,7 +1443,7 @@ void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs )
else
fprintf( pFile, "%s;\n", Gia_ObjGetDumpName(NULL, (char)(Gia_ObjFaninC0(pObj)? 'i':'n'), Gia_ObjFaninId0p(p, pObj), nDigits) );
*/
- fprintf( pFile, " buf( %s, ", Gia_ObjGetDumpName(p->vNamesOut, 'z', i, nDigits2) );
+ fprintf( pFile, " buf ( %s, ", Gia_ObjGetDumpName(p->vNamesOut, 'z', i, nDigitsO) );
if ( Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) )
fprintf( pFile, "1\'b%d );\n", Gia_ObjFaninC0(pObj) );
else
diff --git a/src/aig/gia/giaMf.c b/src/aig/gia/giaMf.c
index 7e699d9b..e732f25e 100644
--- a/src/aig/gia/giaMf.c
+++ b/src/aig/gia/giaMf.c
@@ -24,6 +24,7 @@
#include "misc/extra/extra.h"
#include "sat/cnf/cnf.h"
#include "opt/dau/dau.h"
+#include "bool/kit/kit.h"
ABC_NAMESPACE_IMPL_START
@@ -557,8 +558,8 @@ static inline int Mf_CutComputeTruth6( Mf_Man_t * p, Mf_Cut_t * pCut0, Mf_Cut_t
assert( (int)(t & 1) == 0 );
truthId = Vec_MemHashInsert(p->vTtMem, &t);
pCutR->iFunc = Abc_Var2Lit( truthId, fCompl );
- if ( p->pPars->fGenCnf && truthId == Vec_IntSize(&p->vCnfSizes) )
- Vec_IntPush( &p->vCnfSizes, Abc_Tt6CnfSize(t, pCutR->nLeaves) );
+ if ( (p->pPars->fGenCnf || p->pPars->fGenLit) && truthId == Vec_IntSize(&p->vCnfSizes) )
+ Vec_IntPush( &p->vCnfSizes, p->pPars->fGenCnf ? Abc_Tt6CnfSize(t, pCutR->nLeaves) : Kit_TruthLitNum((unsigned *)&t, pCutR->nLeaves, &p->vCnfMem) );
// p->nCutMux += Mf_ManTtIsMux( t );
assert( (int)pCutR->nLeaves <= nOldSupp );
// Mf_ManTruthCanonicize( &t, pCutR->nLeaves );
@@ -588,8 +589,8 @@ static inline int Mf_CutComputeTruth( Mf_Man_t * p, Mf_Cut_t * pCut0, Mf_Cut_t *
//Kit_DsdPrintFromTruth( uTruth, pCutR->nLeaves ), printf("\n" ), printf("\n" );
truthId = Vec_MemHashInsert(p->vTtMem, uTruth);
pCutR->iFunc = Abc_Var2Lit( truthId, fCompl );
- if ( p->pPars->fGenCnf && truthId == Vec_IntSize(&p->vCnfSizes) && LutSize <= 8 )
- Vec_IntPush( &p->vCnfSizes, Abc_Tt8CnfSize(uTruth, pCutR->nLeaves) );
+ if ( (p->pPars->fGenCnf || p->pPars->fGenLit) && truthId == Vec_IntSize(&p->vCnfSizes) && LutSize <= 8 )
+ Vec_IntPush( &p->vCnfSizes, p->pPars->fGenCnf ? Abc_Tt8CnfSize(uTruth, pCutR->nLeaves) : Kit_TruthLitNum((unsigned *)uTruth, pCutR->nLeaves, &p->vCnfMem) );
assert( (int)pCutR->nLeaves <= nOldSupp );
return (int)pCutR->nLeaves < nOldSupp;
}
@@ -612,8 +613,8 @@ static inline int Mf_CutComputeTruthMux6( Mf_Man_t * p, Mf_Cut_t * pCut0, Mf_Cut
assert( (int)(t & 1) == 0 );
truthId = Vec_MemHashInsert(p->vTtMem, &t);
pCutR->iFunc = Abc_Var2Lit( truthId, fCompl );
- if ( p->pPars->fGenCnf && truthId == Vec_IntSize(&p->vCnfSizes) )
- Vec_IntPush( &p->vCnfSizes, Abc_Tt6CnfSize(t, pCutR->nLeaves) );
+ if ( (p->pPars->fGenCnf || p->pPars->fGenLit) && truthId == Vec_IntSize(&p->vCnfSizes) )
+ Vec_IntPush( &p->vCnfSizes, p->pPars->fGenCnf ? Abc_Tt6CnfSize(t, pCutR->nLeaves) : Kit_TruthLitNum((unsigned *)&t, pCutR->nLeaves, &p->vCnfMem) );
assert( (int)pCutR->nLeaves <= nOldSupp );
return (int)pCutR->nLeaves < nOldSupp;
}
@@ -642,8 +643,8 @@ static inline int Mf_CutComputeTruthMux( Mf_Man_t * p, Mf_Cut_t * pCut0, Mf_Cut_
assert( (uTruth[0] & 1) == 0 );
truthId = Vec_MemHashInsert(p->vTtMem, uTruth);
pCutR->iFunc = Abc_Var2Lit( truthId, fCompl );
- if ( p->pPars->fGenCnf && truthId == Vec_IntSize(&p->vCnfSizes) && LutSize <= 8 )
- Vec_IntPush( &p->vCnfSizes, Abc_Tt8CnfSize(uTruth, pCutR->nLeaves) );
+ if ( (p->pPars->fGenCnf || p->pPars->fGenLit) && truthId == Vec_IntSize(&p->vCnfSizes) && LutSize <= 8 )
+ Vec_IntPush( &p->vCnfSizes, p->pPars->fGenCnf ? Abc_Tt8CnfSize(uTruth, pCutR->nLeaves) : Kit_TruthLitNum((unsigned *)uTruth, pCutR->nLeaves, &p->vCnfMem) );
assert( (int)pCutR->nLeaves <= nOldSupp );
return (int)pCutR->nLeaves < nOldSupp;
}
@@ -699,6 +700,8 @@ static inline void Mf_CutPrint( Mf_Man_t * p, Mf_Cut_t * pCut )
{
if ( p->pPars->fGenCnf )
printf( "CNF = %2d ", Vec_IntEntry(&p->vCnfSizes, Abc_Lit2Var(pCut->iFunc)) );
+ if ( p->pPars->fGenLit )
+ printf( "Lit = %2d ", Vec_IntEntry(&p->vCnfSizes, Abc_Lit2Var(pCut->iFunc)) );
Dau_DsdPrintFromTruth( Vec_MemReadEntry(p->vTtMem, Abc_Lit2Var(pCut->iFunc)), pCut->nLeaves );
}
else
@@ -998,7 +1001,7 @@ static inline int Mf_CutArea( Mf_Man_t * p, int nLeaves, int iFunc )
{
if ( nLeaves < 2 )
return 0;
- if ( p->pPars->fGenCnf )
+ if ( p->pPars->fGenCnf || p->pPars->fGenLit )
return Vec_IntEntry(&p->vCnfSizes, Abc_Lit2Var(iFunc));
if ( p->pPars->fOptEdge )
return nLeaves + p->pPars->nAreaTuner;
@@ -1202,7 +1205,7 @@ int Mf_ManSetMapRefs( Mf_Man_t * p )
Mf_ObjMapRefInc( p, pCut[k] );
p->pPars->Edge += Mf_CutSize(pCut);
p->pPars->Area++;
- if ( p->pPars->fGenCnf )
+ if ( p->pPars->fGenCnf || p->pPars->fGenLit )
p->pPars->Clause += Mf_CutArea(p, Mf_CutSize(pCut), Mf_CutFunc(pCut));
}
// blend references
@@ -1394,7 +1397,7 @@ Mf_Man_t * Mf_ManAlloc( Gia_Man_t * pGia, Jf_Par_t * pPars )
p->pLfObjs = ABC_CALLOC( Mf_Obj_t, Gia_ManObjNum(pGia) );
p->iCur = 2;
Vec_PtrGrow( &p->vPages, 256 );
- if ( pPars->fGenCnf )
+ if ( pPars->fGenCnf || pPars->fGenLit )
{
Vec_IntGrow( &p->vCnfSizes, 10000 );
Vec_IntPush( &p->vCnfSizes, 1 );
@@ -1410,7 +1413,7 @@ Mf_Man_t * Mf_ManAlloc( Gia_Man_t * pGia, Jf_Par_t * pPars )
}
void Mf_ManFree( Mf_Man_t * p )
{
- assert( !p->pPars->fGenCnf || Vec_IntSize(&p->vCnfSizes) == Vec_MemEntryNum(p->vTtMem) );
+ assert( !p->pPars->fGenCnf || !p->pPars->fGenLit || Vec_IntSize(&p->vCnfSizes) == Vec_MemEntryNum(p->vTtMem) );
if ( p->pPars->fCutMin )
Vec_MemHashFree( p->vTtMem );
if ( p->pPars->fCutMin )
@@ -1453,6 +1456,7 @@ void Mf_ManSetDefaultPars( Jf_Par_t * pPars )
pPars->fCoarsen = 1;
pPars->fCutMin = 0;
pPars->fGenCnf = 0;
+ pPars->fGenLit = 0;
pPars->fPureAig = 0;
pPars->fVerbose = 0;
pPars->fVeryVerbose = 0;
@@ -1469,6 +1473,8 @@ void Mf_ManPrintStats( Mf_Man_t * p, char * pTitle )
printf( "Edge =%9lu ", (long)p->pPars->Edge );
if ( p->pPars->fGenCnf )
printf( "CNF =%9lu ", (long)p->pPars->Clause );
+ if ( p->pPars->fGenLit )
+ printf( "FFL =%9lu ", (long)p->pPars->Clause );
Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
fflush( stdout );
}
@@ -1483,6 +1489,7 @@ void Mf_ManPrintInit( Mf_Man_t * p )
printf( "CutMin = %d ", p->pPars->fCutMin );
printf( "Coarse = %d ", p->pPars->fCoarsen );
printf( "CNF = %d ", p->pPars->fGenCnf );
+ printf( "FFL = %d ", p->pPars->fGenLit );
printf( "\n" );
printf( "Computing cuts...\r" );
fflush( stdout );
@@ -1541,51 +1548,97 @@ void Mf_ManComputeCuts( Mf_Man_t * p )
SeeAlso []
***********************************************************************/
-int Mf_CutRef2_rec( Mf_Man_t * p, int * pCut, Vec_Int_t * vTemp, int Limit )
+int Mf_CutRef_rec( Mf_Man_t * p, int * pCut )
{
int i, Count = Mf_CutArea(p, Mf_CutSize(pCut), Mf_CutFunc(pCut));
- if ( Limit == 0 ) return Count;
for ( i = 1; i <= Mf_CutSize(pCut); i++ )
- {
- Vec_IntPush( vTemp, pCut[i] );
if ( !Mf_ObjMapRefInc(p, pCut[i]) && Mf_ManObj(p, pCut[i])->iCutSet )
- Count += Mf_CutRef2_rec( p, Mf_ObjCutBest(p, pCut[i]), vTemp, Limit-1 );
- }
+ Count += Mf_CutRef_rec( p, Mf_ObjCutBest(p, pCut[i]) );
return Count;
}
-static inline int Mf_CutAreaDerefed2( Mf_Man_t * p, int * pCut )
+int Mf_CutDeref_rec( Mf_Man_t * p, int * pCut )
{
- int Ela1, iObj, i;
- Vec_IntClear( &p->vTemp );
- Ela1 = Mf_CutRef2_rec( p, pCut, &p->vTemp, 8 );
- Vec_IntForEachEntry( &p->vTemp, iObj, i )
- Mf_ObjMapRefDec( p, iObj );
+ int i, Count = Mf_CutArea(p, Mf_CutSize(pCut), Mf_CutFunc(pCut));
+ for ( i = 1; i <= Mf_CutSize(pCut); i++ )
+ if ( !Mf_ObjMapRefDec(p, pCut[i]) && Mf_ManObj(p, pCut[i])->iCutSet )
+ Count += Mf_CutDeref_rec( p, Mf_ObjCutBest(p, pCut[i]) );
+ return Count;
+}
+static inline int Mf_CutAreaRefed( Mf_Man_t * p, int * pCut )
+{
+ int Ela1 = Mf_CutDeref_rec( p, pCut );
+ int Ela2 = Mf_CutRef_rec( p, pCut );
+ assert( Ela1 == Ela2 );
+ return Ela1;
+}
+static inline int Mf_CutAreaDerefed( Mf_Man_t * p, int * pCut )
+{
+ int Ela1 = Mf_CutRef_rec( p, pCut );
+ int Ela2 = Mf_CutDeref_rec( p, pCut );
+ assert( Ela1 == Ela2 );
return Ela1;
}
+static inline int Mf_CutAreaMffc( Mf_Man_t * p, int iObj )
+{
+ return Mf_ObjMapRefNum(p, iObj) ?
+ Mf_CutAreaRefed (p, Mf_ObjCutBest(p, iObj)) :
+ Mf_CutAreaDerefed(p, Mf_ObjCutBest(p, iObj));
+}
-int Mf_CutRef_rec( Mf_Man_t * p, int * pCut )
+int Mf_CutRef2_rec( Mf_Man_t * p, int * pCut, Vec_Int_t * vTemp, int Limit )
{
int i, Count = Mf_CutArea(p, Mf_CutSize(pCut), Mf_CutFunc(pCut));
+ if ( Limit == 0 ) return Count;
for ( i = 1; i <= Mf_CutSize(pCut); i++ )
+ {
+ Vec_IntPush( vTemp, pCut[i] );
if ( !Mf_ObjMapRefInc(p, pCut[i]) && Mf_ManObj(p, pCut[i])->iCutSet )
- Count += Mf_CutRef_rec( p, Mf_ObjCutBest(p, pCut[i]) );
+ Count += Mf_CutRef2_rec( p, Mf_ObjCutBest(p, pCut[i]), vTemp, Limit-1 );
+ }
return Count;
}
-int Mf_CutDeref_rec( Mf_Man_t * p, int * pCut )
+int Mf_CutDeref2_rec( Mf_Man_t * p, int * pCut, Vec_Int_t * vTemp, int Limit )
{
int i, Count = Mf_CutArea(p, Mf_CutSize(pCut), Mf_CutFunc(pCut));
+ if ( Limit == 0 ) return Count;
for ( i = 1; i <= Mf_CutSize(pCut); i++ )
+ {
+ Vec_IntPush( vTemp, pCut[i] );
if ( !Mf_ObjMapRefDec(p, pCut[i]) && Mf_ManObj(p, pCut[i])->iCutSet )
- Count += Mf_CutDeref_rec( p, Mf_ObjCutBest(p, pCut[i]) );
+ Count += Mf_CutDeref2_rec( p, Mf_ObjCutBest(p, pCut[i]), vTemp, Limit-1 );
+ }
return Count;
}
-static inline int Mf_CutAreaDerefed( Mf_Man_t * p, int * pCut )
+static inline int Mf_CutAreaRefed2( Mf_Man_t * p, int * pCut )
{
- int Ela1 = Mf_CutRef_rec( p, pCut );
- int Ela2 = Mf_CutDeref_rec( p, pCut );
- assert( Ela1 == Ela2 );
+ int Ela1, iObj, i;
+ Vec_IntClear( &p->vTemp );
+ Ela1 = Mf_CutDeref2_rec( p, pCut, &p->vTemp, 8 );
+ Vec_IntForEachEntry( &p->vTemp, iObj, i )
+ Mf_ObjMapRefInc( p, iObj );
return Ela1;
}
+static inline int Mf_CutAreaDerefed2( Mf_Man_t * p, int * pCut )
+{
+ int Ela1, iObj, i;
+ Vec_IntClear( &p->vTemp );
+ Ela1 = Mf_CutRef2_rec( p, pCut, &p->vTemp, 8 );
+ Vec_IntForEachEntry( &p->vTemp, iObj, i )
+ Mf_ObjMapRefDec( p, iObj );
+ return Ela1;
+}
+static inline int Mf_CutAreaRefed2Multi( Mf_Man_t * p, int iObj, int ** ppCuts, int nCuts )
+{
+ int Ela1 = 0, iTemp, i;
+ Vec_IntClear( &p->vTemp );
+ for ( i = 0; i < nCuts; i++ )
+ Ela1 += Mf_CutDeref2_rec( p, ppCuts[i], &p->vTemp, ABC_INFINITY );
+ assert( Mf_ObjMapRefNum(p, iObj) == 0 );
+ Vec_IntForEachEntry( &p->vTemp, iTemp, i )
+ Mf_ObjMapRefInc( p, iTemp );
+ return Ela1;
+}
+
static inline float Mf_CutFlow( Mf_Man_t * p, int * pCut, int * pTime )
{
Mf_Obj_t * pObj;
@@ -1635,6 +1688,120 @@ static inline void Mf_ObjComputeBestCut( Mf_Man_t * p, int iObj )
/**Function*************************************************************
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Mf_ManMappingFromMapping( Mf_Man_t * p )
+{
+ Gia_Man_t * pGia = p->pGia0;
+ Gia_Obj_t * pObj;
+ int i, iObj, Count = 0;
+ Vec_Int_t * vMapping = Vec_IntAlloc( 3 * Gia_ManObjNum(pGia) );
+ Vec_IntFill( vMapping, Gia_ManObjNum(pGia), 0 );
+ Gia_ManForEachAnd( pGia, pObj, iObj )
+ if ( Mf_ObjMapRefNum(p, iObj) )
+ {
+ int * pCut = Mf_ObjCutBest(p, iObj);
+ Vec_IntWriteEntry( vMapping, iObj, Vec_IntSize(vMapping) );
+ Vec_IntPush( vMapping, Mf_CutSize(pCut) );
+ for ( i = 1; i <= Mf_CutSize(pCut); i++ )
+ Vec_IntPush( vMapping, pCut[i] );
+ Vec_IntPush( vMapping, iObj );
+ Count++;
+ }
+ assert( pGia->vMapping == NULL );
+ pGia->vMapping = vMapping;
+ printf( "Mapping is %.2fx larger than AIG manager.\n", 1.0*Vec_IntSize(vMapping)/Gia_ManObjNum(pGia) );
+ return Count;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Mf_ManPrintFanoutProfile( Mf_Man_t * p, Vec_Int_t * vFanCounts )
+{
+ Gia_Man_t * pGia = p->pGia0;
+ int i, Count, nMax = Vec_IntFindMax( vFanCounts );
+ Vec_Int_t * vCounts = Vec_IntStart( nMax + 1 );
+ Vec_IntForEachEntry( vFanCounts, Count, i )
+ if ( Count && Gia_ObjIsAnd(Gia_ManObj(pGia, i)) )
+ Vec_IntAddToEntry( vCounts, Count, 1 );
+ printf( "\nFanout distribution for internal nodes:\n" );
+ Vec_IntForEachEntry( vCounts, Count, i )
+ if ( Count ) printf( "Fanout = %5d : Nodes = %5d.\n", i, Count );
+ printf( "Total nodes with fanout = %d. Max fanout = %d.\n\n", Vec_IntCountPositive(vCounts), nMax );
+ Vec_IntFree( vCounts );
+}
+int Mf_ManPrintMfccStats( Mf_Man_t * p, int iObj )
+{
+ Gia_Man_t * pGia = p->pGia0;
+ int Area;
+ printf( "%5d : Level = %5d Refs = %5d Mffc = %5d\n",
+ iObj, Gia_ObjLevelId(pGia, iObj), Mf_ObjMapRefNum(p, iObj), (Area = Mf_CutAreaMffc(p, iObj)) );
+ return Area;
+}
+void Mf_ManOptimizationOne( Mf_Man_t * p, int iObj )
+{
+ Gia_Man_t * pGia = p->pGia0;
+ int * ppCuts[32], nCuts = 0;
+ int iFanout, i, nAreaSum = 0, nAreaBest = 0;
+ // skip pivots whose MFFC fanouts are pointed to by COs
+ Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i )
+ if ( Gia_ObjIsCo(Gia_ManObj(pGia, iFanout)) )
+ return;
+ // the pivot is used in the mapping as well as all of its fanouts
+ assert( Mf_ObjMapRefNum(p, iObj) > 1 );
+ Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i )
+ assert( Mf_ObjMapRefNum(p, iFanout) > 0 );
+ // print this pivot and its fanouts
+ printf( "\nPivot node = %d\n", iObj );
+ printf( "Pivot " ), Mf_ManPrintMfccStats( p, iObj );
+ Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i )
+ printf( "Node " ), nAreaSum += Mf_ManPrintMfccStats( p, iFanout );
+ // calculate the shared MFFC
+ Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i )
+ Mf_ObjMapRefInc( p, iFanout );
+ Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i )
+ ppCuts[nCuts++] = Mf_ObjCutBest( p, iFanout );
+ nAreaBest = Mf_CutAreaRefed2Multi( p, iObj, ppCuts, nCuts );
+ Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i )
+ Mf_ObjMapRefDec( p, iFanout );
+ printf( "Sum of MFFC sizes = %d\n", nAreaSum );
+ printf( "Shared MFFC size = %d\n", nAreaBest );
+}
+void Mf_ManOptimization( Mf_Man_t * p )
+{
+ int nOutMax = 3;
+ Gia_Man_t * pGia = p->pGia0;
+ int i, Count, nNodes = Mf_ManMappingFromMapping( p );
+ Gia_ManLevelNum( pGia );
+ Gia_ManStaticMappingFanoutStart( pGia );
+ Mf_ManPrintFanoutProfile( p, pGia->vFanoutNums );
+ printf( "\nIndividual logic cones for mapping with %d nodes:\n", nNodes );
+ Vec_IntForEachEntry( pGia->vFanoutNums, Count, i )
+ if ( Count >= 2 && Count <= nOutMax && Gia_ObjIsAnd(Gia_ManObj(pGia, i)) )
+ Mf_ManOptimizationOne( p, i );
+ printf( "\nFinished printing individual logic cones.\n" );
+ Gia_ManStaticFanoutStop( pGia );
+ Vec_IntFreeP( &pGia->vMapping );
+}
+
+/**Function*************************************************************
+
Synopsis [Technology mappping.]
Description []
@@ -1656,7 +1823,7 @@ Gia_Man_t * Mf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars )
{
Mf_Man_t * p;
Gia_Man_t * pNew, * pCls;
- if ( pPars->fGenCnf )
+ if ( pPars->fGenCnf || pPars->fGenLit )
pPars->fCutMin = 1;
if ( Gia_ManHasChoices(pGia) )
pPars->fCutMin = 1, pPars->fCoarsen = 0;
@@ -1675,6 +1842,7 @@ Gia_Man_t * Mf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars )
p->fUseEla = 1;
for ( ; p->Iter < p->pPars->nRounds + pPars->nRoundsEla; p->Iter++ )
Mf_ManComputeMapping( p );
+ //Mf_ManOptimization( p );
if ( pPars->fVeryVerbose && pPars->fCutMin )
Vec_MemDumpTruthTables( p->vTtMem, Gia_ManName(p->pGia), pPars->nLutSize );
if ( pPars->fCutMin )
@@ -1685,8 +1853,8 @@ Gia_Man_t * Mf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars )
pNew = Mf_ManDeriveMapping( p );
if ( p->pPars->fGenCnf )
pGia->pData = Mf_ManDeriveCnf( p, p->pPars->fCnfObjIds, p->pPars->fAddOrCla );
-// if ( p->pPars->fGenCnf )
-// Mf_ManProfileTruths( p );
+ //if ( p->pPars->fGenCnf || p->pPars->fGenLit )
+ // Mf_ManProfileTruths( p );
Gia_ManMappingVerify( pNew );
Mf_ManPrintQuit( p, pNew );
Mf_ManFree( p );
diff --git a/src/aig/gia/giaMinLut.c b/src/aig/gia/giaMinLut.c
new file mode 100644
index 00000000..5304486d
--- /dev/null
+++ b/src/aig/gia/giaMinLut.c
@@ -0,0 +1,1058 @@
+/**CFile****************************************************************
+
+ FileName [giaMinLut.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Collapsing AIG.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaMinLut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+#include "giaAig.h"
+#include "base/main/mainInt.h"
+#include "opt/sfm/sfm.h"
+
+#ifdef ABC_USE_CUDD
+#include "bdd/extrab/extraBdd.h"
+#include "bdd/dsd/dsd.h"
+#endif
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Wec_t * Vec_WrdReadLayerText( char * pFileName, int * pnIns, int * pnOuts )
+{
+ char * pThis, pLine[1000];
+ Vec_Wec_t * vRes; int iLine;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return NULL;
+ }
+ vRes = Vec_WecAlloc(100);
+ for ( iLine = 0; fgets( pLine, 1000, pFile ); iLine++ )
+ {
+ if ( iLine == 0 )
+ {
+ pThis = strstr( pLine, "[" );
+ *pnIns = atoi( pThis+1 ) + 1;
+ pThis = strstr( pThis+1, "[" );
+ *pnOuts = atoi( pThis+1 ) + 1;
+ }
+ else
+ {
+ Vec_Int_t * vLevel = NULL;
+ for ( pThis = pLine; (pThis = strstr(pThis, "M0[")); pThis++ )
+ {
+ if ( vLevel == NULL )
+ vLevel = Vec_WecPushLevel( vRes );
+ Vec_IntPush( vLevel, atoi( pThis+3 ) );
+ }
+ if ( vLevel )
+ Vec_IntReverseOrder( vLevel );
+ }
+ }
+ fclose( pFile );
+ //Vec_WecPrint( vRes, 0 );
+ return vRes;
+}
+int Vec_WrdReadTruthTextOne( char * pFileName, int nIns, int nOuts, word * pRes )
+{
+ int i, nWords = Abc_TtWordNum( nIns );
+ char * pStart, * pBuffer = Extra_FileReadContents( pFileName );
+ if ( pBuffer == NULL )
+ {
+ printf( "Cannot read file \"%s\".\n", pFileName );
+ return 0;
+ }
+ pStart = pBuffer;
+ for ( i = 0; i < nOuts; i++ )
+ {
+ pStart = strstr( pStart + 1, "0x" );
+ if ( !Extra_ReadHex( (unsigned *)(pRes + i*nWords), pStart + 2, nWords*16 ) )
+ {
+ printf( "Cannot read truth table %d (out of %d) in file \"%s\".\n", i, nOuts, pFileName );
+ ABC_FREE( pBuffer );
+ return 0;
+ }
+ }
+ ABC_FREE( pBuffer );
+ return 1;
+}
+word * Vec_WrdReadTruthText( char * pFileName, int nIns, int nOuts, int nFiles )
+{
+ char FileName[1000];
+ int i, nWords = Abc_TtWordNum( nIns );
+ word * pRes = ABC_CALLOC( word, nOuts*nFiles*nWords );
+ for ( i = 0; i < nFiles; i++ )
+ {
+ assert( strlen(pFileName) < 900 );
+ strcpy( FileName, pFileName );
+ sprintf( FileName + strlen(FileName) - 2, "_N%d.bench", i );
+ if ( !Vec_WrdReadTruthTextOne( FileName, nIns, nOuts, pRes + i*nOuts*nWords ) )
+ {
+ ABC_FREE( pRes );
+ return NULL;
+ }
+ }
+ return pRes;
+}
+Gia_Man_t * Vec_WrdReadTest( char * pFileName )
+{
+ extern int Gia_ManPerformLNetOpt_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj );
+ extern Gia_Man_t * Gia_TryPermOptCare( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose );
+ Gia_Man_t * pPart, * pNew = NULL; Gia_Obj_t * pObj;
+ int i, k, nIns, nOuts, iLit;
+ Vec_Wec_t * vRes = Vec_WrdReadLayerText( pFileName, &nIns, &nOuts );
+ int nBitsI = vRes ? Vec_WecMaxLevelSize(vRes) : 0;
+ int nBitsO = vRes ? nOuts / Vec_WecSize(vRes) : 0;
+ int nWords = Abc_TtWordNum(nBitsI);
+ word * pFuncs = vRes ? Vec_WrdReadTruthText( pFileName, nBitsI, nBitsO, Vec_WecSize(vRes) ) : NULL;
+ Vec_Int_t * vPart, * vLits = Vec_IntAlloc( nOuts );
+ if ( vRes == NULL || pFuncs == NULL )
+ {
+ Vec_WecFreeP( &vRes );
+ Vec_IntFreeP( &vLits );
+ ABC_FREE( pFuncs );
+ return NULL;
+ }
+ assert( nOuts % Vec_WecSize(vRes) == 0 );
+ pNew = Gia_ManStart( 10000 );
+ pNew->pName = Abc_UtilStrsav( pFileName );
+ pNew->pSpec = NULL;
+ for ( i = 0; i < nIns; i++ )
+ Gia_ManAppendCi(pNew);
+ Gia_ManHashStart( pNew );
+ Vec_WecForEachLevel( vRes, vPart, i )
+ {
+ assert( Vec_IntSize(vPart) <= nBitsI );
+ pPart = Gia_TryPermOptCare( pFuncs + i * nBitsO * nWords, nBitsI, nBitsO, nWords, 20, 0 );
+ Gia_ManFillValue( pPart );
+ Gia_ManConst0(pPart)->Value = 0;
+ Gia_ManForEachCi( pPart, pObj, k )
+ pObj->Value = Abc_Var2Lit( 1+Vec_IntEntry(vPart, k), 0 );
+ Gia_ManForEachCo( pPart, pObj, k )
+ {
+ Gia_ManPerformLNetOpt_rec( pNew, pPart, Gia_ObjFanin0(pObj) );
+ Vec_IntPush( vLits, Gia_ObjFanin0Copy(pObj) );
+ }
+ Gia_ManStop( pPart );
+ }
+ Gia_ManHashStop( pNew );
+ Vec_IntForEachEntry( vLits, iLit, i )
+ Gia_ManAppendCo( pNew, iLit );
+ ABC_FREE( pFuncs );
+ Vec_WecFree( vRes );
+ Vec_IntFree( vLits );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Vec_WrdReadText( char * pFileName, Vec_Wrd_t ** pvSimI, Vec_Wrd_t ** pvSimO, int nIns, int nOuts )
+{
+ int i, nSize, iLine, nLines, nWords;
+ char pLine[1000];
+ Vec_Wrd_t * vSimI, * vSimO;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return;
+ }
+ fseek( pFile, 0, SEEK_END );
+ nSize = ftell( pFile );
+ if ( nSize % (nIns + nOuts + 1) > 0 )
+ {
+ printf( "Cannot read file with simulation data that is not aligned at 8 bytes (remainder = %d).\n", nSize % (nIns + nOuts + 1) );
+ fclose( pFile );
+ return;
+ }
+ rewind( pFile );
+ nLines = nSize / (nIns + nOuts + 1);
+ nWords = (nLines + 63)/64;
+ vSimI = Vec_WrdStart( nIns *nWords );
+ vSimO = Vec_WrdStart( nOuts*nWords );
+ for ( iLine = 0; fgets( pLine, 1000, pFile ); iLine++ )
+ {
+ for ( i = 0; i < nIns; i++ )
+ if ( pLine[nIns-1-i] == '1' )
+ Abc_TtXorBit( Vec_WrdArray(vSimI) + i*nWords, iLine );
+ else assert( pLine[nIns-1-i] == '0' );
+ for ( i = 0; i < nOuts; i++ )
+ if ( pLine[nIns+nOuts-1-i] == '1' )
+ Abc_TtXorBit( Vec_WrdArray(vSimO) + i*nWords, iLine );
+ else assert( pLine[nIns+nOuts-1-i] == '0' );
+ }
+ fclose( pFile );
+ *pvSimI = vSimI;
+ *pvSimO = vSimO;
+ printf( "Read %d words of simulation data for %d inputs and %d outputs (padded %d zero-patterns).\n", nWords, nIns, nOuts, nWords*64-nLines );
+}
+int Vec_WrdReadText2( char * pFileName, Vec_Wrd_t ** pvSimI )
+{
+ int i, nSize, iLine, nLines, nWords, nIns;
+ char pLine[1000];
+ Vec_Wrd_t * vSimI;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return 0;
+ }
+ if ( !fgets(pLine, 1000, pFile) || (nIns = strlen(pLine)-1) < 1 )
+ {
+ printf( "Cannot find the number of inputs in file \"%s\".\n", pFileName );
+ fclose( pFile );
+ return 0;
+ }
+ fseek( pFile, 0, SEEK_END );
+ nSize = ftell( pFile );
+ if ( nSize % (nIns + 1) > 0 )
+ {
+ printf( "Cannot read file with simulation data that is not aligned at 8 bytes (remainder = %d).\n", nSize % (nIns + 1) );
+ fclose( pFile );
+ return 0;
+ }
+ rewind( pFile );
+ nLines = nSize / (nIns + 1);
+ nWords = (nLines + 63)/64;
+ vSimI = Vec_WrdStart( nIns *nWords );
+ for ( iLine = 0; fgets( pLine, 1000, pFile ); iLine++ )
+ {
+ for ( i = 0; i < nIns; i++ )
+ if ( pLine[nIns-1-i] == '1' )
+ Abc_TtXorBit( Vec_WrdArray(vSimI) + i*nWords, iLine );
+ else assert( pLine[nIns-1-i] == '0' );
+ }
+ fclose( pFile );
+ *pvSimI = vSimI;
+ printf( "Read %d words of simulation data for %d inputs (padded to 64-bit boundary with %d zero-patterns).\n", nWords, nIns, nWords*64-nLines );
+ return nIns;
+}
+Vec_Int_t * Vec_WrdReadNumsOut( char * pFileName, int fVerbose )
+{
+ char pLine[1000];
+ Vec_Int_t * vNums; int iLine;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return NULL;
+ }
+ vNums = Vec_IntAlloc( 1000 );
+ for ( iLine = 0; fgets( pLine, 1000, pFile ); iLine++ )
+ Vec_IntPush( vNums, atoi(pLine) );
+ fclose( pFile );
+ if ( fVerbose )
+ printf( "Finished reading %d output values from file \"%s\".\n", Vec_IntSize(vNums), pFileName );
+ return vNums;
+}
+Vec_Wrd_t * Vec_WrdReadTextOut( char * pFileName, int nOuts )
+{
+ int i, iLine, nLines, nWords;
+ Vec_Wrd_t * vSimO;
+ Vec_Int_t * vNums = Vec_WrdReadNumsOut( pFileName, 1 );
+ if ( vNums == NULL )
+ return NULL;
+ nLines = Vec_IntSize(vNums);
+ nWords = (nLines + 63)/64;
+ vSimO = Vec_WrdStart( nOuts*nWords );
+ Vec_IntForEachEntry( vNums, i, iLine )
+ Abc_TtXorBit( Vec_WrdArray(vSimO) + i*nWords, iLine );
+ Vec_IntFree( vNums );
+ printf( "Read %d words of simulation data for %d outputs (padded %d zero-patterns).\n", nWords, nOuts, nWords*64-nLines );
+ return vSimO;
+}
+void Gia_ManReadSimInfoInputs( char * pFileName, char * pFileOut1, int fVerbose )
+{
+ Vec_Wrd_t * vSimI;
+ Vec_WrdReadText2( pFileName, &vSimI );
+ Vec_WrdDumpBin( pFileOut1, vSimI, fVerbose );
+ Vec_WrdFree( vSimI );
+}
+void Gia_ManReadSimInfoOutputs( char * pFileName, char * pFileOut, int nOuts )
+{
+ Vec_Wrd_t * vSimO = Vec_WrdReadTextOut( pFileName, nOuts );
+ Vec_WrdDumpBin( pFileOut, vSimO, 1 );
+ Vec_WrdFree( vSimO );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Wrd_t * Vec_WrdZoneExtract( int ZoneSize, Vec_Wrd_t * p, int iWord, int nWords )
+{
+ int z, nZones = Vec_WrdSize(p)/ZoneSize;
+ int w, Limit = Abc_MinInt( nWords, ZoneSize-iWord );
+ Vec_Wrd_t * pNew = Vec_WrdStart( nZones*nWords );
+ for ( z = 0; z < nZones; z++ )
+ for ( w = 0; w < Limit; w++ )
+ Vec_WrdWriteEntry( pNew, z*nWords + w, Vec_WrdEntry(p, z*ZoneSize + iWord + w) );
+ return pNew;
+}
+void Vec_WrdZoneInsert( Vec_Wrd_t * pNew, int ZoneSize, Vec_Wrd_t * p, int iWord, int nWords )
+{
+ int z, nZones = Vec_WrdSize(pNew)/ZoneSize;
+ int w, Limit = Abc_MinInt( nWords, ZoneSize-iWord );
+ for ( z = 0; z < nZones; z++ )
+ for ( w = 0; w < Limit; w++ )
+ Vec_WrdWriteEntry( pNew, z*ZoneSize + iWord + w, Vec_WrdEntry(p, z*nWords + w) );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSimInfoPrintOne( Gia_Man_t * p, Vec_Wrd_t * vSimsIn, Vec_Wrd_t * vSimsOut, int nWords, int nPats )
+{
+ int Id, i, k;
+ for ( k = 0; k < nPats; k++ )
+ {
+ Gia_ManForEachCiId( p, Id, i )
+ // printf( "%d", Vec_WrdEntry(p->vSims, p->nSimWords*Id) & 1 );
+ printf( "%d", (int)(Vec_WrdEntry(vSimsIn, nWords*i) >> k) & 1 );
+ printf( " " );
+ Gia_ManForEachCoId( p, Id, i )
+ // printf( "%d", Vec_WrdEntry(p->vSims, p->nSimWords*Id) & 1 );
+ printf( "%d", (int)(Vec_WrdEntry(vSimsOut, nWords*i) >> k) & 1 );
+ printf( "\n" );
+ }
+}
+Vec_Wrd_t * Gia_ManSimInfoTryOne( Gia_Man_t * p, Vec_Wrd_t * vSimI, int fPrint )
+{
+ extern Vec_Wrd_t * Gia_ManSimulateWordsOut( Gia_Man_t * p, Vec_Wrd_t * vSimsIn );
+ Vec_Wrd_t * vSimsOut = Gia_ManSimulateWordsOut( p, vSimI );
+ int nWords = Vec_WrdSize(vSimI) / Gia_ManCiNum(p);
+ assert( Vec_WrdSize(vSimI) % Gia_ManCiNum(p) == 0 );
+ if ( fPrint )
+ Gia_ManSimInfoPrintOne( p, vSimI, vSimsOut, nWords, 6 );
+ return vSimsOut;
+}
+int Gia_ManSimEvalOne( Gia_Man_t * p, Vec_Wrd_t * vSimO, Vec_Wrd_t * vSimO_new )
+{
+ int i, Count = 0, nWords = Vec_WrdSize(vSimO) / Gia_ManCoNum(p);
+ word * pSim0 = ABC_CALLOC( word, nWords );
+ assert( Vec_WrdSize(vSimO) == Vec_WrdSize(vSimO_new) );
+ for ( i = 0; i < Gia_ManCoNum(p); i++ )
+ {
+ word * pSimGold = Vec_WrdEntryP( vSimO, i * nWords );
+ word * pSimImpl = Vec_WrdEntryP( vSimO_new, i * nWords );
+ Abc_TtOrXor( pSim0, pSimImpl, pSimGold, nWords );
+ }
+ Count = Abc_TtCountOnesVec( pSim0, nWords );
+ printf( "Number of failed patterns is %d (%8.4f %% of %d). The first one is %d.\n",
+ Count, 100.0*Count/(64*nWords), 64*nWords, Abc_TtFindFirstBit2(pSim0, nWords) );
+ ABC_FREE( pSim0 );
+ return Count;
+}
+int Gia_ManSimEvalOne2( Gia_Man_t * p, Vec_Wrd_t * vSimO, Vec_Wrd_t * vSimO_new )
+{
+ int i, Count = 0, nWords = Vec_WrdSize(vSimO) / Gia_ManCoNum(p);
+ word * pSim0 = ABC_CALLOC( word, nWords );
+ assert( Vec_WrdSize(vSimO) == Vec_WrdSize(vSimO_new) );
+ for ( i = 0; i < Gia_ManCoNum(p); i++ )
+ {
+ word * pSimGold = Vec_WrdEntryP( vSimO, i * nWords );
+ word * pSimImpl = Vec_WrdEntryP( vSimO_new, i * nWords );
+ Abc_TtXor( pSim0, pSimImpl, pSimGold, nWords, 0 );
+ Count += Abc_TtCountOnesVec( pSim0, nWords );
+ }
+ printf( "Number of failed patterns is %d (%8.4f %% of %d). The first one is %d.\n",
+ Count, 100.0*Count/(64*nWords*Gia_ManCoNum(p)), 64*nWords*Gia_ManCoNum(p), Abc_TtFindFirstBit2(pSim0, nWords) );
+ ABC_FREE( pSim0 );
+ return Count;
+}
+int Gia_ManSimEvalMaxValue( Vec_Wrd_t * vSimO, int nWords, int nOuts, int nBits, int iPat )
+{
+ int o, ValueMax = -1, OutMax = -1;
+ for ( o = 0; o < nOuts; o++ )
+ {
+ int i, Value = 0;
+ for ( i = 0; i < nBits; i++ )
+ {
+ word * pSim = Vec_WrdEntryP( vSimO, (o*nBits+i) * nWords );
+ if ( Abc_TtGetBit(pSim, iPat) )
+ Value |= 1 << i;
+ }
+ if ( ValueMax <= Value )
+ {
+ ValueMax = Value;
+ OutMax = o;
+ }
+ }
+ return OutMax;
+}
+int Gia_ManSimEvalOne3( Gia_Man_t * p, Vec_Wrd_t * vSimO, Vec_Int_t * vValues, int nBits )
+{
+ int i, Value, nOuts = Gia_ManCoNum(p) / nBits;
+ int First = -1, Count = 0, nWords = Vec_WrdSize(vSimO) / Gia_ManCoNum(p);
+ assert( Gia_ManCoNum(p) % nBits == 0 );
+ assert( 64*(nWords-1) < Vec_IntSize(vValues) && Vec_IntSize(vValues) <= 64*nWords );
+ Vec_IntForEachEntry( vValues, Value, i )
+ if ( Value == Gia_ManSimEvalMaxValue(vSimO, nWords, nOuts, nBits, i) )
+ {
+ Count++;
+ if ( First == -1 )
+ First = i;
+ }
+ printf( "The accuracy is %8.4f %% (%d out of %d output are correct, for example, output number %d).\n",
+ 100.0*Count/Vec_IntSize(vValues), Count, Vec_IntSize(vValues), First );
+ if ( 0 )
+ {
+ FILE * pTable = fopen( "stats.txt", "a+" );
+ fprintf( pTable, "%0.2f \n", 100.0*Count/Vec_IntSize(vValues) );
+ fclose( pTable );
+ }
+ return Count;
+}
+Vec_Wrd_t * Gia_ManSimInfoTry( Gia_Man_t * p, Vec_Wrd_t * vSimI )
+{
+ int nWords = Vec_WrdSize(vSimI) / Gia_ManCiNum(p);
+ int w, nWordsOne = 200, nWordBatches = (nWords + nWordsOne - 1)/nWordsOne;
+ Vec_Wrd_t * vSimO_new = Vec_WrdStart( nWords * Gia_ManCoNum(p) );
+ for ( w = 0; w < nWordBatches; w++ )
+ {
+ //int Value = printf( "%3d / %3d : ", w, nWordBatches );
+ Vec_Wrd_t * vSimI_ = Vec_WrdZoneExtract( nWords, vSimI, w*nWordsOne, nWordsOne );
+ Vec_Wrd_t * vSimO_ = Gia_ManSimInfoTryOne( p, vSimI_, 0 );
+ Vec_WrdZoneInsert( vSimO_new, nWords, vSimO_, w*nWordsOne, nWordsOne );
+ Vec_WrdFree( vSimI_ );
+ Vec_WrdFree( vSimO_ );
+ //Value = 0;
+ }
+ return vSimO_new;
+}
+int Gia_ManSimInfoEval_old( Gia_Man_t * p, Vec_Wrd_t * vSimO, Vec_Wrd_t * vSimO_new )
+{
+ int nResult = Gia_ManSimEvalOne2(p, vSimO, vSimO_new);
+ //Vec_WrdDumpBin( "temp.simo", vSimO_new, 1 );
+ printf( "Total errors = %d. ", nResult );
+ printf( "Density of output patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimO_new), Vec_WrdSize(vSimO_new))/(64*Vec_WrdSize(vSimO_new)) );
+ return nResult;
+}
+void Gia_ManSimInfoPassTest( Gia_Man_t * p, char * pFileName, char * pFileName2, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ Vec_Wrd_t * vSimI = Vec_WrdReadBin( pFileName, fVerbose );
+ Vec_Wrd_t * vSimO = Gia_ManSimInfoTry( p, vSimI );
+ if ( fVerbose )
+ printf( "Density of input patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) );
+ if ( fVerbose )
+ printf( "Density of output patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimO), Vec_WrdSize(vSimO))/(64*Vec_WrdSize(vSimO)) );
+ Vec_WrdDumpBin( pFileName2, vSimO, fVerbose );
+ Vec_WrdFree( vSimI );
+ Vec_WrdFree( vSimO );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+}
+void Gia_ManSimInfoEval( Gia_Man_t * p, char * pFileName, char * pFileName2, int nOuts, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ Vec_Wrd_t * vSim1 = Vec_WrdReadBin( pFileName, fVerbose );
+ Vec_Int_t * vNums = Vec_WrdReadNumsOut( pFileName2, fVerbose );
+ assert( nOuts > 0 );
+ if ( fVerbose )
+ printf( "Density of input patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSim1), Vec_WrdSize(vSim1))/(64*Vec_WrdSize(vSim1)) );
+ Gia_ManSimEvalOne3( p, vSim1, vNums, nOuts );
+ Vec_WrdFree( vSim1 );
+ Vec_IntFree( vNums );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+word * Gia_ManCountFraction( Gia_Man_t * p, Vec_Wrd_t * vSimI, Vec_Int_t * vSupp, int Thresh, int fVerbose, int * pCare )
+{
+ Gia_Obj_t * pObj;
+ int i, k, nUsed = 0, nGood = 0;
+ int nWords = Vec_WrdSize(vSimI) / Gia_ManCiNum(p);
+ int nMints = 1 << Vec_IntSize(vSupp);
+ word ** pSims = ABC_ALLOC( word *, Vec_IntSize(vSupp) );
+ word * pRes = ABC_CALLOC( word, Abc_Truth6WordNum(Vec_IntSize(vSupp)) );
+ int * pCounts = ABC_CALLOC( int, nMints );
+ Gia_ManForEachObjVec( vSupp, p, pObj, i )
+ pSims[i] = Vec_WrdEntryP( vSimI, Gia_ObjCioId(pObj) * nWords );
+ for ( k = 0; k < 64*nWords; k++ )
+ {
+ int iMint = 0;
+ for ( i = 0; i < Vec_IntSize(vSupp); i++ )
+ if ( Abc_TtGetBit(pSims[i], k) )
+ iMint |= 1 << i;
+ assert( iMint < nMints );
+ pCounts[iMint]++;
+ }
+ for ( k = 0; k < nMints; k++ )
+ {
+ nUsed += (pCounts[k] > 0);
+ nGood += (pCounts[k] >= Thresh);
+ if ( pCounts[k] >= Thresh )
+ Abc_TtXorBit( pRes, k );
+ //printf( "%d ", pCounts[k] );
+ }
+ if ( Vec_IntSize(vSupp) < 6 )
+ pRes[0] = Abc_Tt6Stretch( pRes[0], Vec_IntSize(vSupp) );
+ //printf( "\n" );
+ if ( fVerbose )
+ printf( "Used %4d and good %4d (out of %4d).\n", nUsed, nGood, nMints );
+ ABC_FREE( pSims );
+ ABC_FREE( pCounts );
+ *pCare = nGood;
+ return pRes;
+}
+void Gia_ManPermuteSupp_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vLevels, Vec_Int_t * vCounts )
+{
+ Gia_Obj_t * pObj; int n;
+ if ( !iObj || Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ pObj = Gia_ManObj( p, iObj );
+ if ( Gia_ObjIsCi(pObj) )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManPermuteSupp_rec( p, Gia_ObjFaninId0(pObj, iObj), vLevels, vCounts );
+ Gia_ManPermuteSupp_rec( p, Gia_ObjFaninId1(pObj, iObj), vLevels, vCounts );
+ for ( n = 0; n < 2; n++ )
+ {
+ Gia_Obj_t * pFanin = n ? Gia_ObjFanin1(pObj) : Gia_ObjFanin0(pObj);
+ if ( !Gia_ObjIsCi(pFanin) )
+ continue;
+ Vec_IntAddToEntry( vLevels, Gia_ObjCioId(pFanin), Gia_ObjLevel(p, pObj) );
+ Vec_IntAddToEntry( vCounts, Gia_ObjCioId(pFanin), 1 );
+ }
+}
+void Gia_ManPermuteSupp( Gia_Man_t * p, int iOut, int nOuts, Vec_Int_t * vSupp )
+{
+ Vec_Int_t * vLevels = Vec_IntStart( Gia_ManCiNum(p) );
+ Vec_Int_t * vCounts = Vec_IntStart( Gia_ManCiNum(p) );
+ int i, * pCost = ABC_CALLOC( int, Gia_ManCiNum(p) );
+ Gia_Obj_t * pObj;
+ Gia_ManIncrementTravId( p );
+ for ( i = 0; i < nOuts; i++ )
+ Gia_ManPermuteSupp_rec( p, Gia_ObjFaninId0p(p, Gia_ManCo(p, iOut+i)), vLevels, vCounts );
+ Gia_ManForEachObjVec( vSupp, p, pObj, i )
+ pCost[i] = 10000 * Vec_IntEntry(vLevels, Gia_ObjCioId(pObj)) / Abc_MaxInt(1, Vec_IntEntry(vCounts, Gia_ObjCioId(pObj)));
+ Vec_IntFree( vCounts );
+ Vec_IntFree( vLevels );
+ Vec_IntSelectSortCost2( Vec_IntArray(vSupp), Vec_IntSize(vSupp), pCost );
+ assert( Vec_IntSize(vSupp) < 2 || pCost[0] <= pCost[1] );
+ ABC_FREE( pCost );
+}
+void Gia_ManCollectSupp_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vSupp )
+{
+ Gia_Obj_t * pObj;
+ if ( !iObj || Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ pObj = Gia_ManObj( p, iObj );
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ //Vec_IntPush( vSupp, Gia_ObjCioId(pObj) );
+ Vec_IntPush( vSupp, Gia_ObjId(p, pObj) );
+ return;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManCollectSupp_rec( p, Gia_ObjFaninId0(pObj, iObj), vSupp );
+ Gia_ManCollectSupp_rec( p, Gia_ObjFaninId1(pObj, iObj), vSupp );
+}
+Vec_Int_t * Gia_ManCollectSupp( Gia_Man_t * p, int iOut, int nOuts )
+{
+ Vec_Int_t * vSupp = Vec_IntAlloc( 16 ); int i;
+ Gia_ManIncrementTravId( p );
+ for ( i = 0; i < nOuts; i++ )
+ Gia_ManCollectSupp_rec( p, Gia_ObjFaninId0p(p, Gia_ManCo(p, iOut+i)), vSupp );
+ return vSupp;
+}
+Vec_Int_t * Gia_ManCollectSuppNew( Gia_Man_t * p, int iOut, int nOuts )
+{
+ Vec_Int_t * vRes = Gia_ManCollectSupp( p, iOut, nOuts );
+ Gia_ManPermuteSupp( p, iOut, nOuts, vRes );
+ return vRes;
+}
+int Gia_ManPerformLNetOpt_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( ~pObj->Value )
+ return pObj->Value;
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManPerformLNetOpt_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Gia_ManPerformLNetOpt_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ return pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+Gia_Man_t * Gia_ManPerformLNetOpt( Gia_Man_t * p, int fTryNew, char * pFileName, int nIns, int nOuts, int Thresh, int nRounds, int fVerbose )
+{
+ extern Gia_Man_t * Gia_TryPermOpt( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose );
+ extern Gia_Man_t * Gia_TryPermOptCare( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose );
+ extern int Kit_TruthToGia2( Gia_Man_t * p, unsigned * pTruth0, unsigned * pTruth1, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash );
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pNew; Gia_Obj_t * pObj;
+ Vec_Int_t * vMemory = Vec_IntAlloc( 1 << 18 );
+ Vec_Int_t * vLeaves = Vec_IntAlloc( nIns );
+ Vec_Wrd_t * vSimI = pFileName ? Vec_WrdReadBin( pFileName, fVerbose ) : NULL;
+ word * pTruth0 = ABC_CALLOC( word, Abc_Truth6WordNum(nIns) );
+ word * pTruth1 = ABC_CALLOC( word, Abc_Truth6WordNum(nIns) ); int g, k; float CareAve = 0;
+ word * pTruthsTry = ABC_CALLOC( word, 2*nOuts*Abc_Truth6WordNum(nIns) );
+ if ( vSimI && fVerbose )
+ {
+ //int nPats = 64*Vec_WrdSize(vSimI)/Gia_ManCiNum(p);
+ printf( "Density of input patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) );
+ printf( "Using patterns with count %d and higher as cares.\n", Thresh );
+ }
+ Gia_ManLevelNum( p );
+ Gia_ManFillValue( p );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, k )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ObjComputeTruthTableStart( p, nIns );
+ Gia_ManHashStart( pNew );
+ for ( g = 0; g < Gia_ManCoNum(p); g += nOuts )
+ {
+ Vec_Int_t * vSupp = Gia_ManCollectSuppNew( p, g, nOuts );
+ int Care = 1 << Vec_IntSize(vSupp), Temp = fVerbose ? printf( "Group %3d / %3d / %3d : Supp = %3d %s", g, nOuts, Gia_ManCoNum(p), Vec_IntSize(vSupp), vSimI ? "":"\n" ) : 0;
+ word * pCare = vSimI ? Gia_ManCountFraction( p, vSimI, vSupp, Thresh, fVerbose, &Care ) : ABC_FALLOC( word, Abc_Truth6WordNum(Vec_IntSize(vSupp)) );
+ int nWords = Abc_Truth6WordNum( Vec_IntSize(vSupp) );
+ CareAve += 100.0*Care/(1 << Vec_IntSize(vSupp));
+ assert( Vec_IntSize(vSupp) <= nIns );
+ Vec_IntClear( vLeaves );
+ Gia_ManForEachObjVec( vSupp, p, pObj, k )
+ Vec_IntPush( vLeaves, pObj->Value );
+ for ( k = 0; k < nOuts; k++ )
+ {
+ Gia_Obj_t * pObj = Gia_ManCo( p, g+k );
+ word * pTruth = Gia_ObjComputeTruthTableCut( p, Gia_ObjFanin0(pObj), vSupp );
+ Abc_TtSharp( pTruth0, pCare, pTruth, nWords );
+ Abc_TtAnd( pTruth1, pCare, pTruth, nWords, 0 );
+ if ( vSimI )
+ {
+ Abc_TtCopy( pTruthsTry + (2*k+0)*nWords, pTruth1, nWords, 0 );
+ Abc_TtCopy( pTruthsTry + (2*k+1)*nWords, pTruth0, nWords, 0 );
+ }
+ else
+ Abc_TtCopy( pTruthsTry + k*nWords, pTruth1, nWords, 0 );
+ if ( !fTryNew )
+ {
+ pObj->Value = Kit_TruthToGia2( pNew, (unsigned *)pTruth0, (unsigned *)pTruth1, Vec_IntSize(vLeaves), vMemory, vLeaves, 1 );
+ pObj->Value ^= Gia_ObjFaninC0(pObj);
+ }
+ }
+ if ( fTryNew )
+ {
+ Gia_Man_t * pMin;
+ if ( vSimI )
+ pMin = Gia_TryPermOpt( pTruthsTry, Vec_IntSize(vSupp), 2*nOuts, nWords, nRounds, fVerbose );
+ else
+ pMin = Gia_TryPermOptCare( pTruthsTry, Vec_IntSize(vSupp), nOuts, nWords, nRounds, fVerbose );
+ Gia_ManFillValue( pMin );
+ Gia_ManConst0(pMin)->Value = 0;
+ Gia_ManForEachCi( pMin, pObj, k )
+ pObj->Value = Vec_IntEntry( vLeaves, k );
+ for ( k = 0; k < nOuts; k++ )
+ {
+ Gia_Obj_t * pObj = Gia_ManCo( p, g+k );
+ Gia_Obj_t * pObj2 = Gia_ManCo( pMin, k );
+ pObj->Value = Gia_ManPerformLNetOpt_rec( pNew, pMin, Gia_ObjFanin0(pObj2) );
+ pObj->Value ^= Gia_ObjFaninC0(pObj2);
+ pObj->Value ^= Gia_ObjFaninC0(pObj);
+ }
+ Gia_ManStop( pMin );
+ }
+ ABC_FREE( pCare );
+ Vec_IntFree( vSupp );
+ Temp = 0;
+ }
+ CareAve /= Gia_ManCoNum(p)/nOuts;
+ Gia_ManHashStop( pNew );
+ Gia_ManForEachCo( p, pObj, k )
+ pObj->Value = Gia_ManAppendCo( pNew, pObj->Value );
+ Gia_ObjComputeTruthTableStop( p );
+ ABC_FREE( pTruth0 );
+ ABC_FREE( pTruth1 );
+ Vec_IntFree( vLeaves );
+ Vec_IntFree( vMemory );
+ Vec_WrdFreeP( &vSimI );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ printf( "Using patterns with count %d and higher as cares. Average care set is %8.4f %%. ", Thresh, CareAve );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ if ( 0 )
+ {
+ FILE * pTable = fopen( "stats.txt", "a+" );
+ fprintf( pTable, "%0.2f ", CareAve );
+ fclose( pTable );
+ }
+ ABC_FREE( pTruthsTry );
+ return pNew;
+}
+Gia_Man_t * Gia_ManPerformLNetOptNew( Gia_Man_t * p, char * pFileName, int nIns, int nOuts, int Thresh, int nRounds, int fVerbose )
+{
+ extern Gia_Man_t * Gia_TryPermOptNew( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose );
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pNew, * pMin; Gia_Obj_t * pObj;
+ Vec_Int_t * vLeaves = Vec_IntAlloc( nIns );
+ Vec_Wrd_t * vSimI = pFileName ? Vec_WrdReadBin( pFileName, fVerbose ) : NULL;
+ word * pTruthsTry = ABC_CALLOC( word, (nOuts+1)*Abc_Truth6WordNum(nIns) );
+ int k, g; float CareAve = 0;
+ if ( vSimI && fVerbose )
+ {
+ //int nPats = 64*Vec_WrdSize(vSimI)/Gia_ManCiNum(p);
+ printf( "Density of input patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) );
+ printf( "Using patterns with count %d and higher as cares.\n", Thresh );
+ }
+ Gia_ManLevelNum( p );
+ Gia_ManFillValue( p );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, k )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ObjComputeTruthTableStart( p, nIns );
+ Gia_ManHashStart( pNew );
+ for ( g = 0; g < Gia_ManCoNum(p); g += nOuts )
+ {
+ for ( k = 0; k < nOuts; k++ )
+ if ( Gia_ObjIsAnd(Gia_ObjFanin0(Gia_ManCo( p, g+k ))) )
+ break;
+ if ( k == nOuts )
+ {
+ for ( k = 0; k < nOuts; k++ )
+ {
+ Gia_Obj_t * pObj = Gia_ManCo( p, g+k );
+ pObj->Value = Gia_ObjFanin0Copy(pObj);
+ }
+ continue;
+ }
+ else
+ {
+
+ Vec_Int_t * vSupp = Gia_ManCollectSuppNew( p, g, nOuts );
+ int Care = 1 << Vec_IntSize(vSupp), Temp = fVerbose ? printf( "Group %3d / %3d / %3d : Supp = %3d %s", g, nOuts, Gia_ManCoNum(p), Vec_IntSize(vSupp), vSimI ? "":"\n" ) : 0;
+ word * pCare = vSimI ? Gia_ManCountFraction( p, vSimI, vSupp, Thresh, fVerbose, &Care ) : ABC_FALLOC( word, Abc_Truth6WordNum(Vec_IntSize(vSupp)) );
+ int nWords = Abc_Truth6WordNum( Vec_IntSize(vSupp) );
+ CareAve += 100.0*Care/(1 << Vec_IntSize(vSupp));
+ assert( Vec_IntSize(vSupp) <= nIns );
+ Vec_IntClear( vLeaves );
+ Gia_ManForEachObjVec( vSupp, p, pObj, k )
+ Vec_IntPush( vLeaves, pObj->Value );
+ for ( k = 0; k < nOuts; k++ )
+ {
+ Gia_Obj_t * pObj = Gia_ManCo( p, g+k );
+ word * pTruth = Gia_ObjComputeTruthTableCut( p, Gia_ObjFanin0(pObj), vSupp );
+ Abc_TtCopy( pTruthsTry + k*nWords, pTruth, nWords, Gia_ObjFaninC0(pObj) );
+ }
+ Abc_TtCopy( pTruthsTry + nOuts*nWords, pCare, nWords, 0 );
+ ABC_FREE( pCare );
+ pMin = Gia_TryPermOptNew( pTruthsTry, Vec_IntSize(vSupp), nOuts, nWords, nRounds, fVerbose );
+ Gia_ManFillValue( pMin );
+ Gia_ManConst0(pMin)->Value = 0;
+ Gia_ManForEachCi( pMin, pObj, k )
+ pObj->Value = Vec_IntEntry( vLeaves, k );
+ Gia_ManForEachCo( pMin, pObj, k )
+ {
+ Gia_Obj_t * pObj0 = Gia_ManCo( p, g+k );
+ pObj0->Value = Gia_ManPerformLNetOpt_rec( pNew, pMin, Gia_ObjFanin0(pObj) );
+ pObj0->Value ^= Gia_ObjFaninC0(pObj);
+ }
+ Gia_ManStop( pMin );
+ Vec_IntFree( vSupp );
+ Temp = 0;
+
+ }
+ }
+ CareAve /= Gia_ManCoNum(p)/nOuts;
+ Gia_ManHashStop( pNew );
+ Gia_ManForEachCo( p, pObj, k )
+ pObj->Value = Gia_ManAppendCo( pNew, pObj->Value );
+ Gia_ObjComputeTruthTableStop( p );
+ Vec_IntFree( vLeaves );
+ Vec_WrdFreeP( &vSimI );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ printf( "Using patterns with count %d and higher as cares. Average care set is %8.4f %%. ", Thresh, CareAve );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ if ( 0 )
+ {
+ FILE * pTable = fopen( "stats.txt", "a+" );
+ fprintf( pTable, "%0.2f ", CareAve );
+ fclose( pTable );
+ }
+ ABC_FREE( pTruthsTry );
+ return pNew;
+}
+
+#ifdef ABC_USE_CUDD
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManDoMuxMapping( Gia_Man_t * p )
+{
+ extern Gia_Man_t * Gia_ManPerformMfs( Gia_Man_t * p, Sfm_Par_t * pPars );
+ Gia_Man_t * pTemp, * pNew = Gia_ManDup( p );
+ Jf_Par_t Pars, * pPars = &Pars; int c, nIters = 2;
+ Sfm_Par_t Pars2, * pPars2 = &Pars2;
+ Lf_ManSetDefaultPars( pPars );
+ Sfm_ParSetDefault( pPars2 );
+ pPars2->nTfoLevMax = 5;
+ pPars2->nDepthMax = 100;
+ pPars2->nWinSizeMax = 2000;
+ for ( c = 0; c < nIters; c++ )
+ {
+ pNew = Lf_ManPerformMapping( pTemp = pNew, pPars );
+ Gia_ManStop( pTemp );
+ pNew = Gia_ManPerformMfs( pTemp = pNew, pPars2 );
+ Gia_ManStop( pTemp );
+ if ( c == nIters-1 )
+ break;
+ pNew = (Gia_Man_t *)Dsm_ManDeriveGia( pTemp = pNew, 0 );
+ Gia_ManStop( pTemp );
+ }
+ return pNew;
+}
+Gia_Man_t * Gia_ManDoMuxTransform( Gia_Man_t * p, int fReorder )
+{
+ extern Gia_Man_t * Abc_NtkStrashToGia( Abc_Ntk_t * pNtk );
+ extern int Abc_NtkBddToMuxesPerformGlo( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, int Limit, int fReorder, int fUseAdd );
+ Gia_Man_t * pRes = NULL;
+ Aig_Man_t * pMan = Gia_ManToAig( p, 0 );
+ Abc_Ntk_t * pNtk = Abc_NtkFromAigPhase( pMan );
+ Abc_Ntk_t * pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
+ pNtk->pName = Extra_UtilStrsav( pMan->pName );
+ Aig_ManStop( pMan );
+ //pNtkNew = Abc_NtkBddToMuxes( pNtk, 1, 1000000, 1 );
+ if ( Abc_NtkBddToMuxesPerformGlo( pNtk, pNtkNew, 1000000, fReorder, 0 ) )
+ {
+ Abc_Ntk_t * pStrash = Abc_NtkStrash( pNtkNew, 1, 1, 0 );
+ pRes = Abc_NtkStrashToGia( pStrash );
+ Abc_NtkDelete( pStrash );
+ }
+ Abc_NtkDelete( pNtkNew );
+ Abc_NtkDelete( pNtk );
+ return pRes;
+}
+int Gia_ManDoTest1( Gia_Man_t * p, int fReorder )
+{
+ Gia_Man_t * pTemp, * pNew; int Res;
+ pNew = Gia_ManDoMuxTransform( p, fReorder );
+ pNew = Gia_ManDoMuxMapping( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ Res = Gia_ManLutNum( pNew );
+ Gia_ManStop( pNew );
+ return Res;
+}
+Abc_Ntk_t * Gia_ManDoTest2( Gia_Man_t * p, int fReorder, int fTryNew )
+{
+ extern Abc_Ntk_t * Abc_NtkFromMappedGia( Gia_Man_t * p, int fFindEnables, int fUseBuffs );
+ Abc_Ntk_t * pNtkNew;
+ Gia_Man_t * pTemp, * pNew;
+ pNew = fTryNew ? Gia_ManDup(p) : Gia_ManDoMuxTransform( p, fReorder );
+ pNew = Gia_ManDoMuxMapping( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ pNtkNew = Abc_NtkFromMappedGia( pNew, 0, 0 );
+ pNtkNew->pName = Extra_UtilStrsav(p->pName);
+ Gia_ManStop( pNew );
+ Abc_NtkToSop( pNtkNew, 1, ABC_INFINITY );
+ return pNtkNew;
+}
+Abc_Ntk_t * Abc_NtkMapTransform( Gia_Man_t * p, int nOuts, int fUseFixed, int fTryNew, int fVerbose )
+{
+ extern Abc_Ntk_t * Abc_NtkSpecialMapping( Abc_Ntk_t * pNtk, int fVerbose );
+ int i, k, g, nGroups = Gia_ManCoNum(p) / nOuts, CountsAll[3] = {0};
+ Abc_Obj_t * pObjNew, * pFaninNew; Gia_Obj_t * pObj;
+ Abc_Ntk_t * pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 );
+ assert( Gia_ManCoNum(p) % nOuts == 0 );
+ pNtkNew->pName = Extra_UtilStrsav(p->pName);
+ pNtkNew->pSpec = Extra_UtilStrsav(p->pSpec);
+ Gia_ManFillValue( p );
+ Gia_ManForEachPi( p, pObj, i )
+ Abc_NtkCreatePi( pNtkNew );
+ Gia_ManForEachPo( p, pObj, i )
+ Abc_NtkCreatePo( pNtkNew );
+ assert( nOuts <= 64 );
+ for ( g = 0; g < nGroups; g++ )
+ {
+ Gia_Man_t * pNew; Aig_Man_t * pMan;
+ Abc_Ntk_t * pNtk, * pNtkRes, * pNtkMap;
+ int pPos[64], Counter = 0, Counts[3] = {0};
+ for ( i = 0; i < nOuts; i++ )
+ pPos[i] = g*nOuts+i;
+ pNew = Gia_ManDupCones( p, pPos, nOuts, 1 );
+ if ( !fUseFixed )
+ pNtkMap = Gia_ManDoTest2( pNew, 1, fTryNew );
+ else
+ {
+ pMan = Gia_ManToAig( pNew, 0 );
+ pNtk = Abc_NtkFromAigPhase( pMan );
+ Aig_ManStop( pMan );
+ pNtkRes = Abc_NtkBddToMuxes( pNtk, 1, 1000000, 1 );
+ Abc_NtkDelete( pNtk );
+ pNtkMap = Abc_NtkSpecialMapping( pNtkRes, 0 );
+ Abc_NtkDelete( pNtkRes );
+ }
+ Gia_ManStop( pNew );
+ Gia_ManForEachCi( p, pObj, i )
+ if ( ~pObj->Value )
+ Abc_NtkCi(pNtkMap, Counter++)->pCopy = Abc_NtkCi(pNtkNew, i);
+ assert( Counter == Abc_NtkCiNum(pNtkMap) );
+ Abc_NtkForEachNode( pNtkMap, pObjNew, i )
+ {
+ pObjNew->pCopy = Abc_NtkDupObj( pNtkNew, pObjNew, 0 );
+ pObjNew->pCopy->fPersist = pObjNew->fPersist;
+ if ( pObjNew->fPersist )
+ Counts[1]++;
+ else
+ Counts[0]++;
+ Abc_ObjForEachFanin( pObjNew, pFaninNew, k )
+ Abc_ObjAddFanin( pObjNew->pCopy, pFaninNew->pCopy );
+ }
+ Abc_NtkForEachCo( pNtkMap, pObjNew, i )
+ Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, g*nOuts+i), Abc_ObjFanin0(pObjNew)->pCopy );
+ Abc_NtkDelete( pNtkMap );
+
+ if ( fVerbose )
+ {
+ printf( "%3d / %3d : ", g, nGroups );
+ printf( "Test = %4d ", Counts[0] );
+ printf( "MarkA = %4d ", Counts[1] );
+ printf( "MarkB = %4d ", Counts[2] );
+ printf( "\n" );
+ }
+
+ CountsAll[0] += Counts[0];
+ CountsAll[1] += Counts[1];
+ CountsAll[2] += Counts[2];
+ }
+ if ( fVerbose )
+ printf( "Total LUT count = %5d. MarkA = %5d. MarkB = %5d.\n", CountsAll[0], CountsAll[1], CountsAll[2] );
+ // create names
+ Abc_NtkAddDummyPiNames( pNtkNew );
+ Abc_NtkAddDummyPoNames( pNtkNew );
+ Abc_NtkAddDummyBoxNames( pNtkNew );
+ // check the resulting AIG
+ if ( !Abc_NtkCheck( pNtkNew ) )
+ Abc_Print( 1, "Abc_NtkFromMappedGia(): Network check has failed.\n" );
+ return pNtkNew;
+}
+
+Abc_Ntk_t * Gia_ManPerformLNetMap( Gia_Man_t * p, int GroupSize, int fUseFixed, int fTryNew, int fVerbose )
+{
+ int fPrintOnly = 0;
+ int Res1, Res2, Result = 0;
+ int g, nGroups = Gia_ManCoNum(p) / GroupSize;
+ assert( Gia_ManCoNum(p) % GroupSize == 0 );
+ assert( GroupSize <= 64 );
+ if ( fPrintOnly )
+ {
+ for ( g = 0; g < nGroups; g++ )
+ {
+ Gia_Man_t * pNew;
+ int o, pPos[64];
+ for ( o = 0; o < GroupSize; o++ )
+ pPos[o] = g*GroupSize+o;
+ pNew = Gia_ManDupCones( p, pPos, GroupSize, 0 );
+ printf( "%3d / %3d : ", g, nGroups );
+ printf( "Test1 = %4d ", Res1 = Gia_ManDoTest1(pNew, 0) );
+ printf( "Test2 = %4d ", Res2 = Gia_ManDoTest1(pNew, 1) );
+ printf( "Test = %4d ", Abc_MinInt(Res1, Res2) );
+ printf( "\n" );
+ Result += Abc_MinInt(Res1, Res2);
+ //Gia_ManPrintStats( pNew, NULL );
+ Gia_ManStop( pNew );
+ }
+ printf( "Total LUT count = %d.\n", Result );
+ return NULL;
+
+ }
+ return Abc_NtkMapTransform( p, GroupSize, fUseFixed, fTryNew, fVerbose );
+}
+
+#else
+
+Abc_Ntk_t * Gia_ManPerformLNetMap( Gia_Man_t * p, int GroupSize, int fUseFixed, int fTryNew, int fVerbose )
+{
+ return NULL;
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaMinLut2.c b/src/aig/gia/giaMinLut2.c
new file mode 100644
index 00000000..85cae0d2
--- /dev/null
+++ b/src/aig/gia/giaMinLut2.c
@@ -0,0 +1,1372 @@
+/**CFile****************************************************************
+
+ FileName [giaMinLut.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Collapsing AIG.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaMinLut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+#include "giaAig.h"
+#include "base/main/mainInt.h"
+#include "opt/sfm/sfm.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define TREE_MAX_VARS 16
+
+typedef struct Tree_Sto_t_ Tree_Sto_t;
+struct Tree_Sto_t_
+{
+ int nIns;
+ int nOuts;
+ int pTried[TREE_MAX_VARS];
+ int pPerm[TREE_MAX_VARS];
+ int pIPerm[TREE_MAX_VARS];
+ int nNodes[TREE_MAX_VARS];
+ Vec_Int_t vCofs[TREE_MAX_VARS];
+ word * pMem;
+};
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Tree_Sto_t * Gia_ManTreeDup( Tree_Sto_t * p )
+{
+ Tree_Sto_t * pSto = ABC_CALLOC( Tree_Sto_t, 1 );
+ int i, k, Obj;
+ *pSto = *p;
+ pSto->pMem = Abc_TtDup( pSto->pMem, p->nOuts*Abc_TtWordNum(p->nIns), 0 );
+ memset( pSto->vCofs, 0, sizeof(Vec_Int_t)*TREE_MAX_VARS );
+ for ( i = 0; i < TREE_MAX_VARS; i++ )
+ Vec_IntForEachEntry( p->vCofs+i, Obj, k )
+ Vec_IntPush( pSto->vCofs+i, Obj );
+ return pSto;
+}
+void Gia_ManTreeFree( Tree_Sto_t * p )
+{
+ int i;
+ for ( i = 0; i < TREE_MAX_VARS; i++ )
+ ABC_FREE( p->vCofs[i].pArray );
+ ABC_FREE( p->pMem );
+ ABC_FREE( p );
+}
+int Gia_ManTreeCountNodes( Tree_Sto_t * p )
+{
+ int i, nNodes = 0;
+ for ( i = 0; i < TREE_MAX_VARS; i++ )
+ nNodes += p->nNodes[i];
+ return nNodes;
+}
+void Gia_ManTreePrint( Tree_Sto_t * p )
+{
+ int i;
+ printf( "Tree with %d nodes:\n", Gia_ManTreeCountNodes(p) );
+ for ( i = p->nIns-1; i >= 0; i-- )
+ printf( "Level %2d Var %2d : %s Nodes = %3d Cofs = %3d\n",
+ i, p->pIPerm[i], p->pTried[i]?"*":" ", p->nNodes[i], Vec_IntSize(p->vCofs+i) );
+// for ( i = p->nIns-1; i >= 0; i-- )
+// printf( "Var %2d Level %2d\n", i, p->pPerm[i] );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManFindOrAddNode( Tree_Sto_t * pSto, int iVar, int Truth, word * pCof )
+{
+ int k, Obj;
+ if ( iVar > 5 )
+ {
+ int nWords = Abc_TtWordNum(iVar);
+ Vec_IntForEachEntry( pSto->vCofs+iVar, Obj, k )
+ if ( Abc_TtEqual( pSto->pMem + Obj, pCof, nWords ) )
+ return 1;
+ Vec_IntPush( pSto->vCofs+iVar, pCof - pSto->pMem );
+ }
+ else
+ {
+ Vec_IntForEachEntry( pSto->vCofs+iVar, Obj, k )
+ if ( Obj == Truth )
+ return 1;
+ Vec_IntPush( pSto->vCofs+iVar, Truth );
+ }
+ return 0;
+}
+int Gia_ManProcessLevel( Tree_Sto_t * pSto, int iVar )
+{
+ int k, Obj, nNodes = 0;
+ //Vec_IntPrint( pSto->vCofs+iVar );
+ Vec_IntClear( pSto->vCofs+iVar );
+ if ( iVar > 5 )
+ {
+ int nWords = Abc_TtWordNum(iVar);
+ Vec_IntForEachEntry( pSto->vCofs+iVar+1, Obj, k )
+ {
+ word * pCof0 = pSto->pMem + Obj;
+ word * pCof1 = pCof0 + nWords;
+ Gia_ManFindOrAddNode( pSto, iVar, -1, pCof0 );
+ if ( Abc_TtEqual( pCof0, pCof1, nWords ) )
+ continue;
+ Gia_ManFindOrAddNode( pSto, iVar, -1, pCof1 );
+ nNodes++;
+ }
+ }
+ else
+ {
+ Vec_IntForEachEntry( pSto->vCofs+iVar+1, Obj, k )
+ {
+ unsigned Cof0 = iVar < 5 ? Abc_Tt5Cofactor0( Obj, iVar ) : (unsigned) pSto->pMem[Obj];
+ unsigned Cof1 = iVar < 5 ? Abc_Tt5Cofactor1( Obj, iVar ) : (unsigned)(pSto->pMem[Obj] >> 32);
+ Gia_ManFindOrAddNode( pSto, iVar, Cof0, NULL );
+ if ( Cof0 == Cof1 )
+ continue;
+ Gia_ManFindOrAddNode( pSto, iVar, Cof1, NULL );
+ nNodes++;
+ }
+ }
+ //printf( "Level %2d : Nodes = %3d Cofs = %3d\n", iVar, nNodes, Vec_IntSize(pSto->vCofs+iVar) );
+ //Vec_IntPrint( pSto->vCofs+iVar );
+ //printf( "\n" );
+ return nNodes;
+}
+Tree_Sto_t * Gia_ManContructTree( word * pTruths, int nIns, int nOuts, int nWords )
+{
+ Tree_Sto_t * pSto = ABC_CALLOC( Tree_Sto_t, 1 ); int i;
+ assert( Abc_TtWordNum(nIns) == nWords );
+ assert( nIns+1 <= TREE_MAX_VARS );
+ pSto->pMem = Abc_TtDup(pTruths, nOuts*nWords, 0);
+ pSto->nIns = nIns;
+ pSto->nOuts = nOuts;
+ for ( i = 0; i < nIns; i++ )
+ pSto->pPerm[i] = pSto->pIPerm[i] = i;
+ for ( i = 0; i < nOuts; i++ )
+ Gia_ManFindOrAddNode( pSto, nIns, (unsigned)pSto->pMem[i], pSto->pMem + i*nWords );
+ for ( i = nIns-1; i >= 0; i-- )
+ pSto->nNodes[i] = Gia_ManProcessLevel( pSto, i );
+ return pSto;
+}
+void Gia_ManContructTreeTest( word * pTruths, int nIns, int nOuts, int nWords )
+{
+ Tree_Sto_t * pSto = Gia_ManContructTree( pTruths, nIns, nOuts, nWords );
+ printf( "Total nodes = %d.\n", Gia_ManTreeCountNodes(pSto) );
+ Gia_ManTreeFree( pSto );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManSwapTree( Tree_Sto_t * pSto, int i )
+{
+ int nNodes = pSto->nNodes[i+1] + pSto->nNodes[i];
+ int v, o, nWords = Abc_TtWordNum(pSto->nIns);
+ //printf( "Swapping %2d and %2d ", i, i+1 );
+ assert( i >= 0 && i < pSto->nIns-1 );
+ for ( o = 0; o < pSto->nOuts; o++ )
+ Abc_TtSwapAdjacent( pSto->pMem + o*nWords, nWords, i );
+ for ( v = 5; v > i+1; v-- )
+ pSto->nNodes[v] = Gia_ManProcessLevel( pSto, v );
+ pSto->nNodes[i+1] = Gia_ManProcessLevel( pSto, i+1 );
+ pSto->nNodes[i] = Gia_ManProcessLevel( pSto, i );
+ ABC_SWAP( int, pSto->pTried[i], pSto->pTried[i+1] );
+ ABC_SWAP( int, pSto->pIPerm[i], pSto->pIPerm[i+1] );
+ pSto->pPerm[pSto->pIPerm[i+1]] = i+1;
+ pSto->pPerm[pSto->pIPerm[i]] = i;
+ return pSto->nNodes[i+1] + pSto->nNodes[i] - nNodes;
+}
+int Gia_ManFindBestPosition( word * pTruths, int nIns, int nOuts, int nWords, word * pStore, int fMoveMore, int * pnNodesMin, int fVerbose )
+{
+ Tree_Sto_t * pSto = Gia_ManContructTree( pTruths, nIns, nOuts, nWords );
+ //int v, vBest = nIns-1, nNodesCur = Gia_ManTreeCountNodes(pSto), nNodesMin = nNodesCur;
+ int v, vBest = -1, nNodesCur = Gia_ManTreeCountNodes(pSto), nNodesMin = ABC_INFINITY;
+ if ( fVerbose )
+ Gia_ManTreePrint( pSto );
+ Abc_TtCopy( pStore+(nIns-1)*nOuts*nWords, pSto->pMem, nOuts*nWords, 0 );
+ for ( v = nIns-2; v >= 0; v-- )
+ {
+ nNodesCur += Gia_ManSwapTree( pSto, v );
+ if ( fMoveMore ? nNodesMin >= nNodesCur : nNodesMin > nNodesCur )
+ {
+ nNodesMin = nNodesCur;
+ vBest = v;
+ }
+ if ( fVerbose )
+ printf( "Level %2d -> %2d : Nodes = %4d. ", v+1, v, nNodesCur );
+ Abc_TtCopy( pStore+v*nOuts*nWords, pSto->pMem, nOuts*nWords, 0 );
+ if ( fVerbose )
+ Gia_ManContructTreeTest( pSto->pMem, nIns, nOuts, nWords );
+ }
+ assert( vBest != nIns-1 );
+ Gia_ManTreeFree( pSto );
+ if ( fVerbose )
+ printf( "Best level = %d. Best nodes = %d.\n", vBest, nNodesMin );
+ if ( pnNodesMin )
+ *pnNodesMin = nNodesMin;
+ return vBest;
+}
+void Gia_ManPermStats( int nIns, int * pIPerm, int * pTried )
+{
+ int v;
+ for ( v = nIns-1; v >= 0; v-- )
+ printf( "Level = %2d : Var = %2d Tried = %2d\n", v, pIPerm[v], pTried[v] );
+ printf( "\n" );
+}
+int Gia_ManPermuteTreeOne( word * pTruths, int nIns, int nOuts, int nWords, int fRandom, int * pIPermOut, int fVeryVerbose, int fVerbose )
+{
+ extern void Gia_ManDumpMuxes( Tree_Sto_t * p, char * pFileName, int * pIPerm );
+ word * pStore = ABC_ALLOC( word, nIns*nOuts*nWords );
+ int pTried[TREE_MAX_VARS] = {0};
+ int pIPerm[TREE_MAX_VARS] = {0};
+ int v, r, Pos, nNodesPrev = -1, nNodesMin = 0, nNoChange = 0;
+ int nNodesBeg, nNodesEnd;
+ Tree_Sto_t * pSto;
+ for ( v = 0; v < nIns; v++ )
+ pIPerm[v] = v;
+ pSto = Gia_ManContructTree( pTruths, nIns, nOuts, nWords );
+ nNodesBeg = Gia_ManTreeCountNodes(pSto);
+ //Gia_ManDumpMuxes( pSto, "from_tt1.aig", pIPerm );
+ Gia_ManTreeFree( pSto );
+ if ( fRandom )
+ for ( v = 0; v < nIns; v++ )
+ {
+ //int o, vRand = rand() % nIns;
+ int o, vRand = Gia_ManRandom(0) % nIns;
+ for ( o = 0; o < nOuts; o++ )
+ Abc_TtSwapVars( pTruths + o*nWords, nIns, v, vRand );
+ ABC_SWAP( int, pIPerm[vRand], pIPerm[v] );
+ }
+ for ( r = 0; r < 10*nIns; r++ )
+ {
+ nNodesPrev = nNodesMin;
+ if ( fVeryVerbose )
+ printf( "\nRound %d:\n", r );
+ Pos = Gia_ManFindBestPosition( pTruths, nIns, nOuts, nWords, pStore, r&1, &nNodesMin, fVeryVerbose );
+ Abc_TtCopy( pTruths, pStore+Pos*nOuts*nWords, nOuts*nWords, 0 );
+ pTried[nIns-1]++;
+ for ( v = nIns-2; v >= Pos; v-- )
+ {
+ ABC_SWAP( int, pTried[v+1], pTried[v] );
+ ABC_SWAP( int, pIPerm[v+1], pIPerm[v] );
+ }
+ if ( fVeryVerbose )
+ Gia_ManPermStats( nIns, pIPerm, pTried );
+ nNoChange = nNodesPrev == nNodesMin ? nNoChange + 1 : 0;
+ if ( nNoChange == 4 )
+ break;
+ }
+ pSto = Gia_ManContructTree( pTruths, nIns, nOuts, nWords );
+ nNodesEnd = Gia_ManTreeCountNodes(pSto);
+ //Gia_ManDumpMuxes( pSto, "from_tt2.aig", pIPerm );
+ if ( fVerbose )
+ printf( "Nodes %5d -> %5d. ", nNodesBeg, nNodesEnd );
+ Gia_ManTreeFree( pSto );
+ ABC_FREE( pStore );
+ if ( pIPermOut )
+ memcpy( pIPermOut, pIPerm, sizeof(int)*nIns );
+ return nNodesEnd;
+}
+void Gia_ManPermuteTree( word * pTruths, int nIns, int nOuts, int nWords, int fRandom, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ word * pTruthDup = Abc_TtDup( pTruths, nOuts*nWords, 0 );
+ int r;
+ //srand( time(NULL) );
+ Gia_ManRandom(1);
+ for ( r = 0; r < 100; r++ )
+ {
+ Gia_ManPermuteTreeOne( pTruthDup, nIns, nOuts, nWords, fRandom, NULL, 0, fVerbose );
+ Abc_TtCopy( pTruthDup, pTruths, nOuts*nWords, 0 );
+ }
+ ABC_FREE( pTruthDup );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+#define TT_UNDEF ABC_CONST(0x1234567887654321)
+
+static inline word Abc_Tt6Min_rec( word uF, word uR, int nVars, Vec_Wrd_t * vNodes )
+{
+ word uF0, uF1, uR0, uR1, uRes0, uRes1, uRes2; int i, Var;
+ assert( nVars <= 6 );
+ assert( (uF & uR) == 0 );
+ if ( !uF && !uR )
+ return TT_UNDEF;
+ if ( !uF && !~uR )
+ return 0;
+ if ( !~uF && !uR )
+ return ~(word)0;
+ assert( nVars > 0 );
+ for ( Var = nVars-1; Var >= 0; Var-- )
+ if ( Abc_Tt6HasVar( uF, Var ) || Abc_Tt6HasVar( uR, Var ) )
+ break;
+ assert( Var >= 0 );
+ if ( 1 && vNodes )
+ Vec_WrdForEachEntry( vNodes, uRes2, i )
+ if ( !(uF & ~uRes2) && !(uRes2 & uR) )
+ return uRes2;
+// else if ( !(uF & uRes2) && !(~uRes2 & uR) )
+// return ~uRes2;
+ uF0 = Abc_Tt6Cofactor0( uF, Var );
+ uF1 = Abc_Tt6Cofactor1( uF, Var );
+ uR0 = Abc_Tt6Cofactor0( uR, Var );
+ uR1 = Abc_Tt6Cofactor1( uR, Var );
+ uRes0 = Abc_Tt6Min_rec( uF0, uR0, Var, vNodes );
+ uRes1 = Abc_Tt6Min_rec( uF1, uR1, Var, vNodes );
+ if ( uRes0 == TT_UNDEF && uRes1 == TT_UNDEF )
+ return TT_UNDEF;
+ if ( uRes0 == TT_UNDEF )
+ return uRes1;
+ if ( uRes1 == TT_UNDEF )
+ return uRes0;
+ if ( uRes0 == uRes1 )
+ return uRes0;
+// if ( (uRes0 & ~uRes1) == 0 )
+// printf( "0" );
+// else if ( (~uRes0 & uRes1) == 0 )
+// printf( "1" );
+// else
+// printf( "*" );
+ uRes2 = (uRes0 & s_Truths6Neg[Var]) | (uRes1 & s_Truths6[Var]);
+ assert( !(uF & ~uRes2) );
+ assert( !(uRes2 & uR) );
+ if ( vNodes )
+ Vec_WrdPush( vNodes, uRes2 );
+ return uRes2;
+}
+word * Abc_TtMin_rec( word * pF, word * pR, int nVars, Vec_Wrd_t * vMemory, Vec_Wrd_t * vNodes, Vec_Wec_t * vNodes2 )
+{
+ int i, Entry, nWords = Abc_TtWordNum(nVars);
+ word * pRes0, * pRes1, * pRes2 = Vec_WrdFetch( vMemory, nWords );
+ if ( nVars <= 6 )
+ {
+ pRes2[0] = Abc_Tt6Min_rec( pF[0], pR[0], nVars, vNodes );
+ return pRes2;
+ }
+ assert( !Abc_TtIntersect(pF, pR, nWords, 0) );
+ if ( Abc_TtIsConst0(pF, nWords) && Abc_TtIsConst0(pR, nWords) )
+ return NULL;
+ if ( Abc_TtIsConst0(pF, nWords) && Abc_TtIsConst1(pR, nWords) )
+ {
+ Abc_TtClear( pRes2, nWords );
+ return pRes2;
+ }
+ if ( Abc_TtIsConst1(pF, nWords) && Abc_TtIsConst0(pR, nWords) )
+ {
+ Abc_TtFill( pRes2, nWords );
+ return pRes2;
+ }
+ nWords >>= 1;
+ if ( !Abc_TtHasVar( pF, nVars, nVars-1 ) && !Abc_TtHasVar( pR, nVars, nVars-1 ) )
+ {
+ pRes0 = Abc_TtMin_rec( pF, pR, nVars-1, vMemory, vNodes, vNodes2 );
+ Abc_TtCopy( pRes2, pRes0, nWords, 0 );
+ Abc_TtCopy( pRes2 + nWords, pRes0, nWords, 0 );
+ return pRes2;
+ }
+ if ( 1 && vNodes2 )
+ {
+ Vec_Int_t * vLayer = Vec_WecEntry( vNodes2, nVars );
+ Vec_IntForEachEntry( vLayer, Entry, i )
+ {
+ word * pTemp = Vec_WrdEntryP( vMemory, Entry );
+ if ( !Abc_TtIntersect(pTemp, pF, 2*nWords, 1) && !Abc_TtIntersect(pTemp, pR, 2*nWords, 0) )
+ return pTemp;
+/*
+ if ( !Abc_TtIntersect(pTemp, pF, 2*nWords, 0) && !Abc_TtIntersect(pTemp, pR, 2*nWords, 1) )
+ {
+ Abc_TtCopy( pRes2, pTemp, 2*nWords, 1 );
+ return pRes2;
+ }
+*/
+ }
+ }
+ assert( nVars > 6 );
+ pRes0 = Abc_TtMin_rec( pF, pR, nVars-1, vMemory, vNodes, vNodes2 );
+ pRes1 = Abc_TtMin_rec( pF + nWords, pR + nWords, nVars-1, vMemory, vNodes, vNodes2 );
+ if ( pRes0 == NULL && pRes1 == NULL )
+ return NULL;
+ if ( pRes0 == NULL || pRes1 == NULL || Abc_TtEqual(pRes0, pRes1, nWords) )
+ {
+ Abc_TtCopy( pRes2, pRes0 ? pRes0 : pRes1, nWords, 0 );
+ Abc_TtCopy( pRes2 + nWords, pRes0 ? pRes0 : pRes1, nWords, 0 );
+ return pRes2;
+ }
+ Abc_TtCopy( pRes2, pRes0, nWords, 0 );
+ Abc_TtCopy( pRes2 + nWords, pRes1, nWords, 0 );
+ assert( !Abc_TtIntersect(pRes2, pF, 2*nWords, 1) ); // assert( !(uF & ~uRes2) );
+ assert( !Abc_TtIntersect(pRes2, pR, 2*nWords, 0) ); // assert( !(uRes2 & uR) );
+ if ( vNodes2 )
+ Vec_WecPush( vNodes2, nVars, pRes2 - Vec_WrdArray(vMemory) );
+ return pRes2;
+}
+word * Abc_TtMin( word * pF, word * pR, int nVars, Vec_Wrd_t * vMemory, Vec_Wrd_t * vNodes, Vec_Wec_t * vNodes2 )
+{
+ word * pResult;
+ int i, nWords = Abc_TtWordNum(nVars);
+ assert( nVars >= 0 && nVars <= 16 );
+ for ( i = nVars; i < 6; i++ )
+ assert( !Abc_Tt6HasVar(pF[0], i) && !Abc_Tt6HasVar(pR[0], i) );
+ Vec_WrdClear( vMemory );
+ Vec_WrdGrow( vMemory, 1 << 20 );
+ pResult = Abc_TtMin_rec( pF, pR, nVars, vMemory, vNodes, vNodes2 );
+ if ( pResult == NULL )
+ {
+ Vec_WrdFill( vMemory, nWords, 0 );
+ return Vec_WrdArray( vMemory );
+ }
+ //printf( "Memory %d (Truth table %d)\n", Vec_WrdSize(vMemory), nWords );
+ Abc_TtCopy( Vec_WrdArray(vMemory), pResult, nWords, 0 );
+ Vec_WrdShrink( vMemory, nWords );
+ return Vec_WrdArray(vMemory);
+}
+word * Abc_TtMinArray( word * p, int nOuts, int nVars, int * pnNodes, int fVerbose )
+{
+ int o, i, nWords = Abc_TtWordNum(nVars);
+ word * pRes, * pResult = ABC_ALLOC( word, nOuts*nWords/2 );
+ Vec_Wrd_t * vMemory = Vec_WrdAlloc( 100 );
+ Vec_Wrd_t * vNodes = Vec_WrdAlloc( 100 );
+ Vec_Wec_t * vNodes2 = Vec_WecStart( nVars+1 );
+ Vec_WrdGrow( vMemory, 1 << 20 );
+ for ( o = 0; o < nOuts/2; o++ )
+ {
+ word * pF = p + (2*o+0)*nWords;
+ word * pR = p + (2*o+1)*nWords;
+ for ( i = nVars; i < 6; i++ )
+ assert( !Abc_Tt6HasVar(pF[0], i) && !Abc_Tt6HasVar(pR[0], i) );
+ pRes = Abc_TtMin_rec( pF, pR, nVars, vMemory, vNodes, vNodes2 );
+ if ( pResult == NULL )
+ Abc_TtClear( pResult + o*nWords, nWords );
+ else
+ Abc_TtCopy( pResult + o*nWords, pRes, nWords, 0 );
+ }
+ if ( fVerbose )
+ printf( "Nodes = %5d. Nodes2 = %5d. Total = %5d. ",
+ Vec_WrdSize(vNodes), Vec_WecSizeSize(vNodes2), Vec_WrdSize(vNodes) + Vec_WecSizeSize(vNodes2) );
+ //printf( "Memory %d (Truth table %d)\n", Vec_WrdSize(vMemory), nWords );
+ if ( pnNodes )
+ *pnNodes = Vec_WrdSize(vNodes) + Vec_WecSizeSize(vNodes2);
+ Vec_WrdFree( vMemory );
+ Vec_WrdFree( vNodes );
+ Vec_WecFree( vNodes2 );
+ return pResult;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline word Abc_TtSimple6Min_rec( Gia_Man_t * p, word uF, word uC, int nVars, Vec_Wrd_t * vNodes, int * piLit, int * pPerm )
+{
+ word uF0, uF1, uC0, uC1, uRes0, uRes1, uRes2; int i, Var, iLit0, iLit1;
+ word uFC = uF & uC;
+ word uRC = ~uF & uC;
+ assert( nVars <= 6 );
+ *piLit = 0;
+ if ( !uFC )
+ {
+ *piLit = 0;
+ return 0;
+ }
+ if ( !uRC )
+ {
+ *piLit = 1;
+ return ~(word)0;
+ }
+ assert( nVars > 0 );
+ if ( 1 && vNodes )
+ {
+ int iLit;
+ Vec_WrdForEachEntryDouble( vNodes, uRes2, iLit, i )
+ if ( !((uF ^ uRes2) & uC) )
+ {
+ *piLit = (unsigned)iLit;
+ return uRes2;
+ }
+ else if ( !((uF ^ ~uRes2) & uC) )
+ {
+ *piLit = Abc_LitNot( (unsigned)iLit );
+ return ~uRes2;
+ }
+ }
+ for ( Var = nVars-1; Var >= 0; Var-- )
+ if ( Abc_Tt6HasVar( uF, Var ) )
+ break;
+ else
+ uC = Abc_Tt6Cofactor0(uC, Var) | Abc_Tt6Cofactor1(uC, Var);
+ assert( Var >= 0 );
+ uF0 = Abc_Tt6Cofactor0( uF, Var );
+ uF1 = Abc_Tt6Cofactor1( uF, Var );
+ uC0 = Abc_Tt6Cofactor0( uC, Var );
+ uC1 = Abc_Tt6Cofactor1( uC, Var );
+ uRes0 = Abc_TtSimple6Min_rec( p, uF0, uC0, Var, vNodes, &iLit0, pPerm );
+ uRes1 = Abc_TtSimple6Min_rec( p, uF1, uC1, Var, vNodes, &iLit1, pPerm );
+ if ( uRes0 == uRes1 )
+ {
+ *piLit = iLit0;
+ return uRes0;
+ }
+ uRes2 = (uRes0 & s_Truths6Neg[Var]) | (uRes1 & s_Truths6[Var]);
+ Var = pPerm ? pPerm[Var] : Var;
+ //if ( !(uRes0 & ~uRes1 & uC1) )
+ if ( !(uRes0 & ~uRes1) )
+ *piLit = Gia_ManHashOr( p, Gia_ManHashAnd(p, Abc_Var2Lit(1+Var, 0), iLit1), iLit0 );
+ //else if ( !(uRes1 & ~uRes0 & uC0) )
+ else if ( !(uRes1 & ~uRes0) )
+ *piLit = Gia_ManHashOr( p, Gia_ManHashAnd(p, Abc_Var2Lit(1+Var, 1), iLit0), iLit1 );
+ else
+ *piLit = Gia_ManHashMux( p, Abc_Var2Lit(1+Var, 0), iLit1, iLit0 );
+ assert( !(uFC & ~uRes2) );
+ assert( !(uRes2 & uRC) );
+ if ( vNodes )
+ Vec_WrdPushTwo( vNodes, uRes2, (word)*piLit );
+ return uRes2;
+}
+word * Abc_TtSimpleMin_rec( Gia_Man_t * p, word * pF, word * pC, int nVars, Vec_Wrd_t * vMemory, Vec_Wrd_t * vNodes, Vec_Wec_t * vNodes2, int * piLit, int * pPerm )
+{
+ int i, Entry, Var, iLit0, iLit1, nWords = Abc_TtWordNum(nVars);
+ word * pRes0, * pRes1, * pRes2 = Vec_WrdFetch( vMemory, nWords );
+ *piLit = 0;
+ if ( nVars <= 6 )
+ {
+ pRes2[0] = Abc_TtSimple6Min_rec( p, pF[0], pC[0], nVars, vNodes, piLit, pPerm );
+ return pRes2;
+ }
+ if ( !Abc_TtIntersect(pF, pC, nWords, 0) )
+ {
+ *piLit = 0;
+ Abc_TtClear( pRes2, nWords );
+ return pRes2;
+ }
+ if ( !Abc_TtIntersect(pF, pC, nWords, 1) )
+ {
+ *piLit = 1;
+ Abc_TtFill( pRes2, nWords );
+ return pRes2;
+ }
+ nWords >>= 1;
+ if ( !Abc_TtHasVar( pF, nVars, nVars-1 ) )
+ {
+ word * pCn = Vec_WrdFetch( vMemory, nWords );
+ Abc_TtOr( pCn, pC, pC + nWords, nWords );
+ pRes0 = Abc_TtSimpleMin_rec( p, pF, pCn, nVars-1, vMemory, vNodes, vNodes2, piLit, pPerm );
+ Abc_TtCopy( pRes2, pRes0, nWords, 0 );
+ Abc_TtCopy( pRes2 + nWords, pRes0, nWords, 0 );
+ return pRes2;
+ }
+ if ( 1 && vNodes2 )
+ {
+ Vec_Int_t * vLayer = Vec_WecEntry( vNodes2, nVars ); int iLit;
+ Vec_IntForEachEntryDouble( vLayer, Entry, iLit, i )
+ {
+ word * pTemp = Vec_WrdEntryP( vMemory, Entry );
+ if ( Abc_TtEqualCare(pTemp, pF, pC, 0, 2*nWords) )
+ {
+ *piLit = iLit;
+ return pTemp;
+ }
+ else if ( Abc_TtEqualCare(pTemp, pF, pC, 1, 2*nWords) )
+ {
+ *piLit = Abc_LitNot(iLit);
+ Abc_TtCopy( pRes2, pTemp, 2*nWords, 1 );
+ return pRes2;
+ }
+ }
+ }
+ assert( nVars > 6 );
+ pRes0 = Abc_TtSimpleMin_rec( p, pF, pC, nVars-1, vMemory, vNodes, vNodes2, &iLit0, pPerm );
+ pRes1 = Abc_TtSimpleMin_rec( p, pF + nWords, pC + nWords, nVars-1, vMemory, vNodes, vNodes2, &iLit1, pPerm );
+ if ( Abc_TtEqual(pRes0, pRes1, nWords) )
+ {
+ *piLit = iLit0;
+ Abc_TtCopy( pRes2, pRes0, nWords, 0 );
+ Abc_TtCopy( pRes2 + nWords, pRes0, nWords, 0 );
+ return pRes2;
+ }
+ Abc_TtCopy( pRes2, pRes0, nWords, 0 );
+ Abc_TtCopy( pRes2 + nWords, pRes1, nWords, 0 );
+ Var = pPerm ? pPerm[nVars-1] : nVars-1;
+ //if ( !Abc_TtIntersectCare(pRes1, pRes0, pC + nWords, nWords, 1) )
+ if ( !Abc_TtIntersect(pRes1, pRes0, nWords, 1) )
+ *piLit = Gia_ManHashOr( p, Gia_ManHashAnd(p, Abc_Var2Lit(1+Var, 0), iLit1), iLit0 );
+ //else if ( !Abc_TtIntersectCare(pRes0, pRes1, pC, nWords, 1) )
+ else if ( !Abc_TtIntersect(pRes0, pRes1, nWords, 1) )
+ *piLit = Gia_ManHashOr( p, Gia_ManHashAnd(p, Abc_Var2Lit(1+Var, 1), iLit0), iLit1 );
+ else
+ *piLit = Gia_ManHashMux( p, Abc_Var2Lit(1+Var, 0), iLit1, iLit0 );
+ assert( Abc_TtEqualCare(pRes2, pF, pC, 0, 2*nWords) );
+ if ( vNodes2 )
+ {
+ Vec_Int_t * vLayer = Vec_WecEntry( vNodes2, nVars );
+ Vec_IntPushTwo( vLayer, pRes2 - Vec_WrdArray(vMemory), *piLit );
+ }
+ return pRes2;
+}
+Gia_Man_t * Abc_TtSimpleMinArrayNew( word * p, int nVars, int nOuts, int * pnNodes, int fVerbose, int * pIPerm )
+{
+ Gia_Man_t * pNew, * pTemp;
+ int o, i, iLit, nWords = Abc_TtWordNum(nVars);
+ word * pF = ABC_ALLOC( word, nWords );
+ word * pR = ABC_ALLOC( word, nWords );
+ Vec_Wrd_t * vMemory = Vec_WrdAlloc( 100 );
+ Vec_Wrd_t * vNodes = Vec_WrdAlloc( 100 );
+ Vec_Wec_t * vNodes2 = Vec_WecStart( nVars+1 );
+ Vec_WrdGrow( vMemory, 1 << 20 );
+ pNew = Gia_ManStart( 1000 );
+ pNew->pName = Abc_UtilStrsav( "muxes" );
+ for ( i = 0; i < nVars; i++ )
+ Gia_ManAppendCi(pNew);
+ Gia_ManHashAlloc( pNew );
+
+ for ( o = 0; o < nOuts; o++ )
+ {
+ word * pCare = p + nOuts*nWords;
+ word * pTruth = p + o*nWords;
+ for ( i = nVars; i < 6; i++ )
+ assert( !Abc_Tt6HasVar(pTruth[0], i) && !Abc_Tt6HasVar(pCare[0], i) );
+ Abc_TtSimpleMin_rec( pNew, pTruth, pCare, nVars, vMemory, vNodes, vNodes2, &iLit, pIPerm );
+ Gia_ManAppendCo( pNew, iLit );
+ }
+ if ( fVerbose )
+ printf( "Nodes = %5d. Nodes2 = %5d. Total = %5d. ",
+ Vec_WrdSize(vNodes), Vec_WecSizeSize(vNodes2), Vec_WrdSize(vNodes) + Vec_WecSizeSize(vNodes2) );
+ //printf( "Memory %d (Truth table %d)\n", Vec_WrdSize(vMemory), nWords );
+ if ( pnNodes )
+ *pnNodes = Vec_WrdSize(vNodes) + Vec_WecSizeSize(vNodes2);
+ Vec_WrdFree( vMemory );
+ Vec_WrdFree( vNodes );
+ Vec_WecFree( vNodes2 );
+ ABC_FREE( pF );
+ ABC_FREE( pR );
+
+ Gia_ManHashStop( pNew );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline word Abc_TtGia6Min_rec( Gia_Man_t * p, word uF, word uR, int nVars, Vec_Wrd_t * vNodes, int * piLit, int * pPerm )
+{
+ word uF0, uF1, uR0, uR1, uRes0, uRes1, uRes2; int i, Var, iLit0, iLit1;
+ assert( nVars <= 6 );
+ assert( (uF & uR) == 0 );
+ *piLit = 0;
+ if ( !uF && !uR )
+ return TT_UNDEF;
+ if ( !uF && !~uR )
+ {
+ *piLit = 0;
+ return 0;
+ }
+ if ( !~uF && !uR )
+ {
+ *piLit = 1;
+ return ~(word)0;
+ }
+ assert( nVars > 0 );
+ for ( Var = nVars-1; Var >= 0; Var-- )
+ if ( Abc_Tt6HasVar( uF, Var ) || Abc_Tt6HasVar( uR, Var ) )
+ break;
+ assert( Var >= 0 );
+ if ( 1 && vNodes )
+ {
+ int iLit;
+ Vec_WrdForEachEntryDouble( vNodes, uRes2, iLit, i )
+ if ( !(uF & ~uRes2) && !(uRes2 & uR) )
+ {
+ *piLit = (unsigned)iLit;
+ return uRes2;
+ }
+ else if ( !(uF & uRes2) && !(~uRes2 & uR) )
+ {
+ *piLit = Abc_LitNot( (unsigned)iLit );
+ return ~uRes2;
+ }
+ }
+ uF0 = Abc_Tt6Cofactor0( uF, Var );
+ uF1 = Abc_Tt6Cofactor1( uF, Var );
+ uR0 = Abc_Tt6Cofactor0( uR, Var );
+ uR1 = Abc_Tt6Cofactor1( uR, Var );
+ uRes0 = Abc_TtGia6Min_rec( p, uF0, uR0, Var, vNodes, &iLit0, pPerm );
+ uRes1 = Abc_TtGia6Min_rec( p, uF1, uR1, Var, vNodes, &iLit1, pPerm );
+ if ( uRes0 == TT_UNDEF && uRes1 == TT_UNDEF )
+ return TT_UNDEF;
+ if ( uRes0 == TT_UNDEF )
+ {
+ *piLit = iLit1;
+ return uRes1;
+ }
+ if ( uRes1 == TT_UNDEF || uRes0 == uRes1 )
+ {
+ *piLit = iLit0;
+ return uRes0;
+ }
+// if ( (uRes0 & ~uRes1) == 0 )
+// printf( "0" );
+// else if ( (~uRes0 & uRes1) == 0 )
+// printf( "1" );
+// else
+// printf( "*" );
+ uRes2 = (uRes0 & s_Truths6Neg[Var]) | (uRes1 & s_Truths6[Var]);
+ Var = pPerm ? pPerm[Var] : Var;
+ if ( !(uRes0 & ~uRes1) )
+ *piLit = Gia_ManHashOr( p, Gia_ManHashAnd(p, Abc_Var2Lit(1+Var, 0), iLit1), iLit0 );
+ else if ( !(uRes1 & ~uRes0) )
+ *piLit = Gia_ManHashOr( p, Gia_ManHashAnd(p, Abc_Var2Lit(1+Var, 1), iLit0), iLit1 );
+ else
+ *piLit = Gia_ManHashMux( p, Abc_Var2Lit(1+Var, 0), iLit1, iLit0 );
+ assert( !(uF & ~uRes2) );
+ assert( !(uRes2 & uR) );
+ if ( vNodes )
+ Vec_WrdPushTwo( vNodes, uRes2, (word)*piLit );
+ return uRes2;
+}
+word * Abc_TtGiaMin_rec( Gia_Man_t * p, word * pF, word * pR, int nVars, Vec_Wrd_t * vMemory, Vec_Wrd_t * vNodes, Vec_Wec_t * vNodes2, int * piLit, int * pPerm )
+{
+ int i, Entry, Var, iLit0, iLit1, nWords = Abc_TtWordNum(nVars);
+ word * pRes0, * pRes1, * pRes2 = Vec_WrdFetch( vMemory, nWords );
+ *piLit = 0;
+ if ( nVars <= 6 )
+ {
+ pRes2[0] = Abc_TtGia6Min_rec( p, pF[0], pR[0], nVars, vNodes, piLit, pPerm );
+ return pRes2;
+ }
+ assert( !Abc_TtIntersect(pF, pR, nWords, 0) );
+ if ( Abc_TtIsConst0(pF, nWords) && Abc_TtIsConst0(pR, nWords) )
+ return NULL;
+ if ( Abc_TtIsConst0(pF, nWords) && Abc_TtIsConst1(pR, nWords) )
+ {
+ *piLit = 0;
+ Abc_TtClear( pRes2, nWords );
+ return pRes2;
+ }
+ if ( Abc_TtIsConst1(pF, nWords) && Abc_TtIsConst0(pR, nWords) )
+ {
+ *piLit = 1;
+ Abc_TtFill( pRes2, nWords );
+ return pRes2;
+ }
+ nWords >>= 1;
+ if ( !Abc_TtHasVar( pF, nVars, nVars-1 ) && !Abc_TtHasVar( pR, nVars, nVars-1 ) )
+ {
+ pRes0 = Abc_TtGiaMin_rec( p, pF, pR, nVars-1, vMemory, vNodes, vNodes2, piLit, pPerm );
+ Abc_TtCopy( pRes2, pRes0, nWords, 0 );
+ Abc_TtCopy( pRes2 + nWords, pRes0, nWords, 0 );
+ return pRes2;
+ }
+ if ( 1 && vNodes2 )
+ {
+ Vec_Int_t * vLayer = Vec_WecEntry( vNodes2, nVars ); int iLit;
+ Vec_IntForEachEntryDouble( vLayer, Entry, iLit, i )
+ {
+ word * pTemp = Vec_WrdEntryP( vMemory, Entry );
+ if ( !Abc_TtIntersect(pTemp, pF, 2*nWords, 1) && !Abc_TtIntersect(pTemp, pR, 2*nWords, 0) )
+ {
+ *piLit = iLit;
+ return pTemp;
+ }
+ else if ( !Abc_TtIntersect(pTemp, pF, 2*nWords, 0) && !Abc_TtIntersect(pTemp, pR, 2*nWords, 1) )
+ {
+ *piLit = Abc_LitNot(iLit);
+ Abc_TtCopy( pRes2, pTemp, 2*nWords, 1 );
+ return pRes2;
+ }
+ }
+/*
+ if ( nVars > 7 )
+ {
+ vLayer = Vec_WecEntry( vNodes2, nVars-1 );
+ Vec_IntForEachEntryDouble( vLayer, Entry, iLit, i )
+ {
+ word * pTemp = Vec_WrdEntryP( vMemory, Entry );
+ if ( !Abc_TtIntersect(pTemp, pF, 2*nWords, 1) && !Abc_TtIntersect(pTemp, pR, 2*nWords, 0) )
+ {
+ *piLit = iLit;
+ return pTemp;
+ }
+ else if ( !Abc_TtIntersect(pTemp, pF, 2*nWords, 0) && !Abc_TtIntersect(pTemp, pR, 2*nWords, 1) )
+ {
+ *piLit = Abc_LitNot(iLit);
+ Abc_TtCopy( pRes2, pTemp, 2*nWords, 1 );
+ return pRes2;
+ }
+ }
+ }
+*/
+ }
+ assert( nVars > 6 );
+ pRes0 = Abc_TtGiaMin_rec( p, pF, pR, nVars-1, vMemory, vNodes, vNodes2, &iLit0, pPerm );
+ pRes1 = Abc_TtGiaMin_rec( p, pF + nWords, pR + nWords, nVars-1, vMemory, vNodes, vNodes2, &iLit1, pPerm );
+ if ( pRes0 == NULL && pRes1 == NULL )
+ return NULL;
+ if ( pRes0 == NULL || pRes1 == NULL || Abc_TtEqual(pRes0, pRes1, nWords) )
+ {
+ *piLit = pRes0 ? iLit0 : iLit1;
+ Abc_TtCopy( pRes2, pRes0 ? pRes0 : pRes1, nWords, 0 );
+ Abc_TtCopy( pRes2 + nWords, pRes0 ? pRes0 : pRes1, nWords, 0 );
+ return pRes2;
+ }
+ Abc_TtCopy( pRes2, pRes0, nWords, 0 );
+ Abc_TtCopy( pRes2 + nWords, pRes1, nWords, 0 );
+ Var = pPerm ? pPerm[nVars-1] : nVars-1;
+ if ( !Abc_TtIntersect(pRes1, pRes0, nWords, 1) )
+ *piLit = Gia_ManHashOr( p, Gia_ManHashAnd(p, Abc_Var2Lit(1+Var, 0), iLit1), iLit0 );
+ else if ( !Abc_TtIntersect(pRes0, pRes1, nWords, 1) )
+ *piLit = Gia_ManHashOr( p, Gia_ManHashAnd(p, Abc_Var2Lit(1+Var, 1), iLit0), iLit1 );
+ else
+ *piLit = Gia_ManHashMux( p, Abc_Var2Lit(1+Var, 0), iLit1, iLit0 );
+ assert( !Abc_TtIntersect(pRes2, pF, 2*nWords, 1) ); // assert( !(uF & ~uRes2) );
+ assert( !Abc_TtIntersect(pRes2, pR, 2*nWords, 0) ); // assert( !(uRes2 & uR) );
+ if ( vNodes2 )
+ {
+ Vec_Int_t * vLayer = Vec_WecEntry( vNodes2, nVars );
+ Vec_IntPushTwo( vLayer, pRes2 - Vec_WrdArray(vMemory), *piLit );
+ }
+ return pRes2;
+}
+Gia_Man_t * Abc_TtGiaMinArray( word * p, int nVars, int nOuts, int * pnNodes, int fVerbose, int * pIPerm )
+{
+ Gia_Man_t * pNew, * pTemp;
+ int o, i, iLit, nWords = Abc_TtWordNum(nVars);
+ word * pRes, * pResult = ABC_ALLOC( word, nOuts*nWords/2 );
+ Vec_Wrd_t * vMemory = Vec_WrdAlloc( 100 );
+ Vec_Wrd_t * vNodes = Vec_WrdAlloc( 100 );
+ Vec_Wec_t * vNodes2 = Vec_WecStart( nVars+1 );
+ Vec_WrdGrow( vMemory, 1 << 20 );
+ pNew = Gia_ManStart( 1000 );
+ pNew->pName = Abc_UtilStrsav( "muxes" );
+ for ( i = 0; i < nVars; i++ )
+ Gia_ManAppendCi(pNew);
+ Gia_ManHashAlloc( pNew );
+
+ for ( o = 0; o < nOuts/2; o++ )
+ {
+ word * pF = p + (2*o+0)*nWords;
+ word * pR = p + (2*o+1)*nWords;
+ for ( i = nVars; i < 6; i++ )
+ assert( !Abc_Tt6HasVar(pF[0], i) && !Abc_Tt6HasVar(pR[0], i) );
+ pRes = Abc_TtGiaMin_rec( pNew, pF, pR, nVars, vMemory, vNodes, vNodes2, &iLit, pIPerm );
+ if ( pResult == NULL )
+ {
+ Abc_TtClear( pResult + o*nWords, nWords );
+ Gia_ManAppendCo( pNew, 0 );
+ }
+ else
+ {
+ Abc_TtCopy( pResult + o*nWords, pRes, nWords, 0 );
+ Gia_ManAppendCo( pNew, iLit );
+ }
+ }
+ if ( fVerbose )
+ printf( "Nodes = %5d. Nodes2 = %5d. Total = %5d. ",
+ Vec_WrdSize(vNodes), Vec_WecSizeSize(vNodes2), Vec_WrdSize(vNodes) + Vec_WecSizeSize(vNodes2) );
+ //printf( "Memory %d (Truth table %d)\n", Vec_WrdSize(vMemory), nWords );
+ if ( pnNodes )
+ *pnNodes = Vec_WrdSize(vNodes) + Vec_WecSizeSize(vNodes2);
+ Vec_WrdFree( vMemory );
+ Vec_WrdFree( vNodes );
+ Vec_WecFree( vNodes2 );
+ ABC_FREE( pResult );
+
+ Gia_ManHashStop( pNew );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+Gia_Man_t * Abc_TtGiaMinArrayNew( word * p, int nVars, int nOuts, int * pnNodes, int fVerbose, int * pIPerm )
+{
+ Gia_Man_t * pNew, * pTemp;
+ int o, i, iLit, nWords = Abc_TtWordNum(nVars);
+ word * pF = ABC_ALLOC( word, nWords );
+ word * pR = ABC_ALLOC( word, nWords );
+ Vec_Wrd_t * vMemory = Vec_WrdAlloc( 100 );
+ Vec_Wrd_t * vNodes = Vec_WrdAlloc( 100 );
+ Vec_Wec_t * vNodes2 = Vec_WecStart( nVars+1 );
+ Vec_WrdGrow( vMemory, 1 << 20 );
+ pNew = Gia_ManStart( 1000 );
+ pNew->pName = Abc_UtilStrsav( "muxes" );
+ for ( i = 0; i < nVars; i++ )
+ Gia_ManAppendCi(pNew);
+ Gia_ManHashAlloc( pNew );
+
+ for ( o = 0; o < nOuts; o++ )
+ {
+ word * pCare = p + nOuts*nWords;
+ word * pTruth = p + o*nWords;
+ Abc_TtAnd( pF, pCare, pTruth, nWords, 0 );
+ Abc_TtSharp( pR, pCare, pTruth, nWords );
+ for ( i = nVars; i < 6; i++ )
+ assert( !Abc_Tt6HasVar(pF[0], i) && !Abc_Tt6HasVar(pR[0], i) );
+ Abc_TtGiaMin_rec( pNew, pF, pR, nVars, vMemory, vNodes, vNodes2, &iLit, pIPerm );
+ Gia_ManAppendCo( pNew, iLit );
+ }
+ if ( fVerbose )
+ printf( "Nodes = %5d. Nodes2 = %5d. Total = %5d. ",
+ Vec_WrdSize(vNodes), Vec_WecSizeSize(vNodes2), Vec_WrdSize(vNodes) + Vec_WecSizeSize(vNodes2) );
+ //printf( "Memory %d (Truth table %d)\n", Vec_WrdSize(vMemory), nWords );
+ if ( pnNodes )
+ *pnNodes = Vec_WrdSize(vNodes) + Vec_WecSizeSize(vNodes2);
+ Vec_WrdFree( vMemory );
+ Vec_WrdFree( vNodes );
+ Vec_WecFree( vNodes2 );
+ ABC_FREE( pF );
+ ABC_FREE( pR );
+
+ Gia_ManHashStop( pNew );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManBuildMuxes6_rec( Gia_Man_t * p, word t, int nVars, int * pPerm )
+{
+ int iLit0, iLit1, Var;
+ assert( nVars <= 6 );
+ if ( t == 0 )
+ return 0;
+ if ( ~t == 0 )
+ return 1;
+ assert( nVars > 0 );
+ for ( Var = nVars-1; Var >= 0; Var-- )
+ if ( Abc_Tt6HasVar( t, Var ) )
+ break;
+ assert( Var >= 0 );
+ iLit0 = Gia_ManBuildMuxes6_rec( p, Abc_Tt6Cofactor0(t, Var), Var, pPerm );
+ iLit1 = Gia_ManBuildMuxes6_rec( p, Abc_Tt6Cofactor1(t, Var), Var, pPerm );
+ Var = pPerm ? pPerm[Var] : Var;
+ return Gia_ManAppendMux( p, Abc_Var2Lit(1+Var, 0), iLit1, iLit0 );
+}
+int Gia_ManBuildMuxes_rec( Gia_Man_t * p, word * pTruth, int nVars, int * pPerm )
+{
+ int iLit0, iLit1, Var, nWords = Abc_TtWordNum(nVars);
+ if ( nVars <= 6 )
+ return Gia_ManBuildMuxes6_rec( p, pTruth[0], nVars, pPerm );
+ if ( Abc_TtIsConst0(pTruth, nWords) )
+ return 0;
+ if ( Abc_TtIsConst1(pTruth, nWords) )
+ return 1;
+/*
+ assert( nVars > 0 );
+ if ( !Abc_TtHasVar( pTruth, nVars, nVars-1 ) )
+ return Gia_ManBuildMuxes_rec( p, pTruth, nVars-1 );
+ assert( nVars > 6 );
+ iLit0 = Gia_ManBuildMuxes_rec( p, pTruth, nVars-1 );
+ iLit1 = Gia_ManBuildMuxes_rec( p, pTruth+nWords/2, nVars-1 );
+*/
+ assert( nVars > 0 );
+ for ( Var = nVars-1; Var >= 0; Var-- )
+ if ( Abc_TtHasVar( pTruth, nVars, Var ) )
+ break;
+ assert( Var >= 0 );
+ if ( Var < 6 )
+ return Gia_ManBuildMuxes6_rec( p, pTruth[0], Var+1, pPerm );
+ iLit0 = Gia_ManBuildMuxes_rec( p, pTruth, Var, pPerm );
+ iLit1 = Gia_ManBuildMuxes_rec( p, pTruth+Abc_TtWordNum(Var), Var, pPerm );
+ Var = pPerm ? pPerm[Var] : Var;
+ return Gia_ManAppendMux( p, Abc_Var2Lit(1+Var, 0), iLit1, iLit0 );
+}
+Gia_Man_t * Gia_ManBuildMuxesTest( word * pTruth, int nIns, int nOuts, int * pPerm )
+{
+ Gia_Man_t * pNew, * pTemp;
+ int i, nWords = Abc_TtWordNum(nIns);
+ pNew = Gia_ManStart( 1000 );
+ pNew->pName = Abc_UtilStrsav( "muxes" );
+ for ( i = 0; i < nIns; i++ )
+ Gia_ManAppendCi(pNew);
+ Gia_ManHashAlloc( pNew );
+ for ( i = 0; i < nOuts; i++ )
+ Gia_ManAppendCo( pNew, Gia_ManBuildMuxes_rec( pNew, pTruth+i*nWords, nIns, pPerm ) );
+ Gia_ManHashStop( pNew );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+Gia_Man_t * Gia_ManBuildMuxes( Tree_Sto_t * p, int * pIPerm )
+{
+ return Gia_ManBuildMuxesTest( p->pMem, p->nIns, p->nOuts, pIPerm ? pIPerm : p->pIPerm );
+}
+void Gia_ManDumpMuxes( Tree_Sto_t * p, char * pFileName, int * pIPerm )
+{
+ Gia_Man_t * pNew = Gia_ManBuildMuxes( p, pIPerm );
+ Gia_AigerWrite( pNew, pFileName, 0, 0, 0 );
+ Gia_ManStop( pNew );
+ printf( "Finished dumping tree into AIG file \"%s\".\n", pFileName );
+}
+Gia_Man_t * Gia_ManCreateMuxGia( word * pTruths, int nIns, int nOuts, int nWords, int * pIPerm )
+{
+ Tree_Sto_t * pSto = Gia_ManContructTree( pTruths, nIns, nOuts, nWords );
+ Gia_Man_t * pNew = Gia_ManBuildMuxes( pSto, pIPerm );
+ //printf( "Internal nodes = %5d.\n", Gia_ManTreeCountNodes(pSto) );
+ Gia_ManTreeFree( pSto );
+ return pNew;
+}
+void Gia_ManDumpMuxGia( word * pTruths, int nIns, int nOuts, int nWords, int * pIPerm, char * pFileName )
+{
+ Tree_Sto_t * pSto = Gia_ManContructTree( pTruths, nIns, nOuts, nWords );
+ Gia_ManDumpMuxes( pSto, pFileName, pIPerm );
+ Gia_ManTreeFree( pSto );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_TryPermOptCare( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pNew;
+ word * pTruthDup = Abc_TtDup( pTruths, nOuts*nWords, 0 );
+ word * pTruthBest = ABC_FALLOC( word, (nOuts+1)*nWords );
+ int pIPermBest[TREE_MAX_VARS] = {0};
+ int pIPerm[TREE_MAX_VARS] = {0};
+ int r, rBest = -1, nNodes = -1, nNodesBest = ABC_INFINITY;
+ //Gia_ManDumpMuxGia( pTruths, nIns, nOuts, nWords, NULL, "tt_beg.aig" );
+ //srand( time(NULL) );
+ Gia_ManRandom(1);
+ for ( r = 0; r < nRounds; r++ )
+ {
+ nNodes = Gia_ManPermuteTreeOne( pTruthDup, nIns, nOuts, nWords, r>0, pIPerm, 0, fVerbose );
+ if ( nNodesBest > nNodes )
+ {
+ nNodesBest = nNodes;
+ memcpy( pIPermBest, pIPerm, sizeof(int)*nIns );
+ Abc_TtCopy( pTruthBest, pTruthDup, nOuts*nWords, 0 );
+ rBest = r;
+ }
+ Abc_TtCopy( pTruthDup, pTruths, nOuts*nWords, 0 );
+ if ( fVerbose )
+ printf( "\n" );
+ }
+ if ( fVerbose )
+ printf( "Best round %3d. Best nodes %5d. ", rBest, nNodesBest );
+ ABC_FREE( pTruthDup );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ //pNew = Gia_ManCreateMuxGia( pTruthBest, nIns, nOuts, nWords, pIPermBest );
+ pNew = Abc_TtSimpleMinArrayNew( pTruthBest, nIns, nOuts, NULL, 0, pIPermBest );
+ //Gia_ManDumpMuxGia( pTruthBest, nIns, nOuts, nWords, pIPermBest, "tt_end.aig" );
+ ABC_FREE( pTruthBest );
+ return pNew;
+}
+Gia_Man_t * Gia_TryPermOpt2( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pNew;
+ word * pRes, * pTruthDup = Abc_TtDup( pTruths, nOuts*nWords, 0 );
+ word * pTruthBest = ABC_ALLOC( word, nOuts*nWords/2 );
+ int pIPermBest[TREE_MAX_VARS] = {0};
+ int pIPerm[TREE_MAX_VARS] = {0};
+ int r, rBest = -1, nNodes = -1, nNodesBest = ABC_INFINITY;
+ assert( nOuts % 2 == 0 );
+ // collect onsets
+ //for ( r = 0; r < nOuts/2; r++ )
+ // Abc_TtCopy( pTruthBest+r*nWords, pTruths+2*r*nWords, nWords, 0 );
+ //Gia_ManDumpMuxGia( pTruthBest, nIns, nOuts/2, nWords, NULL, "tt_beg.aig" );
+ //srand( time(NULL) );
+ Gia_ManRandom(1);
+ for ( r = 0; r < nRounds; r++ )
+ {
+ int nNodesAll = Gia_ManPermuteTreeOne( pTruthDup, nIns, nOuts, nWords, r>0, pIPerm, 0, fVerbose );
+ pRes = Abc_TtMinArray( pTruthDup, nOuts, nIns, &nNodes, fVerbose );
+ if ( nNodesBest > nNodes )
+ {
+ nNodesBest = nNodes;
+ memcpy( pIPermBest, pIPerm, sizeof(int)*nIns );
+ Abc_TtCopy( pTruthBest, pRes, nOuts*nWords/2, 0 );
+ rBest = r;
+ }
+ ABC_FREE( pRes );
+ Abc_TtCopy( pTruthDup, pTruths, nOuts*nWords, 0 );
+ if ( fVerbose )
+ printf( "\n" );
+ nNodesAll = 0;
+ }
+ if ( fVerbose )
+ printf( "Best round %3d. Best nodes %5d. ", rBest, nNodesBest );
+ ABC_FREE( pTruthDup );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ pNew = Gia_ManCreateMuxGia( pTruthBest, nIns, nOuts/2, nWords, pIPermBest );
+ //Gia_ManDumpMuxGia( pTruthBest, nIns, nOuts/2, nWords, pIPermBest, "tt_end.aig" );
+ ABC_FREE( pTruthBest );
+ return pNew;
+}
+Gia_Man_t * Gia_TryPermOpt( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pBest = NULL;
+ word * pTruthDup = Abc_TtDup( pTruths, nOuts*nWords, 0 );
+ int pIPermBest[TREE_MAX_VARS] = {0};
+ int pIPerm[TREE_MAX_VARS] = {0};
+ int r, rBest = -1, nNodes2 = -1, nNodesBest = ABC_INFINITY;
+ assert( nOuts % 2 == 0 );
+ //srand( time(NULL) );
+ Gia_ManRandom(1);
+ for ( r = 0; r < nRounds; r++ )
+ {
+ int nNodesAll = Gia_ManPermuteTreeOne( pTruthDup, nIns, nOuts, nWords, r>0, pIPerm, 0, fVerbose );
+ Gia_Man_t * pTemp = Abc_TtGiaMinArray( pTruthDup, nIns, nOuts, NULL, 0, pIPerm );
+ nNodes2 = Gia_ManAndNum(pTemp);
+ if ( nNodesBest > nNodes2 )
+ {
+ nNodesBest = nNodes2;
+ memcpy( pIPermBest, pIPerm, sizeof(int)*nIns );
+ rBest = r;
+
+ Gia_ManStopP( &pBest );
+ pBest = pTemp;
+ pTemp = NULL;
+ }
+ Gia_ManStopP( &pTemp );
+ Abc_TtCopy( pTruthDup, pTruths, nOuts*nWords, 0 );
+ if ( fVerbose )
+ printf( "Permuted = %5d. AIG = %5d.\n", nNodesAll, nNodes2 );
+ nNodesAll = 0;
+ }
+ if ( fVerbose )
+ printf( "Best round %3d. Best nodes %5d. ", rBest, nNodesBest );
+ ABC_FREE( pTruthDup );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ return pBest;
+}
+Gia_Man_t * Gia_TryPermOptNew( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pTemp, * pBest = NULL;
+ word * pTruthDup = Abc_TtDup( pTruths, (nOuts+1)*nWords, 0 );
+ int pIPermBest[TREE_MAX_VARS] = {0};
+ int pIPerm[TREE_MAX_VARS] = {0};
+ int r, rBest = -1, nNodes2 = -1, nNodesBest = ABC_INFINITY;
+ //srand( time(NULL) );
+ Gia_ManRandom(1);
+ for ( r = 0; r < nRounds; r++ )
+ {
+ int nNodesAll = Gia_ManPermuteTreeOne( pTruthDup, nIns, nOuts, nWords, r>0, pIPerm, 0, fVerbose );
+ Abc_TtPermute( pTruthDup + nOuts*nWords, pIPerm, nIns );
+ //pTemp = Abc_TtGiaMinArrayNew( pTruthDup, nIns, nOuts, NULL, 0, pIPerm );
+ pTemp = Abc_TtSimpleMinArrayNew( pTruthDup, nIns, nOuts, NULL, 0, pIPerm );
+ nNodes2 = Gia_ManAndNum(pTemp);
+ if ( nNodesBest > nNodes2 )
+ {
+ nNodesBest = nNodes2;
+ memcpy( pIPermBest, pIPerm, sizeof(int)*nIns );
+ rBest = r;
+
+ Gia_ManStopP( &pBest );
+ pBest = pTemp;
+ pTemp = NULL;
+ }
+ Gia_ManStopP( &pTemp );
+/*
+ for ( i = 0; i <= nOuts; i++ )
+ {
+ Abc_TtUnpermute( pTruthDup + i*nWords, pIPerm, nIns );
+ if ( !Abc_TtEqual(pTruthDup + i*nWords, pTruths + i*nWords, nWords) )
+ printf( "Verification failed for output %d (out of %d).\n", i, nOuts );
+ }
+*/
+ Abc_TtCopy( pTruthDup, pTruths, (nOuts+1)*nWords, 0 );
+ if ( fVerbose )
+ printf( "Permuted = %5d. AIG = %5d.\n", nNodesAll, nNodes2 );
+ nNodesAll = 0;
+ }
+ if ( fVerbose )
+ printf( "Best round %3d. Best nodes %5d. ", rBest, nNodesBest );
+ ABC_FREE( pTruthDup );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ return pBest;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_Tt6MinTest3( Gia_Man_t * p )
+{
+ word f = ABC_CONST(0x513B00000819050F);
+ //word r = ABC_CONST(0xA000571507200000);
+ word r = ~f;
+ Vec_Wrd_t * vNodes = Vec_WrdAlloc( 100 );
+ word Res = Abc_Tt6Min_rec( f, r, 6, vNodes );
+ printf( "Nodes = %d.\n", Vec_WrdSize(vNodes) );
+ if ( Res == f )
+ printf( "Verification successful.\n" );
+ else
+ printf( "Verification FAILED.\n" );
+ Vec_WrdFree( vNodes );
+}
+void Abc_Tt6MinTest2( Gia_Man_t * p )
+{
+ int fVerbose = 0;
+ int i, nWords = Abc_TtWordNum(Gia_ManCiNum(p));
+ word * pTruth = ABC_ALLOC( word, 3*nWords );
+ word * pRes = NULL, * pTruths[3] = { pTruth, pTruth+nWords, pTruth+2*nWords };
+
+ Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
+ Vec_Wrd_t * vNodes = Vec_WrdAlloc( 100 );
+ Vec_Wec_t * vNodes2 = Vec_WecAlloc( 100 );
+ Vec_Wrd_t * vMemory = Vec_WrdAlloc( 0 );
+
+ Gia_Obj_t * pObj;
+ Gia_ManForEachCi( p, pObj, i )
+ Vec_IntPush( vSupp, Gia_ObjId(p, pObj) );
+
+ Gia_ObjComputeTruthTableStart( p, Gia_ManCiNum(p) );
+ assert( Gia_ManCoNum(p) == 3 );
+ Gia_ManForEachCo( p, pObj, i )
+ {
+ word * pTruth = Gia_ObjComputeTruthTableCut( p, Gia_ObjFanin0(pObj), vSupp );
+ Abc_TtCopy( pTruths[i], pTruth, nWords, Gia_ObjFaninC0(pObj) );
+ }
+ Gia_ObjComputeTruthTableStop( p );
+
+
+ //Abc_TtSharp( pTruths[0], pTruths[0], pTruths[1], nWords );
+ Abc_TtReverseVars( pTruths[0], Gia_ManCiNum(p) );
+ Abc_TtCopy( pTruths[1], pTruths[0], nWords, 1 );
+
+ pRes = Abc_TtMin( pTruths[0], pTruths[1], Gia_ManCiNum(p), vMemory, vNodes, vNodes2 );
+ printf( "Nodes = %d.\n", Vec_WrdSize(vNodes) );
+ printf( "Nodes2 = %d.\n", Vec_WecSizeSize(vNodes2) );
+ if ( Abc_TtEqual(pRes, pTruths[0], nWords) )
+ printf( "Verification successful.\n" );
+ else
+ printf( "Verification FAILED.\n" );
+
+ //printf( "Printing the tree:\n" );
+// Gia_ManPermuteTree( pTruths[0], Gia_ManCiNum(p), 1, nWords, fVerbose );
+ Gia_ManPermuteTree( pTruth, Gia_ManCiNum(p), 3, nWords, 0, fVerbose );
+
+
+/*
+ Abc_TtReverseVars( pTruths[0], Gia_ManCiNum(p) );
+ Abc_TtReverseVars( pTruths[1], Gia_ManCiNum(p) );
+ Abc_TtReverseVars( pTruths[2], Gia_ManCiNum(p) );
+ printf( "Printing the tree:\n" );
+ Gia_ManContructTree( pTruth, Gia_ManCiNum(p), 3, nWords );
+*/
+
+/*
+ pNew = Gia_ManBuildMuxesTest( pTruth, Gia_ManCiNum(p), Gia_ManCoNum(p), NULL );
+ Gia_AigerWrite( pNew, "from_tt.aig", 0, 0, 0 );
+ printf( "Dumping file \"%s\".\n", "from_tt.aig" );
+ Gia_ManStop( pNew );
+*/
+
+ Vec_WrdFree( vMemory );
+ Vec_WrdFree( vNodes );
+ Vec_WecFree( vNodes2 );
+ Vec_IntFree( vSupp );
+ ABC_FREE( pTruth );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaMini.c b/src/aig/gia/giaMini.c
index ce42f73c..6cc528f2 100644
--- a/src/aig/gia/giaMini.c
+++ b/src/aig/gia/giaMini.c
@@ -32,6 +32,8 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash );
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -57,7 +59,7 @@ int Gia_ObjFromMiniFanin1Copy( Gia_Man_t * pGia, Vec_Int_t * vCopies, Mini_Aig_t
int Lit = Mini_AigNodeFanin1( p, Id );
return Abc_LitNotCond( Vec_IntEntry(vCopies, Abc_Lit2Var(Lit)), Abc_LitIsCompl(Lit) );
}
-Gia_Man_t * Gia_ManFromMiniAig( Mini_Aig_t * p, Vec_Int_t ** pvCopies )
+Gia_Man_t * Gia_ManFromMiniAig( Mini_Aig_t * p, Vec_Int_t ** pvCopies, int fGiaSimple )
{
Gia_Man_t * pGia, * pTemp;
Vec_Int_t * vCopies;
@@ -71,7 +73,10 @@ Gia_Man_t * Gia_ManFromMiniAig( Mini_Aig_t * p, Vec_Int_t ** pvCopies )
vCopies = Vec_IntAlloc( nNodes );
Vec_IntPush( vCopies, 0 );
// iterate through the objects
- Gia_ManHashAlloc( pGia );
+ if ( fGiaSimple )
+ pGia->fGiaSimple = fGiaSimple;
+ else
+ Gia_ManHashAlloc( pGia );
for ( i = 1; i < nNodes; i++ )
{
if ( Mini_AigNodeIsPi( p, i ) )
@@ -83,17 +88,19 @@ Gia_Man_t * Gia_ManFromMiniAig( Mini_Aig_t * p, Vec_Int_t ** pvCopies )
else assert( 0 );
Vec_IntPush( vCopies, iGiaLit );
}
- Gia_ManHashStop( pGia );
assert( Vec_IntSize(vCopies) == nNodes );
if ( pvCopies )
*pvCopies = vCopies;
else
Vec_IntFree( vCopies );
Gia_ManSetRegNum( pGia, Mini_AigRegNum(p) );
- pGia = Gia_ManCleanup( pTemp = pGia );
- if ( pvCopies )
- Gia_ManDupRemapLiterals( *pvCopies, pTemp );
- Gia_ManStop( pTemp );
+ if ( !fGiaSimple )
+ {
+ pGia = Gia_ManCleanup( pTemp = pGia );
+ if ( pvCopies )
+ Gia_ManDupRemapLiterals( *pvCopies, pTemp );
+ Gia_ManStop( pTemp );
+ }
return pGia;
}
@@ -148,7 +155,7 @@ void Abc_FrameGiaInputMiniAig( Abc_Frame_t * pAbc, void * p )
printf( "ABC framework is not initialized by calling Abc_Start()\n" );
Gia_ManStopP( &pAbc->pGiaMiniAig );
Vec_IntFreeP( &pAbc->vCopyMiniAig );
- pGia = Gia_ManFromMiniAig( (Mini_Aig_t *)p, &pAbc->vCopyMiniAig );
+ pGia = Gia_ManFromMiniAig( (Mini_Aig_t *)p, &pAbc->vCopyMiniAig, 0 );
Abc_FrameUpdateGia( pAbc, pGia );
pAbc->pGiaMiniAig = Gia_ManDup( pGia );
// Gia_ManDelete( pGia );
@@ -175,10 +182,10 @@ void * Abc_FrameGiaOutputMiniAig( Abc_Frame_t * pAbc )
SeeAlso []
***********************************************************************/
-Gia_Man_t * Gia_ManReadMiniAig( char * pFileName )
+Gia_Man_t * Gia_ManReadMiniAig( char * pFileName, int fGiaSimple )
{
Mini_Aig_t * p = Mini_AigLoad( pFileName );
- Gia_Man_t * pGia = Gia_ManFromMiniAig( p, NULL );
+ Gia_Man_t * pGia = Gia_ManFromMiniAig( p, NULL, fGiaSimple );
ABC_FREE( pGia->pName );
pGia->pName = Extra_FileNameGeneric( pFileName );
Mini_AigStop( p );
@@ -260,6 +267,65 @@ Gia_Man_t * Gia_ManFromMiniLut( Mini_Lut_t * p, Vec_Int_t ** pvCopies )
return pGia;
}
+
+/**Function*************************************************************
+
+ Synopsis [Converts MiniLUT into GIA.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManFromMiniLut2( Mini_Lut_t * p, Vec_Int_t ** pvCopies )
+{
+ Gia_Man_t * pGia;
+ Vec_Int_t * vCopies;
+ Vec_Int_t * vCover = Vec_IntAlloc( 1000 );
+ Vec_Int_t * vLits = Vec_IntAlloc( 100 );
+ int i, k, Fan, iGiaLit, nNodes;
+ // get the number of nodes
+ nNodes = Mini_LutNodeNum(p);
+ // create ABC network
+ pGia = Gia_ManStart( 3 * nNodes );
+ pGia->pName = Abc_UtilStrsav( "MiniLut" );
+ // create mapping from MiniLUT objects into ABC objects
+ vCopies = Vec_IntAlloc( nNodes );
+ Vec_IntPush( vCopies, 0 );
+ Vec_IntPush( vCopies, 1 );
+ // iterate through the objects
+ pGia->fGiaSimple = 1;
+ for ( i = 2; i < nNodes; i++ )
+ {
+ if ( Mini_LutNodeIsPi( p, i ) )
+ iGiaLit = Gia_ManAppendCi(pGia);
+ else if ( Mini_LutNodeIsPo( p, i ) )
+ iGiaLit = Gia_ManAppendCo(pGia, Vec_IntEntry(vCopies, Mini_LutNodeFanin(p, i, 0)));
+ else if ( Mini_LutNodeIsNode( p, i ) )
+ {
+ unsigned * puTruth = Mini_LutNodeTruth( p, i );
+ Vec_IntClear( vLits );
+ Mini_LutForEachFanin( p, i, Fan, k )
+ Vec_IntPush( vLits, Vec_IntEntry(vCopies, Fan) );
+ iGiaLit = Kit_TruthToGia( pGia, puTruth, Vec_IntSize(vLits), vCover, vLits, 0 );
+ }
+ else assert( 0 );
+ Vec_IntPush( vCopies, iGiaLit );
+ }
+ Vec_IntFree( vCover );
+ Vec_IntFree( vLits );
+ assert( Vec_IntSize(vCopies) == nNodes );
+ if ( pvCopies )
+ *pvCopies = vCopies;
+ else
+ Vec_IntFree( vCopies );
+ Gia_ManSetRegNum( pGia, Mini_LutRegNum(p) );
+ return pGia;
+}
+
+
/**Function*************************************************************
Synopsis [Marks LUTs that should be complemented.]
@@ -412,6 +478,15 @@ void Abc_FrameGiaInputMiniLut( Abc_Frame_t * pAbc, void * p )
Abc_FrameUpdateGia( pAbc, pGia );
// Gia_ManDelete( pGia );
}
+void Abc_FrameGiaInputMiniLut2( Abc_Frame_t * pAbc, void * p )
+{
+ if ( pAbc == NULL )
+ printf( "ABC framework is not initialized by calling Abc_Start()\n" );
+ Vec_IntFreeP( &pAbc->vCopyMiniLut );
+ Gia_ManStopP( &pAbc->pGiaMiniLut );
+ pAbc->pGiaMiniLut = Gia_ManFromMiniLut2( (Mini_Lut_t *)p, &pAbc->vCopyMiniLut );
+// Abc_FrameUpdateGia( pAbc, pGia );
+}
void * Abc_FrameGiaOutputMiniLut( Abc_Frame_t * pAbc )
{
Mini_Lut_t * pRes = NULL;
@@ -589,6 +664,39 @@ int * Abc_FrameReadMiniLutNameMapping( Abc_Frame_t * pAbc )
Gia_ManStop( pGia );
return pRes;
}
+int * Abc_FrameReadMiniLutSwitching( Abc_Frame_t * pAbc )
+{
+ Vec_Int_t * vSwitching;
+ int i, iObj, * pRes = NULL;
+ if ( pAbc->pGiaMiniLut == NULL )
+ {
+ printf( "GIA derived from MiniLut is not available.\n" );
+ return NULL;
+ }
+ vSwitching = Gia_ManComputeSwitchProbs( pAbc->pGiaMiniLut, 48, 16, 0 );
+ pRes = ABC_CALLOC( int, Vec_IntSize(pAbc->vCopyMiniLut) );
+ Vec_IntForEachEntry( pAbc->vCopyMiniLut, iObj, i )
+ if ( iObj >= 0 )
+ pRes[i] = (int)(10000*Vec_FltEntry( (Vec_Flt_t *)vSwitching, Abc_Lit2Var(iObj) ));
+ Vec_IntFree( vSwitching );
+ return pRes;
+}
+int * Abc_FrameReadMiniLutSwitchingPo( Abc_Frame_t * pAbc )
+{
+ Vec_Int_t * vSwitching;
+ int i, iObj, * pRes = NULL;
+ if ( pAbc->pGiaMiniAig == NULL )
+ {
+ printf( "GIA derived from MiniAIG is not available.\n" );
+ return NULL;
+ }
+ vSwitching = Gia_ManComputeSwitchProbs( pAbc->pGiaMiniAig, 48, 16, 0 );
+ pRes = ABC_CALLOC( int, Gia_ManCoNum(pAbc->pGiaMiniAig) );
+ Gia_ManForEachCoDriverId( pAbc->pGiaMiniAig, iObj, i )
+ pRes[i] = (int)(10000*Vec_FltEntry( (Vec_Flt_t *)vSwitching, iObj ));
+ Vec_IntFree( vSwitching );
+ return pRes;
+}
/**Function*************************************************************
@@ -797,6 +905,274 @@ void Gia_MiniAigVerify( Abc_Frame_t * pAbc, char * pFileName )
Mini_AigStop( p );
}
+/**Function*************************************************************
+
+ Synopsis [Collects supergate for the outputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_MiniAigSuperGates_rec( Mini_Aig_t * p, int iObj, Vec_Int_t * vRes, Vec_Int_t * vMap )
+{
+ int iFan0, iFan1;
+ if ( Mini_AigNodeIsPi(p, iObj) )
+ {
+ assert( Vec_IntEntry(vMap, iObj) >= 0 );
+ Vec_IntPush( vRes, Vec_IntEntry(vMap, iObj) );
+ return;
+ }
+ iFan0 = Mini_AigNodeFanin0( p, iObj );
+ iFan1 = Mini_AigNodeFanin1( p, iObj );
+ assert( !Abc_LitIsCompl(iFan0) );
+ assert( !Abc_LitIsCompl(iFan1) );
+ Gia_MiniAigSuperGates_rec( p, Abc_Lit2Var(iFan0), vRes, vMap );
+ Gia_MiniAigSuperGates_rec( p, Abc_Lit2Var(iFan1), vRes, vMap );
+}
+Vec_Wec_t * Gia_MiniAigSuperGates( Mini_Aig_t * p )
+{
+ Vec_Wec_t * vRes = Vec_WecStart( Mini_AigPoNum(p) );
+ Vec_Int_t * vMap = Vec_IntStartFull( Mini_AigNodeNum(p) );
+ int i, Index = 0;
+ Mini_AigForEachPi( p, i )
+ Vec_IntWriteEntry( vMap, i, Index++ );
+ assert( Index == Mini_AigPiNum(p) );
+ Index = 0;
+ Mini_AigForEachPo( p, i )
+ {
+ int iFan0 = Mini_AigNodeFanin0( p, i );
+ assert( !Abc_LitIsCompl(iFan0) );
+ Gia_MiniAigSuperGates_rec( p, Abc_Lit2Var(iFan0), Vec_WecEntry(vRes, Index++), vMap );
+ }
+ assert( Index == Mini_AigPoNum(p) );
+ Vec_IntFree( vMap );
+ return vRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transform.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_MiniAigSuperPrintDouble( Vec_Int_t * p, int nPis )
+{
+ int i, Entry;
+ printf( "\n" );
+ Vec_IntForEachEntry( p, Entry, i )
+ printf( "%d(%d) ", Entry%nPis, Entry/nPis );
+ printf( " Total = %d\n", Vec_IntSize(p) );
+}
+int Gia_MiniAigSuperMerge( Vec_Int_t * p, int nPis )
+{
+ int i, k = 0, This, Prev = -1, fChange = 0;
+ Vec_IntForEachEntry( p, This, i )
+ {
+ if ( Prev == This )
+ {
+ Vec_IntWriteEntry( p, k++, (This/nPis+1)*nPis + This%nPis );
+ Prev = -1;
+ fChange = 1;
+ }
+ else
+ {
+ if ( Prev != -1 )
+ Vec_IntWriteEntry( p, k++, Prev );
+ Prev = This;
+ }
+ }
+ if ( Prev != -1 )
+ Vec_IntWriteEntry( p, k++, Prev );
+ Vec_IntShrink( p, k );
+ return fChange;
+}
+int Gia_MiniAigSuperPreprocess( Mini_Aig_t * p, Vec_Wec_t * vSuper, int nPis, int fVerbose )
+{
+ Vec_Int_t * vRes;
+ int i, nIters, Multi = 1;
+ Vec_WecForEachLevel( vSuper, vRes, i )
+ {
+ Vec_IntSort( vRes, 0 );
+ if ( fVerbose )
+ printf( "\nOutput %d\n", i );
+ if ( fVerbose )
+ Gia_MiniAigSuperPrintDouble( vRes, nPis );
+ for ( nIters = 1; Gia_MiniAigSuperMerge(vRes, nPis); nIters++ )
+ {
+ if ( fVerbose )
+ Gia_MiniAigSuperPrintDouble( vRes, nPis );
+ }
+ Multi = Abc_MaxInt( Multi, nIters );
+ }
+ if ( fVerbose )
+ printf( "Multi = %d.\n", Multi );
+ return Multi;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derive AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_MiniAigSuperDeriveGia( Vec_Wec_t * p, int nPis, int Multi )
+{
+ Gia_Man_t * pNew;
+ Vec_Int_t * vTemp, * vLits = Vec_IntAlloc( 100 );
+ Vec_Int_t * vDrivers = Vec_IntAlloc(100);
+ int i, k, iObj, iLit, nInputs = nPis*Multi;
+ pNew = Gia_ManStart( 1000 );
+ pNew->pName = Abc_UtilStrsav( "tree" );
+ for ( i = 0; i < nInputs; i++ )
+ Gia_ManAppendCi( pNew );
+ Gia_ManHashAlloc( pNew );
+ Vec_WecForEachLevel( p, vTemp, i )
+ {
+ Vec_IntClear( vLits );
+ Vec_IntForEachEntry( vTemp, iObj, k )
+ {
+ assert( iObj < nInputs );
+ Vec_IntPush( vLits, 2+2*((iObj%nPis)*Multi+iObj/nPis) );
+ }
+ Vec_IntPush( vDrivers, Gia_ManHashAndMulti2(pNew, vLits) );
+ }
+ Gia_ManHashStop( pNew );
+ Vec_IntFree( vLits );
+ Vec_IntForEachEntry( vDrivers, iLit, i )
+ Gia_ManAppendCo( pNew, iLit );
+ Vec_IntFree( vDrivers );
+ return pNew;
+}
+Gia_Man_t * Gia_MiniAigSuperDerive( char * pFileName, int fVerbose )
+{
+ Mini_Aig_t * p = Mini_AigLoad( pFileName );
+ Vec_Wec_t * vSuper = Gia_MiniAigSuperGates( p );
+ int Multi = Gia_MiniAigSuperPreprocess( p, vSuper, Mini_AigPiNum(p), fVerbose );
+ Gia_Man_t * pNew = Gia_MiniAigSuperDeriveGia( vSuper, Mini_AigPiNum(p), Multi );
+ Vec_WecFree( vSuper );
+ Mini_AigStop( p );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Process file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_MiniAigProcessFile()
+{
+ Vec_Int_t * vTriples = Vec_IntAlloc( 100 );
+ char * pFileName = "test.txt";
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ printf( "Cannot open the file.\n" );
+ else
+ {
+ int nLines = 0, nLinesAll = 0;
+ char * pToken;
+ char Buffer[1000];
+ while ( fgets( Buffer, 1000, pFile ) != NULL )
+ {
+ nLinesAll++;
+ if ( Buffer[0] != '#' )
+ continue;
+ //printf( "%s", Buffer );
+ nLines++;
+ pToken = strtok( Buffer+3, " \r\n\r+=" );
+ while ( pToken )
+ {
+ Vec_IntPush( vTriples, atoi(pToken) );
+ pToken = strtok( NULL, " \r\n\r+=" );
+ }
+ }
+ fclose( pFile );
+ printf( "Collected %d (out of %d) lines.\n", nLines, nLinesAll );
+ printf( "Entries = %d\n", Vec_IntSize(vTriples) );
+ }
+ return vTriples;
+}
+void Gia_MiniAigGenerate_rec( Mini_Aig_t * p, Vec_Int_t * vTriples, int iObj, Vec_Int_t * vDefs, Vec_Int_t * vMap )
+{
+ int Index, Entry0, Entry1, Entry2, Value;
+ if ( Vec_IntEntry(vMap, iObj) >= 0 )
+ return;
+ Index = Vec_IntEntry( vDefs, iObj );
+ Entry0 = Vec_IntEntry( vTriples, 3*Index+0 );
+ Entry1 = Vec_IntEntry( vTriples, 3*Index+1 );
+ Entry2 = Vec_IntEntry( vTriples, 3*Index+2 );
+ Gia_MiniAigGenerate_rec( p, vTriples, Entry1, vDefs, vMap );
+ Gia_MiniAigGenerate_rec( p, vTriples, Entry2, vDefs, vMap );
+ assert( Vec_IntEntry(vMap, Entry1) >= 0 );
+ assert( Vec_IntEntry(vMap, Entry2) >= 0 );
+ Value = Mini_AigAnd( p, Vec_IntEntry(vMap, Entry1), Vec_IntEntry(vMap, Entry2) );
+ Vec_IntWriteEntry( vMap, Entry0, Value );
+}
+void Gia_MiniAigGenerateFromFile()
+{
+ Mini_Aig_t * p = Mini_AigStart();
+ Vec_Int_t * vTriples = Gia_MiniAigProcessFile();
+ Vec_Int_t * vDefs = Vec_IntStartFull( Vec_IntSize(vTriples) );
+ Vec_Int_t * vMap = Vec_IntStartFull( Vec_IntSize(vTriples) );
+ Vec_Int_t * vMapIn = Vec_IntStart( Vec_IntSize(vTriples) );
+ Vec_Int_t * vMapOut = Vec_IntStart( Vec_IntSize(vTriples) );
+ Vec_Int_t * vPis = Vec_IntAlloc( 100 );
+ Vec_Int_t * vPos = Vec_IntAlloc( 100 );
+ int i, ObjOut, ObjIn;
+ assert( Vec_IntSize(vTriples) % 3 == 0 );
+ for ( i = 0; i < Vec_IntSize(vTriples)/3; i++ )
+ {
+ int Entry0 = Vec_IntEntry(vTriples, 3*i+0);
+ int Entry1 = Vec_IntEntry(vTriples, 3*i+1);
+ int Entry2 = Vec_IntEntry(vTriples, 3*i+2);
+ Vec_IntWriteEntry( vDefs, Entry0, i );
+ Vec_IntAddToEntry( vMapOut, Entry0, 1 );
+ Vec_IntAddToEntry( vMapIn, Entry1, 1 );
+ Vec_IntAddToEntry( vMapIn, Entry2, 1 );
+ }
+ Vec_IntForEachEntryTwo( vMapOut, vMapIn, ObjOut, ObjIn, i )
+ if ( !ObjOut && ObjIn )
+ Vec_IntPush( vPis, i );
+ else if ( ObjOut && !ObjIn )
+ Vec_IntPush( vPos, i );
+ Vec_IntForEachEntry( vPis, ObjIn, i )
+ Vec_IntWriteEntry( vMap, ObjIn, Mini_AigCreatePi(p) );
+ Vec_IntForEachEntry( vPos, ObjOut, i )
+ Gia_MiniAigGenerate_rec( p, vTriples, ObjOut, vDefs, vMap );
+ Vec_IntForEachEntry( vPos, ObjOut, i )
+ {
+ assert( Vec_IntEntry(vMap, ObjOut) >= 0 );
+ Mini_AigCreatePo( p, Vec_IntEntry(vMap, ObjOut) );
+ }
+ Vec_IntFree( vTriples );
+ Vec_IntFree( vDefs );
+ Vec_IntFree( vMap );
+ Vec_IntFree( vMapIn );
+ Vec_IntFree( vMapOut );
+ Vec_IntFree( vPis );
+ Vec_IntFree( vPos );
+ Mini_AigDump( p, "test.miniaig" );
+ Mini_AigStop( p );
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaPat2.c b/src/aig/gia/giaPat2.c
new file mode 100644
index 00000000..f14ce34a
--- /dev/null
+++ b/src/aig/gia/giaPat2.c
@@ -0,0 +1,1329 @@
+/**CFile****************************************************************
+
+ FileName [giaPat2.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Pattern generation.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaPat2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+#include "misc/vec/vecHsh.h"
+#include "sat/cnf/cnf.h"
+#include "sat/bsat/satStore.h"
+#include "misc/util/utilTruth.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Min_Man_t_ Min_Man_t;
+struct Min_Man_t_
+{
+ int nCis;
+ int nCos;
+ int FirstAndLit;
+ int FirstCoLit;
+ Vec_Int_t vFans;
+ Vec_Str_t vValsN;
+ Vec_Str_t vValsL;
+ Vec_Int_t vVis;
+ Vec_Int_t vPat;
+};
+
+static inline int Min_ManCiNum( Min_Man_t * p ) { return p->nCis; }
+static inline int Min_ManCoNum( Min_Man_t * p ) { return p->nCos; }
+static inline int Min_ManObjNum( Min_Man_t * p ) { return Vec_IntSize(&p->vFans) >> 1; }
+static inline int Min_ManAndNum( Min_Man_t * p ) { return Min_ManObjNum(p) - p->nCis - p->nCos - 1; }
+
+static inline int Min_ManCi( Min_Man_t * p, int i ) { return 1 + i; }
+static inline int Min_ManCo( Min_Man_t * p, int i ) { return Min_ManObjNum(p) - Min_ManCoNum(p) + i; }
+
+static inline int Min_ObjIsCi( Min_Man_t * p, int i ) { return i > 0 && i <= Min_ManCiNum(p); }
+static inline int Min_ObjIsNode( Min_Man_t * p, int i ) { return i > Min_ManCiNum(p) && i < Min_ManObjNum(p) - Min_ManCoNum(p); }
+static inline int Min_ObjIsAnd( Min_Man_t * p, int i ) { return Min_ObjIsNode(p, i) && Vec_IntEntry(&p->vFans, 2*i) < Vec_IntEntry(&p->vFans, 2*i+1); }
+static inline int Min_ObjIsXor( Min_Man_t * p, int i ) { return Min_ObjIsNode(p, i) && Vec_IntEntry(&p->vFans, 2*i) > Vec_IntEntry(&p->vFans, 2*i+1); }
+static inline int Min_ObjIsBuf( Min_Man_t * p, int i ) { return Min_ObjIsNode(p, i) && Vec_IntEntry(&p->vFans, 2*i) ==Vec_IntEntry(&p->vFans, 2*i+1); }
+static inline int Min_ObjIsCo( Min_Man_t * p, int i ) { return i >= Min_ManObjNum(p) - Min_ManCoNum(p) && i < Min_ManObjNum(p); }
+
+static inline int Min_ObjLit( Min_Man_t * p, int i, int n ) { return Vec_IntEntry(&p->vFans, i + i + n); }
+static inline int Min_ObjLit0( Min_Man_t * p, int i ) { return Vec_IntEntry(&p->vFans, i + i + 0); }
+static inline int Min_ObjLit1( Min_Man_t * p, int i ) { return Vec_IntEntry(&p->vFans, i + i + 1); }
+static inline int Min_ObjCioId( Min_Man_t * p, int i ) { assert( i && !Min_ObjIsNode(p, i) ); return Min_ObjLit1(p, i); }
+
+static inline int Min_ObjFan0( Min_Man_t * p, int i ) { return Abc_Lit2Var( Min_ObjLit0(p, i) ); }
+static inline int Min_ObjFan1( Min_Man_t * p, int i ) { return Abc_Lit2Var( Min_ObjLit1(p, i) ); }
+
+static inline int Min_ObjFanC0( Min_Man_t * p, int i ) { return Abc_LitIsCompl( Min_ObjLit0(p, i) ); }
+static inline int Min_ObjFanC1( Min_Man_t * p, int i ) { return Abc_LitIsCompl( Min_ObjLit1(p, i) ); }
+
+static inline char Min_ObjValN( Min_Man_t * p, int i ) { return Vec_StrEntry(&p->vValsN, i); }
+static inline void Min_ObjSetValN( Min_Man_t * p, int i, char v ){ Vec_StrWriteEntry(&p->vValsN, i, v); }
+
+static inline char Min_LitValL( Min_Man_t * p, int i ) { return Vec_StrEntry(&p->vValsL, i); }
+static inline void Min_LitSetValL( Min_Man_t * p, int i, char v ){ assert(v==0 || v==1); Vec_StrWriteEntry(&p->vValsL, i, v); Vec_StrWriteEntry(&p->vValsL, i^1, (char)!v); Vec_IntPush(&p->vVis, Abc_Lit2Var(i)); }
+static inline void Min_ObjCleanValL( Min_Man_t * p, int i ) { ((short *)Vec_StrArray(&p->vValsL))[i] = 0x0202; }
+static inline void Min_ObjMarkValL( Min_Man_t * p, int i ) { ((short *)Vec_StrArray(&p->vValsL))[i] |= 0x0404; }
+static inline void Min_ObjMark2ValL( Min_Man_t * p, int i ) { ((short *)Vec_StrArray(&p->vValsL))[i] |= 0x0808; }
+static inline void Min_ObjUnmark2ValL( Min_Man_t * p, int i ) { ((short *)Vec_StrArray(&p->vValsL))[i] &= 0xF7F7; }
+
+static inline int Min_LitIsCi( Min_Man_t * p, int v ) { return v > 1 && v < p->FirstAndLit; }
+static inline int Min_LitIsNode( Min_Man_t * p, int v ) { return v >= p->FirstAndLit && v < p->FirstCoLit; }
+static inline int Min_LitIsCo( Min_Man_t * p, int v ) { return v >= p->FirstCoLit; }
+
+static inline int Min_LitIsAnd( int v, int v0, int v1 ) { return Abc_LitIsCompl(v) ^ (v0 < v1); }
+static inline int Min_LitIsXor( int v, int v0, int v1 ) { return Abc_LitIsCompl(v) ^ (v0 > v1); }
+static inline int Min_LitIsBuf( int v, int v0, int v1 ) { return v0 == v1; }
+
+static inline int Min_LitFan( Min_Man_t * p, int v ) { return Vec_IntEntry(&p->vFans, v); }
+static inline int Min_LitFanC( Min_Man_t * p, int v ) { return Abc_LitIsCompl( Min_LitFan(p, v) ); }
+
+static inline void Min_ManStartValsN( Min_Man_t * p ) { Vec_StrGrow(&p->vValsN, Vec_IntCap(&p->vFans)/2); Vec_StrFill(&p->vValsN, Min_ManObjNum(p), 2); }
+static inline void Min_ManStartValsL( Min_Man_t * p ) { Vec_StrGrow(&p->vValsL, Vec_IntCap(&p->vFans)); Vec_StrFill(&p->vValsL, Vec_IntSize(&p->vFans), 2); }
+static inline int Min_ManCheckCleanValsL( Min_Man_t * p ) { int i; char c; Vec_StrForEachEntry( &p->vValsL, c, i ) if ( c != 2 ) return 0; return 1; }
+static inline void Min_ManCleanVisitedValL( Min_Man_t * p ) { int i, iObj; Vec_IntForEachEntry(&p->vVis, iObj, i) Min_ObjCleanValL(p, iObj); Vec_IntClear(&p->vVis); }
+
+
+#define Min_ManForEachObj( p, i ) \
+ for ( i = 0; i < Min_ManObjNum(p); i++ )
+#define Min_ManForEachCi( p, i ) \
+ for ( i = 1; i <= Min_ManCiNum(p); i++ )
+#define Min_ManForEachCo( p, i ) \
+ for ( i = Min_ManObjNum(p) - Min_ManCoNum(p); i < Min_ManObjNum(p); i++ )
+#define Min_ManForEachAnd( p, i ) \
+ for ( i = 1 + Min_ManCiNum(p); i < Min_ManObjNum(p) - Min_ManCoNum(p); i++ )
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Min_Man_t * Min_ManStart( int nObjMax )
+{
+ Min_Man_t * p = ABC_CALLOC( Min_Man_t, 1 );
+ Vec_IntGrow( &p->vFans, nObjMax );
+ Vec_IntPushTwo( &p->vFans, -1, -1 );
+ return p;
+}
+static inline void Min_ManStop( Min_Man_t * p )
+{
+ Vec_IntErase( &p->vFans );
+ Vec_StrErase( &p->vValsN );
+ Vec_StrErase( &p->vValsL );
+ Vec_IntErase( &p->vVis );
+ Vec_IntErase( &p->vPat );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Min_ManAppendObj( Min_Man_t * p, int iLit0, int iLit1 )
+{
+ int iLit = Vec_IntSize(&p->vFans);
+ Vec_IntPushTwo( &p->vFans, iLit0, iLit1 );
+ return iLit;
+}
+static inline int Min_ManAppendCi( Min_Man_t * p )
+{
+ p->nCis++;
+ p->FirstAndLit = Vec_IntSize(&p->vFans) + 2;
+ return Min_ManAppendObj( p, 0, p->nCis-1 );
+}
+static inline int Min_ManAppendCo( Min_Man_t * p, int iLit0 )
+{
+ p->nCos++;
+ if ( p->FirstCoLit == 0 )
+ p->FirstCoLit = Vec_IntSize(&p->vFans);
+ return Min_ManAppendObj( p, iLit0, p->nCos-1 );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Min_ManFromGia_rec( Min_Man_t * pNew, Gia_Man_t * p, int iObj )
+{
+ Gia_Obj_t * pObj = Gia_ManObj(p, iObj);
+ if ( ~pObj->Value )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ Min_ManFromGia_rec( pNew, p, Gia_ObjFaninId0(pObj, iObj) );
+ Min_ManFromGia_rec( pNew, p, Gia_ObjFaninId1(pObj, iObj) );
+ pObj->Value = Min_ManAppendObj( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+Min_Man_t * Min_ManFromGia( Gia_Man_t * p, Vec_Int_t * vOuts )
+{
+ Gia_Obj_t * pObj; int i;
+ Min_Man_t * pNew = Min_ManStart( Gia_ManObjNum(p) );
+ Gia_ManFillValue(p);
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Min_ManAppendCi( pNew );
+ if ( vOuts == NULL )
+ {
+ Gia_ManForEachAnd( p, pObj, i )
+ pObj->Value = Min_ManAppendObj( pNew, Gia_ObjFaninLit0(pObj, i), Gia_ObjFaninLit1(pObj, i) );
+ Gia_ManForEachCo( p, pObj, i )
+ pObj->Value = Min_ManAppendCo( pNew, Gia_ObjFaninLit0p(p, pObj) );
+ }
+ else
+ {
+ Gia_ManForEachCoVec( vOuts, p, pObj, i )
+ Min_ManFromGia_rec( pNew, p, Gia_ObjFaninId0p(p, pObj) );
+ Gia_ManForEachCoVec( vOuts, p, pObj, i )
+ Min_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ }
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline char Min_XsimNot( char Val )
+{
+ if ( Val < 2 )
+ return Val ^ 1;
+ return 2;
+}
+static inline char Min_XsimXor( char Val0, char Val1 )
+{
+ if ( Val0 < 2 && Val1 < 2 )
+ return Val0 ^ Val1;
+ return 2;
+}
+static inline char Min_XsimAnd( char Val0, char Val1 )
+{
+ if ( Val0 == 0 || Val1 == 0 )
+ return 0;
+ if ( Val0 == 1 && Val1 == 1 )
+ return 1;
+ return 2;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char Min_LitVerify_rec( Min_Man_t * p, int iLit )
+{
+ char Val = Min_LitValL(p, iLit);
+ if ( Val == 2 && Min_LitIsNode(p, iLit) ) // unassigned
+ {
+ int iLit0 = Min_LitFan(p, iLit);
+ int iLit1 = Min_LitFan(p, iLit^1);
+ char Val0 = Min_LitVerify_rec( p, iLit0 );
+ char Val1 = Min_LitVerify_rec( p, iLit1 );
+ assert( Val0 < 3 && Val1 < 3 );
+ if ( Min_LitIsXor(iLit, iLit0, iLit1) )
+ Val = Min_XsimXor( Val0, Val1 );
+ else
+ Val = Min_XsimAnd( Val0, Val1 );
+ if ( Val < 2 )
+ {
+ Val ^= Abc_LitIsCompl(iLit);
+ Min_LitSetValL( p, iLit, Val );
+ }
+ else
+ Vec_IntPush( &p->vVis, Abc_Lit2Var(iLit) );
+ Min_ObjMark2ValL( p, Abc_Lit2Var(iLit) );
+ }
+ return Val&3;
+}
+char Min_LitVerify( Min_Man_t * p, int iLit, Vec_Int_t * vLits )
+{
+ int i, Entry; char Res;
+ if ( iLit < 2 ) return 1;
+ assert( !Min_LitIsCo(p, iLit) );
+ //assert( Min_ManCheckCleanValsL(p) );
+ assert( Vec_IntSize(&p->vVis) == 0 );
+ Vec_IntForEachEntry( vLits, Entry, i )
+ Min_LitSetValL( p, Entry, 1 ); // ms notation
+ Res = Min_LitVerify_rec( p, iLit );
+ Min_ManCleanVisitedValL( p );
+ return Res;
+}
+
+void Min_LitMinimize( Min_Man_t * p, int iLit, Vec_Int_t * vLits )
+{
+ int i, iObj, iTemp; char Res;
+ Vec_IntClear( &p->vPat );
+ if ( iLit < 2 ) return;
+ assert( !Min_LitIsCo(p, iLit) );
+ //assert( Min_ManCheckCleanValsL(p) );
+ assert( Vec_IntSize(&p->vVis) == 0 );
+ Vec_IntForEachEntry( vLits, iTemp, i )
+ Min_LitSetValL( p, iTemp, 1 ); // ms notation
+ Res = Min_LitVerify_rec( p, iLit );
+ assert( Res == 1 );
+ Min_ObjMarkValL( p, Abc_Lit2Var(iLit) );
+ Vec_IntForEachEntryReverse( &p->vVis, iObj, i )
+ {
+ int iLit = Abc_Var2Lit( iObj, 0 );
+ int Value = 7 & Min_LitValL(p, iLit);
+ if ( Value >= 4 )
+ {
+ if ( Min_LitIsCi(p, iLit) )
+ Vec_IntPush( &p->vPat, Abc_LitNotCond(iLit, !(Value&1)) );
+ else
+ {
+ int iLit0 = Min_LitFan(p, iLit);
+ int iLit1 = Min_LitFan(p, iLit^1);
+ char Val0 = Min_LitValL( p, iLit0 );
+ char Val1 = Min_LitValL( p, iLit1 );
+ if ( Value&1 ) // value == 1
+ {
+ assert( (Val0&1) && (Val1&1) );
+ Min_ObjMarkValL( p, Abc_Lit2Var(iLit0) );
+ Min_ObjMarkValL( p, Abc_Lit2Var(iLit1) );
+ }
+ else // value == 0
+ {
+ int Zero0 = !(Val0&3);
+ int Zero1 = !(Val1&3);
+ assert( Zero0 || Zero1 );
+ if ( Zero0 && !Zero1 )
+ Min_ObjMarkValL( p, Abc_Lit2Var(iLit0) );
+ else if ( !Zero0 && Zero1 )
+ Min_ObjMarkValL( p, Abc_Lit2Var(iLit1) );
+ else if ( Val0 == 4 && Val1 != 4 )
+ Min_ObjMarkValL( p, Abc_Lit2Var(iLit0) );
+ else if ( Val1 == 4 && Val1 != 4 )
+ Min_ObjMarkValL( p, Abc_Lit2Var(iLit1) );
+ else if ( Abc_Random(0) & 1 )
+ Min_ObjMarkValL( p, Abc_Lit2Var(iLit0) );
+ else
+ Min_ObjMarkValL( p, Abc_Lit2Var(iLit1) );
+ }
+ }
+ }
+ Min_ObjCleanValL( p, Abc_Lit2Var(iLit) );
+ }
+ Vec_IntClear( &p->vVis );
+ //Min_ManCleanVisitedValL( p );
+ //assert( Min_LitVerify(p, iLit, &p->vPat) == 1 );
+ assert( Vec_IntSize(&p->vPat) <= Vec_IntSize(vLits) );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline char Min_LitIsImplied1( Min_Man_t * p, int iLit )
+{
+ char Val = 2;
+ int iLit0 = Min_LitFan(p, iLit);
+ int iLit1 = Min_LitFan(p, iLit^1);
+ char Val0 = Min_LitValL(p, iLit0);
+ char Val1 = Min_LitValL(p, iLit1);
+ assert( Min_LitIsNode(p, iLit) ); // internal node
+ assert( Min_LitValL(p, iLit) == 2 ); // unassigned
+ if ( Min_LitIsXor(iLit, iLit0, iLit1) )
+ Val = Min_XsimXor( Val0, Val1 );
+ else
+ Val = Min_XsimAnd( Val0, Val1 );
+ if ( Val < 2 )
+ {
+ Val ^= Abc_LitIsCompl(iLit);
+ Min_LitSetValL( p, iLit, Val );
+ }
+ return Val;
+}
+static inline char Min_LitIsImplied2( Min_Man_t * p, int iLit )
+{
+ char Val = 2;
+ int iLit0 = Min_LitFan(p, iLit);
+ int iLit1 = Min_LitFan(p, iLit^1);
+ char Val0 = Min_LitValL(p, iLit0);
+ char Val1 = Min_LitValL(p, iLit1);
+ assert( Min_LitIsNode(p, iLit) ); // internal node
+ assert( Min_LitValL(p, iLit) == 2 ); // unassigned
+ if ( Val0 == 2 && Min_LitIsNode(p, iLit0) )
+ Val0 = Min_LitIsImplied1(p, iLit0);
+ if ( Val1 == 2 && Min_LitIsNode(p, iLit1) )
+ Val1 = Min_LitIsImplied1(p, iLit1);
+ if ( Min_LitIsXor(iLit, iLit0, iLit1) )
+ Val = Min_XsimXor( Val0, Val1 );
+ else
+ Val = Min_XsimAnd( Val0, Val1 );
+ if ( Val < 2 )
+ {
+ Val ^= Abc_LitIsCompl(iLit);
+ Min_LitSetValL( p, iLit, Val );
+ }
+ return Val;
+}
+static inline char Min_LitIsImplied3( Min_Man_t * p, int iLit )
+{
+ char Val = 2;
+ int iLit0 = Min_LitFan(p, iLit);
+ int iLit1 = Min_LitFan(p, iLit^1);
+ char Val0 = Min_LitValL(p, iLit0);
+ char Val1 = Min_LitValL(p, iLit1);
+ assert( Min_LitIsNode(p, iLit) ); // internal node
+ assert( Min_LitValL(p, iLit) == 2 ); // unassigned
+ if ( Val0 == 2 && Min_LitIsNode(p, iLit0) )
+ Val0 = Min_LitIsImplied2(p, iLit0);
+ if ( Val1 == 2 && Min_LitIsNode(p, iLit1) )
+ Val1 = Min_LitIsImplied2(p, iLit1);
+ if ( Min_LitIsXor(iLit, iLit0, iLit1) )
+ Val = Min_XsimXor( Val0, Val1 );
+ else
+ Val = Min_XsimAnd( Val0, Val1 );
+ if ( Val < 2 )
+ {
+ Val ^= Abc_LitIsCompl(iLit);
+ Min_LitSetValL( p, iLit, Val );
+ }
+ return Val;
+}
+static inline char Min_LitIsImplied4( Min_Man_t * p, int iLit )
+{
+ char Val = 2;
+ int iLit0 = Min_LitFan(p, iLit);
+ int iLit1 = Min_LitFan(p, iLit^1);
+ char Val0 = Min_LitValL(p, iLit0);
+ char Val1 = Min_LitValL(p, iLit1);
+ assert( Min_LitIsNode(p, iLit) ); // internal node
+ assert( Min_LitValL(p, iLit) == 2 ); // unassigned
+ if ( Val0 == 2 && Min_LitIsNode(p, iLit0) )
+ Val0 = Min_LitIsImplied3(p, iLit0);
+ if ( Val1 == 2 && Min_LitIsNode(p, iLit1) )
+ Val1 = Min_LitIsImplied3(p, iLit1);
+ if ( Min_LitIsXor(iLit, iLit0, iLit1) )
+ Val = Min_XsimXor( Val0, Val1 );
+ else
+ Val = Min_XsimAnd( Val0, Val1 );
+ if ( Val < 2 )
+ {
+ Val ^= Abc_LitIsCompl(iLit);
+ Min_LitSetValL( p, iLit, Val );
+ }
+ return Val;
+}
+static inline char Min_LitIsImplied5( Min_Man_t * p, int iLit )
+{
+ char Val = 2;
+ int iLit0 = Min_LitFan(p, iLit);
+ int iLit1 = Min_LitFan(p, iLit^1);
+ char Val0 = Min_LitValL(p, iLit0);
+ char Val1 = Min_LitValL(p, iLit1);
+ assert( Min_LitIsNode(p, iLit) ); // internal node
+ assert( Min_LitValL(p, iLit) == 2 ); // unassigned
+ if ( Val0 == 2 && Min_LitIsNode(p, iLit0) )
+ Val0 = Min_LitIsImplied4(p, iLit0);
+ if ( Val1 == 2 && Min_LitIsNode(p, iLit1) )
+ Val1 = Min_LitIsImplied4(p, iLit1);
+ if ( Min_LitIsXor(iLit, iLit0, iLit1) )
+ Val = Min_XsimXor( Val0, Val1 );
+ else
+ Val = Min_XsimAnd( Val0, Val1 );
+ if ( Val < 2 )
+ {
+ Val ^= Abc_LitIsCompl(iLit);
+ Min_LitSetValL( p, iLit, Val );
+ }
+ return Val;
+}
+
+// this recursive procedure is about 10% slower
+char Min_LitIsImplied_rec( Min_Man_t * p, int iLit, int Depth )
+{
+ char Val = 2;
+ int iLit0 = Min_LitFan(p, iLit);
+ int iLit1 = Min_LitFan(p, iLit^1);
+ char Val0 = Min_LitValL(p, iLit0);
+ char Val1 = Min_LitValL(p, iLit1);
+ assert( Depth > 0 );
+ assert( Min_LitIsNode(p, iLit) ); // internal node
+ assert( Min_LitValL(p, iLit) == 2 ); // unassigned
+ if ( Depth > 1 && Val0 == 2 && Min_LitIsNode(p, iLit0) )
+ {
+ Val0 = Min_LitIsImplied_rec(p, iLit0, Depth-1);
+ Val1 = Min_LitValL(p, iLit1);
+ }
+ if ( Depth > 1 && Val1 == 2 && Min_LitIsNode(p, iLit1) )
+ {
+ Val1 = Min_LitIsImplied_rec(p, iLit1, Depth-1);
+ Val0 = Min_LitValL(p, iLit0);
+ }
+ if ( Min_LitIsXor(iLit, iLit0, iLit1) )
+ Val = Min_XsimXor( Val0, Val1 );
+ else
+ Val = Min_XsimAnd( Val0, Val1 );
+ if ( Val < 2 )
+ {
+ Val ^= Abc_LitIsCompl(iLit);
+ Min_LitSetValL( p, iLit, Val );
+ }
+ return Val;
+}
+int Min_LitJustify_rec( Min_Man_t * p, int iLit )
+{
+ int Res = 1, LitValue = !Abc_LitIsCompl(iLit);
+ int Val = (int)Min_LitValL(p, iLit);
+ if ( Val < 2 ) // assigned
+ return Val == LitValue;
+ // unassigned
+ if ( Min_LitIsCi(p, iLit) )
+ Vec_IntPush( &p->vPat, iLit ); // ms notation
+ else
+ {
+ int iLit0 = Min_LitFan(p, iLit);
+ int iLit1 = Min_LitFan(p, iLit^1);
+ char Val0 = Min_LitValL(p, iLit0);
+ char Val1 = Min_LitValL(p, iLit1);
+ if ( Min_LitIsXor(iLit, iLit0, iLit1) )
+ {
+ if ( Val0 < 2 && Val1 < 2 )
+ Res = LitValue == (Val0 ^ Val1);
+ else if ( Val0 < 2 )
+ Res = Min_LitJustify_rec(p, iLit1^Val0^!LitValue);
+ else if ( Val1 < 2 )
+ Res = Min_LitJustify_rec(p, iLit0^Val1^!LitValue);
+ else if ( Abc_Random(0) & 1 )
+ Res = Min_LitJustify_rec(p, iLit0) && Min_LitJustify_rec(p, iLit1^ LitValue);
+ else
+ Res = Min_LitJustify_rec(p, iLit0^1) && Min_LitJustify_rec(p, iLit1^!LitValue);
+ assert( !Res || LitValue == Min_XsimXor(Min_LitValL(p, iLit0), Min_LitValL(p, iLit1)) );
+ }
+ else if ( LitValue ) // value 1
+ {
+ if ( Val0 == 0 || Val1 == 0 )
+ Res = 0;
+ else if ( Val0 == 1 && Val1 == 1 )
+ Res = 1;
+ else if ( Val0 == 1 )
+ Res = Min_LitJustify_rec(p, iLit1);
+ else if ( Val1 == 1 )
+ Res = Min_LitJustify_rec(p, iLit0);
+ else
+ Res = Min_LitJustify_rec(p, iLit0) && Min_LitJustify_rec(p, iLit1);
+ assert( !Res || 1 == Min_XsimAnd(Min_LitValL(p, iLit0), Min_LitValL(p, iLit1)) );
+ }
+ else // value 0
+ {
+/*
+ int Depth = 3;
+ if ( Val0 == 2 && Min_LitIsNode(p, iLit0) )
+ {
+ Val0 = Min_LitIsImplied_rec(p, iLit0, Depth);
+ Val1 = Min_LitValL(p, iLit1);
+ }
+ if ( Val1 == 2 && Min_LitIsNode(p, iLit1) )
+ {
+ Val1 = Min_LitIsImplied_rec(p, iLit1, Depth);
+ Val0 = Min_LitValL(p, iLit0);
+ }
+*/
+ if ( Val0 == 2 && Min_LitIsNode(p, iLit0) )
+ {
+ Val0 = Min_LitIsImplied3(p, iLit0);
+ Val1 = Min_LitValL(p, iLit1);
+ }
+ if ( Val1 == 2 && Min_LitIsNode(p, iLit1) )
+ {
+ Val1 = Min_LitIsImplied3(p, iLit1);
+ Val0 = Min_LitValL(p, iLit0);
+ }
+ if ( Val0 == 0 || Val1 == 0 )
+ Res = 1;
+ else if ( Val0 == 1 && Val1 == 1 )
+ Res = 0;
+ else if ( Val0 == 1 )
+ Res = Min_LitJustify_rec(p, iLit1^1);
+ else if ( Val1 == 1 )
+ Res = Min_LitJustify_rec(p, iLit0^1);
+ else if ( Abc_Random(0) & 1 )
+ //else if ( (p->Random >> (iLit & 0x1F)) & 1 )
+ Res = Min_LitJustify_rec(p, iLit0^1);
+ else
+ Res = Min_LitJustify_rec(p, iLit1^1);
+ //Val0 = Min_LitValL(p, iLit0);
+ //Val1 = Min_LitValL(p, iLit1);
+ assert( !Res || 0 == Min_XsimAnd(Min_LitValL(p, iLit0), Min_LitValL(p, iLit1)) );
+ }
+ }
+ if ( Res )
+ Min_LitSetValL( p, iLit, 1 );
+ return Res;
+}
+int Min_LitJustify( Min_Man_t * p, int iLit )
+{
+ int Res, fCheck = 0;
+ Vec_IntClear( &p->vPat );
+ if ( iLit < 2 ) return 1;
+ assert( !Min_LitIsCo(p, iLit) );
+ //assert( Min_ManCheckCleanValsL(p) );
+ assert( Vec_IntSize(&p->vVis) == 0 );
+ //p->Random = Abc_Random(0);
+ Res = Min_LitJustify_rec( p, iLit );
+ Min_ManCleanVisitedValL( p );
+ if ( Res )
+ {
+ if ( fCheck && Min_LitVerify(p, iLit, &p->vPat) != 1 )
+ printf( "Verification FAILED for literal %d.\n", iLit );
+ //else
+ // printf( "Verification succeeded for literal %d.\n", iLit );
+ }
+ //else
+ // printf( "Could not justify literal %d.\n", iLit );
+ return Res;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Min_TargGenerateCexes( Min_Man_t * p, Vec_Int_t * vCoErrs, int nCexes, int nCexesStop, int * pnComputed, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ int t, iObj, Count = 0, CountPos = 0, CountPosSat = 0, nRuns[2] = {0}, nCountCexes[2] = {0};
+ Vec_Int_t * vPats = Vec_IntAlloc( 1000 );
+ Vec_Int_t * vPatBest = Vec_IntAlloc( Min_ManCiNum(p) );
+ Hsh_VecMan_t * pHash = Hsh_VecManStart( 10000 );
+ Min_ManForEachCo( p, iObj ) if ( Min_ObjLit0(p, iObj) > 1 )
+ {
+ int nCexesGenSim0 = 0;
+ int nCexesGenSim = 0;
+ int nCexesGenSat = 0;
+ if ( vCoErrs && Vec_IntEntry(vCoErrs, Min_ObjCioId(p, iObj)) >= nCexesStop )
+ continue;
+ //printf( "%d ", i );
+ for ( t = 0; t < nCexes; t++ )
+ {
+ nRuns[0]++;
+ if ( Min_LitJustify( p, Min_ObjLit0(p, iObj) ) )
+ {
+ int Before, After;
+ assert( Vec_IntSize(&p->vPat) > 0 );
+ //printf( "%d ", Vec_IntSize(vPat) );
+ Vec_IntClear( vPatBest );
+ if ( 1 ) // no minimization
+ Vec_IntAppend( vPatBest, &p->vPat );
+ else
+ {
+/*
+ for ( k = 0; k < 10; k++ )
+ {
+ Vec_IntClear( vPat2 );
+ Gia_ManIncrementTravId( p );
+ Cexes_MinimizePattern_rec( p, Gia_ObjFanin0(pObj), !Gia_ObjFaninC0(pObj), vPat2 );
+ assert( Vec_IntSize(vPat2) <= Vec_IntSize(vPat) );
+ if ( Vec_IntSize(vPatBest) == 0 || Vec_IntSize(vPatBest) > Vec_IntSize(vPat2) )
+ {
+ Vec_IntClear( vPatBest );
+ Vec_IntAppend( vPatBest, vPat2 );
+ }
+ //printf( "%d ", Vec_IntSize(vPat2) );
+ }
+*/
+ }
+
+ //Gia_CexVerify( p, Gia_ObjFaninId0p(p, pObj), !Gia_ObjFaninC0(pObj), vPatBest );
+ //printf( "\n" );
+ Before = Hsh_VecSize( pHash );
+ Vec_IntSort( vPatBest, 0 );
+ Hsh_VecManAdd( pHash, vPatBest );
+ After = Hsh_VecSize( pHash );
+ if ( Before != After )
+ {
+ Vec_IntPush( vPats, Min_ObjCioId(p, iObj) );
+ Vec_IntPush( vPats, Vec_IntSize(vPatBest) );
+ Vec_IntAppend( vPats, vPatBest );
+ nCexesGenSim++;
+ }
+ nCexesGenSim0++;
+ if ( nCexesGenSim0 > nCexesGenSim*10 )
+ {
+ printf( "**** Skipping output %d (out of %d)\n", Min_ObjCioId(p, iObj), Min_ManCoNum(p) );
+ break;
+ }
+ }
+ if ( nCexesGenSim == nCexesStop )
+ break;
+ }
+ //printf( "(%d %d) ", nCexesGenSim0, nCexesGenSim );
+ //printf( "%d ", t/nCexesGenSim );
+
+ //printf( "The number of CEXes = %d\n", nCexesGen );
+ //if ( fVerbose )
+ // printf( "%d ", nCexesGen );
+ nCountCexes[0] += nCexesGenSim;
+ nCountCexes[1] += nCexesGenSat;
+ Count += nCexesGenSim + nCexesGenSat;
+ CountPos++;
+
+ if ( nCexesGenSim0 == 0 && t == nCexes )
+ printf( "#### Output %d (out of %d)\n", Min_ObjCioId(p, iObj), Min_ManCoNum(p) );
+ }
+ //printf( "\n" );
+ if ( fVerbose )
+ printf( "\n" );
+ if ( fVerbose )
+ printf( "Got %d unique CEXes using %d sim (%d) and %d SAT (%d) runs (ave size %.1f). PO = %d ErrPO = %d SatPO = %d ",
+ Count, nRuns[0], nCountCexes[0], nRuns[1], nCountCexes[1],
+ 1.0*Vec_IntSize(vPats)/Abc_MaxInt(1, Count)-2, Min_ManCoNum(p), CountPos, CountPosSat );
+ if ( fVerbose )
+ Abc_PrintTime( 0, "Time", Abc_Clock() - clk );
+ Hsh_VecManStop( pHash );
+ Vec_IntFree( vPatBest );
+ *pnComputed = Count;
+ return vPats;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Min_ManTest3( Gia_Man_t * p, Vec_Int_t * vCoErrs )
+{
+ int fXor = 0;
+ int nComputed;
+ Vec_Int_t * vPats;
+ Gia_Man_t * pXor = fXor ? Gia_ManDupMuxes(p, 1) : NULL;
+ Min_Man_t * pNew = Min_ManFromGia( fXor ? pXor : p, NULL );
+ Gia_ManStopP( &pXor );
+ Min_ManStartValsL( pNew );
+ //Vec_IntFill( vCoErrs, Vec_IntSize(vCoErrs), 0 );
+ //vPats = Min_TargGenerateCexes( pNew, vCoErrs, 10000, 10, &nComputed, 1 );
+ vPats = Min_TargGenerateCexes( pNew, vCoErrs, 10000, 10, &nComputed, 1 );
+ Vec_IntFree( vPats );
+ Min_ManStop( pNew );
+}
+void Min_ManTest4( Gia_Man_t * p )
+{
+ Vec_Int_t * vCoErrs = Vec_IntStartNatural( Gia_ManCoNum(p) );
+ Min_ManTest3(p, vCoErrs);
+ Vec_IntFree( vCoErrs );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManDupCones2CollectPis_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vMap )
+{
+ Gia_Obj_t * pObj;
+ if ( Gia_ObjUpdateTravIdCurrentId(p, iObj) )
+ return;
+ pObj = Gia_ManObj( p, iObj );
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ Gia_ManDupCones2CollectPis_rec( p, Gia_ObjFaninId0(pObj, iObj), vMap );
+ Gia_ManDupCones2CollectPis_rec( p, Gia_ObjFaninId1(pObj, iObj), vMap );
+ }
+ else if ( Gia_ObjIsCi(pObj) )
+ Vec_IntPush( vMap, iObj );
+ else assert( 0 );
+}
+void Gia_ManDupCones2_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( Gia_ObjIsCi(pObj) || Gia_ObjUpdateTravIdCurrent(p, pObj) )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManDupCones2_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Gia_ManDupCones2_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+Gia_Man_t * Gia_ManDupCones2( Gia_Man_t * p, int * pOuts, int nOuts, Vec_Int_t * vMap )
+{
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj; int i;
+ Vec_IntClear( vMap );
+ Gia_ManIncrementTravId( p );
+ for ( i = 0; i < nOuts; i++ )
+ Gia_ManDupCones2CollectPis_rec( p, Gia_ManCoDriverId(p, pOuts[i]), vMap );
+ pNew = Gia_ManStart( 1000 );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachObjVec( vMap, p, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ Gia_ManIncrementTravId( p );
+ for ( i = 0; i < nOuts; i++ )
+ Gia_ManDupCones2_rec( pNew, p, Gia_ObjFanin0(Gia_ManCo(p, pOuts[i])) );
+ for ( i = 0; i < nOuts; i++ )
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(Gia_ManCo(p, pOuts[i])) );
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Min_ManRemoveItem( Vec_Wec_t * vCexes, int iItem, int iFirst, int iLimit )
+{
+ Vec_Int_t * vLevel, * vLevel0 = Vec_WecEntry(vCexes, iItem); int i;
+ assert( iFirst <= iItem && iItem < iLimit );
+ Vec_WecForEachLevelReverseStartStop( vCexes, vLevel, i, iLimit, iFirst )
+ if ( Vec_IntSize(vLevel) > 0 )
+ break;
+ assert( iFirst <= i && iItem <= i );
+ Vec_IntClear( vLevel0 );
+ if ( iItem < i )
+ ABC_SWAP( Vec_Int_t, *vLevel0, *vLevel );
+ return -1;
+}
+int Min_ManAccumulate( Vec_Wec_t * vCexes, int iFirst, int iLimit, Vec_Int_t * vCex )
+{
+ Vec_Int_t * vLevel; int i, nCommon, nDiff = 0;
+ Vec_WecForEachLevelStartStop( vCexes, vLevel, i, iFirst, iLimit )
+ {
+ if ( Vec_IntSize(vLevel) == 0 )
+ {
+ Vec_IntAppend(vLevel, vCex);
+ return nDiff+1;
+ }
+ nCommon = Vec_IntTwoCountCommon( vLevel, vCex );
+ if ( nCommon == Vec_IntSize(vLevel) ) // ignore vCex
+ return nDiff;
+ if ( nCommon == Vec_IntSize(vCex) ) // remove vLevel
+ nDiff += Min_ManRemoveItem( vCexes, i, iFirst, iLimit );
+ }
+ assert( 0 );
+ return ABC_INFINITY;
+}
+int Min_ManCountSize( Vec_Wec_t * vCexes, int iFirst, int iLimit )
+{
+ Vec_Int_t * vLevel; int i, nTotal = 0;
+ Vec_WecForEachLevelStartStop( vCexes, vLevel, i, iFirst, iLimit )
+ nTotal += Vec_IntSize(vLevel) > 0;
+ return nTotal;
+}
+Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTries, int nMinCexes, Vec_Int_t * vStats[3], int fUseSim, int fUseSat, int fVerbose )
+{
+ Vec_Int_t * vOuts = vOuts0 ? vOuts0 : Vec_IntStartNatural( Gia_ManCoNum(p) );
+ Min_Man_t * pNew = Min_ManFromGia( p, vOuts );
+ Vec_Wec_t * vCexes = Vec_WecStart( Vec_IntSize(vOuts) * nMinCexes );
+ Vec_Int_t * vPatBest = Vec_IntAlloc( 100 );
+ Vec_Int_t * vLits = Vec_IntAlloc( 100 );
+ Gia_Obj_t * pObj; int i, iObj, nOuts = 0, nSimOuts = 0, nSatOuts = 0;
+ vStats[0] = Vec_IntAlloc( Vec_IntSize(vOuts) ); // total calls
+ vStats[1] = Vec_IntAlloc( Vec_IntSize(vOuts) ); // successful calls + SAT runs
+ vStats[2] = Vec_IntAlloc( Vec_IntSize(vOuts) ); // results
+ Min_ManStartValsL( pNew );
+ Min_ManForEachCo( pNew, iObj )
+ {
+ int nAllCalls = 0;
+ int nGoodCalls = 0;
+ int nCurrCexes = 0;
+ if ( fUseSim && Min_ObjLit0(pNew, iObj) >= 2 )
+ {
+ while ( nAllCalls++ < nMaxTries )
+ {
+ if ( Min_LitJustify( pNew, Min_ObjLit0(pNew, iObj) ) )
+ {
+ Vec_IntClearAppend( vLits, &pNew->vPat );
+ Vec_IntClearAppend( vPatBest, &pNew->vPat );
+ if ( 1 ) // minimization
+ {
+ //printf( "%d -> ", Vec_IntSize(vPatBest) );
+ for ( i = 0; i < 20; i++ )
+ {
+ Min_LitMinimize( pNew, Min_ObjLit0(pNew, iObj), vLits );
+ if ( Vec_IntSize(vPatBest) > Vec_IntSize(&pNew->vPat) )
+ Vec_IntClearAppend( vPatBest, &pNew->vPat );
+ }
+ //printf( "%d ", Vec_IntSize(vPatBest) );
+ }
+ assert( Vec_IntSize(vPatBest) > 0 );
+ Vec_IntSort( vPatBest, 0 );
+ nCurrCexes += Min_ManAccumulate( vCexes, nOuts*nMinCexes, (nOuts+1)*nMinCexes, vPatBest );
+ nGoodCalls++;
+ }
+ if ( nCurrCexes == nMinCexes || nGoodCalls > 10*nCurrCexes )
+ break;
+ }
+ nSimOuts++;
+ }
+ assert( nCurrCexes <= nMinCexes );
+ assert( nCurrCexes == Min_ManCountSize(vCexes, nOuts*nMinCexes, (nOuts+1)*nMinCexes) );
+ Vec_IntPush( vStats[0], nAllCalls );
+ Vec_IntPush( vStats[1], nGoodCalls );
+ Vec_IntPush( vStats[2], nCurrCexes );
+ nOuts++;
+ }
+ assert( Vec_IntSize(vOuts) == nOuts );
+ assert( Vec_IntSize(vOuts) == Vec_IntSize(vStats[0]) );
+ assert( Vec_IntSize(vOuts) == Vec_IntSize(vStats[1]) );
+ assert( Vec_IntSize(vOuts) == Vec_IntSize(vStats[2]) );
+
+ if ( fUseSat )
+ Gia_ManForEachCoVec( vOuts, p, pObj, i )
+ {
+ if ( Vec_IntEntry(vStats[2], i) >= nMinCexes || Vec_IntEntry(vStats[1], i) > 10*Vec_IntEntry(vStats[2], i) )
+ continue;
+ {
+ int iObj = Min_ManCo(pNew, i);
+ int Index = Gia_ObjCioId(pObj);
+ Vec_Int_t * vMap = Vec_IntAlloc( 100 );
+ Gia_Man_t * pCon = Gia_ManDupCones2( p, &Index, 1, vMap );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pCon, 8, 0, 0, 0, 0 );
+ sat_solver* pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
+ int Lit = Abc_Var2Lit( 1, 0 );
+ int status = sat_solver_addclause( pSat, &Lit, &Lit+1 );
+ int nAllCalls = 0;
+ int nCurrCexes = Vec_IntEntry(vStats[2], i);
+ //Gia_AigerWrite( pCon, "temp_miter.aig", 0, 0, 0 );
+ if ( status == l_True )
+ {
+ nSatOuts++;
+ //printf( "Running SAT for output %d\n", i );
+ if ( Min_ObjLit0(pNew, iObj) >= 2 )
+ {
+ while ( nAllCalls++ < 100 )
+ {
+ int v, iVar = pCnf->nVars - Gia_ManPiNum(pCon), nVars = Gia_ManPiNum(pCon);
+ sat_solver_randomize( pSat, iVar, nVars );
+ status = sat_solver_solve( pSat, NULL, NULL, 0, 0, 0, 0 );
+ assert( status == l_True );
+ Vec_IntClear( vLits );
+ for ( v = 0; v < nVars; v++ )
+ Vec_IntPush( vLits, Abc_Var2Lit(Vec_IntEntry(vMap, v), !sat_solver_var_value(pSat, iVar + v)) );
+ Min_LitMinimize( pNew, Min_ObjLit0(pNew, iObj), vLits );
+ Vec_IntClearAppend( vPatBest, &pNew->vPat );
+ if ( 1 ) // minimization
+ {
+ //printf( "%d -> ", Vec_IntSize(vPatBest) );
+ for ( v = 0; v < 20; v++ )
+ {
+ Min_LitMinimize( pNew, Min_ObjLit0(pNew, iObj), vLits );
+ if ( Vec_IntSize(vPatBest) > Vec_IntSize(&pNew->vPat) )
+ Vec_IntClearAppend( vPatBest, &pNew->vPat );
+ }
+ //printf( "%d ", Vec_IntSize(vPatBest) );
+ }
+ Vec_IntSort( vPatBest, 0 );
+ nCurrCexes += Min_ManAccumulate( vCexes, i*nMinCexes, (i+1)*nMinCexes, vPatBest );
+ if ( nCurrCexes == nMinCexes || nAllCalls > 10*nCurrCexes )
+ break;
+ }
+ }
+ }
+ Vec_IntWriteEntry( vStats[0], i, nAllCalls*nMaxTries );
+ Vec_IntWriteEntry( vStats[1], i, nAllCalls*nMaxTries );
+ Vec_IntWriteEntry( vStats[2], i, nCurrCexes );
+ sat_solver_delete( pSat );
+ Cnf_DataFree( pCnf );
+ Gia_ManStop( pCon );
+ Vec_IntFree( vMap );
+ }
+ }
+ if ( fVerbose )
+ printf( "Used simulation for %d and SAT for %d outputs (out of %d).\n", nSimOuts, nSatOuts, nOuts );
+ //Vec_WecPrint( vCexes, 0 );
+ if ( vOuts != vOuts0 )
+ Vec_IntFreeP( &vOuts );
+ Min_ManStop( pNew );
+ Vec_IntFree( vPatBest );
+ Vec_IntFree( vLits );
+ return vCexes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Bit-packing for selected patterns.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Min_ManBitPackTry( Vec_Wrd_t * vSimsPi, int nWords, int iPat, Vec_Int_t * vLits )
+{
+ int i, Lit;
+ assert( iPat >= 0 && iPat < 64 * nWords );
+ Vec_IntForEachEntry( vLits, Lit, i )
+ {
+ word * pInfo = Vec_WrdEntryP( vSimsPi, nWords * Abc_Lit2Var(Lit-2) ); // Lit is based on ObjId
+ word * pCare = pInfo + Vec_WrdSize(vSimsPi);
+ if ( Abc_InfoHasBit( (unsigned *)pCare, iPat ) &&
+ Abc_InfoHasBit( (unsigned *)pInfo, iPat ) == Abc_LitIsCompl(Lit) ) // Lit is in ms notation
+ return 0;
+ }
+ Vec_IntForEachEntry( vLits, Lit, i )
+ {
+ word * pInfo = Vec_WrdEntryP( vSimsPi, nWords * Abc_Lit2Var(Lit-2) ); // Lit is based on ObjId
+ word * pCare = pInfo + Vec_WrdSize(vSimsPi);
+ Abc_InfoSetBit( (unsigned *)pCare, iPat );
+ if ( Abc_InfoHasBit( (unsigned *)pInfo, iPat ) == Abc_LitIsCompl(Lit) ) // Lit is in ms notation
+ Abc_InfoXorBit( (unsigned *)pInfo, iPat );
+ }
+ return 1;
+}
+int Min_ManBitPackOne( Vec_Wrd_t * vSimsPi, int iPat0, int nWords, Vec_Int_t * vLits )
+{
+ int iPat, nTotal = 64*nWords;
+ for ( iPat = iPat0 + 1; iPat != iPat0; iPat = (iPat + 1) % nTotal )
+ if ( Min_ManBitPackTry( vSimsPi, nWords, iPat, vLits ) )
+ break;
+ return iPat;
+}
+Vec_Ptr_t * Min_ReloadCexes( Vec_Wec_t * vCexes, int nMinCexes )
+{
+ Vec_Ptr_t * vRes = Vec_PtrAlloc( Vec_WecSize(vCexes) );
+ int i, c, nOuts = Vec_WecSize(vCexes)/nMinCexes;
+ for ( i = 0; i < nMinCexes; i++ )
+ for ( c = 0; c < nOuts; c++ )
+ {
+ Vec_Int_t * vLevel = Vec_WecEntry( vCexes, c*nMinCexes+i );
+ if ( Vec_IntSize(vLevel) )
+ Vec_PtrPush( vRes, vLevel );
+ }
+ return vRes;
+}
+
+Vec_Wrd_t * Min_ManBitPack( Gia_Man_t * p, int nWords0, Vec_Wec_t * vCexes, int fRandom, int nMinCexes, Vec_Int_t * vScores, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ int fVeryVerbose = 0;
+ Vec_Wrd_t * vSimsPi = NULL;
+ Vec_Int_t * vLevel;
+ int w, nBits, nTotal = 0, fFailed = ABC_INFINITY;
+ Vec_Int_t * vOrder = NULL;
+ Vec_Ptr_t * vReload = NULL;
+ if ( 0 )
+ {
+ vOrder = Vec_IntStartNatural( Vec_WecSize(vCexes)/nMinCexes );
+ assert( Vec_IntSize(vOrder) == Vec_IntSize(vScores) );
+ assert( Vec_WecSize(vCexes)%nMinCexes == 0 );
+ Abc_MergeSortCost2Reverse( Vec_IntArray(vOrder), Vec_IntSize(vOrder), Vec_IntArray(vScores) );
+ }
+ else
+ vReload = Min_ReloadCexes( vCexes, nMinCexes );
+ if ( fVerbose )
+ printf( "Packing: " );
+ for ( w = nWords0 ? nWords0 : 1; nWords0 ? w <= nWords0 : fFailed > 0; w++ )
+ {
+ int i, iPatUsed, iPat = 0;
+ //int k, iOut;
+ Vec_WrdFreeP( &vSimsPi );
+ vSimsPi = fRandom ? Vec_WrdStartRandom(2 * Gia_ManCiNum(p) * w) : Vec_WrdStart(2 * Gia_ManCiNum(p) * w);
+ Vec_WrdShrink( vSimsPi, Vec_WrdSize(vSimsPi)/2 );
+ Abc_TtClear( Vec_WrdLimit(vSimsPi), Vec_WrdSize(vSimsPi) );
+ fFailed = nTotal = 0;
+ //Vec_IntForEachEntry( vOrder, iOut, k )
+ //Vec_WecForEachLevelStartStop( vCexes, vLevel, i, iOut*nMinCexes, (iOut+1)*nMinCexes )
+ Vec_PtrForEachEntry( Vec_Int_t *, vReload, vLevel, i )
+ {
+ //if ( fVeryVerbose && i%nMinCexes == 0 )
+ // printf( "\n" );
+ if ( Vec_IntSize(vLevel) == 0 )
+ continue;
+ iPatUsed = Min_ManBitPackOne( vSimsPi, iPat, w, vLevel );
+ fFailed += iPatUsed == iPat;
+ iPat = (iPatUsed + 1) % (64*(w-1) - 1);
+ //if ( fVeryVerbose )
+ //printf( "Adding output %3d cex %3d to pattern %3d ", i/nMinCexes, i%nMinCexes, iPatUsed );
+ //if ( fVeryVerbose )
+ //Vec_IntPrint( vLevel );
+ nTotal++;
+ }
+ if ( fVerbose )
+ printf( "W = %d (F = %d) ", w, fFailed );
+// printf( "Failed patterns = %d\n", fFailed );
+ }
+ if ( fVerbose )
+ printf( "Total = %d\n", nTotal );
+ if ( fVerbose )
+ {
+ nBits = Abc_TtCountOnesVec( Vec_WrdLimit(vSimsPi), Vec_WrdSize(vSimsPi) );
+ printf( "Bit-packing is using %d words and %d bits. Density =%8.4f %%. ",
+ Vec_WrdSize(vSimsPi)/Gia_ManCiNum(p), nBits, 100.0*nBits/64/Vec_WrdSize(vSimsPi) );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ }
+ Vec_IntFreeP( &vOrder );
+ Vec_PtrFreeP( &vReload );
+ return vSimsPi;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Patt_ManOutputErrorCoverage( Vec_Wrd_t * vErrors, int nOuts )
+{
+ Vec_Int_t * vCounts = Vec_IntAlloc( nOuts );
+ int i, nWords = Vec_WrdSize(vErrors)/nOuts;
+ assert( Vec_WrdSize(vErrors) == nOuts * nWords );
+ for ( i = 0; i < nOuts; i++ )
+ Vec_IntPush( vCounts, Abc_TtCountOnesVec(Vec_WrdEntryP(vErrors, nWords * i), nWords) );
+ return vCounts;
+}
+Vec_Wrd_t * Patt_ManTransposeErrors( Vec_Wrd_t * vErrors, int nOuts )
+{
+ extern void Extra_BitMatrixTransposeP( Vec_Wrd_t * vSimsIn, int nWordsIn, Vec_Wrd_t * vSimsOut, int nWordsOut );
+ int nWordsIn = Vec_WrdSize(vErrors) / nOuts;
+ int nWordsOut = Abc_Bit6WordNum(nOuts);
+ Vec_Wrd_t * vSims1 = Vec_WrdStart( 64*nWordsIn*nWordsOut );
+ Vec_Wrd_t * vSims2 = Vec_WrdStart( 64*nWordsIn*nWordsOut );
+ assert( Vec_WrdSize(vErrors) == nWordsIn * nOuts );
+ Abc_TtCopy( Vec_WrdArray(vSims1), Vec_WrdArray(vErrors), Vec_WrdSize(vErrors), 0 );
+ Extra_BitMatrixTransposeP( vSims1, nWordsIn, vSims2, nWordsOut );
+ Vec_WrdFree( vSims1 );
+ return vSims2;
+}
+Vec_Int_t * Patt_ManPatternErrorCoverage( Vec_Wrd_t * vErrors, int nOuts )
+{
+ int nWords = Vec_WrdSize(vErrors)/nOuts;
+ Vec_Wrd_t * vErrors2 = Patt_ManTransposeErrors( vErrors, nOuts );
+ Vec_Int_t * vPatErrs = Patt_ManOutputErrorCoverage( vErrors2, 64*nWords );
+ Vec_WrdFree( vErrors2 );
+ return vPatErrs;
+}
+
+#define ERR_REPT_SIZE 32
+void Patt_ManProfileErrors( Vec_Int_t * vOutErrs, Vec_Int_t * vPatErrs )
+{
+ int nOuts = Vec_IntSize(vOutErrs);
+ int nPats = Vec_IntSize(vPatErrs);
+ int ErrOuts[ERR_REPT_SIZE+1] = {0};
+ int ErrPats[ERR_REPT_SIZE+1] = {0};
+ int i, Errs, nErrors1 = 0, nErrors2 = 0;
+ Vec_IntForEachEntry( vOutErrs, Errs, i )
+ {
+ nErrors1 += Errs;
+ ErrOuts[Errs < ERR_REPT_SIZE ? Errs : ERR_REPT_SIZE]++;
+ }
+ Vec_IntForEachEntry( vPatErrs, Errs, i )
+ {
+ nErrors2 += Errs;
+ ErrPats[Errs < ERR_REPT_SIZE ? Errs : ERR_REPT_SIZE]++;
+ }
+ assert( nErrors1 == nErrors2 );
+ // errors/error_outputs/error_patterns
+ //printf( "\nError statistics:\n" );
+ printf( "Errors =%6d ", nErrors1 );
+ printf( "ErrPOs =%5d (Ave = %5.2f) ", nOuts-ErrOuts[0], 1.0*nErrors1/Abc_MaxInt(1, nOuts-ErrOuts[0]) );
+ printf( "Patterns =%5d (Ave = %5.2f) ", nPats, 1.0*nErrors1/nPats );
+ printf( "Density =%8.4f %%\n", 100.0*nErrors1/nPats/Abc_MaxInt(1, nOuts-ErrOuts[0]) );
+ // how many times each output fails
+ printf( "Outputs: " );
+ for ( i = 0; i <= ERR_REPT_SIZE; i++ )
+ if ( ErrOuts[i] )
+ printf( "%s%d=%d ", i == ERR_REPT_SIZE? ">" : "", i, ErrOuts[i] );
+ printf( "\n" );
+ // how many times each patterns fails an output
+ printf( "Patterns: " );
+ for ( i = 0; i <= ERR_REPT_SIZE; i++ )
+ if ( ErrPats[i] )
+ printf( "%s%d=%d ", i == ERR_REPT_SIZE? ">" : "", i, ErrPats[i] );
+ printf( "\n" );
+}
+int Patt_ManProfileErrorsOne( Vec_Wrd_t * vErrors, int nOuts )
+{
+ Vec_Int_t * vCoErrs = Patt_ManOutputErrorCoverage( vErrors, nOuts );
+ Vec_Int_t * vPatErrs = Patt_ManPatternErrorCoverage( vErrors, nOuts );
+ Patt_ManProfileErrors( vCoErrs, vPatErrs );
+ Vec_IntFree( vPatErrs );
+ Vec_IntFree( vCoErrs );
+ return 1;
+}
+
+Vec_Int_t * Min_ManGetUnsolved( Gia_Man_t * p )
+{
+ Vec_Int_t * vRes = Vec_IntAlloc( 100 );
+ int i, Driver;
+ Gia_ManForEachCoDriverId( p, Driver, i )
+ if ( Driver > 0 )
+ Vec_IntPush( vRes, i );
+ if ( Vec_IntSize(vRes) == 0 )
+ Vec_IntFreeP( &vRes );
+ return vRes;
+}
+Vec_Wrd_t * Min_ManRemapSims( int nInputs, Vec_Int_t * vMap, Vec_Wrd_t * vSimsPi )
+{
+ int i, iObj, nWords = Vec_WrdSize(vSimsPi)/Vec_IntSize(vMap);
+ Vec_Wrd_t * vSimsNew = Vec_WrdStart( 2 * nInputs * nWords );
+ //Vec_Wrd_t * vSimsNew = Vec_WrdStartRandom( nInputs * nWords );
+ //Vec_WrdFillExtra( vSimsNew, 2 * nInputs * nWords, 0 );
+ assert( Vec_WrdSize(vSimsPi)%Vec_IntSize(vMap) == 0 );
+ Vec_WrdShrink( vSimsNew, Vec_WrdSize(vSimsNew)/2 );
+ Vec_IntForEachEntry( vMap, iObj, i )
+ {
+ Abc_TtCopy( Vec_WrdArray(vSimsNew) + (iObj-1)*nWords, Vec_WrdArray(vSimsPi) + i*nWords, nWords, 0 );
+ Abc_TtCopy( Vec_WrdLimit(vSimsNew) + (iObj-1)*nWords, Vec_WrdLimit(vSimsPi) + i*nWords, nWords, 0 );
+ }
+ return vSimsNew;
+}
+Vec_Wrd_t * Gia_ManCollectSims( Gia_Man_t * pSwp, int nWords, Vec_Int_t * vOuts, int nMaxTries, int nMinCexes, int fUseSim, int fUseSat, int fVerbose, int fVeryVerbose )
+{
+ Vec_Int_t * vStats[3] = {0}; int i, iObj;
+ Vec_Int_t * vMap = Vec_IntAlloc( 100 );
+ Gia_Man_t * pSwp2 = Gia_ManDupCones2( pSwp, Vec_IntArray(vOuts), Vec_IntSize(vOuts), vMap );
+ Vec_Wec_t * vCexes = Min_ManComputeCexes( pSwp2, NULL, nMaxTries, nMinCexes, vStats, fUseSim, fUseSat, fVerbose );
+ Vec_Wrd_t * vSimsPi = Min_ManBitPack( pSwp2, nWords, vCexes, 1, nMinCexes, vStats[0], fVerbose );
+ Vec_Wrd_t * vSimsPo = Gia_ManSimPatSimOut( pSwp2, vSimsPi, 1 );
+ Vec_Int_t * vCounts = Patt_ManOutputErrorCoverage( vSimsPo, Vec_IntSize(vOuts) );
+ if ( fVerbose )
+ Patt_ManProfileErrorsOne( vSimsPo, Vec_IntSize(vOuts) );
+ if ( fVeryVerbose )
+ {
+ printf( "Unsolved = %4d ", Vec_IntSize(vOuts) );
+ Gia_ManPrintStats( pSwp2, NULL );
+ Vec_IntForEachEntry( vOuts, iObj, i )
+ {
+ printf( "%4d : ", i );
+ printf( "Out = %5d ", Vec_IntEntry(vMap, i) );
+ printf( "SimAll =%8d ", Vec_IntEntry(vStats[0], i) );
+ printf( "SimGood =%8d ", Vec_IntEntry(vStats[1], i) );
+ printf( "PatsAll =%8d ", Vec_IntEntry(vStats[2], i) );
+ printf( "Count = %5d ", Vec_IntEntry(vCounts, i) );
+ printf( "\n" );
+ if ( i == 20 )
+ break;
+ }
+ }
+ for ( i = 0; i < 3; i++ )
+ Vec_IntFree( vStats[i] );
+ Vec_IntFree( vCounts );
+ Vec_WrdFree( vSimsPo );
+ Vec_WecFree( vCexes );
+ Gia_ManStop( pSwp2 );
+ //printf( "Compressing inputs: %5d -> %5d\n", Gia_ManCiNum(pSwp), Vec_IntSize(vMap) );
+ vSimsPi = Min_ManRemapSims( Gia_ManCiNum(pSwp), vMap, vSimsPo = vSimsPi );
+ Vec_WrdFree( vSimsPo );
+ Vec_IntFree( vMap );
+ return vSimsPi;
+}
+Vec_Wrd_t * Min_ManCollect( Gia_Man_t * p, int nConf, int nConf2, int nMaxTries, int nMinCexes, int fUseSim, int fUseSat, int fVerbose, int fVeryVerbose )
+{
+ abctime clk = Abc_Clock();
+ extern Gia_Man_t * Cec4_ManSimulateTest4( Gia_Man_t * p, int nBTLimit, int nBTLimitPo, int fVerbose );
+ Gia_Man_t * pSwp = Cec4_ManSimulateTest4( p, nConf, nConf2, 0 );
+ abctime clkSweep = Abc_Clock() - clk;
+ int nArgs = fVerbose ? printf( "Generating patterns: Conf = %d (%d). Tries = %d. Pats = %d. Sim = %d. SAT = %d.\n",
+ nConf, nConf2, nMaxTries, nMinCexes, fUseSim, fUseSat ) : 0;
+ Vec_Int_t * vOuts = Min_ManGetUnsolved( pSwp );
+ Vec_Wrd_t * vSimsPi = vOuts ? Gia_ManCollectSims( pSwp, 0, vOuts, nMaxTries, nMinCexes, fUseSim, fUseSat, fVerbose, fVeryVerbose ) : NULL;
+ if ( vOuts == NULL )
+ printf( "There is no satisfiable outputs.\n" );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Sweep time", clkSweep );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Total time", Abc_Clock() - clk );
+ Vec_IntFreeP( &vOuts );
+ Gia_ManStop( pSwp );
+ nArgs = 0;
+ return vSimsPi;
+}
+void Min_ManTest2( Gia_Man_t * p )
+{
+ Vec_Wrd_t * vSimsPi = Min_ManCollect( p, 100000, 100000, 10000, 20, 1, 0, 1, 1 );
+ Vec_WrdFreeP( &vSimsPi );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaSim5.c b/src/aig/gia/giaReshape1.c
index ab33c218..52b40bdc 100644
--- a/src/aig/gia/giaSim5.c
+++ b/src/aig/gia/giaReshape1.c
@@ -1,12 +1,12 @@
/**CFile****************************************************************
- FileName [giaSim5.c]
+ FileName [giaReshape.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Scalable AIG package.]
- Synopsis [Simulation engine.]
+ Synopsis []
Author [Alan Mishchenko]
@@ -14,23 +14,19 @@
Date [Ver. 1.0. Started - June 20, 2005.]
- Revision [$Id: giaSim5.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+ Revision [$Id: gia.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "gia.h"
-#include "base/main/main.h"
ABC_NAMESPACE_IMPL_START
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-void Sim_Init( Abc_Frame_t * pAbc ) {}
-void Sim_End( Abc_Frame_t * pAbc ) {}
-void Gia_DatFree( Gia_Dat_t * p ) {}
-
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -40,12 +36,16 @@ void Gia_DatFree( Gia_Dat_t * p ) {}
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
***********************************************************************/
+Gia_Man_t * Gia_ManReshape1( Gia_Man_t * p, int fUseSimple, int fVerbose, int fVeryVerbose )
+{
+ return NULL;
+}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/aig/gia/giaSim4.c b/src/aig/gia/giaReshape2.c
index 6ce89cf0..98a4d855 100644
--- a/src/aig/gia/giaSim4.c
+++ b/src/aig/gia/giaReshape2.c
@@ -1,12 +1,12 @@
/**CFile****************************************************************
- FileName [giaSim4.c]
+ FileName [giaReshape.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Scalable AIG package.]
- Synopsis [Simulation engine.]
+ Synopsis []
Author [Alan Mishchenko]
@@ -14,7 +14,7 @@
Date [Ver. 1.0. Started - June 20, 2005.]
- Revision [$Id: giaSim4.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+ Revision [$Id: gia.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
@@ -35,15 +35,15 @@ ABC_NAMESPACE_IMPL_START
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
***********************************************************************/
-int Gia_Sim4Try( char * pFileName0, char * pFileName1, char * pFileName2, int nWords, int nBeam, int LevL, int LevU, int fOrder, int fFancy, int fUseBuf, int fVerbose )
+Gia_Man_t * Gia_ManReshape2( Gia_Man_t * p, int fUseSimple, int fVerbose, int fVeryVerbose )
{
- return 0;
+ return NULL;
}
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaResub.c b/src/aig/gia/giaResub.c
index b8c0e294..33fd5276 100644
--- a/src/aig/gia/giaResub.c
+++ b/src/aig/gia/giaResub.c
@@ -22,10 +22,10 @@
#include "misc/vec/vecWec.h"
#include "misc/vec/vecQue.h"
#include "misc/vec/vecHsh.h"
+#include "misc/util/utilTruth.h"
ABC_NAMESPACE_IMPL_START
-
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@@ -271,6 +271,520 @@ Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart );
}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Resubstitution data-structure.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+typedef struct Gia_ResbMan_t_ Gia_ResbMan_t;
+struct Gia_ResbMan_t_
+{
+ int nWords;
+ int nLimit;
+ int nDivsMax;
+ int iChoice;
+ int fUseXor;
+ int fDebug;
+ int fVerbose;
+ int fVeryVerbose;
+ Vec_Ptr_t * vDivs;
+ Vec_Int_t * vGates;
+ Vec_Int_t * vUnateLits[2];
+ Vec_Int_t * vNotUnateVars[2];
+ Vec_Int_t * vUnatePairs[2];
+ Vec_Int_t * vBinateVars;
+ Vec_Int_t * vUnateLitsW[2];
+ Vec_Int_t * vUnatePairsW[2];
+ Vec_Wec_t * vSorter;
+ word * pSets[2];
+ word * pDivA;
+ word * pDivB;
+ Vec_Wrd_t * vSims;
+};
+Gia_ResbMan_t * Gia_ResbAlloc( int nWords )
+{
+ Gia_ResbMan_t * p = ABC_CALLOC( Gia_ResbMan_t, 1 );
+ p->nWords = nWords;
+ p->vUnateLits[0] = Vec_IntAlloc( 100 );
+ p->vUnateLits[1] = Vec_IntAlloc( 100 );
+ p->vNotUnateVars[0] = Vec_IntAlloc( 100 );
+ p->vNotUnateVars[1] = Vec_IntAlloc( 100 );
+ p->vUnatePairs[0] = Vec_IntAlloc( 100 );
+ p->vUnatePairs[1] = Vec_IntAlloc( 100 );
+ p->vUnateLitsW[0] = Vec_IntAlloc( 100 );
+ p->vUnateLitsW[1] = Vec_IntAlloc( 100 );
+ p->vUnatePairsW[0] = Vec_IntAlloc( 100 );
+ p->vUnatePairsW[1] = Vec_IntAlloc( 100 );
+ p->vSorter = Vec_WecAlloc( nWords*64 );
+ p->vBinateVars = Vec_IntAlloc( 100 );
+ p->vGates = Vec_IntAlloc( 100 );
+ p->vDivs = Vec_PtrAlloc( 100 );
+ p->pSets[0] = ABC_CALLOC( word, nWords );
+ p->pSets[1] = ABC_CALLOC( word, nWords );
+ p->pDivA = ABC_CALLOC( word, nWords );
+ p->pDivB = ABC_CALLOC( word, nWords );
+ p->vSims = Vec_WrdAlloc( 100 );
+ return p;
+}
+void Gia_ResbInit( Gia_ResbMan_t * p, Vec_Ptr_t * vDivs, int nWords, int nLimit, int nDivsMax, int iChoice, int fUseXor, int fDebug, int fVerbose, int fVeryVerbose )
+{
+ assert( p->nWords == nWords );
+ p->nLimit = nLimit;
+ p->nDivsMax = nDivsMax;
+ p->iChoice = iChoice;
+ p->fUseXor = fUseXor;
+ p->fDebug = fDebug;
+ p->fVerbose = fVerbose;
+ p->fVeryVerbose = fVeryVerbose;
+ Abc_TtCopy( p->pSets[0], (word *)Vec_PtrEntry(vDivs, 0), nWords, 0 );
+ Abc_TtCopy( p->pSets[1], (word *)Vec_PtrEntry(vDivs, 1), nWords, 0 );
+ Vec_PtrClear( p->vDivs );
+ Vec_PtrAppend( p->vDivs, vDivs );
+ Vec_IntClear( p->vGates );
+ Vec_IntClear( p->vUnateLits[0] );
+ Vec_IntClear( p->vUnateLits[1] );
+ Vec_IntClear( p->vNotUnateVars[0] );
+ Vec_IntClear( p->vNotUnateVars[1] );
+ Vec_IntClear( p->vUnatePairs[0] );
+ Vec_IntClear( p->vUnatePairs[1] );
+ Vec_IntClear( p->vUnateLitsW[0] );
+ Vec_IntClear( p->vUnateLitsW[1] );
+ Vec_IntClear( p->vUnatePairsW[0] );
+ Vec_IntClear( p->vUnatePairsW[1] );
+ Vec_IntClear( p->vBinateVars );
+}
+void Gia_ResbFree( Gia_ResbMan_t * p )
+{
+ Vec_IntFree( p->vUnateLits[0] );
+ Vec_IntFree( p->vUnateLits[1] );
+ Vec_IntFree( p->vNotUnateVars[0] );
+ Vec_IntFree( p->vNotUnateVars[1] );
+ Vec_IntFree( p->vUnatePairs[0] );
+ Vec_IntFree( p->vUnatePairs[1] );
+ Vec_IntFree( p->vUnateLitsW[0] );
+ Vec_IntFree( p->vUnateLitsW[1] );
+ Vec_IntFree( p->vUnatePairsW[0] );
+ Vec_IntFree( p->vUnatePairsW[1] );
+ Vec_IntFree( p->vBinateVars );
+ Vec_IntFree( p->vGates );
+ Vec_WrdFree( p->vSims );
+ Vec_PtrFree( p->vDivs );
+ Vec_WecFree( p->vSorter );
+ ABC_FREE( p->pSets[0] );
+ ABC_FREE( p->pSets[1] );
+ ABC_FREE( p->pDivA );
+ ABC_FREE( p->pDivB );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Print resubstitution.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManResubPrintNode( Vec_Int_t * vRes, int nVars, int Node, int fCompl )
+{
+ extern void Gia_ManResubPrintLit( Vec_Int_t * vRes, int nVars, int iLit );
+ int iLit0 = Vec_IntEntry( vRes, 2*Node + 0 );
+ int iLit1 = Vec_IntEntry( vRes, 2*Node + 1 );
+ assert( iLit0 != iLit1 );
+ if ( iLit0 > iLit1 && Abc_LitIsCompl(fCompl) ) // xor
+ {
+ printf( "~" );
+ fCompl = 0;
+ }
+ printf( "(" );
+ Gia_ManResubPrintLit( vRes, nVars, Abc_LitNotCond(iLit0, fCompl) );
+ printf( " %c ", iLit0 > iLit1 ? '^' : (fCompl ? '|' : '&') );
+ Gia_ManResubPrintLit( vRes, nVars, Abc_LitNotCond(iLit1, fCompl) );
+ printf( ")" );
+}
+void Gia_ManResubPrintLit( Vec_Int_t * vRes, int nVars, int iLit )
+{
+ if ( Abc_Lit2Var(iLit) < nVars )
+ {
+ if ( nVars < 26 )
+ printf( "%s%c", Abc_LitIsCompl(iLit) ? "~":"", 'a' + Abc_Lit2Var(iLit)-2 );
+ else
+ printf( "%si%d", Abc_LitIsCompl(iLit) ? "~":"", Abc_Lit2Var(iLit)-2 );
+ }
+ else
+ Gia_ManResubPrintNode( vRes, nVars, Abc_Lit2Var(iLit) - nVars, Abc_LitIsCompl(iLit) );
+}
+int Gia_ManResubPrint( Vec_Int_t * vRes, int nVars )
+{
+ int iTopLit;
+ if ( Vec_IntSize(vRes) == 0 )
+ return printf( "none" );
+ assert( Vec_IntSize(vRes) % 2 == 1 );
+ iTopLit = Vec_IntEntryLast(vRes);
+ if ( iTopLit == 0 )
+ return printf( "const0" );
+ if ( iTopLit == 1 )
+ return printf( "const1" );
+ Gia_ManResubPrintLit( vRes, nVars, iTopLit );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Verify resubstitution.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManResubVerify( Gia_ResbMan_t * p, word * pFunc )
+{
+ int nVars = Vec_PtrSize(p->vDivs);
+ int iTopLit, RetValue;
+ word * pDivRes;
+ if ( Vec_IntSize(p->vGates) == 0 )
+ return -1;
+ iTopLit = Vec_IntEntryLast(p->vGates);
+ assert( iTopLit >= 0 );
+ if ( iTopLit == 0 )
+ {
+ if ( pFunc ) Abc_TtClear( pFunc, p->nWords );
+ return Abc_TtIsConst0( p->pSets[1], p->nWords );
+ }
+ if ( iTopLit == 1 )
+ {
+ if ( pFunc ) Abc_TtFill( pFunc, p->nWords );
+ return Abc_TtIsConst0( p->pSets[0], p->nWords );
+ }
+ if ( Abc_Lit2Var(iTopLit) < nVars )
+ {
+ assert( Vec_IntSize(p->vGates) == 1 );
+ pDivRes = (word *)Vec_PtrEntry( p->vDivs, Abc_Lit2Var(iTopLit) );
+ }
+ else
+ {
+ int i, iLit0, iLit1;
+ assert( Vec_IntSize(p->vGates) > 1 );
+ assert( Vec_IntSize(p->vGates) % 2 == 1 );
+ assert( Abc_Lit2Var(iTopLit)-nVars == Vec_IntSize(p->vGates)/2-1 );
+ Vec_WrdFill( p->vSims, p->nWords * Vec_IntSize(p->vGates)/2, 0 );
+ Vec_IntForEachEntryDouble( p->vGates, iLit0, iLit1, i )
+ {
+ int iVar0 = Abc_Lit2Var(iLit0);
+ int iVar1 = Abc_Lit2Var(iLit1);
+ word * pDiv0 = iVar0 < nVars ? (word *)Vec_PtrEntry(p->vDivs, iVar0) : Vec_WrdEntryP(p->vSims, p->nWords*(iVar0 - nVars));
+ word * pDiv1 = iVar1 < nVars ? (word *)Vec_PtrEntry(p->vDivs, iVar1) : Vec_WrdEntryP(p->vSims, p->nWords*(iVar1 - nVars));
+ word * pDiv = Vec_WrdEntryP(p->vSims, p->nWords*i/2);
+ if ( iVar0 < iVar1 )
+ Abc_TtAndCompl( pDiv, pDiv0, Abc_LitIsCompl(iLit0), pDiv1, Abc_LitIsCompl(iLit1), p->nWords );
+ else if ( iVar0 > iVar1 )
+ {
+ assert( !Abc_LitIsCompl(iLit0) );
+ assert( !Abc_LitIsCompl(iLit1) );
+ Abc_TtXor( pDiv, pDiv0, pDiv1, p->nWords, 0 );
+ }
+ else assert( 0 );
+ }
+ pDivRes = Vec_WrdEntryP( p->vSims, p->nWords*(Vec_IntSize(p->vGates)/2-1) );
+ }
+ if ( Abc_LitIsCompl(iTopLit) )
+ RetValue = !Abc_TtIntersectOne(p->pSets[1], 0, pDivRes, 0, p->nWords) && !Abc_TtIntersectOne(p->pSets[0], 0, pDivRes, 1, p->nWords);
+ else
+ RetValue = !Abc_TtIntersectOne(p->pSets[0], 0, pDivRes, 0, p->nWords) && !Abc_TtIntersectOne(p->pSets[1], 0, pDivRes, 1, p->nWords);
+ if ( pFunc ) Abc_TtCopy( pFunc, pDivRes, p->nWords, Abc_LitIsCompl(iTopLit) );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Construct AIG manager from gates.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManConstructFromMap( Gia_Man_t * pNew, Vec_Int_t * vGates, int nVars, Vec_Int_t * vUsed, Vec_Int_t * vCopy, int fHash )
+{
+ int i, iLit0, iLit1, iLitRes, iTopLit = Vec_IntEntryLast( vGates );
+ assert( Vec_IntSize(vUsed) == nVars );
+ assert( Vec_IntSize(vGates) > 1 );
+ assert( Vec_IntSize(vGates) % 2 == 1 );
+ assert( Abc_Lit2Var(iTopLit)-nVars == Vec_IntSize(vGates)/2-1 );
+ Vec_IntClear( vCopy );
+ Vec_IntForEachEntryDouble( vGates, iLit0, iLit1, i )
+ {
+ int iVar0 = Abc_Lit2Var(iLit0);
+ int iVar1 = Abc_Lit2Var(iLit1);
+ int iRes0 = iVar0 < nVars ? Vec_IntEntry(vUsed, iVar0) : Vec_IntEntry(vCopy, iVar0 - nVars);
+ int iRes1 = iVar1 < nVars ? Vec_IntEntry(vUsed, iVar1) : Vec_IntEntry(vCopy, iVar1 - nVars);
+ if ( iVar0 < iVar1 )
+ {
+ if ( fHash )
+ iLitRes = Gia_ManHashAnd( pNew, Abc_LitNotCond(iRes0, Abc_LitIsCompl(iLit0)), Abc_LitNotCond(iRes1, Abc_LitIsCompl(iLit1)) );
+ else
+ iLitRes = Gia_ManAppendAnd( pNew, Abc_LitNotCond(iRes0, Abc_LitIsCompl(iLit0)), Abc_LitNotCond(iRes1, Abc_LitIsCompl(iLit1)) );
+ }
+ else if ( iVar0 > iVar1 )
+ {
+ assert( !Abc_LitIsCompl(iLit0) );
+ assert( !Abc_LitIsCompl(iLit1) );
+ if ( fHash )
+ iLitRes = Gia_ManHashXor( pNew, Abc_LitNotCond(iRes0, Abc_LitIsCompl(iLit0)), Abc_LitNotCond(iRes1, Abc_LitIsCompl(iLit1)) );
+ else
+ iLitRes = Gia_ManAppendXor( pNew, Abc_LitNotCond(iRes0, Abc_LitIsCompl(iLit0)), Abc_LitNotCond(iRes1, Abc_LitIsCompl(iLit1)) );
+ }
+ else assert( 0 );
+ Vec_IntPush( vCopy, iLitRes );
+ }
+ assert( Vec_IntSize(vCopy) == Vec_IntSize(vGates)/2 );
+ iLitRes = Vec_IntEntry( vCopy, Vec_IntSize(vGates)/2-1 );
+ return iLitRes;
+}
+Gia_Man_t * Gia_ManConstructFromGates( Vec_Wec_t * vFuncs, int nDivs )
+{
+ Vec_Int_t * vGates; int i, k, iLit;
+ Vec_Int_t * vCopy = Vec_IntAlloc( 100 );
+ Vec_Int_t * vUsed = Vec_IntStartFull( nDivs );
+ Gia_Man_t * pNew = Gia_ManStart( 100 );
+ pNew->pName = Abc_UtilStrsav( "resub" );
+ Vec_WecForEachLevel( vFuncs, vGates, i )
+ {
+ assert( Vec_IntSize(vGates) % 2 == 1 );
+ Vec_IntForEachEntry( vGates, iLit, k )
+ {
+ int iVar = Abc_Lit2Var(iLit);
+ if ( iVar > 0 && iVar < nDivs && Vec_IntEntry(vUsed, iVar) == -1 )
+ Vec_IntWriteEntry( vUsed, iVar, Gia_ManAppendCi(pNew) );
+ }
+ }
+ Vec_WecForEachLevel( vFuncs, vGates, i )
+ {
+ int iLitRes, iTopLit = Vec_IntEntryLast( vGates );
+ if ( Abc_Lit2Var(iTopLit) == 0 )
+ iLitRes = 0;
+ else if ( Abc_Lit2Var(iTopLit) < nDivs )
+ iLitRes = Vec_IntEntry( vUsed, Abc_Lit2Var(iTopLit) );
+ else
+ iLitRes = Gia_ManConstructFromMap( pNew, vGates, nDivs, vUsed, vCopy, 0 );
+ Gia_ManAppendCo( pNew, Abc_LitNotCond( iLitRes, Abc_LitIsCompl(iTopLit) ) );
+ }
+ Vec_IntFree( vCopy );
+ Vec_IntFree( vUsed );
+ return pNew;
+}
+Gia_Man_t * Gia_ManConstructFromGates2( Vec_Wec_t * vFuncs, Vec_Wec_t * vDivs, int nObjs, Vec_Int_t ** pvSupp )
+{
+ Vec_Int_t * vGates; int i, k, iVar, iLit;
+ Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
+ Vec_Int_t * vCopy = Vec_IntAlloc( 100 );
+ Vec_Wec_t * vUseds = Vec_WecStart( Vec_WecSize(vDivs) );
+ Vec_Int_t * vMap = Vec_IntStartFull( nObjs );
+ Gia_Man_t * pNew = Gia_ManStart( 100 );
+ pNew->pName = Abc_UtilStrsav( "resub" );
+ assert( Vec_WecSize(vFuncs) == Vec_WecSize(vDivs) );
+ Vec_WecForEachLevel( vFuncs, vGates, i )
+ {
+ Vec_Int_t * vDiv = Vec_WecEntry( vDivs, i );
+ assert( Vec_IntSize(vGates) % 2 == 1 );
+ Vec_IntForEachEntry( vGates, iLit, k )
+ {
+ int iVar = Abc_Lit2Var(iLit);
+ if ( iVar > 0 && iVar < Vec_IntSize(vDiv) && Vec_IntEntry(vMap, Vec_IntEntry(vDiv, iVar)) == -1 )
+ Vec_IntWriteEntry( vMap, Vec_IntPushReturn(vSupp, Vec_IntEntry(vDiv, iVar)), 0 );
+ }
+ }
+ Vec_IntSort( vSupp, 0 );
+ Vec_IntForEachEntry( vSupp, iVar, k )
+ Vec_IntWriteEntry( vMap, iVar, Gia_ManAppendCi(pNew) );
+ Vec_WecForEachLevel( vFuncs, vGates, i )
+ {
+ Vec_Int_t * vDiv = Vec_WecEntry( vDivs, i );
+ Vec_Int_t * vUsed = Vec_WecEntry( vUseds, i );
+ Vec_IntFill( vUsed, Vec_IntSize(vDiv), -1 );
+ Vec_IntForEachEntry( vGates, iLit, k )
+ {
+ int iVar = Abc_Lit2Var(iLit);
+ if ( iVar > 0 && iVar < Vec_IntSize(vDiv) )
+ {
+ assert( Vec_IntEntry(vMap, Vec_IntEntry(vDiv, iVar)) > 0 );
+ Vec_IntWriteEntry( vUsed, iVar, Vec_IntEntry(vMap, Vec_IntEntry(vDiv, iVar)) );
+ }
+ }
+ }
+ Vec_WecForEachLevel( vFuncs, vGates, i )
+ {
+ Vec_Int_t * vDiv = Vec_WecEntry( vDivs, i );
+ Vec_Int_t * vUsed = Vec_WecEntry( vUseds, i );
+ int iLitRes, iTopLit = Vec_IntEntryLast( vGates );
+ if ( Abc_Lit2Var(iTopLit) == 0 )
+ iLitRes = 0;
+ else if ( Abc_Lit2Var(iTopLit) < Vec_IntSize(vDiv) )
+ iLitRes = Vec_IntEntry( vUsed, Abc_Lit2Var(iTopLit) );
+ else
+ iLitRes = Gia_ManConstructFromMap( pNew, vGates, Vec_IntSize(vDiv), vUsed, vCopy, 0 );
+ Gia_ManAppendCo( pNew, Abc_LitNotCond( iLitRes, Abc_LitIsCompl(iTopLit) ) );
+ }
+ Vec_IntFree( vMap );
+ Vec_IntFree( vCopy );
+ Vec_WecFree( vUseds );
+ if ( pvSupp )
+ *pvSupp = vSupp;
+ else
+ Vec_IntFree( vSupp );
+ return pNew;
+}
+Vec_Int_t * Gia_ManToGates( Gia_Man_t * p )
+{
+ Vec_Int_t * vRes = Vec_IntAlloc( 2*Gia_ManAndNum(p) + 1 );
+ Gia_Obj_t * pRoot = Gia_ManCo( p, 0 );
+ int iRoot = Gia_ObjFaninId0p(p, pRoot) - 1;
+ int nVars = Gia_ManCiNum(p);
+ assert( Gia_ManCoNum(p) == 1 );
+ if ( iRoot == -1 )
+ Vec_IntPush( vRes, Gia_ObjFaninC0(pRoot) );
+ else if ( iRoot < nVars )
+ Vec_IntPush( vRes, 4 + Abc_Var2Lit(iRoot, Gia_ObjFaninC0(pRoot)) );
+ else
+ {
+ Gia_Obj_t * pObj, * pLast = NULL; int i;
+ Gia_ManForEachCi( p, pObj, i )
+ assert( Gia_ObjId(p, pObj) == i+1 );
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ int iLit0 = Abc_Var2Lit( Gia_ObjFaninId0(pObj, i) - 1, Gia_ObjFaninC0(pObj) );
+ int iLit1 = Abc_Var2Lit( Gia_ObjFaninId1(pObj, i) - 1, Gia_ObjFaninC1(pObj) );
+ if ( iLit0 > iLit1 )
+ iLit0 ^= iLit1, iLit1 ^= iLit0, iLit0 ^= iLit1;
+ Vec_IntPushTwo( vRes, 4 + iLit0, 4 + iLit1 );
+ pLast = pObj;
+ }
+ assert( pLast == Gia_ObjFanin0(pRoot) );
+ Vec_IntPush( vRes, 4 + Abc_Var2Lit(iRoot, Gia_ObjFaninC0(pRoot)) );
+ }
+ assert( Vec_IntSize(vRes) == 2*Gia_ManAndNum(p) + 1 );
+ return vRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Construct AIG manager from gates.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManInsertOrder_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vObjs, Vec_Wec_t * vFuncs, Vec_Int_t * vNodes )
+{
+ Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
+ if ( iObj == 0 )
+ return;
+ if ( pObj->fPhase )
+ {
+ int nVars = Gia_ManObjNum(p);
+ int k, iLit, Index = Vec_IntFind( vObjs, iObj );
+ Vec_Int_t * vGates = Vec_WecEntry( vFuncs, Index );
+ assert( Gia_ObjIsCo(pObj) || Gia_ObjIsAnd(pObj) );
+ Vec_IntForEachEntry( vGates, iLit, k )
+ if ( Abc_Lit2Var(iLit) < nVars )
+ Gia_ManInsertOrder_rec( p, Abc_Lit2Var(iLit), vObjs, vFuncs, vNodes );
+ }
+ else if ( Gia_ObjIsCo(pObj) )
+ Gia_ManInsertOrder_rec( p, Gia_ObjFaninId0p(p, pObj), vObjs, vFuncs, vNodes );
+ else if ( Gia_ObjIsAnd(pObj) )
+ {
+ Gia_ManInsertOrder_rec( p, Gia_ObjFaninId0p(p, pObj), vObjs, vFuncs, vNodes );
+ Gia_ManInsertOrder_rec( p, Gia_ObjFaninId1p(p, pObj), vObjs, vFuncs, vNodes );
+ }
+ else assert( Gia_ObjIsCi(pObj) );
+ if ( !Gia_ObjIsCi(pObj) )
+ Vec_IntPush( vNodes, iObj );
+}
+Vec_Int_t * Gia_ManInsertOrder( Gia_Man_t * p, Vec_Int_t * vObjs, Vec_Wec_t * vFuncs )
+{
+ int i, Id;
+ Vec_Int_t * vNodes = Vec_IntAlloc( Gia_ManObjNum(p) );
+ Gia_ManForEachCoId( p, Id, i )
+ Gia_ManInsertOrder_rec( p, Id, vObjs, vFuncs, vNodes );
+ return vNodes;
+}
+Gia_Man_t * Gia_ManInsertFromGates( Gia_Man_t * p, Vec_Int_t * vObjs, Vec_Wec_t * vFuncs )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj;
+ int i, nVars = Gia_ManObjNum(p);
+ Vec_Int_t * vUsed = Vec_IntStartFull( nVars );
+ Vec_Int_t * vNodes, * vCopy = Vec_IntAlloc(100);
+ Gia_ManForEachObjVec( vObjs, p, pObj, i )
+ pObj->fPhase = 1;
+ vNodes = Gia_ManInsertOrder( p, vObjs, vFuncs );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) + 1000 );
+ Gia_ManHashStart( pNew );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ if ( !pObj->fPhase )
+ {
+ if ( Gia_ObjIsCo(pObj) )
+ pObj->Value = Gia_ObjFanin0Copy(pObj);
+ else if ( Gia_ObjIsAnd(pObj) )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ else assert( 0 );
+ }
+ else
+ {
+ int k, iLit, Index = Vec_IntFind( vObjs, Gia_ObjId(p, pObj) );
+ Vec_Int_t * vGates = Vec_WecEntry( vFuncs, Index );
+ int iLitRes, iTopLit = Vec_IntEntryLast( vGates );
+ if ( Abc_Lit2Var(iTopLit) == 0 )
+ iLitRes = 0;
+ else if ( Abc_Lit2Var(iTopLit) < nVars )
+ iLitRes = Gia_ManObj(p, Abc_Lit2Var(iTopLit))->Value;
+ else
+ {
+ Vec_IntForEachEntry( vGates, iLit, k )
+ Vec_IntWriteEntry( vUsed, Abc_Lit2Var(iLit), Gia_ManObj(p, Abc_Lit2Var(iLit))->Value );
+ iLitRes = Gia_ManConstructFromMap( pNew, vGates, nVars, vUsed, vCopy, 1 );
+ Vec_IntForEachEntry( vGates, iLit, k )
+ Vec_IntWriteEntry( vUsed, Abc_Lit2Var(iLit), -1 );
+ }
+ pObj->Value = Abc_LitNotCond( iLitRes, Abc_LitIsCompl(iTopLit) );
+ }
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManAppendCo( pNew, pObj->Value );
+ Gia_ManForEachObjVec( vObjs, p, pObj, i )
+ pObj->fPhase = 0;
+ Gia_ManHashStop( pNew );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ Vec_IntFree( vNodes );
+ Vec_IntFree( vUsed );
+ Vec_IntFree( vCopy );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ return pNew;
+}
+
/**Function*************************************************************
Synopsis [Perform resubstitution.]
@@ -282,6 +796,1257 @@ Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart );
SeeAlso []
***********************************************************************/
+static inline int Gia_ManFindFirstCommonLit( Vec_Int_t * vArr1, Vec_Int_t * vArr2, int fVerbose )
+{
+ int * pBeg1 = vArr1->pArray;
+ int * pBeg2 = vArr2->pArray;
+ int * pEnd1 = vArr1->pArray + vArr1->nSize;
+ int * pEnd2 = vArr2->pArray + vArr2->nSize;
+ int * pStart1 = vArr1->pArray;
+ int * pStart2 = vArr2->pArray;
+ int nRemoved = 0;
+ while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 )
+ {
+ if ( Abc_Lit2Var(*pBeg1) == Abc_Lit2Var(*pBeg2) )
+ {
+ if ( *pBeg1 != *pBeg2 )
+ return *pBeg1;
+ else
+ pBeg1++, pBeg2++;
+ nRemoved++;
+ }
+ else if ( *pBeg1 < *pBeg2 )
+ *pStart1++ = *pBeg1++;
+ else
+ *pStart2++ = *pBeg2++;
+ }
+ while ( pBeg1 < pEnd1 )
+ *pStart1++ = *pBeg1++;
+ while ( pBeg2 < pEnd2 )
+ *pStart2++ = *pBeg2++;
+ Vec_IntShrink( vArr1, pStart1 - vArr1->pArray );
+ Vec_IntShrink( vArr2, pStart2 - vArr2->pArray );
+ //if ( fVerbose ) printf( "Removed %d duplicated entries. Array1 = %d. Array2 = %d.\n", nRemoved, Vec_IntSize(vArr1), Vec_IntSize(vArr2) );
+ return -1;
+}
+
+void Gia_ManFindOneUnateInt( word * pOff, word * pOn, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits, Vec_Int_t * vNotUnateVars )
+{
+ word * pDiv; int i;
+ Vec_IntClear( vUnateLits );
+ Vec_IntClear( vNotUnateVars );
+ Vec_PtrForEachEntryStart( word *, vDivs, pDiv, i, 2 )
+ if ( !Abc_TtIntersectOne( pOff, 0, pDiv, 0, nWords ) )
+ Vec_IntPush( vUnateLits, Abc_Var2Lit(i, 0) );
+ else if ( !Abc_TtIntersectOne( pOff, 0, pDiv, 1, nWords ) )
+ Vec_IntPush( vUnateLits, Abc_Var2Lit(i, 1) );
+ else
+ Vec_IntPush( vNotUnateVars, i );
+}
+int Gia_ManFindOneUnate( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vNotUnateVars[2], int fVerbose )
+{
+ int n;
+ if ( fVerbose ) printf( " " );
+ for ( n = 0; n < 2; n++ )
+ {
+ Gia_ManFindOneUnateInt( pSets[n], pSets[!n], vDivs, nWords, vUnateLits[n], vNotUnateVars[n] );
+ if ( fVerbose ) printf( "U%d =%4d ", n, Vec_IntSize(vUnateLits[n]) );
+ }
+ return Gia_ManFindFirstCommonLit( vUnateLits[0], vUnateLits[1], fVerbose );
+}
+
+static inline int Gia_ManDivCover( word * pOff, word * pOn, word * pDivA, int ComplA, word * pDivB, int ComplB, int nWords )
+{
+ //assert( !Abc_TtIntersectOne(pOff, 0, pDivA, ComplA, nWords) );
+ //assert( !Abc_TtIntersectOne(pOff, 0, pDivB, ComplB, nWords) );
+ return !Abc_TtIntersectTwo( pOn, 0, pDivA, !ComplA, pDivB, !ComplB, nWords );
+}
+int Gia_ManFindTwoUnateInt( word * pOff, word * pOn, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits, Vec_Int_t * vUnateLitsW, int * pnPairs )
+{
+ int i, k, iDiv0_, iDiv1_, Cover0, Cover1;
+ int nTotal = Abc_TtCountOnesVec( pOn, nWords );
+ (*pnPairs) = 0;
+ Vec_IntForEachEntryTwo( vUnateLits, vUnateLitsW, iDiv0_, Cover0, i )
+ {
+ if ( 2*Cover0 < nTotal )
+ break;
+ Vec_IntForEachEntryTwoStart( vUnateLits, vUnateLitsW, iDiv1_, Cover1, k, i+1 )
+ {
+ int iDiv0 = Abc_MinInt( iDiv0_, iDiv1_ );
+ int iDiv1 = Abc_MaxInt( iDiv0_, iDiv1_ );
+ word * pDiv0 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv0));
+ word * pDiv1 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv1));
+ if ( Cover0 + Cover1 < nTotal )
+ break;
+ (*pnPairs)++;
+ if ( Gia_ManDivCover(pOff, pOn, pDiv1, Abc_LitIsCompl(iDiv1), pDiv0, Abc_LitIsCompl(iDiv0), nWords) )
+ return Abc_Var2Lit((Abc_LitNot(iDiv1) << 15) | Abc_LitNot(iDiv0), 1);
+ }
+ }
+ return -1;
+}
+int Gia_ManFindTwoUnate( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vUnateLitsW[2], int fVerbose )
+{
+ int n, iLit, nPairs;
+ if ( fVerbose ) printf( " " );
+ for ( n = 0; n < 2; n++ )
+ {
+ //int nPairsAll = Vec_IntSize(vUnateLits[n])*(Vec_IntSize(vUnateLits[n])-1)/2;
+ iLit = Gia_ManFindTwoUnateInt( pSets[n], pSets[!n], vDivs, nWords, vUnateLits[n], vUnateLitsW[n], &nPairs );
+ if ( fVerbose ) printf( "UU%d =%5d ", n, nPairs );
+ if ( iLit >= 0 )
+ return Abc_LitNotCond(iLit, n);
+ }
+ return -1;
+}
+
+void Gia_ManFindXorInt( word * pOff, word * pOn, Vec_Int_t * vBinate, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs )
+{
+ int i, k, iDiv0_, iDiv1_;
+ int Limit2 = Vec_IntSize(vBinate);//Abc_MinInt( Vec_IntSize(vBinate), 100 );
+ Vec_IntForEachEntryStop( vBinate, iDiv1_, i, Limit2 )
+ Vec_IntForEachEntryStop( vBinate, iDiv0_, k, i )
+ {
+ int iDiv0 = Abc_MinInt( iDiv0_, iDiv1_ );
+ int iDiv1 = Abc_MaxInt( iDiv0_, iDiv1_ );
+ word * pDiv0 = (word *)Vec_PtrEntry(vDivs, iDiv0);
+ word * pDiv1 = (word *)Vec_PtrEntry(vDivs, iDiv1);
+ if ( !Abc_TtIntersectXor( pOff, 0, pDiv0, pDiv1, 0, nWords ) )
+ Vec_IntPush( vUnatePairs, Abc_Var2Lit((Abc_Var2Lit(iDiv0, 0) << 15) | Abc_Var2Lit(iDiv1, 0), 0) );
+ else if ( !Abc_TtIntersectXor( pOff, 0, pDiv0, pDiv1, 1, nWords ) )
+ Vec_IntPush( vUnatePairs, Abc_Var2Lit((Abc_Var2Lit(iDiv0, 0) << 15) | Abc_Var2Lit(iDiv1, 0), 1) );
+ }
+}
+int Gia_ManFindXor( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vBinateVars, Vec_Int_t * vUnatePairs[2], int fVerbose )
+{
+ int n;
+ if ( fVerbose ) printf( " " );
+ for ( n = 0; n < 2; n++ )
+ {
+ Vec_IntClear( vUnatePairs[n] );
+ Gia_ManFindXorInt( pSets[n], pSets[!n], vBinateVars, vDivs, nWords, vUnatePairs[n] );
+ if ( fVerbose ) printf( "UX%d =%5d ", n, Vec_IntSize(vUnatePairs[n]) );
+ }
+ return Gia_ManFindFirstCommonLit( vUnatePairs[0], vUnatePairs[1], fVerbose );
+}
+
+void Gia_ManFindUnatePairsInt( word * pOff, word * pOn, Vec_Int_t * vBinate, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs )
+{
+ int n, i, k, iDiv0_, iDiv1_;
+ int Limit2 = Vec_IntSize(vBinate);//Abc_MinInt( Vec_IntSize(vBinate), 100 );
+ Vec_IntForEachEntryStop( vBinate, iDiv1_, i, Limit2 )
+ Vec_IntForEachEntryStop( vBinate, iDiv0_, k, i )
+ {
+ int iDiv0 = Abc_MinInt( iDiv0_, iDiv1_ );
+ int iDiv1 = Abc_MaxInt( iDiv0_, iDiv1_ );
+ word * pDiv0 = (word *)Vec_PtrEntry(vDivs, iDiv0);
+ word * pDiv1 = (word *)Vec_PtrEntry(vDivs, iDiv1);
+ for ( n = 0; n < 4; n++ )
+ {
+ int iLit0 = Abc_Var2Lit( iDiv0, n&1 );
+ int iLit1 = Abc_Var2Lit( iDiv1, n>>1 );
+ //if ( !Abc_TtIntersectTwo( pOff, 0, pDiv1, n>>1, pDiv0, n&1, nWords ) )
+ if ( !Abc_TtIntersectTwo( pOff, 0, pDiv1, n>>1, pDiv0, n&1, nWords ) && Abc_TtIntersectTwo( pOn, 0, pDiv1, n>>1, pDiv0, n&1, nWords ) )
+ Vec_IntPush( vUnatePairs, Abc_Var2Lit((iLit1 << 15) | iLit0, 0) );
+ }
+ }
+}
+void Gia_ManFindUnatePairs( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vBinateVars, Vec_Int_t * vUnatePairs[2], int fVerbose )
+{
+ int n, RetValue;
+ if ( fVerbose ) printf( " " );
+ for ( n = 0; n < 2; n++ )
+ {
+ int nBefore = Vec_IntSize(vUnatePairs[n]);
+ Gia_ManFindUnatePairsInt( pSets[n], pSets[!n], vBinateVars, vDivs, nWords, vUnatePairs[n] );
+ if ( fVerbose ) printf( "UP%d =%5d ", n, Vec_IntSize(vUnatePairs[n])-nBefore );
+ }
+ RetValue = Gia_ManFindFirstCommonLit( vUnatePairs[0], vUnatePairs[1], fVerbose );
+ assert( RetValue == -1 );
+}
+
+void Gia_ManDeriveDivPair( int iDiv, Vec_Ptr_t * vDivs, int nWords, word * pRes )
+{
+ int fComp = Abc_LitIsCompl(iDiv);
+ int iDiv0 = Abc_Lit2Var(iDiv) & 0x7FFF;
+ int iDiv1 = Abc_Lit2Var(iDiv) >> 15;
+ word * pDiv0 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv0));
+ word * pDiv1 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv1));
+ if ( iDiv0 < iDiv1 )
+ {
+ assert( !fComp );
+ Abc_TtAndCompl( pRes, pDiv0, Abc_LitIsCompl(iDiv0), pDiv1, Abc_LitIsCompl(iDiv1), nWords );
+ }
+ else
+ {
+ assert( !Abc_LitIsCompl(iDiv0) );
+ assert( !Abc_LitIsCompl(iDiv1) );
+ Abc_TtXor( pRes, pDiv0, pDiv1, nWords, 0 );
+ }
+}
+int Gia_ManFindDivGateInt( word * pOff, word * pOn, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits, Vec_Int_t * vUnatePairs, Vec_Int_t * vUnateLitsW, Vec_Int_t * vUnatePairsW, word * pDivTemp )
+{
+ int i, k, iDiv0, iDiv1, Cover0, Cover1;
+ int nTotal = Abc_TtCountOnesVec( pOn, nWords );
+ Vec_IntForEachEntryTwo( vUnateLits, vUnateLitsW, iDiv0, Cover0, i )
+ {
+ word * pDiv0 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv0));
+ if ( 2*Cover0 < nTotal )
+ break;
+ Vec_IntForEachEntryTwo( vUnatePairs, vUnatePairsW, iDiv1, Cover1, k )
+ {
+ int fComp1 = Abc_LitIsCompl(iDiv1);
+ if ( Cover0 + Cover1 < nTotal )
+ break;
+ Gia_ManDeriveDivPair( iDiv1, vDivs, nWords, pDivTemp );
+ if ( Gia_ManDivCover(pOff, pOn, pDiv0, Abc_LitIsCompl(iDiv0), pDivTemp, fComp1, nWords) )
+ return Abc_Var2Lit((Abc_Var2Lit(k, 1) << 15) | Abc_LitNot(iDiv0), 1);
+ }
+ }
+ return -1;
+}
+int Gia_ManFindDivGate( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vUnatePairs[2], Vec_Int_t * vUnateLitsW[2], Vec_Int_t * vUnatePairsW[2], word * pDivTemp )
+{
+ int n, iLit;
+ for ( n = 0; n < 2; n++ )
+ {
+ iLit = Gia_ManFindDivGateInt( pSets[n], pSets[!n], vDivs, nWords, vUnateLits[n], vUnatePairs[n], vUnateLitsW[n], vUnatePairsW[n], pDivTemp );
+ if ( iLit >= 0 )
+ return Abc_LitNotCond( iLit, n );
+ }
+ return -1;
+}
+
+int Gia_ManFindGateGateInt( word * pOff, word * pOn, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs, Vec_Int_t * vUnatePairsW, word * pDivTempA, word * pDivTempB )
+{
+ int i, k, iDiv0, iDiv1, Cover0, Cover1;
+ int nTotal = Abc_TtCountOnesVec( pOn, nWords );
+ Vec_IntForEachEntryTwo( vUnatePairs, vUnatePairsW, iDiv0, Cover0, k )
+ {
+ int fCompA = Abc_LitIsCompl(iDiv0);
+ if ( 2*Cover0 < nTotal )
+ break;
+ Gia_ManDeriveDivPair( iDiv0, vDivs, nWords, pDivTempA );
+ Vec_IntForEachEntryTwoStart( vUnatePairs, vUnatePairsW, iDiv1, Cover1, i, k+1 )
+ {
+ int fCompB = Abc_LitIsCompl(iDiv1);
+ if ( Cover0 + Cover1 < nTotal )
+ break;
+ Gia_ManDeriveDivPair( iDiv1, vDivs, nWords, pDivTempB );
+ if ( Gia_ManDivCover(pOff, pOn, pDivTempA, fCompA, pDivTempB, fCompB, nWords) )
+ return Abc_Var2Lit((Abc_Var2Lit(i, 1) << 15) | Abc_Var2Lit(k, 1), 1);
+ }
+ }
+ return -1;
+}
+int Gia_ManFindGateGate( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs[2], Vec_Int_t * vUnatePairsW[2], word * pDivTempA, word * pDivTempB )
+{
+ int n, iLit;
+ for ( n = 0; n < 2; n++ )
+ {
+ iLit = Gia_ManFindGateGateInt( pSets[n], pSets[!n], vDivs, nWords, vUnatePairs[n], vUnatePairsW[n], pDivTempA, pDivTempB );
+ if ( iLit >= 0 )
+ return Abc_LitNotCond( iLit, n );
+ }
+ return -1;
+}
+
+void Gia_ManSortUnatesInt( word * pOff, word * pOn, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits, Vec_Int_t * vUnateLitsW, Vec_Wec_t * vSorter )
+{
+ int i, k, iLit;
+ Vec_Int_t * vLevel;
+ Vec_WecInit( vSorter, nWords*64 );
+ Vec_IntForEachEntry( vUnateLits, iLit, i )
+ {
+ word * pDiv = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iLit));
+ //assert( !Abc_TtIntersectOne( pOff, 0, pDiv, Abc_LitIsCompl(iLit), nWords ) );
+ Vec_WecPush( vSorter, Abc_TtCountOnesVecMask(pDiv, pOn, nWords, Abc_LitIsCompl(iLit)), iLit );
+ }
+ Vec_IntClear( vUnateLits );
+ Vec_IntClear( vUnateLitsW );
+ Vec_WecForEachLevelReverse( vSorter, vLevel, k )
+ Vec_IntForEachEntry( vLevel, iLit, i )
+ {
+ Vec_IntPush( vUnateLits, iLit );
+ Vec_IntPush( vUnateLitsW, k );
+ }
+ //Vec_IntPrint( Vec_WecEntry(vSorter, 0) );
+ Vec_WecClear( vSorter );
+}
+void Gia_ManSortUnates( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vUnateLitsW[2], Vec_Wec_t * vSorter )
+{
+ int n;
+ for ( n = 0; n < 2; n++ )
+ Gia_ManSortUnatesInt( pSets[n], pSets[!n], vDivs, nWords, vUnateLits[n], vUnateLitsW[n], vSorter );
+}
+
+void Gia_ManSortPairsInt( word * pOff, word * pOn, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs, Vec_Int_t * vUnatePairsW, Vec_Wec_t * vSorter )
+{
+ int i, k, iPair;
+ Vec_Int_t * vLevel;
+ Vec_WecInit( vSorter, nWords*64 );
+ Vec_IntForEachEntry( vUnatePairs, iPair, i )
+ {
+ int fComp = Abc_LitIsCompl(iPair);
+ int iLit0 = Abc_Lit2Var(iPair) & 0x7FFF;
+ int iLit1 = Abc_Lit2Var(iPair) >> 15;
+ word * pDiv0 = (word *)Vec_PtrEntry( vDivs, Abc_Lit2Var(iLit0) );
+ word * pDiv1 = (word *)Vec_PtrEntry( vDivs, Abc_Lit2Var(iLit1) );
+ if ( iLit0 < iLit1 )
+ {
+ assert( !fComp );
+ //assert( !Abc_TtIntersectTwo( pOff, 0, pDiv0, Abc_LitIsCompl(iLit0), pDiv1, Abc_LitIsCompl(iLit1), nWords ) );
+ Vec_WecPush( vSorter, Abc_TtCountOnesVecMask2(pDiv0, pDiv1, Abc_LitIsCompl(iLit0), Abc_LitIsCompl(iLit1), pOn, nWords), iPair );
+ }
+ else
+ {
+ assert( !Abc_LitIsCompl(iLit0) );
+ assert( !Abc_LitIsCompl(iLit1) );
+ //assert( !Abc_TtIntersectXor( pOff, 0, pDiv0, pDiv1, fComp, nWords ) );
+ Vec_WecPush( vSorter, Abc_TtCountOnesVecXorMask(pDiv0, pDiv1, fComp, pOn, nWords), iPair );
+ }
+ }
+ Vec_IntClear( vUnatePairs );
+ Vec_IntClear( vUnatePairsW );
+ Vec_WecForEachLevelReverse( vSorter, vLevel, k )
+ Vec_IntForEachEntry( vLevel, iPair, i )
+ {
+ Vec_IntPush( vUnatePairs, iPair );
+ Vec_IntPush( vUnatePairsW, k );
+ }
+ //Vec_IntPrint( Vec_WecEntry(vSorter, 0) );
+ Vec_WecClear( vSorter );
+
+}
+void Gia_ManSortPairs( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vUnateLitsW[2], Vec_Wec_t * vSorter )
+{
+ int n;
+ for ( n = 0; n < 2; n++ )
+ Gia_ManSortPairsInt( pSets[n], pSets[!n], vDivs, nWords, vUnateLits[n], vUnateLitsW[n], vSorter );
+}
+
+void Gia_ManSortBinate( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vBinateVars, Vec_Wec_t * vSorter )
+{
+ Vec_Int_t * vLevel;
+ int nMints[2] = { Abc_TtCountOnesVec(pSets[0], nWords), Abc_TtCountOnesVec(pSets[1], nWords) };
+ word * pBig = nMints[0] > nMints[1] ? pSets[0] : pSets[1];
+ word * pSmo = nMints[0] > nMints[1] ? pSets[1] : pSets[0];
+ int Big = Abc_MaxInt( nMints[0], nMints[1] );
+ int Smo = Abc_MinInt( nMints[0], nMints[1] );
+ int i, k, iDiv, Gain;
+
+ Vec_WecInit( vSorter, nWords*64 );
+ Vec_IntForEachEntry( vBinateVars, iDiv, i )
+ {
+ word * pDiv = (word *)Vec_PtrEntry( vDivs, iDiv );
+ int nInter[2] = { Abc_TtCountOnesVecMask(pBig, pDiv, nWords, 0), Abc_TtCountOnesVecMask(pSmo, pDiv, nWords, 0) };
+ if ( nInter[0] < Big/2 ) // complement the divisor
+ {
+ nInter[0] = Big - nInter[0];
+ nInter[1] = Smo - nInter[1];
+ }
+ assert( nInter[0] >= Big/2 );
+ Gain = Abc_MaxInt( 0, nInter[0] - Big/2 + Smo/2 - nInter[1] );
+ Vec_WecPush( vSorter, Gain, iDiv );
+ }
+
+ Vec_IntClear( vBinateVars );
+ Vec_WecForEachLevelReverse( vSorter, vLevel, k )
+ Vec_IntForEachEntry( vLevel, iDiv, i )
+ Vec_IntPush( vBinateVars, iDiv );
+ Vec_WecClear( vSorter );
+
+ if ( Vec_IntSize(vBinateVars) > 2000 )
+ Vec_IntShrink( vBinateVars, 2000 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Perform resubstitution.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManResubFindBestBinate( Gia_ResbMan_t * p )
+{
+ int nMintsAll = Abc_TtCountOnesVec(p->pSets[0], p->nWords) + Abc_TtCountOnesVec(p->pSets[1], p->nWords);
+ int i, iDiv, iLitBest = -1, CostBest = -1;
+//Vec_IntPrint( p->vBinateVars );
+//Dau_DsdPrintFromTruth( p->pSets[0], 6 );
+//Dau_DsdPrintFromTruth( p->pSets[1], 6 );
+ Vec_IntForEachEntry( p->vBinateVars, iDiv, i )
+ {
+ word * pDiv = (word *)Vec_PtrEntry(p->vDivs, iDiv);
+ int nMints0 = Abc_TtCountOnesVecMask( pDiv, p->pSets[0], p->nWords, 0 );
+ int nMints1 = Abc_TtCountOnesVecMask( pDiv, p->pSets[1], p->nWords, 0 );
+ if ( CostBest < nMints0 + nMints1 )
+ {
+ CostBest = nMints0 + nMints1;
+ iLitBest = Abc_Var2Lit( iDiv, 0 );
+ }
+ if ( CostBest < nMintsAll - nMints0 - nMints1 )
+ {
+ CostBest = nMintsAll - nMints0 - nMints1;
+ iLitBest = Abc_Var2Lit( iDiv, 1 );
+ }
+ }
+ return iLitBest;
+}
+int Gia_ManResubAddNode( Gia_ResbMan_t * p, int iLit0, int iLit1, int Type )
+{
+ int iNode = Vec_PtrSize(p->vDivs) + Vec_IntSize(p->vGates)/2;
+ int fFlip = (Type == 2) ^ (iLit0 > iLit1);
+ int iFan0 = fFlip ? iLit1 : iLit0;
+ int iFan1 = fFlip ? iLit0 : iLit1;
+ assert( iLit0 != iLit1 );
+ if ( Type == 2 )
+ assert( iFan0 > iFan1 );
+ else
+ assert( iFan0 < iFan1 );
+ Vec_IntPushTwo( p->vGates, Abc_LitNotCond(iFan0, Type==1), Abc_LitNotCond(iFan1, Type==1) );
+ return Abc_Var2Lit( iNode, Type==1 );
+}
+int Gia_ManResubPerformMux_rec( Gia_ResbMan_t * p, int nLimit, int Depth )
+{
+ extern int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit, int Depth );
+ int iDivBest, iResLit0, iResLit1, nNodes;
+ word * pDiv, * pCopy[2];
+ if ( Depth == 0 )
+ return -1;
+ if ( nLimit < 3 )
+ return -1;
+ iDivBest = Gia_ManResubFindBestBinate( p );
+ if ( iDivBest == -1 )
+ return -1;
+ pCopy[0] = ABC_CALLOC( word, p->nWords );
+ pCopy[1] = ABC_CALLOC( word, p->nWords );
+ Abc_TtCopy( pCopy[0], p->pSets[0], p->nWords, 0 );
+ Abc_TtCopy( pCopy[1], p->pSets[1], p->nWords, 0 );
+ pDiv = (word *)Vec_PtrEntry( p->vDivs, Abc_Lit2Var(iDivBest) );
+ Abc_TtAndSharp( p->pSets[0], pCopy[0], pDiv, p->nWords, !Abc_LitIsCompl(iDivBest) );
+ Abc_TtAndSharp( p->pSets[1], pCopy[1], pDiv, p->nWords, !Abc_LitIsCompl(iDivBest) );
+ nNodes = Vec_IntSize(p->vGates)/2;
+ //iResLit0 = Gia_ManResubPerform_rec( p, nLimit-3 );
+ iResLit0 = Gia_ManResubPerform_rec( p, nLimit, 0 );
+ if ( iResLit0 == -1 )
+ iResLit0 = Gia_ManResubPerformMux_rec( p, nLimit, Depth-1 );
+ if ( iResLit0 == -1 )
+ {
+ ABC_FREE( pCopy[0] );
+ ABC_FREE( pCopy[1] );
+ return -1;
+ }
+ Abc_TtAndSharp( p->pSets[0], pCopy[0], pDiv, p->nWords, Abc_LitIsCompl(iDivBest) );
+ Abc_TtAndSharp( p->pSets[1], pCopy[1], pDiv, p->nWords, Abc_LitIsCompl(iDivBest) );
+ ABC_FREE( pCopy[0] );
+ ABC_FREE( pCopy[1] );
+ nNodes = Vec_IntSize(p->vGates)/2 - nNodes;
+ if ( nLimit-nNodes < 3 )
+ return -1;
+ //iResLit1 = Gia_ManResubPerform_rec( p, nLimit-3-nNodes );
+ iResLit1 = Gia_ManResubPerform_rec( p, nLimit, 0 );
+ if ( iResLit1 == -1 )
+ iResLit1 = Gia_ManResubPerformMux_rec( p, nLimit, Depth-1 );
+ if ( iResLit1 == -1 )
+ return -1;
+ else
+ {
+ int iLit0 = Gia_ManResubAddNode( p, Abc_LitNot(iDivBest), iResLit0, 0 );
+ int iLit1 = Gia_ManResubAddNode( p, iDivBest, iResLit1, 0 );
+ return Gia_ManResubAddNode( p, iLit0, iLit1, 1 );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Perform resubstitution.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit, int Depth )
+{
+ int TopOneW[2] = {0}, TopTwoW[2] = {0}, Max1, Max2, iResLit, nVars = Vec_PtrSize(p->vDivs);
+ if ( p->fVerbose )
+ {
+ int nMints[2] = { Abc_TtCountOnesVec(p->pSets[0], p->nWords), Abc_TtCountOnesVec(p->pSets[1], p->nWords) };
+ printf( " " );
+ printf( "ISF: " );
+ printf( "0=%5d (%5.2f %%) ", nMints[0], 100.0*nMints[0]/(64*p->nWords) );
+ printf( "1=%5d (%5.2f %%) ", nMints[1], 100.0*nMints[1]/(64*p->nWords) );
+ }
+ if ( Abc_TtIsConst0( p->pSets[1], p->nWords ) )
+ return 0;
+ if ( Abc_TtIsConst0( p->pSets[0], p->nWords ) )
+ return 1;
+ iResLit = Gia_ManFindOneUnate( p->pSets, p->vDivs, p->nWords, p->vUnateLits, p->vNotUnateVars, p->fVerbose );
+ if ( iResLit >= 0 ) // buffer
+ return iResLit;
+ if ( nLimit == 0 )
+ return -1;
+ Gia_ManSortUnates( p->pSets, p->vDivs, p->nWords, p->vUnateLits, p->vUnateLitsW, p->vSorter );
+ iResLit = Gia_ManFindTwoUnate( p->pSets, p->vDivs, p->nWords, p->vUnateLits, p->vUnateLitsW, p->fVerbose );
+ if ( iResLit >= 0 ) // and
+ {
+ int iNode = nVars + Vec_IntSize(p->vGates)/2;
+ int fComp = Abc_LitIsCompl(iResLit);
+ int iDiv0 = Abc_Lit2Var(iResLit) & 0x7FFF;
+ int iDiv1 = Abc_Lit2Var(iResLit) >> 15;
+ assert( iDiv0 < iDiv1 );
+ Vec_IntPushTwo( p->vGates, iDiv0, iDiv1 );
+ return Abc_Var2Lit( iNode, fComp );
+ }
+ Vec_IntTwoFindCommon( p->vNotUnateVars[0], p->vNotUnateVars[1], p->vBinateVars );
+ if ( Depth )
+ return Gia_ManResubPerformMux_rec( p, nLimit, Depth );
+ if ( Vec_IntSize(p->vBinateVars) > p->nDivsMax )
+ Vec_IntShrink( p->vBinateVars, p->nDivsMax );
+ if ( p->fVerbose ) printf( " B = %3d", Vec_IntSize(p->vBinateVars) );
+ //Gia_ManSortBinate( p->pSets, p->vDivs, p->nWords, p->vBinateVars, p->vSorter );
+ if ( p->fUseXor )
+ {
+ iResLit = Gia_ManFindXor( p->pSets, p->vDivs, p->nWords, p->vBinateVars, p->vUnatePairs, p->fVerbose );
+ if ( iResLit >= 0 ) // xor
+ {
+ int iNode = nVars + Vec_IntSize(p->vGates)/2;
+ int fComp = Abc_LitIsCompl(iResLit);
+ int iDiv0 = Abc_Lit2Var(iResLit) & 0x7FFF;
+ int iDiv1 = Abc_Lit2Var(iResLit) >> 15;
+ assert( !Abc_LitIsCompl(iDiv0) );
+ assert( !Abc_LitIsCompl(iDiv1) );
+ assert( iDiv0 > iDiv1 );
+ Vec_IntPushTwo( p->vGates, iDiv0, iDiv1 );
+ return Abc_Var2Lit( iNode, fComp );
+ }
+ }
+ if ( nLimit == 1 )
+ return -1;
+ Gia_ManFindUnatePairs( p->pSets, p->vDivs, p->nWords, p->vBinateVars, p->vUnatePairs, p->fVerbose );
+ Gia_ManSortPairs( p->pSets, p->vDivs, p->nWords, p->vUnatePairs, p->vUnatePairsW, p->vSorter );
+ iResLit = Gia_ManFindDivGate( p->pSets, p->vDivs, p->nWords, p->vUnateLits, p->vUnatePairs, p->vUnateLitsW, p->vUnatePairsW, p->pDivA );
+ if ( iResLit >= 0 ) // and(div,pair)
+ {
+ int iNode = nVars + Vec_IntSize(p->vGates)/2;
+
+ int fComp = Abc_LitIsCompl(iResLit);
+ int iDiv0 = Abc_Lit2Var(iResLit) & 0x7FFF; // div
+ int iDiv1 = Abc_Lit2Var(iResLit) >> 15; // pair
+
+ int Div1 = Vec_IntEntry( p->vUnatePairs[!fComp], Abc_Lit2Var(iDiv1) );
+ int fComp1 = Abc_LitIsCompl(Div1) ^ Abc_LitIsCompl(iDiv1);
+ int iDiv10 = Abc_Lit2Var(Div1) & 0x7FFF;
+ int iDiv11 = Abc_Lit2Var(Div1) >> 15;
+
+ Vec_IntPushTwo( p->vGates, iDiv10, iDiv11 );
+ Vec_IntPushTwo( p->vGates, iDiv0, Abc_Var2Lit(iNode, fComp1) );
+ return Abc_Var2Lit( iNode+1, fComp );
+ }
+// if ( nLimit == 2 )
+// return -1;
+ if ( nLimit >= 3 )
+ {
+ iResLit = Gia_ManFindGateGate( p->pSets, p->vDivs, p->nWords, p->vUnatePairs, p->vUnatePairsW, p->pDivA, p->pDivB );
+ if ( iResLit >= 0 ) // and(pair,pair)
+ {
+ int iNode = nVars + Vec_IntSize(p->vGates)/2;
+
+ int fComp = Abc_LitIsCompl(iResLit);
+ int iDiv0 = Abc_Lit2Var(iResLit) & 0x7FFF; // pair
+ int iDiv1 = Abc_Lit2Var(iResLit) >> 15; // pair
+
+ int Div0 = Vec_IntEntry( p->vUnatePairs[!fComp], Abc_Lit2Var(iDiv0) );
+ int fComp0 = Abc_LitIsCompl(Div0) ^ Abc_LitIsCompl(iDiv0);
+ int iDiv00 = Abc_Lit2Var(Div0) & 0x7FFF;
+ int iDiv01 = Abc_Lit2Var(Div0) >> 15;
+
+ int Div1 = Vec_IntEntry( p->vUnatePairs[!fComp], Abc_Lit2Var(iDiv1) );
+ int fComp1 = Abc_LitIsCompl(Div1) ^ Abc_LitIsCompl(iDiv1);
+ int iDiv10 = Abc_Lit2Var(Div1) & 0x7FFF;
+ int iDiv11 = Abc_Lit2Var(Div1) >> 15;
+
+ Vec_IntPushTwo( p->vGates, iDiv00, iDiv01 );
+ Vec_IntPushTwo( p->vGates, iDiv10, iDiv11 );
+ Vec_IntPushTwo( p->vGates, Abc_Var2Lit(iNode, fComp0), Abc_Var2Lit(iNode+1, fComp1) );
+ return Abc_Var2Lit( iNode+2, fComp );
+ }
+ }
+// if ( nLimit == 3 )
+// return -1;
+ if ( Vec_IntSize(p->vUnateLits[0]) + Vec_IntSize(p->vUnateLits[1]) + Vec_IntSize(p->vUnatePairs[0]) + Vec_IntSize(p->vUnatePairs[1]) == 0 )
+ return -1;
+
+ TopOneW[0] = Vec_IntSize(p->vUnateLitsW[0]) ? Vec_IntEntry(p->vUnateLitsW[0], 0) : 0;
+ TopOneW[1] = Vec_IntSize(p->vUnateLitsW[1]) ? Vec_IntEntry(p->vUnateLitsW[1], 0) : 0;
+
+ TopTwoW[0] = Vec_IntSize(p->vUnatePairsW[0]) ? Vec_IntEntry(p->vUnatePairsW[0], 0) : 0;
+ TopTwoW[1] = Vec_IntSize(p->vUnatePairsW[1]) ? Vec_IntEntry(p->vUnatePairsW[1], 0) : 0;
+
+ Max1 = Abc_MaxInt(TopOneW[0], TopOneW[1]);
+ Max2 = Abc_MaxInt(TopTwoW[0], TopTwoW[1]);
+ if ( Abc_MaxInt(Max1, Max2) == 0 )
+ return -1;
+
+ if ( Max1 > Max2/2 )
+ {
+ if ( nLimit >= 2 && (Max1 == TopOneW[0] || Max1 == TopOneW[1]) )
+ {
+ int fUseOr = Max1 == TopOneW[0];
+ int iDiv = Vec_IntEntry( p->vUnateLits[!fUseOr], 0 );
+ int fComp = Abc_LitIsCompl(iDiv);
+ word * pDiv = (word *)Vec_PtrEntry( p->vDivs, Abc_Lit2Var(iDiv) );
+ Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], pDiv, p->nWords, !fComp );
+ if ( p->fVerbose )
+ printf( "\n" );
+ iResLit = Gia_ManResubPerform_rec( p, nLimit-1, Depth );
+ if ( iResLit >= 0 )
+ {
+ int iNode = nVars + Vec_IntSize(p->vGates)/2;
+ if ( iDiv < iResLit )
+ Vec_IntPushTwo( p->vGates, Abc_LitNot(iDiv), Abc_LitNotCond(iResLit, fUseOr) );
+ else
+ Vec_IntPushTwo( p->vGates, Abc_LitNotCond(iResLit, fUseOr), Abc_LitNot(iDiv) );
+ return Abc_Var2Lit( iNode, fUseOr );
+ }
+ }
+ if ( Max2 == 0 )
+ return -1;
+/*
+ if ( Max2 == TopTwoW[0] || Max2 == TopTwoW[1] )
+ {
+ int fUseOr = Max2 == TopTwoW[0];
+ int iDiv = Vec_IntEntry( p->vUnatePairs[!fUseOr], 0 );
+ int fComp = Abc_LitIsCompl(iDiv);
+ Gia_ManDeriveDivPair( iDiv, p->vDivs, p->nWords, p->pDivA );
+ Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], p->pDivA, p->nWords, !fComp );
+ if ( p->fVerbose )
+ printf( "\n " );
+ iResLit = Gia_ManResubPerform_rec( p, nLimit-2 );
+ if ( iResLit >= 0 )
+ {
+ int iNode = nVars + Vec_IntSize(p->vGates)/2;
+ int iDiv0 = Abc_Lit2Var(iDiv) & 0x7FFF;
+ int iDiv1 = Abc_Lit2Var(iDiv) >> 15;
+ Vec_IntPushTwo( p->vGates, iDiv0, iDiv1 );
+ Vec_IntPushTwo( p->vGates, Abc_LitNotCond(iResLit, fUseOr), Abc_Var2Lit(iNode, !fComp) );
+ return Abc_Var2Lit( iNode+1, fUseOr );
+ }
+ }
+*/
+ }
+ else
+ {
+ if ( nLimit >= 3 && (Max2 == TopTwoW[0] || Max2 == TopTwoW[1]) )
+ {
+ int fUseOr = Max2 == TopTwoW[0];
+ int iDiv = Vec_IntEntry( p->vUnatePairs[!fUseOr], 0 );
+ int fComp = Abc_LitIsCompl(iDiv);
+ Gia_ManDeriveDivPair( iDiv, p->vDivs, p->nWords, p->pDivA );
+ Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], p->pDivA, p->nWords, !fComp );
+ if ( p->fVerbose )
+ printf( "\n" );
+ iResLit = Gia_ManResubPerform_rec( p, nLimit-2, Depth );
+ if ( iResLit >= 0 )
+ {
+ int iNode = nVars + Vec_IntSize(p->vGates)/2;
+ int iDiv0 = Abc_Lit2Var(iDiv) & 0x7FFF;
+ int iDiv1 = Abc_Lit2Var(iDiv) >> 15;
+ Vec_IntPushTwo( p->vGates, iDiv0, iDiv1 );
+ Vec_IntPushTwo( p->vGates, Abc_LitNotCond(iResLit, fUseOr), Abc_Var2Lit(iNode, !fComp) );
+ return Abc_Var2Lit( iNode+1, fUseOr );
+ }
+ }
+ if ( Max1 == 0 )
+ return -1;
+/*
+ if ( Max1 == TopOneW[0] || Max1 == TopOneW[1] )
+ {
+ int fUseOr = Max1 == TopOneW[0];
+ int iDiv = Vec_IntEntry( p->vUnateLits[!fUseOr], 0 );
+ int fComp = Abc_LitIsCompl(iDiv);
+ word * pDiv = (word *)Vec_PtrEntry( p->vDivs, Abc_Lit2Var(iDiv) );
+ Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], pDiv, p->nWords, !fComp );
+ if ( p->fVerbose )
+ printf( "\n " );
+ iResLit = Gia_ManResubPerform_rec( p, nLimit-1 );
+ if ( iResLit >= 0 )
+ {
+ int iNode = nVars + Vec_IntSize(p->vGates)/2;
+ Vec_IntPushTwo( p->vGates, Abc_LitNot(iDiv), Abc_LitNotCond(iResLit, fUseOr) );
+ return Abc_Var2Lit( iNode, fUseOr );
+ }
+ }
+*/
+ }
+ return -1;
+}
+void Gia_ManResubPerform( Gia_ResbMan_t * p, Vec_Ptr_t * vDivs, int nWords, int nLimit, int nDivsMax, int iChoice, int fUseXor, int fDebug, int fVerbose, int Depth )
+{
+ int Res;
+ Gia_ResbInit( p, vDivs, nWords, nLimit, nDivsMax, iChoice, fUseXor, fDebug, fVerbose, fVerbose );
+ Res = Gia_ManResubPerform_rec( p, nLimit, Depth );
+ if ( Res >= 0 )
+ Vec_IntPush( p->vGates, Res );
+ else
+ Vec_IntClear( p->vGates );
+ if ( fVerbose )
+ printf( "\n" );
+}
+Vec_Int_t * Gia_ManResubOne( Vec_Ptr_t * vDivs, int nWords, int nLimit, int nDivsMax, int iChoice, int fUseXor, int fDebug, int fVerbose, word * pFunc, int Depth )
+{
+ Vec_Int_t * vRes;
+ Gia_ResbMan_t * p = Gia_ResbAlloc( nWords );
+ Gia_ManResubPerform( p, vDivs, nWords, nLimit, nDivsMax, iChoice, fUseXor, fDebug, fVerbose, Depth );
+ if ( fVerbose )
+ Gia_ManResubPrint( p->vGates, Vec_PtrSize(vDivs) );
+ //if ( fVerbose )
+ // printf( "\n" );
+ if ( !Gia_ManResubVerify(p, pFunc) )
+ {
+ Gia_ManResubPrint( p->vGates, Vec_PtrSize(vDivs) );
+ printf( "Verification FAILED.\n" );
+ }
+ else if ( fDebug && fVerbose )
+ printf( "Verification succeeded." );
+ if ( fVerbose )
+ printf( "\n" );
+ vRes = Vec_IntDup( p->vGates );
+ Gia_ResbFree( p );
+ return vRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Top level.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static Gia_ResbMan_t * s_pResbMan = NULL;
+
+void Abc_ResubPrepareManager( int nWords )
+{
+ if ( s_pResbMan != NULL )
+ Gia_ResbFree( s_pResbMan );
+ s_pResbMan = NULL;
+ if ( nWords > 0 )
+ s_pResbMan = Gia_ResbAlloc( nWords );
+}
+
+int Abc_ResubComputeFunction( void ** ppDivs, int nDivs, int nWords, int nLimit, int nDivsMax, int iChoice, int fUseXor, int fDebug, int fVerbose, int ** ppArray )
+{
+ Vec_Ptr_t Divs = { nDivs, nDivs, ppDivs };
+ assert( s_pResbMan != NULL ); // first call Abc_ResubPrepareManager()
+ Gia_ManResubPerform( s_pResbMan, &Divs, nWords, nLimit, nDivsMax, iChoice, fUseXor, fDebug, fVerbose==2, 0 );
+ if ( fVerbose )
+ {
+ int nGates = Vec_IntSize(s_pResbMan->vGates)/2;
+ if ( nGates )
+ {
+ printf( " Gain = %2d Gates = %2d __________ F = ", nLimit+1-nGates, nGates );
+ Gia_ManResubPrint( s_pResbMan->vGates, nDivs );
+ printf( "\n" );
+ }
+ }
+ if ( fDebug )
+ {
+ if ( !Gia_ManResubVerify(s_pResbMan, NULL) )
+ {
+ Gia_ManResubPrint( s_pResbMan->vGates, nDivs );
+ printf( "Verification FAILED.\n" );
+ }
+ //else
+ // printf( "Verification succeeded.\n" );
+ }
+ *ppArray = Vec_IntArray(s_pResbMan->vGates);
+ assert( Vec_IntSize(s_pResbMan->vGates)/2 <= nLimit );
+ return Vec_IntSize(s_pResbMan->vGates);
+}
+
+void Abc_ResubDumpProblem( char * pFileName, void ** ppDivs, int nDivs, int nWords )
+{
+ Vec_Wrd_t * vSims = Vec_WrdAlloc( nDivs * nWords );
+ word ** pDivs = (word **)ppDivs;
+ int d, w;
+ for ( d = 0; d < nDivs; d++ )
+ for ( w = 0; w < nWords; w++ )
+ Vec_WrdPush( vSims, pDivs[d][w] );
+ Vec_WrdDumpHex( pFileName, vSims, nWords, 1 );
+ Vec_WrdFree( vSims );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Top level.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+
+extern void Extra_PrintHex( FILE * pFile, unsigned * pTruth, int nVars );
+extern void Dau_DsdPrintFromTruth2( word * pTruth, int nVarsInit );
+
+void Gia_ManResubTest3()
+{
+ int nVars = 4;
+ int fVerbose = 1;
+ word Divs[6] = { 0, 0,
+ ABC_CONST(0xAAAAAAAAAAAAAAAA),
+ ABC_CONST(0xCCCCCCCCCCCCCCCC),
+ ABC_CONST(0xF0F0F0F0F0F0F0F0),
+ ABC_CONST(0xFF00FF00FF00FF00)
+ };
+ Vec_Ptr_t * vDivs = Vec_PtrAlloc( 6 );
+ Vec_Int_t * vRes = Vec_IntAlloc( 100 );
+ int i, k, ArraySize, * pArray;
+ for ( i = 0; i < 6; i++ )
+ Vec_PtrPush( vDivs, Divs+i );
+ Abc_ResubPrepareManager( 1 );
+ for ( i = 0; i < (1<<(1<<nVars)); i++ ) //if ( i == 0xCA )
+ {
+ word Truth = Abc_Tt6Stretch( i, nVars );
+ Divs[0] = ~Truth;
+ Divs[1] = Truth;
+ printf( "%3d : ", i );
+ Extra_PrintHex( stdout, (unsigned*)&Truth, nVars );
+ printf( " " );
+ Dau_DsdPrintFromTruth2( &Truth, nVars );
+ printf( " " );
+
+ //Abc_ResubDumpProblem( "temp.resub", (void **)Vec_PtrArray(vDivs), Vec_PtrSize(vDivs), 1 );
+ ArraySize = Abc_ResubComputeFunction( (void **)Vec_PtrArray(vDivs), Vec_PtrSize(vDivs), 1, 16, 50, 0, 0, 1, fVerbose, &pArray );
+ printf( "\n" );
+
+ Vec_IntClear( vRes );
+ for ( k = 0; k < ArraySize; k++ )
+ Vec_IntPush( vRes, pArray[k] );
+
+ if ( i == 1000 )
+ break;
+ }
+ Abc_ResubPrepareManager( 0 );
+ Vec_IntFree( vRes );
+ Vec_PtrFree( vDivs );
+}
+void Gia_ManResubTest3_()
+{
+ Gia_ResbMan_t * p = Gia_ResbAlloc( 1 );
+ word Divs[6] = { 0, 0,
+ ABC_CONST(0xAAAAAAAAAAAAAAAA),
+ ABC_CONST(0xCCCCCCCCCCCCCCCC),
+ ABC_CONST(0xF0F0F0F0F0F0F0F0),
+ ABC_CONST(0xFF00FF00FF00FF00)
+ };
+ Vec_Ptr_t * vDivs = Vec_PtrAlloc( 6 );
+ Vec_Int_t * vRes = Vec_IntAlloc( 100 );
+ int i;
+ for ( i = 0; i < 6; i++ )
+ Vec_PtrPush( vDivs, Divs+i );
+
+ {
+ word Truth = (Divs[2] | Divs[3]) & (Divs[4] & Divs[5]);
+// word Truth = (~Divs[2] | Divs[3]) | ~Divs[4];
+ Divs[0] = ~Truth;
+ Divs[1] = Truth;
+ Extra_PrintHex( stdout, (unsigned*)&Truth, 6 );
+ printf( " " );
+ Dau_DsdPrintFromTruth2( &Truth, 6 );
+ printf( " " );
+ Gia_ManResubPerform( p, vDivs, 1, 100, 0, 50, 1, 1, 0, 0 );
+ }
+ Gia_ResbFree( p );
+ Vec_IntFree( vRes );
+ Vec_PtrFree( vDivs );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Top level.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManResubPair( Vec_Wrd_t * vOn, Vec_Wrd_t * vOff, int nWords, int nIns )
+{
+ Gia_ResbMan_t * p = Gia_ResbAlloc( nWords*2 );
+ Vec_Ptr_t * vDivs = Vec_PtrAllocSimInfo( nIns+2, nWords*2 );
+ word * pSim; int i;
+ Vec_PtrForEachEntry( word *, vDivs, pSim, i )
+ {
+ if ( i == 0 )
+ {
+ memset( pSim, 0x00, sizeof(word)*nWords );
+ memset( pSim+nWords, 0xFF, sizeof(word)*nWords );
+ }
+ else if ( i == 1 )
+ {
+ memset( pSim, 0xFF, sizeof(word)*nWords );
+ memset( pSim+nWords, 0x00, sizeof(word)*nWords );
+ }
+ else
+ {
+ memmove( pSim, Vec_WrdEntryP(vOn, (i-2)*nWords), sizeof(word)*nWords );
+ memmove( pSim+nWords, Vec_WrdEntryP(vOff, (i-2)*nWords), sizeof(word)*nWords );
+ }
+ }
+ Gia_ManResubPerform( p, vDivs, nWords*2, 100, 0, 50, 1, 1, 0, 0 );
+ Gia_ManResubPrint( p->vGates, Vec_PtrSize(vDivs) );
+ printf( "\n" );
+ //Vec_PtrFree( vDivs );
+ Gia_ResbFree( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Top level.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManCheckResub( Vec_Ptr_t * vDivs, int nWords )
+{
+ //int i, nVars = 6, pVarSet[10] = { 2, 189, 2127, 2125, 177, 178 };
+ int i, nVars = 3, pVarSet[10] = { 2, 3, 4 };
+ word * pOff = (word *)Vec_PtrEntry( vDivs, 0 );
+ word * pOn = (word *)Vec_PtrEntry( vDivs, 1 );
+ Vec_Int_t * vValue = Vec_IntStartFull( 1 << 6 );
+ printf( "Verifying resub:\n" );
+ for ( i = 0; i < 64*nWords; i++ )
+ {
+ int v, Mint = 0, Value = Abc_TtGetBit(pOn, i);
+ if ( !Abc_TtGetBit(pOff, i) && !Value )
+ continue;
+ for ( v = 0; v < nVars; v++ )
+ if ( Abc_TtGetBit((word *)Vec_PtrEntry(vDivs, pVarSet[v]), i) )
+ Mint |= 1 << v;
+ if ( Vec_IntEntry(vValue, Mint) == -1 )
+ Vec_IntWriteEntry(vValue, Mint, Value);
+ else if ( Vec_IntEntry(vValue, Mint) != Value )
+ printf( "Mismatch in pattern %d\n", i );
+ }
+ printf( "Finished verifying resub.\n" );
+ Vec_IntFree( vValue );
+}
+Vec_Ptr_t * Gia_ManDeriveDivs( Vec_Wrd_t * vSims, int nWords )
+{
+ int i, nDivs = Vec_WrdSize(vSims)/nWords;
+ Vec_Ptr_t * vDivs = Vec_PtrAlloc( nDivs );
+ for ( i = 0; i < nDivs; i++ )
+ Vec_PtrPush( vDivs, Vec_WrdEntryP(vSims, nWords*i) );
+ return vDivs;
+}
+Gia_Man_t * Gia_ManResub2( Gia_Man_t * pGia, int nNodes, int nSupp, int nDivs, int iChoice, int fUseXor, int fVerbose, int fVeryVerbose )
+{
+ return NULL;
+}
+Gia_Man_t * Gia_ManResub1( char * pFileName, int nNodes, int nSupp, int nDivs, int iChoice, int fUseXor, int fVerbose, int fVeryVerbose )
+{
+ int nWords = 0;
+ Gia_Man_t * pMan = NULL;
+ Vec_Wrd_t * vSims = Vec_WrdReadHex( pFileName, &nWords, 1 );
+ Vec_Ptr_t * vDivs = vSims ? Gia_ManDeriveDivs( vSims, nWords ) : NULL;
+ Gia_ResbMan_t * p = Gia_ResbAlloc( nWords );
+ //Gia_ManCheckResub( vDivs, nWords );
+ if ( Vec_PtrSize(vDivs) >= (1<<14) )
+ {
+ printf( "Reducing all divs from %d to %d.\n", Vec_PtrSize(vDivs), (1<<14)-1 );
+ Vec_PtrShrink( vDivs, (1<<14)-1 );
+ }
+ assert( Vec_PtrSize(vDivs) < (1<<14) );
+ Gia_ManResubPerform( p, vDivs, nWords, 100, 50, iChoice, fUseXor, 1, 1, 0 );
+ if ( Vec_IntSize(p->vGates) )
+ {
+ Vec_Wec_t * vGates = Vec_WecStart(1);
+ Vec_IntAppend( Vec_WecEntry(vGates, 0), p->vGates );
+ pMan = Gia_ManConstructFromGates( vGates, Vec_PtrSize(vDivs) );
+ Vec_WecFree( vGates );
+ }
+ else
+ printf( "Decomposition did not succeed.\n" );
+ Gia_ResbFree( p );
+ Vec_PtrFree( vDivs );
+ Vec_WrdFree( vSims );
+ return pMan;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManUnivTfo_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vNodes, Vec_Int_t * vPos )
+{
+ int i, iFan, Count = 1;
+ if ( Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return 0;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ if ( vNodes && Gia_ObjIsCo(Gia_ManObj(p, iObj)) )
+ Vec_IntPush( vNodes, iObj );
+ if ( vPos && Gia_ObjIsCo(Gia_ManObj(p, iObj)) )
+ Vec_IntPush( vPos, iObj );
+ Gia_ObjForEachFanoutStaticId( p, iObj, iFan, i )
+ Count += Gia_ManUnivTfo_rec( p, iFan, vNodes, vPos );
+ return Count;
+}
+int Gia_ManUnivTfo( Gia_Man_t * p, int * pObjs, int nObjs, Vec_Int_t ** pvNodes, Vec_Int_t ** pvPos )
+{
+ int i, Count = 0;
+ if ( pvNodes )
+ {
+ if ( *pvNodes )
+ Vec_IntClear( *pvNodes );
+ else
+ *pvNodes = Vec_IntAlloc( 100 );
+ }
+ if ( pvPos )
+ {
+ if ( *pvPos )
+ Vec_IntClear( *pvPos );
+ else
+ *pvPos = Vec_IntAlloc( 100 );
+ }
+ Gia_ManIncrementTravId( p );
+ for ( i = 0; i < nObjs; i++ )
+ Count += Gia_ManUnivTfo_rec( p, pObjs[i], pvNodes ? *pvNodes : NULL, pvPos ? *pvPos : NULL );
+ if ( pvNodes )
+ Vec_IntSort( *pvNodes, 0 );
+ if ( pvPos )
+ Vec_IntSort( *pvPos, 0 );
+ return Count;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Tuning resub.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManTryResub( Gia_Man_t * p )
+{
+ int nLimit = 20;
+ int nDivsMax = 200;
+ int iChoice = 0;
+ int fUseXor = 1;
+ int fDebug = 1;
+ int fVerbose = 0;
+ abctime clk, clkResub = 0, clkStart = Abc_Clock();
+ Vec_Ptr_t * vvSims = Vec_PtrAlloc( 100 );
+ Vec_Wrd_t * vSims;
+ word * pSets[2], * pFunc;
+ Gia_Obj_t * pObj, * pObj2;
+ int i, i2, nWords, nNonDec = 0, nTotal = 0;
+ assert( Gia_ManCiNum(p) < 16 );
+ Vec_WrdFreeP( &p->vSimsPi );
+ p->vSimsPi = Vec_WrdStartTruthTables( Gia_ManCiNum(p) );
+ nWords = Vec_WrdSize(p->vSimsPi) / Gia_ManCiNum(p);
+ //Vec_WrdPrintHex( p->vSimsPi, nWords );
+ pSets[0] = ABC_CALLOC( word, nWords );
+ pSets[1] = ABC_CALLOC( word, nWords );
+ vSims = Gia_ManSimPatSim( p );
+ Gia_ManLevelNum(p);
+ Gia_ManCreateRefs(p);
+ Abc_ResubPrepareManager( nWords );
+ Gia_ManStaticFanoutStart( p );
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ Vec_Int_t vGates;
+ int * pArray, nArray, nTfo, iObj = Gia_ObjId(p, pObj);
+ int Level = Gia_ObjLevel(p, pObj);
+ int nMffc = Gia_NodeMffcSizeMark(p, pObj);
+ pFunc = Vec_WrdEntryP( vSims, nWords*iObj );
+ Abc_TtCopy( pSets[0], pFunc, nWords, 1 );
+ Abc_TtCopy( pSets[1], pFunc, nWords, 0 );
+ Vec_PtrClear( vvSims );
+ Vec_PtrPushTwo( vvSims, pSets[0], pSets[1] );
+ nTfo = Gia_ManUnivTfo( p, &iObj, 1, NULL, NULL );
+ Gia_ManForEachCi( p, pObj2, i2 )
+ Vec_PtrPush( vvSims, Vec_WrdEntryP(vSims, nWords*Gia_ObjId(p, pObj2)) );
+ Gia_ManForEachAnd( p, pObj2, i2 )
+ if ( !Gia_ObjIsTravIdCurrent(p, pObj2) && !Gia_ObjIsTravIdPrevious(p, pObj2) && Gia_ObjLevel(p, pObj2) <= Level )
+ Vec_PtrPush( vvSims, Vec_WrdEntryP(vSims, nWords*Gia_ObjId(p, pObj2)) );
+ if ( fVerbose )
+ printf( "%3d : Lev = %2d Mffc = %2d Divs = %3d Tfo = %3d\n", iObj, Level, nMffc, Vec_PtrSize(vvSims)-2, nTfo );
+ clk = Abc_Clock();
+ nArray = Abc_ResubComputeFunction( (void **)Vec_PtrArray(vvSims), Vec_PtrSize(vvSims), nWords, Abc_MinInt(nMffc-1, nLimit), nDivsMax, iChoice, fUseXor, fDebug, fVerbose, &pArray );
+ clkResub += Abc_Clock() - clk;
+ vGates.nSize = vGates.nCap = nArray;
+ vGates.pArray = pArray;
+ assert( nMffc > Vec_IntSize(&vGates)/2 );
+ if ( Vec_IntSize(&vGates) > 0 )
+ nTotal += nMffc - Vec_IntSize(&vGates)/2;
+ nNonDec += Vec_IntSize(&vGates) == 0;
+ }
+ printf( "Total nodes = %5d. Non-realizable = %5d. Gain = %6d. ", Gia_ManAndNum(p), nNonDec, nTotal );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart );
+ Abc_PrintTime( 1, "Pure resub time", clkResub );
+ Abc_ResubPrepareManager( 0 );
+ Gia_ManStaticFanoutStop( p );
+ Vec_PtrFree( vvSims );
+ Vec_WrdFree( vSims );
+ ABC_FREE( pSets[0] );
+ ABC_FREE( pSets[1] );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Deriving a subset.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManDeriveShrink( Vec_Wrd_t * vFuncs, int nWords )
+{
+ int i, k = 0, nFuncs = Vec_WrdSize(vFuncs) / nWords / 2;
+ assert( 2 * nFuncs * nWords == Vec_WrdSize(vFuncs) );
+ for ( i = 0; i < nFuncs; i++ )
+ {
+ word * pFunc0 = Vec_WrdEntryP(vFuncs, (2*i+0)*nWords);
+ word * pFunc1 = Vec_WrdEntryP(vFuncs, (2*i+1)*nWords);
+ if ( Abc_TtIsConst0(pFunc0, nWords) || Abc_TtIsConst0(pFunc1, nWords) )
+ continue;
+ if ( k < i ) Abc_TtCopy( Vec_WrdEntryP(vFuncs, (2*k+0)*nWords), pFunc0, nWords, 0 );
+ if ( k < i ) Abc_TtCopy( Vec_WrdEntryP(vFuncs, (2*k+1)*nWords), pFunc1, nWords, 0 );
+ k++;
+ }
+ Vec_WrdShrink( vFuncs, 2*k*nWords );
+ return k;
+}
+void Gia_ManDeriveCounts( Vec_Wrd_t * vFuncs, int nWords, Vec_Int_t * vCounts )
+{
+ int i, nFuncs = Vec_WrdSize(vFuncs) / nWords / 2;
+ assert( 2 * nFuncs * nWords == Vec_WrdSize(vFuncs) );
+ Vec_IntClear( vCounts );
+ for ( i = 0; i < 2*nFuncs; i++ )
+ Vec_IntPush( vCounts, Abc_TtCountOnesVec(Vec_WrdEntryP(vFuncs, i*nWords), nWords) );
+}
+int Gia_ManDeriveCost( Vec_Wrd_t * vFuncs, int nWords, word * pMask, Vec_Int_t * vCounts )
+{
+ int i, Res = 0, nFuncs = Vec_WrdSize(vFuncs) / nWords / 2;
+ assert( 2 * nFuncs * nWords == Vec_WrdSize(vFuncs) );
+ assert( Vec_IntSize(vCounts) * nWords == Vec_WrdSize(vFuncs) );
+ for ( i = 0; i < nFuncs; i++ )
+ {
+ int Total[2] = { Vec_IntEntry(vCounts, 2*i+0), Vec_IntEntry(vCounts, 2*i+1) };
+ int This[2] = { Abc_TtCountOnesVecMask(Vec_WrdEntryP(vFuncs, (2*i+0)*nWords), pMask, nWords, 0),
+ Abc_TtCountOnesVecMask(Vec_WrdEntryP(vFuncs, (2*i+1)*nWords), pMask, nWords, 0) };
+ assert( Total[0] >= This[0] && Total[1] >= This[1] );
+ Res += This[0] * This[1] + (Total[0] - This[0]) * (Total[1] - This[1]);
+ }
+ return Res;
+}
+int Gia_ManDeriveSimpleCost( Vec_Int_t * vCounts )
+{
+ int i, Ent1, Ent2, Res = 0;
+ Vec_IntForEachEntryDouble( vCounts, Ent1, Ent2, i )
+ Res += Ent1*Ent2;
+ return Res;
+}
+void Gia_ManDeriveNext( Vec_Wrd_t * vFuncs, int nWords, word * pMask )
+{
+ int i, iStop = Vec_WrdSize(vFuncs); word Data;
+ int nFuncs = Vec_WrdSize(vFuncs) / nWords / 2;
+ assert( 2 * nFuncs * nWords == Vec_WrdSize(vFuncs) );
+ Vec_WrdForEachEntryStop( vFuncs, Data, i, iStop )
+ Vec_WrdPush( vFuncs, Data );
+ for ( i = 0; i < nFuncs; i++ )
+ {
+ word * pFunc0n = Vec_WrdEntryP(vFuncs, (2*i+0)*nWords);
+ word * pFunc1n = Vec_WrdEntryP(vFuncs, (2*i+1)*nWords);
+ word * pFunc0p = Vec_WrdEntryP(vFuncs, (2*i+0)*nWords + iStop);
+ word * pFunc1p = Vec_WrdEntryP(vFuncs, (2*i+1)*nWords + iStop);
+ Abc_TtAnd( pFunc0p, pFunc0n, pMask, nWords, 0 );
+ Abc_TtAnd( pFunc1p, pFunc1n, pMask, nWords, 0 );
+ Abc_TtSharp( pFunc0n, pFunc0n, pMask, nWords );
+ Abc_TtSharp( pFunc1n, pFunc1n, pMask, nWords );
+ }
+}
+Vec_Int_t * Gia_ManDeriveSubset( Gia_Man_t * p, Vec_Wrd_t * vFuncs, Vec_Int_t * vObjs, Vec_Wrd_t * vSims, int nWords, int fVerbose )
+{
+ int i, k, iObj, CostBestPrev, nFuncs = Vec_WrdSize(vFuncs) / nWords;
+ Vec_Int_t * vRes = Vec_IntAlloc( 100 );
+ Vec_Int_t * vCounts = Vec_IntAlloc( nFuncs * 2 );
+ Vec_Wrd_t * vFSims = Vec_WrdDup( vFuncs );
+ assert( nFuncs * nWords == Vec_WrdSize(vFuncs) );
+ assert( Gia_ManObjNum(p) * nWords == Vec_WrdSize(vSims) );
+ assert( Vec_IntSize(vObjs) <= Gia_ManCandNum(p) );
+ nFuncs = Gia_ManDeriveShrink( vFSims, nWords );
+ Gia_ManDeriveCounts( vFSims, nWords, vCounts );
+ assert( Vec_IntSize(vCounts) * nWords == Vec_WrdSize(vFSims) );
+ CostBestPrev = Gia_ManDeriveSimpleCost( vCounts );
+ if ( fVerbose )
+ printf( "Processing %d functions and %d objects with cost %d\n", nFuncs, Vec_IntSize(vObjs), CostBestPrev );
+ for ( i = 0; nFuncs > 0; i++ )
+ {
+ int iObjBest = -1, CountThis, Count0 = ABC_INFINITY, CountBest = ABC_INFINITY;
+ Vec_IntForEachEntry( vObjs, iObj, k )
+ {
+ if ( Vec_IntFind(vRes, iObj) >= 0 )
+ continue;
+ CountThis = Gia_ManDeriveCost( vFSims, nWords, Vec_WrdEntryP(vSims, iObj*nWords), vCounts );
+ if ( CountBest > CountThis )
+ {
+ CountBest = CountThis;
+ iObjBest = iObj;
+ }
+ if ( !k ) Count0 = CountThis;
+ }
+ if ( Count0 < CostBestPrev )
+ {
+ CountBest = Count0;
+ iObjBest = Vec_IntEntry(vObjs, 0);
+ }
+ Gia_ManDeriveNext( vFSims, nWords, Vec_WrdEntryP(vSims, iObjBest*nWords) );
+ nFuncs = Gia_ManDeriveShrink( vFSims, nWords );
+ Gia_ManDeriveCounts( vFSims, nWords, vCounts );
+ assert( CountBest == Gia_ManDeriveSimpleCost(vCounts) );
+ Vec_IntPush( vRes, iObjBest );
+ CostBestPrev = CountBest;
+ if ( fVerbose )
+ printf( "Iter %2d : Funcs = %6d. Object %6d. Cost %6d.\n", i, nFuncs, iObjBest, CountBest );
+ }
+ Vec_IntFree( vCounts );
+ Vec_WrdFree( vFSims );
+ return vRes;
+}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/aig/gia/giaResub2.c b/src/aig/gia/giaResub2.c
new file mode 100644
index 00000000..1219526f
--- /dev/null
+++ b/src/aig/gia/giaResub2.c
@@ -0,0 +1,1558 @@
+/**CFile****************************************************************
+
+ FileName [giaResub2.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaResub2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+#include "misc/util/utilTruth.h"
+#include "misc/vec/vecHsh.h"
+#include "opt/dau/dau.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Gia_Rsb2Man_t_ Gia_Rsb2Man_t;
+struct Gia_Rsb2Man_t_
+{
+ // hyper-parameters
+ int nDivsMax;
+ int nLevelIncrease;
+ int fUseXor;
+ int fUseZeroCost;
+ int fDebug;
+ int fVerbose;
+ // input AIG
+ int nObjs;
+ int nPis;
+ int nNodes;
+ int nPos;
+ int iFirstPo;
+ int Level;
+ int nMffc;
+ // intermediate data
+ Vec_Int_t vObjs;
+ Vec_Wrd_t vSims;
+ Vec_Ptr_t vpDivs;
+ Vec_Int_t vDivs;
+ Vec_Int_t vLevels;
+ Vec_Int_t vRefs;
+ Vec_Int_t vCopies;
+ Vec_Int_t vTried;
+ word Truth0;
+ word Truth1;
+ word CareSet;
+};
+
+extern void Abc_ResubPrepareManager( int nWords );
+extern int Abc_ResubComputeFunction( void ** ppDivs, int nDivs, int nWords, int nLimit, int nDivsMax, int iChoice, int fUseXor, int fDebug, int fVerbose, int ** ppArray );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Rsb2Man_t * Gia_Rsb2ManAlloc()
+{
+ Gia_Rsb2Man_t * p = ABC_CALLOC( Gia_Rsb2Man_t, 1 );
+ return p;
+}
+void Gia_Rsb2ManFree( Gia_Rsb2Man_t * p )
+{
+ Vec_IntErase( &p->vObjs );
+ Vec_WrdErase( &p->vSims );
+ Vec_PtrErase( &p->vpDivs );
+ Vec_IntErase( &p->vDivs );
+ Vec_IntErase( &p->vLevels );
+ Vec_IntErase( &p->vRefs );
+ Vec_IntErase( &p->vCopies );
+ Vec_IntErase( &p->vTried );
+ ABC_FREE( p );
+}
+void Gia_Rsb2ManStart( Gia_Rsb2Man_t * p, int * pObjs, int nObjs, int nDivsMax, int nLevelIncrease, int fUseXor, int fUseZeroCost, int fDebug, int fVerbose )
+{
+ int i;
+ // hyper-parameters
+ p->nDivsMax = nDivsMax;
+ p->nLevelIncrease = nLevelIncrease;
+ p->fUseXor = fUseXor;
+ p->fUseZeroCost = fUseZeroCost;
+ p->fDebug = fDebug;
+ p->fVerbose = fVerbose;
+ // user data
+ Vec_IntClear( &p->vObjs );
+ Vec_IntPushArray( &p->vObjs, pObjs, 2*nObjs );
+ assert( pObjs[0] == 0 );
+ assert( pObjs[1] == 0 );
+ p->nObjs = nObjs;
+ p->nPis = 0;
+ p->nNodes = 0;
+ p->nPos = 0;
+ p->iFirstPo = 0;
+ for ( i = 1; i < nObjs; i++ )
+ {
+ if ( pObjs[2*i+0] == 0 && pObjs[2*i+1] == 0 )
+ p->nPis++;
+ else if ( pObjs[2*i+0] == pObjs[2*i+1] )
+ p->nPos++;
+ else
+ p->nNodes++;
+ }
+ assert( nObjs == 1 + p->nPis + p->nNodes + p->nPos );
+ p->iFirstPo = nObjs - p->nPos;
+ Vec_WrdClear( &p->vSims );
+ Vec_WrdGrow( &p->vSims, 2*nObjs );
+ Vec_WrdPush( &p->vSims, 0 );
+ Vec_WrdPush( &p->vSims, 0 );
+ for ( i = 0; i < p->nPis; i++ )
+ {
+ Vec_WrdPush( &p->vSims, s_Truths6[i] );
+ Vec_WrdPush( &p->vSims, ~s_Truths6[i] );
+ }
+ p->vSims.nSize = 2*p->nObjs;
+ Vec_IntClear( &p->vDivs );
+ Vec_IntClear( &p->vLevels );
+ Vec_IntClear( &p->vRefs );
+ Vec_IntClear( &p->vCopies );
+ Vec_IntClear( &p->vTried );
+ Vec_PtrClear( &p->vpDivs );
+ Vec_IntGrow( &p->vDivs, nObjs );
+ Vec_IntGrow( &p->vLevels, nObjs );
+ Vec_IntGrow( &p->vRefs, nObjs );
+ Vec_IntGrow( &p->vCopies, nObjs );
+ Vec_IntGrow( &p->vTried, nObjs );
+ Vec_PtrGrow( &p->vpDivs, nObjs );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_Rsb2ManPrint( Gia_Rsb2Man_t * p )
+{
+ int i, * pObjs = Vec_IntArray( &p->vObjs );
+ printf( "PI = %d. PO = %d. Obj = %d.\n", p->nPis, p->nPos, p->nObjs );
+ for ( i = p->nPis + 1; i < p->iFirstPo; i++ )
+ printf( "%2d = %c%2d & %c%2d;\n", i,
+ Abc_LitIsCompl(pObjs[2*i+0]) ? '!' : ' ', Abc_Lit2Var(pObjs[2*i+0]),
+ Abc_LitIsCompl(pObjs[2*i+1]) ? '!' : ' ', Abc_Lit2Var(pObjs[2*i+1]) );
+ for ( i = p->iFirstPo; i < p->nObjs; i++ )
+ printf( "%2d = %c%2d;\n", i,
+ Abc_LitIsCompl(pObjs[2*i+0]) ? '!' : ' ', Abc_Lit2Var(pObjs[2*i+0]) );
+}
+
+int Gia_Rsb2ManLevel( Gia_Rsb2Man_t * p )
+{
+ int i, * pLevs, Level = 0;
+ Vec_IntClear( &p->vLevels );
+ Vec_IntGrow( &p->vLevels, p->nObjs );
+ pLevs = Vec_IntArray( &p->vLevels );
+ for ( i = p->nPis + 1; i < p->iFirstPo; i++ )
+ pLevs[i] = 1 + Abc_MaxInt( pLevs[2*i+0]/2, pLevs[2*i+1]/2 );
+ for ( i = p->iFirstPo; i < p->nObjs; i++ )
+ Level = Abc_MaxInt( Level, pLevs[i] = pLevs[2*i+0]/2 );
+ return Level;
+}
+word Gia_Rsb2ManOdcs( Gia_Rsb2Man_t * p, int iNode )
+{
+ int i; word Res = 0;
+ int * pObjs = Vec_IntArray( &p->vObjs );
+ word * pSims = Vec_WrdArray( &p->vSims );
+ for ( i = p->nPis + 1; i < p->iFirstPo; i++ )
+ {
+ if ( pObjs[2*i+0] < pObjs[2*i+1] )
+ pSims[2*i+0] = pSims[pObjs[2*i+0]] & pSims[pObjs[2*i+1]];
+ else if ( pObjs[2*i+0] > pObjs[2*i+1] )
+ pSims[2*i+0] = pSims[pObjs[2*i+0]] ^ pSims[pObjs[2*i+1]];
+ else assert( 0 );
+ pSims[2*i+1] = ~pSims[2*i+0];
+ }
+ for ( i = p->iFirstPo; i < p->nObjs; i++ )
+ pSims[2*i+0] = pSims[pObjs[2*i+0]];
+ ABC_SWAP( word, pSims[2*iNode+0], pSims[2*iNode+1] );
+ for ( i = iNode + 1; i < p->iFirstPo; i++ )
+ {
+ if ( pObjs[2*i+0] < pObjs[2*i+1] )
+ pSims[2*i+0] = pSims[pObjs[2*i+0]] & pSims[pObjs[2*i+1]];
+ else if ( pObjs[2*i+0] < pObjs[2*i+1] )
+ pSims[2*i+0] = pSims[pObjs[2*i+0]] ^ pSims[pObjs[2*i+1]];
+ else assert( 0 );
+ pSims[2*i+1] = ~pSims[2*i+0];
+ }
+ for ( i = p->iFirstPo; i < p->nObjs; i++ )
+ Res |= pSims[2*i+0] ^ pSims[pObjs[2*i+0]];
+ ABC_SWAP( word, pSims[2*iNode+0], pSims[2*iNode+1] );
+ return Res;
+}
+// marks MFFC and returns its size
+int Gia_Rsb2ManDeref_rec( Gia_Rsb2Man_t * p, int * pObjs, int * pRefs, int iNode )
+{
+ int Counter = 1;
+ if ( iNode <= p->nPis )
+ return 0;
+ if ( --pRefs[Abc_Lit2Var(pObjs[2*iNode+0])] == 0 )
+ Counter += Gia_Rsb2ManDeref_rec( p, pObjs, pRefs, Abc_Lit2Var(pObjs[2*iNode+0]) );
+ if ( --pRefs[Abc_Lit2Var(pObjs[2*iNode+1])] == 0 )
+ Counter += Gia_Rsb2ManDeref_rec( p, pObjs, pRefs, Abc_Lit2Var(pObjs[2*iNode+1]) );
+ return Counter;
+}
+int Gia_Rsb2ManMffc( Gia_Rsb2Man_t * p, int iNode )
+{
+ int i, * pRefs, * pObjs;
+ Vec_IntFill( &p->vRefs, p->nObjs, 0 );
+ pRefs = Vec_IntArray( &p->vRefs );
+ pObjs = Vec_IntArray( &p->vObjs );
+ assert( pObjs[2*iNode+0] != pObjs[2*iNode+1] );
+ for ( i = p->nPis + 1; i < p->iFirstPo; i++ )
+ pRefs[Abc_Lit2Var(pObjs[2*i+0])]++,
+ pRefs[Abc_Lit2Var(pObjs[2*i+1])]++;
+ for ( i = p->iFirstPo; i < p->nObjs; i++ )
+ pRefs[Abc_Lit2Var(pObjs[2*i+0])]++;
+ for ( i = p->nPis + 1; i < p->iFirstPo; i++ )
+ assert( pRefs[i] );
+ pRefs[iNode] = 0;
+ for ( i = iNode + 1; i < p->iFirstPo; i++ )
+ if ( !pRefs[Abc_Lit2Var(pObjs[2*i+0])] || !pRefs[Abc_Lit2Var(pObjs[2*i+1])] )
+ pRefs[i] = 0;
+ return Gia_Rsb2ManDeref_rec( p, pObjs, pRefs, iNode );
+}
+// collects divisors and maps them into nodes
+// assumes MFFC is already marked
+int Gia_Rsb2ManDivs( Gia_Rsb2Man_t * p, int iNode )
+{
+ int i, iNodeLevel = 0;
+ int * pRefs = Vec_IntArray( &p->vRefs );
+ p->CareSet = Gia_Rsb2ManOdcs( p, iNode );
+ p->Truth1 = p->CareSet & Vec_WrdEntry(&p->vSims, 2*iNode);
+ p->Truth0 = p->CareSet & ~p->Truth1;
+ Vec_PtrClear( &p->vpDivs );
+ Vec_PtrPush( &p->vpDivs, &p->Truth0 );
+ Vec_PtrPush( &p->vpDivs, &p->Truth1 );
+ Vec_IntClear( &p->vDivs );
+ Vec_IntPushTwo( &p->vDivs, -1, -1 );
+ for ( i = 1; i <= p->nPis; i++ )
+ {
+ Vec_PtrPush( &p->vpDivs, Vec_WrdEntryP(&p->vSims, 2*i) );
+ Vec_IntPush( &p->vDivs, i );
+ }
+ p->nMffc = Gia_Rsb2ManMffc( p, iNode );
+ if ( p->nLevelIncrease >= 0 )
+ {
+ p->Level = Gia_Rsb2ManLevel(p);
+ iNodeLevel = Vec_IntEntry(&p->vLevels, iNode);
+ }
+ for ( i = p->nPis + 1; i < p->iFirstPo; i++ )
+ {
+ if ( !pRefs[i] || (p->nLevelIncrease >= 0 && Vec_IntEntry(&p->vLevels, i) > iNodeLevel + p->nLevelIncrease) )
+ continue;
+ Vec_PtrPush( &p->vpDivs, Vec_WrdEntryP(&p->vSims, 2*i) );
+ Vec_IntPush( &p->vDivs, i );
+ }
+ assert( Vec_IntSize(&p->vDivs) == Vec_PtrSize(&p->vpDivs) );
+ return Vec_IntSize(&p->vDivs);
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_Rsb2AddNode( Vec_Int_t * vRes, int iLit0, int iLit1, int iRes0, int iRes1 )
+{
+ int iLitMin = iRes0 < iRes1 ? Abc_LitNotCond(iRes0, Abc_LitIsCompl(iLit0)) : Abc_LitNotCond(iRes1, Abc_LitIsCompl(iLit1));
+ int iLitMax = iRes0 < iRes1 ? Abc_LitNotCond(iRes1, Abc_LitIsCompl(iLit1)) : Abc_LitNotCond(iRes0, Abc_LitIsCompl(iLit0));
+ int iLitRes = Vec_IntSize(vRes);
+ if ( iLit0 < iLit1 ) // and
+ {
+ if ( iLitMin == 0 )
+ return 0;
+ if ( iLitMin == 1 )
+ return iLitMax;
+ if ( iLitMin == Abc_LitNot(iLitMax) )
+ return 0;
+ }
+ else if ( iLit0 > iLit1 ) // xor
+ {
+ if ( iLitMin == 0 )
+ return iLitMax;
+ if ( iLitMin == 1 )
+ return Abc_LitNot(iLitMax);
+ if ( iLitMin == Abc_LitNot(iLitMax) )
+ return 1;
+ }
+ else assert( 0 );
+ assert( iLitMin >= 2 && iLitMax >= 2 );
+ if ( iLit0 < iLit1 ) // and
+ Vec_IntPushTwo( vRes, iLitMin, iLitMax );
+ else if ( iLit0 > iLit1 ) // xor
+ {
+ assert( !Abc_LitIsCompl(iLit0) );
+ assert( !Abc_LitIsCompl(iLit1) );
+ Vec_IntPushTwo( vRes, iLitMax, iLitMin );
+ }
+ else assert( 0 );
+ return iLitRes;
+}
+int Gia_Rsb2ManInsert_rec( Vec_Int_t * vRes, int nPis, Vec_Int_t * vObjs, int iNode, Vec_Int_t * vResub, Vec_Int_t * vDivs, Vec_Int_t * vCopies, int iObj )
+{
+ if ( Vec_IntEntry(vCopies, iObj) >= 0 )
+ return Vec_IntEntry(vCopies, iObj);
+ assert( iObj > nPis );
+ if ( iObj == iNode )
+ {
+ int nVars = Vec_IntSize(vDivs);
+ int iLitRes = -1, iTopLit = Vec_IntEntryLast( vResub );
+ if ( Abc_Lit2Var(iTopLit) == 0 )
+ iLitRes = 0;
+ else if ( Abc_Lit2Var(iTopLit) < nVars )
+ iLitRes = Gia_Rsb2ManInsert_rec( vRes, nPis, vObjs, -1, vResub, vDivs, vCopies, Vec_IntEntry(vDivs, Abc_Lit2Var(iTopLit)) );
+ else
+ {
+ Vec_Int_t * vCopy = Vec_IntAlloc( 10 );
+ int k, iLit, iLit0, iLit1;
+ Vec_IntForEachEntryStop( vResub, iLit, k, Vec_IntSize(vResub)-1 )
+ if ( Abc_Lit2Var(iLit) < nVars )
+ Gia_Rsb2ManInsert_rec( vRes, nPis, vObjs, -1, vResub, vDivs, vCopies, Vec_IntEntry(vDivs, Abc_Lit2Var(iLit)) );
+ Vec_IntForEachEntryDouble( vResub, iLit0, iLit1, k )
+ {
+ int iVar0 = Abc_Lit2Var(iLit0);
+ int iVar1 = Abc_Lit2Var(iLit1);
+ int iRes0 = iVar0 < nVars ? Vec_IntEntry(vCopies, Vec_IntEntry(vDivs, iVar0)) : Vec_IntEntry(vCopy, iVar0 - nVars);
+ int iRes1 = iVar1 < nVars ? Vec_IntEntry(vCopies, Vec_IntEntry(vDivs, iVar1)) : Vec_IntEntry(vCopy, iVar1 - nVars);
+ iLitRes = Gia_Rsb2AddNode( vRes, iLit0, iLit1, iRes0, iRes1 );
+ Vec_IntPush( vCopy, iLitRes );
+ }
+ Vec_IntFree( vCopy );
+ }
+ iLitRes = Abc_LitNotCond( iLitRes, Abc_LitIsCompl(iTopLit) );
+ Vec_IntWriteEntry( vCopies, iObj, iLitRes );
+ return iLitRes;
+ }
+ else
+ {
+ int iLit0 = Vec_IntEntry( vObjs, 2*iObj+0 );
+ int iLit1 = Vec_IntEntry( vObjs, 2*iObj+1 );
+ int iRes0 = Gia_Rsb2ManInsert_rec( vRes, nPis, vObjs, iNode, vResub, vDivs, vCopies, Abc_Lit2Var(iLit0) );
+ int iRes1 = Gia_Rsb2ManInsert_rec( vRes, nPis, vObjs, iNode, vResub, vDivs, vCopies, Abc_Lit2Var(iLit1) );
+ int iLitRes = Gia_Rsb2AddNode( vRes, iLit0, iLit1, iRes0, iRes1 );
+ Vec_IntWriteEntry( vCopies, iObj, iLitRes );
+ return iLitRes;
+ }
+}
+Vec_Int_t * Gia_Rsb2ManInsert( int nPis, int nPos, Vec_Int_t * vObjs, int iNode, Vec_Int_t * vResub, Vec_Int_t * vDivs, Vec_Int_t * vCopies )
+{
+ int i, nObjs = Vec_IntSize(vObjs)/2, iFirstPo = nObjs - nPos;
+ Vec_Int_t * vRes = Vec_IntAlloc( Vec_IntSize(vObjs) );
+//Vec_IntPrint( vDivs );
+//Vec_IntPrint( vResub );
+ Vec_IntFill( vCopies, Vec_IntSize(vObjs), -1 );
+ Vec_IntFill( vRes, 2*(nPis + 1), 0 );
+ for ( i = 0; i <= nPis; i++ )
+ Vec_IntWriteEntry( vCopies, i, 2*i );
+ for ( i = iFirstPo; i < nObjs; i++ )
+ Gia_Rsb2ManInsert_rec( vRes, nPis, vObjs, iNode, vResub, vDivs, vCopies, Abc_Lit2Var( Vec_IntEntry(vObjs, 2*i) ) );
+ for ( i = iFirstPo; i < nObjs; i++ )
+ {
+ int iLitNew = Abc_Lit2LitL( Vec_IntArray(vCopies), Vec_IntEntry(vObjs, 2*i) );
+ Vec_IntPushTwo( vRes, iLitNew, iLitNew );
+ }
+ return vRes;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_ResubPrintDivs( void ** ppDivs, int nDivs )
+{
+ word ** pDivs = (word **)ppDivs;
+ int i;
+ for ( i = 0; i < nDivs; i++ )
+ {
+ printf( "Div %2d : ", i );
+ Dau_DsdPrintFromTruth( pDivs[i], 6 );
+ }
+}
+int Abc_ResubNodeToTry( Vec_Int_t * vTried, int iFirst, int iLast )
+{
+ int iNode;
+ //for ( iNode = iFirst; iNode < iLast; iNode++ )
+ for ( iNode = iLast - 1; iNode >= iFirst; iNode-- )
+ if ( Vec_IntFind(vTried, iNode) == -1 )
+ return iNode;
+ return -1;
+}
+int Abc_ResubComputeWindow( int * pObjs, int nObjs, int nDivsMax, int nLevelIncrease, int fUseXor, int fUseZeroCost, int fDebug, int fVerbose, int ** ppArray, int * pnResubs )
+{
+ int iNode, nChanges = 0, RetValue = 0;
+ Gia_Rsb2Man_t * p = Gia_Rsb2ManAlloc();
+ Gia_Rsb2ManStart( p, pObjs, nObjs, nDivsMax, nLevelIncrease, fUseXor, fUseZeroCost, fDebug, fVerbose );
+ *ppArray = NULL;
+ while ( (iNode = Abc_ResubNodeToTry(&p->vTried, p->nPis+1, p->iFirstPo)) > 0 )
+ {
+ int nDivs = Gia_Rsb2ManDivs( p, iNode );
+ int * pResub, nResub = Abc_ResubComputeFunction( Vec_PtrArray(&p->vpDivs), nDivs, 1, p->nMffc-1, nDivsMax, 0, fUseXor, fDebug, fVerbose, &pResub );
+ if ( nResub == 0 )
+ Vec_IntPush( &p->vTried, iNode );
+ else
+ {
+ int i, k = 0, iTried;
+ Vec_Int_t vResub = { nResub, nResub, pResub };
+ Vec_Int_t * vRes = Gia_Rsb2ManInsert( p->nPis, p->nPos, &p->vObjs, iNode, &vResub, &p->vDivs, &p->vCopies );
+ //printf( "\nResubing node %d:\n", iNode );
+ //Gia_Rsb2ManPrint( p );
+ p->nObjs = Vec_IntSize(vRes)/2;
+ p->iFirstPo = p->nObjs - p->nPos;
+ Vec_IntClear( &p->vObjs );
+ Vec_IntAppend( &p->vObjs, vRes );
+ Vec_IntFree( vRes );
+ Vec_IntForEachEntry( &p->vTried, iTried, i )
+ if ( Vec_IntEntry(&p->vCopies, iTried) > Abc_Var2Lit(p->nPis, 0) ) // internal node
+ Vec_IntWriteEntry( &p->vTried, k++, Abc_Lit2Var(Vec_IntEntry(&p->vCopies, iTried)) );
+ Vec_IntShrink( &p->vTried, k );
+ nChanges++;
+ //Gia_Rsb2ManPrint( p );
+ }
+ }
+ if ( nChanges )
+ {
+ RetValue = p->nObjs;
+ *ppArray = p->vObjs.pArray;
+ Vec_IntZero( &p->vObjs );
+ }
+ Gia_Rsb2ManFree( p );
+ if ( pnResubs )
+ *pnResubs = nChanges;
+ return RetValue;
+}
+int Abc_ResubComputeWindow2( int * pObjs, int nObjs, int nDivsMax, int nLevelIncrease, int fUseXor, int fUseZeroCost, int fDebug, int fVerbose, int ** ppArray, int * pnResubs )
+{
+ *ppArray = ABC_ALLOC( int, 2*nObjs );
+ memmove( *ppArray, pObjs, 2*nObjs * sizeof(int) );
+ if ( pnResubs )
+ *pnResubs = 0;
+ return nObjs;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int * Gia_ManToResub( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i, * pObjs = ABC_CALLOC( int, 2*Gia_ManObjNum(p) );
+ assert( Gia_ManIsNormalized(p) );
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ if ( Gia_ObjIsCi(pObj) )
+ continue;
+ pObjs[2*i+0] = Gia_ObjFaninLit0(Gia_ManObj(p, i), i);
+ if ( Gia_ObjIsCo(pObj) )
+ pObjs[2*i+1] = pObjs[2*i+0];
+ else if ( Gia_ObjIsAnd(pObj) )
+ pObjs[2*i+1] = Gia_ObjFaninLit1(Gia_ManObj(p, i), i);
+ else assert( 0 );
+ }
+ return pObjs;
+}
+Gia_Man_t * Gia_ManFromResub( int * pObjs, int nObjs, int nIns )
+{
+ Gia_Man_t * pNew = Gia_ManStart( nObjs );
+ int i;
+ for ( i = 1; i < nObjs; i++ )
+ {
+ if ( pObjs[2*i] == 0 && i <= nIns ) // pi
+ Gia_ManAppendCi( pNew );
+ else if ( pObjs[2*i] == pObjs[2*i+1] ) // po
+ Gia_ManAppendCo( pNew, pObjs[2*i] );
+ else if ( pObjs[2*i] < pObjs[2*i+1] )
+ Gia_ManAppendAnd( pNew, pObjs[2*i], pObjs[2*i+1] );
+ else if ( pObjs[2*i] > pObjs[2*i+1] )
+ Gia_ManAppendXor( pNew, pObjs[2*i], pObjs[2*i+1] );
+ else assert( 0 );
+ }
+ return pNew;
+}
+Gia_Man_t * Gia_ManResub2Test( Gia_Man_t * p )
+{
+ Gia_Man_t * pNew;
+ int nResubs, nObjsNew, * pObjsNew, * pObjs = Gia_ManToResub( p );
+//Gia_ManPrint( p );
+ Abc_ResubPrepareManager( 1 );
+ nObjsNew = Abc_ResubComputeWindow( pObjs, Gia_ManObjNum(p), 1000, -1, 0, 0, 0, 0, &pObjsNew, &nResubs );
+ //printf( "Performed resub %d times. Reduced %d nodes.\n", nResubs, nObjsNew ? Gia_ManObjNum(p) - nObjsNew : 0 );
+ Abc_ResubPrepareManager( 0 );
+ if ( nObjsNew )
+ {
+ pNew = Gia_ManFromResub( pObjsNew, nObjsNew, Gia_ManCiNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ }
+ else
+ pNew = Gia_ManDup( p );
+ ABC_FREE( pObjs );
+ ABC_FREE( pObjsNew );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creating a window with support composed of primary inputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+// returns the number of nodes added to the window when is iPivot is added
+// the window nodes in vNodes are labeled with the current traversal ID
+// the new node iPivot and its fanout are temporarily labeled and then unlabeled
+int Gia_WinTryAddingNode( Gia_Man_t * p, int iPivot, int iPivot2, Vec_Wec_t * vLevels, Vec_Int_t * vNodes )
+{
+ Vec_Int_t * vLevel;
+ Gia_Obj_t * pObj, * pFanout;
+ int k, i, f, Count = 0;
+ // precondition: the levelized structure is empty
+ assert( Vec_WecSizeSize(vLevels) == 0 );
+ // precondition: the new object to be added (iPivot) is not in the window
+ assert( !Gia_ObjIsTravIdCurrentId(p, iPivot) );
+ // add the object to the window and to the levelized structure
+ Gia_ObjSetTravIdCurrentId( p, iPivot );
+ Vec_WecPush( vLevels, Gia_ObjLevelId(p, iPivot), iPivot );
+ // the same about the second node if it is given
+ if ( iPivot2 != -1 )
+ {
+ // precondition: the new object to be added (iPivot2) is not in the window
+ assert( !Gia_ObjIsTravIdCurrentId(p, iPivot2) );
+ // add the object to the window and to the levelized structure
+ Gia_ObjSetTravIdCurrentId( p, iPivot2 );
+ Vec_WecPush( vLevels, Gia_ObjLevelId(p, iPivot2), iPivot2 );
+ }
+ // iterate through all objects and explore their fanouts
+ Vec_WecForEachLevel( vLevels, vLevel, k )
+ Gia_ManForEachObjVec( vLevel, p, pObj, i )
+ Gia_ObjForEachFanoutStatic( p, pObj, pFanout, f )
+ {
+ if ( f == 5 ) // explore first 5 fanouts of the node
+ break;
+ if ( Gia_ObjIsAnd(pFanout) && // internal node
+ !Gia_ObjIsTravIdCurrent(p, pFanout) && // not in the window
+ Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin0(pFanout)) && // but fanins are
+ Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin1(pFanout)) ) // in the window
+ {
+ // add fanout to the window and to the levelized structure
+ Gia_ObjSetTravIdCurrent( p, pFanout );
+ Vec_WecPush( vLevels, Gia_ObjLevel(p, pFanout), Gia_ObjId(p, pFanout) );
+ // count the number of nodes in the structure
+ Count++;
+ }
+ }
+ // iterate through the nodes in the levelized structure
+ Vec_WecForEachLevel( vLevels, vLevel, k )
+ {
+ Gia_ManForEachObjVec( vLevel, p, pObj, i )
+ if ( vNodes == NULL ) // it was a test run - unmark the node
+ Gia_ObjSetTravIdPrevious( p, pObj );
+ else // it was a real run - permanently add to the node to the window
+ Vec_IntPush( vNodes, Gia_ObjId(p, pObj) );
+ // clean the levelized structure
+ Vec_IntClear( vLevel );
+ }
+ // return the number of nodes to be added
+ return Count;
+}
+// find the first PI to add based on the fanout count
+int Gia_WinAddCiWithMaxFanouts( Gia_Man_t * p )
+{
+ int i, Id, nMaxFan = -1, iMaxFan = -1;
+ Gia_ManForEachCiId( p, Id, i )
+ if ( nMaxFan < Gia_ObjFanoutNumId(p, Id) )
+ {
+ nMaxFan = Gia_ObjFanoutNumId(p, Id);
+ iMaxFan = Id;
+ }
+ assert( iMaxFan >= 0 );
+ return iMaxFan;
+}
+// find the next PI to add based on how many nodes will be added to the window
+int Gia_WinAddCiWithMaxDivisors( Gia_Man_t * p, Vec_Wec_t * vLevels )
+{
+ int i, Id, nCurFan, nMaxFan = -1, iMaxFan = -1;
+ Gia_ManForEachCiId( p, Id, i )
+ {
+ if ( Gia_ObjIsTravIdCurrentId( p, Id ) )
+ continue;
+ nCurFan = Gia_WinTryAddingNode( p, Id, -1, vLevels, NULL );
+ if ( nMaxFan < nCurFan )
+ {
+ nMaxFan = nCurFan;
+ iMaxFan = Id;
+ }
+ }
+ assert( iMaxFan >= 0 );
+ return iMaxFan;
+}
+// check if the node has unmarked fanouts
+int Gia_WinNodeHasUnmarkedFanouts( Gia_Man_t * p, int iPivot )
+{
+ int f, iFan;
+ Gia_ObjForEachFanoutStaticId( p, iPivot, iFan, f )
+ if ( !Gia_ObjIsTravIdCurrentId(p, iFan) )
+ return 1;
+ return 0;
+}
+// this is a translation procedure, which converts the array of node IDs (vObjs)
+// into the internal represnetation for the resub engine, which is returned
+// (this procedure is not needed when we simply construct a window)
+Vec_Int_t * Gia_RsbCiTranslate( Gia_Man_t * p, Vec_Int_t * vObjs, Vec_Int_t * vMap )
+{
+ int i, iObj, Lit0, Lit1, Fan0, Fan1;
+ Vec_Int_t * vNodes = Vec_IntAlloc( 100 );
+ assert( Vec_IntSize(vMap) == Gia_ManObjNum(p) );
+ Vec_IntPushTwo( vNodes, 0, 0 ); // const0 node
+ Vec_IntForEachEntry( vObjs, iObj, i )
+ {
+ Gia_Obj_t * pObj = Gia_ManObj(p, iObj);
+ assert( Gia_ObjIsTravIdCurrentId(p, iObj) );
+ Fan0 = Gia_ObjIsCi(pObj) ? 0 : Vec_IntEntry(vMap, Gia_ObjFaninId0(pObj, iObj));
+ Fan1 = Gia_ObjIsCi(pObj) ? 0 : Vec_IntEntry(vMap, Gia_ObjFaninId1(pObj, iObj));
+ Lit0 = Gia_ObjIsCi(pObj) ? 0 : Abc_LitNotCond( Fan0, Gia_ObjFaninC0(pObj) );
+ Lit1 = Gia_ObjIsCi(pObj) ? 0 : Abc_LitNotCond( Fan1, Gia_ObjFaninC1(pObj) );
+ Vec_IntWriteEntry( vMap, iObj, Vec_IntSize(vNodes) );
+ Vec_IntPushTwo( vNodes, Lit0, Lit1 );
+ }
+ Vec_IntForEachEntry( vObjs, iObj, i )
+ if ( Gia_WinNodeHasUnmarkedFanouts( p, iObj ) )
+ Vec_IntPushTwo( vNodes, Vec_IntEntry(vMap, iObj), Vec_IntEntry(vMap, iObj) );
+ return vNodes;
+}
+// construct a high-volume window support by the given number (nPis) of primary inputs
+Vec_Int_t * Gia_RsbCiWindow( Gia_Man_t * p, int nPis )
+{
+ Vec_Int_t * vRes; int i, iMaxFan;
+ Vec_Int_t * vNodes = Vec_IntAlloc( 100 );
+ Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) );
+ Vec_Wec_t * vLevels = Vec_WecStart( Gia_ManLevelNum(p)+1 );
+ Gia_ManStaticFanoutStart( p );
+ Gia_ManIncrementTravId(p);
+ // add the first one
+ iMaxFan = Gia_WinAddCiWithMaxFanouts( p );
+ Gia_ObjSetTravIdCurrentId( p, iMaxFan );
+ Vec_IntPush( vNodes, iMaxFan );
+ // add remaining ones
+ for ( i = 1; i < nPis; i++ )
+ {
+ iMaxFan = Gia_WinAddCiWithMaxDivisors( p, vLevels );
+ Gia_WinTryAddingNode( p, iMaxFan, -1, vLevels, vNodes );
+ }
+ Vec_IntSort( vNodes, 0 );
+ vRes = Gia_RsbCiTranslate( p, vNodes, vMap );
+ Gia_ManStaticFanoutStop( p );
+ Vec_WecFree( vLevels );
+ Vec_IntFree( vMap );
+//Vec_IntPrint( vNodes );
+ Vec_IntFree( vNodes );
+ return vRes;
+}
+void Gia_RsbCiWindowTest( Gia_Man_t * p )
+{
+ Vec_Int_t * vWin = Gia_RsbCiWindow( p, 6 );
+ //Vec_IntPrint( vWin );
+ Vec_IntFree( vWin );
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Return initial window for the given node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Gia_ObjFaninId( Gia_Obj_t * pObj, int iObj, int n ) { return n ? Gia_ObjFaninId1(pObj, iObj) : Gia_ObjFaninId0(pObj, iObj); }
+
+static inline int Gia_ObjTravIsTopTwo( Gia_Man_t * p, int iNodeA ) { return (p->pTravIds[iNodeA] >= p->nTravIds - 1); }
+static inline int Gia_ObjTravIsSame( Gia_Man_t * p, int iNodeA, int iNodeB ) { return (p->pTravIds[iNodeA] == p->pTravIds[iNodeB]); }
+static inline void Gia_ObjTravSetSame( Gia_Man_t * p, int iNodeA, int iNodeB ) { p->pTravIds[iNodeA] = p->pTravIds[iNodeB]; }
+
+// collect nodes on the path from the meeting point to the root node, excluding the meeting point
+void Gia_RsbWindowGather( Gia_Man_t * p, Vec_Int_t * vPaths, int iNode, Vec_Int_t * vVisited )
+{
+ int iPrev;
+ if ( iNode == 0 )
+ return;
+ Vec_IntPush( vVisited, iNode );
+ iPrev = Vec_IntEntry( vPaths, iNode );
+ if ( iPrev == 0 )
+ return;
+ assert( Gia_ObjTravIsSame(p, iPrev, iNode) );
+ Gia_RsbWindowGather( p, vPaths, iPrev, vVisited );
+}
+// explore the frontier of nodes in the breadth-first traversal
+int Gia_RsbWindowExplore( Gia_Man_t * p, Vec_Int_t * vVisited, int iStart, Vec_Int_t * vPaths, int * piMeet, int * piNode )
+{
+ int i, n, iObj, iLimit = Vec_IntSize( vVisited );
+ *piMeet = *piNode = 0;
+ Vec_IntForEachEntryStartStop( vVisited, iObj, i, iStart, iLimit )
+ {
+ Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
+ if ( !Gia_ObjIsAnd(pObj) )
+ continue;
+ for ( n = 0; n < 2; n++ )
+ {
+ int iFan = Gia_ObjFaninId( pObj, iObj, n );
+ // if the node was visited on the paths to both fanins, collect it
+ if ( Gia_ObjTravIsTopTwo(p, iObj) && Gia_ObjTravIsTopTwo(p, iFan) && !Gia_ObjTravIsSame(p, iObj, iFan) )
+ {
+ *piMeet = iFan;
+ *piNode = iObj;
+ return 1;
+ }
+ // if the node was visited already on this path, skip it
+ if ( Gia_ObjTravIsTopTwo(p, iFan) )
+ {
+ assert( Gia_ObjTravIsSame(p, iObj, iFan) );
+ continue;
+ }
+ // label the node as visited
+ Gia_ObjTravSetSame( p, iFan, iObj );
+ Vec_IntWriteEntry( vPaths, iFan, iObj );
+ Vec_IntPush( vVisited, iFan );
+ }
+ }
+ return 0;
+}
+Vec_Int_t * Gia_RsbWindowInit( Gia_Man_t * p, Vec_Int_t * vPaths, int iPivot, int nIter )
+{
+ Vec_Int_t * vVisited = Vec_IntAlloc( 100 );
+ Gia_Obj_t * pPivot = Gia_ManObj( p, iPivot );
+ int i, n, iStart = 0;
+ assert( Gia_ObjIsAnd(pPivot) );
+ // start paths for both fanins of the pivot node
+ for ( n = 0; n < 2; n++ )
+ {
+ int iFan = Gia_ObjFaninId( pPivot, iPivot, n );
+ Gia_ManIncrementTravId(p);
+ Vec_IntPush( vVisited, iFan );
+ Vec_IntWriteEntry( vPaths, iFan, 0 );
+ Gia_ObjSetTravIdCurrentId( p, iFan );
+ }
+ // perform several iterations of breadth-first search
+ for ( i = 0; i < nIter; i++ )
+ {
+ int iMeet, iNode, iNext = Vec_IntSize(vVisited);
+ if ( Gia_RsbWindowExplore( p, vVisited, iStart, vPaths, &iMeet, &iNode ) )
+ {
+ // found the shared path
+ if ( Gia_ObjIsTravIdCurrentId(p, iMeet) )
+ assert( Gia_ObjIsTravIdPreviousId(p, iNode) );
+ else if ( Gia_ObjIsTravIdPreviousId(p, iMeet) )
+ assert( Gia_ObjIsTravIdCurrentId(p, iNode) );
+ else assert( 0 );
+ // collect the initial window
+ Vec_IntClear( vVisited );
+ Gia_RsbWindowGather( p, vPaths, Vec_IntEntry(vPaths, iMeet), vVisited );
+ Gia_RsbWindowGather( p, vPaths, iNode, vVisited );
+ Vec_IntPush( vVisited, iPivot );
+ break;
+ }
+ iStart = iNext;
+ }
+ // if no meeting point is found, make sure to return NULL
+ if ( i == nIter )
+ Vec_IntFreeP( &vVisited );
+ return vVisited;
+}
+Vec_Int_t * Gia_RsbCreateWindowInputs( Gia_Man_t * p, Vec_Int_t * vWin )
+{
+ Vec_Int_t * vInputs = Vec_IntAlloc(10);
+ Gia_Obj_t * pObj; int i, n, iObj;
+ Gia_ManIncrementTravId(p);
+ Gia_ManForEachObjVec( vWin, p, pObj, i )
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ Gia_ManForEachObjVec( vWin, p, pObj, i )
+ {
+ assert( Gia_ObjIsAnd(pObj) );
+ for ( n = 0; n < 2; n++ )
+ {
+ int iFan = n ? Gia_ObjFaninId1p(p, pObj) : Gia_ObjFaninId0p(p, pObj);
+ if ( !Gia_ObjIsTravIdCurrentId(p, iFan) )
+ Vec_IntPushUnique( vInputs, iFan );
+ }
+ }
+ Vec_IntForEachEntry( vInputs, iObj, i )
+ {
+ Gia_ObjSetTravIdCurrentId( p, iObj );
+ Vec_IntPush( vWin, iObj );
+ }
+ return vInputs;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Grow window for the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_RsbAddSideInputs( Gia_Man_t * p, Vec_Wec_t * vLevels, Vec_Int_t * vWin )
+{
+ Vec_Int_t * vLevel;
+ Gia_Obj_t * pObj, * pFanout;
+ int k, i, f, iObj;
+ // precondition: the levelized structure is empty
+ assert( Vec_WecSizeSize(vLevels) == 0 );
+ // precondition: window nodes are labeled with the current ID
+ Vec_IntForEachEntry( vWin, iObj, i )
+ {
+ assert( Gia_ObjIsTravIdCurrentId(p, iObj) );
+ Vec_WecPush( vLevels, Gia_ObjLevelId(p, iObj), iObj );
+ }
+ // iterate through all objects and explore their fanouts
+ Vec_WecForEachLevel( vLevels, vLevel, k )
+ Gia_ManForEachObjVec( vLevel, p, pObj, i )
+ Gia_ObjForEachFanoutStatic( p, pObj, pFanout, f )
+ {
+ if ( f == 5 ) // explore first 5 fanouts of the node
+ break;
+ if ( Gia_ObjIsAnd(pFanout) && // internal node
+ !Gia_ObjIsTravIdCurrent(p, pFanout) && // not in the window
+ Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin0(pFanout)) && // but fanins are
+ Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin1(pFanout)) ) // in the window
+ {
+ // add fanout to the window and to the levelized structure
+ Gia_ObjSetTravIdCurrent( p, pFanout );
+ Vec_WecPush( vLevels, Gia_ObjLevel(p, pFanout), Gia_ObjId(p, pFanout) );
+ Vec_IntPush( vWin, Gia_ObjId(p, pFanout) );
+ }
+ }
+ // iterate through the nodes in the levelized structure
+ Vec_WecForEachLevel( vLevels, vLevel, k )
+ Vec_IntClear( vLevel );
+}
+// expland inputs until saturation while adding the side-fanouts
+void Gia_RsbExpandInputs( Gia_Man_t * p, Vec_Wec_t * vLevels, Vec_Int_t * vWin, Vec_Int_t * vInputs )
+{
+ Gia_Obj_t * pObj;
+ int i, n, iFans[2], fChange = 1;
+ while ( fChange )
+ {
+ fChange = 0;
+ Gia_ManForEachObjVec( vInputs, p, pObj, i )
+ {
+ if ( !Gia_ObjIsAnd(pObj) )
+ continue;
+ iFans[0] = Gia_ObjFaninId0p(p, pObj);
+ iFans[1] = Gia_ObjFaninId1p(p, pObj);
+ if ( !Gia_ObjIsTravIdCurrentId(p, iFans[0]) && !Gia_ObjIsTravIdCurrentId(p, iFans[1]) )
+ continue;
+ Vec_IntRemove( vInputs, Gia_ObjId(p, pObj) );
+ assert( Vec_IntFind(vWin, Gia_ObjId(p, pObj)) >= 0 );
+ for ( n = 0; n < 2; n++ )
+ {
+ if ( Gia_ObjIsTravIdCurrentId(p, iFans[n]) )
+ continue;
+ assert( Vec_IntFind(vInputs, iFans[n]) == -1 );
+ Vec_IntPush( vInputs, iFans[n] );
+ Gia_WinTryAddingNode( p, iFans[n], -1, vLevels, vWin );
+ assert( Gia_ObjIsTravIdCurrentId(p, iFans[n]) );
+ }
+ fChange = 1;
+ }
+ }
+}
+// select the best input to expand, based on its contribution to the window size
+int Gia_RsbSelectOneInput( Gia_Man_t * p, Vec_Wec_t * vLevels, Vec_Int_t * vIns )
+{
+ int i, iNode = 0, WeightThis, WeightBest = -1;
+ Gia_Obj_t * pObj;
+ Gia_ManForEachObjVec( vIns, p, pObj, i )
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ int iFan0 = Gia_ObjFaninId0p(p, pObj);
+ int iFan1 = Gia_ObjFaninId1p(p, pObj);
+ assert( !Gia_ObjIsTravIdCurrentId(p, iFan0) && !Gia_ObjIsTravIdCurrentId(p, iFan1) );
+ WeightThis = Gia_WinTryAddingNode( p, iFan0, iFan1, vLevels, NULL );
+ if ( WeightBest < WeightThis )
+ {
+ WeightBest = WeightThis;
+ iNode = Gia_ObjId(p, pObj);
+ }
+ }
+ return iNode;
+}
+// grow the initial window as long as it fits the input count limit
+void Gia_RsbWindowGrow( Gia_Man_t * p, Vec_Wec_t * vLevels, Vec_Int_t * vWin, Vec_Int_t * vIns, int nInputsMax )
+{
+ int iNode;
+ Gia_RsbAddSideInputs( p, vLevels, vWin );
+ Gia_RsbExpandInputs( p, vLevels, vWin, vIns );
+ while ( Vec_IntSize(vIns) < nInputsMax && (iNode = Gia_RsbSelectOneInput(p, vLevels, vIns)) )
+ {
+ int iFan0 = Gia_ObjFaninId0p(p, Gia_ManObj(p, iNode));
+ int iFan1 = Gia_ObjFaninId1p(p, Gia_ManObj(p, iNode));
+ assert( !Gia_ObjIsTravIdCurrentId(p, iFan0) && !Gia_ObjIsTravIdCurrentId(p, iFan1) );
+ Gia_WinTryAddingNode( p, iFan0, iFan1, vLevels, vWin );
+ assert( Gia_ObjIsTravIdCurrentId(p, iFan0) && Gia_ObjIsTravIdCurrentId(p, iFan1) );
+ Vec_IntRemove( vIns, iNode );
+ Vec_IntPushTwo( vIns, iFan0, iFan1 );
+ Gia_RsbExpandInputs( p, vLevels, vWin, vIns );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Grow window for the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_WinCreateFromCut_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vWin )
+{
+ Gia_Obj_t * pObj;
+ if ( Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ pObj = Gia_ManObj( p, iObj );
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_WinCreateFromCut_rec( p, Gia_ObjFaninId0(pObj, iObj), vWin );
+ Gia_WinCreateFromCut_rec( p, Gia_ObjFaninId1(pObj, iObj), vWin );
+ Vec_IntPush( vWin, iObj );
+}
+// uses levelized structure (vLevels) to collect in array vWin divisors supported by the cut (vIn)
+void Gia_WinCreateFromCut( Gia_Man_t * p, int iPivot, Vec_Int_t * vIn, Vec_Wec_t * vLevels, Vec_Int_t * vWin )
+{
+ Vec_Int_t * vLevel;
+ Gia_Obj_t * pObj, * pFanout;
+ int k, i, f, iObj, Level;
+ Vec_Int_t * vUsed = Vec_IntAlloc( 100 );
+ // precondition: the levelized structure is empty
+ assert( Vec_WecSizeSize(vLevels) == 0 );
+ // clean the resulting array
+ Vec_IntClear( vWin );
+ // collect leaves
+ Gia_ManIncrementTravId( p );
+ Vec_IntForEachEntry( vIn, iObj, i )
+ {
+ Gia_ObjSetTravIdCurrentId( p, iObj );
+ Vec_IntPush( vWin, iObj );
+ }
+ // collect internal cone
+ Gia_WinCreateFromCut_rec( p, iPivot, vWin );
+ // add nodes to the levelized structure
+ Vec_IntForEachEntry( vWin, iObj, i )
+ {
+ Vec_WecPush( vLevels, Gia_ObjLevelId(p, iObj), iObj );
+ Vec_IntPushUniqueOrder( vUsed, Gia_ObjLevelId(p, iObj) );
+ }
+ // iterate through all objects and explore their fanouts
+ //Vec_WecForEachLevel( vLevels, vLevel, k )
+ Vec_IntForEachEntry( vUsed, Level, k )
+ {
+ vLevel = Vec_WecEntry( vLevels, Level );
+ Gia_ManForEachObjVec( vLevel, p, pObj, i )
+ Gia_ObjForEachFanoutStatic( p, pObj, pFanout, f )
+ {
+ if ( f == 5 ) // explore first 5 fanouts of the node
+ break;
+ if ( Gia_ObjIsAnd(pFanout) && // internal node
+ !Gia_ObjIsTravIdCurrent(p, pFanout) && // not in the window
+ Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin0(pFanout)) && // but fanins are
+ Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin1(pFanout)) ) // in the window
+ {
+ // add fanout to the window and to the levelized structure
+ Gia_ObjSetTravIdCurrent( p, pFanout );
+ Vec_WecPush( vLevels, Gia_ObjLevel(p, pFanout), Gia_ObjId(p, pFanout) );
+ Vec_IntPush( vWin, Gia_ObjId(p, pFanout) );
+ Vec_IntPushUniqueOrder( vUsed, Gia_ObjLevel(p, pFanout) );
+ }
+ }
+ Vec_IntClear( vLevel );
+ }
+ Vec_IntSort( vWin, 0 );
+ Vec_IntFree( vUsed );
+}
+// update the cut until both fanins of AND nodes are not in the cut
+int Gia_RsbExpandCut( Gia_Man_t * p, Vec_Int_t * vIns )
+{
+ int fOnlyPis = 0, fChange = 1, nSize = Vec_IntSize(vIns);
+ while ( fChange )
+ {
+ Gia_Obj_t * pObj;
+ int i, iFan0, iFan1, fHave0, fHave1;
+ fOnlyPis = 1;
+ fChange = 0;
+ // check if some nodes can be expanded without increasing cut size
+ Gia_ManForEachObjVec( vIns, p, pObj, i )
+ {
+ assert( Gia_ObjIsTravIdCurrent(p, pObj) );
+ if ( !Gia_ObjIsAnd(pObj) )
+ continue;
+ fOnlyPis = 0;
+ iFan0 = Gia_ObjFaninId0p(p, pObj);
+ iFan1 = Gia_ObjFaninId1p(p, pObj);
+ fHave0 = Gia_ObjIsTravIdCurrentId(p, iFan0);
+ fHave1 = Gia_ObjIsTravIdCurrentId(p, iFan1);
+ if ( !fHave0 && !fHave1 )
+ continue;
+ // can expand because one of the fanins is already in the cut
+ // remove current cut node
+ Vec_IntDrop( vIns, i );
+ // add missing fanin
+ if ( !fHave0 )
+ {
+ Vec_IntPush( vIns, iFan0 );
+ Gia_ObjSetTravIdCurrentId( p, iFan0 );
+ }
+ if ( !fHave1 )
+ {
+ Vec_IntPush( vIns, iFan1 );
+ Gia_ObjSetTravIdCurrentId( p, iFan1 );
+ }
+ fChange = 1;
+ break;
+ }
+ }
+ assert( Vec_IntSize(vIns) <= nSize );
+ return fOnlyPis;
+}
+int Gia_RsbFindFaninAdd( int iFan, int pFanins[32], int pFaninCounts[32], int nFanins )
+{
+ int i;
+ for ( i = 0; i < nFanins; i++ )
+ if ( pFanins[i] == iFan )
+ break;
+ pFanins[i] = iFan;
+ pFaninCounts[i]++;
+ return nFanins + (i == nFanins);
+}
+int Gia_RsbFindFaninToAddToCut( Gia_Man_t * p, Vec_Int_t * vIns )
+{
+ Gia_Obj_t * pObj;
+ int nFanins = 0, pFanins[64] = {0}, pFaninCounts[64] = {0};
+ int i, iFan0, iFan1, iFanMax = -1, CountMax = 0;
+ Gia_ManForEachObjVec( vIns, p, pObj, i )
+ {
+ if ( !Gia_ObjIsAnd(pObj) )
+ continue;
+ iFan0 = Gia_ObjFaninId0p(p, pObj);
+ iFan1 = Gia_ObjFaninId1p(p, pObj);
+ assert( !Gia_ObjIsTravIdCurrentId(p, iFan0) );
+ assert( !Gia_ObjIsTravIdCurrentId(p, iFan1) );
+ nFanins = Gia_RsbFindFaninAdd( iFan0, pFanins, pFaninCounts, nFanins );
+ nFanins = Gia_RsbFindFaninAdd( iFan1, pFanins, pFaninCounts, nFanins );
+ assert( nFanins < 64 );
+ }
+ // find fanin with the highest count
+ if ( p->vFanoutNums != NULL )
+ {
+ for ( i = 0; i < nFanins; i++ )
+ if ( CountMax < pFaninCounts[i] || (CountMax == pFaninCounts[i] && (Gia_ObjFanoutNumId(p, iFanMax) < Gia_ObjFanoutNumId(p, pFanins[i]))) )
+ {
+ CountMax = pFaninCounts[i];
+ iFanMax = pFanins[i];
+ }
+ }
+ else
+ {
+ for ( i = 0; i < nFanins; i++ )
+ if ( CountMax < pFaninCounts[i] || (CountMax == pFaninCounts[i] && (Gia_ObjRefNumId(p, iFanMax) < Gia_ObjRefNumId(p, pFanins[i]))) )
+ {
+ CountMax = pFaninCounts[i];
+ iFanMax = pFanins[i];
+ }
+ }
+ return iFanMax;
+}
+// precondition: nodes in vWin and in vIns are marked with the current ID
+void Gia_RsbWindowGrow2( Gia_Man_t * p, int iObj, Vec_Wec_t * vLevels, Vec_Int_t * vWin, Vec_Int_t * vIns, int nInputsMax )
+{
+ // window will be recomputed later
+ Vec_IntClear( vWin );
+ // expand the cut without increasing its cost
+ if ( !Gia_RsbExpandCut( p, vIns ) )
+ {
+ // save it as the best cut
+ Vec_Int_t * vBest = Vec_IntSize(vIns) <= nInputsMax ? Vec_IntDup(vIns) : NULL;
+ int fOnlyPis = 0, Iter = 0;
+ // iterate expansion until
+ // (1) the cut cannot be expanded because all leaves are PIs
+ // (2) the cut size exceeded the limit for 5 consecutive iterations
+ while ( !fOnlyPis && (Vec_IntSize(vIns) <= nInputsMax || Iter < 5) )
+ {
+ int iFanBest = Gia_RsbFindFaninToAddToCut( p, vIns );
+ Vec_IntPush( vIns, iFanBest );
+ Gia_ObjSetTravIdCurrentId( p, iFanBest );
+ fOnlyPis = Gia_RsbExpandCut( p, vIns );
+ if ( Vec_IntSize(vIns) > nInputsMax )
+ Iter++;
+ else
+ Iter = 0;
+ if ( Vec_IntSize(vIns) <= nInputsMax && (!vBest || Vec_IntSize(vBest) <= Vec_IntSize(vIns)) )
+ {
+ if ( vBest )
+ Vec_IntClear(vBest);
+ else
+ vBest = Vec_IntAlloc( 10 );
+ Vec_IntAppend( vBest, vIns );
+ }
+ }
+ if ( vBest )
+ {
+ Vec_IntClear( vIns );
+ Vec_IntAppend( vIns, vBest );
+ Vec_IntFree( vBest );
+ }
+ else
+ assert( Vec_IntSize(vIns) > nInputsMax );
+ }
+ if ( vLevels && Vec_IntSize(vIns) <= nInputsMax )
+ {
+ Vec_IntSort( vIns, 0 );
+ Gia_WinCreateFromCut( p, iObj, vIns, vLevels, vWin );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Create window for the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_RsbWindowCompute( Gia_Man_t * p, int iObj, int nInputsMax, int nLevelsMax, Vec_Wec_t * vLevels, Vec_Int_t * vPaths, Vec_Int_t ** pvWin, Vec_Int_t ** pvIns )
+{
+ Vec_Int_t * vWin, * vIns;
+ *pvWin = *pvIns = NULL;
+ vWin = Gia_RsbWindowInit( p, vPaths, iObj, nLevelsMax );
+ if ( vWin == NULL )
+ return 0;
+ vIns = Gia_RsbCreateWindowInputs( p, vWin );
+ // vWin and vIns are labeled with the current trav ID
+ //Vec_IntPrint( vWin );
+ //Vec_IntPrint( vIns );
+ if ( Vec_IntSize(vIns) <= nInputsMax + 3 ) // consider windows, which initially has a larger input space
+ Gia_RsbWindowGrow2( p, iObj, vLevels, vWin, vIns, nInputsMax );
+ if ( Vec_IntSize(vIns) <= nInputsMax )
+ {
+ Vec_IntSort( vWin, 0 );
+ Vec_IntSort( vIns, 0 );
+ *pvWin = vWin;
+ *pvIns = vIns;
+ return 1;
+ }
+ else
+ {
+ Vec_IntFree( vWin );
+ Vec_IntFree( vIns );
+ return 0;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derive GIA from the window]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_RsbFindOutputs( Gia_Man_t * p, Vec_Int_t * vWin, Vec_Int_t * vIns, Vec_Int_t * vRefs )
+{
+ Vec_Int_t * vOuts = Vec_IntAlloc( 100 );
+ Gia_Obj_t * pObj; int i;
+ Gia_ManIncrementTravId( p );
+ Gia_ManForEachObjVec( vIns, p, pObj, i )
+ Gia_ObjSetTravIdCurrent( p, pObj );
+ Gia_ManForEachObjVec( vWin, p, pObj, i )
+ if ( !Gia_ObjIsTravIdCurrent(p, pObj) && Gia_ObjIsAnd(pObj) )
+ {
+ Vec_IntAddToEntry( vRefs, Gia_ObjFaninId0p(p, pObj), 1 );
+ Vec_IntAddToEntry( vRefs, Gia_ObjFaninId1p(p, pObj), 1 );
+ }
+ Gia_ManForEachObjVec( vWin, p, pObj, i )
+ if ( !Gia_ObjIsTravIdCurrent(p, pObj) && Gia_ObjFanoutNum(p, pObj) != Vec_IntEntry(vRefs, Gia_ObjId(p, pObj)) )
+ Vec_IntPush( vOuts, Gia_ObjId(p, pObj) );
+ Gia_ManForEachObjVec( vWin, p, pObj, i )
+ if ( !Gia_ObjIsTravIdCurrent(p, pObj) && Gia_ObjIsAnd(pObj) )
+ {
+ Vec_IntAddToEntry( vRefs, Gia_ObjFaninId0p(p, pObj), -1 );
+ Vec_IntAddToEntry( vRefs, Gia_ObjFaninId1p(p, pObj), -1 );
+ }
+ return vOuts;
+}
+
+Gia_Man_t * Gia_RsbDeriveGiaFromWindows( Gia_Man_t * p, Vec_Int_t * vWin, Vec_Int_t * vIns, Vec_Int_t * vOuts )
+{
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj;
+ int i;
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManHashAlloc( pNew );
+ Gia_ManFillValue( p );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachObjVec( vIns, p, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ Gia_ManForEachObjVec( vWin, p, pObj, i )
+ if ( !~pObj->Value )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ Gia_ManForEachObjVec( vOuts, p, pObj, i )
+ Gia_ManAppendCo( pNew, pObj->Value );
+ Gia_ManHashStop( pNew );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Naive truth-table-based verification.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+word Gia_LutComputeTruth66_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ word Truth0, Truth1;
+ if ( Gia_ObjIsCi(pObj) )
+ return s_Truths6[Gia_ObjCioId(pObj)];
+ if ( Gia_ObjIsConst0(pObj) )
+ return 0;
+ assert( Gia_ObjIsAnd(pObj) );
+ Truth0 = Gia_LutComputeTruth66_rec( p, Gia_ObjFanin0(pObj) );
+ Truth1 = Gia_LutComputeTruth66_rec( p, Gia_ObjFanin1(pObj) );
+ if ( Gia_ObjFaninC0(pObj) )
+ Truth0 = ~Truth0;
+ if ( Gia_ObjFaninC1(pObj) )
+ Truth1 = ~Truth1;
+ return Truth0 & Truth1;
+}
+int Gia_ManVerifyTwoTruths( Gia_Man_t * p1, Gia_Man_t * p2 )
+{
+ int i, fFailed = 0;
+ assert( Gia_ManCoNum(p1) == Gia_ManCoNum(p2) );
+ for ( i = 0; i < Gia_ManCoNum(p1); i++ )
+ {
+ Gia_Obj_t * pPo1 = Gia_ManCo(p1, i);
+ Gia_Obj_t * pPo2 = Gia_ManCo(p2, i);
+ word word1 = Gia_LutComputeTruth66_rec( p1, Gia_ObjFanin0(pPo1) );
+ word word2 = Gia_LutComputeTruth66_rec( p2, Gia_ObjFanin0(pPo2) );
+ if ( Gia_ObjFaninC0(pPo1) )
+ word1 = ~word1;
+ if ( Gia_ObjFaninC0(pPo2) )
+ word2 = ~word2;
+ if ( word1 != word2 )
+ {
+ //Dau_DsdPrintFromTruth( &word1, 6 );
+ //Dau_DsdPrintFromTruth( &word2, 6 );
+ printf( "Verification failed for output %d (out of %d).\n", i, Gia_ManCoNum(p1) );
+ fFailed = 1;
+ }
+ }
+// if ( !fFailed )
+// printf( "Verification succeeded for %d outputs.\n", Gia_ManCoNum(p1) );
+ return !fFailed;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Enumerate windows of the nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_RsbEnumerateWindows( Gia_Man_t * p, int nInputsMax, int nLevelsMax )
+{
+ int fVerbose = 0;
+ int fUseHash = 0;
+ int i, nWins = 0, nWinSize = 0, nInsSize = 0, nOutSize = 0, nNodeGain = 0;
+ Vec_Wec_t * vLevels = Vec_WecStart( Gia_ManLevelNum(p)+1 );
+ Vec_Int_t * vPaths = Vec_IntStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vRefs = Vec_IntStart( Gia_ManObjNum(p) );
+ Hsh_VecMan_t * pHash = Hsh_VecManStart( 1000 );
+ Gia_Obj_t * pObj;
+ Gia_Man_t * pIn, * pOut;
+ abctime clk = Abc_Clock();
+ Gia_ManStaticFanoutStart( p );
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ Vec_Int_t * vWin, * vIns, * vOuts;
+ if ( !Gia_RsbWindowCompute( p, i, nInputsMax, nLevelsMax, vLevels, vPaths, &vWin, &vIns ) )
+ continue;
+ vOuts = Gia_RsbFindOutputs( p, vWin, vIns, vRefs );
+ nWins++;
+ nWinSize += Vec_IntSize(vWin);
+ nInsSize += Vec_IntSize(vIns);
+ nOutSize += Vec_IntSize(vOuts);
+
+
+ if ( fVerbose )
+ {
+ printf( "\n\nObj %d\n", i );
+ Vec_IntPrint( vWin );
+ Vec_IntPrint( vIns );
+ Vec_IntPrint( vOuts );
+ printf( "\n" );
+ }
+ else if ( Vec_IntSize(vWin) > 1000 )
+ printf( "Obj %d. Window: Ins = %d. Ands = %d. Outs = %d.\n",
+ i, Vec_IntSize(vIns), Vec_IntSize(vWin)-Vec_IntSize(vIns), Vec_IntSize(vOuts) );
+
+ if ( fUseHash )
+ {
+ int nEntries = Hsh_VecSize(pHash);
+ Hsh_VecManAdd( pHash, vWin );
+ if ( nEntries == Hsh_VecSize(pHash) )
+ {
+ Vec_IntFree( vWin );
+ Vec_IntFree( vIns );
+ Vec_IntFree( vOuts );
+ continue;
+ }
+ }
+
+ pIn = Gia_RsbDeriveGiaFromWindows( p, vWin, vIns, vOuts );
+ pOut = Gia_ManResub2Test( pIn );
+ //pOut = Gia_ManDup( pIn );
+ if ( !Gia_ManVerifyTwoTruths( pIn, pOut ) )
+ {
+ Gia_ManPrint( pIn );
+ Gia_ManPrint( pOut );
+ pOut = pOut;
+ }
+
+ nNodeGain += Gia_ManAndNum(pIn) - Gia_ManAndNum(pOut);
+ Gia_ManStop( pIn );
+ Gia_ManStop( pOut );
+
+ Vec_IntFree( vWin );
+ Vec_IntFree( vIns );
+ Vec_IntFree( vOuts );
+ }
+ Gia_ManStaticFanoutStop( p );
+ Vec_WecFree( vLevels );
+ Vec_IntFree( vPaths );
+ Vec_IntFree( vRefs );
+ printf( "Computed windows for %d nodes (out of %d). Unique = %d. Ave inputs = %.2f. Ave outputs = %.2f. Ave volume = %.2f. Gain = %d. ",
+ nWins, Gia_ManAndNum(p), Hsh_VecSize(pHash), 1.0*nInsSize/Abc_MaxInt(1,nWins),
+ 1.0*nOutSize/Abc_MaxInt(1,nWins), 1.0*nWinSize/Abc_MaxInt(1,nWins), nNodeGain );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ Hsh_VecManStop( pHash );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Apply k-resub to one AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_RsbTryOneWindow( Gia_Man_t * p )
+{
+ return Gia_ManResub2Test( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Apply k-resub to one AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_RsbTestArray()
+{
+ int Array[1000] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 3, 7, 15, 17, 8, 19,
+ 5, 20, 5, 12, 8, 24, 4, 12, 9, 28, 27, 31, 23, 32, 4, 13, 8, 36, 5,
+ 13, 18, 40, 9, 18, 5, 44, 19, 36, 9, 48, 47, 51, 10, 18, 40, 54, 8,
+ 56, 25, 37, 44, 61, 59, 63, 8, 28, 8, 18, 25, 68, 66, 70, 64, 73, 11,
+ 19, 8, 13, 76, 78, 10, 19, 40, 82, 9, 84, 81, 87, 20, 61, 19, 28, 30,
+ 92, 91, 95, 88, 96, 74, 98, 9, 40, 49, 103, 27, 104, 10, 107, 8, 40,
+ 9, 24, 111, 113, 11, 115, 109, 117, 11, 66, 51, 121, 118, 122, 18, 36,
+ 18, 110, 93, 127, 10, 131, 129, 133, 11, 38, 32, 137, 103, 138, 19, 141,
+ 134, 143, 28, 76, 9, 146, 11, 110, 19, 150, 149, 153, 87, 95, 9, 19, 10,
+ 159, 61, 160, 18, 30, 61, 158, 9, 12, 25, 169, 19, 171, 111, 173, 10, 175,
+ 167, 177, 18, 102, 4, 20, 18, 171, 183, 185, 11, 187, 181, 189, 178, 190,
+ 24, 44, 11, 194, 8, 54, 4, 198, 197, 201, 45, 49, 10, 39, 9, 126, 73, 209,
+ 11, 211, 54, 168, 213, 215, 43, 167, 67, 218, 10, 221, 26, 54, 18, 18, 34,
+ 34, 38, 38, 40, 40, 42, 42, 52, 52, 100, 100, 124, 124, 126, 126, 144, 144,
+ 148, 148, 154, 154, 156, 156, 162, 162, 164, 164, 192, 192, 70, 70, 202,
+ 202, 204, 204, 206, 206, 216, 216, 222, 222, 224, 224
+ };
+ int i, iFan0, iFan1, nResubs;
+ int * pRes;
+ // create the internal array
+ Vec_Int_t * vArray = Vec_IntAlloc( 100 );
+ for ( i = 0; i < 50 || Array[i] > 0; i++ )
+ Vec_IntPush( vArray, Array[i] );
+ Vec_IntPrint( vArray );
+ // check the nodes
+ printf( "Constant0 and primary inputs:\n" );
+ Vec_IntForEachEntryDouble( vArray, iFan0, iFan1, i )
+ {
+ if ( iFan0 != iFan1 )
+ break;
+ printf( "%2d = %c%2d & %c%2d;\n", i,
+ Abc_LitIsCompl(iFan0) ? '!' : ' ', Abc_Lit2Var(iFan0),
+ Abc_LitIsCompl(iFan1) ? '!' : ' ', Abc_Lit2Var(iFan1) );
+ }
+ printf( "Primary outputs:\n" );
+ Vec_IntForEachEntryDoubleStart( vArray, iFan0, iFan1, i, 14 )
+ {
+ if ( iFan0 != iFan1 )
+ continue;
+ printf( "%2d = %c%2d & %c%2d;\n", i,
+ Abc_LitIsCompl(iFan0) ? '!' : ' ', Abc_Lit2Var(iFan0),
+ Abc_LitIsCompl(iFan1) ? '!' : ' ', Abc_Lit2Var(iFan1) );
+ }
+ // run the resub
+ Abc_ResubPrepareManager( 1 );
+ Abc_ResubComputeWindow( Vec_IntArray(vArray), Vec_IntSize(vArray)/2, 10, -1, 0, 0, 1, 1, &pRes, &nResubs );
+ Abc_ResubPrepareManager( 0 );
+ Vec_IntFree( vArray );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computing cuts of the nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Wec_t * Gia_ManExtractCuts2( Gia_Man_t * p, int nCutSize, int nCuts, int fVerbose )
+{
+ int c, nLevelMax = 8;
+ abctime clk = Abc_Clock();
+ Vec_Wec_t * vCuts = Vec_WecStart( nCuts );
+ Vec_Int_t * vPaths = Vec_IntStart( Gia_ManObjNum(p) );
+ srand( time(NULL) );
+ for ( c = 0; c < nCuts; )
+ {
+ Vec_Int_t * vCut, * vWin = NULL;
+ while ( vWin == NULL )
+ {
+ int iPivot = 1 + Gia_ManCiNum(p) + rand() % Gia_ManAndNum(p);
+ assert( Gia_ObjIsAnd(Gia_ManObj(p, iPivot)) );
+ vWin = Gia_RsbWindowInit( p, vPaths, iPivot, nLevelMax );
+ }
+ vCut = Gia_RsbCreateWindowInputs( p, vWin );
+ if ( Vec_IntSize(vCut) >= nCutSize - 2 && Vec_IntSize(vCut) <= nCutSize )
+ {
+ Vec_IntPush( Vec_WecEntry(vCuts, c), Vec_IntSize(vCut) );
+ Vec_IntAppend( Vec_WecEntry(vCuts, c++), vCut );
+ }
+ Vec_IntFree( vCut );
+ Vec_IntFree( vWin );
+ }
+ Vec_IntFree( vPaths );
+ Abc_PrintTime( 0, "Computing cuts ", Abc_Clock() - clk );
+ return vCuts;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaResub3.c b/src/aig/gia/giaResub3.c
new file mode 100644
index 00000000..71e182d1
--- /dev/null
+++ b/src/aig/gia/giaResub3.c
@@ -0,0 +1,54 @@
+/**CFile****************************************************************
+
+ FileName [giaResub3.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Resubstitution computation.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaResub3.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManPerformNewResub( Gia_Man_t * p, int nWinCount, int nCutSize, int nProcs, int fVerbose )
+{
+ return NULL;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaScript.c b/src/aig/gia/giaScript.c
index 334b1ee9..b52288a9 100644
--- a/src/aig/gia/giaScript.c
+++ b/src/aig/gia/giaScript.c
@@ -88,7 +88,12 @@ Gia_Man_t * Gia_ManAigSyn2( Gia_Man_t * pInit, int fOldAlgo, int fCoarsen, int f
p = Gia_ManDup( pInit );
Gia_ManTransferTiming( p, pInit );
if ( Gia_ManAndNum(p) == 0 )
- return p;
+ {
+ pNew = Gia_ManDup(p);
+ Gia_ManTransferTiming( pNew, p );
+ Gia_ManStop( p );
+ return pNew;
+ }
// delay optimization
if ( fDelayMin && p->pManTime == NULL )
{
@@ -157,7 +162,12 @@ Gia_Man_t * Gia_ManAigSyn3( Gia_Man_t * p, int fVerbose, int fVeryVerbose )
pPars->nRelaxRatio = 40;
if ( fVerbose ) Gia_ManPrintStats( p, NULL );
if ( Gia_ManAndNum(p) == 0 )
- return Gia_ManDup(p);
+ {
+ pNew = Gia_ManDup(p);
+ Gia_ManTransferTiming( pNew, p );
+ //Gia_ManStop( p );
+ return pNew;
+ }
// perform balancing
pNew = Gia_ManAreaBalance( p, 0, ABC_INFINITY, fVeryVerbose, 0 );
if ( fVerbose ) Gia_ManPrintStats( pNew, NULL );
@@ -189,7 +199,12 @@ Gia_Man_t * Gia_ManAigSyn4( Gia_Man_t * p, int fVerbose, int fVeryVerbose )
pPars->nRelaxRatio = 40;
if ( fVerbose ) Gia_ManPrintStats( p, NULL );
if ( Gia_ManAndNum(p) == 0 )
- return Gia_ManDup(p);
+ {
+ pNew = Gia_ManDup(p);
+ Gia_ManTransferTiming( pNew, p );
+ //Gia_ManStop( p );
+ return pNew;
+ }
//Gia_ManAigPrintPiLevels( p );
// perform balancing
pNew = Gia_ManAreaBalance( p, 0, ABC_INFINITY, fVeryVerbose, 0 );
diff --git a/src/aig/gia/giaSim.c b/src/aig/gia/giaSim.c
index 001bd8ac..ecad182f 100644
--- a/src/aig/gia/giaSim.c
+++ b/src/aig/gia/giaSim.c
@@ -1222,6 +1222,172 @@ int Gia_ManIncrSimCheckEqual( Gia_Man_t * p, int iLit0, int iLit1 )
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSimOneBit( Gia_Man_t * p, Vec_Int_t * vValues )
+{
+ Gia_Obj_t * pObj; int k;
+ assert( Vec_IntSize(vValues) == Gia_ManCiNum(p) );
+
+ Gia_ManConst0(p)->fMark0 = 0;
+ Gia_ManForEachCi( p, pObj, k )
+ pObj->fMark0 = Vec_IntEntry(vValues, k);
+ Gia_ManForEachAnd( p, pObj, k )
+ pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj));
+ Gia_ManForEachCo( p, pObj, k )
+ pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj);
+
+ Gia_ManForEachCi( p, pObj, k )
+ printf( "%d", k % 10 );
+ printf( "\n" );
+ Gia_ManForEachCi( p, pObj, k )
+ printf( "%d", Vec_IntEntry(vValues, k) );
+ printf( "\n" );
+
+ Gia_ManForEachCo( p, pObj, k )
+ printf( "%d", k % 10 );
+ printf( "\n" );
+ Gia_ManForEachCo( p, pObj, k )
+ printf( "%d", pObj->fMark0 );
+ printf( "\n" );
+ printf( "\n" );
+}
+void Gia_ManSimOneBitTest2( Gia_Man_t * p )
+{
+ Vec_Int_t * vValues = Vec_IntStart( Gia_ManCiNum(p) );
+
+ Vec_IntWriteEntry( vValues, 0, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntWriteEntry( vValues, 0, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntWriteEntry( vValues, 0, 1 );
+ Vec_IntWriteEntry( vValues, 1, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2+2, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntWriteEntry( vValues, 0, 1 );
+ Vec_IntWriteEntry( vValues, 1, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntFill( vValues, Vec_IntSize(vValues)/2, 1 );
+ Vec_IntFillExtra( vValues, Gia_ManCiNum(p), 0 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Gia_ManCiNum(p), 0 );
+
+ Vec_IntFill( vValues, Gia_ManCiNum(p), 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Gia_ManCiNum(p), 0 );
+
+ Vec_IntFill( vValues, Gia_ManCiNum(p), 1 );
+ Vec_IntWriteEntry( vValues, 127, 1 );
+ Vec_IntWriteEntry( vValues, 255, 0 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Gia_ManCiNum(p), 0 );
+
+ Vec_IntFill( vValues, Gia_ManCiNum(p), 1 );
+ Vec_IntWriteEntry( vValues, 127, 0 );
+ Vec_IntWriteEntry( vValues, 255, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Gia_ManCiNum(p), 0 );
+
+ Vec_IntFill( vValues, Gia_ManCiNum(p), 1 );
+ Vec_IntWriteEntry( vValues, 127, 0 );
+ Vec_IntWriteEntry( vValues, 255, 0 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Gia_ManCiNum(p), 0 );
+
+ Vec_IntFree( vValues );
+}
+void Gia_ManSimOneBitTest3( Gia_Man_t * p )
+{
+ Vec_Int_t * vValues = Vec_IntStart( Gia_ManCiNum(p) );
+
+ Vec_IntWriteEntry( vValues, 0, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntWriteEntry( vValues, 0, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntWriteEntry( vValues, 0, 1 );
+ Vec_IntWriteEntry( vValues, 1, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2+2, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-1, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -1, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-1, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-2, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -1, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -2, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-2, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -2, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-1, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-2, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-3, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -1, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -2, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -3, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-2, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-3, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -2, 1 );
+ Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -3, 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 1 );
+ Gia_ManSimOneBit( p, vValues );
+ Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
+
+ Vec_IntFree( vValues );
+}
+
+
+void Gia_ManSimOneBitTest( Gia_Man_t * p )
+{
+ Vec_Int_t * vValues = Vec_IntStart( Gia_ManCiNum(p) );
+ int i, k;
+ for ( i = 0; i < 10; i++ )
+ {
+ for ( k = 0; k < Vec_IntSize(vValues); k++ )
+ Vec_IntWriteEntry( vValues, k, Vec_IntEntry(vValues, k) ^ (rand()&1) );
+
+ printf( "Values = %d ", Vec_IntSum(vValues) );
+ Gia_ManSimOneBit( p, vValues );
+ }
+}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c
index c53c1db8..c31064fe 100644
--- a/src/aig/gia/giaSimBase.c
+++ b/src/aig/gia/giaSimBase.c
@@ -21,6 +21,7 @@
#include "gia.h"
#include "misc/util/utilTruth.h"
#include "misc/extra/extra.h"
+//#include <immintrin.h>
ABC_NAMESPACE_IMPL_START
@@ -112,7 +113,13 @@ static inline void Gia_ManSimPatSimPo( Gia_Man_t * p, int i, Gia_Obj_t * pObj, i
word * pSims0 = pSims + nWords*Gia_ObjFaninId0(pObj, i);
word * pSims2 = pSims + nWords*i; int w;
for ( w = 0; w < nWords; w++ )
- pSims2[w] = (pSims0[w] ^ Diff0);
+ pSims2[w] = (pSims0[w] ^ Diff0);
+}
+static inline void Gia_ManSimPatSimNot( Gia_Man_t * p, int i, Gia_Obj_t * pObj, int nWords, Vec_Wrd_t * vSims )
+{
+ word * pSims = Vec_WrdArray(vSims) + nWords*i; int w;
+ for ( w = 0; w < nWords; w++ )
+ pSims[w] = ~pSims[w];
}
Vec_Wrd_t * Gia_ManSimPatSim( Gia_Man_t * pGia )
{
@@ -127,6 +134,427 @@ Vec_Wrd_t * Gia_ManSimPatSim( Gia_Man_t * pGia )
Gia_ManSimPatSimPo( pGia, Gia_ObjId(pGia, pObj), pObj, nWords, vSims );
return vSims;
}
+Vec_Wrd_t * Gia_ManSimPatSimOut( Gia_Man_t * pGia, Vec_Wrd_t * vSimsPi, int fOuts )
+{
+ Gia_Obj_t * pObj;
+ int i, nWords = Vec_WrdSize(vSimsPi) / Gia_ManCiNum(pGia);
+ Vec_Wrd_t * vSimsCo = fOuts ? Vec_WrdStart( Gia_ManCoNum(pGia) * nWords ) : NULL;
+ Vec_Wrd_t * vSims = Vec_WrdStart( Gia_ManObjNum(pGia) * nWords );
+ assert( Vec_WrdSize(vSimsPi) % Gia_ManCiNum(pGia) == 0 );
+ Gia_ManSimPatAssignInputs( pGia, nWords, vSims, vSimsPi );
+ Gia_ManForEachAnd( pGia, pObj, i )
+ Gia_ManSimPatSimAnd( pGia, i, pObj, nWords, vSims );
+ Gia_ManForEachCo( pGia, pObj, i )
+ Gia_ManSimPatSimPo( pGia, Gia_ObjId(pGia, pObj), pObj, nWords, vSims );
+ if ( !fOuts )
+ return vSims;
+ Gia_ManForEachCo( pGia, pObj, i )
+ memcpy( Vec_WrdEntryP(vSimsCo, i*nWords), Vec_WrdEntryP(vSims, Gia_ObjId(pGia, pObj)*nWords), sizeof(word)*nWords );
+ Vec_WrdFree( vSims );
+ return vSimsCo;
+}
+static inline void Gia_ManSimPatSimAnd3( Gia_Man_t * p, int i, Gia_Obj_t * pObj, int nWords, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsC )
+{
+ word pComps[2] = { ~(word)0, 0 };
+ word Diff0 = pComps[Gia_ObjFaninC0(pObj)];
+ word Diff1 = pComps[Gia_ObjFaninC1(pObj)];
+ word * pSims0 = Vec_WrdArray(vSims) + nWords*Gia_ObjFaninId0(pObj, i);
+ word * pSims1 = Vec_WrdArray(vSims) + nWords*Gia_ObjFaninId1(pObj, i);
+ word * pSims2 = Vec_WrdArray(vSims) + nWords*i;
+ word * pSimsC0 = Vec_WrdArray(vSimsC) + nWords*Gia_ObjFaninId0(pObj, i);
+ word * pSimsC1 = Vec_WrdArray(vSimsC) + nWords*Gia_ObjFaninId1(pObj, i);
+ word * pSimsC2 = Vec_WrdArray(vSimsC) + nWords*i; int w;
+ if ( Gia_ObjIsXor(pObj) )
+ for ( w = 0; w < nWords; w++ )
+ {
+ pSimsC0[w] |= pSimsC2[w];
+ pSimsC1[w] |= pSimsC2[w];
+ }
+ else
+ for ( w = 0; w < nWords; w++ )
+ {
+ pSimsC0[w] |= (pSims2[w] | (pSims0[w] ^ Diff0)) & pSimsC2[w];
+ pSimsC1[w] |= (pSims2[w] | (pSims1[w] ^ Diff1)) & pSimsC2[w];
+ }
+}
+Vec_Wrd_t * Gia_ManSimPatSimIn( Gia_Man_t * pGia, Vec_Wrd_t * vSims, int fIns, Vec_Int_t * vAnds )
+{
+ Gia_Obj_t * pObj;
+ int i, Id, nWords = Vec_WrdSize(vSims) / Gia_ManObjNum(pGia);
+ Vec_Wrd_t * vSimsCi = fIns ? Vec_WrdStart( Gia_ManCiNum(pGia) * nWords ) : NULL;
+ Vec_Wrd_t * vSimsC = Vec_WrdStart( Vec_WrdSize(vSims) );
+ assert( Vec_WrdSize(vSims) % Gia_ManObjNum(pGia) == 0 );
+ if ( vAnds )
+ Vec_IntForEachEntry( vAnds, Id, i )
+ memset( Vec_WrdEntryP(vSimsC, Id*nWords), 0xFF, sizeof(word)*nWords );
+ else
+ Gia_ManForEachCoDriverId( pGia, Id, i )
+ memset( Vec_WrdEntryP(vSimsC, Id*nWords), 0xFF, sizeof(word)*nWords );
+ Gia_ManForEachAndReverse( pGia, pObj, i )
+ Gia_ManSimPatSimAnd3( pGia, i, pObj, nWords, vSims, vSimsC );
+ if ( !fIns )
+ return vSimsC;
+ Gia_ManForEachCi( pGia, pObj, i )
+ memcpy( Vec_WrdEntryP(vSimsCi, i*nWords), Vec_WrdEntryP(vSimsC, Gia_ObjId(pGia, pObj)*nWords), sizeof(word)*nWords );
+ Vec_WrdFree( vSimsC );
+ return vSimsCi;
+}
+void Gia_ManSimPatSimInTest( Gia_Man_t * pGia )
+{
+ int nWords = 10;
+ Vec_Wrd_t * vSimsCi = Vec_WrdStartRandom( Gia_ManCiNum(pGia) * nWords );
+ Vec_Wrd_t * vSims = Gia_ManSimPatSimOut( pGia, vSimsCi, 0 );
+ Vec_Wrd_t * vSims2 = Gia_ManSimPatSimIn( pGia, vSims, 0, NULL );
+ int nOnes = Abc_TtCountOnesVec( Vec_WrdArray(vSims2), Vec_WrdSize(vSims2) );
+ int nTotal = 64*nWords*Gia_ManCandNum(pGia);
+ printf( "Ratio = %6.2f %%\n", 100.0*nOnes/nTotal );
+ Vec_WrdFree( vSims );
+ Vec_WrdFree( vSims2 );
+ Vec_WrdFree( vSimsCi );
+}
+static inline void Gia_ManSimPatSimAnd4( Gia_Man_t * p, int i, Gia_Obj_t * pObj, int nWords, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsC )
+{
+ word pComps[2] = { ~(word)0, 0 };
+ word Diff0 = pComps[Gia_ObjFaninC0(pObj)];
+ word Diff1 = pComps[Gia_ObjFaninC1(pObj)];
+ word * pSims0 = Vec_WrdArray(vSims) + nWords*Gia_ObjFaninId0(pObj, i);
+ word * pSims1 = Vec_WrdArray(vSims) + nWords*Gia_ObjFaninId1(pObj, i);
+ word * pSimsC0 = Vec_WrdArray(vSimsC) + nWords*Gia_ObjFaninId0(pObj, i);
+ word * pSimsC1 = Vec_WrdArray(vSimsC) + nWords*Gia_ObjFaninId1(pObj, i);
+ word * pSimsC2 = Vec_WrdArray(vSimsC) + nWords*i; int w;
+ if ( Gia_ObjIsXor(pObj) )
+ for ( w = 0; w < nWords; w++ )
+ pSimsC2[w] = pSimsC0[w] & pSimsC1[w];
+ else
+ for ( w = 0; w < nWords; w++ )
+ pSimsC2[w] = (pSimsC0[w] & pSimsC1[w]) | ((pSims0[w] ^ Diff0) & pSimsC0[w]) | ((pSims1[w] ^ Diff1) & pSimsC1[w]);
+}
+Vec_Wrd_t * Gia_ManSimPatSimC( Gia_Man_t * pGia, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsCiC )
+{
+ Gia_Obj_t * pObj;
+ int i, Id, nWords = Vec_WrdSize(vSims) / Gia_ManObjNum(pGia);
+ Vec_Wrd_t * vSimsC = Vec_WrdStart( Vec_WrdSize(vSims) );
+ assert( Vec_WrdSize(vSims) % Gia_ManObjNum(pGia) == 0 );
+ memset( Vec_WrdEntryP(vSimsC, 0), 0xFF, sizeof(word)*nWords );
+ Gia_ManForEachCiId( pGia, Id, i )
+ memmove( Vec_WrdEntryP(vSimsC, Id*nWords), Vec_WrdEntryP(vSimsCiC, i*nWords), sizeof(word)*nWords );
+ Gia_ManForEachAnd( pGia, pObj, i )
+ Gia_ManSimPatSimAnd4( pGia, i, pObj, nWords, vSims, vSimsC );
+ return vSimsC;
+}
+void Gia_ManSimPatSimCTest( Gia_Man_t * pGia )
+{
+ int nWords = 10;
+ Vec_Wrd_t * vSimsCi = Vec_WrdStartRandom( Gia_ManCiNum(pGia) * nWords );
+ Vec_Wrd_t * vSims = Gia_ManSimPatSimOut( pGia, vSimsCi, 0 );
+ Vec_Wrd_t * vSims2 = Gia_ManSimPatSimIn( pGia, vSims, 0, NULL );
+ Vec_Wrd_t * vSimsCi2 = Gia_ManSimPatSimIn( pGia, vSims, 1, NULL );
+ Vec_Wrd_t * vSims3 = Gia_ManSimPatSimC( pGia, vSims, vSimsCi2 );
+ int nOnes2 = Abc_TtCountOnesVec( Vec_WrdArray(vSims2), Vec_WrdSize(vSims2) );
+ int nOnes3 = Abc_TtCountOnesVec( Vec_WrdArray(vSims3), Vec_WrdSize(vSims3) );
+ int nTotal = 64*nWords*Gia_ManCandNum(pGia);
+ printf( "Ratio = %6.2f %% Ratio = %6.2f %%\n", 100.0*nOnes2/nTotal, 100.0*nOnes3/nTotal );
+ Vec_WrdFree( vSims );
+ Vec_WrdFree( vSims2 );
+ Vec_WrdFree( vSims3 );
+ Vec_WrdFree( vSimsCi );
+ Vec_WrdFree( vSimsCi2 );
+}
+void Gia_ManSimPatResim( Gia_Man_t * pGia, Vec_Int_t * vObjs, int nWords, Vec_Wrd_t * vSims )
+{
+ Gia_Obj_t * pObj; int i;
+ Gia_ManForEachObjVec( vObjs, pGia, pObj, i )
+ if ( i == 0 )
+ Gia_ManSimPatSimNot( pGia, Gia_ObjId(pGia, pObj), pObj, nWords, vSims );
+ else if ( Gia_ObjIsAnd(pObj) )
+ Gia_ManSimPatSimAnd( pGia, Gia_ObjId(pGia, pObj), pObj, nWords, vSims );
+ else if ( !Gia_ObjIsCo(pObj) ) assert(0);
+}
+void Gia_ManSimPatWrite( char * pFileName, Vec_Wrd_t * vSimsIn, int nWords )
+{
+ Vec_WrdDumpHex( pFileName, vSimsIn, nWords, 0 );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+word * Gia_ManDeriveFuncs( Gia_Man_t * p )
+{
+ int nVars2 = (Gia_ManCiNum(p) + 6)/2;
+ int nVars3 = Gia_ManCiNum(p) - nVars2;
+ int nWords = Abc_Truth6WordNum( Gia_ManCiNum(p) );
+ int nWords2 = Abc_Truth6WordNum( nVars2 );
+ word * pRes = ABC_ALLOC( word, Gia_ManCoNum(p) * nWords );
+ Vec_Wrd_t * vSims = Vec_WrdStart( nWords2 * Gia_ManObjNum(p) );
+ Vec_Ptr_t * vTruths = Vec_PtrAllocTruthTables( nVars2 );
+ Gia_Obj_t * pObj; int i, v, m;
+ Gia_ManForEachCi( p, pObj, i )
+ assert( Gia_ObjId(p, pObj) == i+1 );
+ for ( i = 0; i < nVars2; i++ )
+ Abc_TtCopy( Vec_WrdEntryP(vSims, nWords2*(i+1)), (word *)Vec_PtrEntry(vTruths, i), nWords2, 0 );
+ Vec_PtrFree( vTruths );
+ for ( m = 0; m < (1 << nVars3); m++ )
+ {
+ for ( v = 0; v < nVars3; v++ )
+ Abc_TtConst( Vec_WrdEntryP(vSims, nWords2*(nVars2+v+1)), nWords2, (m >> v) & 1 );
+ Gia_ManForEachAnd( p, pObj, i )
+ Gia_ManSimPatSimAnd( p, i, pObj, nWords2, vSims );
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManSimPatSimPo( p, Gia_ObjId(p, pObj), pObj, nWords2, vSims );
+ Gia_ManForEachCo( p, pObj, i )
+ Abc_TtCopy( pRes + i*nWords + m*nWords2, Vec_WrdEntryP(vSims, nWords2*Gia_ObjId(p, pObj)), nWords2, 0 );
+ }
+ Vec_WrdFree( vSims );
+ return pRes;
+}
+Gia_Man_t * Gia_ManPerformMuxDec( Gia_Man_t * p )
+{
+ extern int Gia_ManFindMuxTree_rec( Gia_Man_t * pNew, int * pCtrl, int nCtrl, Vec_Int_t * vData, int Shift );
+ extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash );
+ int nWords = Abc_Truth6WordNum( Gia_ManCiNum(p) );
+ int nCofs = 1 << (Gia_ManCiNum(p) - 6);
+ word * pRes = Gia_ManDeriveFuncs( p );
+ Vec_Int_t * vMemory = Vec_IntAlloc( 1 << 16 );
+ Vec_Int_t * vLeaves = Vec_IntAlloc( 6 );
+ Vec_Int_t * vCtrls = Vec_IntAlloc( nCofs );
+ Vec_Int_t * vDatas = Vec_IntAlloc( Gia_ManCoNum(p) );
+ Gia_Man_t * pNew, * pTemp; int i, o;
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManConst0(p)->Value = 0;
+ for ( i = 0; i < Gia_ManCiNum(p); i++ )
+ Vec_IntPush( i < 6 ? vLeaves : vCtrls, Gia_ManAppendCi(pNew) );
+ Gia_ManHashAlloc( pNew );
+ for ( o = 0; o < Gia_ManCoNum(p); o++ )
+ {
+ Vec_IntClear( vDatas );
+ for ( i = 0; i < nWords; i++ )
+ Vec_IntPush( vDatas, Kit_TruthToGia(pNew, (unsigned *)(pRes+o*nWords+i), 6, vMemory, vLeaves, 1) );
+ Gia_ManAppendCo( pNew, Gia_ManFindMuxTree_rec(pNew, Vec_IntArray(vCtrls), Vec_IntSize(vCtrls), vDatas, 0) );
+ }
+ Gia_ManHashStop( pNew );
+ ABC_FREE( pRes );
+ Vec_IntFree( vMemory );
+ Vec_IntFree( vLeaves );
+ Vec_IntFree( vCtrls );
+ Vec_IntFree( vDatas );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ Gia_ManTransferTiming( pNew, p );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManComputeTfos_rec( Gia_Man_t * p, int iObj, int iRoot, Vec_Int_t * vNode )
+{
+ Gia_Obj_t * pObj;
+ if ( Gia_ObjIsTravIdPreviousId(p, iObj) )
+ return 1;
+ if ( Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return 0;
+ pObj = Gia_ManObj( p, iObj );
+ if ( !Gia_ObjIsAnd(pObj) )
+ return 0;
+ if ( Gia_ManComputeTfos_rec( p, Gia_ObjFaninId0(pObj, iObj), iRoot, vNode ) |
+ Gia_ManComputeTfos_rec( p, Gia_ObjFaninId1(pObj, iObj), iRoot, vNode ) )
+ {
+ Gia_ObjSetTravIdPreviousId(p, iObj);
+ Vec_IntPush( vNode, iObj );
+ return 1;
+ }
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ return 0;
+}
+Vec_Wec_t * Gia_ManComputeTfos( Gia_Man_t * p )
+{
+ Vec_Wec_t * vNodes = Vec_WecStart( Gia_ManCiNum(p) );
+ Vec_Int_t * vTemp = Vec_IntAlloc( 100 );
+ int i, o, IdCi, IdCo;
+ Gia_ManForEachCiId( p, IdCi, i )
+ {
+ Vec_Int_t * vNode = Vec_WecEntry( vNodes, i );
+ Gia_ManIncrementTravId( p );
+ Gia_ManIncrementTravId( p );
+ Gia_ObjSetTravIdPreviousId(p, IdCi);
+ Vec_IntPush( vNode, IdCi );
+ Vec_IntClear( vTemp );
+ Gia_ManForEachCoId( p, IdCo, o )
+ if ( Gia_ManComputeTfos_rec( p, Gia_ObjFaninId0(Gia_ManObj(p, IdCo), IdCo), IdCi, vNode ) )
+ Vec_IntPush( vTemp, Gia_ManObjNum(p) + (o >> 1) );
+ Vec_IntUniqify( vTemp );
+ Vec_IntAppend( vNode, vTemp );
+ }
+ Vec_IntFree( vTemp );
+ Vec_WecSort( vNodes, 1 );
+ //Vec_WecPrint( vNodes, 0 );
+ //Gia_AigerWrite( p, "dump.aig", 0, 0, 0 );
+ return vNodes;
+}
+int Gia_ManFindDividerVar( Gia_Man_t * p, int fVerbose )
+{
+ int iVar, Target = 1 << 28;
+ for ( iVar = 6; iVar < Gia_ManCiNum(p); iVar++ )
+ if ( (1 << (iVar-3)) * Gia_ManObjNum(p) > Target )
+ break;
+ if ( iVar == Gia_ManCiNum(p) )
+ iVar = Gia_ManCiNum(p) - 1;
+ if ( fVerbose )
+ printf( "Split var = %d. Rounds = %d. Bytes per node = %d. Total = %.2f MB.\n", iVar, 1 << (Gia_ManCiNum(p) - iVar), 1 << (iVar-3), 1.0*(1 << (iVar-3)) * Gia_ManObjNum(p)/(1<<20) );
+ return iVar;
+}
+int Gia_ManComparePair( Gia_Man_t * p, Vec_Wrd_t * vSims, int iOut, int nWords2 )
+{
+ Gia_Obj_t * pObj0 = Gia_ManCo( p, 2*iOut+0 );
+ Gia_Obj_t * pObj1 = Gia_ManCo( p, 2*iOut+1 );
+ word * pSim0 = Vec_WrdEntryP( vSims, nWords2*Gia_ObjId(p, pObj0) );
+ word * pSim1 = Vec_WrdEntryP( vSims, nWords2*Gia_ObjId(p, pObj1) );
+ Gia_ManSimPatSimPo( p, Gia_ObjId(p, pObj0), pObj0, nWords2, vSims );
+ Gia_ManSimPatSimPo( p, Gia_ObjId(p, pObj1), pObj1, nWords2, vSims );
+ return Abc_TtEqual( pSim0, pSim1, nWords2 );
+}
+int Gia_ManCheckSimEquiv( Gia_Man_t * p, int fVerbose )
+{
+ abctime clk = Abc_Clock(); int fWarning = 0;
+ //int nVars2 = (Gia_ManCiNum(p) + 6)/2;
+ int nVars2 = Gia_ManFindDividerVar( p, fVerbose );
+ int nVars3 = Gia_ManCiNum(p) - nVars2;
+ int nWords2 = Abc_Truth6WordNum( nVars2 );
+ Vec_Wrd_t * vSims = Vec_WrdStart( nWords2 * Gia_ManObjNum(p) );
+ Vec_Wec_t * vNodes = Gia_ManComputeTfos( p );
+ Vec_Ptr_t * vTruths = Vec_PtrAllocTruthTables( nVars2 );
+ Gia_Obj_t * pObj; Vec_Int_t * vNode; int i, m, iObj;
+ Vec_WecForEachLevelStop( vNodes, vNode, i, nVars2 )
+ Abc_TtCopy( Vec_WrdEntryP(vSims, nWords2*Vec_IntEntry(vNode,0)), (word *)Vec_PtrEntry(vTruths, i), nWords2, 0 );
+ Vec_PtrFree( vTruths );
+ Gia_ManForEachAnd( p, pObj, i )
+ Gia_ManSimPatSimAnd( p, i, pObj, nWords2, vSims );
+ for ( i = 0; i < Gia_ManCoNum(p)/2; i++ )
+ {
+ if ( !Gia_ManComparePair( p, vSims, i, nWords2 ) )
+ {
+ printf( "Miter is asserted for output %d.\n", i );
+ Vec_WecFree( vNodes );
+ Vec_WrdFree( vSims );
+ return 0;
+ }
+ }
+ for ( m = 0; m < (1 << nVars3); m++ )
+ {
+ int iVar = m ? Abc_TtSuppFindFirst( m ^ (m >> 1) ^ (m-1) ^ ((m-1) >> 1) ) : 0;
+ vNode = Vec_WecEntry( vNodes, nVars2+iVar );
+ Abc_TtNot( Vec_WrdEntryP(vSims, nWords2*Vec_IntEntry(vNode,0)), nWords2 );
+ Vec_IntForEachEntryStart( vNode, iObj, i, 1 )
+ {
+ if ( iObj < Gia_ManObjNum(p) )
+ {
+ pObj = Gia_ManObj( p, iObj );
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManSimPatSimAnd( p, iObj, pObj, nWords2, vSims );
+ }
+ else if ( !Gia_ManComparePair( p, vSims, iObj - Gia_ManObjNum(p), nWords2 ) )
+ {
+ printf( "Miter is asserted for output %d.\n", iObj - Gia_ManObjNum(p) );
+ Vec_WecFree( vNodes );
+ Vec_WrdFree( vSims );
+ return 0;
+ }
+ }
+ //for ( i = 0; i < Gia_ManObjNum(p); i++ )
+ // printf( "%3d : ", i), Extra_PrintHex2( stdout, (unsigned *)Vec_WrdEntryP(vSims, i), 6 ), printf( "\n" );
+ if ( !fWarning && Abc_Clock() > clk + 5*CLOCKS_PER_SEC )
+ printf( "The computation is expected to take about %.2f sec.\n", 5.0*(1 << nVars3)/m ), fWarning = 1;
+ //if ( (m & 0x3F) == 0x3F )
+ if ( fVerbose && (m & 0xFF) == 0xFF )
+ printf( "Finished %6d (out of %6d)...\n", m, 1 << nVars3 );
+ }
+ Vec_WecFree( vNodes );
+ Vec_WrdFree( vSims );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSimPatAssignInputs2( Gia_Man_t * p, int nWords, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsIn )
+{
+ int i, Id;
+ assert( Vec_WrdSize(vSims) == 2 * nWords * Gia_ManObjNum(p) );
+ assert( Vec_WrdSize(vSimsIn) == nWords * Gia_ManCiNum(p) );
+ Gia_ManForEachCiId( p, Id, i )
+ {
+ Abc_TtCopy( Vec_WrdEntryP(vSims, 2*Id*nWords+0), Vec_WrdEntryP(vSimsIn, i*nWords), nWords, 0 );
+ Abc_TtCopy( Vec_WrdEntryP(vSims, 2*Id*nWords+1), Vec_WrdEntryP(vSimsIn, i*nWords), nWords, 1 );
+ }
+}
+static inline void Gia_ManSimPatSimAnd2( Gia_Man_t * p, int i, Gia_Obj_t * pObj, int nWords, Vec_Wrd_t * vSims )
+{
+ word * pSims = Vec_WrdArray(vSims);
+ word * pSims0 = pSims + nWords*Gia_ObjFaninLit0(pObj, i);
+ word * pSims1 = pSims + nWords*Gia_ObjFaninLit1(pObj, i);
+ word * pSims2 = pSims + nWords*(2*i+0);
+ word * pSims3 = pSims + nWords*(2*i+1); int w;
+ assert( !Gia_ObjIsXor(pObj) );
+// if ( Gia_ObjIsXor(pObj) )
+// for ( w = 0; w < nWords; w++ )
+// pSims2[w] = pSims0[w] ^ pSims1[w];
+// else
+ for ( w = 0; w < nWords; w++ )
+ {
+ pSims2[w] = pSims0[w] & pSims1[w];
+ pSims3[w] = ~pSims2[w];
+ }
+ //_mm256_storeu_ps( (float *)pSims2, _mm256_and_ps(_mm256_loadu_ps((float *)pSims0), _mm256_loadu_ps((float *)pSims1)) );
+}
+static inline void Gia_ManSimPatSimPo2( Gia_Man_t * p, int i, Gia_Obj_t * pObj, int nWords, Vec_Wrd_t * vSims )
+{
+ word * pSims = Vec_WrdArray(vSims);
+ word * pSims0 = pSims + nWords*Gia_ObjFaninLit0(pObj, i);
+ word * pSims2 = pSims + nWords*i; int w;
+ for ( w = 0; w < nWords; w++ )
+ pSims2[w] = pSims0[w];
+}
+Vec_Wrd_t * Gia_ManSimPatSim2( Gia_Man_t * pGia )
+{
+ Gia_Obj_t * pObj;
+ int i, nWords = Vec_WrdSize(pGia->vSimsPi) / Gia_ManCiNum(pGia);
+ Vec_Wrd_t * vSims = Vec_WrdStart( Gia_ManObjNum(pGia) * nWords * 2 );
+ assert( Vec_WrdSize(pGia->vSimsPi) % Gia_ManCiNum(pGia) == 0 );
+ Gia_ManSimPatAssignInputs2( pGia, nWords, vSims, pGia->vSimsPi );
+ Gia_ManForEachAnd( pGia, pObj, i )
+ Gia_ManSimPatSimAnd2( pGia, i, pObj, nWords, vSims );
+ Gia_ManForEachCo( pGia, pObj, i )
+ Gia_ManSimPatSimPo2( pGia, Gia_ObjId(pGia, pObj), pObj, nWords, vSims );
+ return vSims;
+}
/**Function*************************************************************
@@ -248,7 +676,6 @@ Vec_Wrd_t * Gia_ManSimBitPacking( Gia_Man_t * p, Vec_Int_t * vCexStore, int nCex
return vSimsRes;
}
-
/**Function*************************************************************
Synopsis []
@@ -306,87 +733,6 @@ Gia_Man_t * Gia_ManSimPatGenMiter( Gia_Man_t * p, Vec_Wrd_t * vSims )
}
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Gia_ManSimPatWriteOne( FILE * pFile, word * pSim, int nWords )
-{
- int k, Digit, nDigits = nWords*16;
- for ( k = 0; k < nDigits; k++ )
- {
- Digit = (int)((pSim[k/16] >> ((k%16) * 4)) & 15);
- if ( Digit < 10 )
- fprintf( pFile, "%d", Digit );
- else
- fprintf( pFile, "%c", 'A' + Digit-10 );
- }
- fprintf( pFile, "\n" );
-}
-void Gia_ManSimPatWrite( char * pFileName, Vec_Wrd_t * vSimsIn, int nWords )
-{
- int i, nNodes = Vec_WrdSize(vSimsIn) / nWords;
- FILE * pFile = fopen( pFileName, "wb" );
- if ( pFile == NULL )
- {
- printf( "Cannot open file \"%s\" for writing.\n", pFileName );
- return;
- }
- assert( Vec_WrdSize(vSimsIn) % nWords == 0 );
- for ( i = 0; i < nNodes; i++ )
- Gia_ManSimPatWriteOne( pFile, Vec_WrdEntryP(vSimsIn, i*nWords), nWords );
- fclose( pFile );
- printf( "Written %d words of simulation data into file \"%s\".\n", nWords, pFileName );
-}
-int Gia_ManSimPatReadOne( char c )
-{
- int Digit = 0;
- if ( c >= '0' && c <= '9' )
- Digit = c - '0';
- else if ( c >= 'A' && c <= 'F' )
- Digit = c - 'A' + 10;
- else if ( c >= 'a' && c <= 'f' )
- Digit = c - 'a' + 10;
- else assert( 0 );
- assert( Digit >= 0 && Digit < 16 );
- return Digit;
-}
-Vec_Wrd_t * Gia_ManSimPatRead( char * pFileName )
-{
- Vec_Wrd_t * vSimsIn = NULL;
- int c, nWords = -1, nChars = 0; word Num = 0;
- FILE * pFile = fopen( pFileName, "rb" );
- if ( pFile == NULL )
- {
- printf( "Cannot open file \"%s\" for reading.\n", pFileName );
- return NULL;
- }
- vSimsIn = Vec_WrdAlloc( 1000 );
- while ( (c = fgetc(pFile)) != EOF )
- {
- if ( c == '\n' && nWords == -1 )
- nWords = Vec_WrdSize(vSimsIn);
- if ( c == '\n' || c == '\r' || c == '\t' || c == ' ' )
- continue;
- Num |= (word)Gia_ManSimPatReadOne((char)c) << (nChars * 4);
- if ( ++nChars < 16 )
- continue;
- Vec_WrdPush( vSimsIn, Num );
- nChars = 0;
- Num = 0;
- }
- assert( Vec_WrdSize(vSimsIn) % nWords == 0 );
- fclose( pFile );
- printf( "Read %d words of simulation data.\n", nWords );
- return vSimsIn;
-}
/**Function*************************************************************
@@ -2029,6 +2375,331 @@ void Gia_ManPatRareImprove( Gia_Man_t * p, int RareLimit, int fVerbose )
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
}
+/**Function*************************************************************
+
+ Synopsis [Trying vectorized simulation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSimTest( Gia_Man_t * pGia )
+{
+ int n, nWords = 4;
+ Vec_Wrd_t * vSim1, * vSim2;
+ Vec_Wrd_t * vSim0 = Vec_WrdStartRandom( Gia_ManCiNum(pGia) * nWords );
+ abctime clk = Abc_Clock();
+
+ pGia->vSimsPi = vSim0;
+ for ( n = 0; n < 20; n++ )
+ {
+ vSim1 = Gia_ManSimPatSim( pGia );
+ Vec_WrdFree( vSim1 );
+ }
+ Abc_PrintTime( 1, "Time1", Abc_Clock() - clk );
+
+ clk = Abc_Clock();
+ for ( n = 0; n < 20; n++ )
+ {
+ vSim2 = Gia_ManSimPatSim2( pGia );
+ Vec_WrdFree( vSim2 );
+ }
+ Abc_PrintTime( 1, "Time2", Abc_Clock() - clk );
+
+ pGia->vSimsPi = NULL;
+ Vec_WrdFree( vSim0 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Trying compiled simulation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSimGen( Gia_Man_t * pGia )
+{
+ int nWords = 4;
+ Gia_Obj_t * pObj;
+ Vec_Wrd_t * vSim0 = Vec_WrdStartRandom( Gia_ManCiNum(pGia) * nWords );
+ FILE * pFile = fopen( "comp_sim.c", "wb" );
+ int i, k, Id;
+ fprintf( pFile, "#include <stdio.h>\n" );
+ fprintf( pFile, "#include <stdlib.h>\n" );
+ fprintf( pFile, "#include <time.h>\n" );
+ fprintf( pFile, "int main()\n" );
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " clock_t clkThis = clock();\n" );
+ fprintf( pFile, " unsigned long Res = 0;\n" );
+ fprintf( pFile, " int i;\n" );
+ fprintf( pFile, " srand(time(NULL));\n" );
+ fprintf( pFile, " for ( i = 0; i < 2000; i++ )\n" );
+ fprintf( pFile, " {\n" );
+ for ( k = 0; k < nWords; k++ )
+ fprintf( pFile, " unsigned long s%07d_%d = 0x%08x%08x;\n", 0, k, 0, 0 );
+ Gia_ManForEachCiId( pGia, Id, i )
+ {
+ //word * pSim = Vec_WrdEntryP(vSim0, i*nWords);
+ //unsigned * pSimU = (unsigned *)pSim;
+ for ( k = 0; k < nWords; k++ )
+ fprintf( pFile, " unsigned long s%07d_%d = ((unsigned long)rand() << 48) | ((unsigned long)rand() << 32) | ((unsigned long)rand() << 16) | (unsigned long)rand();\n", Id, k );
+ }
+ Gia_ManForEachAnd( pGia, pObj, Id )
+ {
+ for ( k = 0; k < nWords; k++ )
+ fprintf( pFile, " unsigned long s%07d_%d = %cs%07d_%d & %cs%07d_%d;\n", Id, k,
+ Gia_ObjFaninC0(pObj) ? '~' : ' ', Gia_ObjFaninId0(pObj, Id), k,
+ Gia_ObjFaninC1(pObj) ? ' ' : '~', Gia_ObjFaninId1(pObj, Id), k );
+ }
+ Gia_ManForEachCoId( pGia, Id, i )
+ {
+ pObj = Gia_ManObj(pGia, Id);
+ for ( k = 0; k < nWords; k++ )
+ fprintf( pFile, " Res ^= %cs%07d_%d;\n", Gia_ObjFaninC0(pObj) ? '~' : ' ', Gia_ObjFaninId0(pObj, Id), k );
+ }
+ Vec_WrdFree( vSim0 );
+ fprintf( pFile, " }\n" );
+ fprintf( pFile, " printf( \"Res = 0x%%08x \", (unsigned)Res );\n" );
+ fprintf( pFile, " printf( \"Time = %%6.2f sec\\n\", (float)(clock() - clkThis)/CLOCKS_PER_SEC );\n" );
+ fprintf( pFile, " return 1;\n" );
+ fprintf( pFile, "}\n" );
+ fclose( pFile );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Trying vectorized simulation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManSimTwo( Gia_Man_t * p0, Gia_Man_t * p1, int nWords, int nRounds, int fVerbose )
+{
+ Vec_Wrd_t * vSim0, * vSim1, * vSim2;
+ abctime clk = Abc_Clock();
+ int n, i, RetValue = 1;
+ printf( "Simulating %d round with %d machine words.\n", nRounds, nWords );
+ Abc_RandomW(0);
+ for ( n = 0; RetValue && n < nRounds; n++ )
+ {
+ vSim0 = Vec_WrdStartRandom( Gia_ManCiNum(p0) * nWords );
+ p0->vSimsPi = vSim0;
+ p1->vSimsPi = vSim0;
+ vSim1 = Gia_ManSimPatSim( p0 );
+ vSim2 = Gia_ManSimPatSim( p1 );
+ for ( i = 0; i < Gia_ManCoNum(p0); i++ )
+ {
+ word * pSim1 = Vec_WrdEntryP(vSim1, Gia_ObjId(p0, Gia_ManCo(p0, i))*nWords);
+ word * pSim2 = Vec_WrdEntryP(vSim2, Gia_ObjId(p1, Gia_ManCo(p1, i))*nWords);
+ if ( memcmp(pSim1, pSim2, sizeof(word)*nWords) )
+ {
+ printf( "Output %d failed simulation at round %d. ", i, n );
+ RetValue = 0;
+ break;
+ }
+ }
+ Vec_WrdFree( vSim1 );
+ Vec_WrdFree( vSim2 );
+ Vec_WrdFree( vSim0 );
+ p0->vSimsPi = NULL;
+ p1->vSimsPi = NULL;
+ }
+ if ( RetValue == 1 )
+ printf( "Simulation did not detect a bug. " );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Serialization.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSim2ArrayOne( Vec_Wrd_t * vSimsPi, Vec_Int_t * vRes )
+{
+ word * pInfo = Vec_WrdArray(vSimsPi); int w, i;
+ word * pCare = pInfo + Vec_WrdSize(vSimsPi);
+ Vec_IntClear( vRes );
+ for ( w = 0; w < Vec_WrdSize(vSimsPi); w++ )
+ if ( pCare[w] )
+ for ( i = 0; i < 64; i++ )
+ if ( Abc_TtGetBit(pCare, w*64+i) )
+ Vec_IntPush( vRes, Abc_Var2Lit(w*64+i, Abc_TtGetBit(pInfo, w*64+i)) );
+ Vec_IntPush( vRes, Vec_WrdSize(vSimsPi) );
+}
+Vec_Wec_t * Gia_ManSim2Array( Vec_Ptr_t * vSims )
+{
+ Vec_Wec_t * vRes = Vec_WecStart( Vec_PtrSize(vSims) );
+ Vec_Int_t * vLevel; int i;
+ Vec_WecForEachLevel( vRes, vLevel, i )
+ Gia_ManSim2ArrayOne( (Vec_Wrd_t *)Vec_PtrEntry(vSims, i), vLevel );
+ return vRes;
+}
+
+Vec_Wrd_t * Gia_ManArray2SimOne( Vec_Int_t * vRes )
+{
+ int i, iLit, nWords = Vec_IntEntryLast(vRes);
+ Vec_Wrd_t * vSimsPi = Vec_WrdStart( 2*nWords );
+ word * pInfo = Vec_WrdArray(vSimsPi);
+ word * pCare = pInfo + nWords;
+ Vec_IntPop( vRes );
+ Vec_IntForEachEntry( vRes, iLit, i )
+ {
+ Abc_TtXorBit( pCare, Abc_Lit2Var(iLit) );
+ if ( Abc_LitIsCompl(iLit) )
+ Abc_TtXorBit( pInfo, Abc_Lit2Var(iLit) );
+ }
+ Vec_IntPush( vRes, nWords );
+ Vec_WrdShrink( vSimsPi, Vec_WrdSize(vSimsPi)/2 );
+ return vSimsPi;
+}
+Vec_Ptr_t * Gia_ManArray2Sim( Vec_Wec_t * vRes )
+{
+ Vec_Ptr_t * vSims = Vec_PtrAlloc( Vec_WecSize(vRes) );
+ Vec_Int_t * vLevel; int i;
+ Vec_WecForEachLevel( vRes, vLevel, i )
+ Vec_PtrPush( vSims, Gia_ManArray2SimOne(vLevel) );
+ return vSims;
+}
+
+void Gia_ManSimArrayTest( Vec_Wrd_t * vSimsPi )
+{
+ Vec_Ptr_t * vTemp = Vec_PtrAlloc( 2 );
+ Vec_PtrPushTwo( vTemp, vSimsPi, vSimsPi );
+ {
+ Vec_Wec_t * vRes = Gia_ManSim2Array( vTemp );
+ Vec_WecDumpBin( "temp.sims", vRes, 1 );
+ {
+ Vec_Wec_t * vRes = Vec_WecReadBin( "temp.sims", 1 );
+ Vec_Ptr_t * vTemp2 = Gia_ManArray2Sim( vRes );
+ Vec_Wrd_t * vSimsPi2 = (Vec_Wrd_t *)Vec_PtrEntry( vTemp2, 0 );
+ Vec_Wrd_t * vSimsPi3 = (Vec_Wrd_t *)Vec_PtrEntry( vTemp2, 1 );
+
+ Abc_TtAnd( Vec_WrdArray(vSimsPi), Vec_WrdArray(vSimsPi), Vec_WrdArray(vSimsPi)+Vec_WrdSize(vSimsPi), Vec_WrdSize(vSimsPi), 0 );
+
+ vSimsPi->nSize *= 2;
+ vSimsPi2->nSize *= 2;
+ vSimsPi3->nSize *= 2;
+ Vec_WrdDumpHex( "test1.hex", vSimsPi, 1, 1 );
+ Vec_WrdDumpHex( "test2.hex", vSimsPi2, 1, 1 );
+ Vec_WrdDumpHex( "test3.hex", vSimsPi3, 1, 1 );
+ vSimsPi->nSize /= 2;
+ vSimsPi2->nSize /= 2;
+ vSimsPi3->nSize /= 2;
+
+ if ( Vec_WrdEqual( vSimsPi, vSimsPi2 ) )
+ printf( "Success.\n" );
+ else
+ printf( "Failure.\n" );
+ if ( Vec_WrdEqual( vSimsPi, vSimsPi3 ) )
+ printf( "Success.\n" );
+ else
+ printf( "Failure.\n" );
+ Vec_WrdFree( vSimsPi2 );
+ Vec_WrdFree( vSimsPi3 );
+ Vec_PtrFree( vTemp2 );
+ Vec_WecFree( vRes );
+ }
+ Vec_WecFree( vRes );
+ }
+ Vec_PtrFree( vTemp );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Serialization.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManPtrWrdDumpBin( char * pFileName, Vec_Ptr_t * p, int fVerbose )
+{
+ Vec_Wrd_t * vLevel;
+ int i, nSize, RetValue;
+ FILE * pFile = fopen( pFileName, "wb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for writing.\n", pFileName );
+ return;
+ }
+ nSize = Vec_PtrSize(p);
+ RetValue = fwrite( &nSize, 1, sizeof(int), pFile );
+ Vec_PtrForEachEntry( Vec_Wrd_t *, p, vLevel, i )
+ {
+ nSize = Vec_WrdSize(vLevel);
+ RetValue += fwrite( &nSize, 1, sizeof(int), pFile );
+ RetValue += fwrite( Vec_WrdArray(vLevel), 1, sizeof(word)*nSize, pFile );
+ }
+ fclose( pFile );
+ if ( fVerbose )
+ printf( "Written %d arrays into file \"%s\".\n", Vec_PtrSize(p), pFileName );
+}
+Vec_Ptr_t * Gia_ManPtrWrdReadBin( char * pFileName, int fVerbose )
+{
+ Vec_Ptr_t * p = NULL; Vec_Wrd_t * vLevel; int i, nSize, RetValue;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return NULL;
+ }
+ fseek( pFile, 0, SEEK_END );
+ nSize = ftell( pFile );
+ if ( nSize == 0 )
+ {
+ printf( "The input file is empty.\n" );
+ fclose( pFile );
+ return NULL;
+ }
+ if ( nSize % (int)sizeof(int) > 0 )
+ {
+ printf( "Cannot read file with integers because it is not aligned at 4 bytes (remainder = %d).\n", nSize % (int)sizeof(int) );
+ fclose( pFile );
+ return NULL;
+ }
+ rewind( pFile );
+ RetValue = fread( &nSize, 1, sizeof(int), pFile );
+ assert( RetValue == 4 );
+ p = Vec_PtrAlloc( nSize );
+ for ( i = 0; i < nSize; i++ )
+ Vec_PtrPush( p, Vec_WrdAlloc(100) );
+ Vec_PtrForEachEntry( Vec_Wrd_t *, p, vLevel, i )
+ {
+ RetValue = fread( &nSize, 1, sizeof(int), pFile );
+ assert( RetValue == 4 );
+ Vec_WrdFill( vLevel, nSize, 0 );
+ RetValue = fread( Vec_WrdArray(vLevel), 1, sizeof(word)*nSize, pFile );
+ assert( RetValue == 8*nSize );
+ }
+ fclose( pFile );
+ if ( fVerbose )
+ printf( "Read %d arrays from file \"%s\".\n", Vec_PtrSize(p), pFileName );
+ return p;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaStoch.c b/src/aig/gia/giaStoch.c
new file mode 100644
index 00000000..94f53998
--- /dev/null
+++ b/src/aig/gia/giaStoch.c
@@ -0,0 +1,448 @@
+/**CFile****************************************************************
+
+ FileName [giaDeep.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Experiments with synthesis.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaDeep.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+#include "base/main/main.h"
+#include "base/cmd/cmd.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManDupMapping( Gia_Man_t * pNew, Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj, * pFanin; int i, k;
+ Vec_Int_t * vMapping = p->vMapping ? Vec_IntAlloc( Vec_IntSize(p->vMapping) ) : NULL;
+ if ( p->vMapping == NULL )
+ return;
+ Vec_IntFill( vMapping, Gia_ManObjNum(p), 0 );
+ Gia_ManForEachLut( p, i )
+ {
+ pObj = Gia_ManObj( p, i );
+ Vec_IntWriteEntry( vMapping, Abc_Lit2Var(pObj->Value), Vec_IntSize(vMapping) );
+ Vec_IntPush( vMapping, Gia_ObjLutSize(p, i) );
+ Gia_LutForEachFaninObj( p, i, pFanin, k )
+ Vec_IntPush( vMapping, Abc_Lit2Var(pFanin->Value) );
+ Vec_IntPush( vMapping, Abc_Lit2Var(pObj->Value) );
+ }
+ pNew->vMapping = vMapping;
+}
+Gia_Man_t * Gia_ManDupWithMapping( Gia_Man_t * pGia )
+{
+ Gia_Man_t * pCopy = Gia_ManDup(pGia);
+ Gia_ManDupMapping( pCopy, pGia );
+ return pCopy;
+}
+void Gia_ManStochSynthesis( Vec_Ptr_t * vAigs, char * pScript )
+{
+ Gia_Man_t * pGia, * pNew; int i;
+ Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, i )
+ {
+ Gia_Man_t * pCopy = Gia_ManDupWithMapping(pGia);
+ Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), pGia );
+ if ( Abc_FrameIsBatchMode() )
+ {
+ if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), pScript) )
+ {
+ Abc_Print( 1, "Something did not work out with the command \"%s\".\n", pScript );
+ return;
+ }
+ }
+ else
+ {
+ Abc_FrameSetBatchMode( 1 );
+ if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), pScript) )
+ {
+ Abc_Print( 1, "Something did not work out with the command \"%s\".\n", pScript );
+ Abc_FrameSetBatchMode( 0 );
+ return;
+ }
+ Abc_FrameSetBatchMode( 0 );
+ }
+ pNew = Abc_FrameReadGia(Abc_FrameGetGlobalFrame());
+ if ( Gia_ManHasMapping(pNew) && Gia_ManHasMapping(pCopy) )
+ {
+ if ( Gia_ManLutNum(pNew) < Gia_ManLutNum(pCopy) )
+ {
+ Gia_ManStop( pCopy );
+ pCopy = Gia_ManDupWithMapping( pNew );
+ }
+ }
+ else
+ {
+ if ( Gia_ManAndNum(pNew) < Gia_ManAndNum(pCopy) )
+ {
+ Gia_ManStop( pCopy );
+ pCopy = Gia_ManDup( pNew );
+ }
+ }
+ Vec_PtrWriteEntry( vAigs, i, pCopy );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManCollectNodes_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vAnds )
+{
+ Gia_Obj_t * pObj;
+ if ( Gia_ObjUpdateTravIdCurrentId( p, iObj ) )
+ return;
+ pObj = Gia_ManObj( p, iObj );
+ if ( Gia_ObjIsCi(pObj) || iObj == 0 )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManCollectNodes_rec( p, Gia_ObjFaninId0(pObj, iObj), vAnds );
+ Gia_ManCollectNodes_rec( p, Gia_ObjFaninId1(pObj, iObj), vAnds );
+ Vec_IntPush( vAnds, iObj );
+}
+void Gia_ManCollectNodes( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos )
+{
+ int i, iObj;
+ if ( !Gia_ManHasMapping(p) )
+ return;
+ Vec_IntClear( vAnds );
+ Gia_ManIncrementTravId( p );
+ Vec_IntForEachEntry( vCis, iObj, i )
+ Gia_ObjSetTravIdCurrentId( p, iObj );
+ Vec_IntForEachEntry( vCos, iObj, i )
+ Gia_ManCollectNodes_rec( p, iObj, vAnds );
+}
+Gia_Man_t * Gia_ManDupDivideOne( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos )
+{
+ Vec_Int_t * vMapping; int i;
+ Gia_Man_t * pNew; Gia_Obj_t * pObj;
+ pNew = Gia_ManStart( 1+Vec_IntSize(vCis)+Vec_IntSize(vAnds)+Vec_IntSize(vCos) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ Gia_ManFillValue(p);
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachObjVec( vCis, p, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ Gia_ManForEachObjVec( vAnds, p, pObj, i )
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ Gia_ManForEachObjVec( vCos, p, pObj, i )
+ Gia_ManAppendCo( pNew, pObj->Value );
+ assert( Gia_ManCiNum(pNew) > 0 && Gia_ManCoNum(pNew) > 0 );
+ if ( !Gia_ManHasMapping(p) )
+ return pNew;
+ vMapping = Vec_IntAlloc( 4*Gia_ManObjNum(pNew) );
+ Vec_IntFill( vMapping, Gia_ManObjNum(pNew), 0 );
+ Gia_ManForEachObjVec( vAnds, p, pObj, i )
+ {
+ Gia_Obj_t * pFanin; int k;
+ int iObj = Gia_ObjId(p, pObj);
+ if ( !Gia_ObjIsLut(p, iObj) )
+ continue;
+ Vec_IntWriteEntry( vMapping, Abc_Lit2Var(pObj->Value), Vec_IntSize(vMapping) );
+ Vec_IntPush( vMapping, Gia_ObjLutSize(p, iObj) );
+ Gia_LutForEachFaninObj( p, iObj, pFanin, k )
+ Vec_IntPush( vMapping, Abc_Lit2Var(pFanin->Value) );
+ Vec_IntPush( vMapping, Abc_Lit2Var(pObj->Value) );
+ }
+ pNew->vMapping = vMapping;
+ return pNew;
+}
+Vec_Ptr_t * Gia_ManDupDivide( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds, Vec_Wec_t * vCos, char * pScript )
+{
+ Vec_Ptr_t * vAigs = Vec_PtrAlloc( Vec_WecSize(vCis) ); int i;
+ for ( i = 0; i < Vec_WecSize(vCis); i++ )
+ {
+ Gia_ManCollectNodes( p, Vec_WecEntry(vCis, i), Vec_WecEntry(vAnds, i), Vec_WecEntry(vCos, i) );
+ Vec_PtrPush( vAigs, Gia_ManDupDivideOne(p, Vec_WecEntry(vCis, i), Vec_WecEntry(vAnds, i), Vec_WecEntry(vCos, i)) );
+ }
+ Gia_ManStochSynthesis( vAigs, pScript );
+ return vAigs;
+}
+Gia_Man_t * Gia_ManDupStitch( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds, Vec_Wec_t * vCos, Vec_Ptr_t * vAigs, int fHash )
+{
+ Gia_Man_t * pGia, * pNew;
+ Gia_Obj_t * pObj; int i, k;
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManCleanValue( p );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ if ( fHash )
+ Gia_ManHashAlloc( pNew );
+ Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, i )
+ {
+ Vec_Int_t * vCi = Vec_WecEntry( vCis, i );
+ Vec_Int_t * vCo = Vec_WecEntry( vCos, i );
+ Gia_ManCleanValue( pGia );
+ Gia_ManConst0(pGia)->Value = 0;
+ Gia_ManForEachObjVec( vCi, p, pObj, k )
+ Gia_ManCi(pGia, k)->Value = pObj->Value;
+ if ( fHash )
+ Gia_ManForEachAnd( pGia, pObj, k )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ else
+ Gia_ManForEachAnd( pGia, pObj, k )
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ Gia_ManForEachObjVec( vCo, p, pObj, k )
+ pObj->Value = Gia_ObjFanin0Copy(Gia_ManCo(pGia, k));
+ }
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ if ( fHash )
+ {
+ pNew = Gia_ManCleanup( pGia = pNew );
+ Gia_ManStop( pGia );
+ }
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ return pNew;
+}
+Gia_Man_t * Gia_ManDupStitchMap( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds, Vec_Wec_t * vCos, Vec_Ptr_t * vAigs )
+{
+ Vec_Int_t * vMapping; int n;
+ Gia_Man_t * pGia, * pNew = Gia_ManDupStitch( p, vCis, vAnds, vCos, vAigs, !Gia_ManHasMapping(p) );
+ if ( !Gia_ManHasMapping(p) )
+ return pNew;
+ vMapping = Vec_IntAlloc( Vec_IntSize(p->vMapping) );
+ Vec_IntFill( vMapping, Gia_ManObjNum(pNew), 0 );
+ Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, n )
+ {
+ Gia_Obj_t * pFanin; int iObj, k;
+ //printf( "Gia %d has %d Luts\n", n, Gia_ManLutNum(pGia) );
+
+ Gia_ManForEachLut( pGia, iObj )
+ {
+ Gia_Obj_t * pObj = Gia_ManObj( pGia, iObj );
+ Vec_IntWriteEntry( vMapping, Abc_Lit2Var(pObj->Value), Vec_IntSize(vMapping) );
+ Vec_IntPush( vMapping, Gia_ObjLutSize(pGia, iObj) );
+ Gia_LutForEachFaninObj( pGia, iObj, pFanin, k )
+ Vec_IntPush( vMapping, Abc_Lit2Var(pFanin->Value) );
+ Vec_IntPush( vMapping, Abc_Lit2Var(pObj->Value) );
+ }
+ }
+ pNew->vMapping = vMapping;
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Wec_t * Gia_ManStochNodes( Gia_Man_t * p, int nMaxSize, int Seed )
+{
+ Vec_Wec_t * vRes = Vec_WecAlloc( 100 );
+ Vec_Int_t * vPart = Vec_WecPushLevel( vRes );
+ int i, iStart = Seed % Gia_ManCoNum(p);
+ //Gia_ManLevelNum( p );
+ Gia_ManIncrementTravId( p );
+ for ( i = 0; i < Gia_ManCoNum(p); i++ )
+ {
+ Gia_Obj_t * pObj = Gia_ManCo( p, (iStart+i) % Gia_ManCoNum(p) );
+ if ( Vec_IntSize(vPart) > nMaxSize )
+ vPart = Vec_WecPushLevel( vRes );
+ Gia_ManCollectNodes_rec( p, Gia_ObjFaninId0p(p, pObj), vPart );
+ }
+ if ( Vec_IntSize(vPart) == 0 )
+ Vec_WecShrink( vRes, Vec_WecSize(vRes)-1 );
+ //Vec_WecPrint( vRes, 0 );
+ return vRes;
+}
+Vec_Wec_t * Gia_ManStochInputs( Gia_Man_t * p, Vec_Wec_t * vAnds )
+{
+ Vec_Wec_t * vRes = Vec_WecAlloc( 100 );
+ Vec_Int_t * vLevel; Gia_Obj_t * pObj; int i, k, iObj, iFan, f;
+ Vec_WecForEachLevel( vAnds, vLevel, i )
+ {
+ Vec_Int_t * vVec = Vec_WecPushLevel( vRes );
+ assert( Vec_IntSize(vVec) == 0 );
+ Gia_ManIncrementTravId( p );
+ Vec_IntForEachEntry( vLevel, iObj, k )
+ Gia_ObjSetTravIdCurrentId( p, iObj );
+ if ( Gia_ManHasMapping(p) )
+ {
+ Vec_IntForEachEntry( vLevel, iObj, k )
+ if ( Gia_ObjIsLut(p, iObj) )
+ Gia_LutForEachFanin( p, iObj, iFan, f )
+ if ( !Gia_ObjUpdateTravIdCurrentId(p, iFan) )
+ Vec_IntPush( vVec, iFan );
+ }
+ else
+ {
+ Gia_ManForEachObjVec( vLevel, p, pObj, k )
+ {
+ iObj = Gia_ObjFaninId0p(p, pObj);
+ if ( !Gia_ObjUpdateTravIdCurrentId(p, iObj) )
+ Vec_IntPush( vVec, iObj );
+ iObj = Gia_ObjFaninId1p(p, pObj);
+ if ( !Gia_ObjUpdateTravIdCurrentId(p, iObj) )
+ Vec_IntPush( vVec, iObj );
+ }
+ }
+ assert( Vec_IntSize(vVec) > 0 );
+ }
+ return vRes;
+}
+Vec_Wec_t * Gia_ManStochOutputs( Gia_Man_t * p, Vec_Wec_t * vAnds )
+{
+ Vec_Wec_t * vRes = Vec_WecAlloc( 100 );
+ Vec_Int_t * vLevel; Gia_Obj_t * pObj; int i, k, iObj, iFan, f;
+ if ( Gia_ManHasMapping(p) )
+ {
+ Gia_ManSetLutRefs( p );
+ Vec_WecForEachLevel( vAnds, vLevel, i )
+ {
+ Vec_Int_t * vVec = Vec_WecPushLevel( vRes );
+ assert( Vec_IntSize(vVec) == 0 );
+ Vec_IntForEachEntry( vLevel, iObj, k )
+ if ( Gia_ObjIsLut(p, iObj) )
+ Gia_LutForEachFanin( p, iObj, iFan, f )
+ Gia_ObjLutRefDecId( p, iFan );
+ Vec_IntForEachEntry( vLevel, iObj, k )
+ if ( Gia_ObjIsLut(p, iObj) )
+ if ( Gia_ObjLutRefNumId(p, iObj) )
+ Vec_IntPush( vVec, iObj );
+ Vec_IntForEachEntry( vLevel, iObj, k )
+ if ( Gia_ObjIsLut(p, iObj) )
+ Gia_LutForEachFanin( p, iObj, iFan, f )
+ Gia_ObjLutRefIncId( p, iFan );
+ assert( Vec_IntSize(vVec) > 0 );
+ }
+ }
+ else
+ {
+ Gia_ManCreateRefs( p );
+ Vec_WecForEachLevel( vAnds, vLevel, i )
+ {
+ Vec_Int_t * vVec = Vec_WecPushLevel( vRes );
+ Gia_ManForEachObjVec( vLevel, p, pObj, k )
+ {
+ Gia_ObjRefDecId( p, Gia_ObjFaninId0p(p, pObj) );
+ Gia_ObjRefDecId( p, Gia_ObjFaninId1p(p, pObj) );
+ }
+ Gia_ManForEachObjVec( vLevel, p, pObj, k )
+ if ( Gia_ObjRefNum(p, pObj) )
+ Vec_IntPush( vVec, Gia_ObjId(p, pObj) );
+ Gia_ManForEachObjVec( vLevel, p, pObj, k )
+ {
+ Gia_ObjRefIncId( p, Gia_ObjFaninId0p(p, pObj) );
+ Gia_ObjRefIncId( p, Gia_ObjFaninId1p(p, pObj) );
+ }
+ }
+ }
+ return vRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManStochSyn( int nMaxSize, int nIters, int TimeOut, int Seed, int fVerbose, char * pScript )
+{
+ abctime nTimeToStop = TimeOut ? Abc_Clock() + TimeOut * CLOCKS_PER_SEC : 0;
+ abctime clkStart = Abc_Clock();
+ int fMapped = Gia_ManHasMapping(Abc_FrameReadGia(Abc_FrameGetGlobalFrame()));
+ int nLutEnd, nLutBeg = fMapped ? Gia_ManLutNum(Abc_FrameReadGia(Abc_FrameGetGlobalFrame())) : 0;
+ int i, nEnd, nBeg = Gia_ManAndNum(Abc_FrameReadGia(Abc_FrameGetGlobalFrame()));
+ Abc_Random(1);
+ for ( i = 0; i < 10+Seed; i++ )
+ Abc_Random(0);
+ if ( fVerbose )
+ printf( "Running %d iterations of script \"%s\".\n", nIters, pScript );
+ for ( i = 0; i < nIters; i++ )
+ {
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pGia = Gia_ManDupWithMapping( Abc_FrameReadGia(Abc_FrameGetGlobalFrame()) );
+ Vec_Wec_t * vAnds = Gia_ManStochNodes( pGia, nMaxSize, Abc_Random(0) & 0x7FFFFFFF );
+ Vec_Wec_t * vIns = Gia_ManStochInputs( pGia, vAnds );
+ Vec_Wec_t * vOuts = Gia_ManStochOutputs( pGia, vAnds );
+ Vec_Ptr_t * vAigs = Gia_ManDupDivide( pGia, vIns, vAnds, vOuts, pScript );
+ Gia_Man_t * pNew = Gia_ManDupStitchMap( pGia, vIns, vAnds, vOuts, vAigs );
+ int fMapped = Gia_ManHasMapping(pGia) && Gia_ManHasMapping(pNew);
+ Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), pNew );
+ if ( fVerbose )
+ printf( "Iteration %3d : Using %3d partitions. Reducing %6d to %6d %s. ",
+ i, Vec_PtrSize(vAigs), fMapped ? Gia_ManLutNum(pGia) : Gia_ManAndNum(pGia),
+ fMapped ? Gia_ManLutNum(pNew) : Gia_ManAndNum(pNew),
+ fMapped ? "LUTs" : "ANDs" );
+ if ( fVerbose )
+ Abc_PrintTime( 0, "Time", Abc_Clock() - clk );
+ Gia_ManStop( pGia );
+ Vec_PtrFreeFunc( vAigs, (void (*)(void *)) Gia_ManStop );
+ Vec_WecFree( vAnds );
+ Vec_WecFree( vIns );
+ Vec_WecFree( vOuts );
+ if ( nTimeToStop && Abc_Clock() > nTimeToStop )
+ {
+ printf( "Runtime limit (%d sec) is reached after %d iterations.\n", TimeOut, i );
+ break;
+ }
+ }
+ fMapped &= Gia_ManHasMapping(Abc_FrameReadGia(Abc_FrameGetGlobalFrame()));
+ nLutEnd = fMapped ? Gia_ManLutNum(Abc_FrameReadGia(Abc_FrameGetGlobalFrame())) : 0;
+ nEnd = Gia_ManAndNum(Abc_FrameReadGia(Abc_FrameGetGlobalFrame()));
+ if ( fVerbose )
+ printf( "Cumulatively reduced %d %s after %d iterations. ",
+ fMapped ? nLutBeg - nLutEnd : nBeg - nEnd, fMapped ? "LUTs" : "ANDs", nIters );
+ if ( fVerbose )
+ Abc_PrintTime( 0, "Total time", Abc_Clock() - clkStart );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaStr.c b/src/aig/gia/giaStr.c
index 085738c3..a87662a8 100644
--- a/src/aig/gia/giaStr.c
+++ b/src/aig/gia/giaStr.c
@@ -736,7 +736,7 @@ Str_Ntk_t * Str_ManNormalizeInt( Gia_Man_t * p, Vec_Wec_t * vGroups, Vec_Int_t *
if ( p->vStore == NULL )
p->vStore = Vec_IntAlloc( STR_SUPER );
Gia_ManFillValue( p );
- pNtk = Str_NtkCreate( Gia_ManObjNum(p), 1 + Gia_ManCoNum(p) + 2 * Gia_ManAndNum(p) + Gia_ManMuxNum(p) );
+ pNtk = Str_NtkCreate( Gia_ManObjNum(p) + 10000, 1 + Gia_ManCoNum(p) + 2 * Gia_ManAndNum(p) + Gia_ManMuxNum(p) + 10000 );
Gia_ManConst0(p)->Value = 0;
Gia_ManForEachObj1( p, pObj, i )
{
@@ -749,7 +749,7 @@ Str_Ntk_t * Str_ManNormalizeInt( Gia_Man_t * p, Vec_Wec_t * vGroups, Vec_Int_t *
pObj->Value = Str_ObjCreate( pNtk, STR_PO, 1, &iFanin );
}
}
- assert( pNtk->nObjs <= Gia_ManObjNum(p) );
+ //assert( pNtk->nObjs <= Gia_ManObjNum(p) );
return pNtk;
}
Str_Ntk_t * Str_ManNormalize( Gia_Man_t * p )
@@ -859,21 +859,23 @@ static inline void transpose64( word A[64] )
static inline int Str_ManNum( Gia_Man_t * p, int iObj ) { return Vec_IntEntry(&p->vCopies, iObj); }
static inline void Str_ManSetNum( Gia_Man_t * p, int iObj, int Num ) { Vec_IntWriteEntry(&p->vCopies, iObj, Num); }
-int Str_ManVectorAffinity( Gia_Man_t * p, Vec_Int_t * vSuper, Vec_Int_t * vDelay, word Matrix[256], int nLimit )
+int Str_ManVectorAffinity( Gia_Man_t * p, Vec_Int_t * vSuper, Vec_Int_t * vDelay, word * Matrix, int nLimit )
{
int fVerbose = 0;
- int Levels[256];
+ int * Levels = NULL;
int nSize = Vec_IntSize(vSuper);
int Prev = nSize, nLevels = 1;
int i, k, iLit, iFanin, nSizeNew;
word Mask;
assert( nSize > 2 );
+ assert( nSize <= nLimit );
if ( nSize > 64 )
{
for ( i = 0; i < 64; i++ )
Matrix[i] = 0;
return 0;
}
+ Levels = ABC_ALLOC( int, nLimit+256 );
// mark current nodes
Gia_ManIncrementTravId( p );
Vec_IntForEachEntry( vSuper, iLit, i )
@@ -948,6 +950,7 @@ int Str_ManVectorAffinity( Gia_Man_t * p, Vec_Int_t * vSuper, Vec_Int_t * vDelay
if ( nSizeNew == 0 )
{
Vec_IntShrink( vSuper, nSize );
+ ABC_FREE( Levels );
return 0;
}
/*
@@ -979,6 +982,7 @@ int Str_ManVectorAffinity( Gia_Man_t * p, Vec_Int_t * vSuper, Vec_Int_t * vDelay
}
i = 0;
}
+ ABC_FREE( Levels );
Vec_IntShrink( vSuper, nSize );
return nSizeNew;
}
@@ -1088,15 +1092,14 @@ int Str_NtkBalanceTwo( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, int i,
void Str_NtkBalanceMulti( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, Vec_Int_t * vDelay, int nLutSize )
{
- word pMatrix[256];
- int Limit = 256;
+ word * pMatrix = ABC_ALLOC( word, pObj->nFanins+256 );
Vec_Int_t * vSuper = pNew->vSuper;
Vec_Int_t * vCosts = pNew->vStore;
int * pSuper = Vec_IntArray(vSuper);
int * pCost = Vec_IntArray(vCosts);
int k, iLit, MatrixSize = 0;
- assert( Limit <= Vec_IntCap(vSuper) );
- assert( Limit <= Vec_IntCap(vCosts) );
+ assert( (int)pObj->nFanins <= Vec_IntCap(vSuper) );
+ assert( (int)pObj->nFanins <= Vec_IntCap(vCosts) );
// collect nodes
Vec_IntClear( vSuper );
@@ -1111,11 +1114,13 @@ void Str_NtkBalanceMulti( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, Vec
if ( Vec_IntSize(vSuper) == 1 )
{
pObj->iCopy = Vec_IntEntry(vSuper, 0);
+ ABC_FREE( pMatrix );
return;
}
if ( Vec_IntSize(vSuper) == 2 )
{
pObj->iCopy = Str_NtkBalanceTwo( pNew, p, pObj, 0, 1, vDelay, pCost, pSuper, pMatrix, 2, nLutSize, -1 );
+ ABC_FREE( pMatrix );
return;
}
@@ -1127,7 +1132,7 @@ void Str_NtkBalanceMulti( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, Vec
// compute affinity
if ( Vec_IntSize(vSuper) < 64 )
- MatrixSize = Str_ManVectorAffinity( pNew, vSuper, vCosts, pMatrix, Limit );
+ MatrixSize = Str_ManVectorAffinity( pNew, vSuper, vCosts, pMatrix, pObj->nFanins );
// start the new product
while ( Vec_IntSize(vSuper) > 2 )
@@ -1147,7 +1152,7 @@ void Str_NtkBalanceMulti( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, Vec
// compute affinity
if ( Vec_IntSize(vSuper) == 64 )
- MatrixSize = Str_ManVectorAffinity( pNew, vSuper, vCosts, pMatrix, Limit );
+ MatrixSize = Str_ManVectorAffinity( pNew, vSuper, vCosts, pMatrix, pObj->nFanins );
assert( Vec_IntSize(vSuper) <= 64 );
// Str_PrintState( pCost, pSuper, pMatrix, Vec_IntSize(vSuper) );
@@ -1236,6 +1241,7 @@ void Str_NtkBalanceMulti( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, Vec
continue;
}
pObj->iCopy = Str_NtkBalanceTwo( pNew, p, pObj, 0, 1, vDelay, pCost, pSuper, pMatrix, 2, nLutSize, -1 );
+ ABC_FREE( pMatrix );
/*
// simple
diff --git a/src/aig/gia/giaSupps.c b/src/aig/gia/giaSupps.c
new file mode 100644
index 00000000..f95d815d
--- /dev/null
+++ b/src/aig/gia/giaSupps.c
@@ -0,0 +1,817 @@
+/**CFile****************************************************************
+
+ FileName [giaSupp.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Support computation manager.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaSupp.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "aig/gia/gia.h"
+#include "base/main/mainInt.h"
+#include "misc/util/utilTruth.h"
+#include "misc/extra/extra.h"
+#include "misc/vec/vecHsh.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Supp_Man_t_ Supp_Man_t;
+struct Supp_Man_t_
+{
+ // user data
+ int nIters; // optimization rounds
+ int nRounds; // optimization rounds
+ int nWords; // the number of simulation words
+ int nDivWords; // the number of divisor words
+ Vec_Wrd_t * vIsfs; // functions to synthesize
+ Vec_Int_t * vCands; // candidate divisors
+ Vec_Int_t * vWeights; // divisor weights (optional)
+ Vec_Wrd_t * vSims; // simulation values
+ Vec_Wrd_t * vSimsC; // simulation values
+ Gia_Man_t * pGia; // used for object names
+ // computed data
+ Vec_Wrd_t * vDivs[2]; // simulation values
+ Vec_Wrd_t * vPats[2]; // simulation values
+ Vec_Ptr_t * vMatrix; // simulation values
+ Vec_Wrd_t * vMask; // simulation values
+ Vec_Wrd_t * vRowTemp; // simulation values
+ Vec_Int_t * vCosts; // candidate costs
+ Hsh_VecMan_t * pHash; // subsets considered
+ Vec_Wrd_t * vSFuncs; // ISF storage
+ Vec_Int_t * vSStarts; // subset function starts
+ Vec_Int_t * vSCount; // subset function count
+ Vec_Int_t * vSPairs; // subset pair count
+ Vec_Int_t * vTemp; // temporary
+ Vec_Int_t * vTempSets; // temporary
+ Vec_Int_t * vTempPairs; // temporary
+ Vec_Wec_t * vSolutions; // solutions for each node count
+};
+
+extern void Extra_BitMatrixTransposeP( Vec_Wrd_t * vSimsIn, int nWordsIn, Vec_Wrd_t * vSimsOut, int nWordsOut );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Supp_ManFuncInit( Vec_Wrd_t * vFuncs, int nWords )
+{
+ int i, k = 0, nFuncs = Vec_WrdSize(vFuncs) / nWords / 2;
+ assert( 2 * nFuncs * nWords == Vec_WrdSize(vFuncs) );
+ for ( i = 0; i < nFuncs; i++ )
+ {
+ word * pFunc0 = Vec_WrdEntryP(vFuncs, (2*i+0)*nWords);
+ word * pFunc1 = Vec_WrdEntryP(vFuncs, (2*i+1)*nWords);
+ if ( Abc_TtIsConst0(pFunc0, nWords) || Abc_TtIsConst0(pFunc1, nWords) )
+ continue;
+ if ( k < i ) Abc_TtCopy( Vec_WrdEntryP(vFuncs, (2*k+0)*nWords), pFunc0, nWords, 0 );
+ if ( k < i ) Abc_TtCopy( Vec_WrdEntryP(vFuncs, (2*k+1)*nWords), pFunc1, nWords, 0 );
+ k++;
+ }
+ Vec_WrdShrink( vFuncs, 2*k*nWords );
+ return k;
+}
+int Supp_ManCostInit( Vec_Wrd_t * vFuncs, int nWords )
+{
+ int Res = 0, i, nFuncs = Vec_WrdSize(vFuncs) / nWords / 2;
+ assert( 2 * nFuncs * nWords == Vec_WrdSize(vFuncs) );
+ for ( i = 0; i < nFuncs; i++ )
+ {
+ word * pFunc0 = Vec_WrdEntryP(vFuncs, (2*i+0)*nWords);
+ word * pFunc1 = Vec_WrdEntryP(vFuncs, (2*i+1)*nWords);
+ Res += Abc_TtCountOnesVec(pFunc0, nWords) * Abc_TtCountOnesVec(pFunc1, nWords);
+ }
+ assert( nFuncs < 128 );
+ assert( Res < (1 << 24) );
+ return (nFuncs << 24) | Res;
+}
+void Supp_ManInit( Supp_Man_t * p )
+{
+ int Value, nFuncs, iSet = Hsh_VecManAdd( p->pHash, p->vTemp ); // empty set
+ assert( iSet == 0 );
+ Vec_IntPush( p->vSStarts, Vec_WrdSize(p->vSFuncs) );
+ Vec_WrdAppend( p->vSFuncs, p->vIsfs );
+ nFuncs = Supp_ManFuncInit( p->vSFuncs, p->nWords );
+ assert( Vec_WrdSize(p->vSFuncs) == 2 * nFuncs * p->nWords );
+ Value = Supp_ManCostInit(p->vSFuncs, p->nWords);
+ Vec_IntPush( p->vSCount, Value >> 24 );
+ Vec_IntPush( p->vSPairs, Value & 0xFFFFFF );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Supp_DeriveLines( Supp_Man_t * p )
+{
+ int n, i, iObj, nWords = p->nWords;
+ int nDivWords = Abc_Bit6WordNum( Vec_IntSize(p->vCands) );
+ for ( n = 0; n < 2; n++ )
+ {
+ p->vDivs[n] = Vec_WrdStart( 64*nWords*nDivWords );
+ p->vPats[n] = Vec_WrdStart( 64*nWords*nDivWords );
+ if ( p->vSimsC )
+ Vec_IntForEachEntry( p->vCands, iObj, i )
+ Abc_TtAndSharp( Vec_WrdEntryP(p->vDivs[n], i*nWords), Vec_WrdEntryP(p->vSimsC, iObj*nWords), Vec_WrdEntryP(p->vSims, iObj*nWords), nWords, !n );
+ else
+ Vec_IntForEachEntry( p->vCands, iObj, i )
+ Abc_TtCopy( Vec_WrdEntryP(p->vDivs[n], i*nWords), Vec_WrdEntryP(p->vSims, iObj*nWords), nWords, !n );
+ Extra_BitMatrixTransposeP( p->vDivs[n], nWords, p->vPats[n], nDivWords );
+ }
+ return nDivWords;
+}
+Supp_Man_t * Supp_ManCreate( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vWeights, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsC, int nWords, Gia_Man_t * pGia, int nIters, int nRounds )
+{
+ Supp_Man_t * p = ABC_CALLOC( Supp_Man_t, 1 );
+ p->nIters = nIters;
+ p->nRounds = nRounds;
+ p->nWords = nWords;
+ p->vIsfs = vIsfs;
+ p->vCands = vCands;
+ p->vWeights = vWeights;
+ p->vSims = vSims;
+ p->vSimsC = vSimsC;
+ p->pGia = pGia;
+ // computed data
+ p->nDivWords = Supp_DeriveLines( p );
+ p->vMatrix = Vec_PtrAlloc( 100 );
+ p->vMask = Vec_WrdAlloc( 100 );
+ p->vRowTemp = Vec_WrdStart( 64*p->nDivWords );
+ p->vCosts = Vec_IntStart( Vec_IntSize(p->vCands) );
+ p->pHash = Hsh_VecManStart( 1000 );
+ p->vSFuncs = Vec_WrdAlloc( 1000 );
+ p->vSStarts = Vec_IntAlloc( 1000 );
+ p->vSCount = Vec_IntAlloc( 1000 );
+ p->vSPairs = Vec_IntAlloc( 1000 );
+ p->vSolutions = Vec_WecStart( 16 );
+ p->vTemp = Vec_IntAlloc( 10 );
+ p->vTempSets = Vec_IntAlloc( 10 );
+ p->vTempPairs = Vec_IntAlloc( 10 );
+ Supp_ManInit( p );
+ return p;
+}
+void Supp_ManCleanMatrix( Supp_Man_t * p )
+{
+ Vec_Wrd_t * vTemp; int i;
+ Vec_PtrForEachEntry( Vec_Wrd_t *, p->vMatrix, vTemp, i )
+ Vec_WrdFreeP( &vTemp );
+ Vec_PtrClear( p->vMatrix );
+}
+void Supp_ManDelete( Supp_Man_t * p )
+{
+ Supp_ManCleanMatrix( p );
+ Vec_WrdFreeP( &p->vDivs[0] );
+ Vec_WrdFreeP( &p->vDivs[1] );
+ Vec_WrdFreeP( &p->vPats[0] );
+ Vec_WrdFreeP( &p->vPats[1] );
+ Vec_PtrFreeP( &p->vMatrix );
+ Vec_WrdFreeP( &p->vMask );
+ Vec_WrdFreeP( &p->vRowTemp );
+ Vec_IntFreeP( &p->vCosts );
+ Hsh_VecManStop( p->pHash );
+ Vec_WrdFreeP( &p->vSFuncs );
+ Vec_IntFreeP( &p->vSStarts );
+ Vec_IntFreeP( &p->vSCount );
+ Vec_IntFreeP( &p->vSPairs );
+ Vec_WecFreeP( &p->vSolutions );
+ Vec_IntFreeP( &p->vTemp );
+ Vec_IntFreeP( &p->vTempSets );
+ Vec_IntFreeP( &p->vTempPairs );
+ ABC_FREE( p );
+}
+int Supp_ManMemory( Supp_Man_t * p )
+{
+ int nMem = sizeof(Supp_Man_t);
+ nMem += 2*(int)Vec_WrdMemory( p->vDivs[0] );
+ nMem += 2*(int)Vec_WrdMemory( p->vPats[0] );
+ nMem += (Vec_PtrSize(p->vMatrix)+1)*(int)Vec_WrdMemory( p->vRowTemp );
+ nMem += (int)Vec_WrdMemory( p->vMask );
+ nMem += (int)Vec_IntMemory( p->vCosts );
+ nMem += (int)Hsh_VecManMemory( p->pHash );
+ nMem += (int)Vec_WrdMemory( p->vSFuncs );
+ nMem += (int)Vec_IntMemory( p->vSStarts );
+ nMem += (int)Vec_IntMemory( p->vSCount );
+ nMem += (int)Vec_IntMemory( p->vSPairs );
+ nMem += (int)Vec_WecMemory( p->vSolutions );
+ nMem += (int)Vec_IntMemory( p->vTemp );
+ nMem += (int)Vec_IntMemory( p->vTempSets );
+ nMem += (int)Vec_IntMemory( p->vTempPairs );
+ return nMem;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Supp_ArrayWeight( Vec_Int_t * vRes, Vec_Int_t * vWeights )
+{
+ int i, iObj, Cost = 0;
+ if ( !vWeights )
+ return Vec_IntSize(vRes);
+ Vec_IntForEachEntry( vRes, iObj, i )
+ Cost += Vec_IntEntry(vWeights, iObj);
+ return Cost;
+}
+int Supp_SetWeight( Supp_Man_t * p, int iSet )
+{
+ return Supp_ArrayWeight( Hsh_VecReadEntry(p->pHash, iSet), p->vWeights );
+}
+int Supp_SetSize( Supp_Man_t * p, int iSet )
+{
+ return Vec_IntSize( Hsh_VecReadEntry(p->pHash, iSet) );
+}
+int Supp_SetFuncNum( Supp_Man_t * p, int iSet )
+{
+ return Vec_IntEntry(p->vSCount, iSet);
+}
+int Supp_SetPairNum( Supp_Man_t * p, int iSet )
+{
+ return Vec_IntEntry(p->vSPairs, iSet);
+}
+void Supp_SetConvert( Vec_Int_t * vSet, Vec_Int_t * vCands )
+{
+ int i, iObj;
+ Vec_IntForEachEntry( vSet, iObj, i )
+ Vec_IntWriteEntry( vSet, i, Vec_IntEntry(vCands, iObj) );
+}
+void Supp_PrintNodes( Gia_Man_t * pGia, Vec_Int_t * vObjs, int Skip, int Limit )
+{
+ int i, iObj;
+ //printf( "Considering %d targets: ", Vec_IntSize(vObjs) );
+ Vec_IntForEachEntryStart( vObjs, iObj, i, Skip )
+ {
+ if ( iObj < 0 )
+ continue;
+ printf( "(%d)", iObj );
+ if ( pGia && pGia->vWeights && Vec_IntEntry(pGia->vWeights, iObj) > 0 )
+ printf( "(%d)", Vec_IntEntry(pGia->vWeights, iObj) );
+ if ( pGia )
+ printf( " %s ", Gia_ObjName(pGia, iObj)+2 );
+ else
+ printf( " n%d ", iObj );
+ if ( i >= Limit )
+ {
+ printf( "... " );
+ break;
+ }
+ }
+ printf( "Cost = %d", Supp_ArrayWeight(vObjs, pGia ? pGia->vWeights : NULL) );
+ printf( "\n" );
+}
+void Supp_PrintOne( Supp_Man_t * p, int iSet )
+{
+ Vec_Int_t * vSet = Hsh_VecReadEntry(p->pHash, iSet);
+ printf( "Set %5d : ", iSet );
+ printf( "Funcs %2d ", Supp_SetFuncNum(p, iSet) );
+ printf( "Pairs %4d ", Supp_SetPairNum(p, iSet) );
+ printf( "Start %8d ", Vec_IntEntry(p->vSStarts, iSet) );
+ printf( "Weight %4d ", Supp_ArrayWeight(vSet, p->vWeights) );
+ Vec_IntClearAppend( p->vTemp, vSet );
+ Supp_SetConvert( p->vTemp, p->vCands );
+ Supp_PrintNodes( p->pGia, p->vTemp, 0, 6 );
+}
+int Supp_ManRefine1( Supp_Man_t * p, int iSet, int iObj )
+{
+ word * pSet = Vec_WrdEntryP( p->vSims, Vec_IntEntry(p->vCands, iObj)*p->nWords );
+ word * pIsf; int nFuncs = Vec_IntEntry(p->vSCount, iSet);
+ int i, n, f, w, nFuncsNew = 0, Mark = Vec_WrdSize(p->vSFuncs), Res = 0;
+ if ( Vec_WrdSize(p->vSFuncs) + 4*nFuncs*p->nWords > Vec_WrdCap(p->vSFuncs) )
+ Vec_WrdGrow( p->vSFuncs, 2*Vec_WrdCap(p->vSFuncs) );
+ pIsf = Vec_WrdEntryP( p->vSFuncs, Vec_IntEntry(p->vSStarts, iSet) );
+ for ( i = 0; i < nFuncs; i++ )
+ {
+ word * pFunc[2] = { pIsf + (2*i+0)*p->nWords, pIsf + (2*i+1)*p->nWords };
+ for ( f = 0; f < 2; f++ )
+ {
+ int nOnes[2], Start = Vec_WrdSize(p->vSFuncs);
+ for ( n = 0; n < 2; n++ )
+ {
+ word * pLimit = Vec_WrdLimit(p->vSFuncs);
+ if ( f )
+ for ( w = 0; w < p->nWords; w++ )
+ Vec_WrdPush( p->vSFuncs, pFunc[n][w] & pSet[w] );
+ else
+ for ( w = 0; w < p->nWords; w++ )
+ Vec_WrdPush( p->vSFuncs, pFunc[n][w] & ~pSet[w] );
+ nOnes[n] = Abc_TtCountOnesVec( pLimit, p->nWords );
+ }
+ if ( nOnes[0] && nOnes[1] )
+ Res += nOnes[0] * nOnes[1];
+ else
+ Vec_WrdShrink( p->vSFuncs, Start );
+ }
+ }
+ assert( Res < (1 << 24) );
+ nFuncsNew = (Vec_WrdSize(p->vSFuncs) - Mark)/2/p->nWords;
+ assert( nFuncsNew < 128 );
+ assert( nFuncsNew >= 0 && nFuncsNew <= 2*nFuncs );
+ return (nFuncsNew << 24) | Res;
+}
+void Supp_ManRefine( Supp_Man_t * p, int iSet, int iObj, int * pnFuncs, int * pnPairs )
+{
+ word * pDivs0 = Vec_WrdEntryP( p->vDivs[0], iObj*p->nWords );
+ word * pDivs1 = Vec_WrdEntryP( p->vDivs[1], iObj*p->nWords );
+ word * pIsf; int nFuncs = Supp_SetFuncNum(p, iSet);
+ int i, f, w, nFuncsNew = 0, Mark = Vec_WrdSize(p->vSFuncs), Res = 0;
+ if ( Vec_WrdSize(p->vSFuncs) + 6*nFuncs*p->nWords > Vec_WrdCap(p->vSFuncs) )
+ Vec_WrdGrow( p->vSFuncs, 2*Vec_WrdCap(p->vSFuncs) );
+ if ( Vec_WrdSize(p->vSFuncs) == Vec_IntEntry(p->vSStarts, iSet) )
+ pIsf = Vec_WrdLimit( p->vSFuncs );
+ else
+ pIsf = Vec_WrdEntryP( p->vSFuncs, Vec_IntEntry(p->vSStarts, iSet) );
+ for ( i = 0; i < nFuncs; i++ )
+ {
+ word * pFunc[2] = { pIsf + (2*i+0)*p->nWords, pIsf + (2*i+1)*p->nWords };
+ for ( f = 0; f < 3; f++ )
+ {
+ int nOnes[2], Start = Vec_WrdSize(p->vSFuncs);
+ word * pLimit[2] = { Vec_WrdLimit(p->vSFuncs), Vec_WrdLimit(p->vSFuncs) + p->nWords };
+ if ( f == 0 )
+ {
+ for ( w = 0; w < p->nWords; w++ )
+ Vec_WrdPush( p->vSFuncs, pFunc[0][w] & pDivs0[w] );
+ for ( w = 0; w < p->nWords; w++ )
+ Vec_WrdPush( p->vSFuncs, pFunc[1][w] & ~pDivs1[w] );
+ }
+ else if ( f == 1 )
+ {
+ for ( w = 0; w < p->nWords; w++ )
+ Vec_WrdPush( p->vSFuncs, pFunc[0][w] & pDivs1[w] );
+ for ( w = 0; w < p->nWords; w++ )
+ Vec_WrdPush( p->vSFuncs, pFunc[1][w] & ~pDivs0[w] );
+ }
+ else
+ {
+ for ( w = 0; w < p->nWords; w++ )
+ Vec_WrdPush( p->vSFuncs, pFunc[0][w] & ~pDivs0[w] & ~pDivs1[w] );
+ for ( w = 0; w < p->nWords; w++ )
+ Vec_WrdPush( p->vSFuncs, pFunc[1][w] );
+ }
+ nOnes[0] = Abc_TtCountOnesVec( pLimit[0], p->nWords );
+ nOnes[1] = Abc_TtCountOnesVec( pLimit[1], p->nWords );
+ if ( nOnes[0] && nOnes[1] )
+ Res += nOnes[0] * nOnes[1];
+ else
+ Vec_WrdShrink( p->vSFuncs, Start );
+ }
+ }
+ assert( Res < (1 << 24) );
+ nFuncsNew = (Vec_WrdSize(p->vSFuncs) - Mark)/2/p->nWords;
+ *pnFuncs = nFuncsNew;
+ *pnPairs = Res;
+}
+int Supp_ManSubsetAdd( Supp_Man_t * p, int iSet, int iObj, int fVerbose )
+{
+ int iSetNew, nEntries = Hsh_VecSize( p->pHash );
+ Vec_Int_t * vSet = Hsh_VecReadEntry( p->pHash, iSet );
+ Vec_IntClear( p->vTemp );
+ Vec_IntAppend( p->vTemp, vSet );
+ Vec_IntPushOrder( p->vTemp, iObj );
+ assert( Vec_IntIsOrdered(p->vTemp, 0) );
+ iSetNew = Hsh_VecManAdd( p->pHash, p->vTemp );
+ if ( iSetNew == nEntries ) // new entry
+ {
+ int nFuncs, nPairs;
+ Vec_IntPush( p->vSStarts, Vec_WrdSize(p->vSFuncs) );
+ Supp_ManRefine( p, iSet, iObj, &nFuncs, &nPairs );
+ Vec_IntPush( p->vSCount, nFuncs );
+ Vec_IntPush( p->vSPairs, nPairs );
+ assert( Hsh_VecSize(p->pHash) == Vec_IntSize(p->vSStarts) );
+ assert( Hsh_VecSize(p->pHash) == Vec_IntSize(p->vSCount) );
+ assert( Hsh_VecSize(p->pHash) == Vec_IntSize(p->vSPairs) );
+ if ( Supp_SetFuncNum(p, iSetNew) == 0 && Supp_SetSize(p, iSetNew) < Vec_WecSize(p->vSolutions) )
+ Vec_WecPush( p->vSolutions, Supp_SetSize(p, iSetNew), iSetNew );
+ if ( fVerbose )
+ Supp_PrintOne( p, iSetNew );
+ }
+ return iSetNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Supp_ComputePair1( Supp_Man_t * p, int iSet )
+{
+ int Random = 0xFFFFFF & Abc_Random(0);
+ int nFuncs = Vec_IntEntry(p->vSCount, iSet);
+ int iFunc = Random % nFuncs;
+ word * pIsf = Vec_WrdEntryP( p->vSFuncs, Vec_IntEntry(p->vSStarts, iSet) );
+ word * pFunc[2] = { pIsf + (2*iFunc+0)*p->nWords, pIsf + (2*iFunc+1)*p->nWords };
+ int iBit0 = ((Random >> 16) & 1) ? Abc_TtFindFirstBit2(pFunc[0], p->nWords) : Abc_TtFindLastBit2(pFunc[0], p->nWords);
+ int iBit1 = ((Random >> 17) & 1) ? Abc_TtFindFirstBit2(pFunc[1], p->nWords) : Abc_TtFindLastBit2(pFunc[1], p->nWords);
+ if ( 1 )
+ {
+ Vec_Int_t * vSet = Hsh_VecReadEntry( p->pHash, iSet ); int i, iObj;
+ Vec_IntForEachEntry( vSet, iObj, i )
+ {
+ word * pSet = Vec_WrdEntryP( p->vSims, Vec_IntEntry(p->vCands, iObj)*p->nWords );
+ assert( Abc_TtGetBit(pSet, iBit0) == Abc_TtGetBit(pSet, iBit1) );
+ }
+ }
+ return (iBit0 << 16) | iBit1;
+}
+int Supp_ComputePair( Supp_Man_t * p, int iSet )
+{
+ int Random = 0xFFFFFF & Abc_Random(0);
+ int nFuncs = Vec_IntEntry(p->vSCount, iSet);
+ int iFunc = Random % nFuncs;
+ word * pIsf = Vec_WrdEntryP( p->vSFuncs, Vec_IntEntry(p->vSStarts, iSet) );
+ word * pFunc[2] = { pIsf + (2*iFunc+0)*p->nWords, pIsf + (2*iFunc+1)*p->nWords };
+ int iBit0 = ((Random >> 16) & 1) ? Abc_TtFindFirstBit2(pFunc[0], p->nWords) : Abc_TtFindLastBit2(pFunc[0], p->nWords);
+ int iBit1 = ((Random >> 17) & 1) ? Abc_TtFindFirstBit2(pFunc[1], p->nWords) : Abc_TtFindLastBit2(pFunc[1], p->nWords);
+ if ( 1 )
+ {
+ Vec_Int_t * vSet = Hsh_VecReadEntry( p->pHash, iSet ); int i, iObj;
+ Vec_IntForEachEntry( vSet, iObj, i )
+ {
+ word * pSet0 = Vec_WrdEntryP( p->vDivs[0], iObj*p->nWords );
+ word * pSet1 = Vec_WrdEntryP( p->vDivs[1], iObj*p->nWords );
+ int Value00 = Abc_TtGetBit(pSet0, iBit0);
+ int Value01 = Abc_TtGetBit(pSet0, iBit1);
+ int Value10 = Abc_TtGetBit(pSet1, iBit0);
+ int Value11 = Abc_TtGetBit(pSet1, iBit1);
+ assert( !Value00 || !Value11 );
+ assert( !Value01 || !Value10 );
+ }
+ }
+ return (iBit0 << 16) | iBit1;
+}
+Vec_Int_t * Supp_Compute64Pairs( Supp_Man_t * p, Vec_Int_t * vSets )
+{
+ int i;
+ Vec_IntClear( p->vTempPairs );
+ for ( i = 0; i < 64; i++ )
+ {
+ int Rand = 0xFFFFFF & Abc_Random(0);
+ int iSet = Vec_IntEntry( vSets, Rand % Vec_IntSize(vSets) );
+ Vec_IntPush( p->vTempPairs, Supp_ComputePair(p, iSet) );
+ }
+ return p->vTempPairs;
+}
+void Supp_ManFillBlock( Supp_Man_t * p, Vec_Int_t * vPairs, Vec_Wrd_t * vRes )
+{
+ int i, Pair;
+ assert( Vec_IntSize(vPairs) == 64 );
+ Vec_IntForEachEntry( vPairs, Pair, i )
+ {
+ int iBit0 = Pair >> 16, iBit1 = Pair & 0xFFFF;
+ word * pPat00 = Vec_WrdEntryP(p->vPats[0], iBit0*p->nDivWords);
+ word * pPat01 = Vec_WrdEntryP(p->vPats[0], iBit1*p->nDivWords);
+ word * pPat10 = Vec_WrdEntryP(p->vPats[1], iBit0*p->nDivWords);
+ word * pPat11 = Vec_WrdEntryP(p->vPats[1], iBit1*p->nDivWords);
+ word * pPat = Vec_WrdEntryP(p->vRowTemp, i*p->nDivWords);
+ Abc_TtAnd( pPat, pPat00, pPat11, p->nDivWords, 0 );
+ Abc_TtOrAnd( pPat, pPat01, pPat10, p->nDivWords );
+ }
+ Extra_BitMatrixTransposeP( p->vRowTemp, p->nDivWords, vRes, 1 );
+}
+void Supp_ManAddPatterns( Supp_Man_t * p, Vec_Int_t * vSets )
+{
+ Vec_Int_t * vPairs = Supp_Compute64Pairs( p, vSets );
+ Vec_Wrd_t * vRow = Vec_WrdStart( 64*p->nDivWords );
+ Supp_ManFillBlock( p, vPairs, vRow );
+ Vec_PtrPush( p->vMatrix, vRow );
+}
+Vec_Int_t * Supp_ManCollectOnes( word * pSim, int nWords )
+{
+ Vec_Int_t * vRes = Vec_IntAlloc( 100 ); int i;
+ for ( i = 0; i < 64*nWords; i++ )
+ if ( Abc_TtGetBit(pSim, i) )
+ Vec_IntPush( vRes, i );
+ return vRes;
+}
+Vec_Int_t * Supp_Compute64PairsFunc( Supp_Man_t * p, Vec_Int_t * vBits0, Vec_Int_t * vBits1 )
+{
+ int i;
+ Vec_IntClear( p->vTempPairs );
+ for ( i = 0; i < 64; i++ )
+ {
+ int Random = 0xFFFFFF & Abc_Random(0);
+ int iBit0 = Vec_IntEntry( vBits0, (Random & 0xFFF) % Vec_IntSize(vBits0) );
+ int iBit1 = Vec_IntEntry( vBits1, (Random >> 12) % Vec_IntSize(vBits1) );
+ Vec_IntPush( p->vTempPairs, (iBit0 << 16) | iBit1 );
+ }
+ return p->vTempPairs;
+}
+void Supp_ManAddPatternsFunc( Supp_Man_t * p, int nBatches )
+{
+ int b;
+ Vec_Int_t * vBits0 = Supp_ManCollectOnes( Vec_WrdEntryP(p->vSFuncs, 0*p->nWords), p->nWords );
+ Vec_Int_t * vBits1 = Supp_ManCollectOnes( Vec_WrdEntryP(p->vSFuncs, 1*p->nWords), p->nWords );
+ for ( b = 0; b < nBatches; b++ )
+ {
+ Vec_Int_t * vPairs = Supp_Compute64PairsFunc( p, vBits0, vBits1 );
+ Vec_Wrd_t * vRow = Vec_WrdStart( 64*p->nDivWords );
+ Supp_ManFillBlock( p, vPairs, vRow );
+ Vec_PtrPush( p->vMatrix, vRow );
+ }
+ Vec_IntFree( vBits0 );
+ Vec_IntFree( vBits1 );
+}
+int Supp_FindNextDiv( Supp_Man_t * p, int Pair )
+{
+ int iDiv, iBit0 = Pair >> 16, iBit1 = Pair & 0xFFFF;
+ word * pPat00 = Vec_WrdEntryP(p->vPats[0], iBit0*p->nDivWords);
+ word * pPat01 = Vec_WrdEntryP(p->vPats[0], iBit1*p->nDivWords);
+ word * pPat10 = Vec_WrdEntryP(p->vPats[1], iBit0*p->nDivWords);
+ word * pPat11 = Vec_WrdEntryP(p->vPats[1], iBit1*p->nDivWords);
+ int iDiv1 = Abc_TtFindFirstAndBit2( pPat00, pPat11, p->nDivWords );
+ int iDiv2 = Abc_TtFindFirstAndBit2( pPat01, pPat10, p->nDivWords );
+ iDiv1 = iDiv1 == -1 ? ABC_INFINITY : iDiv1;
+ iDiv2 = iDiv2 == -1 ? ABC_INFINITY : iDiv2;
+ iDiv = Abc_MinInt( iDiv1, iDiv2 );
+ assert( iDiv >= 0 && iDiv < Vec_IntSize(p->vCands) );
+ return iDiv;
+}
+int Supp_ManRandomSolution( Supp_Man_t * p, int iSet, int fVerbose )
+{
+ Vec_IntClear( p->vTempSets );
+ while ( Supp_SetFuncNum(p, iSet) > 0 )
+ {
+ int Pair = Supp_ComputePair( p, iSet );
+ int iDiv = Supp_FindNextDiv( p, Pair );
+ iSet = Supp_ManSubsetAdd( p, iSet, iDiv, fVerbose );
+ if ( Supp_SetFuncNum(p, iSet) > 0 )
+ Vec_IntPush( p->vTempSets, iSet );
+ }
+ if ( Vec_IntSize(p->vTempSets) < 2 )
+ return iSet;
+ Supp_ManAddPatterns( p, p->vTempSets );
+ return iSet;
+}
+int Supp_ManSubsetRemove( Supp_Man_t * p, int iSet, int iPos )
+{
+ int i, iSetNew = 0, nSize = Supp_SetSize(p, iSet);
+ for ( i = 0; i < nSize; i++ )
+ if ( i != iPos && Supp_SetFuncNum(p, iSetNew) > 0 )
+ iSetNew = Supp_ManSubsetAdd( p, iSetNew, Vec_IntEntry(Hsh_VecReadEntry(p->pHash, iSet), i), 0 );
+ return iSetNew;
+}
+int Supp_ManMinimize( Supp_Man_t * p, int iSet0, int r, int fVerbose )
+{
+ int i, nSize = Supp_SetSize(p, iSet0);
+ Vec_Int_t * vPerm = Vec_IntStartNatural( Supp_SetSize(p, iSet0) );
+ Vec_IntRandomizeOrder( vPerm );
+ Vec_IntClear( p->vTempSets );
+ if ( fVerbose )
+ printf( "Removing items from %d:\n", iSet0 );
+ // make sure we first try to remove items with higher weight
+ for ( i = 0; i < nSize; i++ )
+ {
+ int Index = Vec_IntEntry( vPerm, i );
+ int iSet = Supp_ManSubsetRemove( p, iSet0, Index );
+ if ( fVerbose )
+ printf( "Item %2d : ", Index );
+ if ( fVerbose )
+ Supp_PrintOne( p, iSet );
+ if ( Supp_SetFuncNum(p, iSet) == 0 )
+ {
+ Vec_IntFree( vPerm );
+ return Supp_ManMinimize( p, iSet, r, fVerbose );
+ }
+ Vec_IntPush( p->vTempSets, iSet );
+ }
+ Supp_ManAddPatterns( p, p->vTempSets );
+ Vec_IntFree( vPerm );
+ return iSet0;
+}
+int Supp_ManFindNextObj( Supp_Man_t * p, int fVerbose )
+{
+ Vec_Wrd_t * vTemp; int r, k, iDiv;
+ word Sim, * pMask = Vec_WrdArray(p->vMask);
+ assert( Vec_WrdSize(p->vMask) == Vec_PtrSize(p->vMatrix) );
+ Vec_IntFill( p->vCosts, Vec_IntSize(p->vCosts), 0 );
+ Vec_PtrForEachEntry( Vec_Wrd_t *, p->vMatrix, vTemp, r )
+ Vec_WrdForEachEntryStop( vTemp, Sim, k, Vec_IntSize(p->vCosts) )
+ Vec_IntAddToEntry( p->vCosts, k, Abc_TtCountOnes(Sim & pMask[r]) );
+ iDiv = Vec_IntArgMax( p->vCosts );
+ if ( fVerbose )
+ printf( "Choosing divisor %d with weight %d.\n", iDiv, Vec_IntEntry(p->vCosts, iDiv) );
+ Vec_PtrForEachEntry( Vec_Wrd_t *, p->vMatrix, vTemp, r )
+ pMask[r] &= ~Vec_WrdEntry( vTemp, iDiv );
+ return iDiv;
+}
+int Supp_ManReconstruct( Supp_Man_t * p, int fVerbose )
+{
+ int iSet = 0;
+ Vec_WrdFill( p->vMask, Vec_PtrSize(p->vMatrix), ~(word)0 );
+ if ( fVerbose )
+ printf( "\nBuilding a new set:\n" );
+ while ( Supp_SetPairNum(p, iSet) )
+ {
+ int iDiv = Supp_ManFindNextObj( p, fVerbose );
+ iSet = Supp_ManSubsetAdd( p, iSet, iDiv, fVerbose );
+ if ( Abc_TtIsConst0(Vec_WrdArray(p->vMask), Vec_WrdSize(p->vMask)) )
+ break;
+ }
+ if ( fVerbose )
+ printf( "Adding random part:\n" );
+ return Supp_ManRandomSolution( p, iSet, fVerbose );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Supp_ManFindBestSolution( Supp_Man_t * p, Vec_Wec_t * vSols, int fVerbose, Vec_Int_t ** pvDivs )
+{
+ Vec_Int_t * vLevel, * vRes = NULL;
+ int i, k, iSet, nFuncs = 0, Count = 0;
+ int iSolBest = -1, Cost, CostBest = ABC_INFINITY;
+ Vec_WecForEachLevel( vSols, vLevel, i )
+ {
+ Count += Vec_IntSize(vLevel) > 0;
+ Vec_IntForEachEntry( vLevel, iSet, k )
+ {
+ if ( fVerbose )
+ printf( "%3d : ", nFuncs++ );
+ Cost = Gia_ManEvalSolutionOne( p->pGia, p->vSims, p->vIsfs, p->vCands, Hsh_VecReadEntry(p->pHash, iSet), p->nWords, fVerbose );
+ if ( Cost == -1 )
+ continue;
+ if ( CostBest > Cost )
+ {
+ CostBest = Cost;
+ iSolBest = iSet;
+ }
+ if ( nFuncs > 5 )
+ break;
+ }
+ if ( Count == 2 || k < Vec_IntSize(vLevel) )
+ break;
+ }
+ if ( iSolBest > 0 && (CostBest >> 2) < 50 )
+ {
+ Vec_Int_t * vSet = Hsh_VecReadEntry( p->pHash, iSolBest ); int i, iObj;
+ vRes = Gia_ManDeriveSolutionOne( p->pGia, p->vSims, p->vIsfs, p->vCands, vSet, p->nWords, CostBest & 3 );
+ assert( !vRes || Vec_IntSize(vRes) == 2*(CostBest >> 2)+1 );
+ if ( vRes && pvDivs )
+ {
+ Vec_IntClear( *pvDivs );
+ Vec_IntPushTwo( *pvDivs, -1, -1 );
+ Vec_IntForEachEntry( vSet, iObj, i )
+ Vec_IntPush( *pvDivs, Vec_IntEntry(p->vCands, iObj) );
+ }
+ }
+ return vRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Supp_FindGivenOne( Supp_Man_t * p )
+{
+ int i, iObj, iSet = 0;
+ Vec_Int_t * vSet = Vec_IntStart( 2 );
+ //extern void Patch_GenerateSet11( Gia_Man_t * p, Vec_Int_t * vDivs, Vec_Int_t * vCands );
+ //Patch_GenerateSet11( p->pGia, vSet, p->vCands );
+ Vec_IntDrop( vSet, 0 );
+ Vec_IntDrop( vSet, 0 );
+ Vec_IntForEachEntry( vSet, iObj, i )
+ iSet = Supp_ManSubsetAdd( p, iSet, iObj, 1 );
+ Vec_IntFree( vSet );
+ return iSet;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Supp_ManCompute( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vWeights, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsC, int nWords, Gia_Man_t * pGia, Vec_Int_t ** pvDivs, int nIters, int nRounds, int fVerbose )
+{
+ int fVeryVerbose = 0;
+ int i, r, iSet, iBest = -1;
+ abctime clk = Abc_Clock();
+ Vec_Int_t * vRes = NULL;
+ Supp_Man_t * p = Supp_ManCreate( vIsfs, vCands, vWeights, vSims, vSimsC, nWords, pGia, nIters, nRounds );
+ if ( Supp_SetFuncNum(p, 0) == 0 )
+ {
+ Supp_ManDelete( p );
+ Vec_IntClear( *pvDivs );
+ Vec_IntPushTwo( *pvDivs, -1, -1 );
+ vRes = Vec_IntAlloc( 1 );
+ Vec_IntPush( vRes, Abc_TtIsConst0(Vec_WrdArray(vIsfs), nWords) );
+ return vRes;
+ }
+ if ( fVerbose )
+ printf( "\nUsing %d divisors with %d words. Problem has %d functions and %d minterm pairs.\n",
+ Vec_IntSize(p->vCands), p->nWords, Supp_SetFuncNum(p, 0), Supp_SetPairNum(p, 0) );
+ //iBest = Supp_FindGivenOne( p );
+ if ( iBest == -1 )
+ for ( i = 0; i < p->nIters; i++ )
+ {
+ Supp_ManAddPatternsFunc( p, i );
+ iSet = Supp_ManRandomSolution( p, 0, fVeryVerbose );
+ for ( r = 0; r < p->nRounds; r++ )
+ {
+ if ( fVeryVerbose )
+ printf( "\n\nITER %d ROUND %d\n", i, r );
+ iSet = Supp_ManMinimize( p, iSet, r, fVeryVerbose );
+ if ( iBest == -1 || Supp_SetWeight(p, iBest) > Supp_SetWeight(p, iSet) )
+ //if ( Supp_SetSize(p, iBest) > Supp_SetSize(p, iSet) )
+ {
+ if ( fVeryVerbose )
+ printf( "\nThe best solution found:\n" );
+ if ( fVeryVerbose )
+ Supp_PrintOne( p, iSet );
+ iBest = iSet;
+ }
+ iSet = Supp_ManReconstruct( p, fVeryVerbose );
+ }
+ if ( fVeryVerbose )
+ printf( "Matrix size %d.\n", Vec_PtrSize(p->vMatrix) );
+ Supp_ManCleanMatrix( p );
+ }
+ if ( fVerbose )
+ {
+ printf( "Explored %d divisor sets. Found %d solutions. Memory usage %.2f MB. ",
+ Hsh_VecSize(p->pHash), Vec_WecSizeSize(p->vSolutions), 1.0*Supp_ManMemory(p)/(1<<20) );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ printf( "The best solution: " );
+ if ( iBest == -1 )
+ printf( "No solution.\n" );
+ else
+ Supp_PrintOne( p, iBest );
+ }
+ vRes = Supp_ManFindBestSolution( p, p->vSolutions, fVerbose, pvDivs );
+ Supp_ManDelete( p );
+// if ( vRes && Vec_IntSize(vRes) == 0 )
+// Vec_IntFreeP( &vRes );
+ return vRes;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaSweep.c b/src/aig/gia/giaSweep.c
index 1d66caee..8a7fcbd0 100644
--- a/src/aig/gia/giaSweep.c
+++ b/src/aig/gia/giaSweep.c
@@ -388,6 +388,14 @@ Vec_Int_t * Gia_ManComputeCarryOuts( Gia_Man_t * p )
Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime;
int i, iLast, iBox, nBoxes = Tim_ManBoxNum( pManTime );
Vec_Int_t * vCarryOuts = Vec_IntAlloc( nBoxes );
+
+ // Create and populate reference count (and free later) only if not already
+ // done.
+ int createRefs = (p->pRefs == NULL);
+ if (createRefs) {
+ Gia_ManCreateRefs( p );
+ }
+
for ( i = 0; i < nBoxes; i++ )
{
iLast = Tim_ManBoxInputLast( pManTime, i );
@@ -398,9 +406,24 @@ Vec_Int_t * Gia_ManComputeCarryOuts( Gia_Man_t * p )
if ( iBox == -1 )
continue;
assert( Gia_ObjIsCi(pObj) );
- if ( Gia_ObjCioId(pObj) == Tim_ManBoxOutputLast(pManTime, iBox) )
+ if ( Gia_ObjCioId(pObj) == Tim_ManBoxOutputLast(pManTime, iBox) ) {
Vec_IntPush( vCarryOuts, Gia_ObjId(p, pObj) );
+
+ // We have identified a carry connection. Check if the carry out
+ // of the destination box is unconnected. If so then add it to
+ // the carry list as well.
+ iLast = Tim_ManBoxOutputLast(pManTime, i);
+ pObj = Gia_ManCi(p, iLast);
+ if ( Gia_ObjRefNum(p, pObj) == 0 ) {
+ Vec_IntPush( vCarryOuts, Gia_ObjId(p, pObj) );
+ }
+ }
+ }
+
+ if (createRefs) {
+ ABC_FREE( p->pRefs );
}
+
return vCarryOuts;
}
diff --git a/src/aig/gia/giaTruth.c b/src/aig/gia/giaTruth.c
index 91c4fa24..c24748ed 100644
--- a/src/aig/gia/giaTruth.c
+++ b/src/aig/gia/giaTruth.c
@@ -118,27 +118,6 @@ word Gia_LutComputeTruth6Map( Gia_Man_t * p, int iPo, Vec_Int_t * vMap )
SeeAlso []
***********************************************************************/
-static unsigned s_Truths5[5] = {
- 0xAAAAAAAA,
- 0xCCCCCCCC,
- 0xF0F0F0F0,
- 0xFF00FF00,
- 0xFFFF0000,
-};
-static inline int Abc_Tt5HasVar( unsigned t, int iVar )
-{
- return ((t << (1<<iVar)) & s_Truths5[iVar]) != (t & s_Truths5[iVar]);
-}
-static inline unsigned Abc_Tt5Cofactor0( unsigned t, int iVar )
-{
- assert( iVar >= 0 && iVar < 6 );
- return (t & ~s_Truths5[iVar]) | ((t & ~s_Truths5[iVar]) << (1<<iVar));
-}
-static inline unsigned Abc_Tt5Cofactor1( unsigned t, int iVar )
-{
- assert( iVar >= 0 && iVar < 6 );
- return (t & s_Truths5[iVar]) | ((t & s_Truths5[iVar]) >> (1<<iVar));
-}
int Gia_Truth5ToGia( Gia_Man_t * p, int * pVarLits, int nVars, unsigned Truth, int fHash )
{
int Var, Lit0, Lit1;
@@ -645,9 +624,18 @@ word * Gia_ObjComputeTruthTableCut( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t
{
Gia_Obj_t * pTemp;
word * pTruth, * pTruthL, * pTruth0, * pTruth1;
- int i, iObj, Id0, Id1;
+ int i, iObj, Id0, Id1, Index = Vec_IntFind(vLeaves, Gia_ObjId(p, pRoot));
assert( p->vTtMemory != NULL );
assert( Vec_IntSize(vLeaves) <= p->nTtVars );
+ if ( Index >= 0 )
+ return Gla_ObjTruthElem( p, Index );
+ if ( Gia_ObjIsConst0(pRoot) )
+ {
+ if ( Vec_WrdSize(p->vTtMemory) < p->nTtWords )
+ Vec_WrdFillExtra( p->vTtMemory, p->nTtWords, 0 );
+ return Gla_ObjTruthConst0( p, Gla_ObjTruthFree1(p) );
+ }
+ assert( Gia_ObjIsAnd(pRoot) );
// extend ID numbers
if ( Vec_IntSize(p->vTtNums) < Gia_ManObjNum(p) )
Vec_IntFillExtra( p->vTtNums, Gia_ManObjNum(p), -ABC_INFINITY );
diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c
index d0ec969f..431be5b7 100644
--- a/src/aig/gia/giaUtil.c
+++ b/src/aig/gia/giaUtil.c
@@ -522,6 +522,28 @@ int Gia_ManLevelNum( Gia_Man_t * p )
}
return p->nLevels;
}
+int Gia_ManLevelRNum( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i;
+ Gia_ManCleanLevels( p, Gia_ManObjNum(p) );
+ p->nLevels = 0;
+ Gia_ManForEachObjReverse( p, pObj, i )
+ {
+ if ( !p->fGiaSimple && Gia_ObjIsBuf(pObj) )
+ Gia_ObjUpdateLevelId( p, Gia_ObjFaninId0(pObj, i), Gia_ObjLevel(p, pObj) );
+ else if ( Gia_ObjIsAnd(pObj) )
+ {
+ Gia_ObjUpdateLevelId( p, Gia_ObjFaninId0(pObj, i), 1+Gia_ObjLevel(p, pObj) );
+ Gia_ObjUpdateLevelId( p, Gia_ObjFaninId1(pObj, i), 1+Gia_ObjLevel(p, pObj) );
+ }
+ else if ( Gia_ObjIsCo(pObj) )
+ Gia_ObjUpdateLevelId( p, Gia_ObjFaninId0(pObj, i), 1 );
+ else
+ p->nLevels = Abc_MaxInt( p->nLevels, Gia_ObjLevel(p, pObj) );
+ }
+ return p->nLevels;
+}
float Gia_ManLevelAve( Gia_Man_t * p )
{
Gia_Obj_t * pObj;
@@ -1101,19 +1123,20 @@ int Gia_NodeDeref_rec( Gia_Man_t * p, Gia_Obj_t * pNode )
SeeAlso []
***********************************************************************/
-int Gia_NodeRef_rec( Gia_Man_t * p, Gia_Obj_t * pNode )
+int Gia_NodeRef_rec( Gia_Man_t * p, Gia_Obj_t * pNode, int fMark )
{
Gia_Obj_t * pFanin;
int Counter = 0;
if ( Gia_ObjIsCi(pNode) )
return 0;
assert( Gia_ObjIsAnd(pNode) );
+ if ( fMark ) Gia_ObjSetTravIdCurrent(p, pNode);
pFanin = Gia_ObjFanin0(pNode);
if ( Gia_ObjRefInc(p, pFanin) == 0 )
- Counter += Gia_NodeRef_rec( p, pFanin );
+ Counter += Gia_NodeRef_rec( p, pFanin, fMark );
pFanin = Gia_ObjFanin1(pNode);
if ( Gia_ObjRefInc(p, pFanin) == 0 )
- Counter += Gia_NodeRef_rec( p, pFanin );
+ Counter += Gia_NodeRef_rec( p, pFanin, fMark );
return Counter + 1;
}
@@ -1152,7 +1175,19 @@ int Gia_NodeMffcSize( Gia_Man_t * p, Gia_Obj_t * pNode )
assert( !Gia_IsComplement(pNode) );
assert( Gia_ObjIsCand(pNode) );
ConeSize1 = Gia_NodeDeref_rec( p, pNode );
- ConeSize2 = Gia_NodeRef_rec( p, pNode );
+ ConeSize2 = Gia_NodeRef_rec( p, pNode, 0 );
+ assert( ConeSize1 == ConeSize2 );
+ assert( ConeSize1 >= 0 );
+ return ConeSize1;
+}
+int Gia_NodeMffcSizeMark( Gia_Man_t * p, Gia_Obj_t * pNode )
+{
+ int ConeSize1, ConeSize2;
+ assert( !Gia_IsComplement(pNode) );
+ assert( Gia_ObjIsCand(pNode) );
+ ConeSize1 = Gia_NodeDeref_rec( p, pNode );
+ Gia_ManIncrementTravId( p );
+ ConeSize2 = Gia_NodeRef_rec( p, pNode, 1 );
assert( ConeSize1 == ConeSize2 );
assert( ConeSize1 >= 0 );
return ConeSize1;
@@ -1193,7 +1228,7 @@ int Gia_NodeMffcSizeSupp( Gia_Man_t * p, Gia_Obj_t * pNode, Vec_Int_t * vSupp )
ConeSize1 = Gia_NodeDeref_rec( p, pNode );
Gia_NodeCollect_rec( p, Gia_ObjFanin0(pNode), vSupp );
Gia_NodeCollect_rec( p, Gia_ObjFanin1(pNode), vSupp );
- ConeSize2 = Gia_NodeRef_rec( p, pNode );
+ ConeSize2 = Gia_NodeRef_rec( p, pNode, 0 );
assert( ConeSize1 == ConeSize2 );
assert( ConeSize1 >= 0 );
return ConeSize1;
@@ -1201,6 +1236,53 @@ int Gia_NodeMffcSizeSupp( Gia_Man_t * p, Gia_Obj_t * pNode, Vec_Int_t * vSupp )
/**Function*************************************************************
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_NodeMffcMapping_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vMapping, Vec_Int_t * vSupp )
+{
+ Gia_Obj_t * pObj; int i, iNode, Count = 1;
+ if ( !iObj || Vec_IntEntry(vMapping, iObj) )
+ return 0;
+ pObj = Gia_ManObj( p, iObj );
+ if ( Gia_ObjIsCi(pObj) )
+ return 0;
+ Gia_NodeMffcSizeSupp( p, pObj, vSupp );
+ Vec_IntSort( vSupp, 0 );
+ Vec_IntWriteEntry( vMapping, iObj, Vec_IntSize(vMapping) );
+ Vec_IntPush( vMapping, Vec_IntSize(vSupp) );
+ Vec_IntAppend( vMapping, vSupp );
+ Vec_IntPush( vMapping, iObj );
+ Vec_IntForEachEntry( vSupp, iNode, i )
+ Count += Gia_NodeMffcMapping_rec( p, iNode, vMapping, vSupp );
+ return Count;
+}
+int Gia_NodeMffcMapping( Gia_Man_t * p )
+{
+ int i, Id, Count = 0;
+ int * pRefsOld;
+ Vec_Int_t * vMapping, * vSupp = Vec_IntAlloc( 100 );
+ vMapping = Vec_IntAlloc( 2 * Gia_ManObjNum(p) );
+ Vec_IntFill( vMapping, Gia_ManObjNum(p), 0 );
+ pRefsOld = p->pRefs; p->pRefs = NULL;
+ Gia_ManCreateRefs( p );
+ Gia_ManForEachCoDriverId( p, Id, i )
+ Count += Gia_NodeMffcMapping_rec( p, Id, vMapping, vSupp );
+ p->pRefs = pRefsOld;
+ Vec_IntFree( vSupp );
+ p->vMapping = vMapping;
+ //printf( "Mapping is %.2fx larger than AIG manager.\n", 1.0*Vec_IntSize(vMapping)/Gia_ManObjNum(p) );
+ return Count;
+}
+
+/**Function*************************************************************
+
Synopsis [Returns 1 if AIG has dangling nodes.]
Description []
@@ -2027,11 +2109,13 @@ void Gia_AigerWriteLut( Gia_Man_t * p, char * pFileName )
Gia_ManForEachObj( p, pObj, i )
if ( i && Gia_ObjIsLut(p, i) )
{
+ word truth;
pLuts[iLut].Type = 3;
Gia_LutForEachFanin( p, i, iFan, k )
pLuts[iLut].pFans[k] = Gia_ManObj(p, iFan)->Value;
pLuts[iLut].nFans = k;
- *(word *)pLuts[iLut].pTruth = Gia_LutComputeTruth6(p, i, vTruths);
+ truth = Gia_LutComputeTruth6(p, i, vTruths);
+ memcpy( pLuts[iLut].pTruth, &truth, sizeof(word) );
pObj->Value = pLuts[iLut].Out = Abc_Var2Lit( iLut, 0 );
iLut++;
}
@@ -2290,6 +2374,713 @@ Gia_Man_t * Gia_ManDupWithMuxPos( Gia_Man_t * p )
return pNew;
}
+/**Function*************************************************************
+
+ Synopsis [Collect distance info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManRingAdd( Gia_Man_t * p, int iObj, Vec_Int_t * vRes, Vec_Int_t * vDists, int Dist )
+{
+ if ( Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ Vec_IntWriteEntry( vDists, iObj, Dist );
+ Vec_IntPush( vRes, iObj );
+}
+void Gia_ManCollectRing( Gia_Man_t * p, Vec_Int_t * vStart, Vec_Int_t * vRes, Vec_Int_t * vDists )
+{
+ int i, k, iObj, iFan;
+ Vec_IntForEachEntry( vStart, iObj, i )
+ {
+ int Weight = Vec_IntEntry( vDists, iObj );
+ Gia_Obj_t * pObj = Gia_ManObj(p, iObj);
+ assert( Weight > 0 );
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ Gia_ManRingAdd( p, Gia_ObjFaninId0(pObj, iObj), vRes, vDists, Weight + 1*!Gia_ObjIsBuf(Gia_ObjFanin0(pObj)) );
+ Gia_ManRingAdd( p, Gia_ObjFaninId1(pObj, iObj), vRes, vDists, Weight + 1*!Gia_ObjIsBuf(Gia_ObjFanin1(pObj)) );
+ }
+ Gia_ObjForEachFanoutStaticId( p, iObj, iFan, k )
+ Gia_ManRingAdd( p, iFan, vRes, vDists, Weight + 1*!Gia_ObjIsBuf(Gia_ManObj(p, iFan)) );
+ }
+}
+Vec_Int_t * Gia_ManComputeDistanceInt( Gia_Man_t * p, int iTarg, Vec_Int_t * vObjs, int fVerbose )
+{
+ int i, iObj;
+ Vec_Int_t * vDists, * vStart, * vNexts;
+ vStart = Vec_IntAlloc( 100 );
+ vNexts = Vec_IntAlloc( 100 );
+ vDists = Vec_IntStart( Gia_ManObjNum(p) );
+ Gia_ManIncrementTravId( p );
+ if ( vObjs )
+ {
+ Vec_IntForEachEntry( vObjs, iObj, i )
+ {
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ Vec_IntWriteEntry( vDists, iObj, 1 );
+ Vec_IntPush( vStart, iObj );
+ }
+ }
+ else
+ {
+ Gia_ObjSetTravIdCurrentId(p, iTarg);
+ Vec_IntWriteEntry( vDists, iTarg, 1 );
+ Vec_IntPush( vStart, iTarg );
+ }
+ for ( i = 0; ; i++ )
+ {
+ if ( fVerbose )
+ printf( "Ring %2d : %6d\n", i, Vec_IntSize(vDists)-Vec_IntCountZero(vDists) );
+ Gia_ManCollectRing( p, vStart, vNexts, vDists );
+ if ( Vec_IntSize(vNexts) == 0 )
+ break;
+ Vec_IntClear( vStart );
+ ABC_SWAP( Vec_Int_t, *vStart, *vNexts );
+ }
+ Vec_IntFree( vStart );
+ Vec_IntFree( vNexts );
+ return vDists;
+}
+Vec_Int_t * Gia_ManComputeDistance( Gia_Man_t * p, int iObj, Vec_Int_t * vObjs, int fVerbose )
+{
+ Vec_Int_t * vDists;
+ if ( p->vFanoutNums )
+ vDists = Gia_ManComputeDistanceInt( p, iObj, vObjs, fVerbose );
+ else
+ {
+ Gia_ManStaticFanoutStart( p );
+ vDists = Gia_ManComputeDistanceInt( p, iObj, vObjs, fVerbose );
+ Gia_ManStaticFanoutStop( p );
+ }
+ return vDists;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ComputeTest()
+{
+ char * pStart, Line [1000]; float Total = 0;
+ char * pFileName = "data.txt";
+ FILE * pFile = fopen( pFileName, "r" );
+ if ( pFile == NULL )
+ { printf( "Input file \"%s\" cannot be opened.\n", pFileName ); return; }
+ while ( fgets( Line, 1000, pFile ) != NULL )
+ {
+ if ( !strstr(Line, "xxx") )
+ continue;
+ if ( !strstr(Line, "yyy") )
+ continue;
+ //printf( "%s", Line );
+ pStart = strstr(Line, "zzz");
+ if ( pStart == NULL )
+ continue;
+ //printf( "%s", pStart + 4 );
+ Total += -atof( pStart + 4 );
+ }
+ printf( "Total = %.2f\n", Total );
+ fclose( pFile );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Computes sum total of support size of primary outputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManSumTotalOfSupportSizes( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ Vec_Wec_t * vSupps = Vec_WecStart( Gia_ManObjNum(p) );
+ int i, nResult = 0;
+ for ( i = 0; i < Gia_ManCiNum(p); i++ )
+ Vec_IntPush( Vec_WecEntry(vSupps, 1+i), i );
+ Gia_ManForEachAnd( p, pObj, i )
+ Vec_IntTwoMerge2( Vec_WecEntry(vSupps, Gia_ObjFaninId0(pObj, i)), Vec_WecEntry(vSupps, Gia_ObjFaninId1(pObj, i)), Vec_WecEntry(vSupps, i) );
+ Gia_ManForEachCo( p, pObj, i )
+ nResult += Vec_IntSize( Vec_WecEntry(vSupps, Gia_ObjFaninId0p(p, pObj)) );
+ Vec_WecFree( vSupps );
+ return nResult;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes sum total of support size of primary outputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManSumTotalOfSupportSizes2( Gia_Man_t * p )
+{
+ Vec_Wrd_t * vSims = Vec_WrdStart( Gia_ManObjNum(p) );
+ int r, nResult = 0, nRounds = (Gia_ManCiNum(p) + 63)/64;
+ for ( r = 0; r < nRounds; r++ )
+ {
+ Gia_Obj_t * pObj;
+ int i, Limit = r == nRounds-1 ? Gia_ManCiNum(p) % 64 : 64;
+ for ( i = 0; i < Limit; i++ )
+ Vec_WrdWriteEntry( vSims, 1+64*r+i, (word)1 << i );
+ Gia_ManForEachAnd( p, pObj, i )
+ Vec_WrdWriteEntry( vSims, i, Vec_WrdEntry(vSims, Gia_ObjFaninId0(pObj, i)) | Vec_WrdEntry(vSims, Gia_ObjFaninId1(pObj, i)) );
+ Gia_ManForEachCo( p, pObj, i )
+ nResult += Abc_TtCountOnes( Vec_WrdEntry(vSims, Gia_ObjFaninId0p(p, pObj)) );
+ for ( i = 0; i < Limit; i++ )
+ Vec_WrdWriteEntry( vSims, 1+64*r+i, 0 );
+ }
+ Vec_WrdFree( vSims );
+ return nResult;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compute dependency.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManComputeCofs( Gia_Man_t * p, int nVars )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj; int i, m;
+ Gia_Obj_t * pSink = Gia_ManCo(p, 0);
+ Vec_Int_t * vRoots = Vec_IntAlloc( 1 );
+ Vec_Int_t * vNodes = Vec_IntAlloc( 1000 );
+ Vec_IntPush( vRoots, Gia_ObjFaninId0p(p, pSink) );
+ Gia_ManCollectTfi( p, vRoots, vNodes );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ManHashAlloc( pNew );
+ for ( m = 0; m < (1 << nVars); m++ )
+ {
+ for ( i = 0; i < nVars; i++ )
+ Gia_ManCi(p, Gia_ManCiNum(p)-nVars+i)->Value = (m >> i) & 1;
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pSink) );
+ }
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ Vec_IntFree( vRoots );
+ Vec_IntFree( vNodes );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compute dependency.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManComputeCofs2( Gia_Man_t * p )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj, * pSink; int i, o, m;
+ Vec_Int_t * vSupp = Vec_IntAlloc( 1000 );
+ Vec_Int_t * vAnds = Vec_IntAlloc( 1000 );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ Gia_ManForEachCi( p, pObj, i )
+ {
+ pObj->Value = Gia_ManAppendCi(pNew);
+ assert( (int)pObj->Value == Abc_Var2Lit( 1 + Gia_ObjCioId(pObj), 0 ) );
+ }
+ Gia_ManHashAlloc( pNew );
+ Gia_ManForEachRi( p, pSink, o )
+ {
+ int Fanin = Gia_ObjFaninId0p( p, pSink );
+ Vec_Int_t * vNodes = Gia_ManCollectNodesCis( p, &Fanin, 1 );
+ Vec_IntClear( vSupp );
+ Vec_IntClear( vAnds );
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ Vec_IntPush( Gia_ObjIsAnd(pObj) ? vAnds : vSupp, Gia_ObjId(p, pObj) );
+ Vec_IntFree( vNodes );
+ Vec_IntSort( vSupp, 0 );
+ for ( m = 0; m < 5; m++ )
+ {
+ Gia_ManForEachObjVec( vSupp, p, pObj, i )
+ if ( i >= Vec_IntSize(vSupp)-5 )
+ pObj->Value = (i == Vec_IntSize(vSupp)-5+m) ? 1 : 0;
+ Gia_ManForEachObjVec( vAnds, p, pObj, i )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ //if ( m == 4 )
+ // Gia_ManAppendCo( pNew, 0 );
+ //else
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pSink) );
+ Gia_ManAppendCo( pNew, Abc_Var2Lit( Vec_IntEntry(vSupp, Vec_IntSize(vSupp)-5+m), 0 ) );
+ Gia_ManForEachObjVec( vSupp, p, pObj, i )
+ if ( i >= Vec_IntSize(vSupp)-5 )
+ pObj->Value = Abc_Var2Lit( 1 + Gia_ObjCioId(pObj), 0 );
+ }
+ }
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ Vec_IntFree( vSupp );
+ Vec_IntFree( vAnds );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compute dependency.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManComputeDepAig( Gia_Man_t * p, int iIn, int iOut )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj; int i, n, iLits[2];
+ Gia_Obj_t * pPivot = Gia_ManCi(p, iIn);
+ Gia_Obj_t * pSink = Gia_ManCo(p, iOut);
+ Vec_Int_t * vRoots = Vec_IntAlloc( 1 );
+ Vec_Int_t * vNodes = Vec_IntAlloc( 1000 );
+ Vec_IntPush( vRoots, Gia_ObjFaninId0p(p, pSink) );
+ Gia_ManCollectTfi( p, vRoots, vNodes );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ManHashAlloc( pNew );
+ for ( n = 0; n < 2; n++ )
+ {
+ pPivot->Value = n;
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ iLits[n] = Gia_ObjFanin0Copy(pSink);
+ }
+ Gia_ManAppendCo( pNew, Gia_ManHashAnd(pNew, iLits[1], Abc_LitNot(iLits[0])) );
+ Gia_ManAppendCo( pNew, Gia_ManHashAnd(pNew, iLits[0], Abc_LitNot(iLits[1])) );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ Vec_IntFree( vRoots );
+ Vec_IntFree( vNodes );
+ return pNew;
+}
+int Gia_ManComputeDep( Gia_Man_t * p, int iIn, int iOut )
+{
+ extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose );
+ Gia_Man_t * pNew = Gia_ManComputeDepAig( p, iIn, iOut );
+ Gia_Man_t * pSwp = Cec4_ManSimulateTest3( pNew, 100000, 0 );
+ int iLit[2] = { Gia_ObjFaninId0p( pSwp, Gia_ManCo(pSwp, 0) ), Gia_ObjFaninId0p( pSwp, Gia_ManCo(pSwp, 1) ) };
+ Gia_ManStop( pNew );
+ Gia_ManStop( pSwp );
+ if ( iLit[0] == 0 && iLit[1] == 0 )
+ return 2;
+ if ( iLit[1] == 0 )
+ return 1;
+ if ( iLit[0] == 0 )
+ return 0;
+ return -1;
+}
+Gia_Man_t * Gia_ManComputeDepTest( Gia_Man_t * p )
+{
+ abctime clk = Abc_Clock();
+ int i;
+ for ( i = 0; i < Gia_ManCiNum(p); i++ )
+ printf( "%3d : %3d\n", i, Gia_ManComputeDep(p, i, 0) );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ return Gia_ManDup(p);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compute support diffs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Wec_t * Gia_ManComputeSupports( Gia_Man_t * p )
+{
+ Vec_Wec_t * vRes = Vec_WecStart( Gia_ManCoNum(p) );
+ Vec_Wec_t * vSupps = Vec_WecStart( Gia_ManObjNum(p) );
+ Gia_Obj_t * pObj; int i;
+ for ( i = 0; i < Gia_ManCiNum(p); i++ )
+ Vec_IntPush( Vec_WecEntry(vSupps, 1+i), i );
+ Gia_ManForEachAnd( p, pObj, i )
+ Vec_IntTwoMerge2( Vec_WecEntry(vSupps, Gia_ObjFaninId0(pObj, i)), Vec_WecEntry(vSupps, Gia_ObjFaninId1(pObj, i)), Vec_WecEntry(vSupps, i) );
+ Gia_ManForEachCo( p, pObj, i )
+ Vec_IntAppend( Vec_WecEntry(vRes, i), Vec_WecEntry(vSupps, Gia_ObjFaninId0p(p, pObj)) );
+ Vec_WecFree( vSupps );
+ return vRes;
+}
+Vec_Wec_t * Gia_ManComputeSharing( Vec_Wec_t * vSupps )
+{
+ Vec_Wec_t * vDiffs = Vec_WecStart( Vec_WecSize(vSupps) );
+ Vec_Int_t * vNew, * vOld; int i;
+ Vec_WecForEachLevelTwo( vDiffs, vSupps, vNew, vOld, i ) if ( i )
+ Vec_IntTwoFindCommon( Vec_WecEntry(vSupps, i-1), vOld, vNew );
+ return vDiffs;
+}
+Vec_Str_t * Gia_ManConvertDump( Gia_Man_t * p, Vec_Wec_t * vSupps )
+{
+ int fPrintDep = 1;
+ int nSize = Gia_ManCoNum(p) * (Gia_ManCiNum(p) + 1) + 1;
+ Vec_Str_t * vRes = Vec_StrAlloc( nSize );
+ Vec_Int_t * vLevel; int i, k, Obj;
+ assert( Gia_ManCoNum(p) == Vec_WecSize(vSupps) );
+ Vec_StrFill( vRes, nSize-1, '_' );
+ Vec_StrPush( vRes, '\0' );
+ Vec_WecForEachLevel( vSupps, vLevel, i )
+ {
+ Vec_IntForEachEntry( vLevel, Obj, k )
+ {
+ if ( !fPrintDep )
+ Vec_StrWriteEntry( vRes, i * (Gia_ManCiNum(p) + 1) + Obj, '*' );
+ else
+ {
+ int Value = Gia_ManComputeDep( p, Obj, i );
+ if ( Value == -1 )
+ Vec_StrWriteEntry( vRes, i * (Gia_ManCiNum(p) + 1) + Obj, '*' );
+ else
+ Vec_StrWriteEntry( vRes, i * (Gia_ManCiNum(p) + 1) + Obj, (char)('0'+Value) );
+ }
+ }
+ Vec_StrWriteEntry( vRes, i * (Gia_ManCiNum(p) + 1) + Gia_ManCiNum(p), '\n' );
+ //printf( "Output %d\n", i );
+ }
+ return vRes;
+}
+void Gia_ManDumpSuppFile( Vec_Str_t * p, char * pFileName )
+{
+ FILE * pFile = fopen( pFileName, "wb" );
+ if ( pFile == NULL )
+ printf( "Cannot open file \"%s\" for writing.\n", pFileName );
+ else
+ {
+ int nOuts = Vec_StrCountEntry(p, '\n');
+ int nIns = Vec_StrSize(p)/Vec_StrCountEntry(p, '\n') - 1;
+ int nSize1 = Vec_StrSize(p) - 1;
+ int nSize2 = fwrite( Vec_StrArray(p), 1, nSize1, pFile );
+ assert( nSize1 == nSize2 );
+ printf( "Successfully dumped file \"%s\" with support data for %d outputs and %d inputs.\n", pFileName, nOuts, nIns );
+ }
+ fclose( pFile );
+}
+void Gia_ManDumpSuppFileTest3( Gia_Man_t * p, char * pFileName )
+{
+ Vec_Wec_t * vSupps = Gia_ManComputeSupports( p );
+ Vec_Wec_t * vDiffs = Gia_ManComputeSharing( vSupps );
+ Vec_Wec_t * vDiffs2 = Gia_ManComputeSharing( vDiffs );
+ Vec_Str_t * vRes = Gia_ManConvertDump( p, vDiffs2 );
+ Gia_ManDumpSuppFile( vRes, pFileName );
+ Vec_WecFree( vDiffs2 );
+ Vec_WecFree( vDiffs );
+ Vec_WecFree( vSupps );
+ Vec_StrFree( vRes );
+}
+void Gia_ManDumpSuppFileTest( Gia_Man_t * p, char * pFileName )
+{
+ Vec_Wec_t * vSupps = Gia_ManComputeSupports( p );
+ Vec_Str_t * vRes = Gia_ManConvertDump( p, vSupps );
+ Gia_ManDumpSuppFile( vRes, pFileName );
+ Vec_WecFree( vSupps );
+ Vec_StrFree( vRes );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Compute support diffs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManConvertSupp_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( !Gia_ObjIsAnd(pObj) )
+ return;
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ Gia_ManConvertSupp_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Gia_ManConvertSupp_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+Gia_Man_t * Gia_ManConvertSupp( Gia_Man_t * p )
+{
+ int fOnly1 = 0;
+ int fVerbose = 1;
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObjPi, * pObjRi, * pObjRo;
+ Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
+ Vec_Int_t * vAnds = Vec_IntAlloc( 100 );
+ int i, n, iLits[2];
+ assert( Gia_ManRegNum(p) && Gia_ManRegNum(p) % 8 == 0 );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManFillValue(p);
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachPi( p, pObjPi, i )
+ pObjPi->Value = Gia_ManAppendCi( pNew );
+ Gia_ManHashAlloc( pNew );
+ Gia_ManForEachRi( p, pObjRi, i )
+ {
+ pObjRo = Gia_ObjRiToRo(p, pObjRi);
+ if ( (i - Gia_ManPoNum(p)) % 8 != 0 )
+ continue;
+ if ( fOnly1 )
+ {
+ assert( pObjRo->Value == ~0 );
+ for ( n = 0; n < 2; n++ )
+ {
+ pObjRo->Value = n;
+ Gia_ManIncrementTravId( p );
+ Gia_ManConvertSupp_rec( pNew, p, Gia_ObjFanin0(pObjRi) );
+ iLits[n] = Gia_ObjFanin0Copy(pObjRi);
+ }
+ pObjRo->Value = ~0;
+ Gia_ManAppendCo( pNew, Abc_LitNot(Gia_ManHashAnd( pNew, iLits[1], Abc_LitNot(iLits[0]) )) );
+ }
+ else
+ {
+ int Fanin = Gia_ObjFaninId0p( p, pObjRi );
+ Vec_Int_t * vNodes = Gia_ManCollectNodesCis( p, &Fanin, 1 );
+ Gia_Obj_t * pObj; int i, m;
+ Vec_IntClear( vSupp );
+ Vec_IntClear( vAnds );
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ Vec_IntPush( Gia_ObjIsAnd(pObj) ? vAnds : vSupp, Gia_ObjId(p, pObj) );
+ Vec_IntFree( vNodes );
+ Vec_IntSort( vSupp, 0 );
+ for ( m = 0; m < 4; m++ )
+ {
+ Gia_ManForEachObjVec( vSupp, p, pObj, i )
+ if ( i >= Vec_IntSize(vSupp)-5 )
+ pObj->Value = (i == Vec_IntSize(vSupp)-5+m) ? 1 : 0;
+ Gia_ManForEachObjVec( vAnds, p, pObj, i )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ //if ( m == 4 )
+ // Gia_ManAppendCo( pNew, 0 );
+ //else
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObjRi) );
+ //Gia_ManAppendCo( pNew, Abc_Var2Lit( Vec_IntEntry(vSupp, Vec_IntSize(vSupp)-5+m), 0 ) );
+ Gia_ManForEachObjVec( vSupp, p, pObj, i )
+ if ( i >= Vec_IntSize(vSupp)-5 )
+ pObj->Value = Abc_Var2Lit( 1 + Gia_ObjCioId(pObj), 0 );
+ }
+ }
+ }
+ Vec_IntFree( vSupp );
+ Vec_IntFree( vAnds );
+ Gia_ManHashStop( pNew );
+ //Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ if ( fVerbose )
+ printf( "Transformed %d outputs, ", Gia_ManPoNum(pNew) );
+ if ( fVerbose )
+ Abc_PrintTime( 0, "Time", Abc_Clock() - clk );
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Transform flops.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManTransformCond2( Gia_Man_t * p )
+{
+ int fVerbose = 1;
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObjPi, * pObjRi, * pObjRo;
+ int i, n, iTempLit, iLits[2];
+ assert( Gia_ManRegNum(p) > 0 );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManFillValue(p);
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObjPi, i )
+ pObjPi->Value = Gia_ManAppendCi( pNew );
+ Gia_ManHashAlloc( pNew );
+ Gia_ManForEachRi( p, pObjRi, i )
+ {
+ //if ( (i - Gia_ManPoNum(p)) % 8 != 0 )
+ // continue;
+ pObjRo = Gia_ObjRiToRo(p, pObjRi);
+ iTempLit = pObjRo->Value;
+ for ( n = 0; n < 2; n++ )
+ {
+ pObjRo->Value = n;
+ Gia_ManIncrementTravId( p );
+ Gia_ManConvertSupp_rec( pNew, p, Gia_ObjFanin0(pObjRi) );
+ iLits[n] = Gia_ObjFanin0Copy(pObjRi);
+ }
+ pObjRo->Value = iTempLit;
+ Gia_ManAppendCo( pNew, Abc_LitNot(Gia_ManHashAnd( pNew, iLits[1], Abc_LitNot(iLits[0]) )) );
+ Gia_ManAppendCo( pNew, Abc_LitNot(Gia_ManHashAnd( pNew, iLits[0], Abc_LitNot(iLits[1]) )) );
+ }
+ Gia_ManHashStop( pNew );
+ //Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ if ( fVerbose )
+ printf( "Created %d outputs. ", Gia_ManPoNum(pNew) );
+ if ( fVerbose )
+ Abc_PrintTime( 0, "Time", Abc_Clock() - clk );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transform flops.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Wrd_t * Gia_ManDetectSims( Gia_Man_t * p, int iCo, int nWords )
+{
+ extern int Cec4_ManGeneratePatterns_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int Value, Vec_Int_t * vPat, Vec_Int_t * vVisit );
+ Vec_Wrd_t * vSim = Vec_WrdStart( nWords * Gia_ManCiNum(p) );
+ Vec_Int_t * vPat = Vec_IntAlloc( Gia_ManCiNum(p) );
+ Vec_Int_t * vVis = Vec_IntAlloc( Gia_ManAndNum(p) );
+ Gia_Obj_t * pObj = Gia_ManCo( p, iCo ), * pTemp; int iLit, i, k, nTries = 0;
+ if ( Gia_ObjFanin0(pObj) == Gia_ManConst0(p) )
+ return NULL;
+ Gia_ManForEachObj( p, pTemp, k )
+ assert( !pTemp->fMark0 && !pTemp->fMark1 );
+ for ( i = 0; i < 64*nWords; )
+ {
+ int Res = Cec4_ManGeneratePatterns_rec( p, Gia_ObjFanin0(pObj), !Gia_ObjFaninC0(pObj), vPat, vVis );
+ if ( Res )
+ {
+ Vec_IntForEachEntry( vPat, iLit, k )
+ {
+ if ( Abc_LitIsCompl(iLit) )
+ continue;
+ pTemp = Gia_ManObj( p, Abc_Lit2Var(iLit) );
+ assert( Gia_ObjIsCi(pTemp) );
+ Abc_InfoSetBit( (unsigned *)Vec_WrdEntryP(vSim, nWords*Gia_ObjCioId(pTemp)), i );
+ }
+ i++;
+ }
+ Gia_ManForEachObjVec( vVis, p, pTemp, k )
+ pTemp->fMark0 = pTemp->fMark1 = 0;
+ nTries++;
+ }
+ //printf( "%d ", nTries );
+ Vec_IntFree( vPat );
+ Vec_IntFree( vVis );
+ return vSim;
+}
+Vec_Wrd_t * Vec_WrdInterleave( Vec_Wrd_t * p1, Vec_Wrd_t * p2, int nWords, int nIns )
+{
+ Vec_Wrd_t * p = Vec_WrdAlloc( Vec_WrdSize(p1)+Vec_WrdSize(p2) );
+ int i, k;
+ assert( Vec_WrdSize(p1) == nWords*nIns );
+ assert( Vec_WrdSize(p2) == nWords*nIns );
+ for ( i = 0; i < nIns; i++ )
+ {
+ for ( k = 0; k < nWords; k++ )
+ Vec_WrdPush( p, Vec_WrdEntry(p1, i*nWords+k) );
+ for ( k = 0; k < nWords; k++ )
+ Vec_WrdPush( p, Vec_WrdEntry(p2, i*nWords+k) );
+ }
+ return p;
+}
+Gia_Man_t * Gia_ManTransformCond( Gia_Man_t * p )
+{
+ extern void Gia_ManResubPair( Vec_Wrd_t * vOn, Vec_Wrd_t * vOff, int nWords, int nIns );
+ abctime clk = Abc_Clock();
+ Vec_Wrd_t * vSims;
+ Vec_Wrd_t * vSim[4];
+ Vec_Wrd_t * vInt[6];
+ int i;
+ for ( i = 0; i < Gia_ManCoNum(p); i++ )
+ {
+ vSims = Gia_ManDetectSims( p, i, 1 );
+ if ( i >= Gia_ManCoNum(p)-4 )
+ vSim[i-(Gia_ManCoNum(p)-4)] = vSims;
+ else
+ Vec_WrdFreeP( &vSims );
+ //Vec_PtrPush( vAll, vSims );
+ }
+ vInt[0] = Vec_WrdInterleave( vSim[0], vSim[1], 1, Gia_ManCiNum(p) );
+ vInt[1] = Vec_WrdInterleave( vSim[0], vSim[2], 1, Gia_ManCiNum(p) );
+ vInt[2] = Vec_WrdInterleave( vSim[0], vSim[3], 1, Gia_ManCiNum(p) );
+ vInt[3] = Vec_WrdInterleave( vSim[1], vSim[2], 1, Gia_ManCiNum(p) );
+ vInt[4] = Vec_WrdInterleave( vSim[1], vSim[3], 1, Gia_ManCiNum(p) );
+ vInt[5] = Vec_WrdInterleave( vSim[2], vSim[3], 1, Gia_ManCiNum(p) );
+
+ Gia_ManResubPair( vInt[0], vInt[5], 2, Gia_ManCiNum(p) );
+ Gia_ManResubPair( vInt[1], vInt[4], 2, Gia_ManCiNum(p) );
+ Gia_ManResubPair( vInt[2], vInt[3], 2, Gia_ManCiNum(p) );
+
+ Gia_ManResubPair( vInt[5], vInt[0], 2, Gia_ManCiNum(p) );
+ Gia_ManResubPair( vInt[4], vInt[1], 2, Gia_ManCiNum(p) );
+ Gia_ManResubPair( vInt[3], vInt[2], 2, Gia_ManCiNum(p) );
+
+/*
+ for ( i = 0; i < 4; i++ )
+ for ( k = i+1; k < 4; k++ )
+ Gia_ManResubPair( vSim[i], vSim[k], 1, Gia_ManCiNum(p) );
+*/
+ Abc_PrintTime( 0, "Time", Abc_Clock() - clk );
+ return NULL;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make
index 26909410..d801a243 100644
--- a/src/aig/gia/module.make
+++ b/src/aig/gia/module.make
@@ -14,8 +14,10 @@ SRC += src/aig/gia/giaAig.c \
src/aig/gia/giaCSatOld.c \
src/aig/gia/giaCSat.c \
src/aig/gia/giaCSat2.c \
+ src/aig/gia/giaCSat3.c \
src/aig/gia/giaCTas.c \
src/aig/gia/giaCut.c \
+ src/aig/gia/giaDecs.c \
src/aig/gia/giaDeep.c \
src/aig/gia/giaDfs.c \
src/aig/gia/giaDup.c \
@@ -51,14 +53,21 @@ SRC += src/aig/gia/giaAig.c \
src/aig/gia/giaMem.c \
src/aig/gia/giaMfs.c \
src/aig/gia/giaMini.c \
+ src/aig/gia/giaMinLut.c \
+ src/aig/gia/giaMinLut2.c \
src/aig/gia/giaMuxes.c \
src/aig/gia/giaNf.c \
src/aig/gia/giaOf.c \
src/aig/gia/giaPack.c \
src/aig/gia/giaPat.c \
+ src/aig/gia/giaPat2.c \
src/aig/gia/giaPf.c \
src/aig/gia/giaQbf.c \
+ src/aig/gia/giaReshape1.c \
+ src/aig/gia/giaReshape2.c \
src/aig/gia/giaResub.c \
+ src/aig/gia/giaResub2.c \
+ src/aig/gia/giaResub3.c \
src/aig/gia/giaRetime.c \
src/aig/gia/giaRex.c \
src/aig/gia/giaSatEdge.c \
@@ -75,16 +84,16 @@ SRC += src/aig/gia/giaAig.c \
src/aig/gia/giaShrink7.c \
src/aig/gia/giaSim.c \
src/aig/gia/giaSim2.c \
- src/aig/gia/giaSim4.c \
- src/aig/gia/giaSim5.c \
src/aig/gia/giaSimBase.c \
src/aig/gia/giaSort.c \
src/aig/gia/giaSpeedup.c \
src/aig/gia/giaSplit.c \
src/aig/gia/giaStg.c \
+ src/aig/gia/giaStoch.c \
src/aig/gia/giaStr.c \
src/aig/gia/giaSupMin.c \
src/aig/gia/giaSupp.c \
+ src/aig/gia/giaSupps.c \
src/aig/gia/giaSweep.c \
src/aig/gia/giaSweeper.c \
src/aig/gia/giaSwitch.c \
diff --git a/src/aig/hop/hopBalance.c b/src/aig/hop/hopBalance.c
index e9aa4d4d..a3ce1c86 100644
--- a/src/aig/hop/hopBalance.c
+++ b/src/aig/hop/hopBalance.c
@@ -246,7 +246,7 @@ Hop_Obj_t * Hop_NodeBalanceBuildSuper( Hop_Man_t * p, Vec_Ptr_t * vSuper, Hop_Ty
int LeftBound;
assert( vSuper->nSize > 1 );
// sort the new nodes by level in the decreasing order
- Vec_PtrSort( vSuper, (int (*)(void))Hop_NodeCompareLevelsDecrease );
+ Vec_PtrSort( vSuper, (int (*)(const void *, const void *))Hop_NodeCompareLevelsDecrease );
// balance the nodes
while ( vSuper->nSize > 1 )
{
diff --git a/src/aig/ivy/ivyBalance.c b/src/aig/ivy/ivyBalance.c
index 6eba318c..2bcc69ee 100644
--- a/src/aig/ivy/ivyBalance.c
+++ b/src/aig/ivy/ivyBalance.c
@@ -178,7 +178,7 @@ Ivy_Obj_t * Ivy_NodeBalanceBuildSuper( Ivy_Man_t * p, Vec_Ptr_t * vSuper, Ivy_Ty
int LeftBound;
assert( vSuper->nSize > 1 );
// sort the new nodes by level in the decreasing order
- Vec_PtrSort( vSuper, (int (*)(void))Ivy_NodeCompareLevelsDecrease );
+ Vec_PtrSort( vSuper, (int (*)(const void *, const void *))Ivy_NodeCompareLevelsDecrease );
// balance the nodes
while ( vSuper->nSize > 1 )
{
diff --git a/src/aig/ivy/ivyCutTrav.c b/src/aig/ivy/ivyCutTrav.c
index 74212b10..b1cdb456 100644
--- a/src/aig/ivy/ivyCutTrav.c
+++ b/src/aig/ivy/ivyCutTrav.c
@@ -329,7 +329,7 @@ void Ivy_NodeComputeVolume2( Ivy_Obj_t * pObj, int nNodeLimit, Vec_Ptr_t * vNode
} while ( Vec_PtrSize(vNodes) < nNodeLimit );
// sort nodes by level
- Vec_PtrSort( vNodes, (int (*)(void))Ivy_CompareNodesByLevel );
+ Vec_PtrSort( vNodes, (int (*)(const void *, const void *))Ivy_CompareNodesByLevel );
// make sure the nodes are ordered in the increasing number of levels
pFanin = (Ivy_Obj_t *)Vec_PtrEntry( vNodes, 0 );
pPivot = (Ivy_Obj_t *)Vec_PtrEntryLast( vNodes );
diff --git a/src/aig/ivy/ivyRwrAlg.c b/src/aig/ivy/ivyRwrAlg.c
index ce605003..53fe5817 100644
--- a/src/aig/ivy/ivyRwrAlg.c
+++ b/src/aig/ivy/ivyRwrAlg.c
@@ -371,7 +371,7 @@ int Ivy_ManFindAlgCut( Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vLeave
if ( Vec_PtrSize(vFront) <= 2 )
return 1;
// sort the entries in increasing order
- Vec_PtrSort( vFront, (int (*)(void))Ivy_ManFindAlgCutCompare );
+ Vec_PtrSort( vFront, (int (*)(const void *, const void *))Ivy_ManFindAlgCutCompare );
// remove duplicates from vFront and save the nodes in vLeaves
pPrev = Vec_PtrEntry(vFront, 0);
Vec_PtrPush( vLeaves, pPrev );
diff --git a/src/aig/miniaig/abcOper.h b/src/aig/miniaig/abcOper.h
index 2fd7ab24..c3d6e176 100644
--- a/src/aig/miniaig/abcOper.h
+++ b/src/aig/miniaig/abcOper.h
@@ -29,7 +29,9 @@
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
+#ifndef _YOSYS_
ABC_NAMESPACE_HEADER_START
+#endif
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
@@ -232,6 +234,26 @@ static inline const char * Abc_OperName( int Type )
return NULL;
}
+// printing operator types
+static inline const char * Abc_OperNameSimple( int Type )
+{
+ if ( Type == ABC_OPER_NONE ) return NULL;
+ if ( Type == ABC_OPER_CONST_F ) return "buf";
+ if ( Type == ABC_OPER_CONST_T ) return "buf";
+ if ( Type == ABC_OPER_CONST_X ) return "buf";
+ if ( Type == ABC_OPER_CONST_Z ) return "buf";
+ if ( Type == ABC_OPER_BIT_BUF ) return "buf";
+ if ( Type == ABC_OPER_BIT_INV ) return "not";
+ if ( Type == ABC_OPER_BIT_AND ) return "and";
+ if ( Type == ABC_OPER_BIT_OR ) return "or";
+ if ( Type == ABC_OPER_BIT_XOR ) return "xor";
+ if ( Type == ABC_OPER_BIT_NAND ) return "nand";
+ if ( Type == ABC_OPER_BIT_NOR ) return "nor";
+ if ( Type == ABC_OPER_BIT_NXOR ) return "xnor";
+ assert( 0 );
+ return NULL;
+}
+
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -244,9 +266,9 @@ static inline const char * Abc_OperName( int Type )
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-
+#ifndef _YOSYS_
ABC_NAMESPACE_HEADER_END
-
+#endif
#endif
diff --git a/src/aig/miniaig/minilut.h b/src/aig/miniaig/minilut.h
index b080c983..2a27ccad 100644
--- a/src/aig/miniaig/minilut.h
+++ b/src/aig/miniaig/minilut.h
@@ -179,7 +179,37 @@ static void Mini_LutPrintStats( Mini_Lut_t * p )
nNodes = 0;
Mini_LutForEachNode( p, i )
nNodes++;
- printf( "PI = %d. PO = %d. LUT = %d.\n", nPis, nPos, nNodes );
+ printf( "PI = %d. PO = %d. LUT = %d. FF = %d.\n", nPis, nPos, nNodes, p->nRegs );
+}
+static void Mini_LutPrint( Mini_Lut_t * p )
+{
+ int i, k, Fan;
+ printf( "MiniLUT statistics: " );
+ Mini_LutPrintStats( p );
+ printf( "Printout of nodes:\n" );
+ for ( i = 0; i < p->nSize; i++ )
+ {
+ printf( "%6d : ", i );
+ if ( Mini_LutNodeIsConst(p, i) )
+ printf( "Const%d", i );
+ else if ( Mini_LutNodeIsPi(p, i) )
+ printf( "PI" );
+ else if ( Mini_LutNodeIsPo(p, i) )
+ printf( "PO" );
+ else if ( Mini_LutNodeIsNode(p, i) )
+ {
+ printf( "LUT%d Fanins:", p->LutSize );
+ Mini_LutForEachFanin( p, i, Fan, k )
+ printf( " %6d", Fan );
+ while ( k++ < p->LutSize )
+ printf( " " );
+ printf( " Function: " );
+ for ( k = 31; k >= 0; k-- )
+ printf( "%c", '0' + ((p->pTruths[i] >> k) & 1) );
+ }
+ printf( "\n" );
+ }
+ printf( "End of printout.\n" );
}
// serialization
diff --git a/src/aig/miniaig/ndr.h b/src/aig/miniaig/ndr.h
index 8d630159..68c2779c 100644
--- a/src/aig/miniaig/ndr.h
+++ b/src/aig/miniaig/ndr.h
@@ -33,7 +33,9 @@
#include "abcOper.h"
+#ifndef _YOSYS_
ABC_NAMESPACE_HEADER_START
+#endif
#ifdef _WIN32
#define inline __inline
@@ -215,8 +217,9 @@ static inline void Ndr_DataPushString( Ndr_Data_t * p, int ObjType, int Type, ch
return;
if ( ObjType == ABC_OPER_LUT )
{
- word Truth = (word)pFunc;
- Ndr_DataPushArray( p, Type, 2, (int *)&Truth );
+ //word Truth = (word)pFunc;
+ //Ndr_DataPushArray( p, Type, 2, (int *)&Truth );
+ Ndr_DataPushArray( p, Type, 2, (int *)&pFunc );
}
else
{
@@ -334,7 +337,7 @@ static inline int Ndr_DataObjNum( Ndr_Data_t * p, int Mod )
}
// to write signal names, this procedure takes a mapping of name IDs into actual char-strings (pNames)
-static inline void Ndr_WriteVerilogModule( FILE * pFile, void * pDesign, int Mod, char ** pNames )
+static inline void Ndr_WriteVerilogModule( FILE * pFile, void * pDesign, int Mod, char ** pNames, int fSimple )
{
Ndr_Data_t * p = (Ndr_Data_t *)pDesign;
int * pOuts = NDR_ALLOC( int, Ndr_DataCoNum(p, Mod) );
@@ -377,6 +380,8 @@ static inline void Ndr_WriteVerilogModule( FILE * pFile, void * pDesign, int Mod
break;
if ( k < i )
continue;
+ if ( Ndr_ObjReadOutName(p, Obj, pNames)[0] == '1' )
+ continue;
fprintf( pFile, " wire " );
Ndr_ObjWriteRange( p, Obj, pFile, 1 );
fprintf( pFile, " %s;\n", Ndr_ObjReadOutName(p, Obj, pNames) );
@@ -459,6 +464,24 @@ static inline void Ndr_WriteVerilogModule( FILE * pFile, void * pDesign, int Mod
fprintf( pFile, ");\n" );
continue;
}
+ if ( fSimple )
+ {
+ if ( Ndr_ObjReadOutName(p, Obj, pNames)[0] == '1' )
+ continue;
+ nArray = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray );
+ fprintf( pFile, " %s ( %s", Abc_OperNameSimple(Type), Ndr_ObjReadOutName(p, Obj, pNames) );
+ if ( nArray == 0 )
+ fprintf( pFile, ", %s );\n", (char *)Ndr_ObjReadBodyP(p, Obj, NDR_FUNCTION) );
+ else if ( nArray == 1 && Ndr_ObjReadBody(p, Obj, NDR_OPERTYPE) == ABC_OPER_BIT_BUF )
+ fprintf( pFile, ", %s );\n", pNames[pArray[0]] );
+ else
+ {
+ for ( i = 0; i < nArray; i++ )
+ fprintf( pFile, ", %s", pNames[pArray[i]] );
+ fprintf( pFile, " );\n" );
+ }
+ continue;
+ }
fprintf( pFile, " assign %s = ", Ndr_ObjReadOutName(p, Obj, pNames) );
nArray = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray );
if ( nArray == 0 )
@@ -492,15 +515,15 @@ static inline void Ndr_WriteVerilogModule( FILE * pFile, void * pDesign, int Mod
}
// to write signal names, this procedure takes a mapping of name IDs into actual char-strings (pNames)
-static inline void Ndr_WriteVerilog( char * pFileName, void * pDesign, char ** pNames )
+static inline void Ndr_WriteVerilog( char * pFileName, void * pDesign, char ** pNames, int fSimple )
{
Ndr_Data_t * p = (Ndr_Data_t *)pDesign; int Mod;
FILE * pFile = pFileName ? fopen( pFileName, "wb" ) : stdout;
- if ( pFile == NULL ) { printf( "Cannot open file \"%s\" for writing.\n", pFileName ); return; }
+ if ( pFile == NULL ) { printf( "Cannot open file \"%s\" for writing.\n", pFileName ? pFileName : "stdout" ); return; }
Ndr_DesForEachMod( p, Mod )
- Ndr_WriteVerilogModule( pFile, p, Mod, pNames );
+ Ndr_WriteVerilogModule( pFile, p, Mod, pNames, fSimple );
if ( pFileName ) fclose( pFile );
}
@@ -613,7 +636,7 @@ static inline void Ndr_Write( char * pFileName, void * pDesign )
{
Ndr_Data_t * p = (Ndr_Data_t *)pDesign; int RetValue;
FILE * pFile = fopen( pFileName, "wb" );
- if ( pFile == NULL ) { printf( "Cannot open file \"%s\" for writing.\n", pFileName ); return; }
+ if ( pFile == NULL ) { printf( "Cannot open file \"%s\" for writing.\n", pFileName ? pFileName : "stdout" ); return; }
RetValue = (int)fwrite( p->pBody, 4, p->pBody[0], pFile );
RetValue = (int)fwrite( p->pHead, 1, p->pBody[0], pFile );
fclose( pFile );
@@ -642,7 +665,7 @@ static inline void Ndr_ModuleTest()
// array of fanins of node s
int Fanins[2] = { NameIdA, NameIdC };
// map name IDs into char strings
- char * ppNames[5] = { NULL, "add10", "a", "s", "const10" };
+ //char * ppNames[5] = { NULL, "add10", "a", "s", "const10" };
// create a new module
void * pDesign = Ndr_Create( 1 );
@@ -651,13 +674,13 @@ static inline void Ndr_ModuleTest()
// add objects to the modele
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 3, 0, 0, 0, NULL, 1, &NameIdA, NULL ); // no fanins
- Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CONST, 0, 3, 0, 0, 0, NULL, 1, &NameIdC, "4'b1010" ); // no fanins
+ Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CONST, 0, 3, 0, 0, 0, NULL, 1, &NameIdC, (char*)"4'b1010" ); // no fanins
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_ARI_ADD, 0, 3, 0, 0, 2, Fanins, 1, &NameIdS, NULL ); // fanins are a and const10
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 3, 0, 0, 1, &NameIdS, 0, NULL, NULL ); // fanin is a
// write Verilog for verification
- Ndr_WriteVerilog( NULL, pDesign, ppNames );
- Ndr_Write( "add4.ndr", pDesign );
+ //Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 );
+ Ndr_Write( (char*)"add4.ndr", pDesign );
Ndr_Delete( pDesign );
}
@@ -686,6 +709,7 @@ static inline void Ndr_ModuleTest()
static inline void Ndr_ModuleTestAdder()
{
+/*
// map name IDs into char strings
char * ppNames[20] = { NULL,
"a", "b", "s", "co", // 1, 2, 3, 4
@@ -693,6 +717,7 @@ static inline void Ndr_ModuleTestAdder()
"r0", "s0", "rco", // 9, 10, 11
"r1", "s1", "add8" // 12, 13, 14
};
+*/
// fanins
int FaninA = 1;
int FaninB = 2;
@@ -744,8 +769,8 @@ static inline void Ndr_ModuleTestAdder()
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 0, 0, 0, 1, &FaninCO, 0, NULL, NULL );
// write Verilog for verification
- Ndr_WriteVerilog( NULL, pDesign, ppNames );
- Ndr_Write( "add8.ndr", pDesign );
+ //Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 );
+ Ndr_Write( (char*)"add8.ndr", pDesign );
Ndr_Delete( pDesign );
}
@@ -772,6 +797,7 @@ static inline void Ndr_ModuleTestAdder()
static inline void Ndr_ModuleTestHierarchy()
{
+/*
// map name IDs into char strings
char * ppNames[20] = { NULL,
"mux21w", "mux41w", // 1, 2
@@ -781,6 +807,7 @@ static inline void Ndr_ModuleTestHierarchy()
"t0", "t1", // 12, 13
"i0", "i1", "i2" // 14, 15, 16
};
+*/
// fanins
int FaninSel = 3;
int FaninSel0 = 10;
@@ -830,8 +857,8 @@ static inline void Ndr_ModuleTestHierarchy()
Ndr_AddObject( pDesign, Module41, ABC_OPER_CO, 0, 3, 0, 0, 1, &FaninOut, 0, NULL, NULL );
// write Verilog for verification
- Ndr_WriteVerilog( NULL, pDesign, ppNames );
- Ndr_Write( "mux41w.ndr", pDesign );
+ //Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 );
+ Ndr_Write( (char*)"mux41w.ndr", pDesign );
Ndr_Delete( pDesign );
}
@@ -859,6 +886,7 @@ static inline void Ndr_ModuleTestHierarchy()
static inline void Ndr_ModuleTestMemory()
{
+/*
// map name IDs into char strings
char * ppNames[20] = { NULL,
"clk", "raddr", "waddr", "data", "mem_init", "out", // 1, 2, 3, 4, 5, 6
@@ -868,6 +896,7 @@ static inline void Ndr_ModuleTestMemory()
"i_read1", "i_read2", // 15, 16
"i_write1", "i_write2", "memtest" // 17, 18, 19
};
+*/
// inputs
int NameIdClk = 1;
int NameIdRaddr = 2;
@@ -919,8 +948,8 @@ static inline void Ndr_ModuleTestMemory()
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_COMP_NOTEQU, 0, 0, 0, 0, 2, FaninsComp, 1, &NameIdComp, NULL );
// write Verilog for verification
- Ndr_WriteVerilog( NULL, pDesign, ppNames );
- Ndr_Write( "memtest.ndr", pDesign );
+ //Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 );
+ Ndr_Write( (char*)"memtest.ndr", pDesign );
Ndr_Delete( pDesign );
}
@@ -934,7 +963,7 @@ static inline void Ndr_ModuleTestMemory()
static inline void Ndr_ModuleTestFlop()
{
// map name IDs into char strings
- char * ppNames[12] = { NULL, "flop", "data", "clk", "reset", "set", "enable", "async", "sre", "init", "q" };
+ //char * ppNames[12] = { NULL, "flop", "data", "clk", "reset", "set", "enable", "async", "sre", "init", "q" };
// name IDs
int NameIdData = 2;
int NameIdClk = 3;
@@ -968,8 +997,8 @@ static inline void Ndr_ModuleTestFlop()
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 3, 0, 0, 1, &NameIdQ, 0, NULL, NULL );
// write Verilog for verification
- Ndr_WriteVerilog( NULL, pDesign, ppNames );
- Ndr_Write( "flop.ndr", pDesign );
+ //Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 );
+ Ndr_Write( (char*)"flop.ndr", pDesign );
Ndr_Delete( pDesign );
}
@@ -1022,8 +1051,8 @@ static inline void Ndr_ModuleTestSelSel()
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 2, 0, 0, 1, &NameIdOut,0, NULL, NULL );
// write Verilog for verification
- //Ndr_WriteVerilog( NULL, pDesign, ppNames );
- Ndr_Write( "sel.ndr", pDesign );
+ //Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 );
+ Ndr_Write( (char*)"sel.ndr", pDesign );
Ndr_Delete( pDesign );
}
@@ -1056,7 +1085,7 @@ static inline void Ndr_ModuleTestDec()
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_SEL_DEC, 0, 3, 0, 0, 1, &NameIdIn, 1, &NameIdOut, NULL );
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 3, 0, 0, 1, &NameIdOut, 0, NULL, NULL );
- Ndr_Write( "dec.ndr", pDesign );
+ Ndr_Write( (char*)"dec.ndr", pDesign );
Ndr_Delete( pDesign );
}
@@ -1092,7 +1121,7 @@ static inline void Ndr_ModuleTestAddSub()
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_ARI_ADDSUB, 0, 3, 0, 0, 4, Fanins, 1, &NameIdOut, NULL );
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 3, 0, 0, 1, &NameIdOut, 0, NULL, NULL );
- Ndr_Write( "addsub.ndr", pDesign );
+ Ndr_Write( (char*)"addsub.ndr", pDesign );
Ndr_Delete( pDesign );
}
@@ -1116,16 +1145,20 @@ static inline void Ndr_ModuleTestLut()
int ModuleID = Ndr_AddModule( pDesign, 1 );
+ unsigned pTruth[2] = { 0x88888888, 0x88888888 };
+
// add objects to the modele
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 1, 0, 0, 0, NULL, 1, &NameIdIn, NULL );
- Ndr_AddObject( pDesign, ModuleID, ABC_OPER_LUT, 0, 0, 0, 0, 1, &NameIdIn, 1, &NameIdOut, (char *)(ABC_CONST(0x8)) );
+ Ndr_AddObject( pDesign, ModuleID, ABC_OPER_LUT, 0, 0, 0, 0, 1, &NameIdIn, 1, &NameIdOut, (char *)pTruth );
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 0, 0, 0, 1, &NameIdOut, 0, NULL, NULL );
- Ndr_Write( "lut_test.ndr", pDesign );
+ Ndr_Write( (char*)"lut_test.ndr", pDesign );
Ndr_Delete( pDesign );
}
+#ifndef _YOSYS_
ABC_NAMESPACE_HEADER_END
+#endif
#endif
diff --git a/src/aig/saig/saigConstr.c b/src/aig/saig/saigConstr.c
index ac58839b..90e82816 100644
--- a/src/aig/saig/saigConstr.c
+++ b/src/aig/saig/saigConstr.c
@@ -300,8 +300,8 @@ Aig_Man_t * Saig_ManDupUnfoldConstrs( Aig_Man_t * pAig )
Vec_VecFree( (Vec_Vec_t *)vConsAll );
return Aig_ManDupDfs( pAig );
}
- Vec_PtrSort( vOuts, (int (*)(void))Saig_ManDupCompare );
- Vec_PtrSort( vCons, (int (*)(void))Saig_ManDupCompare );
+ Vec_PtrSort( vOuts, (int (*)(const void *, const void *))Saig_ManDupCompare );
+ Vec_PtrSort( vCons, (int (*)(const void *, const void *))Saig_ManDupCompare );
Vec_PtrPush( vOutsAll, vOuts );
Vec_PtrPush( vConsAll, vCons );
}
diff --git a/src/aig/saig/saigIso.c b/src/aig/saig/saigIso.c
index 40500361..7b8d488a 100644
--- a/src/aig/saig/saigIso.c
+++ b/src/aig/saig/saigIso.c
@@ -63,7 +63,7 @@ Vec_Int_t * Saig_ManFindIsoPermCos( Aig_Man_t * pAig, Vec_Int_t * vPermCis )
pObj->iData = Abc_Var2Lit( pFanin->iData, Aig_ObjFaninC0(pObj) );
Vec_PtrPush( vRoots, pObj );
}
- Vec_PtrSort( vRoots, (int (*)(void))Iso_ObjCompareByData );
+ Vec_PtrSort( vRoots, (int (*)(const void *, const void *))Iso_ObjCompareByData );
Vec_PtrForEachEntry( Aig_Obj_t *, vRoots, pObj, i )
Vec_IntPush( vPermCos, Aig_ObjCioId(pObj) );
Vec_PtrFree( vRoots );
@@ -467,7 +467,7 @@ Aig_Man_t * Iso_ManFilterPos( Aig_Man_t * pAig, Vec_Ptr_t ** pvPosEquivs, int fV
// sort the infos
clk = Abc_Clock();
- Vec_PtrSort( vBuffers, (int (*)(void))Iso_StoCompareVecStr );
+ Vec_PtrSort( vBuffers, (int (*)(const void *, const void *))Iso_StoCompareVecStr );
// create classes
clk = Abc_Clock();
diff --git a/src/aig/saig/saigIsoFast.c b/src/aig/saig/saigIsoFast.c
index 7393e7fc..10d1384d 100644
--- a/src/aig/saig/saigIsoFast.c
+++ b/src/aig/saig/saigIsoFast.c
@@ -303,7 +303,7 @@ Vec_Vec_t * Saig_IsoDetectFast( Aig_Man_t * pAig )
// sort the infos
clk = Abc_Clock();
- Vec_PtrSort( vInfos, (int (*)(void))Iso_StoCompareVecInt );
+ Vec_PtrSort( vInfos, (int (*)(const void *, const void *))Iso_StoCompareVecInt );
// create classes
clk = Abc_Clock();
diff --git a/src/aig/saig/saigIsoSlow.c b/src/aig/saig/saigIsoSlow.c
index a0e2d1d0..4784d98a 100644
--- a/src/aig/saig/saigIsoSlow.c
+++ b/src/aig/saig/saigIsoSlow.c
@@ -572,8 +572,8 @@ void Iso_ManCollectClasses( Iso_Man_t * p )
}
}
clk = Abc_Clock();
- Vec_PtrSort( p->vSingles, (int (*)(void))Iso_ObjCompare );
- Vec_PtrSort( p->vClasses, (int (*)(void))Iso_ObjCompare );
+ Vec_PtrSort( p->vSingles, (int (*)(const void *, const void *))Iso_ObjCompare );
+ Vec_PtrSort( p->vClasses, (int (*)(const void *, const void *))Iso_ObjCompare );
p->timeSort += Abc_Clock() - clk;
assert( Vec_PtrSize(p->vSingles) == p->nSingles );
assert( Vec_PtrSize(p->vClasses) == p->nClasses );
@@ -1115,8 +1115,8 @@ Vec_Int_t * Iso_ManFinalize( Iso_Man_t * p )
Vec_PtrPush( p->vTemp1, pObj );
}
// sort CIs by their IDs
- Vec_PtrSort( p->vTemp1, (int (*)(void))Iso_ObjCompareByData );
- Vec_PtrSort( p->vTemp2, (int (*)(void))Iso_ObjCompareByData );
+ Vec_PtrSort( p->vTemp1, (int (*)(const void *, const void *))Iso_ObjCompareByData );
+ Vec_PtrSort( p->vTemp2, (int (*)(const void *, const void *))Iso_ObjCompareByData );
// create the result
vRes = Vec_IntAlloc( Aig_ManCiNum(p->pAig) );
Vec_PtrForEachEntry( Aig_Obj_t *, p->vTemp1, pObj, i )
diff --git a/src/aig/saig/saigWnd.c b/src/aig/saig/saigWnd.c
index ce70e7b4..949a2728 100644
--- a/src/aig/saig/saigWnd.c
+++ b/src/aig/saig/saigWnd.c
@@ -106,7 +106,7 @@ Vec_Ptr_t * Saig_ManWindowOutline( Aig_Man_t * p, Aig_Obj_t * pObj, int nDist )
vNodes = Vec_PtrAlloc( 1000 );
Aig_ManIncrementTravId( p );
Saig_ManWindowOutline_rec( p, pObj, nDist, vNodes, pDists );
- Vec_PtrSort( vNodes, (int (*)(void))Aig_ObjCompareIdIncrease );
+ Vec_PtrSort( vNodes, (int (*)(const void *, const void *))Aig_ObjCompareIdIncrease );
// make sure LI/LO are labeled/unlabeled mutually
Saig_ManForEachLiLo( p, pObjLi, pObjLo, i )
assert( Aig_ObjIsTravIdCurrent(p, pObjLi) ==
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h
index 312354da..e7f6c0ad 100644
--- a/src/base/abc/abc.h
+++ b/src/base/abc/abc.h
@@ -600,7 +600,7 @@ extern ABC_DLL int Abc_NtkCheckUniqueCiNames( Abc_Ntk_t * pNtk );
extern ABC_DLL int Abc_NtkCheckUniqueCoNames( Abc_Ntk_t * pNtk );
extern ABC_DLL int Abc_NtkCheckUniqueCioNames( Abc_Ntk_t * pNtk );
/*=== abcCollapse.c ==========================================================*/
-extern ABC_DLL Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fReorder, int fReverse, int fVerbose );
+extern ABC_DLL Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fReorder, int fReverse, int fDumpOrder, int fVerbose );
extern ABC_DLL Abc_Ntk_t * Abc_NtkCollapseSat( Abc_Ntk_t * pNtk, int nCubeLim, int nBTLimit, int nCostMax, int fCanon, int fReverse, int fCnfShared, int fVerbose );
extern ABC_DLL Gia_Man_t * Abc_NtkClpGia( Abc_Ntk_t * pNtk );
/*=== abcCut.c ==========================================================*/
@@ -671,7 +671,7 @@ extern ABC_DLL Abc_Ntk_t * Abc_NtkFraigRestore( int nPatsRand, int nPatsD
extern ABC_DLL void Abc_NtkFraigStoreClean();
/*=== abcFunc.c ==========================================================*/
extern ABC_DLL int Abc_NtkSopToBdd( Abc_Ntk_t * pNtk );
-extern ABC_DLL int Abc_NtkBddToSop( Abc_Ntk_t * pNtk, int fMode, int nCubeLimit );
+extern ABC_DLL int Abc_NtkBddToSop( Abc_Ntk_t * pNtk, int fMode, int nCubeLimit, int fCubeSort );
extern ABC_DLL void Abc_NodeBddToCnf( Abc_Obj_t * pNode, Mem_Flex_t * pMmMan, Vec_Str_t * vCube, int fAllPrimes, char ** ppSop0, char ** ppSop1 );
extern ABC_DLL void Abc_NtkLogicMakeDirectSops( Abc_Ntk_t * pNtk );
extern ABC_DLL int Abc_NtkSopToAig( Abc_Ntk_t * pNtk );
@@ -752,6 +752,7 @@ extern ABC_DLL void Abc_NtkAddDummyPiNames( Abc_Ntk_t * pNtk );
extern ABC_DLL void Abc_NtkAddDummyPoNames( Abc_Ntk_t * pNtk );
extern ABC_DLL void Abc_NtkAddDummyBoxNames( Abc_Ntk_t * pNtk );
extern ABC_DLL void Abc_NtkShortNames( Abc_Ntk_t * pNtk );
+extern ABC_DLL void Abc_NtkCleanNames( Abc_Ntk_t * pNtk );
extern ABC_DLL void Abc_NtkStartNameIds( Abc_Ntk_t * p );
extern ABC_DLL void Abc_NtkTransferNameIds( Abc_Ntk_t * p, Abc_Ntk_t * pNew );
extern ABC_DLL void Abc_NtkUpdateNameIds( Abc_Ntk_t * p );
@@ -761,7 +762,7 @@ extern ABC_DLL Abc_Ntk_t * Abc_NtkToNetlist( Abc_Ntk_t * pNtk );
extern ABC_DLL Abc_Ntk_t * Abc_NtkToNetlistBench( Abc_Ntk_t * pNtk );
/*=== abcNtbdd.c ==========================================================*/
extern ABC_DLL Abc_Ntk_t * Abc_NtkDeriveFromBdd( void * dd, void * bFunc, char * pNamePo, Vec_Ptr_t * vNamesPi );
-extern ABC_DLL Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk, int fGlobal, int Limit );
+extern ABC_DLL Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk, int fGlobal, int Limit, int fUseAdd );
extern ABC_DLL void * Abc_NtkBuildGlobalBdds( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDropInternal, int fReorder, int fReverse, int fVerbose );
extern ABC_DLL void * Abc_NtkFreeGlobalBdds( Abc_Ntk_t * pNtk, int fFreeMan );
extern ABC_DLL int Abc_NtkSizeOfGlobalBdds( Abc_Ntk_t * pNtk );
diff --git a/src/base/abc/abcCheck.c b/src/base/abc/abcCheck.c
index 3e978bf0..a7448530 100644
--- a/src/base/abc/abcCheck.c
+++ b/src/base/abc/abcCheck.c
@@ -865,7 +865,7 @@ int Abc_NtkCheckUniqueCiNames( Abc_Ntk_t * pNtk )
vNames = Vec_PtrAlloc( Abc_NtkCiNum(pNtk) );
Abc_NtkForEachCi( pNtk, pObj, i )
Vec_PtrPush( vNames, Abc_ObjName(pObj) );
- Vec_PtrSort( vNames, (int (*)())Abc_NtkNamesCompare );
+ Vec_PtrSort( vNames, (int (*)(const void *, const void *))Abc_NtkNamesCompare );
for ( i = 1; i < Abc_NtkCiNum(pNtk); i++ )
if ( !strcmp( (const char *)Vec_PtrEntry(vNames,i-1), (const char *)Vec_PtrEntry(vNames,i) ) )
{
@@ -896,7 +896,7 @@ int Abc_NtkCheckUniqueCoNames( Abc_Ntk_t * pNtk )
vNames = Vec_PtrAlloc( Abc_NtkCoNum(pNtk) );
Abc_NtkForEachCo( pNtk, pObj, i )
Vec_PtrPush( vNames, Abc_ObjName(pObj) );
- Vec_PtrSort( vNames, (int (*)())Abc_NtkNamesCompare );
+ Vec_PtrSort( vNames, (int (*)(const void *, const void *))Abc_NtkNamesCompare );
for ( i = 1; i < Abc_NtkCoNum(pNtk); i++ )
{
// printf( "%s\n", Vec_PtrEntry(vNames,i) );
diff --git a/src/base/abc/abcDfs.c b/src/base/abc/abcDfs.c
index 731d35f5..a1345db8 100644
--- a/src/base/abc/abcDfs.c
+++ b/src/base/abc/abcDfs.c
@@ -897,9 +897,9 @@ Vec_Ptr_t * Abc_NtkNodeSupport( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNod
vNodes = Vec_PtrAlloc( 100 );
// go through the PO nodes and call for each of them
for ( i = 0; i < nNodes; i++ )
- if ( Abc_ObjIsCo(ppNodes[i]) )
+ if ( Abc_ObjIsCo(ppNodes[i]) && Abc_ObjFaninNum(Abc_ObjFanin0(ppNodes[i])) != 0 )
Abc_NtkNodeSupport_rec( Abc_ObjFanin0(ppNodes[i]), vNodes );
- else
+ else if ( !Abc_ObjIsCo(ppNodes[i]) && Abc_ObjFaninNum(ppNodes[i]) != 0 )
Abc_NtkNodeSupport_rec( ppNodes[i], vNodes );
return vNodes;
}
diff --git a/src/base/abc/abcFanOrder.c b/src/base/abc/abcFanOrder.c
index 12df7d85..949170aa 100644
--- a/src/base/abc/abcFanOrder.c
+++ b/src/base/abc/abcFanOrder.c
@@ -476,9 +476,9 @@ void Abc_NodeSortCubes( Abc_Obj_t * pNode, Vec_Ptr_t * vCubes, Vec_Str_t * vStor
Vec_PtrPush( vCubes, pCube );
}
if ( fWeight )
- Vec_PtrSort( vCubes, (int (*)())Abc_NodeCompareCubes2 );
+ Vec_PtrSort( vCubes, (int (*)(const void *, const void *))Abc_NodeCompareCubes2 );
else
- Vec_PtrSort( vCubes, (int (*)())Abc_NodeCompareCubes1 );
+ Vec_PtrSort( vCubes, (int (*)(const void *, const void *))Abc_NodeCompareCubes1 );
Vec_StrGrow( vStore, Vec_PtrSize(vCubes) * (nVars + 3) );
pPivot = Vec_StrArray( vStore );
Vec_PtrForEachEntry( char *, vCubes, pCube, i )
diff --git a/src/base/abc/abcFunc.c b/src/base/abc/abcFunc.c
index 8f68d4be..84ecf7bf 100644
--- a/src/base/abc/abcFunc.c
+++ b/src/base/abc/abcFunc.c
@@ -356,7 +356,7 @@ char * Abc_ConvertBddToSop( Mem_Flex_t * pMan, DdManager * dd, DdNode * bFuncOn,
SeeAlso []
***********************************************************************/
-int Abc_NtkBddToSop( Abc_Ntk_t * pNtk, int fMode, int nCubeLimit )
+int Abc_NtkBddToSop( Abc_Ntk_t * pNtk, int fMode, int nCubeLimit, int fCubeSort )
{
Vec_Int_t * vGuide;
Vec_Str_t * vCube;
@@ -445,6 +445,7 @@ int Abc_NtkBddToSop( Abc_Ntk_t * pNtk, int fMode, int nCubeLimit )
Extra_StopManager( dd );
// reorder fanins and cubes to make SOPs more human-readable
+ if ( fCubeSort )
Abc_NtkSortSops( pNtk );
return 1;
}
@@ -788,7 +789,7 @@ DdNode * Abc_ConvertAigToBdd( DdManager * dd, Hop_Obj_t * pRoot )
#else
int Abc_NtkSopToBdd( Abc_Ntk_t * pNtk ) { return 1; }
-int Abc_NtkBddToSop( Abc_Ntk_t * pNtk, int fMode, int nCubeLimit ) { return 1; }
+int Abc_NtkBddToSop( Abc_Ntk_t * pNtk, int fMode, int nCubeLimit, int fCubeSort ) { return 1; }
void Abc_NodeBddToCnf( Abc_Obj_t * pNode, Mem_Flex_t * pMmMan, Vec_Str_t * vCube, int fAllPrimes, char ** ppSop0, char ** ppSop1 ) {}
void Abc_NtkLogicMakeDirectSops( Abc_Ntk_t * pNtk ) {}
int Abc_NtkAigToBdd( Abc_Ntk_t * pNtk ) { return 1; }
@@ -1178,17 +1179,17 @@ int Abc_NtkToSop( Abc_Ntk_t * pNtk, int fMode, int nCubeLimit )
return 1;
if ( !Abc_NtkSopToBdd(pNtk) )
return 0;
- return Abc_NtkBddToSop(pNtk, fMode, nCubeLimit);
+ return Abc_NtkBddToSop(pNtk, fMode, nCubeLimit, 1);
}
if ( Abc_NtkHasMapping(pNtk) )
return Abc_NtkMapToSop(pNtk);
if ( Abc_NtkHasBdd(pNtk) )
- return Abc_NtkBddToSop(pNtk, fMode, nCubeLimit);
+ return Abc_NtkBddToSop(pNtk, fMode, nCubeLimit, 1);
if ( Abc_NtkHasAig(pNtk) )
{
if ( !Abc_NtkAigToBdd(pNtk) )
return 0;
- return Abc_NtkBddToSop(pNtk, fMode, nCubeLimit);
+ return Abc_NtkBddToSop(pNtk, fMode, nCubeLimit, 1);
}
assert( 0 );
return 0;
@@ -1253,7 +1254,7 @@ int Abc_NtkToAig( Abc_Ntk_t * pNtk )
}
if ( Abc_NtkHasBdd(pNtk) )
{
- if ( !Abc_NtkBddToSop(pNtk, -1, ABC_INFINITY) )
+ if ( !Abc_NtkBddToSop(pNtk, -1, ABC_INFINITY, 1) )
return 0;
return Abc_NtkSopToAig(pNtk);
}
diff --git a/src/base/abc/abcHie.c b/src/base/abc/abcHie.c
index 8397301f..bd08c35d 100644
--- a/src/base/abc/abcHie.c
+++ b/src/base/abc/abcHie.c
@@ -442,7 +442,7 @@ void Abc_NtkPrintBoxInfo( Abc_Ntk_t * pNtk )
}
// sort models by name
vMods = pNtk->pDesign->vModules;
- Vec_PtrSort( vMods, (int(*)())Abc_NtkCompareNames );
+ Vec_PtrSort( vMods, (int(*)(const void *, const void *))Abc_NtkCompareNames );
// Vec_PtrForEachEntry( Abc_Ntk_t *, vMods, pModel, i )
// printf( "%s\n", Abc_NtkName(pModel) );
diff --git a/src/base/abc/abcHieNew.c b/src/base/abc/abcHieNew.c
index 0f191707..54a61609 100644
--- a/src/base/abc/abcHieNew.c
+++ b/src/base/abc/abcHieNew.c
@@ -558,7 +558,7 @@ void Au_ManPrintBoxInfo( Au_Ntk_t * pNtk )
vMods->nSize--;
vMods->pArray++;
// sort models by name
- Vec_PtrSort( vMods, (int(*)())Au_NtkCompareNames );
+ Vec_PtrSort( vMods, (int(*)(const void *, const void *))Au_NtkCompareNames );
// swap the first model
Num = Vec_PtrFind( vMods, pNtk );
assert( Num >= 0 && Num < Vec_PtrSize(vMods) );
@@ -643,7 +643,7 @@ void Au_ManPrintBoxInfoSorted( Au_Ntk_t * pNtk )
vMods->pArray--;
vMods->nSize++;
- Vec_PtrSort( vModsNew, (int(*)())Au_NtkCompareSign );
+ Vec_PtrSort( vModsNew, (int(*)(const void *, const void *))Au_NtkCompareSign );
Vec_PtrForEachEntryStart( Au_Ntk_t *, vModsNew, pModel, i, 1 )
{
printf( "MODULE " );
diff --git a/src/base/abc/abcLatch.c b/src/base/abc/abcLatch.c
index fcace105..d8432382 100644
--- a/src/base/abc/abcLatch.c
+++ b/src/base/abc/abcLatch.c
@@ -148,7 +148,7 @@ int Abc_NtkRemoveSelfFeedLatches( Abc_Ntk_t * pNtk )
void Abc_NtkLatchPipe( Abc_Ntk_t * pNtk, int nLatches )
{
Vec_Ptr_t * vNodes;
- Abc_Obj_t * pObj, * pLatch, * pFanin, * pFanout;
+ Abc_Obj_t * pObj, * pFanin, * pFanout;
int i, k, nTotal, nDigits;
if ( nLatches < 1 )
return;
@@ -157,18 +157,9 @@ void Abc_NtkLatchPipe( Abc_Ntk_t * pNtk, int nLatches )
vNodes = Vec_PtrAlloc( 100 );
Abc_NtkForEachPi( pNtk, pObj, i )
{
- // remember current fanins of the PI
Abc_NodeCollectFanouts( pObj, vNodes );
- // create the latches
- for ( pFanin = pObj, k = 0; k < nLatches; k++, pFanin = pLatch )
- {
- pLatch = Abc_NtkCreateLatch( pNtk );
- Abc_ObjAddFanin( pLatch, pFanin );
- Abc_LatchSetInitDc( pLatch );
- // create the name of the new latch
- Abc_ObjAssignName( pLatch, Abc_ObjNameDummy("LL", i*nLatches + k, nDigits), NULL );
- }
- // patch the PI fanouts
+ for ( pFanin = pObj, k = 0; k < nLatches; k++ )
+ pFanin = Abc_NtkAddLatch( pNtk, pFanin, ABC_INIT_ZERO );
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pFanout, k )
Abc_ObjPatchFanin( pFanout, pObj, pFanin );
}
diff --git a/src/base/abc/abcMinBase.c b/src/base/abc/abcMinBase.c
index 22d1e285..3f441e99 100644
--- a/src/base/abc/abcMinBase.c
+++ b/src/base/abc/abcMinBase.c
@@ -72,7 +72,7 @@ int Abc_NtkMinimumBase( Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
-int Abc_NodeMinimumBase( Abc_Obj_t * pNode )
+int Abc_NodeMinimumBase_buggy( Abc_Obj_t * pNode )
{
Vec_Str_t * vSupport;
Vec_Ptr_t * vFanins;
@@ -107,6 +107,55 @@ int Abc_NodeMinimumBase( Abc_Obj_t * pNode )
return 1;
}
+int Abc_NodeMinimumBase( Abc_Obj_t * pNode )
+{
+ DdManager * dd = (DdManager *)pNode->pNtk->pManFunc;
+ DdNode * bTemp, ** pbVars;
+ Vec_Str_t * vSupport;
+ int i, nVars, j, iFanin, iFanin2, k = 0;
+
+ assert( Abc_NtkIsBddLogic(pNode->pNtk) );
+ assert( Abc_ObjIsNode(pNode) );
+
+ // compute support
+ vSupport = Vec_StrAlloc( 10 );
+ nVars = Abc_NodeSupport( Cudd_Regular(pNode->pData), vSupport, Abc_ObjFaninNum(pNode) );
+ if ( nVars == Abc_ObjFaninNum(pNode) )
+ {
+ Vec_StrFree( vSupport );
+ return 0;
+ }
+
+ // remove unused fanins
+ pbVars = ABC_CALLOC( DdNode *, Abc_ObjFaninNum(pNode) );
+ Vec_IntForEachEntry( &pNode->vFanins, iFanin, i )
+ {
+ Abc_Obj_t * pFanin = Abc_NtkObj( pNode->pNtk, iFanin );
+ if ( !Vec_StrEntry(vSupport, i) )
+ {
+ if ( !Vec_IntRemove( &pFanin->vFanouts, pNode->Id ) )
+ printf( "The obj %d is not found among the fanouts of obj %d ...\n", pNode->Id, iFanin );
+ continue;
+ }
+ Vec_IntForEachEntryStop( &pNode->vFanins, iFanin2, j, k )
+ if ( iFanin == iFanin2 )
+ break;
+ if ( j == k )
+ Vec_IntWriteEntry( &pNode->vFanins, k++, iFanin );
+ else if ( !Vec_IntRemove( &pFanin->vFanouts, pNode->Id ) )
+ printf( "The obj %d is not found among the fanouts of obj %d ...\n", pNode->Id, iFanin );
+ pbVars[i] = Cudd_bddIthVar( dd, j );
+ }
+ Vec_IntShrink( &pNode->vFanins, k );
+
+ // update the function of the node
+ pNode->pData = Cudd_bddVectorCompose( dd, bTemp = (DdNode *)pNode->pData, pbVars ); Cudd_Ref( (DdNode *)pNode->pData );
+ Cudd_RecursiveDeref( dd, bTemp );
+ Vec_StrFree( vSupport );
+ ABC_FREE( pbVars );
+ return 1;
+}
+
/**Function*************************************************************
Synopsis [Makes nodes of the network fanin-dup-free.]
@@ -447,7 +496,7 @@ int Abc_NtkEliminate( Abc_Ntk_t * pNtk, int nMaxSize, int fReverse, int fVerbose
return 0;
}
// prepare nodes for sweeping
- Abc_NtkRemoveDupFanins( pNtk );
+ //Abc_NtkRemoveDupFanins( pNtk );
Abc_NtkMinimumBase( pNtk );
Abc_NtkCleanup( pNtk, 0 );
// get the nodes in the given order
@@ -703,7 +752,7 @@ void Abc_ObjSortInReverseOrder( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes )
vOrder = Abc_NtkDfsReverse( pNtk );
Vec_PtrForEachEntry( Abc_Obj_t *, vOrder, pNode, i )
pNode->iTemp = i;
- Vec_PtrSort( vNodes, (int (*)())Abc_ObjCompareByNumber );
+ Vec_PtrSort( vNodes, (int (*)(const void *, const void *))Abc_ObjCompareByNumber );
Vec_PtrForEachEntry( Abc_Obj_t *, vOrder, pNode, i )
pNode->iTemp = 0;
Vec_PtrFree( vOrder );
@@ -740,7 +789,7 @@ int Abc_NtkEliminateSpecial( Abc_Ntk_t * pNtk, int nMaxSize, int fVerbose )
}
// prepare nodes for sweeping
- Abc_NtkRemoveDupFanins( pNtk );
+ //Abc_NtkRemoveDupFanins( pNtk );
Abc_NtkMinimumBase( pNtk );
Abc_NtkCleanup( pNtk, 0 );
diff --git a/src/base/abc/abcNames.c b/src/base/abc/abcNames.c
index fe9b3dca..dec5f01e 100644
--- a/src/base/abc/abcNames.c
+++ b/src/base/abc/abcNames.c
@@ -606,6 +606,17 @@ void Abc_NtkShortNames( Abc_Ntk_t * pNtk )
Abc_NtkAddDummyPoNames( pNtk );
Abc_NtkAddDummyBoxNames( pNtk );
}
+void Abc_NtkCleanNames( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj; int i;
+ Nm_Man_t * pManName = Nm_ManCreate( Abc_NtkCiNum(pNtk) + Abc_NtkCoNum(pNtk) + Abc_NtkBoxNum(pNtk) );
+ Abc_NtkForEachCi( pNtk, pObj, i )
+ Nm_ManStoreIdName( pManName, pObj->Id, pObj->Type, Abc_ObjName(pObj), NULL );
+ Abc_NtkForEachCo( pNtk, pObj, i )
+ Nm_ManStoreIdName( pManName, pObj->Id, pObj->Type, Abc_ObjName(pObj), NULL );
+ Nm_ManFree( pNtk->pManName );
+ pNtk->pManName = pManName;
+}
/**Function*************************************************************
diff --git a/src/base/abc/abcNtk.c b/src/base/abc/abcNtk.c
index 7c54f3c4..f8e40b41 100644
--- a/src/base/abc/abcNtk.c
+++ b/src/base/abc/abcNtk.c
@@ -1286,6 +1286,7 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )
Abc_Obj_t * pObj;
void * pAttrMan;
int TotalMemory, i;
+ int fWarning = 0;
// int LargePiece = (4 << ABC_NUM_STEPS);
if ( pNtk == NULL )
return;
@@ -1310,9 +1311,11 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )
// ABC_FREE( pObj->vFanouts.pArray );
// these flags should be always zero
// if this is not true, something is wrong somewhere
- assert( pObj->fMarkA == 0 );
- assert( pObj->fMarkB == 0 );
- assert( pObj->fMarkC == 0 );
+// assert( pObj->fMarkA == 0 );
+// assert( pObj->fMarkB == 0 );
+// assert( pObj->fMarkC == 0 );
+ if ( !fWarning && (pObj->fMarkA || pObj->fMarkB || pObj->fMarkC) )
+ { printf( "Flags A, B, or C are not zero.\n" ), fWarning = 1; }
}
// free the nodes
if ( pNtk->pMmStep == NULL )
diff --git a/src/base/abc/abcObj.c b/src/base/abc/abcObj.c
index 533f1f73..65ea91dc 100644
--- a/src/base/abc/abcObj.c
+++ b/src/base/abc/abcObj.c
@@ -393,6 +393,7 @@ Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int fCopyName
}
else if ( Abc_ObjIsLatch(pObj) ) // copy the reset value
pObjNew->pData = pObj->pData;
+ pObjNew->fPersist = pObj->fPersist;
// transfer HAIG
// pObjNew->pEquiv = pObj->pEquiv;
// remember the new node in the old node
diff --git a/src/base/abc/abcShow.c b/src/base/abc/abcShow.c
index 7df1e323..dd8e9efe 100644
--- a/src/base/abc/abcShow.c
+++ b/src/base/abc/abcShow.c
@@ -121,7 +121,7 @@ void Abc_NodeShowBdd( Abc_Obj_t * pNode, int fCompl )
// visualize the file
Abc_ShowFile( FileNameDot );
}
-void Abc_NtkShowBdd( Abc_Ntk_t * pNtk, int fCompl )
+void Abc_NtkShowBdd( Abc_Ntk_t * pNtk, int fCompl, int fReorder )
{
char FileNameDot[200];
char ** ppNamesIn, ** ppNamesOut;
@@ -131,7 +131,7 @@ void Abc_NtkShowBdd( Abc_Ntk_t * pNtk, int fCompl )
FILE * pFile;
assert( Abc_NtkIsStrash(pNtk) );
- dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, 0, 0 );
+ dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, fReorder, 0, 0 );
if ( dd == NULL )
{
printf( "Construction of global BDDs has failed.\n" );
@@ -186,7 +186,7 @@ void Abc_NtkShowBdd( Abc_Ntk_t * pNtk, int fCompl )
#else
void Abc_NodeShowBdd( Abc_Obj_t * pNode, int fCompl ) {}
-void Abc_NtkShowBdd( Abc_Ntk_t * pNtk, int fCompl ) {}
+void Abc_NtkShowBdd( Abc_Ntk_t * pNtk, int fCompl, int fReorder ) {}
#endif
/**Function*************************************************************
diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c
index 1f0c9725..29753210 100644
--- a/src/base/abc/abcUtil.c
+++ b/src/base/abc/abcUtil.c
@@ -3122,7 +3122,10 @@ Vec_Wec_t * Abc_SopSynthesize( Vec_Ptr_t * vSops )
Abc_Obj_t * pObj, * pFanin;
int i, k, iNode = 0;
Abc_FrameReplaceCurrentNetwork( Abc_FrameReadGlobalFrame(), pNtk );
- Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "fx; strash; balance; dc2; map -a" );
+ //Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "fx; strash; balance; dc2; map -a" );
+ Abc_FrameSetBatchMode( 1 );
+ Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "st; collapse; sop; fx; strash; &get; &ps; &deepsyn -I 4 -J 50 -T 5 -S 111 -t; &ps; &put; map -a" );
+ Abc_FrameSetBatchMode( 0 );
pNtkNew = Abc_FrameReadNtk( Abc_FrameReadGlobalFrame() );
vRes = Vec_WecStart( Abc_NtkPiNum(pNtkNew) + Abc_NtkNodeNum(pNtkNew) + Abc_NtkPoNum(pNtkNew) );
Abc_NtkForEachPi( pNtkNew, pObj, i )
@@ -3149,7 +3152,9 @@ Vec_Wec_t * Abc_GiaSynthesize( Vec_Ptr_t * vGias, Gia_Man_t * pMulti )
Abc_Obj_t * pObj, * pFanin;
int i, k, iNode = 0;
Abc_FrameReplaceCurrentNetwork( Abc_FrameReadGlobalFrame(), pNtk );
- Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "compress2rs; dch; map -a; strash; compress2rs; dch; map -a; strash; compress2rs; dch; map -a" );
+ Abc_FrameSetBatchMode( 1 );
+ Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "clp; sop; fx; strash; compress2rs; dch; map -a; strash; compress2rs; dch; map -a" );
+ Abc_FrameSetBatchMode( 0 );
pNtkNew = Abc_FrameReadNtk( Abc_FrameReadGlobalFrame() );
vRes = Vec_WecStart( Abc_NtkPiNum(pNtkNew) + Abc_NtkNodeNum(pNtkNew) + Abc_NtkPoNum(pNtkNew) );
Abc_NtkForEachPi( pNtkNew, pObj, i )
@@ -3253,9 +3258,11 @@ Gia_Man_t * Abc_SopSynthesizeOne( char * pSop, int fClp )
pNtk = Abc_NtkCreateFromSops( "top", vSops );
Vec_PtrFree( vSops );
Abc_FrameReplaceCurrentNetwork( Abc_FrameReadGlobalFrame(), pNtk );
+ Abc_FrameSetBatchMode( 1 );
if ( fClp )
Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "clp; sop" );
Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "fx; strash; balance; dc2" );
+ Abc_FrameSetBatchMode( 0 );
pNtkNew = Abc_FrameReadNtk( Abc_FrameReadGlobalFrame() );
return Abc_NtkStrashToGia( pNtkNew );
}
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c
index 85053e18..29732bc6 100644
--- a/src/base/abci/abc.c
+++ b/src/base/abci/abc.c
@@ -86,7 +86,9 @@ static int Abc_CommandPrintMffc ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandPrintFactor ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPrintLevel ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPrintSupport ( Abc_Frame_t * pAbc, int argc, char ** argv );
+#ifdef ABC_USE_CUDD
static int Abc_CommandPrintMint ( Abc_Frame_t * pAbc, int argc, char ** argv );
+#endif
static int Abc_CommandPrintSymms ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPrintUnate ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPrintAuto ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -138,7 +140,6 @@ static int Abc_CommandTestRPO ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandTestTruth ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandRunEco ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandRunGen ( Abc_Frame_t * pAbc, int argc, char ** argv );
-static int Abc_CommandRunSim ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandRunTest ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandRewrite ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -193,6 +194,7 @@ static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandNode ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandCof ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandTopmost ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandBottommost ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandTopAnd ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandTrim ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandShortNames ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -378,6 +380,7 @@ static int Abc_CommandAbcLoad ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandAbc9Get ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Put ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9MoveNames ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Save ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Save2 ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9SaveAig ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -399,6 +402,7 @@ static int Abc_CommandAbc9Status ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandAbc9MuxProfile ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9MuxPos ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9MuxStr ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9MuxDec ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9PrintTruth ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Unate ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Rex2Gia ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -412,9 +416,11 @@ static int Abc_CommandAbc9Cof ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandAbc9Trim ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Dfs ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Sim ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9Sim2 ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Sim3 ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9MLGen ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9MLTest ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9Iwls21Test ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9ReadSim ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9WriteSim ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9PrintSim ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -435,8 +441,11 @@ static int Abc_CommandAbc9Dsd ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandAbc9Bidec ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Shrink ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Fx ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9Extract ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Balance ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9BalanceLut ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9Resub ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9Reshape ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Syn2 ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Syn3 ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Syn4 ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -482,6 +491,11 @@ static int Abc_CommandAbc9Of ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandAbc9Pack ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Edge ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9SatLut ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9LNetRead ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9LNetSim ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9LNetEval ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9LNetOpt ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9LNetMap ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Unmap ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Struct ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Trace ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -503,6 +517,7 @@ static int Abc_CommandAbc9Mesh ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandAbc9Iso ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9IsoNpn ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9IsoSt ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9Compare ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9CexInfo ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Cycle ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Cone ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -540,6 +555,7 @@ static int Abc_CommandAbc9Exorcism ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandAbc9Mfs ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Mfsd ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9DeepSyn ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9StochSyn ( Abc_Frame_t * pAbc, int argc, char ** argv );
//static int Abc_CommandAbc9PoPart2 ( Abc_Frame_t * pAbc, int argc, char ** argv );
//static int Abc_CommandAbc9CexCut ( Abc_Frame_t * pAbc, int argc, char ** argv );
//static int Abc_CommandAbc9CexMerge ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -572,6 +588,9 @@ extern int Abc_CommandNChooseK ( Abc_Frame_t * pAbc, int argc, cha
extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters );
extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan );
+extern Vec_Ptr_t * Abc_NtkCollectCiNames( Abc_Ntk_t * pNtk );
+extern Vec_Ptr_t * Abc_NtkCollectCoNames( Abc_Ntk_t * pNtk );
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -754,6 +773,11 @@ void Abc_FrameUpdateGia( Abc_Frame_t * pAbc, Gia_Man_t * pNew )
pNew->vNamesOut = pAbc->pGia->vNamesOut;
pAbc->pGia->vNamesOut = NULL;
}
+ if (!pNew->vNamesNode && pAbc->pGia && pAbc->pGia->vNamesNode && Gia_ManObjNum(pNew) == Vec_PtrSize(pAbc->pGia->vNamesNode))
+ {
+ pNew->vNamesNode = pAbc->pGia->vNamesNode;
+ pAbc->pGia->vNamesNode = NULL;
+ }
// update
if ( pAbc->pGia2 )
Gia_ManStop( pAbc->pGia2 );
@@ -806,7 +830,9 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Printing", "print_factor", Abc_CommandPrintFactor, 0 );
Cmd_CommandAdd( pAbc, "Printing", "print_level", Abc_CommandPrintLevel, 0 );
Cmd_CommandAdd( pAbc, "Printing", "print_supp", Abc_CommandPrintSupport, 0 );
+#ifdef ABC_USE_CUDD
Cmd_CommandAdd( pAbc, "Printing", "print_mint", Abc_CommandPrintMint, 0 );
+#endif
Cmd_CommandAdd( pAbc, "Printing", "print_symm", Abc_CommandPrintSymms, 0 );
Cmd_CommandAdd( pAbc, "Printing", "print_unate", Abc_CommandPrintUnate, 0 );
Cmd_CommandAdd( pAbc, "Printing", "print_auto", Abc_CommandPrintAuto, 0 );
@@ -858,8 +884,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Synthesis", "testtruth", Abc_CommandTestTruth, 0 );
Cmd_CommandAdd( pAbc, "Synthesis", "runeco", Abc_CommandRunEco, 0 );
Cmd_CommandAdd( pAbc, "Synthesis", "rungen", Abc_CommandRunGen, 0 );
- Cmd_CommandAdd( pAbc, "Synthesis", "runsim", Abc_CommandRunSim, 0 );
- Cmd_CommandAdd( pAbc, "Synthesis", "runtest", Abc_CommandRunTest, 0 );
+ Cmd_CommandAdd( pAbc, "Synthesis", "xec", Abc_CommandRunTest, 0 );
Cmd_CommandAdd( pAbc, "Synthesis", "rewrite", Abc_CommandRewrite, 1 );
Cmd_CommandAdd( pAbc, "Synthesis", "refactor", Abc_CommandRefactor, 1 );
@@ -914,6 +939,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Various", "node", Abc_CommandNode, 1 );
Cmd_CommandAdd( pAbc, "Various", "cof", Abc_CommandCof, 1 );
Cmd_CommandAdd( pAbc, "Various", "topmost", Abc_CommandTopmost, 1 );
+ Cmd_CommandAdd( pAbc, "Various", "bottommost", Abc_CommandBottommost, 1 );
Cmd_CommandAdd( pAbc, "Various", "topand", Abc_CommandTopAnd, 1 );
Cmd_CommandAdd( pAbc, "Various", "trim", Abc_CommandTrim, 1 );
Cmd_CommandAdd( pAbc, "Various", "short_names", Abc_CommandShortNames, 0 );
@@ -1013,7 +1039,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Sequential", "zero", Abc_CommandZero, 1 );
Cmd_CommandAdd( pAbc, "Sequential", "undc", Abc_CommandUndc, 1 );
Cmd_CommandAdd( pAbc, "Sequential", "onehot", Abc_CommandOneHot, 1 );
-// Cmd_CommandAdd( pAbc, "Sequential", "pipe", Abc_CommandPipe, 1 );
+ Cmd_CommandAdd( pAbc, "Sequential", "pipe", Abc_CommandPipe, 1 );
Cmd_CommandAdd( pAbc, "Sequential", "retime", Abc_CommandRetime, 1 );
Cmd_CommandAdd( pAbc, "Sequential", "dretime", Abc_CommandDRetime, 1 );
Cmd_CommandAdd( pAbc, "Sequential", "fretime", Abc_CommandFlowRetime, 1 );
@@ -1095,6 +1121,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "ABC9", "&get", Abc_CommandAbc9Get, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&put", Abc_CommandAbc9Put, 0 );
+ Cmd_CommandAdd( pAbc, "ABC9", "&move_names", Abc_CommandAbc9MoveNames, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&save", Abc_CommandAbc9Save, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&save2", Abc_CommandAbc9Save2, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&saveaig", Abc_CommandAbc9SaveAig, 0 );
@@ -1118,6 +1145,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "ABC9", "&profile", Abc_CommandAbc9MuxProfile, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&muxpos", Abc_CommandAbc9MuxPos, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&muxstr", Abc_CommandAbc9MuxStr, 0 );
+ Cmd_CommandAdd( pAbc, "ABC9", "&muxdec", Abc_CommandAbc9MuxDec, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&print_truth", Abc_CommandAbc9PrintTruth, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&unate", Abc_CommandAbc9Unate, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&rex2gia", Abc_CommandAbc9Rex2Gia, 0 );
@@ -1131,9 +1159,11 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "ABC9", "&trim", Abc_CommandAbc9Trim, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&dfs", Abc_CommandAbc9Dfs, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&sim", Abc_CommandAbc9Sim, 0 );
+ Cmd_CommandAdd( pAbc, "ABC9", "&sim2", Abc_CommandAbc9Sim2, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&sim3", Abc_CommandAbc9Sim3, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&mlgen", Abc_CommandAbc9MLGen, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&mltest", Abc_CommandAbc9MLTest, 0 );
+ Cmd_CommandAdd( pAbc, "ABC9", "&iwls21test", Abc_CommandAbc9Iwls21Test, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&sim_read", Abc_CommandAbc9ReadSim, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&sim_write", Abc_CommandAbc9WriteSim, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&sim_print", Abc_CommandAbc9PrintSim, 0 );
@@ -1154,8 +1184,11 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "ABC9", "&bidec", Abc_CommandAbc9Bidec, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&shrink", Abc_CommandAbc9Shrink, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&fx", Abc_CommandAbc9Fx, 0 );
+ Cmd_CommandAdd( pAbc, "ABC9", "&extract", Abc_CommandAbc9Extract, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&b", Abc_CommandAbc9Balance, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&blut", Abc_CommandAbc9BalanceLut, 0 );
+ Cmd_CommandAdd( pAbc, "ABC9", "&resub", Abc_CommandAbc9Resub, 0 );
+ Cmd_CommandAdd( pAbc, "ABC9", "&reshape", Abc_CommandAbc9Reshape, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&syn2", Abc_CommandAbc9Syn2, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&syn3", Abc_CommandAbc9Syn3, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&syn4", Abc_CommandAbc9Syn4, 0 );
@@ -1201,6 +1234,11 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "ABC9", "&pack", Abc_CommandAbc9Pack, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&edge", Abc_CommandAbc9Edge, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&satlut", Abc_CommandAbc9SatLut, 0 );
+ Cmd_CommandAdd( pAbc, "ABC9", "&lnetread", Abc_CommandAbc9LNetRead, 0 );
+ Cmd_CommandAdd( pAbc, "ABC9", "&lnetsim", Abc_CommandAbc9LNetSim, 0 );
+ Cmd_CommandAdd( pAbc, "ABC9", "&lneteval", Abc_CommandAbc9LNetEval, 0 );
+ Cmd_CommandAdd( pAbc, "ABC9", "&lnetopt", Abc_CommandAbc9LNetOpt, 0 );
+ Cmd_CommandAdd( pAbc, "ABC9", "&lnetmap", Abc_CommandAbc9LNetMap, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&unmap", Abc_CommandAbc9Unmap, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&struct", Abc_CommandAbc9Struct, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&trace", Abc_CommandAbc9Trace, 0 );
@@ -1222,6 +1260,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "ABC9", "&iso", Abc_CommandAbc9Iso, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&isonpn", Abc_CommandAbc9IsoNpn, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&isost", Abc_CommandAbc9IsoSt, 0 );
+ Cmd_CommandAdd( pAbc, "ABC9", "&compare", Abc_CommandAbc9Compare, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&cexinfo", Abc_CommandAbc9CexInfo, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&cycle", Abc_CommandAbc9Cycle, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&cone", Abc_CommandAbc9Cone, 0 );
@@ -1259,6 +1298,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "ABC9", "&mfs", Abc_CommandAbc9Mfs, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&mfsd", Abc_CommandAbc9Mfsd, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&deepsyn", Abc_CommandAbc9DeepSyn, 0 );
+ Cmd_CommandAdd( pAbc, "ABC9", "&stochsyn", Abc_CommandAbc9StochSyn, 0 );
// Cmd_CommandAdd( pAbc, "ABC9", "&popart2", Abc_CommandAbc9PoPart2, 0 );
// Cmd_CommandAdd( pAbc, "ABC9", "&cexcut", Abc_CommandAbc9CexCut, 0 );
// Cmd_CommandAdd( pAbc, "ABC9", "&cexmerge", Abc_CommandAbc9CexMerge, 0 );
@@ -2075,6 +2115,7 @@ usage:
SeeAlso []
***********************************************************************/
+#ifdef ABC_USE_CUDD
int Abc_CommandPrintMint( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
@@ -2113,6 +2154,7 @@ int Abc_CommandPrintMint( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -1, "This command works only for logic networks with local functions represented by BDDs.\n" );
return 1;
}
+
Abc_NtkForEachNode( pNtk, pObj, c )
printf( "ObjId %3d : SuppSize = %5d MintCount = %32.0f\n", c, Abc_ObjFaninNum(pObj),
Cudd_CountMinterm((DdManager *)pNtk->pManFunc, (DdNode *)pObj->pData, Abc_ObjFaninNum(pObj)) );
@@ -2125,6 +2167,7 @@ usage:
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
}
+#endif
/**Function*************************************************************
@@ -3152,13 +3195,13 @@ int Abc_CommandShowBdd( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
Abc_Obj_t * pNode;
- int c, fCompl = 0, fGlobal = 0;
+ int c, fCompl = 0, fGlobal = 0, fReorder = 1;
extern void Abc_NodeShowBdd( Abc_Obj_t * pNode, int fCompl );
- extern void Abc_NtkShowBdd( Abc_Ntk_t * pNtk, int fCompl );
+ extern void Abc_NtkShowBdd( Abc_Ntk_t * pNtk, int fCompl, int fReorder );
// set defaults
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "cgh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "cgrh" ) ) != EOF )
{
switch ( c )
{
@@ -3168,6 +3211,9 @@ int Abc_CommandShowBdd( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'g':
fGlobal ^= 1;
break;
+ case 'r':
+ fReorder ^= 1;
+ break;
case 'h':
goto usage;
default:
@@ -3184,7 +3230,7 @@ int Abc_CommandShowBdd( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( fGlobal )
{
Abc_Ntk_t * pTemp = Abc_NtkIsStrash(pNtk) ? pNtk : Abc_NtkStrash(pNtk, 0, 0, 0);
- Abc_NtkShowBdd( pTemp, fCompl );
+ Abc_NtkShowBdd( pTemp, fCompl, fReorder );
if ( pTemp != pNtk )
Abc_NtkDelete( pTemp );
return 0;
@@ -3222,7 +3268,7 @@ int Abc_CommandShowBdd( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: show_bdd [-cgh] <node>\n" );
+ Abc_Print( -2, "usage: show_bdd [-cgrh] <node>\n" );
Abc_Print( -2, " uses DOT and GSVIEW to visualize the global BDDs of primary outputs\n" );
Abc_Print( -2, " in terms of primary inputs or the local BDD of a node in terms of its fanins\n" );
#ifdef WIN32
@@ -3232,6 +3278,7 @@ usage:
Abc_Print( -2, "\t<node>: (optional) the node to consider [default = the driver of the first PO]\n");
Abc_Print( -2, "\t-c : toggle visualizing BDD with complemented edges [default = %s].\n", fCompl? "yes": "no" );
Abc_Print( -2, "\t-g : toggle visualizing the global BDDs of primary outputs [default = %s].\n", fGlobal? "yes": "no" );
+ Abc_Print( -2, "\t-r : toggles dynamic variable reordering [default = %s]\n", fReorder? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
}
@@ -3353,6 +3400,7 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv )
int fDualRail;
int fReorder;
int fReverse;
+ int fDumpOrder;
int c;
char * pLogFileName = NULL;
pNtk = Abc_FrameReadNtk(pAbc);
@@ -3362,9 +3410,10 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv )
fReorder = 1;
fReverse = 0;
fDualRail = 0;
+ fDumpOrder = 0;
fBddSizeMax = ABC_INFINITY;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "BLrodvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "BLrodxvh" ) ) != EOF )
{
switch ( c )
{
@@ -3397,6 +3446,9 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'd':
fDualRail ^= 1;
break;
+ case 'x':
+ fDumpOrder ^= 1;
+ break;
case 'v':
fVerbose ^= 1;
break;
@@ -3421,11 +3473,11 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv )
// get the new network
if ( Abc_NtkIsStrash(pNtk) )
- pNtkRes = Abc_NtkCollapse( pNtk, fBddSizeMax, fDualRail, fReorder, fReverse, fVerbose );
+ pNtkRes = Abc_NtkCollapse( pNtk, fBddSizeMax, fDualRail, fReorder, fReverse, fDumpOrder, fVerbose );
else
{
pNtk = Abc_NtkStrash( pNtk, 0, 0, 0 );
- pNtkRes = Abc_NtkCollapse( pNtk, fBddSizeMax, fDualRail, fReorder, fReverse, fVerbose );
+ pNtkRes = Abc_NtkCollapse( pNtk, fBddSizeMax, fDualRail, fReorder, fReverse, fDumpOrder, fVerbose );
Abc_NtkDelete( pNtk );
}
if ( pNtkRes == NULL )
@@ -3448,13 +3500,14 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: collapse [-B <num>] [-L file] [-rodvh]\n" );
+ Abc_Print( -2, "usage: collapse [-B <num>] [-L file] [-rodxvh]\n" );
Abc_Print( -2, "\t collapses the network by constructing global BDDs\n" );
Abc_Print( -2, "\t-B <num>: limit on live BDD nodes during collapsing [default = %d]\n", fBddSizeMax );
Abc_Print( -2, "\t-L file : the log file name [default = %s]\n", pLogFileName ? pLogFileName : "no logging" );
Abc_Print( -2, "\t-r : toggles dynamic variable reordering [default = %s]\n", fReorder? "yes": "no" );
Abc_Print( -2, "\t-o : toggles reverse variable ordering [default = %s]\n", fReverse? "yes": "no" );
Abc_Print( -2, "\t-d : toggles dual-rail collapsing mode [default = %s]\n", fDualRail? "yes": "no" );
+ Abc_Print( -2, "\t-x : toggles dumping file \"order.txt\" with variable order [default = %s]\n", fDumpOrder? "yes": "no" );
Abc_Print( -2, "\t-v : print verbose information [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
@@ -5417,7 +5470,7 @@ int Abc_CommandMfs2( Abc_Frame_t * pAbc, int argc, char ** argv )
// set defaults
Sfm_ParSetDefault( pPars );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "WFDMLCZNIdaeijvwh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "WFDMLCZNIdaeijlvwh" ) ) != EOF )
{
switch ( c )
{
@@ -5535,6 +5588,9 @@ int Abc_CommandMfs2( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'j':
fUseAllFfs ^= 1;
break;
+ case 'l':
+ pPars->fUseDcs ^= 1;
+ break;
case 'v':
pPars->fVerbose ^= 1;
break;
@@ -5606,7 +5662,7 @@ int Abc_CommandMfs2( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: mfs2 [-WFDMLCZNI <num>] [-daeijvwh]\n" );
+ Abc_Print( -2, "usage: mfs2 [-WFDMLCZNI <num>] [-daeijlvwh]\n" );
Abc_Print( -2, "\t performs don't-care-based optimization of logic networks\n" );
Abc_Print( -2, "\t-W <num> : the number of levels in the TFO cone (0 <= num) [default = %d]\n", pPars->nTfoLevMax );
Abc_Print( -2, "\t-F <num> : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nFanoutMax );
@@ -5622,6 +5678,7 @@ usage:
Abc_Print( -2, "\t-i : toggle using inductive don't-cares [default = %s]\n", fIndDCs? "yes": "no" );
Abc_Print( -2, "\t-j : toggle using all flops when \"-i\" is enabled [default = %s]\n", fUseAllFfs? "yes": "no" );
Abc_Print( -2, "\t-I : the number of additional frames inserted [default = %d]\n", nFramesAdd );
+ Abc_Print( -2, "\t-l : toggle deriving don't-cares [default = %s]\n", pPars->fUseDcs? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" );
Abc_Print( -2, "\t-w : toggle printing detailed stats for each node [default = %s]\n", pPars->fVeryVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
@@ -7051,20 +7108,37 @@ usage:
***********************************************************************/
int Abc_CommandRunEco( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- extern void Acb_NtkRunEco( char * pFileNames[4], int fCheck, int fRandom, int fVerbose, int fVeryVerbose );
+ extern void Acb_NtkRunEco( char * pFileNames[4], int nTimeout, int fCheck, int fRandom, int fInputs, int fUnitW, int fVerbose, int fVeryVerbose );
char * pFileNames[4] = {NULL};
- int c, fCheck = 0, fRandom = 0, fVerbose = 0, fVeryVerbose = 0;
+ int c, nTimeout = 0, fCheck = 0, fRandom = 0, fInputs = 0, fUnitW = 0, fVerbose = 0, fVeryVerbose = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "crvwh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Tcriuvwh" ) ) != EOF )
{
switch ( c )
{
+ case 'T':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nTimeout = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nTimeout < 0 )
+ goto usage;
+ break;
case 'c':
fCheck ^= 1;
break;
case 'r':
fRandom ^= 1;
break;
+ case 'i':
+ fInputs ^= 1;
+ break;
+ case 'u':
+ fUnitW ^= 1;
+ break;
case 'v':
fVerbose ^= 1;
break;
@@ -7096,11 +7170,11 @@ int Abc_CommandRunEco( Abc_Frame_t * pAbc, int argc, char ** argv )
fclose( pFile );
pFileNames[c] = argv[globalUtilOptind+c];
}
- Acb_NtkRunEco( pFileNames, fCheck, fRandom, fVerbose, fVeryVerbose );
+ Acb_NtkRunEco( pFileNames, nTimeout, fCheck, fRandom, fInputs, fUnitW, fVerbose, fVeryVerbose );
return 0;
usage:
- Abc_Print( -2, "usage: runeco [-crvwh] <implementation> <specification> <weights>\n" );
+ Abc_Print( -2, "usage: runeco [-T num] [-criuvwh] <implementation> <specification> <weights>\n" );
Abc_Print( -2, "\t performs computation of patch functions during ECO,\n" );
Abc_Print( -2, "\t as described in the following paper: A. Q. Dao et al\n" );
Abc_Print( -2, "\t \"Efficient computation of ECO patch functions\", Proc. DAC\'18\n" );
@@ -7108,8 +7182,11 @@ usage:
Abc_Print( -2, "\t (currently only applicable to benchmarks from 2017 ICCAD CAD competition\n" );
Abc_Print( -2, "\t http://cad-contest-2017.el.cycu.edu.tw/Problem_A/default.html as follows:\n" );
Abc_Print( -2, "\t \"runeco unit1/F.v unit1/G.v unit1/weight.txt; cec -n out.v unit1/G.v\")\n" );
+ Abc_Print( -2, "\t-T num : the timeout in seconds [default = %d]\n", nTimeout );
Abc_Print( -2, "\t-c : toggle checking that the problem has a solution [default = %s]\n", fCheck? "yes": "no" );
Abc_Print( -2, "\t-r : toggle using random permutation of support variables [default = %s]\n", fRandom? "yes": "no" );
+ Abc_Print( -2, "\t-i : toggle using primary inputs as support variables [default = %s]\n", fInputs? "yes": "no" );
+ Abc_Print( -2, "\t-u : toggle using unit weights [default = %s]\n", fUnitW? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-w : toggle printing more verbose information [default = %s]\n", fVeryVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
@@ -7176,139 +7253,6 @@ usage:
SeeAlso []
***********************************************************************/
-int Abc_CommandRunSim( Abc_Frame_t * pAbc, int argc, char ** argv )
-{
- extern void Acb_NtkRunSim( char * pFileName[4], int nWords, int nBeam, int LevL, int LevU, int fOrder, int fFancy, int fUseBuf, int fRandom, int fUseWeights, int fVerbose, int fVeryVerbose );
- char * pFileNames[4] = {NULL, NULL, "out.v", NULL};
- int c, nWords = 8, nBeam = 4, LevL = -1, LevU = -1, fOrder = 0, fFancy = 0, fUseBuf = 0, fRandom = 0, fUseWeights = 0, fVerbose = 0, fVeryVerbose = 0;
- Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "WBLUofbruvwh" ) ) != EOF )
- {
- switch ( c )
- {
- case 'W':
- if ( globalUtilOptind >= argc )
- {
- Abc_Print( -1, "Command line switch \"-W\" should be followed by an integer.\n" );
- goto usage;
- }
- nWords = atoi(argv[globalUtilOptind]);
- globalUtilOptind++;
- if ( nWords < 0 )
- goto usage;
- break;
- case 'B':
- if ( globalUtilOptind >= argc )
- {
- Abc_Print( -1, "Command line switch \"-B\" should be followed by an integer.\n" );
- goto usage;
- }
- nBeam = atoi(argv[globalUtilOptind]);
- globalUtilOptind++;
- if ( nBeam < 0 )
- goto usage;
- break;
- case 'L':
- if ( globalUtilOptind >= argc )
- {
- Abc_Print( -1, "Command line switch \"-L\" should be followed by an integer.\n" );
- goto usage;
- }
- LevL = atoi(argv[globalUtilOptind]);
- globalUtilOptind++;
- if ( LevL < 0 )
- goto usage;
- break;
- case 'U':
- if ( globalUtilOptind >= argc )
- {
- Abc_Print( -1, "Command line switch \"-U\" should be followed by an integer.\n" );
- goto usage;
- }
- LevU = atoi(argv[globalUtilOptind]);
- globalUtilOptind++;
- if ( LevU < 0 )
- goto usage;
- break;
- case 'o':
- fOrder ^= 1;
- break;
- case 'f':
- fFancy ^= 1;
- break;
- case 'b':
- fUseBuf ^= 1;
- break;
- case 'r':
- fRandom ^= 1;
- break;
- case 'u':
- fUseWeights ^= 1;
- break;
- case 'v':
- fVerbose ^= 1;
- break;
- case 'w':
- fVeryVerbose ^= 1;
- break;
- case 'h':
- goto usage;
- default:
- goto usage;
- }
- }
- if ( argc - globalUtilOptind < 2 || argc - globalUtilOptind > 4 )
- {
- Abc_Print( 1, "Expecting two or three file names on the command line.\n" );
- goto usage;
- }
- Gia_ManRandom(1);
- for ( c = 0; c < argc - globalUtilOptind; c++ )
- pFileNames[c] = argv[globalUtilOptind+c];
- for ( c = 0; c < argc - globalUtilOptind - 1; c++ )
- {
- FILE * pFile = fopen( pFileNames[c], "rb" );
- if ( pFile == NULL )
- {
- printf( "Cannot open input file \"%s\".\n", pFileNames[c] );
- return 0;
- }
- else
- fclose( pFile );
- }
- Acb_NtkRunSim( pFileNames, nWords, nBeam, LevL, LevU, fOrder, fFancy, fUseBuf, fRandom, fUseWeights, fVerbose, fVeryVerbose );
- return 0;
-
-usage:
- Abc_Print( -2, "usage: runsim [-WBLU] [-ofbruvwh] [-N <num>] <file1> <file2> <file3>\n" );
- Abc_Print( -2, "\t experimental simulation command\n" );
- Abc_Print( -2, "\t-W <num> : the number of words of simulation info [default = %d]\n", nWords );
- Abc_Print( -2, "\t-B <num> : the beam width parameter [default = %d]\n", nBeam );
- Abc_Print( -2, "\t-L <num> : the lower bound on level [default = %d]\n", LevL );
- Abc_Print( -2, "\t-U <num> : the upper bound on level [default = %d]\n", LevU );
- Abc_Print( -2, "\t-o : toggle using a different node ordering [default = %s]\n", fOrder? "yes": "no" );
- Abc_Print( -2, "\t-f : toggle using experimental feature [default = %s]\n", fFancy? "yes": "no" );
- Abc_Print( -2, "\t-b : toggle using buffers [default = %s]\n", fUseBuf? "yes": "no" );
- Abc_Print( -2, "\t-r : toggle using random permutation of support variables [default = %s]\n", fRandom? "yes": "no" );
- Abc_Print( -2, "\t-u : toggle using topological info to select support variables [default = %s]\n", fUseWeights? "yes": "no" );
- Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
- Abc_Print( -2, "\t-w : toggle printing more verbose information [default = %s]\n", fVeryVerbose? "yes": "no" );
- Abc_Print( -2, "\t-h : print the command usage\n");
- return 1;
-}
-
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
int Abc_CommandRunTest( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern void Acb_NtkRunTest( char * pFileNames[4], int fFancy, int fVerbose );
@@ -7342,8 +7286,8 @@ int Abc_CommandRunTest( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: runtest [-fvh] <file1> <file2>\n" );
- Abc_Print( -2, "\t experimental simulation command\n" );
+ Abc_Print( -2, "usage: xec [-fvh] <file1> <file2>\n" );
+ Abc_Print( -2, "\t combinational equivalence checking with x-values\n" );
Abc_Print( -2, "\t-f : toggle using experimental feature [default = %s]\n", fFancy? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
@@ -10353,7 +10297,7 @@ int Abc_CommandPutOnTop( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern Abc_Ntk_t * Abc_NtkPutOnTop( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtk2 );
- Abc_Ntk_t * pNtk, * pNtk2, * pNtkRes;
+ Abc_Ntk_t * pNtk, * pNtk2, * pNtkRes = NULL;
char * FileName;
int fComb = 0;
int c;
@@ -10373,6 +10317,36 @@ int Abc_CommandPutOnTop( Abc_Frame_t * pAbc, int argc, char ** argv )
}
}
+ if ( argc > globalUtilOptind + 1 )
+ {
+ for ( c = 1; c < argc; c++ )
+ {
+ Abc_Ntk_t * pTemp, * pLogic = Io_Read( argv[c], Io_ReadFileType(argv[c]), 1, 0 );
+ if ( pLogic == NULL )
+ return 1;
+ if ( Abc_NtkIsStrash(pLogic) )
+ {
+ pLogic = Abc_NtkToLogic( pTemp = pLogic );
+ Abc_NtkDelete( pTemp );
+ }
+ if ( pLogic == NULL )
+ return 1;
+ if ( pNtkRes == NULL )
+ pNtkRes = pLogic;
+ else
+ {
+ pNtkRes = Abc_NtkPutOnTop( pTemp = pNtkRes, pLogic );
+ Abc_NtkDelete( pTemp );
+ Abc_NtkDelete( pLogic );
+ if ( pNtkRes == NULL )
+ return 1;
+ }
+ }
+ assert( Abc_NtkIsLogic(pNtkRes) );
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+ }
+
// get the second network
if ( argc != globalUtilOptind + 1 )
{
@@ -10415,7 +10389,15 @@ int Abc_CommandPutOnTop( Abc_Frame_t * pAbc, int argc, char ** argv )
}
// get the new network
- pNtkRes = Abc_NtkPutOnTop( pNtk, pNtk2 );
+ if ( Abc_NtkIsLogic(pNtk2) )
+ pNtkRes = Abc_NtkPutOnTop( pNtk, pNtk2 );
+ else if ( Abc_NtkIsStrash(pNtk2) )
+ {
+ Abc_Ntk_t * pLogic = Abc_NtkToLogic( pNtk2 );
+ pNtkRes = Abc_NtkPutOnTop( pNtk, pLogic );
+ Abc_NtkDelete( pLogic );
+ }
+ else assert( 0 );
Abc_NtkDelete( pNtk2 );
// replace the current network
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
@@ -10426,6 +10408,7 @@ usage:
Abc_Print( -2, "\t connects PIs of network in <file> to POs of current network\n" );
Abc_Print( -2, "\t-h : print the command usage\n");
Abc_Print( -2, "\t<file> : file name with the second network\n");
+ Abc_Print( -2, "\t : (given several files, all networks are stacked on top of each other)\n");
return 1;
}
@@ -10640,11 +10623,11 @@ usage:
int Abc_CommandSop( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
- int c, fMode = -1, nCubeLimit = 1000000;
+ int c, fCubeSort = 1, fMode = -1, nCubeLimit = 1000000;
// set defaults
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "Cdnh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Csdnh" ) ) != EOF )
{
switch ( c )
{
@@ -10659,6 +10642,9 @@ int Abc_CommandSop( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( nCubeLimit < 0 )
goto usage;
break;
+ case 's':
+ fCubeSort ^= 1;
+ break;
case 'd':
fMode = 1;
break;
@@ -10681,6 +10667,11 @@ int Abc_CommandSop( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -1, "Converting to SOP is possible only for logic networks.\n" );
return 1;
}
+ if ( !fCubeSort && Abc_NtkHasBdd(pNtk) && !Abc_NtkBddToSop(pNtk, -1, ABC_INFINITY, 0) )
+ {
+ Abc_Print( -1, "Converting to SOP has failed.\n" );
+ return 0;
+ }
if ( !Abc_NtkToSop(pNtk, fMode, nCubeLimit) )
{
Abc_Print( -1, "Converting to SOP has failed.\n" );
@@ -10689,9 +10680,10 @@ int Abc_CommandSop( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: sop [-C num] [-dnh]\n" );
+ Abc_Print( -2, "usage: sop [-C num] [-sdnh]\n" );
Abc_Print( -2, "\t converts node functions to SOP\n" );
Abc_Print( -2, "\t-C num : the limit on the number of cubes at a node [default = %d]\n", nCubeLimit );
+ Abc_Print( -2, "\t-s : toggles cube sort when converting from BDDs [default = %s]\n", fCubeSort ? "yes": "no" );
Abc_Print( -2, "\t-d : toggles using only positive polarity [default = %s]\n", fMode == 1 ? "yes": "no" );
Abc_Print( -2, "\t-n : toggles using only negative polarity [default = %s]\n", fMode == 0 ? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
@@ -11036,11 +11028,11 @@ usage:
int Abc_CommandMuxes( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Abc_Ntk_t * pNtk, * pNtkRes;
- int c, fGlobal = 0, Limit = 1000000;
+ int c, fGlobal = 0, fUseAdd = 0, Limit = 1000000;
pNtk = Abc_FrameReadNtk(pAbc);
// set defaults
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "Bgh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Bgah" ) ) != EOF )
{
switch ( c )
{
@@ -11058,6 +11050,9 @@ int Abc_CommandMuxes( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'g':
fGlobal ^= 1;
break;
+ case 'a':
+ fUseAdd ^= 1;
+ break;
case 'h':
goto usage;
default:
@@ -11089,7 +11084,7 @@ int Abc_CommandMuxes( Abc_Frame_t * pAbc, int argc, char ** argv )
}
// get the new network
- pNtkRes = Abc_NtkBddToMuxes( pNtk, fGlobal, Limit );
+ pNtkRes = Abc_NtkBddToMuxes( pNtk, fGlobal, Limit, fUseAdd );
if ( pNtkRes == NULL )
{
Abc_Print( 0, "Converting to MUXes has failed.\n" );
@@ -11100,11 +11095,12 @@ int Abc_CommandMuxes( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: muxes [-B num] [-gh]\n" );
+ Abc_Print( -2, "usage: muxes [-B num] [-gah]\n" );
Abc_Print( -2, "\t converts the current network into a network derived by\n" );
Abc_Print( -2, "\t replacing all nodes by DAGs isomorphic to the local BDDs\n" );
Abc_Print( -2, "\t-B <num>: limit on live BDD nodes during collapsing [default = %d]\n", Limit );
Abc_Print( -2, "\t-g : toggle visualizing the global BDDs of primary outputs [default = %s].\n", fGlobal? "yes": "no" );
+ Abc_Print( -2, "\t-a : toggle using ADDs instead of BDDs [default = %s].\n", fUseAdd? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
}
@@ -11895,12 +11891,7 @@ int Abc_CommandTopmost( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( Abc_NtkLatchNum(pNtk) > 0 )
{
- Abc_Print( -1, "Currently can only works for combinational circuits.\n" );
- return 0;
- }
- if ( Abc_NtkPoNum(pNtk) != 1 )
- {
- Abc_Print( -1, "Currently expects a single-output miter.\n" );
+ Abc_Print( -1, "Currently only works for combinational circuits.\n" );
return 0;
}
@@ -11934,6 +11925,86 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandBottommost( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ int c, nLevels;
+ extern Abc_Ntk_t * Abc_NtkBottommost( Abc_Ntk_t * pNtk, int nLevels );
+
+ pNtk = Abc_FrameReadNtk(pAbc);
+ // set defaults
+ nLevels = 10;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Nh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'N':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nLevels = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nLevels < 0 )
+ goto usage;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ Abc_Print( -1, "Empty network.\n" );
+ return 1;
+ }
+
+ if ( !Abc_NtkIsStrash(pNtk) )
+ {
+ Abc_Print( -1, "Currently only works for structurally hashed circuits.\n" );
+ return 0;
+ }
+
+ if ( Abc_NtkLatchNum(pNtk) > 0 )
+ {
+ Abc_Print( -1, "Currently only works for combinational circuits.\n" );
+ return 0;
+ }
+
+ pNtkRes = Abc_NtkBottommost( pNtk, nLevels );
+ if ( pNtkRes == NULL )
+ {
+ Abc_Print( -1, "The command has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: bottommost [-N num] [-h]\n" );
+ Abc_Print( -2, "\t replaces the current network by several of its bottommost levels\n" );
+ Abc_Print( -2, "\t-N num : max number of levels [default = %d]\n", nLevels );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ Abc_Print( -2, "\tname : the node name\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandTopAnd( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Abc_Ntk_t * pNtk, * pNtkRes;
@@ -12085,13 +12156,16 @@ usage:
int Abc_CommandShortNames( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
- int c;
+ int c, fKeepIo = 0;
// set defaults
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "kh" ) ) != EOF )
{
switch ( c )
{
+ case 'k':
+ fKeepIo ^= 1;
+ break;
case 'h':
goto usage;
default:
@@ -12104,12 +12178,16 @@ int Abc_CommandShortNames( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -1, "Empty network.\n" );
return 1;
}
- Abc_NtkShortNames( pNtk );
+ if ( fKeepIo )
+ Abc_NtkCleanNames( pNtk );
+ else
+ Abc_NtkShortNames( pNtk );
return 0;
usage:
- Abc_Print( -2, "usage: short_names [-h]\n" );
+ Abc_Print( -2, "usage: short_names [-kh]\n" );
Abc_Print( -2, "\t replaces PI/PO/latch names by short char strings\n" );
+ Abc_Print( -2, "\t-k : toggle keeping PI/PO names unchanged [default = %s]\n", fKeepIo? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
}
@@ -13893,7 +13971,6 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
//Dau_NetworkEnumTest();
//Extra_SimulationTest( nDivMax, nNumOnes, fNewOrder );
//Mnist_ExperimentWithScaling( nDecMax );
- Gia_Gen2CodeTest();
return 0;
usage:
Abc_Print( -2, "usage: test [-CKDNM] [-aovwh] <file_name>\n" );
@@ -14913,7 +14990,7 @@ int Abc_CommandDch( Abc_Frame_t * pAbc, int argc, char ** argv )
// set defaults
Dch_ManSetDefaultParams( pPars );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "WCSsptgcfrvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "WCSsptgcfrxvh" ) ) != EOF )
{
switch ( c )
{
@@ -14971,6 +15048,9 @@ int Abc_CommandDch( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'r':
pPars->fSkipRedSupp ^= 1;
break;
+ case 'x':
+ pPars->fUseNew ^= 1;
+ break;
case 'v':
pPars->fVerbose ^= 1;
break;
@@ -15001,7 +15081,7 @@ int Abc_CommandDch( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: dch [-WCS num] [-sptgcfrvh]\n" );
+ Abc_Print( -2, "usage: dch [-WCS num] [-sptgcfrxvh]\n" );
Abc_Print( -2, "\t computes structural choices using a new approach\n" );
Abc_Print( -2, "\t-W num : the max number of simulation words [default = %d]\n", pPars->nWords );
Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit );
@@ -15013,6 +15093,7 @@ usage:
Abc_Print( -2, "\t-c : toggle using circuit-based SAT vs. MiniSat [default = %s]\n", pPars->fUseCSat? "yes": "no" );
Abc_Print( -2, "\t-f : toggle using faster logic synthesis [default = %s]\n", pPars->fLightSynth? "yes": "no" );
Abc_Print( -2, "\t-r : toggle skipping choices with redundant support [default = %s]\n", pPars->fSkipRedSupp? "yes": "no" );
+ Abc_Print( -2, "\t-x : toggle using new choice computation [default = %s]\n", pPars->fUseNew? "yes": "no" );
Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", pPars->fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
@@ -15337,7 +15418,7 @@ int Abc_CommandIFraig( Abc_Frame_t * pAbc, int argc, char ** argv )
nPartSize = 0;
nLevelMax = 0;
nConfLimit = 100;
- fDoSparse = 0;
+ fDoSparse = 1;
fProve = 0;
fVerbose = 0;
Extra_UtilGetoptReset();
@@ -20302,9 +20383,15 @@ int Abc_CommandPipe( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
- if ( Abc_NtkIsComb(pNtk) )
+ if ( !Abc_NtkIsLogic(pNtk) )
{
- Abc_Print( 0, "The current network is combinational.\n" );
+ Abc_Print( 0, "Abc_CommandPipe(): Expecting a logic network (run command \"logic\").\n" );
+ return 0;
+ }
+
+ if ( !Abc_NtkIsComb(pNtk) )
+ {
+ Abc_Print( 0, "Abc_CommandPipe(): Expecting a combinational network.\n" );
return 0;
}
@@ -23540,12 +23627,24 @@ int Abc_CommandPermute( Abc_Frame_t * pAbc, int argc, char ** argv )
int fFlops = 1;
int fNodes = 1;
int fFanout = 0;
+ int Seed = -1;
int c;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "Fiofnxh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "SFiofnxh" ) ) != EOF )
{
switch ( c )
{
+ case 'S':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ Seed = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( Seed < 0 )
+ goto usage;
+ break;
case 'F':
if ( globalUtilOptind >= argc )
{
@@ -23577,6 +23676,8 @@ int Abc_CommandPermute( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
}
}
+ if ( Seed >= 0 )
+ srand( (unsigned)Seed );
if ( pNtk == NULL )
{
Abc_Print( -1, "Empty network.\n" );
@@ -23611,8 +23712,9 @@ int Abc_CommandPermute( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: permute [-iofnxh] [-F filename]\n" );
+ Abc_Print( -2, "usage: permute [-S num] [-iofnxh] [-F filename]\n" );
Abc_Print( -2, "\t performs random permutation of inputs/outputs/flops\n" );
+ Abc_Print( -2, "\t-S num : the random seed to generate permutations (0 <= num < INT_MAX) [default = %d]\n", Seed );
Abc_Print( -2, "\t-i : toggle permuting primary inputs [default = %s]\n", fInputs? "yes": "no" );
Abc_Print( -2, "\t-o : toggle permuting primary outputs [default = %s]\n", fOutputs? "yes": "no" );
Abc_Print( -2, "\t-f : toggle permuting flip-flops [default = %s]\n", fFlops? "yes": "no" );
@@ -29728,8 +29830,10 @@ static inline int Abc_NtkCompareWithBest( Abc_Ntk_t * pBest, Abc_Ntk_t * p,
Abc_NtkPoNum(pBest) != Abc_NtkPoNum(p) ||
Abc_NtkLatchNum(pBest) != Abc_NtkLatchNum(p) ||
strcmp(Abc_NtkName(pBest), Abc_NtkName(p)) ||
- (!fArea && (*pnBestNtkLevels > nNtkLevels || (*pnBestNtkLevels == nNtkLevels && *pnBestNtkDelay > nNtkDelay ))) ||
- ( fArea && (*pnBestNtkNodes > nNtkNodes || (*pnBestNtkNodes == nNtkNodes && *pnBestNtkArea > nNtkArea )))
+// (!fArea && (*pnBestNtkLevels > nNtkLevels || (*pnBestNtkLevels == nNtkLevels && *pnBestNtkDelay > nNtkDelay ))) ||
+// ( fArea && (*pnBestNtkNodes > nNtkNodes || (*pnBestNtkNodes == nNtkNodes && *pnBestNtkArea > nNtkArea )))
+ (!fArea && (*pnBestNtkDelay > nNtkDelay || (*pnBestNtkDelay == nNtkDelay && *pnBestNtkArea > nNtkArea ))) ||
+ ( fArea && (*pnBestNtkArea > nNtkArea || (*pnBestNtkArea == nNtkArea && *pnBestNtkDelay > nNtkDelay )))
)
{
*pnBestNtkArea = nNtkArea;
@@ -29854,18 +29958,22 @@ usage:
int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern void Abc3_ReadShowHie( char * pFileName, int fFlat );
+ extern Gia_Man_t * Gia_MiniAigSuperDerive( char * pFileName, int fVerbose );
+ extern Gia_Man_t * Gia_FileSimpleRead( char * pFileName, int fNames, char * pFileW );
Gia_Man_t * pAig = NULL;
FILE * pFile;
char ** pArgvNew;
char * FileName, * pTemp;
int c, nArgcNew;
int fMiniAig = 0;
+ int fMiniAig2 = 0;
int fMiniLut = 0;
int fVerbose = 0;
int fGiaSimple = 0;
int fSkipStrash = 0;
+ int fNewReader = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "csmlvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "csmnlpvh" ) ) != EOF )
{
switch ( c )
{
@@ -29878,9 +29986,15 @@ int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'm':
fMiniAig ^= 1;
break;
+ case 'n':
+ fMiniAig2 ^= 1;
+ break;
case 'l':
fMiniLut ^= 1;
break;
+ case 'p':
+ fNewReader ^= 1;
+ break;
case 'v':
fVerbose ^= 1;
break;
@@ -29912,8 +30026,12 @@ int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv )
}
fclose( pFile );
- if ( fMiniAig )
- pAig = Gia_ManReadMiniAig( FileName );
+ if ( fNewReader )
+ pAig = Gia_FileSimpleRead( FileName, fGiaSimple, NULL );
+ else if ( fMiniAig )
+ pAig = Gia_ManReadMiniAig( FileName, fGiaSimple || fSkipStrash );
+ else if ( fMiniAig2 )
+ pAig = Gia_MiniAigSuperDerive( FileName, fVerbose );
else if ( fMiniLut )
pAig = Gia_ManReadMiniLut( FileName );
// else if ( Extra_FileIsType( FileName, ".v", NULL, NULL ) )
@@ -29925,11 +30043,12 @@ int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: &r [-csmlvh] <file>\n" );
+ Abc_Print( -2, "usage: &r [-csmnlvh] <file>\n" );
Abc_Print( -2, "\t reads the current AIG from the AIGER file\n" );
Abc_Print( -2, "\t-c : toggles reading simple AIG [default = %s]\n", fGiaSimple? "yes": "no" );
Abc_Print( -2, "\t-s : toggles structural hashing while reading [default = %s]\n", !fSkipStrash? "yes": "no" );
Abc_Print( -2, "\t-m : toggles reading MiniAIG rather than AIGER file [default = %s]\n", fMiniAig? "yes": "no" );
+ Abc_Print( -2, "\t-n : toggles reading MiniAIG as a set of supergates [default = %s]\n", fMiniAig2? "yes": "no" );
Abc_Print( -2, "\t-l : toggles reading MiniLUT rather than AIGER file [default = %s]\n", fMiniLut? "yes": "no" );
Abc_Print( -2, "\t-v : toggles additional verbose output [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
@@ -30250,8 +30369,6 @@ usage:
int Abc_CommandAbc9Get( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern Aig_Man_t * Abc_NtkToDarChoices( Abc_Ntk_t * pNtk );
- extern Vec_Ptr_t * Abc_NtkCollectCiNames( Abc_Ntk_t * pNtk );
- extern Vec_Ptr_t * Abc_NtkCollectCoNames( Abc_Ntk_t * pNtk );
Abc_Ntk_t * pStrash;
Aig_Man_t * pAig;
Gia_Man_t * pGia, * pTemp;
@@ -30419,7 +30536,7 @@ int Abc_CommandAbc9Put( Abc_Frame_t * pAbc, int argc, char ** argv )
else
{
Abc_Ntk_t * pNtkNoCh;
-// Abc_Print( -1, "Transforming AIG with %d choice nodes.\n", Gia_ManEquivCountClasses(pAbc->pGia) );
+ Abc_Print( -1, "Transforming AIG with %d choice nodes.\n", Gia_ManEquivCountClasses(pAbc->pGia) );
// create network without choices
pMan = Gia_ManToAig( pAbc->pGia, 0 );
pNtkNoCh = Abc_NtkFromAigPhase( pMan );
@@ -30463,6 +30580,8 @@ int Abc_CommandAbc9Put( Abc_Frame_t * pAbc, int argc, char ** argv )
}
}
}
+ if ( pAbc->pGia->vNamesNode )
+ Abc_Print( 0, "Internal nodes names are not transferred.\n" );
// decouple CI/CO with the same name
if ( pAbc->pGia->vNamesIn || pAbc->pGia->vNamesOut )
@@ -30503,6 +30622,67 @@ usage:
/**Function*************************************************************
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandAbc9MoveNames( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ int c, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "nvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ default:
+ goto usage;
+ }
+ }
+ if ( pAbc->pNtkCur == NULL )
+ {
+ Abc_Print( -1, "There is no current network\n" );
+ return 1;
+ }
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "There is no current AIG.\n" );
+ return 1;
+ }
+ if ( Gia_ManCiNum(pAbc->pGia) != Abc_NtkCiNum(pAbc->pNtkCur) )
+ {
+ Abc_Print( -1, "The number of CIs does not match.\n" );
+ return 1;
+ }
+ if ( Gia_ManCoNum(pAbc->pGia) != Abc_NtkCoNum(pAbc->pNtkCur) )
+ {
+ Abc_Print( -1, "The number of COs does not match.\n" );
+ return 1;
+ }
+ if ( pAbc->pGia->vNamesIn ) Vec_PtrFreeFree( pAbc->pGia->vNamesIn );
+ if ( pAbc->pGia->vNamesOut ) Vec_PtrFreeFree( pAbc->pGia->vNamesOut );
+ pAbc->pGia->vNamesIn = Abc_NtkCollectCiNames( pAbc->pNtkCur );
+ pAbc->pGia->vNamesOut = Abc_NtkCollectCoNames( pAbc->pNtkCur );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &move_names [-vh]\n" );
+ Abc_Print( -2, "\t move CI/CO names\n" );
+ Abc_Print( -2, "\t-v : toggles additional verbose output [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ Abc_Print( -2, "\t<file> : the file name\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
Synopsis [Compares to versions of the design and finds the best.]
Description []
@@ -30919,12 +31099,13 @@ int Abc_CommandAbc9Write( Abc_Frame_t * pAbc, int argc, char ** argv )
int c, nArgcNew;
int fUnique = 0;
int fVerilog = 0;
+ int fVerBufs = 0;
int fMiniAig = 0;
int fMiniLut = 0;
int fWriteNewLine = 0;
int fVerbose = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "upmlnvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "upbmlnvh" ) ) != EOF )
{
switch ( c )
{
@@ -30934,6 +31115,9 @@ int Abc_CommandAbc9Write( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'p':
fVerilog ^= 1;
break;
+ case 'b':
+ fVerBufs ^= 1;
+ break;
case 'm':
fMiniAig ^= 1;
break;
@@ -30972,7 +31156,7 @@ int Abc_CommandAbc9Write( Abc_Frame_t * pAbc, int argc, char ** argv )
Gia_ManStop( pGia );
}
else if ( fVerilog )
- Gia_ManDumpVerilog( pAbc->pGia, pFileName, NULL );
+ Gia_ManDumpVerilog( pAbc->pGia, pFileName, NULL, fVerBufs );
else if ( fMiniAig )
Gia_ManWriteMiniAig( pAbc->pGia, pFileName );
else if ( fMiniLut )
@@ -30982,10 +31166,11 @@ int Abc_CommandAbc9Write( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: &w [-upmlnvh] <file>\n" );
+ Abc_Print( -2, "usage: &w [-upbmlnvh] <file>\n" );
Abc_Print( -2, "\t writes the current AIG into the AIGER file\n" );
Abc_Print( -2, "\t-u : toggle writing canonical AIG structure [default = %s]\n", fUnique? "yes" : "no" );
Abc_Print( -2, "\t-p : toggle writing Verilog with 'and' and 'not' [default = %s]\n", fVerilog? "yes" : "no" );
+ Abc_Print( -2, "\t-b : toggle writing additional buffers in Verilog [default = %s]\n", fVerBufs? "yes" : "no" );
Abc_Print( -2, "\t-m : toggle writing MiniAIG rather than AIGER [default = %s]\n", fMiniAig? "yes" : "no" );
Abc_Print( -2, "\t-l : toggle writing MiniLUT rather than AIGER [default = %s]\n", fMiniLut? "yes" : "no" );
Abc_Print( -2, "\t-n : toggle writing \'\\n\' after \'c\' in the AIGER file [default = %s]\n", fWriteNewLine? "yes": "no" );
@@ -31500,6 +31685,58 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandAbc9MuxDec( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern Gia_Man_t * Gia_ManPerformMuxDec( Gia_Man_t * p );
+ Gia_Man_t * pGia;
+ int c, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9MuxDec(): There is no AIG.\n" );
+ return 1;
+ }
+ if ( Gia_ManCiNum(pAbc->pGia) <= 6 || Gia_ManCiNum(pAbc->pGia) > 26 )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9MuxDec(): The number of inputs is wrong.\n" );
+ return 1;
+ }
+ pGia = Gia_ManPerformMuxDec( pAbc->pGia );
+ Abc_FrameUpdateGia( pAbc, pGia );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &muxdec [-vh]\n" );
+ Abc_Print( -2, "\t performs restructuring\n" );
+ Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandAbc9PrintTruth( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern word Gia_LutComputeTruth6Simple( Gia_Man_t * p, int iPo );
@@ -31902,13 +32139,14 @@ int Abc_CommandAbc9Strash( Abc_Frame_t * pAbc, int argc, char ** argv )
extern Gia_Man_t * Gia_ManDupMuxRestructure( Gia_Man_t * p );
Gia_Man_t * pTemp;
int c, Limit = 2;
+ int Multi = 0;
int fAddStrash = 0;
int fCollapse = 0;
int fAddMuxes = 0;
int fStrMuxes = 0;
int fRehashMap = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "Lacmrsh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "LMacmrsh" ) ) != EOF )
{
switch ( c )
{
@@ -31923,6 +32161,17 @@ int Abc_CommandAbc9Strash( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( Limit < 0 )
goto usage;
break;
+ case 'M':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ Multi = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( Multi <= 0 )
+ goto usage;
+ break;
case 'a':
fAddStrash ^= 1;
break;
@@ -31949,6 +32198,13 @@ int Abc_CommandAbc9Strash( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -1, "Abc_CommandAbc9Strash(): There is no AIG.\n" );
return 1;
}
+ if ( Multi > 0 )
+ {
+ extern Gia_Man_t * Gia_ManDupAddPis( Gia_Man_t * p, int nMulti );
+ pTemp = Gia_ManDupAddPis( pAbc->pGia, Multi );
+ Abc_FrameUpdateGia( pAbc, pTemp );
+ return 0;
+ }
if ( fStrMuxes )
{
if ( Gia_ManHasMapping(pAbc->pGia) )
@@ -32016,13 +32272,14 @@ int Abc_CommandAbc9Strash( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: &st [-L num] [-acmrsh]\n" );
+ Abc_Print( -2, "usage: &st [-LM num] [-acmrsh]\n" );
Abc_Print( -2, "\t performs structural hashing\n" );
Abc_Print( -2, "\t-a : toggle additional hashing [default = %s]\n", fAddStrash? "yes": "no" );
Abc_Print( -2, "\t-c : toggle collapsing hierarchical AIG [default = %s]\n", fCollapse? "yes": "no" );
Abc_Print( -2, "\t-m : toggle converting to larger gates [default = %s]\n", fAddMuxes? "yes": "no" );
Abc_Print( -2, "\t-L num : create MUX when sum of refs does not exceed this limit [default = %d]\n", Limit );
Abc_Print( -2, "\t (use L = 1 to create AIG with XORs but without MUXes)\n" );
+ Abc_Print( -2, "\t-M num : create an AIG with additional primary inputs [default = %d]\n", Multi );
Abc_Print( -2, "\t-r : toggle rehashing AIG while preserving mapping [default = %s]\n", fRehashMap? "yes": "no" );
Abc_Print( -2, "\t-s : toggle using MUX restructuring [default = %s]\n", fStrMuxes? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
@@ -32139,11 +32396,12 @@ usage:
***********************************************************************/
int Abc_CommandAbc9Cof( Abc_Frame_t * pAbc, int argc, char ** argv )
{
+ extern Gia_Man_t * Gia_ManComputeCofs( Gia_Man_t * p, int nVars );
Gia_Man_t * pTemp;
int c, fVerbose = 0;
- int iVar = 0, nLimFan = 0;
+ int iVar = 0, nLimFan = 0, nVars = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "VLvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "VLNvh" ) ) != EOF )
{
switch ( c )
{
@@ -32169,6 +32427,17 @@ int Abc_CommandAbc9Cof( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( nLimFan < 0 )
goto usage;
break;
+ case 'N':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nVars = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nVars < 0 )
+ goto usage;
+ break;
case 'v':
fVerbose ^= 1;
break;
@@ -32183,15 +32452,21 @@ int Abc_CommandAbc9Cof( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -1, "Abc_CommandAbc9Cof(): There is no AIG.\n" );
return 1;
}
- if ( nLimFan )
+ if ( nVars )
+ {
+ Abc_Print( 0, "Cofactoring the last %d inputs.\n", nVars );
+ pTemp = Gia_ManComputeCofs( pAbc->pGia, nVars );
+ Abc_FrameUpdateGia( pAbc, pTemp );
+ }
+ else if ( nLimFan )
{
- Abc_Print( -1, "Cofactoring all variables whose fanout count is higher than %d.\n", nLimFan );
+ Abc_Print( 0, "Cofactoring all variables whose fanout count is higher than %d.\n", nLimFan );
pTemp = Gia_ManDupCofAll( pAbc->pGia, nLimFan, fVerbose );
Abc_FrameUpdateGia( pAbc, pTemp );
}
else if ( iVar )
{
- Abc_Print( -1, "Cofactoring one variable with object ID %d.\n", iVar );
+ Abc_Print( 0, "Cofactoring one variable with object ID %d.\n", iVar );
pTemp = Gia_ManDupCof( pAbc->pGia, iVar );
Abc_FrameUpdateGia( pAbc, pTemp );
}
@@ -32203,10 +32478,11 @@ int Abc_CommandAbc9Cof( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: &cof [-VL num] [-vh]\n" );
+ Abc_Print( -2, "usage: &cof [-VLN num] [-vh]\n" );
Abc_Print( -2, "\t performs cofactoring w.r.t. variable(s)\n" );
Abc_Print( -2, "\t-V num : the zero-based ID of one variable to cofactor [default = %d]\n", iVar );
Abc_Print( -2, "\t-L num : cofactor vars with fanout count higher than this [default = %d]\n", nLimFan );
+ Abc_Print( -2, "\t-N num : cofactoring the given number of last input variables [default = %d]\n", nVars );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
@@ -32232,8 +32508,9 @@ int Abc_CommandAbc9Trim( Abc_Frame_t * pAbc, int argc, char ** argv )
int fTrimCos = 1;
int fDualOut = 0;
int fPoFedByPi = 0;
+ int fPoFedByPo = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "Viocdh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Viocpdh" ) ) != EOF )
{
switch ( c )
{
@@ -32257,6 +32534,9 @@ int Abc_CommandAbc9Trim( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'c':
fPoFedByPi ^= 1;
break;
+ case 'p':
+ fPoFedByPo ^= 1;
+ break;
case 'd':
fDualOut ^= 1;
break;
@@ -32278,16 +32558,23 @@ int Abc_CommandAbc9Trim( Abc_Frame_t * pAbc, int argc, char ** argv )
pTemp = Gia_ManDupTrimmed2( pTemp2 = pTemp );
Gia_ManStop( pTemp2 );
}
+ if ( fPoFedByPo )
+ {
+ extern Gia_Man_t * Gia_ManDupTrimmed3( Gia_Man_t * p );
+ pTemp = Gia_ManDupTrimmed3( pTemp2 = pTemp );
+ Gia_ManStop( pTemp2 );
+ }
Abc_FrameUpdateGia( pAbc, pTemp );
return 0;
usage:
- Abc_Print( -2, "usage: &trim [-V num] [-iocdh]\n" );
+ Abc_Print( -2, "usage: &trim [-V num] [-iocpdh]\n" );
Abc_Print( -2, "\t removes PIs without fanout and PO driven by constants\n" );
Abc_Print( -2, "\t-V num : the value (0 or 1) of POs to remove [default = both]\n" );
Abc_Print( -2, "\t-i : toggle removing PIs [default = %s]\n", fTrimCis? "yes": "no" );
Abc_Print( -2, "\t-o : toggle removing POs [default = %s]\n", fTrimCos? "yes": "no" );
Abc_Print( -2, "\t-c : toggle additionally removing POs fed by PIs [default = %s]\n", fPoFedByPi? "yes": "no" );
+ Abc_Print( -2, "\t-p : toggle additionally removing duplicated POs [default = %s]\n", fPoFedByPo? "yes": "no" );
Abc_Print( -2, "\t-d : toggle using dual-output miter [default = %s]\n", fDualOut? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
@@ -32309,18 +32596,22 @@ int Abc_CommandAbc9Dfs( Abc_Frame_t * pAbc, int argc, char ** argv )
Gia_Man_t * pTemp;
int c;
int fNormal = 0;
- int fReverse = 0;
+ int fRevFans = 0;
+ int fRevOuts = 0;
int fVerbose = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "nrvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "nfovh" ) ) != EOF )
{
switch ( c )
{
case 'n':
fNormal ^= 1;
break;
- case 'r':
- fReverse ^= 1;
+ case 'f':
+ fRevFans ^= 1;
+ break;
+ case 'o':
+ fRevOuts ^= 1;
break;
case 'v':
fVerbose ^= 1;
@@ -32337,31 +32628,18 @@ int Abc_CommandAbc9Dfs( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
if ( fNormal )
- {
pTemp = Gia_ManDupOrderAiger( pAbc->pGia );
- if ( fVerbose )
- Abc_Print( -1, "AIG objects are reordered as follows: CIs, ANDs, COs.\n" );
- }
- else if ( fReverse )
- {
- pTemp = Gia_ManDupOrderDfsReverse( pAbc->pGia );
- if ( fVerbose )
- Abc_Print( -1, "AIG objects are reordered in the reserve DFS order.\n" );
- }
- else
- {
- pTemp = Gia_ManDupOrderDfs( pAbc->pGia );
- if ( fVerbose )
- Abc_Print( -1, "AIG objects are reordered in the DFS order.\n" );
- }
+ else
+ pTemp = Gia_ManDupOrderDfsReverse( pAbc->pGia, fRevFans, fRevOuts );
Abc_FrameUpdateGia( pAbc, pTemp );
return 0;
usage:
- Abc_Print( -2, "usage: &dfs [-nrvh]\n" );
+ Abc_Print( -2, "usage: &dfs [-nfovh]\n" );
Abc_Print( -2, "\t orders objects in the DFS order\n" );
Abc_Print( -2, "\t-n : toggle using normalized ordering [default = %s]\n", fNormal? "yes": "no" );
- Abc_Print( -2, "\t-r : toggle using reverse DFS ordering [default = %s]\n", fReverse? "yes": "no" );
+ Abc_Print( -2, "\t-f : toggle using reverse fanin traversal order [default = %s]\n", fRevFans? "yes": "no" );
+ Abc_Print( -2, "\t-o : toggle using reverse output traversal order [default = %s]\n", fRevOuts? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
@@ -32514,6 +32792,184 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandAbc9Sim2( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern int Gia_ManSimTwo( Gia_Man_t * p0, Gia_Man_t * p1, int nWords, int nRounds, int fVerbose );
+ Gia_Man_t * pGias[2]; FILE * pFile;
+ char ** pArgvNew; int nArgcNew;
+ int c, RetValue = 0, fVerbose = 0, nWords = 16, nRounds = 10, RandSeed = 1, TimeLimit = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "WRNTvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'W':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-W\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nWords = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nWords < 0 )
+ goto usage;
+ break;
+ case 'R':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-R\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nRounds = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nRounds < 0 )
+ goto usage;
+ break;
+ case 'N':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ RandSeed = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( RandSeed < 0 )
+ goto usage;
+ break;
+ case 'T':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ TimeLimit = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( TimeLimit < 0 )
+ goto usage;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ pArgvNew = argv + globalUtilOptind;
+ nArgcNew = argc - globalUtilOptind;
+ if ( nArgcNew > 2 )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Cec(): Wrong number of command-line arguments.\n" );
+ return 1;
+ }
+ if ( nArgcNew == 2 )
+ {
+ char * pFileNames[2] = { pArgvNew[0], pArgvNew[1] }, * pTemp;
+ int n;
+ for ( n = 0; n < 2; n++ )
+ {
+ // fix the wrong symbol
+ for ( pTemp = pFileNames[n]; *pTemp; pTemp++ )
+ if ( *pTemp == '>' )
+ *pTemp = '\\';
+ if ( (pFile = fopen( pFileNames[n], "r" )) == NULL )
+ {
+ Abc_Print( -1, "Cannot open input file \"%s\". ", pFileNames[n] );
+ if ( (pFileNames[n] = Extra_FileGetSimilarName( pFileNames[n], ".aig", NULL, NULL, NULL, NULL )) )
+ Abc_Print( 1, "Did you mean \"%s\"?", pFileNames[n] );
+ Abc_Print( 1, "\n" );
+ return 1;
+ }
+ fclose( pFile );
+ pGias[n] = Gia_AigerRead( pFileNames[n], 0, 0, 0 );
+ if ( pGias[n] == NULL )
+ {
+ Abc_Print( -1, "Reading AIGER from file \"%s\" has failed.\n", pFileNames[n] );
+ return 0;
+ }
+ }
+ }
+ else
+ {
+ char * FileName, * pTemp;
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Cec(): There is no current AIG.\n" );
+ return 1;
+ }
+ pGias[0] = pAbc->pGia;
+ if ( nArgcNew == 1 )
+ FileName = pArgvNew[0];
+ else
+ {
+ assert( nArgcNew == 0 );
+ if ( pAbc->pGia->pSpec == NULL )
+ {
+ Abc_Print( -1, "File name is not given on the command line.\n" );
+ return 1;
+ }
+ FileName = pAbc->pGia->pSpec;
+ }
+ // fix the wrong symbol
+ for ( pTemp = FileName; *pTemp; pTemp++ )
+ if ( *pTemp == '>' )
+ *pTemp = '\\';
+ if ( (pFile = fopen( FileName, "r" )) == NULL )
+ {
+ Abc_Print( -1, "Cannot open input file \"%s\". ", FileName );
+ if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) )
+ Abc_Print( 1, "Did you mean \"%s\"?", FileName );
+ Abc_Print( 1, "\n" );
+ return 1;
+ }
+ fclose( pFile );
+ pGias[1] = Gia_AigerRead( FileName, 0, 0, 0 );
+ if ( pGias[1] == NULL )
+ {
+ Abc_Print( -1, "Reading AIGER has failed.\n" );
+ return 0;
+ }
+ }
+ if ( Gia_ManCiNum(pGias[0]) != Gia_ManCiNum(pGias[1]) )
+ {
+ Abc_Print( -1, "The number of CIs does not match.\n" );
+ return 1;
+ }
+ if ( Gia_ManCoNum(pGias[0]) != Gia_ManCoNum(pGias[1]) )
+ {
+ Abc_Print( -1, "The number of COs does not match.\n" );
+ return 1;
+ }
+ RetValue = Gia_ManSimTwo( pGias[0], pGias[1], nWords, nRounds, fVerbose );
+ if ( pGias[0] != pAbc->pGia )
+ Gia_ManStopP( &pGias[0] );
+ Gia_ManStopP( &pGias[1] );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &sim2 [-WRNT num] [-vh] <file1.aig> <file2.aig>\n" );
+ Abc_Print( -2, "\t performs random of two circuits\n" );
+ Abc_Print( -2, "\t-W num : the number of words to simulate [default = %d]\n", nWords );
+ Abc_Print( -2, "\t-R num : the number of simulation rounds [default = %d]\n", nRounds );
+ Abc_Print( -2, "\t-N num : random number seed (1 <= num <= 1000) [default = %d]\n", RandSeed );
+ Abc_Print( -2, "\t-T num : approximate runtime limit in seconds [default = %d]\n", TimeLimit );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandAbc9Sim3( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern int Ssw_RarSimulateGia( Gia_Man_t * p, Ssw_RarPars_t * pPars );
@@ -32837,9 +33293,108 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandAbc9Iwls21Test( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Gia_ManTestWordFile( Gia_Man_t * p, char * pFileName, char * pDumpFile, int fVerbose );
+ int c, fVerbose = 0;
+ char * pDumpFile = NULL;
+ char ** pArgvNew;
+ int nArgcNew;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Dvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'D':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-D\" should be followed by a file name.\n" );
+ goto usage;
+ }
+ pDumpFile = argv[globalUtilOptind];
+ globalUtilOptind++;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ pArgvNew = argv + globalUtilOptind;
+ nArgcNew = argc - globalUtilOptind;
+ if ( nArgcNew == 2 )
+ {
+ Gia_Man_t * pAig = Gia_AigerRead( pArgvNew[0], 0, 0, 0 );
+ if ( pAig == NULL )
+ {
+ Abc_Print( -1, "Reading AIGER from file \"%s\" has failed.\n", pArgvNew[0] );
+ return 0;
+ }
+ if ( Gia_ManRegNum(pAig) > 0 )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Iwls21Test(): This command works only for combinational AIGs.\n" );
+ return 0;
+ }
+ if ( Gia_ManCoNum(pAig) != 10 )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Iwls21Test(): Expecting an AIG with 10 outputs.\n" );
+ return 0;
+ }
+ Gia_ManTestWordFile( pAig, pArgvNew[1], pDumpFile, fVerbose );
+ Gia_ManStop( pAig );
+ return 0;
+ }
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Iwls21Test(): There is no AIG.\n" );
+ return 1;
+ }
+ if ( Gia_ManCoNum(pAbc->pGia) != 10 )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Iwls21Test(): Expecting an AIG with 10 outputs.\n" );
+ return 0;
+ }
+ if ( nArgcNew != 1 )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Iwls21Test(): Expecting data file name on the command line.\n" );
+ return 0;
+ }
+ if ( Gia_ManRegNum(pAbc->pGia) > 0 )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Iwls21Test(): This command works only for combinational AIGs.\n" );
+ return 0;
+ }
+ Vec_WrdFreeP( &pAbc->pGia->vSimsPi );
+ Gia_ManTestWordFile( pAbc->pGia, pArgvNew[0], pDumpFile, fVerbose );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &iwls21test [-vh] [-D file] <file1> <file2>\n" );
+ Abc_Print( -2, "\t this command evaluates AIG for 2021 IWLS ML+LS Contest\n" );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ Abc_Print( -2, "\t-D file : file name to dump statistics [default = none]\n" );
+ Abc_Print( -2, "\tfile1 : file with input AIG (or \"&read <file1.aig>; &iwls21test <file2>\" can be used)\n");
+ Abc_Print( -2, "\tfile2 : file with CIFAR10 image data (https://www.cs.toronto.edu/~kriz/cifar.html)\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandAbc9ReadSim( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- extern Vec_Wrd_t * Gia_ManSimPatRead( char * pFileName );
int c, fOutputs = 0, nWords = 4, fVerbose = 0;
char ** pArgvNew;
int nArgcNew;
@@ -32891,7 +33446,7 @@ int Abc_CommandAbc9ReadSim( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( fOutputs )
{
Vec_WrdFreeP( &pAbc->pGia->vSimsPo );
- pAbc->pGia->vSimsPo = Gia_ManSimPatRead( pArgvNew[0] );
+ pAbc->pGia->vSimsPo = Vec_WrdReadHex( pArgvNew[0], NULL, 1 );
if ( Vec_WrdSize(pAbc->pGia->vSimsPo) % Gia_ManCoNum(pAbc->pGia) != 0 )
{
Vec_WrdFreeP( &pAbc->pGia->vSimsPo );
@@ -32905,7 +33460,7 @@ int Abc_CommandAbc9ReadSim( Abc_Frame_t * pAbc, int argc, char ** argv )
else
{
Vec_WrdFreeP( &pAbc->pGia->vSimsPi );
- pAbc->pGia->vSimsPi = Gia_ManSimPatRead( pArgvNew[0] );
+ pAbc->pGia->vSimsPi = Vec_WrdReadHex( pArgvNew[0], NULL, 1 );
if ( Vec_WrdSize(pAbc->pGia->vSimsPi) % Gia_ManCiNum(pAbc->pGia) != 0 )
{
Vec_WrdFreeP( &pAbc->pGia->vSimsPi );
@@ -32942,7 +33497,6 @@ usage:
***********************************************************************/
int Abc_CommandAbc9WriteSim( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- extern void Gia_ManSimPatWrite( char * pFileName, Vec_Wrd_t * vSimsIn, int nWords );
int c, fOutputs = 0, fVerbose = 0;
char ** pArgvNew;
int nArgcNew;
@@ -32988,12 +33542,12 @@ int Abc_CommandAbc9WriteSim( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( fOutputs )
{
assert( Vec_WrdSize(pAbc->pGia->vSimsPo) % Gia_ManCoNum(pAbc->pGia) == 0 );
- Gia_ManSimPatWrite( pArgvNew[0], pAbc->pGia->vSimsPo, Vec_WrdSize(pAbc->pGia->vSimsPo) / Gia_ManCoNum(pAbc->pGia) );
+ Vec_WrdDumpHex( pArgvNew[0], pAbc->pGia->vSimsPo, Vec_WrdSize(pAbc->pGia->vSimsPo) / Gia_ManCoNum(pAbc->pGia), 1 );
}
else
{
assert( Vec_WrdSize(pAbc->pGia->vSimsPi) % Gia_ManCiNum(pAbc->pGia) == 0 );
- Gia_ManSimPatWrite( pArgvNew[0], pAbc->pGia->vSimsPi, Vec_WrdSize(pAbc->pGia->vSimsPi) / Gia_ManCiNum(pAbc->pGia) );
+ Vec_WrdDumpHex( pArgvNew[0], pAbc->pGia->vSimsPi, Vec_WrdSize(pAbc->pGia->vSimsPi) / Gia_ManCiNum(pAbc->pGia), 1 );
}
return 0;
@@ -34593,6 +35147,72 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandAbc9Extract( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern Gia_Man_t * Abc_NtkShareXorGia( Gia_Man_t * p, int nMultiSize, int fAnd, int fVerbose );
+ Gia_Man_t * pTemp;
+ int nMultiSize = 3;
+ int c, fAnds = 0;
+ int fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( (c = Extra_UtilGetopt(argc, argv, "Kavh")) != EOF )
+ {
+ switch (c)
+ {
+ case 'K':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-K\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nMultiSize = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nMultiSize < 0 )
+ goto usage;
+ break;
+ case 'a':
+ fAnds ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ break;
+ default:
+ goto usage;
+ }
+ }
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Shrink(): There is no AIG.\n" );
+ return 1;
+ }
+ pTemp = Abc_NtkShareXorGia( pAbc->pGia, nMultiSize, fAnds, fVerbose );
+ Abc_FrameUpdateGia( pAbc, pTemp );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &extract [-K <num>] [-vh]\n");
+ Abc_Print( -2, "\t extract shared logic for XOR-rich circuits\n");
+ Abc_Print( -2, "\t-K <num> : the minimum gate size to consider for extraction [default = %d]\n", nMultiSize );
+ Abc_Print( -2, "\t-a : toogle extracting ANDs instead of XORs [default = %s]\n", fAnds? "yes": "no" );
+ Abc_Print( -2, "\t-v : print verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandAbc9Balance( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Gia_Man_t * pTemp = NULL;
@@ -34780,6 +35400,170 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandAbc9Resub( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern Gia_Man_t * Gia_ManResub1( char * pFileName, int nNodes, int nSupp, int nDivs, int iChoice, int fUseXor, int fVerbose, int fVeryVerbose );
+ extern Gia_Man_t * Gia_ManResub2( Gia_Man_t * pGia, int nNodes, int nSupp, int nDivs, int iChoice, int fUseXor, int fVerbose, int fVeryVerbose );
+ Gia_Man_t * pTemp;
+ int nNodes = 0;
+ int nSupp = 0;
+ int nDivs = 0;
+ int c, fVerbose = 0;
+ int fVeryVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "NSDvwh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'N':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( 1, "Command line switch \"-N\" should be followed by a floating point number.\n" );
+ return 0;
+ }
+ nNodes = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nNodes < 0 )
+ goto usage;
+ break;
+ case 'S':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( 1, "Command line switch \"-S\" should be followed by a floating point number.\n" );
+ return 0;
+ }
+ nSupp = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nSupp < 0 )
+ goto usage;
+ break;
+ case 'D':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( 1, "Command line switch \"-D\" should be followed by a floating point number.\n" );
+ return 0;
+ }
+ nDivs = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nDivs < 0 )
+ goto usage;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'w':
+ fVeryVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( argc == globalUtilOptind + 1 )
+ {
+ pTemp = Gia_ManResub1( argv[globalUtilOptind], nNodes, nSupp, nDivs, 0, 0, fVerbose, fVeryVerbose );
+ Abc_FrameUpdateGia( pAbc, pTemp );
+ return 0;
+ }
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Resub(): There is no AIG.\n" );
+ return 1;
+ }
+ pTemp = Gia_ManResub2( pAbc->pGia, nNodes, nSupp, nDivs, 0, 0, fVerbose, fVeryVerbose );
+ Abc_FrameUpdateGia( pAbc, pTemp );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &resub [-NSD num] [-vwh]\n" );
+ Abc_Print( -2, "\t performs AIG resubstitution\n" );
+ Abc_Print( -2, "\t-N num : the limit on added nodes (num >= 0) [default = %d]\n", nNodes );
+ Abc_Print( -2, "\t-S num : the limit on support size (num > 0) [default = %d]\n", nSupp );
+ Abc_Print( -2, "\t-D num : the limit on divisor count (num > 0) [default = %d]\n", nDivs );
+ Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-w : toggles printing additional information [default = %s]\n", fVeryVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandAbc9Reshape( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern Gia_Man_t * Gia_ManReshape1( Gia_Man_t * pGia, int fUseSimple, int fVerbose, int fVeryVerbose );
+ extern Gia_Man_t * Gia_ManReshape2( Gia_Man_t * pGia, int fUseSimple, int fVerbose, int fVeryVerbose );
+ Gia_Man_t * pTemp;
+ int fUseReshape1 = 0;
+ int fUseSimple = 0;
+ int c, fVerbose = 0;
+ int fVeryVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "asvwh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'a':
+ fUseReshape1 ^= 1;
+ break;
+ case 's':
+ fUseSimple ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'w':
+ fVeryVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Resub(): There is no AIG.\n" );
+ return 1;
+ }
+ if ( fUseReshape1 )
+ pTemp = Gia_ManReshape1( pAbc->pGia, fUseSimple, fVerbose, fVeryVerbose );
+ else
+ pTemp = Gia_ManReshape2( pAbc->pGia, fUseSimple, fVerbose, fVeryVerbose );
+ Abc_FrameUpdateGia( pAbc, pTemp );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &reshape [-asvwh]\n" );
+ Abc_Print( -2, "\t performs AIG resubstitution\n" );
+ Abc_Print( -2, "\t-a : toggles selecting the algorithm [default = %s]\n", fUseReshape1? "yes": "no" );
+ Abc_Print( -2, "\t-s : toggles using simple method [default = %s]\n", fUseSimple? "yes": "no" );
+ Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-w : toggles printing additional information [default = %s]\n", fVeryVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandAbc9Syn2( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Gia_Man_t * pTemp;
@@ -35175,6 +35959,7 @@ usage:
***********************************************************************/
int Abc_CommandAbc9Miter( Abc_Frame_t * pAbc, int argc, char ** argv )
{
+ extern Gia_Man_t * Gia_ManPairWiseMiter( Gia_Man_t * p );
FILE * pFile;
Gia_Man_t * pAux;
Gia_Man_t * pSecond;
@@ -35185,13 +35970,14 @@ int Abc_CommandAbc9Miter( Abc_Frame_t * pAbc, int argc, char ** argv )
int nInsDup = 0;
int fDualOut = 0;
int fSeq = 0;
+ int fPairWise= 0;
int fTrans = 0;
int fTransX = 0;
int fConvert = 0;
int fTransZ = 0;
int fVerbose = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "Idstxyzvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Idsptxyzvh" ) ) != EOF )
{
switch ( c )
{
@@ -35212,6 +35998,9 @@ int Abc_CommandAbc9Miter( Abc_Frame_t * pAbc, int argc, char ** argv )
case 's':
fSeq ^= 1;
break;
+ case 'p':
+ fPairWise ^= 1;
+ break;
case 't':
fTrans ^= 1;
break;
@@ -35233,6 +36022,17 @@ int Abc_CommandAbc9Miter( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
}
}
+ if ( fPairWise )
+ {
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Miter(): There is no AIG.\n" );
+ return 1;
+ }
+ pAux = Gia_ManPairWiseMiter( pAbc->pGia );
+ Abc_FrameUpdateGia( pAbc, pAux );
+ return 0;
+ }
if ( fTrans || fTransX || fTransZ || fConvert )
{
if ( pAbc->pGia == NULL )
@@ -35306,11 +36106,12 @@ int Abc_CommandAbc9Miter( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: &miter [-I num] [-dstxyzvh] <file>\n" );
+ Abc_Print( -2, "usage: &miter [-I num] [-dsptxyzvh] <file>\n" );
Abc_Print( -2, "\t creates miter of two designs (current AIG vs. <file>)\n" );
Abc_Print( -2, "\t-I num : the number of last PIs to replicate [default = %d]\n", nInsDup );
Abc_Print( -2, "\t-d : toggle creating dual-output miter [default = %s]\n", fDualOut? "yes": "no" );
Abc_Print( -2, "\t-s : toggle creating sequential miter [default = %s]\n", fSeq? "yes": "no" );
+ Abc_Print( -2, "\t-p : toggle creating pair-wise miter [default = %s]\n", fPairWise? "yes": "no" );
Abc_Print( -2, "\t-t : toggle XORing POs of dual-output miter [default = %s]\n", fTrans? "yes": "no" );
Abc_Print( -2, "\t-x : toggle XORing POs of two-word miter [default = %s]\n", fTransX? "yes": "no" );
Abc_Print( -2, "\t-y : toggle convering two-word miter into dual-output miter [default = %s]\n", fConvert? "yes": "no" );
@@ -35872,16 +36673,28 @@ usage:
int Abc_CommandAbc9Sat( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern Vec_Int_t * Cbs2_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int fVerbose );
+ extern Vec_Int_t * Cbs3_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, int nRestarts, Vec_Str_t ** pvStatus, int fVerbose );
Cec_ParSat_t ParsSat, * pPars = &ParsSat;
Gia_Man_t * pTemp;
int c;
- int fNewSolver = 0, fCSat = 0;
+ int fNewSolver = 0, fNewSolver2 = 0, fCSat = 0, f0Proved = 0, nRestarts = 1;
Cec_ManSatSetDefaultParams( pPars );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "CSNanmtcxvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "JCRSNanmtcxyzvh" ) ) != EOF )
{
switch ( c )
{
+ case 'J':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-J\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->SolverType = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->SolverType < 0 )
+ goto usage;
+ break;
case 'C':
if ( globalUtilOptind >= argc )
{
@@ -35893,6 +36706,17 @@ int Abc_CommandAbc9Sat( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->nBTLimit < 0 )
goto usage;
break;
+ case 'R':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-R\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nRestarts = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nRestarts < 0 )
+ goto usage;
+ break;
case 'S':
if ( globalUtilOptind >= argc )
{
@@ -35933,6 +36757,12 @@ int Abc_CommandAbc9Sat( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'x':
fNewSolver ^= 1;
break;
+ case 'y':
+ fNewSolver2 ^= 1;
+ break;
+ case 'z':
+ f0Proved ^= 1;
+ break;
case 'v':
pPars->fVerbose ^= 1;
break;
@@ -35951,10 +36781,12 @@ int Abc_CommandAbc9Sat( Abc_Frame_t * pAbc, int argc, char ** argv )
Vec_Str_t * vStatus;
if ( fNewSolver )
vCounters = Cbs2_ManSolveMiterNc( pAbc->pGia, pPars->nBTLimit, &vStatus, pPars->fVerbose );
+ else if ( fNewSolver2 )
+ vCounters = Cbs3_ManSolveMiterNc( pAbc->pGia, pPars->nBTLimit, nRestarts, &vStatus, pPars->fVerbose );
else if ( pPars->fLearnCls )
vCounters = Tas_ManSolveMiterNc( pAbc->pGia, pPars->nBTLimit, &vStatus, pPars->fVerbose );
else if ( pPars->fNonChrono )
- vCounters = Cbs_ManSolveMiterNc( pAbc->pGia, pPars->nBTLimit, &vStatus, pPars->fVerbose );
+ vCounters = Cbs_ManSolveMiterNc( pAbc->pGia, pPars->nBTLimit, &vStatus, f0Proved, pPars->fVerbose );
else
vCounters = Cbs_ManSolveMiter( pAbc->pGia, pPars->nBTLimit, &vStatus, pPars->fVerbose );
Vec_IntFree( vCounters );
@@ -35962,7 +36794,7 @@ int Abc_CommandAbc9Sat( Abc_Frame_t * pAbc, int argc, char ** argv )
}
else
{
- pTemp = Cec_ManSatSolving( pAbc->pGia, pPars );
+ pTemp = Cec_ManSatSolving( pAbc->pGia, pPars, f0Proved );
Abc_FrameUpdateGia( pAbc, pTemp );
}
if ( pAbc->pGia->vSeqModelVec )
@@ -35974,9 +36806,11 @@ int Abc_CommandAbc9Sat( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: &sat [-CSN <num>] [-anmctxvh]\n" );
+ Abc_Print( -2, "usage: &sat [-JCRSN <num>] [-anmctxzvh]\n" );
Abc_Print( -2, "\t performs SAT solving for the combinational outputs\n" );
+ Abc_Print( -2, "\t-J num : the SAT solver type [default = %d]\n", pPars->SolverType );
Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit );
+ Abc_Print( -2, "\t-R num : the max number of restarts at a node [default = %d]\n", nRestarts );
Abc_Print( -2, "\t-S num : the min number of variables to recycle the solver [default = %d]\n", pPars->nSatVarMax );
Abc_Print( -2, "\t-N num : the min number of calls to recycle the solver [default = %d]\n", pPars->nCallsRecycle );
Abc_Print( -2, "\t-a : toggle solving all outputs and saving counter-examples [default = %s]\n", pPars->fSaveCexes? "yes": "no" );
@@ -35985,6 +36819,8 @@ usage:
Abc_Print( -2, "\t-c : toggle using circuit-based SAT solver [default = %s]\n", fCSat? "yes": "no" );
Abc_Print( -2, "\t-t : toggle using learning in curcuit-based solver [default = %s]\n", pPars->fLearnCls? "yes": "no" );
Abc_Print( -2, "\t-x : toggle using new solver [default = %s]\n", fNewSolver? "yes": "no" );
+ Abc_Print( -2, "\t-y : toggle using new solver [default = %s]\n", fNewSolver2? "yes": "no" );
+ Abc_Print( -2, "\t-z : toggle replacing proved cones by const0 [default = %s]\n", f0Proved? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
@@ -36070,18 +36906,29 @@ usage:
***********************************************************************/
int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv )
{
+ extern void Cec4_ManSetParams( Cec_ParFra_t * pPars );
extern Gia_Man_t * Cec2_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars );
extern Gia_Man_t * Cec3_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars );
- Cec_ParFra_t ParsFra, * pPars = &ParsFra;
- Gia_Man_t * pTemp;
- int c, fUseAlgo = 0, fUseAlgoG = 0;
- Cec_ManFraSetDefaultParams( pPars );
- pPars->fSatSweeping = 1;
+ extern Gia_Man_t * Cec4_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars );
+ Cec_ParFra_t ParsFra, * pPars = &ParsFra; Gia_Man_t * pTemp;
+ int c, fUseAlgo = 0, fUseAlgoG = 0, fUseAlgoG2 = 0;
+ Cec4_ManSetParams( pPars );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "WRILDCrmdckngwvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "JWRILDCNPrmdckngxwvh" ) ) != EOF )
{
switch ( c )
{
+ case 'J':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-J\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->jType = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->jType < 0 )
+ goto usage;
+ break;
case 'W':
if ( globalUtilOptind >= argc )
{
@@ -36148,6 +36995,28 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->nBTLimit < 0 )
goto usage;
break;
+ case 'N':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nCallsRecycle = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nCallsRecycle < 0 )
+ goto usage;
+ break;
+ case 'P':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-P\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nGenIters = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nGenIters < 0 )
+ goto usage;
+ break;
case 'r':
pPars->fRewriting ^= 1;
break;
@@ -36169,6 +37038,9 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'g':
fUseAlgoG ^= 1;
break;
+ case 'x':
+ fUseAlgoG2 ^= 1;
+ break;
case 'w':
pPars->fVeryVerbose ^= 1;
break;
@@ -36188,20 +37060,25 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv )
pTemp = Cec2_ManSimulateTest( pAbc->pGia, pPars );
else if ( fUseAlgoG )
pTemp = Cec3_ManSimulateTest( pAbc->pGia, pPars );
+ else if ( fUseAlgoG2 )
+ pTemp = Cec4_ManSimulateTest( pAbc->pGia, pPars );
else
pTemp = Cec_ManSatSweeping( pAbc->pGia, pPars, 0 );
Abc_FrameUpdateGia( pAbc, pTemp );
return 0;
usage:
- Abc_Print( -2, "usage: &fraig [-WRILDC <num>] [-rmdckngwvh]\n" );
+ Abc_Print( -2, "usage: &fraig [-JWRILDCNP <num>] [-rmdckngwvh]\n" );
Abc_Print( -2, "\t performs combinational SAT sweeping\n" );
+ Abc_Print( -2, "\t-J num : the solver type [default = %d]\n", pPars->jType );
Abc_Print( -2, "\t-W num : the number of simulation words [default = %d]\n", pPars->nWords );
Abc_Print( -2, "\t-R num : the number of simulation rounds [default = %d]\n", pPars->nRounds );
Abc_Print( -2, "\t-I num : the number of sweeping iterations [default = %d]\n", pPars->nItersMax );
Abc_Print( -2, "\t-L num : the max number of levels of nodes to consider [default = %d]\n", pPars->nLevelMax );
Abc_Print( -2, "\t-D num : the max number of steps of speculative reduction [default = %d]\n", pPars->nDepthMax );
Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit );
+ Abc_Print( -2, "\t-N num : the min number of calls to recycle the solver [default = %d]\n", pPars->nCallsRecycle );
+ Abc_Print( -2, "\t-P num : the number of pattern generation iterations [default = %d]\n", pPars->nGenIters );
Abc_Print( -2, "\t-r : toggle the use of AIG rewriting [default = %s]\n", pPars->fRewriting? "yes": "no" );
Abc_Print( -2, "\t-m : toggle miter vs. any circuit [default = %s]\n", pPars->fCheckMiter? "miter": "circuit" );
Abc_Print( -2, "\t-d : toggle using double output miters [default = %s]\n", pPars->fDualOut? "yes": "no" );
@@ -36316,8 +37193,9 @@ int Abc_CommandAbc9Srm( Abc_Frame_t * pAbc, int argc, char ** argv )
int fSpeculate = 1;
int fSkipSome = 0;
int fDualOut = 0;
+ int fComb = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "Adrsfvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Adrsfcvh" ) ) != EOF )
{
switch ( c )
{
@@ -36342,6 +37220,9 @@ int Abc_CommandAbc9Srm( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'f':
fSkipSome ^= 1;
break;
+ case 'c':
+ fComb ^= 1;
+ break;
case 'v':
fVerbose ^= 1;
break;
@@ -36356,6 +37237,16 @@ int Abc_CommandAbc9Srm( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -1, "Abc_CommandAbc9Srm(): There is no AIG.\n" );
return 1;
}
+ if ( fComb )
+ {
+ extern int Cec4_ManSimulateOnlyTest( Gia_Man_t * p, int fVerbose );
+ int Result = Cec4_ManSimulateOnlyTest( pAbc->pGia, fVerbose );
+ extern Gia_Man_t * Gia_ManCombSpecReduce( Gia_Man_t * p );
+ pTemp = Gia_ManCombSpecReduce( pAbc->pGia );
+ Abc_FrameUpdateGia( pAbc, pTemp );
+ Result = 0;
+ return 0;
+ }
sprintf(pFileName, "gsrm%s.aig", fSpeculate? "" : "s" );
sprintf(pFileName2, "gsyn%s.aig", fSpeculate? "" : "s" );
pTemp = Gia_ManSpecReduce( pAbc->pGia, fDualOut, fSynthesis, fSpeculate, fSkipSome, fVerbose );
@@ -36388,13 +37279,14 @@ int Abc_CommandAbc9Srm( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: &srm [-A file] [-drsfvh]\n" );
- Abc_Print( -2, "\t writes speculatively reduced model into file \"%s\"\n", pFileName );
+ Abc_Print( -2, "usage: &srm [-A file] [-drsfcvh]\n" );
+ Abc_Print( -2, "\t derives or writes speculatively reduced model into file \"%s\"\n", pFileName );
Abc_Print( -2, "\t-A file : file name for dumping speculative-reduced model [default = \"gsrm.aig\"]\n" );
Abc_Print( -2, "\t-d : toggle creating dual-output miter [default = %s]\n", fDualOut? "yes": "no" );
Abc_Print( -2, "\t-r : toggle writing reduced network for synthesis [default = %s]\n", fSynthesis? "yes": "no" );
Abc_Print( -2, "\t-s : toggle using speculation at the internal nodes [default = %s]\n", fSpeculate? "yes": "no" );
Abc_Print( -2, "\t-f : toggle filtering to remove redundant equivalences [default = %s]\n", fSkipSome? "yes": "no" );
+ Abc_Print( -2, "\t-c : toggle using combinational speculation [default = %s]\n", fComb? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
@@ -36771,10 +37663,10 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
FILE * pFile;
Gia_Man_t * pGias[2] = {NULL, NULL}, * pMiter;
char ** pArgvNew;
- int c, nArgcNew, fMiter = 0, fDualOutput = 0, fDumpMiter = 0;
+ int c, nArgcNew, fUseSim = 0, fUseNew = 0, fMiter = 0, fDualOutput = 0, fDumpMiter = 0;
Cec_ManCecSetDefaultParams( pPars );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "CTnmdasvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "CTnmdasxtvwh" ) ) != EOF )
{
switch ( c )
{
@@ -36815,9 +37707,18 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
case 's':
pPars->fSilent ^= 1;
break;
+ case 'x':
+ fUseNew ^= 1;
+ break;
+ case 't':
+ fUseSim ^= 1;
+ break;
case 'v':
pPars->fVerbose ^= 1;
break;
+ case 'w':
+ pPars->fVeryVerbose ^= 1;
+ break;
case 'h':
goto usage;
default:
@@ -36846,13 +37747,46 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
}
else
{
- Gia_Man_t * pTemp;
+ abctime clk = Abc_Clock();
+ Gia_Obj_t * pObj; int i;
if ( !pPars->fSilent )
Abc_Print( 1, "Assuming the current network is a single-output miter.\n" );
- pTemp = Gia_ManDemiterToDual( pAbc->pGia );
- pAbc->Status = Cec_ManVerify( pTemp, pPars );
- ABC_SWAP( Abc_Cex_t *, pAbc->pGia->pCexComb, pTemp->pCexComb );
- Gia_ManStop( pTemp );
+ if ( fUseSim )
+ {
+ abctime clk = Abc_Clock();
+ extern int Gia_ManCheckSimEquiv( Gia_Man_t * p, int fVerbose );
+ int Status = Gia_ManCheckSimEquiv( pAbc->pGia, pPars->fVerbose );
+ if ( Status == 1 )
+ Abc_Print( 1, "Networks are equivalent. " );
+ else if ( Status == 0 )
+ Abc_Print( 1, "Networks are NOT equivalent. " );
+ else
+ Abc_Print( 1, "Networks are UNDECIDED. " );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ return 0;
+ }
+ // handle the case when the output is disproved by an all-0 primary input pattern
+ ABC_FREE( pAbc->pGia->pCexComb );
+ Gia_ManSetPhase( pAbc->pGia );
+ Gia_ManForEachCo( pAbc->pGia, pObj, i )
+ if ( pObj->fPhase )
+ {
+ pAbc->pGia->pCexComb = Abc_CexAlloc( 0, Gia_ManCiNum(pAbc->pGia), 1 );
+ if ( !pPars->fSilent )
+ {
+ Abc_Print( 1, "Networks are NOT EQUIVALENT. Output %d trivially differs (different phase). ", i );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ }
+ pAbc->Status = 0;// satisfiable
+ break;
+ }
+ if ( pAbc->pGia->pCexComb == NULL )
+ {
+ Gia_Man_t * pTemp = Gia_ManDemiterToDual( pAbc->pGia );
+ pAbc->Status = Cec_ManVerify( pTemp, pPars );
+ ABC_SWAP( Abc_Cex_t *, pAbc->pGia->pCexComb, pTemp->pCexComb );
+ Gia_ManStop( pTemp );
+ }
}
Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb );
return 0;
@@ -36931,7 +37865,7 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
}
}
// compute the miter
- pMiter = Gia_ManMiter( pGias[0], pGias[1], 0, 1, 0, 0, pPars->fVerbose );
+ pMiter = Gia_ManMiter( pGias[0], pGias[1], 0, !fUseNew, 0, 0, pPars->fVerbose );
if ( pMiter )
{
if ( fDumpMiter )
@@ -36939,8 +37873,46 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( 0, "The verification miter is written into file \"%s\".\n", "cec_miter.aig" );
Gia_AigerWrite( pMiter, "cec_miter.aig", 0, 0, 0 );
}
- pAbc->Status = Cec_ManVerify( pMiter, pPars );
- Abc_FrameReplaceCex( pAbc, &pGias[0]->pCexComb );
+ if ( pGias[0]->vSimsPi )
+ {
+ pMiter->vSimsPi = Vec_WrdDup(pGias[0]->vSimsPi);
+ pMiter->nSimWords = pGias[0]->nSimWords;
+ }
+ if ( fUseSim && Gia_ManCiNum(pMiter) > 40 )
+ {
+ Abc_Print( -1, "This type of CEC can only be applied to AIGs with no more than 40 inputs.\n" );
+ return 0;
+ }
+ if ( fUseSim )
+ {
+ abctime clk = Abc_Clock();
+ extern int Gia_ManCheckSimEquiv( Gia_Man_t * p, int fVerbose );
+ int Status = Gia_ManCheckSimEquiv( pMiter, pPars->fVerbose );
+ if ( Status == 1 )
+ Abc_Print( 1, "Networks are equivalent. " );
+ else if ( Status == 0 )
+ Abc_Print( 1, "Networks are NOT equivalent. " );
+ else
+ Abc_Print( 1, "Networks are UNDECIDED. " );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ }
+ else if ( fUseNew )
+ {
+ abctime clk = Abc_Clock();
+ extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose );
+ Gia_Man_t * pNew = Cec4_ManSimulateTest3( pMiter, pPars->nBTLimit, pPars->fVerbose );
+ if ( Gia_ManAndNum(pNew) == 0 )
+ Abc_Print( 1, "Networks are equivalent. " );
+ else
+ Abc_Print( 1, "Networks are UNDECIDED. " );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ Gia_ManStop( pNew );
+ }
+ else
+ {
+ pAbc->Status = Cec_ManVerify( pMiter, pPars );
+ Abc_FrameReplaceCex( pAbc, &pGias[0]->pCexComb );
+ }
Gia_ManStop( pMiter );
}
if ( pGias[0] != pAbc->pGia )
@@ -36949,7 +37921,7 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: &cec [-CT num] [-nmdasvh]\n" );
+ Abc_Print( -2, "usage: &cec [-CT num] [-nmdasxtvwh]\n" );
Abc_Print( -2, "\t new combinational equivalence checker\n" );
Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit );
Abc_Print( -2, "\t-T num : approximate runtime limit in seconds [default = %d]\n", pPars->TimeLimit );
@@ -36958,7 +37930,10 @@ usage:
Abc_Print( -2, "\t-d : toggle using dual output miter [default = %s]\n", fDualOutput? "yes":"no");
Abc_Print( -2, "\t-a : toggle writing dual-output miter [default = %s]\n", fDumpMiter? "yes":"no");
Abc_Print( -2, "\t-s : toggle silent operation [default = %s]\n", pPars->fSilent ? "yes":"no");
+ Abc_Print( -2, "\t-x : toggle using new solver [default = %s]\n", fUseNew? "yes":"no");
+ Abc_Print( -2, "\t-t : toggle using simulation [default = %s]\n", fUseSim? "yes":"no");
Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes":"no");
+ Abc_Print( -2, "\t-w : toggle printing SAT solver statistics [default = %s]\n", pPars->fVeryVerbose? "yes":"no");
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
}
@@ -39302,7 +40277,7 @@ int Abc_CommandAbc9Mf( Abc_Frame_t * pAbc, int argc, char ** argv )
Gia_Man_t * pNew; int c;
Mf_ManSetDefaultPars( pPars );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "KCFARLEDWaekmcgvwh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "KCFARLEDWaekmclgvwh" ) ) != EOF )
{
switch ( c )
{
@@ -39426,6 +40401,9 @@ int Abc_CommandAbc9Mf( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'c':
pPars->fGenCnf ^= 1;
break;
+ case 'l':
+ pPars->fGenLit ^= 1;
+ break;
case 'g':
pPars->fPureAig ^= 1;
break;
@@ -39478,6 +40456,7 @@ usage:
Abc_Print( -2, "\t-k : toggles coarsening the subject graph [default = %s]\n", pPars->fCoarsen? "yes": "no" );
Abc_Print( -2, "\t-m : toggles cut minimization [default = %s]\n", pPars->fCutMin? "yes": "no" );
Abc_Print( -2, "\t-c : toggles mapping for CNF generation [default = %s]\n", pPars->fGenCnf? "yes": "no" );
+ Abc_Print( -2, "\t-l : toggles mapping for literals [default = %s]\n", pPars->fGenLit? "yes": "no" );
Abc_Print( -2, "\t-g : toggles generating AIG without mapping [default = %s]\n", pPars->fPureAig? "yes": "no" );
Abc_Print( -2, "\t-v : toggles verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" );
Abc_Print( -2, "\t-w : toggles very verbose output [default = %s]\n", pPars->fVeryVerbose? "yes": "no" );
@@ -40314,6 +41293,365 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandAbc9LNetRead( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern Gia_Man_t * Vec_WrdReadTest( char * pFileName );
+ extern void Gia_ManReadSimInfoInputs( char * pFileName, char * pFileOut1, int fVerbose );
+ int c, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ default:
+ goto usage;
+ }
+ }
+ if ( argc == globalUtilOptind + 2 ) // read 1 file, write 1 file
+ {
+ Gia_ManReadSimInfoInputs( argv[globalUtilOptind], argv[globalUtilOptind+1], fVerbose );
+ return 0;
+ }
+ if ( strstr(argv[globalUtilOptind], ".v") )
+ {
+ Gia_Man_t * pNew = Vec_WrdReadTest( argv[globalUtilOptind] );
+ if ( pNew == NULL )
+ {
+ printf( "Cannot read network from file \"%s\".\n", argv[globalUtilOptind] );
+ return 0;
+ }
+ Abc_FrameUpdateGia( pAbc, pNew );
+ }
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &lnetread [-vh] <file> <file2>\n" );
+ Abc_Print( -2, "\t reads and converts the network or the simulation data\n" );
+ Abc_Print( -2, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : prints the command usage\n");
+ Abc_Print( -2, "\t<file> : input file name with simulation information\n");
+ Abc_Print( -2, "\t<file2> : output file name with simulation information\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandAbc9LNetSim( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Gia_ManSimInfoPassTest( Gia_Man_t * p, char * pFileName, char * pFileName2, int fVerbose );
+ int c, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ default:
+ goto usage;
+ }
+ }
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Empty GIA network.\n" );
+ return 1;
+ }
+ if ( argc != globalUtilOptind + 2 )
+ {
+ Abc_Print( -1, "Expecting two file names on the command line.\n" );
+ return 1;
+ }
+ Gia_ManSimInfoPassTest( pAbc->pGia, argv[globalUtilOptind], argv[globalUtilOptind+1], fVerbose );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &lnetsim [-vh] <file> <file2>\n" );
+ Abc_Print( -2, "\t performs specialized AIG simulation\n" );
+ Abc_Print( -2, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : prints the command usage\n");
+ Abc_Print( -2, "\t<file> : input file name with simulation information\n");
+ Abc_Print( -2, "\t<file2> : output file name with simulation information\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandAbc9LNetEval( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Gia_ManSimInfoEval( Gia_Man_t * p, char * pFileName, char * pFileName2, int nOuts, int fVerbose );
+ int c, nOuts = -1, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Ovh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'O':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-O\" should be followed by a positive integer.\n" );
+ goto usage;
+ }
+ nOuts = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ default:
+ goto usage;
+ }
+ }
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Empty GIA network.\n" );
+ return 1;
+ }
+ if ( argc != globalUtilOptind + 2 )
+ {
+ Abc_Print( -1, "Expecting two file names on the command line.\n" );
+ return 1;
+ }
+ Gia_ManSimInfoEval( pAbc->pGia, argv[globalUtilOptind], argv[globalUtilOptind+1], nOuts, fVerbose );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &lneteval [-O num] [-vh] <file> <file2>\n" );
+ Abc_Print( -2, "\t performs testing of the AIG on the simulation data\n" );
+ Abc_Print( -2, "\t-O num : the output group size [default = %d]\n", nOuts );
+ Abc_Print( -2, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : prints the command usage\n");
+ Abc_Print( -2, "\t<file> : file name with simulation information\n");
+ Abc_Print( -2, "\t<file2> : file name with simulation information\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandAbc9LNetOpt( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern Gia_Man_t * Gia_ManPerformLNetOpt( Gia_Man_t * p, int fTryNew, char * pFileName, int nIns, int nOuts, int Thresh, int nRounds, int fVerbose );
+ extern Gia_Man_t * Gia_ManPerformLNetOptNew( Gia_Man_t * p, char * pFileName, int nIns, int nOuts, int Thresh, int nRounds, int fVerbose );
+ Gia_Man_t * pTemp;
+ char * pFileName = NULL;
+ int c, nIns = 6, nOuts = 2, Limit = 0, nRounds = 20, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "IORXvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'I':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-I\" should be followed by a positive integer.\n" );
+ goto usage;
+ }
+ nIns = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
+ case 'O':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-O\" should be followed by a positive integer.\n" );
+ goto usage;
+ }
+ nOuts = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
+ case 'R':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-R\" should be followed by a positive integer.\n" );
+ goto usage;
+ }
+ Limit = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
+ case 'X':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-X\" should be followed by a positive integer.\n" );
+ goto usage;
+ }
+ nRounds = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ default:
+ goto usage;
+ }
+ }
+ if ( argc > globalUtilOptind + 1 )
+ {
+ return 0;
+ }
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Empty GIA network.\n" );
+ return 1;
+ }
+ if ( argc == globalUtilOptind + 1 )
+ {
+ FILE * pFile = fopen( argv[globalUtilOptind], "rb" );
+ if ( pFile == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9BCore(): Cannot open file \"%s\" for reading the simulation information.\n", argv[globalUtilOptind] );
+ return 0;
+ }
+ fclose( pFile );
+ pFileName = argv[globalUtilOptind];
+ }
+ pTemp = Gia_ManPerformLNetOptNew( pAbc->pGia, pFileName, nIns, nOuts, Limit, nRounds, fVerbose );
+ Abc_FrameUpdateGia( pAbc, pTemp );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &lnetopt [-IORX num] [-vh] <file>\n" );
+ Abc_Print( -2, "\t performs specialized AIG optimization\n" );
+ Abc_Print( -2, "\t-I num : the input support size [default = %d]\n", nIns );
+ Abc_Print( -2, "\t-O num : the output group size [default = %d]\n", nOuts );
+ Abc_Print( -2, "\t-R num : patterns are cares starting this value [default = %d]\n", Limit );
+ Abc_Print( -2, "\t-X num : the number of optimization rounds [default = %d]\n", nRounds );
+ Abc_Print( -2, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : prints the command usage\n");
+ Abc_Print( -2, "\t<file> : file name with simulation information\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandAbc9LNetMap( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern Abc_Ntk_t * Gia_ManPerformLNetMap( Gia_Man_t * p, int GroupSize, int fUseFixed, int fTryNew, int fVerbose );
+ Abc_Ntk_t * pTemp;
+ char * pFileName = NULL;
+ int c, fTryNew = 1, nIns = 6, nOuts = 2, fUseFixed = 0, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "IOfxvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'I':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-I\" should be followed by a positive integer.\n" );
+ goto usage;
+ }
+ nIns = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
+ case 'O':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-O\" should be followed by a positive integer.\n" );
+ goto usage;
+ }
+ nOuts = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
+ case 'f':
+ fUseFixed ^= 1;
+ break;
+ case 'x':
+ fTryNew ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ default:
+ goto usage;
+ }
+ }
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Empty GIA network.\n" );
+ return 1;
+ }
+ if ( argc == globalUtilOptind + 1 )
+ {
+ FILE * pFile = fopen( argv[globalUtilOptind], "rb" );
+ if ( pFile == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9BCore(): Cannot open file \"%s\" for reading the simulation information.\n", argv[globalUtilOptind] );
+ return 0;
+ }
+ fclose( pFile );
+ pFileName = argv[globalUtilOptind];
+ }
+ pTemp = Gia_ManPerformLNetMap( pAbc->pGia, nOuts, fUseFixed, fTryNew, fVerbose );
+ Abc_FrameReplaceCurrentNetwork( pAbc, pTemp );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &lnetmap [-IO num] [-fxvh] <file>\n" );
+ Abc_Print( -2, "\t performs specialized LUT mapping\n" );
+ Abc_Print( -2, "\t-I num : the input support size [default = %d]\n", nIns );
+ Abc_Print( -2, "\t-O num : the output group size [default = %d]\n", nOuts );
+ Abc_Print( -2, "\t-f : toggles using fixed primitives [default = %s]\n", fUseFixed? "yes": "no" );
+ Abc_Print( -2, "\t-x : toggles using another computation [default = %s]\n", fTryNew? "yes": "no" );
+ Abc_Print( -2, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : prints the command usage\n");
+ Abc_Print( -2, "\t<file> : file name with simulation information\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandAbc9Unmap( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern void Gia_ManTestStruct( Gia_Man_t * p );
@@ -40675,7 +42013,7 @@ int Abc_CommandAbc9Dch( Abc_Frame_t * pAbc, int argc, char ** argv )
// set defaults
Dch_ManSetDefaultParams( pPars );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "WCSsptfremvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "WCSsptfremgcxvh" ) ) != EOF )
{
switch ( c )
{
@@ -40733,6 +42071,15 @@ int Abc_CommandAbc9Dch( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'm':
fMinLevel ^= 1;
break;
+ case 'g':
+ pPars->fUseGia ^= 1;
+ break;
+ case 'c':
+ pPars->fUseCSat ^= 1;
+ break;
+ case 'x':
+ pPars->fUseNew ^= 1;
+ break;
case 'v':
pPars->fVerbose ^= 1;
break;
@@ -40772,7 +42119,7 @@ int Abc_CommandAbc9Dch( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: &dch [-WCS num] [-sptfremvh]\n" );
+ Abc_Print( -2, "usage: &dch [-WCS num] [-sptfremgcxvh]\n" );
Abc_Print( -2, "\t computes structural choices using a new approach\n" );
Abc_Print( -2, "\t-W num : the max number of simulation words [default = %d]\n", pPars->nWords );
Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit );
@@ -40784,6 +42131,9 @@ usage:
Abc_Print( -2, "\t-r : toggle skipping choices with redundant support [default = %s]\n", pPars->fSkipRedSupp? "yes": "no" );
Abc_Print( -2, "\t-e : toggle computing and merging equivalences [default = %s]\n", fEquiv? "yes": "no" );
Abc_Print( -2, "\t-m : toggle minimizing logic level after merging equivalences [default = %s]\n", fMinLevel? "yes": "no" );
+ Abc_Print( -2, "\t-g : toggle using GIA to prove equivalences [default = %s]\n", pPars->fUseGia? "yes": "no" );
+ Abc_Print( -2, "\t-c : toggle using circuit-based SAT vs. MiniSat [default = %s]\n", pPars->fUseCSat? "yes": "no" );
+ Abc_Print( -2, "\t-x : toggle using new choice computation [default = %s]\n", pPars->fUseNew? "yes": "no" );
Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", pPars->fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
@@ -42083,6 +43433,64 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandAbc9Compare( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Gia_Iso4TestTwo( Gia_Man_t * pGia0, Gia_Man_t * pGia1 );
+ Gia_Man_t * pGia0, * pGia1;
+ char ** pArgvNew; int nArgcNew;
+ int c, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ pArgvNew = argv + globalUtilOptind;
+ nArgcNew = argc - globalUtilOptind;
+ if ( nArgcNew != 2 )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Compare(): This command expects two AIG file names on the command line.\n" );
+ return 1;
+ }
+ pGia0 = Gia_AigerRead( pArgvNew[0], 0, 0, 0 );
+ pGia1 = Gia_AigerRead( pArgvNew[1], 0, 0, 0 );
+ if ( pGia0 == NULL || pGia1 == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Compare(): Reading input files did not work.\n" );
+ return 1;
+ }
+ Gia_Iso4TestTwo( pGia0, pGia1 );
+ Gia_ManStop( pGia0 );
+ Gia_ManStop( pGia1 );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &compare <file1> <file2> [-vh]\n" );
+ Abc_Print( -2, "\t compared two AIGs for structural similarity\n" );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandAbc9CexInfo( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern void Bmc_CexTest( Gia_Man_t * p, Abc_Cex_t * pCex, int fVerbose );
@@ -44409,6 +45817,7 @@ int Abc_CommandAbc9SatClp( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
}
vSop = Bmc_CollapseOne( pAbc->pGia, nCubeLim, nBTLimit, fCanon, 0, fVerbose );
+ printf( "%s\n", Vec_StrArray(vSop) );
Vec_StrFree( vSop );
return 0;
@@ -45703,7 +47112,7 @@ int Abc_CommandAbc9Mfs( Abc_Frame_t * pAbc, int argc, char ** argv )
pPars->nDepthMax = 100;
pPars->nWinSizeMax = 2000;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "WFDMLCNdaebvwh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "WFDMLCNdaeblvwh" ) ) != EOF )
{
switch ( c )
{
@@ -45796,6 +47205,9 @@ int Abc_CommandAbc9Mfs( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'b':
pPars->fAllBoxes ^= 1;
break;
+ case 'l':
+ pPars->fUseDcs ^= 1;
+ break;
case 'v':
pPars->fVerbose ^= 1;
break;
@@ -45835,12 +47247,21 @@ int Abc_CommandAbc9Mfs( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
}
*/
- pTemp = Gia_ManPerformMfs( pAbc->pGia, pPars );
+ if ( Gia_ManRegNum(pAbc->pGia) == 0 )
+ pTemp = Gia_ManPerformMfs( pAbc->pGia, pPars );
+ else
+ {
+ int nRegs = Gia_ManRegNum(pAbc->pGia);
+ pAbc->pGia->nRegs = 0;
+ pTemp = Gia_ManPerformMfs( pAbc->pGia, pPars );
+ Gia_ManSetRegNum( pAbc->pGia, nRegs );
+ Gia_ManSetRegNum( pTemp, nRegs );
+ }
Abc_FrameUpdateGia( pAbc, pTemp );
return 0;
usage:
- Abc_Print( -2, "usage: &mfs [-WFDMLCN <num>] [-daebvwh]\n" );
+ Abc_Print( -2, "usage: &mfs [-WFDMLCN <num>] [-daeblvwh]\n" );
Abc_Print( -2, "\t performs don't-care-based optimization of logic networks\n" );
Abc_Print( -2, "\t-W <num> : the number of levels in the TFO cone (0 <= num) [default = %d]\n", pPars->nTfoLevMax );
Abc_Print( -2, "\t-F <num> : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nFanoutMax );
@@ -45853,6 +47274,7 @@ usage:
Abc_Print( -2, "\t-a : toggle minimizing area or area+edges [default = %s]\n", pPars->fArea? "area": "area+edges" );
Abc_Print( -2, "\t-e : toggle high-effort resubstitution [default = %s]\n", pPars->fMoreEffort? "yes": "no" );
Abc_Print( -2, "\t-b : toggle preserving all white boxes [default = %s]\n", pPars->fAllBoxes? "yes": "no" );
+ Abc_Print( -2, "\t-l : toggle deriving don't-cares [default = %s]\n", pPars->fUseDcs? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" );
Abc_Print( -2, "\t-w : toggle printing detailed stats for each node [default = %s]\n", pPars->fVeryVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
@@ -46043,13 +47465,35 @@ usage:
***********************************************************************/
int Abc_CommandAbc9DeepSyn( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- extern Gia_Man_t * Gia_ManDeepSyn( Gia_Man_t * pGia, int TimeOut, int nAnds, int Seed, int fVerbose );
- Gia_Man_t * pTemp; int c, TimeOut = 0, nAnds = 0, Seed = 0, fVerbose = 0;
+ extern Gia_Man_t * Gia_ManDeepSyn( Gia_Man_t * pGia, int nIters, int nNoImpr, int TimeOut, int nAnds, int Seed, int fUseTwo, int fVerbose );
+ Gia_Man_t * pTemp; int c, nIters = 1, nNoImpr = ABC_INFINITY, TimeOut = 0, nAnds = 0, Seed = 0, fUseTwo = 0, fVerbose = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "TASvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "IJTAStvh" ) ) != EOF )
{
switch ( c )
{
+ case 'I':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nIters = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nIters < 0 )
+ goto usage;
+ break;
+ case 'J':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-J\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nNoImpr = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nNoImpr < 0 )
+ goto usage;
+ break;
case 'T':
if ( globalUtilOptind >= argc )
{
@@ -46083,6 +47527,9 @@ int Abc_CommandAbc9DeepSyn( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( Seed < 0 )
goto usage;
break;
+ case 't':
+ fUseTwo ^= 1;
+ break;
case 'v':
fVerbose ^= 1;
break;
@@ -46097,16 +47544,19 @@ int Abc_CommandAbc9DeepSyn( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -1, "Abc_CommandAbc9DeepSyn(): There is no AIG.\n" );
return 0;
}
- pTemp = Gia_ManDeepSyn( pAbc->pGia, TimeOut, nAnds, Seed, fVerbose );
+ pTemp = Gia_ManDeepSyn( pAbc->pGia, nIters, nNoImpr, TimeOut, nAnds, Seed, fUseTwo, fVerbose );
Abc_FrameUpdateGia( pAbc, pTemp );
return 0;
usage:
- Abc_Print( -2, "usage: &deepsyn [-TAS <num>] [-vh]\n" );
+ Abc_Print( -2, "usage: &deepsyn [-IJTAS <num>] [-tvh]\n" );
Abc_Print( -2, "\t performs synthesis\n" );
+ Abc_Print( -2, "\t-I <num> : the number of iterations [default = %d]\n", nIters );
+ Abc_Print( -2, "\t-J <num> : the number of steps without improvements [default = %d]\n", nNoImpr );
Abc_Print( -2, "\t-T <num> : the timeout in seconds (0 = no timeout) [default = %d]\n", TimeOut );
Abc_Print( -2, "\t-A <num> : the number of nodes to stop (0 = no limit) [default = %d]\n", nAnds );
- Abc_Print( -2, "\t-S <num> : user-specified random seed (0 <= num <= 100) [default = %d]\n", Seed );
+ Abc_Print( -2, "\t-S <num> : user-specified random seed (0 <= num <= 100) [default = %d]\n", Seed );
+ Abc_Print( -2, "\t-t : toggle using two-input LUTs [default = %s]\n", fUseTwo? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
@@ -46123,6 +47573,107 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandAbc9StochSyn( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Gia_ManStochSyn( int nMaxSize, int nIters, int TimeOut, int Seed, int fVerbose, char * pScript );
+ int c, nMaxSize = 1000, nIters = 10, TimeOut = 0, Seed = 0, fVerbose = 0; char * pScript;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "NITSvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'N':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nMaxSize = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nMaxSize < 0 )
+ goto usage;
+ break;
+ case 'I':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nIters = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nIters < 0 )
+ goto usage;
+ break;
+ case 'T':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ TimeOut = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( TimeOut < 0 )
+ goto usage;
+ break;
+ case 'S':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ Seed = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( Seed < 0 )
+ goto usage;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9StochSyn(): There is no AIG.\n" );
+ return 0;
+ }
+ if ( argc != globalUtilOptind + 1 )
+ {
+ printf( "Expecting a synthesis script in quotes on the command line (for example: \"&st; &dch; &if\").\n" );
+ goto usage;
+ }
+ pScript = Abc_UtilStrsav( argv[globalUtilOptind] );
+ Gia_ManStochSyn( nMaxSize, nIters, TimeOut, Seed, fVerbose, pScript );
+ ABC_FREE( pScript );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &stochsyn [-NITS <num>] [-tvh] <script>\n" );
+ Abc_Print( -2, "\t performs stochastic synthesis\n" );
+ Abc_Print( -2, "\t-N <num> : the max partition size (in AIG nodes or LUTs) [default = %d]\n", nMaxSize );
+ Abc_Print( -2, "\t-I <num> : the number of iterations [default = %d]\n", nIters );
+ Abc_Print( -2, "\t-T <num> : the timeout in seconds (0 = no timeout) [default = %d]\n", TimeOut );
+ Abc_Print( -2, "\t-S <num> : user-specified random seed (0 <= num <= 100) [default = %d]\n", Seed );
+ Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ Abc_Print( -2, "\t<script> : synthesis script to use for each partition\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandAbc9CexCut( Abc_Frame_t * pAbc, int argc, char ** argv )
{
return -1;
@@ -47779,6 +49330,10 @@ usage:
***********************************************************************/
int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv )
{
+ extern Gia_Man_t * Gia_ManPerformNewResub( Gia_Man_t * p, int nWinCount, int nCutSize, int nProcs, int fVerbose );
+ extern void Gia_RsbEnumerateWindows( Gia_Man_t * p, int nInputsMax, int nLevelsMax );
+ extern int Gia_ManSumTotalOfSupportSizes( Gia_Man_t * p );
+ extern void Abc_Tt6MinTest2( Gia_Man_t * p );
int c, fVerbose = 0;
int nFrames = 5;
int fSwitch = 0;
@@ -47834,13 +49389,13 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
}
}
-// if ( pAbc->pGia == NULL )
-// {
-// Abc_Print( -1, "Abc_CommandAbc9Test(): There is no AIG.\n" );
-// return 1;
-// }
-// Abc_FrameUpdateGia( pAbc, Abc_Procedure(pAbc->pGia) );
-// Gia_SimQualityTest( pAbc->pGia );
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Test(): There is no AIG.\n" );
+ return 1;
+ }
+ Abc_FrameUpdateGia( pAbc, Gia_ManPerformNewResub(pAbc->pGia, 100, 6, 1, 1) );
+// printf( "AIG in \"%s\" has the sum of output support sizes equal to %d.\n", pAbc->pGia->pSpec, Gia_ManSumTotalOfSupportSizes(pAbc->pGia) );
return 0;
usage:
Abc_Print( -2, "usage: &test [-FW num] [-svh]\n" );
diff --git a/src/base/abci/abcBalance.c b/src/base/abci/abcBalance.c
index 552cba7f..185ef9c1 100644
--- a/src/base/abci/abcBalance.c
+++ b/src/base/abci/abcBalance.c
@@ -266,7 +266,7 @@ Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, Vec_
if ( vSuper->nSize < 2 )
printf( "BUG!\n" );
// sort the new nodes by level in the decreasing order
- Vec_PtrSort( vSuper, (int (*)(void))Abc_NodeCompareLevelsDecrease );
+ Vec_PtrSort( vSuper, (int (*)(const void *, const void *))Abc_NodeCompareLevelsDecrease );
// balance the nodes
assert( vSuper->nSize > 1 );
while ( vSuper->nSize > 1 )
diff --git a/src/base/abci/abcCollapse.c b/src/base/abci/abcCollapse.c
index ca54d542..136712cb 100644
--- a/src/base/abci/abcCollapse.c
+++ b/src/base/abci/abcCollapse.c
@@ -195,7 +195,16 @@ Abc_Ntk_t * Abc_NtkFromGlobalBdds( Abc_Ntk_t * pNtk, int fReverse )
Extra_ProgressBarStop( pProgress );
return pNtkNew;
}
-Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fReorder, int fReverse, int fVerbose )
+void Abc_NtkDumpVariableOrder( Abc_Ntk_t * pNtk )
+{
+ DdManager * dd = (DdManager *)Abc_NtkGlobalBddMan( pNtk );
+ FILE * pFile = fopen( "order.txt", "wb" ); int i;
+ for ( i = 0; i < dd->size; i++ )
+ fprintf( pFile, "%d ", dd->invperm[i] );
+ fprintf( pFile, "\n" );
+ fclose( pFile );
+}
+Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fReorder, int fReverse, int fDumpOrder, int fVerbose )
{
Abc_Ntk_t * pNtkNew;
abctime clk = Abc_Clock();
@@ -210,6 +219,8 @@ Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, i
printf( "Shared BDD size = %6d nodes. ", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) );
ABC_PRT( "BDD construction time", Abc_Clock() - clk );
}
+ if ( fDumpOrder )
+ Abc_NtkDumpVariableOrder( pNtk );
// create the new network
pNtkNew = Abc_NtkFromGlobalBdds( pNtk, fReverse );
@@ -236,7 +247,7 @@ Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, i
#else
-Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fReorder, int fReverse, int fVerbose )
+Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fReorder, int fReverse, int fDumpOrder, int fVerbose )
{
return NULL;
}
diff --git a/src/base/abci/abcDar.c b/src/base/abci/abcDar.c
index 56eb139a..483f65b9 100644
--- a/src/base/abci/abcDar.c
+++ b/src/base/abci/abcDar.c
@@ -91,7 +91,7 @@ void Abc_CollectTopOr( Abc_Obj_t * pObj, Vec_Ptr_t * vSuper )
if ( Abc_ObjIsComplement(pObj) )
{
Abc_CollectTopOr_rec( Abc_ObjNot(pObj), vSuper );
- Vec_PtrUniqify( vSuper, (int (*)())Abc_ObjCompareById );
+ Vec_PtrUniqify( vSuper, (int (*)(const void *, const void *))Abc_ObjCompareById );
}
else
Vec_PtrPush( vSuper, Abc_ObjNot(pObj) );
@@ -858,6 +858,7 @@ Abc_Ntk_t * Abc_NtkFromMappedGia( Gia_Man_t * p, int fFindEnables, int fUseBuffs
Gia_LutForEachFanin( p, i, iFan, k )
Abc_ObjAddFanin( pObjNew, Abc_NtkObj(pNtkNew, Gia_ObjValue(Gia_ManObj(p, iFan))) );
pObjNew->pData = Abc_ObjHopFromGia( (Hop_Man_t *)pNtkNew->pManFunc, p, i, vReflect );
+ pObjNew->fPersist = Gia_ObjLutIsMux(p, i) && Gia_ObjLutSize(p, i) == 3;
pObj->Value = Abc_ObjId( pObjNew );
}
Vec_PtrFree( vReflect );
@@ -1650,6 +1651,7 @@ Abc_Ntk_t * Abc_NtkDChoice( Abc_Ntk_t * pNtk, int fBalance, int fUpdateLevel, in
***********************************************************************/
Abc_Ntk_t * Abc_NtkDch( Abc_Ntk_t * pNtk, Dch_Pars_t * pPars )
{
+ extern Aig_Man_t * Dar_ManChoiceNew( Aig_Man_t * pAig, Dch_Pars_t * pPars );
extern Gia_Man_t * Dar_NewChoiceSynthesis( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fPower, int fLightSynth, int fVerbose );
extern Aig_Man_t * Cec_ComputeChoices( Gia_Man_t * pGia, Dch_Pars_t * pPars );
@@ -1661,23 +1663,28 @@ Abc_Ntk_t * Abc_NtkDch( Abc_Ntk_t * pNtk, Dch_Pars_t * pPars )
pMan = Abc_NtkToDar( pNtk, 0, 0 );
if ( pMan == NULL )
return NULL;
-clk = Abc_Clock();
- if ( pPars->fSynthesis )
- pGia = Dar_NewChoiceSynthesis( pMan, 1, 1, pPars->fPower, pPars->fLightSynth, pPars->fVerbose );
- else
+ if ( pPars->fUseNew )
+ pMan = Dar_ManChoiceNew( pMan, pPars );
+ else
{
- pGia = Gia_ManFromAig( pMan );
- Aig_ManStop( pMan );
- }
+clk = Abc_Clock();
+ if ( pPars->fSynthesis )
+ pGia = Dar_NewChoiceSynthesis( pMan, 1, 1, pPars->fPower, pPars->fLightSynth, pPars->fVerbose );
+ else
+ {
+ pGia = Gia_ManFromAig( pMan );
+ Aig_ManStop( pMan );
+ }
pPars->timeSynth = Abc_Clock() - clk;
- if ( pPars->fUseGia )
- pMan = Cec_ComputeChoices( pGia, pPars );
- else
- {
- pMan = Gia_ManToAigSkip( pGia, 3 );
- Gia_ManStop( pGia );
- pMan = Dch_ComputeChoices( pTemp = pMan, pPars );
- Aig_ManStop( pTemp );
+ if ( pPars->fUseGia )
+ pMan = Cec_ComputeChoices( pGia, pPars );
+ else
+ {
+ pMan = Gia_ManToAigSkip( pGia, 3 );
+ Gia_ManStop( pGia );
+ pMan = Dch_ComputeChoices( pTemp = pMan, pPars );
+ Aig_ManStop( pTemp );
+ }
}
pNtkAig = Abc_NtkFromDarChoices( pNtk, pMan );
Aig_ManStop( pMan );
diff --git a/src/base/abci/abcDress2.c b/src/base/abci/abcDress2.c
index 1b1eb9bf..e7adb41f 100644
--- a/src/base/abci/abcDress2.c
+++ b/src/base/abci/abcDress2.c
@@ -21,6 +21,7 @@
#include "base/abc/abc.h"
#include "aig/aig/aig.h"
#include "proof/dch/dch.h"
+#include "aig/gia/giaAig.h"
ABC_NAMESPACE_IMPL_START
@@ -274,6 +275,32 @@ Vec_Ptr_t * Abc_NtkDressMapIds( Aig_Man_t * pMiter, Abc_Ntk_t * pNtk1, Abc_Ntk_t
/**Function*************************************************************
+ Synopsis [Alternative way to compute equivalences.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Dch_ComputeEquivalences2( Aig_Man_t * pMiter, Dch_Pars_t * pPars )
+{
+ extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose );
+ Gia_Man_t * pGia = Gia_ManFromAigSimple(pMiter);
+ Gia_Man_t * pNew = Cec4_ManSimulateTest3( pGia, pPars->nBTLimit, pPars->fVerbose );
+ int i, k;
+ ABC_FREE( pMiter->pReprs );
+ pMiter->pReprs = ABC_CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(pMiter) );
+ Gia_ManForEachClass( pGia, i )
+ Gia_ClassForEachObj1( pGia, i, k )
+ pMiter->pReprs[k] = Aig_ManObj( pMiter, i );
+ Gia_ManStop( pGia );
+ Gia_ManStop( pNew );
+}
+
+/**Function*************************************************************
+
Synopsis [Computes equivalence classes of objects in pNtk1 and pNtk2.]
Description [Returns the array (Vec_Ptr_t) of integer arrays (Vec_Int_t).
@@ -307,7 +334,7 @@ Vec_Ptr_t * Abc_NtkDressComputeEquivs( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int
pPars->nBTLimit = nConflictLimit;
pPars->fVerbose = fVerbose;
// perform SAT sweeping
- Dch_ComputeEquivalences( pMiter, pPars );
+ Dch_ComputeEquivalences2( pMiter, pPars );
// now, pMiter is annotated with the equivl class info
// convert this info into the resulting array
vRes = Abc_NtkDressMapIds( pMiter, pNtk1, pNtk2 );
diff --git a/src/base/abci/abcEspresso.c b/src/base/abci/abcEspresso.c
index 2da389da..9296b1e7 100644
--- a/src/base/abci/abcEspresso.c
+++ b/src/base/abci/abcEspresso.c
@@ -58,7 +58,7 @@ void Abc_NtkEspresso( Abc_Ntk_t * pNtk, int fVerbose )
Abc_NtkMapToSop(pNtk);
else if ( Abc_NtkHasBdd(pNtk) )
{
- if ( !Abc_NtkBddToSop(pNtk, -1, ABC_INFINITY) )
+ if ( !Abc_NtkBddToSop(pNtk, -1, ABC_INFINITY, 1) )
{
printf( "Abc_NtkEspresso(): Converting to SOPs has failed.\n" );
return;
diff --git a/src/base/abci/abcExtract.c b/src/base/abci/abcExtract.c
index 1b247841..870bc7dc 100644
--- a/src/base/abci/abcExtract.c
+++ b/src/base/abci/abcExtract.c
@@ -19,6 +19,7 @@
***********************************************************************/
#include "base/abc/abc.h"
+#include "aig/gia/giaAig.h"
ABC_NAMESPACE_IMPL_START
@@ -741,7 +742,21 @@ Abc_Ntk_t * Abc_NtkShareXor( Abc_Ntk_t * pNtk, int nMultiSize, int fAnd, int fVe
Abc_ShaManStop( p );
return pNtkNew;
}
-
+Gia_Man_t * Abc_NtkShareXorGia( Gia_Man_t * p, int nMultiSize, int fAnd, int fVerbose )
+{
+ extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters );
+ extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan );
+ Aig_Man_t * pMan = Gia_ManToAig( p, 0 );
+ Abc_Ntk_t * pNtk = Abc_NtkFromAigPhase( pMan );
+ Abc_Ntk_t * pNtkNew = Abc_NtkShareXor( pNtk, nMultiSize, fAnd, fVerbose );
+ Aig_Man_t * pAig = Abc_NtkToDar( pNtkNew, 0, 0 );
+ Gia_Man_t * pNew = Gia_ManFromAig( pAig );
+ Abc_NtkDelete( pNtkNew );
+ Abc_NtkDelete( pNtk );
+ Aig_ManStop( pAig );
+ Aig_ManStop( pMan );
+ return pNew;
+}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/base/abci/abcFx.c b/src/base/abci/abcFx.c
index 60461a4a..487aee3c 100644
--- a/src/base/abci/abcFx.c
+++ b/src/base/abci/abcFx.c
@@ -201,7 +201,7 @@ void Abc_NtkFxInsert( Abc_Ntk_t * pNtk, Vec_Wec_t * vCubes )
// quit if nothing changes
if ( iNodeMax < Abc_NtkObjNumMax(pNtk) )
{
- printf( "The network is unchanged by fast extract.\n" );
+ //printf( "The network is unchanged by fast extract.\n" );
return;
}
// create new nodes
diff --git a/src/base/abci/abcFxu.c b/src/base/abci/abcFxu.c
index 8da306bf..99b3a5eb 100644
--- a/src/base/abci/abcFxu.c
+++ b/src/base/abci/abcFxu.c
@@ -88,7 +88,7 @@ int Abc_NtkFastExtract( Abc_Ntk_t * pNtk, Fxu_Data_t * p )
if ( Abc_NtkIsSopLogic(pNtk) )
{ // to make sure the SOPs are SCC-free
// Abc_NtkSopToBdd(pNtk);
-// Abc_NtkBddToSop(pNtk);
+// Abc_NtkBddToSop(pNtk, 1);
}
// get the network in the SOP form
if ( !Abc_NtkToSop(pNtk, -1, ABC_INFINITY) )
diff --git a/src/base/abci/abcIf.c b/src/base/abci/abcIf.c
index ab88c5e2..491e2c14 100644
--- a/src/base/abci/abcIf.c
+++ b/src/base/abci/abcIf.c
@@ -230,9 +230,13 @@ If_Man_t * Abc_NtkToIf( Abc_Ntk_t * pNtk, If_Par_t * pPars )
Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)If_ManConst1( pIfMan );
Abc_NtkForEachCi( pNtk, pNode, i )
{
- pNode->pCopy = (Abc_Obj_t *)If_ManCreateCi( pIfMan );
+ If_Obj_t * pIfObj = If_ManCreateCi( pIfMan );
+ pNode->pCopy = (Abc_Obj_t *)pIfObj;
// transfer logic level information
Abc_ObjIfCopy(pNode)->Level = pNode->Level;
+ // mark the largest level
+ if ( pIfMan->nLevelMax < (int)pIfObj->Level )
+ pIfMan->nLevelMax = (int)pIfObj->Level;
}
// load the AIG into the mapper
diff --git a/src/base/abci/abcIvy.c b/src/base/abci/abcIvy.c
index 5dc125d0..c680f85a 100644
--- a/src/base/abci/abcIvy.c
+++ b/src/base/abci/abcIvy.c
@@ -91,7 +91,7 @@ Ivy_Man_t * Abc_NtkIvyBefore( Abc_Ntk_t * pNtk, int fSeq, int fUseDc )
assert( !Abc_NtkIsNetlist(pNtk) );
if ( Abc_NtkIsBddLogic(pNtk) )
{
- if ( !Abc_NtkBddToSop(pNtk, -1, ABC_INFINITY) )
+ if ( !Abc_NtkBddToSop(pNtk, -1, ABC_INFINITY, 1) )
{
printf( "Abc_NtkIvyBefore(): Converting to SOPs has failed.\n" );
return NULL;
@@ -601,7 +601,7 @@ int Abc_NtkIvyProve( Abc_Ntk_t ** ppNtk, void * pPars )
printf( "Attempting BDDs with node limit %d ...\n", pParams->nBddSizeLimit );
fflush( stdout );
}
- pNtk = Abc_NtkCollapse( pNtkTemp = pNtk, pParams->nBddSizeLimit, 0, pParams->fBddReorder, 0, 0 );
+ pNtk = Abc_NtkCollapse( pNtkTemp = pNtk, pParams->nBddSizeLimit, 0, pParams->fBddReorder, 0, 0, 0 );
if ( pNtk )
{
Abc_NtkDelete( pNtkTemp );
@@ -640,7 +640,7 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
assert( !Abc_NtkIsNetlist(pNtk) );
if ( Abc_NtkIsBddLogic(pNtk) )
{
- if ( !Abc_NtkBddToSop(pNtk, -1, ABC_INFINITY) )
+ if ( !Abc_NtkBddToSop(pNtk, -1, ABC_INFINITY, 1) )
{
Vec_IntFree( vInit );
printf( "Abc_NtkIvy(): Converting to SOPs has failed.\n" );
diff --git a/src/base/abci/abcLut.c b/src/base/abci/abcLut.c
index edc2b7de..49c74e6b 100644
--- a/src/base/abci/abcLut.c
+++ b/src/base/abci/abcLut.c
@@ -783,6 +783,166 @@ int Abc_NodeDecomposeStep( Abc_ManScl_t * p )
return 1;
}
+/**Function*************************************************************
+
+ Synopsis [Performs specialized mapping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static word s__Truths6[6] = {
+ ABC_CONST(0xAAAAAAAAAAAAAAAA),
+ ABC_CONST(0xCCCCCCCCCCCCCCCC),
+ ABC_CONST(0xF0F0F0F0F0F0F0F0),
+ ABC_CONST(0xFF00FF00FF00FF00),
+ ABC_CONST(0xFFFF0000FFFF0000),
+ ABC_CONST(0xFFFFFFFF00000000)
+};
+word Abc_ObjComputeTruth( Abc_Obj_t * pObj, Vec_Int_t * vSupp )
+{
+ int Index; word t0, t1, tc;
+ assert( Vec_IntSize(vSupp) <= 6 );
+ if ( (Index = Vec_IntFind(vSupp, Abc_ObjId(pObj))) >= 0 )
+ return s__Truths6[Index];
+ assert( Abc_ObjIsNode(pObj) );
+ if ( Abc_ObjFaninNum(pObj) == 0 )
+ return Abc_NodeIsConst0(pObj) ? (word)0 : ~(word)0;
+ assert( Abc_ObjFaninNum(pObj) == 3 );
+ t0 = Abc_ObjComputeTruth( Abc_ObjFanin(pObj, 2), vSupp );
+ t1 = Abc_ObjComputeTruth( Abc_ObjFanin(pObj, 1), vSupp );
+ tc = Abc_ObjComputeTruth( Abc_ObjFanin(pObj, 0), vSupp );
+ return (tc & t1) | (~tc & t0);
+}
+Abc_Obj_t * Abc_NtkSpecialMap_rec( Abc_Ntk_t * pNew, Abc_Obj_t * pObj, Vec_Wec_t * vSupps, Vec_Int_t * vCover )
+{
+ if ( pObj->pCopy )
+ return pObj->pCopy;
+ if ( Abc_ObjFaninNum(pObj) == 0 )
+ return NULL;
+ assert( Abc_ObjFaninNum(pObj) == 3 );
+ if ( pObj->fMarkA || pObj->fMarkB )
+ {
+ Abc_Obj_t * pFan0 = Abc_NtkSpecialMap_rec( pNew, Abc_ObjFanin(pObj, 2), vSupps, vCover );
+ Abc_Obj_t * pFan1 = Abc_NtkSpecialMap_rec( pNew, Abc_ObjFanin(pObj, 1), vSupps, vCover );
+ Abc_Obj_t * pFanC = Abc_NtkSpecialMap_rec( pNew, Abc_ObjFanin(pObj, 0), vSupps, vCover );
+ if ( pFan0 == NULL )
+ pFan0 = Abc_NodeIsConst0(Abc_ObjFanin(pObj, 2)) ? Abc_NtkCreateNodeConst0(pNew) : Abc_NtkCreateNodeConst1(pNew);
+ if ( pFan1 == NULL )
+ pFan1 = Abc_NodeIsConst0(Abc_ObjFanin(pObj, 1)) ? Abc_NtkCreateNodeConst0(pNew) : Abc_NtkCreateNodeConst1(pNew);
+ pObj->pCopy = Abc_NtkCreateNodeMux( pNew, pFanC, pFan1, pFan0 );
+ pObj->pCopy->fMarkA = pObj->fMarkA;
+ pObj->pCopy->fMarkB = pObj->fMarkB;
+ }
+ else
+ {
+ Abc_Obj_t * pTemp; int i; word Truth;
+ Vec_Int_t * vSupp = Vec_WecEntry( vSupps, Abc_ObjId(pObj) );
+ Abc_NtkForEachObjVec( vSupp, pObj->pNtk, pTemp, i )
+ Abc_NtkSpecialMap_rec( pNew, pTemp, vSupps, vCover );
+ pObj->pCopy = Abc_NtkCreateNode( pNew );
+ Abc_NtkForEachObjVec( vSupp, pObj->pNtk, pTemp, i )
+ Abc_ObjAddFanin( pObj->pCopy, pTemp->pCopy );
+ Truth = Abc_ObjComputeTruth( pObj, vSupp );
+ pObj->pCopy->pData = Abc_SopCreateFromTruthIsop( (Mem_Flex_t *)pNew->pManFunc, Vec_IntSize(vSupp), &Truth, vCover );
+ assert( Abc_SopGetVarNum((char *)pObj->pCopy->pData) == Vec_IntSize(vSupp) );
+ }
+ return pObj->pCopy;
+}
+Abc_Ntk_t * Abc_NtkSpecialMapping( Abc_Ntk_t * pNtk, int fVerbose )
+{
+ Abc_Ntk_t * pNtkNew;
+ Vec_Int_t * vCover = Vec_IntAlloc( 1 << 16 );
+ Vec_Wec_t * vSupps = Vec_WecStart( Abc_NtkObjNumMax(pNtk) );
+ Abc_Obj_t * pObj, * pFan0, * pFan1, * pFanC; int i, Count[2] = {0};
+ Abc_NtkForEachCi( pNtk, pObj, i )
+ Vec_IntPush( Vec_WecEntry(vSupps, i), i );
+ Abc_NtkForEachNode( pNtk, pObj, i )
+ {
+ Vec_Int_t * vSupp = Vec_WecEntry(vSupps, i);
+ if ( Abc_ObjFaninNum(pObj) == 0 )
+ continue;
+ assert( Abc_ObjFaninNum(pObj) == 3 );
+ pFan0 = Abc_ObjFanin( pObj, 2 );
+ pFan1 = Abc_ObjFanin( pObj, 1 );
+ pFanC = Abc_ObjFanin0( pObj );
+ assert( Abc_ObjIsCi(pFanC) );
+ if ( pFan0->fMarkA && pFan1->fMarkA )
+ {
+ pObj->fMarkB = 1;
+ Vec_IntPush( vSupp, Abc_ObjId(pObj) );
+ continue;
+ }
+ Vec_IntTwoMerge2( Vec_WecEntry(vSupps, Abc_ObjId(pFan0)), Vec_WecEntry(vSupps, Abc_ObjId(pFan1)), vSupp );
+ assert( Vec_IntFind(vSupp, Abc_ObjId(pFanC)) == -1 );
+ Vec_IntPushOrder( vSupp, Abc_ObjId(pFanC) );
+ if ( Vec_IntSize(vSupp) <= 6 )
+ continue;
+ Vec_IntClear( vSupp );
+ if ( !pFan0->fMarkA && !pFan1->fMarkA )
+ {
+ pObj->fMarkA = 1;
+ Vec_IntPush( vSupp, Abc_ObjId(pObj) );
+ }
+ else
+ {
+ Vec_IntPushOrder( vSupp, Abc_ObjId(pFan0) );
+ Vec_IntPushOrder( vSupp, Abc_ObjId(pFan1) );
+ Vec_IntPushOrder( vSupp, Abc_ObjId(pFanC) );
+ }
+ }
+
+ if ( fVerbose )
+ {
+ Abc_NtkForEachNode( pNtk, pObj, i )
+ {
+ printf( "Node %4d : ", i );
+ if ( pObj->fMarkA )
+ printf( " MarkA " );
+ else
+ printf( " " );
+ if ( pObj->fMarkB )
+ printf( " MarkB " );
+ else
+ printf( " " );
+ Vec_IntPrint( Vec_WecEntry(vSupps, i) );
+ }
+ }
+
+ Abc_NtkCleanCopy( pNtk );
+ pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
+ Abc_NtkForEachCo( pNtk, pObj, i )
+ if ( Abc_ObjFaninNum(Abc_ObjFanin0(pObj)) == 0 )
+ Abc_ObjFanin0(pObj)->pCopy = Abc_NodeIsConst0(Abc_ObjFanin0(pObj)) ? Abc_NtkCreateNodeConst0(pNtkNew) : Abc_NtkCreateNodeConst1(pNtkNew);
+ else
+ Abc_NtkSpecialMap_rec( pNtkNew, Abc_ObjFanin0(pObj), vSupps, vCover );
+ Abc_NtkFinalize( pNtk, pNtkNew );
+ Abc_NtkCleanMarkAB( pNtk );
+ Vec_WecFree( vSupps );
+ Vec_IntFree( vCover );
+
+ Abc_NtkForEachNode( pNtkNew, pObj, i )
+ {
+ Count[0] += pObj->fMarkA,
+ Count[1] += pObj->fMarkB;
+ pObj->fPersist = pObj->fMarkA | pObj->fMarkB;
+ pObj->fMarkA = pObj->fMarkB = 0;
+ }
+ //printf( "Total = %3d. Nodes = %3d. MarkA = %3d. MarkB = %3d.\n", Abc_NtkNodeNum(pNtkNew),
+ // Abc_NtkNodeNum(pNtkNew) - Count[0] - Count[1], Count[0], Count[1] );
+
+ if ( !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkSpecialMapping: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/abci/abcLutmin.c b/src/base/abci/abcLutmin.c
index 2ac44060..7bac74bf 100644
--- a/src/base/abci/abcLutmin.c
+++ b/src/base/abci/abcLutmin.c
@@ -610,7 +610,7 @@ Abc_Obj_t * Abc_NtkBddDecompose( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, int nLu
// cofactor w.r.t. the bound set variables
vCofs = Abc_NtkBddCofactors( dd, (DdNode *)pNode->pData, nLutSize );
vUniq = Vec_PtrDup( vCofs );
- Vec_PtrUniqify( vUniq, (int (*)())Vec_PtrSortCompare );
+ Vec_PtrUniqify( vUniq, (int (*)(const void *, const void *))Vec_PtrSortCompare );
// only perform decomposition with it is support reduring with two less vars
if( Vec_PtrSize(vUniq) > (1 << (nLutSize-2)) )
{
@@ -739,7 +739,7 @@ Abc_Ntk_t * Abc_NtkLutmin( Abc_Ntk_t * pNtkInit, int nLutSize, int fVerbose )
else
pNtkNew = Abc_NtkStrash( pNtkInit, 0, 1, 0 );
// collapse the network
- pNtkNew = Abc_NtkCollapse( pTemp = pNtkNew, 10000, 0, 1, 0, 0 );
+ pNtkNew = Abc_NtkCollapse( pTemp = pNtkNew, 10000, 0, 1, 0, 0, 0 );
Abc_NtkDelete( pTemp );
if ( pNtkNew == NULL )
return NULL;
diff --git a/src/base/abci/abcMap.c b/src/base/abci/abcMap.c
index 5389b669..8f5e4ee2 100644
--- a/src/base/abci/abcMap.c
+++ b/src/base/abci/abcMap.c
@@ -32,8 +32,8 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-static Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, float * pSwitching, int fVerbose );
-static Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk, int fUseBuffs );
+extern Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, float * pSwitching, int fVerbose );
+extern Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk, int fUseBuffs );
static Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase );
static Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase );
@@ -612,7 +612,7 @@ Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
// duplicate the network
pNtkNew2 = Abc_NtkDup( pNtk );
pNtkNew = Abc_NtkMulti( pNtkNew2, 0, 20, 0, 0, 1, 0 );
- if ( !Abc_NtkBddToSop( pNtkNew, -1, ABC_INFINITY ) )
+ if ( !Abc_NtkBddToSop( pNtkNew, -1, ABC_INFINITY, 1 ) )
{
printf( "Abc_NtkFromMapSuperChoice(): Converting to SOPs has failed.\n" );
return NULL;
diff --git a/src/base/abci/abcMffc.c b/src/base/abci/abcMffc.c
index 1d64df5c..55f39252 100644
--- a/src/base/abci/abcMffc.c
+++ b/src/base/abci/abcMffc.c
@@ -1141,7 +1141,7 @@ Vec_Ptr_t * Abc_NktMffcServer( Abc_Ntk_t * pNtk, int nInMax, int nOutMax )
// sort by their MFFC size
Vec_PtrForEachEntry( Abc_Obj_t *, vPivots, pObj, i )
pObj->iTemp = Vec_IntSize((Vec_Int_t *)Vec_PtrEntry(vVolumes, Abc_ObjId(pObj)));
- Vec_PtrSort( vPivots, (int (*)(void))Abc_NodeCompareVolumeDecrease );
+ Vec_PtrSort( vPivots, (int (*)(const void *, const void *))Abc_NodeCompareVolumeDecrease );
// create marks
vMarks = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
Vec_PtrForEachEntry( Abc_Obj_t *, vPivots, pObj, i )
diff --git a/src/base/abci/abcMiter.c b/src/base/abci/abcMiter.c
index 81b032d4..6086fc61 100644
--- a/src/base/abci/abcMiter.c
+++ b/src/base/abci/abcMiter.c
@@ -863,7 +863,7 @@ void Abc_NtkAddFrame( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFrame )
{
int fVerbose = 0;
int NodeBef = Abc_NtkNodeNum(pNtkFrames);
- char Buffer[10];
+ char Buffer[16];
Abc_Obj_t * pNode, * pLatch;
int i;
// create the prefix to be added to the node names
@@ -1008,7 +1008,7 @@ Abc_Ntk_t * Abc_NtkFrames2( Abc_Ntk_t * pNtk, int nFrames, int fInitial, AddFram
void Abc_NtkAddFrame2( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFrame, Vec_Ptr_t * vNodes, AddFrameMapping addFrameMapping, void* arg )
{
/*
- char Buffer[10];
+ char Buffer[16];
Abc_Obj_t * pNode, * pNodeNew, * pLatch;
Abc_Obj_t * pConst1, * pConst1New;
int i;
diff --git a/src/base/abci/abcNpnSave.c b/src/base/abci/abcNpnSave.c
index 0e2d13d5..3dd97432 100644
--- a/src/base/abci/abcNpnSave.c
+++ b/src/base/abci/abcNpnSave.c
@@ -564,7 +564,7 @@ void Npn_ManWrite( Npn_Man_t * p, char * pFileName )
for ( i = 0; i < p->nBins; i++ )
for ( pEntry = Npn_ManObj(p, p->pBins[i]); pEntry; pEntry = Npn_ManObj(p, pEntry->iNext) )
Vec_PtrPush( vEntries, pEntry );
- Vec_PtrSort( vEntries, (int (*)())Npn_ManCompareEntries );
+ Vec_PtrSort( vEntries, (int (*)(const void *, const void *))Npn_ManCompareEntries );
Vec_PtrForEachEntry( Npn_Obj_t *, vEntries, pEntry, i )
{
Extra_PrintHexadecimal( pFile, (unsigned *)&pEntry->uTruth, 6 );
diff --git a/src/base/abci/abcNtbdd.c b/src/base/abci/abcNtbdd.c
index d3a19d83..cbf4bbb8 100644
--- a/src/base/abci/abcNtbdd.c
+++ b/src/base/abci/abcNtbdd.c
@@ -34,7 +34,7 @@ ABC_NAMESPACE_IMPL_START
#ifdef ABC_USE_CUDD
-static int Abc_NtkBddToMuxesPerformGlo( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, int Limit );
+ int Abc_NtkBddToMuxesPerformGlo( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, int Limit, int fReorder, int fUseAdd );
static void Abc_NtkBddToMuxesPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
static Abc_Obj_t * Abc_NodeBddToMuxes( Abc_Obj_t * pNodeOld, Abc_Ntk_t * pNtkNew );
static Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t * pNtkNew, st__table * tBdd2Node );
@@ -129,13 +129,13 @@ Abc_Ntk_t * Abc_NtkDeriveFromBdd( void * dd0, void * bFunc, char * pNamePo, Vec_
SeeAlso []
***********************************************************************/
-Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk, int fGlobal, int Limit )
+Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk, int fGlobal, int Limit, int fUseAdd )
{
Abc_Ntk_t * pNtkNew;
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
if ( fGlobal )
{
- if ( !Abc_NtkBddToMuxesPerformGlo( pNtk, pNtkNew, Limit ) )
+ if ( !Abc_NtkBddToMuxesPerformGlo( pNtk, pNtkNew, Limit, 0, fUseAdd ) )
{
Abc_NtkDelete( pNtkNew );
return NULL;
@@ -237,8 +237,10 @@ Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t *
{
Abc_Obj_t * pNodeNew, * pNodeNew0, * pNodeNew1, * pNodeNewC;
assert( !Cudd_IsComplement(bFunc) );
- if ( bFunc == b1 )
+ if ( bFunc == b1 || bFunc == a1 )
return Abc_NtkCreateNodeConst1(pNtkNew);
+ if ( bFunc == a0 )
+ return Abc_NtkCreateNodeConst0(pNtkNew);
if ( st__lookup( tBdd2Node, (char *)bFunc, (char **)&pNodeNew ) )
return pNodeNew;
// solve for the children nodes
@@ -265,13 +267,14 @@ Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t *
SeeAlso []
***********************************************************************/
-int Abc_NtkBddToMuxesPerformGlo( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, int Limit )
+int Abc_NtkBddToMuxesPerformGlo( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, int Limit, int fReorder, int fUseAdd )
{
DdManager * dd;
+ Vec_Ptr_t * vAdds = fUseAdd ? Vec_PtrAlloc(100) : NULL;
Abc_Obj_t * pObj, * pObjNew; int i;
st__table * tBdd2Node;
assert( Abc_NtkIsStrash(pNtk) );
- dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, Limit, 1, 1, 0, 0 );
+ dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, Limit, 1, fReorder, 0, 0 );
if ( dd == NULL )
{
printf( "Construction of global BDDs has failed.\n" );
@@ -286,16 +289,32 @@ int Abc_NtkBddToMuxesPerformGlo( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, int Limi
// complement the global functions
Abc_NtkForEachCo( pNtk, pObj, i )
{
- DdNode * bFunc = Abc_ObjGlobalBdd(pObj);
- pObjNew = Abc_NodeBddToMuxes_rec( dd, Cudd_Regular(bFunc), pNtkNew, tBdd2Node );
- if ( Cudd_IsComplement(bFunc) )
- pObjNew = Abc_NtkCreateNodeInv( pNtkNew, pObjNew );
+ DdNode * bFunc = (DdNode *)Abc_ObjGlobalBdd(pObj);
+ if ( fUseAdd )
+ {
+ DdNode * aFunc = Cudd_BddToAdd( dd, bFunc ); Cudd_Ref( aFunc );
+ pObjNew = Abc_NodeBddToMuxes_rec( dd, aFunc, pNtkNew, tBdd2Node );
+ Vec_PtrPush( vAdds, aFunc );
+ }
+ else
+ {
+ pObjNew = Abc_NodeBddToMuxes_rec( dd, Cudd_Regular(bFunc), pNtkNew, tBdd2Node );
+ if ( Cudd_IsComplement(bFunc) )
+ pObjNew = Abc_NtkCreateNodeInv( pNtkNew, pObjNew );
+ }
Abc_ObjAddFanin( pObj->pCopy, pObjNew );
}
// cleanup
st__free_table( tBdd2Node );
Abc_NtkFreeGlobalBdds( pNtk, 0 );
+ if ( vAdds )
+ {
+ DdNode * aTemp;
+ Vec_PtrForEachEntry( DdNode *, vAdds, aTemp, i )
+ Cudd_RecursiveDeref( dd, aTemp );
+ Vec_PtrFree( vAdds );
+ }
Extra_StopManager( dd );
Abc_NtkCleanCopy( pNtk );
return 1;
@@ -410,6 +429,7 @@ void * Abc_NtkBuildGlobalBdds( Abc_Ntk_t * pNtk, int nBddSizeMax, int fDropInter
if ( fReorder )
{
Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 1 );
+// Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 1 );
Cudd_AutodynDisable( dd );
}
// Cudd_PrintInfo( dd, stdout );
@@ -662,7 +682,7 @@ ABC_PRT( "Time", Abc_Clock() - clk );
#else
double Abc_NtkSpacePercentage( Abc_Obj_t * pNode ) { return 0.0; }
-Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk, int fGlobal, int Limit ) { return NULL; }
+Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk, int fGlobal, int Limit, int fUseAdd ) { return NULL; }
#endif
diff --git a/src/base/abci/abcPrint.c b/src/base/abci/abcPrint.c
index ad5fba91..44d5c2c3 100644
--- a/src/base/abci/abcPrint.c
+++ b/src/base/abci/abcPrint.c
@@ -453,6 +453,15 @@ void Abc_NtkPrintStats( Abc_Ntk_t * pNtk, int fFactored, int fSaveBest, int fDum
// if ( Abc_NtkHasSop(pNtk) )
// printf( "The total number of cube pairs = %d.\n", Abc_NtkGetCubePairNum(pNtk) );
+ if ( 0 )
+ {
+ FILE * pTable = fopen( "stats.txt", "a+" );
+ if ( Abc_NtkIsStrash(pNtk) )
+ fprintf( pTable, "%s ", pNtk->pName );
+ fprintf( pTable, "%d ", Abc_NtkNodeNum(pNtk) );
+ fclose( pTable );
+ }
+
fflush( stdout );
if ( pNtk->pExdc )
Abc_NtkPrintStats( pNtk->pExdc, fFactored, fSaveBest, fDumpResult, fUseLutLib, fPrintMuxes, fPower, fGlitch, fSkipBuf, fSkipSmall, fPrintMem );
@@ -1399,7 +1408,7 @@ void Abc_NtkPrintGates( Abc_Ntk_t * pNtk, int fUseLibrary, int fUpdateProfile )
// transform logic functions from BDD to SOP
if ( (fHasBdds = Abc_NtkIsBddLogic(pNtk)) )
{
- if ( !Abc_NtkBddToSop(pNtk, -1, ABC_INFINITY) )
+ if ( !Abc_NtkBddToSop(pNtk, -1, ABC_INFINITY, 1) )
{
printf( "Abc_NtkPrintGates(): Converting to SOPs has failed.\n" );
return;
diff --git a/src/base/abci/abcProve.c b/src/base/abci/abcProve.c
index 03722926..b14c0827 100644
--- a/src/base/abci/abcProve.c
+++ b/src/base/abci/abcProve.c
@@ -201,7 +201,7 @@ int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pPars )
fflush( stdout );
}
clk = Abc_Clock();
- pNtk = Abc_NtkCollapse( pNtkTemp = pNtk, pParams->nBddSizeLimit, 0, pParams->fBddReorder, 0, 0 );
+ pNtk = Abc_NtkCollapse( pNtkTemp = pNtk, pParams->nBddSizeLimit, 0, pParams->fBddReorder, 0, 0, 0 );
if ( pNtk )
{
Abc_NtkDelete( pNtkTemp );
diff --git a/src/base/abci/abcReorder.c b/src/base/abci/abcReorder.c
index cf8759c7..8557be1e 100644
--- a/src/base/abci/abcReorder.c
+++ b/src/base/abci/abcReorder.c
@@ -84,7 +84,7 @@ void Abc_NtkBddReorder( Abc_Ntk_t * pNtk, int fVerbose )
reo_man * p;
Abc_Obj_t * pNode;
int i;
- Abc_NtkRemoveDupFanins( pNtk );
+ //Abc_NtkRemoveDupFanins( pNtk );
Abc_NtkMinimumBase( pNtk );
p = Extra_ReorderInit( Abc_NtkGetFaninMax(pNtk), 100 );
Abc_NtkForEachNode( pNtk, pNode, i )
diff --git a/src/base/abci/abcStrash.c b/src/base/abci/abcStrash.c
index e4868d7e..d54957a6 100644
--- a/src/base/abci/abcStrash.c
+++ b/src/base/abci/abcStrash.c
@@ -548,25 +548,27 @@ Abc_Obj_t * Abc_NtkTopmost_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, int Leve
Abc_Ntk_t * Abc_NtkTopmost( Abc_Ntk_t * pNtk, int nLevels )
{
Abc_Ntk_t * pNtkNew;
- Abc_Obj_t * pObjNew, * pObjPo;
- int LevelCut;
+ Abc_Obj_t * pObjNew, * pObj;
+ int LevelCut, i;
assert( Abc_NtkIsStrash(pNtk) );
- assert( Abc_NtkCoNum(pNtk) == 1 );
// get the cutoff level
LevelCut = Abc_MaxInt( 0, Abc_AigLevel(pNtk) - nLevels );
// start the network
pNtkNew = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 );
pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
- Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
// create PIs below the cut and nodes above the cut
Abc_NtkCleanCopy( pNtk );
- pObjNew = Abc_NtkTopmost_rec( pNtkNew, Abc_ObjFanin0(Abc_NtkPo(pNtk, 0)), LevelCut );
- pObjNew = Abc_ObjNotCond( pObjNew, Abc_ObjFaninC0(Abc_NtkPo(pNtk, 0)) );
+ Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
+ Abc_NtkForEachCo( pNtk, pObj, i )
+ {
+ pObjNew = Abc_NtkTopmost_rec( pNtkNew, Abc_ObjFanin0(pObj), LevelCut );
+ pObjNew = Abc_ObjNotCond( pObjNew, Abc_ObjFaninC0(pObj) );
+ Abc_ObjAddFanin( (pObj->pCopy = Abc_NtkCreatePo(pNtkNew)), pObjNew );
+ }
// add the PO node and name
- pObjPo = Abc_NtkCreatePo(pNtkNew);
- Abc_ObjAddFanin( pObjPo, pObjNew );
Abc_NtkAddDummyPiNames( pNtkNew );
- Abc_ObjAssignName( pObjPo, Abc_ObjName(Abc_NtkPo(pNtk, 0)), NULL );
+ Abc_NtkForEachCo( pNtk, pObj, i )
+ Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(pObj), NULL );
// make sure everything is okay
if ( !Abc_NtkCheck( pNtkNew ) )
{
@@ -578,6 +580,74 @@ Abc_Ntk_t * Abc_NtkTopmost( Abc_Ntk_t * pNtk, int nLevels )
}
+/**Function*************************************************************
+
+ Synopsis [Copies the bottommost levels of the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NtkBottommost_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, int LevelCut )
+{
+ assert( !Abc_ObjIsComplement(pNode) );
+ if ( pNode->pCopy )
+ return pNode->pCopy;
+ Abc_NtkBottommost_rec( pNtkNew, Abc_ObjFanin0(pNode), LevelCut );
+ Abc_NtkBottommost_rec( pNtkNew, Abc_ObjFanin1(pNode), LevelCut );
+ if ( pNode->Level > (unsigned)LevelCut )
+ return NULL;
+ return pNode->pCopy = Abc_AigAnd( (Abc_Aig_t *)pNtkNew->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Copies the topmost levels of the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkBottommost( Abc_Ntk_t * pNtk, int nLevels )
+{
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pObj, * pObjNew;
+ int i;
+ assert( Abc_NtkIsStrash(pNtk) );
+ assert( nLevels >= 0 );
+ // start the network
+ pNtkNew = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 );
+ pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
+ // create PIs below the cut and nodes above the cut
+ Abc_NtkCleanCopy( pNtk );
+ Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
+ Abc_NtkForEachCi( pNtk, pObj, i )
+ pObj->pCopy = Abc_NtkCreatePi( pNtkNew );
+ Abc_NtkForEachCo( pNtk, pObj, i )
+ Abc_NtkBottommost_rec( pNtkNew, Abc_ObjFanin0(pObj), nLevels );
+ // add POs to nodes without fanout
+ Abc_NtkForEachNode( pNtkNew, pObjNew, i )
+ if ( Abc_ObjFanoutNum(pObjNew) == 0 )
+ Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pObjNew );
+ Abc_NtkAddDummyPiNames( pNtkNew );
+ Abc_NtkAddDummyPoNames( pNtkNew );
+ // make sure everything is okay
+ if ( !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkBottommost: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+
/**Function*************************************************************
@@ -642,7 +712,7 @@ Vec_Ptr_t * Abc_NodeGetSuper( Abc_Obj_t * pNode )
Vec_PtrFree( vSuper );
vSuper = vFront;
// uniquify and return the frontier
- Vec_PtrUniqify( vSuper, (int (*)())Vec_CompareNodeIds );
+ Vec_PtrUniqify( vSuper, (int (*)(const void *, const void *))Vec_CompareNodeIds );
return vSuper;
}
diff --git a/src/base/abci/abcSweep.c b/src/base/abci/abcSweep.c
index e970ac38..3306a6af 100644
--- a/src/base/abci/abcSweep.c
+++ b/src/base/abci/abcSweep.c
@@ -619,7 +619,7 @@ int Abc_NtkSweep( Abc_Ntk_t * pNtk, int fVerbose )
nNodesOld = Abc_NtkNodeNum(pNtk);
Abc_NtkCleanup( pNtk, 0 );
// prepare nodes for sweeping
- Abc_NtkRemoveDupFanins(pNtk);
+ //Abc_NtkRemoveDupFanins(pNtk);
Abc_NtkMinimumBase(pNtk);
// collect sweepable nodes
vNodes = Vec_PtrAlloc( 100 );
@@ -649,7 +649,7 @@ int Abc_NtkSweep( Abc_Ntk_t * pNtk, int fVerbose )
Abc_NodeComplementInput( pFanout, pNode );
Abc_ObjPatchFanin( pFanout, pNode, pDriver );
}
- Abc_NodeRemoveDupFanins( pFanout );
+ //Abc_NodeRemoveDupFanins( pFanout );
Abc_NodeMinimumBase( pFanout );
// check if the fanout should be added
if ( Abc_ObjFaninNum(pFanout) < 2 )
@@ -888,7 +888,7 @@ int Abc_NtkReplaceAutonomousLogic( Abc_Ntk_t * pNtk )
Vec_PtrPush( vNodes, pFanin );
}
}
- Vec_PtrUniqify( vNodes, (int (*)(void))Abc_ObjPointerCompare );
+ Vec_PtrUniqify( vNodes, (int (*)(const void *, const void *))Abc_ObjPointerCompare );
// replace these nodes by the PIs
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
{
diff --git a/src/base/abci/abcTiming.c b/src/base/abci/abcTiming.c
index ae0e7f45..84cda931 100644
--- a/src/base/abci/abcTiming.c
+++ b/src/base/abci/abcTiming.c
@@ -24,9 +24,11 @@
#include "base/main/main.h"
#include "map/mio/mio.h"
+
ABC_NAMESPACE_IMPL_START
+
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@@ -187,8 +189,9 @@ void Abc_NtkTimeSetDefaultRequired( Abc_Ntk_t * pNtk, float Rise, float Fall )
pNtk->pManTime->tReqDef.Rise = Rise;
pNtk->pManTime->tReqDef.Fall = Fall;
// set the required times for each output
- Abc_NtkForEachCo( pNtk, pObj, i )
- Abc_NtkTimeSetRequired( pNtk, Abc_ObjId(pObj), Rise, Fall );
+ Abc_NtkForEachCo( pNtk, pObj, i ){
+ Abc_NtkTimeSetRequired( pNtk, Abc_ObjId(pObj), Rise, Fall );
+ }
}
/**Function*************************************************************
@@ -206,6 +209,7 @@ void Abc_NtkTimeSetArrival( Abc_Ntk_t * pNtk, int ObjId, float Rise, float Fall
{
Vec_Ptr_t * vTimes;
Abc_Time_t * pTime;
+
if ( pNtk->pManTime == NULL )
pNtk->pManTime = Abc_ManTimeStart(pNtk);
Abc_ManTimeExpand( pNtk->pManTime, ObjId + 1, 1 );
@@ -214,6 +218,8 @@ void Abc_NtkTimeSetArrival( Abc_Ntk_t * pNtk, int ObjId, float Rise, float Fall
pTime = (Abc_Time_t *)vTimes->pArray[ObjId];
pTime->Rise = Rise;
pTime->Fall = Fall;
+
+
}
void Abc_NtkTimeSetRequired( Abc_Ntk_t * pNtk, int ObjId, float Rise, float Fall )
{
@@ -473,6 +479,7 @@ Abc_ManTime_t * Abc_ManTimeStart( Abc_Ntk_t * pNtk )
{
int fUseZeroDefaultOutputRequired = 1;
Abc_ManTime_t * p;
+ Abc_Time_t* pTime;
Abc_Obj_t * pObj; int i;
p = pNtk->pManTime = ABC_ALLOC( Abc_ManTime_t, 1 );
memset( p, 0, sizeof(Abc_ManTime_t) );
@@ -480,16 +487,49 @@ Abc_ManTime_t * Abc_ManTimeStart( Abc_Ntk_t * pNtk )
p->vReqs = Vec_PtrAlloc( 0 );
// set default default input=arrivals (assumed to be 0)
// set default default output-requireds (can be either 0 or +infinity, based on the flag)
- p->tReqDef.Rise = fUseZeroDefaultOutputRequired ? 0 : ABC_INFINITY;
- p->tReqDef.Fall = fUseZeroDefaultOutputRequired ? 0 : ABC_INFINITY;
+
// extend manager
Abc_ManTimeExpand( p, Abc_NtkObjNumMax(pNtk) + 1, 0 );
// set the default timing for CIs
- Abc_NtkForEachCi( pNtk, pObj, i )
- Abc_NtkTimeSetArrival( pNtk, Abc_ObjId(pObj), p->tArrDef.Rise, p->tArrDef.Rise );
- // set the default timing for COs
- Abc_NtkForEachCo( pNtk, pObj, i )
- Abc_NtkTimeSetRequired( pNtk, Abc_ObjId(pObj), p->tReqDef.Rise, p->tReqDef.Rise );
+ Abc_NtkForEachCi( pNtk, pObj, i ){
+
+ //get the constrained value, if there is one
+ Vec_Ptr_t * vTimes;
+ vTimes = pNtk->pManTime->vArrs;
+ pTime = (Abc_Time_t *)vTimes->pArray[Abc_ObjId(pObj)];
+ //unconstrained arrival defaults. Note that
+ //unconstrained value in vTimes set to -ABC_INFINITY.
+ if (pTime &&
+ (!(p-> tArrDef.Fall == -ABC_INFINITY ||
+ p-> tArrDef.Rise != -ABC_INFINITY ))
+ ){
+ p->tArrDef.Fall = pTime -> Fall;
+ p->tArrDef.Rise = pTime -> Rise;
+ }
+ else {
+ //use the default arrival time 0 (implicit in memset 0, above).
+ p->tArrDef.Rise = 0;
+ p->tArrDef.Fall = 0;
+ }
+ Abc_NtkTimeSetArrival( pNtk, Abc_ObjId(pObj), p->tArrDef.Rise, p->tArrDef.Rise );
+ }
+
+
+ Abc_NtkForEachCo( pNtk, pObj, i ){
+ Vec_Ptr_t * vTimes;
+ vTimes = pNtk->pManTime->vArrs;
+ pTime = (Abc_Time_t *)vTimes->pArray[Abc_ObjId(pObj)];
+ if (pTime){
+ p->tReqDef.Fall = pTime -> Fall;
+ p->tReqDef.Rise = pTime -> Rise;
+ }
+ else{
+ //use the default
+ p->tReqDef.Rise = fUseZeroDefaultOutputRequired ? 0 : ABC_INFINITY;
+ p->tReqDef.Fall = fUseZeroDefaultOutputRequired ? 0 : ABC_INFINITY;
+ }
+ Abc_NtkTimeSetRequired( pNtk, Abc_ObjId(pObj), p->tReqDef.Rise, p->tReqDef.Rise );
+ }
return p;
}
@@ -571,6 +611,8 @@ void Abc_ManTimeDup( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkNew )
pNtkNew->pManTime->tOutLoad = ABC_ALLOC( Abc_Time_t, Abc_NtkCiNum(pNtkOld) );
memcpy( pNtkNew->pManTime->tOutLoad, pNtkOld->pManTime->tOutLoad, sizeof(Abc_Time_t) * Abc_NtkCoNum(pNtkOld) );
}
+
+
}
/**Function*************************************************************
diff --git a/src/base/abci/abcUnreach.c b/src/base/abci/abcUnreach.c
index ae4bc84b..5a20e5d8 100644
--- a/src/base/abci/abcUnreach.c
+++ b/src/base/abci/abcUnreach.c
@@ -342,7 +342,7 @@ Abc_Ntk_t * Abc_NtkConstructExdc( DdManager * dd, Abc_Ntk_t * pNtk, DdNode * bUn
Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
// transform the network to the SOP representation
- if ( !Abc_NtkBddToSop( pNtkNew, -1, ABC_INFINITY ) )
+ if ( !Abc_NtkBddToSop( pNtkNew, -1, ABC_INFINITY, 1 ) )
{
printf( "Abc_NtkConstructExdc(): Converting to SOPs has failed.\n" );
return NULL;
diff --git a/src/base/abci/abcVerify.c b/src/base/abci/abcVerify.c
index 7199c529..f3e86746 100644
--- a/src/base/abci/abcVerify.c
+++ b/src/base/abci/abcVerify.c
@@ -781,6 +781,8 @@ void Abc_NtkVerifyReportError( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int * pMode
Abc_NtkForEachCi( pNtk1, pNode, i )
pNode->pCopy = (Abc_Obj_t *)(ABC_PTRINT_T)i;
// print the model
+ if ( Vec_PtrSize(vNodes) )
+ {
pNode = (Abc_Obj_t *)Vec_PtrEntry( vNodes, 0 );
if ( Abc_ObjIsCi(pNode) )
{
@@ -790,6 +792,7 @@ void Abc_NtkVerifyReportError( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int * pMode
printf( " %s=%d", Abc_ObjName(pNode), pModel[(int)(ABC_PTRINT_T)pNode->pCopy] );
}
}
+ }
printf( "\n" );
Vec_PtrFree( vNodes );
}
diff --git a/src/base/acb/acb.h b/src/base/acb/acb.h
index 9aed414c..0a188d0f 100644
--- a/src/base/acb/acb.h
+++ b/src/base/acb/acb.h
@@ -1019,6 +1019,12 @@ static inline void Acb_ManPrintStats( Acb_Man_t * p, int nModules, int fVerbose
extern Vec_Int_t * Acb_ObjCollectTfi( Acb_Ntk_t * p, int iObj, int fTerm );
extern Vec_Int_t * Acb_ObjCollectTfo( Acb_Ntk_t * p, int iObj, int fTerm );
+extern Vec_Int_t * Acb_ObjCollectTfiVec( Acb_Ntk_t * p, Vec_Int_t * vObjs );
+extern Vec_Int_t * Acb_ObjCollectTfoVec( Acb_Ntk_t * p, Vec_Int_t * vObjs );
+extern int Acb_NtkCountPiBuffers( Acb_Ntk_t * p, Vec_Int_t * vObjs );
+extern int Acb_NtkCountPoDrivers( Acb_Ntk_t * p, Vec_Int_t * vObjs );
+extern int Acb_NtkFindMffcSize( Acb_Ntk_t * p, Vec_Int_t * vObjsRefed, Vec_Int_t * vObjsDerefed, int nGates[5] );
+
extern int Acb_ObjComputeLevelD( Acb_Ntk_t * p, int iObj );
extern int Acb_NtkComputeLevelD( Acb_Ntk_t * p, Vec_Int_t * vTfo );
extern void Acb_NtkUpdateLevelD( Acb_Ntk_t * p, int iObj );
diff --git a/src/base/acb/acbFunc.c b/src/base/acb/acbFunc.c
index 8f72a00f..3c0bb5f0 100644
--- a/src/base/acb/acbFunc.c
+++ b/src/base/acb/acbFunc.c
@@ -35,8 +35,6 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-#define ACB_LAST_NAME_ID 14
-
typedef enum {
ACB_NONE = 0, // 0: unused
ACB_MODULE, // 1: "module"
@@ -52,6 +50,8 @@ typedef enum {
ACB_NOR, // 11: "nor"
ACB_XOR, // 12: "xor"
ACB_XNOR, // 13: "xnor"
+ ACB_MUX, // 14: "_HMUX"
+ ACB_DC, // 15: "_DC"
ACB_UNUSED // 14: unused
} Acb_KeyWords_t;
@@ -70,6 +70,8 @@ static inline char * Acb_Num2Name( int i )
if ( i == 11 ) return "nor";
if ( i == 12 ) return "xor";
if ( i == 13 ) return "xnor";
+ if ( i == 14 ) return "_HMUX";
+ if ( i == 15 ) return "_DC";
return NULL;
}
@@ -83,6 +85,8 @@ static inline int Acb_Type2Oper( int i )
if ( i == 11 ) return ABC_OPER_BIT_NOR;
if ( i == 12 ) return ABC_OPER_BIT_XOR;
if ( i == 13 ) return ABC_OPER_BIT_NXOR;
+ if ( i == 14 ) return ABC_OPER_BIT_MUX;
+ if ( i == 15 ) return ABC_OPER_TRI;
assert( 0 );
return -1;
}
@@ -91,6 +95,7 @@ static inline char * Acb_Oper2Name( int i )
{
if ( i == ABC_OPER_CONST_F ) return "const0";
if ( i == ABC_OPER_CONST_T ) return "const1";
+ if ( i == ABC_OPER_CONST_X ) return "constX";
if ( i == ABC_OPER_BIT_BUF ) return "buf";
if ( i == ABC_OPER_BIT_INV ) return "not";
if ( i == ABC_OPER_BIT_AND ) return "and";
@@ -99,6 +104,8 @@ static inline char * Acb_Oper2Name( int i )
if ( i == ABC_OPER_BIT_NOR ) return "nor";
if ( i == ABC_OPER_BIT_XOR ) return "xor";
if ( i == ABC_OPER_BIT_NXOR ) return "xnor";
+ if ( i == ABC_OPER_BIT_MUX ) return "mux";
+ if ( i == ABC_OPER_TRI ) return "_DC";
assert( 0 );
return NULL;
}
@@ -138,15 +145,28 @@ char * pLibStr[25] = {
"GATE zero 0 O=CONST0;\n"
"GATE one 0 O=CONST1;\n"
};
-void Acb_IntallLibrary()
+char * pLibStr2[25] = {
+ "GATE buf 1 O=a; PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
+ "GATE inv 1 O=!a; PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
+ "GATE and2 1 O=a*b; PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
+ "GATE or2 1 O=a+b; PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
+ "GATE nand2 1 O=!(a*b); PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
+ "GATE nor2 1 O=!(a+b); PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
+ "GATE xor 1 O=!a*b+a*!b; PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
+ "GATE xnor 1 O=a*b+!a*!b; PIN * INV 1 999 1.0 0.0 1.0 0.0\n"
+ "GATE zero 0 O=CONST0;\n"
+ "GATE one 0 O=CONST1;\n"
+};
+void Acb_IntallLibrary( int f2Ins )
{
extern Mio_Library_t * Mio_LibraryReadBuffer( char * pBuffer, int fExtendedFormat, st__table * tExcludeGate, int fVerbose );
Mio_Library_t * pLib;
int i;
// create library string
Vec_Str_t * vLibStr = Vec_StrAlloc( 1000 );
- for ( i = 0; pLibStr[i]; i++ )
- Vec_StrAppend( vLibStr, pLibStr[i] );
+ char ** ppLibStr = f2Ins ? pLibStr2 : pLibStr;
+ for ( i = 0; ppLibStr[i]; i++ )
+ Vec_StrAppend( vLibStr, ppLibStr[i] );
Vec_StrPush( vLibStr, '\0' );
// create library
pLib = Mio_LibraryReadBuffer( Vec_StrArray(vLibStr), 0, NULL, 0 );
@@ -190,17 +210,78 @@ Vec_Int_t * Acb_VerilogSimpleLex( char * pFileName, Abc_Nam_t * pNames )
Vec_Int_t * vBuffer = Vec_IntAlloc( 1000 );
char * pBuffer = Extra_FileReadContents( pFileName );
char * pToken, * pStart, * pLimit = pBuffer + strlen(pBuffer);
+ int i, iToken, RLeft = -1, RRight = -1;
if ( pBuffer == NULL )
return NULL;
Acb_VerilogRemoveComments( pBuffer );
pToken = strtok( pBuffer, " \n\r\t(),;=" );
while ( pToken )
{
- int iToken = Abc_NamStrFindOrAdd( pNames, pToken, NULL );
+ if ( 0 )
+ {
+ if ( !strcmp(pToken, "assign") )
+ {
+ int fBuffer = 0;
+ int nToks = 0, pToks[4];
+ while ( 1 )
+ {
+ pToken = strtok( NULL, " \n\r\t(),=~&" );
+ if ( pToken[0] == ';' )
+ break;
+ if ( pToken[strlen(pToken)-1] == ';' )
+ {
+ pToken[strlen(pToken)-1] = 0;
+ assert( nToks < 3 );
+ pToks[nToks++] = Abc_NamStrFindOrAdd( pNames, pToken, NULL );
+ fBuffer = 1;
+ break;
+ }
+ else
+ {
+ assert( nToks < 3 );
+ pToks[nToks++] = Abc_NamStrFindOrAdd( pNames, pToken, NULL );
+ }
+ }
+ assert( nToks == 2 || nToks == 3 );
+ Vec_IntPush( vBuffer, fBuffer ? ACB_AND : ACB_NAND );
+ Vec_IntPush( vBuffer, pToks[0] );
+ Vec_IntPush( vBuffer, pToks[1] );
+ Vec_IntPush( vBuffer, nToks == 3 ? pToks[2] : pToks[1] );
+ pToken = strtok( NULL, " \n\r\t(),;=" );
+ continue;
+ }
+ }
+
+ if ( pToken[0] == '[' )
+ {
+ assert( RLeft == -1 );
+ RLeft = atoi(pToken+1);
+ RRight = atoi(strstr(pToken,":")+1);
+ pToken = strtok( NULL, " \n\r\t(),;=" );
+ continue;
+ }
+ if ( pToken[0] == '\\' )
+ pToken++;
if ( !strcmp(pToken, "assign") )
- Vec_IntPush( vBuffer, ACB_BUF );
+ iToken = ACB_BUF;
else
- Vec_IntPush( vBuffer, iToken );
+ iToken = Abc_NamStrFindOrAdd( pNames, pToken, NULL );
+ if ( iToken < ACB_UNUSED )
+ RLeft = RRight = -1;
+ else if ( RLeft != -1 )
+ {
+ char Buffer[1000];
+ assert( strlen(pToken) < 990 );
+ for ( i = RRight; i <= RLeft; i++ )
+ {
+ sprintf( Buffer, "%s[%d]", pToken, i );
+ iToken = Abc_NamStrFindOrAdd( pNames, Buffer, NULL );
+ Vec_IntPush( vBuffer, iToken );
+ }
+ pToken = strtok( NULL, " \n\r\t(),;=" );
+ continue;
+ }
+ Vec_IntPush( vBuffer, iToken );
if ( iToken >= ACB_BUF && iToken < ACB_UNUSED )
{
for ( pStart = pToken; pStart < pLimit && *pStart != '\n'; pStart++ )
@@ -245,14 +326,11 @@ void * Acb_VerilogSimpleParse( Vec_Int_t * vBuffer, Abc_Nam_t * pNames )
vCur = vOutputs;
else if ( Token == ACB_WIRE )
vCur = vWires;
- else if ( Token >= ACB_BUF && Token <= ACB_XNOR )
+ else if ( Token >= ACB_BUF && Token < ACB_UNUSED )
{
- //char * pToken = Abc_NamStr(pNames, Vec_IntEntry(vBuffer, i+1));
Vec_IntPush( vTypes, Token );
Vec_IntPush( vTypes, Vec_IntSize(vFanins) );
vCur = vFanins;
- //if ( pToken[1] == 'z' && pToken[2] == '_' && pToken[3] == 'g' && pToken[4] == '_' )
- // i++;
}
else
Vec_IntPush( vCur, Token );
@@ -288,6 +366,8 @@ void * Acb_VerilogSimpleParse( Vec_Int_t * vBuffer, Abc_Nam_t * pNames )
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CONST_F, 0, 0, 0, 0, 0, NULL, 1, &Token, NULL ); // no fanins
if ( (Token = Abc_NamStrFind(pNames, "1\'b1")) )
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CONST_T, 0, 0, 0, 0, 0, NULL, 1, &Token, NULL ); // no fanins
+ if ( (Token = Abc_NamStrFind(pNames, "1\'bx")) )
+ Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CONST_X, 0, 0, 0, 0, 0, NULL, 1, &Token, NULL ); // no fanins
Vec_IntForEachEntryDouble( vTypes, Token, Size, i )
if ( Token > 0 )
{
@@ -309,6 +389,182 @@ void * Acb_VerilogSimpleParse( Vec_Int_t * vBuffer, Abc_Nam_t * pNames )
/**Function*************************************************************
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_FileSimpleParse_rec( Gia_Man_t * pNew, int Token, Vec_Int_t * vMapType, Vec_Int_t * vTypes, Vec_Int_t * vFanins, Vec_Int_t * vMap )
+{
+ int nFanins, * pFanins, pLits[16];
+ int i, Type, Size, Place = Vec_IntEntry( vMapType, Token );
+ int iLit = Vec_IntEntry( vMap, Token );
+ if ( iLit >= 0 )
+ return iLit;
+ Place = Vec_IntEntry( vMapType, Token );
+ assert( Place >= 0 );
+ Type = Vec_IntEntry( vTypes, Place );
+ Size = Vec_IntEntry( vTypes, Place+1 );
+ nFanins = Vec_IntEntry(vTypes, Place+3) - Size - 1;
+ pFanins = Vec_IntEntryP(vFanins, Size+1);
+ assert( nFanins > 0 && nFanins < 16 );
+ for ( i = 0; i < nFanins; i++ )
+ Gia_FileSimpleParse_rec( pNew, pFanins[i], vMapType, vTypes, vFanins, vMap );
+ for ( i = 0; i < nFanins; i++ )
+ pLits[i] = Vec_IntEntry( vMap, pFanins[i] );
+ if ( nFanins == 1 )
+ {
+ assert( Type == ACB_BUF || Type == ACB_NOT );
+ iLit = Abc_LitNotCond( pLits[0], Type == ACB_NOT );
+ iLit = Gia_ManAppendAnd2( pNew, iLit, iLit );
+ }
+ else
+ {
+ iLit = pLits[0];
+ if ( Type == ACB_AND || Type == ACB_NAND )
+ for ( i = 1; i < nFanins; i++ )
+ iLit = Gia_ManAppendAnd2( pNew, iLit, pLits[i] );
+ else if ( Type == ACB_OR || Type == ACB_NOR )
+ for ( i = 1; i < nFanins; i++ )
+ iLit = Gia_ManAppendOr2( pNew, iLit, pLits[i] );
+ else if ( Type == ACB_XOR || Type == ACB_XNOR )
+ for ( i = 1; i < nFanins; i++ )
+ iLit = Gia_ManAppendXor2( pNew, iLit, pLits[i] );
+ else assert( 0 );
+ iLit = Abc_LitNotCond( iLit, (Type == ACB_NAND || Type == ACB_NOR || Type == ACB_XNOR) );
+ }
+ Vec_IntWriteEntry( vMap, Token, iLit );
+ return iLit;
+}
+Gia_Man_t * Gia_FileSimpleParse( Vec_Int_t * vBuffer, Abc_Nam_t * pNames, int fNames, char * pFileW )
+{
+ Gia_Man_t * pNew = NULL;
+ Vec_Int_t * vInputs = Vec_IntAlloc(100);
+ Vec_Int_t * vOutputs = Vec_IntAlloc(100);
+ Vec_Int_t * vWires = Vec_IntAlloc(100);
+ Vec_Int_t * vTypes = Vec_IntAlloc(100);
+ Vec_Int_t * vFanins = Vec_IntAlloc(100);
+ Vec_Int_t * vCur = NULL;
+ Vec_Int_t * vMap = Vec_IntStartFull( Abc_NamObjNumMax(pNames) );
+ Vec_Int_t * vMapType = Vec_IntStartFull( Abc_NamObjNumMax(pNames) );
+ int i, iLit, Token, Size;
+ char Buffer[1000];
+ assert( Vec_IntEntry(vBuffer, 0) == ACB_MODULE );
+ Vec_IntForEachEntryStart( vBuffer, Token, i, 2 )
+ {
+ if ( vCur == NULL && Token >= ACB_UNUSED )
+ continue;
+ if ( Token == ACB_ENDMODULE )
+ break;
+ if ( Token == ACB_INPUT )
+ vCur = vInputs;
+ else if ( Token == ACB_OUTPUT )
+ vCur = vOutputs;
+ else if ( Token == ACB_WIRE )
+ vCur = vWires;
+ else if ( Token >= ACB_BUF && Token < ACB_UNUSED )
+ {
+ Vec_IntPush( vTypes, Token );
+ Vec_IntPush( vTypes, Vec_IntSize(vFanins) );
+ vCur = vFanins;
+ }
+ else if ( pFileW && vCur == vWires && Abc_NamStr(pNames, Token)[0] == 't' )
+ Vec_IntPush( vInputs, Token );
+ else
+ Vec_IntPush( vCur, Token );
+ }
+ Vec_IntPush( vTypes, -1 );
+ Vec_IntPush( vTypes, Vec_IntSize(vFanins) );
+ // map types
+ Vec_IntForEachEntryDouble( vTypes, Token, Size, i )
+ if ( Token > 0 )
+ Vec_IntWriteEntry( vMapType, Vec_IntEntry(vFanins, Size), i );
+ // create design
+ pNew = Gia_ManStart( 10000 );
+ pNew->pName = Abc_UtilStrsav( Abc_NamStr(pNames, Vec_IntEntry(vBuffer, 1)) );
+ pNew->fGiaSimple = 1;
+ if ( (Token = Abc_NamStrFind(pNames, "1\'b0")) )
+ Vec_IntWriteEntry( vMap, Token, 0 );
+ if ( (Token = Abc_NamStrFind(pNames, "1\'b1")) )
+ Vec_IntWriteEntry( vMap, Token, 1 );
+ if ( (Token = Abc_NamStrFind(pNames, "1\'bx")) )
+ Vec_IntWriteEntry( vMap, Token, 0 );
+ if ( (Token = Abc_NamStrFind(pNames, "1\'bz")) )
+ Vec_IntWriteEntry( vMap, Token, 0 );
+ Vec_IntForEachEntry( vInputs, Token, i )
+ Gia_ManAppendCi(pNew);
+ Vec_IntForEachEntry( vInputs, Token, i )
+ Vec_IntWriteEntry( vMap, Token, Gia_ManAppendAnd2(pNew, Gia_ManCiLit(pNew, i), Gia_ManCiLit(pNew, i)) );
+ Vec_IntForEachEntry( vOutputs, Token, i )
+ Gia_FileSimpleParse_rec( pNew, Token, vMapType, vTypes, vFanins, vMap );
+ Vec_IntForEachEntry( vOutputs, Token, i )
+ Gia_ManAppendCo( pNew, Vec_IntEntry(vMap, Token) );
+ // create names
+ if ( fNames )
+ {
+ pNew->vPolars = Vec_BitStart( Gia_ManObjNum(pNew) );
+ pNew->vNamesNode = Vec_PtrStart( Gia_ManObjNum(pNew) );
+ Vec_IntForEachEntry( vMap, iLit, Token )
+ {
+ if ( iLit == -1 || !Gia_ObjIsAnd(Gia_ManObj(pNew, Abc_Lit2Var(iLit))) )
+ continue;
+ sprintf( Buffer, "%c_%s", Abc_LitIsCompl(iLit) ? 'c' : 'd', Abc_NamStr(pNames, Token) );
+ assert( Vec_PtrEntry(pNew->vNamesNode, Abc_Lit2Var(iLit)) == NULL );
+ Vec_PtrWriteEntry( pNew->vNamesNode, Abc_Lit2Var(iLit), Abc_UtilStrsav(Buffer) );
+ Vec_BitWriteEntry( pNew->vPolars, Abc_Lit2Var(iLit), Abc_LitIsCompl(iLit) );
+ }
+ }
+ else
+ {
+ Gia_Man_t * pTemp;
+ pNew = Gia_ManDupDfsRehash( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ }
+ pNew->vNamesIn = Vec_PtrAlloc( Vec_IntSize(vInputs) );
+ Vec_IntForEachEntry( vInputs, Token, i )
+ Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(Abc_NamStr(pNames, Token)) );
+ pNew->vNamesOut = Vec_PtrAlloc( Vec_IntSize(vOutputs) );
+ Vec_IntForEachEntry( vOutputs, Token, i )
+ Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Abc_NamStr(pNames, Token)) );
+ if ( pFileW && fNames )
+ {
+ extern Vec_Int_t * Acb_ReadWeightMap( char * pFileName, Abc_Nam_t * pNames );
+ Vec_Int_t * vT2W = Acb_ReadWeightMap( pFileW, pNames );
+ assert( pNew->vWeights == NULL );
+ pNew->vWeights = Vec_IntStartFull( Gia_ManObjNum(pNew) );
+ Vec_IntForEachEntry( vMap, iLit, Token )
+ if ( iLit != -1 && Vec_IntEntry(vT2W, Token) != -1 )
+ Vec_IntWriteEntry( pNew->vWeights, Abc_Lit2Var(iLit), Vec_IntEntry(vT2W, Token) );
+ Vec_IntFree( vT2W );
+ }
+ // cleanup
+ Vec_IntFree( vInputs );
+ Vec_IntFree( vOutputs );
+ Vec_IntFree( vWires );
+ Vec_IntFree( vTypes );
+ Vec_IntFree( vFanins );
+ Vec_IntFree( vMap );
+ Vec_IntFree( vMapType );
+ return pNew;
+}
+Gia_Man_t * Gia_FileSimpleRead( char * pFileName, int fNames, char * pFileW )
+{
+ Abc_Nam_t * pNames = Acb_VerilogStartNames();
+ Vec_Int_t * vBuffer = Acb_VerilogSimpleLex( pFileName, pNames );
+ Gia_Man_t * pNew = vBuffer ? Gia_FileSimpleParse( vBuffer, pNames, fNames, pFileW ) : NULL;
+ assert( pNew->pSpec == NULL );
+ pNew->pSpec = Abc_UtilStrsav( pFileName );
+ Abc_NamDeref( pNames );
+ Vec_IntFree( vBuffer );
+ return pNew;
+}
+
+/**Function*************************************************************
+
Synopsis [Read weights of nodes from the weight file.]
Description []
@@ -355,10 +611,18 @@ Vec_Int_t * Acb_ReadWeightMap( char * pFileName, Abc_Nam_t * pNames )
SeeAlso []
***********************************************************************/
+char ** Acb_PrepareNames( Abc_Nam_t * p )
+{
+ char ** ppRes = ABC_CALLOC( char *, Abc_NamObjNumMax(p) );
+ int i;
+ for ( i = 0; i < Abc_NamObjNumMax(p); i++ )
+ ppRes[i] = Abc_NamStr( p, i );
+ return ppRes;
+}
Acb_Ntk_t * Acb_VerilogSimpleRead( char * pFileName, char * pFileNameW )
{
extern Acb_Ntk_t * Acb_NtkFromNdr( char * pFileName, void * pModule, Abc_Nam_t * pNames, Vec_Int_t * vWeights, int nNameIdMax );
- Acb_Ntk_t * pNtk;
+ Acb_Ntk_t * pNtk;
Abc_Nam_t * pNames = Acb_VerilogStartNames();
Vec_Int_t * vBuffer = Acb_VerilogSimpleLex( pFileName, pNames );
void * pModule = vBuffer ? Acb_VerilogSimpleParse( vBuffer, pNames ) : NULL;
@@ -373,7 +637,12 @@ Acb_Ntk_t * Acb_VerilogSimpleRead( char * pFileName, char * pFileNameW )
printf( "Cannot read weight file \"%s\".\n", pFileNameW );
return NULL;
}
-// Ndr_ModuleWriteVerilog( "iccad17/unit1/test.v", pModule, pNameStrs );
+ if ( 0 )
+ {
+ char ** ppNames = Acb_PrepareNames(pNames);
+ Ndr_WriteVerilog( Extra_FileNameGenericAppend(pFileName, "_ndr.v"), pModule, ppNames, 1 );
+ ABC_FREE( ppNames );
+ }
pNtk = Acb_NtkFromNdr( pFileName, pModule, pNames, vWeights, Abc_NamObjNumMax(pNames) );
Ndr_Delete( pModule );
Vec_IntFree( vBuffer );
@@ -381,6 +650,11 @@ Acb_Ntk_t * Acb_VerilogSimpleRead( char * pFileName, char * pFileNameW )
Abc_NamDeref( pNames );
return pNtk;
}
+void Acb_VerilogSimpleReadTest( char * pFileName )
+{
+ Acb_Ntk_t * p = Acb_VerilogSimpleRead( pFileName, NULL );
+ Acb_NtkFree( p );
+}
/**Function*************************************************************
@@ -440,7 +714,10 @@ void Acb_VerilogSimpleWrite( Acb_Ntk_t * p, char * pFileName )
{
assert( Acb_ObjType(p, iObj) == ABC_OPER_CONST_F || Acb_ObjType(p, iObj) == ABC_OPER_CONST_T );
fprintf( pFile, " %s (", Acb_Oper2Name( ABC_OPER_BIT_BUF ) );
- fprintf( pFile, " 1\'b%d", Acb_ObjType(p, iObj) == ABC_OPER_CONST_T );
+ if ( Acb_ObjType(p, iObj) == ABC_OPER_CONST_X )
+ fprintf( pFile, " 1\'bx" );
+ else
+ fprintf( pFile, " 1\'b%d", Acb_ObjType(p, iObj) == ABC_OPER_CONST_T );
fprintf( pFile, " );\n" );
}
@@ -579,12 +856,18 @@ Vec_Int_t * Acb_NtkFindDivsCis( Acb_Ntk_t * p, Vec_Int_t * vSupp )
printf( "Divisors are %d support variables (CIs in the TFO of the targets).\n", Vec_IntSize(vSupp) );
return vDivs;
}
-Vec_Int_t * Acb_NtkFindDivs( Acb_Ntk_t * p, Vec_Int_t * vSupp, Vec_Bit_t * vBlock, int fVerbose )
+Vec_Int_t * Acb_NtkFindDivs( Acb_Ntk_t * p, Vec_Int_t * vSupp, Vec_Bit_t * vBlock, int fUnitW, int fVerbose )
{
int fPrintWeights = 0;
int nDivLimit = 5000;
int i, iObj;
Vec_Int_t * vDivs = Vec_IntAlloc( 1000 );
+ if ( fUnitW )
+ {
+ Acb_NtkForEachNode( p, iObj )
+ if ( Acb_ObjWeight(p, iObj) > 0 )
+ Vec_IntWriteEntry( &p->vObjWeight, iObj, 1 );
+ }
// mark inputs
Acb_NtkIncTravId( p );
Acb_NtkForEachCiVec( vSupp, p, iObj, i )
@@ -754,6 +1037,31 @@ Gia_Man_t * Acb_NtkToGia( Acb_Ntk_t * p, Vec_Int_t * vSupp, Vec_Int_t * vNodes,
Gia_ManStop( pOne );
return pNew;
}
+int Acb_NtkSaveNames( Acb_Ntk_t * p, Vec_Int_t * vSupp, Vec_Int_t * vNodes, Vec_Int_t * vRoots, Vec_Int_t * vDivs, Vec_Int_t * vTargets, Gia_Man_t * pNew )
+{
+ int i, iObj;
+ assert( pNew->vNamesIn == NULL );
+
+ pNew->vNamesIn = Vec_PtrAlloc( Gia_ManCiNum(pNew) );
+ Acb_NtkForEachCiVec( vSupp, p, iObj, i )
+ Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(Acb_ObjNameStr(p, iObj)) );
+ if ( vTargets )
+ Vec_IntForEachEntry( vTargets, iObj, i )
+ Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(Acb_ObjNameStr(p, iObj)) );
+
+ pNew->vNamesOut = Vec_PtrAlloc( Gia_ManCoNum(pNew) );
+ Acb_NtkForEachCoDriverVec( vRoots, p, iObj, i )
+ Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Acb_ObjNameStr(p, iObj)) );
+ if ( vDivs )
+ Vec_IntForEachEntry( vDivs, iObj, i )
+ {
+ char Buffer[100];
+ assert( strlen(Acb_ObjNameStr(p, iObj)) < 90 );
+ sprintf( Buffer, "%s_%d", Acb_ObjNameStr(p, iObj), Acb_ObjWeight(p, iObj) );
+ Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) );
+ }
+ return 1;
+}
/**Function*************************************************************
@@ -825,6 +1133,21 @@ void Vec_IntPermute( Vec_Int_t * p )
}
}
+void Vec_IntPermute2( Vec_Int_t * p )
+{
+ int i, nSize = Vec_IntSize( p );
+ int * pArray = Vec_IntArray( p );
+ srand( time(NULL) );
+ for ( i = 0; i < nSize-1; i++ )
+ {
+ if ( rand() % 3 == 0 )
+ {
+ printf( "Permuting %d and %d\n", i, i+1 );
+ ABC_SWAP( int, pArray[i], pArray[i+1] );
+ }
+ }
+}
+
void Acb_PrintPatterns( Vec_Wrd_t * vPats, int nPats, Vec_Int_t * vWeights )
{
int i, k, Entry, nDivs = Vec_IntSize(vWeights);
@@ -1541,7 +1864,7 @@ char * Acb_EnumerateSatAssigns( sat_solver * pSat, int PivotVar, int FreeVar, Ve
{
if ( iMint == 1000 )
{
- //if ( Vec_IntSize(vDivVars) == 0 )
+ if ( Vec_IntSize(vDivVars) == 0 )
{
printf( "Assuming constant 0 function.\n" );
Vec_StrClear( vTempSop );
@@ -1897,34 +2220,66 @@ Vec_Ptr_t * Acb_GenerateSignalNames( Acb_Ntk_t * p, Vec_Int_t * vDivs, Vec_Int_t
Vec_StrFree( vStr );
return vRes;
}
+Vec_Int_t * Acb_GetUsedDivs( Vec_Int_t * vDivs, Vec_Int_t * vUsed )
+{
+ int i, iObj;
+ Vec_Int_t * vRes = Vec_IntAlloc( Vec_IntSize(vUsed) );
+ Vec_IntForEachEntryInVec( vDivs, vUsed, iObj, i )
+ Vec_IntPush( vRes, iObj );
+ return vRes;
+}
+Vec_Ptr_t * Acb_SignalNames( Acb_Ntk_t * p, Vec_Int_t * vObjs )
+{
+ Vec_Ptr_t * vNames = Vec_PtrAlloc( Vec_IntSize(vObjs) );
+ int i, iObj;
+ Vec_IntForEachEntry( vObjs, iObj, i )
+ Vec_PtrPush( vNames, Acb_ObjNameStr(p, iObj) );
+ return vNames;
+}
Vec_Str_t * Acb_GeneratePatch( Acb_Ntk_t * p, Vec_Int_t * vDivs, Vec_Int_t * vUsed, Vec_Ptr_t * vSops, Vec_Ptr_t * vGias, Vec_Int_t * vTars )
{
+ extern int Acb_NtkCollectMfsGates( char * pFileName, Vec_Ptr_t * vNamesRefed, Vec_Ptr_t * vNamesDerefed, int nGates1[5] );
extern Vec_Wec_t * Abc_SopSynthesize( Vec_Ptr_t * vSops );
extern Vec_Wec_t * Abc_GiaSynthesize( Vec_Ptr_t * vGias, Gia_Man_t * pMulti );
Vec_Wec_t * vGates = vGias ? Abc_GiaSynthesize(vGias, NULL) : Abc_SopSynthesize(vSops); Vec_Int_t * vGate;
int nOuts = vGias ? Vec_PtrSize(vGias) : Vec_PtrSize(vSops);
int i, k, iObj, nWires = Vec_WecSize(vGates) - Vec_IntSize(vUsed) - nOuts, fFirst = 1;
+ int nGates1[5] = {0}, nGates0[5] = {0};
Vec_Ptr_t * vNames = Acb_GenerateSignalNames( p, vDivs, vUsed, nWires, vTars, vGates );
Vec_Str_t * vStr = Vec_StrAlloc( 100 );
-
- int nInvs = 0, nBufs = 0, nNodes = 0, nConst = 0;
+ Vec_Int_t * vSup = Acb_GetUsedDivs( vDivs, vUsed );
+ Vec_Ptr_t * vSpN = Acb_SignalNames( p, vSup );
+ Vec_Int_t * vTfi = Acb_ObjCollectTfiVec( p, vSup );
+ Vec_Int_t * vTfo = Acb_ObjCollectTfoVec( p, vTars );
+ int nPiCount = Acb_NtkCountPiBuffers( p, vSup );
+ int nPoCount = Acb_NtkCountPoDrivers( p, vTars );
+ int nMffc = Abc_FrameReadSpecName() ? Acb_NtkCollectMfsGates( Abc_FrameReadSpecName(), vSpN, Abc_FrameReadSignalNames(), nGates1 ) : 0;
+ Vec_PtrFree( vSpN );
+ Vec_IntFree( vSup );
Vec_WecForEachLevelStartStop( vGates, vGate, i, Vec_IntSize(vUsed), Vec_IntSize(vUsed)+nWires )
{
if ( Vec_IntSize(vGate) > 2 )
{
char * pName = Acb_Oper2Name(Vec_IntEntry(vGate, 0));
if ( !strcmp(pName, "buf") )
- nBufs++;
+ nGates0[2]++;
else if ( !strcmp(pName, "not") )
- nInvs++;
+ nGates0[3]++;
else
- nNodes++;
+ nGates0[4] += Vec_IntSize(vGate) - 3;
}
else
- nConst++;
+ nGates0[Vec_IntEntry(vGate, 0) == ABC_OPER_CONST_T]++;
}
- Vec_StrPrintF( vStr, "// Patch statistics: in = %d out = %d gate = %d (const = %d buf = %d inv = %d other = %d)\n\n",
- Vec_IntSize(vUsed), nOuts, nWires, nConst, nBufs, nInvs, nNodes );
+
+ Vec_StrPrintF( vStr, "// Patch : in = %d out = %d : pi_in = %d po_out = %d : tfi = %d tfo = %d\n", Vec_IntSize(vUsed), nOuts, nPiCount, nPoCount, Vec_IntSize(vTfi), Vec_IntSize(vTfo) );
+ Vec_StrPrintF( vStr, "// Added : gate =%4d : c0 =%2d c1 =%2d buf =%3d inv =%3d two-input =%4d\n", nWires, nGates0[0], nGates0[1], nGates0[2], nGates0[3], nGates0[4] );
+ if ( Abc_FrameReadSpecName() )
+ Vec_StrPrintF( vStr, "// Removed : gate =%4d : c0 =%2d c1 =%2d buf =%3d inv =%3d two-input =%4d\n", nMffc, nGates1[0], nGates1[1], nGates1[2], nGates1[3], nGates1[4] );
+ if ( Abc_FrameReadSpecName() )
+ Vec_StrPrintF( vStr, "// TOTAL : gate =%4d : c0 =%2d c1 =%2d buf =%3d inv =%3d two-input =%4d\n", nWires-nMffc, nGates0[0]-nGates1[0], nGates0[1]-nGates1[1], nGates0[2]-nGates1[2], nGates0[3]-nGates1[3], nGates0[4]-nGates1[4] );
+ Vec_StrPrintF( vStr, "\n" );
+
Vec_StrAppend( vStr, "module patch (" );
assert( Vec_IntSize(vTars) == nOuts );
@@ -1980,8 +2335,17 @@ Vec_Str_t * Acb_GeneratePatch( Acb_Ntk_t * p, Vec_Int_t * vDivs, Vec_Int_t * vUs
Vec_PtrFreeFree( vNames );
Vec_WecFree( vGates );
- printf( "Synthesized patch with %d inputs, %d outputs and %d gates (const = %d buf = %d inv = %d other = %d).\n",
- Vec_IntSize(vUsed), nOuts, nWires, nConst, nBufs, nInvs, nNodes );
+// printf( "Synthesized patch with %d inputs, %d outputs and %d gates (const = %d buf = %d inv = %d other = %d).\n",
+// Vec_IntSize(vUsed), nOuts, nWires, nConst, nBufs, nInvs, nNodes );
+// printf( "Summary of the results\n" );
+ printf( "\n" );
+ printf( "Patch : in = %d out = %d : pi_in = %d po_out = %d : tfi = %d tfo = %d\n", Vec_IntSize(vUsed), nOuts, nPiCount, nPoCount, Vec_IntSize(vTfi), Vec_IntSize(vTfo) );
+ printf( "Added : gate =%4d : c0 =%2d c1 =%2d buf =%3d inv =%3d two-input =%4d\n", nWires, nGates0[0], nGates0[1], nGates0[2], nGates0[3], nGates0[4] );
+ if ( Abc_FrameReadSpecName() )
+ printf( "Removed : gate =%4d : c0 =%2d c1 =%2d buf =%3d inv =%3d two-input =%4d\n", nMffc, nGates1[0], nGates1[1], nGates1[2], nGates1[3], nGates1[4] );
+ if ( Abc_FrameReadSpecName() )
+ printf( "TOTAL : gate =%4d : c0 =%2d c1 =%2d buf =%3d inv =%3d two-input =%4d\n", nWires-nMffc, nGates0[0]-nGates1[0], nGates0[1]-nGates1[1], nGates0[2]-nGates1[2], nGates0[3]-nGates1[3], nGates0[4]-nGates1[4] );
+ printf( "\n" );
return vStr;
}
@@ -2040,7 +2404,7 @@ Vec_Str_t * Acb_GeneratePatch2( Gia_Man_t * pGia, Vec_Ptr_t * vIns, Vec_Ptr_t *
extern Vec_Wec_t * Abc_GiaSynthesize( Vec_Ptr_t * vGias, Gia_Man_t * pMulti );
Vec_Wec_t * vGates = Abc_GiaSynthesize( NULL, pGia ); Vec_Int_t * vGate;
int nIns = Vec_PtrSize(vIns), nOuts = Vec_PtrSize(vOuts); char * pName;
- int i, k, iObj, nWires = Vec_WecSize(vGates) - nIns - nOuts, fFirst = 1;
+ int i, k, iObj, nWires = Vec_WecSize(vGates) - nIns - nOuts, nTwoIns = 0, fFirst = 1;
Vec_Ptr_t * vNames = Acb_GenerateSignalNames2( vGates, vIns, vOuts );
Vec_Str_t * vStr = Vec_StrAlloc( 100 );
@@ -2049,7 +2413,7 @@ Vec_Str_t * Acb_GeneratePatch2( Gia_Man_t * pGia, Vec_Ptr_t * vIns, Vec_Ptr_t *
Vec_PtrForEachEntry( char *, vOuts, pName, i )
Vec_StrPrintF( vStr, "%s %s", i ? ",":"", pName );
Vec_PtrForEachEntry( char *, vIns, pName, i )
- Vec_StrPrintF( vStr, ", %s", pName );
+ Vec_StrPrintF( vStr, ", %s%s", i ? "":" ", pName );
Vec_StrAppend( vStr, " );\n\n" );
Vec_StrAppend( vStr, " output" );
@@ -2071,8 +2435,9 @@ Vec_Str_t * Acb_GeneratePatch2( Gia_Man_t * pGia, Vec_Ptr_t * vIns, Vec_Ptr_t *
if ( !strncmp(pName, "ww", 2) )
Vec_StrPrintF( vStr, "%s %s", fFirst ? "":",", pName ), fFirst = 0;
}
- Vec_StrAppend( vStr, ";\n\n" );
+ Vec_StrAppend( vStr, ";\n" );
}
+ Vec_StrAppend( vStr, "\n" );
// create internal nodes
Vec_WecForEachLevelStartStop( vGates, vGate, i, nIns, nIns+nWires )
@@ -2083,6 +2448,7 @@ Vec_Str_t * Acb_GeneratePatch2( Gia_Man_t * pGia, Vec_Ptr_t * vIns, Vec_Ptr_t *
Vec_IntForEachEntryStart( vGate, iObj, k, 1 )
Vec_StrPrintF( vStr, "%s %s", k > 1 ? ",":"", (char *)Vec_PtrEntry(vNames, iObj) );
Vec_StrAppend( vStr, " );\n" );
+ nTwoIns += Vec_IntSize(vGate) - 3;
}
else
{
@@ -2098,14 +2464,14 @@ Vec_Str_t * Acb_GeneratePatch2( Gia_Man_t * pGia, Vec_Ptr_t * vIns, Vec_Ptr_t *
Vec_PtrFreeFree( vNames );
Vec_WecFree( vGates );
- printf( "Synthesized patch with %d inputs, %d outputs and %d gates.\n", nIns, nOuts, nWires );
+ printf( "Synthesized patch with %d inputs, %d outputs and %d gates (including %d two-input gates).\n", nIns, nOuts, nWires, nTwoIns );
return vStr;
}
-void Acb_GenerateFile2( Gia_Man_t * pGia, Vec_Ptr_t * vIns, Vec_Ptr_t * vOuts, char * pFileName, char * pFileNameOut )
+void Acb_GenerateFile2( Gia_Man_t * pGia, Vec_Ptr_t * vIns, Vec_Ptr_t * vOuts, char * pFileName, char * pFileNameOut, int fSkipMffc )
{
extern void Acb_GenerateFilePatch( Vec_Str_t * p, char * pFileNamePatch );
extern void Acb_GenerateFileOut( Vec_Str_t * vPatchLine, char * pFileNameF, char * pFileNameOut, Vec_Str_t * vPatch );
- extern void Acb_NtkInsert( char * pFileNameIn, char * pFileNameOut, Vec_Ptr_t * vNames, int fNumber );
+ extern void Acb_NtkInsert( char * pFileNameIn, char * pFileNameOut, Vec_Ptr_t * vNames, int fNumber, int fSkipMffc );
Vec_Str_t * vInst = Acb_GenerateInstance2( vIns, vOuts );
Vec_Str_t * vPatch = Acb_GeneratePatch2( pGia, vIns, vOuts );
//printf( "%s", Vec_StrArray(vPatch) );
@@ -2113,7 +2479,7 @@ void Acb_GenerateFile2( Gia_Man_t * pGia, Vec_Ptr_t * vIns, Vec_Ptr_t * vOuts, c
// generate output files
Acb_GenerateFilePatch( vPatch, "patch.v" );
printf( "Finished dumping patch file \"%s\".\n", "patch.v" );
- Acb_NtkInsert( pFileName, "temp.v", vOuts, 0 );
+ Acb_NtkInsert( pFileName, "temp.v", vOuts, 0, fSkipMffc );
printf( "Finished dumping intermediate file \"%s\".\n", "temp.v" );
Acb_GenerateFileOut( vInst, "temp.v", pFileNameOut, vPatch );
printf( "Finished dumping the resulting file \"%s\".\n", pFileNameOut );
@@ -2479,7 +2845,7 @@ Vec_Ptr_t * Acb_TransformPatchFunctions( Vec_Ptr_t * vSops, Vec_Wec_t * vSupps,
Vec_IntWriteEntry( vMap, iVar, Vec_IntSize(vUsed) );
Vec_IntPush( vUsed, iVar );
}
- printf( "The number of used variables %d (out of %d).\n", Vec_IntSum(vPres), Vec_IntSize(vPres) );
+ //printf( "The number of used variables %d (out of %d).\n", Vec_IntSum(vPres), Vec_IntSize(vPres) );
// remap SOPs
Vec_WecForEachLevel( vSupps, vLevel, i )
{
@@ -2505,13 +2871,14 @@ Vec_Ptr_t * Acb_TransformPatchFunctions( Vec_Ptr_t * vSops, Vec_Wec_t * vSupps,
SeeAlso []
***********************************************************************/
-int Acb_NtkEcoPerform( Acb_Ntk_t * pNtkF, Acb_Ntk_t * pNtkG, char * pFileName[4], int fCisOnly, int fCheck, int fVerbose, int fVeryVerbose )
+int Acb_NtkEcoPerform( Acb_Ntk_t * pNtkF, Acb_Ntk_t * pNtkG, char * pFileName[4], int nTimeout, int fCisOnly, int fInputs, int fCheck, int fUnitW, int fVerbose, int fVeryVerbose )
{
extern Gia_Man_t * Abc_SopSynthesizeOne( char * pSop, int fClp );
+ abctime clkStart = Abc_Clock();
abctime clk = Abc_Clock();
int nTargets = Vec_IntSize(&pNtkF->vTargets);
- int TimeOut = fCisOnly ? 0 : 60; // 60 seconds
+ int TimeOut = fCisOnly ? 0 : 120; // 60 seconds
int RetValue = 1;
// compute various sets of nodes
@@ -2520,7 +2887,7 @@ int Acb_NtkEcoPerform( Acb_Ntk_t * pNtkF, Acb_Ntk_t * pNtkG, char * pFileName[4]
Vec_Int_t * vSuppF = Acb_NtkFindSupp( pNtkF, vRoots );
Vec_Int_t * vSuppG = Acb_NtkFindSupp( pNtkG, vRoots );
Vec_Int_t * vSupp = Vec_IntTwoMerge( vSuppF, vSuppG );
- Vec_Int_t * vDivs = fCisOnly ? Acb_NtkFindDivsCis( pNtkF, vSupp ) : Acb_NtkFindDivs( pNtkF, vSupp, vBlock, fVerbose );
+ Vec_Int_t * vDivs = (fCisOnly || fInputs) ? Acb_NtkFindDivsCis( pNtkF, vSupp ) : Acb_NtkFindDivs( pNtkF, vSupp, vBlock, fUnitW, fVerbose );
Vec_Int_t * vNodesF = Acb_NtkFindNodes( pNtkF, vRoots, vDivs );
Vec_Int_t * vNodesG = Acb_NtkFindNodes( pNtkG, vRoots, NULL );
@@ -2543,6 +2910,10 @@ int Acb_NtkEcoPerform( Acb_Ntk_t * pNtkF, Acb_Ntk_t * pNtkG, char * pFileName[4]
char * pSop = NULL;
int i;
+// int Value = Acb_NtkSaveNames( pNtkF, vSupp, vNodesF, vRoots, vDivs, &pNtkF->vTargets, pGiaF );
+// Gia_AigerWrite( pGiaF, pFileBase, 0, 0, 0 );
+// return 0;
+
if ( fVerbose )
{
printf( "The number of targets = %d.\n", nTargets );
@@ -2622,6 +2993,14 @@ int Acb_NtkEcoPerform( Acb_Ntk_t * pNtkF, Acb_Ntk_t * pNtkG, char * pFileName[4]
RetValue = 0;
goto cleanup;
}
+ if ( nTimeout && (Abc_Clock() - clkStart)/CLOCKS_PER_SEC >= nTimeout )
+ {
+ Vec_IntFreeP( &vSupp );
+ ABC_FREE( pSop );
+ printf( "The target computation timed out after %d seconds.\n", nTimeout );
+ RetValue = 0;
+ goto cleanup;
+ }
// add new function to the miter
pOne = Abc_SopSynthesizeOne( pSop, 1 );
@@ -2683,6 +3062,16 @@ int Acb_NtkEcoPerform( Acb_Ntk_t * pNtkF, Acb_Ntk_t * pNtkG, char * pFileName[4]
if ( pFileName[3] == NULL ) Acb_GenerateFilePatch( vPatch, "patch.v" );
Acb_GenerateFileOut( vInst, pFileName[0], pFileName[3] ? pFileName[3] : (char *)"out.v", vPatch );
printf( "Finished dumping resulting file \"%s\".\n\n", pFileName[3] ? pFileName[3] : "out.v" );
+/*
+ {
+ char * pFileBase = Extra_FileNameGenericAppend( pFileName[0], "_patch.v" );
+ Acb_GenerateFilePatch( vPatch, pFileBase );
+ pFileBase = Extra_FileNameGenericAppend( pFileName[0], "_out.v" );
+ Acb_GenerateFileOut( vInst, pFileName[0], pFileName[3] ? pFileName[3] : pFileBase, vPatch );
+ Acb_GenerateFileOut( vInst, pFileName[0], pFileName[3] ? pFileName[3] : "out.v", vPatch );
+ printf( "Finished dumping resulting file \"%s\".\n\n", pFileName[3] ? pFileName[3] : pFileBase );
+ }
+*/
//Gia_AigerWrite( pGiaG, "test.aig", 0, 0, 0 );
cleanup:
// cleanup
@@ -2734,7 +3123,7 @@ void Acb_NtkTestRun2( char * pFileNames[3], int fVerbose )
Acb_Ntk_t * pNtk = Acb_VerilogSimpleRead( pFileNames[0], pFileNames[2] );
Acb_VerilogSimpleWrite( pNtk, pFileNameOut );
Acb_ManFree( pNtk->pDesign );
- Acb_IntallLibrary();
+ Acb_IntallLibrary( 0 );
}
/**Function*************************************************************
@@ -2748,7 +3137,7 @@ void Acb_NtkTestRun2( char * pFileNames[3], int fVerbose )
SeeAlso []
***********************************************************************/
-void Acb_NtkRunEco( char * pFileNames[4], int fCheck, int fRandom, int fVerbose, int fVeryVerbose )
+void Acb_NtkRunEco( char * pFileNames[4], int nTimeout, int fCheck, int fRandom, int fInputs, int fUnitW, int fVerbose, int fVeryVerbose )
{
char Command[1000]; int Result = 1;
Acb_Ntk_t * pNtkF = Acb_VerilogSimpleRead( pFileNames[0], pFileNames[2] );
@@ -2768,12 +3157,12 @@ void Acb_NtkRunEco( char * pFileNames[4], int fCheck, int fRandom, int fVerbose,
assert( Acb_NtkCiNum(pNtkF) == Acb_NtkCiNum(pNtkG) );
assert( Acb_NtkCoNum(pNtkF) == Acb_NtkCoNum(pNtkG) );
- Acb_IntallLibrary();
+ Acb_IntallLibrary( Abc_FrameReadSignalNames() != NULL );
- if ( !Acb_NtkEcoPerform( pNtkF, pNtkG, pFileNames, 0, fCheck, fVerbose, fVeryVerbose ) )
+ if ( !Acb_NtkEcoPerform( pNtkF, pNtkG, pFileNames, nTimeout, 0, fInputs, fCheck, fUnitW, fVerbose, fVeryVerbose ) )
{
// printf( "General computation timed out. Trying inputs only.\n\n" );
-// if ( !Acb_NtkEcoPerform( pNtkF, pNtkG, pFileNames, 1, fCheck, fVerbose, fVeryVerbose ) )
+// if ( !Acb_NtkEcoPerform( pNtkF, pNtkG, pFileNames, nTimeout, 1, fInputs, fCheck, fUnitW, fVerbose, fVeryVerbose ) )
// printf( "Input-only computation also timed out.\n\n" );
printf( "Computation did not succeed.\n" );
Result = 0;
diff --git a/src/base/acb/acbTest.c b/src/base/acb/acbTest.c
index fa632ca0..1faea72a 100644
--- a/src/base/acb/acbTest.c
+++ b/src/base/acb/acbTest.c
@@ -19,6 +19,11 @@
***********************************************************************/
#include "acb.h"
+#include "aig/saig/saig.h"
+#include "aig/gia/giaAig.h"
+#include "base/abc/abc.h"
+#include "proof/fraig/fraig.h"
+#include "misc/util/utilTruth.h"
ABC_NAMESPACE_IMPL_START
@@ -26,6 +31,8 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+static int fForceZero = 0;
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -41,8 +48,612 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
+void Gia_ManSimTry( Gia_Man_t * pF, Gia_Man_t * pG )
+{
+ int i, j, n, nWords = 500;
+ Vec_Wrd_t * vSimsF, * vSimsG;
+ Abc_Random(1);
+ Vec_WrdFreeP( &pF->vSimsPi );
+ Vec_WrdFreeP( &pG->vSimsPi );
+ pF->vSimsPi = Vec_WrdStartRandom( Gia_ManCiNum(pF) * nWords );
+ pG->vSimsPi = Vec_WrdDup( pF->vSimsPi );
+ vSimsF = Gia_ManSimPatSim( pF );
+ vSimsG = Gia_ManSimPatSim( pG );
+ assert( Gia_ManObjNum(pF) * nWords == Vec_WrdSize(vSimsF) );
+ for ( i = 0; i < Gia_ManCoNum(pF)/2; i++ )
+ {
+ Gia_Obj_t * pObjFb = Gia_ManCo( pF, 2*i+0 );
+ Gia_Obj_t * pObjFx = Gia_ManCo( pF, 2*i+1 );
+ Gia_Obj_t * pObjGb = Gia_ManCo( pG, 2*i+0 );
+ Gia_Obj_t * pObjGx = Gia_ManCo( pG, 2*i+1 );
+ word * pSimFb = Vec_WrdEntryP(vSimsF, Gia_ObjId(pF, pObjFb)*nWords);
+ word * pSimFx = Vec_WrdEntryP(vSimsF, Gia_ObjId(pF, pObjFx)*nWords);
+ word * pSimGb = Vec_WrdEntryP(vSimsG, Gia_ObjId(pG, pObjGb)*nWords);
+ word * pSimGx = Vec_WrdEntryP(vSimsG, Gia_ObjId(pG, pObjGx)*nWords);
+
+ int nBitsFx = Abc_TtCountOnesVec(pSimFx, nWords);
+ int nBitsF1 = Abc_TtCountOnesVecMask(pSimFx, pSimFb, nWords, 1);
+ int nBitsF0 = nWords*64 - nBitsFx - nBitsF1;
+
+ int nBitsGx = Abc_TtCountOnesVec(pSimGx, nWords);
+ int nBitsG1 = Abc_TtCountOnesVecMask(pSimGx, pSimGb, nWords, 1);
+ int nBitsG0 = nWords*64 - nBitsGx - nBitsG1;
+
+ printf( "Output %4d : ", i );
+
+ printf( " RF : " );
+ printf( "0 =%7.3f %% ", 100.0*nBitsF0/64/nWords );
+ printf( "1 =%7.3f %% ", 100.0*nBitsF1/64/nWords );
+ printf( "X =%7.3f %% ", 100.0*nBitsFx/64/nWords );
+
+ printf( " GF : " );
+ printf( "0 =%7.3f %% ", 100.0*nBitsG0/64/nWords );
+ printf( "1 =%7.3f %% ", 100.0*nBitsG1/64/nWords );
+ printf( "X =%7.3f %% ", 100.0*nBitsGx/64/nWords );
+
+ printf( "\n" );
+ if ( i == 20 )
+ break;
+ }
+
+ printf( "\n" );
+ for ( j = 0; j < 20; j++ )
+ {
+ for ( n = 0; n < 2; n++ )
+ {
+ for ( i = 0; i < Gia_ManCoNum(pF)/2; i++ )
+ {
+ Gia_Obj_t * pObjFb = Gia_ManCo( pF, 2*i+0 );
+ Gia_Obj_t * pObjFx = Gia_ManCo( pF, 2*i+1 );
+ Gia_Obj_t * pObjGb = Gia_ManCo( pG, 2*i+0 );
+ Gia_Obj_t * pObjGx = Gia_ManCo( pG, 2*i+1 );
+ word * pSimFb = Vec_WrdEntryP(vSimsF, Gia_ObjId(pF, pObjFb)*nWords);
+ word * pSimFx = Vec_WrdEntryP(vSimsF, Gia_ObjId(pF, pObjFx)*nWords);
+ word * pSimGb = Vec_WrdEntryP(vSimsG, Gia_ObjId(pG, pObjGb)*nWords);
+ word * pSimGx = Vec_WrdEntryP(vSimsG, Gia_ObjId(pG, pObjGx)*nWords);
+ word * pSimb = n ? pSimGb : pSimFb;
+ word * pSimx = n ? pSimGx : pSimFx;
+ if ( Abc_TtGetBit(pSimx, j) )
+ printf( "x" );
+ else if ( Abc_TtGetBit(pSimb, j) )
+ printf( "1" );
+ else
+ printf( "0" );
+ }
+ printf( "\n" );
+ }
+ printf( "\n" );
+ }
+
+ Vec_WrdFree( vSimsF );
+ Vec_WrdFree( vSimsG );
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManDualNot( Gia_Man_t * p, int LitA[2], int LitZ[2] )
+{
+ LitZ[0] = Abc_LitNot(LitA[0]);
+ LitZ[1] = LitA[1];
+
+ if ( fForceZero ) LitZ[0] = Gia_ManHashAnd( p, LitZ[0], Abc_LitNot(LitZ[1]) );
+}
+// computes Z = XOR(A, B) where A, B, Z belong to {0,1,x} encoded as 0=00, 1=01, x=1-
+void Gia_ManDualXor2( Gia_Man_t * p, int LitA[2], int LitB[2], int LitZ[2] )
+{
+ LitZ[0] = Gia_ManHashXor( p, LitA[0], LitB[0] );
+ LitZ[1] = Gia_ManHashOr( p, LitA[1], LitB[1] );
+
+ if ( fForceZero ) LitZ[0] = Gia_ManHashAnd( p, LitZ[0], Abc_LitNot(LitZ[1]) );
+}
+void Gia_ManDualXorN( Gia_Man_t * p, int * pLits, int n, int LitZ[2] )
+{
+ int i;
+ LitZ[0] = 0;
+ LitZ[1] = 0;
+ for ( i = 0; i < n; i++ )
+ {
+ LitZ[0] = Gia_ManHashXor( p, LitZ[0], pLits[2*i] );
+ LitZ[1] = Gia_ManHashOr ( p, LitZ[1], pLits[2*i+1] );
+ }
+}
+// computes Z = AND(A, B) where A, B, Z belong to {0,1,x} encoded as 0=00, 1=01, z=1-
+void Gia_ManDualAnd2( Gia_Man_t * p, int LitA[2], int LitB[2], int LitZ[2] )
+{
+ int ZeroA = Gia_ManHashAnd( p, Abc_LitNot(LitA[0]), Abc_LitNot(LitA[1]) );
+ int ZeroB = Gia_ManHashAnd( p, Abc_LitNot(LitB[0]), Abc_LitNot(LitB[1]) );
+ int ZeroZ = Gia_ManHashOr( p, ZeroA, ZeroB );
+ LitZ[0] = Gia_ManHashAnd( p, LitA[0], LitB[0] );
+ LitZ[1] = Gia_ManHashAnd( p, Gia_ManHashOr( p, LitA[1], LitB[1] ), Abc_LitNot(ZeroZ) );
+
+ //LitZ[0] = Gia_ManHashAnd( p, Gia_ManHashAnd(p, LitA[0], Abc_LitNot(LitA[1])), Gia_ManHashAnd(p, LitB[0], Abc_LitNot(LitB[1])) );
+ //LitZ[1] = Gia_ManHashAnd( p, Gia_ManHashOr(p, LitA[0], LitA[1]), Gia_ManHashOr(p, LitB[0], LitB[1]) );
+ //LitZ[1] = Gia_ManHashAnd( p, LitZ[1], Abc_LitNot(LitZ[0]) );
+}
+void Gia_ManDualAndN( Gia_Man_t * p, int * pLits, int n, int LitZ[2] )
+{
+ int i, LitZero = 0, LitOne = 0;
+ LitZ[0] = 1;
+ for ( i = 0; i < n; i++ )
+ {
+ int Lit = Gia_ManHashAnd( p, Abc_LitNot(pLits[2*i]), Abc_LitNot(pLits[2*i+1]) );
+ LitZero = Gia_ManHashOr( p, LitZero, Lit );
+ LitOne = Gia_ManHashOr( p, LitOne, pLits[2*i+1] );
+ LitZ[0] = Gia_ManHashAnd( p, LitZ[0], pLits[2*i] );
+ }
+ LitZ[1] = Gia_ManHashAnd( p, LitOne, Abc_LitNot(LitZero) );
+
+ if ( fForceZero ) LitZ[0] = Gia_ManHashAnd( p, LitZ[0], Abc_LitNot(LitZ[1]) );
+}
+/*
+module _DC(O, C, D);
+ output O;
+ input C, D;
+ assign O = D ? 1'bx : C;
+endmodule
+*/
+void Gia_ManDualDc( Gia_Man_t * p, int LitC[2], int LitD[2], int LitZ[2] )
+{
+ LitZ[0] = LitC[0];
+// LitZ[0] = Gia_ManHashMux( p, LitD[0], 0, LitC[0] );
+ LitZ[1] = Gia_ManHashOr(p, Gia_ManHashOr(p,LitD[0],LitD[1]), LitC[1] );
+
+ if ( fForceZero ) LitZ[0] = Gia_ManHashAnd( p, LitZ[0], Abc_LitNot(LitZ[1]) );
+}
+void Gia_ManDualMux( Gia_Man_t * p, int LitC[2], int LitT[2], int LitE[2], int LitZ[2] )
+{
+/*
+ // total logic size: 18 nodes
+ int Xnor = Gia_ManHashXor( p, Abc_LitNot(LitT[0]), LitE[0] );
+ int Cond = Gia_ManHashAnd( p, Abc_LitNot(LitT[1]), Abc_LitNot(LitE[1]) );
+ int pTempE[2], pTempT[2];
+ pTempE[0] = Gia_ManHashMux( p, LitC[0], LitT[0], LitE[0] );
+ pTempE[1] = Gia_ManHashMux( p, LitC[0], LitT[1], LitE[1] );
+ //pTempT[0] = LitT[0];
+ pTempT[0] = Gia_ManHashAnd( p, LitT[0], LitE[0] );
+ pTempT[1] = Gia_ManHashAnd( p, Cond, Xnor );
+ LitZ[0] = Gia_ManHashMux( p, LitC[1], pTempT[0], pTempE[0] );
+ LitZ[1] = Gia_ManHashMux( p, LitC[1], pTempT[1], pTempE[1] );
+*/
+ // total logic size: 14 nodes
+ int Xnor = Gia_ManHashXor( p, Abc_LitNot(LitT[0]), LitE[0] );
+ int Cond = Gia_ManHashAnd( p, Abc_LitNot(LitT[1]), Abc_LitNot(LitE[1]) );
+ int XVal1 = Abc_LitNot( Gia_ManHashAnd( p, Cond, Xnor ) );
+ int XVal0 = Gia_ManHashMux( p, LitC[0], LitT[1], LitE[1] );
+ LitZ[0] = Gia_ManHashMux( p, LitC[0], LitT[0], LitE[0] );
+ LitZ[1] = Gia_ManHashMux( p, LitC[1], XVal1, XVal0 );
+
+ if ( fForceZero ) LitZ[0] = Gia_ManHashAnd( p, LitZ[0], Abc_LitNot(LitZ[1]) );
+}
+int Gia_ManDualCompare( Gia_Man_t * p, int LitF[2], int LitS[2] )
+{
+ int iMiter = Gia_ManHashXor( p, LitF[0], LitS[0] );
+ iMiter = Gia_ManHashOr( p, LitF[1], iMiter );
+ iMiter = Gia_ManHashAnd( p, Abc_LitNot(LitS[1]), iMiter );
+ return iMiter;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acb_ObjToGiaDual( Gia_Man_t * pNew, Acb_Ntk_t * p, int iObj, Vec_Int_t * vTemp, Vec_Int_t * vCopies, int pRes[2] )
+{
+ //char * pName = Abc_NamStr( p->pDesign->pStrs, Acb_ObjName(p, iObj) );
+ int * pFanin, iFanin, k, Type;
+ assert( !Acb_ObjIsCio(p, iObj) );
+ Vec_IntClear( vTemp );
+ Acb_ObjForEachFaninFast( p, iObj, pFanin, iFanin, k )
+ {
+ int * pLits = Vec_IntEntryP( vCopies, 2*iFanin );
+ assert( pLits[0] >= 0 && pLits[1] >= 0 );
+ Vec_IntPushTwo( vTemp, pLits[0], pLits[1] );
+ }
+ Type = Acb_ObjType( p, iObj );
+ if ( Type == ABC_OPER_CONST_F )
+ {
+ pRes[0] = 0;
+ pRes[1] = 0;
+ return;
+ }
+ if ( Type == ABC_OPER_CONST_T )
+ {
+ pRes[0] = 1;
+ pRes[1] = 0;
+ return;
+ }
+ if ( Type == ABC_OPER_CONST_X )
+ {
+ pRes[0] = 0;
+ pRes[1] = 1;
+ return;
+ }
+ if ( Type == ABC_OPER_BIT_BUF )
+ {
+ pRes[0] = Vec_IntEntry(vTemp, 0);
+ pRes[1] = Vec_IntEntry(vTemp, 1);
+ return;
+ }
+ if ( Type == ABC_OPER_BIT_INV )
+ {
+ Gia_ManDualNot( pNew, Vec_IntArray(vTemp), pRes );
+ return;
+ }
+ if ( Type == ABC_OPER_TRI )
+ {
+ // in the file inputs are ordered as follows: _DC \n6_5[9] ( .O(\108 ), .C(\96 ), .D(\107 ));
+ // in this code, we expect them as follows: void Gia_ManDualDc( Gia_Man_t * p, int LitC[2], int LitD[2], int LitZ[2] )
+ assert( Vec_IntSize(vTemp) == 4 );
+ Gia_ManDualDc( pNew, Vec_IntArray(vTemp), Vec_IntArray(vTemp) + 2, pRes );
+ return;
+ }
+ if ( Type == ABC_OPER_BIT_MUX )
+ {
+ // in the file inputs are ordered as follows: _HMUX \U$1 ( .O(\282 ), .I0(1'b1), .I1(\277 ), .S(\281 ));
+ // in this code, we expect them as follows: void Gia_ManDualMux( Gia_Man_t * p, int LitC[2], int LitT[2], int LitE[2], int LitZ[2] )
+ assert( Vec_IntSize(vTemp) == 6 );
+ ABC_SWAP( int, Vec_IntArray(vTemp)[0], Vec_IntArray(vTemp)[4] );
+ ABC_SWAP( int, Vec_IntArray(vTemp)[1], Vec_IntArray(vTemp)[5] );
+ Gia_ManDualMux( pNew, Vec_IntArray(vTemp), Vec_IntArray(vTemp) + 2, Vec_IntArray(vTemp) + 4, pRes );
+ return;
+ }
+ if ( Type == ABC_OPER_BIT_AND || Type == ABC_OPER_BIT_NAND )
+ {
+ Gia_ManDualAndN( pNew, Vec_IntArray(vTemp), Vec_IntSize(vTemp)/2, pRes );
+ if ( Type == ABC_OPER_BIT_NAND )
+ pRes[0] = Abc_LitNot( pRes[0] );
+ return;
+ }
+ if ( Type == ABC_OPER_BIT_OR || Type == ABC_OPER_BIT_NOR )
+ {
+ int * pArray = Vec_IntArray( vTemp );
+ for ( k = 0; k < Vec_IntSize(vTemp)/2; k++ )
+ pArray[2*k] = Abc_LitNot( pArray[2*k] );
+ Gia_ManDualAndN( pNew, pArray, Vec_IntSize(vTemp)/2, pRes );
+ if ( Type == ABC_OPER_BIT_OR )
+ pRes[0] = Abc_LitNot( pRes[0] );
+ return;
+ }
+ if ( Type == ABC_OPER_BIT_XOR || Type == ABC_OPER_BIT_NXOR )
+ {
+ assert( Vec_IntSize(vTemp) == 4 );
+ Gia_ManDualXor2( pNew, Vec_IntArray(vTemp), Vec_IntArray(vTemp) + 2, pRes );
+ if ( Type == ABC_OPER_BIT_NXOR )
+ pRes[0] = Abc_LitNot( pRes[0] );
+ return;
+ }
+ assert( 0 );
+}
+Gia_Man_t * Acb_NtkGiaDeriveDual( Acb_Ntk_t * p )
+{
+ extern Vec_Int_t * Acb_NtkFindNodes2( Acb_Ntk_t * p );
+ Gia_Man_t * pNew, * pOne;
+ Vec_Int_t * vFanins, * vNodes;
+ Vec_Int_t * vCopies = Vec_IntStartFull( 2*Acb_NtkObjNum(p) );
+ int i, iObj, * pLits;
+ pNew = Gia_ManStart( 5 * Acb_NtkObjNum(p) );
+ pNew->pName = Abc_UtilStrsav(Acb_NtkName(p));
+ Gia_ManHashAlloc( pNew );
+ pLits = Vec_IntEntryP( vCopies, 0 );
+ pLits[0] = 0;
+ pLits[1] = 0;
+ Acb_NtkForEachCi( p, iObj, i )
+ {
+ pLits = Vec_IntEntryP( vCopies, 2*iObj );
+ pLits[0] = Gia_ManAppendCi(pNew);
+ pLits[1] = 0;
+ }
+ vFanins = Vec_IntAlloc( 4 );
+ vNodes = Acb_NtkFindNodes2( p );
+ Vec_IntForEachEntry( vNodes, iObj, i )
+ {
+ pLits = Vec_IntEntryP( vCopies, 2*iObj );
+ Acb_ObjToGiaDual( pNew, p, iObj, vFanins, vCopies, pLits );
+ }
+ Vec_IntFree( vNodes );
+ Vec_IntFree( vFanins );
+ Acb_NtkForEachCo( p, iObj, i )
+ {
+ pLits = Vec_IntEntryP( vCopies, 2*Acb_ObjFanin(p, iObj, 0) );
+ Gia_ManAppendCo( pNew, pLits[0] );
+ Gia_ManAppendCo( pNew, pLits[1] );
+ }
+ Vec_IntFree( vCopies );
+ pNew = Gia_ManCleanup( pOne = pNew );
+ Gia_ManStop( pOne );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Acb_NtkGiaDeriveMiter( Gia_Man_t * pOne, Gia_Man_t * pTwo, int Type )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj;
+ int i;
+ assert( Gia_ManCiNum(pOne) == Gia_ManCiNum(pTwo) );
+ assert( Gia_ManCoNum(pOne) == Gia_ManCoNum(pTwo) );
+ pNew = Gia_ManStart( Gia_ManObjNum(pOne) + Gia_ManObjNum(pTwo) + 5*Gia_ManCoNum(pOne)/2 );
+ pNew->pName = Abc_UtilStrsav( "miter" );
+ pNew->pSpec = NULL;
+ Gia_ManHashAlloc( pNew );
+ Gia_ManConst0(pOne)->Value = 0;
+ Gia_ManConst0(pTwo)->Value = 0;
+ Gia_ManForEachCi( pOne, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ Gia_ManForEachCi( pTwo, pObj, i )
+ pObj->Value = Gia_ManCi(pOne, i)->Value;
+ Gia_ManForEachAnd( pOne, pObj, i )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ Gia_ManForEachAnd( pTwo, pObj, i )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ Gia_ManForEachCo( pOne, pObj, i )
+ pObj->Value = Gia_ObjFanin0Copy(pObj);
+ Gia_ManForEachCo( pTwo, pObj, i )
+ pObj->Value = Gia_ObjFanin0Copy(pObj);
+ if ( Type == 0 ) // only main circuit
+ {
+ for ( i = 0; i < Gia_ManCoNum(pOne); i += 2 )
+ {
+ int pLitsF[2] = { Gia_ManCo(pOne, i)->Value, Gia_ManCo(pOne, i+1)->Value };
+ int pLitsS[2] = { Gia_ManCo(pTwo, i)->Value, Gia_ManCo(pTwo, i+1)->Value };
+ Gia_ManAppendCo( pNew, pLitsF[0] );
+ Gia_ManAppendCo( pNew, pLitsS[0] );
+ }
+ }
+ else if ( Type == 1 ) // only shadow circuit
+ {
+ for ( i = 0; i < Gia_ManCoNum(pOne); i += 2 )
+ {
+ int pLitsF[2] = { Gia_ManCo(pOne, i)->Value, Gia_ManCo(pOne, i+1)->Value };
+ int pLitsS[2] = { Gia_ManCo(pTwo, i)->Value, Gia_ManCo(pTwo, i+1)->Value };
+ Gia_ManAppendCo( pNew, pLitsF[1] );
+ Gia_ManAppendCo( pNew, pLitsS[1] );
+ }
+ }
+ else // comparator of the two
+ {
+ for ( i = 0; i < Gia_ManCoNum(pOne); i += 2 )
+ {
+ int pLitsF[2] = { Gia_ManCo(pOne, i)->Value, Gia_ManCo(pOne, i+1)->Value };
+ int pLitsS[2] = { Gia_ManCo(pTwo, i)->Value, Gia_ManCo(pTwo, i+1)->Value };
+ Gia_ManAppendCo( pNew, Gia_ManDualCompare( pNew, pLitsF, pLitsS ) );
+ }
+ }
+ Gia_ManHashStop( pNew );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acb_OutputFile( char * pFileName, Acb_Ntk_t * pNtkF, int * pModel )
+{
+ char * pFileName0 = pFileName? pFileName : "output";
+ FILE * pFile = fopen( pFileName0, "wb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open results file \"%s\".\n", pFileName0 );
+ return;
+ }
+ if ( pModel == NULL )
+ fprintf( pFile, "EQ\n" );
+ else
+ {
+ /*
+ NEQ
+ in 1
+ a 1
+ b 0
+ */
+ int i, iObj;
+ fprintf( pFile, "NEQ\n" );
+ Acb_NtkForEachPi( pNtkF, iObj, i )
+ fprintf( pFile, "%s %d\n", Acb_ObjNameStr(pNtkF, iObj), pModel[i] );
+ }
+ fclose( pFile );
+ printf( "Produced output file \"%s\".\n\n", pFileName0 );
+}
+int * Acb_NtkSolve( Gia_Man_t * p )
+{
+ extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan );
+ Aig_Man_t * pMan = Gia_ManToAig( p, 0 );
+ Abc_Ntk_t * pNtkTemp = Abc_NtkFromAigPhase( pMan );
+ Prove_Params_t Params, * pParams = &Params;
+ Prove_ParamsSetDefault( pParams );
+ pParams->fUseRewriting = 1;
+ pParams->fVerbose = 0;
+ Aig_ManStop( pMan );
+ if ( pNtkTemp )
+ {
+ abctime clk = Abc_Clock();
+ int RetValue = Abc_NtkIvyProve( &pNtkTemp, pParams );
+ int * pModel = pNtkTemp->pModel;
+ pNtkTemp->pModel = NULL;
+ Abc_NtkDelete( pNtkTemp );
+ printf( "The networks are %s. ", RetValue == 1 ? "equivalent" : (RetValue == 0 ? "NOT equivalent" : "UNDECIDED") );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ if ( RetValue == 0 )
+ return pModel;
+ }
+ return NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Various statistics.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acb_NtkPrintCecStats( Acb_Ntk_t * pNtk )
+{
+ int iObj, nDcs = 0, nMuxes = 0;
+ Acb_NtkForEachNode( pNtk, iObj )
+ if ( Acb_ObjType( pNtk, iObj ) == ABC_OPER_TRI )
+ nDcs++;
+ else if ( Acb_ObjType( pNtk, iObj ) == ABC_OPER_BIT_MUX )
+ nMuxes++;
+
+ printf( "PI = %6d ", Acb_NtkCiNum(pNtk) );
+ printf( "PO = %6d ", Acb_NtkCoNum(pNtk) );
+ printf( "Obj = %6d ", Acb_NtkObjNum(pNtk) );
+ printf( "DC = %4d ", nDcs );
+ printf( "Mux = %4d ", nMuxes );
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Changing the PI order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acb_NtkUpdateCiOrder( Acb_Ntk_t * pNtkF, Acb_Ntk_t * pNtkG )
+{
+ int i, iObj;
+ Vec_Int_t * vMap = Vec_IntStartFull( Acb_ManNameIdMax(pNtkG->pDesign) );
+ Vec_Int_t * vOrder = Vec_IntStartFull( Acb_NtkCiNum(pNtkG) );
+ Acb_NtkForEachCi( pNtkG, iObj, i )
+ Vec_IntWriteEntry( vMap, Acb_ObjName(pNtkG, iObj), i );
+ Acb_NtkForEachCi( pNtkF, iObj, i )
+ {
+ int NameIdG = Acb_ManStrId( pNtkG->pDesign, Acb_ObjNameStr(pNtkF, iObj) );
+ int iPerm = NameIdG < Vec_IntSize(vMap) ? Vec_IntEntry( vMap, NameIdG ) : -1;
+ if ( iPerm == -1 )
+ printf( "Cannot find name \"%s\" of PI %d of F among PIs of G.\n", Acb_ObjNameStr(pNtkF, iObj), i );
+ else
+ Vec_IntWriteEntry( vOrder, iPerm, iObj );
+ }
+ Vec_IntClear( &pNtkF->vCis );
+ Vec_IntAppend( &pNtkF->vCis, vOrder );
+ Vec_IntFree( vOrder );
+ Vec_IntFree( vMap );
+}
+int Acb_NtkCheckPiOrder( Acb_Ntk_t * pNtkF, Acb_Ntk_t * pNtkG )
+{
+ int i, nPis = Acb_NtkCiNum(pNtkF);
+ for ( i = 0; i < nPis; i++ )
+ {
+ char * pNameF = Acb_ObjNameStr( pNtkF, Acb_NtkCi(pNtkF, i) );
+ char * pNameG = Acb_ObjNameStr( pNtkG, Acb_NtkCi(pNtkG, i) );
+ if ( strcmp(pNameF, pNameG) )
+ {
+// printf( "PI %d has different names (%s and %s) in these networks.\n", i, pNameF, pNameG );
+ printf( "Networks have different PI names. Reordering PIs of the implementation network.\n" );
+ Acb_NtkUpdateCiOrder( pNtkF, pNtkG );
+ break;
+ }
+ }
+ if ( i == nPis )
+ printf( "Networks have the same PI names.\n" );
+ return i == nPis;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
void Acb_NtkRunTest( char * pFileNames[4], int fFancy, int fVerbose )
{
+ extern Acb_Ntk_t * Acb_VerilogSimpleRead( char * pFileName, char * pFileNameW );
+ extern void Gia_AigerWrite( Gia_Man_t * p, char * pFileName, int fWriteSymbols, int fCompact, int fWriteNewLine );
+
+ int fSolve = 1;
+ int * pModel = NULL;
+ Gia_Man_t * pGiaF = NULL;
+ Gia_Man_t * pGiaG = NULL;
+ Gia_Man_t * pGia = NULL;
+ Acb_Ntk_t * pNtkF = Acb_VerilogSimpleRead( pFileNames[0], NULL );
+ Acb_Ntk_t * pNtkG = Acb_VerilogSimpleRead( pFileNames[1], NULL );
+ if ( !pNtkF || !pNtkG )
+ return;
+
+ assert( Acb_NtkCiNum(pNtkF) == Acb_NtkCiNum(pNtkG) );
+ assert( Acb_NtkCoNum(pNtkF) == Acb_NtkCoNum(pNtkG) );
+
+ Acb_NtkCheckPiOrder( pNtkF, pNtkG );
+ //Acb_NtkCheckPiOrder( pNtkG, pNtkF );
+ Acb_NtkPrintCecStats( pNtkF );
+ Acb_NtkPrintCecStats( pNtkG );
+
+ pGiaF = Acb_NtkGiaDeriveDual( pNtkF );
+ pGiaG = Acb_NtkGiaDeriveDual( pNtkG );
+ pGia = Acb_NtkGiaDeriveMiter( pGiaF, pGiaG, 2 );
+ //Gia_AigerWrite( pGiaF, Extra_FileNameGenericAppend(pFileNames[1], "_f2.aig"), 0, 0, 0 );
+ //Gia_AigerWrite( pGiaG, Extra_FileNameGenericAppend(pFileNames[1], "_g2.aig"), 0, 0, 0 );
+ //Gia_AigerWrite( pGia, Extra_FileNameGenericAppend(pFileNames[1], "_miter_0.aig"), 0, 0, 0 );
+ //printf( "Written the miter info file \"%s\".\n", Extra_FileNameGenericAppend(pFileNames[1], "_miter_0.aig") );
+
+ //Gia_ManPrintStats( pGia, NULL );
+ //Gia_ManSimTry( pGiaF, pGiaG );
+
+ if ( fSolve )
+ {
+ pModel = Acb_NtkSolve( pGia );
+ Acb_OutputFile( pFileNames[2], pNtkF, pModel );
+ ABC_FREE( pModel );
+ }
+
+ Gia_ManStop( pGia );
+ Gia_ManStop( pGiaF );
+ Gia_ManStop( pGiaG );
+
+ Acb_ManFree( pNtkF->pDesign );
+ Acb_ManFree( pNtkG->pDesign );
}
diff --git a/src/base/acb/acbUtil.c b/src/base/acb/acbUtil.c
index 2243541b..ef106e86 100644
--- a/src/base/acb/acbUtil.c
+++ b/src/base/acb/acbUtil.c
@@ -21,6 +21,7 @@
#include "acb.h"
#include "base/abc/abc.h"
#include "base/io/ioAbc.h"
+#include "base/main/main.h"
ABC_NAMESPACE_IMPL_START
@@ -71,6 +72,15 @@ Vec_Int_t * Acb_ObjCollectTfi( Acb_Ntk_t * p, int iObj, int fTerm )
Acb_ObjCollectTfi_rec( p, iObj, fTerm );
return &p->vArray0;
}
+Vec_Int_t * Acb_ObjCollectTfiVec( Acb_Ntk_t * p, Vec_Int_t * vObjs )
+{
+ int i, iObj;
+ Vec_IntClear( &p->vArray0 );
+ Acb_NtkIncTravId( p );
+ Vec_IntForEachEntry( vObjs, iObj, i )
+ Acb_ObjCollectTfi_rec( p, iObj, 0 );
+ return &p->vArray0;
+}
void Acb_ObjCollectTfo_rec( Acb_Ntk_t * p, int iObj, int fTerm )
{
@@ -95,6 +105,219 @@ Vec_Int_t * Acb_ObjCollectTfo( Acb_Ntk_t * p, int iObj, int fTerm )
Acb_ObjCollectTfo_rec( p, iObj, fTerm );
return &p->vArray1;
}
+Vec_Int_t * Acb_ObjCollectTfoVec( Acb_Ntk_t * p, Vec_Int_t * vObjs )
+{
+ int i, iObj;
+ if ( !Acb_NtkHasObjFanout(p) )
+ Acb_NtkCreateFanout( p );
+ Vec_IntClear( &p->vArray1 );
+ Acb_NtkIncTravId( p );
+ Vec_IntForEachEntry( vObjs, iObj, i )
+ Acb_ObjCollectTfo_rec( p, iObj, 0 );
+ return &p->vArray1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Count the number of nodes driving the POs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Acb_NtkIsPiBuffers( Acb_Ntk_t * p, int iObj )
+{
+ if ( Acb_ObjIsCi(p, iObj) )
+ return 1;
+ if ( Acb_ObjFaninNum(p, iObj) != 1 )
+ return 0;
+ return Acb_NtkIsPiBuffers( p, Acb_ObjFanin(p, iObj, 0) );
+}
+int Acb_NtkCountPiBuffers( Acb_Ntk_t * p, Vec_Int_t * vObjs )
+{
+ int i, iObj, Count = 0;
+ Vec_IntForEachEntry( vObjs, iObj, i )
+ Count += Acb_NtkIsPiBuffers( p, iObj );
+ return Count;
+}
+int Acb_NtkCountPoDrivers( Acb_Ntk_t * p, Vec_Int_t * vObjs )
+{
+ int i, iObj, Count = 0;
+ Acb_NtkIncTravId( p );
+ Acb_NtkForEachCo( p, iObj, i )
+ {
+ int Fanin0 = Acb_ObjFanin0(p, iObj);
+ Acb_ObjSetTravIdCur( p, iObj );
+ Acb_ObjSetTravIdCur( p, Fanin0 );
+ if ( Acb_ObjFaninNum(p, Fanin0) == 1 )
+ Acb_ObjSetTravIdCur( p, Acb_ObjFanin0(p, Fanin0) );
+ }
+ Vec_IntForEachEntry( vObjs, iObj, i )
+ Count += Acb_ObjIsTravIdCur(p, iObj);
+ return Count;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compute MFFC size.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Acb_NtkNodeDeref_rec( Vec_Int_t * vRefs, Acb_Ntk_t * p, int iObj )
+{
+ int i, Fanin, * pFanins, Counter = 1;
+ if ( Acb_ObjIsCi(p, iObj) )
+ return 0;
+ Acb_ObjForEachFaninFast( p, iObj, pFanins, Fanin, i )
+ {
+ assert( Vec_IntEntry(vRefs, Fanin) > 0 );
+ Vec_IntAddToEntry( vRefs, Fanin, -1 );
+ if ( Vec_IntEntry(vRefs, Fanin) == 0 )
+ Counter += Acb_NtkNodeDeref_rec( vRefs, p, Fanin );
+ }
+ return Counter;
+}
+int Acb_NtkNodeRef_rec( Vec_Int_t * vRefs, Acb_Ntk_t * p, int iObj )
+{
+ int i, Fanin, * pFanins, Counter = 1;
+ if ( Acb_ObjIsCi(p, iObj) )
+ return 0;
+ Acb_ObjForEachFaninFast( p, iObj, pFanins, Fanin, i )
+ {
+ if ( Vec_IntEntry(vRefs, Fanin) == 0 )
+ Counter += Acb_NtkNodeRef_rec( vRefs, p, Fanin );
+ Vec_IntAddToEntry( vRefs, Fanin, 1 );
+ }
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computing and updating direct and reverse logic level.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acb_NtkCollectDeref_rec( Vec_Int_t * vRefs, Acb_Ntk_t * p, int iObj, Vec_Int_t * vRes )
+{
+ int i, Fanin, * pFanins;
+ if ( Acb_ObjIsCi(p, iObj) )
+ return;
+ Vec_IntPush( vRes, iObj );
+ Acb_ObjForEachFaninFast( p, iObj, pFanins, Fanin, i )
+ {
+ assert( Vec_IntEntry(vRefs, Fanin) > 0 );
+ Vec_IntAddToEntry( vRefs, Fanin, -1 );
+ if ( Vec_IntEntry(vRefs, Fanin) == 0 )
+ Acb_NtkCollectDeref_rec( vRefs, p, Fanin, vRes );
+ }
+}
+Vec_Int_t * Acb_NtkCollectMffc( Acb_Ntk_t * p, Vec_Int_t * vObjsRefed, Vec_Int_t * vObjsDerefed )
+{
+ Vec_Int_t * vRes = Vec_IntAlloc( 100 );
+ Vec_Int_t * vRefs = Vec_IntStart( Acb_NtkObjNumMax(p) );
+ int i, iObj, Fanin, * pFanins;
+ Acb_NtkForEachObj( p, iObj )
+ Acb_ObjForEachFaninFast( p, iObj, pFanins, Fanin, i )
+ Vec_IntAddToEntry( vRefs, Fanin, 1 );
+ Acb_NtkForEachCo( p, iObj, i )
+ Vec_IntAddToEntry( vRefs, iObj, 1 );
+ if ( vObjsRefed )
+ Vec_IntForEachEntry( vObjsRefed, iObj, i )
+ Vec_IntAddToEntry( vRefs, iObj, 1 );
+ Vec_IntForEachEntry( vObjsDerefed, iObj, i )
+ {
+ if ( Acb_ObjIsCo(p, iObj) )
+ iObj = Acb_ObjFanin0(p, iObj);
+ if ( Vec_IntEntry(vRefs, iObj) != 0 )
+ Acb_NtkCollectDeref_rec( vRefs, p, iObj, vRes );
+ }
+ Vec_IntFree( vRefs );
+ Vec_IntUniqify( vRes );
+ return vRes;
+}
+
+Vec_Int_t * Acb_NamesToIds( Acb_Ntk_t * pNtk, Vec_Int_t * vNamesInv, Vec_Ptr_t * vNames )
+{
+ Vec_Int_t * vRes = Vec_IntAlloc( Vec_PtrSize(vNames) );
+ char * pName; int i;
+ Vec_PtrForEachEntry( char *, vNames, pName, i )
+ {
+ int NameId = Acb_NtkStrId(pNtk, pName);
+ int iObjId = 0;
+ if ( NameId < 1 )
+ printf( "Cannot find name \"%s\" in the network \"%s\".\n", pName, pNtk->pDesign->pName );
+ else
+ iObjId = Vec_IntEntry( vNamesInv, NameId );
+ Vec_IntPush( vRes, iObjId );
+ }
+ return vRes;
+}
+int Acb_NtkCollectMfsGates( char * pFileName, Vec_Ptr_t * vNamesRefed, Vec_Ptr_t * vNamesDerefed, int nGates[5] )
+{
+ Acb_Ntk_t * pNtkF = Acb_VerilogSimpleRead( pFileName, NULL );
+ Vec_Int_t * vNamesInv = Vec_IntInvert( &pNtkF->vObjName, 0 ) ;
+ Vec_Int_t * vObjsRefed = Acb_NamesToIds( pNtkF, vNamesInv, vNamesRefed );
+ Vec_Int_t * vObjsDerefed = Acb_NamesToIds( pNtkF, vNamesInv, vNamesDerefed );
+ Vec_Int_t * vNodes = Acb_NtkCollectMffc( pNtkF, vObjsRefed, vObjsDerefed );
+ int i, iObj, RetValue = Vec_IntSize(vNodes);
+ Vec_IntFree( vNamesInv );
+ Vec_IntFree( vObjsRefed );
+ Vec_IntFree( vObjsDerefed );
+ for ( i = 0; i < 5; i++ )
+ nGates[i] = 0;
+ Vec_IntForEachEntry( vNodes, iObj, i )
+ {
+ int nFan = Acb_ObjFaninNum(pNtkF, iObj);
+ int Type = Acb_ObjType( pNtkF, iObj );
+ if ( Type == ABC_OPER_CONST_F )
+ nGates[0]++;
+ else if ( Type == ABC_OPER_CONST_T )
+ nGates[1]++;
+ else if ( Type == ABC_OPER_BIT_BUF || Type == ABC_OPER_CO )
+ nGates[2]++;
+ else if ( Type == ABC_OPER_BIT_INV )
+ nGates[3]++;
+ else
+ {
+ assert( nFan >= 2 );
+ nGates[4] += Acb_ObjFaninNum(pNtkF, iObj)-1;
+ }
+ }
+ Vec_IntFree( vNodes );
+ Acb_ManFree( pNtkF->pDesign );
+ return RetValue;
+}
+Vec_Ptr_t * Acb_NtkReturnMfsGates( char * pFileName, Vec_Ptr_t * vNodes )
+{
+ Vec_Ptr_t * vMffc = Vec_PtrAlloc( 100 );
+ Acb_Ntk_t * pNtkF = Acb_VerilogSimpleRead( pFileName, NULL );
+ Vec_Int_t * vNamesInv = Vec_IntInvert( &pNtkF->vObjName, 0 ) ;
+ Vec_Int_t * vNodeObjs = Acb_NamesToIds( pNtkF, vNamesInv, vNodes );
+ Vec_Int_t * vNodeMffc = Acb_NtkCollectMffc( pNtkF, NULL, vNodeObjs );
+ int i, iObj;
+ Vec_IntForEachEntry( vNodeMffc, iObj, i )
+ Vec_PtrPush( vMffc, Abc_UtilStrsav( Acb_ObjNameStr(pNtkF, iObj) ) );
+//Vec_IntPrint( vNodeMffc );
+//Vec_PtrPrintNames( vMffc );
+ Vec_IntFree( vNodeMffc );
+ Vec_IntFree( vNodeObjs );
+ Vec_IntFree( vNamesInv );
+ Acb_ManFree( pNtkF->pDesign );
+ return vMffc;
+}
/**Function*************************************************************
@@ -671,6 +894,8 @@ int Acb_NtkExtract( char * pFileName0, char * pFileName1, int fUseXors, int fVer
int nTargets = Vec_IntSize(&pNtkF->vTargets);
Gia_Man_t * pGiaF = Acb_NtkToGia2( pNtkF, fUseBuf, fUseXors, &pNtkF->vTargets, 0 );
Gia_Man_t * pGiaG = Acb_NtkToGia2( pNtkG, 0, 0, NULL, nTargets );
+ pGiaF->pSpec = Abc_UtilStrsav( pNtkF->pDesign->pSpec );
+ pGiaG->pSpec = Abc_UtilStrsav( pNtkG->pDesign->pSpec );
assert( Acb_NtkCiNum(pNtkF) == Acb_NtkCiNum(pNtkG) );
assert( Acb_NtkCoNum(pNtkF) == Acb_NtkCoNum(pNtkG) );
*ppGiaF = pGiaF;
@@ -784,6 +1009,8 @@ int Abc_NtkExtract( char * pFileName0, char * pFileName1, int fUseXors, int fVer
Gia_Man_t * pGiaG = Abc_NtkToGia2( pNtkG, 0 );
assert( Abc_NtkCiNum(pNtkF) == Abc_NtkCiNum(pNtkG) );
assert( Abc_NtkCoNum(pNtkF) == Abc_NtkCoNum(pNtkG) );
+ pGiaF->pSpec = Abc_UtilStrsav( pNtkF->pSpec );
+ pGiaG->pSpec = Abc_UtilStrsav( pNtkG->pSpec );
*ppGiaF = pGiaF;
*ppGiaG = pGiaG;
*pvNodes = Abc_NtkCollectCopies( pNtkF, pGiaF, pvNodesR, pvPolar );
@@ -846,7 +1073,7 @@ Vec_Int_t * Acb_NtkPlaces( char * pFileName, Vec_Ptr_t * vNames )
ABC_FREE( pBuffer );
return vPlaces;
}
-void Acb_NtkInsert( char * pFileNameIn, char * pFileNameOut, Vec_Ptr_t * vNames, int fNumber )
+void Acb_NtkInsert( char * pFileNameIn, char * pFileNameOut, Vec_Ptr_t * vNames, int fNumber, int fSkipMffc )
{
int i, k, Prev = 0, Pos, Pos2, iObj;
Vec_Int_t * vPlaces;
@@ -864,15 +1091,32 @@ void Acb_NtkInsert( char * pFileNameIn, char * pFileNameOut, Vec_Ptr_t * vNames,
printf( "Cannot open input file \"%s\".\n", pFileNameIn );
return;
}
- vPlaces = Acb_NtkPlaces( pFileNameIn, vNames );
- Vec_IntForEachEntryDouble( vPlaces, Pos, iObj, i )
+ if ( fSkipMffc )
{
- for ( k = Prev; k < Pos; k++ )
- fputc( pBuffer[k], pFile );
- fprintf( pFile, "// [t_%d = %s] //", iObj, (char *)Vec_PtrEntry(vNames, iObj) );
- Prev = Pos;
+ Vec_Ptr_t * vMffcNames = Acb_NtkReturnMfsGates( pFileNameIn, vNames );
+ vPlaces = Acb_NtkPlaces( pFileNameIn, vMffcNames );
+ Vec_IntForEachEntryDouble( vPlaces, Pos, iObj, i )
+ {
+ for ( k = Prev; k < Pos; k++ )
+ fputc( pBuffer[k], pFile );
+ fprintf( pFile, "// MFFC %d = %s //", iObj, (char *)Vec_PtrEntry(vMffcNames, iObj) );
+ Prev = Pos;
+ }
+ Vec_IntFree( vPlaces );
+ Vec_PtrFreeFree( vMffcNames );
+ }
+ else
+ {
+ vPlaces = Acb_NtkPlaces( pFileNameIn, vNames );
+ Vec_IntForEachEntryDouble( vPlaces, Pos, iObj, i )
+ {
+ for ( k = Prev; k < Pos; k++ )
+ fputc( pBuffer[k], pFile );
+ fprintf( pFile, "// [t_%d = %s] //", iObj, (char *)Vec_PtrEntry(vNames, iObj) );
+ Prev = Pos;
+ }
+ Vec_IntFree( vPlaces );
}
- Vec_IntFree( vPlaces );
pName = strstr(pBuffer, "endmodule");
Pos2 = pName - pBuffer;
for ( k = Prev; k < Pos2; k++ )
@@ -939,7 +1183,7 @@ void Acb_Ntk4CollectRing( Acb_Ntk_t * pNtk, Vec_Int_t * vStart, Vec_Int_t * vRes
}
void Acb_Ntk4DumpWeightsInt( Acb_Ntk_t * pNtk, Vec_Int_t * vObjs, char * pFileName )
{
- int i, iObj;//, Weight;
+ int i, iObj;//, Count = 0;//, Weight;
Vec_Int_t * vDists, * vStart, * vNexts;
FILE * pFile = fopen( pFileName, "wb" );
if ( pFile == NULL )
@@ -971,15 +1215,30 @@ void Acb_Ntk4DumpWeightsInt( Acb_Ntk_t * pNtk, Vec_Int_t * vObjs, char * pFileNa
// Vec_IntForEachEntry( vDists, Weight, i )
// if ( Weight && Acb_ObjNameStr(pNtk, i)[0] != '1' )
// fprintf( pFile, "%s %d\n", Acb_ObjNameStr(pNtk, i), 10000+Weight );
+/*
+ // mark reachable
+ Vec_IntClear( &pNtk->vArray0 );
+ Acb_NtkIncTravId( pNtk );
+ Acb_NtkForEachCo( pNtk, iObj, i )
+ if ( !Vec_IntEntry(vStatus, i) )
+ Acb_ObjCollectTfi_rec( pNtk, iObj, 0 );
+*/
Acb_NtkForEachObj( pNtk, iObj )
{
char * pName = Acb_ObjNameStr(pNtk, iObj);
int Weight = Vec_IntEntry(vDists, iObj);
if ( Weight == 0 )
Weight = 10000;
+/*
+ if ( !Acb_ObjSetTravIdCur(pNtk, iObj) )
+ {
+ Count++;
+ continue;
+ }
+*/
fprintf( pFile, "%s %d\n", pName, 100000+Weight );
}
-
+ //printf( "Skipped %d nodes.\n", Count );
Vec_IntFree( vDists );
fclose( pFile );
}
@@ -1000,27 +1259,6 @@ void Acb_Ntk4DumpWeights( char * pFileNameIn, Vec_Ptr_t * vObjNames, char * pFil
Vec_IntFree( vObjs );
}
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Acb_NtkRunSim( char * pFileName[4], int nWords, int nBeam, int LevL, int LevU, int fOrder, int fFancy, int fUseBuf, int fRandom, int fUseWeights, int fVerbose, int fVeryVerbose )
-{
- extern int Gia_Sim4Try( char * pFileName0, char * pFileName1, char * pFileName2, int nWords, int nBeam, int LevL, int LevU, int fOrder, int fFancy, int fUseBuf, int fVerbose );
- extern void Acb_NtkRunEco( char * pFileNames[4], int fCheck, int fRandom, int fVerbose, int fVeryVerbose );
- char * pFileNames[4] = { pFileName[2], pFileName[1], fUseWeights ? (char *)"weights.txt" : NULL, pFileName[2] };
- if ( Gia_Sim4Try( pFileName[0], pFileName[1], pFileName[2], nWords, nBeam, LevL, LevU, fOrder, fFancy, fUseBuf, fVerbose ) )
- Acb_NtkRunEco( pFileNames, 1, fRandom, fVerbose, fVeryVerbose );
-}
-
-
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/cba/cbaNtk.c b/src/base/cba/cbaNtk.c
index 5be0aa6c..c3f8fae9 100644
--- a/src/base/cba/cbaNtk.c
+++ b/src/base/cba/cbaNtk.c
@@ -445,7 +445,7 @@ void Cba_NtkObjOrder( Cba_Ntk_t * p, Vec_Int_t * vObjs, Vec_Int_t * vNameIds )
// printf( "%s \n", pName );
// printf( "\n" );
// do the sorting
- Vec_PtrSort( vNames, (int (*)(void))Cba_StrCmp );
+ Vec_PtrSort( vNames, (int (*)(const void *, const void *))Cba_StrCmp );
// print after
// Vec_PtrForEachEntry( char *, vNames, pName, i )
// printf( "%s \n", pName );
diff --git a/src/base/cmd/cmdHist.c b/src/base/cmd/cmdHist.c
index 218d832f..b8cfc98f 100644
--- a/src/base/cmd/cmdHist.c
+++ b/src/base/cmd/cmdHist.c
@@ -65,7 +65,8 @@ void Cmd_HistoryAddCommand( Abc_Frame_t * p, const char * command )
strncmp(Buffer,"time",4) &&
strncmp(Buffer,"quit",4) &&
strncmp(Buffer,"alias",5) &&
-// strncmp(Buffer,"source",6) &&
+ strncmp(Buffer,"source abc.rc",13) &&
+ strncmp(Buffer,"source ..\\abc.rc",16) &&
strncmp(Buffer,"history",7) && strncmp(Buffer,"hi ", 3) && strcmp(Buffer,"hi") &&
Buffer[strlen(Buffer)-1] != '?' )
{
diff --git a/src/base/io/io.c b/src/base/io/io.c
index a5cffbf4..5cf74ef9 100644
--- a/src/base/io/io.c
+++ b/src/base/io/io.c
@@ -24,6 +24,13 @@
#include "proof/abs/abs.h"
#include "sat/bmc/bmc.h"
+#ifdef WIN32
+#include <process.h>
+#define unlink _unlink
+#else
+#include <unistd.h>
+#endif
+
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
@@ -49,6 +56,7 @@ static int IoCommandReadVerilog ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandReadStatus ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandReadGig ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandReadJson ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int IoCommandReadSF ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWrite ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteHie ( Abc_Frame_t * pAbc, int argc, char **argv );
@@ -118,6 +126,7 @@ void Io_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "I/O", "read_status", IoCommandReadStatus, 0 );
Cmd_CommandAdd( pAbc, "I/O", "&read_gig", IoCommandReadGig, 0 );
Cmd_CommandAdd( pAbc, "I/O", "read_json", IoCommandReadJson, 0 );
+ Cmd_CommandAdd( pAbc, "I/O", "read_sf", IoCommandReadSF, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write", IoCommandWrite, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_hie", IoCommandWriteHie, 0 );
@@ -1415,6 +1424,73 @@ usage:
return 1;
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IoCommandReadSF( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Io_TransformSF2PLA( char * pNameIn, char * pNameOut );
+
+ Abc_Ntk_t * pNtk;
+ FILE * pFile;
+ char * pFileName, * pFileTemp = "_temp_sf_.pla";
+ int c;
+
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( argc != globalUtilOptind + 1 )
+ {
+ goto usage;
+ }
+
+ // get the input file name
+ pFileName = argv[globalUtilOptind];
+ if ( (pFile = fopen( pFileName, "r" )) == NULL )
+ {
+ fprintf( pAbc->Err, "Cannot open input file \"%s\". \n", pFileName );
+ return 1;
+ }
+ fclose( pFile );
+ Io_TransformSF2PLA( pFileName, pFileTemp );
+ pNtk = Io_Read( pFileTemp, IO_FILE_PLA, 1, 0 );
+ unlink( pFileTemp );
+ if ( pNtk == NULL )
+ return 1;
+ ABC_FREE( pNtk->pName );
+ pNtk->pName = Extra_FileNameGeneric( pFileName );
+ ABC_FREE( pNtk->pSpec );
+ pNtk->pSpec = Abc_UtilStrsav( pFileName );
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
+ Abc_FrameClearVerifStatus( pAbc );
+
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: read_sf [-h] <file>\n" );
+ fprintf( pAbc->Err, "\t reads file in SF format\n" );
+ fprintf( pAbc->Err, "\t-h : prints the command summary\n" );
+ fprintf( pAbc->Err, "\tfile : the name of a file to read\n" );
+ return 1;
+}
+
/**Function*************************************************************
@@ -2906,17 +2982,36 @@ usage:
***********************************************************************/
int IoCommandWriteVerilog( Abc_Frame_t * pAbc, int argc, char **argv )
{
+ extern void Io_WriteVerilogLut( Abc_Ntk_t * pNtk, char * pFileName, int nLutSize, int fFixed, int fNoModules );
char * pFileName;
- int c, fOnlyAnds = 0;
+ int c, fFixed = 0, fOnlyAnds = 0, fNoModules = 0;
+ int nLutSize = -1;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "ah" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Kfamh" ) ) != EOF )
{
switch ( c )
{
+ case 'K':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-K\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nLutSize = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nLutSize < 2 || nLutSize > 6 )
+ goto usage;
+ break;
+ case 'f':
+ fFixed ^= 1;
+ break;
case 'a':
fOnlyAnds ^= 1;
break;
+ case 'm':
+ fNoModules ^= 1;
+ break;
case 'h':
goto usage;
default:
@@ -2930,6 +3025,8 @@ int IoCommandWriteVerilog( Abc_Frame_t * pAbc, int argc, char **argv )
}
if ( argc != globalUtilOptind + 1 )
goto usage;
+ if ( fFixed )
+ nLutSize = 6;
// get the output file name
pFileName = argv[globalUtilOptind];
// call the corresponding file writer
@@ -2941,14 +3038,19 @@ int IoCommandWriteVerilog( Abc_Frame_t * pAbc, int argc, char **argv )
Io_WriteVerilog( pNtkTemp, pFileName, 1 );
Abc_NtkDelete( pNtkTemp );
}
+ else if ( nLutSize >= 2 && nLutSize <= 6 )
+ Io_WriteVerilogLut( pAbc->pNtkCur, pFileName, nLutSize, fFixed, fNoModules );
else
- Io_Write( pAbc->pNtkCur, pFileName, IO_FILE_VERILOG );
+ Io_Write( pAbc->pNtkCur, pFileName, IO_FILE_VERILOG );
return 0;
usage:
- fprintf( pAbc->Err, "usage: write_verilog [-ah] <file>\n" );
+ fprintf( pAbc->Err, "usage: write_verilog [-K num] [-famh] <file>\n" );
fprintf( pAbc->Err, "\t writes the current network in Verilog format\n" );
+ fprintf( pAbc->Err, "\t-K num : write the network using instances of K-LUTs (2 <= K <= 6) [default = not used]\n" );
+ fprintf( pAbc->Err, "\t-f : toggle using fixed format [default = %s]\n", fFixed? "yes":"no" );
fprintf( pAbc->Err, "\t-a : toggle writing expressions with only ANDs (without XORs and MUXes) [default = %s]\n", fOnlyAnds? "yes":"no" );
+ fprintf( pAbc->Err, "\t-m : toggle writing additional modules [default = %s]\n", !fNoModules? "yes":"no" );
fprintf( pAbc->Err, "\t-h : print the help massage\n" );
fprintf( pAbc->Err, "\tfile : the name of the file to write\n" );
return 1;
diff --git a/src/base/io/ioReadAiger.c b/src/base/io/ioReadAiger.c
index f87d971f..9cf41413 100644
--- a/src/base/io/ioReadAiger.c
+++ b/src/base/io/ioReadAiger.c
@@ -480,6 +480,7 @@ Abc_Ntk_t * Io_ReadAiger( char * pFileName, int fCheck )
if ( pCur < pContents + nFileSize && *pCur != 'c' )
{
int Counter = 0;
+ int fNodeNames = 0;
while ( pCur < pContents + nFileSize && *pCur != 'c' )
{
// get the terminal type
@@ -490,6 +491,12 @@ Abc_Ntk_t * Io_ReadAiger( char * pFileName, int fCheck )
vTerms = pNtkNew->vBoxes;
else if ( *pCur == 'o' || *pCur == 'b' || *pCur == 'c' || *pCur == 'j' || *pCur == 'f' )
vTerms = pNtkNew->vPos;
+ else if ( *pCur == 'n' )
+ {
+ fNodeNames++;
+ while ( *pCur++ != '\n' );
+ continue;
+ }
else
{
// fprintf( stdout, "Wrong terminal type.\n" );
@@ -543,6 +550,8 @@ Abc_Ntk_t * Io_ReadAiger( char * pFileName, int fCheck )
}
// if ( Counter )
// printf( "Io_ReadAiger(): Added %d default names for nameless I/O/register objects.\n", Counter );
+ if ( fNodeNames )
+ printf( "Io_ReadAiger(): The names of internal nodes are not supported. Ignoring %d node names.\n", fNodeNames );
}
else
{
diff --git a/src/base/io/ioReadBench.c b/src/base/io/ioReadBench.c
index 3ea3fb70..42eb908d 100644
--- a/src/base/io/ioReadBench.c
+++ b/src/base/io/ioReadBench.c
@@ -88,7 +88,7 @@ Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p )
Abc_Ntk_t * pNtk;
Abc_Obj_t * pNode, * pNet;
Vec_Str_t * vString;
- unsigned uTruth[8];
+ unsigned uTruth[2048];
char * pType, ** ppNames, * pString;
int iLine, nNames, nDigits, fLutsPresent = 0;
@@ -161,7 +161,7 @@ Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p )
ppNames = (char **)vTokens->pArray + 3;
nNames = vTokens->nSize - 3;
// check the number of inputs
- if ( nNames > 8 )
+ if ( nNames > 15 )
{
printf( "%s: Currently cannot read truth tables with more than 8 inputs (%d).\n", Extra_FileReaderGetFileName(p), nNames );
Vec_StrFree( vString );
diff --git a/src/base/io/ioReadBlif.c b/src/base/io/ioReadBlif.c
index 405b44d6..e8979c9b 100644
--- a/src/base/io/ioReadBlif.c
+++ b/src/base/io/ioReadBlif.c
@@ -22,6 +22,9 @@
#include "base/main/main.h"
#include "map/mio/mio.h"
+
+
+
ABC_NAMESPACE_IMPL_START
@@ -877,10 +880,13 @@ int Io_ReadBlifNetworkInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
return 1;
}
// set timing info
- //Abc_NtkTimeSetArrival( p->pNtkCur, Abc_ObjFanin0(pNet)->Id, (float)TimeRise, (float)TimeFall );
- Vec_IntPush( p->vInArrs, Abc_ObjFanin0(pNet)->Id );
- Vec_IntPush( p->vInArrs, Abc_Float2Int((float)TimeRise) );
- Vec_IntPush( p->vInArrs, Abc_Float2Int((float)TimeFall) );
+ // printf("Debug: Forcing setting of arrival times\n");
+ if (Abc_ObjFaninNum(pNet) >0){
+ Abc_NtkTimeSetArrival( p->pNtkCur, Abc_ObjFanin0(pNet)->Id, (float)TimeRise, (float)TimeFall );
+ Vec_IntPush( p->vInArrs, Abc_ObjFanin0(pNet)->Id );
+ Vec_IntPush( p->vInArrs, Abc_Float2Int((float)TimeRise) );
+ Vec_IntPush( p->vInArrs, Abc_Float2Int((float)TimeFall) );
+ }
return 0;
}
@@ -928,7 +934,10 @@ int Io_ReadBlifNetworkOutputRequired( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
return 1;
}
// set timing info
-// Abc_NtkTimeSetRequired( p->pNtkCur, Abc_ObjFanout0(pNet)->Id, (float)TimeRise, (float)TimeFall );
+ // printf("Setting required time for object %d to R %f F %f\n",
+ // Abc_ObjFanout0(pNet)->Id, (float)TimeRise, (float)TimeFall );
+
+ Abc_NtkTimeSetRequired( p->pNtkCur, Abc_ObjFanout0(pNet)->Id, (float)TimeRise, (float)TimeFall );
Vec_IntPush( p->vOutReqs, Abc_ObjFanout0(pNet)->Id );
Vec_IntPush( p->vOutReqs, Abc_Float2Int((float)TimeRise) );
Vec_IntPush( p->vOutReqs, Abc_Float2Int((float)TimeFall) );
diff --git a/src/base/io/ioReadBlifMv.c b/src/base/io/ioReadBlifMv.c
index c1808ef5..e5c6fe49 100644
--- a/src/base/io/ioReadBlifMv.c
+++ b/src/base/io/ioReadBlifMv.c
@@ -1351,7 +1351,8 @@ static int Io_MvParseLineSubckt( Io_MvMod_t * p, char * pLine )
Abc_Ntk_t * pModel;
Abc_Obj_t * pBox, * pNet, * pTerm;
char * pToken, * pName, * pName2, ** ppNames;
- int nEquals, Last, i, k;
+ int nEquals, i, k;
+ word Last;
// split the line into tokens
nEquals = Io_MvCountChars( pLine, '=' );
@@ -1404,9 +1405,9 @@ static int Io_MvParseLineSubckt( Io_MvMod_t * p, char * pLine )
pName2 = NULL;
pName = Abc_ObjName(Abc_ObjFanout0(pTerm));
for ( k = 0; k < nEquals; k++ )
- if ( !strcmp( ppNames[2*((k+Last)%nEquals)], pName ) )
+ if ( !strcmp( ppNames[2*(int)((k+Last)%nEquals)], pName ) )
{
- pName2 = ppNames[2*((k+Last)%nEquals)+1];
+ pName2 = ppNames[2*(int)((k+Last)%nEquals)+1];
Last = k+Last+1;
break;
}
@@ -1656,7 +1657,7 @@ static int Io_MvWriteValues( Abc_Obj_t * pNode, Vec_Str_t * vFunc )
***********************************************************************/
static int Io_MvParseLiteralMv( Io_MvMod_t * p, Abc_Obj_t * pNode, char * pToken, Vec_Str_t * vFunc, int iLit )
{
- char Buffer[10];
+ char Buffer[16];
Io_MvVar_t * pVar;
Abc_Obj_t * pFanin, * pNet;
char * pCur, * pNext;
diff --git a/src/base/io/ioUtil.c b/src/base/io/ioUtil.c
index c6b47b11..ddfcc91a 100644
--- a/src/base/io/ioUtil.c
+++ b/src/base/io/ioUtil.c
@@ -862,6 +862,62 @@ FILE * Io_FileOpen( const char * FileName, const char * PathVar, const char * Mo
}
}
+/**Function*************************************************************
+
+ Synopsis [Tranform SF into PLA.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_TransformSF2PLA( char * pNameIn, char * pNameOut )
+{
+ int fStart = 0, Size = 1000000;
+ char * pBuffer, * pToken;
+ FILE * pFileIn = fopen( pNameIn, "rb" );
+ FILE * pFileOut = fopen( pNameOut, "wb" );
+ if ( pFileIn == NULL )
+ {
+ if ( pFileOut ) fclose( pFileOut );
+ printf( "Cannot open file \"%s\" for reading.\n", pNameIn );
+ return;
+ }
+ if ( pFileOut == NULL )
+ {
+ if ( pFileIn ) fclose( pFileIn );
+ printf( "Cannot open file \"%s\" for reading.\n", pNameOut );
+ return;
+ }
+ pBuffer = ABC_ALLOC( char, Size );
+ fprintf( pFileOut, ".type fd\n" );
+ while ( fgets(pBuffer, Size, pFileIn) )
+ {
+ if ( strstr(pBuffer, "END_SDF") )
+ break;
+ if ( strstr(pBuffer, "SDF") )
+ {
+ char * pRes = fgets(pBuffer, Size, pFileIn);
+ assert( pRes != NULL );
+ if ( (pToken = strtok( pBuffer, " \t\r\n" )) )
+ fprintf( pFileOut, ".i %d\n", atoi(pToken) );
+ if ( (pToken = strtok( NULL, " \t\r\n" )) )
+ fprintf( pFileOut, ".o %d\n", atoi(pToken) );
+ if ( (pToken = strtok( NULL, " \t\r\n" )) )
+ fprintf( pFileOut, ".p %d\n", atoi(pToken) );
+ fStart = 1;
+ }
+ else if ( fStart )
+ fprintf( pFileOut, "%s", pBuffer );
+ }
+ fprintf( pFileOut, ".e\n" );
+ fclose( pFileIn );
+ fclose( pFileOut );
+ ABC_FREE( pBuffer );
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/io/ioWriteBench.c b/src/base/io/ioWriteBench.c
index 81d64582..23de719e 100644
--- a/src/base/io/ioWriteBench.c
+++ b/src/base/io/ioWriteBench.c
@@ -259,7 +259,7 @@ int Io_WriteBenchLutOneNode( FILE * pFile, Abc_Obj_t * pNode, Vec_Int_t * vTruth
int i, nFanins;
assert( Abc_ObjIsNode(pNode) );
nFanins = Abc_ObjFaninNum(pNode);
- assert( nFanins <= 8 );
+ assert( nFanins <= 15 );
// compute the truth table
pTruth = Hop_ManConvertAigToTruth( (Hop_Man_t *)pNode->pNtk->pManFunc, Hop_Regular((Hop_Obj_t *)pNode->pData), nFanins, vTruth, 0 );
if ( Hop_IsComplement((Hop_Obj_t *)pNode->pData) )
diff --git a/src/base/io/ioWriteDot.c b/src/base/io/ioWriteDot.c
index d9687c6e..0ab3c4d2 100644
--- a/src/base/io/ioWriteDot.c
+++ b/src/base/io/ioWriteDot.c
@@ -100,7 +100,7 @@ void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
// transform logic functions from BDD to SOP
if ( (fHasBdds = Abc_NtkIsBddLogic(pNtk)) )
{
- if ( !Abc_NtkBddToSop(pNtk, -1, ABC_INFINITY) )
+ if ( !Abc_NtkBddToSop(pNtk, -1, ABC_INFINITY, 1) )
{
printf( "Io_WriteDotNtk(): Converting to SOPs has failed.\n" );
return;
@@ -463,7 +463,7 @@ void Io_WriteDotSeq( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
// transform logic functions from BDD to SOP
if ( (fHasBdds = Abc_NtkIsBddLogic(pNtk)) )
{
- if ( !Abc_NtkBddToSop(pNtk, -1, ABC_INFINITY) )
+ if ( !Abc_NtkBddToSop(pNtk, -1, ABC_INFINITY, 1) )
{
printf( "Io_WriteDotNtk(): Converting to SOPs has failed.\n" );
return;
diff --git a/src/base/io/ioWriteVerilog.c b/src/base/io/ioWriteVerilog.c
index 2e481324..e05aed2e 100644
--- a/src/base/io/ioWriteVerilog.c
+++ b/src/base/io/ioWriteVerilog.c
@@ -567,6 +567,14 @@ void Io_WriteVerilogObjects( FILE * pFile, Abc_Ntk_t * pNtk, int fOnlyAnds )
Hop_IthVar((Hop_Man_t *)pNtk->pManFunc, k)->pData = Extra_UtilStrsav(Io_WriteVerilogGetName(Abc_ObjName(pFanin)));
// write the formula
Hop_ObjPrintVerilog( pFile, pFunc, vLevels, 0, fOnlyAnds );
+ if ( pObj->fPersist )
+ {
+ Abc_Obj_t * pFan0 = Abc_ObjFanin0(Abc_ObjFanin(pObj, 0));
+ Abc_Obj_t * pFan1 = Abc_ObjFanin0(Abc_ObjFanin(pObj, 1));
+ int Cond = Abc_ObjIsNode(pFan0) && Abc_ObjIsNode(pFan1) && !pFan0->fPersist && !pFan1->fPersist;
+ fprintf( pFile, "; // MUXF7 %s\n", Cond ? "":"to be legalized" );
+ }
+ else
fprintf( pFile, ";\n" );
// clear the input names
Abc_ObjForEachFanin( pObj, pFanin, k )
@@ -631,10 +639,8 @@ int Io_WriteVerilogWiresCount( Abc_Ntk_t * pNtk )
char * Io_WriteVerilogGetName( char * pName )
{
static char Buffer[500];
- int Length, i;
- Length = strlen(pName);
- // consider the case of a signal having name "0" or "1"
- if ( !(Length == 1 && (pName[0] == '0' || pName[0] == '1')) )
+ int i, Length = strlen(pName);
+ if ( pName[0] < '0' || pName[0] > '9' )
{
for ( i = 0; i < Length; i++ )
if ( !((pName[i] >= 'a' && pName[i] <= 'z') ||
@@ -653,6 +659,248 @@ char * Io_WriteVerilogGetName( char * pName )
return Buffer;
}
+
+/**Function*************************************************************
+
+ Synopsis [Write the network of K-input LUTs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_WriteLutModule( FILE * pFile, int nLutSize )
+{
+ fprintf( pFile, "module lut%d #( parameter TT = %d\'h0 ) ( input [%d:0] in, output out );\n", nLutSize, 1<<nLutSize, nLutSize-1 );
+ fprintf( pFile, " assign out = TT[in];\n" );
+ fprintf( pFile, "endmodule\n\n" );
+}
+void Io_WriteFixedModules( FILE * pFile )
+{
+ fprintf( pFile, "module LUT6 #( parameter INIT = 64\'h0000000000000000 ) (\n" );
+ fprintf( pFile, " output O,\n" );
+ fprintf( pFile, " input I0,\n" );
+ fprintf( pFile, " input I1,\n" );
+ fprintf( pFile, " input I2,\n" );
+ fprintf( pFile, " input I3,\n" );
+ fprintf( pFile, " input I4,\n" );
+ fprintf( pFile, " input I5\n" );
+ fprintf( pFile, ");\n" );
+ fprintf( pFile, " assign O = INIT[ {I5, I4, I3, I2, I1, I0} ];\n" );
+ fprintf( pFile, "endmodule\n\n" );
+
+ fprintf( pFile, "module MUXF7 (\n" );
+ fprintf( pFile, " output O,\n" );
+ fprintf( pFile, " input I0,\n" );
+ fprintf( pFile, " input I1,\n" );
+ fprintf( pFile, " input S\n" );
+ fprintf( pFile, ");\n" );
+ fprintf( pFile, " assign O = S ? I1 : I0;\n" );
+ fprintf( pFile, "endmodule\n\n" );
+
+ fprintf( pFile, "module MUXF8 (\n" );
+ fprintf( pFile, " output O,\n" );
+ fprintf( pFile, " input I0,\n" );
+ fprintf( pFile, " input I1,\n" );
+ fprintf( pFile, " input S\n" );
+ fprintf( pFile, ");\n" );
+ fprintf( pFile, " assign O = S ? I1 : I0;\n" );
+ fprintf( pFile, "endmodule\n\n" );
+}
+void Io_WriteVerilogObjectsLut( FILE * pFile, Abc_Ntk_t * pNtk, int nLutSize, int fFixed )
+{
+ Abc_Ntk_t * pNtkBox;
+ Abc_Obj_t * pObj, * pTerm;
+ int i, k, Counter, nDigits, Length = 0;
+
+ // write boxes
+ nDigits = Abc_Base10Log( Abc_NtkBoxNum(pNtk)-Abc_NtkLatchNum(pNtk) );
+ Counter = 0;
+ Abc_NtkForEachBox( pNtk, pObj, i )
+ {
+ if ( Abc_ObjIsLatch(pObj) )
+ continue;
+ pNtkBox = (Abc_Ntk_t *)pObj->pData;
+ fprintf( pFile, " %s box%0*d", pNtkBox->pName, nDigits, Counter++ );
+ fprintf( pFile, "(" );
+ Abc_NtkForEachPi( pNtkBox, pTerm, k )
+ {
+ fprintf( pFile, ".%s", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(pTerm))) );
+ fprintf( pFile, "(%s), ", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanin0(Abc_ObjFanin(pObj,k)))) );
+ }
+ Abc_NtkForEachPo( pNtkBox, pTerm, k )
+ {
+ fprintf( pFile, ".%s", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanin0(pTerm))) );
+ fprintf( pFile, "(%s)%s", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(Abc_ObjFanout(pObj,k)))), k==Abc_NtkPoNum(pNtkBox)-1? "":", " );
+ }
+ fprintf( pFile, ");\n" );
+ }
+
+ // find the longest signal name
+ Abc_NtkForEachNode( pNtk, pObj, i )
+ {
+ Length = Abc_MaxInt( Length, strlen(Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(pObj)))) );
+ Abc_ObjForEachFanin( pObj, pTerm, k )
+ Length = Abc_MaxInt( Length, strlen(Io_WriteVerilogGetName(Abc_ObjName(pTerm))) );
+ }
+
+ // write LUT instances
+ nDigits = Abc_Base10Log( Abc_NtkNodeNum(pNtk) );
+ Counter = 0;
+ if ( fFixed )
+ Abc_NtkForEachNode( pNtk, pObj, i )
+ {
+ if ( pObj->fPersist )
+ {
+ int One = Abc_ObjFanin0(Abc_ObjFanin(pObj, 1))->fPersist && Abc_ObjFanin0(Abc_ObjFanin(pObj, 2))->fPersist;
+ fprintf( pFile, " MUXF%d ", 7+One );
+ fprintf( pFile, " mux_%0*d (", nDigits, Counter++ );
+ fprintf( pFile, " %*s", Length, Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(pObj))) );
+ for ( k = Abc_ObjFaninNum(pObj) - 1; k >= 0; k-- )
+ fprintf( pFile, ", %*s", Length, Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanin(pObj, k))) );
+ fprintf( pFile, " );\n" );
+ }
+ else
+ {
+ word Truth = Abc_SopToTruth( (char *)pObj->pData, Abc_ObjFaninNum(pObj) );
+ fprintf( pFile, " LUT6 #(64\'h" );
+ fprintf( pFile, "%08x%08x", (unsigned)(Truth >> 32), (unsigned)Truth );
+ fprintf( pFile, ") lut_%0*d (", nDigits, Counter++ );
+ fprintf( pFile, " %*s", Length, Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(pObj))) );
+ for ( k = 0; k < Abc_ObjFaninNum(pObj); k++ )
+ fprintf( pFile, ", %*s", Length, Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanin(pObj, k))) );
+ for ( ; k < 6; k++ )
+ fprintf( pFile, ", %*s", Length, "1\'b0" );
+ fprintf( pFile, " );\n" );
+ }
+ }
+ else
+ Abc_NtkForEachNode( pNtk, pObj, i )
+ {
+ word Truth = Abc_SopToTruth( (char *)pObj->pData, Abc_ObjFaninNum(pObj) );
+ fprintf( pFile, " lut%d #(%d\'h", nLutSize, 1<<nLutSize );
+ if ( nLutSize == 6 )
+ fprintf( pFile, "%08x%08x", (unsigned)(Truth >> 32), (unsigned)Truth );
+ else
+ fprintf( pFile, "%0*x", 1<<(nLutSize-2), Abc_InfoMask(1 << nLutSize) & (unsigned)Truth );
+ fprintf( pFile, ") lut_%0*d ( {", nDigits, Counter++ );
+ for ( k = nLutSize - 1; k >= Abc_ObjFaninNum(pObj); k-- )
+ fprintf( pFile, "%*s, ", Length, "1\'b0" );
+ for ( k = Abc_ObjFaninNum(pObj) - 1; k >= 0; k-- )
+ fprintf( pFile, "%*s%s", Length, Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanin(pObj, k))), k==0 ? "":", " );
+ fprintf( pFile, "}, %*s );\n", Length, Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(pObj))) );
+ }
+}
+void Io_WriteVerilogLutInt( FILE * pFile, Abc_Ntk_t * pNtk, int nLutSize, int fFixed )
+{
+ // write inputs and outputs
+// fprintf( pFile, "module %s ( gclk,\n ", Abc_NtkName(pNtk) );
+ fprintf( pFile, "module %s ( ", Io_WriteVerilogGetName(Abc_NtkName(pNtk)) );
+ // add the clock signal if it does not exist
+ if ( Abc_NtkLatchNum(pNtk) > 0 && Nm_ManFindIdByName(pNtk->pManName, "clock", ABC_OBJ_PI) == -1 )
+ fprintf( pFile, "clock, " );
+ // write other primary inputs
+ fprintf( pFile, "\n " );
+ if ( Abc_NtkPiNum(pNtk) > 0 )
+ {
+ Io_WriteVerilogPis( pFile, pNtk, 3 );
+ fprintf( pFile, ",\n " );
+ }
+ if ( Abc_NtkPoNum(pNtk) > 0 )
+ Io_WriteVerilogPos( pFile, pNtk, 3 );
+ fprintf( pFile, " );\n\n" );
+ // add the clock signal if it does not exist
+ if ( Abc_NtkLatchNum(pNtk) > 0 && Nm_ManFindIdByName(pNtk->pManName, "clock", ABC_OBJ_PI) == -1 )
+ fprintf( pFile, " input clock;\n" );
+ // write inputs, outputs, registers, and wires
+ if ( Abc_NtkPiNum(pNtk) > 0 )
+ {
+// fprintf( pFile, " input gclk," );
+ fprintf( pFile, " input " );
+ Io_WriteVerilogPis( pFile, pNtk, 10 );
+ fprintf( pFile, ";\n" );
+ }
+ if ( Abc_NtkPoNum(pNtk) > 0 )
+ {
+ fprintf( pFile, " output" );
+ Io_WriteVerilogPos( pFile, pNtk, 5 );
+ fprintf( pFile, ";\n\n" );
+ }
+ // if this is not a blackbox, write internal signals
+ if ( !Abc_NtkHasBlackbox(pNtk) )
+ {
+ if ( Abc_NtkLatchNum(pNtk) > 0 )
+ {
+ fprintf( pFile, " reg" );
+ Io_WriteVerilogRegs( pFile, pNtk, 4 );
+ fprintf( pFile, ";\n\n" );
+ }
+ if ( Io_WriteVerilogWiresCount(pNtk) > 0 )
+ {
+ fprintf( pFile, " wire" );
+ Io_WriteVerilogWires( pFile, pNtk, 4 );
+ fprintf( pFile, ";\n\n" );
+ }
+ // write nodes
+ Io_WriteVerilogObjectsLut( pFile, pNtk, nLutSize, fFixed );
+ // write registers
+ if ( Abc_NtkLatchNum(pNtk) > 0 )
+ {
+ fprintf( pFile, "\n" );
+ Io_WriteVerilogLatches( pFile, pNtk );
+ }
+ }
+ // finalize the file
+ fprintf( pFile, "\nendmodule\n\n" );
+}
+void Io_WriteVerilogLut( Abc_Ntk_t * pNtk, char * pFileName, int nLutSize, int fFixed, int fNoModules )
+{
+ FILE * pFile;
+ Abc_Ntk_t * pNtkTemp;
+ Abc_Obj_t * pObj;
+ int i, Counter = 0;
+ Abc_NtkForEachNode( pNtk, pObj, i )
+ if ( Abc_ObjFaninNum(pObj) > nLutSize )
+ {
+ if ( Counter < 3 )
+ printf( "Node \"%s\" has the fanin count (%d) larger than the LUT size (%d).\n", Abc_ObjName(pObj), Abc_ObjFaninNum(pObj), nLutSize );
+ Counter++;
+ }
+ if ( Counter )
+ {
+ printf( "In total, %d internal logic nodes exceed the fanin count limit. Verilog is not written.\n", Counter );
+ return;
+ }
+
+ // start the output stream
+ pFile = fopen( pFileName, "w" );
+ if ( pFile == NULL )
+ {
+ fprintf( stdout, "Io_WriteVerilog(): Cannot open the output file \"%s\".\n", pFileName );
+ return;
+ }
+
+ // write the equations for the network
+ fprintf( pFile, "// Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() );
+ fprintf( pFile, "\n" );
+ if ( !fNoModules )
+ {
+ if ( fFixed )
+ Io_WriteFixedModules( pFile );
+ else
+ Io_WriteLutModule( pFile, nLutSize );
+ }
+ pNtkTemp = Abc_NtkToNetlist( pNtk );
+ Abc_NtkToSop( pNtkTemp, -1, ABC_INFINITY );
+ Io_WriteVerilogLutInt( pFile, pNtkTemp, nLutSize, fFixed );
+ Abc_NtkDelete( pNtkTemp );
+
+ fprintf( pFile, "\n" );
+ fclose( pFile );
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/main/abcapis.h b/src/base/main/abcapis.h
index e384896d..d34306ba 100644
--- a/src/base/main/abcapis.h
+++ b/src/base/main/abcapis.h
@@ -78,8 +78,11 @@ extern ABC_DLL void Abc_NtkSetFlopNum( Abc_Frame_t * pAbc, int nFlops );
// procedures to input/output 'mini LUT'
extern ABC_DLL void Abc_FrameGiaInputMiniLut( Abc_Frame_t * pAbc, void * pMiniLut );
+extern ABC_DLL void Abc_FrameGiaInputMiniLut2( Abc_Frame_t * pAbc, void * pMiniLut );
extern ABC_DLL void * Abc_FrameGiaOutputMiniLut( Abc_Frame_t * pAbc );
extern ABC_DLL char * Abc_FrameGiaOutputMiniLutAttr( Abc_Frame_t * pAbc, void * pMiniLut );
+extern ABC_DLL int * Abc_FrameReadMiniLutSwitching( Abc_Frame_t * pAbc );
+extern ABC_DLL int * Abc_FrameReadMiniLutSwitchingPo( Abc_Frame_t * pAbc );
// procedures to input/output NDR data-structure
extern ABC_DLL void Abc_FrameInputNdr( Abc_Frame_t * pAbc, void * pData );
diff --git a/src/base/main/main.h b/src/base/main/main.h
index 2efb3358..f3457e27 100644
--- a/src/base/main/main.h
+++ b/src/base/main/main.h
@@ -105,10 +105,13 @@ extern ABC_DLL void * Abc_FrameReadManDd();
extern ABC_DLL void * Abc_FrameReadManDec();
extern ABC_DLL void * Abc_FrameReadManDsd();
extern ABC_DLL void * Abc_FrameReadManDsd2();
+extern ABC_DLL Vec_Ptr_t * Abc_FrameReadSignalNames();
+extern ABC_DLL char * Abc_FrameReadSpecName();
extern ABC_DLL char * Abc_FrameReadFlag( char * pFlag );
extern ABC_DLL int Abc_FrameIsFlagEnabled( char * pFlag );
extern ABC_DLL int Abc_FrameIsBatchMode();
+extern ABC_DLL void Abc_FrameSetBatchMode( int Mode );
extern ABC_DLL int Abc_FrameIsBridgeMode();
extern ABC_DLL void Abc_FrameSetBridgeMode();
@@ -147,6 +150,8 @@ extern ABC_DLL void Abc_FrameSetCnf( Vec_Int_t * vInv );
extern ABC_DLL void Abc_FrameSetStr( Vec_Str_t * vInv );
extern ABC_DLL void Abc_FrameSetJsonStrs( Abc_Nam_t * pStrs );
extern ABC_DLL void Abc_FrameSetJsonObjs( Vec_Wec_t * vObjs );
+extern ABC_DLL void Abc_FrameSetSignalNames( Vec_Ptr_t * vNames );
+extern ABC_DLL void Abc_FrameSetSpecName( char * pFileName );
extern ABC_DLL int Abc_FrameCheckPoConst( Abc_Frame_t * p, int iPoNum );
diff --git a/src/base/main/mainFrame.c b/src/base/main/mainFrame.c
index 1d54f4e4..ba41d4c1 100644
--- a/src/base/main/mainFrame.c
+++ b/src/base/main/mainFrame.c
@@ -67,6 +67,8 @@ void * Abc_FrameReadManDec() { if ( s_GlobalFram
void * Abc_FrameReadManDsd() { return s_GlobalFrame->pManDsd; }
void * Abc_FrameReadManDsd2() { return s_GlobalFrame->pManDsd2; }
char * Abc_FrameReadFlag( char * pFlag ) { return Cmd_FlagReadByName( s_GlobalFrame, pFlag ); }
+Vec_Ptr_t * Abc_FrameReadSignalNames() { return s_GlobalFrame->vSignalNames; }
+char * Abc_FrameReadSpecName() { return s_GlobalFrame->pSpecName; }
int Abc_FrameReadBmcFrames( Abc_Frame_t * p ) { return s_GlobalFrame->nFrames; }
int Abc_FrameReadProbStatus( Abc_Frame_t * p ) { return s_GlobalFrame->Status; }
@@ -102,8 +104,11 @@ void Abc_FrameSetManDsd2( void * pMan ) { if (s_GlobalFrame
void Abc_FrameSetInv( Vec_Int_t * vInv ) { Vec_IntFreeP(&s_GlobalFrame->pAbcWlcInv); s_GlobalFrame->pAbcWlcInv = vInv; }
void Abc_FrameSetJsonStrs( Abc_Nam_t * pStrs ) { Abc_NamDeref( s_GlobalFrame->pJsonStrs ); s_GlobalFrame->pJsonStrs = pStrs; }
void Abc_FrameSetJsonObjs( Vec_Wec_t * vObjs ) { Vec_WecFreeP(&s_GlobalFrame->vJsonObjs ); s_GlobalFrame->vJsonObjs = vObjs; }
+void Abc_FrameSetSignalNames( Vec_Ptr_t * vNames ) { if ( s_GlobalFrame->vSignalNames ) Vec_PtrFreeFree( s_GlobalFrame->vSignalNames ); s_GlobalFrame->vSignalNames = vNames; }
+void Abc_FrameSetSpecName( char * pFileName ) { ABC_FREE( s_GlobalFrame->pSpecName ); s_GlobalFrame->pSpecName = pFileName; }
int Abc_FrameIsBatchMode() { return s_GlobalFrame ? s_GlobalFrame->fBatchMode : 0; }
+void Abc_FrameSetBatchMode( int Mode ) { if ( s_GlobalFrame ) s_GlobalFrame->fBatchMode = Mode; }
int Abc_FrameIsBridgeMode() { return s_GlobalFrame ? s_GlobalFrame->fBridgeMode : 0; }
void Abc_FrameSetBridgeMode() { if ( s_GlobalFrame ) s_GlobalFrame->fBridgeMode = 1; }
@@ -231,6 +236,9 @@ void Abc_FrameDeallocate( Abc_Frame_t * p )
}
Vec_IntFreeP( &p->vIndFlops );
Vec_PtrFreeP( &p->vLTLProperties_global );
+ if ( p->vSignalNames )
+ Vec_PtrFreeFree( p->vSignalNames );
+ ABC_FREE( p->pSpecName );
Abc_FrameDeleteAllNetworks( p );
ABC_FREE( p->pDrivingCell );
ABC_FREE( p->pCex2 );
diff --git a/src/base/main/mainInit.c b/src/base/main/mainInit.c
index d85d7b67..693cea90 100644
--- a/src/base/main/mainInit.c
+++ b/src/base/main/mainInit.c
@@ -65,6 +65,8 @@ extern void Abc85_Init( Abc_Frame_t * pAbc );
extern void Abc85_End( Abc_Frame_t * pAbc );
extern void Glucose_Init( Abc_Frame_t *pAbc );
extern void Glucose_End( Abc_Frame_t * pAbc );
+extern void Glucose2_Init( Abc_Frame_t *pAbc );
+extern void Glucose2_End( Abc_Frame_t * pAbc );
static Abc_FrameInitializer_t* s_InitializerStart = NULL;
static Abc_FrameInitializer_t* s_InitializerEnd = NULL;
@@ -117,9 +119,9 @@ void Abc_FrameInit( Abc_Frame_t * pAbc )
Bac_Init( pAbc );
Cba_Init( pAbc );
Pla_Init( pAbc );
- Sim_Init( pAbc );
Test_Init( pAbc );
Glucose_Init( pAbc );
+ Glucose2_Init( pAbc );
for( p = s_InitializerStart ; p ; p = p->next )
if(p->init)
p->init(pAbc);
@@ -157,7 +159,6 @@ void Abc_FrameEnd( Abc_Frame_t * pAbc )
Bac_End( pAbc );
Cba_End( pAbc );
Pla_End( pAbc );
- Sim_End( pAbc );
Test_End( pAbc );
Glucose_End( pAbc );
}
diff --git a/src/base/main/mainInt.h b/src/base/main/mainInt.h
index bc57ad2a..e860878e 100644
--- a/src/base/main/mainInt.h
+++ b/src/base/main/mainInt.h
@@ -133,6 +133,8 @@ struct Abc_Frame_t_
int nFrames; // the number of time frames completed by BMC
Vec_Ptr_t * vPlugInComBinPairs; // pairs of command and its binary name
Vec_Ptr_t * vLTLProperties_global; // related to LTL
+ Vec_Ptr_t * vSignalNames; // temporary storage for signal names
+ char * pSpecName;
void * pSave1;
void * pSave2;
void * pSave3;
diff --git a/src/base/main/mainUtils.c b/src/base/main/mainUtils.c
index d1fe1d20..377299fd 100644
--- a/src/base/main/mainUtils.c
+++ b/src/base/main/mainUtils.c
@@ -52,7 +52,14 @@ static char * DateReadFromDateString( char * datestr );
char * Abc_UtilsGetVersion( Abc_Frame_t * pAbc )
{
static char Version[1000];
+#if __GNUC__
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wdate-time"
+#endif
sprintf(Version, "%s (compiled %s %s)", ABC_VERSION, __DATE__, __TIME__);
+#if __GNUC__
+ #pragma GCC diagnostic pop
+#endif
return Version;
}
diff --git a/src/base/wlc/wlc.c b/src/base/wlc/wlc.c
index 6f0890e2..261ec96b 100644
--- a/src/base/wlc/wlc.c
+++ b/src/base/wlc/wlc.c
@@ -265,6 +265,446 @@ void Wlc_BlastMultiplierCnfTest( int nBits )
sat_solver_delete( pSat );
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Wlc_ManGenAdderN( Gia_Man_t * p, int nLits, int * pLitsA, int * pLitsB, int Carry )
+{
+ extern void Wlc_BlastFullAdder( Gia_Man_t * pNew, int a, int b, int c, int * pc, int * ps );
+ Vec_Int_t * vRes = Vec_IntStart( nLits + 1 );
+ int i, * pRes = Vec_IntArray(vRes);
+ for ( i = 0; i < nLits; i++ )
+ Wlc_BlastFullAdder( p, pLitsA[i], pLitsB[i], Carry, &Carry, &pRes[i] );
+ pRes[nLits] = Carry;
+ return vRes;
+}
+Vec_Int_t * Wlc_ManGenAdder2_rec( Gia_Man_t * p, int nLits, int * pLitsA, int * pLitsB, int Carry, int Size )
+{
+ Vec_Int_t * vRes, * vRes0, * vRes1, * vRes2; int i, iCtrl;
+ if ( nLits == Size )
+ return Wlc_ManGenAdderN( p, nLits, pLitsA, pLitsB, Carry );
+ vRes0 = Wlc_ManGenAdder2_rec( p, nLits/2, pLitsA, pLitsB, Carry, Size );
+ vRes1 = Wlc_ManGenAdder2_rec( p, nLits/2, pLitsA + nLits/2, pLitsB + nLits/2, 0, Size );
+ vRes2 = Wlc_ManGenAdder2_rec( p, nLits/2, pLitsA + nLits/2, pLitsB + nLits/2, 1, Size );
+ vRes = Vec_IntAlloc( nLits + 1 );
+ Vec_IntAppend( vRes, vRes0 );
+ iCtrl = Vec_IntPop( vRes );
+ for ( i = 0; i <= nLits/2; i++ )
+ Vec_IntPush( vRes, Gia_ManHashMux(p, iCtrl, Vec_IntEntry(vRes2, i), Vec_IntEntry(vRes1, i)) );
+ assert( Vec_IntSize(vRes) == nLits + 1 );
+ Vec_IntFree( vRes0 );
+ Vec_IntFree( vRes1 );
+ Vec_IntFree( vRes2 );
+ return vRes;
+}
+Gia_Man_t * Wlc_ManGenAdder2( int nBits, int Size, int fSigned )
+{
+ Gia_Man_t * pTemp, * pNew; int n, i, iLit, nBitsAll;
+ Vec_Int_t * vOuts, * vLits = Vec_IntAlloc( 1000 );
+ pNew = Gia_ManStart( 1000 );
+ pNew->pName = Abc_UtilStrsav( "adder" );
+ for ( nBitsAll = Size; nBitsAll < nBits; nBitsAll *= 2 )
+ ;
+ for ( n = 0; n < 2; n++ )
+ {
+ for ( i = 0; i < nBits; i++ )
+ Vec_IntPush( vLits, Gia_ManAppendCi(pNew) );
+ for ( ; i < nBitsAll; i++ )
+ Vec_IntPush( vLits, fSigned ? Vec_IntEntry(vLits, nBits-1) : 0 );
+ }
+ Gia_ManHashAlloc( pNew );
+ vOuts = Wlc_ManGenAdder2_rec( pNew, nBitsAll, Vec_IntEntryP(vLits, 0), Vec_IntEntryP(vLits, Vec_IntSize(vLits)/2), 0, Size );
+ Gia_ManHashStop( pNew );
+ Vec_IntForEachEntry( vOuts, iLit, i )
+ Gia_ManAppendCo( pNew, iLit );
+ Vec_IntFree( vLits );
+ Vec_IntFree( vOuts );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+Vec_Int_t * Wlc_ManGenAdder_rec( Gia_Man_t * p, int nLits, int * pLitsA, int * pLitsB, int Carry, int Size )
+{
+ Vec_Int_t * vRes, * vRes0, * vRes1, * vRes2, * vRes3, * vRes4; int i, iCtrl;
+ if ( nLits == Size )
+ return Wlc_ManGenAdderN( p, nLits, pLitsA, pLitsB, Carry );
+ assert( nLits % 3 == 0 );
+ vRes0 = Wlc_ManGenAdder_rec( p, nLits/3, pLitsA + 0*nLits/3, pLitsB + 0*nLits/3, Carry, Size );
+ vRes1 = Wlc_ManGenAdder_rec( p, nLits/3, pLitsA + 1*nLits/3, pLitsB + 1*nLits/3, 0, Size );
+ vRes2 = Wlc_ManGenAdder_rec( p, nLits/3, pLitsA + 1*nLits/3, pLitsB + 1*nLits/3, 1, Size );
+ vRes3 = Wlc_ManGenAdder_rec( p, nLits/3, pLitsA + 2*nLits/3, pLitsB + 2*nLits/3, 0, Size );
+ vRes4 = Wlc_ManGenAdder_rec( p, nLits/3, pLitsA + 2*nLits/3, pLitsB + 2*nLits/3, 1, Size );
+ vRes = Vec_IntAlloc( nLits + 1 );
+ Vec_IntAppend( vRes, vRes0 );
+ iCtrl = Vec_IntPop( vRes );
+ for ( i = 0; i <= nLits/3; i++ )
+ Vec_IntPush( vRes, Gia_ManHashMux(p, iCtrl, Vec_IntEntry(vRes2, i), Vec_IntEntry(vRes1, i)) );
+ iCtrl = Vec_IntPop( vRes );
+ for ( i = 0; i <= nLits/3; i++ )
+ Vec_IntPush( vRes, Gia_ManHashMux(p, iCtrl, Vec_IntEntry(vRes4, i), Vec_IntEntry(vRes3, i)) );
+ assert( Vec_IntSize(vRes) == nLits + 1 );
+ Vec_IntFree( vRes0 );
+ Vec_IntFree( vRes1 );
+ Vec_IntFree( vRes2 );
+ Vec_IntFree( vRes3 );
+ Vec_IntFree( vRes4 );
+ return vRes;
+}
+Gia_Man_t * Wlc_ManGenAdder( int nBits )
+{
+ Gia_Man_t * pTemp, * pNew; int n, i, iLit, nBitsAll;
+ Vec_Int_t * vOuts, * vLits = Vec_IntAlloc( 1000 );
+ pNew = Gia_ManStart( 1000 );
+ pNew->pName = Abc_UtilStrsav( "adder" );
+ for ( nBitsAll = 3; nBitsAll < nBits; nBitsAll *= 3 )
+ ;
+ for ( n = 0; n < 2; n++ )
+ {
+ for ( i = 0; i < nBits; i++ )
+ Vec_IntPush( vLits, Gia_ManAppendCi(pNew) );
+ for ( ; i < nBitsAll; i++ )
+ Vec_IntPush( vLits, 0 );
+ }
+ Gia_ManHashAlloc( pNew );
+ vOuts = Wlc_ManGenAdder_rec( pNew, nBitsAll, Vec_IntEntryP(vLits, 0), Vec_IntEntryP(vLits, Vec_IntSize(vLits)/2), 0, 3 );
+ Gia_ManHashStop( pNew );
+ Vec_IntForEachEntryStop( vOuts, iLit, i, nBits+1 )
+ Gia_ManAppendCo( pNew, iLit );
+ Vec_IntFree( vLits );
+ Vec_IntFree( vOuts );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wlc_BuildOne32( Gia_Man_t * p, int * pLitIn, int * pLitOut )
+{
+ Wlc_BlastFullAdder( p, pLitIn[0], pLitIn[1], pLitIn[2], &pLitIn[5], &pLitOut[0] );
+ Wlc_BlastFullAdder( p, pLitIn[3], pLitIn[4], pLitIn[5], &pLitOut[2], &pLitOut[1] );
+}
+void Wlc_BuildOne51( Gia_Man_t * p, int * pLitIn, int * pLitOut )
+{
+ int Lit00, Lit01, Lit11;
+ Wlc_BlastFullAdder( p, pLitIn[0], pLitIn[1], pLitIn[2], &Lit01, &Lit00 );
+ Wlc_BlastFullAdder( p, pLitIn[3], pLitIn[4], Lit00, &Lit11, &pLitOut[0] );
+ Wlc_BlastFullAdder( p, pLitIn[5], Lit01, Lit11, &pLitOut[2], &pLitOut[1] );
+}
+void Wlc_BuildOne6( Gia_Man_t * p, int * pLitIn, int Const1, int * pLitOut )
+{
+ int Lit00, Lit01, Lit10, Lit11, Lit12;
+ Wlc_BlastFullAdder( p, pLitIn[0], pLitIn[1], pLitIn[2], &Lit01, &Lit00 );
+ Wlc_BlastFullAdder( p, pLitIn[3], pLitIn[4], pLitIn[5], &Lit11, &Lit10 );
+ Wlc_BlastFullAdder( p, Lit00, Lit10, Const1, &Lit12, &pLitOut[0] );
+ Wlc_BlastFullAdder( p, Lit01, Lit11, Lit12, &pLitOut[2],&pLitOut[1] );
+}
+Vec_Wec_t * Wlc_ManGenTree_iter( Gia_Man_t * p, Vec_Wec_t * vBits, int * pCounter )
+{
+ Vec_Wec_t * vBitsNew = Vec_WecStart( Vec_WecSize(vBits) );
+ int i, k, pLitsIn[16], pLitsOut[16], Count = 0, fSimple = Vec_WecMaxLevelSize(vBits) <= 3;
+ for ( i = 0; i < Vec_WecSize(vBits)-1; i++ )
+ {
+ Vec_Int_t * vBits0 = Vec_WecEntry(vBits, i);
+ Vec_Int_t * vBits1 = Vec_WecEntry(vBits, i+1);
+ if ( fSimple )
+ {
+ assert( Vec_IntSize(vBits0) <= 3 );
+ for ( k = 0; Vec_IntSize(vBits0) > 0; k++ )
+ pLitsIn[k] = Vec_IntPop( vBits0 );
+ for ( ; k < 3; k++ )
+ pLitsIn[k] = 0;
+ assert( k == 3 );
+ Wlc_BlastFullAdder( p, pLitsIn[0], pLitsIn[1], pLitsIn[2], &pLitsOut[1], &pLitsOut[0] );
+ Vec_WecPush( vBitsNew, i+0, pLitsOut[0] );
+ Vec_WecPush( vBitsNew, i+1, pLitsOut[1] );
+ Count += 2;
+ continue;
+ }
+ while ( Vec_IntSize(vBits0) >= 6 )
+ {
+ for ( k = 0; k < 6; k++ )
+ pLitsIn[k] = Vec_IntPop( vBits0 );
+ assert( k == 6 );
+ Wlc_BuildOne6( p, pLitsIn, 0, pLitsOut );
+ Vec_WecPush( vBitsNew, i+0, pLitsOut[0] );
+ Vec_WecPush( vBitsNew, i+1, pLitsOut[1] );
+ Vec_WecPush( vBitsNew, i+2, pLitsOut[2] );
+ Count += 3;
+ }
+ if ( Vec_IntSize(vBits0) == 5 && Vec_IntSize(vBits1) > 0 )
+ {
+ for ( k = 0; Vec_IntSize(vBits0) > 0; k++ )
+ pLitsIn[k] = Vec_IntPop( vBits0 );
+ pLitsIn[k++] = Vec_IntPop( vBits1 );
+ assert( k == 6 );
+ Wlc_BuildOne51( p, pLitsIn, pLitsOut );
+ Vec_WecPush( vBitsNew, i+0, pLitsOut[0] );
+ Vec_WecPush( vBitsNew, i+1, pLitsOut[1] );
+ Vec_WecPush( vBitsNew, i+2, pLitsOut[2] );
+ Count += 3;
+ }
+ if ( Vec_IntSize(vBits0) == 5 && Vec_IntSize(vBits1) == 0 )
+ {
+ for ( k = 0; Vec_IntSize(vBits0) > 0; k++ )
+ pLitsIn[k] = Vec_IntPop( vBits0 );
+ pLitsIn[k++] = 0;
+ assert( k == 6 );
+ Wlc_BuildOne6( p, pLitsIn, 0, pLitsOut );
+ Vec_WecPush( vBitsNew, i+0, pLitsOut[0] );
+ Vec_WecPush( vBitsNew, i+1, pLitsOut[1] );
+ Vec_WecPush( vBitsNew, i+2, pLitsOut[2] );
+ Count += 3;
+ }
+ if ( Vec_IntSize(vBits0) == 4 && Vec_IntSize(vBits1) > 0 )
+ {
+ for ( k = 0; Vec_IntSize(vBits0) > 0; k++ )
+ pLitsIn[k] = Vec_IntPop( vBits0 );
+ pLitsIn[k++] = 0;
+ pLitsIn[k++] = Vec_IntPop( vBits1 );
+ assert( k == 6 );
+ Wlc_BuildOne51( p, pLitsIn, pLitsOut );
+ Vec_WecPush( vBitsNew, i+0, pLitsOut[0] );
+ Vec_WecPush( vBitsNew, i+1, pLitsOut[1] );
+ Vec_WecPush( vBitsNew, i+2, pLitsOut[2] );
+ Count += 3;
+ }
+ if ( Vec_IntSize(vBits0) == 3 && Vec_IntSize(vBits1) >= 2 )
+ {
+ for ( k = 0; Vec_IntSize(vBits0) > 0; k++ )
+ pLitsIn[k] = Vec_IntPop( vBits0 );
+ pLitsIn[k++] = Vec_IntPop( vBits1 );
+ pLitsIn[k++] = Vec_IntPop( vBits1 );
+ assert( k == 5 );
+ Wlc_BuildOne32( p, pLitsIn, pLitsOut );
+ Vec_WecPush( vBitsNew, i+0, pLitsOut[0] );
+ Vec_WecPush( vBitsNew, i+1, pLitsOut[1] );
+ Vec_WecPush( vBitsNew, i+2, pLitsOut[2] );
+ Count += 3;
+ }
+ if ( Vec_IntSize(vBits0) >= 3 )
+ {
+ for ( k = 0; k < 3; k++ )
+ pLitsIn[k] = Vec_IntPop( vBits0 );
+ assert( k == 3 );
+ Wlc_BlastFullAdder( p, pLitsIn[0], pLitsIn[1], pLitsIn[2], &pLitsOut[1], &pLitsOut[0] );
+ Vec_WecPush( vBitsNew, i+0, pLitsOut[0] );
+ Vec_WecPush( vBitsNew, i+1, pLitsOut[1] );
+ Count += 2;
+ }
+/*
+ if ( Vec_IntSize(vBits0) == 2 )
+ {
+ Vec_IntClear( vBits0 );
+ Vec_WecPush( vBitsNew, i+0, 0 );
+ Vec_WecPush( vBitsNew, i+1, 0 );
+ Count += 2;
+ }
+*/
+ for ( k = 0; Vec_IntSize(vBits0) > 0; k++ )
+ Vec_WecPush( vBitsNew, i, Vec_IntPop(vBits0) );
+ }
+ if ( pCounter )
+ *pCounter = Count;
+ return vBitsNew;
+}
+void Wlc_ManGenTreeOne( Gia_Man_t * pNew, Vec_Wec_t * vBits0, int fMult, int fVerbose )
+{
+ extern int Wlc_BlastAdder( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ); // result is in pAdd0
+
+ Vec_Wec_t * vTemp, * vBits = Vec_WecDup( vBits0 );
+ Vec_Int_t * vOuts = Vec_IntAlloc( 1000 ), * vOuts2;
+ Vec_Int_t * vLits0 = Vec_IntAlloc( 1000 );
+ Vec_Int_t * vLits1 = Vec_IntAlloc( 1000 );
+ int i, iLit, nBitsAll = 0, CounterAll = 0, Counter = 1;
+ for ( i = 0; Counter && i < 1000; i++ )
+ {
+ if ( fVerbose ) printf( "LEVEL %d\n", i );
+ if ( fVerbose ) Vec_WecPrint( vBits, 0 );
+ if ( Vec_WecMaxLevelSize(vBits) <= 2 )
+ break;
+ vBits = Wlc_ManGenTree_iter( pNew, vTemp = vBits, &Counter );
+ Vec_WecFree( vTemp );
+ CounterAll += Counter;
+ }
+ printf( "Total count = %d.\n", CounterAll );
+ if ( !fMult )
+ {
+ int Carry;
+/*
+ Vec_WecForEachLevel( vBits, vOuts2, i )
+ {
+ if ( i == 10 )
+ break;
+ if ( i == 0 )
+ {
+ assert( Vec_IntSize(vOuts2) == 1 );
+ Vec_IntPush( vOuts, Vec_IntPop(vOuts2) );
+ continue;
+ }
+ assert( Vec_IntSize(vOuts2) == 1 || Vec_IntSize(vOuts2) == 2 );
+ Vec_IntPush( vLits0, Vec_IntPop(vOuts2) );
+ if ( Vec_IntSize(vOuts2) == 1 )
+ Vec_IntPush( vLits1, Vec_IntPop(vOuts2) );
+ else
+ {
+ Vec_IntPush( vLits1, 0 );
+ }
+ }
+ assert( Vec_IntSize(vLits0) == 9 );
+ assert( Vec_IntSize(vLits1) == 9 );
+*/
+ Vec_WecForEachLevel( vBits, vOuts2, i )
+ {
+ if ( Vec_IntSize(vOuts2) == 0 )
+ break;
+ assert( Vec_IntSize(vOuts2) == 1 || Vec_IntSize(vOuts2) == 2 );
+ Vec_IntPush( vLits0, Vec_IntPop(vOuts2) );
+ if ( Vec_IntSize(vOuts2) == 1 )
+ Vec_IntPush( vLits1, Vec_IntPop(vOuts2) );
+ else
+ Vec_IntPush( vLits1, 0 );
+ }
+ printf( "The adder size is %d.\n", Vec_IntSize(vLits0) );
+ Vec_IntShrink( vLits0, 11 );
+ Vec_IntShrink( vLits1, 11 );
+
+// vOuts2 = Wlc_ManGenAdder_rec( pNew, 9, Vec_IntArray(vLits0), Vec_IntArray(vLits1), 0, 3 );
+// Vec_IntAppend( vOuts, vOuts2 );
+// Vec_IntFree( vOuts2 );
+
+ Carry = Wlc_BlastAdder( pNew, Vec_IntArray(vLits0), Vec_IntArray(vLits1), 11, 0 );
+ Vec_IntAppend( vOuts, vLits0 );
+ Vec_IntPush( vOuts, Carry );
+
+
+ Gia_ManAppendCo( pNew, Vec_IntEntry(vOuts, 11) );
+ }
+ else
+ {
+ Vec_WecForEachLevel( vBits, vOuts2, i )
+ {
+ if ( Vec_IntSize(vOuts2) == 0 )
+ break;
+ assert( Vec_IntSize(vOuts2) == 1 || Vec_IntSize(vOuts2) == 2 );
+ Vec_IntPush( vLits0, Vec_IntPop(vOuts2) );
+ if ( Vec_IntSize(vOuts2) == 1 )
+ Vec_IntPush( vLits1, Vec_IntPop(vOuts2) );
+ else
+ Vec_IntPush( vLits1, 0 );
+ }
+ printf( "The adder size is %d.\n", Vec_IntSize(vLits0) );
+ Vec_IntShrink( vLits0, Gia_ManCiNum(pNew)+1 ); // mult
+ Vec_IntShrink( vLits1, Gia_ManCiNum(pNew)+1 ); // mult
+
+ for ( nBitsAll = 3; nBitsAll < Vec_IntSize(vLits0); nBitsAll *= 3 )
+ ;
+ for ( i = Vec_IntSize(vLits0); i < nBitsAll; i++ )
+ {
+ Vec_IntPush( vLits0, 0 );
+ Vec_IntPush( vLits1, 0 );
+ }
+ assert( Vec_IntSize(vLits0) == nBitsAll );
+ assert( Vec_IntSize(vLits1) == nBitsAll );
+
+ vOuts2 = Wlc_ManGenAdder_rec( pNew, nBitsAll, Vec_IntArray(vLits0), Vec_IntArray(vLits1), 0, 3 );
+ Vec_IntAppend( vOuts, vOuts2 );
+ Vec_IntFree( vOuts2 );
+ //Carry = Wlc_BlastAdder( pNew, Vec_IntArray(vLits0), Vec_IntArray(vLits1), nBitsAll, 0 );
+ //Vec_IntAppend( vOuts, vLits0 );
+ //Vec_IntPush( vOuts, Carry );
+
+ Vec_IntShrink( vOuts, Gia_ManCiNum(pNew) ); // mult
+ //Vec_IntShrink( vOuts, Gia_ManCiNum(pNew)/2 );
+
+ Vec_IntForEachEntry( vOuts, iLit, i )
+ Gia_ManAppendCo( pNew, iLit );
+ }
+
+ Vec_IntFree( vOuts );
+ Vec_IntFree( vLits0 );
+ Vec_IntFree( vLits1 );
+ Vec_WecFree( vBits );
+}
+Gia_Man_t * Wlc_ManGenTree( int nInputs, int Value, int nBits, int fVerbose )
+{
+ Gia_Man_t * pTemp, * pNew; int i, Counter = 0;
+ Vec_Wec_t * vBits = Vec_WecStart( nBits+2 );
+ for ( i = 0; i < nBits+2; i++ )
+ Vec_WecPush( vBits, i, (Value >> i) & 1 );
+ pNew = Gia_ManStart( 1000 );
+ pNew->pName = Abc_UtilStrsav( "tree" );
+ for ( i = 0; i < nInputs; i++ )
+ Vec_WecPush( vBits, 0, Gia_ManAppendCi(pNew) );
+ Gia_ManHashAlloc( pNew );
+ Wlc_ManGenTreeOne( pNew, vBits, 0, fVerbose );
+ Gia_ManHashStop( pNew );
+ Vec_WecFree( vBits );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Wlc_ManGenProd( int nInputs, int fVerbose )
+{
+ extern void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds );
+ extern void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds );
+ Vec_Int_t * vIns = Vec_IntAlloc( 2*nInputs );
+ Gia_Man_t * pTemp, * pNew;
+ Vec_Wec_t * vProds; int i;
+ pNew = Gia_ManStart( 1000 );
+ pNew->pName = Abc_UtilStrsav( "tree" );
+
+ for ( i = 0; i < 2*nInputs; i++ )
+ Vec_IntPush( vIns, Gia_ManAppendCi(pNew) );
+ //for ( i = 0; i < nInputs; i++ )
+ // Vec_IntPush( vIns, Gia_ManAppendCi(pNew) );
+ //for ( i = 0; i < nInputs; i++ )
+ // Vec_IntPush( vIns, Vec_IntEntry(vIns, i) );
+
+ Gia_ManHashAlloc( pNew );
+ Wlc_BlastBooth( pNew, Vec_IntArray(vIns), Vec_IntArray(vIns)+nInputs, nInputs, nInputs, NULL, 0, 0, &vProds );
+ //Wlc_BlastMultiplier3( pNew, Vec_IntArray(vIns), Vec_IntArray(vIns)+nInputs, nInputs, nInputs, NULL, 0, 0, &vProds );
+ //Vec_WecPrint( vProds, 0 );
+ Wlc_ManGenTreeOne( pNew, vProds, 1, fVerbose );
+ Gia_ManHashStop( pNew );
+ Vec_WecFree( vProds );
+ Vec_IntFree( vIns );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h
index 0a4f745c..0b3bed6c 100644
--- a/src/base/wlc/wlc.h
+++ b/src/base/wlc/wlc.h
@@ -217,6 +217,7 @@ struct Wlc_BstPar_t_
int fBooth;
int fNonRest;
int fCla;
+ int fDivBy0;
int fNoCleanup;
int fCreateMiter;
int fCreateWordMiter;
@@ -238,6 +239,7 @@ static inline void Wlc_BstParDefault( Wlc_BstPar_t * pPar )
pPar->fMulti = 0;
pPar->fBooth = 0;
pPar->fCla = 0;
+ pPar->fDivBy0 = 0;
pPar->fCreateMiter = 0;
pPar->fCreateWordMiter = 0;
pPar->fDecMuxes = 0;
diff --git a/src/base/wlc/wlcAbc.c b/src/base/wlc/wlcAbc.c
index e1b06ffd..8b7dbfa7 100644
--- a/src/base/wlc/wlcAbc.c
+++ b/src/base/wlc/wlcAbc.c
@@ -140,7 +140,7 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vCounts, int fVerbose )
SeeAlso []
***********************************************************************/
-Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv )
+Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Ptr_t * vNamesIn )
{
extern Vec_Int_t * Pdr_InvCounts( Vec_Int_t * vInv );
extern Vec_Str_t * Pdr_InvPrintStr( Vec_Int_t * vInv, Vec_Int_t * vCounts );
@@ -166,8 +166,16 @@ Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv )
if ( Entry == 0 )
continue;
pMainObj = Abc_NtkCreatePi( pMainNtk );
- sprintf( Buffer, "pi%d", i );
- Abc_ObjAssignName( pMainObj, Buffer, NULL );
+ // If vNamesIn is given, take names from there for as many entries as possible
+ // otherwise generate names from counter
+ if (vNamesIn != NULL && i < Vec_PtrSize(vNamesIn)) {
+ Abc_ObjAssignName( pMainObj, (char *)Vec_PtrEntry(vNamesIn, i), NULL );
+ }
+ else
+ {
+ sprintf( Buffer, "pi%d", i );
+ Abc_ObjAssignName( pMainObj, Buffer, NULL );
+ }
}
if ( Abc_NtkPiNum(pMainNtk) != nInputs )
{
diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c
index 402ce21b..c297c54f 100644
--- a/src/base/wlc/wlcAbs.c
+++ b/src/base/wlc/wlcAbs.c
@@ -867,10 +867,10 @@ static Vec_Bit_t * Wlc_NtkMarkLimit( Wlc_Ntk_t * p, Wlc_Par_t * pPars )
}
}
- Vec_PtrSort( vAdds, (int (*)(void))IntPairPtrCompare ) ;
- Vec_PtrSort( vMults, (int (*)(void))IntPairPtrCompare ) ;
- Vec_PtrSort( vMuxes, (int (*)(void))IntPairPtrCompare ) ;
- Vec_PtrSort( vFlops, (int (*)(void))IntPairPtrCompare ) ;
+ Vec_PtrSort( vAdds, (int (*)(const void *, const void *))IntPairPtrCompare ) ;
+ Vec_PtrSort( vMults, (int (*)(const void *, const void *))IntPairPtrCompare ) ;
+ Vec_PtrSort( vMuxes, (int (*)(const void *, const void *))IntPairPtrCompare ) ;
+ Vec_PtrSort( vFlops, (int (*)(const void *, const void *))IntPairPtrCompare ) ;
Vec_PtrForEachEntry( Int_Pair_t *, vAdds, pPair, i )
{
diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c
index 3a01e238..6e910cd8 100644
--- a/src/base/wlc/wlcBlast.c
+++ b/src/base/wlc/wlcBlast.c
@@ -345,11 +345,12 @@ void Wlc_BlastFullAdder( Gia_Man_t * pNew, int a, int b, int c, int * pc, int *
if ( fCompl )
*ps = Abc_LitNot(*ps), *pc = Abc_LitNot(*pc);
}
-void Wlc_BlastAdder( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ) // result is in pAdd0
+int Wlc_BlastAdder( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ) // result is in pAdd0
{
int b;
for ( b = 0; b < nBits; b++ )
Wlc_BlastFullAdder( pNew, pAdd0[b], pAdd1[b], Carry, &Carry, &pAdd0[b] );
+ return Carry;
}
void Wlc_BlastSubtract( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ) // result is in pAdd0
{
@@ -1022,7 +1023,7 @@ void Wlc_BlastReduceMatrix2( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Int_t * v
}
-void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla )
+void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds )
{
Vec_Wec_t * vProds = Vec_WecStart( nArgA + nArgB );
Vec_Wec_t * vLevels = Vec_WecStart( nArgA + nArgB );
@@ -1043,7 +1044,10 @@ void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA
Vec_WecPush( vLevels, nArgA+nArgB-1, 0 );
}
- Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes, fSigned, fCla );
+ if ( pvProds )
+ *pvProds = Vec_WecDup(vProds);
+ else
+ Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes, fSigned, fCla );
// Wlc_BlastReduceMatrix2( pNew, vProds, vRes, fSigned, fCla );
Vec_WecFree( vProds );
@@ -1086,7 +1090,7 @@ void Wlc_BlastDecoder( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vTmp,
Vec_IntPush( vRes, iMint );
}
}
-void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla )
+void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds )
{
Vec_Wec_t * vProds = Vec_WecStart( nArgA + nArgB + 3 );
Vec_Wec_t * vLevels = Vec_WecStart( nArgA + nArgB + 3 );
@@ -1159,9 +1163,11 @@ void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int
//Vec_WecPrint( vProds, 0 );
//Wlc_BlastPrintMatrix( pNew, vProds, 1 );
//printf( "Cutoff ID for partial products = %d.\n", Gia_ManObjNum(pNew) );
- Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes, fSigned, fCla );
-// Wlc_BlastReduceMatrix2( pNew, vProds, vRes, fSigned, fCla );
-
+ if ( pvProds )
+ *pvProds = Vec_WecDup(vProds);
+ else
+ Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes, fSigned, fCla );
+ // Wlc_BlastReduceMatrix2( pNew, vProds, vRes, fSigned, fCla );
Vec_WecFree( vProds );
Vec_WecFree( vLevels );
Vec_IntFree( vArgB );
@@ -1792,9 +1798,9 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
if ( Wlc_NtkCountConstBits(pArg0, nRangeMax) < Wlc_NtkCountConstBits(pArg1, nRangeMax) )
ABC_SWAP( int *, pArg0, pArg1 );
if ( pPar->fBooth )
- Wlc_BlastBooth( pNew, pArg0, pArg1, nRange0, nRange1, vRes, fSigned, pPar->fCla );
+ Wlc_BlastBooth( pNew, pArg0, pArg1, nRange0, nRange1, vRes, fSigned, pPar->fCla, NULL );
else if ( pPar->fCla )
- Wlc_BlastMultiplier3( pNew, pArg0, pArg1, nRange0, nRange1, vRes, Wlc_ObjIsSignedFanin01(p, pObj), pPar->fCla );
+ Wlc_BlastMultiplier3( pNew, pArg0, pArg1, nRange0, nRange1, vRes, Wlc_ObjIsSignedFanin01(p, pObj), pPar->fCla, NULL );
else
Wlc_BlastMultiplier( pNew, pArg0, pArg1, nRangeMax, nRangeMax, vTemp2, vRes, fSigned );
if ( nRange > Vec_IntSize(vRes) )
@@ -1815,7 +1821,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
else
Wlc_BlastDivider( pNew, pArg0, nRangeMax, pArg1, nRangeMax, pObj->Type == WLC_OBJ_ARI_DIVIDE, vRes );
Vec_IntShrink( vRes, nRange );
- //if ( pObj->Type == WLC_OBJ_ARI_DIVIDE )
+ if ( !pPar->fDivBy0 )
Wlc_BlastZeroCondition( pNew, pFans1, nRange1, vRes );
}
else if ( pObj->Type == WLC_OBJ_ARI_MINUS )
@@ -2104,7 +2110,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
// complement flop inputs whose init state is 1
for ( i = 0; i < nFf2Regs; i++ )
Gia_ManAppendCo( pNew, Gia_ManAppendCi(pNew) );
- //Gia_ManSetRegNum( pNew, nFf2Regs );
+ Gia_ManSetRegNum( pNew, nFf2Regs );
}
else
{
@@ -2490,6 +2496,98 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
return pNew;
}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float * Extra_FileReadFloat( FILE * pFile, int * pnFileSize )
+{
+ float * pBuffer;
+ int RetValue, nFileSize;
+ fseek( pFile, 0, SEEK_END );
+ nFileSize = *pnFileSize = ftell( pFile );
+ rewind( pFile );
+ assert( nFileSize%4 == 0 );
+ pBuffer = ABC_CALLOC( float, nFileSize/4 );
+ RetValue = fread( pBuffer, nFileSize, 1, pFile );
+ return pBuffer;
+}
+float * Extra_FileReadFloatContents( char * pFileName, int * pnFileSize )
+{
+ FILE * pFile;
+ float * pBuffer;
+ pFile = fopen( pFileName, "rb" );
+ pBuffer = pFile ? Extra_FileReadFloat( pFile, pnFileSize ) : NULL;
+ if ( pFile ) fclose( pFile );
+ return pBuffer;
+}
+static inline int Extra_FixedFound( int Value, int Fixed )
+{
+ Value += 1 << (Fixed-1);
+ Value >>= Fixed;
+ return Value;
+}
+static inline int Extra_ConvertFloat8( float Value )
+{
+ return Extra_FixedFound( (int)(Value * (1 << 16)), 8 );
+}
+Gia_Man_t * Wlc_BlastArray( char * pFileName )
+{
+ int nFileSize = 0;
+ float * pBuffer = Extra_FileReadFloatContents( pFileName, &nFileSize );
+ int i, v, Value, nInputs = nFileSize/4 - 1;
+ Vec_Int_t * vArg0 = Vec_IntAlloc( 100 );
+ Vec_Int_t * vArg1 = Vec_IntAlloc( 100 );
+ Vec_Int_t * vTemp = Vec_IntAlloc( 100 );
+ Vec_Int_t * vRes = Vec_IntAlloc( 100 );
+ Vec_Int_t * vSum = Vec_IntAlloc( 100 );
+ Gia_Man_t * pTemp, * pNew = Gia_ManStart( 10000 );
+ pNew->pName = Abc_UtilStrsav( "blast" );
+ Gia_ManHashAlloc( pNew );
+ for ( i = 0; i < 8*nInputs; i++ )
+ Gia_ManAppendCi(pNew);
+
+ Value = (Extra_ConvertFloat8(pBuffer[0]) << 8) | (1 << 7);
+ for ( v = 0; v < 20; v++ )
+ Vec_IntPush( vSum, (Value >> v) & 1 );
+
+ for ( i = 0; i < nInputs; i++ )
+ {
+ Value = Extra_ConvertFloat8( pBuffer[1+i] );
+
+ Vec_IntClear( vArg0 );
+ for ( v = 0; v < 8; v++ )
+ Vec_IntPush( vArg0, Gia_ManCiLit(pNew, 8*i+v) );
+
+ Vec_IntClear( vArg1 );
+ for ( v = 0; v < 12; v++ )
+ Vec_IntPush( vArg1, (Value >> v) & 1 );
+
+ Wlc_BlastMultiplier( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), 8, 12, vTemp, vRes, 1 );
+ Wlc_BlastAdder( pNew, Vec_IntArray(vSum), Vec_IntArray(vRes), 20, 0 );
+ }
+ ABC_FREE( pBuffer );
+ for ( v = 8; v < 16; v++ )
+ Gia_ManAppendCo( pNew, Vec_IntEntry(vSum, v) );
+ Vec_IntFree( vArg0 );
+ Vec_IntFree( vArg1 );
+ Vec_IntFree( vTemp );
+ Vec_IntFree( vRes );
+ Vec_IntFree( vSum );
+
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c
index 51f15597..39f1bebd 100644
--- a/src/base/wlc/wlcCom.c
+++ b/src/base/wlc/wlcCom.c
@@ -1037,7 +1037,7 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv )
Wlc_BstParDefault( pPar );
pPar->nOutputRange = 2;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "ORAMcombqadestnizvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ORAMcombqaydestnizvh" ) ) != EOF )
{
switch ( c )
{
@@ -1103,6 +1103,9 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'a':
pPar->fCla ^= 1;
break;
+ case 'y':
+ pPar->fDivBy0 ^= 1;
+ break;
case 'd':
pPar->fCreateMiter ^= 1;
break;
@@ -1198,7 +1201,7 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_FrameUpdateGia( pAbc, pNew );
return 0;
usage:
- Abc_Print( -2, "usage: %%blast [-ORAM num] [-combqadestnizvh]\n" );
+ Abc_Print( -2, "usage: %%blast [-ORAM num] [-combqaydestnizvh]\n" );
Abc_Print( -2, "\t performs bit-blasting of the word-level design\n" );
Abc_Print( -2, "\t-O num : zero-based index of the first word-level PO to bit-blast [default = %d]\n", pPar->iOutput );
Abc_Print( -2, "\t-R num : the total number of word-level POs to bit-blast [default = %d]\n", pPar->nOutputRange );
@@ -1210,6 +1213,7 @@ usage:
Abc_Print( -2, "\t-b : toggle generating radix-4 Booth multipliers [default = %s]\n", pPar->fBooth? "yes": "no" );
Abc_Print( -2, "\t-q : toggle generating non-restoring square root [default = %s]\n", pPar->fNonRest? "yes": "no" );
Abc_Print( -2, "\t-a : toggle generating carry-look-ahead adder [default = %s]\n", pPar->fCla? "yes": "no" );
+ Abc_Print( -2, "\t-y : toggle creating different divide-by-0 condition [default = %s]\n", pPar->fDivBy0? "yes": "no" );
Abc_Print( -2, "\t-d : toggle creating dual-output multi-output miter [default = %s]\n", pPar->fCreateMiter? "yes": "no" );
Abc_Print( -2, "\t-e : toggle creating miter with output word bits combined [default = %s]\n", pPar->fCreateWordMiter? "yes": "no" );
Abc_Print( -2, "\t-s : toggle creating decoded MUXes [default = %s]\n", pPar->fDecMuxes? "yes": "no" );
@@ -1327,16 +1331,20 @@ usage:
******************************************************************************/
int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- extern void Wln_NtkRetimeTest( char * pFileName, int fSkipSimple, int fDump, int fVerbose );
+ extern void Wln_NtkRetimeTest( char * pFileName, int fIgnoreIO, int fSkipSimple, int fDump, int fVerbose );
FILE * pFile;
char * pFileName = NULL;
+ int fIgnoreIO = 0;
int fSkipSimple = 0;
int c, fDump = 0, fVerbose = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "sdvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "isdvh" ) ) != EOF )
{
switch ( c )
{
+ case 'i':
+ fIgnoreIO ^= 1;
+ break;
case 's':
fSkipSimple ^= 1;
break;
@@ -1362,7 +1370,7 @@ int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv )
printf( "Transforming NDR into internal represnetation has failed.\n" );
return 0;
}
- vMoves = Wln_NtkRetime( pNtk, fSkipSimple, fVerbose );
+ vMoves = Wln_NtkRetime( pNtk, fIgnoreIO, fSkipSimple, fVerbose );
Wln_NtkFree( pNtk );
ABC_FREE( pAbc->pNdrArray );
if ( vMoves ) pAbc->pNdrArray = Vec_IntReleaseNewArray( vMoves );
@@ -1385,11 +1393,12 @@ int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
}
fclose( pFile );
- Wln_NtkRetimeTest( pFileName, fSkipSimple, fDump, fVerbose );
+ Wln_NtkRetimeTest( pFileName, fIgnoreIO, fSkipSimple, fDump, fVerbose );
return 0;
usage:
- Abc_Print( -2, "usage: %%retime [-sdvh]\n" );
+ Abc_Print( -2, "usage: %%retime [-isdvh]\n" );
Abc_Print( -2, "\t performs retiming for the NDR design\n" );
+ Abc_Print( -2, "\t-i : toggle ignoring delays of IO paths [default = %s]\n", fIgnoreIO? "yes": "no" );
Abc_Print( -2, "\t-s : toggle printing simple nodes [default = %s]\n", !fSkipSimple? "yes": "no" );
Abc_Print( -2, "\t-d : toggle dumping the network in Verilog [default = %s]\n", fDump? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
@@ -1718,15 +1727,19 @@ usage:
******************************************************************************/
int Abc_CommandInvGet( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- extern Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv );
+ extern Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Ptr_t * vNamesIn );
Abc_Ntk_t * pMainNtk;
Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
- int c, fVerbose = 0;
+ int c, i, fVerbose = 0, fFlopNamesFromGia = 0;
+ Vec_Ptr_t * vNamesIn = NULL;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "fvh" ) ) != EOF )
{
switch ( c )
{
+ case 'f':
+ fFlopNamesFromGia ^= 1;
+ break;
case 'v':
fVerbose ^= 1;
break;
@@ -1741,16 +1754,38 @@ int Abc_CommandInvGet( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( 1, "Abc_CommandInvGet(): Invariant is not available.\n" );
return 0;
}
+ // See if we shall and can copy the PI names from the current GIA
+ if ( fFlopNamesFromGia )
+ {
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( 1, "Abc_CommandInvGet(): No network in &-space, cannot copy names.\n" );
+ fFlopNamesFromGia = 0;
+ }
+ else
+ {
+ vNamesIn = Vec_PtrStart( Gia_ManRegNum(pAbc->pGia) );
+ for ( i = 0; i < Gia_ManRegNum(pAbc->pGia); ++i )
+ {
+ // Only the registers
+ Vec_PtrSetEntry( vNamesIn, i, Extra_UtilStrsav( (const char*)Vec_PtrEntry( pAbc->pGia->vNamesIn, Gia_ManPiNum(pAbc->pGia)+i ) ) );
+ }
+ }
+ }
// derive the network
- pMainNtk = Wlc_NtkGetInv( pNtk, Wlc_AbcGetInv(pAbc) );
+ pMainNtk = Wlc_NtkGetInv( pNtk, Wlc_AbcGetInv(pAbc), vNamesIn );
+ // Delete names
+ if (vNamesIn)
+ Vec_PtrFree( vNamesIn );
// replace the current network
if ( pMainNtk )
Abc_FrameReplaceCurrentNetwork( pAbc, pMainNtk );
return 0;
usage:
- Abc_Print( -2, "usage: inv_get [-vh]\n" );
+ Abc_Print( -2, "usage: inv_get [-fvh]\n" );
Abc_Print( -2, "\t places invariant found by PDR as the current network in the main-space\n" );
- Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\n" );
+ Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', infinity clauses are used)\n" );
+ Abc_Print( -2, "\t-f : toggle reading flop names from the &-space [default = %s]\n", fFlopNamesFromGia? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
diff --git a/src/base/wlc/wlcNdr.c b/src/base/wlc/wlcNdr.c
index 3212500f..d401281a 100644
--- a/src/base/wlc/wlcNdr.c
+++ b/src/base/wlc/wlcNdr.c
@@ -263,7 +263,7 @@ void Wlc_NtkToNdrTest( Wlc_Ntk_t * pNtk )
ppNames[i] = Wlc_ObjName(pNtk, i);
// verify by writing Verilog
- Ndr_WriteVerilog( NULL, pDesign, ppNames );
+ Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 );
Ndr_Write( "test.ndr", pDesign );
// cleanup
@@ -368,7 +368,7 @@ Wlc_Ntk_t * Wlc_NtkFromNdr( void * pData )
Ndr_Data_t * p = (Ndr_Data_t *)pData;
Wlc_Obj_t * pObj; Vec_Int_t * vName2Obj, * vFanins = Vec_IntAlloc( 100 );
int Mod = 2, i, k, Obj, * pArray, nDigits, fFound, NameId, NameIdMax;
- Vec_Wrd_t * vTruths = NULL;
+ Vec_Wrd_t * vTruths = NULL; int nTruths[2] = {0};
Wlc_Ntk_t * pTemp, * pNtk = Wlc_NtkAlloc( "top", Ndr_DataObjNum(p, Mod)+1 );
Wlc_NtkCheckIntegrity( pData );
Vec_IntClear( &pNtk->vFfs );
@@ -415,11 +415,14 @@ Wlc_Ntk_t * Wlc_NtkFromNdr( void * pData )
Vec_IntPush( &pNtk->vFfs2, iObj );
if ( Type == ABC_OPER_LUT )
{
+ word * pTruth;
if ( vTruths == NULL )
vTruths = Vec_WrdStart( 1000 );
if ( NameId >= Vec_WrdSize(vTruths) )
Vec_WrdFillExtra( vTruths, 2*NameId, 0 );
- Vec_WrdWriteEntry( vTruths, NameId, *((word *)Ndr_ObjReadBodyP(p, Obj, NDR_FUNCTION)) );
+ pTruth = (word *)Ndr_ObjReadBodyP(p, Obj, NDR_FUNCTION);
+ Vec_WrdWriteEntry( vTruths, NameId, pTruth ? *pTruth : 0 );
+ nTruths[ pTruth != NULL ]++;
}
if ( Type == ABC_OPER_SLICE )
Vec_IntPushTwo( vFanins, End, Beg );
@@ -437,6 +440,8 @@ Wlc_Ntk_t * Wlc_NtkFromNdr( void * pData )
Wlc_ObjFanin1(pNtk, pObj)->Signed = 1;
}
}
+ if ( nTruths[0] )
+ printf( "Warning! The number of LUTs without function is %d (out of %d).\n", nTruths[0], nTruths[0]+nTruths[1] );
// mark primary outputs
Ndr_ModForEachPo( p, Mod, Obj )
{
@@ -487,7 +492,7 @@ Wlc_Ntk_t * Wlc_NtkFromNdr( void * pData )
pNtk->pManName = Abc_NamStart( NameIdMax+1, 10 );
for ( i = 1; i <= NameIdMax; i++ )
{
- char pName[20]; sprintf( pName, "s%0*d", nDigits, i );
+ char pName[100]; sprintf( pName, "s%0*d", nDigits, i );
NameId = Abc_NamStrFindOrAdd( pNtk->pManName, pName, &fFound );
assert( !fFound && i == NameId );
}
@@ -535,7 +540,7 @@ Wlc_Ntk_t * Wlc_ReadNdr( char * pFileName )
void * pData = Ndr_Read( pFileName );
Wlc_Ntk_t * pNtk = Wlc_NtkFromNdr( pData );
//char * ppNames[10] = { NULL, "a", "b", "c", "d", "e", "f", "g", "h", "i" };
- //Ndr_WriteVerilog( NULL, pData, ppNames );
+ //Ndr_WriteVerilog( NULL, pData, ppNames, 0 );
//Ndr_Delete( pData );
Abc_FrameInputNdr( Abc_FrameGetGlobalFrame(), pData );
return pNtk;
diff --git a/src/base/wln/wln.h b/src/base/wln/wln.h
index 510d74c1..93a1a92a 100644
--- a/src/base/wln/wln.h
+++ b/src/base/wln/wln.h
@@ -246,7 +246,7 @@ extern int Wln_ObjClone( Wln_Ntk_t * pNew, Wln_Ntk_t * p, int iObj );
extern int Wln_ObjCreateCo( Wln_Ntk_t * p, int iFanin );
extern void Wln_ObjPrint( Wln_Ntk_t * p, int iObj );
/*=== wlcRetime.c ========================================================*/
-extern Vec_Int_t * Wln_NtkRetime( Wln_Ntk_t * p, int fSkipSimple, int fVerbose );
+extern Vec_Int_t * Wln_NtkRetime( Wln_Ntk_t * p, int fIgnoreIO, int fSkipSimple, int fVerbose );
extern void Wln_NtkRetimeCreateDelayInfo( Wln_Ntk_t * pNtk );
/*=== wlcWriteVer.c ========================================================*/
extern void Wln_WriteVer( Wln_Ntk_t * p, char * pFileName );
diff --git a/src/base/wln/wlnNdr.c b/src/base/wln/wlnNdr.c
index eb685463..9eaf71ed 100644
--- a/src/base/wln/wlnNdr.c
+++ b/src/base/wln/wlnNdr.c
@@ -96,7 +96,7 @@ void Wln_NtkToNdrTest( Wln_Ntk_t * p )
ppNames[i] = Abc_UtilStrsav(Wln_ObjName(p, i));
// verify by writing Verilog
- Ndr_WriteVerilog( NULL, pDesign, ppNames );
+ Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 );
Ndr_Write( "test.ndr", pDesign );
// cleanup
@@ -256,7 +256,7 @@ Wln_Ntk_t * Wln_NtkFromNdr( void * pData, int fDump )
pNtk->pManName = Abc_NamStart( NameIdMax+1, 10 );
for ( i = 1; i <= NameIdMax; i++ )
{
- char pName[20]; sprintf( pName, "s%0*d", nDigits, i );
+ char pName[100]; sprintf( pName, "s%0*d", nDigits, i );
NameId = Abc_NamStrFindOrAdd( pNtk->pManName, pName, &fFound );
assert( !fFound && i == NameId );
}
@@ -301,7 +301,7 @@ Wln_Ntk_t * Wln_ReadNdr( char * pFileName )
Wln_Ntk_t * pNtk = pData ? Wln_NtkFromNdr( pData, 0 ) : NULL;
if ( pNtk ) return NULL;
//char * ppNames[10] = { NULL, "a", "b", "c", "d", "e", "f", "g", "h", "i" };
- //Ndr_WriteVerilog( NULL, pData, ppNames );
+ //Ndr_WriteVerilog( NULL, pData, ppNames, 0 );
Ndr_Delete( pData );
return pNtk;
}
@@ -314,7 +314,7 @@ void Wln_ReadNdrTest()
Wln_NtkStaticFanoutTest( pNtk );
Wln_NtkFree( pNtk );
}
-void Wln_NtkRetimeTest( char * pFileName, int fSkipSimple, int fDump, int fVerbose )
+void Wln_NtkRetimeTest( char * pFileName, int fIgnoreIO, int fSkipSimple, int fDump, int fVerbose )
{
Vec_Int_t * vMoves;
void * pData = Ndr_Read( pFileName );
@@ -326,7 +326,7 @@ void Wln_NtkRetimeTest( char * pFileName, int fSkipSimple, int fDump, int fVerbo
return;
}
Wln_NtkRetimeCreateDelayInfo( pNtk );
- vMoves = Wln_NtkRetime( pNtk, fSkipSimple, fVerbose );
+ vMoves = Wln_NtkRetime( pNtk, fIgnoreIO, fSkipSimple, fVerbose );
//Vec_IntPrint( vMoves );
Vec_IntFree( vMoves );
Wln_NtkFree( pNtk );
diff --git a/src/base/wln/wlnRetime.c b/src/base/wln/wlnRetime.c
index 734ac194..5ccc1dd0 100644
--- a/src/base/wln/wlnRetime.c
+++ b/src/base/wln/wlnRetime.c
@@ -335,6 +335,55 @@ void Wln_RetFindSources( Wln_Ret_t * p )
/**Function*************************************************************
+ Synopsis [Mark paths from PIs to POs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Wln_RetMarkPaths_rec( Wln_Ntk_t * p, int iObj, int fVerbose )
+{
+ int k, iFanin, fPrev = 1;
+ if ( Wln_ObjIsTravIdPrevious(p, iObj) )
+ return 1;
+ if ( Wln_ObjIsTravIdCurrent(p, iObj) )
+ return 0;
+ if ( Wln_ObjIsCio(p, iObj) || Wln_ObjIsFf(p, iObj) )
+ return 0;
+ Wln_ObjForEachFanin( p, iObj, iFanin, k )
+ fPrev &= Wln_RetMarkPaths_rec( p, iFanin, fVerbose );
+ if ( fPrev )
+ {
+ Wln_ObjSetTravIdPrevious( p, iObj );
+ if ( Vec_IntEntry(&p->vInstIds, iObj) > 0 )
+ {
+ if ( fVerbose )
+ printf( "Updating delay %5d -> %5d : ", Vec_IntEntry(&p->vInstIds, iObj), 1 );
+ if ( fVerbose )
+ Wln_ObjPrint( p, iObj );
+ Vec_IntWriteEntry( &p->vInstIds, iObj, 1 );
+ }
+ return 1;
+ }
+ Wln_ObjSetTravIdCurrent( p, iObj );
+ return 0;
+}
+void Wln_RetMarkPaths( Wln_Ntk_t * p, int fVerbose )
+{
+ int i, iObj;
+ Wln_NtkIncrementTravId( p );
+ Wln_NtkIncrementTravId( p );
+ Wln_NtkForEachPi( p, iObj, i )
+ Wln_ObjSetTravIdPrevious( p, iObj );
+ Wln_NtkForEachPo( p, iObj, i )
+ Wln_RetMarkPaths_rec( p, Wln_ObjFanin0(p, iObj), fVerbose );
+}
+
+/**Function*************************************************************
+
Synopsis [Retimability check.]
Description []
@@ -571,7 +620,7 @@ void Wln_NtkRetimeCreateDelayInfo( Wln_Ntk_t * pNtk )
printf( "Assuming default delays: 10 units for most nodes and 1 unit for bit-slice, concat, and buffers driving COs.\n" );
}
}
-Vec_Int_t * Wln_NtkRetime( Wln_Ntk_t * pNtk, int fSkipSimple, int fVerbose )
+Vec_Int_t * Wln_NtkRetime_int( Wln_Ntk_t * pNtk, int fSkipSimple, int fVerbose )
{
Wln_Ret_t * p = Wln_RetAlloc( pNtk );
Vec_Int_t * vSources = &p->vSources;
@@ -666,6 +715,12 @@ Vec_Int_t * Wln_NtkRetime( Wln_Ntk_t * pNtk, int fSkipSimple, int fVerbose )
}
return vMoves;
}
+Vec_Int_t * Wln_NtkRetime( Wln_Ntk_t * pNtk, int fIgnoreIO, int fSkipSimple, int fVerbose )
+{
+ if ( fIgnoreIO )
+ Wln_RetMarkPaths( pNtk, fVerbose );
+ return Wln_NtkRetime_int( pNtk, fSkipSimple, fVerbose );
+}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/bdd/extrab/extraBddMisc.c b/src/bdd/extrab/extraBddMisc.c
index 42003864..f4ec0712 100644
--- a/src/bdd/extrab/extraBddMisc.c
+++ b/src/bdd/extrab/extraBddMisc.c
@@ -1291,7 +1291,7 @@ static DdNode * extraBddCountCubes( DdManager * dd, DdNode * L, DdNode * U, st__
if (r)
{
int nCubes = 0;
- if ( st__lookup( table, (char *)r, (char **)&nCubes ) )
+ if ( st__lookup_int( table, (char *)r, &nCubes ) )
*pnCubes = nCubes;
else assert( 0 );
return r;
diff --git a/src/bdd/llb/llb4Nonlin.c b/src/bdd/llb/llb4Nonlin.c
index f8ee825e..d99109fd 100644
--- a/src/bdd/llb/llb4Nonlin.c
+++ b/src/bdd/llb/llb4Nonlin.c
@@ -1156,7 +1156,7 @@ Aig_Man_t * Llb_ReachableStates( Aig_Man_t * pAig )
Cudd_Quit( dd );
// convert
- pNtkMuxes = Abc_NtkBddToMuxes( pNtk, 0, 1000000 );
+ pNtkMuxes = Abc_NtkBddToMuxes( pNtk, 0, 1000000, 0 );
Abc_NtkDelete( pNtk );
pNtk = Abc_NtkStrash( pNtkMuxes, 0, 1, 0 );
Abc_NtkDelete( pNtkMuxes );
diff --git a/src/bool/bdc/bdc.h b/src/bool/bdc/bdc.h
index bd0f7d7d..cc3cfeab 100644
--- a/src/bool/bdc/bdc.h
+++ b/src/bool/bdc/bdc.h
@@ -79,6 +79,8 @@ extern void * Bdc_FuncCopy( Bdc_Fun_t * p );
extern int Bdc_FuncCopyInt( Bdc_Fun_t * p );
extern void Bdc_FuncSetCopy( Bdc_Fun_t * p, void * pCopy );
extern void Bdc_FuncSetCopyInt( Bdc_Fun_t * p, int iCopy );
+extern int Bdc_ManBidecNodeNum( word * pFunc, word * pCare, int nVars, int fVerbose );
+extern Vec_Int_t * Bdc_ManBidecResub( word * pFunc, word * pCare, int nVars );
/*=== working with saved copies ==========================================*/
static inline int Bdc_FunObjCopy( Bdc_Fun_t * pObj ) { return Abc_LitNotCond( Bdc_FuncCopyInt(Bdc_Regular(pObj)), Bdc_IsComplement(pObj) ); }
diff --git a/src/bool/bdc/bdcCore.c b/src/bool/bdc/bdcCore.c
index 5a7a0c3a..cce0e306 100644
--- a/src/bool/bdc/bdcCore.c
+++ b/src/bool/bdc/bdcCore.c
@@ -364,6 +364,85 @@ void Bdc_ManDecomposeTest( unsigned uTruth, int nVars )
Bdc_ManFree( p );
}
+/**Function*************************************************************
+
+ Synopsis [Performs decomposition of one function.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Bdc_ManBidecNodeNum( word * pFunc, word * pCare, int nVars, int fVerbose )
+{
+ int nNodes;
+ Bdc_Man_t * pManDec;
+ Bdc_Par_t Pars = {0}, * pPars = &Pars;
+ pPars->nVarsMax = nVars;
+ pManDec = Bdc_ManAlloc( pPars );
+ Bdc_ManDecompose( pManDec, (unsigned *)pFunc, (unsigned *)pCare, nVars, NULL, 1000 );
+ nNodes = Bdc_ManAndNum( pManDec );
+ if ( fVerbose )
+ Bdc_ManDecPrint( pManDec );
+ Bdc_ManFree( pManDec );
+ return nNodes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs decomposition of one function.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Bdc_ManBidecResubInt( Bdc_Man_t * p, Vec_Int_t * vRes )
+{
+ int i, iRoot = Bdc_FunId(p,Bdc_Regular(p->pRoot)) - 1;
+ if ( iRoot == -1 )
+ Vec_IntPush( vRes, !Bdc_IsComplement(p->pRoot) );
+ else if ( iRoot < p->nVars )
+ Vec_IntPush( vRes, 4 + Abc_Var2Lit(iRoot, Bdc_IsComplement(p->pRoot)) );
+ else
+ {
+ for ( i = p->nVars+1; i < p->nNodes; i++ )
+ {
+ Bdc_Fun_t * pNode = p->pNodes + i;
+ int iLit0 = Abc_Var2Lit( Bdc_FunId(p,Bdc_Regular(pNode->pFan0)) - 1, Bdc_IsComplement(pNode->pFan0) );
+ int iLit1 = Abc_Var2Lit( Bdc_FunId(p,Bdc_Regular(pNode->pFan1)) - 1, Bdc_IsComplement(pNode->pFan1) );
+ if ( iLit0 > iLit1 )
+ iLit0 ^= iLit1, iLit1 ^= iLit0, iLit0 ^= iLit1;
+ Vec_IntPushTwo( vRes, 4 + iLit0, 4 + iLit1 );
+ }
+ assert( 2 + iRoot == p->nNodes );
+ Vec_IntPush( vRes, 4 + Abc_Var2Lit(iRoot, Bdc_IsComplement(p->pRoot)) );
+ }
+}
+Vec_Int_t * Bdc_ManBidecResub( word * pFunc, word * pCare, int nVars )
+{
+ Vec_Int_t * vRes = NULL;
+ int nNodes;
+ Bdc_Man_t * pManDec;
+ Bdc_Par_t Pars = {0}, * pPars = &Pars;
+ pPars->nVarsMax = nVars;
+ pManDec = Bdc_ManAlloc( pPars );
+ Bdc_ManDecompose( pManDec, (unsigned *)pFunc, (unsigned *)pCare, nVars, NULL, 1000 );
+ if ( pManDec->pRoot != NULL )
+ {
+ //Bdc_ManDecPrint( pManDec );
+ nNodes = Bdc_ManAndNum( pManDec );
+ vRes = Vec_IntAlloc( 2*nNodes + 1 );
+ Bdc_ManBidecResubInt( pManDec, vRes );
+ assert( Vec_IntSize(vRes) == 2*nNodes + 1 );
+ }
+ Bdc_ManFree( pManDec );
+ return vRes;
+}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/bool/kit/kit.h b/src/bool/kit/kit.h
index 47f06403..ee82b084 100644
--- a/src/bool/kit/kit.h
+++ b/src/bool/kit/kit.h
@@ -568,11 +568,14 @@ extern unsigned Kit_GraphToTruth( Kit_Graph_t * pGraph );
extern Kit_Graph_t * Kit_TruthToGraph( unsigned * pTruth, int nVars, Vec_Int_t * vMemory );
extern Kit_Graph_t * Kit_TruthToGraph2( unsigned * pTruth0, unsigned * pTruth1, int nVars, Vec_Int_t * vMemory );
extern int Kit_GraphLeafDepth_rec( Kit_Graph_t * pGraph, Kit_Node_t * pNode, Kit_Node_t * pLeaf );
+extern int Kit_TruthLitNum( unsigned * pTruth, int nVars, Vec_Int_t * vMemory );
/*=== kitHop.c ==========================================================*/
//extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash );
//extern Hop_Obj_t * Kit_GraphToHop( Hop_Man_t * pMan, Kit_Graph_t * pGraph );
//extern Hop_Obj_t * Kit_TruthToHop( Hop_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory );
//extern Hop_Obj_t * Kit_CoverToHop( Hop_Man_t * pMan, Vec_Int_t * vCover, int nVars, Vec_Int_t * vMemory );
+extern int Kit_IsopNodeNum( unsigned * pTruth0, unsigned * pTruth1, int nVars, Vec_Int_t * vMemory );
+extern Vec_Int_t * Kit_IsopResub( unsigned * pTruth0, unsigned * pTruth1, int nVars, Vec_Int_t * vMemory );
/*=== kitIsop.c ==========================================================*/
extern int Kit_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vMemory, int fTryBoth );
extern int Kit_TruthIsop2( unsigned * puTruth0, unsigned * puTruth1, int nVars, Vec_Int_t * vMemory, int fTryBoth, int fReturnTt );
diff --git a/src/bool/kit/kitGraph.c b/src/bool/kit/kitGraph.c
index 0e548575..a81b6404 100644
--- a/src/bool/kit/kitGraph.c
+++ b/src/bool/kit/kitGraph.c
@@ -19,6 +19,7 @@
***********************************************************************/
#include "kit.h"
+#include "misc/extra/extra.h"
ABC_NAMESPACE_IMPL_START
@@ -385,7 +386,7 @@ Kit_Graph_t * Kit_TruthToGraph2( unsigned * pTruth0, unsigned * pTruth1, int nVa
Kit_Graph_t * pGraph;
int RetValue;
// derive SOP
- RetValue = Kit_TruthIsop2( pTruth0, pTruth1, nVars, vMemory, 1, 0 ); // tried 1 and found not useful in "renode"
+ RetValue = Kit_TruthIsop2( pTruth0, pTruth1, nVars, vMemory, 0, 0 ); // tried 1 and found not useful in "renode"
if ( RetValue == -1 )
return NULL;
if ( Vec_IntSize(vMemory) > (1<<16) )
@@ -496,6 +497,31 @@ int * Kit_TruthTest( char * pFileName )
return pResult;
}
+/**Function*************************************************************
+
+ Synopsis [Derives the factored form from the truth table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Kit_TruthLitNum( unsigned * pTruth, int nVars, Vec_Int_t * vMemory )
+{
+ Kit_Graph_t * pGraph;
+ int RetValue, nLits;
+ RetValue = Kit_TruthIsop( pTruth, nVars, vMemory, 1 );
+ if ( RetValue == -1 || Vec_IntSize(vMemory) > (1<<16) )
+ return -1;
+ assert( RetValue == 0 || RetValue == 1 );
+ pGraph = Kit_SopFactor( vMemory, RetValue, nVars, vMemory );
+ nLits = 1 + Kit_GraphNodeNum( pGraph );
+ Kit_GraphFree( pGraph );
+ return nLits;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/bool/kit/kitHop.c b/src/bool/kit/kitHop.c
index 4ac82ac9..4509dadf 100644
--- a/src/bool/kit/kitHop.c
+++ b/src/bool/kit/kitHop.c
@@ -136,6 +136,107 @@ int Kit_TruthToGia2( Gia_Man_t * pMan, unsigned * pTruth0, unsigned * pTruth1, i
SeeAlso []
***********************************************************************/
+int Kit_IsopNodeNum( unsigned * pTruth0, unsigned * pTruth1, int nVars, Vec_Int_t * vMemory )
+{
+ Kit_Graph_t * pGraph;
+ int nNodes;
+ // transform truth table into the decomposition tree
+ if ( vMemory == NULL )
+ {
+ vMemory = Vec_IntAlloc( 0 );
+ pGraph = Kit_TruthToGraph2( pTruth0, pTruth1, nVars, vMemory );
+ Vec_IntFree( vMemory );
+ }
+ else
+ pGraph = Kit_TruthToGraph2( pTruth0, pTruth1, nVars, vMemory );
+ if ( pGraph == NULL )
+ {
+ printf( "Kit_TruthToGia2(): Converting truth table to AIG has failed for function:\n" );
+ Kit_DsdPrintFromTruth( pTruth0, nVars ); printf( "\n" );
+ Kit_DsdPrintFromTruth( pTruth1, nVars ); printf( "\n" );
+ }
+ // derive the AIG for the decomposition tree
+ nNodes = Kit_GraphNodeNum( pGraph );
+ Kit_GraphFree( pGraph );
+ return nNodes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transforms the decomposition graph into the AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Kit_IsopResubInt( Kit_Graph_t * pGraph, Vec_Int_t * vRes )
+{
+ int nVars = Kit_GraphLeaveNum(pGraph);
+ assert( nVars >= 0 && nVars <= pGraph->nSize );
+ if ( Kit_GraphIsConst(pGraph) )
+ Vec_IntPush( vRes, Kit_GraphIsConst1(pGraph) );
+ else if ( Kit_GraphIsVar(pGraph) )
+ Vec_IntPush( vRes, 4 + Abc_Var2Lit(Kit_GraphVarInt(pGraph), Kit_GraphIsComplement(pGraph)) );
+ else
+ {
+ Kit_Node_t * pNode; int i;
+ Kit_GraphForEachNode( pGraph, pNode, i )
+ {
+ Kit_Node_t * pFan0 = Kit_GraphNodeFanin0( pGraph, pNode );
+ Kit_Node_t * pFan1 = Kit_GraphNodeFanin1( pGraph, pNode );
+ int iLit0 = Abc_Var2Lit( Kit_GraphNodeInt(pGraph, pFan0), pNode->eEdge0.fCompl );
+ int iLit1 = Abc_Var2Lit( Kit_GraphNodeInt(pGraph, pFan1), pNode->eEdge1.fCompl );
+ if ( iLit0 > iLit1 )
+ iLit0 ^= iLit1, iLit1 ^= iLit0, iLit0 ^= iLit1;
+ Vec_IntPushTwo( vRes, 4 + iLit0, 4 + iLit1 );
+ }
+ assert( pNode == Kit_GraphNode(pGraph, pGraph->eRoot.Node) );
+ Vec_IntPush( vRes, 4 + Abc_Var2Lit(Kit_GraphNodeInt(pGraph, pNode), Kit_GraphIsComplement(pGraph)) );
+ }
+}
+Vec_Int_t * Kit_IsopResub( unsigned * pTruth0, unsigned * pTruth1, int nVars, Vec_Int_t * vMemory )
+{
+ Vec_Int_t * vRes = NULL;
+ Kit_Graph_t * pGraph;
+ int nNodes;
+ // transform truth table into the decomposition tree
+ if ( vMemory == NULL )
+ {
+ vMemory = Vec_IntAlloc( 0 );
+ pGraph = Kit_TruthToGraph2( pTruth0, pTruth1, nVars, vMemory );
+ Vec_IntFree( vMemory );
+ }
+ else
+ pGraph = Kit_TruthToGraph2( pTruth0, pTruth1, nVars, vMemory );
+ if ( pGraph == NULL )
+ {
+ printf( "Kit_TruthToGia2(): Converting truth table to AIG has failed for function:\n" );
+ Kit_DsdPrintFromTruth( pTruth0, nVars ); printf( "\n" );
+ Kit_DsdPrintFromTruth( pTruth1, nVars ); printf( "\n" );
+ }
+ // derive the AIG for the decomposition tree
+ nNodes = Kit_GraphNodeNum( pGraph );
+ vRes = Vec_IntAlloc( 2*nNodes + 1 );
+ Kit_IsopResubInt( pGraph, vRes );
+ assert( Vec_IntSize(vRes) == 2*nNodes + 1 );
+ Kit_GraphFree( pGraph );
+ return vRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transforms the decomposition graph into the AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
Hop_Obj_t * Kit_GraphToHopInternal( Hop_Man_t * pMan, Kit_Graph_t * pGraph )
{
Kit_Node_t * pNode = NULL;
diff --git a/src/map/if/ifCut.c b/src/map/if/ifCut.c
index ad37b77f..2d6889c0 100644
--- a/src/map/if/ifCut.c
+++ b/src/map/if/ifCut.c
@@ -608,6 +608,10 @@ static inline int If_ManSortCompare( If_Man_t * p, If_Cut_t * pC0, If_Cut_t * pC
return -1;
if ( pC0->Delay > pC1->Delay + p->fEpsilon )
return 1;
+ if ( pC0->fUseless < pC1->fUseless )
+ return -1;
+ if ( pC0->fUseless > pC1->fUseless )
+ return 1;
return 0;
}
if ( p->SortMode == 0 ) // delay
@@ -632,6 +636,10 @@ static inline int If_ManSortCompare( If_Man_t * p, If_Cut_t * pC0, If_Cut_t * pC
return -1;
if ( pC0->Power > pC1->Power + p->fEpsilon )
return 1;
+ if ( pC0->fUseless < pC1->fUseless )
+ return -1;
+ if ( pC0->fUseless > pC1->fUseless )
+ return 1;
return 0;
}
assert( p->SortMode == 2 ); // delay old
@@ -639,6 +647,10 @@ static inline int If_ManSortCompare( If_Man_t * p, If_Cut_t * pC0, If_Cut_t * pC
return -1;
if ( pC0->Delay > pC1->Delay + p->fEpsilon )
return 1;
+ if ( pC0->fUseless < pC1->fUseless )
+ return -1;
+ if ( pC0->fUseless > pC1->fUseless )
+ return 1;
if ( pC0->Area < pC1->Area - p->fEpsilon )
return -1;
if ( pC0->Area > pC1->Area + p->fEpsilon )
@@ -1129,8 +1141,8 @@ float If_CutAreaRefed( If_Man_t * p, If_Cut_t * pCut )
return 0;
aResult2 = If_CutAreaDeref( p, pCut );
aResult = If_CutAreaRef( p, pCut );
- assert( aResult > aResult2 - p->fEpsilon );
- assert( aResult < aResult2 + p->fEpsilon );
+// assert( aResult > aResult2 - p->fEpsilon );
+// assert( aResult < aResult2 + p->fEpsilon );
return aResult;
}
@@ -1207,8 +1219,8 @@ float If_CutEdgeDerefed( If_Man_t * p, If_Cut_t * pCut )
return pCut->nLeaves;
aResult2 = If_CutEdgeRef( p, pCut );
aResult = If_CutEdgeDeref( p, pCut );
- assert( aResult > aResult2 - 3*p->fEpsilon );
- assert( aResult < aResult2 + 3*p->fEpsilon );
+// assert( aResult > aResult2 - 3*p->fEpsilon );
+// assert( aResult < aResult2 + 3*p->fEpsilon );
return aResult;
}
@@ -1230,8 +1242,8 @@ float If_CutEdgeRefed( If_Man_t * p, If_Cut_t * pCut )
return pCut->nLeaves;
aResult2 = If_CutEdgeDeref( p, pCut );
aResult = If_CutEdgeRef( p, pCut );
- assert( aResult > aResult2 - p->fEpsilon );
- assert( aResult < aResult2 + p->fEpsilon );
+// assert( aResult > aResult2 - p->fEpsilon );
+// assert( aResult < aResult2 + p->fEpsilon );
return aResult;
}
diff --git a/src/map/if/ifMap.c b/src/map/if/ifMap.c
index bd8ebed7..f234d354 100644
--- a/src/map/if/ifMap.c
+++ b/src/map/if/ifMap.c
@@ -225,7 +225,7 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep
if ( p->pPars->fPower )
pCut->Power = (Mode == 2)? If_CutPowerDerefed( p, pCut, pObj ) : If_CutPowerFlow( p, pCut, pObj );
// save the best cut from the previous iteration
- if ( !fPreprocess )
+ if ( !fPreprocess || pCut->nLeaves <= 1 )
If_CutCopy( p, pCutSet->ppCuts[pCutSet->nCuts++], pCut );
}
@@ -516,7 +516,8 @@ void If_ObjPerformMappingChoice( If_Man_t * p, If_Obj_t * pObj, int Mode, int fP
// remove elementary cuts
for ( pTemp = pObj; pTemp; pTemp = pTemp->pEquiv )
- pTemp->pCutSet->nCuts--;
+ if ( pTemp != pObj || pTemp->pCutSet->nCuts > 1 )
+ pTemp->pCutSet->nCuts--;
// update the cutset of the node
pCutSet = pObj->pCutSet;
diff --git a/src/map/if/ifTruth.c b/src/map/if/ifTruth.c
index 83c40952..ae4bcea4 100644
--- a/src/map/if/ifTruth.c
+++ b/src/map/if/ifTruth.c
@@ -20,6 +20,7 @@
#include "if.h"
#include "bool/kit/kit.h"
+#include "misc/extra/extra.h"
ABC_NAMESPACE_IMPL_START
diff --git a/src/map/mio/mio.c b/src/map/mio/mio.c
index 8648a604..3010bbd3 100644
--- a/src/map/mio/mio.c
+++ b/src/map/mio/mio.c
@@ -408,6 +408,7 @@ int Mio_CommandWriteGenlib( Abc_Frame_t * pAbc, int argc, char **argv )
FILE * pOut, * pErr, * pFile;
char * pFileName;
int fSelected = 0;
+ int fVerilog = 0;
int fVerbose = 0;
int c;
@@ -415,16 +416,19 @@ int Mio_CommandWriteGenlib( Abc_Frame_t * pAbc, int argc, char **argv )
pErr = Abc_FrameReadErr(pAbc);
Extra_UtilGetoptReset();
- while ( (c = Extra_UtilGetopt(argc, argv, "vah")) != EOF )
+ while ( (c = Extra_UtilGetopt(argc, argv, "agvh")) != EOF )
{
switch (c)
{
- case 'v':
- fVerbose ^= 1;
- break;
case 'a':
fSelected ^= 1;
break;
+ case 'g':
+ fVerilog ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
case 'h':
goto usage;
break;
@@ -450,16 +454,20 @@ int Mio_CommandWriteGenlib( Abc_Frame_t * pAbc, int argc, char **argv )
printf( "Error! Cannot open file \"%s\" for writing the library.\n", pFileName );
return 1;
}
- Mio_WriteLibrary( pFile, (Mio_Library_t *)Abc_FrameReadLibGen(), 0, 0, fSelected );
+ if ( fVerilog )
+ Mio_WriteLibraryVerilog( pFile, (Mio_Library_t *)Abc_FrameReadLibGen(), 0, 0, fSelected );
+ else
+ Mio_WriteLibrary( pFile, (Mio_Library_t *)Abc_FrameReadLibGen(), 0, 0, fSelected );
fclose( pFile );
printf( "The current genlib library is written into file \"%s\".\n", pFileName );
return 0;
usage:
- fprintf( pErr, "\nusage: write_genlib [-vah] <file>\n");
+ fprintf( pErr, "\nusage: write_genlib [-agvh] <file>\n");
fprintf( pErr, "\t writes the current genlib library into a file\n" );
- fprintf( pErr, "\t-v : toggles enabling of verbose output [default = %s]\n", fVerbose? "yes" : "no" );
fprintf( pErr, "\t-a : toggles writing min-area gates [default = %s]\n", fSelected? "yes" : "no" );
+ fprintf( pErr, "\t-g : toggles writing the library in Verilog [default = %s]\n", fVerilog? "yes" : "no" );
+ fprintf( pErr, "\t-v : toggles enabling of verbose output [default = %s]\n", fVerbose? "yes" : "no" );
fprintf( pErr, "\t-h : print the command usage\n");
fprintf( pErr, "\t<file> : optional file name to write the library\n");
return 1;
diff --git a/src/map/mio/mio.h b/src/map/mio/mio.h
index d7f52f8c..18e3b92b 100644
--- a/src/map/mio/mio.h
+++ b/src/map/mio/mio.h
@@ -194,6 +194,7 @@ extern void Mio_GateDelete( Mio_Gate_t * pGate );
extern void Mio_PinDelete( Mio_Pin_t * pPin );
extern Mio_Pin_t * Mio_PinDup( Mio_Pin_t * pPin );
extern void Mio_WriteLibrary( FILE * pFile, Mio_Library_t * pLib, int fPrintSops, int fShort, int fSelected );
+extern void Mio_WriteLibraryVerilog( FILE * pFile, Mio_Library_t * pLib, int fPrintSops, int fShort, int fSelected );
extern Mio_Gate_t ** Mio_CollectRoots( Mio_Library_t * pLib, int nInputs, float tDelay, int fSkipInv, int * pnGates, int fVerbose );
extern Mio_Cell_t * Mio_CollectRootsNew( Mio_Library_t * pLib, int nInputs, int * pnGates, int fVerbose );
extern Mio_Cell_t * Mio_CollectRootsNewDefault( int nInputs, int * pnGates, int fVerbose );
diff --git a/src/map/mio/mioUtils.c b/src/map/mio/mioUtils.c
index 9cd44cba..c7180e1c 100644
--- a/src/map/mio/mioUtils.c
+++ b/src/map/mio/mioUtils.c
@@ -288,6 +288,99 @@ void Mio_WriteLibrary( FILE * pFile, Mio_Library_t * pLib, int fPrintSops, int f
/**Function*************************************************************
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Exp_PrintNodeVerilog( FILE * pFile, int nVars, Vec_Int_t * p, Vec_Ptr_t * vNames, int Node, int fCompl )
+{
+ extern void Exp_PrintLitVerilog( FILE * pFile, int nVars, Vec_Int_t * p, Vec_Ptr_t * vNames, int Lit );
+ if ( Vec_IntEntry(p, 2*Node+1) >= 2*nVars )
+ fprintf( pFile, "(" );
+ Exp_PrintLitVerilog( pFile, nVars, p, vNames, Vec_IntEntry(p, 2*Node+1) ^ fCompl );
+ if ( Vec_IntEntry(p, 2*Node+1) >= 2*nVars )
+ fprintf( pFile, ")" );
+ fprintf( pFile, " %c ", fCompl ? '|' : '&' );
+ if ( Vec_IntEntry(p, 2*Node+0) >= 2*nVars )
+ fprintf( pFile, "(" );
+ Exp_PrintLitVerilog( pFile, nVars, p, vNames, Vec_IntEntry(p, 2*Node+0) ^ fCompl );
+ if ( Vec_IntEntry(p, 2*Node+0) >= 2*nVars )
+ fprintf( pFile, ")" );
+}
+void Exp_PrintLitVerilog( FILE * pFile, int nVars, Vec_Int_t * p, Vec_Ptr_t * vNames, int Lit )
+{
+ if ( Lit == EXP_CONST0 )
+ fprintf( pFile, "1\'b0" );
+ else if ( Lit == EXP_CONST1 )
+ fprintf( pFile, "1\'b1" );
+ else if ( Lit < 2 * nVars )
+ fprintf( pFile, "%s%s", (Lit&1) ? "~" : "", (char *)Vec_PtrEntry(vNames, Lit/2) );
+ else
+ Exp_PrintNodeVerilog( pFile, nVars, p, vNames, Lit/2-nVars, Lit&1 );
+}
+void Exp_PrintVerilog( FILE * pFile, int nVars, Vec_Int_t * p, Vec_Ptr_t * vNames )
+{
+ Exp_PrintLitVerilog( pFile, nVars, p, vNames, Vec_IntEntryLast(p) );
+}
+void Mio_WriteGateVerilog( FILE * pFile, Mio_Gate_t * pGate, Vec_Ptr_t * vNames )
+{
+ char * pName; int i;
+ fprintf( pFile, "module %s ( ", pGate->pName );
+ fprintf( pFile, "%s", pGate->pOutName );
+ Vec_PtrForEachEntry( char *, vNames, pName, i )
+ fprintf( pFile, ", %s", pName );
+ fprintf( pFile, " );\n" );
+ fprintf( pFile, " output %s;\n", pGate->pOutName );
+ if ( Vec_PtrSize(vNames) > 0 )
+ {
+ fprintf( pFile, " input %s", (char *)Vec_PtrEntry(vNames, 0) );
+ Vec_PtrForEachEntryStart( char *, vNames, pName, i, 1 )
+ fprintf( pFile, ", %s", pName );
+ fprintf( pFile, ";\n" );
+ }
+ fprintf( pFile, " assign %s = ", pGate->pOutName );
+ Exp_PrintVerilog( pFile, Vec_PtrSize(vNames), pGate->vExpr, vNames );
+ fprintf( pFile, ";\n" );
+ fprintf( pFile, "endmodule\n\n" );
+}
+void Mio_WriteLibraryVerilog( FILE * pFile, Mio_Library_t * pLib, int fPrintSops, int fShort, int fSelected )
+{
+ Mio_Gate_t * pGate;
+ Mio_Pin_t * pPin;
+ Vec_Ptr_t * vGates = Vec_PtrAlloc( 1000 );
+ Vec_Ptr_t * vNames = Vec_PtrAlloc( 100 );
+ int i, nCells;
+ if ( fSelected )
+ {
+ Mio_Cell2_t * pCells = Mio_CollectRootsNewDefault2( 6, &nCells, 0 );
+ for ( i = 0; i < nCells; i++ )
+ Vec_PtrPush( vGates, pCells[i].pMioGate );
+ ABC_FREE( pCells );
+ }
+ else
+ {
+ for ( i = 0; i < pLib->nGates; i++ )
+ Vec_PtrPush( vGates, pLib->ppGates0[i] );
+ }
+ fprintf( pFile, "// Verilog for genlib library \"%s\" with %d gates written by ABC on %s\n\n", pLib->pName, Vec_PtrSize(vGates), Extra_TimeStamp() );
+ Vec_PtrForEachEntry( Mio_Gate_t *, vGates, pGate, i )
+ {
+ Vec_PtrClear( vNames );
+ Mio_GateForEachPin( pGate, pPin )
+ Vec_PtrPush( vNames, pPin->pName );
+ Mio_WriteGateVerilog( pFile, pGate, vNames );
+ }
+ Vec_PtrFree( vNames );
+ Vec_PtrFree( vGates );
+}
+
+/**Function*************************************************************
+
Synopsis [Compares the max delay of two gates.]
Description []
diff --git a/src/map/scl/scl.c b/src/map/scl/scl.c
index 27342458..635ec19e 100644
--- a/src/map/scl/scl.c
+++ b/src/map/scl/scl.c
@@ -153,11 +153,12 @@ int Scl_CommandReadLib( Abc_Frame_t * pAbc, int argc, char ** argv )
float Gain = 0;
int nGatesMin = 0;
int fShortNames = 0;
+ int fUnit = 0;
int fVerbose = 1;
int fVeryVerbose = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "SGMdnvwh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "SGMdnuvwh" ) ) != EOF )
{
switch ( c )
{
@@ -200,6 +201,9 @@ int Scl_CommandReadLib( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'n':
fShortNames ^= 1;
break;
+ case 'u':
+ fUnit ^= 1;
+ break;
case 'v':
fVerbose ^= 1;
break;
@@ -242,6 +246,12 @@ int Scl_CommandReadLib( Abc_Frame_t * pAbc, int argc, char ** argv )
// dump the resulting library
if ( fDump && pAbc->pLibScl )
Abc_SclWriteLiberty( Extra_FileNameGenericAppend(pFileName, "_temp.lib"), (SC_Lib *)pAbc->pLibScl );
+ if ( fUnit )
+ {
+ SC_Cell * pCell; int i;
+ SC_LibForEachCell( pLib, pCell, i )
+ pCell->area = 1;
+ }
// extract genlib library
if ( pAbc->pLibScl )
{
@@ -251,13 +261,14 @@ int Scl_CommandReadLib( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- fprintf( pAbc->Err, "usage: read_lib [-SG float] [-M num] [-dnvwh] <file>\n" );
+ fprintf( pAbc->Err, "usage: read_lib [-SG float] [-M num] [-dnuvwh] <file>\n" );
fprintf( pAbc->Err, "\t reads Liberty library from file\n" );
fprintf( pAbc->Err, "\t-S float : the slew parameter used to generate the library [default = %.2f]\n", Slew );
fprintf( pAbc->Err, "\t-G float : the gain parameter used to generate the library [default = %.2f]\n", Gain );
fprintf( pAbc->Err, "\t-M num : skip gate classes whose size is less than this [default = %d]\n", nGatesMin );
fprintf( pAbc->Err, "\t-d : toggle dumping the parsed library into file \"*_temp.lib\" [default = %s]\n", fDump? "yes": "no" );
fprintf( pAbc->Err, "\t-n : toggle replacing gate/pin names by short strings [default = %s]\n", fShortNames? "yes": "no" );
+ fprintf( pAbc->Err, "\t-u : toggle setting unit area for all cells [default = %s]\n", fUnit? "yes": "no" );
fprintf( pAbc->Err, "\t-v : toggle writing verbose information [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pAbc->Err, "\t-w : toggle writing information about skipped gates [default = %s]\n", fVeryVerbose? "yes": "no" );
fprintf( pAbc->Err, "\t-h : prints the command summary\n" );
diff --git a/src/map/scl/sclBufSize.c b/src/map/scl/sclBufSize.c
index be9cc3bd..4d438af0 100644
--- a/src/map/scl/sclBufSize.c
+++ b/src/map/scl/sclBufSize.c
@@ -435,7 +435,7 @@ void Abc_SclBufSize( Bus_Man_t * p, float Gain )
// add one or more inverters
// Abc_NtkPrintFanoutProfile( pObj );
Abc_NodeCollectFanouts( pObj, p->vFanouts );
- Vec_PtrSort( p->vFanouts, (int(*)(void))Bus_SclCompareFanouts );
+ Vec_PtrSort( p->vFanouts, (int(*)(const void *, const void *))Bus_SclCompareFanouts );
do
{
Abc_Obj_t * pInv;
diff --git a/src/map/scl/sclBuffer.c b/src/map/scl/sclBuffer.c
index 97f5f095..8417b317 100644
--- a/src/map/scl/sclBuffer.c
+++ b/src/map/scl/sclBuffer.c
@@ -371,7 +371,7 @@ Abc_Obj_t * Abc_SclPerformBufferingOne( Abc_Obj_t * pObj, int Degree, int fUseIn
// collect fanouts and sort by reverse level
vFanouts = Vec_PtrAlloc( Abc_ObjFanoutNum(pObj) );
Abc_NodeCollectFanouts( pObj, vFanouts );
- Vec_PtrSort( vFanouts, (int (*)(void))Abc_NodeCompareLevels );
+ Vec_PtrSort( vFanouts, (int (*)(const void *, const void *))Abc_NodeCompareLevels );
// select the first Degree fanouts
if ( fUseInvs )
pBuffer = Abc_NtkCreateNodeInv( pObj->pNtk, NULL );
diff --git a/src/misc/bzlib/decompress.c b/src/misc/bzlib/decompress.c
index 47dd98e4..4b7370f1 100644
--- a/src/misc/bzlib/decompress.c
+++ b/src/misc/bzlib/decompress.c
@@ -21,6 +21,10 @@
#include "bzlib_private.h"
+#if (__GNUC__ >= 8)
+ #pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#endif
+
ABC_NAMESPACE_IMPL_START
diff --git a/src/misc/extra/extra.h b/src/misc/extra/extra.h
index 2f38692d..3ab09965 100644
--- a/src/misc/extra/extra.h
+++ b/src/misc/extra/extra.h
@@ -106,6 +106,7 @@ extern char * Extra_FileNameGenericAppend( char * pBase, char * pSuffix );
extern void Extra_FileNameCorrectPath( char * FileName );
extern char * Extra_FileNameWithoutPath( char * FileName );
extern char * Extra_FilePathWithoutName( char * FileName );
+extern char * Extra_FileInTheSameDir( char * pPathFile, char * pFileName );
extern char * Extra_FileDesignName( char * pFileName );
extern int Extra_FileCheck( char * pFileName );
extern int Extra_FileSize( char * pFileName );
diff --git a/src/misc/extra/extraUtilFile.c b/src/misc/extra/extraUtilFile.c
index 38192c71..54e6efc2 100644
--- a/src/misc/extra/extraUtilFile.c
+++ b/src/misc/extra/extraUtilFile.c
@@ -240,13 +240,25 @@ char * Extra_FilePathWithoutName( char * FileName )
for ( pRes = FileName + strlen(FileName) - 1; pRes >= FileName; pRes-- )
if ( *pRes == '\\' || *pRes == '/' )
{
- *pRes = 0;
+ pRes[1] = '\0';
Extra_FileNameCorrectPath( FileName );
return FileName;
}
ABC_FREE( FileName );
return NULL;
}
+char * Extra_FileInTheSameDir( char * pPathFile, char * pFileName )
+{
+ static char pBuffer[1000]; char * pThis;
+ assert( strlen(pPathFile) + strlen(pFileName) < 990 );
+ memmove( pBuffer, pPathFile, strlen(pPathFile) );
+ for ( pThis = pBuffer + strlen(pPathFile) - 1; pThis >= pBuffer; pThis-- )
+ if ( *pThis == '\\' || *pThis == '/' )
+ break;
+ memmove( ++pThis, pFileName, strlen(pFileName) );
+ pThis[strlen(pFileName)] = '\0';
+ return pBuffer;
+}
char * Extra_FileDesignName( char * pFileName )
{
char * pBeg, * pEnd, * pStore, * pCur;
diff --git a/src/misc/extra/extraUtilPrime.c b/src/misc/extra/extraUtilPrime.c
index 215de367..13558092 100644
--- a/src/misc/extra/extraUtilPrime.c
+++ b/src/misc/extra/extraUtilPrime.c
@@ -583,7 +583,7 @@ void Tab_DecomposeTest()
Vec_Int_t * vPrimes = Abc_GenPrimes( nVars );
Tab_Man_t * p = Tab_ManAlloc( nVars, Vec_IntSize(vPrimes) );
Tab_ManStart( p, vPrimes );
- printf( "Created %d cubes dependent on %d variables with %d literals.\n", p->nCubes, p->nVars );
+ printf( "Created %d cubes dependent on %d variables.\n", p->nCubes, p->nVars );
vPairs = Tab_ManCollectDist1( p, 0 );
printf( "Collected %d pairs.\n", Vec_IntSize(vPairs)/2 );
Vec_IntFree( vPairs );
diff --git a/src/misc/extra/extraUtilReader.c b/src/misc/extra/extraUtilReader.c
index db604396..7ee3ddc3 100644
--- a/src/misc/extra/extraUtilReader.c
+++ b/src/misc/extra/extraUtilReader.c
@@ -22,8 +22,11 @@
#include "extra.h"
#include "misc/vec/vec.h"
-ABC_NAMESPACE_IMPL_START
+#if (__GNUC__ >= 8)
+ #pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#endif
+ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
diff --git a/src/misc/mem/mem.c b/src/misc/mem/mem.c
index 23d8d7ec..347d0130 100644
--- a/src/misc/mem/mem.c
+++ b/src/misc/mem/mem.c
@@ -156,6 +156,22 @@ void Mem_FixedStop( Mem_Fixed_t * p, int fVerbose )
/**Function*************************************************************
+ Synopsis [Wrapper for Mem_FlexStop for use in Vec_AttAlloc]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Mem_FlexStop2( Mem_Flex_t * p )
+{
+ Mem_FlexStop( p, 0 );
+}
+
+/**Function*************************************************************
+
Synopsis []
Description []
diff --git a/src/misc/mem/mem.h b/src/misc/mem/mem.h
index 4c0aa038..7bc5306c 100644
--- a/src/misc/mem/mem.h
+++ b/src/misc/mem/mem.h
@@ -50,6 +50,7 @@ extern int Mem_FixedReadMaxEntriesUsed( Mem_Fixed_t * p );
// flexible-size-block memory manager
extern Mem_Flex_t * Mem_FlexStart();
extern void Mem_FlexStop( Mem_Flex_t * p, int fVerbose );
+extern void Mem_FlexStop2( Mem_Flex_t * p );
extern char * Mem_FlexEntryFetch( Mem_Flex_t * p, int nBytes );
extern void Mem_FlexRestart( Mem_Flex_t * p );
extern int Mem_FlexReadMemUsage( Mem_Flex_t * p );
diff --git a/src/misc/util/abc_global.h b/src/misc/util/abc_global.h
index d7c5bea7..d1a9b4d3 100644
--- a/src/misc/util/abc_global.h
+++ b/src/misc/util/abc_global.h
@@ -288,6 +288,8 @@ static inline int Abc_Base2Log( unsigned n ) { int r; if ( n <
static inline int Abc_Base10Log( unsigned n ) { int r; if ( n < 2 ) return (int)n; for ( r = 0, n--; n; n /= 10, r++ ) {}; return r; }
static inline int Abc_Base16Log( unsigned n ) { int r; if ( n < 2 ) return (int)n; for ( r = 0, n--; n; n /= 16, r++ ) {}; return r; }
static inline char * Abc_UtilStrsav( char * s ) { return s ? strcpy(ABC_ALLOC(char, strlen(s)+1), s) : NULL; }
+static inline char * Abc_UtilStrsavTwo( char * s, char * a ){ char * r; if (!a) return Abc_UtilStrsav(s); r = ABC_ALLOC(char, strlen(s)+strlen(a)+1); sprintf(r, "%s%s", s, a ); return r; }
+static inline char * Abc_UtilStrsavNum( char * s, int n ) { char * r; if (!s) return NULL; r = ABC_ALLOC(char, strlen(s)+12+1); sprintf(r, "%s%d", s, n ); return r; }
static inline int Abc_BitByteNum( int nBits ) { return (nBits>>3) + ((nBits&7) > 0); }
static inline int Abc_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); }
static inline int Abc_Bit6WordNum( int nBits ) { return (nBits>>6) + ((nBits&63) > 0); }
@@ -327,7 +329,12 @@ static inline int Abc_Lit2Att4( int Lit ) { assert(Lit >= 0)
typedef ABC_INT64_T abctime;
static inline abctime Abc_Clock()
{
-#if (defined(LIN) || defined(LIN64)) && !(__APPLE__ & __MACH__) && !defined(__MINGW32__)
+#if defined(__APPLE__) && defined(__MACH__)
+ #define APPLE_MACH (__APPLE__ & __MACH__)
+#else
+ #define APPLE_MACH 0
+#endif
+#if (defined(LIN) || defined(LIN64)) && !APPLE_MACH && !defined(__MINGW32__)
struct timespec ts;
if ( clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) < 0 )
return (abctime)-1;
@@ -513,6 +520,8 @@ static inline void Abc_ReverseOrder( int * pA, int nA )
// sorting
extern void Abc_MergeSort( int * pInput, int nSize );
extern int * Abc_MergeSortCost( int * pCosts, int nSize );
+extern void Abc_MergeSortCost2( int * pInput, int nSize, int * pCost );
+extern void Abc_MergeSortCost2Reverse( int * pInput, int nSize, int * pCost );
extern void Abc_QuickSort1( word * pData, int nSize, int fDecrease );
extern void Abc_QuickSort2( word * pData, int nSize, int fDecrease );
extern void Abc_QuickSort3( word * pData, int nSize, int fDecrease );
diff --git a/src/misc/util/utilNam.c b/src/misc/util/utilNam.c
index 30a68c63..f6539f03 100644
--- a/src/misc/util/utilNam.c
+++ b/src/misc/util/utilNam.c
@@ -144,6 +144,45 @@ void Abc_NamPrint( Abc_Nam_t * p, char * pFileName )
/**Function*************************************************************
+ Synopsis [Writes into a file and reads from a file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NamSave( Abc_Nam_t * p, char * pFileName )
+{
+ FILE * pFile = fopen( pFileName, "wb" ); int h, i;
+ if ( pFile == NULL ) { printf( "Count node open input file %s\n", pFileName ); return; }
+ Vec_IntForEachEntryStart( &p->vInt2Handle, h, i, 1 )
+ fprintf( pFile, "%s\n", Abc_NamHandleToStr(p, h) );
+ fclose(pFile);
+}
+Abc_Nam_t * Abc_NamLoad( char * pFileName )
+{
+ Abc_Nam_t * p;
+ int fFound, NameId = -1, nLineSize = 1 << 20;
+ char * pBuffer = ABC_ALLOC( char, nLineSize+1 );
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL ) { printf( "Count node open output file %s\n", pFileName ); return NULL; }
+ p = Abc_NamStart( 1000, 20 );
+ while ( fgets( pBuffer, nLineSize, pFile ) != NULL )
+ {
+ pBuffer[strlen(pBuffer)-1] = 0;
+ NameId = Abc_NamStrFindOrAdd( p, pBuffer, &fFound );
+ assert( !fFound );
+ }
+ assert( NameId+1 == Abc_NamObjNumMax(p) );
+ fclose( pFile );
+ ABC_FREE( pBuffer );
+ return p;
+}
+
+/**Function*************************************************************
+
Synopsis [References the manager.]
Description []
diff --git a/src/misc/util/utilNam.h b/src/misc/util/utilNam.h
index 8e054fc1..cf2d27e7 100644
--- a/src/misc/util/utilNam.h
+++ b/src/misc/util/utilNam.h
@@ -53,6 +53,8 @@ typedef struct Abc_Nam_t_ Abc_Nam_t;
extern Abc_Nam_t * Abc_NamStart( int nObjs, int nAveSize );
extern void Abc_NamStop( Abc_Nam_t * p );
extern void Abc_NamPrint( Abc_Nam_t * p, char * pFileName );
+extern void Abc_NamSave( Abc_Nam_t * p, char * pFileName );
+extern Abc_Nam_t * Abc_NamLoad( char * pFileName );
extern Abc_Nam_t * Abc_NamRef( Abc_Nam_t * p );
extern void Abc_NamDeref( Abc_Nam_t * p );
extern int Abc_NamObjNumMax( Abc_Nam_t * p );
diff --git a/src/misc/util/utilSort.c b/src/misc/util/utilSort.c
index 31890503..a748caf9 100644
--- a/src/misc/util/utilSort.c
+++ b/src/misc/util/utilSort.c
@@ -137,6 +137,210 @@ void Abc_MergeSort( int * pInput, int nSize )
}
+/**Function*************************************************************
+
+ Synopsis [Merging two lists of entries.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_SortMergeCost2( int * p1Beg, int * p1End, int * p2Beg, int * p2End, int * pOut, int * pCost )
+{
+ int nEntries = (p1End - p1Beg) + (p2End - p2Beg);
+ int * pOutBeg = pOut;
+ while ( p1Beg < p1End && p2Beg < p2End )
+ {
+ if ( pCost[*p1Beg] == pCost[*p2Beg] )
+ *pOut++ = *p1Beg++, *pOut++ = *p2Beg++;
+ else if ( pCost[*p1Beg] < pCost[*p2Beg] )
+ *pOut++ = *p1Beg++;
+ else // if ( pCost[*p1Beg] > pCost[*p2Beg] )
+ *pOut++ = *p2Beg++;
+ }
+ while ( p1Beg < p1End )
+ *pOut++ = *p1Beg++;
+ while ( p2Beg < p2End )
+ *pOut++ = *p2Beg++;
+ assert( pOut - pOutBeg == nEntries );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Recursive sorting.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_SortCost2_rec( int * pInBeg, int * pInEnd, int * pOutBeg, int * pCost )
+{
+ int nSize = pInEnd - pInBeg;
+ assert( nSize > 0 );
+ if ( nSize == 1 )
+ return;
+ if ( nSize == 2 )
+ {
+ if ( pCost[pInBeg[0]] > pCost[pInBeg[1]] )
+ {
+ pInBeg[0] ^= pInBeg[1];
+ pInBeg[1] ^= pInBeg[0];
+ pInBeg[0] ^= pInBeg[1];
+ }
+ }
+ else if ( nSize < 8 )
+ {
+ int temp, i, j, best_i;
+ for ( i = 0; i < nSize-1; i++ )
+ {
+ best_i = i;
+ for ( j = i+1; j < nSize; j++ )
+ if ( pCost[pInBeg[j]] < pCost[pInBeg[best_i]] )
+ best_i = j;
+ temp = pInBeg[i];
+ pInBeg[i] = pInBeg[best_i];
+ pInBeg[best_i] = temp;
+ }
+ }
+ else
+ {
+ Abc_SortCost2_rec( pInBeg, pInBeg + nSize/2, pOutBeg, pCost );
+ Abc_SortCost2_rec( pInBeg + nSize/2, pInEnd, pOutBeg + nSize/2, pCost );
+ Abc_SortMergeCost2( pInBeg, pInBeg + nSize/2, pInBeg + nSize/2, pInEnd, pOutBeg, pCost );
+ memcpy( pInBeg, pOutBeg, sizeof(int) * nSize );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the sorted array of integers.]
+
+ Description [This procedure is about 10% faster than qsort().]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_MergeSortCost2( int * pInput, int nSize, int * pCost )
+{
+ int * pOutput;
+ if ( nSize < 2 )
+ return;
+ pOutput = (int *) malloc( sizeof(int) * nSize );
+ Abc_SortCost2_rec( pInput, pInput + nSize, pOutput, pCost );
+ free( pOutput );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Merging two lists of entries.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_SortMergeCost2Reverse( int * p1Beg, int * p1End, int * p2Beg, int * p2End, int * pOut, int * pCost )
+{
+ int nEntries = (p1End - p1Beg) + (p2End - p2Beg);
+ int * pOutBeg = pOut;
+ while ( p1Beg < p1End && p2Beg < p2End )
+ {
+ if ( pCost[*p1Beg] == pCost[*p2Beg] )
+ *pOut++ = *p1Beg++, *pOut++ = *p2Beg++;
+ else if ( pCost[*p1Beg] > pCost[*p2Beg] )
+ *pOut++ = *p1Beg++;
+ else // if ( pCost[*p1Beg] < pCost[*p2Beg] )
+ *pOut++ = *p2Beg++;
+ }
+ while ( p1Beg < p1End )
+ *pOut++ = *p1Beg++;
+ while ( p2Beg < p2End )
+ *pOut++ = *p2Beg++;
+ assert( pOut - pOutBeg == nEntries );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Recursive sorting.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_SortCost2Reverse_rec( int * pInBeg, int * pInEnd, int * pOutBeg, int * pCost )
+{
+ int nSize = pInEnd - pInBeg;
+ assert( nSize > 0 );
+ if ( nSize == 1 )
+ return;
+ if ( nSize == 2 )
+ {
+ if ( pCost[pInBeg[0]] < pCost[pInBeg[1]] )
+ {
+ pInBeg[0] ^= pInBeg[1];
+ pInBeg[1] ^= pInBeg[0];
+ pInBeg[0] ^= pInBeg[1];
+ }
+ }
+ else if ( nSize < 8 )
+ {
+ int temp, i, j, best_i;
+ for ( i = 0; i < nSize-1; i++ )
+ {
+ best_i = i;
+ for ( j = i+1; j < nSize; j++ )
+ if ( pCost[pInBeg[j]] > pCost[pInBeg[best_i]] )
+ best_i = j;
+ temp = pInBeg[i];
+ pInBeg[i] = pInBeg[best_i];
+ pInBeg[best_i] = temp;
+ }
+ }
+ else
+ {
+ Abc_SortCost2Reverse_rec( pInBeg, pInBeg + nSize/2, pOutBeg, pCost );
+ Abc_SortCost2Reverse_rec( pInBeg + nSize/2, pInEnd, pOutBeg + nSize/2, pCost );
+ Abc_SortMergeCost2Reverse( pInBeg, pInBeg + nSize/2, pInBeg + nSize/2, pInEnd, pOutBeg, pCost );
+ memcpy( pInBeg, pOutBeg, sizeof(int) * nSize );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the sorted array of integers.]
+
+ Description [This procedure is about 10% faster than qsort().]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_MergeSortCost2Reverse( int * pInput, int nSize, int * pCost )
+{
+ int * pOutput;
+ if ( nSize < 2 )
+ return;
+ pOutput = (int *) malloc( sizeof(int) * nSize );
+ Abc_SortCost2Reverse_rec( pInput, pInput + nSize, pOutput, pCost );
+ free( pOutput );
+}
+
+
/**Function*************************************************************
diff --git a/src/misc/util/utilTruth.h b/src/misc/util/utilTruth.h
index e0ee1720..d9efa55f 100644
--- a/src/misc/util/utilTruth.h
+++ b/src/misc/util/utilTruth.h
@@ -35,6 +35,22 @@ ABC_NAMESPACE_HEADER_START
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
+static unsigned s_Truths5[6] = {
+ 0xAAAAAAAA,
+ 0xCCCCCCCC,
+ 0xF0F0F0F0,
+ 0xFF00FF00,
+ 0xFFFF0000
+};
+
+static unsigned s_Truths5Neg[6] = {
+ 0x55555555,
+ 0x33333333,
+ 0x0F0F0F0F,
+ 0x00FF00FF,
+ 0x0000FFFF
+};
+
static word s_Truths6[6] = {
ABC_CONST(0xAAAAAAAAAAAAAAAA),
ABC_CONST(0xCCCCCCCCCCCCCCCC),
@@ -216,6 +232,12 @@ static inline void Abc_TtMask( word * pTruth, int nWords, int nBits )
SeeAlso []
***********************************************************************/
+static inline void Abc_TtVec( word * pOut, int nWords, word Entry )
+{
+ int w;
+ for ( w = 0; w < nWords; w++ )
+ pOut[w] = Entry;
+}
static inline void Abc_TtConst( word * pOut, int nWords, int fConst1 )
{
int w;
@@ -256,6 +278,12 @@ static inline void Abc_TtCopy( word * pOut, word * pIn, int nWords, int fCompl )
for ( w = 0; w < nWords; w++ )
pOut[w] = pIn[w];
}
+static inline word * Abc_TtDup( word * pIn, int nWords, int fCompl )
+{
+ word * pOut = ABC_ALLOC( word, nWords );
+ Abc_TtCopy( pOut, pIn, nWords, fCompl );
+ return pOut;
+}
static inline void Abc_TtAnd( word * pOut, word * pIn1, word * pIn2, int nWords, int fCompl )
{
int w;
@@ -316,6 +344,24 @@ static inline void Abc_TtOrXor( word * pOut, word * pIn1, word * pIn2, int nWord
for ( w = 0; w < nWords; w++ )
pOut[w] |= pIn1[w] ^ pIn2[w];
}
+static inline void Abc_TtAndXor( word * pOut, word * pIn1, word * pIn2, int nWords )
+{
+ int w;
+ for ( w = 0; w < nWords; w++ )
+ pOut[w] &= pIn1[w] ^ pIn2[w];
+}
+static inline void Abc_TtOrAnd( word * pOut, word * pIn1, word * pIn2, int nWords )
+{
+ int w;
+ for ( w = 0; w < nWords; w++ )
+ pOut[w] |= pIn1[w] & pIn2[w];
+}
+static inline void Abc_TtSharpOr( word * pOut, word * pIn1, word * pIn2, int nWords )
+{
+ int w;
+ for ( w = 0; w < nWords; w++ )
+ pOut[w] = (pOut[w] & ~pIn1[w]) | pIn2[w];
+}
static inline void Abc_TtXor( word * pOut, word * pIn1, word * pIn2, int nWords, int fCompl )
{
int w;
@@ -365,6 +411,157 @@ static inline int Abc_TtIntersect( word * pIn1, word * pIn2, int nWords, int fCo
}
return 0;
}
+static inline int Abc_TtIntersectCare( word * pIn1, word * pIn2, word * pCare, int nWords, int fCompl )
+{
+ int w;
+ if ( fCompl )
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( ~pIn1[w] & pIn2[w] & pCare[w] )
+ return 1;
+ }
+ else
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( pIn1[w] & pIn2[w] & pCare[w] )
+ return 1;
+ }
+ return 0;
+}static inline int Abc_TtIntersectOne( word * pOut, int fComp, word * pIn, int fComp0, int nWords )
+{
+ int w;
+ if ( fComp0 )
+ {
+ if ( fComp )
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( ~pIn[w] & ~pOut[w] )
+ return 1;
+ }
+ else
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( ~pIn[w] & pOut[w] )
+ return 1;
+ }
+ }
+ else
+ {
+ if ( fComp )
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( pIn[w] & ~pOut[w] )
+ return 1;
+ }
+ else
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( pIn[w] & pOut[w] )
+ return 1;
+ }
+ }
+ return 0;
+}
+static inline int Abc_TtIntersectTwo( word * pOut, int fComp, word * pIn0, int fComp0, word * pIn1, int fComp1, int nWords )
+{
+ int w;
+ if ( fComp0 && fComp1 )
+ {
+ if ( fComp )
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( ~pIn0[w] & ~pIn1[w] & ~pOut[w] )
+ return 1;
+ }
+ else
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( ~pIn0[w] & ~pIn1[w] & pOut[w] )
+ return 1;
+ }
+ }
+ else if ( fComp0 )
+ {
+ if ( fComp )
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( ~pIn0[w] & pIn1[w] & ~pOut[w] )
+ return 1;
+ }
+ else
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( ~pIn0[w] & pIn1[w] & pOut[w] )
+ return 1;
+ }
+ }
+ else if ( fComp1 )
+ {
+ if ( fComp )
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( pIn0[w] & ~pIn1[w] & ~pOut[w] )
+ return 1;
+ }
+ else
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( pIn0[w] & ~pIn1[w] & pOut[w] )
+ return 1;
+ }
+ }
+ else
+ {
+ if ( fComp )
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( pIn0[w] & pIn1[w] & ~pOut[w] )
+ return 1;
+ }
+ else
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( pIn0[w] & pIn1[w] & pOut[w] )
+ return 1;
+ }
+ }
+ return 0;
+}
+static inline int Abc_TtIntersectXor( word * pOut, int fComp, word * pIn0, word * pIn1, int fComp01, int nWords )
+{
+ int w;
+ if ( fComp01 )
+ {
+ if ( fComp )
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( ~(pIn0[w] ^ pIn1[w]) & ~pOut[w] )
+ return 1;
+ }
+ else
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( ~(pIn0[w] ^ pIn1[w]) & pOut[w] )
+ return 1;
+ }
+ }
+ else
+ {
+ if ( fComp )
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( (pIn0[w] ^ pIn1[w]) & ~pOut[w] )
+ return 1;
+ }
+ else
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( (pIn0[w] ^ pIn1[w]) & pOut[w] )
+ return 1;
+ }
+ }
+ return 0;
+}
static inline int Abc_TtEqual( word * pIn1, word * pIn2, int nWords )
{
int w;
@@ -373,6 +570,23 @@ static inline int Abc_TtEqual( word * pIn1, word * pIn2, int nWords )
return 0;
return 1;
}
+static inline int Abc_TtEqualCare( word * pIn1, word * pIn2, word * pCare, int fComp, int nWords )
+{
+ int w;
+ if ( fComp )
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( (~pIn1[w] ^ pIn2[w]) & pCare[w] )
+ return 0;
+ }
+ else
+ {
+ for ( w = 0; w < nWords; w++ )
+ if ( (pIn1[w] ^ pIn2[w]) & pCare[w] )
+ return 0;
+ }
+ return 1;
+}
static inline int Abc_TtOpposite( word * pIn1, word * pIn2, int nWords )
{
int w;
@@ -683,6 +897,33 @@ static inline void Abc_TtElemInit2( word * pTtElems, int nVars )
SeeAlso []
***********************************************************************/
+static inline int Abc_Tt5HasVar( unsigned t, int iVar )
+{
+ return ((t << (1<<iVar)) & s_Truths5[iVar]) != (t & s_Truths5[iVar]);
+}
+static inline unsigned Abc_Tt5Cofactor0( unsigned t, int iVar )
+{
+ assert( iVar >= 0 && iVar < 5 );
+ return (t &s_Truths5Neg[iVar]) | ((t &s_Truths5Neg[iVar]) << (1<<iVar));
+}
+static inline unsigned Abc_Tt5Cofactor1( unsigned t, int iVar )
+{
+ assert( iVar >= 0 && iVar < 5 );
+ return (t & s_Truths5[iVar]) | ((t & s_Truths5[iVar]) >> (1<<iVar));
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
static inline word Abc_Tt6Cofactor0( word t, int iVar )
{
assert( iVar >= 0 && iVar < 6 );
@@ -1478,31 +1719,6 @@ static inline void Abc_TtFlip( word * pTruth, int nWords, int iVar )
SeeAlso []
***********************************************************************/
-static inline word Abc_Tt6Permute_rec( word t, int * pPerm, int nVars )
-{
- word uRes0, uRes1; int Var;
- if ( t == 0 ) return 0;
- if ( ~t == 0 ) return ~(word)0;
- for ( Var = nVars-1; Var >= 0; Var-- )
- if ( Abc_Tt6HasVar( t, Var ) )
- break;
- assert( Var >= 0 );
- uRes0 = Abc_Tt6Permute_rec( Abc_Tt6Cofactor0(t, Var), pPerm, Var );
- uRes1 = Abc_Tt6Permute_rec( Abc_Tt6Cofactor1(t, Var), pPerm, Var );
- return (uRes0 & s_Truths6Neg[pPerm[Var]]) | (uRes1 & s_Truths6[pPerm[Var]]);
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
static inline word Abc_Tt6SwapAdjacent( word Truth, int iVar )
{
return (Truth & s_PMasks[iVar][0]) | ((Truth & s_PMasks[iVar][1]) << (1 << iVar)) | ((Truth & s_PMasks[iVar][2]) >> (1 << iVar));
@@ -1609,6 +1825,69 @@ static inline word Abc_Tt6RemoveVar( word t, int iVar )
/**Function*************************************************************
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline word Abc_Tt6Permute_rec( word t, int * pPerm, int nVars )
+{
+ word uRes0, uRes1; int Var;
+ if ( t == 0 ) return 0;
+ if ( ~t == 0 ) return ~(word)0;
+ for ( Var = nVars-1; Var >= 0; Var-- )
+ if ( Abc_Tt6HasVar( t, Var ) )
+ break;
+ assert( Var >= 0 );
+ uRes0 = Abc_Tt6Permute_rec( Abc_Tt6Cofactor0(t, Var), pPerm, Var );
+ uRes1 = Abc_Tt6Permute_rec( Abc_Tt6Cofactor1(t, Var), pPerm, Var );
+ return (uRes0 & s_Truths6Neg[pPerm[Var]]) | (uRes1 & s_Truths6[pPerm[Var]]);
+}
+static inline void Abc_TtPermute( word * p, int * pPerm, int nVars )
+{
+ int v, UnPerm[16], Perm[16];
+ assert( nVars <= 16 );
+ for ( v = 0; v < nVars; v++ )
+ UnPerm[v] = Perm[v] = v;
+ for ( v = nVars-1; v >= 0; v-- )
+ {
+ int Lev = UnPerm[pPerm[v]];
+ if ( v == Lev )
+ continue;
+ Abc_TtSwapVars( p, nVars, v, Lev );
+ ABC_SWAP( int, Perm[v], Perm[Lev] );
+ UnPerm[Perm[Lev]] = Lev;
+ UnPerm[Perm[v]] = v;
+ }
+ for ( v = 0; v < nVars; v++ )
+ assert( Perm[v] == pPerm[v] );
+}
+static inline void Abc_TtUnpermute( word * p, int * pPerm, int nVars )
+{
+ int v, Perm[16];
+ assert( nVars <= 16 );
+ for ( v = 0; v < nVars; v++ )
+ Perm[v] = pPerm[v];
+ for ( v = nVars-1; v >= 0; v-- )
+ {
+ while ( v != Perm[v] )
+ {
+ int vCur = Perm[v];
+ Abc_TtSwapVars( p, nVars, v, vCur );
+ Perm[v] = Perm[vCur];
+ Perm[vCur]= vCur;
+ }
+ }
+ for ( v = 0; v < nVars; v++ )
+ assert( Perm[v] == v );
+}
+
+/**Function*************************************************************
+
Synopsis [Support minimization.]
Description []
@@ -1827,22 +2106,30 @@ static inline int Abc_TtCountOnes( word x )
x = x + (x >> 32);
return (int)(x & 0xFF);
}
+static inline int Abc_TtCountOnes2( word x )
+{
+ return x ? Abc_TtCountOnes(x) : 0;
+}
static inline int Abc_TtCountOnesVec( word * x, int nWords )
{
int w, Count = 0;
for ( w = 0; w < nWords; w++ )
- Count += Abc_TtCountOnes( x[w] );
+ Count += Abc_TtCountOnes2( x[w] );
return Count;
}
static inline int Abc_TtCountOnesVecMask( word * x, word * pMask, int nWords, int fCompl )
{
int w, Count = 0;
if ( fCompl )
+ {
for ( w = 0; w < nWords; w++ )
- Count += Abc_TtCountOnes( pMask[w] & ~x[w] );
+ Count += Abc_TtCountOnes2( pMask[w] & ~x[w] );
+ }
else
+ {
for ( w = 0; w < nWords; w++ )
- Count += Abc_TtCountOnes( pMask[w] & x[w] );
+ Count += Abc_TtCountOnes2( pMask[w] & x[w] );
+ }
return Count;
}
static inline int Abc_TtCountOnesVecMask2( word * x0, word * x1, int fComp0, int fComp1, word * pMask, int nWords )
@@ -1850,23 +2137,34 @@ static inline int Abc_TtCountOnesVecMask2( word * x0, word * x1, int fComp0, int
int w, Count = 0;
if ( !fComp0 && !fComp1 )
for ( w = 0; w < nWords; w++ )
- Count += Abc_TtCountOnes( pMask[w] & x0[w] & x1[w] );
+ Count += Abc_TtCountOnes2( pMask[w] & x0[w] & x1[w] );
else if ( fComp0 && !fComp1 )
for ( w = 0; w < nWords; w++ )
- Count += Abc_TtCountOnes( pMask[w] & ~x0[w] & x1[w] );
+ Count += Abc_TtCountOnes2( pMask[w] & ~x0[w] & x1[w] );
else if ( !fComp0 && fComp1 )
for ( w = 0; w < nWords; w++ )
- Count += Abc_TtCountOnes( pMask[w] & x0[w] & ~x1[w] );
+ Count += Abc_TtCountOnes2( pMask[w] & x0[w] & ~x1[w] );
else
for ( w = 0; w < nWords; w++ )
- Count += Abc_TtCountOnes( pMask[w] & ~x0[w] & ~x1[w] );
+ Count += Abc_TtCountOnes2( pMask[w] & ~x0[w] & ~x1[w] );
return Count;
}
static inline int Abc_TtCountOnesVecXor( word * x, word * y, int nWords )
{
int w, Count = 0;
for ( w = 0; w < nWords; w++ )
- Count += Abc_TtCountOnes( x[w] ^ y[w] );
+ Count += Abc_TtCountOnes2( x[w] ^ y[w] );
+ return Count;
+}
+static inline int Abc_TtCountOnesVecXorMask( word * x, word * y, int fCompl, word * pMask, int nWords )
+{
+ int w, Count = 0;
+ if ( fCompl )
+ for ( w = 0; w < nWords; w++ )
+ Count += Abc_TtCountOnes2( pMask[w] & (x[w] ^ ~y[w]) );
+ else
+ for ( w = 0; w < nWords; w++ )
+ Count += Abc_TtCountOnes2( pMask[w] & (x[w] ^ y[w]) );
return Count;
}
static inline int Abc_TtAndXorSum( word * pOut, word * pIn1, word * pIn2, int nWords )
@@ -1875,10 +2173,20 @@ static inline int Abc_TtAndXorSum( word * pOut, word * pIn1, word * pIn2, int nW
for ( w = 0; w < nWords; w++ )
{
pOut[w] &= pIn1[w] ^ pIn2[w];
- Count += Abc_TtCountOnes( pOut[w] );
+ Count += Abc_TtCountOnes2( pOut[w] );
}
return Count;
}
+static inline void Abc_TtIsfPrint( word * pOff, word * pOn, int nWords )
+{
+ int nTotal = 64*nWords;
+ int nOffset = Abc_TtCountOnesVec(pOff, nWords);
+ int nOnset = Abc_TtCountOnesVec(pOn, nWords);
+ int nDcset = nTotal - nOffset - nOnset;
+ printf( "OFF =%6d (%6.2f %%) ", nOffset, 100.0*nOffset/nTotal );
+ printf( "ON =%6d (%6.2f %%) ", nOnset, 100.0*nOnset/nTotal );
+ printf( "DC =%6d (%6.2f %%)", nDcset, 100.0*nDcset/nTotal );
+}
/**Function*************************************************************
@@ -1979,6 +2287,22 @@ static inline int Abc_TtFindLastDiffBit2( word * pIn1, word * pIn2, int nWords )
return 64*w + Abc_Tt6LastBit(pIn1[w] ^ pIn2[w]);
return -1;
}
+static inline int Abc_TtFindFirstAndBit2( 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_TtFindLastAndBit2( word * pIn1, word * pIn2, int nWords )
+{
+ int w;
+ for ( w = nWords - 1; w >= 0; w-- )
+ if ( pIn1[w] & pIn2[w] )
+ return 64*w + Abc_Tt6LastBit(pIn1[w] & pIn2[w]);
+ return -1;
+}
static inline int Abc_TtFindFirstZero( word * pIn, int nVars )
{
int w, nWords = Abc_TtWordNum(nVars);
diff --git a/src/misc/vec/vecHsh.h b/src/misc/vec/vecHsh.h
index 00da8450..b87904a2 100644
--- a/src/misc/vec/vecHsh.h
+++ b/src/misc/vec/vecHsh.h
@@ -492,6 +492,10 @@ static inline int Hsh_VecSize( Hsh_VecMan_t * p )
{
return Vec_IntSize(p->vMap);
}
+static inline double Hsh_VecManMemory( Hsh_VecMan_t * p )
+{
+ return !p ? 0.0 : Vec_IntMemory(p->vTable) + Vec_IntMemory(p->vData) + Vec_IntMemory(p->vMap);
+}
/**Function*************************************************************
diff --git a/src/misc/vec/vecInt.h b/src/misc/vec/vecInt.h
index 514ce455..c15369d2 100644
--- a/src/misc/vec/vecInt.h
+++ b/src/misc/vec/vecInt.h
@@ -63,6 +63,8 @@ struct Vec_Int_t_
for ( i = Vec_IntSize(vVec) - 1; (i >= 0) && (((pEntry) = Vec_IntEntry(vVec, i)), 1); i-- )
#define Vec_IntForEachEntryTwo( vVec1, vVec2, Entry1, Entry2, i ) \
for ( i = 0; (i < Vec_IntSize(vVec1)) && (((Entry1) = Vec_IntEntry(vVec1, i)), 1) && (((Entry2) = Vec_IntEntry(vVec2, i)), 1); i++ )
+#define Vec_IntForEachEntryTwoStart( vVec1, vVec2, Entry1, Entry2, i, Start ) \
+ for ( i = Start; (i < Vec_IntSize(vVec1)) && (((Entry1) = Vec_IntEntry(vVec1, i)), 1) && (((Entry2) = Vec_IntEntry(vVec2, i)), 1); i++ )
#define Vec_IntForEachEntryDouble( vVec, Entry1, Entry2, i ) \
for ( i = 0; (i+1 < Vec_IntSize(vVec)) && (((Entry1) = Vec_IntEntry(vVec, i)), 1) && (((Entry2) = Vec_IntEntry(vVec, i+1)), 1); i += 2 )
#define Vec_IntForEachEntryDoubleStart( vVec, Entry1, Entry2, i, Start ) \
@@ -148,6 +150,23 @@ static inline Vec_Int_t * Vec_IntStartRange( int First, int Range )
p->pArray[i] = First + i;
return p;
}
+static inline Vec_Int_t * Vec_IntStartRandomLimit( int nSize, int Upper, int Lower )
+{
+ Vec_Int_t * p = Vec_IntAlloc( nSize );
+ int i, Gap = Upper - Lower + 1;
+ for ( i = 0; i < p->nSize; i++ )
+ p->pArray[i] = Lower + Abc_Random(0) % Gap;
+ return p;
+}
+static inline void Vec_IntRandomizeOrder( Vec_Int_t * p )
+{
+ int v;
+ for ( v = 0; v < p->nSize; v++ )
+ {
+ int vRand = Abc_Random(0) % p->nSize;
+ ABC_SWAP( int, p->pArray[vRand], p->pArray[v] );
+ }
+}
/**Function*************************************************************
@@ -732,6 +751,11 @@ static inline void Vec_IntPush( Vec_Int_t * p, int Entry )
}
p->pArray[p->nSize++] = Entry;
}
+static inline int Vec_IntPushReturn( Vec_Int_t * p, int Entry )
+{
+ Vec_IntPush( p, Entry );
+ return Entry;
+}
static inline void Vec_IntPushTwo( Vec_Int_t * p, int Entry1, int Entry2 )
{
Vec_IntPush( p, Entry1 );
@@ -756,6 +780,12 @@ static inline void Vec_IntPushArray( Vec_Int_t * p, int * pEntries, int nEntries
for ( i = 0; i < nEntries; i++ )
Vec_IntPush( p, pEntries[i] );
}
+static inline void Vec_IntShift( Vec_Int_t * p, int Shift )
+{
+ p->nSize -= Shift;
+ p->nCap -= Shift;
+ p->pArray += Shift;
+}
/**Function*************************************************************
@@ -834,6 +864,52 @@ static inline void Vec_IntPushOrderCost( Vec_Int_t * p, int Entry, Vec_Int_t * v
/**Function*************************************************************
+ Synopsis [Check if the array is ordered.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntIsOrdered( Vec_Int_t * p, int fReverse )
+{
+ int i;
+ if ( fReverse )
+ {
+ for ( i = 1; i < p->nSize; i++ )
+ if ( p->pArray[i-1] < p->pArray[i] )
+ return 0;
+ }
+ else
+ {
+ for ( i = 1; i < p->nSize; i++ )
+ if ( p->pArray[i-1] > p->pArray[i] )
+ return 0;
+ }
+ return 1;
+}
+static inline int Vec_IntIsOrderedCost( Vec_Int_t * p, Vec_Int_t * vCost, int fReverse )
+{
+ int i;
+ if ( fReverse )
+ {
+ for ( i = 1; i < p->nSize; i++ )
+ if ( Vec_IntEntry(vCost, p->pArray[i-1]) < Vec_IntEntry(vCost, p->pArray[i]) )
+ return 0;
+ }
+ else
+ {
+ for ( i = 1; i < p->nSize; i++ )
+ if ( Vec_IntEntry(vCost, p->pArray[i-1]) > Vec_IntEntry(vCost, p->pArray[i]) )
+ return 0;
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
Synopsis [Inserts the entry while preserving the increasing order.]
Description []
@@ -1078,6 +1154,17 @@ static inline int Vec_IntFindMax( Vec_Int_t * p )
Best = p->pArray[i];
return Best;
}
+static inline int Vec_IntArgMax( Vec_Int_t * p )
+{
+ int i, Best, Arg = 0;
+ if ( p->nSize == 0 )
+ return -1;
+ Best = p->pArray[0];
+ for ( i = 1; i < p->nSize; i++ )
+ if ( Best < p->pArray[i] )
+ Best = p->pArray[i], Arg = i;
+ return Arg;
+}
/**Function*************************************************************
@@ -1101,6 +1188,17 @@ static inline int Vec_IntFindMin( Vec_Int_t * p )
Best = p->pArray[i];
return Best;
}
+static inline int Vec_IntArgMin( Vec_Int_t * p )
+{
+ int i, Best, Arg = 0;
+ if ( p->nSize == 0 )
+ return 0;
+ Best = p->pArray[0];
+ for ( i = 1; i < p->nSize; i++ )
+ if ( Best > p->pArray[i] )
+ Best = p->pArray[i], Arg = i;
+ return Arg;
+}
/**Function*************************************************************
@@ -1277,6 +1375,26 @@ static inline int Vec_IntCountZero( Vec_Int_t * p )
/**Function*************************************************************
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntAddPositive( Vec_Int_t * p )
+{
+ int i, Counter = 0;
+ for ( i = 0; i < p->nSize; i++ )
+ if ( p->pArray[i] > 0 )
+ Counter += p->pArray[i];
+ return Counter;
+}
+
+/**Function*************************************************************
+
Synopsis [Checks if two vectors are equal.]
Description []
@@ -1296,6 +1414,19 @@ static inline int Vec_IntEqual( Vec_Int_t * p1, Vec_Int_t * p2 )
return 0;
return 1;
}
+static inline int Vec_IntContained( Vec_Int_t * pSmall, Vec_Int_t * pLarge )
+{
+ int i, k;
+ for ( i = 0; i < pSmall->nSize; i++ )
+ {
+ for ( k = 0; k < pLarge->nSize; k++ )
+ if ( pSmall->pArray[i] == pLarge->pArray[k] )
+ break;
+ if ( k == pLarge->nSize )
+ return 0;
+ }
+ return 1;
+}
/**Function*************************************************************
@@ -1397,6 +1528,14 @@ static inline void Vec_IntSortMulti( Vec_Int_t * p, int nMulti, int fReverse )
qsort( (void *)p->pArray, (size_t)(p->nSize/nMulti), nMulti*sizeof(int),
(int (*)(const void *, const void *)) Vec_IntSortCompare1 );
}
+static inline int Vec_IntIsSorted( Vec_Int_t * p, int fReverse )
+{
+ int i;
+ for ( i = 1; i < p->nSize; i++ )
+ if ( fReverse ? (p->pArray[i-1] < p->pArray[i]) : (p->pArray[i-1] > p->pArray[i]) )
+ return 0;
+ return 1;
+}
/**Function*************************************************************
@@ -1795,6 +1934,70 @@ static inline int Vec_IntTwoRemove( Vec_Int_t * vArr1, Vec_Int_t * vArr2 )
Synopsis [Returns the result of merging the two vectors.]
+ Description [Keeps only those entries of vArr1, which are in vArr2.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntTwoMerge1( Vec_Int_t * vArr1, Vec_Int_t * vArr2 )
+{
+ int * pBeg = vArr1->pArray;
+ int * pBeg1 = vArr1->pArray;
+ int * pBeg2 = vArr2->pArray;
+ int * pEnd1 = vArr1->pArray + vArr1->nSize;
+ int * pEnd2 = vArr2->pArray + vArr2->nSize;
+ while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 )
+ {
+ if ( *pBeg1 == *pBeg2 )
+ *pBeg++ = *pBeg1++, pBeg2++;
+ else if ( *pBeg1 < *pBeg2 )
+ pBeg1++;
+ else
+ pBeg2++;
+ }
+ assert( vArr1->nSize >= pBeg - vArr1->pArray );
+ vArr1->nSize = pBeg - vArr1->pArray;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the result of subtracting for two vectors.]
+
+ Description [Keeps only those entries of vArr1, which are not in vArr2.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntTwoRemove1( Vec_Int_t * vArr1, Vec_Int_t * vArr2 )
+{
+ int * pBeg = vArr1->pArray;
+ int * pBeg1 = vArr1->pArray;
+ int * pBeg2 = vArr2->pArray;
+ int * pEnd1 = vArr1->pArray + vArr1->nSize;
+ int * pEnd2 = vArr2->pArray + vArr2->nSize;
+ while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 )
+ {
+ if ( *pBeg1 == *pBeg2 )
+ pBeg1++, pBeg2++;
+ else if ( *pBeg1 < *pBeg2 )
+ *pBeg++ = *pBeg1++;
+ else
+ pBeg2++;
+ }
+ while ( pBeg1 < pEnd1 )
+ *pBeg++ = *pBeg1++;
+ assert( vArr1->nSize >= pBeg - vArr1->pArray );
+ vArr1->nSize = pBeg - vArr1->pArray;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the result of merging the two vectors.]
+
Description [Assumes that the vectors are sorted in the increasing order.]
SideEffects []
@@ -2032,6 +2235,13 @@ static inline int Vec_IntCompareVec( Vec_Int_t * p1, Vec_Int_t * p2 )
SeeAlso []
***********************************************************************/
+static inline void Vec_IntClearAppend( Vec_Int_t * vVec1, Vec_Int_t * vVec2 )
+{
+ int Entry, i;
+ Vec_IntClear( vVec1 );
+ Vec_IntForEachEntry( vVec2, Entry, i )
+ Vec_IntPush( vVec1, Entry );
+}
static inline void Vec_IntAppend( Vec_Int_t * vVec1, Vec_Int_t * vVec2 )
{
int Entry, i;
@@ -2075,6 +2285,67 @@ static inline void Vec_IntRemapArray( Vec_Int_t * vOld2New, Vec_Int_t * vOld, Ve
Vec_IntWriteEntry( vNew, iNew, Vec_IntEntry(vOld, iOld) );
}
+/**Function*************************************************************
+
+ Synopsis [File interface.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntDumpBin( char * pFileName, Vec_Int_t * p, int fVerbose )
+{
+ int RetValue;
+ FILE * pFile = fopen( pFileName, "wb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for writing.\n", pFileName );
+ return;
+ }
+ RetValue = fwrite( Vec_IntArray(p), 1, sizeof(int)*Vec_IntSize(p), pFile );
+ fclose( pFile );
+ if ( RetValue != (int)sizeof(int)*Vec_IntSize(p) )
+ printf( "Error reading data from file.\n" );
+ if ( fVerbose )
+ printf( "Written %d integers into file \"%s\".\n", Vec_IntSize(p), pFileName );
+}
+static inline Vec_Int_t * Vec_IntReadBin( char * pFileName, int fVerbose )
+{
+ Vec_Int_t * p = NULL; int nSize, RetValue;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return NULL;
+ }
+ fseek( pFile, 0, SEEK_END );
+ nSize = ftell( pFile );
+ if ( nSize == 0 )
+ {
+ printf( "The input file is empty.\n" );
+ fclose( pFile );
+ return NULL;
+ }
+ if ( nSize % sizeof(int) > 0 )
+ {
+ printf( "Cannot read file with integers because it is not aligned at 4 bytes (remainder = %d).\n", (int)(nSize % sizeof(int)) );
+ fclose( pFile );
+ return NULL;
+ }
+ rewind( pFile );
+ p = Vec_IntStart( (int)(nSize/sizeof(int)) );
+ RetValue = fread( Vec_IntArray(p), 1, nSize, pFile );
+ fclose( pFile );
+ if ( RetValue != nSize )
+ printf( "Error reading data from file.\n" );
+ if ( fVerbose )
+ printf( "Read %d integers from file \"%s\".\n", (int)(nSize/sizeof(int)), pFileName );
+ return p;
+}
+
ABC_NAMESPACE_HEADER_END
#endif
diff --git a/src/misc/vec/vecPtr.h b/src/misc/vec/vecPtr.h
index ed2a481e..0f024f68 100644
--- a/src/misc/vec/vecPtr.h
+++ b/src/misc/vec/vecPtr.h
@@ -607,6 +607,26 @@ static inline void Vec_PtrFreeFree( Vec_Ptr_t * p )
/**Function*************************************************************
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void Vec_PtrFreeFunc( Vec_Ptr_t * p, void (*pFuncItemFree)(void *) ) ___unused;
+static void Vec_PtrFreeFunc( Vec_Ptr_t * p, void (*pFuncItemFree)(void *) )
+{
+ void * pItem; int i;
+ Vec_PtrForEachEntry( void *, p, pItem, i )
+ if ( pItem ) pFuncItemFree( pItem );
+ Vec_PtrFree( p );
+}
+
+/**Function*************************************************************
+
Synopsis [Copies the interger array.]
Description []
@@ -626,6 +646,26 @@ static inline void Vec_PtrCopy( Vec_Ptr_t * pDest, Vec_Ptr_t * pSour )
/**Function*************************************************************
+ Synopsis [Print names stored in the array.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrPrintNames( Vec_Ptr_t * p )
+{
+ char * pName; int i;
+ printf( "Vector has %d entries: {", Vec_PtrSize(p) );
+ Vec_PtrForEachEntry( char *, p, pName, i )
+ printf( "%s ", pName );
+ printf( " }\n" );
+}
+
+/**Function*************************************************************
+
Synopsis []
Description []
@@ -651,6 +691,12 @@ static inline void Vec_PtrPushTwo( Vec_Ptr_t * p, void * Entry1, void * Entry2 )
Vec_PtrPush( p, Entry1 );
Vec_PtrPush( p, Entry2 );
}
+static inline void Vec_PtrAppend( Vec_Ptr_t * vVec1, Vec_Ptr_t * vVec2 )
+{
+ void * Entry; int i;
+ Vec_PtrForEachEntry( void *, vVec2, Entry, i )
+ Vec_PtrPush( vVec1, Entry );
+}
/**Function*************************************************************
@@ -912,8 +958,8 @@ static int Vec_PtrSortComparePtr( void ** pp1, void ** pp2 )
SeeAlso []
***********************************************************************/
-static void Vec_PtrSort( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)() ) ___unused;
-static void Vec_PtrSort( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)() )
+static void Vec_PtrSort( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)(const void *, const void *) ) ___unused;
+static void Vec_PtrSort( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)(const void *, const void *) )
{
if ( p->nSize < 2 )
return;
@@ -936,8 +982,8 @@ static void Vec_PtrSort( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)() )
SeeAlso []
***********************************************************************/
-static void Vec_PtrUniqify( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)() ) ___unused;
-static void Vec_PtrUniqify( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)() )
+static void Vec_PtrUniqify( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)(const void *, const void *) ) ___unused;
+static void Vec_PtrUniqify( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)(const void *, const void *) )
{
int i, k;
if ( p->nSize < 2 )
@@ -948,15 +994,15 @@ static void Vec_PtrUniqify( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)() )
p->pArray[k++] = p->pArray[i];
p->nSize = k;
}
-static void Vec_PtrUniqify2( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)(void**, void**), void (*Vec_PtrObjFree)(void*), Vec_Int_t * vCounts ) ___unused;
-static void Vec_PtrUniqify2( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)(void**, void**), void (*Vec_PtrObjFree)(void*), Vec_Int_t * vCounts )
+static void Vec_PtrUniqify2( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)(const void *, const void *), void (*Vec_PtrObjFree)(void*), Vec_Int_t * vCounts ) ___unused;
+static void Vec_PtrUniqify2( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)(const void *, const void *), void (*Vec_PtrObjFree)(void*), Vec_Int_t * vCounts )
{
int i, k;
if ( vCounts )
Vec_IntFill( vCounts, 1, 1 );
if ( p->nSize < 2 )
return;
- Vec_PtrSort( p, (int (*)())Vec_PtrSortCompare );
+ Vec_PtrSort( p, Vec_PtrSortCompare );
for ( i = k = 1; i < p->nSize; i++ )
if ( Vec_PtrSortCompare(p->pArray+i, p->pArray+k-1) != 0 )
{
diff --git a/src/misc/vec/vecQue.h b/src/misc/vec/vecQue.h
index 54a10a29..6a8a68d0 100644
--- a/src/misc/vec/vecQue.h
+++ b/src/misc/vec/vecQue.h
@@ -119,6 +119,10 @@ static inline void Vec_QueClear( Vec_Que_t * p )
}
p->nSize = 1;
}
+static inline double Vec_QueMemory( Vec_Que_t * p )
+{
+ return !p ? 0.0 : 2.0 * sizeof(int) * (size_t)p->nCap + sizeof(Vec_Que_t) ;
+}
/**Function*************************************************************
diff --git a/src/misc/vec/vecStr.h b/src/misc/vec/vecStr.h
index 12053d3d..16e15761 100644
--- a/src/misc/vec/vecStr.h
+++ b/src/misc/vec/vecStr.h
@@ -561,6 +561,11 @@ static inline void Vec_StrPush( Vec_Str_t * p, char Entry )
}
p->pArray[p->nSize++] = Entry;
}
+static inline void Vec_StrPushTwo( Vec_Str_t * p, char Entry1, char Entry2 )
+{
+ Vec_StrPush( p, Entry1 );
+ Vec_StrPush( p, Entry2 );
+}
static inline void Vec_StrPushBuffer( Vec_Str_t * p, char * pBuffer, int nSize )
{
if ( p->nSize + nSize > p->nCap )
diff --git a/src/misc/vec/vecWec.h b/src/misc/vec/vecWec.h
index fdbded9c..cd463e01 100644
--- a/src/misc/vec/vecWec.h
+++ b/src/misc/vec/vecWec.h
@@ -275,6 +275,13 @@ static inline void Vec_WecClear( Vec_Wec_t * p )
Vec_IntClear( vVec );
p->nSize = 0;
}
+static inline void Vec_WecClearLevels( Vec_Wec_t * p )
+{
+ Vec_Int_t * vVec;
+ int i;
+ Vec_WecForEachLevel( p, vVec, i )
+ Vec_IntClear( vVec );
+}
/**Function*************************************************************
@@ -296,6 +303,15 @@ static inline void Vec_WecPush( Vec_Wec_t * p, int Level, int Entry )
}
Vec_IntPush( Vec_WecEntry(p, Level), Entry );
}
+static inline void Vec_WecPushTwo( Vec_Wec_t * p, int Level, int Entry1, int Entry2 )
+{
+ if ( p->nSize < Level + 1 )
+ {
+ Vec_WecGrow( p, Abc_MaxInt(2*p->nSize, Level + 1) );
+ p->nSize = Level + 1;
+ }
+ Vec_IntPushTwo( Vec_WecEntry(p, Level), Entry1, Entry2 );
+}
static inline Vec_Int_t * Vec_WecPushLevel( Vec_Wec_t * p )
{
if ( p->nSize == p->nCap )
@@ -422,7 +438,7 @@ static inline Vec_Wec_t * Vec_WecDup( Vec_Wec_t * p )
Vec_Wec_t * vNew;
Vec_Int_t * vVec;
int i, k, Entry;
- vNew = Vec_WecAlloc( Vec_WecSize(p) );
+ vNew = Vec_WecStart( Vec_WecSize(p) );
Vec_WecForEachLevel( p, vVec, i )
Vec_IntForEachEntry( vVec, Entry, k )
Vec_WecPush( vNew, i, Entry );
@@ -552,6 +568,29 @@ static inline void Vec_WecSortByLastInt( Vec_Wec_t * p, int fReverse )
SeeAlso []
***********************************************************************/
+static inline void Vec_WecKeepLevels( Vec_Wec_t * p, int Limit )
+{
+ Vec_Int_t * vLevel; int i, k = 0;
+ Vec_WecForEachLevel( p, vLevel, i )
+ if ( Vec_IntSize(vLevel) > Limit )
+ {
+ ABC_SWAP( Vec_Int_t, Vec_WecArray(p)[i], Vec_WecArray(p)[k] );
+ k++;
+ }
+ Vec_WecShrink( p, k );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
static inline void Vec_WecPrint( Vec_Wec_t * p, int fSkipSingles )
{
Vec_Int_t * vVec;
@@ -637,6 +676,25 @@ static inline int Vec_WecCountNonTrivial( Vec_Wec_t * p, int * pnUsed )
SeeAlso []
***********************************************************************/
+static inline int Vec_WecMaxLevelSize( Vec_Wec_t * p )
+{
+ Vec_Int_t * vTemp; int i, Res = 0;
+ Vec_WecForEachLevel( p, vTemp, i )
+ Res = Abc_MaxInt( Res, Vec_IntSize(vTemp) );
+ return Res;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
static inline Vec_Int_t * Vec_WecCollectFirsts( Vec_Wec_t * p )
{
Vec_Int_t * vFirsts, * vLevel;
@@ -733,6 +791,83 @@ static inline void Vec_WecRemoveEmpty( Vec_Wec_t * vCubes )
}
+/**Function*************************************************************
+
+ Synopsis [File interface.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_WecDumpBin( char * pFileName, Vec_Wec_t * p, int fVerbose )
+{
+ Vec_Int_t * vLevel;
+ int i, nSize, RetValue;
+ FILE * pFile = fopen( pFileName, "wb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for writing.\n", pFileName );
+ return;
+ }
+ nSize = Vec_WecSize(p);
+ RetValue = fwrite( &nSize, 1, sizeof(int), pFile );
+ Vec_WecForEachLevel( p, vLevel, i )
+ {
+ nSize = Vec_IntSize(vLevel);
+ RetValue += fwrite( &nSize, 1, sizeof(int), pFile );
+ RetValue += fwrite( Vec_IntArray(vLevel), 1, sizeof(int)*nSize, pFile );
+ }
+ fclose( pFile );
+ if ( RetValue != (int)sizeof(int)*(Vec_WecSizeSize(p)+Vec_WecSize(p)+1) )
+ printf( "Error writing data into file.\n" );
+ if ( fVerbose )
+ printf( "Written %d integer arrays into file \"%s\".\n", Vec_WecSize(p), pFileName );
+}
+static inline Vec_Wec_t * Vec_WecReadBin( char * pFileName, int fVerbose )
+{
+ Vec_Wec_t * p = NULL; Vec_Int_t * vLevel; int i, nSize, RetValue;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return NULL;
+ }
+ fseek( pFile, 0, SEEK_END );
+ nSize = ftell( pFile );
+ if ( nSize == 0 )
+ {
+ printf( "The input file is empty.\n" );
+ fclose( pFile );
+ return NULL;
+ }
+ if ( nSize % sizeof(int) > 0 )
+ {
+ printf( "Cannot read file with integers because it is not aligned at 4 bytes (remainder = %d).\n", (int)(nSize % sizeof(int)) );
+ fclose( pFile );
+ return NULL;
+ }
+ rewind( pFile );
+ RetValue = fread( &nSize, 1, sizeof(int), pFile );
+ assert( RetValue == 4 );
+ p = Vec_WecStart( nSize );
+ Vec_WecForEachLevel( p, vLevel, i )
+ {
+ RetValue = fread( &nSize, 1, sizeof(int), pFile );
+ assert( RetValue == 4 );
+ Vec_IntFill( vLevel, nSize, 0 );
+ RetValue = fread( Vec_IntArray(vLevel), 1, sizeof(int)*nSize, pFile );
+ assert( RetValue == 4*nSize );
+ }
+ fclose( pFile );
+ if ( fVerbose )
+ printf( "Read %d integer arrays from file \"%s\".\n", Vec_WecSize(p), pFileName );
+ return p;
+}
+
+
ABC_NAMESPACE_HEADER_END
#endif
diff --git a/src/misc/vec/vecWrd.h b/src/misc/vec/vecWrd.h
index e123c054..8275702a 100644
--- a/src/misc/vec/vecWrd.h
+++ b/src/misc/vec/vecWrd.h
@@ -61,6 +61,8 @@ struct Vec_Wrd_t_
for ( i = Start; (i < Stop) && (((Entry) = Vec_WrdEntry(vVec, i)), 1); i++ )
#define Vec_WrdForEachEntryReverse( vVec, pEntry, i ) \
for ( i = Vec_WrdSize(vVec) - 1; (i >= 0) && (((pEntry) = Vec_WrdEntry(vVec, i)), 1); i-- )
+#define Vec_WrdForEachEntryDouble( vVec, Entry1, Entry2, i ) \
+ for ( i = 0; (i+1 < Vec_WrdSize(vVec)) && (((Entry1) = Vec_WrdEntry(vVec, i)), 1) && (((Entry2) = Vec_WrdEntry(vVec, i+1)), 1); i += 2 )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@@ -167,6 +169,32 @@ static inline Vec_Wrd_t * Vec_WrdStartRandom( int nSize )
vSims->pArray[i] = Abc_RandomW(0);
return vSims;
}
+static inline Vec_Wrd_t * Vec_WrdStartTruthTables( int nVars )
+{
+ Vec_Wrd_t * p;
+ unsigned Masks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
+ int i, k, nWords;
+ nWords = nVars <= 6 ? 1 : (1 << (nVars - 6));
+ p = Vec_WrdStart( nWords * nVars );
+ for ( i = 0; i < nVars; i++ )
+ {
+ unsigned * pTruth = (unsigned *)(p->pArray + nWords * i);
+ if ( i < 5 )
+ {
+ for ( k = 0; k < 2*nWords; k++ )
+ pTruth[k] = Masks[i];
+ }
+ else
+ {
+ for ( k = 0; k < 2*nWords; k++ )
+ if ( k & (1 << (i-5)) )
+ pTruth[k] = ~(unsigned)0;
+ else
+ pTruth[k] = 0;
+ }
+ }
+ return p;
+}
/**Function*************************************************************
@@ -354,6 +382,10 @@ static inline int Vec_WrdSize( Vec_Wrd_t * p )
{
return p->nSize;
}
+static inline int Vec_WrdChangeSize( Vec_Wrd_t * p, int Shift )
+{
+ return p->nSize += Shift;
+}
/**Function*************************************************************
@@ -643,6 +675,30 @@ static inline void Vec_WrdPush( Vec_Wrd_t * p, word Entry )
}
p->pArray[p->nSize++] = Entry;
}
+static inline void Vec_WrdPushTwo( Vec_Wrd_t * p, word Entry1, word Entry2 )
+{
+ Vec_WrdPush( p, Entry1 );
+ Vec_WrdPush( p, Entry2 );
+}
+static inline void Vec_WrdPushThree( Vec_Wrd_t * p, word Entry1, word Entry2, word Entry3 )
+{
+ Vec_WrdPush( p, Entry1 );
+ Vec_WrdPush( p, Entry2 );
+ Vec_WrdPush( p, Entry3 );
+}
+static inline void Vec_WrdPushFour( Vec_Wrd_t * p, word Entry1, word Entry2, word Entry3, word Entry4 )
+{
+ Vec_WrdPush( p, Entry1 );
+ Vec_WrdPush( p, Entry2 );
+ Vec_WrdPush( p, Entry3 );
+ Vec_WrdPush( p, Entry4 );
+}
+static inline void Vec_WrdPushArray( Vec_Wrd_t * p, word * pEntries, int nEntries )
+{
+ int i;
+ for ( i = 0; i < nEntries; i++ )
+ Vec_WrdPush( p, pEntries[i] );
+}
/**Function*************************************************************
@@ -851,6 +907,14 @@ static inline void Vec_WrdInsert( Vec_Wrd_t * p, int iHere, word Entry )
p->pArray[i] = p->pArray[i-1];
p->pArray[i] = Entry;
}
+static inline void Vec_WrdDrop( Vec_Wrd_t * p, int i )
+{
+ int k;
+ assert( i >= 0 && i < Vec_WrdSize(p) );
+ p->nSize--;
+ for ( k = i; k < p->nSize; k++ )
+ p->pArray[k] = p->pArray[k+1];
+}
/**Function*************************************************************
@@ -1201,6 +1265,169 @@ static inline void Vec_WrdAppend( Vec_Wrd_t * vVec1, Vec_Wrd_t * vVec2 )
Vec_WrdPush( vVec1, Entry );
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Gia_ManSimPatWriteOne( FILE * pFile, word * pSim, int nWords )
+{
+ int k, Digit, nDigits = nWords*16;
+ for ( k = 0; k < nDigits; k++ )
+ {
+ Digit = (int)((pSim[k/16] >> ((k%16) * 4)) & 15);
+ if ( Digit < 10 )
+ fprintf( pFile, "%d", Digit );
+ else
+ fprintf( pFile, "%c", 'A' + Digit-10 );
+ }
+ fprintf( pFile, "\n" );
+}
+static inline void Vec_WrdPrintHex( Vec_Wrd_t * p, int nWords )
+{
+ int i, nNodes = Vec_WrdSize(p) / nWords;
+ assert( Vec_WrdSize(p) % nWords == 0 );
+ for ( i = 0; i < nNodes; i++ )
+ Gia_ManSimPatWriteOne( stdout, Vec_WrdEntryP(p, i*nWords), nWords );
+}
+static inline void Vec_WrdDumpHex( char * pFileName, Vec_Wrd_t * p, int nWords, int fVerbose )
+{
+ int i, nNodes = Vec_WrdSize(p) / nWords;
+ FILE * pFile = fopen( pFileName, "wb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for writing.\n", pFileName );
+ return;
+ }
+ assert( Vec_WrdSize(p) % nWords == 0 );
+ for ( i = 0; i < nNodes; i++ )
+ Gia_ManSimPatWriteOne( pFile, Vec_WrdEntryP(p, i*nWords), nWords );
+ fclose( pFile );
+ if ( fVerbose )
+ printf( "Written %d words of simulation data for %d objects into file \"%s\".\n", nWords, Vec_WrdSize(p)/nWords, pFileName );
+}
+static inline int Vec_WrdReadHexOne( char c )
+{
+ int Digit = 0;
+ if ( c >= '0' && c <= '9' )
+ Digit = c - '0';
+ else if ( c >= 'A' && c <= 'F' )
+ Digit = c - 'A' + 10;
+ else if ( c >= 'a' && c <= 'f' )
+ Digit = c - 'a' + 10;
+ else assert( 0 );
+ assert( Digit >= 0 && Digit < 16 );
+ return Digit;
+}
+static inline Vec_Wrd_t * Vec_WrdReadHex( char * pFileName, int * pnWords, int fVerbose )
+{
+ Vec_Wrd_t * p = NULL;
+ int c, nWords = -1, nChars = 0; word Num = 0;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return NULL;
+ }
+ p = Vec_WrdAlloc( 1000 );
+ while ( (c = fgetc(pFile)) != EOF )
+ {
+ if ( c == '\r' || c == '\t' || c == ' ' )
+ continue;
+ if ( c == '\n' )
+ {
+ if ( nChars > 0 )
+ {
+ Vec_WrdPush( p, Num );
+ nChars = 0;
+ Num = 0;
+ }
+ if ( nWords == -1 && Vec_WrdSize(p) > 0 )
+ nWords = Vec_WrdSize(p);
+ continue;
+ }
+ Num |= (word)Vec_WrdReadHexOne((char)c) << (nChars * 4);
+ if ( ++nChars < 16 )
+ continue;
+ Vec_WrdPush( p, Num );
+ nChars = 0;
+ Num = 0;
+ }
+ assert( Vec_WrdSize(p) % nWords == 0 );
+ fclose( pFile );
+ if ( pnWords )
+ *pnWords = nWords;
+ if ( fVerbose )
+ printf( "Read %d words of simulation data for %d objects.\n", nWords, Vec_WrdSize(p)/nWords );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_WrdDumpBin( char * pFileName, Vec_Wrd_t * p, int fVerbose )
+{
+ int RetValue;
+ FILE * pFile = fopen( pFileName, "wb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for writing.\n", pFileName );
+ return;
+ }
+ RetValue = fwrite( Vec_WrdArray(p), 1, 8*Vec_WrdSize(p), pFile );
+ fclose( pFile );
+ if ( RetValue != 8*Vec_WrdSize(p) )
+ printf( "Error reading data from file.\n" );
+ if ( fVerbose )
+ printf( "Written %d words of simulation data into file \"%s\".\n", Vec_WrdSize(p), pFileName );
+}
+static inline Vec_Wrd_t * Vec_WrdReadBin( char * pFileName, int fVerbose )
+{
+ Vec_Wrd_t * p = NULL; int nSize, RetValue;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return NULL;
+ }
+ fseek( pFile, 0, SEEK_END );
+ nSize = ftell( pFile );
+ if ( nSize == 0 )
+ {
+ printf( "The input file is empty.\n" );
+ fclose( pFile );
+ return NULL;
+ }
+ if ( nSize % 8 > 0 )
+ {
+ printf( "Cannot read file with simulation data that is not aligned at 8 bytes (remainder = %d).\n", nSize % 8 );
+ fclose( pFile );
+ return NULL;
+ }
+ rewind( pFile );
+ p = Vec_WrdStart( nSize/8 );
+ RetValue = fread( Vec_WrdArray(p), 1, nSize, pFile );
+ fclose( pFile );
+ if ( RetValue != nSize )
+ printf( "Error reading data from file.\n" );
+ if ( fVerbose )
+ printf( "Read %d words of simulation data from file \"%s\".\n", nSize/8, pFileName );
+ return p;
+}
ABC_NAMESPACE_HEADER_END
diff --git a/src/opt/cgt/cgtAig.c b/src/opt/cgt/cgtAig.c
index 9421b75e..2a3b342c 100644
--- a/src/opt/cgt/cgtAig.c
+++ b/src/opt/cgt/cgtAig.c
@@ -133,7 +133,7 @@ void Cgt_ManDetectFanout( Aig_Man_t * pAig, Aig_Obj_t * pObj, int nOdcMax, Vec_P
Vec_PtrWriteEntry( vFanout, k++, pObj );
}
Vec_PtrShrink( vFanout, k );
- Vec_PtrSort( vFanout, (int (*)(void))Aig_ObjCompareIdIncrease );
+ Vec_PtrSort( vFanout, (int (*)(const void *, const void *))Aig_ObjCompareIdIncrease );
assert( Vec_PtrSize(vFanout) > 0 );
}
diff --git a/src/opt/dar/darBalance.c b/src/opt/dar/darBalance.c
index f51a7852..d8195762 100644
--- a/src/opt/dar/darBalance.c
+++ b/src/opt/dar/darBalance.c
@@ -59,7 +59,7 @@ void Dar_BalanceUniqify( Aig_Obj_t * pObj, Vec_Ptr_t * vNodes, int fExor )
Aig_Obj_t * pTemp, * pTempNext;
int i, k;
// sort the nodes by their literal
- Vec_PtrSort( vNodes, (int (*)())Dar_ObjCompareLits );
+ Vec_PtrSort( vNodes, (int (*)(const void *, const void *))Dar_ObjCompareLits );
// remove duplicates
k = 0;
Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pTemp, i )
@@ -402,7 +402,7 @@ Aig_Obj_t * Dar_BalanceBuildSuper( Aig_Man_t * p, Vec_Ptr_t * vSuper, Aig_Type_t
int LeftBound;
assert( vSuper->nSize > 1 );
// sort the new nodes by level in the decreasing order
- Vec_PtrSort( vSuper, (int (*)(void))Aig_NodeCompareLevelsDecrease );
+ Vec_PtrSort( vSuper, (int (*)(const void *, const void *))Aig_NodeCompareLevelsDecrease );
// balance the nodes
while ( vSuper->nSize > 1 )
{
@@ -415,7 +415,7 @@ Aig_Obj_t * Dar_BalanceBuildSuper( Aig_Man_t * p, Vec_Ptr_t * vSuper, Aig_Type_t
pObj2 = (Aig_Obj_t *)Vec_PtrPop(vSuper);
Dar_BalancePushUniqueOrderByLevel( vSuper, Aig_Oper(p, pObj1, pObj2, Type), Type == AIG_OBJ_EXOR );
}
- return (Aig_Obj_t *)Vec_PtrEntry(vSuper, 0);
+ return vSuper->nSize ? (Aig_Obj_t *)Vec_PtrEntry(vSuper, 0) : Aig_ManConst0(p);
}
@@ -462,7 +462,7 @@ Aig_Obj_t * Dar_BalanceBuildSuperTop( Aig_Man_t * p, Vec_Ptr_t * vSuper, Aig_Typ
int i, nBaseSizeAll, nBaseSize;
assert( vSuper->nSize > 1 );
// sort the new nodes by level in the decreasing order
- Vec_PtrSort( vSuper, (int (*)(void))Aig_NodeCompareLevelsDecrease );
+ Vec_PtrSort( vSuper, (int (*)(const void *, const void *))Aig_NodeCompareLevelsDecrease );
// add one LUT at a time
while ( Vec_PtrSize(vSuper) > 1 )
{
diff --git a/src/opt/dar/darScript.c b/src/opt/dar/darScript.c
index f8fa3788..d95c23d7 100644
--- a/src/opt/dar/darScript.c
+++ b/src/opt/dar/darScript.c
@@ -848,6 +848,7 @@ pPars->timeSynth = Abc_Clock() - clk;
***********************************************************************/
Aig_Man_t * Dar_ManChoiceNew( Aig_Man_t * pAig, Dch_Pars_t * pPars )
{
+ extern Aig_Man_t * Cec_ComputeChoicesNew( Gia_Man_t * pGia, int nConfs, int fVerbose );
extern Aig_Man_t * Cec_ComputeChoices( Gia_Man_t * pGia, Dch_Pars_t * pPars );
// extern Aig_Man_t * Dch_DeriveTotalAig( Vec_Ptr_t * vAigs );
extern Aig_Man_t * Dch_ComputeChoices( Aig_Man_t * pAig, Dch_Pars_t * pPars );
@@ -870,15 +871,17 @@ clk = Abc_Clock();
pPars->timeSynth = Abc_Clock() - clk;
// perform choice computation
- if ( pPars->fUseGia )
+ if ( pPars->fUseNew )
+ pMan = Cec_ComputeChoicesNew( pGia, pPars->nBTLimit, pPars->fVerbose );
+ else if ( pPars->fUseGia )
pMan = Cec_ComputeChoices( pGia, pPars );
else
{
pMan = Gia_ManToAigSkip( pGia, 3 );
- Gia_ManStop( pGia );
pMan = Dch_ComputeChoices( pTemp = pMan, pPars );
Aig_ManStop( pTemp );
}
+ Gia_ManStop( pGia );
// create guidence
vPios = Aig_ManOrderPios( pMan, pAig );
diff --git a/src/opt/dau/dauDsd.c b/src/opt/dau/dauDsd.c
index b1e7e0d8..3e11a15d 100644
--- a/src/opt/dau/dauDsd.c
+++ b/src/opt/dau/dauDsd.c
@@ -1973,6 +1973,14 @@ void Dau_DsdPrintFromTruth( word * pTruth, int nVarsInit )
Dau_DsdDecompose( pTemp, nVarsInit, 0, 1, pRes );
fprintf( stdout, "%s\n", pRes );
}
+void Dau_DsdPrintFromTruth2( word * pTruth, int nVarsInit )
+{
+ char pRes[DAU_MAX_STR];
+ word pTemp[DAU_MAX_WORD];
+ Abc_TtCopy( pTemp, pTruth, Abc_TtWordNum(nVarsInit), 0 );
+ Dau_DsdDecompose( pTemp, nVarsInit, 0, 1, pRes );
+ fprintf( stdout, "%s", pRes );
+}
void Dau_DsdTest44()
{
diff --git a/src/opt/fxch/FxchSCHashTable.c b/src/opt/fxch/FxchSCHashTable.c
index 28f925e1..c574509f 100644
--- a/src/opt/fxch/FxchSCHashTable.c
+++ b/src/opt/fxch/FxchSCHashTable.c
@@ -17,6 +17,10 @@
***********************************************************************/
#include "Fxch.h"
+#if (__GNUC__ >= 8)
+ #pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#endif
+
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
diff --git a/src/opt/fxu/fxuReduce.c b/src/opt/fxu/fxuReduce.c
index 7542a432..84e2bf87 100644
--- a/src/opt/fxu/fxuReduce.c
+++ b/src/opt/fxu/fxuReduce.c
@@ -86,8 +86,7 @@ int Fxu_PreprocessCubePairs( Fxu_Matrix * p, Vec_Ptr_t * vCovers, int nPairsTota
assert( iPair == nPairsTotal );
// allocate storage for counters of cube pairs by difference
- pnPairCounters = ABC_FALLOC( int, 2 * nBitsMax );
- memset( pnPairCounters, 0, sizeof(int) * 2 * nBitsMax );
+ pnPairCounters = ABC_CALLOC( int, 2 * nBitsMax );
// count the number of different pairs
for ( k = 0; k < nPairsTotal; k++ )
pnPairCounters[ pnLitsDiff[k] ]++;
diff --git a/src/opt/mfs/mfsDiv.c b/src/opt/mfs/mfsDiv.c
index ece8ec64..535e8d23 100644
--- a/src/opt/mfs/mfsDiv.c
+++ b/src/opt/mfs/mfsDiv.c
@@ -282,7 +282,7 @@ Vec_Ptr_t * Abc_MfsComputeDivisors( Mfs_Man_t * p, Abc_Obj_t * pNode, int nLevDi
p->nMaxDivs += (Vec_PtrSize(vDivs) >= p->pPars->nWinMax);
// sort the divisors by level in the increasing order
- Vec_PtrSort( vDivs, (int (*)(void))Abc_NodeCompareLevelsIncrease );
+ Vec_PtrSort( vDivs, (int (*)(const void *, const void *))Abc_NodeCompareLevelsIncrease );
// add the fanins of the node
Abc_ObjForEachFanin( pNode, pFanin, k )
diff --git a/src/opt/sbd/sbdCut2.c b/src/opt/sbd/sbdCut2.c
index b4a8be74..b9ef4d82 100644
--- a/src/opt/sbd/sbdCut2.c
+++ b/src/opt/sbd/sbdCut2.c
@@ -193,7 +193,7 @@ static inline int Sbd_ManCutExpandOne( Gia_Man_t * p, Vec_Int_t * vMirrors, Vec_
Vec_IntPushOrder( vCut, Fan1 );
return 1;
}
-void Vec_IntIsOrdered( Vec_Int_t * vCut )
+void Vec_IntOrdered( Vec_Int_t * vCut )
{
int i, Prev, Entry;
Prev = Vec_IntEntry( vCut, 0 );
@@ -229,7 +229,7 @@ void Sbd_ManCutReload( Vec_Int_t * vMirrors, Vec_Int_t * vLutLevs, int LevStop,
else
Vec_IntPush( vCutBot, Entry );
}
- Vec_IntIsOrdered( vCut );
+ Vec_IntOrdered( vCut );
}
int Sbd_ManCutCollect_rec( Gia_Man_t * p, Vec_Int_t * vMirrors, int iObj, int LevStop, Vec_Int_t * vLutLevs, Vec_Int_t * vCut )
{
@@ -267,7 +267,7 @@ int Sbd_ManCutReduceTop( Gia_Man_t * p, Vec_Int_t * vMirrors, int iObj, Vec_Int_
{
int i, Entry, Lit0m, Lit1m, Fan0, Fan1;
int LevStop = Vec_IntEntry(vLutLevs, iObj) - 2;
- Vec_IntIsOrdered( vCut );
+ Vec_IntOrdered( vCut );
Vec_IntForEachEntryReverse( vCutTop, Entry, i )
{
Gia_Obj_t * pObj = Gia_ManObj( p, Entry );
diff --git a/src/opt/sfm/sfm.h b/src/opt/sfm/sfm.h
index 1aa8b7d0..f9c95c83 100644
--- a/src/opt/sfm/sfm.h
+++ b/src/opt/sfm/sfm.h
@@ -66,6 +66,7 @@ struct Sfm_Par_t_
int fUseAndOr; // enable internal detection of AND/OR gates
int fZeroCost; // enable zero-cost replacement
int fUseSim; // enable simulation
+ int fUseDcs; // enable deriving don't-cares
int fPrintDecs; // enable printing decompositions
int fAllBoxes; // enable preserving all boxes
int fLibVerbose; // enable library stats
diff --git a/src/opt/sfm/sfmCore.c b/src/opt/sfm/sfmCore.c
index 27d584b4..356aea35 100644
--- a/src/opt/sfm/sfmCore.c
+++ b/src/opt/sfm/sfmCore.c
@@ -19,6 +19,7 @@
***********************************************************************/
#include "sfmInt.h"
+#include "bool/kit/kit.h"
ABC_NAMESPACE_IMPL_START
@@ -79,6 +80,8 @@ void Sfm_NtkPrintStats( Sfm_Ntk_t * p )
printf( "Attempts : " );
printf( "Remove %6d out of %6d (%6.2f %%) ", p->nRemoves, p->nTryRemoves, 100.0*p->nRemoves/Abc_MaxInt(1, p->nTryRemoves) );
printf( "Resub %6d out of %6d (%6.2f %%) ", p->nResubs, p->nTryResubs, 100.0*p->nResubs /Abc_MaxInt(1, p->nTryResubs) );
+ if ( p->pPars->fUseDcs )
+ printf( "Improves %6d out of %6d (%6.2f %%) ", p->nImproves,p->nTryImproves,100.0*p->nImproves/Abc_MaxInt(1, p->nTryImproves));
printf( "\n" );
printf( "Reduction: " );
@@ -213,7 +216,69 @@ finish:
// update the network
Sfm_NtkUpdate( p, iNode, f, (iVar == -1 ? iVar : Vec_IntEntry(p->vDivs, iVar)), uTruth );
return 1;
- }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs resubstitution for the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Sfm_NodeResubOne( Sfm_Ntk_t * p, int iNode )
+{
+ int fSkipUpdate = 0;
+ int i, iFanin;
+ word uTruth;
+ abctime clk;
+ assert( Sfm_ObjIsNode(p, iNode) );
+ p->nTryImproves++;
+ // report init stats
+ if ( p->pPars->fVeryVerbose )
+ printf( "%5d : Lev =%3d. Leaf =%3d. Node =%3d. Div=%3d. Fanins = %d. MFFC = %d\n",
+ iNode, Sfm_ObjLevel(p, iNode), 0, Vec_IntSize(p->vNodes), Vec_IntSize(p->vDivs),
+ Sfm_ObjFaninNum(p, iNode), Sfm_ObjMffcSize(p, iNode) );
+ // collect fanins
+ Vec_IntClear( p->vDivIds );
+ Sfm_ObjForEachFanin( p, iNode, iFanin, i )
+ Vec_IntPush( p->vDivIds, Sfm_ObjSatVar(p, iFanin) );
+clk = Abc_Clock();
+ uTruth = Sfm_ComputeInterpolant2( p );
+p->timeSat += Abc_Clock() - clk;
+ // analyze outcomes
+ if ( uTruth == SFM_SAT_UNDEC )
+ {
+ p->nTimeOuts++;
+ return 0;
+ }
+ assert( uTruth != SFM_SAT_SAT );
+ if ( uTruth == Vec_WrdEntry(p->vTruths, iNode) )
+ return 0;
+ else
+ {
+ word uTruth0 = Vec_WrdEntry(p->vTruths, iNode);
+ //word uTruth0N = ~uTruth0;
+ //word uTruthN = ~uTruth;
+ int Old = Kit_TruthLitNum((unsigned*)&uTruth0, Sfm_ObjFaninNum(p, iNode), p->vCover);
+ //int OldN = Kit_TruthLitNum((unsigned*)&uTruth0N, Sfm_ObjFaninNum(p, iNode), p->vCover);
+ int New = Kit_TruthLitNum((unsigned*)&uTruth, Sfm_ObjFaninNum(p, iNode), p->vCover);
+ //int NewN = Kit_TruthLitNum((unsigned*)&uTruthN, Sfm_ObjFaninNum(p, iNode), p->vCover);
+ //if ( Abc_MinInt(New, NewN) > Abc_MinInt(Old, OldN) )
+ if ( New > Old )
+ return 0;
+ }
+ p->nImproves++;
+ if ( fSkipUpdate )
+ return 0;
+ // update truth table
+ Vec_WrdWriteEntry( p->vTruths, iNode, uTruth );
+ Sfm_TruthToCnf( uTruth, NULL, Sfm_ObjFaninNum(p, iNode), p->vCover, (Vec_Str_t *)Vec_WecEntry(p->vCnfs, iNode) );
+ return 1;
+}
int Sfm_NodeResub( Sfm_Ntk_t * p, int iNode )
{
int i, iFanin;
@@ -230,15 +295,18 @@ int Sfm_NodeResub( Sfm_Ntk_t * p, int iNode )
if ( Sfm_NodeResubSolve( p, iNode, i, 0 ) )
return 1;
}
- if ( p->pPars->fArea )
- return 0;
// try removing redundant edges
+ if ( !p->pPars->fArea )
Sfm_ObjForEachFanin( p, iNode, iFanin, i )
if ( !(Sfm_ObjIsNode(p, iFanin) && Sfm_ObjFanoutNum(p, iFanin) == 1) )
{
if ( Sfm_NodeResubSolve( p, iNode, i, 1 ) )
return 1;
}
+ // try simplifying local functions
+ if ( p->pPars->fUseDcs )
+ if ( Sfm_NodeResubOne( p, iNode ) )
+ return 1;
/*
// try replacing area critical fanins while adding two new fanins
if ( Sfm_ObjFaninNum(p, iNode) < p->nFaninMax )
diff --git a/src/opt/sfm/sfmInt.h b/src/opt/sfm/sfmInt.h
index 80edd54d..08edf353 100644
--- a/src/opt/sfm/sfmInt.h
+++ b/src/opt/sfm/sfmInt.h
@@ -107,8 +107,10 @@ struct Sfm_Ntk_t_
sat_solver * pSat; // SAT solver
int nSatVars; // the number of variables
int nTryRemoves; // number of fanin removals
+ int nTryImproves;// number of node improvements
int nTryResubs; // number of resubstitutions
int nRemoves; // number of fanin removals
+ int nImproves; // number of node improvements
int nResubs; // number of resubstitutions
// counter-examples
int nCexes; // number of CEXes
@@ -218,6 +220,7 @@ extern void Sfm_NtkUpdate( Sfm_Ntk_t * p, int iNode, int f, int iFaninNe
/*=== sfmSat.c ==========================================================*/
extern int Sfm_NtkWindowToSolver( Sfm_Ntk_t * p );
extern word Sfm_ComputeInterpolant( Sfm_Ntk_t * p );
+extern word Sfm_ComputeInterpolant2( Sfm_Ntk_t * p );
/*=== sfmTim.c ==========================================================*/
extern Sfm_Tim_t * Sfm_TimStart( Mio_Library_t * pLib, Scl_Con_t * pExt, Abc_Ntk_t * pNtk, int DeltaCrit );
extern void Sfm_TimStop( Sfm_Tim_t * p );
diff --git a/src/opt/sfm/sfmSat.c b/src/opt/sfm/sfmSat.c
index 6ccdd903..ed38e681 100644
--- a/src/opt/sfm/sfmSat.c
+++ b/src/opt/sfm/sfmSat.c
@@ -19,6 +19,7 @@
***********************************************************************/
#include "sfmInt.h"
+#include "misc/util/utilTruth.h"
ABC_NAMESPACE_IMPL_START
@@ -27,15 +28,6 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-static word s_Truths6[6] = {
- ABC_CONST(0xAAAAAAAAAAAAAAAA),
- ABC_CONST(0xCCCCCCCCCCCCCCCC),
- ABC_CONST(0xF0F0F0F0F0F0F0F0),
- ABC_CONST(0xFF00FF00FF00FF00),
- ABC_CONST(0xFFFF0000FFFF0000),
- ABC_CONST(0xFFFFFFFF00000000)
-};
-
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -228,6 +220,100 @@ word Sfm_ComputeInterpolant( Sfm_Ntk_t * p )
/**Function*************************************************************
+ Synopsis [Takes SAT solver and returns interpolant.]
+
+ Description [If interpolant does not exist, records difference variables.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Sfm_ComputeInterpolantInt( Sfm_Ntk_t * p, word Truth[2] )
+{
+ int fOnSet, iMint, iVar, nVars = sat_solver_nvars( p->pSat );
+ int iVarPivot = Sfm_ObjSatVar( p, p->iPivotNode );
+ int status, iNewLit, i, Div, nIter = 0;
+ Truth[0] = Truth[1] = 0;
+ sat_solver_setnvars( p->pSat, nVars + 1 );
+ iNewLit = Abc_Var2Lit( nVars, 0 ); // iNewLit
+ assert( Vec_IntSize(p->vDivIds) <= 6 );
+ Vec_IntFill( p->vValues, (1 << Vec_IntSize(p->vDivIds)) * Vec_IntSize(p->vDivVars), -1 );
+ while ( 1 )
+ {
+ // find care minterm
+ p->nSatCalls++; nIter++;
+ status = sat_solver_solve( p->pSat, &iNewLit, &iNewLit + 1, p->pPars->nBTLimit, 0, 0, 0 );
+ if ( status == l_Undef )
+ return l_Undef;
+ if ( status == l_False )
+ return l_False;
+ assert( status == l_True );
+ // collect values
+ iMint = 0;
+ fOnSet = sat_solver_var_value(p->pSat, iVarPivot);
+ Vec_IntClear( p->vLits );
+ Vec_IntPush( p->vLits, Abc_LitNot(iNewLit) ); // NOT(iNewLit)
+ Vec_IntPush( p->vLits, Abc_LitNot(sat_solver_var_literal(p->pSat, iVarPivot)) );
+ Vec_IntForEachEntry( p->vDivIds, Div, i )
+ {
+ Vec_IntPush( p->vLits, Abc_LitNot(sat_solver_var_literal(p->pSat, Div)) );
+ if ( sat_solver_var_value(p->pSat, Div) )
+ iMint |= 1 << i;
+ }
+ if ( Truth[!fOnSet] & ((word)1 << iMint) )
+ break;
+ assert( !(Truth[fOnSet] & ((word)1 << iMint)) );
+ Truth[fOnSet] |= ((word)1 << iMint);
+ // remember variable values
+ Vec_IntForEachEntry( p->vDivVars, iVar, i )
+ Vec_IntWriteEntry( p->vValues, iMint * Vec_IntSize(p->vDivVars) + i, sat_solver_var_value(p->pSat, iVar) );
+ status = sat_solver_addclause( p->pSat, Vec_IntArray(p->vLits), Vec_IntArray(p->vLits) + Vec_IntSize(p->vLits) );
+ if ( status == 0 )
+ return l_False;
+ }
+ assert( status == l_True );
+ // store the counter-example
+ assert( iMint < (1 << Vec_IntSize(p->vDivIds)) );
+ Vec_IntForEachEntry( p->vDivVars, iVar, i )
+ {
+ int Value = Vec_IntEntry(p->vValues, iMint * Vec_IntSize(p->vDivVars) + i);
+ assert( Value != -1 );
+ if ( Value ^ sat_solver_var_value(p->pSat, iVar) ) // insert 1
+ {
+ word * pSign = Vec_WrdEntryP( p->vDivCexes, i );
+ assert( !Abc_InfoHasBit( (unsigned *)pSign, p->nCexes) );
+ Abc_InfoXorBit( (unsigned *)pSign, p->nCexes );
+ }
+ }
+ p->nCexes++;
+ return l_True;
+}
+word Sfm_ComputeInterpolant2( Sfm_Ntk_t * p )
+{
+ word Res, ResP, ResN, Truth[2];
+ int nCubesP = 0, nCubesN = 0;
+ int RetValue = Sfm_ComputeInterpolantInt( p, Truth );
+ if ( RetValue == l_Undef )
+ return SFM_SAT_UNDEC;
+ if ( RetValue == l_True )
+ return SFM_SAT_SAT;
+ assert( RetValue == l_False );
+ //printf( "Offset = %2d. Onset = %2d. DC = %2d. Total = %2d.\n",
+ // Abc_TtCountOnes(Truth[0]), Abc_TtCountOnes(Truth[1]),
+ // (1<<Vec_IntSize(p->vDivIds)) - (Abc_TtCountOnes(Truth[0]) + Abc_TtCountOnes(Truth[1])),
+ // 1<<Vec_IntSize(p->vDivIds) );
+ Truth[0] = Abc_Tt6Stretch( Truth[0], Vec_IntSize(p->vDivIds) );
+ Truth[1] = Abc_Tt6Stretch( Truth[1], Vec_IntSize(p->vDivIds) );
+ ResP = Abc_Tt6Isop( Truth[1], ~Truth[0], Vec_IntSize(p->vDivIds), &nCubesP );
+ ResN = Abc_Tt6Isop( Truth[0], ~Truth[1], Vec_IntSize(p->vDivIds), &nCubesN );
+ Res = nCubesP <= nCubesN ? ResP : ~ResN;
+ //Dau_DsdPrintFromTruth( &Res, Vec_IntSize(p->vDivIds) );
+ return Res;
+}
+
+/**Function*************************************************************
+
Synopsis [Checks resubstitution.]
Description []
diff --git a/src/opt/sfm/sfmWin.c b/src/opt/sfm/sfmWin.c
index 63750407..53f9a71e 100644
--- a/src/opt/sfm/sfmWin.c
+++ b/src/opt/sfm/sfmWin.c
@@ -365,15 +365,15 @@ int Sfm_NtkCreateWindow( Sfm_Ntk_t * p, int iNode, int fVerbose )
Vec_IntAppend( p->vDivs, p->vNodes );
Vec_IntPop( p->vDivs );
// add non-topological divisors
- if ( Vec_IntSize(p->vDivs) < p->pPars->nWinSizeMax + 0 )
+ if ( !p->pPars->nWinSizeMax || Vec_IntSize(p->vDivs) < p->pPars->nWinSizeMax + 0 )
{
Sfm_NtkIncrementTravId2( p );
Vec_IntForEachEntry( p->vDivs, iTemp, i )
- if ( Vec_IntSize(p->vDivs) < p->pPars->nWinSizeMax + 0 )
+ if ( !p->pPars->nWinSizeMax || Vec_IntSize(p->vDivs) < p->pPars->nWinSizeMax + 0 )
// Sfm_NtkAddDivisors( p, iTemp, Sfm_ObjLevel(p, iNode) - 1 );
Sfm_NtkAddDivisors( p, iTemp, p->nLevelMax - Sfm_ObjLevelR(p, iNode) );
}
- if ( Vec_IntSize(p->vDivs) > p->pPars->nWinSizeMax )
+ if ( p->pPars->nWinSizeMax && Vec_IntSize(p->vDivs) > p->pPars->nWinSizeMax )
{
/*
k = 0;
@@ -383,8 +383,8 @@ int Sfm_NtkCreateWindow( Sfm_Ntk_t * p, int iNode, int fVerbose )
*/
Vec_IntShrink( p->vDivs, p->pPars->nWinSizeMax );
}
- assert( Vec_IntSize(p->vDivs) <= p->pPars->nWinSizeMax );
- p->nMaxDivs += (int)(Vec_IntSize(p->vDivs) == p->pPars->nWinSizeMax);
+ assert( !p->pPars->nWinSizeMax || Vec_IntSize(p->vDivs) <= p->pPars->nWinSizeMax );
+ p->nMaxDivs += (int)(p->pPars->nWinSizeMax && Vec_IntSize(p->vDivs) == p->pPars->nWinSizeMax);
// remove node/fanins from divisors
// mark fanins
Sfm_NtkIncrementTravId2( p );
@@ -397,7 +397,7 @@ int Sfm_NtkCreateWindow( Sfm_Ntk_t * p, int iNode, int fVerbose )
if ( !Sfm_ObjIsTravIdCurrent2(p, iTemp) && Sfm_ObjIsUseful(p, iTemp) )
Vec_IntWriteEntry( p->vDivs, k++, iTemp );
Vec_IntShrink( p->vDivs, k );
- assert( Vec_IntSize(p->vDivs) <= p->pPars->nWinSizeMax );
+ assert( !p->pPars->nWinSizeMax || Vec_IntSize(p->vDivs) <= p->pPars->nWinSizeMax );
clkDiv = Abc_Clock() - clkDiv;
p->timeDiv += clkDiv;
p->nTotalDivs += Vec_IntSize(p->vDivs);
diff --git a/src/proof/abs/absVta.c b/src/proof/abs/absVta.c
index 597e4b72..b6001d3f 100644
--- a/src/proof/abs/absVta.c
+++ b/src/proof/abs/absVta.c
@@ -705,8 +705,8 @@ Abc_Cex_t * Vta_ManRefineAbstraction( Vta_Man_t * p, int f )
// objects with equal distance should receive priority based on number
// those objects whose prototypes have been added in other timeframes
// should have higher priority than the current object
- Vec_PtrSort( vTermsUsed, (int (*)(void))Vta_ManComputeDepthIncrease );
- Vec_PtrSort( vTermsUnused, (int (*)(void))Vta_ManComputeDepthIncrease );
+ Vec_PtrSort( vTermsUsed, (int (*)(const void *, const void *))Vta_ManComputeDepthIncrease );
+ Vec_PtrSort( vTermsUnused, (int (*)(const void *, const void *))Vta_ManComputeDepthIncrease );
if ( Vec_PtrSize(vTermsUsed) > 1 )
{
pThis0 = (Vta_Obj_t *)Vec_PtrEntry(vTermsUsed, 0);
diff --git a/src/proof/acec/acecFadds.c b/src/proof/acec/acecFadds.c
index d55eefe2..a2bdcfbe 100644
--- a/src/proof/acec/acecFadds.c
+++ b/src/proof/acec/acecFadds.c
@@ -314,16 +314,21 @@ void Dtc_ManCutMerge( Gia_Man_t * p, int iObj, int * pList0, int * pList1, Vec_I
if ( Type == 0 )
continue;
vTemp = Type == 1 ? vCutsXor : vCutsMaj;
- if ( fVerbose )
- printf( "%d = %s(", iObj, Type == 1 ? "XOR" : "MAJ" );
- for ( c = 1; c <= pCut[0]; c++ )
+ if ( 0 && Type == 2 )
{
+ fVerbose = 1;
+ if ( fVerbose )
+ printf( "%d = %s(", iObj, Type == 1 ? "XOR" : "MAJ" );
+ for ( c = 1; c <= pCut[0]; c++ )
+ {
+ if ( fVerbose )
+ printf( " %d", pCut[c] );
+ Vec_IntPush( vTemp, pCut[c] );
+ }
if ( fVerbose )
- printf( " %d", pCut[c] );
- Vec_IntPush( vTemp, pCut[c] );
+ printf( " )\n" );
+ fVerbose = 0;
}
- if ( fVerbose )
- printf( " )\n" );
Vec_IntPush( vTemp, iObj );
}
}
@@ -450,6 +455,16 @@ Vec_Int_t * Gia_ManDetectFullAdders( Gia_Man_t * p, int fVerbose, Vec_Int_t ** p
Vec_IntFree( vCutsMaj );
return vFadds;
}
+void Gia_ManDetectFullAdders2( Gia_Man_t * p, int fVerbose )
+{
+ Vec_Int_t * vCutsXor2, * vCutsXor, * vCutsMaj;
+ Dtc_ManComputeCuts( p, &vCutsXor2, &vCutsXor, &vCutsMaj, fVerbose );
+ if ( fVerbose )
+ printf( "XOR3 cuts = %d. MAJ cuts = %d.\n", Vec_IntSize(vCutsXor)/4, Vec_IntSize(vCutsMaj)/4 );
+ Vec_IntFree( vCutsXor2 );
+ Vec_IntFree( vCutsXor );
+ Vec_IntFree( vCutsMaj );
+}
/**Function*************************************************************
@@ -1238,6 +1253,7 @@ Gia_Man_t * Gia_ManDupWithArtificialBoxes( Gia_Man_t * p, int DelayC, int nPathM
return pNew;
}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/proof/cec/cec.h b/src/proof/cec/cec.h
index 757d9fd3..7c101570 100644
--- a/src/proof/cec/cec.h
+++ b/src/proof/cec/cec.h
@@ -43,6 +43,7 @@ ABC_NAMESPACE_HEADER_START
typedef struct Cec_ParSat_t_ Cec_ParSat_t;
struct Cec_ParSat_t_
{
+ int SolverType; // SAT solver type
int nBTLimit; // conflict limit at a node
int nSatVarMax; // the max number of SAT variables
int nCallsRecycle; // calls to perform before recycling SAT solver
@@ -95,13 +96,18 @@ struct Cec_ParSmf_t_
typedef struct Cec_ParFra_t_ Cec_ParFra_t;
struct Cec_ParFra_t_
{
+ int jType; // solver type
int nWords; // the number of simulation words
int nRounds; // the number of simulation rounds
int nItersMax; // the maximum number of iterations of SAT sweeping
int nBTLimit; // conflict limit at a node
+ int nBTLimitPo; // conflict limit at an output
int TimeLimit; // the runtime limit in seconds
int nLevelMax; // restriction on the level nodes to be swept
int nDepthMax; // the depth in terms of steps of speculative reduction
+ int nCallsRecycle; // calls to perform before recycling SAT solver
+ int nSatVarMax; // the max number of SAT variables
+ int nGenIters; // pattern generation iterations
int fRewriting; // enables AIG rewriting
int fCheckMiter; // the circuit is the miter
// int fFirstStop; // stop on the first sat output
@@ -215,7 +221,7 @@ extern void Cec_ManCecSetDefaultParams( Cec_ParCec_t * p );
extern void Cec_ManCorSetDefaultParams( Cec_ParCor_t * p );
extern void Cec_ManChcSetDefaultParams( Cec_ParChc_t * p );
extern Gia_Man_t * Cec_ManSatSweeping( Gia_Man_t * pAig, Cec_ParFra_t * pPars, int fSilent );
-extern Gia_Man_t * Cec_ManSatSolving( Gia_Man_t * pAig, Cec_ParSat_t * pPars );
+extern Gia_Man_t * Cec_ManSatSolving( Gia_Man_t * pAig, Cec_ParSat_t * pPars, int f0Proved );
extern void Cec_ManSimulation( Gia_Man_t * pAig, Cec_ParSim_t * pPars );
/*=== cecSeq.c ==========================================================*/
extern int Cec_ManSeqResimulateCounter( Gia_Man_t * pAig, Cec_ParSim_t * pPars, Abc_Cex_t * pCex );
diff --git a/src/proof/cec/cecCec.c b/src/proof/cec/cecCec.c
index ee45aa6c..cfa07ff8 100644
--- a/src/proof/cec/cecCec.c
+++ b/src/proof/cec/cecCec.c
@@ -349,12 +349,18 @@ int Cec_ManVerify( Gia_Man_t * pInit, Cec_ParCec_t * pPars )
Gia_ManStop( p );
return RetValue;
}
+ if ( pInit->vSimsPi )
+ {
+ p->vSimsPi = Vec_WrdDup(pInit->vSimsPi);
+ p->nSimWords = pInit->nSimWords;
+ }
// sweep for equivalences
Cec_ManFraSetDefaultParams( pParsFra );
pParsFra->nItersMax = 1000;
pParsFra->nBTLimit = pPars->nBTLimit;
pParsFra->TimeLimit = pPars->TimeLimit;
pParsFra->fVerbose = pPars->fVerbose;
+ pParsFra->fVeryVerbose = pPars->fVeryVerbose;
pParsFra->fCheckMiter = 1;
pParsFra->fDualOut = 1;
pNew = Cec_ManSatSweeping( p, pParsFra, pPars->fSilent );
diff --git a/src/proof/cec/cecChoice.c b/src/proof/cec/cecChoice.c
index 49025630..db0059fd 100644
--- a/src/proof/cec/cecChoice.c
+++ b/src/proof/cec/cecChoice.c
@@ -256,7 +256,7 @@ int Cec_ManChoiceComputation_int( Gia_Man_t * pAig, Cec_ParChc_t * pPars )
// found counter-examples to speculation
clk2 = Abc_Clock();
if ( pPars->fUseCSat )
- vCexStore = Cbs_ManSolveMiterNc( pSrm, pPars->nBTLimit, &vStatus, 0 );
+ vCexStore = Cbs_ManSolveMiterNc( pSrm, pPars->nBTLimit, &vStatus, 0, 0 );
else
vCexStore = Cec_ManSatSolveMiter( pSrm, pParsSat, &vStatus );
Gia_ManStop( pSrm );
@@ -401,6 +401,29 @@ Aig_Man_t * Cec_ComputeChoices( Gia_Man_t * pGia, Dch_Pars_t * pPars )
return pAig;
}
+/**Function*************************************************************
+
+ Synopsis [Performs computation of AIGs with choices.]
+
+ Description [Takes several AIGs and performs choicing.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Cec_ComputeChoicesNew( Gia_Man_t * pGia, int nConfs, int fVerbose )
+{
+ extern void Cec4_ManSimulateTest2( Gia_Man_t * p, int nConfs, int fVerbose );
+ Aig_Man_t * pAig;
+ Cec4_ManSimulateTest2( pGia, nConfs, fVerbose );
+ pGia = Gia_ManEquivToChoices( pGia, 3 );
+ Gia_ManSetRegNum( pGia, Gia_ManRegNum(pGia) );
+ pAig = Gia_ManToAig( pGia, 1 );
+ Gia_ManStop( pGia );
+ return pAig;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/proof/cec/cecClass.c b/src/proof/cec/cecClass.c
index 2d820c39..be88b9be 100644
--- a/src/proof/cec/cecClass.c
+++ b/src/proof/cec/cecClass.c
@@ -878,19 +878,34 @@ int Cec_ManSimClassesPrepare( Cec_ManSim_t * p, int LevelMax )
if ( pObj->Value )
Gia_ObjSetRepr( p->pAig, Gia_ObjId(p->pAig, pObj), 0 );
// perform simulation
- p->nWords = 1;
- do {
+ if ( p->pAig->nSimWords )
+ {
+ p->nWords = 2*p->pAig->nSimWords;
+ assert( Vec_WrdSize(p->pAig->vSimsPi) == Gia_ManCiNum(p->pAig) * p->pAig->nSimWords );
+ //Cec_ManSimCreateInfo( p, p->vCiSimInfo, p->vCoSimInfo );
+ for ( i = 0; i < Gia_ManCiNum(p->pAig); i++ )
+ memmove( Vec_PtrEntry(p->vCiSimInfo, i), Vec_WrdEntryP(p->pAig->vSimsPi, i*p->pAig->nSimWords), sizeof(word)*p->pAig->nSimWords );
+ if ( Cec_ManSimSimulateRound( p, p->vCiSimInfo, p->vCoSimInfo ) )
+ return 1;
if ( p->pPars->fVerbose )
Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) );
- for ( i = 0; i < 4; i++ )
- {
- Cec_ManSimCreateInfo( p, p->vCiSimInfo, p->vCoSimInfo );
- if ( Cec_ManSimSimulateRound( p, p->vCiSimInfo, p->vCoSimInfo ) )
- return 1;
+ }
+ else
+ {
+ p->nWords = 1;
+ do {
+ if ( p->pPars->fVerbose )
+ Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) );
+ for ( i = 0; i < 4; i++ )
+ {
+ Cec_ManSimCreateInfo( p, p->vCiSimInfo, p->vCoSimInfo );
+ if ( Cec_ManSimSimulateRound( p, p->vCiSimInfo, p->vCoSimInfo ) )
+ return 1;
+ }
+ p->nWords = 2 * p->nWords + 1;
}
- p->nWords = 2 * p->nWords + 1;
+ while ( p->nWords <= p->pPars->nWords );
}
- while ( p->nWords <= p->pPars->nWords );
return 0;
}
diff --git a/src/proof/cec/cecCore.c b/src/proof/cec/cecCore.c
index b9529658..f94bd27f 100644
--- a/src/proof/cec/cecCore.c
+++ b/src/proof/cec/cecCore.c
@@ -45,6 +45,7 @@ ABC_NAMESPACE_IMPL_START
void Cec_ManSatSetDefaultParams( Cec_ParSat_t * p )
{
memset( p, 0, sizeof(Cec_ParSat_t) );
+ p->SolverType = -1; // SAT solver type
p->nBTLimit = 100; // conflict limit at a node
p->nSatVarMax = 2000; // the max number of SAT variables
p->nCallsRecycle = 200; // calls to perform before recycling SAT solver
@@ -232,14 +233,17 @@ void Cec_ManChcSetDefaultParams( Cec_ParChc_t * p )
SeeAlso []
***********************************************************************/
-Gia_Man_t * Cec_ManSatSolving( Gia_Man_t * pAig, Cec_ParSat_t * pPars )
+Gia_Man_t * Cec_ManSatSolving( Gia_Man_t * pAig, Cec_ParSat_t * pPars, int f0Proved )
{
Gia_Man_t * pNew;
Cec_ManPat_t * pPat;
pPat = Cec_ManPatStart();
- Cec_ManSatSolve( pPat, pAig, pPars, NULL, NULL, NULL );
+ if ( pPars->SolverType == -1 )
+ Cec_ManSatSolve( pPat, pAig, pPars, NULL, NULL, NULL, f0Proved );
+ else
+ CecG_ManSatSolve( pPat, pAig, pPars, f0Proved );
// pNew = Gia_ManDupDfsSkip( pAig );
- pNew = Gia_ManDup( pAig );
+ pNew = Gia_ManCleanup( pAig );
Cec_ManPatStop( pPat );
pNew->vSeqModelVec = pAig->vSeqModelVec;
pAig->vSeqModelVec = NULL;
@@ -348,6 +352,8 @@ Gia_Man_t * Cec_ManSatSweeping( Gia_Man_t * pAig, Cec_ParFra_t * pPars, int fSil
Cec_ManPat_t * pPat;
int i, fTimeOut = 0, nMatches = 0;
abctime clk, clk2, clkTotal = Abc_Clock();
+ if ( pPars->fVerbose )
+ printf( "Simulating %d words for %d rounds. SAT solving with %d conflicts.\n", pPars->nWords, pPars->nRounds, pPars->nBTLimit );
// duplicate AIG and transfer equivalence classes
Gia_ManRandom( 1 );
@@ -360,6 +366,11 @@ Gia_Man_t * Cec_ManSatSweeping( Gia_Man_t * pAig, Cec_ParFra_t * pPars, int fSil
Vec_IntFreeP( &pAig->vIdsEquiv );
pAig->vIdsEquiv = Vec_IntAlloc( 1000 );
}
+ if ( pAig->vSimsPi )
+ {
+ pIni->vSimsPi = Vec_WrdDup(pAig->vSimsPi);
+ pIni->nSimWords = pAig->nSimWords;
+ }
// prepare the managers
// SAT sweeping
@@ -368,25 +379,25 @@ Gia_Man_t * Cec_ManSatSweeping( Gia_Man_t * pAig, Cec_ParFra_t * pPars, int fSil
pPars->fColorDiff = 1;
// simulation
Cec_ManSimSetDefaultParams( pParsSim );
- pParsSim->nWords = pPars->nWords;
+ pParsSim->nWords = Abc_MaxInt(2*pAig->nSimWords, pPars->nWords);
pParsSim->nFrames = pPars->nRounds;
pParsSim->fCheckMiter = pPars->fCheckMiter;
pParsSim->fDualOut = pPars->fDualOut;
pParsSim->fVerbose = pPars->fVerbose;
- pSim = Cec_ManSimStart( p->pAig, pParsSim );
+ pSim = Cec_ManSimStart( pIni, pParsSim );
// SAT solving
Cec_ManSatSetDefaultParams( pParsSat );
pParsSat->nBTLimit = pPars->nBTLimit;
pParsSat->fVerbose = pPars->fVeryVerbose;
// simulation patterns
pPat = Cec_ManPatStart();
- pPat->fVerbose = pPars->fVeryVerbose;
+ //pPat->fVerbose = pPars->fVeryVerbose;
// start equivalence classes
clk = Abc_Clock();
if ( p->pAig->pReprs == NULL )
{
- if ( Cec_ManSimClassesPrepare(pSim, -1) || Cec_ManSimClassesRefine(pSim) )
+ if ( Cec_ManSimClassesPrepare(pSim, -1) || (!p->pAig->nSimWords && Cec_ManSimClassesRefine(pSim)) )
{
Gia_ManStop( p->pAig );
p->pAig = NULL;
@@ -438,7 +449,7 @@ clk = Abc_Clock();
if ( pPars->fRunCSat )
Cec_ManSatSolveCSat( pPat, pSrm, pParsSat );
else
- Cec_ManSatSolve( pPat, pSrm, pParsSat, p->pAig->vIdsOrig, p->vXorNodes, pAig->vIdsEquiv );
+ Cec_ManSatSolve( pPat, pSrm, pParsSat, p->pAig->vIdsOrig, p->vXorNodes, pAig->vIdsEquiv, 0 );
p->timeSat += Abc_Clock() - clk;
if ( Cec_ManFraClassesUpdate( p, pSim, pPat, pSrm ) )
{
@@ -514,6 +525,9 @@ p->timeSat += Abc_Clock() - clk;
}
}
finalize:
+ if ( pPars->fVerbose )
+ printf( "Performed %d SAT calls: P = %d D = %d F = %d\n",
+ p->nAllProvedS + p->nAllDisprovedS + p->nAllFailedS, p->nAllProvedS, p->nAllDisprovedS, p->nAllFailedS );
if ( p->pPars->fVerbose && p->pAig )
{
Abc_Print( 1, "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n",
@@ -543,6 +557,8 @@ finalize:
Cec_ManSimStop( pSim );
Cec_ManPatStop( pPat );
Cec_ManFraStop( p );
+ if ( pTemp ) ABC_FREE( pTemp->pReprs );
+ if ( pTemp ) ABC_FREE( pTemp->pNexts );
return pTemp;
}
diff --git a/src/proof/cec/cecCorr.c b/src/proof/cec/cecCorr.c
index 8f708910..ce7e0885 100644
--- a/src/proof/cec/cecCorr.c
+++ b/src/proof/cec/cecCorr.c
@@ -996,7 +996,7 @@ int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars )
// found counter-examples to speculation
clk2 = Abc_Clock();
if ( pPars->fUseCSat )
- vCexStore = Cbs_ManSolveMiterNc( pSrm, pPars->nBTLimit, &vStatus, 0 );
+ vCexStore = Cbs_ManSolveMiterNc( pSrm, pPars->nBTLimit, &vStatus, 0, 0 );
else
vCexStore = Cec_ManSatSolveMiter( pSrm, pParsSat, &vStatus );
Gia_ManStop( pSrm );
diff --git a/src/proof/cec/cecInt.h b/src/proof/cec/cecInt.h
index d93e5e86..f78e5f25 100644
--- a/src/proof/cec/cecInt.h
+++ b/src/proof/cec/cecInt.h
@@ -27,6 +27,7 @@
////////////////////////////////////////////////////////////////////////
#include "sat/bsat/satSolver.h"
+#include "sat/glucose2/AbcGlucose2.h"
#include "misc/bar/bar.h"
#include "aig/gia/gia.h"
#include "cec.h"
@@ -80,7 +81,8 @@ struct Cec_ManSat_t_
Gia_Man_t * pAig; // the AIG whose outputs are considered
Vec_Int_t * vStatus; // status for each output
// SAT solving
- sat_solver * pSat; // recyclable SAT solver
+ sat_solver * pSat; // recyclable SAT solver (MiniSAT)
+ bmcg2_sat_solver*pSat2; // recyclable SAT solver (Glucose)
int nSatVars; // the counter of SAT variables
int * pSatVars; // mapping of each node into its SAT var
Vec_Ptr_t * vUsedNodes; // nodes whose SAT vars are assigned
@@ -153,6 +155,9 @@ struct Cec_ManFra_t_
int nAllProved; // total number of proved nodes
int nAllDisproved; // total number of disproved nodes
int nAllFailed; // total number of failed nodes
+ int nAllProvedS; // total number of proved nodes
+ int nAllDisprovedS; // total number of disproved nodes
+ int nAllFailedS; // total number of failed nodes
// runtime stats
abctime timeSim; // unsat
abctime timePat; // unsat
@@ -201,7 +206,7 @@ extern int Cec_ManCountNonConstOutputs( Gia_Man_t * pAig );
extern int Cec_ManCheckNonTrivialCands( Gia_Man_t * pAig );
/*=== cecSolve.c ============================================================*/
extern int Cec_ObjSatVarValue( Cec_ManSat_t * p, Gia_Obj_t * pObj );
-extern void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPars, Vec_Int_t * vIdsOrig, Vec_Int_t * vMiterPairs, Vec_Int_t * vEquivPairs );
+extern void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPars, Vec_Int_t * vIdsOrig, Vec_Int_t * vMiterPairs, Vec_Int_t * vEquivPairs, int f0Proved );
extern void Cec_ManSatSolveCSat( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPars );
extern Vec_Str_t * Cec_ManSatSolveSeq( Vec_Ptr_t * vPatts, Gia_Man_t * pAig, Cec_ParSat_t * pPars, int nRegs, int * pnPats );
extern Vec_Int_t * Cec_ManSatSolveMiter( Gia_Man_t * pAig, Cec_ParSat_t * pPars, Vec_Str_t ** pvStatus );
@@ -209,6 +214,8 @@ extern int Cec_ManSatCheckNode( Cec_ManSat_t * p, Gia_Obj_t * p
extern int Cec_ManSatCheckNodeTwo( Cec_ManSat_t * p, Gia_Obj_t * pObj1, Gia_Obj_t * pObj2 );
extern void Cec_ManSavePattern( Cec_ManSat_t * p, Gia_Obj_t * pObj1, Gia_Obj_t * pObj2 );
extern Vec_Int_t * Cec_ManSatReadCex( Cec_ManSat_t * p );
+/*=== cecSolveG.c ============================================================*/
+extern void CecG_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPars, int f0Proved );
/*=== ceFraeep.c ============================================================*/
extern Gia_Man_t * Cec_ManFraSpecReduction( Cec_ManFra_t * p );
extern int Cec_ManFraClassesUpdate( Cec_ManFra_t * p, Cec_ManSim_t * pSim, Cec_ManPat_t * pPat, Gia_Man_t * pNew );
diff --git a/src/proof/cec/cecMan.c b/src/proof/cec/cecMan.c
index 1d32b99e..c636a00d 100644
--- a/src/proof/cec/cecMan.c
+++ b/src/proof/cec/cecMan.c
@@ -73,6 +73,7 @@ Cec_ManSat_t * Cec_ManSatCreate( Gia_Man_t * pAig, Cec_ParSat_t * pPars )
***********************************************************************/
void Cec_ManSatPrintStats( Cec_ManSat_t * p )
{
+ printf( "SAT solver statistics:\n" );
Abc_Print( 1, "CO = %8d ", Gia_ManCoNum(p->pAig) );
Abc_Print( 1, "AND = %8d ", Gia_ManAndNum(p->pAig) );
Abc_Print( 1, "Conf = %5d ", p->pPars->nBTLimit );
diff --git a/src/proof/cec/cecSatG2.c b/src/proof/cec/cecSatG2.c
new file mode 100644
index 00000000..ce299c66
--- /dev/null
+++ b/src/proof/cec/cecSatG2.c
@@ -0,0 +1,1921 @@
+/**CFile****************************************************************
+
+ FileName [cecSatG2.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: cecSatG2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "aig/gia/gia.h"
+#include "misc/util/utilTruth.h"
+#include "cec.h"
+
+#define USE_GLUCOSE2
+
+#ifdef USE_GLUCOSE2
+
+#include "sat/glucose2/AbcGlucose2.h"
+
+#define sat_solver bmcg2_sat_solver
+#define sat_solver_start bmcg2_sat_solver_start
+#define sat_solver_stop bmcg2_sat_solver_stop
+#define sat_solver_addclause bmcg2_sat_solver_addclause
+#define sat_solver_add_and bmcg2_sat_solver_add_and
+#define sat_solver_add_xor bmcg2_sat_solver_add_xor
+#define sat_solver_addvar bmcg2_sat_solver_addvar
+#define sat_solver_read_cex_varvalue bmcg2_sat_solver_read_cex_varvalue
+#define sat_solver_reset bmcg2_sat_solver_reset
+#define sat_solver_set_conflict_budget bmcg2_sat_solver_set_conflict_budget
+#define sat_solver_conflictnum bmcg2_sat_solver_conflictnum
+#define sat_solver_solve bmcg2_sat_solver_solve
+#define sat_solver_read_cex_varvalue bmcg2_sat_solver_read_cex_varvalue
+#define sat_solver_read_cex bmcg2_sat_solver_read_cex
+#define sat_solver_jftr bmcg2_sat_solver_jftr
+#define sat_solver_set_jftr bmcg2_sat_solver_set_jftr
+#define sat_solver_set_var_fanin_lit bmcg2_sat_solver_set_var_fanin_lit
+#define sat_solver_start_new_round bmcg2_sat_solver_start_new_round
+#define sat_solver_mark_cone bmcg2_sat_solver_mark_cone
+
+#else
+
+#include "sat/glucose/AbcGlucose.h"
+
+#define sat_solver bmcg_sat_solver
+#define sat_solver_start bmcg_sat_solver_start
+#define sat_solver_stop bmcg_sat_solver_stop
+#define sat_solver_addclause bmcg_sat_solver_addclause
+#define sat_solver_add_and bmcg_sat_solver_add_and
+#define sat_solver_add_xor bmcg_sat_solver_add_xor
+#define sat_solver_addvar bmcg_sat_solver_addvar
+#define sat_solver_read_cex_varvalue bmcg_sat_solver_read_cex_varvalue
+#define sat_solver_reset bmcg_sat_solver_reset
+#define sat_solver_set_conflict_budget bmcg_sat_solver_set_conflict_budget
+#define sat_solver_conflictnum bmcg_sat_solver_conflictnum
+#define sat_solver_solve bmcg_sat_solver_solve
+#define sat_solver_read_cex_varvalue bmcg_sat_solver_read_cex_varvalue
+#define sat_solver_read_cex bmcg_sat_solver_read_cex
+#define sat_solver_jftr bmcg_sat_solver_jftr
+#define sat_solver_set_jftr bmcg_sat_solver_set_jftr
+#define sat_solver_set_var_fanin_lit bmcg_sat_solver_set_var_fanin_lit
+#define sat_solver_start_new_round bmcg_sat_solver_start_new_round
+#define sat_solver_mark_cone bmcg_sat_solver_mark_cone
+
+#endif
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// SAT solving manager
+typedef struct Cec4_Man_t_ Cec4_Man_t;
+struct Cec4_Man_t_
+{
+ Cec_ParFra_t * pPars; // parameters
+ Gia_Man_t * pAig; // user's AIG
+ Gia_Man_t * pNew; // internal AIG
+ // SAT solving
+ sat_solver * pSat; // SAT solver
+ Vec_Ptr_t * vFrontier; // CNF construction
+ Vec_Ptr_t * vFanins; // CNF construction
+ Vec_Int_t * vCexMin; // minimized CEX
+ Vec_Int_t * vClassUpdates; // updated equiv classes
+ Vec_Int_t * vCexStamps; // time stamps
+ Vec_Int_t * vCands;
+ Vec_Int_t * vVisit;
+ Vec_Int_t * vPat;
+ Vec_Int_t * vDisprPairs;
+ Vec_Bit_t * vFails;
+ Vec_Bit_t * vCoDrivers;
+ int iPosRead; // candidate reading position
+ int iPosWrite; // candidate writing position
+ int iLastConst; // last const node proved
+ // refinement
+ Vec_Int_t * vRefClasses;
+ Vec_Int_t * vRefNodes;
+ Vec_Int_t * vRefBins;
+ int * pTable;
+ int nTableSize;
+ // statistics
+ int nItersSim;
+ int nItersSat;
+ int nAndNodes;
+ int nPatterns;
+ int nSatSat;
+ int nSatUnsat;
+ int nSatUndec;
+ int nCallsSince;
+ int nSimulates;
+ int nRecycles;
+ int nConflicts[2][3];
+ int nGates[2];
+ int nFaster[2];
+ abctime timeCnf;
+ abctime timeGenPats;
+ abctime timeSatSat0;
+ abctime timeSatUnsat0;
+ abctime timeSatSat;
+ abctime timeSatUnsat;
+ abctime timeSatUndec;
+ abctime timeSim;
+ abctime timeRefine;
+ abctime timeResimGlo;
+ abctime timeResimLoc;
+ abctime timeStart;
+};
+
+static inline int Cec4_ObjSatId( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjCopy2Array(p, Gia_ObjId(p, pObj)); }
+static inline int Cec4_ObjSetSatId( Gia_Man_t * p, Gia_Obj_t * pObj, int Num ) { assert(Cec4_ObjSatId(p, pObj) == -1); Gia_ObjSetCopy2Array(p, Gia_ObjId(p, pObj), Num); Vec_IntPush(&p->vSuppVars, Gia_ObjId(p, pObj)); if ( Gia_ObjIsCi(pObj) ) Vec_IntPushTwo(&p->vCopiesTwo, Gia_ObjId(p, pObj), Num); assert(Vec_IntSize(&p->vVarMap) == Num); Vec_IntPush(&p->vVarMap, Gia_ObjId(p, pObj)); return Num; }
+static inline void Cec4_ObjCleanSatId( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert(Cec4_ObjSatId(p, pObj) != -1); Gia_ObjSetCopy2Array(p, Gia_ObjId(p, pObj), -1); }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Wrd_t * Cec4_EvalCombine( Vec_Int_t * vPats, int nPats, int nInputs, int nWords )
+{
+ //Vec_Wrd_t * vSimsPi = Vec_WrdStart( nInputs * nWords );
+ Vec_Wrd_t * vSimsPi = Vec_WrdStartRandom( nInputs * nWords );
+ int i, k, iLit, iPat = 0; word * pSim;
+ for ( i = 0; i < Vec_IntSize(vPats); i += Vec_IntEntry(vPats, i), iPat++ )
+ for ( k = 1; k < Vec_IntEntry(vPats, i)-1; k++ )
+ if ( (iLit = Vec_IntEntry(vPats, i+k)) )
+ {
+ assert( Abc_Lit2Var(iLit) > 0 && Abc_Lit2Var(iLit) <= nInputs );
+ pSim = Vec_WrdEntryP( vSimsPi, (Abc_Lit2Var(iLit)-1)*nWords );
+ if ( Abc_InfoHasBit( (unsigned*)pSim, iPat ) != Abc_LitIsCompl(iLit) )
+ Abc_InfoXorBit( (unsigned*)pSim, iPat );
+ }
+ assert( iPat == nPats );
+ return vSimsPi;
+}
+void Cec4_EvalPatterns( Gia_Man_t * p, Vec_Int_t * vPats, int nPats )
+{
+ int nWords = Abc_Bit6WordNum(nPats);
+ Vec_Wrd_t * vSimsPi = Cec4_EvalCombine( vPats, nPats, Gia_ManCiNum(p), nWords );
+ Vec_Wrd_t * vSimsPo = Gia_ManSimPatSimOut( p, vSimsPi, 1 );
+ int i, Count = 0, nErrors = 0;
+ for ( i = 0; i < Gia_ManCoNum(p); i++ )
+ {
+ int CountThis = Abc_TtCountOnesVec( Vec_WrdEntryP(vSimsPo, i*nWords), nWords );
+ if ( CountThis == 0 )
+ continue;
+ printf( "%d ", CountThis );
+ nErrors += CountThis;
+ Count++;
+ }
+ printf( "\nDetected %d error POs with %d errors (average %.2f).\n", Count, nErrors, 1.0*nErrors/Abc_MaxInt(1, Count) );
+ Vec_WrdFree( vSimsPi );
+ Vec_WrdFree( vSimsPo );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Default parameter settings.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec4_ManSetParams( Cec_ParFra_t * pPars )
+{
+ memset( pPars, 0, sizeof(Cec_ParFra_t) );
+ pPars->jType = 2; // solver type
+ pPars->fSatSweeping = 1; // conflict limit at a node
+ pPars->nWords = 4; // simulation words
+ pPars->nRounds = 10; // simulation rounds
+ pPars->nItersMax = 2000; // this is a miter
+ pPars->nBTLimit = 1000000; // use logic cones
+ pPars->nBTLimitPo = 0; // use logic outputs
+ pPars->nSatVarMax = 1000; // the max number of SAT variables before recycling SAT solver
+ pPars->nCallsRecycle = 500; // calls to perform before recycling SAT solver
+ pPars->nGenIters = 100; // pattern generation iterations
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Cec4_Man_t * Cec4_ManCreate( Gia_Man_t * pAig, Cec_ParFra_t * pPars )
+{
+ Cec4_Man_t * p = ABC_CALLOC( Cec4_Man_t, 1 );
+ memset( p, 0, sizeof(Cec4_Man_t) );
+ p->timeStart = Abc_Clock();
+ p->pPars = pPars;
+ p->pAig = pAig;
+ p->pSat = sat_solver_start();
+ sat_solver_set_jftr( p->pSat, pPars->jType );
+ p->vFrontier = Vec_PtrAlloc( 1000 );
+ p->vFanins = Vec_PtrAlloc( 100 );
+ p->vCexMin = Vec_IntAlloc( 100 );
+ p->vClassUpdates = Vec_IntAlloc( 100 );
+ p->vCexStamps = Vec_IntStart( Gia_ManObjNum(pAig) );
+ p->vCands = Vec_IntAlloc( 100 );
+ p->vVisit = Vec_IntAlloc( 100 );
+ p->vPat = Vec_IntAlloc( 100 );
+ p->vDisprPairs = Vec_IntAlloc( 100 );
+ p->vFails = Vec_BitStart( Gia_ManObjNum(pAig) );
+ //pAig->pData = p->pSat; // point AIG manager to the solver
+ //Vec_IntFreeP( &p->pAig->vPats );
+ //p->pAig->vPats = Vec_IntAlloc( 1000 );
+ if ( pPars->nBTLimitPo )
+ {
+ int i, Driver;
+ p->vCoDrivers = Vec_BitStart( Gia_ManObjNum(pAig) );
+ Gia_ManForEachCoDriverId( pAig, Driver, i )
+ Vec_BitWriteEntry( p->vCoDrivers, Driver, 1 );
+ }
+ return p;
+}
+void Cec4_ManDestroy( Cec4_Man_t * p )
+{
+ if ( p->pPars->fVerbose )
+ {
+ abctime timeTotal = Abc_Clock() - p->timeStart;
+ abctime timeSat = p->timeSatSat0 + p->timeSatSat + p->timeSatUnsat0 + p->timeSatUnsat + p->timeSatUndec;
+ abctime timeOther = timeTotal - timeSat - p->timeSim - p->timeRefine - p->timeResimLoc - p->timeGenPats;// - p->timeResimGlo;
+ ABC_PRTP( "SAT solving ", timeSat, timeTotal );
+ ABC_PRTP( " sat(easy) ", p->timeSatSat0, timeTotal );
+ ABC_PRTP( " sat ", p->timeSatSat, timeTotal );
+ ABC_PRTP( " unsat(easy)", p->timeSatUnsat0, timeTotal );
+ ABC_PRTP( " unsat ", p->timeSatUnsat, timeTotal );
+ ABC_PRTP( " fail ", p->timeSatUndec, timeTotal );
+ ABC_PRTP( "Generate CNF ", p->timeCnf, timeTotal );
+ ABC_PRTP( "Generate pats", p->timeGenPats, timeTotal );
+ ABC_PRTP( "Simulation ", p->timeSim, timeTotal );
+ ABC_PRTP( "Refinement ", p->timeRefine, timeTotal );
+ ABC_PRTP( "Resim global ", p->timeResimGlo, timeTotal );
+ ABC_PRTP( "Resim local ", p->timeResimLoc, timeTotal );
+ ABC_PRTP( "Other ", timeOther, timeTotal );
+ ABC_PRTP( "TOTAL ", timeTotal, timeTotal );
+ fflush( stdout );
+ }
+ //printf( "Recorded %d patterns with %d literals (average %.2f).\n",
+ // p->pAig->nBitPats, Vec_IntSize(p->pAig->vPats) - 2*p->pAig->nBitPats, 1.0*Vec_IntSize(p->pAig->vPats)/Abc_MaxInt(1, p->pAig->nBitPats)-2 );
+ //Cec4_EvalPatterns( p->pAig, p->pAig->vPats, p->pAig->nBitPats );
+ //Vec_IntFreeP( &p->pAig->vPats );
+ Vec_WrdFreeP( &p->pAig->vSims );
+ Vec_WrdFreeP( &p->pAig->vSimsPi );
+ Gia_ManCleanMark01( p->pAig );
+ sat_solver_stop( p->pSat );
+ Gia_ManStopP( &p->pNew );
+ Vec_PtrFreeP( &p->vFrontier );
+ Vec_PtrFreeP( &p->vFanins );
+ Vec_IntFreeP( &p->vCexMin );
+ Vec_IntFreeP( &p->vClassUpdates );
+ Vec_IntFreeP( &p->vCexStamps );
+ Vec_IntFreeP( &p->vCands );
+ Vec_IntFreeP( &p->vVisit );
+ Vec_IntFreeP( &p->vPat );
+ Vec_IntFreeP( &p->vDisprPairs );
+ Vec_BitFreeP( &p->vFails );
+ Vec_BitFreeP( &p->vCoDrivers );
+ Vec_IntFreeP( &p->vRefClasses );
+ Vec_IntFreeP( &p->vRefNodes );
+ Vec_IntFreeP( &p->vRefBins );
+ ABC_FREE( p->pTable );
+ ABC_FREE( p );
+}
+Gia_Man_t * Cec4_ManStartNew( Gia_Man_t * pAig )
+{
+ Gia_Obj_t * pObj; int i;
+ Gia_Man_t * pNew = Gia_ManStart( Gia_ManObjNum(pAig) );
+ pNew->pName = Abc_UtilStrsav( pAig->pName );
+ pNew->pSpec = Abc_UtilStrsav( pAig->pSpec );
+ if ( pAig->pMuxes )
+ pNew->pMuxes = ABC_CALLOC( unsigned, pNew->nObjsAlloc );
+ Gia_ManFillValue( pAig );
+ Gia_ManConst0(pAig)->Value = 0;
+ Gia_ManForEachCi( pAig, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ Gia_ManHashAlloc( pNew );
+ Vec_IntFill( &pNew->vCopies2, Gia_ManObjNum(pAig), -1 );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(pAig) );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds clauses to the solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec4_AddClausesMux( Gia_Man_t * p, Gia_Obj_t * pNode, sat_solver * 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 = Cec4_ObjSatId(p, pNode);
+ VarI = Cec4_ObjSatId(p, pNodeI);
+ VarT = Cec4_ObjSatId(p, Gia_Regular(pNodeT));
+ VarE = Cec4_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 = sat_solver_addclause( 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 = sat_solver_addclause( 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 = sat_solver_addclause( 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 = sat_solver_addclause( 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 = sat_solver_addclause( 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 = sat_solver_addclause( pSat, pLits, 3 );
+ assert( RetValue );
+}
+void Cec4_AddClausesSuper( Gia_Man_t * p, Gia_Obj_t * pNode, Vec_Ptr_t * vSuper, sat_solver * 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(Cec4_ObjSatId(p, Gia_Regular(pFanin)), Gia_IsComplement(pFanin));
+ pLits[1] = Abc_Var2Lit(Cec4_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 = sat_solver_addclause( 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(Cec4_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(Cec4_ObjSatId(p, pNode), 0);
+ if ( fPolarFlip )
+ {
+ if ( pNode->fPhase ) pLits[nLits-1] = Abc_LitNot( pLits[nLits-1] );
+ }
+ RetValue = sat_solver_addclause( pSat, pLits, nLits );
+ assert( RetValue );
+ ABC_FREE( pLits );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds clauses and returns CNF variable of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec4_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
+ Cec4_CollectSuper_rec( Gia_ObjChild0(pObj), vSuper, 0, fUseMuxes );
+ Cec4_CollectSuper_rec( Gia_ObjChild1(pObj), vSuper, 0, fUseMuxes );
+}
+void Cec4_CollectSuper( Gia_Obj_t * pObj, int fUseMuxes, Vec_Ptr_t * vSuper )
+{
+ assert( !Gia_IsComplement(pObj) );
+ assert( !Gia_ObjIsCi(pObj) );
+ Vec_PtrClear( vSuper );
+ Cec4_CollectSuper_rec( pObj, vSuper, 1, fUseMuxes );
+}
+void Cec4_ObjAddToFrontier( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Ptr_t * vFrontier, sat_solver * pSat )
+{
+ assert( !Gia_IsComplement(pObj) );
+ assert( !Gia_ObjIsConst0(pObj) );
+ if ( Cec4_ObjSatId(p, pObj) >= 0 )
+ return;
+ assert( Cec4_ObjSatId(p, pObj) == -1 );
+ Cec4_ObjSetSatId( p, pObj, sat_solver_addvar(pSat) );
+ if ( Gia_ObjIsAnd(pObj) )
+ Vec_PtrPush( vFrontier, pObj );
+}
+int Cec4_ObjGetCnfVar( Cec4_Man_t * p, int iObj )
+{
+ int fUseSimple = 1; // enable simple CNF
+ int fUseMuxes = 1; // enable MUXes when using complex CNF
+ Gia_Obj_t * pNode, * pFanin;
+ Gia_Obj_t * pObj = Gia_ManObj(p->pNew, iObj);
+ int i, k;
+ // quit if CNF is ready
+ if ( Cec4_ObjSatId(p->pNew,pObj) >= 0 )
+ return Cec4_ObjSatId(p->pNew,pObj);
+ assert( iObj > 0 );
+ if ( Gia_ObjIsCi(pObj) )
+ return Cec4_ObjSetSatId( p->pNew, pObj, sat_solver_addvar(p->pSat) );
+ assert( Gia_ObjIsAnd(pObj) );
+ if ( fUseSimple )
+ {
+ Gia_Obj_t * pFan0, * pFan1;
+ //if ( Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) )
+ // printf( "%d", (Gia_IsComplement(pFan1) << 1) + Gia_IsComplement(pFan0) );
+ if ( p->pNew->pMuxes == NULL && Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) && Gia_IsComplement(pFan0) == Gia_IsComplement(pFan1) )
+ {
+ int iVar0 = Cec4_ObjGetCnfVar( p, Gia_ObjId(p->pNew, Gia_Regular(pFan0)) );
+ int iVar1 = Cec4_ObjGetCnfVar( p, Gia_ObjId(p->pNew, Gia_Regular(pFan1)) );
+ int iVar = Cec4_ObjSetSatId( p->pNew, pObj, sat_solver_addvar(p->pSat) );
+ if ( p->pPars->jType < 2 )
+ sat_solver_add_xor( p->pSat, iVar, iVar0, iVar1, 0 );
+ if ( p->pPars->jType > 0 )
+ {
+ int Lit0 = Abc_Var2Lit( iVar0, 0 );
+ int Lit1 = Abc_Var2Lit( iVar1, 0 );
+ if ( Lit0 < Lit1 )
+ Lit1 ^= Lit0, Lit0 ^= Lit1, Lit1 ^= Lit0;
+ assert( Lit0 > Lit1 );
+ sat_solver_set_var_fanin_lit( p->pSat, iVar, Lit0, Lit1 );
+ p->nGates[1]++;
+ }
+ }
+ else
+ {
+ int iVar0 = Cec4_ObjGetCnfVar( p, Gia_ObjFaninId0(pObj, iObj) );
+ int iVar1 = Cec4_ObjGetCnfVar( p, Gia_ObjFaninId1(pObj, iObj) );
+ int iVar = Cec4_ObjSetSatId( p->pNew, pObj, sat_solver_addvar(p->pSat) );
+ if ( p->pPars->jType < 2 )
+ {
+ if ( Gia_ObjIsXor(pObj) )
+ sat_solver_add_xor( p->pSat, iVar, iVar0, iVar1, Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC1(pObj) );
+ else
+ sat_solver_add_and( p->pSat, iVar, iVar0, iVar1, Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj), 0 );
+ }
+ if ( p->pPars->jType > 0 )
+ {
+ int Lit0 = Abc_Var2Lit( iVar0, Gia_ObjFaninC0(pObj) );
+ int Lit1 = Abc_Var2Lit( iVar1, Gia_ObjFaninC1(pObj) );
+ if ( (Lit0 > Lit1) ^ Gia_ObjIsXor(pObj) )
+ Lit1 ^= Lit0, Lit0 ^= Lit1, Lit1 ^= Lit0;
+ sat_solver_set_var_fanin_lit( p->pSat, iVar, Lit0, Lit1 );
+ p->nGates[Gia_ObjIsXor(pObj)]++;
+ }
+ }
+ return Cec4_ObjSatId( p->pNew, pObj );
+ }
+ assert( !Gia_ObjIsXor(pObj) );
+ // start the frontier
+ Vec_PtrClear( p->vFrontier );
+ Cec4_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( Cec4_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 )
+ Cec4_ObjAddToFrontier( p->pNew, Gia_Regular(pFanin), p->vFrontier, p->pSat );
+ Cec4_AddClausesMux( p->pNew, pNode, p->pSat );
+ }
+ else
+ {
+ Cec4_CollectSuper( pNode, fUseMuxes, p->vFanins );
+ Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k )
+ Cec4_ObjAddToFrontier( p->pNew, Gia_Regular(pFanin), p->vFrontier, p->pSat );
+ Cec4_AddClausesSuper( p->pNew, pNode, p->vFanins, p->pSat );
+ }
+ assert( Vec_PtrSize(p->vFanins) > 1 );
+ }
+ return Cec4_ObjSatId(p->pNew,pObj);
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Refinement of equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline word * Cec4_ObjSim( Gia_Man_t * p, int iObj )
+{
+ return Vec_WrdEntryP( p->vSims, p->nSimWords * iObj );
+}
+static inline int Cec4_ObjSimEqual( Gia_Man_t * p, int iObj0, int iObj1 )
+{
+ int w;
+ word * pSim0 = Cec4_ObjSim( p, iObj0 );
+ word * pSim1 = Cec4_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;
+ }
+}
+int Cec4_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);
+
+}
+void Cec4_RefineOneClassIter( Gia_Man_t * p, int iRepr )
+{
+ int iObj, iPrev = iRepr, iPrev2, iRepr2;
+ assert( Gia_ObjRepr(p, iRepr) == GIA_VOID );
+ assert( Gia_ObjNext(p, iRepr) > 0 );
+ Gia_ClassForEachObj1( p, iRepr, iRepr2 )
+ if ( Cec4_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 ( Cec4_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 );
+ // refine incrementally
+ if ( Gia_ObjNext(p, iRepr2) > 0 )
+ Cec4_RefineOneClassIter( p, iRepr2 );
+}
+void Cec4_RefineOneClass( Gia_Man_t * p, Cec4_Man_t * pMan, Vec_Int_t * vNodes )
+{
+ int k, iObj, Bin;
+ Vec_IntClear( pMan->vRefBins );
+ Vec_IntForEachEntryReverse( vNodes, iObj, k )
+ {
+ int Key = Cec4_ManSimHashKey( Cec4_ObjSim(p, iObj), p->nSimWords, pMan->nTableSize );
+ assert( Key >= 0 && Key < pMan->nTableSize );
+ if ( pMan->pTable[Key] == -1 )
+ Vec_IntPush( pMan->vRefBins, Key );
+ p->pNexts[iObj] = pMan->pTable[Key];
+ pMan->pTable[Key] = iObj;
+ }
+ Vec_IntForEachEntry( pMan->vRefBins, Bin, k )
+ {
+ int iRepr = pMan->pTable[Bin];
+ pMan->pTable[Bin] = -1;
+ assert( p->pReprs[iRepr].iRepr == GIA_VOID );
+ assert( p->pNexts[iRepr] != 0 );
+ if ( p->pNexts[iRepr] == -1 )
+ continue;
+ for ( iObj = p->pNexts[iRepr]; iObj > 0; iObj = p->pNexts[iObj] )
+ p->pReprs[iObj].iRepr = iRepr;
+ Cec4_RefineOneClassIter( p, iRepr );
+ }
+ Vec_IntClear( pMan->vRefBins );
+}
+void Cec4_RefineClasses( Gia_Man_t * p, Cec4_Man_t * pMan, Vec_Int_t * vClasses )
+{
+ if ( Vec_IntSize(pMan->vRefClasses) == 0 )
+ return;
+ if ( Vec_IntSize(pMan->vRefNodes) > 0 )
+ Cec4_RefineOneClass( p, pMan, pMan->vRefNodes );
+ else
+ {
+ int i, k, iObj, iRepr;
+ Vec_IntForEachEntry( pMan->vRefClasses, iRepr, i )
+ {
+ assert( p->pReprs[iRepr].fColorA );
+ p->pReprs[iRepr].fColorA = 0;
+ Vec_IntClear( pMan->vRefNodes );
+ Vec_IntPush( pMan->vRefNodes, iRepr );
+ Gia_ClassForEachObj1( p, iRepr, k )
+ Vec_IntPush( pMan->vRefNodes, k );
+ Vec_IntForEachEntry( pMan->vRefNodes, iObj, k )
+ {
+ p->pReprs[iObj].iRepr = GIA_VOID;
+ p->pNexts[iObj] = -1;
+ }
+ Cec4_RefineOneClass( p, pMan, pMan->vRefNodes );
+ }
+ }
+ Vec_IntClear( pMan->vRefClasses );
+ Vec_IntClear( pMan->vRefNodes );
+}
+void Cec4_RefineInit( Gia_Man_t * p, Cec4_Man_t * pMan )
+{
+ Gia_Obj_t * pObj; int i;
+ ABC_FREE( p->pReprs );
+ ABC_FREE( p->pNexts );
+ p->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p) );
+ p->pNexts = ABC_FALLOC( int, Gia_ManObjNum(p) );
+ pMan->nTableSize = Abc_PrimeCudd( Gia_ManObjNum(p) );
+ pMan->pTable = ABC_FALLOC( int, pMan->nTableSize );
+ pMan->vRefNodes = Vec_IntAlloc( Gia_ManObjNum(p) );
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ p->pReprs[i].iRepr = GIA_VOID;
+ if ( !Gia_ObjIsCo(pObj) && (!pMan->pPars->nLevelMax || Gia_ObjLevel(p, pObj) <= pMan->pPars->nLevelMax) )
+ Vec_IntPush( pMan->vRefNodes, i );
+ }
+ pMan->vRefBins = Vec_IntAlloc( Gia_ManObjNum(p)/2 );
+ pMan->vRefClasses = Vec_IntAlloc( Gia_ManObjNum(p)/2 );
+ Vec_IntPush( pMan->vRefClasses, 0 );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Internal simulation APIs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Cec4_ObjSimSetInputBit( Gia_Man_t * p, int iObj, int Bit )
+{
+ word * pSim = Cec4_ObjSim( p, iObj );
+ if ( Abc_InfoHasBit( (unsigned*)pSim, p->iPatsPi ) != Bit )
+ Abc_InfoXorBit( (unsigned*)pSim, p->iPatsPi );
+}
+static inline int Cec4_ObjSimGetInputBit( Gia_Man_t * p, int iObj )
+{
+ word * pSim = Cec4_ObjSim( p, iObj );
+ return Abc_InfoHasBit( (unsigned*)pSim, p->iPatsPi );
+}
+static inline void Cec4_ObjSimRo( Gia_Man_t * p, int iObj )
+{
+ int w;
+ word * pSimRo = Cec4_ObjSim( p, iObj );
+ word * pSimRi = Cec4_ObjSim( p, Gia_ObjRoToRiId(p, iObj) );
+ for ( w = 0; w < p->nSimWords; w++ )
+ pSimRo[w] = pSimRi[w];
+}
+static inline void Cec4_ObjSimCo( Gia_Man_t * p, int iObj )
+{
+ int w;
+ Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
+ word * pSimCo = Cec4_ObjSim( p, iObj );
+ word * pSimDri = Cec4_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 Cec4_ObjSimAnd( Gia_Man_t * p, int iObj )
+{
+ int w;
+ Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
+ word * pSim = Cec4_ObjSim( p, iObj );
+ word * pSim0 = Cec4_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) );
+ word * pSim1 = Cec4_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 void Cec4_ObjSimXor( Gia_Man_t * p, int iObj )
+{
+ int w;
+ Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
+ word * pSim = Cec4_ObjSim( p, iObj );
+ word * pSim0 = Cec4_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) );
+ word * pSim1 = Cec4_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
+ for ( w = 0; w < p->nSimWords; w++ )
+ pSim[w] = pSim0[w] ^ pSim1[w];
+}
+static inline void Cec4_ObjSimCi( Gia_Man_t * p, int iObj )
+{
+ int w;
+ word * pSim = Cec4_ObjSim( p, iObj );
+ for ( w = 0; w < p->nSimWords; w++ )
+ pSim[w] = Gia_ManRandomW( 0 );
+ pSim[0] <<= 1;
+}
+static inline void Cec4_ObjClearSimCi( Gia_Man_t * p, int iObj )
+{
+ int w;
+ word * pSim = Cec4_ObjSim( p, iObj );
+ for ( w = 0; w < p->nSimWords; w++ )
+ pSim[w] = 0;
+}
+void Cec4_ManSimulateCis( Gia_Man_t * p )
+{
+ int i, Id;
+ Gia_ManForEachCiId( p, Id, i )
+ Cec4_ObjSimCi( p, Id );
+ p->iPatsPi = 0;
+}
+void Cec4_ManClearCis( Gia_Man_t * p )
+{
+ int i, Id;
+ Gia_ManForEachCiId( p, Id, i )
+ Cec4_ObjClearSimCi( p, Id );
+ p->iPatsPi = 0;
+}
+Abc_Cex_t * Cec4_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 *)Cec4_ObjSim(p, Id), iPat) )
+ Abc_InfoSetBit( pCex->pData, i );
+ return pCex;
+}
+int Cec4_ManSimulateCos( Gia_Man_t * p )
+{
+ int i, Id;
+ // check outputs and generate CEX if they fail
+ Gia_ManForEachCoId( p, Id, i )
+ {
+ Cec4_ObjSimCo( p, Id );
+ if ( Cec4_ObjSimEqual(p, Id, 0) )
+ continue;
+ p->pCexSeq = Cec4_ManDeriveCex( p, i, Abc_TtFindFirstBit2(Cec4_ObjSim(p, Id), p->nSimWords) );
+ return 0;
+ }
+ return 1;
+}
+void Cec4_ManSimulate( Gia_Man_t * p, Cec4_Man_t * pMan )
+{
+ abctime clk = Abc_Clock();
+ Gia_Obj_t * pObj; int i;
+ pMan->nSimulates++;
+ if ( pMan->pTable == NULL )
+ Cec4_RefineInit( p, pMan );
+ else
+ assert( Vec_IntSize(pMan->vRefClasses) == 0 );
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ int iRepr = Gia_ObjRepr( p, i );
+ if ( Gia_ObjIsXor(pObj) )
+ Cec4_ObjSimXor( p, i );
+ else
+ Cec4_ObjSimAnd( p, i );
+ if ( iRepr == GIA_VOID || p->pReprs[iRepr].fColorA || Cec4_ObjSimEqual(p, iRepr, i) )
+ continue;
+ p->pReprs[iRepr].fColorA = 1;
+ Vec_IntPush( pMan->vRefClasses, iRepr );
+ }
+ pMan->timeSim += Abc_Clock() - clk;
+ clk = Abc_Clock();
+ Cec4_RefineClasses( p, pMan, pMan->vRefClasses );
+ pMan->timeRefine += Abc_Clock() - clk;
+}
+void Cec4_ManSimulate_rec( Gia_Man_t * p, Cec4_Man_t * pMan, int iObj )
+{
+ Gia_Obj_t * pObj;
+ if ( !iObj || Vec_IntEntry(pMan->vCexStamps, iObj) == p->iPatsPi )
+ return;
+ Vec_IntWriteEntry( pMan->vCexStamps, iObj, p->iPatsPi );
+ pObj = Gia_ManObj(p, iObj);
+ if ( Gia_ObjIsCi(pObj) )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ Cec4_ManSimulate_rec( p, pMan, Gia_ObjFaninId0(pObj, iObj) );
+ Cec4_ManSimulate_rec( p, pMan, Gia_ObjFaninId1(pObj, iObj) );
+ if ( Gia_ObjIsXor(pObj) )
+ Cec4_ObjSimXor( p, iObj );
+ else
+ Cec4_ObjSimAnd( p, iObj );
+}
+void Cec4_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_WrdStart( (Gia_ManCiNum(p) + 1) * nWords );
+ p->nSimWords = nWords;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Creating initial equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec4_ManPrintTfiConeStats( Gia_Man_t * p )
+{
+ Vec_Int_t * vRoots = Vec_IntAlloc( 100 );
+ Vec_Int_t * vNodes = Vec_IntAlloc( 100 );
+ Vec_Int_t * vLeaves = Vec_IntAlloc( 100 );
+ int i, k;
+ Gia_ManForEachClass0( p, i )
+ {
+ Vec_IntClear( vRoots );
+ if ( i % 100 != 0 )
+ continue;
+ Vec_IntPush( vRoots, i );
+ Gia_ClassForEachObj1( p, i, k )
+ Vec_IntPush( vRoots, k );
+ Gia_ManCollectTfi( p, vRoots, vNodes );
+ printf( "Class %6d : ", i );
+ printf( "Roots = %6d ", Vec_IntSize(vRoots) );
+ printf( "Nodes = %6d ", Vec_IntSize(vNodes) );
+ printf( "\n" );
+ }
+ Vec_IntFree( vRoots );
+ Vec_IntFree( vNodes );
+ Vec_IntFree( vLeaves );
+}
+void Cec4_ManPrintStats( Gia_Man_t * p, Cec_ParFra_t * pPars, Cec4_Man_t * pMan, int fSim )
+{
+ static abctime clk = 0;
+ abctime clkThis = 0;
+ int i, nLits, Counter = 0, Counter0 = 0, CounterX = 0;
+ if ( !pPars->fVerbose )
+ return;
+ if ( pMan->nItersSim + pMan->nItersSat )
+ clkThis = Abc_Clock() - clk;
+ clk = Abc_Clock();
+ for ( i = 0; i < Gia_ManObjNum(p); i++ )
+ {
+ if ( Gia_ObjIsHead(p, i) )
+ Counter++;
+ else if ( Gia_ObjIsConst(p, i) )
+ Counter0++;
+ else if ( Gia_ObjIsNone(p, i) )
+ CounterX++;
+ }
+ nLits = Gia_ManObjNum(p) - Counter - CounterX;
+ if ( fSim )
+ {
+ printf( "Sim %4d : ", pMan->nItersSim++ + pMan->nItersSat );
+ printf( "%6.2f %% ", 100.0*nLits/Gia_ManCandNum(p) );
+ }
+ else
+ {
+ printf( "SAT %4d : ", pMan->nItersSim + pMan->nItersSat++ );
+ printf( "%6.2f %% ", 100.0*pMan->nAndNodes/Gia_ManAndNum(p) );
+ }
+ printf( "P =%7d ", pMan ? pMan->nSatUnsat : 0 );
+ printf( "D =%7d ", pMan ? pMan->nSatSat : 0 );
+ printf( "F =%8d ", pMan ? pMan->nSatUndec : 0 );
+ //printf( "Last =%6d ", pMan ? pMan->iLastConst : 0 );
+ Abc_Print( 1, "cst =%9d cls =%8d lit =%9d ", Counter0, Counter, nLits );
+ Abc_PrintTime( 1, "Time", clkThis );
+}
+void Cec4_ManPrintClasses2( Gia_Man_t * p )
+{
+ int i, k;
+ Gia_ManForEachClass0( p, i )
+ {
+ printf( "Class %d : ", i );
+ Gia_ClassForEachObj1( p, i, k )
+ printf( "%d ", k );
+ printf( "\n" );
+ }
+}
+void Cec4_ManPrintClasses( Gia_Man_t * p )
+{
+ int k, Count = 0;
+ Gia_ClassForEachObj1( p, 0, k )
+ Count++;
+ printf( "Const0 class has %d entries.\n", Count );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Verify counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec4_ManVerify_rec( Gia_Man_t * p, int iObj, sat_solver * pSat )
+{
+ int Value0, Value1;
+ Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
+ if ( iObj == 0 ) return 0;
+ if ( Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return pObj->fMark1;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ if ( Gia_ObjIsCi(pObj) )
+ return pObj->fMark1 = sat_solver_read_cex_varvalue(pSat, Cec4_ObjSatId(p, pObj));
+ assert( Gia_ObjIsAnd(pObj) );
+ Value0 = Cec4_ManVerify_rec( p, Gia_ObjFaninId0(pObj, iObj), pSat ) ^ Gia_ObjFaninC0(pObj);
+ Value1 = Cec4_ManVerify_rec( p, Gia_ObjFaninId1(pObj, iObj), pSat ) ^ Gia_ObjFaninC1(pObj);
+ return pObj->fMark1 = Gia_ObjIsXor(pObj) ? Value0 ^ Value1 : Value0 & Value1;
+}
+void Cec4_ManVerify( Gia_Man_t * p, int iObj0, int iObj1, int fPhase, sat_solver * pSat )
+{
+ int Value0, Value1;
+ Gia_ManIncrementTravId( p );
+ Value0 = Cec4_ManVerify_rec( p, iObj0, pSat );
+ Value1 = Cec4_ManVerify_rec( p, iObj1, pSat );
+ if ( (Value0 ^ Value1) == fPhase )
+ printf( "CEX verification FAILED for obj %d and obj %d.\n", iObj0, iObj1 );
+// else
+// printf( "CEX verification succeeded for obj %d and obj %d.\n", iObj0, iObj1 );;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Verify counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec4_ManCexVerify_rec( Gia_Man_t * p, int iObj )
+{
+ int Value0, Value1;
+ Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
+ if ( iObj == 0 ) return 0;
+ if ( Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return pObj->fMark1;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ if ( Gia_ObjIsCi(pObj) )
+ return pObj->fMark1 = Cec4_ObjSimGetInputBit(p, iObj);
+ assert( Gia_ObjIsAnd(pObj) );
+ Value0 = Cec4_ManCexVerify_rec( p, Gia_ObjFaninId0(pObj, iObj) ) ^ Gia_ObjFaninC0(pObj);
+ Value1 = Cec4_ManCexVerify_rec( p, Gia_ObjFaninId1(pObj, iObj) ) ^ Gia_ObjFaninC1(pObj);
+ return pObj->fMark1 = Gia_ObjIsXor(pObj) ? Value0 ^ Value1 : Value0 & Value1;
+}
+void Cec4_ManCexVerify( Gia_Man_t * p, int iObj0, int iObj1, int fPhase )
+{
+ int Value0, Value1;
+ Gia_ManIncrementTravId( p );
+ Value0 = Cec4_ManCexVerify_rec( p, iObj0 );
+ Value1 = Cec4_ManCexVerify_rec( p, iObj1 );
+ if ( (Value0 ^ Value1) == fPhase )
+ printf( "CEX verification FAILED for obj %d and obj %d.\n", iObj0, iObj1 );
+// else
+// printf( "CEX verification succeeded for obj %d and obj %d.\n", iObj0, iObj1 );;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Packs simulation patterns into array of simulation info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+*************************************`**********************************/
+void Cec4_ManPackAddPatterns( Gia_Man_t * p, int iBit, Vec_Int_t * vLits )
+{
+ int k, Limit = Abc_MinInt( Vec_IntSize(vLits), 64 * p->nSimWords - 1 );
+ for ( k = 0; k < Limit; k++ )
+ {
+ int i, Lit, iBitLocal = (iBit + k + 1) % Limit + 1;
+ assert( iBitLocal > 0 && iBitLocal < 64 * p->nSimWords );
+ Vec_IntForEachEntry( vLits, Lit, i )
+ {
+ word * pInfo = Vec_WrdEntryP( p->vSims, p->nSimWords * Abc_Lit2Var(Lit) );
+ word * pPres = Vec_WrdEntryP( p->vSimsPi, p->nSimWords * Abc_Lit2Var(Lit) );
+ if ( Abc_InfoHasBit( (unsigned *)pPres, iBitLocal ) )
+ continue;
+ if ( Abc_InfoHasBit( (unsigned *)pInfo, iBitLocal ) != Abc_LitIsCompl(Lit ^ (i == k)) )
+ Abc_InfoXorBit( (unsigned *)pInfo, iBitLocal );
+ }
+ }
+}
+int Cec4_ManPackAddPatternTry( Gia_Man_t * p, int iBit, Vec_Int_t * vLits )
+{
+ int i, Lit;
+ assert( p->iPatsPi > 0 && p->iPatsPi < 64 * p->nSimWords );
+ Vec_IntForEachEntry( vLits, Lit, i )
+ {
+ word * pInfo = Vec_WrdEntryP( p->vSims, p->nSimWords * Abc_Lit2Var(Lit) );
+ word * pPres = Vec_WrdEntryP( p->vSimsPi, p->nSimWords * Abc_Lit2Var(Lit) );
+ if ( Abc_InfoHasBit( (unsigned *)pPres, iBit ) &&
+ Abc_InfoHasBit( (unsigned *)pInfo, iBit ) != Abc_LitIsCompl(Lit) )
+ return 0;
+ }
+ Vec_IntForEachEntry( vLits, Lit, i )
+ {
+ word * pInfo = Vec_WrdEntryP( p->vSims, p->nSimWords * Abc_Lit2Var(Lit) );
+ word * pPres = Vec_WrdEntryP( p->vSimsPi, p->nSimWords * Abc_Lit2Var(Lit) );
+ Abc_InfoSetBit( (unsigned *)pPres, iBit );
+ if ( Abc_InfoHasBit( (unsigned *)pInfo, iBit ) != Abc_LitIsCompl(Lit) )
+ Abc_InfoXorBit( (unsigned *)pInfo, iBit );
+ }
+ return 1;
+}
+int Cec4_ManPackAddPattern( Gia_Man_t * p, Vec_Int_t * vLits, int fExtend )
+{
+ int k;
+ for ( k = 1; k < 64 * p->nSimWords - 1; k++ )
+ {
+ if ( ++p->iPatsPi == 64 * p->nSimWords - 1 )
+ p->iPatsPi = 1;
+ if ( Cec4_ManPackAddPatternTry( p, p->iPatsPi, vLits ) )
+ {
+ if ( fExtend )
+ Cec4_ManPackAddPatterns( p, p->iPatsPi, vLits );
+ break;
+ }
+ }
+ if ( k == 64 * p->nSimWords - 1 )
+ {
+ p->iPatsPi = k;
+ if ( !Cec4_ManPackAddPatternTry( p, p->iPatsPi, vLits ) )
+ printf( "Internal error.\n" );
+ else if ( fExtend )
+ Cec4_ManPackAddPatterns( p, p->iPatsPi, vLits );
+ return 64 * p->nSimWords;
+ }
+ return k;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Generates counter-examples to refine the candidate equivalences.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cec4_ObjFan0IsAssigned( Gia_Obj_t * pObj )
+{
+ return Gia_ObjFanin0(pObj)->fMark0 || Gia_ObjFanin0(pObj)->fMark1;
+}
+static inline int Cec4_ObjFan1IsAssigned( Gia_Obj_t * pObj )
+{
+ return Gia_ObjFanin1(pObj)->fMark0 || Gia_ObjFanin1(pObj)->fMark1;
+}
+static inline int Cec4_ObjFan0HasValue( Gia_Obj_t * pObj, int v )
+{
+ return (v ^ Gia_ObjFaninC0(pObj)) ? Gia_ObjFanin0(pObj)->fMark1 : Gia_ObjFanin0(pObj)->fMark0;
+}
+static inline int Cec4_ObjFan1HasValue( Gia_Obj_t * pObj, int v )
+{
+ return (v ^ Gia_ObjFaninC1(pObj)) ? Gia_ObjFanin1(pObj)->fMark1 : Gia_ObjFanin1(pObj)->fMark0;
+}
+static inline int Cec4_ObjObjIsImpliedValue( Gia_Obj_t * pObj, int v )
+{
+ assert( !pObj->fMark0 && !pObj->fMark1 ); // not visited
+ if ( v )
+ return Cec4_ObjFan0HasValue(pObj, 1) && Cec4_ObjFan1HasValue(pObj, 1);
+ return Cec4_ObjFan0HasValue(pObj, 0) || Cec4_ObjFan1HasValue(pObj, 0);
+}
+static inline int Cec4_ObjFan0IsImpliedValue( Gia_Obj_t * pObj, int v )
+{
+ return Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) && Cec4_ObjObjIsImpliedValue( Gia_ObjFanin0(pObj), v ^ Gia_ObjFaninC0(pObj) );
+}
+static inline int Cec4_ObjFan1IsImpliedValue( Gia_Obj_t * pObj, int v )
+{
+ return Gia_ObjIsAnd(Gia_ObjFanin1(pObj)) && Cec4_ObjObjIsImpliedValue( Gia_ObjFanin1(pObj), v ^ Gia_ObjFaninC1(pObj) );
+}
+int Cec4_ManGeneratePatterns_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int Value, Vec_Int_t * vPat, Vec_Int_t * vVisit )
+{
+ Gia_Obj_t * pFan0, * pFan1;
+ assert( !pObj->fMark0 && !pObj->fMark1 ); // not visited
+ if ( Value ) pObj->fMark1 = 1; else pObj->fMark0 = 1;
+ Vec_IntPush( vVisit, Gia_ObjId(p, pObj) );
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ Vec_IntPush( vPat, Abc_Var2Lit(Gia_ObjId(p, pObj), Value) );
+ return 1;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ pFan0 = Gia_ObjFanin0(pObj);
+ pFan1 = Gia_ObjFanin1(pObj);
+ if ( Gia_ObjIsXor(pObj) )
+ {
+ int Ass0 = Cec4_ObjFan0IsAssigned(pObj);
+ int Ass1 = Cec4_ObjFan1IsAssigned(pObj);
+ assert( Gia_ObjFaninC0(pObj) == 0 && Gia_ObjFaninC1(pObj) == 0 );
+ if ( Ass0 && Ass1 )
+ return Value == (Cec4_ObjFan0HasValue(pObj, 1) ^ Cec4_ObjFan1HasValue(pObj, 1));
+ if ( Ass0 )
+ {
+ int ValueInt = Value ^ Cec4_ObjFan0HasValue(pObj, 1);
+ if ( !Cec4_ManGeneratePatterns_rec(p, pFan1, ValueInt, vPat, vVisit) )
+ return 0;
+ }
+ else if ( Ass1 )
+ {
+ int ValueInt = Value ^ Cec4_ObjFan1HasValue(pObj, 1);
+ if ( !Cec4_ManGeneratePatterns_rec(p, pFan0, ValueInt, vPat, vVisit) )
+ return 0;
+ }
+ else if ( Abc_Random(0) & 1 )
+ {
+ if ( !Cec4_ManGeneratePatterns_rec(p, pFan0, 0, vPat, vVisit) )
+ return 0;
+ if ( Cec4_ObjFan1HasValue(pObj, !Value) || (!Cec4_ObjFan1HasValue(pObj, Value) && !Cec4_ManGeneratePatterns_rec(p, pFan1, Value, vPat, vVisit)) )
+ return 0;
+ }
+ else
+ {
+ if ( !Cec4_ManGeneratePatterns_rec(p, pFan0, 1, vPat, vVisit) )
+ return 0;
+ if ( Cec4_ObjFan1HasValue(pObj, Value) || (!Cec4_ObjFan1HasValue(pObj, !Value) && !Cec4_ManGeneratePatterns_rec(p, pFan1, !Value, vPat, vVisit)) )
+ return 0;
+ }
+ assert( Value == (Cec4_ObjFan0HasValue(pObj, 1) ^ Cec4_ObjFan1HasValue(pObj, 1)) );
+ return 1;
+ }
+ else if ( Value )
+ {
+ if ( Cec4_ObjFan0HasValue(pObj, 0) || Cec4_ObjFan1HasValue(pObj, 0) )
+ return 0;
+ if ( !Cec4_ObjFan0HasValue(pObj, 1) && !Cec4_ManGeneratePatterns_rec(p, pFan0, !Gia_ObjFaninC0(pObj), vPat, vVisit) )
+ return 0;
+ if ( !Cec4_ObjFan1HasValue(pObj, 1) && !Cec4_ManGeneratePatterns_rec(p, pFan1, !Gia_ObjFaninC1(pObj), vPat, vVisit) )
+ return 0;
+ assert( Cec4_ObjFan0HasValue(pObj, 1) && Cec4_ObjFan1HasValue(pObj, 1) );
+ return 1;
+ }
+ else
+ {
+ if ( Cec4_ObjFan0HasValue(pObj, 1) && Cec4_ObjFan1HasValue(pObj, 1) )
+ return 0;
+ if ( Cec4_ObjFan0HasValue(pObj, 0) || Cec4_ObjFan1HasValue(pObj, 0) )
+ return 1;
+ if ( Cec4_ObjFan0HasValue(pObj, 1) )
+ {
+ if ( !Cec4_ManGeneratePatterns_rec(p, pFan1, Gia_ObjFaninC1(pObj), vPat, vVisit) )
+ return 0;
+ }
+ else if ( Cec4_ObjFan1HasValue(pObj, 1) )
+ {
+ if ( !Cec4_ManGeneratePatterns_rec(p, pFan0, Gia_ObjFaninC0(pObj), vPat, vVisit) )
+ return 0;
+ }
+ else
+ {
+ if ( Cec4_ObjFan0IsImpliedValue( pObj, 0 ) )
+ {
+ if ( !Cec4_ManGeneratePatterns_rec(p, pFan0, Gia_ObjFaninC0(pObj), vPat, vVisit) )
+ return 0;
+ }
+ else if ( Cec4_ObjFan1IsImpliedValue( pObj, 0 ) )
+ {
+ if ( !Cec4_ManGeneratePatterns_rec(p, pFan1, Gia_ObjFaninC1(pObj), vPat, vVisit) )
+ return 0;
+ }
+ else if ( Cec4_ObjFan0IsImpliedValue( pObj, 1 ) )
+ {
+ if ( !Cec4_ManGeneratePatterns_rec(p, pFan1, Gia_ObjFaninC1(pObj), vPat, vVisit) )
+ return 0;
+ }
+ else if ( Cec4_ObjFan1IsImpliedValue( pObj, 1 ) )
+ {
+ if ( !Cec4_ManGeneratePatterns_rec(p, pFan0, Gia_ObjFaninC0(pObj), vPat, vVisit) )
+ return 0;
+ }
+ else if ( Abc_Random(0) & 1 )
+ {
+ if ( !Cec4_ManGeneratePatterns_rec(p, pFan1, Gia_ObjFaninC1(pObj), vPat, vVisit) )
+ return 0;
+ }
+ else
+ {
+ if ( !Cec4_ManGeneratePatterns_rec(p, pFan0, Gia_ObjFaninC0(pObj), vPat, vVisit) )
+ return 0;
+ }
+ }
+ assert( Cec4_ObjFan0HasValue(pObj, 0) || Cec4_ObjFan1HasValue(pObj, 0) );
+ return 1;
+ }
+}
+int Cec4_ManGeneratePatternOne( Gia_Man_t * p, int iRepr, int iReprVal, int iCand, int iCandVal, Vec_Int_t * vPat, Vec_Int_t * vVisit )
+{
+ int Res, k;
+ Gia_Obj_t * pObj;
+ assert( iCand > 0 );
+ if ( !iRepr && iReprVal )
+ return 0;
+ Vec_IntClear( vPat );
+ Vec_IntClear( vVisit );
+ //Gia_ManForEachObj( p, pObj, k )
+ // assert( !pObj->fMark0 && !pObj->fMark1 );
+ Res = (!iRepr || Cec4_ManGeneratePatterns_rec(p, Gia_ManObj(p, iRepr), iReprVal, vPat, vVisit)) && Cec4_ManGeneratePatterns_rec(p, Gia_ManObj(p, iCand), iCandVal, vPat, vVisit);
+ Gia_ManForEachObjVec( vVisit, p, pObj, k )
+ pObj->fMark0 = pObj->fMark1 = 0;
+ return Res;
+}
+void Cec4_ManCandIterStart( Cec4_Man_t * p )
+{
+ int i, * pArray;
+ assert( p->iPosWrite == 0 );
+ assert( p->iPosRead == 0 );
+ assert( Vec_IntSize(p->vCands) == 0 );
+ for ( i = 1; i < Gia_ManObjNum(p->pAig); i++ )
+ if ( Gia_ObjRepr(p->pAig, i) != GIA_VOID )
+ Vec_IntPush( p->vCands, i );
+ pArray = Vec_IntArray( p->vCands );
+ for ( i = 0; i < Vec_IntSize(p->vCands); i++ )
+ {
+ int iNew = Abc_Random(0) % Vec_IntSize(p->vCands);
+ ABC_SWAP( int, pArray[i], pArray[iNew] );
+ }
+}
+int Cec4_ManCandIterNext( Cec4_Man_t * p )
+{
+ while ( Vec_IntSize(p->vCands) > 0 )
+ {
+ int fStop, iCand = Vec_IntEntry( p->vCands, p->iPosRead );
+ if ( (fStop = (Gia_ObjRepr(p->pAig, iCand) != GIA_VOID)) )
+ Vec_IntWriteEntry( p->vCands, p->iPosWrite++, iCand );
+ if ( ++p->iPosRead == Vec_IntSize(p->vCands) )
+ {
+ Vec_IntShrink( p->vCands, p->iPosWrite );
+ p->iPosWrite = 0;
+ p->iPosRead = 0;
+ }
+ if ( fStop )
+ return iCand;
+ }
+ return 0;
+}
+int Cec4_ManGeneratePatterns( Cec4_Man_t * p )
+{
+ abctime clk = Abc_Clock();
+ int i, iCand, nPats = 100 * 64 * p->pAig->nSimWords, CountPat = 0, Packs = 0;
+ //int iRepr;
+ //Vec_IntForEachEntryDouble( p->vDisprPairs, iRepr, iCand, i )
+ // if ( iRepr == Gia_ObjRepr(p->pAig, iCand) )
+ // printf( "Pair %6d (%6d, %6d) (new repr = %9d) is FAILED to disprove.\n", i, iRepr, iCand, Gia_ObjRepr(p->pAig, iCand) );
+ // else
+ // printf( "Pair %6d (%6d, %6d) (new repr = %9d) is disproved.\n", i, iRepr, iCand, Gia_ObjRepr(p->pAig, iCand) );
+ //Vec_IntClear( p->vDisprPairs );
+ p->pAig->iPatsPi = 0;
+ Vec_WrdFill( p->pAig->vSimsPi, Vec_WrdSize(p->pAig->vSimsPi), 0 );
+ for ( i = 0; i < nPats; i++ )
+ if ( (iCand = Cec4_ManCandIterNext(p)) )
+ {
+ int iRepr = Gia_ObjRepr( p->pAig, iCand );
+ int iCandVal = Gia_ManObj(p->pAig, iCand)->fPhase;
+ int iReprVal = Gia_ManObj(p->pAig, iRepr)->fPhase;
+ int Res = Cec4_ManGeneratePatternOne( p->pAig, iRepr, iReprVal, iCand, !iCandVal, p->vPat, p->vVisit );
+ if ( !Res )
+ Res = Cec4_ManGeneratePatternOne( p->pAig, iRepr, !iReprVal, iCand, iCandVal, p->vPat, p->vVisit );
+ if ( Res )
+ {
+ int Ret = Cec4_ManPackAddPattern( p->pAig, p->vPat, 1 );
+ if ( p->pAig->vPats )
+ {
+ Vec_IntPush( p->pAig->vPats, Vec_IntSize(p->vPat)+2 );
+ Vec_IntAppend( p->pAig->vPats, p->vPat );
+ Vec_IntPush( p->pAig->vPats, -1 );
+ }
+ //Vec_IntPushTwo( p->vDisprPairs, iRepr, iCand );
+ Packs += Ret;
+ if ( Ret == 64 * p->pAig->nSimWords )
+ break;
+ if ( ++CountPat == 8 * 64 * p->pAig->nSimWords )
+ break;
+ //Cec4_ManCexVerify( p->pAig, iRepr, iCand, iReprVal ^ iCandVal );
+ //Gia_ManCleanMark01( p->pAig );
+ }
+ }
+ p->timeGenPats += Abc_Clock() - clk;
+ p->nSatSat += CountPat;
+ //printf( "%3d : %6.2f %% : Generated %6d CEXs after trying %6d pairs. Ave packs = %9.2f Ave tries = %9.2f (Limit = %9.2f)\n",
+ // p->nItersSim++, 100.0*Vec_IntSize(p->vCands)/Gia_ManAndNum(p->pAig),
+ // CountPat, i, (float)Packs / Abc_MaxInt(1, CountPat), (float)i / Abc_MaxInt(1, CountPat), (float)nPats / p->pPars->nItersMax );
+ return CountPat >= i / p->pPars->nItersMax;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Internal simulation APIs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec4_ManSatSolverRecycle( Cec4_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i;
+ //printf( "Solver size = %d.\n", sat_solver_varnum(p->pSat) );
+ p->nRecycles++;
+ p->nCallsSince = 0;
+ sat_solver_reset( p->pSat );
+ // clean mapping of AigIds into SatIds
+ Gia_ManForEachObjVec( &p->pNew->vSuppVars, p->pNew, pObj, i )
+ Cec4_ObjCleanSatId( p->pNew, pObj );
+ Vec_IntClear( &p->pNew->vSuppVars ); // AigIds for which SatId is defined
+ Vec_IntClear( &p->pNew->vCopiesTwo ); // pairs (CiAigId, SatId)
+ Vec_IntClear( &p->pNew->vVarMap ); // mapping of SatId into AigId
+}
+int Cec4_ManSolveTwo( Cec4_Man_t * p, int iObj0, int iObj1, int fPhase, int * pfEasy, int fVerbose, int fEffort )
+{
+ abctime clk;
+ int nBTLimit = fEffort ? p->pPars->nBTLimitPo : (Vec_BitEntry(p->vFails, iObj0) || Vec_BitEntry(p->vFails, iObj1)) ? Abc_MaxInt(1, p->pPars->nBTLimit/10) : p->pPars->nBTLimit;
+ int nConfEnd, nConfBeg, status, iVar0, iVar1, Lits[2];
+ int UnsatConflicts[3] = {0};
+ //printf( "%d ", nBTLimit );
+ if ( iObj1 < iObj0 )
+ iObj1 ^= iObj0, iObj0 ^= iObj1, iObj1 ^= iObj0;
+ assert( iObj0 < iObj1 );
+ *pfEasy = 0;
+ // check if SAT solver needs recycling
+ p->nCallsSince++;
+ if ( p->nCallsSince > p->pPars->nCallsRecycle &&
+ Vec_IntSize(&p->pNew->vSuppVars) > p->pPars->nSatVarMax && p->pPars->nSatVarMax )
+ Cec4_ManSatSolverRecycle( p );
+ // add more logic to the solver
+ if ( !iObj0 && Cec4_ObjSatId(p->pNew, Gia_ManConst0(p->pNew)) == -1 )
+ Cec4_ObjSetSatId( p->pNew, Gia_ManConst0(p->pNew), sat_solver_addvar(p->pSat) );
+ clk = Abc_Clock();
+ iVar0 = Cec4_ObjGetCnfVar( p, iObj0 );
+ iVar1 = Cec4_ObjGetCnfVar( p, iObj1 );
+ if( p->pPars->jType > 0 )
+ {
+ sat_solver_start_new_round( p->pSat );
+ sat_solver_mark_cone( p->pSat, Cec4_ObjSatId(p->pNew, Gia_ManObj(p->pNew, iObj0)) );
+ sat_solver_mark_cone( p->pSat, Cec4_ObjSatId(p->pNew, Gia_ManObj(p->pNew, iObj1)) );
+ }
+ p->timeCnf += Abc_Clock() - clk;
+ // perform solving
+ Lits[0] = Abc_Var2Lit(iVar0, 1);
+ Lits[1] = Abc_Var2Lit(iVar1, fPhase);
+ sat_solver_set_conflict_budget( p->pSat, nBTLimit );
+ nConfBeg = sat_solver_conflictnum( p->pSat );
+ status = sat_solver_solve( p->pSat, Lits, 2 );
+ nConfEnd = sat_solver_conflictnum( p->pSat );
+ assert( nConfEnd >= nConfBeg );
+ if ( fVerbose )
+ {
+ if ( status == GLUCOSE_SAT )
+ {
+ p->nConflicts[0][0] += nConfEnd == nConfBeg;
+ p->nConflicts[0][1] += nConfEnd - nConfBeg;
+ p->nConflicts[0][2] = Abc_MaxInt(p->nConflicts[0][2], nConfEnd - nConfBeg);
+ *pfEasy = nConfEnd == nConfBeg;
+ }
+ else if ( status == GLUCOSE_UNSAT )
+ {
+ if ( iObj0 > 0 )
+ {
+ UnsatConflicts[0] = nConfEnd == nConfBeg;
+ UnsatConflicts[1] = nConfEnd - nConfBeg;
+ UnsatConflicts[2] = Abc_MaxInt(p->nConflicts[1][2], nConfEnd - nConfBeg);
+ }
+ else
+ {
+ p->nConflicts[1][0] += nConfEnd == nConfBeg;
+ p->nConflicts[1][1] += nConfEnd - nConfBeg;
+ p->nConflicts[1][2] = Abc_MaxInt(p->nConflicts[1][2], nConfEnd - nConfBeg);
+ *pfEasy = nConfEnd == nConfBeg;
+ }
+ }
+ }
+ if ( status == GLUCOSE_UNSAT && iObj0 > 0 )
+ {
+ Lits[0] = Abc_Var2Lit(iVar0, 0);
+ Lits[1] = Abc_Var2Lit(iVar1, !fPhase);
+ sat_solver_set_conflict_budget( p->pSat, nBTLimit );
+ nConfBeg = sat_solver_conflictnum( p->pSat );
+ status = sat_solver_solve( p->pSat, Lits, 2 );
+ nConfEnd = sat_solver_conflictnum( p->pSat );
+ assert( nConfEnd >= nConfBeg );
+ if ( fVerbose )
+ {
+ if ( status == GLUCOSE_SAT )
+ {
+ p->nConflicts[0][0] += nConfEnd == nConfBeg;
+ p->nConflicts[0][1] += nConfEnd - nConfBeg;
+ p->nConflicts[0][2] = Abc_MaxInt(p->nConflicts[0][2], nConfEnd - nConfBeg);
+ *pfEasy = nConfEnd == nConfBeg;
+ }
+ else if ( status == GLUCOSE_UNSAT )
+ {
+ UnsatConflicts[0] &= nConfEnd == nConfBeg;
+ UnsatConflicts[1] += nConfEnd - nConfBeg;
+ UnsatConflicts[2] = Abc_MaxInt(p->nConflicts[1][2], nConfEnd - nConfBeg);
+
+ p->nConflicts[1][0] += UnsatConflicts[0];
+ p->nConflicts[1][1] += UnsatConflicts[1];
+ p->nConflicts[1][2] = Abc_MaxInt(p->nConflicts[1][2], UnsatConflicts[2]);
+ *pfEasy = UnsatConflicts[0];
+ }
+ }
+ }
+ //if ( status == GLUCOSE_UNDEC )
+ // printf( "* " );
+ return status;
+}
+int Cec4_ManSweepNode( Cec4_Man_t * p, int iObj, int iRepr )
+{
+ abctime clk = Abc_Clock();
+ int i, IdAig, IdSat, status, fEasy, RetValue = 1;
+ Gia_Obj_t * pObj = Gia_ManObj( p->pAig, iObj );
+ Gia_Obj_t * pRepr = Gia_ManObj( p->pAig, iRepr );
+ int fCompl = Abc_LitIsCompl(pObj->Value) ^ Abc_LitIsCompl(pRepr->Value) ^ pObj->fPhase ^ pRepr->fPhase;
+ int fEffort = p->vCoDrivers ? Vec_BitEntry(p->vCoDrivers, iObj) || Vec_BitEntry(p->vCoDrivers, iRepr) : 0;
+ status = Cec4_ManSolveTwo( p, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl, &fEasy, p->pPars->fVerbose, fEffort );
+ if ( status == GLUCOSE_SAT )
+ {
+ int iLit;
+ //int iPatsOld = p->pAig->iPatsPi;
+ //printf( "Disproved: %d == %d.\n", Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value) );
+ p->nSatSat++;
+ p->nPatterns++;
+ Vec_IntClear( p->vPat );
+ if ( p->pPars->jType == 0 )
+ {
+ Vec_IntForEachEntryDouble( &p->pNew->vCopiesTwo, IdAig, IdSat, i )
+ Vec_IntPush( p->vPat, Abc_Var2Lit(IdAig, sat_solver_read_cex_varvalue(p->pSat, IdSat)) );
+ }
+ else
+ {
+ int * pCex = sat_solver_read_cex( p->pSat );
+ int * pMap = Vec_IntArray(&p->pNew->vVarMap);
+ for ( i = 0; i < pCex[0]; )
+ Vec_IntPush( p->vPat, Abc_Lit2LitV(pMap, Abc_LitNot(pCex[++i])) );
+ }
+ assert( p->pAig->iPatsPi >= 0 && p->pAig->iPatsPi < 64 * p->pAig->nSimWords - 1 );
+ p->pAig->iPatsPi++;
+ Vec_IntForEachEntry( p->vPat, iLit, i )
+ Cec4_ObjSimSetInputBit( p->pAig, Abc_Lit2Var(iLit), Abc_LitIsCompl(iLit) );
+ if ( p->pAig->vPats )
+ {
+ Vec_IntPush( p->pAig->vPats, Vec_IntSize(p->vPat)+2 );
+ Vec_IntAppend( p->pAig->vPats, p->vPat );
+ Vec_IntPush( p->pAig->vPats, -1 );
+ }
+ //Cec4_ManPackAddPattern( p->pAig, p->vPat, 0 );
+ //assert( iPatsOld + 1 == p->pAig->iPatsPi );
+ if ( fEasy )
+ p->timeSatSat0 += Abc_Clock() - clk;
+ else
+ p->timeSatSat += Abc_Clock() - clk;
+ RetValue = 0;
+ // this is not needed, but we keep it here anyway, because it takes very little time
+ //Cec4_ManVerify( p->pNew, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl, p->pSat );
+ // resimulated once in a while
+ if ( p->pAig->iPatsPi == 64 * p->pAig->nSimWords - 2 )
+ {
+ abctime clk2 = Abc_Clock();
+ Cec4_ManSimulate( p->pAig, p );
+ //printf( "FasterSmall = %d. FasterBig = %d.\n", p->nFaster[0], p->nFaster[1] );
+ p->nFaster[0] = p->nFaster[1] = 0;
+ //if ( p->nSatSat && p->nSatSat % 100 == 0 )
+ Cec4_ManPrintStats( p->pAig, p->pPars, p, 0 );
+ Vec_IntFill( p->vCexStamps, Gia_ManObjNum(p->pAig), 0 );
+ p->pAig->iPatsPi = 0;
+ Vec_WrdFill( p->pAig->vSimsPi, Vec_WrdSize(p->pAig->vSimsPi), 0 );
+ p->timeResimGlo += Abc_Clock() - clk2;
+ }
+ }
+ else if ( status == GLUCOSE_UNSAT )
+ {
+ //printf( "Proved: %d == %d.\n", Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value) );
+ p->nSatUnsat++;
+ pObj->Value = Abc_LitNotCond( pRepr->Value, fCompl );
+ Gia_ObjSetProved( p->pAig, iObj );
+ if ( iRepr == 0 )
+ p->iLastConst = iObj;
+ if ( fEasy )
+ p->timeSatUnsat0 += Abc_Clock() - clk;
+ else
+ p->timeSatUnsat += Abc_Clock() - clk;
+ RetValue = 1;
+ }
+ else
+ {
+ p->nSatUndec++;
+ assert( status == GLUCOSE_UNDEC );
+ Gia_ObjSetFailed( p->pAig, iObj );
+ Vec_BitWriteEntry( p->vFails, iObj, 1 );
+ //if ( iRepr )
+ //Vec_BitWriteEntry( p->vFails, iRepr, 1 );
+ p->timeSatUndec += Abc_Clock() - clk;
+ RetValue = 2;
+ }
+ return RetValue;
+}
+Gia_Obj_t * Cec4_ManFindRepr( Gia_Man_t * p, Cec4_Man_t * pMan, int iObj )
+{
+ abctime clk = Abc_Clock();
+ int iMem, iRepr;
+ assert( Gia_ObjHasRepr(p, iObj) );
+ assert( !Gia_ObjProved(p, iObj) );
+ iRepr = Gia_ObjRepr(p, iObj);
+ assert( iRepr != iObj );
+ assert( !Gia_ObjProved(p, iRepr) );
+ Cec4_ManSimulate_rec( p, pMan, iObj );
+ Cec4_ManSimulate_rec( p, pMan, iRepr );
+ if ( Cec4_ObjSimEqual(p, iObj, iRepr) )
+ {
+ pMan->timeResimLoc += Abc_Clock() - clk;
+ return Gia_ManObj(p, iRepr);
+ }
+ Gia_ClassForEachObj1( p, iRepr, iMem )
+ {
+ if ( iObj == iMem )
+ break;
+ if ( Gia_ObjProved(p, iMem) || Gia_ObjFailed(p, iMem) )
+ continue;
+ Cec4_ManSimulate_rec( p, pMan, iMem );
+ if ( Cec4_ObjSimEqual(p, iObj, iMem) )
+ {
+ pMan->nFaster[0]++;
+ pMan->timeResimLoc += Abc_Clock() - clk;
+ return Gia_ManObj(p, iMem);
+ }
+ }
+ pMan->nFaster[1]++;
+ pMan->timeResimLoc += Abc_Clock() - clk;
+ return NULL;
+}
+int Cec4_ManPerformSweeping( Gia_Man_t * p, Cec_ParFra_t * pPars, Gia_Man_t ** ppNew, int fSimOnly )
+{
+ Cec4_Man_t * pMan = Cec4_ManCreate( p, pPars );
+ Gia_Obj_t * pObj, * pRepr;
+ int i, fSimulate = 1;
+ if ( pPars->fVerbose )
+ printf( "Solver type = %d. Simulate %d words in %d rounds. SAT with %d confs. Recycle after %d SAT calls.\n",
+ pPars->jType, pPars->nWords, pPars->nRounds, pPars->nBTLimit, pPars->nCallsRecycle );
+
+ // this is currently needed to have a correct mapping
+ Gia_ManForEachCi( p, pObj, i )
+ assert( Gia_ObjId(p, pObj) == i+1 );
+
+ // check if any output trivially fails under all-0 pattern
+ Gia_ManRandom( 1 );
+ Gia_ManSetPhase( p );
+ if ( pPars->nLevelMax )
+ Gia_ManLevelNum(p);
+ //Gia_ManStaticFanoutStart( p );
+ if ( pPars->fCheckMiter )
+ {
+ Gia_ManForEachCo( p, pObj, i )
+ if ( pObj->fPhase )
+ {
+ p->pCexSeq = Cec4_ManDeriveCex( p, i, -1 );
+ goto finalize;
+ }
+ }
+
+ // simulate one round and create classes
+ Cec4_ManSimAlloc( p, pPars->nWords );
+ Cec4_ManSimulateCis( p );
+ Cec4_ManSimulate( p, pMan );
+ if ( pPars->fCheckMiter && !Cec4_ManSimulateCos(p) ) // cex detected
+ goto finalize;
+ if ( pPars->fVerbose )
+ Cec4_ManPrintStats( p, pPars, pMan, 1 );
+
+ // perform simulation
+ for ( i = 0; i < pPars->nRounds; i++ )
+ {
+ Cec4_ManSimulateCis( p );
+ Cec4_ManSimulate( p, pMan );
+ if ( pPars->fCheckMiter && !Cec4_ManSimulateCos(p) ) // cex detected
+ goto finalize;
+ if ( i && i % (pPars->nRounds / 5) == 0 && pPars->fVerbose )
+ Cec4_ManPrintStats( p, pPars, pMan, 1 );
+ }
+ if ( fSimOnly )
+ goto finalize;
+
+ // perform additional simulation
+ Cec4_ManCandIterStart( pMan );
+ for ( i = 0; fSimulate && i < pPars->nGenIters; i++ )
+ {
+ Cec4_ManSimulateCis( p );
+ fSimulate = Cec4_ManGeneratePatterns( pMan );
+ Cec4_ManSimulate( p, pMan );
+ if ( pPars->fCheckMiter && !Cec4_ManSimulateCos(p) ) // cex detected
+ goto finalize;
+ if ( i && i % 5 == 0 && pPars->fVerbose )
+ Cec4_ManPrintStats( p, pPars, pMan, 1 );
+ }
+ if ( i && i % 5 && pPars->fVerbose )
+ Cec4_ManPrintStats( p, pPars, pMan, 1 );
+
+ p->iPatsPi = 0;
+ Vec_WrdFill( p->vSimsPi, Vec_WrdSize(p->vSimsPi), 0 );
+ pMan->nSatSat = 0;
+ pMan->pNew = Cec4_ManStartNew( p );
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ Gia_Obj_t * pObjNew;
+ pMan->nAndNodes++;
+ if ( Gia_ObjIsXor(pObj) )
+ pObj->Value = Gia_ManHashXorReal( pMan->pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ else
+ pObj->Value = Gia_ManHashAnd( pMan->pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ if ( pPars->nLevelMax && Gia_ObjLevel(p, pObj) > pPars->nLevelMax )
+ continue;
+ pObjNew = Gia_ManObj( pMan->pNew, Abc_Lit2Var(pObj->Value) );
+ if ( Gia_ObjIsAnd(pObjNew) )
+ if ( Vec_BitEntry(pMan->vFails, Gia_ObjFaninId0(pObjNew, Abc_Lit2Var(pObj->Value))) ||
+ Vec_BitEntry(pMan->vFails, Gia_ObjFaninId1(pObjNew, Abc_Lit2Var(pObj->Value))) )
+ Vec_BitWriteEntry( pMan->vFails, Abc_Lit2Var(pObjNew->Value), 1 );
+ //if ( Gia_ObjIsAnd(pObjNew) )
+ // Gia_ObjSetAndLevel( pMan->pNew, pObjNew );
+ // select representative based on candidate equivalence classes
+ pRepr = Gia_ObjReprObj( p, i );
+ if ( pRepr == NULL )
+ continue;
+ if ( 1 ) // select representative based on recent counter-examples
+ {
+ pRepr = Cec4_ManFindRepr( p, pMan, i );
+ if ( pRepr == NULL )
+ continue;
+ }
+ if ( Abc_Lit2Var(pObj->Value) == Abc_Lit2Var(pRepr->Value) )
+ {
+ assert( (pObj->Value ^ pRepr->Value) == (pObj->fPhase ^ pRepr->fPhase) );
+ Gia_ObjSetProved( p, i );
+ if ( Gia_ObjId(p, pRepr) == 0 )
+ pMan->iLastConst = i;
+ continue;
+ }
+ if ( Cec4_ManSweepNode(pMan, i, Gia_ObjId(p, pRepr)) && Gia_ObjProved(p, i) )
+ pObj->Value = Abc_LitNotCond( pRepr->Value, pObj->fPhase ^ pRepr->fPhase );
+ }
+ if ( p->iPatsPi > 0 )
+ {
+ abctime clk2 = Abc_Clock();
+ Cec4_ManSimulate( p, pMan );
+ p->iPatsPi = 0;
+ Vec_IntFill( pMan->vCexStamps, Gia_ManObjNum(p), 0 );
+ pMan->timeResimGlo += Abc_Clock() - clk2;
+ }
+ if ( pPars->fVerbose )
+ Cec4_ManPrintStats( p, pPars, pMan, 0 );
+ if ( ppNew )
+ {
+ Gia_ManForEachCo( p, pObj, i )
+ pObj->Value = Gia_ManAppendCo( pMan->pNew, Gia_ObjFanin0Copy(pObj) );
+ *ppNew = Gia_ManCleanup( pMan->pNew );
+ }
+finalize:
+ if ( pPars->fVerbose )
+ printf( "SAT calls = %d: P = %d (0=%d a=%.2f m=%d) D = %d (0=%d a=%.2f m=%d) F = %d Sim = %d Recyc = %d Xor = %.2f %%\n",
+ pMan->nSatUnsat + pMan->nSatSat + pMan->nSatUndec,
+ pMan->nSatUnsat, pMan->nConflicts[1][0], (float)pMan->nConflicts[1][1]/Abc_MaxInt(1, pMan->nSatUnsat-pMan->nConflicts[1][0]), pMan->nConflicts[1][2],
+ pMan->nSatSat, pMan->nConflicts[0][0], (float)pMan->nConflicts[0][1]/Abc_MaxInt(1, pMan->nSatSat -pMan->nConflicts[0][0]), pMan->nConflicts[0][2],
+ pMan->nSatUndec,
+ pMan->nSimulates, pMan->nRecycles, 100.0*pMan->nGates[1]/Abc_MaxInt(1, pMan->nGates[0]+pMan->nGates[1]) );
+ Cec4_ManDestroy( pMan );
+ //Gia_ManStaticFanoutStop( p );
+ //Gia_ManEquivPrintClasses( p, 1, 0 );
+ return p->pCexSeq ? 0 : 1;
+}
+Gia_Man_t * Cec4_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars )
+{
+ Gia_Man_t * pNew = NULL;
+ Cec4_ManPerformSweeping( p, pPars, &pNew, 0 );
+ return pNew;
+}
+void Cec4_ManSimulateTest2( Gia_Man_t * p, int nConfs, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ Cec_ParFra_t ParsFra, * pPars = &ParsFra;
+ Cec4_ManSetParams( pPars );
+ Cec4_ManPerformSweeping( p, pPars, NULL, 0 );
+ pPars->fVerbose = fVerbose;
+ pPars->nBTLimit = nConfs;
+ if ( fVerbose )
+ Abc_PrintTime( 1, "New choice computation time", Abc_Clock() - clk );
+}
+Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose )
+{
+ Gia_Man_t * pNew = NULL;
+ Cec_ParFra_t ParsFra, * pPars = &ParsFra;
+ Cec4_ManSetParams( pPars );
+ pPars->fVerbose = fVerbose;
+ pPars->nBTLimit = nBTLimit;
+ Cec4_ManPerformSweeping( p, pPars, &pNew, 0 );
+ return pNew;
+}
+Gia_Man_t * Cec4_ManSimulateTest4( Gia_Man_t * p, int nBTLimit, int nBTLimitPo, int fVerbose )
+{
+ Gia_Man_t * pNew = NULL;
+ Cec_ParFra_t ParsFra, * pPars = &ParsFra;
+ Cec4_ManSetParams( pPars );
+ pPars->fVerbose = fVerbose;
+ pPars->nBTLimit = nBTLimit;
+ pPars->nBTLimitPo = nBTLimitPo;
+ Cec4_ManPerformSweeping( p, pPars, &pNew, 0 );
+ return pNew;
+}
+int Cec4_ManSimulateOnlyTest( Gia_Man_t * p, int fVerbose )
+{
+ Cec_ParFra_t ParsFra, * pPars = &ParsFra;
+ Cec4_ManSetParams( pPars );
+ pPars->fVerbose = fVerbose;
+ return Cec4_ManPerformSweeping( p, pPars, NULL, 1 );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/cec/cecSim.c b/src/proof/cec/cecSim.c
index 92f8fc2e..48a789f3 100644
--- a/src/proof/cec/cecSim.c
+++ b/src/proof/cec/cecSim.c
@@ -6,7 +6,7 @@
PackageName [Combinational equivalence checking.]
- Synopsis [Simulation manager.]
+ Synopsis [Simulation.]
Author [Alan Mishchenko]
@@ -19,14 +19,40 @@
***********************************************************************/
#include "cecInt.h"
+#include "aig/gia/giaAig.h"
+#include "misc/util/utilTruth.h"
-ABC_NAMESPACE_IMPL_START
+ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+#define SIM_RANDS 113
+
+typedef struct Cec_ManS_t_ Cec_ManS_t;
+struct Cec_ManS_t_
+{
+ int nWords;
+ int nLevelMax;
+ int nLevelMin;
+ int iRand;
+ Gia_Man_t * pAig;
+ Vec_Int_t * vInputs;
+ Vec_Wec_t * vLevels;
+ Vec_Wrd_t * vSims;
+ word * pTemp[4];
+ word Rands[SIM_RANDS];
+ int nSkipped;
+ int nVisited;
+ int nCexes;
+ abctime clkSat;
+ abctime clkUnsat;
+};
+
+static inline word * Cec_ManSSim( Cec_ManS_t * p, int iNode, int Value ) { return Vec_WrdEntryP(p->vSims, p->nWords*(iNode+iNode+Value)); }
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -36,12 +62,340 @@ ABC_NAMESPACE_IMPL_START
Synopsis []
Description []
-
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Cec_ManS_t * Cec_ManSStart( Gia_Man_t * pAig, int nWords )
+{
+ Cec_ManS_t * p; int i;
+ p = ABC_ALLOC( Cec_ManS_t, 1 );
+ memset( p, 0, sizeof(Cec_ManS_t) );
+ p->nWords = nWords;
+ p->pAig = pAig;
+ p->vInputs = Vec_IntAlloc( 100 );
+ p->vLevels = Vec_WecStart( Gia_ManLevelNum(pAig) + 1 );
+ p->vSims = Vec_WrdStart( Gia_ManObjNum(pAig) * nWords * 2 );
+ p->pTemp[0] = ABC_ALLOC( word, 4*nWords );
+ for ( i = 1; i < 4; i++ )
+ p->pTemp[i] = p->pTemp[i-1] + nWords;
+ for ( i = 0; i < SIM_RANDS; i++ )
+ p->Rands[i] = Gia_ManRandomW(0);
+ return p;
+}
+void Cec_ManSStop( Cec_ManS_t * p )
+{
+ Vec_IntFree( p->vInputs );
+ Vec_WecFree( p->vLevels );
+ Vec_WrdFree( p->vSims );
+ ABC_FREE( p->pTemp[0] );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Verify counter-example.]
+
+ Description []
+
SideEffects []
SeeAlso []
***********************************************************************/
+int Cec_ManSVerify_rec( Gia_Man_t * p, int iObj )
+{
+ int Value0, Value1;
+ Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
+ if ( iObj == 0 ) return 0;
+ if ( Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return pObj->fMark1;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ if ( Gia_ObjIsCi(pObj) )
+ return pObj->fMark1;
+ assert( Gia_ObjIsAnd(pObj) );
+ Value0 = Cec_ManSVerify_rec( p, Gia_ObjFaninId0(pObj, iObj) ) ^ Gia_ObjFaninC0(pObj);
+ Value1 = Cec_ManSVerify_rec( p, Gia_ObjFaninId1(pObj, iObj) ) ^ Gia_ObjFaninC1(pObj);
+ return pObj->fMark1 = Gia_ObjIsXor(pObj) ? Value0 ^ Value1 : Value0 & Value1;
+}
+void Cec_ManSVerifyTwo( Gia_Man_t * p, int iObj0, int iObj1 )
+{
+ int Value0, Value1;
+ Gia_ManIncrementTravId( p );
+ Value0 = Cec_ManSVerify_rec( p, iObj0 );
+ Value1 = Cec_ManSVerify_rec( p, iObj1 );
+ if ( (Value0 ^ Value1) == Gia_ObjPhaseDiff(p, iObj0, iObj1) )
+ printf( "CEX verification FAILED for obj %d and obj %d.\n", iObj0, iObj1 );
+// else
+// printf( "CEX verification succeeded for obj %d and obj %d.\n", iObj0, iObj1 );;
+}
+void Cec_ManSVerify( Cec_ManS_t * p, int iObj0, int iObj1 )
+{
+ int fDoVerify = 0;
+ int w, i, iObj, nCares;
+ word * pCare = Vec_WrdArray(p->vSims);
+ if ( Vec_IntSize(p->vInputs) == 0 )
+ {
+ printf( "No primary inputs.\n" );
+ return;
+ }
+ Vec_IntForEachEntry( p->vInputs, iObj, i )
+ {
+ word * pSim_0 = Cec_ManSSim( p, iObj, 0 );
+ word * pSim_1 = Cec_ManSSim( p, iObj, 1 );
+ if ( p->nWords == 1 )
+ pCare[0] |= pSim_0[0] & pSim_1[0];
+ else
+ Abc_TtOrAnd( pCare, pSim_0, pSim_1, p->nWords );
+ }
+ nCares = Abc_TtCountOnesVec( pCare, p->nWords );
+ if ( nCares == 64*p->nWords )
+ {
+ printf( "No CEXes.\n" );
+ return;
+ }
+ assert( Vec_IntSize(p->vInputs) > 0 );
+ for ( w = 0; w < 64*p->nWords; w++ )
+ {
+ if ( Abc_TtGetBit(pCare, w) )
+ continue;
+ if ( !fDoVerify )
+ continue;
+ Vec_IntForEachEntry( p->vInputs, iObj, i )
+ Gia_ManObj(p->pAig, iObj)->fMark1 = Abc_TtGetBit( Cec_ManSSim(p, iObj, 1), w );
+ Cec_ManSVerifyTwo( p->pAig, iObj0, iObj1 );
+ }
+ printf( "Considered %d CEXes of nodes %d and %d.\n", 64*p->nWords - nCares, iObj0, iObj1 );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec_ManSRunImply( Cec_ManS_t * p, int iNode )
+{
+ Gia_Obj_t * pNode = Gia_ManObj( p->pAig, iNode );
+ if ( Gia_ObjIsAnd(pNode) )
+ {
+ int iFan0 = Gia_ObjFaninId0( pNode, iNode );
+ int iFan1 = Gia_ObjFaninId1( pNode, iNode );
+ word * pSim__ = Cec_ManSSim( p, 0, 0 );
+ word * pSim_0 = Cec_ManSSim( p, iNode, 0 );
+ word * pSim_1 = Cec_ManSSim( p, iNode, 1 );
+ word * pSim00 = Cec_ManSSim( p, iFan0, Gia_ObjFaninC0(pNode) );
+ word * pSim01 = Cec_ManSSim( p, iFan0, !Gia_ObjFaninC0(pNode) );
+ word * pSim10 = Cec_ManSSim( p, iFan1, Gia_ObjFaninC1(pNode) );
+ word * pSim11 = Cec_ManSSim( p, iFan1, !Gia_ObjFaninC1(pNode) );
+ if ( p->nWords == 1 )
+ {
+ pSim_0[0] |= pSim00[0] | pSim10[0];
+ pSim_1[0] |= pSim01[0] & pSim11[0];
+ pSim__[0] |= pSim_0[0] & pSim_1[0];
+ pSim_0[0] &= ~pSim__[0];
+ pSim_1[0] &= ~pSim__[0];
+ }
+ else
+ {
+ Abc_TtOr( pSim_0, pSim_0, pSim00, p->nWords );
+ Abc_TtOr( pSim_0, pSim_0, pSim10, p->nWords );
+ Abc_TtOrAnd( pSim_1, pSim01, pSim11, p->nWords );
+ Abc_TtOrAnd( pSim__, pSim_0, pSim_1, p->nWords );
+ Abc_TtAndSharp( pSim_0, pSim_0, pSim__, p->nWords, 1 );
+ Abc_TtAndSharp( pSim_1, pSim_1, pSim__, p->nWords, 1 );
+ }
+ }
+}
+int Cec_ManSRunPropagate( Cec_ManS_t * p, int iNode )
+{
+ Gia_Obj_t * pNode = Gia_ManObj( p->pAig, iNode );
+ int iFan0 = Gia_ObjFaninId0( pNode, iNode );
+ int iFan1 = Gia_ObjFaninId1( pNode, iNode );
+ word * pSim_0 = Cec_ManSSim( p, iNode, 0 );
+ word * pSim_1 = Cec_ManSSim( p, iNode, 1 );
+ if ( Abc_TtIsConst0(pSim_0, p->nWords) && Abc_TtIsConst0(pSim_1, p->nWords) )
+ {
+ p->nSkipped++;
+ return 0;
+ }
+ p->nVisited++;
+ //Cec_ManSRunImply( p, iFan0 );
+ //Cec_ManSRunImply( p, iFan1 );
+ {
+ word * pSim__ = Cec_ManSSim( p, 0, 0 );
+ word * pSim00 = Cec_ManSSim( p, iFan0, Gia_ObjFaninC0(pNode) );
+ word * pSim01 = Cec_ManSSim( p, iFan0, !Gia_ObjFaninC0(pNode) );
+ word * pSim10 = Cec_ManSSim( p, iFan1, Gia_ObjFaninC1(pNode) );
+ word * pSim11 = Cec_ManSSim( p, iFan1, !Gia_ObjFaninC1(pNode) );
+ p->iRand = p->iRand == SIM_RANDS-1 ? 0 : p->iRand + 1;
+ if ( p->nWords == 1 )
+ {
+ pSim01[0] |= pSim_1[0];
+ pSim11[0] |= pSim_1[0];
+
+ pSim00[0] |= pSim_0[0] & (pSim11[0] | ~p->Rands[p->iRand]);
+ pSim10[0] |= pSim_0[0] & (pSim01[0] | p->Rands[p->iRand]);
+
+ pSim__[0] |= pSim00[0] & pSim01[0];
+ pSim__[0] |= pSim10[0] & pSim11[0];
+
+ pSim00[0] &= ~pSim__[0];
+ pSim01[0] &= ~pSim__[0];
+ pSim10[0] &= ~pSim__[0];
+ pSim11[0] &= ~pSim__[0];
+ }
+ else
+ {
+ int w;
+ for ( w = 0; w < p->nWords; w++ )
+ p->pTemp[0][w] = ~p->Rands[(p->iRand + w) % SIM_RANDS];
+
+ Abc_TtOr( pSim01, pSim01, pSim_1, p->nWords );
+ Abc_TtOr( pSim11, pSim11, pSim_1, p->nWords );
+
+ Abc_TtOr( p->pTemp[1], pSim11, p->pTemp[0], p->nWords );
+ Abc_TtOrAnd( pSim00, pSim_0, p->pTemp[1], p->nWords );
+
+ Abc_TtNot( p->pTemp[0], p->nWords );
+ Abc_TtOr( p->pTemp[1], pSim01, p->pTemp[0], p->nWords );
+ Abc_TtOrAnd( pSim10, pSim_0, p->pTemp[1], p->nWords );
+
+ Abc_TtOrAnd( pSim__, pSim00, pSim01, p->nWords );
+ Abc_TtOrAnd( pSim__, pSim10, pSim11, p->nWords );
+
+ Abc_TtAndSharp( pSim00, pSim00, pSim__, p->nWords, 1 );
+ Abc_TtAndSharp( pSim01, pSim01, pSim__, p->nWords, 1 );
+ Abc_TtAndSharp( pSim10, pSim10, pSim__, p->nWords, 1 );
+ Abc_TtAndSharp( pSim11, pSim11, pSim__, p->nWords, 1 );
+ }
+ }
+ return 1;
+}
+void Cec_ManSInsert( Cec_ManS_t * p, int iNode )
+{
+ Gia_Obj_t * pNode; int Level;
+ assert( iNode > 0 );
+ if ( Gia_ObjIsTravIdCurrentId(p->pAig, iNode) )
+ return;
+ Gia_ObjSetTravIdCurrentId(p->pAig, iNode);
+ pNode = Gia_ManObj( p->pAig, iNode );
+ if ( Gia_ObjIsCi(pNode) )
+ {
+ Vec_IntPush( p->vInputs, iNode );
+ return;
+ }
+ assert( Gia_ObjIsAnd(pNode) );
+ Level = Gia_ObjLevelId( p->pAig, iNode );
+ assert( Level > 0 );
+ Vec_WecPush( p->vLevels, Level, iNode );
+ p->nLevelMax = Abc_MaxInt( p->nLevelMax, Level );
+ p->nLevelMin = Abc_MinInt( p->nLevelMin, Level );
+ assert( p->nLevelMin <= p->nLevelMax );
+}
+int Cec_ManSRunSimInt( Cec_ManS_t * p )
+{
+ Vec_Int_t * vLevel;
+ int i, k, iNode, fSolved = 0;
+ Vec_WecForEachLevelReverseStartStop( p->vLevels, vLevel, i, p->nLevelMax+1, p->nLevelMin )
+ {
+ Vec_IntForEachEntry( vLevel, iNode, k )
+ {
+ Gia_Obj_t * pNode = Gia_ManObj( p->pAig, iNode );
+ if ( !fSolved && Cec_ManSRunPropagate( p, iNode ) )
+ {
+ Cec_ManSInsert( p, Gia_ObjFaninId0(pNode, iNode) );
+ Cec_ManSInsert( p, Gia_ObjFaninId1(pNode, iNode) );
+ if ( Abc_TtIsConst1(Vec_WrdArray(p->vSims), p->nWords) )
+ fSolved = 1;
+ }
+ Abc_TtClear( Cec_ManSSim(p, iNode, 0), 2*p->nWords );
+ }
+ Vec_IntClear( vLevel );
+ }
+ //Vec_WecForEachLevel( p->vLevels, vLevel, i )
+ // assert( Vec_IntSize(vLevel) == 0 );
+ return fSolved;
+}
+int Cec_ManSRunSim( Cec_ManS_t * p, int iNode0, int iNode1 )
+{
+ abctime clk = Abc_Clock();
+ //Vec_Int_t * vLevel;
+ //int pNodes[2] = { iNode0, iNode1 };
+ int i, iNode, Status, fDiff = Gia_ObjPhaseDiff( p->pAig, iNode0, iNode1 );
+ word * pSim00 = Cec_ManSSim( p, iNode0, 0 );
+ word * pSim01 = Cec_ManSSim( p, iNode0, 1 );
+ word * pSim10 = Cec_ManSSim( p, iNode1, fDiff );
+ word * pSim11 = Cec_ManSSim( p, iNode1, !fDiff );
+ Abc_TtClear( Vec_WrdArray(p->vSims), p->nWords );
+ //for ( i = 0; i < Vec_WrdSize(p->vSims); i++ )
+ // assert( p->vSims->pArray[i] == 0 );
+ assert( Vec_IntSize(p->vInputs) == 0 );
+ if ( iNode0 == 0 )
+ Abc_TtFill( pSim11, p->nWords );
+ else
+ {
+ if ( p->nWords == 1 )
+ {
+ pSim00[0] = (word)0xFFFFFFFF;
+ pSim11[0] = (word)0xFFFFFFFF;
+ pSim01[0] = pSim00[0] << 32;
+ pSim10[0] = pSim11[0] << 32;
+ }
+ else
+ {
+ assert( p->nWords % 2 == 0 );
+ Abc_TtFill( pSim00, p->nWords/2 );
+ Abc_TtFill( pSim11, p->nWords/2 );
+ Abc_TtFill( pSim01 + p->nWords/2, p->nWords/2 );
+ Abc_TtFill( pSim10 + p->nWords/2, p->nWords/2 );
+ }
+ }
+ p->nLevelMin = ABC_INFINITY;
+ p->nLevelMax = 0;
+ Gia_ManIncrementTravId( p->pAig );
+ if ( iNode0 )
+ Cec_ManSInsert( p, iNode0 );
+ Cec_ManSInsert( p, iNode1 );
+ p->nSkipped = p->nVisited = 0;
+ Status = Cec_ManSRunSimInt( p );
+ if ( Status == 0 )
+ p->clkSat += Abc_Clock() - clk;
+ else
+ p->clkUnsat += Abc_Clock() - clk;
+// if ( Status == 0 )
+// printf( "Solving %6d and %6d. Skipped = %6d. Visited = %6d. Cone = %6d. Min = %3d. Max = %3d.\n",
+// iNode0, iNode1, p->nSkipped, p->nVisited, Gia_ManConeSize(p->pAig, pNodes, 2), p->nLevelMin, p->nLevelMax );
+ if ( Status == 0 )
+ Cec_ManSVerify( p, iNode0, iNode1 ), p->nCexes++;
+ Vec_IntForEachEntry( p->vInputs, iNode, i )
+ Abc_TtClear( Cec_ManSSim(p, iNode, 0), 2*p->nWords );
+ Vec_IntClear( p->vInputs );
+ return Status;
+}
+void Cec_ManSRunTest( Gia_Man_t * pAig )
+{
+ abctime clk = Abc_Clock();
+ Cec_ManS_t * p;
+ int i, k, nWords = 1;
+ Gia_ManRandomW( 1 );
+ p = Cec_ManSStart( pAig, nWords );
+ Gia_ManForEachClass0( p->pAig, i )
+ Gia_ClassForEachObj1( p->pAig, i, k )
+ Cec_ManSRunSim( p, i, k );
+ printf( "Detected %d CEXes. ", p->nCexes );
+ Abc_PrintTime( 1, "Time ", Abc_Clock() - clk );
+ Abc_PrintTime( 1, "Sat ", p->clkSat );
+ Abc_PrintTime( 1, "Unsat", p->clkUnsat );
+ Cec_ManSStop( p );
+}
////////////////////////////////////////////////////////////////////////
diff --git a/src/proof/cec/cecSolve.c b/src/proof/cec/cecSolve.c
index af6a4fdb..f8342859 100644
--- a/src/proof/cec/cecSolve.c
+++ b/src/proof/cec/cecSolve.c
@@ -696,7 +696,7 @@ Abc_Cex_t * Cex_ManGenCex( Cec_ManSat_t * p, int iOut )
}
return pCex;
}
-void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPars, Vec_Int_t * vIdsOrig, Vec_Int_t * vMiterPairs, Vec_Int_t * vEquivPairs )
+void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPars, Vec_Int_t * vIdsOrig, Vec_Int_t * vMiterPairs, Vec_Int_t * vEquivPairs, int f0Proved )
{
Bar_Progress_t * pProgress = NULL;
Cec_ManSat_t * p;
@@ -747,6 +747,9 @@ clk2 = Abc_Clock();
if ( pPars->fSaveCexes && status != -1 )
Vec_PtrWriteEntry( pAig->vSeqModelVec, i, status ? (Abc_Cex_t *)(ABC_PTRINT_T)1 : Cex_ManGenCex(p, i) );
+ if ( f0Proved && status == 1 )
+ Gia_ManPatchCoDriver( pAig, i, 0 );
+
/*
if ( status == -1 )
{
@@ -807,7 +810,7 @@ void Cec_ManSatSolveCSat( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t *
{
Vec_Str_t * vStatus;
Vec_Int_t * vPat = Vec_IntAlloc( 1000 );
- Vec_Int_t * vCexStore = Cbs_ManSolveMiterNc( pAig, pPars->nBTLimit, &vStatus, 0 );
+ Vec_Int_t * vCexStore = Cbs_ManSolveMiterNc( pAig, pPars->nBTLimit, &vStatus, 0, 0 );
Gia_Obj_t * pObj;
int i, status, iStart = 0;
assert( Vec_StrSize(vStatus) == Gia_ManCoNum(pAig) );
diff --git a/src/proof/cec/cecSolveG.c b/src/proof/cec/cecSolveG.c
new file mode 100644
index 00000000..0bb68a7f
--- /dev/null
+++ b/src/proof/cec/cecSolveG.c
@@ -0,0 +1,641 @@
+/**CFile****************************************************************
+
+ FileName [cecSolve.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinational equivalence checking.]
+
+ Synopsis [Performs one round of SAT solving.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cecSolve.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cecInt.h"
+
+
+#define USE_GLUCOSE2
+
+#ifdef USE_GLUCOSE2
+
+#include "sat/glucose2/AbcGlucose2.h"
+
+#define sat_solver bmcg2_sat_solver
+#define sat_solver_start bmcg2_sat_solver_start
+#define sat_solver_stop bmcg2_sat_solver_stop
+#define sat_solver_addclause bmcg2_sat_solver_addclause
+#define sat_solver_add_and bmcg2_sat_solver_add_and
+#define sat_solver_add_xor bmcg2_sat_solver_add_xor
+#define sat_solver_addvar bmcg2_sat_solver_addvar
+#define sat_solver_reset bmcg2_sat_solver_reset
+#define sat_solver_set_conflict_budget bmcg2_sat_solver_set_conflict_budget
+#define sat_solver_conflictnum bmcg2_sat_solver_conflictnum
+#define sat_solver_solve bmcg2_sat_solver_solve
+#define sat_solver_read_cex_varvalue bmcg2_sat_solver_read_cex_varvalue
+#define sat_solver_read_cex bmcg2_sat_solver_read_cex
+#define sat_solver_jftr bmcg2_sat_solver_jftr
+#define sat_solver_set_jftr bmcg2_sat_solver_set_jftr
+#define sat_solver_set_var_fanin_lit bmcg2_sat_solver_set_var_fanin_lit
+#define sat_solver_start_new_round bmcg2_sat_solver_start_new_round
+#define sat_solver_mark_cone bmcg2_sat_solver_mark_cone
+//#define sat_solver_set_nvars bmcg2_sat_solver_set_nvars
+#define sat_solver_varnum bmcg2_sat_solver_varnum
+#else
+
+#include "sat/glucose/AbcGlucose.h"
+
+#define sat_solver bmcg_sat_solver
+#define sat_solver_start bmcg_sat_solver_start
+#define sat_solver_stop bmcg_sat_solver_stop
+#define sat_solver_addclause bmcg_sat_solver_addclause
+#define sat_solver_add_and bmcg_sat_solver_add_and
+#define sat_solver_add_xor bmcg_sat_solver_add_xor
+#define sat_solver_addvar bmcg_sat_solver_addvar
+#define sat_solver_reset bmcg_sat_solver_reset
+#define sat_solver_set_conflict_budget bmcg_sat_solver_set_conflict_budget
+#define sat_solver_conflictnum bmcg_sat_solver_conflictnum
+#define sat_solver_solve bmcg_sat_solver_solve
+#define sat_solver_read_cex_varvalue bmcg_sat_solver_read_cex_varvalue
+#define sat_solver_read_cex bmcg_sat_solver_read_cex
+#define sat_solver_jftr bmcg_sat_solver_jftr
+#define sat_solver_set_jftr bmcg_sat_solver_set_jftr
+#define sat_solver_set_var_fanin_lit bmcg_sat_solver_set_var_fanin_lit
+#define sat_solver_start_new_round bmcg_sat_solver_start_new_round
+#define sat_solver_mark_cone bmcg_sat_solver_mark_cone
+#define sat_solver_set_nvars bmcg_sat_solver_set_nvars
+
+#endif
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static inline int CecG_ObjSatNum( Cec_ManSat_t * p, Gia_Obj_t * pObj ) { return p->pSatVars[Gia_ObjId(p->pAig,pObj)]; }
+static inline void CecG_ObjSetSatNum( Cec_ManSat_t * p, Gia_Obj_t * pObj, int Num ) { p->pSatVars[Gia_ObjId(p->pAig,pObj)] = Num; }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Returns value of the SAT variable.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int CecG_ObjSatVarValue( Cec_ManSat_t * p, Gia_Obj_t * pObj )
+{
+ return sat_solver_read_cex_varvalue( p->pSat, CecG_ObjSatNum(p, pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Addes clauses to the solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void CecG_AddClausesMux( Cec_ManSat_t * p, Gia_Obj_t * pNode )
+{
+ Gia_Obj_t * pNodeI, * pNodeT, * pNodeE;
+ int pLits[4], RetValue, VarF, VarI, VarT, VarE, fCompT, fCompE;
+
+ assert( !Gia_IsComplement( pNode ) );
+ assert( Gia_ObjIsMuxType( pNode ) );
+ // get nodes (I = if, T = then, E = else)
+ pNodeI = Gia_ObjRecognizeMux( pNode, &pNodeT, &pNodeE );
+ // get the variable numbers
+ VarF = CecG_ObjSatNum(p,pNode);
+ VarI = CecG_ObjSatNum(p,pNodeI);
+ VarT = CecG_ObjSatNum(p,Gia_Regular(pNodeT));
+ VarE = CecG_ObjSatNum(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] = toLitCond(VarI, 1);
+ pLits[1] = toLitCond(VarT, 1^fCompT);
+ pLits[2] = toLitCond(VarF, 0);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( Gia_Regular(pNodeT)->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
+ }
+ RetValue = sat_solver_addclause( p->pSat, pLits, 3 );
+ assert( RetValue );
+ pLits[0] = toLitCond(VarI, 1);
+ pLits[1] = toLitCond(VarT, 0^fCompT);
+ pLits[2] = toLitCond(VarF, 1);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( Gia_Regular(pNodeT)->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
+ }
+ RetValue = sat_solver_addclause( p->pSat, pLits, 3 );
+ assert( RetValue );
+ pLits[0] = toLitCond(VarI, 0);
+ pLits[1] = toLitCond(VarE, 1^fCompE);
+ pLits[2] = toLitCond(VarF, 0);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
+ }
+ RetValue = sat_solver_addclause( p->pSat, pLits, 3 );
+ assert( RetValue );
+ pLits[0] = toLitCond(VarI, 0);
+ pLits[1] = toLitCond(VarE, 0^fCompE);
+ pLits[2] = toLitCond(VarF, 1);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
+ }
+ RetValue = sat_solver_addclause( p->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] = toLitCond(VarT, 0^fCompT);
+ pLits[1] = toLitCond(VarE, 0^fCompE);
+ pLits[2] = toLitCond(VarF, 1);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( Gia_Regular(pNodeT)->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
+ }
+ RetValue = sat_solver_addclause( p->pSat, pLits, 3 );
+ assert( RetValue );
+ pLits[0] = toLitCond(VarT, 1^fCompT);
+ pLits[1] = toLitCond(VarE, 1^fCompE);
+ pLits[2] = toLitCond(VarF, 0);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( Gia_Regular(pNodeT)->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
+ }
+ RetValue = sat_solver_addclause( p->pSat, pLits, 3 );
+ assert( RetValue );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Addes clauses to the solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void CecG_AddClausesSuper( Cec_ManSat_t * p, Gia_Obj_t * pNode, Vec_Ptr_t * vSuper )
+{
+ 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] = toLitCond(CecG_ObjSatNum(p,Gia_Regular(pFanin)), Gia_IsComplement(pFanin));
+ pLits[1] = toLitCond(CecG_ObjSatNum(p,pNode), 1);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( Gia_Regular(pFanin)->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( pNode->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ }
+ RetValue = sat_solver_addclause( p->pSat, pLits, 2 );
+ assert( RetValue );
+ }
+ // add A & B => C or !A + !B + C
+ Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i )
+ {
+ pLits[i] = toLitCond(CecG_ObjSatNum(p,Gia_Regular(pFanin)), !Gia_IsComplement(pFanin));
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( Gia_Regular(pFanin)->fPhase ) pLits[i] = lit_neg( pLits[i] );
+ }
+ }
+ pLits[nLits-1] = toLitCond(CecG_ObjSatNum(p,pNode), 0);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pNode->fPhase ) pLits[nLits-1] = lit_neg( pLits[nLits-1] );
+ }
+ RetValue = sat_solver_addclause( p->pSat, pLits, nLits );
+ assert( RetValue );
+ ABC_FREE( pLits );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects the supergate.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void CecG_CollectSuper_rec( Gia_Obj_t * pObj, Vec_Ptr_t * vSuper, int fFirst, int fUseMuxes, int fUseSuper )
+{
+ // 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 && Gia_ObjIsMuxType(pObj)) )
+ {
+ Vec_PtrPushUnique( vSuper, pObj );
+ return;
+ }
+ if( !fUseSuper ){
+ Vec_PtrPushUnique( vSuper, Gia_ObjChild0(pObj) );
+ Vec_PtrPushUnique( vSuper, Gia_ObjChild1(pObj) );
+ return ;
+ }
+ // go through the branches
+ CecG_CollectSuper_rec( Gia_ObjChild0(pObj), vSuper, 0, fUseMuxes, fUseSuper );
+ CecG_CollectSuper_rec( Gia_ObjChild1(pObj), vSuper, 0, fUseMuxes, fUseSuper );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects the supergate.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void CecG_CollectSuper( Gia_Obj_t * pObj, int fUseMuxes, int fUseSuper, Vec_Ptr_t * vSuper )
+{
+ assert( !Gia_IsComplement(pObj) );
+ assert( !Gia_ObjIsCi(pObj) );
+ Vec_PtrClear( vSuper );
+ CecG_CollectSuper_rec( pObj, vSuper, 1, fUseMuxes, fUseSuper );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Updates the solver clause database.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void CecG_ObjAddToFrontier( Cec_ManSat_t * p, Gia_Obj_t * pObj, Vec_Ptr_t * vFrontier )
+{
+ assert( !Gia_IsComplement(pObj) );
+ if ( CecG_ObjSatNum(p,pObj) )
+ return;
+ assert( CecG_ObjSatNum(p,pObj) == 0 );
+ if ( Gia_ObjIsConst0(pObj) )
+ return;
+ Vec_PtrPush( p->vUsedNodes, pObj );
+ CecG_ObjSetSatNum( p, pObj, sat_solver_addvar( p->pSat ) );
+ if ( Gia_ObjIsAnd(pObj) )
+ Vec_PtrPush( vFrontier, pObj );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Updates the solver clause database.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void CecG_CnfNodeAddToSolver( Cec_ManSat_t * p, Gia_Obj_t * pObj )
+{
+ Vec_Ptr_t * vFrontier;
+ Gia_Obj_t * pNode, * pFanin;
+ int i, k, fUseMuxes = 0 == p->pPars->SolverType;
+ // quit if CNF is ready
+ if ( CecG_ObjSatNum(p,pObj) )
+ return;
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ Vec_PtrPush( p->vUsedNodes, pObj );
+ CecG_ObjSetSatNum( p, pObj, sat_solver_addvar( p->pSat ) );
+ return;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+
+ // start the frontier
+ vFrontier = Vec_PtrAlloc( 100 );
+ CecG_ObjAddToFrontier( p, pObj, vFrontier );
+ // explore nodes in the frontier
+ Vec_PtrForEachEntry( Gia_Obj_t *, vFrontier, pNode, i )
+ {
+ // create the supergate
+ assert( CecG_ObjSatNum(p,pNode) );
+ if ( fUseMuxes && Gia_ObjIsMuxType(pNode) )
+ {
+ 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 )
+ CecG_ObjAddToFrontier( p, Gia_Regular(pFanin), vFrontier );
+ CecG_AddClausesMux( p, pNode );
+ }
+ else
+ {
+ CecG_CollectSuper( pNode, fUseMuxes, 0 == p->pPars->SolverType, p->vFanins );
+ Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k )
+ CecG_ObjAddToFrontier( p, Gia_Regular(pFanin), vFrontier );
+
+ if( p->pPars->SolverType < 2 )
+ CecG_AddClausesSuper( p, pNode, p->vFanins );
+ }
+ assert( Vec_PtrSize(p->vFanins) > 1 );
+ }
+ if( p->pPars->SolverType )
+ Vec_PtrForEachEntry( Gia_Obj_t *, vFrontier, pNode, i ){
+ int var = CecG_ObjSatNum( p, pNode );
+ int Lit0 = Abc_Var2Lit( CecG_ObjSatNum( p, Gia_ObjFanin0(pNode) ), Gia_ObjFaninC0(pNode) );
+ int Lit1 = Abc_Var2Lit( CecG_ObjSatNum( p, Gia_ObjFanin1(pNode) ), Gia_ObjFaninC1(pNode) );
+ assert(Gia_ObjIsAnd(pNode));
+ if ( (Lit0 > Lit1) ^ Gia_ObjIsXor(pNode) )
+ Lit1 ^= Lit0, Lit0 ^= Lit1, Lit1 ^= Lit0;
+ sat_solver_set_var_fanin_lit( p->pSat, var, Lit0, Lit1 );
+ }
+ Vec_PtrFree( vFrontier );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Recycles the SAT solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void CecG_ManSatSolverRecycle( Cec_ManSat_t * p )
+{
+ int Lit;
+ if ( p->pSat )
+ {
+ Gia_Obj_t * pObj;
+ int i;
+ Vec_PtrForEachEntry( Gia_Obj_t *, p->vUsedNodes, pObj, i )
+ CecG_ObjSetSatNum( p, pObj, 0 );
+ Vec_PtrClear( p->vUsedNodes );
+// memset( p->pSatVars, 0, sizeof(int) * Gia_ManObjNumMax(p->pAigTotal) );
+ sat_solver_stop( p->pSat );
+ }
+ p->pSat = sat_solver_start();
+ assert( 0 <= p->pPars->SolverType && p->pPars->SolverType <= 2 );
+ sat_solver_set_jftr( p->pSat, p->pPars->SolverType );
+ //sat_solver_setnvars( p->pSat, 1000 ); // minisat only
+ //p->pSat->factors = ABC_CALLOC( double, p->pSat->cap );
+ // var 0 is not used
+ // var 1 is reserved for const0 node - add the clause
+
+// p->nSatVars = 0;
+ CecG_ObjSetSatNum( p, Gia_ManConst0(p->pAig), sat_solver_addvar( p->pSat ) );
+ Lit = toLitCond( CecG_ObjSatNum( p, Gia_ManConst0(p->pAig) ), 1 );
+ sat_solver_addclause( p->pSat, &Lit, 1 );
+// if ( p->pPars->fPolarFlip ) // no need to normalize const0 node (bug fix by SS on 9/17/2012)
+// Lit = lit_neg( Lit );
+
+ p->nRecycles++;
+ p->nCallsSince = 0;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Runs equivalence test for the two nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int CecG_ManSatCheckNode( Cec_ManSat_t * p, Gia_Obj_t * pObj )
+{
+ Gia_Obj_t * pObjR = Gia_Regular(pObj);
+ int nBTLimit = p->pPars->nBTLimit;
+ int Lit, RetValue, nConflicts;
+ abctime clk = Abc_Clock();
+
+ if ( pObj == Gia_ManConst0(p->pAig) )
+ return 1;
+ if ( pObj == Gia_ManConst1(p->pAig) )
+ {
+ assert( 0 );
+ return 0;
+ }
+
+ p->nCallsSince++; // experiment with this!!!
+ p->nSatTotal++;
+
+ // check if SAT solver needs recycling
+ if ( p->pSat == NULL ||
+ (p->pPars->nSatVarMax &&
+ sat_solver_varnum(p->pSat) > p->pPars->nSatVarMax &&
+ p->nCallsSince > p->pPars->nCallsRecycle) )
+ CecG_ManSatSolverRecycle( p );
+
+ // if the nodes do not have SAT variables, allocate them
+ CecG_CnfNodeAddToSolver( p, pObjR );
+
+ if( p->pPars->SolverType ){
+ sat_solver_start_new_round( p->pSat );
+ sat_solver_mark_cone( p->pSat, CecG_ObjSatNum(p, pObjR) );
+ }
+
+ // propage unit clauses // minisat only
+ //if ( p->pSat->qtail != p->pSat->qhead )
+ //{
+ // status = sat_solver_simplify(p->pSat);
+ // assert( status != 0 );
+ // assert( p->pSat->qtail == p->pSat->qhead );
+ //}
+
+ // solve under assumptions
+ // A = 1; B = 0 OR A = 1; B = 1
+ Lit = toLitCond( CecG_ObjSatNum(p,pObjR), Gia_IsComplement(pObj) );
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pObjR->fPhase ) Lit = lit_neg( Lit );
+ }
+ nConflicts = sat_solver_conflictnum(p->pSat);
+
+ sat_solver_set_conflict_budget( p->pSat, nBTLimit );
+ RetValue = sat_solver_solve( p->pSat, &Lit, 1 );
+ //RetValue = sat_solver_solve( p->pSat, &Lit, &Lit + 1,
+ // (ABC_INT64_T)nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
+ if ( RetValue == l_False )
+ {
+p->timeSatUnsat += Abc_Clock() - clk;
+ Lit = lit_neg( Lit );
+ RetValue = sat_solver_addclause( p->pSat, &Lit, 1 );
+ assert( RetValue );
+ p->nSatUnsat++;
+ p->nConfUnsat += sat_solver_conflictnum(p->pSat) - nConflicts;
+//Abc_Print( 1, "UNSAT after %d conflicts\n", sat_solver_conflictnum(p->pSat) - nConflicts );
+ return 1;
+ }
+ else if ( RetValue == l_True )
+ {
+p->timeSatSat += Abc_Clock() - clk;
+ p->nSatSat++;
+ p->nConfSat += sat_solver_conflictnum(p->pSat) - nConflicts;
+//Abc_Print( 1, "SAT after %d conflicts\n", sat_solver_conflictnum(p->pSat) - nConflicts );
+ return 0;
+ }
+ else // if ( RetValue == l_Undef )
+ {
+p->timeSatUndec += Abc_Clock() - clk;
+ p->nSatUndec++;
+ p->nConfUndec += sat_solver_conflictnum(p->pSat) - nConflicts;
+//Abc_Print( 1, "UNDEC after %d conflicts\n", sat_solver_conflictnum(p->pSat) - nConflicts );
+ return -1;
+ }
+}
+
+void CecG_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPars, int f0Proved )
+{
+ Bar_Progress_t * pProgress = NULL;
+ Cec_ManSat_t * p;
+ Gia_Obj_t * pObj;
+ int i, status;
+ abctime clk = Abc_Clock(), clk2;
+ Vec_PtrFreeP( &pAig->vSeqModelVec );
+ if( pPars->SolverType )
+ pPars->fPolarFlip = 0;
+ // reset the manager
+ if ( pPat )
+ {
+ pPat->iStart = Vec_StrSize(pPat->vStorage);
+ pPat->nPats = 0;
+ pPat->nPatLits = 0;
+ pPat->nPatLitsMin = 0;
+ }
+ Gia_ManSetPhase( pAig );
+ Gia_ManLevelNum( pAig );
+ Gia_ManIncrementTravId( pAig );
+ p = Cec_ManSatCreate( pAig, pPars );
+ pProgress = Bar_ProgressStart( stdout, Gia_ManPoNum(pAig) );
+ Gia_ManForEachCo( pAig, pObj, i )
+ {
+ if ( Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) )
+ {
+ status = !Gia_ObjFaninC0(pObj);
+ pObj->fMark0 = (status == 0);
+ pObj->fMark1 = (status == 1);
+ continue;
+ }
+ Bar_ProgressUpdate( pProgress, i, "SAT..." );
+clk2 = Abc_Clock();
+ status = CecG_ManSatCheckNode( p, Gia_ObjChild0(pObj) );
+ pObj->fMark0 = (status == 0);
+ pObj->fMark1 = (status == 1);
+
+ if ( f0Proved && status == 1 )
+ Gia_ManPatchCoDriver( pAig, i, 0 );
+/*
+ if ( status == -1 )
+ {
+ Gia_Man_t * pTemp = Gia_ManDupDfsCone( pAig, pObj );
+ Gia_AigerWrite( pTemp, "gia_hard.aig", 0, 0, 0 );
+ Gia_ManStop( pTemp );
+ Abc_Print( 1, "Dumping hard cone into file \"%s\".\n", "gia_hard.aig" );
+ }
+*/
+ if ( status != 0 )
+ continue;
+ // save the pattern
+ //if ( pPat )
+ //{
+ // abctime clk3 = Abc_Clock();
+ // Cec_ManPatSavePattern( pPat, p, pObj );
+ // pPat->timeTotalSave += Abc_Clock() - clk3;
+ //}
+ // quit if one of them is solved
+ if ( pPars->fCheckMiter )
+ break;
+ }
+ p->timeTotal = Abc_Clock() - clk;
+ printf("Recycles %d\n", p->nRecycles);
+ Bar_ProgressStop( pProgress );
+ if ( pPars->fVerbose )
+ Cec_ManSatPrintStats( p );
+ if( p->pSat )
+ sat_solver_stop( p->pSat );
+ p->pSat = NULL;
+ Cec_ManSatStop( p );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/cec/cecSweep.c b/src/proof/cec/cecSweep.c
index 55f2219f..abe77960 100644
--- a/src/proof/cec/cecSweep.c
+++ b/src/proof/cec/cecSweep.c
@@ -289,6 +289,9 @@ p->timeSim += Abc_Clock() - clk;
p->nAllFailed++;
}
}
+ p->nAllProvedS += p->nAllProved;
+ p->nAllDisprovedS += p->nAllDisproved;
+ p->nAllFailedS += p->nAllFailed;
return 0;
}
diff --git a/src/proof/cec/module.make b/src/proof/cec/module.make
index 86ec2677..23595f23 100644
--- a/src/proof/cec/module.make
+++ b/src/proof/cec/module.make
@@ -8,8 +8,11 @@ SRC += src/proof/cec/cecCec.c \
src/proof/cec/cecPat.c \
src/proof/cec/cecSat.c \
src/proof/cec/cecSatG.c \
+ src/proof/cec/cecSatG2.c \
src/proof/cec/cecSeq.c \
+ src/proof/cec/cecSim.c \
src/proof/cec/cecSolve.c \
+ src/proof/cec/cecSolveG.c \
src/proof/cec/cecSplit.c \
src/proof/cec/cecSynth.c \
src/proof/cec/cecSweep.c
diff --git a/src/proof/dch/dch.h b/src/proof/dch/dch.h
index 5d644643..07f6a1d2 100644
--- a/src/proof/dch/dch.h
+++ b/src/proof/dch/dch.h
@@ -52,6 +52,7 @@ struct Dch_Pars_t_
int fPower; // uses power-aware rewriting
int fUseGia; // uses GIA package
int fUseCSat; // uses circuit-based solver
+ int fUseNew; // uses new implementation
int fLightSynth; // uses lighter version of synthesis
int fSkipRedSupp; // skip choices with redundant support vars
int fVerbose; // verbose stats
diff --git a/src/proof/dch/dchCore.c b/src/proof/dch/dchCore.c
index 0da65bee..19907f00 100644
--- a/src/proof/dch/dchCore.c
+++ b/src/proof/dch/dchCore.c
@@ -90,7 +90,7 @@ Aig_Man_t * Dch_ComputeChoices( Aig_Man_t * pAig, Dch_Pars_t * pPars )
{
Dch_Man_t * p;
Aig_Man_t * pResult;
- abctime clk, clkTotal = Abc_Clock();
+ abctime clk, clk2 = Abc_Clock(), clkTotal = Abc_Clock();
// reset random numbers
Aig_ManRandom(1);
// start the choicing manager
@@ -106,6 +106,8 @@ p->timeSimInit = Abc_Clock() - clk;
// free memory ahead of time
p->timeTotal = Abc_Clock() - clkTotal;
Dch_ManStop( p );
+ if ( pPars->fVerbose )
+ Abc_PrintTime( 1, "Old choice computation time", Abc_Clock() - clk2 );
// create choices
ABC_FREE( pAig->pTable );
pResult = Dch_DeriveChoiceAig( pAig, pPars->fSkipRedSupp );
diff --git a/src/proof/dch/dchSimSat.c b/src/proof/dch/dchSimSat.c
index d3dbbe16..bbab0529 100644
--- a/src/proof/dch/dchSimSat.c
+++ b/src/proof/dch/dchSimSat.c
@@ -91,8 +91,8 @@ void Dch_ManCollectTfoCands( Dch_Man_t * p, Aig_Obj_t * pObj1, Aig_Obj_t * pObj2
Aig_ObjSetTravIdCurrent( p->pAigTotal, Aig_ManConst1(p->pAigTotal) );
Dch_ManCollectTfoCands_rec( p, pObj1 );
Dch_ManCollectTfoCands_rec( p, pObj2 );
- Vec_PtrSort( p->vSimRoots, (int (*)(void))Aig_ObjCompareIdIncrease );
- Vec_PtrSort( p->vSimClasses, (int (*)(void))Aig_ObjCompareIdIncrease );
+ Vec_PtrSort( p->vSimRoots, (int (*)(const void *, const void *))Aig_ObjCompareIdIncrease );
+ Vec_PtrSort( p->vSimClasses, (int (*)(const void *, const void *))Aig_ObjCompareIdIncrease );
Vec_PtrForEachEntry( Aig_Obj_t *, p->vSimClasses, pObj, i )
pObj->fMarkA = 0;
}
diff --git a/src/proof/fra/fraSec.c b/src/proof/fra/fraSec.c
index 7e382fc8..eadd06c9 100644
--- a/src/proof/fra/fraSec.c
+++ b/src/proof/fra/fraSec.c
@@ -20,6 +20,7 @@
#include "fra.h"
#include "aig/ioa/ioa.h"
+#include "aig/gia/giaAig.h"
#include "proof/int/int.h"
#include "proof/ssw/ssw.h"
#include "aig/saig/saig.h"
@@ -92,6 +93,28 @@ void Fra_SecSetDefaultParams( Fra_Sec_t * p )
SeeAlso []
***********************************************************************/
+Aig_Man_t * Fra_FraigEquivence2( Aig_Man_t * pAig, int nConfs, int fVerbose )
+{
+ extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose );
+ Gia_Man_t * pGia = Gia_ManFromAig( pAig );
+ Gia_Man_t * pGiaNew = Cec4_ManSimulateTest3( pGia, nConfs, 0 );
+ Aig_Man_t * pAigNew = Gia_ManToAig( pGiaNew, 0 );
+ Gia_ManStop( pGiaNew );
+ Gia_ManStop( pGia );
+ return pAigNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Fra_FraigSec( Aig_Man_t * p, Fra_Sec_t * pParSec, Aig_Man_t ** ppResult )
{
Ssw_Pars_t Pars2, * pPars2 = &Pars2;
@@ -267,6 +290,7 @@ ABC_PRT( "Time", Abc_Clock() - clk );
{
clk = Abc_Clock();
pNew = Fra_FraigEquivence( pTemp = pNew, 100, 0 );
+ //pNew = Fra_FraigEquivence2( pTemp = pNew, 100, 0 );
Aig_ManStop( pTemp );
if ( pParSec->fVerbose )
{
diff --git a/src/proof/int/int.h b/src/proof/int/int.h
index 906d8aaf..3dc8490d 100644
--- a/src/proof/int/int.h
+++ b/src/proof/int/int.h
@@ -24,7 +24,7 @@
/*
The interpolation algorithm implemented here was introduced in the paper:
- K. L. McMillan. Interpolation and SAT-based model checking. CAV’03, pp. 1-13.
+ K. L. McMillan. Interpolation and SAT-based model checking. CAV 03, pp. 1-13.
*/
////////////////////////////////////////////////////////////////////////
diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c
index f71569a3..d77fd4e1 100644
--- a/src/proof/pdr/pdrCore.c
+++ b/src/proof/pdr/pdrCore.c
@@ -157,7 +157,7 @@ int Pdr_ManPushClauses( Pdr_Man_t * p )
assert( p->iUseFrame > 0 );
Vec_VecForEachLevelStartStop( p->vClauses, vArrayK, k, iStartFrame, kMax )
{
- Vec_PtrSort( vArrayK, (int (*)(void))Pdr_SetCompare );
+ Vec_PtrSort( vArrayK, (int (*)(const void *, const void *))Pdr_SetCompare );
vArrayK1 = Vec_VecEntry( p->vClauses, k+1 );
Vec_PtrForEachEntry( Pdr_Set_t *, vArrayK, pCubeK, j )
{
@@ -216,7 +216,7 @@ int Pdr_ManPushClauses( Pdr_Man_t * p )
// clean up the last one
vArrayK = Vec_VecEntry( p->vClauses, kMax );
- Vec_PtrSort( vArrayK, (int (*)(void))Pdr_SetCompare );
+ Vec_PtrSort( vArrayK, (int (*)(const void *, const void *))Pdr_SetCompare );
Vec_PtrForEachEntry( Pdr_Set_t *, vArrayK, pCubeK, j )
{
// remove cubes in the same frame that are contained by pCubeK
diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c
index f4f2c8c8..9ca72ba6 100644
--- a/src/proof/pdr/pdrIncr.c
+++ b/src/proof/pdr/pdrIncr.c
@@ -47,7 +47,7 @@ Vec_Ptr_t * IPdr_ManPushClausesK( Pdr_Man_t * p, int k )
assert( Vec_VecSize(p->vClauses) == k + 1 );
vArrayK = Vec_VecEntry( p->vClauses, k );
- Vec_PtrSort( vArrayK, (int (*)(void))Pdr_SetCompare );
+ Vec_PtrSort( vArrayK, (int (*)(const void *, const void *))Pdr_SetCompare );
vArrayK1 = Vec_PtrAlloc( 100 );
Vec_PtrForEachEntry( Pdr_Set_t *, vArrayK, pCubeK, j )
{
@@ -117,7 +117,7 @@ void IPdr_ManPrintClauses( Vec_Vec_t * vClauses, int kStart, int nRegs )
int i, k, Counter = 0;
Vec_VecForEachLevelStart( vClauses, vArrayK, k, kStart )
{
- Vec_PtrSort( vArrayK, (int (*)(void))Pdr_SetCompare );
+ Vec_PtrSort( vArrayK, (int (*)(const void *, const void *))Pdr_SetCompare );
Vec_PtrForEachEntry( Pdr_Set_t *, vArrayK, pCube, i )
{
Abc_Print( 1, "Frame[%4d]Cube[%4d] = ", k, Counter++ );
diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c
index ba4f0448..ae61ce2c 100644
--- a/src/proof/pdr/pdrInv.c
+++ b/src/proof/pdr/pdrInv.c
@@ -248,7 +248,7 @@ void Pdr_ManPrintClauses( Pdr_Man_t * p, int kStart )
int i, k, Counter = 0;
Vec_VecForEachLevelStart( p->vClauses, vArrayK, k, kStart )
{
- Vec_PtrSort( vArrayK, (int (*)(void))Pdr_SetCompare );
+ Vec_PtrSort( vArrayK, (int (*)(const void *, const void *))Pdr_SetCompare );
Vec_PtrForEachEntry( Pdr_Set_t *, vArrayK, pCube, i )
{
Abc_Print( 1, "C=%4d. F=%4d ", Counter++, k );
@@ -370,7 +370,7 @@ void Pdr_ManDumpClauses( Pdr_Man_t * p, char * pFileName, int fProved )
vCubes = Pdr_ManCollectCubes( p, kStart );
else
vCubes = Vec_PtrDup( p->vInfCubes );
- Vec_PtrSort( vCubes, (int (*)(void))Pdr_SetCompare );
+ Vec_PtrSort( vCubes, (int (*)(const void *, const void *))Pdr_SetCompare );
// Pdr_ManDumpAig( p->pAig, vCubes );
// count cubes
Count = 0;
@@ -446,7 +446,7 @@ Vec_Str_t * Pdr_ManDumpString( Pdr_Man_t * p )
vCubes = Pdr_ManCollectCubes( p, kStart );
else
vCubes = Vec_PtrDup( p->vInfCubes );
- Vec_PtrSort( vCubes, (int (*)(void))Pdr_SetCompare );
+ Vec_PtrSort( vCubes, (int (*)(const void *, const void *))Pdr_SetCompare );
// collect variable appearances
vFlopCounts = p->pPars->fUseSupp ? Pdr_ManCountFlops( p, vCubes ) : NULL;
// output cubes
diff --git a/src/sat/bsat/satSolver.h b/src/sat/bsat/satSolver.h
index f4126567..53f3ebe2 100644
--- a/src/sat/bsat/satSolver.h
+++ b/src/sat/bsat/satSolver.h
@@ -292,6 +292,24 @@ static inline int sat_solver_final(sat_solver* s, int ** ppArray)
return s->conf_final.size;
}
+static inline void sat_solver_randomize( sat_solver * pSat, int iVar, int nVars )
+{
+ int i, nPols = 0, * pVars = ABC_ALLOC( int, nVars );
+ for ( i = 0; i < nVars; i++ )
+ if ( Abc_Random(0) & 1 )
+ pVars[nPols++] = iVar + i;
+ sat_solver_set_polarity( pSat, pVars, nPols );
+ for ( i = 0; i < nVars; i++ )
+ pVars[i] = iVar + i;
+ for ( i = 0; i < nVars; i++ )
+ {
+ int j = Abc_Random(0) % nVars;
+ ABC_SWAP( int, pVars[i], pVars[j] );
+ }
+ sat_solver_set_var_activity( pSat, pVars, nVars );
+ ABC_FREE( pVars );
+}
+
static inline abctime sat_solver_set_runtime_limit(sat_solver* s, abctime Limit)
{
abctime nRuntimeLimit = s->nRuntimeLimit;
diff --git a/src/sat/glucose/AbcGlucose.cpp b/src/sat/glucose/AbcGlucose.cpp
index 247bc89a..ad595ab9 100644
--- a/src/sat/glucose/AbcGlucose.cpp
+++ b/src/sat/glucose/AbcGlucose.cpp
@@ -58,7 +58,7 @@ using namespace Gluco;
SeeAlso []
***********************************************************************/
-Gluco::SimpSolver * glucose_solver_start()
+SimpSolver * glucose_solver_start()
{
SimpSolver * S = new SimpSolver;
S->setIncrementalMode();
@@ -116,6 +116,11 @@ int glucose_solver_addvar(Gluco::SimpSolver* S)
return S->nVars() - 1;
}
+int * glucose_solver_read_cex(Gluco::SimpSolver* S )
+{
+ return S->getCex();
+}
+
int glucose_solver_read_cex_varvalue(Gluco::SimpSolver* S, int ivar)
{
return S->model[ivar] == l_True;
@@ -208,6 +213,10 @@ int bmcg_sat_solver_elim_varnum(bmcg_sat_solver* s)
return ((Gluco::SimpSolver*)s)->eliminated_vars;
}
+int * bmcg_sat_solver_read_cex(bmcg_sat_solver* s)
+{
+ return glucose_solver_read_cex((Gluco::SimpSolver*)s);
+}
int bmcg_sat_solver_read_cex_varvalue(bmcg_sat_solver* s, int ivar)
{
return glucose_solver_read_cex_varvalue((Gluco::SimpSolver*)s, ivar);
@@ -317,6 +326,64 @@ int bmcg_sat_solver_add_and( bmcg_sat_solver * s, int iVar, int iVar0, int iVar1
return 1;
}
+int bmcg_solver_add_xor( bmcg_sat_solver * pSat, int iVarA, int iVarB, int iVarC, int fCompl )
+{
+ int Lits[3];
+ int Cid;
+ assert( iVarA >= 0 && iVarB >= 0 && iVarC >= 0 );
+
+ Lits[0] = Abc_Var2Lit( iVarA, !fCompl );
+ Lits[1] = Abc_Var2Lit( iVarB, 1 );
+ Lits[2] = Abc_Var2Lit( iVarC, 1 );
+ Cid = bmcg_sat_solver_addclause( pSat, Lits, 3 );
+ assert( Cid );
+
+ Lits[0] = Abc_Var2Lit( iVarA, !fCompl );
+ Lits[1] = Abc_Var2Lit( iVarB, 0 );
+ Lits[2] = Abc_Var2Lit( iVarC, 0 );
+ Cid = bmcg_sat_solver_addclause( pSat, Lits, 3 );
+ assert( Cid );
+
+ Lits[0] = Abc_Var2Lit( iVarA, fCompl );
+ Lits[1] = Abc_Var2Lit( iVarB, 1 );
+ Lits[2] = Abc_Var2Lit( iVarC, 0 );
+ Cid = bmcg_sat_solver_addclause( pSat, Lits, 3 );
+ assert( Cid );
+
+ Lits[0] = Abc_Var2Lit( iVarA, fCompl );
+ Lits[1] = Abc_Var2Lit( iVarB, 0 );
+ Lits[2] = Abc_Var2Lit( iVarC, 1 );
+ Cid = bmcg_sat_solver_addclause( pSat, Lits, 3 );
+ assert( Cid );
+ return 4;
+}
+
+int bmcg_sat_solver_jftr(bmcg_sat_solver* s)
+{
+ return ((Gluco::SimpSolver*)s)->jftr;
+}
+
+void bmcg_sat_solver_set_jftr(bmcg_sat_solver* s, int jftr)
+{
+ ((Gluco::SimpSolver*)s)->jftr = jftr;
+}
+
+void bmcg_sat_solver_set_var_fanin_lit(bmcg_sat_solver* s, int var, int lit0, int lit1)
+{
+ ((Gluco::SimpSolver*)s)->sat_solver_set_var_fanin_lit(var, lit0, lit1);
+}
+
+void bmcg_sat_solver_start_new_round(bmcg_sat_solver* s)
+{
+ ((Gluco::SimpSolver*)s)->sat_solver_start_new_round();
+}
+
+void bmcg_sat_solver_mark_cone(bmcg_sat_solver* s, int var)
+{
+ ((Gluco::SimpSolver*)s)->sat_solver_mark_cone(var);
+}
+
+
#else
/**Function*************************************************************
@@ -330,7 +397,7 @@ int bmcg_sat_solver_add_and( bmcg_sat_solver * s, int iVar, int iVar0, int iVar1
SeeAlso []
***********************************************************************/
-Gluco::Solver * glucose_solver_start()
+Solver * glucose_solver_start()
{
Solver * S = new Solver;
S->setIncrementalMode();
@@ -342,6 +409,11 @@ void glucose_solver_stop(Gluco::Solver* S)
delete S;
}
+void glucose_solver_reset(Gluco::Solver* S)
+{
+ S->reset();
+}
+
int glucose_solver_addclause(Gluco::Solver* S, int * plits, int nlits)
{
vec<Lit> lits;
@@ -383,6 +455,11 @@ int glucose_solver_addvar(Gluco::Solver* S)
return S->nVars() - 1;
}
+int * glucose_solver_read_cex(Gluco::Solver* S )
+{
+ return S->getCex();
+}
+
int glucose_solver_read_cex_varvalue(Gluco::Solver* S, int ivar)
{
return S->model[ivar] == l_True;
@@ -413,6 +490,10 @@ void bmcg_sat_solver_stop(bmcg_sat_solver* s)
{
glucose_solver_stop((Gluco::Solver*)s);
}
+void bmcg_sat_solver_reset(bmcg_sat_solver* s)
+{
+ glucose_solver_reset((Gluco::Solver*)s);
+}
int bmcg_sat_solver_addclause(bmcg_sat_solver* s, int * plits, int nlits)
{
@@ -470,6 +551,11 @@ int bmcg_sat_solver_elim_varnum(bmcg_sat_solver* s)
// return ((Gluco::SimpSolver*)s)->eliminated_vars;
}
+int * bmcg_sat_solver_read_cex(bmcg_sat_solver* s)
+{
+ return glucose_solver_read_cex((Gluco::Solver*)s);
+}
+
int bmcg_sat_solver_read_cex_varvalue(bmcg_sat_solver* s, int ivar)
{
return glucose_solver_read_cex_varvalue((Gluco::Solver*)s, ivar);
@@ -556,6 +642,86 @@ int bmcg_sat_solver_minimize_assumptions( bmcg_sat_solver * s, int * plits, int
return nresL + nresR;
}
+int bmcg_sat_solver_add_and( bmcg_sat_solver * s, int iVar, int iVar0, int iVar1, int fCompl0, int fCompl1, int fCompl )
+{
+ int Lits[3];
+
+ Lits[0] = Abc_Var2Lit( iVar, !fCompl );
+ Lits[1] = Abc_Var2Lit( iVar0, fCompl0 );
+ if ( !bmcg_sat_solver_addclause( s, Lits, 2 ) )
+ return 0;
+
+ Lits[0] = Abc_Var2Lit( iVar, !fCompl );
+ Lits[1] = Abc_Var2Lit( iVar1, fCompl1 );
+ if ( !bmcg_sat_solver_addclause( s, Lits, 2 ) )
+ return 0;
+
+ Lits[0] = Abc_Var2Lit( iVar, fCompl );
+ Lits[1] = Abc_Var2Lit( iVar0, !fCompl0 );
+ Lits[2] = Abc_Var2Lit( iVar1, !fCompl1 );
+ if ( !bmcg_sat_solver_addclause( s, Lits, 3 ) )
+ return 0;
+
+ return 1;
+}
+
+int bmcg_solver_add_xor( bmcg_sat_solver * pSat, int iVarA, int iVarB, int iVarC, int fCompl )
+{
+ int Lits[3];
+ int Cid;
+ assert( iVarA >= 0 && iVarB >= 0 && iVarC >= 0 );
+
+ Lits[0] = Abc_Var2Lit( iVarA, !fCompl );
+ Lits[1] = Abc_Var2Lit( iVarB, 1 );
+ Lits[2] = Abc_Var2Lit( iVarC, 1 );
+ Cid = bmcg_sat_solver_addclause( pSat, Lits, 3 );
+ assert( Cid );
+
+ Lits[0] = Abc_Var2Lit( iVarA, !fCompl );
+ Lits[1] = Abc_Var2Lit( iVarB, 0 );
+ Lits[2] = Abc_Var2Lit( iVarC, 0 );
+ Cid = bmcg_sat_solver_addclause( pSat, Lits, 3 );
+ assert( Cid );
+
+ Lits[0] = Abc_Var2Lit( iVarA, fCompl );
+ Lits[1] = Abc_Var2Lit( iVarB, 1 );
+ Lits[2] = Abc_Var2Lit( iVarC, 0 );
+ Cid = bmcg_sat_solver_addclause( pSat, Lits, 3 );
+ assert( Cid );
+
+ Lits[0] = Abc_Var2Lit( iVarA, fCompl );
+ Lits[1] = Abc_Var2Lit( iVarB, 0 );
+ Lits[2] = Abc_Var2Lit( iVarC, 1 );
+ Cid = bmcg_sat_solver_addclause( pSat, Lits, 3 );
+ assert( Cid );
+ return 4;
+}
+
+int bmcg_sat_solver_jftr(bmcg_sat_solver* s)
+{
+ return ((Gluco::Solver*)s)->jftr;
+}
+
+void bmcg_sat_solver_set_jftr(bmcg_sat_solver* s, int jftr)
+{
+ ((Gluco::Solver*)s)->jftr = jftr;
+}
+
+void bmcg_sat_solver_set_var_fanin_lit(bmcg_sat_solver* s, int var, int lit0, int lit1)
+{
+ ((Gluco::Solver*)s)->sat_solver_set_var_fanin_lit(var, lit0, lit1);
+}
+
+void bmcg_sat_solver_start_new_round(bmcg_sat_solver* s)
+{
+ ((Gluco::Solver*)s)->sat_solver_start_new_round();
+}
+
+void bmcg_sat_solver_mark_cone(bmcg_sat_solver* s, int var)
+{
+ ((Gluco::Solver*)s)->sat_solver_mark_cone(var);
+}
+
#endif
diff --git a/src/sat/glucose/AbcGlucose.h b/src/sat/glucose/AbcGlucose.h
index 4489adc7..89a3652f 100644
--- a/src/sat/glucose/AbcGlucose.h
+++ b/src/sat/glucose/AbcGlucose.h
@@ -83,6 +83,7 @@ extern int bmcg_sat_solver_eliminate( bmcg_sat_solver* s, int turn
extern int bmcg_sat_solver_var_is_elim( bmcg_sat_solver* s, int v );
extern void bmcg_sat_solver_var_set_frozen( bmcg_sat_solver* s, int v, int freeze );
extern int bmcg_sat_solver_elim_varnum(bmcg_sat_solver* s);
+extern int * bmcg_sat_solver_read_cex( bmcg_sat_solver* s );
extern int bmcg_sat_solver_read_cex_varvalue( bmcg_sat_solver* s, int );
extern void bmcg_sat_solver_set_stop( bmcg_sat_solver* s, int * pstop );
extern abctime bmcg_sat_solver_set_runtime_limit( bmcg_sat_solver* s, abctime Limit );
@@ -93,9 +94,16 @@ extern int bmcg_sat_solver_learntnum( bmcg_sat_solver* s );
extern int bmcg_sat_solver_conflictnum( bmcg_sat_solver* s );
extern int bmcg_sat_solver_minimize_assumptions( bmcg_sat_solver * s, int * plits, int nlits, int pivot );
extern int bmcg_sat_solver_add_and( bmcg_sat_solver * s, int iVar, int iVar0, int iVar1, int fCompl0, int fCompl1, int fCompl );
+extern int bmcg_sat_solver_add_xor( bmcg_sat_solver * s, int iVarA, int iVarB, int iVarC, int fCompl );
extern int bmcg_sat_solver_quantify( bmcg_sat_solver * s[], Gia_Man_t * p, int iLit, int fHash, int(*pFuncCiToKeep)(void *, int), void * pData, Vec_Int_t * vDLits );
extern int bmcg_sat_solver_equiv_overlap_check( bmcg_sat_solver * s, Gia_Man_t * p, int iLit0, int iLit1, int fEquiv );
extern Vec_Str_t * bmcg_sat_solver_sop( Gia_Man_t * p, int CubeLimit );
+extern int bmcg_sat_solver_jftr( bmcg_sat_solver * s );
+extern void bmcg_sat_solver_set_jftr( bmcg_sat_solver * s, int jftr );
+extern void bmcg_sat_solver_set_var_fanin_lit( bmcg_sat_solver * s, int var, int lit0, int lit1 );
+extern void bmcg_sat_solver_start_new_round( bmcg_sat_solver * s );
+extern void bmcg_sat_solver_mark_cone( bmcg_sat_solver * s, int var );
+
extern void Glucose_SolveCnf( char * pFilename, Glucose_Pars * pPars );
extern int Glucose_SolveAig( Gia_Man_t * p, Glucose_Pars * pPars );
diff --git a/src/sat/glucose/Glucose.cpp b/src/sat/glucose/Glucose.cpp
index 0f2d2fce..c975c6ca 100644
--- a/src/sat/glucose/Glucose.cpp
+++ b/src/sat/glucose/Glucose.cpp
@@ -609,7 +609,7 @@ void Solver::analyze(CRef confl, vec<Lit>& out_learnt,vec<Lit>&selectors, int& o
for(i = 0;i<selectors.size();i++)
out_learnt.push(selectors[i]);
- out_learnt.copyTo(analyze_toclear);
+ out_learnt.copyTo_(analyze_toclear);
if (ccmin_mode == 2){
uint32_t abstract_level = 0;
for (i = 1; i < out_learnt.size(); i++)
diff --git a/src/sat/glucose/Solver.h b/src/sat/glucose/Solver.h
index df72660a..3d7d26ea 100644
--- a/src/sat/glucose/Solver.h
+++ b/src/sat/glucose/Solver.h
@@ -64,6 +64,12 @@ public:
vec<int> user_vec;
vec<Lit> user_lits;
+ // circuit-based solving
+ int jftr;
+ void sat_solver_set_var_fanin_lit(int, int, int);
+ void sat_solver_start_new_round();
+ void sat_solver_mark_cone(int);
+
// Problem specification:
//
Var newVar (bool polarity = true, bool dvar = true); // Add a new variable with parameters specifying variable mode.
@@ -116,6 +122,7 @@ public:
int nLearnts () const; // The current number of learnt clauses.
int nVars () const; // The current number of variables.
int nFreeVars () const;
+ int * getCex () const;
// Incremental mode
void setIncrementalMode();
@@ -418,6 +425,7 @@ inline int Solver::nClauses () const { return clauses.size(); }
inline int Solver::nLearnts () const { return learnts.size(); }
inline int Solver::nVars () const { return vardata.size(); }
inline int Solver::nFreeVars () const { return (int)dec_vars - (trail_lim.size() == 0 ? trail.size() : trail_lim[0]); }
+inline int * Solver::getCex () const { return NULL; }
inline void Solver::setPolarity (Var v, bool b) { polarity[v] = b; }
inline void Solver::setDecisionVar(Var v, bool b)
{
@@ -455,6 +463,10 @@ inline void Solver::toDimacs (const char* file, Lit p, Lit q, Lit r){ v
inline void Solver::addVar(Var v) { while (v >= nVars()) newVar(); }
+inline void Solver::sat_solver_set_var_fanin_lit(int var, int lit0, int lit1) {}
+inline void Solver::sat_solver_start_new_round() {}
+inline void Solver::sat_solver_mark_cone(int var) {}
+
//=================================================================================================
// Debug etc:
diff --git a/src/sat/glucose/SolverTypes.h b/src/sat/glucose/SolverTypes.h
index 4f2670a7..b29699fa 100644
--- a/src/sat/glucose/SolverTypes.h
+++ b/src/sat/glucose/SolverTypes.h
@@ -306,9 +306,15 @@ class OccLists
}
void clear(bool free = true){
- occs .clear(free);
- dirty .clear(free);
- dirties.clear(free);
+ if(free){
+ occs .clear(free);
+ dirty .clear(free);
+ dirties.clear(free);
+ } else {
+ occs .shrink_(occs .size());
+ dirty .shrink_(dirty .size());
+ dirties.shrink_(dirties.size());
+ }
}
};
diff --git a/src/sat/glucose/Vec.h b/src/sat/glucose/Vec.h
index da87af35..dd1bc20a 100644
--- a/src/sat/glucose/Vec.h
+++ b/src/sat/glucose/Vec.h
@@ -89,7 +89,8 @@ public:
T& operator [] (int index) { return data[index]; }
// Duplicatation (preferred instead):
- void copyTo(vec<T>& copy) const { copy.clear(); copy.growTo(sz); for (int i = 0; i < sz; i++) copy[i] = data[i]; }
+ void copyTo (vec<T>& copy) const { copy.clear(); copy.growTo(sz); for (int i = 0; i < sz; i++) copy[i] = data[i]; }
+ void copyTo_(vec<T>& copy) const { copy.shrink_(copy.size()); copy.growTo(sz); for (int i = 0; i < sz; i++) copy[i] = data[i]; }
void moveTo(vec<T>& dest) { dest.clear(true); dest.data = data; dest.sz = sz; dest.cap = cap; data = NULL; sz = 0; cap = 0; }
};
diff --git a/src/sat/glucose/stdint.h b/src/sat/glucose/stdint.h
deleted file mode 100644
index e36a136d..00000000
--- a/src/sat/glucose/stdint.h
+++ /dev/null
@@ -1,1628 +0,0 @@
-
-
-
-
-
-
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <meta charset="utf-8">
- <link rel="dns-prefetch" href="https://assets-cdn.github.com">
- <link rel="dns-prefetch" href="https://avatars0.githubusercontent.com">
- <link rel="dns-prefetch" href="https://avatars1.githubusercontent.com">
- <link rel="dns-prefetch" href="https://avatars2.githubusercontent.com">
- <link rel="dns-prefetch" href="https://avatars3.githubusercontent.com">
- <link rel="dns-prefetch" href="https://github-cloud.s3.amazonaws.com">
- <link rel="dns-prefetch" href="https://user-images.githubusercontent.com/">
-
-
-
- <link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/frameworks-7db951ed87f8f6cbd3a9e89c294e300cf23c1a83ad7ae64c70b8f99b21031340.css" integrity="sha256-fblR7Yf49svTqeicKU4wDPI8GoOteuZMcLj5myEDE0A=" media="all" rel="stylesheet" />
- <link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/github-4b2158409cc56f58dafd534ae676475b1bfe7cb057c415e2c5984e3c13b041e5.css" integrity="sha256-SyFYQJzFb1ja/VNK5nZHWxv+fLBXxBXixZhOPBOwQeU=" media="all" rel="stylesheet" />
-
-
- <link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/site-955690c4e09b2eeb3627ae6048471522eb98b42054150bd855ad4183db364816.css" integrity="sha256-lVaQxOCbLus2J65gSEcVIuuYtCBUFQvYVa1Bg9s2SBY=" media="all" rel="stylesheet" />
-
-
- <meta name="viewport" content="width=device-width">
-
- <title>gntp-send/stdint.h at master · mattn/gntp-send · GitHub</title>
- <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub">
- <link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub">
- <meta property="fb:app_id" content="1401488693436528">
-
-
- <meta content="https://avatars1.githubusercontent.com/u/10111?v=4&amp;s=400" property="og:image" /><meta content="GitHub" property="og:site_name" /><meta content="object" property="og:type" /><meta content="mattn/gntp-send" property="og:title" /><meta content="https://github.com/mattn/gntp-send" property="og:url" /><meta content="gntp-send - command line program that send to growl using GNTP protocol." property="og:description" />
-
- <link rel="assets" href="https://assets-cdn.github.com/">
-
- <meta name="pjax-timeout" content="1000">
-
- <meta name="request-id" content="C6BC:2817D:56F2228:8688546:59B04B65" data-pjax-transient>
-
-
- <meta name="selected-link" value="repo_source" data-pjax-transient>
-
- <meta name="google-site-verification" content="KT5gs8h0wvaagLKAVWq8bbeNwnZZK1r1XQysX3xurLU">
-<meta name="google-site-verification" content="ZzhVyEFwb7w3e0-uOTltm8Jsck2F5StVihD0exw2fsA">
- <meta name="google-analytics" content="UA-3769691-2">
-
-<meta content="collector.githubapp.com" name="octolytics-host" /><meta content="github" name="octolytics-app-id" /><meta content="https://collector.githubapp.com/github-external/browser_event" name="octolytics-event-url" /><meta content="C6BC:2817D:56F2228:8688546:59B04B65" name="octolytics-dimension-request_id" /><meta content="sea" name="octolytics-dimension-region_edge" /><meta content="iad" name="octolytics-dimension-region_render" />
-<meta content="/&lt;user-name&gt;/&lt;repo-name&gt;/blob/show" data-pjax-transient="true" name="analytics-location" />
-
-
-
-
- <meta class="js-ga-set" name="dimension1" content="Logged Out">
-
-
-
-
- <meta name="hostname" content="github.com">
- <meta name="user-login" content="">
-
- <meta name="expected-hostname" content="github.com">
- <meta name="js-proxy-site-detection-payload" content="YmNhNTY5Y2Y4MjdmNjMyMzc4ODViZmFkM2JmYmE5MDA4YWFkMWRmZWU5YzNjMGZmMmU3M2U2YTc1YWE0ZTEzYXx7InJlbW90ZV9hZGRyZXNzIjoiNzMuMjUyLjEzOC45MyIsInJlcXVlc3RfaWQiOiJDNkJDOjI4MTdEOjU2RjIyMjg6ODY4ODU0Njo1OUIwNEI2NSIsInRpbWVzdGFtcCI6MTUwNDcyNTg2NiwiaG9zdCI6ImdpdGh1Yi5jb20ifQ==">
-
-
- <meta name="html-safe-nonce" content="c7ac7dad53ebbb213745963c771e009cd0ec2414">
-
- <meta http-equiv="x-pjax-version" content="ef2b97c5ce9b111269ce538c13af797b">
-
-
- <link href="https://github.com/mattn/gntp-send/commits/master.atom" rel="alternate" title="Recent Commits to gntp-send:master" type="application/atom+xml">
-
- <meta name="description" content="gntp-send - command line program that send to growl using GNTP protocol.">
- <meta name="go-import" content="github.com/mattn/gntp-send git https://github.com/mattn/gntp-send.git">
-
- <meta content="10111" name="octolytics-dimension-user_id" /><meta content="mattn" name="octolytics-dimension-user_login" /><meta content="160637" name="octolytics-dimension-repository_id" /><meta content="mattn/gntp-send" name="octolytics-dimension-repository_nwo" /><meta content="true" name="octolytics-dimension-repository_public" /><meta content="false" name="octolytics-dimension-repository_is_fork" /><meta content="160637" name="octolytics-dimension-repository_network_root_id" /><meta content="mattn/gntp-send" name="octolytics-dimension-repository_network_root_nwo" /><meta content="false" name="octolytics-dimension-repository_explore_github_marketplace_ci_cta_shown" />
-
-
- <link rel="canonical" href="https://github.com/mattn/gntp-send/blob/master/include/msinttypes/stdint.h" data-pjax-transient>
-
-
- <meta name="browser-stats-url" content="https://api.github.com/_private/browser/stats">
-
- <meta name="browser-errors-url" content="https://api.github.com/_private/browser/errors">
-
- <link rel="mask-icon" href="https://assets-cdn.github.com/pinned-octocat.svg" color="#000000">
- <link rel="icon" type="image/x-icon" href="https://assets-cdn.github.com/favicon.ico">
-
-<meta name="theme-color" content="#1e2327">
-
-
-
- </head>
-
- <body class="logged-out env-production page-blob">
-
-
- <div class="position-relative js-header-wrapper ">
- <a href="#start-of-content" tabindex="1" class="px-2 py-4 show-on-focus js-skip-to-content">Skip to content</a>
- <div id="js-pjax-loader-bar" class="pjax-loader-bar"><div class="progress"></div></div>
-
-
-
-
-
-
-
- <header class="Header header-logged-out position-relative f4 py-3" role="banner">
- <div class="container-lg d-flex px-3">
- <div class="d-flex flex-justify-between flex-items-center">
- <a class="header-logo-invertocat my-0" href="https://github.com/" aria-label="Homepage" data-ga-click="(Logged out) Header, go to homepage, icon:logo-wordmark">
- <svg aria-hidden="true" class="octicon octicon-mark-github" height="32" version="1.1" viewBox="0 0 16 16" width="32"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"/></svg>
- </a>
-
- </div>
-
- <div class="HeaderMenu HeaderMenu--bright d-flex flex-justify-between flex-auto">
- <nav class="mt-0">
- <ul class="d-flex list-style-none">
- <li class="ml-2">
- <a href="/features" class="js-selected-navigation-item HeaderNavlink px-0 py-2 m-0" data-ga-click="Header, click, Nav menu - item:features" data-selected-links="/features /features/project-management /features/code-review /features/project-management /features/integrations /features">
- Features
-</a> </li>
- <li class="ml-4">
- <a href="/business" class="js-selected-navigation-item HeaderNavlink px-0 py-2 m-0" data-ga-click="Header, click, Nav menu - item:business" data-selected-links="/business /business/security /business/customers /business">
- Business
-</a> </li>
-
- <li class="ml-4">
- <a href="/explore" class="js-selected-navigation-item HeaderNavlink px-0 py-2 m-0" data-ga-click="Header, click, Nav menu - item:explore" data-selected-links="/explore /trending /trending/developers /integrations /integrations/feature/code /integrations/feature/collaborate /integrations/feature/ship showcases showcases_search showcases_landing /explore">
- Explore
-</a> </li>
-
- <li class="ml-4">
- <a href="/marketplace" class="js-selected-navigation-item HeaderNavlink px-0 py-2 m-0" data-ga-click="Header, click, Nav menu - item:marketplace" data-selected-links=" /marketplace">
- Marketplace
-</a> </li>
- <li class="ml-4">
- <a href="/pricing" class="js-selected-navigation-item HeaderNavlink px-0 py-2 m-0" data-ga-click="Header, click, Nav menu - item:pricing" data-selected-links="/pricing /pricing/developer /pricing/team /pricing/business-hosted /pricing/business-enterprise /pricing">
- Pricing
-</a> </li>
- </ul>
- </nav>
-
- <div class="d-flex">
- <div class="d-lg-flex flex-items-center mr-3">
- <div class="header-search scoped-search site-scoped-search js-site-search" role="search">
- <!-- '"` --><!-- </textarea></xmp> --></option></form><form accept-charset="UTF-8" action="/mattn/gntp-send/search" class="js-site-search-form" data-scoped-search-url="/mattn/gntp-send/search" data-unscoped-search-url="/search" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div>
- <label class="form-control header-search-wrapper js-chromeless-input-container">
- <a href="/mattn/gntp-send/blob/master/include/msinttypes/stdint.h" class="header-search-scope no-underline">This repository</a>
- <input type="text"
- class="form-control header-search-input js-site-search-focus js-site-search-field is-clearable"
- data-hotkey="s"
- name="q"
- value=""
- placeholder="Search"
- aria-label="Search this repository"
- data-unscoped-placeholder="Search GitHub"
- data-scoped-placeholder="Search"
- autocapitalize="off">
- <input type="hidden" class="js-site-search-type-field" name="type" >
- </label>
-</form></div>
-
- </div>
-
- <span class="d-inline-block">
- <div class="HeaderNavlink px-0 py-2 m-0">
- <a class="text-bold text-white no-underline" href="/login?return_to=%2Fmattn%2Fgntp-send%2Fblob%2Fmaster%2Finclude%2Fmsinttypes%2Fstdint.h" data-ga-click="(Logged out) Header, clicked Sign in, text:sign-in">Sign in</a>
- <span class="text-gray">or</span>
- <a class="text-bold text-white no-underline" href="/join?source=header-repo" data-ga-click="(Logged out) Header, clicked Sign up, text:sign-up">Sign up</a>
- </div>
- </span>
- </div>
- </div>
- </div>
-</header>
-
-
- </div>
-
- <div id="start-of-content" class="show-on-focus"></div>
-
- <div id="js-flash-container">
-</div>
-
-
-
- <div role="main">
- <div itemscope itemtype="http://schema.org/SoftwareSourceCode">
- <div id="js-repo-pjax-container" data-pjax-container>
-
-
-
-
-
-
- <div class="pagehead repohead instapaper_ignore readability-menu experiment-repo-nav">
- <div class="container repohead-details-container">
-
- <ul class="pagehead-actions">
- <li>
- <a href="/login?return_to=%2Fmattn%2Fgntp-send"
- class="btn btn-sm btn-with-count tooltipped tooltipped-n"
- aria-label="You must be signed in to watch a repository" rel="nofollow">
- <svg aria-hidden="true" class="octicon octicon-eye" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z"/></svg>
- Watch
- </a>
- <a class="social-count" href="/mattn/gntp-send/watchers"
- aria-label="7 users are watching this repository">
- 7
- </a>
-
- </li>
-
- <li>
- <a href="/login?return_to=%2Fmattn%2Fgntp-send"
- class="btn btn-sm btn-with-count tooltipped tooltipped-n"
- aria-label="You must be signed in to star a repository" rel="nofollow">
- <svg aria-hidden="true" class="octicon octicon-star" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74z"/></svg>
- Star
- </a>
-
- <a class="social-count js-social-count" href="/mattn/gntp-send/stargazers"
- aria-label="44 users starred this repository">
- 44
- </a>
-
- </li>
-
- <li>
- <a href="/login?return_to=%2Fmattn%2Fgntp-send"
- class="btn btn-sm btn-with-count tooltipped tooltipped-n"
- aria-label="You must be signed in to fork a repository" rel="nofollow">
- <svg aria-hidden="true" class="octicon octicon-repo-forked" height="16" version="1.1" viewBox="0 0 10 16" width="10"><path fill-rule="evenodd" d="M8 1a1.993 1.993 0 0 0-1 3.72V6L5 8 3 6V4.72A1.993 1.993 0 0 0 2 1a1.993 1.993 0 0 0-1 3.72V6.5l3 3v1.78A1.993 1.993 0 0 0 5 15a1.993 1.993 0 0 0 1-3.72V9.5l3-3V4.72A1.993 1.993 0 0 0 8 1zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3 10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3-10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"/></svg>
- Fork
- </a>
-
- <a href="/mattn/gntp-send/network" class="social-count"
- aria-label="45 users forked this repository">
- 45
- </a>
- </li>
-</ul>
-
- <h1 class="public ">
- <svg aria-hidden="true" class="octicon octicon-repo" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M4 9H3V8h1v1zm0-3H3v1h1V6zm0-2H3v1h1V4zm0-2H3v1h1V2zm8-1v12c0 .55-.45 1-1 1H6v2l-1.5-1.5L3 16v-2H1c-.55 0-1-.45-1-1V1c0-.55.45-1 1-1h10c.55 0 1 .45 1 1zm-1 10H1v2h2v-1h3v1h5v-2zm0-10H2v9h9V1z"/></svg>
- <span class="author" itemprop="author"><a href="/mattn" class="url fn" rel="author">mattn</a></span><!--
---><span class="path-divider">/</span><!--
---><strong itemprop="name"><a href="/mattn/gntp-send" data-pjax="#js-repo-pjax-container">gntp-send</a></strong>
-
-</h1>
-
- </div>
- <div class="container">
-
-<nav class="reponav js-repo-nav js-sidenav-container-pjax"
- itemscope
- itemtype="http://schema.org/BreadcrumbList"
- role="navigation"
- data-pjax="#js-repo-pjax-container">
-
- <span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
- <a href="/mattn/gntp-send" class="js-selected-navigation-item selected reponav-item" data-hotkey="g c" data-selected-links="repo_source repo_downloads repo_commits repo_releases repo_tags repo_branches /mattn/gntp-send" itemprop="url">
- <svg aria-hidden="true" class="octicon octicon-code" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M9.5 3L8 4.5 11.5 8 8 11.5 9.5 13 14 8 9.5 3zm-5 0L0 8l4.5 5L6 11.5 2.5 8 6 4.5 4.5 3z"/></svg>
- <span itemprop="name">Code</span>
- <meta itemprop="position" content="1">
-</a> </span>
-
- <span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
- <a href="/mattn/gntp-send/issues" class="js-selected-navigation-item reponav-item" data-hotkey="g i" data-selected-links="repo_issues repo_labels repo_milestones /mattn/gntp-send/issues" itemprop="url">
- <svg aria-hidden="true" class="octicon octicon-issue-opened" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"/></svg>
- <span itemprop="name">Issues</span>
- <span class="Counter">1</span>
- <meta itemprop="position" content="2">
-</a> </span>
-
- <span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
- <a href="/mattn/gntp-send/pulls" class="js-selected-navigation-item reponav-item" data-hotkey="g p" data-selected-links="repo_pulls /mattn/gntp-send/pulls" itemprop="url">
- <svg aria-hidden="true" class="octicon octicon-git-pull-request" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M11 11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3 3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993 1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98 1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"/></svg>
- <span itemprop="name">Pull requests</span>
- <span class="Counter">0</span>
- <meta itemprop="position" content="3">
-</a> </span>
-
- <a href="/mattn/gntp-send/projects" class="js-selected-navigation-item reponav-item" data-selected-links="repo_projects new_repo_project repo_project /mattn/gntp-send/projects">
- <svg aria-hidden="true" class="octicon octicon-project" height="16" version="1.1" viewBox="0 0 15 16" width="15"><path fill-rule="evenodd" d="M10 12h3V2h-3v10zm-4-2h3V2H6v8zm-4 4h3V2H2v12zm-1 1h13V1H1v14zM14 0H1a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h13a1 1 0 0 0 1-1V1a1 1 0 0 0-1-1z"/></svg>
- Projects
- <span class="Counter" >0</span>
-</a>
- <a href="/mattn/gntp-send/wiki" class="js-selected-navigation-item reponav-item" data-hotkey="g w" data-selected-links="repo_wiki /mattn/gntp-send/wiki">
- <svg aria-hidden="true" class="octicon octicon-book" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M3 5h4v1H3V5zm0 3h4V7H3v1zm0 2h4V9H3v1zm11-5h-4v1h4V5zm0 2h-4v1h4V7zm0 2h-4v1h4V9zm2-6v9c0 .55-.45 1-1 1H9.5l-1 1-1-1H2c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h5.5l1 1 1-1H15c.55 0 1 .45 1 1zm-8 .5L7.5 3H2v9h6V3.5zm7-.5H9.5l-.5.5V12h6V3z"/></svg>
- Wiki
-</a>
-
- <div class="reponav-dropdown js-menu-container">
- <button type="button" class="btn-link reponav-item reponav-dropdown js-menu-target " data-no-toggle aria-expanded="false" aria-haspopup="true">
- Insights
- <svg aria-hidden="true" class="octicon octicon-triangle-down v-align-middle text-gray" height="11" version="1.1" viewBox="0 0 12 16" width="8"><path fill-rule="evenodd" d="M0 5l6 6 6-6z"/></svg>
- </button>
- <div class="dropdown-menu-content js-menu-content">
- <div class="dropdown-menu dropdown-menu-sw">
- <a class="dropdown-item" href="/mattn/gntp-send/pulse" data-skip-pjax>
- <svg aria-hidden="true" class="octicon octicon-pulse" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M11.5 8L8.8 5.4 6.6 8.5 5.5 1.6 2.38 8H0v2h3.6l.9-1.8.9 5.4L9 8.5l1.6 1.5H14V8z"/></svg>
- Pulse
- </a>
- <a class="dropdown-item" href="/mattn/gntp-send/graphs" data-skip-pjax>
- <svg aria-hidden="true" class="octicon octicon-graph" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M16 14v1H0V0h1v14h15zM5 13H3V8h2v5zm4 0H7V3h2v10zm4 0h-2V6h2v7z"/></svg>
- Graphs
- </a>
- </div>
- </div>
- </div>
-</nav>
-
- </div>
- </div>
-
-<div class="container new-discussion-timeline experiment-repo-nav">
- <div class="repository-content">
-
-
- <a href="/mattn/gntp-send/blob/090b1276fb4a30601113551bed88c58329646818/include/msinttypes/stdint.h" class="d-none js-permalink-shortcut" data-hotkey="y">Permalink</a>
-
- <!-- blob contrib key: blob_contributors:v21:1fdd18f08c206edbaba4a5b47a34cc57 -->
-
- <div class="file-navigation js-zeroclipboard-container">
-
-<div class="select-menu branch-select-menu js-menu-container js-select-menu float-left">
- <button class=" btn btn-sm select-menu-button js-menu-target css-truncate" data-hotkey="w"
-
- type="button" aria-label="Switch branches or tags" aria-expanded="false" aria-haspopup="true">
- <i>Branch:</i>
- <span class="js-select-button css-truncate-target">master</span>
- </button>
-
- <div class="select-menu-modal-holder js-menu-content js-navigation-container" data-pjax>
-
- <div class="select-menu-modal">
- <div class="select-menu-header">
- <svg aria-label="Close" class="octicon octicon-x js-menu-close" height="16" role="img" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"/></svg>
- <span class="select-menu-title">Switch branches/tags</span>
- </div>
-
- <div class="select-menu-filters">
- <div class="select-menu-text-filter">
- <input type="text" aria-label="Filter branches/tags" id="context-commitish-filter-field" class="form-control js-filterable-field js-navigation-enable" placeholder="Filter branches/tags">
- </div>
- <div class="select-menu-tabs">
- <ul>
- <li class="select-menu-tab">
- <a href="#" data-tab-filter="branches" data-filter-placeholder="Filter branches/tags" class="js-select-menu-tab" role="tab">Branches</a>
- </li>
- <li class="select-menu-tab">
- <a href="#" data-tab-filter="tags" data-filter-placeholder="Find a tag…" class="js-select-menu-tab" role="tab">Tags</a>
- </li>
- </ul>
- </div>
- </div>
-
- <div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket" data-tab-filter="branches" role="menu">
-
- <div data-filterable-for="context-commitish-filter-field" data-filterable-type="substring">
-
-
- <a class="select-menu-item js-navigation-item js-navigation-open selected"
- href="/mattn/gntp-send/blob/master/include/msinttypes/stdint.h"
- data-name="master"
- data-skip-pjax="true"
- rel="nofollow">
- <svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
- <span class="select-menu-item-text css-truncate-target js-select-menu-filter-text">
- master
- </span>
- </a>
- </div>
-
- <div class="select-menu-no-results">Nothing to show</div>
- </div>
-
- <div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket" data-tab-filter="tags">
- <div data-filterable-for="context-commitish-filter-field" data-filterable-type="substring">
-
-
- <a class="select-menu-item js-navigation-item js-navigation-open "
- href="/mattn/gntp-send/tree/0.3.4/include/msinttypes/stdint.h"
- data-name="0.3.4"
- data-skip-pjax="true"
- rel="nofollow">
- <svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
- <span class="select-menu-item-text css-truncate-target" title="0.3.4">
- 0.3.4
- </span>
- </a>
- </div>
-
- <div class="select-menu-no-results">Nothing to show</div>
- </div>
-
- </div>
- </div>
-</div>
-
- <div class="BtnGroup float-right">
- <a href="/mattn/gntp-send/find/master"
- class="js-pjax-capture-input btn btn-sm BtnGroup-item"
- data-pjax
- data-hotkey="t">
- Find file
- </a>
- <button aria-label="Copy file path to clipboard" class="js-zeroclipboard btn btn-sm BtnGroup-item tooltipped tooltipped-s" data-copied-hint="Copied!" type="button">Copy path</button>
- </div>
- <div class="breadcrumb js-zeroclipboard-target">
- <span class="repo-root js-repo-root"><span class="js-path-segment"><a href="/mattn/gntp-send"><span>gntp-send</span></a></span></span><span class="separator">/</span><span class="js-path-segment"><a href="/mattn/gntp-send/tree/master/include"><span>include</span></a></span><span class="separator">/</span><span class="js-path-segment"><a href="/mattn/gntp-send/tree/master/include/msinttypes"><span>msinttypes</span></a></span><span class="separator">/</span><strong class="final-path">stdint.h</strong>
- </div>
- </div>
-
-
-
- <div class="commit-tease">
- <span class="float-right">
- <a class="commit-tease-sha" href="/mattn/gntp-send/commit/700f4a2d844001a6197d68440a9123f197be6096" data-pjax>
- 700f4a2
- </a>
- <relative-time datetime="2011-10-06T00:28:08Z">Oct 6, 2011</relative-time>
- </span>
- <div>
- <img alt="@mattn" class="avatar" height="20" src="https://avatars1.githubusercontent.com/u/10111?v=4&amp;s=40" width="20" />
- <a href="/mattn" class="user-mention" rel="author">mattn</a>
- <a href="/mattn/gntp-send/commit/700f4a2d844001a6197d68440a9123f197be6096" class="message" data-pjax="true" title="perfer include/src name.">perfer include/src name.</a>
- </div>
-
- <div class="commit-tease-contributors">
- <button type="button" class="btn-link muted-link contributors-toggle" data-facebox="#blob_contributors_box">
- <strong>1</strong>
- contributor
- </button>
-
- </div>
-
- <div id="blob_contributors_box" style="display:none">
- <h2 class="facebox-header" data-facebox-id="facebox-header">Users who have contributed to this file</h2>
- <ul class="facebox-user-list" data-facebox-id="facebox-description">
- <li class="facebox-user-list-item">
- <img alt="@mattn" height="24" src="https://avatars3.githubusercontent.com/u/10111?v=4&amp;s=48" width="24" />
- <a href="/mattn">mattn</a>
- </li>
- </ul>
- </div>
- </div>
-
-
- <div class="file">
- <div class="file-header">
- <div class="file-actions">
-
- <div class="BtnGroup">
- <a href="/mattn/gntp-send/raw/master/include/msinttypes/stdint.h" class="btn btn-sm BtnGroup-item" id="raw-url">Raw</a>
- <a href="/mattn/gntp-send/blame/master/include/msinttypes/stdint.h" class="btn btn-sm js-update-url-with-hash BtnGroup-item" data-hotkey="b">Blame</a>
- <a href="/mattn/gntp-send/commits/master/include/msinttypes/stdint.h" class="btn btn-sm BtnGroup-item" rel="nofollow">History</a>
- </div>
-
- <a class="btn-octicon tooltipped tooltipped-nw"
- href="https://desktop.github.com"
- aria-label="Open this file in GitHub Desktop"
- data-ga-click="Repository, open with desktop, type:windows">
- <svg aria-hidden="true" class="octicon octicon-device-desktop" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M15 2H1c-.55 0-1 .45-1 1v9c0 .55.45 1 1 1h5.34c-.25.61-.86 1.39-2.34 2h8c-1.48-.61-2.09-1.39-2.34-2H15c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1zm0 9H1V3h14v8z"/></svg>
- </a>
-
- <button type="button" class="btn-octicon disabled tooltipped tooltipped-nw"
- aria-label="You must be signed in to make or propose changes">
- <svg aria-hidden="true" class="octicon octicon-pencil" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M0 12v3h3l8-8-3-3-8 8zm3 2H1v-2h1v1h1v1zm10.3-9.3L12 6 9 3l1.3-1.3a.996.996 0 0 1 1.41 0l1.59 1.59c.39.39.39 1.02 0 1.41z"/></svg>
- </button>
- <button type="button" class="btn-octicon btn-octicon-danger disabled tooltipped tooltipped-nw"
- aria-label="You must be signed in to make or propose changes">
- <svg aria-hidden="true" class="octicon octicon-trashcan" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M11 2H9c0-.55-.45-1-1-1H5c-.55 0-1 .45-1 1H2c-.55 0-1 .45-1 1v1c0 .55.45 1 1 1v9c0 .55.45 1 1 1h7c.55 0 1-.45 1-1V5c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1zm-1 12H3V5h1v8h1V5h1v8h1V5h1v8h1V5h1v9zm1-10H2V3h9v1z"/></svg>
- </button>
- </div>
-
- <div class="file-info">
- 248 lines (207 sloc)
- <span class="file-info-divider"></span>
- 7.55 KB
- </div>
-</div>
-
-
-
- <div itemprop="text" class="blob-wrapper data type-c">
- <table class="highlight tab-size js-file-line-container" data-tab-size="8">
- <tr>
- <td id="L1" class="blob-num js-line-number" data-line-number="1"></td>
- <td id="LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> ISO C9x compliant stdint.h for Microsoft Visual Studio</span></td>
- </tr>
- <tr>
- <td id="L2" class="blob-num js-line-number" data-line-number="2"></td>
- <td id="LC2" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 </span></td>
- </tr>
- <tr>
- <td id="L3" class="blob-num js-line-number" data-line-number="3"></td>
- <td id="LC3" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> </span></td>
- </tr>
- <tr>
- <td id="L4" class="blob-num js-line-number" data-line-number="4"></td>
- <td id="LC4" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> Copyright (c) 2006-2008 Alexander Chemeris</span></td>
- </tr>
- <tr>
- <td id="L5" class="blob-num js-line-number" data-line-number="5"></td>
- <td id="LC5" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> </span></td>
- </tr>
- <tr>
- <td id="L6" class="blob-num js-line-number" data-line-number="6"></td>
- <td id="LC6" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> Redistribution and use in source and binary forms, with or without</span></td>
- </tr>
- <tr>
- <td id="L7" class="blob-num js-line-number" data-line-number="7"></td>
- <td id="LC7" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> modification, are permitted provided that the following conditions are met:</span></td>
- </tr>
- <tr>
- <td id="L8" class="blob-num js-line-number" data-line-number="8"></td>
- <td id="LC8" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> </span></td>
- </tr>
- <tr>
- <td id="L9" class="blob-num js-line-number" data-line-number="9"></td>
- <td id="LC9" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> 1. Redistributions of source code must retain the above copyright notice,</span></td>
- </tr>
- <tr>
- <td id="L10" class="blob-num js-line-number" data-line-number="10"></td>
- <td id="LC10" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> this list of conditions and the following disclaimer.</span></td>
- </tr>
- <tr>
- <td id="L11" class="blob-num js-line-number" data-line-number="11"></td>
- <td id="LC11" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> </span></td>
- </tr>
- <tr>
- <td id="L12" class="blob-num js-line-number" data-line-number="12"></td>
- <td id="LC12" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> 2. Redistributions in binary form must reproduce the above copyright</span></td>
- </tr>
- <tr>
- <td id="L13" class="blob-num js-line-number" data-line-number="13"></td>
- <td id="LC13" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> notice, this list of conditions and the following disclaimer in the</span></td>
- </tr>
- <tr>
- <td id="L14" class="blob-num js-line-number" data-line-number="14"></td>
- <td id="LC14" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> documentation and/or other materials provided with the distribution.</span></td>
- </tr>
- <tr>
- <td id="L15" class="blob-num js-line-number" data-line-number="15"></td>
- <td id="LC15" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> </span></td>
- </tr>
- <tr>
- <td id="L16" class="blob-num js-line-number" data-line-number="16"></td>
- <td id="LC16" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> 3. The name of the author may be used to endorse or promote products</span></td>
- </tr>
- <tr>
- <td id="L17" class="blob-num js-line-number" data-line-number="17"></td>
- <td id="LC17" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> derived from this software without specific prior written permission.</span></td>
- </tr>
- <tr>
- <td id="L18" class="blob-num js-line-number" data-line-number="18"></td>
- <td id="LC18" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> </span></td>
- </tr>
- <tr>
- <td id="L19" class="blob-num js-line-number" data-line-number="19"></td>
- <td id="LC19" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS&#39;&#39; AND ANY EXPRESS OR IMPLIED</span></td>
- </tr>
- <tr>
- <td id="L20" class="blob-num js-line-number" data-line-number="20"></td>
- <td id="LC20" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF</span></td>
- </tr>
- <tr>
- <td id="L21" class="blob-num js-line-number" data-line-number="21"></td>
- <td id="LC21" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO</span></td>
- </tr>
- <tr>
- <td id="L22" class="blob-num js-line-number" data-line-number="22"></td>
- <td id="LC22" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,</span></td>
- </tr>
- <tr>
- <td id="L23" class="blob-num js-line-number" data-line-number="23"></td>
- <td id="LC23" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,</span></td>
- </tr>
- <tr>
- <td id="L24" class="blob-num js-line-number" data-line-number="24"></td>
- <td id="LC24" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;</span></td>
- </tr>
- <tr>
- <td id="L25" class="blob-num js-line-number" data-line-number="25"></td>
- <td id="LC25" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, </span></td>
- </tr>
- <tr>
- <td id="L26" class="blob-num js-line-number" data-line-number="26"></td>
- <td id="LC26" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR</span></td>
- </tr>
- <tr>
- <td id="L27" class="blob-num js-line-number" data-line-number="27"></td>
- <td id="LC27" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF</span></td>
- </tr>
- <tr>
- <td id="L28" class="blob-num js-line-number" data-line-number="28"></td>
- <td id="LC28" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</span></td>
- </tr>
- <tr>
- <td id="L29" class="blob-num js-line-number" data-line-number="29"></td>
- <td id="LC29" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> </span></td>
- </tr>
- <tr>
- <td id="L30" class="blob-num js-line-number" data-line-number="30"></td>
- <td id="LC30" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span>/////////////////////////////////////////////////////////////////////////////</span></td>
- </tr>
- <tr>
- <td id="L31" class="blob-num js-line-number" data-line-number="31"></td>
- <td id="LC31" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L32" class="blob-num js-line-number" data-line-number="32"></td>
- <td id="LC32" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">ifndef</span> _MSC_VER <span class="pl-c"><span class="pl-c">//</span> [</span></td>
- </tr>
- <tr>
- <td id="L33" class="blob-num js-line-number" data-line-number="33"></td>
- <td id="LC33" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">error</span> &quot;Use this header only with Microsoft Visual C++ compilers!&quot;</td>
- </tr>
- <tr>
- <td id="L34" class="blob-num js-line-number" data-line-number="34"></td>
- <td id="LC34" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">endif</span> <span class="pl-c"><span class="pl-c">//</span> _MSC_VER ]</span></td>
- </tr>
- <tr>
- <td id="L35" class="blob-num js-line-number" data-line-number="35"></td>
- <td id="LC35" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L36" class="blob-num js-line-number" data-line-number="36"></td>
- <td id="LC36" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">ifndef</span> _MSC_STDINT_H_ <span class="pl-c"><span class="pl-c">//</span> [</span></td>
- </tr>
- <tr>
- <td id="L37" class="blob-num js-line-number" data-line-number="37"></td>
- <td id="LC37" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">_MSC_STDINT_H_</span></td>
- </tr>
- <tr>
- <td id="L38" class="blob-num js-line-number" data-line-number="38"></td>
- <td id="LC38" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L39" class="blob-num js-line-number" data-line-number="39"></td>
- <td id="LC39" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">if</span> _MSC_VER &gt; 1000</td>
- </tr>
- <tr>
- <td id="L40" class="blob-num js-line-number" data-line-number="40"></td>
- <td id="LC40" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">pragma</span> once</td>
- </tr>
- <tr>
- <td id="L41" class="blob-num js-line-number" data-line-number="41"></td>
- <td id="LC41" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">endif</span></td>
- </tr>
- <tr>
- <td id="L42" class="blob-num js-line-number" data-line-number="42"></td>
- <td id="LC42" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L43" class="blob-num js-line-number" data-line-number="43"></td>
- <td id="LC43" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">include</span> <span class="pl-s"><span class="pl-pds">&lt;</span>limits.h<span class="pl-pds">&gt;</span></span></td>
- </tr>
- <tr>
- <td id="L44" class="blob-num js-line-number" data-line-number="44"></td>
- <td id="LC44" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L45" class="blob-num js-line-number" data-line-number="45"></td>
- <td id="LC45" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> For Visual Studio 6 in C++ mode and for many Visual Studio versions when</span></td>
- </tr>
- <tr>
- <td id="L46" class="blob-num js-line-number" data-line-number="46"></td>
- <td id="LC46" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> compiling for ARM we should wrap &lt;wchar.h&gt; include with &#39;extern &quot;C++&quot; {}&#39;</span></td>
- </tr>
- <tr>
- <td id="L47" class="blob-num js-line-number" data-line-number="47"></td>
- <td id="LC47" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> or compiler give many errors like this:</span></td>
- </tr>
- <tr>
- <td id="L48" class="blob-num js-line-number" data-line-number="48"></td>
- <td id="LC48" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> error C2733: second C linkage of overloaded function &#39;wmemchr&#39; not allowed</span></td>
- </tr>
- <tr>
- <td id="L49" class="blob-num js-line-number" data-line-number="49"></td>
- <td id="LC49" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">ifdef</span> __cplusplus</td>
- </tr>
- <tr>
- <td id="L50" class="blob-num js-line-number" data-line-number="50"></td>
- <td id="LC50" class="blob-code blob-code-inner js-file-line"><span class="pl-k">extern</span> <span class="pl-s"><span class="pl-pds">&quot;</span>C<span class="pl-pds">&quot;</span></span> {</td>
- </tr>
- <tr>
- <td id="L51" class="blob-num js-line-number" data-line-number="51"></td>
- <td id="LC51" class="blob-code blob-code-inner js-file-line">#endif</td>
- </tr>
- <tr>
- <td id="L52" class="blob-num js-line-number" data-line-number="52"></td>
- <td id="LC52" class="blob-code blob-code-inner js-file-line"># <span class="pl-k">include</span> <span class="pl-s"><span class="pl-pds">&lt;</span>wchar.h<span class="pl-pds">&gt;</span></span></td>
- </tr>
- <tr>
- <td id="L53" class="blob-num js-line-number" data-line-number="53"></td>
- <td id="LC53" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">ifdef</span> __cplusplus</td>
- </tr>
- <tr>
- <td id="L54" class="blob-num js-line-number" data-line-number="54"></td>
- <td id="LC54" class="blob-code blob-code-inner js-file-line">}</td>
- </tr>
- <tr>
- <td id="L55" class="blob-num js-line-number" data-line-number="55"></td>
- <td id="LC55" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">endif</span></td>
- </tr>
- <tr>
- <td id="L56" class="blob-num js-line-number" data-line-number="56"></td>
- <td id="LC56" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L57" class="blob-num js-line-number" data-line-number="57"></td>
- <td id="LC57" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> Define _W64 macros to mark types changing their size, like intptr_t.</span></td>
- </tr>
- <tr>
- <td id="L58" class="blob-num js-line-number" data-line-number="58"></td>
- <td id="LC58" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">ifndef</span> _W64</td>
- </tr>
- <tr>
- <td id="L59" class="blob-num js-line-number" data-line-number="59"></td>
- <td id="LC59" class="blob-code blob-code-inner js-file-line"># <span class="pl-k">if</span> !defined(__midl) &amp;&amp; (defined(_X86_) || defined(_M_IX86)) &amp;&amp; _MSC_VER &gt;= 1300</td>
- </tr>
- <tr>
- <td id="L60" class="blob-num js-line-number" data-line-number="60"></td>
- <td id="LC60" class="blob-code blob-code-inner js-file-line"># <span class="pl-k">define</span> <span class="pl-en">_W64</span> __w64</td>
- </tr>
- <tr>
- <td id="L61" class="blob-num js-line-number" data-line-number="61"></td>
- <td id="LC61" class="blob-code blob-code-inner js-file-line"># <span class="pl-k">else</span></td>
- </tr>
- <tr>
- <td id="L62" class="blob-num js-line-number" data-line-number="62"></td>
- <td id="LC62" class="blob-code blob-code-inner js-file-line"># <span class="pl-k">define</span> <span class="pl-en">_W64</span></td>
- </tr>
- <tr>
- <td id="L63" class="blob-num js-line-number" data-line-number="63"></td>
- <td id="LC63" class="blob-code blob-code-inner js-file-line"># <span class="pl-k">endif</span></td>
- </tr>
- <tr>
- <td id="L64" class="blob-num js-line-number" data-line-number="64"></td>
- <td id="LC64" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">endif</span></td>
- </tr>
- <tr>
- <td id="L65" class="blob-num js-line-number" data-line-number="65"></td>
- <td id="LC65" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L66" class="blob-num js-line-number" data-line-number="66"></td>
- <td id="LC66" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L67" class="blob-num js-line-number" data-line-number="67"></td>
- <td id="LC67" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> 7.18.1 Integer types</span></td>
- </tr>
- <tr>
- <td id="L68" class="blob-num js-line-number" data-line-number="68"></td>
- <td id="LC68" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L69" class="blob-num js-line-number" data-line-number="69"></td>
- <td id="LC69" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> 7.18.1.1 Exact-width integer types</span></td>
- </tr>
- <tr>
- <td id="L70" class="blob-num js-line-number" data-line-number="70"></td>
- <td id="LC70" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L71" class="blob-num js-line-number" data-line-number="71"></td>
- <td id="LC71" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> Visual Studio 6 and Embedded Visual C++ 4 doesn&#39;t</span></td>
- </tr>
- <tr>
- <td id="L72" class="blob-num js-line-number" data-line-number="72"></td>
- <td id="LC72" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> realize that, e.g. char has the same size as __int8</span></td>
- </tr>
- <tr>
- <td id="L73" class="blob-num js-line-number" data-line-number="73"></td>
- <td id="LC73" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> so we give up on __intX for them.</span></td>
- </tr>
- <tr>
- <td id="L74" class="blob-num js-line-number" data-line-number="74"></td>
- <td id="LC74" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">if</span> (_MSC_VER &lt; 1300)</td>
- </tr>
- <tr>
- <td id="L75" class="blob-num js-line-number" data-line-number="75"></td>
- <td id="LC75" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">typedef</span> <span class="pl-k">signed</span> <span class="pl-k">char</span> <span class="pl-c1">int8_t</span>;</td>
- </tr>
- <tr>
- <td id="L76" class="blob-num js-line-number" data-line-number="76"></td>
- <td id="LC76" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">typedef</span> <span class="pl-k">signed</span> <span class="pl-k">short</span> <span class="pl-c1">int16_t</span>;</td>
- </tr>
- <tr>
- <td id="L77" class="blob-num js-line-number" data-line-number="77"></td>
- <td id="LC77" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">typedef</span> <span class="pl-k">signed</span> <span class="pl-k">int</span> <span class="pl-c1">int32_t</span>;</td>
- </tr>
- <tr>
- <td id="L78" class="blob-num js-line-number" data-line-number="78"></td>
- <td id="LC78" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">typedef</span> <span class="pl-k">unsigned</span> <span class="pl-k">char</span> <span class="pl-c1">uint8_t</span>;</td>
- </tr>
- <tr>
- <td id="L79" class="blob-num js-line-number" data-line-number="79"></td>
- <td id="LC79" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">typedef</span> <span class="pl-k">unsigned</span> <span class="pl-k">short</span> <span class="pl-c1">uint16_t</span>;</td>
- </tr>
- <tr>
- <td id="L80" class="blob-num js-line-number" data-line-number="80"></td>
- <td id="LC80" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">typedef</span> <span class="pl-k">unsigned</span> <span class="pl-k">int</span> <span class="pl-c1">uint32_t</span>;</td>
- </tr>
- <tr>
- <td id="L81" class="blob-num js-line-number" data-line-number="81"></td>
- <td id="LC81" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">else</span></td>
- </tr>
- <tr>
- <td id="L82" class="blob-num js-line-number" data-line-number="82"></td>
- <td id="LC82" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">typedef</span> <span class="pl-k">signed</span> __int8 <span class="pl-c1">int8_t</span>;</td>
- </tr>
- <tr>
- <td id="L83" class="blob-num js-line-number" data-line-number="83"></td>
- <td id="LC83" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">typedef</span> <span class="pl-k">signed</span> __int16 <span class="pl-c1">int16_t</span>;</td>
- </tr>
- <tr>
- <td id="L84" class="blob-num js-line-number" data-line-number="84"></td>
- <td id="LC84" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">typedef</span> <span class="pl-k">signed</span> __int32 <span class="pl-c1">int32_t</span>;</td>
- </tr>
- <tr>
- <td id="L85" class="blob-num js-line-number" data-line-number="85"></td>
- <td id="LC85" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">typedef</span> <span class="pl-k">unsigned</span> __int8 <span class="pl-c1">uint8_t</span>;</td>
- </tr>
- <tr>
- <td id="L86" class="blob-num js-line-number" data-line-number="86"></td>
- <td id="LC86" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">typedef</span> <span class="pl-k">unsigned</span> __int16 <span class="pl-c1">uint16_t</span>;</td>
- </tr>
- <tr>
- <td id="L87" class="blob-num js-line-number" data-line-number="87"></td>
- <td id="LC87" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">typedef</span> <span class="pl-k">unsigned</span> __int32 <span class="pl-c1">uint32_t</span>;</td>
- </tr>
- <tr>
- <td id="L88" class="blob-num js-line-number" data-line-number="88"></td>
- <td id="LC88" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">endif</span></td>
- </tr>
- <tr>
- <td id="L89" class="blob-num js-line-number" data-line-number="89"></td>
- <td id="LC89" class="blob-code blob-code-inner js-file-line"><span class="pl-k">typedef</span> <span class="pl-k">signed</span> __int64 <span class="pl-c1">int64_t</span>;</td>
- </tr>
- <tr>
- <td id="L90" class="blob-num js-line-number" data-line-number="90"></td>
- <td id="LC90" class="blob-code blob-code-inner js-file-line"><span class="pl-k">typedef</span> <span class="pl-k">unsigned</span> __int64 <span class="pl-c1">uint64_t</span>;</td>
- </tr>
- <tr>
- <td id="L91" class="blob-num js-line-number" data-line-number="91"></td>
- <td id="LC91" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L92" class="blob-num js-line-number" data-line-number="92"></td>
- <td id="LC92" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L93" class="blob-num js-line-number" data-line-number="93"></td>
- <td id="LC93" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> 7.18.1.2 Minimum-width integer types</span></td>
- </tr>
- <tr>
- <td id="L94" class="blob-num js-line-number" data-line-number="94"></td>
- <td id="LC94" class="blob-code blob-code-inner js-file-line"><span class="pl-k">typedef</span> <span class="pl-c1">int8_t</span> <span class="pl-c1">int_least8_t</span>;</td>
- </tr>
- <tr>
- <td id="L95" class="blob-num js-line-number" data-line-number="95"></td>
- <td id="LC95" class="blob-code blob-code-inner js-file-line"><span class="pl-k">typedef</span> <span class="pl-c1">int16_t</span> <span class="pl-c1">int_least16_t</span>;</td>
- </tr>
- <tr>
- <td id="L96" class="blob-num js-line-number" data-line-number="96"></td>
- <td id="LC96" class="blob-code blob-code-inner js-file-line"><span class="pl-k">typedef</span> <span class="pl-c1">int32_t</span> <span class="pl-c1">int_least32_t</span>;</td>
- </tr>
- <tr>
- <td id="L97" class="blob-num js-line-number" data-line-number="97"></td>
- <td id="LC97" class="blob-code blob-code-inner js-file-line"><span class="pl-k">typedef</span> <span class="pl-c1">int64_t</span> <span class="pl-c1">int_least64_t</span>;</td>
- </tr>
- <tr>
- <td id="L98" class="blob-num js-line-number" data-line-number="98"></td>
- <td id="LC98" class="blob-code blob-code-inner js-file-line"><span class="pl-k">typedef</span> <span class="pl-c1">uint8_t</span> <span class="pl-c1">uint_least8_t</span>;</td>
- </tr>
- <tr>
- <td id="L99" class="blob-num js-line-number" data-line-number="99"></td>
- <td id="LC99" class="blob-code blob-code-inner js-file-line"><span class="pl-k">typedef</span> <span class="pl-c1">uint16_t</span> <span class="pl-c1">uint_least16_t</span>;</td>
- </tr>
- <tr>
- <td id="L100" class="blob-num js-line-number" data-line-number="100"></td>
- <td id="LC100" class="blob-code blob-code-inner js-file-line"><span class="pl-k">typedef</span> <span class="pl-c1">uint32_t</span> <span class="pl-c1">uint_least32_t</span>;</td>
- </tr>
- <tr>
- <td id="L101" class="blob-num js-line-number" data-line-number="101"></td>
- <td id="LC101" class="blob-code blob-code-inner js-file-line"><span class="pl-k">typedef</span> <span class="pl-c1">uint64_t</span> <span class="pl-c1">uint_least64_t</span>;</td>
- </tr>
- <tr>
- <td id="L102" class="blob-num js-line-number" data-line-number="102"></td>
- <td id="LC102" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L103" class="blob-num js-line-number" data-line-number="103"></td>
- <td id="LC103" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> 7.18.1.3 Fastest minimum-width integer types</span></td>
- </tr>
- <tr>
- <td id="L104" class="blob-num js-line-number" data-line-number="104"></td>
- <td id="LC104" class="blob-code blob-code-inner js-file-line"><span class="pl-k">typedef</span> <span class="pl-c1">int8_t</span> <span class="pl-c1">int_fast8_t</span>;</td>
- </tr>
- <tr>
- <td id="L105" class="blob-num js-line-number" data-line-number="105"></td>
- <td id="LC105" class="blob-code blob-code-inner js-file-line"><span class="pl-k">typedef</span> <span class="pl-c1">int16_t</span> <span class="pl-c1">int_fast16_t</span>;</td>
- </tr>
- <tr>
- <td id="L106" class="blob-num js-line-number" data-line-number="106"></td>
- <td id="LC106" class="blob-code blob-code-inner js-file-line"><span class="pl-k">typedef</span> <span class="pl-c1">int32_t</span> <span class="pl-c1">int_fast32_t</span>;</td>
- </tr>
- <tr>
- <td id="L107" class="blob-num js-line-number" data-line-number="107"></td>
- <td id="LC107" class="blob-code blob-code-inner js-file-line"><span class="pl-k">typedef</span> <span class="pl-c1">int64_t</span> <span class="pl-c1">int_fast64_t</span>;</td>
- </tr>
- <tr>
- <td id="L108" class="blob-num js-line-number" data-line-number="108"></td>
- <td id="LC108" class="blob-code blob-code-inner js-file-line"><span class="pl-k">typedef</span> <span class="pl-c1">uint8_t</span> <span class="pl-c1">uint_fast8_t</span>;</td>
- </tr>
- <tr>
- <td id="L109" class="blob-num js-line-number" data-line-number="109"></td>
- <td id="LC109" class="blob-code blob-code-inner js-file-line"><span class="pl-k">typedef</span> <span class="pl-c1">uint16_t</span> <span class="pl-c1">uint_fast16_t</span>;</td>
- </tr>
- <tr>
- <td id="L110" class="blob-num js-line-number" data-line-number="110"></td>
- <td id="LC110" class="blob-code blob-code-inner js-file-line"><span class="pl-k">typedef</span> <span class="pl-c1">uint32_t</span> <span class="pl-c1">uint_fast32_t</span>;</td>
- </tr>
- <tr>
- <td id="L111" class="blob-num js-line-number" data-line-number="111"></td>
- <td id="LC111" class="blob-code blob-code-inner js-file-line"><span class="pl-k">typedef</span> <span class="pl-c1">uint64_t</span> <span class="pl-c1">uint_fast64_t</span>;</td>
- </tr>
- <tr>
- <td id="L112" class="blob-num js-line-number" data-line-number="112"></td>
- <td id="LC112" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L113" class="blob-num js-line-number" data-line-number="113"></td>
- <td id="LC113" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> 7.18.1.4 Integer types capable of holding object pointers</span></td>
- </tr>
- <tr>
- <td id="L114" class="blob-num js-line-number" data-line-number="114"></td>
- <td id="LC114" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">ifdef</span> _WIN64 <span class="pl-c"><span class="pl-c">//</span> [</span></td>
- </tr>
- <tr>
- <td id="L115" class="blob-num js-line-number" data-line-number="115"></td>
- <td id="LC115" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">typedef</span> <span class="pl-k">signed</span> __int64 <span class="pl-c1">intptr_t</span>;</td>
- </tr>
- <tr>
- <td id="L116" class="blob-num js-line-number" data-line-number="116"></td>
- <td id="LC116" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">typedef</span> <span class="pl-k">unsigned</span> __int64 <span class="pl-c1">uintptr_t</span>;</td>
- </tr>
- <tr>
- <td id="L117" class="blob-num js-line-number" data-line-number="117"></td>
- <td id="LC117" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">else</span> <span class="pl-c"><span class="pl-c">//</span> _WIN64 ][</span></td>
- </tr>
- <tr>
- <td id="L118" class="blob-num js-line-number" data-line-number="118"></td>
- <td id="LC118" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">typedef</span> _W64 <span class="pl-k">signed</span> <span class="pl-k">int</span> <span class="pl-c1">intptr_t</span>;</td>
- </tr>
- <tr>
- <td id="L119" class="blob-num js-line-number" data-line-number="119"></td>
- <td id="LC119" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">typedef</span> _W64 <span class="pl-k">unsigned</span> <span class="pl-k">int</span> <span class="pl-c1">uintptr_t</span>;</td>
- </tr>
- <tr>
- <td id="L120" class="blob-num js-line-number" data-line-number="120"></td>
- <td id="LC120" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">endif</span> <span class="pl-c"><span class="pl-c">//</span> _WIN64 ]</span></td>
- </tr>
- <tr>
- <td id="L121" class="blob-num js-line-number" data-line-number="121"></td>
- <td id="LC121" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L122" class="blob-num js-line-number" data-line-number="122"></td>
- <td id="LC122" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> 7.18.1.5 Greatest-width integer types</span></td>
- </tr>
- <tr>
- <td id="L123" class="blob-num js-line-number" data-line-number="123"></td>
- <td id="LC123" class="blob-code blob-code-inner js-file-line"><span class="pl-k">typedef</span> <span class="pl-c1">int64_t</span> <span class="pl-c1">intmax_t</span>;</td>
- </tr>
- <tr>
- <td id="L124" class="blob-num js-line-number" data-line-number="124"></td>
- <td id="LC124" class="blob-code blob-code-inner js-file-line"><span class="pl-k">typedef</span> <span class="pl-c1">uint64_t</span> <span class="pl-c1">uintmax_t</span>;</td>
- </tr>
- <tr>
- <td id="L125" class="blob-num js-line-number" data-line-number="125"></td>
- <td id="LC125" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L126" class="blob-num js-line-number" data-line-number="126"></td>
- <td id="LC126" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L127" class="blob-num js-line-number" data-line-number="127"></td>
- <td id="LC127" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> 7.18.2 Limits of specified-width integer types</span></td>
- </tr>
- <tr>
- <td id="L128" class="blob-num js-line-number" data-line-number="128"></td>
- <td id="LC128" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L129" class="blob-num js-line-number" data-line-number="129"></td>
- <td id="LC129" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">if</span> !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) <span class="pl-c"><span class="pl-c">//</span> [ See footnote 220 at page 257 and footnote 221 at page 259</span></td>
- </tr>
- <tr>
- <td id="L130" class="blob-num js-line-number" data-line-number="130"></td>
- <td id="LC130" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L131" class="blob-num js-line-number" data-line-number="131"></td>
- <td id="LC131" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> 7.18.2.1 Limits of exact-width integer types</span></td>
- </tr>
- <tr>
- <td id="L132" class="blob-num js-line-number" data-line-number="132"></td>
- <td id="LC132" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT8_MIN</span> ((<span class="pl-c1">int8_t</span>)_I8_MIN)</td>
- </tr>
- <tr>
- <td id="L133" class="blob-num js-line-number" data-line-number="133"></td>
- <td id="LC133" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT8_MAX</span> _I8_MAX</td>
- </tr>
- <tr>
- <td id="L134" class="blob-num js-line-number" data-line-number="134"></td>
- <td id="LC134" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT16_MIN</span> ((<span class="pl-c1">int16_t</span>)_I16_MIN)</td>
- </tr>
- <tr>
- <td id="L135" class="blob-num js-line-number" data-line-number="135"></td>
- <td id="LC135" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT16_MAX</span> _I16_MAX</td>
- </tr>
- <tr>
- <td id="L136" class="blob-num js-line-number" data-line-number="136"></td>
- <td id="LC136" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT32_MIN</span> ((<span class="pl-c1">int32_t</span>)_I32_MIN)</td>
- </tr>
- <tr>
- <td id="L137" class="blob-num js-line-number" data-line-number="137"></td>
- <td id="LC137" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT32_MAX</span> _I32_MAX</td>
- </tr>
- <tr>
- <td id="L138" class="blob-num js-line-number" data-line-number="138"></td>
- <td id="LC138" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT64_MIN</span> ((<span class="pl-c1">int64_t</span>)_I64_MIN)</td>
- </tr>
- <tr>
- <td id="L139" class="blob-num js-line-number" data-line-number="139"></td>
- <td id="LC139" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT64_MAX</span> _I64_MAX</td>
- </tr>
- <tr>
- <td id="L140" class="blob-num js-line-number" data-line-number="140"></td>
- <td id="LC140" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">UINT8_MAX</span> _UI8_MAX</td>
- </tr>
- <tr>
- <td id="L141" class="blob-num js-line-number" data-line-number="141"></td>
- <td id="LC141" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">UINT16_MAX</span> _UI16_MAX</td>
- </tr>
- <tr>
- <td id="L142" class="blob-num js-line-number" data-line-number="142"></td>
- <td id="LC142" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">UINT32_MAX</span> _UI32_MAX</td>
- </tr>
- <tr>
- <td id="L143" class="blob-num js-line-number" data-line-number="143"></td>
- <td id="LC143" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">UINT64_MAX</span> _UI64_MAX</td>
- </tr>
- <tr>
- <td id="L144" class="blob-num js-line-number" data-line-number="144"></td>
- <td id="LC144" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L145" class="blob-num js-line-number" data-line-number="145"></td>
- <td id="LC145" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> 7.18.2.2 Limits of minimum-width integer types</span></td>
- </tr>
- <tr>
- <td id="L146" class="blob-num js-line-number" data-line-number="146"></td>
- <td id="LC146" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT_LEAST8_MIN</span> INT8_MIN</td>
- </tr>
- <tr>
- <td id="L147" class="blob-num js-line-number" data-line-number="147"></td>
- <td id="LC147" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT_LEAST8_MAX</span> INT8_MAX</td>
- </tr>
- <tr>
- <td id="L148" class="blob-num js-line-number" data-line-number="148"></td>
- <td id="LC148" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT_LEAST16_MIN</span> INT16_MIN</td>
- </tr>
- <tr>
- <td id="L149" class="blob-num js-line-number" data-line-number="149"></td>
- <td id="LC149" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT_LEAST16_MAX</span> INT16_MAX</td>
- </tr>
- <tr>
- <td id="L150" class="blob-num js-line-number" data-line-number="150"></td>
- <td id="LC150" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT_LEAST32_MIN</span> INT32_MIN</td>
- </tr>
- <tr>
- <td id="L151" class="blob-num js-line-number" data-line-number="151"></td>
- <td id="LC151" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT_LEAST32_MAX</span> INT32_MAX</td>
- </tr>
- <tr>
- <td id="L152" class="blob-num js-line-number" data-line-number="152"></td>
- <td id="LC152" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT_LEAST64_MIN</span> INT64_MIN</td>
- </tr>
- <tr>
- <td id="L153" class="blob-num js-line-number" data-line-number="153"></td>
- <td id="LC153" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT_LEAST64_MAX</span> INT64_MAX</td>
- </tr>
- <tr>
- <td id="L154" class="blob-num js-line-number" data-line-number="154"></td>
- <td id="LC154" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">UINT_LEAST8_MAX</span> UINT8_MAX</td>
- </tr>
- <tr>
- <td id="L155" class="blob-num js-line-number" data-line-number="155"></td>
- <td id="LC155" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">UINT_LEAST16_MAX</span> UINT16_MAX</td>
- </tr>
- <tr>
- <td id="L156" class="blob-num js-line-number" data-line-number="156"></td>
- <td id="LC156" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">UINT_LEAST32_MAX</span> UINT32_MAX</td>
- </tr>
- <tr>
- <td id="L157" class="blob-num js-line-number" data-line-number="157"></td>
- <td id="LC157" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">UINT_LEAST64_MAX</span> UINT64_MAX</td>
- </tr>
- <tr>
- <td id="L158" class="blob-num js-line-number" data-line-number="158"></td>
- <td id="LC158" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L159" class="blob-num js-line-number" data-line-number="159"></td>
- <td id="LC159" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> 7.18.2.3 Limits of fastest minimum-width integer types</span></td>
- </tr>
- <tr>
- <td id="L160" class="blob-num js-line-number" data-line-number="160"></td>
- <td id="LC160" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT_FAST8_MIN</span> INT8_MIN</td>
- </tr>
- <tr>
- <td id="L161" class="blob-num js-line-number" data-line-number="161"></td>
- <td id="LC161" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT_FAST8_MAX</span> INT8_MAX</td>
- </tr>
- <tr>
- <td id="L162" class="blob-num js-line-number" data-line-number="162"></td>
- <td id="LC162" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT_FAST16_MIN</span> INT16_MIN</td>
- </tr>
- <tr>
- <td id="L163" class="blob-num js-line-number" data-line-number="163"></td>
- <td id="LC163" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT_FAST16_MAX</span> INT16_MAX</td>
- </tr>
- <tr>
- <td id="L164" class="blob-num js-line-number" data-line-number="164"></td>
- <td id="LC164" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT_FAST32_MIN</span> INT32_MIN</td>
- </tr>
- <tr>
- <td id="L165" class="blob-num js-line-number" data-line-number="165"></td>
- <td id="LC165" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT_FAST32_MAX</span> INT32_MAX</td>
- </tr>
- <tr>
- <td id="L166" class="blob-num js-line-number" data-line-number="166"></td>
- <td id="LC166" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT_FAST64_MIN</span> INT64_MIN</td>
- </tr>
- <tr>
- <td id="L167" class="blob-num js-line-number" data-line-number="167"></td>
- <td id="LC167" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT_FAST64_MAX</span> INT64_MAX</td>
- </tr>
- <tr>
- <td id="L168" class="blob-num js-line-number" data-line-number="168"></td>
- <td id="LC168" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">UINT_FAST8_MAX</span> UINT8_MAX</td>
- </tr>
- <tr>
- <td id="L169" class="blob-num js-line-number" data-line-number="169"></td>
- <td id="LC169" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">UINT_FAST16_MAX</span> UINT16_MAX</td>
- </tr>
- <tr>
- <td id="L170" class="blob-num js-line-number" data-line-number="170"></td>
- <td id="LC170" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">UINT_FAST32_MAX</span> UINT32_MAX</td>
- </tr>
- <tr>
- <td id="L171" class="blob-num js-line-number" data-line-number="171"></td>
- <td id="LC171" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">UINT_FAST64_MAX</span> UINT64_MAX</td>
- </tr>
- <tr>
- <td id="L172" class="blob-num js-line-number" data-line-number="172"></td>
- <td id="LC172" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L173" class="blob-num js-line-number" data-line-number="173"></td>
- <td id="LC173" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> 7.18.2.4 Limits of integer types capable of holding object pointers</span></td>
- </tr>
- <tr>
- <td id="L174" class="blob-num js-line-number" data-line-number="174"></td>
- <td id="LC174" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">ifdef</span> _WIN64 <span class="pl-c"><span class="pl-c">//</span> [</span></td>
- </tr>
- <tr>
- <td id="L175" class="blob-num js-line-number" data-line-number="175"></td>
- <td id="LC175" class="blob-code blob-code-inner js-file-line"># <span class="pl-k">define</span> <span class="pl-en">INTPTR_MIN</span> INT64_MIN</td>
- </tr>
- <tr>
- <td id="L176" class="blob-num js-line-number" data-line-number="176"></td>
- <td id="LC176" class="blob-code blob-code-inner js-file-line"># <span class="pl-k">define</span> <span class="pl-en">INTPTR_MAX</span> INT64_MAX</td>
- </tr>
- <tr>
- <td id="L177" class="blob-num js-line-number" data-line-number="177"></td>
- <td id="LC177" class="blob-code blob-code-inner js-file-line"># <span class="pl-k">define</span> <span class="pl-en">UINTPTR_MAX</span> UINT64_MAX</td>
- </tr>
- <tr>
- <td id="L178" class="blob-num js-line-number" data-line-number="178"></td>
- <td id="LC178" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">else</span> <span class="pl-c"><span class="pl-c">//</span> _WIN64 ][</span></td>
- </tr>
- <tr>
- <td id="L179" class="blob-num js-line-number" data-line-number="179"></td>
- <td id="LC179" class="blob-code blob-code-inner js-file-line"># <span class="pl-k">define</span> <span class="pl-en">INTPTR_MIN</span> INT32_MIN</td>
- </tr>
- <tr>
- <td id="L180" class="blob-num js-line-number" data-line-number="180"></td>
- <td id="LC180" class="blob-code blob-code-inner js-file-line"># <span class="pl-k">define</span> <span class="pl-en">INTPTR_MAX</span> INT32_MAX</td>
- </tr>
- <tr>
- <td id="L181" class="blob-num js-line-number" data-line-number="181"></td>
- <td id="LC181" class="blob-code blob-code-inner js-file-line"># <span class="pl-k">define</span> <span class="pl-en">UINTPTR_MAX</span> UINT32_MAX</td>
- </tr>
- <tr>
- <td id="L182" class="blob-num js-line-number" data-line-number="182"></td>
- <td id="LC182" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">endif</span> <span class="pl-c"><span class="pl-c">//</span> _WIN64 ]</span></td>
- </tr>
- <tr>
- <td id="L183" class="blob-num js-line-number" data-line-number="183"></td>
- <td id="LC183" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L184" class="blob-num js-line-number" data-line-number="184"></td>
- <td id="LC184" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> 7.18.2.5 Limits of greatest-width integer types</span></td>
- </tr>
- <tr>
- <td id="L185" class="blob-num js-line-number" data-line-number="185"></td>
- <td id="LC185" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INTMAX_MIN</span> INT64_MIN</td>
- </tr>
- <tr>
- <td id="L186" class="blob-num js-line-number" data-line-number="186"></td>
- <td id="LC186" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INTMAX_MAX</span> INT64_MAX</td>
- </tr>
- <tr>
- <td id="L187" class="blob-num js-line-number" data-line-number="187"></td>
- <td id="LC187" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">UINTMAX_MAX</span> UINT64_MAX</td>
- </tr>
- <tr>
- <td id="L188" class="blob-num js-line-number" data-line-number="188"></td>
- <td id="LC188" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L189" class="blob-num js-line-number" data-line-number="189"></td>
- <td id="LC189" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> 7.18.3 Limits of other integer types</span></td>
- </tr>
- <tr>
- <td id="L190" class="blob-num js-line-number" data-line-number="190"></td>
- <td id="LC190" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L191" class="blob-num js-line-number" data-line-number="191"></td>
- <td id="LC191" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">ifdef</span> _WIN64 <span class="pl-c"><span class="pl-c">//</span> [</span></td>
- </tr>
- <tr>
- <td id="L192" class="blob-num js-line-number" data-line-number="192"></td>
- <td id="LC192" class="blob-code blob-code-inner js-file-line"># <span class="pl-k">define</span> <span class="pl-en">PTRDIFF_MIN</span> _I64_MIN</td>
- </tr>
- <tr>
- <td id="L193" class="blob-num js-line-number" data-line-number="193"></td>
- <td id="LC193" class="blob-code blob-code-inner js-file-line"># <span class="pl-k">define</span> <span class="pl-en">PTRDIFF_MAX</span> _I64_MAX</td>
- </tr>
- <tr>
- <td id="L194" class="blob-num js-line-number" data-line-number="194"></td>
- <td id="LC194" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">else</span> <span class="pl-c"><span class="pl-c">//</span> _WIN64 ][</span></td>
- </tr>
- <tr>
- <td id="L195" class="blob-num js-line-number" data-line-number="195"></td>
- <td id="LC195" class="blob-code blob-code-inner js-file-line"># <span class="pl-k">define</span> <span class="pl-en">PTRDIFF_MIN</span> _I32_MIN</td>
- </tr>
- <tr>
- <td id="L196" class="blob-num js-line-number" data-line-number="196"></td>
- <td id="LC196" class="blob-code blob-code-inner js-file-line"># <span class="pl-k">define</span> <span class="pl-en">PTRDIFF_MAX</span> _I32_MAX</td>
- </tr>
- <tr>
- <td id="L197" class="blob-num js-line-number" data-line-number="197"></td>
- <td id="LC197" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">endif</span> <span class="pl-c"><span class="pl-c">//</span> _WIN64 ]</span></td>
- </tr>
- <tr>
- <td id="L198" class="blob-num js-line-number" data-line-number="198"></td>
- <td id="LC198" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L199" class="blob-num js-line-number" data-line-number="199"></td>
- <td id="LC199" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">SIG_ATOMIC_MIN</span> INT_MIN</td>
- </tr>
- <tr>
- <td id="L200" class="blob-num js-line-number" data-line-number="200"></td>
- <td id="LC200" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">SIG_ATOMIC_MAX</span> INT_MAX</td>
- </tr>
- <tr>
- <td id="L201" class="blob-num js-line-number" data-line-number="201"></td>
- <td id="LC201" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L202" class="blob-num js-line-number" data-line-number="202"></td>
- <td id="LC202" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">ifndef</span> SIZE_MAX <span class="pl-c"><span class="pl-c">//</span> [</span></td>
- </tr>
- <tr>
- <td id="L203" class="blob-num js-line-number" data-line-number="203"></td>
- <td id="LC203" class="blob-code blob-code-inner js-file-line"># <span class="pl-k">ifdef</span> _WIN64 <span class="pl-c"><span class="pl-c">//</span> [</span></td>
- </tr>
- <tr>
- <td id="L204" class="blob-num js-line-number" data-line-number="204"></td>
- <td id="LC204" class="blob-code blob-code-inner js-file-line"># <span class="pl-k">define</span> <span class="pl-en">SIZE_MAX</span> _UI64_MAX</td>
- </tr>
- <tr>
- <td id="L205" class="blob-num js-line-number" data-line-number="205"></td>
- <td id="LC205" class="blob-code blob-code-inner js-file-line"># <span class="pl-k">else</span> <span class="pl-c"><span class="pl-c">//</span> _WIN64 ][</span></td>
- </tr>
- <tr>
- <td id="L206" class="blob-num js-line-number" data-line-number="206"></td>
- <td id="LC206" class="blob-code blob-code-inner js-file-line"># <span class="pl-k">define</span> <span class="pl-en">SIZE_MAX</span> _UI32_MAX</td>
- </tr>
- <tr>
- <td id="L207" class="blob-num js-line-number" data-line-number="207"></td>
- <td id="LC207" class="blob-code blob-code-inner js-file-line"># <span class="pl-k">endif</span> <span class="pl-c"><span class="pl-c">//</span> _WIN64 ]</span></td>
- </tr>
- <tr>
- <td id="L208" class="blob-num js-line-number" data-line-number="208"></td>
- <td id="LC208" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">endif</span> <span class="pl-c"><span class="pl-c">//</span> SIZE_MAX ]</span></td>
- </tr>
- <tr>
- <td id="L209" class="blob-num js-line-number" data-line-number="209"></td>
- <td id="LC209" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L210" class="blob-num js-line-number" data-line-number="210"></td>
- <td id="LC210" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> WCHAR_MIN and WCHAR_MAX are also defined in &lt;wchar.h&gt;</span></td>
- </tr>
- <tr>
- <td id="L211" class="blob-num js-line-number" data-line-number="211"></td>
- <td id="LC211" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">ifndef</span> WCHAR_MIN <span class="pl-c"><span class="pl-c">//</span> [</span></td>
- </tr>
- <tr>
- <td id="L212" class="blob-num js-line-number" data-line-number="212"></td>
- <td id="LC212" class="blob-code blob-code-inner js-file-line"># <span class="pl-k">define</span> <span class="pl-en">WCHAR_MIN</span> <span class="pl-c1">0</span></td>
- </tr>
- <tr>
- <td id="L213" class="blob-num js-line-number" data-line-number="213"></td>
- <td id="LC213" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">endif</span> <span class="pl-c"><span class="pl-c">//</span> WCHAR_MIN ]</span></td>
- </tr>
- <tr>
- <td id="L214" class="blob-num js-line-number" data-line-number="214"></td>
- <td id="LC214" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">ifndef</span> WCHAR_MAX <span class="pl-c"><span class="pl-c">//</span> [</span></td>
- </tr>
- <tr>
- <td id="L215" class="blob-num js-line-number" data-line-number="215"></td>
- <td id="LC215" class="blob-code blob-code-inner js-file-line"># <span class="pl-k">define</span> <span class="pl-en">WCHAR_MAX</span> _UI16_MAX</td>
- </tr>
- <tr>
- <td id="L216" class="blob-num js-line-number" data-line-number="216"></td>
- <td id="LC216" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">endif</span> <span class="pl-c"><span class="pl-c">//</span> WCHAR_MAX ]</span></td>
- </tr>
- <tr>
- <td id="L217" class="blob-num js-line-number" data-line-number="217"></td>
- <td id="LC217" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L218" class="blob-num js-line-number" data-line-number="218"></td>
- <td id="LC218" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">WINT_MIN</span> <span class="pl-c1">0</span></td>
- </tr>
- <tr>
- <td id="L219" class="blob-num js-line-number" data-line-number="219"></td>
- <td id="LC219" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">WINT_MAX</span> _UI16_MAX</td>
- </tr>
- <tr>
- <td id="L220" class="blob-num js-line-number" data-line-number="220"></td>
- <td id="LC220" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L221" class="blob-num js-line-number" data-line-number="221"></td>
- <td id="LC221" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">endif</span> <span class="pl-c"><span class="pl-c">//</span> __STDC_LIMIT_MACROS ]</span></td>
- </tr>
- <tr>
- <td id="L222" class="blob-num js-line-number" data-line-number="222"></td>
- <td id="LC222" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L223" class="blob-num js-line-number" data-line-number="223"></td>
- <td id="LC223" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L224" class="blob-num js-line-number" data-line-number="224"></td>
- <td id="LC224" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> 7.18.4 Limits of other integer types</span></td>
- </tr>
- <tr>
- <td id="L225" class="blob-num js-line-number" data-line-number="225"></td>
- <td id="LC225" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L226" class="blob-num js-line-number" data-line-number="226"></td>
- <td id="LC226" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">if</span> !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) <span class="pl-c"><span class="pl-c">//</span> [ See footnote 224 at page 260</span></td>
- </tr>
- <tr>
- <td id="L227" class="blob-num js-line-number" data-line-number="227"></td>
- <td id="LC227" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L228" class="blob-num js-line-number" data-line-number="228"></td>
- <td id="LC228" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> 7.18.4.1 Macros for minimum-width integer constants</span></td>
- </tr>
- <tr>
- <td id="L229" class="blob-num js-line-number" data-line-number="229"></td>
- <td id="LC229" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L230" class="blob-num js-line-number" data-line-number="230"></td>
- <td id="LC230" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT8_C</span>(<span class="pl-v">val</span>) val##i8</td>
- </tr>
- <tr>
- <td id="L231" class="blob-num js-line-number" data-line-number="231"></td>
- <td id="LC231" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT16_C</span>(<span class="pl-v">val</span>) val##i16</td>
- </tr>
- <tr>
- <td id="L232" class="blob-num js-line-number" data-line-number="232"></td>
- <td id="LC232" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT32_C</span>(<span class="pl-v">val</span>) val##i32</td>
- </tr>
- <tr>
- <td id="L233" class="blob-num js-line-number" data-line-number="233"></td>
- <td id="LC233" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INT64_C</span>(<span class="pl-v">val</span>) val##i64</td>
- </tr>
- <tr>
- <td id="L234" class="blob-num js-line-number" data-line-number="234"></td>
- <td id="LC234" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L235" class="blob-num js-line-number" data-line-number="235"></td>
- <td id="LC235" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">UINT8_C</span>(<span class="pl-v">val</span>) val##ui8</td>
- </tr>
- <tr>
- <td id="L236" class="blob-num js-line-number" data-line-number="236"></td>
- <td id="LC236" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">UINT16_C</span>(<span class="pl-v">val</span>) val##ui16</td>
- </tr>
- <tr>
- <td id="L237" class="blob-num js-line-number" data-line-number="237"></td>
- <td id="LC237" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">UINT32_C</span>(<span class="pl-v">val</span>) val##ui32</td>
- </tr>
- <tr>
- <td id="L238" class="blob-num js-line-number" data-line-number="238"></td>
- <td id="LC238" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">UINT64_C</span>(<span class="pl-v">val</span>) val##ui64</td>
- </tr>
- <tr>
- <td id="L239" class="blob-num js-line-number" data-line-number="239"></td>
- <td id="LC239" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L240" class="blob-num js-line-number" data-line-number="240"></td>
- <td id="LC240" class="blob-code blob-code-inner js-file-line"><span class="pl-c"><span class="pl-c">//</span> 7.18.4.2 Macros for greatest-width integer constants</span></td>
- </tr>
- <tr>
- <td id="L241" class="blob-num js-line-number" data-line-number="241"></td>
- <td id="LC241" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">INTMAX_C</span> INT64_C</td>
- </tr>
- <tr>
- <td id="L242" class="blob-num js-line-number" data-line-number="242"></td>
- <td id="LC242" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">define</span> <span class="pl-en">UINTMAX_C</span> UINT64_C</td>
- </tr>
- <tr>
- <td id="L243" class="blob-num js-line-number" data-line-number="243"></td>
- <td id="LC243" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L244" class="blob-num js-line-number" data-line-number="244"></td>
- <td id="LC244" class="blob-code blob-code-inner js-file-line">#<span class="pl-k">endif</span> <span class="pl-c"><span class="pl-c">//</span> __STDC_CONSTANT_MACROS ]</span></td>
- </tr>
- <tr>
- <td id="L245" class="blob-num js-line-number" data-line-number="245"></td>
- <td id="LC245" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L246" class="blob-num js-line-number" data-line-number="246"></td>
- <td id="LC246" class="blob-code blob-code-inner js-file-line">
-</td>
- </tr>
- <tr>
- <td id="L247" class="blob-num js-line-number" data-line-number="247"></td>
- <td id="LC247" class="blob-code blob-code-inner js-file-line">#endif <span class="pl-c"><span class="pl-c">//</span> _MSC_STDINT_H_ ]</span></td>
- </tr>
-</table>
-
- <div class="BlobToolbar position-absolute js-file-line-actions dropdown js-menu-container js-select-menu d-none" aria-hidden="true">
- <button class="btn-octicon ml-0 px-2 p-0 bg-white border border-gray-dark rounded-1 dropdown-toggle js-menu-target" id="js-file-line-action-button" type="button" aria-expanded="false" aria-haspopup="true" aria-label="Inline file action toolbar" aria-controls="inline-file-actions">
- <svg aria-hidden="true" class="octicon" height="16" version="1.1" viewBox="0 0 13 4" width="14">
- <g stroke="none" stroke-width="1" fill-rule="evenodd">
- <g transform="translate(-1.000000, -6.000000)">
- <path d="M2.5,9.5 C1.67157288,9.5 1,8.82842712 1,8 C1,7.17157288 1.67157288,6.5 2.5,6.5 C3.32842712,6.5 4,7.17157288 4,8 C4,8.82842712 3.32842712,9.5 2.5,9.5 Z M7.5,9.5 C6.67157288,9.5 6,8.82842712 6,8 C6,7.17157288 6.67157288,6.5 7.5,6.5 C8.32842712,6.5 9,7.17157288 9,8 C9,8.82842712 8.32842712,9.5 7.5,9.5 Z M12.5,9.5 C11.6715729,9.5 11,8.82842712 11,8 C11,7.17157288 11.6715729,6.5 12.5,6.5 C13.3284271,6.5 14,7.17157288 14,8 C14,8.82842712 13.3284271,9.5 12.5,9.5 Z"></path>
- </g>
- </g>
- </svg>
- </button>
- <div class="dropdown-menu-content js-menu-content" id="inline-file-actions">
- <ul class="BlobToolbar-dropdown dropdown-menu dropdown-menu-se mt-2">
- <li><a class="js-zeroclipboard dropdown-item" style="cursor:pointer;" id="js-copy-lines" data-original-text="Copy lines">Copy lines</a></li>
- <li><a class="js-zeroclipboard dropdown-item" id= "js-copy-permalink" style="cursor:pointer;" data-original-text="Copy permalink">Copy permalink</a></li>
- <li><a href="/mattn/gntp-send/blame/090b1276fb4a30601113551bed88c58329646818/include/msinttypes/stdint.h" class="dropdown-item js-update-url-with-hash" id="js-view-git-blame">View git blame</a></li>
- <li><a href="/mattn/gntp-send/issues/new" class="dropdown-item" id="js-new-issue">Open new issue</a></li>
- </ul>
- </div>
- </div>
-
- </div>
-
- </div>
-
- <button type="button" data-facebox="#jump-to-line" data-facebox-class="linejump" data-hotkey="l" class="d-none">Jump to Line</button>
- <div id="jump-to-line" style="display:none">
- <!-- '"` --><!-- </textarea></xmp> --></option></form><form accept-charset="UTF-8" action="" class="js-jump-to-line-form" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div>
- <input class="form-control linejump-input js-jump-to-line-field" type="text" placeholder="Jump to line&hellip;" aria-label="Jump to line" autofocus>
- <button type="submit" class="btn">Go</button>
-</form> </div>
-
- </div>
- <div class="modal-backdrop js-touch-events"></div>
-</div>
-
- </div>
- </div>
-
- </div>
-
-
-<div class="footer container-lg px-3" role="contentinfo">
- <div class="position-relative d-flex flex-justify-between py-6 mt-6 f6 text-gray border-top border-gray-light ">
- <ul class="list-style-none d-flex flex-wrap ">
- <li class="mr-3">&copy; 2017 <span title="0.12140s from unicorn-1420858540-p0bxs">GitHub</span>, Inc.</li>
- <li class="mr-3"><a href="https://github.com/site/terms" data-ga-click="Footer, go to terms, text:terms">Terms</a></li>
- <li class="mr-3"><a href="https://github.com/site/privacy" data-ga-click="Footer, go to privacy, text:privacy">Privacy</a></li>
- <li class="mr-3"><a href="https://github.com/security" data-ga-click="Footer, go to security, text:security">Security</a></li>
- <li class="mr-3"><a href="https://status.github.com/" data-ga-click="Footer, go to status, text:status">Status</a></li>
- <li><a href="https://help.github.com" data-ga-click="Footer, go to help, text:help">Help</a></li>
- </ul>
-
- <a href="https://github.com" aria-label="Homepage" class="footer-octicon" title="GitHub">
- <svg aria-hidden="true" class="octicon octicon-mark-github" height="24" version="1.1" viewBox="0 0 16 16" width="24"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"/></svg>
-</a>
- <ul class="list-style-none d-flex flex-wrap ">
- <li class="mr-3"><a href="https://github.com/contact" data-ga-click="Footer, go to contact, text:contact">Contact GitHub</a></li>
- <li class="mr-3"><a href="https://developer.github.com" data-ga-click="Footer, go to api, text:api">API</a></li>
- <li class="mr-3"><a href="https://training.github.com" data-ga-click="Footer, go to training, text:training">Training</a></li>
- <li class="mr-3"><a href="https://shop.github.com" data-ga-click="Footer, go to shop, text:shop">Shop</a></li>
- <li class="mr-3"><a href="https://github.com/blog" data-ga-click="Footer, go to blog, text:blog">Blog</a></li>
- <li><a href="https://github.com/about" data-ga-click="Footer, go to about, text:about">About</a></li>
-
- </ul>
- </div>
-</div>
-
-
-
- <div id="ajax-error-message" class="ajax-error-message flash flash-error">
- <svg aria-hidden="true" class="octicon octicon-alert" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-2V6h2v4z"/></svg>
- <button type="button" class="flash-close js-flash-close js-ajax-error-dismiss" aria-label="Dismiss error">
- <svg aria-hidden="true" class="octicon octicon-x" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"/></svg>
- </button>
- You can't perform that action at this time.
- </div>
-
-
-
- <script crossorigin="anonymous" integrity="sha256-Sxs+Reu4luxVVaYLalcHLGmPG0uGt2qgtP4QZ/RAsfM=" src="https://assets-cdn.github.com/assets/frameworks-4b1b3e45ebb896ec5555a60b6a57072c698f1b4b86b76aa0b4fe1067f440b1f3.js"></script>
-
- <script async="async" crossorigin="anonymous" integrity="sha256-rhTSU9vJG0Aq7OSJ05kyOeUQ/RwV/IBUApQ7VS8xXXM=" src="https://assets-cdn.github.com/assets/github-ae14d253dbc91b402aece489d3993239e510fd1c15fc805402943b552f315d73.js"></script>
-
-
-
-
- <div class="js-stale-session-flash stale-session-flash flash flash-warn flash-banner d-none">
- <svg aria-hidden="true" class="octicon octicon-alert" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-2V6h2v4z"/></svg>
- <span class="signed-in-tab-flash">You signed in with another tab or window. <a href="">Reload</a> to refresh your session.</span>
- <span class="signed-out-tab-flash">You signed out in another tab or window. <a href="">Reload</a> to refresh your session.</span>
- </div>
- <div class="facebox" id="facebox" style="display:none;">
- <div class="facebox-popup">
- <div class="facebox-content" role="dialog" aria-labelledby="facebox-header" aria-describedby="facebox-description">
- </div>
- <button type="button" class="facebox-close js-facebox-close" aria-label="Close modal">
- <svg aria-hidden="true" class="octicon octicon-x" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"/></svg>
- </button>
- </div>
-</div>
-
-
- </body>
-</html>
-
diff --git a/src/sat/glucose2/AbcGlucose2.cpp b/src/sat/glucose2/AbcGlucose2.cpp
new file mode 100644
index 00000000..9a8b97eb
--- /dev/null
+++ b/src/sat/glucose2/AbcGlucose2.cpp
@@ -0,0 +1,1543 @@
+/**CFile****************************************************************
+
+ FileName [AbcGlucose.cpp]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [SAT solver Glucose 3.0 by Gilles Audemard and Laurent Simon.]
+
+ Synopsis [Interface to Glucose.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 6, 2017.]
+
+ Revision [$Id: AbcGlucose.cpp,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sat/glucose2/System.h"
+#include "sat/glucose2/ParseUtils.h"
+#include "sat/glucose2/Options.h"
+#include "sat/glucose2/Dimacs.h"
+#include "sat/glucose2/SimpSolver.h"
+
+#include "sat/glucose2/AbcGlucose2.h"
+
+#include "base/abc/abc.h"
+#include "aig/gia/gia.h"
+#include "sat/cnf/cnf.h"
+#include "misc/extra/extra.h"
+
+ABC_NAMESPACE_IMPL_START
+
+using namespace Gluco2;
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define USE_SIMP_SOLVER 1
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#ifdef USE_SIMP_SOLVER
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+SimpSolver * glucose2_solver_start()
+{
+ SimpSolver * S = new SimpSolver;
+ S->setIncrementalMode();
+ return S;
+}
+
+void glucose2_solver_stop(Gluco2::SimpSolver* S)
+{
+ delete S;
+}
+
+void glucose2_solver_reset(Gluco2::SimpSolver* S)
+{
+ S->reset();
+}
+
+int glucose2_solver_addclause(Gluco2::SimpSolver* S, int * plits, int nlits)
+{
+ vec<Lit> lits;
+ for ( int i = 0; i < nlits; i++,plits++)
+ {
+ // note: Glucose uses the same var->lit conventiaon as ABC
+ while ((*plits)/2 >= S->nVars()) S->newVar();
+ assert((*plits)/2 < S->nVars()); // NOTE: since we explicitely use new function bmc_add_var
+ Lit p;
+ p.x = *plits;
+ lits.push(p);
+ }
+ return S->addClause(lits); // returns 0 if the problem is UNSAT
+}
+
+void glucose2_solver_setcallback(Gluco2::SimpSolver* S, void * pman, int(*pfunc)(void*, int, int*))
+{
+ S->pCnfMan = pman;
+ S->pCnfFunc = pfunc;
+ S->nCallConfl = 1000;
+}
+
+int glucose2_solver_solve(Gluco2::SimpSolver* S, int * plits, int nlits)
+{
+// vec<Lit> lits;
+// for (int i=0;i<nlits;i++,plits++)
+// {
+// Lit p;
+// p.x = *plits;
+// lits.push(p);
+// }
+// Gluco2::lbool res = S->solveLimited(lits, 0);
+// return (res == l_True ? 1 : res == l_False ? -1 : 0);
+ return S->solveLimited(plits, nlits, 0);
+}
+
+int glucose2_solver_addvar(Gluco2::SimpSolver* S)
+{
+ S->newVar();
+ return S->nVars() - 1;
+}
+
+int * glucose2_solver_read_cex(Gluco2::SimpSolver* S )
+{
+ return S->getCex();
+}
+
+int glucose2_solver_read_cex_varvalue(Gluco2::SimpSolver* S, int ivar)
+{
+ return S->model[ivar] == l_True;
+}
+
+void glucose2_solver_setstop(Gluco2::SimpSolver* S, int * pstop)
+{
+ S->pstop = pstop;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Wrapper APIs to calling from ABC.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bmcg2_sat_solver * bmcg2_sat_solver_start()
+{
+ return (bmcg2_sat_solver *)glucose2_solver_start();
+}
+void bmcg2_sat_solver_stop(bmcg2_sat_solver* s)
+{
+ glucose2_solver_stop((Gluco2::SimpSolver*)s);
+}
+void bmcg2_sat_solver_reset(bmcg2_sat_solver* s)
+{
+ glucose2_solver_reset((Gluco2::SimpSolver*)s);
+}
+
+
+int bmcg2_sat_solver_addclause(bmcg2_sat_solver* s, int * plits, int nlits)
+{
+ return glucose2_solver_addclause((Gluco2::SimpSolver*)s,plits,nlits);
+}
+
+void bmcg2_sat_solver_setcallback(bmcg2_sat_solver* s, void * pman, int(*pfunc)(void*, int, int*))
+{
+ glucose2_solver_setcallback((Gluco2::SimpSolver*)s,pman,pfunc);
+}
+
+int bmcg2_sat_solver_solve(bmcg2_sat_solver* s, int * plits, int nlits)
+{
+ return glucose2_solver_solve((Gluco2::SimpSolver*)s,plits,nlits);
+}
+
+int bmcg2_sat_solver_final(bmcg2_sat_solver* s, int ** ppArray)
+{
+ *ppArray = (int *)(Lit *)((Gluco2::SimpSolver*)s)->conflict;
+ return ((Gluco2::SimpSolver*)s)->conflict.size();
+}
+
+int bmcg2_sat_solver_addvar(bmcg2_sat_solver* s)
+{
+ return glucose2_solver_addvar((Gluco2::SimpSolver*)s);
+}
+
+void bmcg2_sat_solver_set_nvars( bmcg2_sat_solver* s, int nvars )
+{
+ int i;
+ for ( i = bmcg2_sat_solver_varnum(s); i < nvars; i++ )
+ bmcg2_sat_solver_addvar(s);
+}
+
+int bmcg2_sat_solver_eliminate( bmcg2_sat_solver* s, int turn_off_elim )
+{
+// return 1;
+ return ((Gluco2::SimpSolver*)s)->eliminate(turn_off_elim != 0);
+}
+
+int bmcg2_sat_solver_var_is_elim( bmcg2_sat_solver* s, int v )
+{
+// return 0;
+ return ((Gluco2::SimpSolver*)s)->isEliminated(v);
+}
+
+void bmcg2_sat_solver_var_set_frozen( bmcg2_sat_solver* s, int v, int freeze )
+{
+ ((Gluco2::SimpSolver*)s)->setFrozen(v, freeze != 0);
+}
+
+int bmcg2_sat_solver_elim_varnum(bmcg2_sat_solver* s)
+{
+// return 0;
+ return ((Gluco2::SimpSolver*)s)->eliminated_vars;
+}
+
+int * bmcg2_sat_solver_read_cex(bmcg2_sat_solver* s)
+{
+ return glucose2_solver_read_cex((Gluco2::SimpSolver*)s);
+}
+int bmcg2_sat_solver_read_cex_varvalue(bmcg2_sat_solver* s, int ivar)
+{
+ return glucose2_solver_read_cex_varvalue((Gluco2::SimpSolver*)s, ivar);
+}
+
+void bmcg2_sat_solver_set_stop(bmcg2_sat_solver* s, int * pstop)
+{
+ glucose2_solver_setstop((Gluco2::SimpSolver*)s, pstop);
+}
+
+abctime bmcg2_sat_solver_set_runtime_limit(bmcg2_sat_solver* s, abctime Limit)
+{
+ abctime nRuntimeLimit = ((Gluco2::SimpSolver*)s)->nRuntimeLimit;
+ ((Gluco2::SimpSolver*)s)->nRuntimeLimit = Limit;
+ return nRuntimeLimit;
+}
+
+void bmcg2_sat_solver_set_conflict_budget(bmcg2_sat_solver* s, int Limit)
+{
+ if ( Limit > 0 )
+ ((Gluco2::SimpSolver*)s)->setConfBudget( (int64_t)Limit );
+ else
+ ((Gluco2::SimpSolver*)s)->budgetOff();
+}
+
+int bmcg2_sat_solver_varnum(bmcg2_sat_solver* s)
+{
+ return ((Gluco2::SimpSolver*)s)->nVars();
+}
+int bmcg2_sat_solver_clausenum(bmcg2_sat_solver* s)
+{
+ return ((Gluco2::SimpSolver*)s)->nClauses();
+}
+int bmcg2_sat_solver_learntnum(bmcg2_sat_solver* s)
+{
+ return ((Gluco2::SimpSolver*)s)->nLearnts();
+}
+int bmcg2_sat_solver_conflictnum(bmcg2_sat_solver* s)
+{
+ return ((Gluco2::SimpSolver*)s)->conflicts;
+}
+
+int bmcg2_sat_solver_minimize_assumptions( bmcg2_sat_solver * s, int * plits, int nlits, int pivot )
+{
+ vec<int>*array = &((Gluco2::SimpSolver*)s)->user_vec;
+ int i, nlitsL, nlitsR, nresL, nresR, status;
+ assert( pivot >= 0 );
+// assert( nlits - pivot >= 2 );
+ assert( nlits - pivot >= 1 );
+ if ( nlits - pivot == 1 )
+ {
+ // since the problem is UNSAT, we try to solve it without assuming the last literal
+ // if the result is UNSAT, the last literal can be dropped; otherwise, it is needed
+ status = bmcg2_sat_solver_solve( s, plits, pivot );
+ return status != GLUCOSE_UNSAT; // return 1 if the problem is not UNSAT
+ }
+ assert( nlits - pivot >= 2 );
+ nlitsL = (nlits - pivot) / 2;
+ nlitsR = (nlits - pivot) - nlitsL;
+ assert( nlitsL + nlitsR == nlits - pivot );
+ // solve with these assumptions
+ status = bmcg2_sat_solver_solve( s, plits, pivot + nlitsL );
+ if ( status == GLUCOSE_UNSAT ) // these are enough
+ return bmcg2_sat_solver_minimize_assumptions( s, plits, pivot + nlitsL, pivot );
+ // these are not enough
+ // solve for the right lits
+// nResL = nLitsR == 1 ? 1 : sat_solver_minimize_assumptions( s, pLits + nLitsL, nLitsR, nConfLimit );
+ nresL = nlitsR == 1 ? 1 : bmcg2_sat_solver_minimize_assumptions( s, plits, nlits, pivot + nlitsL );
+ // swap literals
+ array->clear();
+ for ( i = 0; i < nlitsL; i++ )
+ array->push(plits[pivot + i]);
+ for ( i = 0; i < nresL; i++ )
+ plits[pivot + i] = plits[pivot + nlitsL + i];
+ for ( i = 0; i < nlitsL; i++ )
+ plits[pivot + nresL + i] = (*array)[i];
+ // solve with these assumptions
+ status = bmcg2_sat_solver_solve( s, plits, pivot + nresL );
+ if ( status == GLUCOSE_UNSAT ) // these are enough
+ return nresL;
+ // solve for the left lits
+// nResR = nLitsL == 1 ? 1 : sat_solver_minimize_assumptions( s, pLits + nResL, nLitsL, nConfLimit );
+ nresR = nlitsL == 1 ? 1 : bmcg2_sat_solver_minimize_assumptions( s, plits, pivot + nresL + nlitsL, pivot + nresL );
+ return nresL + nresR;
+}
+
+int bmcg2_sat_solver_add_and( bmcg2_sat_solver * s, int iVar, int iVar0, int iVar1, int fCompl0, int fCompl1, int fCompl )
+{
+ int Lits[3];
+
+ Lits[0] = Abc_Var2Lit( iVar, !fCompl );
+ Lits[1] = Abc_Var2Lit( iVar0, fCompl0 );
+ if ( !bmcg2_sat_solver_addclause( s, Lits, 2 ) )
+ return 0;
+
+ Lits[0] = Abc_Var2Lit( iVar, !fCompl );
+ Lits[1] = Abc_Var2Lit( iVar1, fCompl1 );
+ if ( !bmcg2_sat_solver_addclause( s, Lits, 2 ) )
+ return 0;
+
+ Lits[0] = Abc_Var2Lit( iVar, fCompl );
+ Lits[1] = Abc_Var2Lit( iVar0, !fCompl0 );
+ Lits[2] = Abc_Var2Lit( iVar1, !fCompl1 );
+ if ( !bmcg2_sat_solver_addclause( s, Lits, 3 ) )
+ return 0;
+
+ return 1;
+}
+
+int bmcg2_sat_solver_add_xor( bmcg2_sat_solver * pSat, int iVarA, int iVarB, int iVarC, int fCompl )
+{
+ int Lits[3];
+ int Cid;
+ assert( iVarA >= 0 && iVarB >= 0 && iVarC >= 0 );
+
+ Lits[0] = Abc_Var2Lit( iVarA, !fCompl );
+ Lits[1] = Abc_Var2Lit( iVarB, 1 );
+ Lits[2] = Abc_Var2Lit( iVarC, 1 );
+ Cid = bmcg2_sat_solver_addclause( pSat, Lits, 3 );
+ assert( Cid );
+
+ Lits[0] = Abc_Var2Lit( iVarA, !fCompl );
+ Lits[1] = Abc_Var2Lit( iVarB, 0 );
+ Lits[2] = Abc_Var2Lit( iVarC, 0 );
+ Cid = bmcg2_sat_solver_addclause( pSat, Lits, 3 );
+ assert( Cid );
+
+ Lits[0] = Abc_Var2Lit( iVarA, fCompl );
+ Lits[1] = Abc_Var2Lit( iVarB, 1 );
+ Lits[2] = Abc_Var2Lit( iVarC, 0 );
+ Cid = bmcg2_sat_solver_addclause( pSat, Lits, 3 );
+ assert( Cid );
+
+ Lits[0] = Abc_Var2Lit( iVarA, fCompl );
+ Lits[1] = Abc_Var2Lit( iVarB, 0 );
+ Lits[2] = Abc_Var2Lit( iVarC, 1 );
+ Cid = bmcg2_sat_solver_addclause( pSat, Lits, 3 );
+ assert( Cid );
+ return 4;
+}
+
+int bmcg2_sat_solver_jftr(bmcg2_sat_solver* s)
+{
+ return ((Gluco2::SimpSolver*)s)->jftr;
+}
+
+void bmcg2_sat_solver_set_jftr(bmcg2_sat_solver* s, int jftr)
+{
+ ((Gluco2::SimpSolver*)s)->jftr = jftr;
+}
+
+void bmcg2_sat_solver_set_var_fanin_lit(bmcg2_sat_solver* s, int var, int lit0, int lit1)
+{
+ ((Gluco2::SimpSolver*)s)->sat_solver_set_var_fanin_lit(var, lit0, lit1);
+}
+
+void bmcg2_sat_solver_start_new_round(bmcg2_sat_solver* s)
+{
+ ((Gluco2::SimpSolver*)s)->sat_solver_start_new_round();
+}
+
+void bmcg2_sat_solver_mark_cone(bmcg2_sat_solver* s, int var)
+{
+ ((Gluco2::SimpSolver*)s)->sat_solver_mark_cone(var);
+}
+
+void bmcg2_sat_solver_prelocate( bmcg2_sat_solver * s, int var_num ){
+ ((Gluco2::SimpSolver*)s)->prelocate(var_num);
+}
+
+#else
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Solver * glucose2_solver_start()
+{
+ Solver * S = new Solver;
+ S->setIncrementalMode();
+ return S;
+}
+
+void glucose2_solver_stop(Gluco2::Solver* S)
+{
+ delete S;
+}
+
+void glucose2_solver_reset(Gluco2::Solver* S)
+{
+ S->reset();
+}
+
+int glucose2_solver_addclause(Gluco2::Solver* S, int * plits, int nlits)
+{
+ vec<Lit> lits;
+ for ( int i = 0; i < nlits; i++,plits++)
+ {
+ // note: Glucose uses the same var->lit conventiaon as ABC
+ while ((*plits)/2 >= S->nVars()) S->newVar();
+ assert((*plits)/2 < S->nVars()); // NOTE: since we explicitely use new function bmc_add_var
+ Lit p;
+ p.x = *plits;
+ lits.push(p);
+ }
+ return S->addClause(lits); // returns 0 if the problem is UNSAT
+}
+
+void glucose2_solver_setcallback(Gluco2::Solver* S, void * pman, int(*pfunc)(void*, int, int*))
+{
+ S->pCnfMan = pman;
+ S->pCnfFunc = pfunc;
+ S->nCallConfl = 1000;
+}
+
+int glucose2_solver_solve(Gluco2::Solver* S, int * plits, int nlits)
+{
+ vec<Lit> lits;
+ for (int i=0;i<nlits;i++,plits++)
+ {
+ Lit p;
+ p.x = *plits;
+ lits.push(p);
+ }
+ Gluco2::lbool res = S->solveLimited(lits);
+ return (res == l_True ? 1 : res == l_False ? -1 : 0);
+}
+
+int glucose2_solver_addvar(Gluco2::Solver* S)
+{
+ S->newVar();
+ return S->nVars() - 1;
+}
+
+int * glucose2_solver_read_cex(Gluco2::Solver* S )
+{
+ return S->getCex();
+}
+
+int glucose2_solver_read_cex_varvalue(Gluco2::Solver* S, int ivar)
+{
+ return S->model[ivar] == l_True;
+}
+
+void glucose2_solver_setstop(Gluco2::Solver* S, int * pstop)
+{
+ S->pstop = pstop;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Wrapper APIs to calling from ABC.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bmcg2_sat_solver * bmcg2_sat_solver_start()
+{
+ return (bmcg2_sat_solver *)glucose2_solver_start();
+}
+void bmcg2_sat_solver_stop(bmcg2_sat_solver* s)
+{
+ glucose2_solver_stop((Gluco2::Solver*)s);
+}
+void bmcg2_sat_solver_reset(bmcg2_sat_solver* s)
+{
+ glucose2_solver_reset((Gluco2::Solver*)s);
+}
+
+int bmcg2_sat_solver_addclause(bmcg2_sat_solver* s, int * plits, int nlits)
+{
+ return glucose2_solver_addclause((Gluco2::Solver*)s,plits,nlits);
+}
+
+void bmcg2_sat_solver_setcallback(bmcg2_sat_solver* s, void * pman, int(*pfunc)(void*, int, int*))
+{
+ glucose2_solver_setcallback((Gluco2::Solver*)s,pman,pfunc);
+}
+
+int bmcg2_sat_solver_solve(bmcg2_sat_solver* s, int * plits, int nlits)
+{
+ return glucose2_solver_solve((Gluco2::Solver*)s,plits,nlits);
+}
+
+int bmcg2_sat_solver_final(bmcg2_sat_solver* s, int ** ppArray)
+{
+ *ppArray = (int *)(Lit *)((Gluco2::Solver*)s)->conflict;
+ return ((Gluco2::Solver*)s)->conflict.size();
+}
+
+int bmcg2_sat_solver_addvar(bmcg2_sat_solver* s)
+{
+ return glucose2_solver_addvar((Gluco2::Solver*)s);
+}
+
+void bmcg2_sat_solver_set_nvars( bmcg2_sat_solver* s, int nvars )
+{
+ int i;
+ for ( i = bmcg2_sat_solver_varnum(s); i < nvars; i++ )
+ bmcg2_sat_solver_addvar(s);
+}
+
+int bmcg2_sat_solver_eliminate( bmcg2_sat_solver* s, int turn_off_elim )
+{
+ return 1;
+// return ((Gluco2::SimpSolver*)s)->eliminate(turn_off_elim != 0);
+}
+
+int bmcg2_sat_solver_var_is_elim( bmcg2_sat_solver* s, int v )
+{
+ return 0;
+// return ((Gluco2::SimpSolver*)s)->isEliminated(v);
+}
+
+void bmcg2_sat_solver_var_set_frozen( bmcg2_sat_solver* s, int v, int freeze )
+{
+// ((Gluco2::SimpSolver*)s)->setFrozen(v, freeze);
+}
+
+int bmcg2_sat_solver_elim_varnum(bmcg2_sat_solver* s)
+{
+ return 0;
+// return ((Gluco2::SimpSolver*)s)->eliminated_vars;
+}
+
+int * bmcg2_sat_solver_read_cex(bmcg2_sat_solver* s)
+{
+ return glucose2_solver_read_cex((Gluco2::Solver*)s);
+}
+
+int bmcg2_sat_solver_read_cex_varvalue(bmcg2_sat_solver* s, int ivar)
+{
+ return glucose2_solver_read_cex_varvalue((Gluco2::Solver*)s, ivar);
+}
+
+void bmcg2_sat_solver_set_stop(bmcg2_sat_solver* s, int * pstop)
+{
+ glucose2_solver_setstop((Gluco2::Solver*)s, pstop);
+}
+
+abctime bmcg2_sat_solver_set_runtime_limit(bmcg2_sat_solver* s, abctime Limit)
+{
+ abctime nRuntimeLimit = ((Gluco2::Solver*)s)->nRuntimeLimit;
+ ((Gluco2::Solver*)s)->nRuntimeLimit = Limit;
+ return nRuntimeLimit;
+}
+
+void bmcg2_sat_solver_set_conflict_budget(bmcg2_sat_solver* s, int Limit)
+{
+ if ( Limit > 0 )
+ ((Gluco2::Solver*)s)->setConfBudget( (int64_t)Limit );
+ else
+ ((Gluco2::Solver*)s)->budgetOff();
+}
+
+int bmcg2_sat_solver_varnum(bmcg2_sat_solver* s)
+{
+ return ((Gluco2::Solver*)s)->nVars();
+}
+int bmcg2_sat_solver_clausenum(bmcg2_sat_solver* s)
+{
+ return ((Gluco2::Solver*)s)->nClauses();
+}
+int bmcg2_sat_solver_learntnum(bmcg2_sat_solver* s)
+{
+ return ((Gluco2::Solver*)s)->nLearnts();
+}
+int bmcg2_sat_solver_conflictnum(bmcg2_sat_solver* s)
+{
+ return ((Gluco2::Solver*)s)->conflicts;
+}
+
+int bmcg2_sat_solver_minimize_assumptions( bmcg2_sat_solver * s, int * plits, int nlits, int pivot )
+{
+ vec<int>*array = &((Gluco2::Solver*)s)->user_vec;
+ int i, nlitsL, nlitsR, nresL, nresR, status;
+ assert( pivot >= 0 );
+// assert( nlits - pivot >= 2 );
+ assert( nlits - pivot >= 1 );
+ if ( nlits - pivot == 1 )
+ {
+ // since the problem is UNSAT, we try to solve it without assuming the last literal
+ // if the result is UNSAT, the last literal can be dropped; otherwise, it is needed
+ status = bmcg2_sat_solver_solve( s, plits, pivot );
+ return status != GLUCOSE_UNSAT; // return 1 if the problem is not UNSAT
+ }
+ assert( nlits - pivot >= 2 );
+ nlitsL = (nlits - pivot) / 2;
+ nlitsR = (nlits - pivot) - nlitsL;
+ assert( nlitsL + nlitsR == nlits - pivot );
+ // solve with these assumptions
+ status = bmcg2_sat_solver_solve( s, plits, pivot + nlitsL );
+ if ( status == GLUCOSE_UNSAT ) // these are enough
+ return bmcg2_sat_solver_minimize_assumptions( s, plits, pivot + nlitsL, pivot );
+ // these are not enough
+ // solve for the right lits
+// nResL = nLitsR == 1 ? 1 : sat_solver_minimize_assumptions( s, pLits + nLitsL, nLitsR, nConfLimit );
+ nresL = nlitsR == 1 ? 1 : bmcg2_sat_solver_minimize_assumptions( s, plits, nlits, pivot + nlitsL );
+ // swap literals
+ array->clear();
+ for ( i = 0; i < nlitsL; i++ )
+ array->push(plits[pivot + i]);
+ for ( i = 0; i < nresL; i++ )
+ plits[pivot + i] = plits[pivot + nlitsL + i];
+ for ( i = 0; i < nlitsL; i++ )
+ plits[pivot + nresL + i] = (*array)[i];
+ // solve with these assumptions
+ status = bmcg2_sat_solver_solve( s, plits, pivot + nresL );
+ if ( status == GLUCOSE_UNSAT ) // these are enough
+ return nresL;
+ // solve for the left lits
+// nResR = nLitsL == 1 ? 1 : sat_solver_minimize_assumptions( s, pLits + nResL, nLitsL, nConfLimit );
+ nresR = nlitsL == 1 ? 1 : bmcg2_sat_solver_minimize_assumptions( s, plits, pivot + nresL + nlitsL, pivot + nresL );
+ return nresL + nresR;
+}
+
+int bmcg2_sat_solver_add_and( bmcg2_sat_solver * s, int iVar, int iVar0, int iVar1, int fCompl0, int fCompl1, int fCompl )
+{
+ int Lits[3];
+
+ Lits[0] = Abc_Var2Lit( iVar, !fCompl );
+ Lits[1] = Abc_Var2Lit( iVar0, fCompl0 );
+ if ( !bmcg2_sat_solver_addclause( s, Lits, 2 ) )
+ return 0;
+
+ Lits[0] = Abc_Var2Lit( iVar, !fCompl );
+ Lits[1] = Abc_Var2Lit( iVar1, fCompl1 );
+ if ( !bmcg2_sat_solver_addclause( s, Lits, 2 ) )
+ return 0;
+
+ Lits[0] = Abc_Var2Lit( iVar, fCompl );
+ Lits[1] = Abc_Var2Lit( iVar0, !fCompl0 );
+ Lits[2] = Abc_Var2Lit( iVar1, !fCompl1 );
+ if ( !bmcg2_sat_solver_addclause( s, Lits, 3 ) )
+ return 0;
+
+ return 1;
+}
+
+int bmcg2_solver_add_xor( bmcg2_sat_solver * pSat, int iVarA, int iVarB, int iVarC, int fCompl )
+{
+ int Lits[3];
+ int Cid;
+ assert( iVarA >= 0 && iVarB >= 0 && iVarC >= 0 );
+
+ Lits[0] = Abc_Var2Lit( iVarA, !fCompl );
+ Lits[1] = Abc_Var2Lit( iVarB, 1 );
+ Lits[2] = Abc_Var2Lit( iVarC, 1 );
+ Cid = bmcg2_sat_solver_addclause( pSat, Lits, 3 );
+ assert( Cid );
+
+ Lits[0] = Abc_Var2Lit( iVarA, !fCompl );
+ Lits[1] = Abc_Var2Lit( iVarB, 0 );
+ Lits[2] = Abc_Var2Lit( iVarC, 0 );
+ Cid = bmcg2_sat_solver_addclause( pSat, Lits, 3 );
+ assert( Cid );
+
+ Lits[0] = Abc_Var2Lit( iVarA, fCompl );
+ Lits[1] = Abc_Var2Lit( iVarB, 1 );
+ Lits[2] = Abc_Var2Lit( iVarC, 0 );
+ Cid = bmcg2_sat_solver_addclause( pSat, Lits, 3 );
+ assert( Cid );
+
+ Lits[0] = Abc_Var2Lit( iVarA, fCompl );
+ Lits[1] = Abc_Var2Lit( iVarB, 0 );
+ Lits[2] = Abc_Var2Lit( iVarC, 1 );
+ Cid = bmcg2_sat_solver_addclause( pSat, Lits, 3 );
+ assert( Cid );
+ return 4;
+}
+
+int bmcg2_sat_solver_jftr(bmcg2_sat_solver* s)
+{
+ return ((Gluco2::Solver*)s)->jftr;
+}
+
+void bmcg2_sat_solver_set_jftr(bmcg2_sat_solver* s, int jftr)
+{
+ ((Gluco2::Solver*)s)->jftr = jftr;
+}
+
+void bmcg2_sat_solver_set_var_fanin_lit(bmcg2_sat_solver* s, int var, int lit0, int lit1)
+{
+ ((Gluco2::Solver*)s)->sat_solver_set_var_fanin_lit(var, lit0, lit1);
+}
+
+void bmcg2_sat_solver_start_new_round(bmcg2_sat_solver* s)
+{
+ ((Gluco2::Solver*)s)->sat_solver_start_new_round();
+}
+
+void bmcg2_sat_solver_mark_cone(bmcg2_sat_solver* s, int var)
+{
+ ((Gluco2::Solver*)s)->sat_solver_mark_cone(var);
+}
+
+void bmcg2_sat_solver_prelocate( bmcg2_sat_solver * s, int var_num ){
+ ((Gluco2::Solver*)s)->prelocate(var_num);
+}
+
+#endif
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void glucose2_print_stats(SimpSolver& s, abctime clk)
+{
+ double cpu_time = (double)(unsigned)clk / CLOCKS_PER_SEC;
+ double mem_used = memUsed();
+ printf("c restarts : %d (%d conflicts on average)\n", (int)s.starts, s.starts > 0 ? (int)(s.conflicts/s.starts) : 0);
+ printf("c blocked restarts : %d (multiple: %d) \n", (int)s.nbstopsrestarts, (int)s.nbstopsrestartssame);
+ printf("c last block at restart : %d\n", (int)s.lastblockatrestart);
+ printf("c nb ReduceDB : %-12d\n", (int)s.nbReduceDB);
+ printf("c nb removed Clauses : %-12d\n", (int)s.nbRemovedClauses);
+ printf("c nb learnts DL2 : %-12d\n", (int)s.nbDL2);
+ printf("c nb learnts size 2 : %-12d\n", (int)s.nbBin);
+ printf("c nb learnts size 1 : %-12d\n", (int)s.nbUn);
+ printf("c conflicts : %-12d (%.0f /sec)\n", (int)s.conflicts, s.conflicts /cpu_time);
+ printf("c decisions : %-12d (%4.2f %% random) (%.0f /sec)\n", (int)s.decisions, (float)s.rnd_decisions*100 / (float)s.decisions, s.decisions /cpu_time);
+ printf("c propagations : %-12d (%.0f /sec)\n", (int)s.propagations, s.propagations/cpu_time);
+ printf("c conflict literals : %-12d (%4.2f %% deleted)\n", (int)s.tot_literals, (s.max_literals - s.tot_literals)*100 / (double)s.max_literals);
+ printf("c nb reduced Clauses : %-12d\n", (int)s.nbReducedClauses);
+ if (mem_used != 0) printf("Memory used : %.2f MB\n", mem_used);
+ //printf("c CPU time : %.2f sec\n", cpu_time);
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Glucose_ReadDimacs( char * pFileName, SimpSolver& s )
+{
+ vec<Lit> * lits = &s.user_lits;
+ char * pBuffer = Extra_FileReadContents( pFileName );
+ char * pTemp; int fComp, Var, VarMax = 0;
+ lits->clear();
+ for ( pTemp = pBuffer; *pTemp; pTemp++ )
+ {
+ if ( *pTemp == 'c' || *pTemp == 'p' ) {
+ while ( *pTemp != '\n' )
+ pTemp++;
+ continue;
+ }
+ while ( *pTemp == ' ' || *pTemp == '\t' || *pTemp == '\r' || *pTemp == '\n' )
+ pTemp++;
+ fComp = 0;
+ if ( *pTemp == '-' )
+ fComp = 1, pTemp++;
+ if ( *pTemp == '+' )
+ pTemp++;
+ Var = atoi( pTemp );
+ if ( Var == 0 ) {
+ if ( lits->size() > 0 ) {
+ s.addVar( VarMax );
+ s.addClause(*lits);
+ lits->clear();
+ }
+ }
+ else {
+ Var--;
+ VarMax = Abc_MaxInt( VarMax, Var );
+ lits->push( toLit(Abc_Var2Lit(Var, fComp)) );
+ }
+ while ( *pTemp >= '0' && *pTemp <= '9' )
+ pTemp++;
+ }
+ ABC_FREE( pBuffer );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Glucose2_SolveCnf( char * pFileName, Glucose2_Pars * pPars )
+{
+ abctime clk = Abc_Clock();
+
+ SimpSolver S;
+ S.verbosity = pPars->verb;
+ S.setConfBudget( pPars->nConfls > 0 ? (int64_t)pPars->nConfls : -1 );
+
+// gzFile in = gzopen(pFilename, "rb");
+// parse_DIMACS(in, S);
+// gzclose(in);
+ Glucose_ReadDimacs( pFileName, S );
+
+ if ( pPars->verb )
+ {
+ printf("c ============================[ Problem Statistics ]=============================\n");
+ printf("c | |\n");
+ printf("c | Number of variables: %12d |\n", S.nVars());
+ printf("c | Number of clauses: %12d |\n", S.nClauses());
+ }
+
+ if ( pPars->pre )
+ {
+ S.eliminate(true);
+ printf( "c Simplication removed %d variables and %d clauses. ", S.eliminated_vars, S.eliminated_clauses );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ }
+
+ vec<Lit> dummy;
+ lbool ret = S.solveLimited(dummy, 0);
+ if ( pPars->verb ) glucose2_print_stats(S, Abc_Clock() - clk);
+ printf(ret == l_True ? "SATISFIABLE" : ret == l_False ? "UNSATISFIABLE" : "INDETERMINATE");
+ Abc_PrintTime( 1, " Time", Abc_Clock() - clk );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Glucose_SolverFromAig( Gia_Man_t * p, SimpSolver& s )
+{
+ abctime clk = Abc_Clock();
+ vec<Lit> * lits = &s.user_lits;
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8 /*nLutSize*/, 0 /*fCnfObjIds*/, 1/*fAddOrCla*/, 0, 0/*verbose*/ );
+ for ( int i = 0; i < pCnf->nClauses; i++ )
+ {
+ lits->clear();
+ for ( int * pLit = pCnf->pClauses[i]; pLit < pCnf->pClauses[i+1]; pLit++ )
+ lits->push( toLit(*pLit) ), s.addVar( *pLit >> 1 );
+ s.addClause(*lits);
+ }
+ Vec_Int_t * vCnfIds = Vec_IntAllocArrayCopy(pCnf->pVarNums,pCnf->nVars);
+ printf( "CNF stats: Vars = %6d. Clauses = %7d. Literals = %8d. ", pCnf->nVars, pCnf->nClauses, pCnf->nLiterals );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ Cnf_DataFree(pCnf);
+ return vCnfIds;
+}
+
+// procedure below does not work because glucose2_solver_addclause() expects Solver
+Vec_Int_t * Glucose_SolverFromAig2( Gia_Man_t * p, SimpSolver& S )
+{
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8 /*nLutSize*/, 0 /*fCnfObjIds*/, 1/*fAddOrCla*/, 0, 0/*verbose*/ );
+ for ( int i = 0; i < pCnf->nClauses; i++ )
+ if ( !glucose2_solver_addclause( &S, pCnf->pClauses[i], pCnf->pClauses[i+1]-pCnf->pClauses[i] ) )
+ assert( 0 );
+ Vec_Int_t * vCnfIds = Vec_IntAllocArrayCopy(pCnf->pVarNums,pCnf->nVars);
+ //printf( "CNF stats: Vars = %6d. Clauses = %7d. Literals = %8d. ", pCnf->nVars, pCnf->nClauses, pCnf->nLiterals );
+ //Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ Cnf_DataFree(pCnf);
+ return vCnfIds;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Str_t * Glucose2_GenerateCubes( bmcg2_sat_solver * pSat[2], Vec_Int_t * vCiSatVars, Vec_Int_t * vVar2Index, int CubeLimit )
+{
+ int fCreatePrime = 1;
+ int nCubes, nSupp = Vec_IntSize(vCiSatVars);
+ Vec_Str_t * vSop = Vec_StrAlloc( 1000 );
+ Vec_Int_t * vLits = Vec_IntAlloc( nSupp );
+ Vec_Str_t * vCube = Vec_StrAlloc( nSupp + 4 );
+ Vec_StrFill( vCube, nSupp, '-' );
+ Vec_StrPrintF( vCube, " 1\n\0" );
+ for ( nCubes = 0; !CubeLimit || nCubes < CubeLimit; nCubes++ )
+ {
+ int * pFinal, nFinal, iVar, i, k = 0;
+ // generate onset minterm
+ int status = bmcg2_sat_solver_solve( pSat[1], NULL, 0 );
+ if ( status == GLUCOSE_UNSAT )
+ break;
+ assert( status == GLUCOSE_SAT );
+ Vec_IntClear( vLits );
+ Vec_IntForEachEntry( vCiSatVars, iVar, i )
+ Vec_IntPush( vLits, Abc_Var2Lit(iVar, !bmcg2_sat_solver_read_cex_varvalue(pSat[1], iVar)) );
+ // expand against offset
+ if ( fCreatePrime )
+ {
+ nFinal = bmcg2_sat_solver_minimize_assumptions( pSat[0], Vec_IntArray(vLits), Vec_IntSize(vLits), 0 );
+ Vec_IntShrink( vLits, nFinal );
+ pFinal = Vec_IntArray( vLits );
+ for ( i = 0; i < nFinal; i++ )
+ pFinal[i] = Abc_LitNot(pFinal[i]);
+ }
+ else
+ {
+ status = bmcg2_sat_solver_solve( pSat[0], Vec_IntArray(vLits), Vec_IntSize(vLits) );
+ assert( status == GLUCOSE_UNSAT );
+ nFinal = bmcg2_sat_solver_final( pSat[0], &pFinal );
+ }
+ // print cube
+ Vec_StrFill( vCube, nSupp, '-' );
+ for ( i = 0; i < nFinal; i++ )
+ {
+ int Index = Vec_IntEntry(vVar2Index, Abc_Lit2Var(pFinal[i]));
+ if ( Index == -1 )
+ continue;
+ pFinal[k++] = pFinal[i];
+ assert( Index >= 0 && Index < nSupp );
+ Vec_StrWriteEntry( vCube, Index, (char)('0' + Abc_LitIsCompl(pFinal[i])) );
+ }
+ nFinal = k;
+ Vec_StrAppend( vSop, Vec_StrArray(vCube) );
+ //printf( "%s\n", Vec_StrArray(vCube) );
+ // add blocking clause
+ if ( !bmcg2_sat_solver_addclause( pSat[1], pFinal, nFinal ) )
+ break;
+ }
+ Vec_IntFree( vLits );
+ Vec_StrFree( vCube );
+ Vec_StrPush( vSop, '\0' );
+ return vSop;
+}
+Vec_Str_t * bmcg2_sat_solver_sop( Gia_Man_t * p, int CubeLimit )
+{
+ bmcg2_sat_solver * pSat[2] = { bmcg2_sat_solver_start(), bmcg2_sat_solver_start() };
+
+ // generate CNF for the on-set and off-set
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8 /*nLutSize*/, 0 /*fCnfObjIds*/, 0/*fAddOrCla*/, 0, 0/*verbose*/ );
+ int i, n, nVars = Gia_ManCiNum(p), Lit;//, Count = 0;
+ int iFirstVar = pCnf->nVars - nVars;
+ assert( Gia_ManCoNum(p) == 1 );
+ for ( n = 0; n < 2; n++ )
+ {
+ bmcg2_sat_solver_set_nvars( pSat[n], pCnf->nVars );
+ Lit = Abc_Var2Lit( 1, !n ); // output variable is 1
+ for ( i = 0; i < pCnf->nClauses; i++ )
+ if ( !bmcg2_sat_solver_addclause( pSat[n], pCnf->pClauses[i], pCnf->pClauses[i+1]-pCnf->pClauses[i] ) )
+ assert( 0 );
+ if ( !bmcg2_sat_solver_addclause( pSat[n], &Lit, 1 ) )
+ {
+ Vec_Str_t * vSop = Vec_StrAlloc( 10 );
+ Vec_StrPrintF( vSop, " %d\n\0", !n );
+ Cnf_DataFree( pCnf );
+ return vSop;
+ }
+ }
+ Cnf_DataFree( pCnf );
+
+ // collect cube vars and map SAT vars into them
+ Vec_Int_t * vVars = Vec_IntAlloc( 100 );
+ Vec_Int_t * vVarMap = Vec_IntStartFull( iFirstVar + nVars );
+ for ( i = 0; i < nVars; i++ )
+ {
+ Vec_IntPush( vVars, iFirstVar+i );
+ Vec_IntWriteEntry( vVarMap, iFirstVar+i, i );
+ }
+
+ Vec_Str_t * vSop = Glucose2_GenerateCubes( pSat, vVars, vVarMap, CubeLimit );
+ Vec_IntFree( vVarMap );
+ Vec_IntFree( vVars );
+
+ bmcg2_sat_solver_stop( pSat[0] );
+ bmcg2_sat_solver_stop( pSat[1] );
+ return vSop;
+}
+void bmcg2_sat_solver_print_sop( Gia_Man_t * p )
+{
+ Vec_Str_t * vSop = bmcg2_sat_solver_sop( p, 0 );
+ printf( "%s", Vec_StrArray(vSop) );
+ Vec_StrFree( vSop );
+}
+void bmcg2_sat_solver_print_sop_lit( Gia_Man_t * p, int Lit )
+{
+ Vec_Int_t * vCisUsed = Vec_IntAlloc( 100 );
+ int i, ObjId, iNode = Abc_Lit2Var( Lit );
+ Gia_ManCollectCis( p, &iNode, 1, vCisUsed );
+ Vec_IntSort( vCisUsed, 0 );
+ Vec_IntForEachEntry( vCisUsed, ObjId, i )
+ Vec_IntWriteEntry( vCisUsed, i, Gia_ManIdToCioId(p, ObjId) );
+ Vec_IntPrint( vCisUsed );
+ Gia_Man_t * pNew = Gia_ManDupConeSupp( p, Lit, vCisUsed );
+ Vec_IntFree( vCisUsed );
+ bmcg2_sat_solver_print_sop( pNew );
+ Gia_ManStop( pNew );
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computing d-literals.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+#define Gia_CubeForEachVar( pCube, Value, i ) \
+ for ( i = 0; (pCube[i] != ' ') && (Value = pCube[i]); i++ )
+#define Gia_SopForEachCube( pSop, nFanins, pCube ) \
+ for ( pCube = (pSop); *pCube; pCube += (nFanins) + 3 )
+
+void bmcg2_sat_generate_dvars( Vec_Int_t * vCiVars, Vec_Str_t * vSop, Vec_Int_t * vDLits )
+{
+ int i, Lit, Counter, nCubes = 0;
+ char Value, * pCube, * pSop = Vec_StrArray( vSop );
+ Vec_Int_t * vCounts = Vec_IntStart( 2*Vec_IntSize(vCiVars) );
+ Vec_IntClear( vDLits );
+ Gia_SopForEachCube( pSop, Vec_IntSize(vCiVars), pCube )
+ {
+ nCubes++;
+ Gia_CubeForEachVar( pCube, Value, i )
+ {
+ if ( Value == '1' )
+ Vec_IntAddToEntry( vCounts, 2*i, 1 );
+ else if ( Value == '0' )
+ Vec_IntAddToEntry( vCounts, 2*i+1, 1 );
+ }
+ }
+ Vec_IntForEachEntry( vCounts, Counter, Lit )
+ if ( Counter == nCubes )
+ Vec_IntPush( vDLits, Abc_Var2Lit(Vec_IntEntry(vCiVars, Abc_Lit2Var(Lit)), Abc_LitIsCompl(Lit)) );
+ Vec_IntSort( vDLits, 0 );
+ Vec_IntFree( vCounts );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs SAT-based quantification.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int bmcg2_sat_solver_quantify2( Gia_Man_t * p, int iLit, int fHash, int(*pFuncCiToKeep)(void *, int), void * pData, Vec_Int_t * vDLits )
+{
+ int fSynthesize = 0;
+ extern Gia_Man_t * Abc_SopSynthesizeOne( char * pSop, int fClp );
+ Gia_Man_t * pMan, * pNew, * pTemp; Vec_Str_t * vSop;
+ int i, CiId, ObjId, Res, nCubes = 0, nNodes, Count = 0, iNode = Abc_Lit2Var(iLit);
+ Vec_Int_t * vCisUsed = Vec_IntAlloc( 100 );
+ Gia_ManCollectCis( p, &iNode, 1, vCisUsed );
+ Vec_IntSort( vCisUsed, 0 );
+ if ( vDLits ) Vec_IntClear( vDLits );
+ if ( iLit < 2 )
+ return iLit;
+ // remap into CI Ids
+ Vec_IntForEachEntry( vCisUsed, ObjId, i )
+ Vec_IntWriteEntry( vCisUsed, i, Gia_ManIdToCioId(p, ObjId) );
+ // duplicate cone
+ pNew = Gia_ManDupConeSupp( p, iLit, vCisUsed );
+ assert( Gia_ManCiNum(pNew) == Vec_IntSize(vCisUsed) );
+ nNodes = Gia_ManAndNum(pNew);
+
+ // perform quantification one CI at a time
+ assert( pFuncCiToKeep );
+ Vec_IntForEachEntry( vCisUsed, CiId, i )
+ if ( !pFuncCiToKeep( pData, CiId ) )
+ {
+ //printf( "Quantifying %d.\n", CiId );
+ pNew = Gia_ManDupExist( pTemp = pNew, i );
+ Gia_ManStop( pTemp );
+ Count++;
+ }
+ if ( Gia_ManPoIsConst(pNew, 0) )
+ {
+ int RetValue = Gia_ManPoIsConst1(pNew, 0);
+ Vec_IntFree( vCisUsed );
+ Gia_ManStop( pNew );
+ return RetValue;
+ }
+
+ if ( fSynthesize )
+ {
+ vSop = bmcg2_sat_solver_sop( pNew, 0 );
+ Gia_ManStop( pNew );
+ pMan = Abc_SopSynthesizeOne( Vec_StrArray(vSop), 1 );
+ nCubes = Vec_StrCountEntry(vSop, '\n');
+ if ( vDLits )
+ {
+ // convert into object IDs
+ Vec_Int_t * vCisObjs = Vec_IntAlloc( Vec_IntSize(vCisUsed) );
+ Vec_IntForEachEntry( vCisUsed, CiId, i )
+ Vec_IntPush( vCisObjs, CiId + 1 );
+ bmcg2_sat_generate_dvars( vCisObjs, vSop, vDLits );
+ Vec_IntFree( vCisObjs );
+ }
+ Vec_StrFree( vSop );
+
+ if ( Gia_ManPoIsConst(pMan, 0) )
+ {
+ int RetValue = Gia_ManPoIsConst1(pMan, 0);
+ Vec_IntFree( vCisUsed );
+ Gia_ManStop( pMan );
+ return RetValue;
+ }
+ }
+ else
+ {
+ pMan = pNew;
+ }
+
+ Res = Gia_ManDupConeBack( p, pMan, vCisUsed );
+
+ // report the result
+ //printf( "Performed quantification with %5d nodes, %3d keep-vars, %3d quant-vars, resulting in %5d cubes and %5d nodes. ",
+ // nNodes, Vec_IntSize(vCisUsed) - Count, Count, nCubes, Gia_ManAndNum(pMan) );
+ //Abc_PrintTime( 1, "Time", Abc_Clock() - clkAll );
+
+ Vec_IntFree( vCisUsed );
+ Gia_ManStop( pMan );
+ return Res;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs SAT-based quantification.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManSatAndCollect2_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vObjsUsed, Vec_Int_t * vCiVars )
+{
+ Gia_Obj_t * pObj; int iVar;
+ if ( (iVar = Gia_ObjCopyArray(p, iObj)) >= 0 )
+ return iVar;
+ pObj = Gia_ManObj( p, iObj );
+ assert( Gia_ObjIsCand(pObj) );
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ Gia_ManSatAndCollect2_rec( p, Gia_ObjFaninId0(pObj, iObj), vObjsUsed, vCiVars );
+ Gia_ManSatAndCollect2_rec( p, Gia_ObjFaninId1(pObj, iObj), vObjsUsed, vCiVars );
+ }
+ iVar = Vec_IntSize( vObjsUsed );
+ Vec_IntPush( vObjsUsed, iObj );
+ Gia_ObjSetCopyArray( p, iObj, iVar );
+ if ( vCiVars && Gia_ObjIsCi(pObj) )
+ Vec_IntPush( vCiVars, iVar );
+ return iVar;
+}
+void Gia_ManQuantLoadCnf2( Gia_Man_t * p, Vec_Int_t * vObjsUsed, bmcg2_sat_solver * pSats[] )
+{
+ Gia_Obj_t * pObj; int i;
+ bmcg2_sat_solver_reset( pSats[0] );
+ if ( pSats[1] )
+ bmcg2_sat_solver_reset( pSats[1] );
+ bmcg2_sat_solver_set_nvars( pSats[0], Vec_IntSize(vObjsUsed) );
+ if ( pSats[1] )
+ bmcg2_sat_solver_set_nvars( pSats[1], Vec_IntSize(vObjsUsed) );
+ Gia_ManForEachObjVec( vObjsUsed, p, pObj, i )
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ int iObj = Gia_ObjId( p, pObj );
+ int iVar = Gia_ObjCopyArray(p, iObj);
+ int iVar0 = Gia_ObjCopyArray(p, Gia_ObjFaninId0(pObj, iObj));
+ int iVar1 = Gia_ObjCopyArray(p, Gia_ObjFaninId1(pObj, iObj));
+ bmcg2_sat_solver_add_and( pSats[0], iVar, iVar0, iVar1, Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj), 0 );
+ if ( pSats[1] )
+ bmcg2_sat_solver_add_and( pSats[1], iVar, iVar0, iVar1, Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj), 0 );
+ }
+ else if ( Gia_ObjIsConst0(pObj) )
+ {
+ int Lit = Abc_Var2Lit( Gia_ObjCopyArray(p, 0), 1 );
+ int RetValue = bmcg2_sat_solver_addclause( pSats[0], &Lit, 1 );
+ assert( RetValue );
+ if ( pSats[1] )
+ bmcg2_sat_solver_addclause( pSats[1], &Lit, 1 );
+ assert( Lit == 1 );
+ }
+}
+int Gia_ManFactorSop2( Gia_Man_t * p, Vec_Int_t * vCiObjIds, Vec_Str_t * vSop, int fHash )
+{
+ extern Gia_Man_t * Abc_SopSynthesizeOne( char * pSop, int fClp );
+ Gia_Man_t * pMan = Abc_SopSynthesizeOne( Vec_StrArray(vSop), 1 );
+ Gia_Obj_t * pObj; int i, Result;
+ assert( Gia_ManPiNum(pMan) == Vec_IntSize(vCiObjIds) );
+ Gia_ManConst0(pMan)->Value = 0;
+ Gia_ManForEachPi( pMan, pObj, i )
+ pObj->Value = Abc_Var2Lit( Vec_IntEntry(vCiObjIds, i), 0 );
+ Gia_ManForEachAnd( pMan, pObj, i )
+ if ( fHash )
+ pObj->Value = Gia_ManHashAnd( p, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ else
+ pObj->Value = Gia_ManAppendAnd( p, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ pObj = Gia_ManPo(pMan, 0);
+ Result = Gia_ObjFanin0Copy(pObj);
+ Gia_ManStop( pMan );
+ return Result;
+}
+int bmcg2_sat_solver_quantify( bmcg2_sat_solver * pSats[], Gia_Man_t * p, int iLit, int fHash, int(*pFuncCiToKeep)(void *, int), void * pData, Vec_Int_t * vDLits )
+{
+ Vec_Int_t * vObjsUsed = Vec_IntAlloc( 100 ); // GIA objs
+ Vec_Int_t * vCiVars = Vec_IntAlloc( 100 ); // CI SAT vars
+ Vec_Int_t * vVarMap = NULL; Vec_Str_t * vSop = NULL;
+ int i, iVar, iVarLast, Lit, RetValue, Count = 0, Result = -1;
+ if ( vDLits ) Vec_IntClear( vDLits );
+ if ( iLit < 2 )
+ return iLit;
+ if ( Vec_IntSize(&p->vCopies) < Gia_ManObjNum(p) )
+ Vec_IntFillExtra( &p->vCopies, Gia_ManObjNum(p), -1 );
+ // assign variable number 0 to const0 node
+ iVar = Vec_IntSize(vObjsUsed);
+ Vec_IntPush( vObjsUsed, 0 );
+ Gia_ObjSetCopyArray( p, 0, iVar );
+ assert( iVar == 0 );
+
+ // collect other variables
+ iVarLast = Gia_ManSatAndCollect2_rec( p, Abc_Lit2Var(iLit), vObjsUsed, vCiVars );
+ Gia_ManQuantLoadCnf2( p, vObjsUsed, pSats );
+
+ // check constants
+ Lit = Abc_Var2Lit( iVarLast, !Abc_LitIsCompl(iLit) );
+ RetValue = bmcg2_sat_solver_addclause( pSats[0], &Lit, 1 ); // offset
+ if ( !RetValue || bmcg2_sat_solver_solve(pSats[0], NULL, 0) == GLUCOSE_UNSAT )
+ {
+ Result = 1;
+ goto cleanup;
+ }
+ Lit = Abc_Var2Lit( iVarLast, Abc_LitIsCompl(iLit) );
+ RetValue = bmcg2_sat_solver_addclause( pSats[1], &Lit, 1 ); // onset
+ if ( !RetValue || bmcg2_sat_solver_solve(pSats[1], NULL, 0) == GLUCOSE_UNSAT )
+ {
+ Result = 0;
+ goto cleanup;
+ }
+/*
+ // reorder CI SAT variables to have keep-vars first
+ Vec_Int_t * vCiVars2 = Vec_IntAlloc( 100 ); // CI SAT vars
+ Vec_IntForEachEntry( vCiVars, iVar, i )
+ {
+ Gia_Obj_t * pObj = Gia_ManObj( p, Vec_IntEntry(vObjsUsed, iVar) );
+ assert( Gia_ObjIsCi(pObj) );
+ if ( pFuncCiToKeep(pData, Gia_ObjCioId(pObj)) )
+ Vec_IntPush( vCiVars2, iVar );
+ }
+ Vec_IntForEachEntry( vCiVars, iVar, i )
+ {
+ Gia_Obj_t * pObj = Gia_ManObj( p, Vec_IntEntry(vObjsUsed, iVar) );
+ assert( Gia_ObjIsCi(pObj) );
+ if ( !pFuncCiToKeep(pData, Gia_ObjCioId(pObj)) )
+ Vec_IntPush( vCiVars2, iVar );
+ }
+ ABC_SWAP( Vec_Int_t *, vCiVars2, vCiVars );
+ Vec_IntFree( vCiVars2 );
+*/
+ // map CI SAT variables into their indexes used in the cubes
+ vVarMap = Vec_IntStartFull( Vec_IntSize(vObjsUsed) );
+ Vec_IntForEachEntry( vCiVars, iVar, i )
+ {
+ Gia_Obj_t * pObj = Gia_ManObj( p, Vec_IntEntry(vObjsUsed, iVar) );
+ assert( Gia_ObjIsCi(pObj) );
+ if ( pFuncCiToKeep(pData, Gia_ObjCioId(pObj)) )
+ Vec_IntWriteEntry( vVarMap, iVar, i ), Count++;
+ }
+ if ( Count == 0 || Count == Vec_IntSize(vCiVars) )
+ {
+ Result = Count == 0 ? 1 : iLit;
+ goto cleanup;
+ }
+ // generate cubes
+ vSop = Glucose2_GenerateCubes( pSats, vCiVars, vVarMap, 0 );
+ //printf( "%s", Vec_StrArray(vSop) );
+ // convert into object IDs
+ Vec_IntForEachEntry( vCiVars, iVar, i )
+ Vec_IntWriteEntry( vCiVars, i, Vec_IntEntry(vObjsUsed, iVar) );
+ // generate unate variables
+ if ( vDLits )
+ bmcg2_sat_generate_dvars( vCiVars, vSop, vDLits );
+ // convert into an AIG
+ RetValue = Gia_ManAndNum(p);
+ Result = Gia_ManFactorSop2( p, vCiVars, vSop, fHash );
+
+ // report the result
+// printf( "Performed quantification with %5d nodes, %3d keep-vars, %3d quant-vars, resulting in %5d cubes and %5d nodes. ",
+// Vec_IntSize(vObjsUsed), Count, Vec_IntSize(vCiVars) - Count, Vec_StrCountEntry(vSop, '\n'), Gia_ManAndNum(p)-RetValue );
+// Abc_PrintTime( 1, "Time", Abc_Clock() - clkAll );
+
+cleanup:
+ Vec_IntForEachEntry( vObjsUsed, iVar, i )
+ Gia_ObjSetCopyArray( p, iVar, -1 );
+ Vec_IntFree( vObjsUsed );
+ Vec_IntFree( vCiVars );
+ Vec_IntFreeP( &vVarMap );
+ Vec_StrFreeP( &vSop );
+ return Result;
+}
+int Gia_ManCiIsToKeep2( void * pData, int i )
+{
+ return i % 5 != 0;
+}
+void Glucose2_QuantifyAigTest( Gia_Man_t * p )
+{
+ bmcg2_sat_solver * pSats[3] = { bmcg2_sat_solver_start(), bmcg2_sat_solver_start(), bmcg2_sat_solver_start() };
+
+ abctime clk1 = Abc_Clock();
+ int iRes1 = bmcg2_sat_solver_quantify( pSats, p, Gia_ObjFaninLit0p(p, Gia_ManPo(p, 0)), 0, Gia_ManCiIsToKeep2, NULL, NULL );
+ abctime clk1d = Abc_Clock()-clk1;
+
+ abctime clk2 = Abc_Clock();
+ int iRes2 = bmcg2_sat_solver_quantify2( p, Gia_ObjFaninLit0p(p, Gia_ManPo(p, 0)), 0, Gia_ManCiIsToKeep2, NULL, NULL );
+ abctime clk2d = Abc_Clock()-clk2;
+
+ Abc_PrintTime( 1, "Time1", clk1d );
+ Abc_PrintTime( 1, "Time2", clk2d );
+
+ if ( bmcg2_sat_solver_equiv_overlap_check( pSats[2], p, iRes1, iRes2, 1 ) )
+ printf( "Verification passed.\n" );
+ else
+ printf( "Verification FAILED.\n" );
+
+ Gia_ManAppendCo( p, iRes1 );
+ Gia_ManAppendCo( p, iRes2 );
+
+ bmcg2_sat_solver_stop( pSats[0] );
+ bmcg2_sat_solver_stop( pSats[1] );
+ bmcg2_sat_solver_stop( pSats[2] );
+}
+int bmcg2_sat_solver_quantify_test( bmcg2_sat_solver * pSats[], Gia_Man_t * p, int iLit, int fHash, int(*pFuncCiToKeep)(void *, int), void * pData, Vec_Int_t * vDLits )
+{
+ extern int Gia_ManQuantExist( Gia_Man_t * p, int iLit, int(*pFuncCiToKeep)(void *, int), void * pData );
+ int Res1 = Gia_ManQuantExist( p, iLit, pFuncCiToKeep, pData );
+ int Res2 = bmcg2_sat_solver_quantify2( p, iLit, 1, pFuncCiToKeep, pData, NULL );
+
+ bmcg2_sat_solver * pSat = bmcg2_sat_solver_start();
+ if ( bmcg2_sat_solver_equiv_overlap_check( pSat, p, Res1, Res2, 1 ) )
+ printf( "Verification passed.\n" );
+ else
+ {
+ printf( "Verification FAILED.\n" );
+ bmcg2_sat_solver_print_sop_lit( p, Res1 );
+ bmcg2_sat_solver_print_sop_lit( p, Res2 );
+ printf( "\n" );
+ }
+ return Res1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks equivalence or intersection of two nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int bmcg2_sat_solver_equiv_overlap_check( bmcg2_sat_solver * pSat, Gia_Man_t * p, int iLit0, int iLit1, int fEquiv )
+{
+ bmcg2_sat_solver * pSats[2] = { pSat, NULL };
+ Vec_Int_t * vObjsUsed = Vec_IntAlloc( 100 );
+ int i, iVar, iSatVar[2], iSatLit[2], Lits[2], status;
+ if ( Vec_IntSize(&p->vCopies) < Gia_ManObjNum(p) )
+ Vec_IntFillExtra( &p->vCopies, Gia_ManObjNum(p), -1 );
+
+ // assign const0 variable number 0
+ iVar = Vec_IntSize(vObjsUsed);
+ Vec_IntPush( vObjsUsed, 0 );
+ Gia_ObjSetCopyArray( p, 0, iVar );
+ assert( iVar == 0 );
+
+ iSatVar[0] = Gia_ManSatAndCollect2_rec( p, Abc_Lit2Var(iLit0), vObjsUsed, NULL );
+ iSatVar[1] = Gia_ManSatAndCollect2_rec( p, Abc_Lit2Var(iLit1), vObjsUsed, NULL );
+
+ iSatLit[0] = Abc_Var2Lit( iSatVar[0], Abc_LitIsCompl(iLit0) );
+ iSatLit[1] = Abc_Var2Lit( iSatVar[1], Abc_LitIsCompl(iLit1) );
+ Gia_ManQuantLoadCnf2( p, vObjsUsed, pSats );
+ Vec_IntForEachEntry( vObjsUsed, iVar, i )
+ Gia_ObjSetCopyArray( p, iVar, -1 );
+ Vec_IntFree( vObjsUsed );
+
+ if ( fEquiv )
+ {
+ Lits[0] = iSatLit[0];
+ Lits[1] = Abc_LitNot(iSatLit[1]);
+ status = bmcg2_sat_solver_solve( pSats[0], Lits, 2 );
+ if ( status == GLUCOSE_UNSAT )
+ {
+ Lits[0] = Abc_LitNot(iSatLit[0]);
+ Lits[1] = iSatLit[1];
+ status = bmcg2_sat_solver_solve( pSats[0], Lits, 2 );
+ }
+ return status == GLUCOSE_UNSAT;
+ }
+ else
+ {
+ Lits[0] = iSatLit[0];
+ Lits[1] = iSatLit[1];
+ status = bmcg2_sat_solver_solve( pSats[0], Lits, 2 );
+ return status == GLUCOSE_SAT;
+ }
+}
+void Glucose2_CheckTwoNodesTest( Gia_Man_t * p )
+{
+ int n, Res;
+ bmcg2_sat_solver * pSat = bmcg2_sat_solver_start();
+ for ( n = 0; n < 2; n++ )
+ {
+ Res = bmcg2_sat_solver_equiv_overlap_check(
+ pSat, p,
+ Gia_ObjFaninLit0p(p, Gia_ManPo(p, 0)),
+ Gia_ObjFaninLit0p(p, Gia_ManPo(p, 1)),
+ n );
+ bmcg2_sat_solver_reset( pSat );
+ printf( "%s %s.\n", n ? "Equivalence" : "Overlap", Res ? "holds" : "fails" );
+ }
+ bmcg2_sat_solver_stop( pSat );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Glucose2_SolveAig(Gia_Man_t * p, Glucose2_Pars * pPars)
+{
+ abctime clk = Abc_Clock();
+
+ SimpSolver S;
+ S.verbosity = pPars->verb;
+ S.verbEveryConflicts = 50000;
+ S.showModel = false;
+ //S.verbosity = 2;
+ S.setConfBudget( pPars->nConfls > 0 ? (int64_t)pPars->nConfls : -1 );
+
+ S.parsing = 1;
+ Vec_Int_t * vCnfIds = Glucose_SolverFromAig(p,S);
+ S.parsing = 0;
+
+ if (pPars->verb)
+ {
+ printf("c ============================[ Problem Statistics ]=============================\n");
+ printf("c | |\n");
+ printf("c | Number of variables: %12d |\n", S.nVars());
+ printf("c | Number of clauses: %12d |\n", S.nClauses());
+ }
+
+ if (pPars->pre)
+ {
+ S.eliminate(true);
+ printf( "c Simplication removed %d variables and %d clauses. ", S.eliminated_vars, S.eliminated_clauses );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ }
+
+ vec<Lit> dummy;
+ lbool ret = S.solveLimited(dummy, 0);
+
+ if ( pPars->verb ) glucose2_print_stats(S, Abc_Clock() - clk);
+ printf(ret == l_True ? "SATISFIABLE" : ret == l_False ? "UNSATISFIABLE" : "INDETERMINATE");
+ Abc_PrintTime( 1, " Time", Abc_Clock() - clk );
+
+ // port counterexample
+ if (ret == l_True)
+ {
+ Gia_Obj_t * pObj; int i;
+ p->pCexComb = Abc_CexAlloc(0,Gia_ManCiNum(p),1);
+ Gia_ManForEachCi( p, pObj, i )
+ {
+ assert(Vec_IntEntry(vCnfIds,Gia_ObjId(p, pObj))!=-1);
+ if (S.model[Vec_IntEntry(vCnfIds,Gia_ObjId(p, pObj))] == l_True)
+ Abc_InfoSetBit( p->pCexComb->pData, i);
+ }
+ }
+ Vec_IntFree(vCnfIds);
+ return (ret == l_True ? 10 : ret == l_False ? 20 : 0);
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+ABC_NAMESPACE_IMPL_END
diff --git a/src/sat/glucose2/AbcGlucose2.h b/src/sat/glucose2/AbcGlucose2.h
new file mode 100644
index 00000000..9299d290
--- /dev/null
+++ b/src/sat/glucose2/AbcGlucose2.h
@@ -0,0 +1,118 @@
+/**CFile****************************************************************
+
+ FileName [AbcGlucose.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [SAT solver Glucose 3.0 by Gilles Audemard and Laurent Simon.]
+
+ Synopsis [Interface to Glucose.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 6, 2017.]
+
+ Revision [$Id: AbcGlucose.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef ABC_SAT_GLUCOSE_H_
+#define ABC_SAT_GLUCOSE_H_
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include "aig/gia/gia.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+#define GLUCOSE_UNSAT -1
+#define GLUCOSE_SAT 1
+#define GLUCOSE_UNDEC 0
+
+
+ABC_NAMESPACE_HEADER_START
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Glucose2_Pars_ Glucose2_Pars;
+struct Glucose2_Pars_ {
+ int pre; // preprocessing
+ int verb; // verbosity
+ int cust; // customizable
+ int nConfls; // conflict limit (0 = no limit)
+};
+
+static inline Glucose2_Pars Glucose_CreatePars(int p, int v, int c, int nConfls)
+{
+ Glucose2_Pars pars;
+ pars.pre = p;
+ pars.verb = v;
+ pars.cust = c;
+ pars.nConfls = nConfls;
+ return pars;
+}
+
+typedef void bmcg2_sat_solver;
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+extern bmcg2_sat_solver * bmcg2_sat_solver_start();
+extern void bmcg2_sat_solver_stop( bmcg2_sat_solver* s );
+extern void bmcg2_sat_solver_reset( bmcg2_sat_solver* s );
+extern int bmcg2_sat_solver_addclause( bmcg2_sat_solver* s, int * plits, int nlits );
+extern void bmcg2_sat_solver_setcallback( bmcg2_sat_solver* s, void * pman, int(*pfunc)(void*, int, int*) );
+extern int bmcg2_sat_solver_solve( bmcg2_sat_solver* s, int * plits, int nlits );
+extern int bmcg2_sat_solver_final( bmcg2_sat_solver* s, int ** ppArray );
+extern int bmcg2_sat_solver_addvar( bmcg2_sat_solver* s );
+extern void bmcg2_sat_solver_set_nvars( bmcg2_sat_solver* s, int nvars );
+extern int bmcg2_sat_solver_eliminate( bmcg2_sat_solver* s, int turn_off_elim );
+extern int bmcg2_sat_solver_var_is_elim( bmcg2_sat_solver* s, int v );
+extern void bmcg2_sat_solver_var_set_frozen( bmcg2_sat_solver* s, int v, int freeze );
+extern int bmcg2_sat_solver_elim_varnum(bmcg2_sat_solver* s);
+extern int * bmcg2_sat_solver_read_cex( bmcg2_sat_solver* s );
+extern int bmcg2_sat_solver_read_cex_varvalue( bmcg2_sat_solver* s, int );
+extern void bmcg2_sat_solver_set_stop( bmcg2_sat_solver* s, int * pstop );
+extern abctime bmcg2_sat_solver_set_runtime_limit( bmcg2_sat_solver* s, abctime Limit );
+extern void bmcg2_sat_solver_set_conflict_budget( bmcg2_sat_solver* s, int Limit );
+extern int bmcg2_sat_solver_varnum( bmcg2_sat_solver* s );
+extern int bmcg2_sat_solver_clausenum( bmcg2_sat_solver* s );
+extern int bmcg2_sat_solver_learntnum( bmcg2_sat_solver* s );
+extern int bmcg2_sat_solver_conflictnum( bmcg2_sat_solver* s );
+extern int bmcg2_sat_solver_minimize_assumptions( bmcg2_sat_solver * s, int * plits, int nlits, int pivot );
+extern int bmcg2_sat_solver_add_and( bmcg2_sat_solver * s, int iVar, int iVar0, int iVar1, int fCompl0, int fCompl1, int fCompl );
+extern int bmcg2_sat_solver_add_xor( bmcg2_sat_solver * s, int iVarA, int iVarB, int iVarC, int fCompl );
+extern int bmcg2_sat_solver_quantify( bmcg2_sat_solver * s[], Gia_Man_t * p, int iLit, int fHash, int(*pFuncCiToKeep)(void *, int), void * pData, Vec_Int_t * vDLits );
+extern int bmcg2_sat_solver_equiv_overlap_check( bmcg2_sat_solver * s, Gia_Man_t * p, int iLit0, int iLit1, int fEquiv );
+extern Vec_Str_t * bmcg2_sat_solver_sop( Gia_Man_t * p, int CubeLimit );
+extern int bmcg2_sat_solver_jftr( bmcg2_sat_solver * s );
+extern void bmcg2_sat_solver_set_jftr( bmcg2_sat_solver * s, int jftr );
+extern void bmcg2_sat_solver_set_var_fanin_lit( bmcg2_sat_solver * s, int var, int lit0, int lit1 );
+extern void bmcg2_sat_solver_start_new_round( bmcg2_sat_solver * s );
+extern void bmcg2_sat_solver_mark_cone( bmcg2_sat_solver * s, int var );
+extern void bmcg2_sat_solver_prelocate( bmcg2_sat_solver * s, int var_num );
+
+extern void Glucose2_SolveCnf( char * pFilename, Glucose2_Pars * pPars );
+extern int Glucose2_SolveAig( Gia_Man_t * p, Glucose2_Pars * pPars );
+
+ABC_NAMESPACE_HEADER_END
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/sat/glucose2/AbcGlucoseCmd2.cpp b/src/sat/glucose2/AbcGlucoseCmd2.cpp
new file mode 100644
index 00000000..54bae608
--- /dev/null
+++ b/src/sat/glucose2/AbcGlucoseCmd2.cpp
@@ -0,0 +1,149 @@
+/**CFile****************************************************************
+
+ FileName [AbcGlucoseCmd.cpp]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [SAT solver Glucose 3.0 by Gilles Audemard and Laurent Simon.]
+
+ Synopsis [Interface to Glucose.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 6, 2017.]
+
+ Revision [$Id: AbcGlucoseCmd.cpp,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "aig/gia/gia.h"
+#include "base/main/mainInt.h"
+
+#include "sat/glucose2/AbcGlucose2.h"
+
+
+ABC_NAMESPACE_HEADER_START
+
+extern void Glucose2_Init( Abc_Frame_t *pAbc );
+extern void Glucose2_End( Abc_Frame_t * pAbc );
+
+ABC_NAMESPACE_HEADER_END
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static int Abc_CommandGlucose( Abc_Frame_t * pAbc, int argc, char ** argv );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+
+void Glucose2_Init(Abc_Frame_t *pAbc)
+{
+ Cmd_CommandAdd( pAbc, "ABC9", "&glucose2", Abc_CommandGlucose, 0 );
+}
+
+void Glucose2_End( Abc_Frame_t * pAbc )
+{
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandGlucose( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ int c = 0;
+ int pre = 1;
+ int verb = 0;
+ int nConfls = 0;
+
+ Glucose2_Pars pPars;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Cpvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'C':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nConfls = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nConfls < 0 )
+ goto usage;
+ break;
+ case 'p':
+ pre ^= 1;
+ break;
+ case 'v':
+ verb ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ pPars = Glucose_CreatePars(pre,verb,0,nConfls);
+
+ if ( argc == globalUtilOptind + 1 )
+ {
+ Glucose2_SolveCnf( argv[globalUtilOptind], &pPars );
+ return 0;
+ }
+
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandGlucose(): There is no AIG.\n" );
+ return 1;
+ }
+
+ if ( Glucose2_SolveAig( pAbc->pGia, &pPars ) == 10 )
+ Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb );
+
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &glucose2 [-C num] [-pvh] <file.cnf>\n" );
+ Abc_Print( -2, "\t run Glucose 3.0 by Gilles Audemard and Laurent Simon\n" );
+ Abc_Print( -2, "\t-C num : conflict limit [default = %d]\n", nConfls );
+ Abc_Print( -2, "\t-p : enable preprocessing [default = %d]\n",pre);
+ Abc_Print( -2, "\t-v : verbosity [default = %d]\n",verb);
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ Abc_Print( -2, "\t<file.cnf> : (optional) CNF file to solve\n");
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+ABC_NAMESPACE_IMPL_END
diff --git a/src/sat/glucose2/Alg.h b/src/sat/glucose2/Alg.h
new file mode 100644
index 00000000..96f6ab70
--- /dev/null
+++ b/src/sat/glucose2/Alg.h
@@ -0,0 +1,88 @@
+/*******************************************************************************************[Alg.h]
+Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
+Copyright (c) 2007-2010, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#ifndef Glucose_Alg_h
+#define Glucose_Alg_h
+
+#include "sat/glucose2/Vec.h"
+
+ABC_NAMESPACE_CXX_HEADER_START
+
+namespace Gluco2 {
+
+//=================================================================================================
+// Useful functions on vector-like types:
+
+//=================================================================================================
+// Removing and searching for elements:
+//
+
+template<class V, class T>
+static inline void remove(V& ts, const T& t)
+{
+ int j = 0;
+ for (; j < ts.size() && ts[j] != t; j++);
+ assert(j < ts.size());
+ for (; j < ts.size()-1; j++) ts[j] = ts[j+1];
+ ts.pop();
+}
+
+
+template<class V, class T>
+static inline bool find(V& ts, const T& t)
+{
+ int j = 0;
+ for (; j < ts.size() && ts[j] != t; j++);
+ return j < ts.size();
+}
+
+
+//=================================================================================================
+// Copying vectors with support for nested vector types:
+//
+
+// Base case:
+template<class T>
+static inline void copy(const T& from, T& to)
+{
+ to = from;
+}
+
+// Recursive case:
+template<class T>
+static inline void copy(const vec<T>& from, vec<T>& to, bool append = false)
+{
+ if (!append)
+ to.clear();
+ for (int i = 0; i < from.size(); i++){
+ to.push();
+ copy(from[i], to.last());
+ }
+}
+
+template<class T>
+static inline void append(const vec<T>& from, vec<T>& to){ copy(from, to, true); }
+
+//=================================================================================================
+}
+
+ABC_NAMESPACE_CXX_HEADER_END
+
+#endif
diff --git a/src/sat/glucose2/Alloc.h b/src/sat/glucose2/Alloc.h
new file mode 100644
index 00000000..b7bebaca
--- /dev/null
+++ b/src/sat/glucose2/Alloc.h
@@ -0,0 +1,136 @@
+/*****************************************************************************************[Alloc.h]
+Copyright (c) 2008-2010, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+
+#ifndef Glucose_Alloc_h
+#define Glucose_Alloc_h
+
+#include "sat/glucose2/XAlloc.h"
+#include "sat/glucose2/Vec.h"
+
+ABC_NAMESPACE_CXX_HEADER_START
+
+namespace Gluco2 {
+
+//=================================================================================================
+// Simple Region-based memory allocator:
+
+template<class T>
+class RegionAllocator
+{
+ T* memory;
+ uint32_t sz;
+ uint32_t cap;
+ uint32_t wasted_;
+
+ void capacity(uint32_t min_cap);
+
+ public:
+ // TODO: make this a class for better type-checking?
+ typedef uint32_t Ref;
+ enum { Ref_Undef = UINT32_MAX };
+ enum { Unit_Size = sizeof(uint32_t) };
+
+ explicit RegionAllocator(uint32_t start_cap = 1024*1024) : memory(NULL), sz(0), cap(0), wasted_(0){ capacity(start_cap); }
+ ~RegionAllocator()
+ {
+ if (memory != NULL)
+ ::free(memory);
+ }
+
+
+ uint32_t size () const { return sz; }
+ uint32_t wasted () const { return wasted_; }
+
+ Ref alloc (int size);
+ void free_ (int size) { wasted_ += size; }
+ void clear () { sz = 0; wasted_=0; }
+
+ // Deref, Load Effective Address (LEA), Inverse of LEA (AEL):
+ T& operator[](Ref r) { assert(r >= 0 && r < sz); return memory[r]; }
+ const T& operator[](Ref r) const { assert(r >= 0 && r < sz); return memory[r]; }
+
+ T* lea (Ref r) { assert(r >= 0 && r < sz); return &memory[r]; }
+ const T* lea (Ref r) const { assert(r >= 0 && r < sz); return &memory[r]; }
+ Ref ael (const T* t) { assert((void*)t >= (void*)&memory[0] && (void*)t < (void*)&memory[sz-1]);
+ return (Ref)(t - &memory[0]); }
+
+ void moveTo(RegionAllocator& to) {
+ if (to.memory != NULL) ::free(to.memory);
+ to.memory = memory;
+ to.sz = sz;
+ to.cap = cap;
+ to.wasted_ = wasted_;
+
+ memory = NULL;
+ sz = cap = wasted_ = 0;
+ }
+
+
+};
+
+template<class T>
+void RegionAllocator<T>::capacity(uint32_t min_cap)
+{
+ if (cap >= min_cap) return;
+
+ uint32_t prev_cap = cap;
+ while (cap < min_cap){
+ // NOTE: Multiply by a factor (13/8) without causing overflow, then add 2 and make the
+ // result even by clearing the least significant bit. The resulting sequence of capacities
+ // is carefully chosen to hit a maximum capacity that is close to the '2^32-1' limit when
+ // using 'uint32_t' as indices so that as much as possible of this space can be used.
+ uint32_t delta = ((cap >> 1) + (cap >> 3) + 2) & ~1;
+ cap += delta;
+
+ if (cap <= prev_cap)
+ throw OutOfMemoryException();
+ }
+ //printf(" .. (%p) cap = %u\n", this, cap);
+
+ assert(cap > 0);
+ memory = (T*)xrealloc(memory, sizeof(T)*cap);
+}
+
+
+template<class T>
+typename RegionAllocator<T>::Ref
+RegionAllocator<T>::alloc(int size)
+{
+ //printf("ALLOC called (this = %p, size = %d)\n", this, size); fflush(stdout);
+ assert(size > 0);
+ capacity(sz + size);
+
+ uint32_t prev_sz = sz;
+ sz += size;
+
+ // Handle overflow:
+ if (sz < prev_sz)
+ throw OutOfMemoryException();
+
+ return prev_sz;
+}
+
+
+//=================================================================================================
+}
+
+ABC_NAMESPACE_CXX_HEADER_END
+
+#endif
diff --git a/src/sat/glucose2/BoundedQueue.h b/src/sat/glucose2/BoundedQueue.h
new file mode 100644
index 00000000..1a0d2148
--- /dev/null
+++ b/src/sat/glucose2/BoundedQueue.h
@@ -0,0 +1,114 @@
+/***********************************************************************************[BoundedQueue.h]
+ Glucose -- Copyright (c) 2009, Gilles Audemard, Laurent Simon
+ CRIL - Univ. Artois, France
+ LRI - Univ. Paris Sud, France
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+
+#ifndef BoundedQueue_h
+#define BoundedQueue_h
+
+#include "sat/glucose2/Vec.h"
+
+ABC_NAMESPACE_CXX_HEADER_START
+
+//=================================================================================================
+
+namespace Gluco2 {
+
+template <class T>
+class bqueue {
+ vec<T> elems;
+ int first;
+ int last;
+ uint64_t sumofqueue;
+ int maxsize;
+ int queuesize; // Number of current elements (must be < maxsize !)
+ bool expComputed;
+ double exp,value;
+public:
+ bqueue(void) : first(0), last(0), sumofqueue(0), maxsize(0), queuesize(0),expComputed(false) { }
+
+ void initSize(int size) {growTo(size);exp = 2.0/(size+1);} // Init size of bounded size queue
+
+ void push(T x) {
+ expComputed = false;
+ if (queuesize==maxsize) {
+ assert(last==first); // The queue is full, next value to enter will replace oldest one
+ sumofqueue -= elems[last];
+ if ((++last) == maxsize) last = 0;
+ } else
+ queuesize++;
+ sumofqueue += x;
+ elems[first] = x;
+ if ((++first) == maxsize) {first = 0;last = 0;}
+ }
+
+ T peek() { assert(queuesize>0); return elems[last]; }
+ void pop() {sumofqueue-=elems[last]; queuesize--; if ((++last) == maxsize) last = 0;}
+
+ uint64_t getsum() const {return sumofqueue;}
+ unsigned int getavg() const {return (unsigned int)(sumofqueue/((uint64_t)queuesize));}
+ int maxSize() const {return maxsize;}
+ double getavgDouble() const {
+ double tmp = 0;
+ for(int i=0;i<elems.size();i++) {
+ tmp+=elems[i];
+ }
+ return tmp/elems.size();
+ }
+ int isvalid() const {return (queuesize==maxsize);}
+
+ void growTo(int size) {
+ elems.growTo(size);
+ first=0; maxsize=size; queuesize = 0;last = 0;
+ for(int i=0;i<size;i++) elems[i]=0;
+ }
+
+ double getAvgExp() {
+ if(expComputed) return value;
+ double a=exp;
+ value = elems[first];
+ for(int i = first;i<maxsize;i++) {
+ value+=a*((double)elems[i]);
+ a=a*exp;
+ }
+ for(int i = 0;i<last;i++) {
+ value+=a*((double)elems[i]);
+ a=a*exp;
+ }
+ value = value*(1-exp)/(1-a);
+ expComputed = true;
+ return value;
+
+
+ }
+ void fastclear() {first = 0; last = 0; queuesize=0; sumofqueue=0;} // to be called after restarts... Discard the queue
+
+ int size(void) { return queuesize; }
+
+ void clear(bool dealloc = false) { elems.clear(dealloc); first = 0; maxsize=0; queuesize=0;sumofqueue=0;}
+
+
+};
+}
+//=================================================================================================
+
+ABC_NAMESPACE_CXX_HEADER_END
+
+#endif
diff --git a/src/sat/glucose2/CGlucose.h b/src/sat/glucose2/CGlucose.h
new file mode 100644
index 00000000..7fbf8f83
--- /dev/null
+++ b/src/sat/glucose2/CGlucose.h
@@ -0,0 +1,7 @@
+#ifndef Glucose_CGlucose_h
+#define Glucose_CGlucose_h
+
+#define CGLUCOSE_EXP 1
+#include "sat/glucose2/Heap2.h"
+
+#endif \ No newline at end of file
diff --git a/src/sat/glucose2/CGlucoseCore.h b/src/sat/glucose2/CGlucoseCore.h
new file mode 100644
index 00000000..c0f96fc4
--- /dev/null
+++ b/src/sat/glucose2/CGlucoseCore.h
@@ -0,0 +1,620 @@
+// The code in this file was developed by He-Teng Zhang (National Taiwan University)
+
+#ifndef Glucose_CGlucoseCore_h
+#define Glucose_CGlucoseCore_h
+
+/*
+ * justification for glucose
+ */
+
+#include "sat/glucose2/Options.h"
+#include "sat/glucose2/Solver.h"
+
+ABC_NAMESPACE_IMPL_START
+
+namespace Gluco2 {
+inline int Solver::justUsage() const { return jftr; }
+
+inline Lit Solver::gateJustFanin(Var v) const {
+ assert(v < nVars());
+ assert(isJReason(v));
+
+
+ lbool val0, val1;
+ val0 = value(getFaninLit0(v));
+ val1 = value(getFaninLit1(v));
+
+ if(isAND(v)){
+ // should be handled by conflict analysis before entering here
+ assert( value(v) != l_False || l_True != val0 || l_True != val1 );
+
+ if(val0 == l_False || val1 == l_False)
+ return lit_Undef;
+
+ // branch
+ if(val0 == l_True)
+ return ~getFaninLit1(v);
+ if(val1 == l_True)
+ return ~getFaninLit0(v);
+
+ //assert( jdata[v].act_fanin == activity[getFaninVar0(v)] || jdata[v].act_fanin == activity[getFaninVar1(v)] );
+ //assert( jdata[v].act_fanin == (jdata[v].adir? activity[getFaninVar1(v)]: activity[getFaninVar0(v)]) );
+ return maxActiveLit( ~getFaninLit0(v), ~getFaninLit1(v) );
+ //return jdata[v].adir? ~getFaninLit1(v): ~getFaninLit0(v);
+ } else { // xor scope
+ // should be handled by conflict analysis before entering here
+ assert( value(v) == l_Undef || value(v) != l_False || val0 == val1 );
+
+ // both are assigned
+ if( l_Undef != val0 && l_Undef != val1 )
+ return lit_Undef;
+
+ // should be handled by propagation before entering here
+ assert( l_Undef == val0 && l_Undef == val1 );
+ return maxActiveLit( getFaninPlt0(v), getFaninPlt1(v) );
+ }
+}
+
+
+// a var should at most be enqueued one time
+inline void Solver::pushJustQueue(Var v, int index){
+ assert(v < nVars());
+ assert(isJReason(v));
+
+ if( ! isRoundWatch(v) )\
+ return;
+
+ var2NodeData[v].now = true;
+
+
+ if( activity[getFaninVar1(v)] > activity[getFaninVar0(v)] )
+ jheap.update( JustKey( activity[getFaninVar1(v)], v, index ) );
+ else
+ jheap.update( JustKey( activity[getFaninVar0(v)], v, index ) );
+}
+
+inline void Solver::uncheckedEnqueue2(Lit p, CRef from)
+{
+ //assert( isRoundWatch(var(p)) ); // inplace sorting guarantee this
+ assert(value(p) == l_Undef);
+ assigns[var(p)] = lbool(!sign(p));
+ vardata[var(p)] = mkVarData(from, decisionLevel());
+ trail.push_(p);
+}
+
+inline void Solver::ResetJustData(bool fCleanMemory){
+ jhead = 0;
+ jheap .clear_( fCleanMemory );
+}
+
+inline Lit Solver::pickJustLit( int& index ){
+ Var next = var_Undef;
+ Lit jlit = lit_Undef;
+
+ for( ; jhead < trail.size() ; jhead++ ){
+ Var x = var(trail[jhead]);
+ if( !decisionLevel() && !isRoundWatch(x) ) continue;
+ if( isJReason(x) && l_Undef == value( getFaninVar0(x) ) && l_Undef == value( getFaninVar1(x) ) )
+ pushJustQueue(x,jhead);
+ }
+
+ while( ! jheap.empty() ){
+ next = jheap.removeMin(index);
+ if( ! var2NodeData[next].now )
+ continue;
+
+ assert(isJReason(next));
+ if( lit_Undef != (jlit = gateJustFanin(next)) ){
+ //assert( jheap.prev.key() == activity[getFaninVar0(next)] || jheap.prev.key() == activity[getFaninVar1(next)] );
+ break;
+ }
+ gateAddJwatch(next,index);
+ }
+
+ return jlit;
+}
+
+
+inline void Solver::gateAddJwatch(Var v,int index){
+ assert(v < nVars());
+ assert(isJReason(v));
+
+ lbool val0, val1;
+ Var var0, var1;
+ var0 = getFaninVar0(v);
+ var1 = getFaninVar1(v);
+ val0 = value(getFaninLit0(v));
+ val1 = value(getFaninLit1(v));
+
+ assert( !isAND(v) || l_False == val0 || l_False == val1 );
+ assert( isAND(v) || (l_Undef != val0 && l_Undef != val1) );
+
+ if( (val0 == l_False && val1 == l_False) || !isAND(v) ){
+ addJwatch(vardata[var0].level < vardata[var1].level? var0: var1, v, index);
+ return;
+ }
+
+ addJwatch(l_False == val0? var0: var1, v, index);
+
+ return;
+}
+
+inline void Solver::updateJustActivity( Var v ){
+ if( ! var2NodeData[v].sort )
+ inplace_sort(v);
+
+ int nFanout = 0;
+ for(Lit lfo = var2Fanout0[ v ]; nFanout < var2NodeData[v].sort; lfo = var2FanoutN[ toInt(lfo) ], nFanout ++ ){
+ Var x = var(lfo);
+ if( var2NodeData[x].now && jheap.inHeap(x) ){
+ if( activity[getFaninVar1(x)] > activity[getFaninVar0(x)] )
+ jheap.update( JustKey( activity[getFaninVar1(x)], x, jheap.data_attr(x) ) );
+ else
+ jheap.update( JustKey( activity[getFaninVar0(x)], x, jheap.data_attr(x) ) );
+ }
+ }
+}
+
+
+inline void Solver::addJwatch( Var host, Var member, int index ){
+ assert(level(host) >= level(member));
+ jnext[index] = jlevel[level(host)];
+ jlevel[level(host)] = index;
+}
+
+/*
+ * circuit propagation
+ */
+
+inline void Solver::justCheck(){
+ Lit lit;
+ int i, nJustFail = 0;
+ for(i=0; i<trail.size(); i++){
+ Var x = var(trail[i]);
+ if( ! isRoundWatch(x) )
+ continue;
+ if( !isJReason(x) )
+ continue;
+ if( lit_Undef != (lit = gateJustFanin(x)) ){
+ printf("\t%8d is not justified (value=%d, level=%3d)\n", x, l_True == value(x)? 1: 0, vardata[x].level), nJustFail ++ ;
+
+ assert(false);
+ }
+ }
+ if( nJustFail )
+ printf("%d just-fails\n", nJustFail);
+}
+/**
+inline void Solver::delVarFaninLits( Var v ){
+ if( toLit(~0) != getFaninLit0(v) ){
+ if( toLit(~0) == var2FanoutP[ (v<<1) + 0 ] ){
+ // head of linked-list
+ Lit root = mkLit(getFaninVar0(v));
+ Lit next = var2FanoutN[ (v<<1) + 0 ];
+ if( toLit(~0) != next ){
+ assert( var2Fanout0[ toInt(root) ] == toLit((v<<1) + 0) );
+ assert( var2FanoutP[ toInt(next) ] == toLit((v<<1) + 0) );
+ var2Fanout0[ getFaninVar0(v) ] = next;
+ var2FanoutP[ toInt(next) ] = toLit(~0);
+ }
+ } else {
+ Lit prev = var2FanoutP[ (v<<1) + 0 ];
+ Lit next = var2FanoutN[ (v<<1) + 0 ];
+ if( toLit(~0) != next ){
+ assert( var2FanoutN[ toInt(prev) ] == toLit((v<<1) + 0) );
+ assert( var2FanoutP[ toInt(next) ] == toLit((v<<1) + 0) );
+ var2FanoutN[ toInt(prev) ] = next;
+ var2FanoutP[ toInt(next) ] = prev;
+ }
+ }
+ }
+
+
+ if( toLit(~0) != getFaninLit1(v) ){
+ if( toLit(~0) == var2FanoutP[ (v<<1) + 1 ] ){
+ // head of linked-list
+ Lit root = mkLit(getFaninVar1(v));
+ Lit next = var2FanoutN[ (v<<1) + 1 ];
+ if( toLit(~0) != next ){
+ assert( var2Fanout0[ toInt(root) ] == toLit((v<<1) + 1) );
+ assert( var2FanoutP[ toInt(next) ] == toLit((v<<1) + 1) );
+ var2Fanout0[ getFaninVar1(v) ] = next;
+ var2FanoutP[ toInt(next) ] = toLit(~0);
+ }
+ } else {
+ Lit prev = var2FanoutP[ (v<<1) + 1 ];
+ Lit next = var2FanoutN[ (v<<1) + 1 ];
+ if( toLit(~0) != next ){
+ assert( var2FanoutN[ toInt(prev) ] == toLit((v<<1) + 1) );
+ assert( var2FanoutP[ toInt(next) ] == toLit((v<<1) + 1) );
+ var2FanoutN[ toInt(prev) ] = next;
+ var2FanoutP[ toInt(next) ] = prev;
+ }
+ }
+ }
+
+ var2FanoutP [ (v<<1) + 0 ] = toLit(~0);
+ var2FanoutP [ (v<<1) + 1 ] = toLit(~0);
+ var2FanoutN [ (v<<1) + 0 ] = toLit(~0);
+ var2FanoutN [ (v<<1) + 1 ] = toLit(~0);
+ var2FaninLits[ (v<<1) + 0 ] = toLit(~0);
+ var2FaninLits[ (v<<1) + 1 ] = toLit(~0);
+}
+**/
+inline void Solver::setVarFaninLits( Var v, Lit lit1, Lit lit2 ){
+ assert( var(lit1) != var(lit2) );
+ int mincap = var(lit1) < var(lit2)? var(lit2): var(lit1);
+ mincap = (v < mincap? mincap: v) + 1;
+
+ var2NodeData[ v ].lit0 = lit1;
+ var2NodeData[ v ].lit1 = lit2;
+
+
+ assert( toLit(~0) != lit1 && toLit(~0) != lit2 );
+
+ var2FanoutN[ (v<<1) + 0 ] = var2Fanout0[ var(lit1) ];
+ var2FanoutN[ (v<<1) + 1 ] = var2Fanout0[ var(lit2) ];
+ var2Fanout0[ var(lit1) ] = toLit( (v<<1) + 0 );
+ var2Fanout0[ var(lit2) ] = toLit( (v<<1) + 1 );
+
+ //if( toLit(~0) != var2FanoutN[ (v<<1) + 0 ] )
+ // var2FanoutP[ toInt(var2FanoutN[ (v<<1) + 0 ]) ] = toLit((v<<1) + 0);
+
+ //if( toLit(~0) != var2FanoutN[ (v<<1) + 1 ] )
+ // var2FanoutP[ toInt(var2FanoutN[ (v<<1) + 1 ]) ] = toLit((v<<1) + 1);
+}
+
+
+inline bool Solver::isTwoFanin( Var v ) const {
+ Lit lit0 = var2NodeData[ v ].lit0;
+ Lit lit1 = var2NodeData[ v ].lit1;
+ assert( toLit(~0) == lit0 || var(lit0) < nVars() );
+ assert( toLit(~0) == lit1 || var(lit1) < nVars() );
+ lit0.x = lit1.x = 0; // suppress the warning - alanmi
+ return toLit(~0) != var2NodeData[ v ].lit0 && toLit(~0) != var2NodeData[ v ].lit1;
+}
+
+// this implementation return the last conflict encountered
+// which follows minisat concept
+inline CRef Solver::gatePropagate( Lit p ){
+ CRef confl = CRef_Undef, stats;
+ if( justUsage() < 2 )
+ return CRef_Undef;
+
+ if( ! isRoundWatch(var(p)) )
+ return CRef_Undef;
+
+ if( ! isTwoFanin( var(p) ) )
+ goto check_fanout;
+
+
+ // check fanin consistency
+ if( CRef_Undef != (stats = gatePropagateCheckThis( var(p) )) ){
+ confl = stats;
+ if( l_True == value(var(p)) )
+ return confl;
+ }
+
+ // check fanout consistency
+check_fanout:
+ assert( var(p) < var2Fanout0.size() );
+
+ if( ! var2NodeData[var(p)].sort )
+ inplace_sort(var(p));
+
+ int nFanout = 0;
+ for( Lit lfo = var2Fanout0[ var(p) ]; nFanout < var2NodeData[var(p)].sort; lfo = var2FanoutN[ toInt(lfo) ], nFanout ++ )
+ {
+ if( CRef_Undef != (stats = gatePropagateCheckFanout( var(p), lfo )) ){
+ confl = stats;
+ if( l_True == value(var(lfo)) )
+ return confl;
+ }
+ }
+
+ return confl;
+}
+
+inline CRef Solver::gatePropagateCheckFanout( Var v, Lit lfo ){
+ Lit faninLit = sign(lfo)? getFaninLit1(var(lfo)): getFaninLit0(var(lfo));
+ assert( var(faninLit) == v );
+ if( isAND(var(lfo)) ){
+ if( l_False == value(faninLit) )
+ {
+ if( l_False == value(var(lfo)) )
+ return CRef_Undef;
+
+ if( l_True == value(var(lfo)) )
+ return Var2CRef(var(lfo));
+
+ var2NodeData[var(lfo)].dir = sign(lfo);
+ uncheckedEnqueue2(~mkLit(var(lfo)), Var2CRef( var(lfo) ) );
+ } else {
+ assert( l_True == value(faninLit) );
+
+ if( l_True == value(var(lfo)) )
+ return CRef_Undef;
+
+ // check value of the other fanin
+ Lit faninLitP = sign(lfo)? getFaninLit0(var(lfo)): getFaninLit1(var(lfo));
+ if( l_False == value(var(lfo)) ){
+
+ if( l_False == value(faninLitP) )
+ return CRef_Undef;
+
+ if( l_True == value(faninLitP) )
+ return Var2CRef(var(lfo));
+
+ uncheckedEnqueue2( ~faninLitP, Var2CRef( var(lfo) ) );
+ }
+ else
+ if( l_True == value(faninLitP) )
+ uncheckedEnqueue2( mkLit(var(lfo)), Var2CRef( var(lfo) ) );
+ }
+ } else { // xor scope
+ // check value of the other fanin
+ Lit faninLitP = sign(lfo)? getFaninLit0(var(lfo)): getFaninLit1(var(lfo));
+
+ lbool val0, val1, valo;
+ val0 = value(faninLit );
+ val1 = value(faninLitP);
+ valo = value(var(lfo));
+
+ if( l_Undef == val1 && l_Undef == valo )
+ return CRef_Undef;
+ else
+ if( l_Undef == val1 )
+ uncheckedEnqueue2( ~faninLitP ^ ( (l_True == val0) ^ (l_True == valo) ), Var2CRef( var(lfo) ) );
+ else
+ if( l_Undef == valo )
+ uncheckedEnqueue2( ~mkLit( var(lfo), (l_True == val0) ^ (l_True == val1) ), Var2CRef( var(lfo) ) );
+ else
+ if( l_False == (valo ^ (val0 == val1)) )
+ return Var2CRef(var(lfo));
+
+ }
+
+ return CRef_Undef;
+}
+
+inline CRef Solver::gatePropagateCheckThis( Var v ){
+ CRef confl = CRef_Undef;
+ if( isAND(v) ){
+ if( l_False == value(v) ){
+ if( l_True == value(getFaninLit0(v)) && l_True == value(getFaninLit1(v)) )
+ return Var2CRef(v);
+
+ if( l_False == value(getFaninLit0(v)) || l_False == value(getFaninLit1(v)) )
+ return CRef_Undef;
+
+ if( l_True == value(getFaninLit0(v)) )
+ uncheckedEnqueue2(~getFaninLit1( v ), Var2CRef( v ) );
+ if( l_True == value(getFaninLit1(v)) )
+ uncheckedEnqueue2(~getFaninLit0( v ), Var2CRef( v ) );
+ } else {
+ assert( l_True == value(v) );
+ if( l_False == value(getFaninLit0(v)) || l_False == value(getFaninLit1(v)) )
+ confl = Var2CRef(v);
+
+ if( l_Undef == value( getFaninLit0( v )) )
+ uncheckedEnqueue2( getFaninLit0( v ), Var2CRef( v ) );
+
+ if( l_Undef == value( getFaninLit1( v )) )
+ uncheckedEnqueue2( getFaninLit1( v ), Var2CRef( v ) );
+
+ }
+ } else { // xor scope
+ lbool val0, val1, valo;
+ val0 = value(getFaninLit0(v));
+ val1 = value(getFaninLit1(v));
+ valo = value(v);
+ if( l_Undef == val0 && l_Undef == val1 )
+ return CRef_Undef;
+ if( l_Undef == val0 )
+ uncheckedEnqueue2(~getFaninLit0( v ) ^ ( (l_True == val1) ^ (l_True == valo) ), Var2CRef( v ) );
+ else
+ if( l_Undef == val1 )
+ uncheckedEnqueue2(~getFaninLit1( v ) ^ ( (l_True == val0) ^ (l_True == valo) ), Var2CRef( v ) );
+ else
+ if( l_False == (valo ^ (val0 == val1)) )
+ return Var2CRef(v);
+ }
+
+ return confl;
+}
+
+inline CRef Solver::getConfClause( CRef r ){
+ if( !isGateCRef(r) )
+ return r;
+ Var v = CRef2Var(r);
+ assert( isTwoFanin(v) );
+
+ if(isAND(v)){
+ if( l_False == value(v) ){
+ setItpcSize(3);
+ Clause& c = ca[itpc];
+ c[0] = mkLit(v);
+ c[1] = ~getFaninLit0( v );
+ c[2] = ~getFaninLit1( v );
+ } else {
+ setItpcSize(2);
+ Clause& c = ca[itpc];
+ c[0] = ~mkLit(v);
+
+ lbool val0 = value(getFaninLit0(v));
+ lbool val1 = value(getFaninLit1(v));
+
+ if( l_False == val0 && l_False == val1 )
+ c[1] = level(getFaninVar0(v)) < level(getFaninVar1(v))? getFaninLit0( v ): getFaninLit1( v );
+ else
+ if( l_False == val0 )
+ c[1] = getFaninLit0( v );
+ else
+ c[1] = getFaninLit1( v );
+ }
+ } else { // xor scope
+ setItpcSize(3);
+ Clause& c = ca[itpc];
+ c[0] = mkLit(v, l_True == value(v));
+ c[1] = mkLit(getFaninVar0(v), l_True == value(getFaninVar0(v)));
+ c[2] = mkLit(getFaninVar1(v), l_True == value(getFaninVar1(v)));
+ }
+
+
+ return itpc;
+}
+
+inline void Solver::setItpcSize( int sz ){
+ assert( 3 >= sz );
+ assert( CRef_Undef != itpc );
+ ca[itpc].header.size = sz;
+}
+
+inline CRef Solver::interpret( Var v, Var t )
+{ // get gate-clause on implication graph
+ assert( isTwoFanin(v) );
+
+ lbool val0, val1, valo;
+ Var var0, var1;
+ var0 = getFaninVar0( v );
+ var1 = getFaninVar1( v );
+ val0 = value(var0);
+ val1 = value(var1);
+ valo = value( v );
+
+ // phased values
+ if(l_Undef != val0) val0 = val0 ^ getFaninC0( v );
+ if(l_Undef != val1) val1 = val1 ^ getFaninC1( v );
+
+
+ if( isAND(v) ){
+ if( v == t ){ // tracing output
+ if( l_False == valo ){
+ setItpcSize(2);
+ Clause& c = ca[itpc];
+ c[0] = ~mkLit(v);
+
+ c[1] = var2NodeData[v].dir ? getFaninLit1( v ): getFaninLit0( v );
+ } else {
+ setItpcSize(3);
+ Clause& c = ca[itpc];
+ c[0] = mkLit(v);
+ c[1] = ~getFaninLit0( v );
+ c[2] = ~getFaninLit1( v );
+ }
+ } else {
+ assert( t == var0 || t == var1 );
+ if( l_False == valo ){
+ setItpcSize(3);
+ Clause& c = ca[itpc];
+ c[0] = ~getFaninLit0( v );
+ c[1] = ~getFaninLit1( v );
+ c[2] = mkLit(v);
+ if( t == var1 )
+ c[1].x ^= c[0].x, c[0].x ^= c[1].x, c[1].x ^= c[0].x;
+ } else {
+ setItpcSize(2);
+ Clause& c = ca[itpc];
+ c[0] = t == var0? getFaninLit0( v ): getFaninLit1( v );
+ c[1] = ~mkLit(v);
+ }
+ }
+ } else { // xor scope
+ setItpcSize(3);
+ Clause& c = ca[itpc];
+ if( v == t ){
+ c[0] = mkLit(v, l_False == value(v));
+ c[1] = mkLit(var0, l_True == value(var0));
+ c[2] = mkLit(var1, l_True == value(var1));
+ } else {
+ if( t == var0)
+ c[0] = mkLit(var0, l_False == value(var0)), c[1] = mkLit(var1, l_True == value(var1));
+ else
+ c[1] = mkLit(var0, l_True == value(var0)), c[0] = mkLit(var1, l_False == value(var1));
+ c[2] = mkLit(v, l_True == value(v));
+ }
+ }
+
+ return itpc;
+}
+
+inline CRef Solver::castCRef( Lit p ){
+ CRef cr = reason( var(p) );
+ if( CRef_Undef == cr )
+ return cr;
+ if( ! isGateCRef(cr) )
+ return cr;
+ Var v = CRef2Var(cr);
+ return interpret(v,var(p));
+}
+
+inline void Solver::markCone( Var v ){
+ if( var2TravId[v] >= travId )
+ return;
+ var2TravId[v] = travId;
+ var2NodeData[v].sort = 0;
+ Var var0, var1;
+ var0 = getFaninVar0(v);
+ var1 = getFaninVar1(v);
+ if( !isTwoFanin(v) )
+ return;
+ markCone( var0 );
+ markCone( var1 );
+}
+
+inline void Solver::inplace_sort( Var v ){
+ Lit w, next, prev;
+ prev= var2Fanout0[v];
+
+ if( toLit(~0) == prev ) return;
+
+ if( isRoundWatch(var(prev)) )
+ var2NodeData[v].sort ++ ;
+
+ if( toLit(~0) == (w = var2FanoutN[toInt(prev)]) )
+ return;
+
+ while( toLit(~0) != w ){
+ next = var2FanoutN[toInt(w)];
+ if( isRoundWatch(var(w)) )
+ var2NodeData[v].sort ++ ;
+ if( isRoundWatch(var(w)) && !isRoundWatch(var(prev)) ){
+ var2FanoutN[toInt(w)] = var2Fanout0[v];
+ var2Fanout0[v] = w;
+ var2FanoutN[toInt(prev)] = next;
+ } else
+ prev = w;
+ w = next;
+ }
+}
+
+inline void Solver::prelocate( int base_var_num ){
+ if( justUsage() ){
+ var2FanoutN .prelocate( base_var_num << 1 );
+ var2Fanout0 .prelocate( base_var_num );
+ var2NodeData.prelocate( base_var_num );
+ var2TravId .prelocate( base_var_num );
+ jheap .prelocate( base_var_num );
+ jlevel .prelocate( base_var_num );
+ jnext .prelocate( base_var_num );
+ }
+ watches .prelocate( base_var_num << 1 );
+ watchesBin .prelocate( base_var_num << 1 );
+
+ decision .prelocate( base_var_num );
+ trail .prelocate( base_var_num );
+ assigns .prelocate( base_var_num );
+ vardata .prelocate( base_var_num );
+ activity .prelocate( base_var_num );
+
+
+ seen .prelocate( base_var_num );
+ permDiff .prelocate( base_var_num );
+ polarity .prelocate( base_var_num );
+}
+
+};
+
+ABC_NAMESPACE_IMPL_END
+
+#endif
diff --git a/src/sat/glucose2/Constants.h b/src/sat/glucose2/Constants.h
new file mode 100644
index 00000000..4cccad24
--- /dev/null
+++ b/src/sat/glucose2/Constants.h
@@ -0,0 +1,33 @@
+/************************************************************************************[Constants.h]
+ Glucose -- Copyright (c) 2009, Gilles Audemard, Laurent Simon
+ CRIL - Univ. Artois, France
+ LRI - Univ. Paris Sud, France
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#define DYNAMICNBLEVEL
+#define CONSTANTREMOVECLAUSE
+#define UPDATEVARACTIVITY
+
+// Constants for clauses reductions
+#define RATIOREMOVECLAUSES 2
+
+
+
+// Constants for restarts
+#define LOWER_BOUND_FOR_BLOCKING_RESTART 10000
+
diff --git a/src/sat/glucose2/Dimacs.h b/src/sat/glucose2/Dimacs.h
new file mode 100644
index 00000000..1d6a0bed
--- /dev/null
+++ b/src/sat/glucose2/Dimacs.h
@@ -0,0 +1,93 @@
+/****************************************************************************************[Dimacs.h]
+Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
+Copyright (c) 2007-2010, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#ifndef Glucose_Dimacs_h
+#define Glucose_Dimacs_h
+
+#include <stdio.h>
+
+#include "sat/glucose2/ParseUtils.h"
+#include "sat/glucose2/SolverTypes.h"
+
+ABC_NAMESPACE_CXX_HEADER_START
+
+namespace Gluco2 {
+
+//=================================================================================================
+// DIMACS Parser:
+
+template<class B, class Solver>
+static void readClause(B& in, Solver& S, vec<Lit>& lits) {
+ int parsed_lit, var;
+ lits.clear();
+ for (;;){
+ parsed_lit = parseInt(in);
+ if (parsed_lit == 0) break;
+ var = abs(parsed_lit)-1;
+ while (var >= S.nVars()) S.newVar();
+ lits.push( (parsed_lit > 0) ? mkLit(var) : ~mkLit(var) );
+ }
+}
+
+template<class B, class Solver>
+static void parse_DIMACS_main(B& in, Solver& S) {
+ vec<Lit> lits;
+ int vars = 0;
+ int clauses = 0;
+ int cnt = 0;
+ for (;;){
+ skipWhitespace(in);
+ if (*in == EOF) break;
+ else if (*in == 'p'){
+ if (eagerMatch(in, "p cnf")){
+ vars = parseInt(in);
+ clauses = parseInt(in);
+ // SATRACE'06 hack
+ // if (clauses > 4000000)
+ // S.eliminate(true);
+ }else{
+ printf("PARSE ERROR! Unexpected char: %c\n", *in), exit(3);
+ }
+ } else if (*in == 'c' || *in == 'p')
+ skipLine(in);
+ else{
+ cnt++;
+ readClause(in, S, lits);
+ S.addClause_(lits); }
+ }
+ if (vars != S.nVars())
+ fprintf(stderr, "WARNING! DIMACS header mismatch: wrong number of variables.\n");
+ if (cnt != clauses)
+ fprintf(stderr, "WARNING! DIMACS header mismatch: wrong number of clauses.\n");
+}
+
+// Inserts problem into solver.
+//
+template<class Solver>
+static void parse_DIMACS(gzFile input_stream, Solver& S) {
+ StreamBuffer in(input_stream);
+ parse_DIMACS_main(in, S); }
+
+//=================================================================================================
+}
+
+ABC_NAMESPACE_CXX_HEADER_END
+
+#endif
diff --git a/src/sat/glucose2/Glucose2.cpp b/src/sat/glucose2/Glucose2.cpp
new file mode 100644
index 00000000..7a8b265b
--- /dev/null
+++ b/src/sat/glucose2/Glucose2.cpp
@@ -0,0 +1,1749 @@
+/***************************************************************************************[Solver.cc]
+ Glucose -- Copyright (c) 2013, Gilles Audemard, Laurent Simon
+ CRIL - Univ. Artois, France
+ LRI - Univ. Paris Sud, France
+
+Glucose sources are based on MiniSat (see below MiniSat copyrights). Permissions and copyrights of
+Glucose are exactly the same as Minisat on which it is based on. (see below).
+
+---------------
+
+Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
+Copyright (c) 2007-2010, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+#include <math.h>
+
+#include "sat/glucose2/Sort.h"
+#include "sat/glucose2/Constants.h"
+#include "sat/glucose2/System.h"
+#include "sat/glucose2/Solver.h"
+
+#include "sat/glucose2/CGlucose.h"
+
+ABC_NAMESPACE_IMPL_START
+
+using namespace Gluco2;
+
+//=================================================================================================
+// Options:
+namespace Gluco2 {
+static const char* _cat = "CORE";
+static const char* _cr = "CORE -- RESTART";
+static const char* _cred = "CORE -- REDUCE";
+static const char* _cm = "CORE -- MINIMIZE";
+static const char* _certified = "CORE -- CERTIFIED UNSAT";
+
+
+
+
+static BoolOption opt_incremental (_cat,"incremental", "Use incremental SAT solving", false);
+static DoubleOption opt_K (_cr, "K", "The constant used to force restart", 0.8, DoubleRange(0, false, 1, false));
+static DoubleOption opt_R (_cr, "R", "The constant used to block restart", 1.4, DoubleRange(1, false, 5, false));
+static IntOption opt_size_lbd_queue (_cr, "szLBDQueue", "The size of moving average for LBD (restarts)", 50, IntRange(10, INT32_MAX));
+static IntOption opt_size_trail_queue (_cr, "szTrailQueue", "The size of moving average for trail (block restarts)", 5000, IntRange(10, INT32_MAX));
+
+static IntOption opt_first_reduce_db (_cred, "firstReduceDB", "The number of conflicts before the first reduce DB", 2000, IntRange(0, INT32_MAX));
+static IntOption opt_inc_reduce_db (_cred, "incReduceDB", "Increment for reduce DB", 300, IntRange(0, INT32_MAX));
+static IntOption opt_spec_inc_reduce_db (_cred, "specialIncReduceDB", "Special increment for reduce DB", 1000, IntRange(0, INT32_MAX));
+static IntOption opt_lb_lbd_frozen_clause (_cred, "minLBDFrozenClause", "Protect clauses if their LBD decrease and is lower than (for one turn)", 30, IntRange(0, INT32_MAX));
+
+static IntOption opt_lb_size_minimzing_clause (_cm, "minSizeMinimizingClause", "The min size required to minimize clause", 30, IntRange(3, INT32_MAX));
+static IntOption opt_lb_lbd_minimzing_clause (_cm, "minLBDMinimizingClause", "The min LBD required to minimize clause", 6, IntRange(3, INT32_MAX));
+
+
+static DoubleOption opt_var_decay (_cat, "var-decay", "The variable activity decay factor", 0.8, DoubleRange(0, false, 1, false));
+static DoubleOption opt_clause_decay (_cat, "cla-decay", "The clause activity decay factor", 0.999, DoubleRange(0, false, 1, false));
+static DoubleOption opt_random_var_freq (_cat, "rnd-freq", "The frequency with which the decision heuristic tries to choose a random variable", 0, DoubleRange(0, true, 1, true));
+static DoubleOption opt_random_seed (_cat, "rnd-seed", "Used by the random variable selection", 91648253, DoubleRange(0, false, HUGE_VAL, false));
+static IntOption opt_ccmin_mode (_cat, "ccmin-mode", "Controls conflict clause minimization (0=none, 1=basic, 2=deep)", 2, IntRange(0, 2));
+static IntOption opt_phase_saving (_cat, "phase-saving", "Controls the level of phase saving (0=none, 1=limited, 2=full)", 2, IntRange(0, 2));
+static BoolOption opt_rnd_init_act (_cat, "rnd-init", "Randomize the initial activity", false);
+/*
+static IntOption opt_restart_first (_cat, "rfirst", "The base restart interval", 100, IntRange(1, INT32_MAX));
+static DoubleOption opt_restart_inc (_cat, "rinc", "Restart interval increase factor", 2, DoubleRange(1, false, HUGE_VAL, false));
+*/
+static DoubleOption opt_garbage_frac (_cat, "gc-frac", "The fraction of wasted memory allowed before a garbage collection is triggered", 0.20, DoubleRange(0, false, HUGE_VAL, false));
+
+
+BoolOption opt_certified_ (_certified, "certified", "Certified UNSAT using DRUP format", false );
+StringOption opt_certified_file_ (_certified, "certified-output", "Certified UNSAT output file", "NULL");
+};
+
+//=================================================================================================
+// Constructor/Destructor:
+
+
+Solver::Solver() :
+
+ // Parameters (user settable):
+ //
+ SolverType(0)
+ , pCnfFunc(NULL)
+ , nCallConfl(1000)
+ , terminate_search_early(false)
+ , pstop(NULL)
+ , nRuntimeLimit(0)
+
+ , verbosity (0)
+ , verbEveryConflicts(10000)
+ , showModel (0)
+ , K (opt_K)
+ , R (opt_R)
+ , sizeLBDQueue (opt_size_lbd_queue)
+ , sizeTrailQueue (opt_size_trail_queue)
+ , firstReduceDB (opt_first_reduce_db)
+ , incReduceDB (opt_inc_reduce_db)
+ , specialIncReduceDB (opt_spec_inc_reduce_db)
+ , lbLBDFrozenClause (opt_lb_lbd_frozen_clause)
+ , lbSizeMinimizingClause (opt_lb_size_minimzing_clause)
+ , lbLBDMinimizingClause (opt_lb_lbd_minimzing_clause)
+ , var_decay (opt_var_decay)
+ , clause_decay (opt_clause_decay)
+ , random_var_freq (opt_random_var_freq)
+ , random_seed (opt_random_seed)
+ , ccmin_mode (opt_ccmin_mode)
+ , phase_saving (opt_phase_saving)
+ , rnd_pol (false)
+ , rnd_init_act (opt_rnd_init_act)
+ , garbage_frac (opt_garbage_frac)
+ , certifiedOutput (NULL)
+ , certifiedUNSAT (opt_certified_)
+ // Statistics: (formerly in 'SolverStats')
+ //
+ , nbRemovedClauses(0),nbReducedClauses(0), nbDL2(0),nbBin(0),nbUn(0) , nbReduceDB(0)
+ , solves(0), starts(0), decisions(0), rnd_decisions(0), propagations(0),conflicts(0),conflictsRestarts(0),nbstopsrestarts(0),nbstopsrestartssame(0),lastblockatrestart(0)
+ , dec_vars(0), clauses_literals(0), learnts_literals(0), max_literals(0), tot_literals(0)
+ , curRestart(1)
+
+ , ok (true)
+ , cla_inc (1)
+ , var_inc (1)
+ , watches (WatcherDeleted(ca))
+ , watchesBin (WatcherDeleted(ca))
+ , qhead (0)
+ , simpDB_assigns (-1)
+ , simpDB_props (0)
+ , order_heap (VarOrderLt(activity))
+ , progress_estimate (0)
+ , remove_satisfied (true)
+
+ // Resource constraints:
+ //
+ , conflict_budget (-1)
+ , propagation_budget (-1)
+ , asynch_interrupt (false)
+ , incremental(opt_incremental)
+ , nbVarsInitialFormula(INT32_MAX)
+
+ #ifdef CGLUCOSE_EXP
+ //, jheap (JustOrderLt(this))
+ , jheap (JustOrderLt2(this))
+ #endif
+{
+ MYFLAG=0;
+
+ // Initialize only first time. Useful for incremental solving, useless otherwise
+ lbdQueue.initSize(sizeLBDQueue);
+ trailQueue.initSize(sizeTrailQueue);
+ sumLBD = 0;
+ nbclausesbeforereduce = firstReduceDB;
+ totalTime4Sat=0;totalTime4Unsat=0;
+ nbSatCalls=0;nbUnsatCalls=0;
+
+
+ if(certifiedUNSAT) {
+ if(!strcmp(opt_certified_file_,"NULL")) {
+ certifiedOutput = fopen("/dev/stdout", "wb");
+ } else {
+ certifiedOutput = fopen(opt_certified_file_, "wb");
+ }
+ // fprintf(certifiedOutput,"o proof DRUP\n");
+ }
+
+ #ifdef CGLUCOSE_EXP
+ jhead= 0;
+ jftr = 0;
+ travId = 0;
+ travId_prev = 0;
+
+ // allocate space for clause interpretation
+ vec<Lit> tmp; tmp.growTo(3);
+ itpc = ca.alloc(tmp);
+ ca[itpc].shrink( ca[itpc].size() );
+
+ #endif
+}
+
+
+Solver::~Solver()
+{
+}
+
+
+/****************************************************************
+ Set the incremental mode
+****************************************************************/
+
+// This function set the incremental mode to true.
+// You can add special code for this mode here.
+
+void Solver::setIncrementalMode() {
+ incremental = true;
+}
+
+// Number of variables without selectors
+void Solver::initNbInitialVars(int nb) {
+ nbVarsInitialFormula = nb;
+}
+
+
+//=================================================================================================
+// Minor methods:
+
+
+// Creates a new SAT variable in the solver. If 'decision' is cleared, variable will not be
+// used as a decision variable (NOTE! This has effects on the meaning of a SATISFIABLE result).
+//
+Var Solver::newVar(bool sign, bool dvar)
+{
+ int v = nVars();
+ watches .init(mkLit(v, false));
+ watches .init(mkLit(v, true ));
+ watchesBin .init(mkLit(v, false));
+ watchesBin .init(mkLit(v, true ));
+ assigns .push(l_Undef);
+ vardata .push(mkVarData(CRef_Undef, 0));
+ //activity .push(0);
+ activity .push(rnd_init_act ? drand(random_seed) * 0.00001 : 0);
+ seen .push(0);
+ permDiff .push(0);
+ polarity .push(sign);
+ decision .push();
+ trail .capacity(v+1);
+
+
+ #ifdef CGLUCOSE_EXP
+ //jreason .capacity(v+1);
+ if( justUsage() ){
+ //jdata .push(mkJustData(false));
+ //jwatch .push(mkJustWatch());
+
+ jlevel .push(-1);
+ jnext .push(-1);
+
+ var2FanoutN.growTo( nVars()<<1, toLit(~0));
+ //var2FanoutP.growTo( nVars()<<1, toLit(~0));
+ var2Fanout0.growTo( nVars(), toLit(~0));
+ var2NodeData.growTo( nVars(), mkNodeData());
+ var2TravId .growTo( nVars(), 0);
+
+ setDecisionVar(v, dvar, false);
+ } else
+ setDecisionVar(v, dvar);
+ #else
+ setDecisionVar(v, dvar);
+ #endif
+
+ return v;
+}
+
+
+
+bool Solver::addClause_(vec<Lit>& ps)
+{
+ assert(decisionLevel() == 0);
+ if (!ok) return false;
+
+ if ( 0 ) {
+ for ( int i = 0; i < ps.size(); i++ )
+ printf( "%s%d ", (toInt(ps[i]) & 1) ? "-":"", toInt(ps[i]) >> 1 );
+ printf( "\n" );
+ }
+
+ // Check if clause is satisfied and remove false/duplicate literals:
+ sort(ps);
+
+ vec<Lit> oc;
+ oc.clear();
+
+ Lit p; int i, j, flag = 0;
+ if(certifiedUNSAT) {
+ for (i = j = 0, p = lit_Undef; i < ps.size(); i++) {
+ oc.push(ps[i]);
+ if (value(ps[i]) == l_True || ps[i] == ~p || value(ps[i]) == l_False)
+ flag = 1;
+ }
+ }
+
+ for (i = j = 0, p = lit_Undef; i < ps.size(); i++)
+ if (value(ps[i]) == l_True || ps[i] == ~p)
+ return true;
+ else if (value(ps[i]) != l_False && ps[i] != p)
+ ps[j++] = p = ps[i];
+ ps.shrink_(i - j);
+
+ if ( 0 ) {
+ for ( int i = 0; i < ps.size(); i++ )
+ printf( "%s%d ", (toInt(ps[i]) & 1) ? "-":"", toInt(ps[i]) >> 1 );
+ printf( "\n" );
+ }
+
+ if (flag && (certifiedUNSAT)) {
+ for (i = j = 0, p = lit_Undef; i < ps.size(); i++)
+ fprintf(certifiedOutput, "%i ", (var(ps[i]) + 1) * (-2 * sign(ps[i]) + 1));
+ fprintf(certifiedOutput, "0\n");
+
+ fprintf(certifiedOutput, "d ");
+ for (i = j = 0, p = lit_Undef; i < oc.size(); i++)
+ fprintf(certifiedOutput, "%i ", (var(oc[i]) + 1) * (-2 * sign(oc[i]) + 1));
+ fprintf(certifiedOutput, "0\n");
+ }
+
+ if (ps.size() == 0)
+ return ok = false;
+ else if (ps.size() == 1){
+ uncheckedEnqueue(ps[0]);
+ return ok = (propagate() == CRef_Undef);
+ }else{
+ CRef cr = ca.alloc(ps, false);
+ clauses.push(cr);
+ attachClause(cr);
+ }
+
+ return true;
+}
+
+
+void Solver::attachClause(CRef cr) {
+ const Clause& c = ca[cr];
+
+ assert(c.size() > 1);
+ if(c.size()==2) {
+ watchesBin[~c[0]].push(Watcher(cr, c[1]));
+ watchesBin[~c[1]].push(Watcher(cr, c[0]));
+ } else {
+ watches[~c[0]].push(Watcher(cr, c[1]));
+ watches[~c[1]].push(Watcher(cr, c[0]));
+ }
+ if (c.learnt()) learnts_literals += c.size();
+ else clauses_literals += c.size(); }
+
+
+
+
+void Solver::detachClause(CRef cr, bool strict) {
+ const Clause& c = ca[cr];
+
+ assert(c.size() > 1);
+ if(c.size()==2) {
+ if (strict){
+ remove(watchesBin[~c[0]], Watcher(cr, c[1]));
+ remove(watchesBin[~c[1]], Watcher(cr, c[0]));
+ }else{
+ // Lazy detaching: (NOTE! Must clean all watcher lists before garbage collecting this clause)
+ watchesBin.smudge(~c[0]);
+ watchesBin.smudge(~c[1]);
+ }
+ } else {
+ if (strict){
+ remove(watches[~c[0]], Watcher(cr, c[1]));
+ remove(watches[~c[1]], Watcher(cr, c[0]));
+ }else{
+ // Lazy detaching: (NOTE! Must clean all watcher lists before garbage collecting this clause)
+ watches.smudge(~c[0]);
+ watches.smudge(~c[1]);
+ }
+ }
+ if (c.learnt()) learnts_literals -= c.size();
+ else clauses_literals -= c.size(); }
+
+
+void Solver::removeClause(CRef cr) {
+
+ Clause& c = ca[cr];
+
+ if (certifiedUNSAT) {
+ fprintf(certifiedOutput, "d ");
+ for (int i = 0; i < c.size(); i++)
+ fprintf(certifiedOutput, "%i ", (var(c[i]) + 1) * (-2 * sign(c[i]) + 1));
+ fprintf(certifiedOutput, "0\n");
+ }
+
+ detachClause(cr);
+ // Don't leave pointers to free'd memory!
+ if (locked(c)) vardata[var(c[0])].reason = CRef_Undef;
+ c.mark(1);
+ ca.free_(cr);
+}
+
+
+bool Solver::satisfied(const Clause& c) const {
+ if(incremental) // Check clauses with many selectors is too time consuming
+ return (value(c[0]) == l_True) || (value(c[1]) == l_True);
+
+ // Default mode.
+ for (int i = 0; i < c.size(); i++)
+ if (value(c[i]) == l_True)
+ return true;
+ return false;
+}
+
+/************************************************************
+ * Compute LBD functions
+ *************************************************************/
+
+inline unsigned int Solver::computeLBD(const vec<Lit> & lits,int end) {
+ int nblevels = 0;
+ MYFLAG++;
+
+ if(incremental) { // ----------------- INCREMENTAL MODE
+ if(end==-1) end = lits.size();
+ unsigned int nbDone = 0;
+ for(int i=0;i<lits.size();i++) {
+ if(nbDone>=end) break;
+ if(isSelector(var(lits[i]))) continue;
+ nbDone++;
+ int l = level(var(lits[i]));
+ if (permDiff[l] != MYFLAG) {
+ permDiff[l] = MYFLAG;
+ nblevels++;
+ }
+ }
+ } else { // -------- DEFAULT MODE. NOT A LOT OF DIFFERENCES... BUT EASIER TO READ
+ for(int i=0;i<lits.size();i++) {
+ int l = level(var(lits[i]));
+ if (permDiff[l] != MYFLAG) {
+ permDiff[l] = MYFLAG;
+ nblevels++;
+ }
+ }
+ }
+
+ return nblevels;
+}
+
+inline unsigned int Solver::computeLBD(const Clause &c) {
+ int nblevels = 0;
+ MYFLAG++;
+
+ if(incremental) { // ----------------- INCREMENTAL MODE
+ int nbDone = 0;
+ for(int i=0;i<c.size();i++) {
+ if(nbDone>=c.sizeWithoutSelectors()) break;
+ if(isSelector(var(c[i]))) continue;
+ nbDone++;
+ int l = level(var(c[i]));
+ if (permDiff[l] != MYFLAG) {
+ permDiff[l] = MYFLAG;
+ nblevels++;
+ }
+ }
+ } else { // -------- DEFAULT MODE. NOT A LOT OF DIFFERENCES... BUT EASIER TO READ
+ for(int i=0;i<c.size();i++) {
+ int l = level(var(c[i]));
+ if (permDiff[l] != MYFLAG) {
+ permDiff[l] = MYFLAG;
+ nblevels++;
+ }
+ }
+ }
+ return nblevels;
+}
+
+
+/******************************************************************
+ * Minimisation with binary reolution
+ ******************************************************************/
+void Solver::minimisationWithBinaryResolution(vec<Lit> &out_learnt) {
+
+ // Find the LBD measure
+ unsigned int lbd = computeLBD(out_learnt);
+ Lit p = ~out_learnt[0];
+
+ if(lbd<=lbLBDMinimizingClause){
+ MYFLAG++;
+
+ for(int i = 1;i<out_learnt.size();i++) {
+ permDiff[var(out_learnt[i])] = MYFLAG;
+ }
+
+ vec<Watcher>& wbin = watchesBin[p];
+ int nb = 0;
+ for(int k = 0;k<wbin.size();k++) {
+ Lit imp = wbin[k].blocker;
+ if(permDiff[var(imp)]==MYFLAG && value(imp)==l_True) {
+ nb++;
+ permDiff[var(imp)]= MYFLAG-1;
+ }
+ }
+ int l = out_learnt.size()-1;
+ if(nb>0) {
+ nbReducedClauses++;
+ for(int i = 1;i<out_learnt.size()-nb;i++) {
+ if(permDiff[var(out_learnt[i])]!=MYFLAG) {
+ Lit p = out_learnt[l];
+ out_learnt[l] = out_learnt[i];
+ out_learnt[i] = p;
+ l--;i--;
+ }
+ }
+
+ out_learnt.shrink_(nb);
+
+ }
+ }
+}
+
+// Revert to the state at given level (keeping all assignment at 'level' but not beyond).
+//
+void Solver::cancelUntil(int level) {
+ if (decisionLevel() > level){
+
+ #ifdef CGLUCOSE_EXP
+ if( 0 < justUsage() ){
+
+ for (int c = trail.size()-1; c >= trail_lim[level]; c--){
+ Var x = var(trail[c]);
+ assigns [x] = l_Undef;
+ if (phase_saving > 1 || ((phase_saving == 1) && c > trail_lim.last()))
+ polarity[x] = sign(trail[c]);
+ //gateClearJwatch(x, level);
+
+ var2NodeData[x].now = false;
+ }
+ for (int l = decisionLevel(); l > level; l -- ){
+ int q = jlevel[l], k;
+ jlevel[l] = -1;
+ while( -1 != q ){
+ k = jnext[q];
+ jnext[q] = -1;
+ Var v = var(trail[q]);
+ if( Solver::level(v) <= level ){
+ pushJustQueue(v,q);
+ }
+ q = k;
+ }
+ }
+ } else
+ #endif
+ for (int c = trail.size()-1; c >= trail_lim[level]; c--){
+ Var x = var(trail[c]);
+ assigns [x] = l_Undef;
+ if (phase_saving > 1 || ((phase_saving == 1) && c > trail_lim.last()))
+ polarity[x] = sign(trail[c]);
+ insertVarOrder(x);
+ }
+
+ jhead = qhead = trail_lim[level];
+
+ trail.shrink_(trail.size() - trail_lim[level]);
+ trail_lim.shrink_(trail_lim.size() - level);
+ }
+}
+
+
+//=================================================================================================
+// Major methods:
+
+
+Lit Solver::pickBranchLit()
+{
+ Var next = var_Undef;
+
+ // Random decision:
+ if (drand(random_seed) < random_var_freq && !order_heap.empty()){
+ next = order_heap[irand(random_seed,order_heap.size())];
+ if (value(next) == l_Undef && decision[next])
+ rnd_decisions++; }
+
+ // Activity based decision:
+ while (next == var_Undef || value(next) != l_Undef || !decision[next])
+ if (order_heap.empty()){
+ next = var_Undef;
+ break;
+ }else
+ next = order_heap.removeMin();
+
+ return next == var_Undef ? lit_Undef : mkLit(next, rnd_pol ? drand(random_seed) < 0.5 : (polarity[next] != 0));
+}
+
+
+/*_________________________________________________________________________________________________
+|
+| analyze : (confl : Clause*) (out_learnt : vec<Lit>&) (out_btlevel : int&) -> [void]
+|
+| Description:
+| Analyze conflict and produce a reason clause.
+|
+| Pre-conditions:
+| * 'out_learnt' is assumed to be cleared.
+| * Current decision level must be greater than root level.
+|
+| Post-conditions:
+| * 'out_learnt[0]' is the asserting literal at level 'out_btlevel'.
+| * If out_learnt.size() > 1 then 'out_learnt[1]' has the greatest decision level of the
+| rest of literals. There may be others from the same level though.
+|
+|________________________________________________________________________________________________@*/
+void Solver::analyze(CRef confl, vec<Lit>& out_learnt,vec<Lit>&selectors, int& out_btlevel,unsigned int &lbd,unsigned int &szWithoutSelectors)
+{
+ //double clk = Abc_Clock();
+ heap_rescale = 0;
+
+ int pathC = 0;
+ Lit p = lit_Undef;
+
+ // Generate conflict clause:
+ //
+ out_learnt.push(); // (leave room for the asserting literal)
+ int index = trail.size() - 1;
+
+ analyze_toclear.shrink_( analyze_toclear.size() );
+ do{
+ assert(confl != CRef_Undef); // (otherwise should be UIP)
+
+ #ifdef CGLUCOSE_EXP
+ Clause& c = ca[ lit_Undef != p ? castCRef(p): getConfClause(confl) ];
+ #else
+ Clause& c = ca[confl];
+ #endif
+
+ // Special case for binary clauses
+ // The first one has to be SAT
+ if( p != lit_Undef && c.size()==2 && value(c[0])==l_False) {
+
+ assert(value(c[1])==l_True);
+ Lit tmp = c[0];
+ c[0] = c[1], c[1] = tmp;
+ }
+
+ if (c.learnt())
+ claBumpActivity(c);
+
+#ifdef DYNAMICNBLEVEL
+ // DYNAMIC NBLEVEL trick (see competition'09 companion paper)
+ if(c.learnt() && c.lbd()>2) {
+ unsigned int nblevels = computeLBD(c);
+ if(nblevels+1<c.lbd() ) { // improve the LBD
+ if(c.lbd()<=lbLBDFrozenClause) {
+ c.setCanBeDel(false);
+ }
+ // seems to be interesting : keep it for the next round
+ c.setLBD(nblevels); // Update it
+ }
+ }
+#endif
+
+
+ for (int j = (p == lit_Undef) ? 0 : 1; j < c.size(); j++){
+ Lit q = c[j];
+ bool fBump = 0;
+
+ if (!seen[var(q)] && level(var(q)) > 0){
+ if(!isSelector(var(q))){
+ fBump = 1;
+ varBumpActivity(var(q));
+ }
+ seen[var(q)] = 1;
+ if (level(var(q)) >= decisionLevel()) {
+ if( fBump )
+ analyze_toclear.push(q);
+ pathC++;
+ #ifdef UPDATEVARACTIVITY
+ // UPDATEVARACTIVITY trick (see competition'09 companion paper)
+ #ifdef CGLUCOSE_EXP
+ if(!isSelector(var(q)) && (reason(var(q))!= CRef_Undef)
+ && ! isGateCRef(reason(var(q))) && ca[reason(var(q))].learnt())
+ lastDecisionLevel.push(q);
+ #else
+ if(!isSelector(var(q)) && (reason(var(q))!= CRef_Undef) && ca[reason(var(q))].learnt())
+ lastDecisionLevel.push(q);
+ #endif
+ #endif
+
+ } else {
+ if(isSelector(var(q))) {
+ assert(value(q) == l_False);
+ selectors.push(q);
+ } else
+ out_learnt.push(q);
+ }
+ }
+ }
+
+ // Select next clause to look at:
+ while (!seen[var(trail[index--])]);
+ p = trail[index+1];
+ confl = reason(var(p));
+ seen[var(p)] = 0;
+ pathC--;
+
+ }while (pathC > 0);
+ out_learnt[0] = ~p;
+
+ // Simplify conflict clause:
+ //
+ int i, j;
+
+ for(i = 0;i<selectors.size();i++) out_learnt.push(selectors[i]);
+
+
+ #ifdef CGLUCOSE_EXP
+ for(i = 0;i<out_learnt.size();i++)
+ analyze_toclear.push(out_learnt[i]);
+ #else
+ out_learnt.copyTo_(analyze_toclear);
+ #endif
+ if (ccmin_mode == 2){
+ uint32_t abstract_level = 0;
+ for (i = 1; i < out_learnt.size(); i++)
+ abstract_level |= abstractLevel(var(out_learnt[i])); // (maintain an abstraction of levels involved in conflict)
+
+ for (i = j = 1; i < out_learnt.size(); i++)
+ if (reason(var(out_learnt[i])) == CRef_Undef || !litRedundant(out_learnt[i], abstract_level))
+ out_learnt[j++] = out_learnt[i];
+
+ }else if (ccmin_mode == 1){
+ for (i = j = 1; i < out_learnt.size(); i++){
+ Var x = var(out_learnt[i]);
+
+ if (reason(x) == CRef_Undef)
+ out_learnt[j++] = out_learnt[i];
+ else{
+ #ifdef CGLUCOSE_EXP
+ Clause& c = ca[castCRef(out_learnt[i])];
+ #else
+ Clause& c = ca[reason(var(out_learnt[i]))];
+ #endif
+ // Thanks to Siert Wieringa for this bug fix!
+ for (int k = ((c.size()==2) ? 0:1); k < c.size(); k++)
+ if (!seen[var(c[k])] && level(var(c[k])) > 0){
+ out_learnt[j++] = out_learnt[i];
+ break; }
+ }
+ }
+ }else
+ i = j = out_learnt.size();
+
+ max_literals += out_learnt.size();
+ out_learnt.shrink_(i - j);
+ tot_literals += out_learnt.size();
+
+
+ /* ***************************************
+ Minimisation with binary clauses of the asserting clause
+ First of all : we look for small clauses
+ Then, we reduce clauses with small LBD.
+ Otherwise, this can be useless
+ */
+ if(!incremental && out_learnt.size()<=lbSizeMinimizingClause) {
+ minimisationWithBinaryResolution(out_learnt);
+ }
+ // Find correct backtrack level:
+ //
+ if (out_learnt.size() == 1)
+ out_btlevel = 0;
+ else{
+ int max_i = 1;
+ // Find the first literal assigned at the next-highest level:
+ for (int i = 2; i < out_learnt.size(); i++)
+ if (level(var(out_learnt[i])) > level(var(out_learnt[max_i])))
+ max_i = i;
+ // Swap-in this literal at index 1:
+ Lit p = out_learnt[max_i];
+ out_learnt[max_i] = out_learnt[1];
+ out_learnt[1] = p;
+ out_btlevel = level(var(p));
+ }
+
+
+ // Compute the size of the clause without selectors (incremental mode)
+ if(incremental) {
+ szWithoutSelectors = 0;
+ for(int i=0;i<out_learnt.size();i++) {
+ if(!isSelector(var((out_learnt[i])))) szWithoutSelectors++;
+ else if(i>0) break;
+ }
+ } else
+ szWithoutSelectors = out_learnt.size();
+
+ // Compute LBD
+ lbd = computeLBD(out_learnt,out_learnt.size()-selectors.size());
+
+
+#ifdef UPDATEVARACTIVITY
+ // UPDATEVARACTIVITY trick (see competition'09 companion paper)
+ if(lastDecisionLevel.size()>0) {
+ for(int i = 0;i<lastDecisionLevel.size();i++) {
+ Lit t = lastDecisionLevel[i];
+ //assert( ca[reason(var(t))].learnt() );
+ if(ca[reason(var(t))].lbd()<lbd)
+ varBumpActivity(var(t));
+ }
+ lastDecisionLevel.shrink_( lastDecisionLevel.size() );
+ }
+#endif
+
+
+ if( justUsage() ){
+ if( heap_rescale )
+ {
+ for (j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0;
+
+ analyze_toclear.shrink_( analyze_toclear.size() );
+ for (j = 0; j < jheap.size(); j++){
+ Var x = jheap[j];
+ if( var2NodeData[x].now )
+ analyze_toclear.push(mkLit(x));
+ }
+ for (j = 0; j < analyze_toclear.size(); j++){
+ Var x = var(analyze_toclear[j]);
+// jdata[x].act_fanin = activity[getFaninVar0(x)] > activity[getFaninVar1(x)]? activity[getFaninVar0(x)]: activity[getFaninVar1(x)];
+// jheap.update(x);
+ if( activity[getFaninVar1(x)] > activity[getFaninVar0(x)] )
+ jheap.update( JustKey( activity[getFaninVar1(x)], x, jheap.data_attr(x) ) );
+ else
+ jheap.update( JustKey( activity[getFaninVar0(x)], x, jheap.data_attr(x) ) );
+ }
+
+ } else {
+
+ for (j = 0; j < analyze_toclear.size(); j++)
+ {
+ seen[var(analyze_toclear[j])] = 0;
+ updateJustActivity(var(analyze_toclear[j]));
+ }
+ }
+ } else
+ for (j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0; // ('seen[]' is now cleared)
+ for(j = 0 ; j<selectors.size() ; j++) seen[var(selectors[j])] = 0;
+}
+
+
+// Check if 'p' can be removed. 'abstract_levels' is used to abort early if the algorithm is
+// visiting literals at levels that cannot be removed later.
+bool Solver::litRedundant(Lit p, uint32_t abstract_levels)
+{
+ analyze_stack.shrink_( analyze_stack.size() ); analyze_stack.push(p);
+ int top = analyze_toclear.size();
+ while (analyze_stack.size() > 0){
+ assert(reason(var(analyze_stack.last())) != CRef_Undef);
+ #ifdef CGLUCOSE_EXP
+ Clause& c = ca[castCRef(analyze_stack.last())]; analyze_stack.pop();
+ #else
+ Clause& c = ca[reason(var(analyze_stack.last()))]; analyze_stack.pop();
+ #endif
+ if(c.size()==2 && value(c[0])==l_False) {
+ assert(value(c[1])==l_True);
+ Lit tmp = c[0];
+ c[0] = c[1], c[1] = tmp;
+ }
+
+ for (int i = 1; i < c.size(); i++){
+ Lit p = c[i];
+ if (!seen[var(p)] && level(var(p)) > 0){
+ if (reason(var(p)) != CRef_Undef && (abstractLevel(var(p)) & abstract_levels) != 0){
+ seen[var(p)] = 1;
+ analyze_stack.push(p);
+ analyze_toclear.push(p);
+ }else{
+ for (int j = top; j < analyze_toclear.size(); j++)
+ seen[var(analyze_toclear[j])] = 0;
+ analyze_toclear.shrink_(analyze_toclear.size() - top);
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+
+/*_________________________________________________________________________________________________
+|
+| analyzeFinal : (p : Lit) -> [void]
+|
+| Description:
+| Specialized analysis procedure to express the final conflict in terms of assumptions.
+| Calculates the (possibly empty) set of assumptions that led to the assignment of 'p', and
+| stores the result in 'out_conflict'.
+|________________________________________________________________________________________________@*/
+void Solver::analyzeFinal(Lit p, vec<Lit>& out_conflict)
+{
+ out_conflict.shrink_( out_conflict.size() );
+ out_conflict.push(p);
+
+ if (decisionLevel() == 0)
+ return;
+
+ seen[var(p)] = 1;
+
+ for (int i = trail.size()-1; i >= trail_lim[0]; i--){
+ Var x = var(trail[i]);
+ if (seen[x]){
+ if (reason(x) == CRef_Undef){
+ assert(level(x) > 0);
+ out_conflict.push(~trail[i]);
+ }else{
+ #ifdef CGLUCOSE_EXP
+ Clause& c = ca[castCRef(trail[i])];
+ #else
+ Clause& c = ca[reason(x)];
+ #endif
+ // for (int j = 1; j < c.size(); j++) Minisat (glucose 2.0) loop
+ // Bug in case of assumptions due to special data structures for Binary.
+ // Many thanks to Sam Bayless (sbayless@cs.ubc.ca) for discover this bug.
+ for (int j = ((c.size()==2) ? 0:1); j < c.size(); j++)
+ if (level(var(c[j])) > 0)
+ seen[var(c[j])] = 1;
+ }
+
+ seen[x] = 0;
+ }
+ }
+
+ seen[var(p)] = 0;
+}
+
+void Solver::uncheckedEnqueue(Lit p, CRef from)
+{
+ if( justUsage() && !isRoundWatch(var(p)) )
+ return;
+ assert(value(p) == l_Undef);
+ assigns[var(p)] = lbool(!sign(p));
+ vardata[var(p)] = mkVarData(from, decisionLevel());
+ trail.push_(p);
+}
+
+
+/*_________________________________________________________________________________________________
+|
+| propagate : [void] -> [Clause*]
+|
+| Description:
+| Propagates all enqueued facts. If a conflict arises, the conflicting clause is returned,
+| otherwise CRef_Undef.
+|
+| Post-conditions:
+| * the propagation queue is empty, even if there was a conflict.
+|________________________________________________________________________________________________@*/
+CRef Solver::propagate()
+{
+ CRef confl = CRef_Undef;
+ int num_props = 0;
+ watches.cleanAll();
+ watchesBin.cleanAll();
+ while (qhead < trail.size()){
+ Lit p = trail[qhead++]; // 'p' is enqueued fact to propagate.
+ vec<Watcher>& ws = watches[p];
+ Watcher *i, *j, *end;
+ num_props++;
+
+ #ifdef CGLUCOSE_EXP
+ if( 2 <= justUsage() ){
+ CRef stats;
+ if( CRef_Undef != (stats = gatePropagate(p)) ){
+ confl = stats;
+ if( l_True == value(var(p)) ) return confl;
+ }
+ }
+ #endif
+
+ // First, Propagate binary clauses
+ vec<Watcher>& wbin = watchesBin[p];
+ for(int k = 0;k<wbin.size();k++) {
+ Lit imp = wbin[k].blocker;
+ if(value(imp) == l_False) {
+ return wbin[k].cref;
+ }
+ if(value(imp) == l_Undef) {
+ uncheckedEnqueue(imp,wbin[k].cref);
+ }
+ }
+
+
+
+ for (i = j = (Watcher*)ws, end = i + ws.size(); i != end;){
+ // Try to avoid inspecting the clause:
+ Lit blocker = i->blocker;
+ if (value(blocker) == l_True){
+ *j++ = *i++; continue; }
+
+ // Make sure the false literal is data[1]:
+ CRef cr = i->cref;
+ Clause& c = ca[cr];
+ Lit false_lit = ~p;
+ if (c[0] == false_lit)
+ c[0] = c[1], c[1] = false_lit;
+ assert(c[1] == false_lit);
+ i++;
+
+ // If 0th watch is true, then clause is already satisfied.
+ Lit first = c[0];
+ Watcher w = Watcher(cr, first);
+ if (first != blocker && value(first) == l_True){
+ *j++ = w; continue; }
+
+ // Look for new watch:
+ if(incremental) { // ----------------- INCREMENTAL MODE
+ int choosenPos = -1;
+ for (int k = 2; k < c.size(); k++) {
+
+ if (value(c[k]) != l_False){
+ if(decisionLevel()>assumptions.size()) {
+ choosenPos = k;
+ break;
+ } else {
+ choosenPos = k;
+
+ if(value(c[k])==l_True || !isSelector(var(c[k]))) {
+ break;
+ }
+ }
+
+ }
+ }
+ if(choosenPos!=-1) {
+ c[1] = c[choosenPos]; c[choosenPos] = false_lit;
+ watches[~c[1]].push(w);
+ goto NextClause; }
+ } else { // ----------------- DEFAULT MODE (NOT INCREMENTAL)
+ for (int k = 2; k < c.size(); k++) {
+
+ if (value(c[k]) != l_False){
+ c[1] = c[k]; c[k] = false_lit;
+ watches[~c[1]].push(w);
+ goto NextClause; }
+ }
+ }
+
+ // Did not find watch -- clause is unit under assignment:
+ *j++ = w;
+ if (value(first) == l_False){
+ confl = cr;
+ qhead = trail.size();
+ // Copy the remaining watches:
+ while (i < end)
+ *j++ = *i++;
+ }else {
+ uncheckedEnqueue(first, cr);
+
+
+ }
+ NextClause:;
+ }
+ ws.shrink_(i - j);
+ }
+ propagations += num_props;
+ simpDB_props -= num_props;
+
+ return confl;
+}
+
+
+
+
+
+
+/*_________________________________________________________________________________________________
+|
+| reduceDB : () -> [void]
+|
+| Description:
+| Remove half of the learnt clauses, minus the clauses locked by the current assignment. Locked
+| clauses are clauses that are reason to some assignment. Binary clauses are never removed.
+|________________________________________________________________________________________________@*/
+struct reduceDB_lt {
+ ClauseAllocator& ca;
+ reduceDB_lt(ClauseAllocator& ca_) : ca(ca_) {}
+ bool operator () (CRef x, CRef y) {
+
+ // Main criteria... Like in MiniSat we keep all binary clauses
+ if(ca[x].size()> 2 && ca[y].size()==2) return 1;
+
+ if(ca[y].size()> 2 && ca[x].size()==2) return 0;
+ if(ca[x].size()==2 && ca[y].size()==2) return 0;
+
+ // Second one based on literal block distance
+ if(ca[x].lbd()> ca[y].lbd()) return 1;
+ if(ca[x].lbd()< ca[y].lbd()) return 0;
+
+ // Finally we can use old activity or size, we choose the last one
+ return ca[x].activity() < ca[y].activity();
+ //return x->size() < y->size();
+ //return ca[x].size() > 2 && (ca[y].size() == 2 || ca[x].activity() < ca[y].activity()); }
+ }
+};
+
+void Solver::reduceDB()
+{
+ int i, j;
+ nbReduceDB++;
+ sort(learnts, reduceDB_lt(ca));
+
+ // We have a lot of "good" clauses, it is difficult to compare them. Keep more !
+ if(ca[learnts[learnts.size() / RATIOREMOVECLAUSES]].lbd()<=3) nbclausesbeforereduce +=specialIncReduceDB;
+ // Useless :-)
+ if(ca[learnts.last()].lbd()<=5) nbclausesbeforereduce +=specialIncReduceDB;
+
+ // Don't delete binary or locked clauses. From the rest, delete clauses from the first half
+ // Keep clauses which seem to be usefull (their lbd was reduce during this sequence)
+
+ int limit = learnts.size() / 2;
+ for (i = j = 0; i < learnts.size(); i++){
+ Clause& c = ca[learnts[i]];
+ if (c.lbd()>2 && c.size() > 2 && c.canBeDel() && !locked(c) && (i < limit)) {
+ removeClause(learnts[i]);
+ nbRemovedClauses++;
+ }
+ else {
+ if(!c.canBeDel()) limit++; //we keep c, so we can delete an other clause
+ c.setCanBeDel(true); // At the next step, c can be delete
+ learnts[j++] = learnts[i];
+ }
+ }
+ learnts.shrink_(i - j);
+ checkGarbage();
+}
+
+
+void Solver::removeSatisfied(vec<CRef>& cs)
+{
+ int i, j;
+ for (i = j = 0; i < cs.size(); i++){
+ Clause& c = ca[cs[i]];
+ if (satisfied(c))
+ removeClause(cs[i]);
+ else
+ cs[j++] = cs[i];
+ }
+ cs.shrink_(i - j);
+}
+
+
+void Solver::rebuildOrderHeap()
+{
+ vec<Var> vs;
+ for (Var v = 0; v < nVars(); v++)
+ if (decision[v] && value(v) == l_Undef)
+ vs.push(v);
+ order_heap.build(vs);
+}
+
+
+/*_________________________________________________________________________________________________
+|
+| simplify : [void] -> [bool]
+|
+| Description:
+| Simplify the clause database according to the current top-level assigment. Currently, the only
+| thing done here is the removal of satisfied clauses, but more things can be put here.
+|________________________________________________________________________________________________@*/
+bool Solver::simplify()
+{
+ assert(decisionLevel() == 0);
+
+ if (!ok || propagate() != CRef_Undef)
+ return ok = false;
+
+ if (nAssigns() == simpDB_assigns || (simpDB_props > 0))
+ return true;
+
+ // Remove satisfied clauses:
+ removeSatisfied(learnts);
+ if (remove_satisfied) // Can be turned off.
+ removeSatisfied(clauses);
+
+ checkGarbage();
+
+ #ifdef CGLUCOSE_EXP
+ if( !justUsage() )
+ #endif
+ rebuildOrderHeap();
+
+ simpDB_assigns = nAssigns();
+ simpDB_props = clauses_literals + learnts_literals; // (shouldn't depend on stats really, but it will do for now)
+
+ return true;
+}
+
+
+/*_________________________________________________________________________________________________
+|
+| search : (nof_conflicts : int) (params : const SearchParams&) -> [lbool]
+|
+| Description:
+| Search for a model the specified number of conflicts.
+| NOTE! Use negative value for 'nof_conflicts' indicate infinity.
+|
+| Output:
+| 'l_True' if a partial assigment that is consistent with respect to the clauseset is found. If
+| all variables are decision variables, this means that the clause set is satisfiable. 'l_False'
+| if the clause set is unsatisfiable. 'l_Undef' if the bound on number of conflicts is reached.
+|________________________________________________________________________________________________@*/
+lbool Solver::search(int nof_conflicts)
+{
+ assert(ok);
+ int backtrack_level;
+ int conflictC = 0;
+ vec<Lit> learnt_clause,selectors;
+ unsigned int nblevels,szWoutSelectors;
+ bool blocked=false;
+ starts++;
+
+ for (;;){
+ CRef confl = propagate();
+
+ // exact conflict limit
+ if ( !withinBudget() && confl != CRef_Undef ) {
+ lbdQueue.fastclear();
+ cancelUntil(0);
+ return l_Undef; }
+
+ if (confl != CRef_Undef){
+
+ // CONFLICT
+ conflicts++; conflictC++;conflictsRestarts++;
+ if(conflicts%5000==0 && var_decay<0.95)
+ var_decay += 0.01;
+
+ if (verbosity >= 1 && conflicts%verbEveryConflicts==0){
+ printf("c | %8d %7d %5d | %7d %8d %8d | %5d %8d %6d %8d | %6.3f %% \n",
+ (int)starts,(int)nbstopsrestarts, (int)(conflicts/starts),
+ (int)dec_vars - (trail_lim.size() == 0 ? trail.size() : trail_lim[0]), nClauses(), (int)clauses_literals,
+ (int)nbReduceDB, nLearnts(), (int)nbDL2,(int)nbRemovedClauses, progressEstimate()*100);
+ }
+ if (decisionLevel() == 0)
+ return l_False;
+
+
+ trailQueue.push(trail.size());
+ // BLOCK RESTART (CP 2012 paper)
+ if( conflictsRestarts>LOWER_BOUND_FOR_BLOCKING_RESTART && lbdQueue.isvalid() && trail.size()>R*trailQueue.getavg()) {
+ lbdQueue.fastclear();
+ nbstopsrestarts++;
+ if(!blocked) {lastblockatrestart=starts;nbstopsrestartssame++;blocked=true;}
+ }
+
+ learnt_clause.shrink_( learnt_clause.size() );
+ selectors .shrink_( selectors.size() );
+ analyze(confl, learnt_clause, selectors,backtrack_level,nblevels,szWoutSelectors);
+
+ lbdQueue.push(nblevels);
+ sumLBD += nblevels;
+ cancelUntil(backtrack_level);
+ if (certifiedUNSAT) {
+ for (int i = 0; i < learnt_clause.size(); i++)
+ fprintf(certifiedOutput, "%i " , (var(learnt_clause[i]) + 1) *
+ (-2 * sign(learnt_clause[i]) + 1) );
+ fprintf(certifiedOutput, "0\n");
+ }
+
+ if (learnt_clause.size() == 1){
+ uncheckedEnqueue(learnt_clause[0]);nbUn++;
+ }else{
+ CRef cr = ca.alloc(learnt_clause, true);
+ ca[cr].setLBD(nblevels);
+ ca[cr].setSizeWithoutSelectors(szWoutSelectors);
+ if(nblevels<=2) nbDL2++; // stats
+ if(ca[cr].size()==2) nbBin++; // stats
+ learnts.push(cr);
+ attachClause(cr);
+
+ claBumpActivity(ca[cr]);
+ uncheckedEnqueue(learnt_clause[0], cr);
+ }
+ varDecayActivity();
+ claDecayActivity();
+
+ }else{
+ // Our dynamic restart, see the SAT09 competition compagnion paper
+ if ( (conflictsRestarts && lbdQueue.isvalid() && lbdQueue.getavg()*K > sumLBD/conflictsRestarts) || (pstop && *pstop) ) {
+ lbdQueue.fastclear();
+ progress_estimate = progressEstimate();
+ int bt = 0;
+ if(incremental) { // DO NOT BACKTRACK UNTIL 0.. USELESS
+ bt = (decisionLevel()<assumptions.size()) ? decisionLevel() : assumptions.size();
+ }
+ cancelUntil(bt);
+ return l_Undef;
+ }
+
+ // Simplify the set of problem clauses:
+ if (decisionLevel() == 0 && !simplify()) {
+ return l_False;
+ }
+ // Perform clause database reduction !
+ if(conflicts>=curRestart* nbclausesbeforereduce)
+ {
+ assert(learnts.size()>0);
+ curRestart = (conflicts/ nbclausesbeforereduce)+1;
+ reduceDB();
+ nbclausesbeforereduce += incReduceDB;
+ }
+
+ Lit next = lit_Undef;
+ while (decisionLevel() < assumptions.size()){
+ // Perform user provided assumption:
+ Lit p = assumptions[decisionLevel()];
+ if (value(p) == l_True){
+ // Dummy decision level:
+ newDecisionLevel();
+ } else if (value(p) == l_False){
+ analyzeFinal(~p, conflict);
+ return l_False;
+ } else {
+ next = p;
+ break;
+ }
+ }
+
+ #ifdef CGLUCOSE_EXP
+ // pick from JustQueue
+
+ if (0 < justUsage())
+ if ( next == lit_Undef ){
+ int index = -1;
+ decisions++;
+ next = pickJustLit( index );
+ if(next == lit_Undef)
+ return l_True;
+ //addJwatch(var(next), j_reason);
+ jnext[index] = jlevel[decisionLevel()+1];
+ jlevel[decisionLevel()+1] = index;
+ }
+ #endif
+
+ if (next == lit_Undef){
+ // New variable decision:
+ decisions++;
+ next = pickBranchLit();
+
+ if (next == lit_Undef){
+ // Model found:
+ return l_True;
+ }
+ }
+
+ // Increase decision level and enqueue 'next'
+ newDecisionLevel();
+ uncheckedEnqueue(next);
+ }
+ }
+}
+
+
+
+double Solver::progressEstimate() const
+{
+ double progress = 0;
+ double F = 1.0 / nVars();
+
+ for (int i = 0; i <= decisionLevel(); i++){
+ int beg = i == 0 ? 0 : trail_lim[i - 1];
+ int end = i == decisionLevel() ? trail.size() : trail_lim[i];
+ progress += pow(F, i) * (end - beg);
+ }
+
+ return progress / nVars();
+}
+
+void Solver::printIncrementalStats() {
+
+ printf("c---------- Glucose Stats -------------------------\n");
+ printf("c restarts : %ld\n", starts);
+ printf("c nb ReduceDB : %ld\n", nbReduceDB);
+ printf("c nb removed Clauses : %ld\n", nbRemovedClauses);
+ printf("c nb learnts DL2 : %ld\n", nbDL2);
+ printf("c nb learnts size 2 : %ld\n", nbBin);
+ printf("c nb learnts size 1 : %ld\n", nbUn);
+
+ printf("c conflicts : %ld\n", conflicts);
+ printf("c decisions : %ld\n", decisions);
+ printf("c propagations : %ld\n", propagations);
+
+ printf("c SAT Calls : %d in %g seconds\n", nbSatCalls, totalTime4Sat);
+ printf("c UNSAT Calls : %d in %g seconds\n", nbUnsatCalls, totalTime4Unsat);
+ printf("c--------------------------------------------------\n");
+
+
+}
+
+
+// NOTE: assumptions passed in member-variable 'assumptions'.
+lbool Solver::solve_()
+{
+
+ #ifdef CGLUCOSE_EXP
+ ResetJustData(false);
+ #endif
+
+ if(incremental && certifiedUNSAT) {
+ printf("Can not use incremental and certified unsat in the same time\n");
+ exit(-1);
+ }
+
+ conflict.shrink_(conflict.size());
+ if (!ok){
+ travId_prev = travId;
+ return l_False;
+ }
+ double curTime = cpuTime();
+
+ solves++;
+
+ lbool status = l_Undef;
+ if(!incremental && verbosity>=1) {
+ printf("c ========================================[ MAGIC CONSTANTS ]==============================================\n");
+ printf("c | Constants are supposed to work well together :-) |\n");
+ printf("c | however, if you find better choices, please let us known... |\n");
+ printf("c |-------------------------------------------------------------------------------------------------------|\n");
+ printf("c | | | |\n");
+ printf("c | - Restarts: | - Reduce Clause DB: | - Minimize Asserting: |\n");
+ printf("c | * LBD Queue : %6d | * First : %6d | * size < %3d |\n",lbdQueue.maxSize(),nbclausesbeforereduce,lbSizeMinimizingClause);
+ printf("c | * Trail Queue : %6d | * Inc : %6d | * lbd < %3d |\n",trailQueue.maxSize(),incReduceDB,lbLBDMinimizingClause);
+ printf("c | * K : %6.2f | * Special : %6d | |\n",K,specialIncReduceDB);
+ printf("c | * R : %6.2f | * Protected : (lbd)< %2d | |\n",R,lbLBDFrozenClause);
+ printf("c | | | |\n");
+printf("c ==================================[ Search Statistics (every %6d conflicts) ]=========================\n",verbEveryConflicts);
+ printf("c | |\n");
+
+ printf("c | RESTARTS | ORIGINAL | LEARNT | Progress |\n");
+ printf("c | NB Blocked Avg Cfc | Vars Clauses Literals | Red Learnts LBD2 Removed | | pol-inconsist\n");
+ printf("c =========================================================================================================\n");
+ }
+
+ // Search:
+ int curr_restarts = 0;
+ while (status == l_Undef){
+ status = search(0); // the parameter is useless in glucose, kept to allow modifications
+ if (!withinBudget() || terminate_search_early || (pstop && *pstop)) break;
+ if (nRuntimeLimit && Abc_Clock() > nRuntimeLimit) break;
+ curr_restarts++;
+ }
+
+ if (!incremental && verbosity >= 1)
+ printf("c =========================================================================================================\n");
+
+
+ if (certifiedUNSAT){ // Want certified output
+ if (status == l_False)
+ fprintf(certifiedOutput, "0\n");
+ fclose(certifiedOutput);
+ }
+
+
+ if (status == l_True){
+
+ if( justUsage() ){
+ JustModel.shrink_(JustModel.size());
+ assert(jheap.empty());
+ //JustModel.growTo(nVars());
+ int i = 0, j = 0;
+ JustModel.push(toLit(0));
+ for (; i < trail.size(); i++)
+ if( isRoundWatch(var(trail[i])) && !isTwoFanin(var(trail[i])) )
+ JustModel.push(trail[i]), j++;
+ JustModel[0] = toLit(j);
+ } else {
+ // Extend & copy model:
+ model.shrink_(model.size());
+ model.growTo(nVars());
+ for (int i = 0; i < trail.size(); i++) model[ var(trail[i]) ] = value(var(trail[i]));
+ }
+ }else if (status == l_False && conflict.size() == 0)
+ ok = false;
+
+ //#ifdef CGLUCOSE_EXP
+ //if(status == l_True && 0 < justUsage())
+ // justCheck();
+ //#endif
+
+ cancelUntil(0);
+
+ double finalTime = cpuTime();
+ if(status==l_True) {
+ nbSatCalls++;
+ totalTime4Sat +=(finalTime-curTime);
+ }
+ if(status==l_False) {
+ nbUnsatCalls++;
+ totalTime4Unsat +=(finalTime-curTime);
+ }
+
+ // ABC callback
+ if (pCnfFunc && !terminate_search_early) {// hack to avoid calling callback twise if the solver was terminated early
+ int * pCex = NULL;
+ int message = (status == l_True ? 1 : status == l_False ? 0 : -1);
+ if (status == l_True) {
+ pCex = new int[nVars()];
+ for (int i = 0; i < nVars(); i++)
+ pCex[i] = (model[i] == l_True);
+ }
+
+ int callback_result = pCnfFunc(pCnfMan, message, pCex);
+ assert(callback_result == 0);
+ }
+ else if (pCnfFunc)
+ terminate_search_early = false; // for next run
+
+ travId_prev = travId;
+ return status;
+}
+
+//=================================================================================================
+// Writing CNF to DIMACS:
+//
+// FIXME: this needs to be rewritten completely.
+
+static Var mapVar(Var x, vec<Var>& map, Var& max)
+{
+ if (map.size() <= x || map[x] == -1){
+ map.growTo(x+1, -1);
+ map[x] = max++;
+ }
+ return map[x];
+}
+
+
+void Solver::toDimacs(FILE* f, Clause& c, vec<Var>& map, Var& max)
+{
+ if (satisfied(c)) return;
+
+ for (int i = 0; i < c.size(); i++)
+ if (value(c[i]) != l_False)
+ fprintf(f, "%s%d ", sign(c[i]) ? "-" : "", mapVar(var(c[i]), map, max)+1);
+ fprintf(f, "0\n");
+}
+
+
+void Solver::toDimacs(const char *file, const vec<Lit>& assumps)
+{
+ FILE* f = fopen(file, "wr");
+ if (f == NULL)
+ fprintf(stderr, "could not open file %s\n", file), exit(1);
+ toDimacs(f, assumps);
+ fclose(f);
+}
+
+
+void Solver::toDimacs(FILE* f, const vec<Lit>& assumps)
+{
+ // Handle case when solver is in contradictory state:
+ if (!ok){
+ fprintf(f, "p cnf 1 2\n1 0\n-1 0\n");
+ return; }
+
+ vec<Var> map; Var max = 0;
+
+ // Cannot use removeClauses here because it is not safe
+ // to deallocate them at this point. Could be improved.
+ int i, cnt = 0;
+ for (i = 0; i < clauses.size(); i++)
+ if (!satisfied(ca[clauses[i]]))
+ cnt++;
+
+ for (i = 0; i < clauses.size(); i++)
+ if (!satisfied(ca[clauses[i]])){
+ Clause& c = ca[clauses[i]];
+ for (int j = 0; j < c.size(); j++)
+ if (value(c[j]) != l_False)
+ mapVar(var(c[j]), map, max);
+ }
+
+ // Assumptions are added as unit clauses:
+ cnt += assumptions.size();
+
+ fprintf(f, "p cnf %d %d\n", max, cnt);
+
+ for (i = 0; i < assumptions.size(); i++){
+ assert(value(assumptions[i]) != l_False);
+ fprintf(f, "%s%d 0\n", sign(assumptions[i]) ? "-" : "", mapVar(var(assumptions[i]), map, max)+1);
+ }
+
+ for (i = 0; i < clauses.size(); i++)
+ toDimacs(f, ca[clauses[i]], map, max);
+
+ if (verbosity > 0)
+ printf("Wrote %d clauses with %d variables.\n", cnt, max);
+}
+
+
+//=================================================================================================
+// Garbage Collection methods:
+
+void Solver::relocAll(ClauseAllocator& to)
+{
+ #ifdef CGLUCOSE_EXP
+ if( CRef_Undef != itpc ){
+ setItpcSize(3);
+ ca.reloc(itpc, to);
+ }
+ #endif
+ int v, s, i, j;
+ // All watchers:
+ //
+ // for (int i = 0; i < watches.size(); i++)
+ watches.cleanAll();
+ watchesBin.cleanAll();
+ for (v = 0; v < nVars(); v++)
+ for (s = 0; s < 2; s++){
+ Lit p = mkLit(v, s != 0);
+ // printf(" >>> RELOCING: %s%d\n", sign(p)?"-":"", var(p)+1);
+ vec<Watcher>& ws = watches[p];
+ for (j = 0; j < ws.size(); j++)
+ ca.reloc(ws[j].cref, to);
+ vec<Watcher>& ws2 = watchesBin[p];
+ for (j = 0; j < ws2.size(); j++)
+ ca.reloc(ws2[j].cref, to);
+ }
+
+ // All reasons:
+ //
+ for (i = 0; i < trail.size(); i++){
+ Var v = var(trail[i]);
+
+ #ifdef CGLUCOSE_EXP
+ if( isGateCRef(reason(v)) )
+ continue;
+ #endif
+ if (reason(v) != CRef_Undef && (ca[reason(v)].reloced() || locked(ca[reason(v)])))
+ ca.reloc(vardata[v].reason, to);
+ }
+
+ // All learnt:
+ //
+ for (i = 0; i < learnts.size(); i++)
+ ca.reloc(learnts[i], to);
+
+ // All original:
+ //
+ for (i = 0; i < clauses.size(); i++)
+ ca.reloc(clauses[i], to);
+}
+
+
+void Solver::garbageCollect()
+{
+ // Initialize the next region to a size corresponding to the estimated utilization degree. This
+ // is not precise but should avoid some unnecessary reallocations for the new region:
+ ClauseAllocator to(ca.size() - ca.wasted());
+
+ relocAll(to);
+ if (verbosity >= 2)
+ printf("| Garbage collection: %12d bytes => %12d bytes |\n",
+ ca.size()*ClauseAllocator::Unit_Size, to.size()*ClauseAllocator::Unit_Size);
+ to.moveTo(ca);
+}
+
+void Solver::reset()
+{
+ // Reset everything
+ ok = true;
+ K = (double)opt_K;
+ R = (double)opt_R;
+ firstReduceDB = opt_first_reduce_db;
+ var_decay = (double)opt_var_decay;
+ //max_var_decay = opt_max_var_decay;
+ solves = starts = decisions = propagations = conflicts = conflictsRestarts = 0;
+ curRestart = 1;
+ cla_inc = var_inc = 1;
+ watches.clear(false); // We don't free the memory, new calls should be of the same size order.
+ watchesBin.clear(false);
+ //unaryWatches.clear(false);
+ qhead = 0;
+ simpDB_assigns = -1;
+ simpDB_props = 0;
+ order_heap.clear(false);
+ progress_estimate = 0;
+ //lastLearntClause = CRef_Undef;
+ conflict_budget = -1;
+ propagation_budget = -1;
+ nbVarsInitialFormula = INT32_MAX;
+ totalTime4Sat = 0.;
+ totalTime4Unsat = 0.;
+ nbSatCalls = nbUnsatCalls = 0;
+ MYFLAG = 0;
+ lbdQueue.clear(false);
+ lbdQueue.initSize(sizeLBDQueue);
+ trailQueue.clear(false);
+ trailQueue.initSize(sizeTrailQueue);
+ sumLBD = 0;
+ nbclausesbeforereduce = firstReduceDB;
+ //stats.clear();
+ //stats.growTo(coreStatsSize, 0);
+ clauses.clear(false);
+ learnts.clear(false);
+ //permanentLearnts.clear(false);
+ //unaryWatchedClauses.clear(false);
+ model .shrink_(model .size());
+ conflict.shrink_(conflict.size());
+ activity.shrink_(activity.size());
+ assigns .shrink_(assigns .size());
+ polarity.shrink_(polarity.size());
+ //forceUNSAT.clear(false);
+ decision .shrink_(decision .size());
+ trail .shrink_(trail .size());
+ trail_lim .shrink_(trail_lim .size());
+ vardata .shrink_(vardata .size());
+ assumptions.shrink_(assumptions.size());
+ nbpos .shrink_(nbpos .size());
+ permDiff .shrink_(permDiff .size());
+ #ifdef UPDATEVARACTIVITY
+ lastDecisionLevel.shrink_(lastDecisionLevel.size());
+ #endif
+ ca.clear();
+ seen .shrink_(seen.size());
+ analyze_stack .shrink_(analyze_stack .size());
+ analyze_toclear.shrink_(analyze_toclear.size());
+ add_tmp.clear(false);
+ assumptionPositions.clear(false);
+ initialPositions.clear(false);
+
+ #ifdef CGLUCOSE_EXP
+
+ ResetJustData(false);
+
+ //jwatch.shrink_(jwatch.size());
+ //jdata .shrink_(jdata .size());
+
+ jhead = 0;
+ travId = 0;
+ travId_prev = 0;
+ var2TravId .shrink_(var2TravId.size());
+ JustModel .shrink_(JustModel .size());
+ jlevel .shrink_(jlevel.size());
+ jnext .shrink_(jnext.size());
+
+ //var2FaninLits.shrink_(var2FaninLits.size());
+ var2NodeData .shrink_(var2NodeData .size());
+ var2Fanout0 .shrink_(var2Fanout0 .size());
+ var2FanoutN .shrink_(var2FanoutN .size());
+ //var2FanoutP.clear(false);
+ if( CRef_Undef != itpc ){
+ itpc = CRef_Undef; // clause allocator has been cleared, do not worry
+ // allocate space for clause interpretation
+ vec<Lit> tmp; tmp.growTo(3);
+ itpc = ca.alloc(tmp);
+ ca[itpc].shrink( ca[itpc].size() );
+ }
+ #endif
+}
+
+ABC_NAMESPACE_IMPL_END
diff --git a/src/sat/glucose2/Heap.h b/src/sat/glucose2/Heap.h
new file mode 100644
index 00000000..d68229f6
--- /dev/null
+++ b/src/sat/glucose2/Heap.h
@@ -0,0 +1,163 @@
+/******************************************************************************************[Heap.h]
+Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
+Copyright (c) 2007-2010, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#ifndef Glucose_Heap_h
+#define Glucose_Heap_h
+
+#include "sat/glucose2/Vec.h"
+
+ABC_NAMESPACE_CXX_HEADER_START
+
+namespace Gluco2 {
+
+//=================================================================================================
+// A heap implementation with support for decrease/increase key.
+
+
+template<class Comp>
+class Heap {
+ Comp lt; // The heap is a minimum-heap with respect to this comparator
+ vec<int> heap; // Heap of integers
+ vec<int> indices; // Each integers position (index) in the Heap
+
+ // Index "traversal" functions
+ static inline int left (int i) { return i*2+1; }
+ static inline int right (int i) { return (i+1)*2; }
+ static inline int parent(int i) { return (i-1) >> 1; }
+
+
+ void percolateUp(int i)
+ {
+ int x = heap[i];
+ int p = parent(i);
+
+ while (i != 0 && lt(x, heap[p])){
+ heap[i] = heap[p];
+ indices[heap[p]] = i;
+ i = p;
+ p = parent(p);
+ }
+ heap [i] = x;
+ indices[x] = i;
+ }
+
+
+ void percolateDown(int i)
+ {
+ int x = heap[i];
+ while (left(i) < heap.size()){
+ int child = right(i) < heap.size() && lt(heap[right(i)], heap[left(i)]) ? right(i) : left(i);
+ if (!lt(heap[child], x)) break;
+ heap[i] = heap[child];
+ indices[heap[i]] = i;
+ i = child;
+ }
+ heap [i] = x;
+ indices[x] = i;
+ }
+
+
+ public:
+ Heap(const Comp& c) : lt(c) { }
+
+ int size () const { return heap.size(); }
+ bool empty () const { return heap.size() == 0; }
+ bool inHeap (int n) const { return n < indices.size() && indices[n] >= 0; }
+ int operator[](int index) const { assert(index < heap.size()); return heap[index]; }
+
+
+ void decrease (int n) { assert(inHeap(n)); percolateUp (indices[n]); }
+ void increase (int n) { assert(inHeap(n)); percolateDown(indices[n]); }
+ void prelocate (int ext_cap){ indices.prelocate(ext_cap); }
+
+ // Safe variant of insert/decrease/increase:
+ void update(int n)
+ {
+ if (!inHeap(n))
+ insert(n);
+ else {
+ percolateUp(indices[n]);
+ percolateDown(indices[n]); }
+ }
+
+
+ void insert(int n)
+ {
+ indices.growTo(n+1, -1);
+ assert(!inHeap(n));
+
+ indices[n] = heap.size();
+ heap.push(n);
+ percolateUp(indices[n]);
+ }
+
+
+ int removeMin()
+ {
+ int x = heap[0];
+ heap[0] = heap.last();
+ indices[heap[0]] = 0;
+ indices[x] = -1;
+ heap.pop();
+ if (heap.size() > 1) percolateDown(0);
+ return x;
+ }
+
+
+ // Rebuild the heap from scratch, using the elements in 'ns':
+ void build(vec<int>& ns) {
+ int i;
+ for (i = 0; i < heap.size(); i++)
+ indices[heap[i]] = -1;
+ heap.clear();
+
+ for (i = 0; i < ns.size(); i++){
+ indices[ns[i]] = i;
+ heap.push(ns[i]); }
+
+ for (i = heap.size() / 2 - 1; i >= 0; i--)
+ percolateDown(i);
+ }
+
+ void clear(bool dealloc = false)
+ {
+ int i;
+ for (i = 0; i < heap.size(); i++)
+ indices[heap[i]] = -1;
+ heap.clear(dealloc);
+ }
+ void clear_(bool dealloc = false)
+ {
+ int i;
+ for (i = 0; i < heap.size(); i++)
+ indices[heap[i]] = -1;
+
+ if( ! dealloc ) heap.shrink_( heap.size() );
+ else heap.clear(true);
+ }
+};
+
+
+//=================================================================================================
+}
+
+ABC_NAMESPACE_CXX_HEADER_END
+
+#endif
diff --git a/src/sat/glucose2/Heap2.h b/src/sat/glucose2/Heap2.h
new file mode 100644
index 00000000..ef6d8302
--- /dev/null
+++ b/src/sat/glucose2/Heap2.h
@@ -0,0 +1,169 @@
+/******************************************************************************************[Heap.h]
+Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
+Copyright (c) 2007-2010, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#ifndef Glucose_Heap2_h
+#define Glucose_Heap2_h
+
+#include "sat/glucose2/Vec.h"
+
+ABC_NAMESPACE_CXX_HEADER_START
+
+namespace Gluco2 {
+
+//=================================================================================================
+// A heap implementation with support for decrease/increase key.
+
+
+template<class Comp, class Obj>
+class Heap2 {
+ Comp lt; // The heap is a minimum-heap with respect to this comparator
+ vec<Obj> heap; // Heap of integers
+ vec<int> indices; // Each integers position (index) in the Heap
+
+ // Index "traversal" functions
+ static inline int left (int i) { return i*2+1; }
+ static inline int right (int i) { return (i+1)*2; }
+ static inline int parent(int i) { return (i-1) >> 1; }
+
+ inline int data (int i) const { return heap[i].data();}
+
+ void percolateUp(int i)
+ {
+ Obj x = heap[i];
+ int p = parent(i);
+
+ while (i != 0 && lt(x, heap[p])){
+ heap[i] = heap[p];
+ indices[data(p)] = i;
+ i = p;
+ p = parent(p);
+ }
+ heap [i] = x;
+ indices[x.data()] = i;
+ }
+
+
+ void percolateDown(int i)
+ {
+ Obj x = heap[i];
+ while (left(i) < heap.size()){
+ int child = right(i) < heap.size() && lt(heap[right(i)], heap[left(i)]) ? right(i) : left(i);
+ if (!lt(heap[child], x)) break;
+ heap[i] = heap[child];
+ indices[data(i)] = i;
+ i = child;
+ }
+ heap [i] = x;
+ indices[x.data()] = i;
+ }
+
+
+ public:
+ Heap2(const Comp& c) : lt(c) { }
+
+ int size () const { return heap.size(); }
+ bool empty () const { return heap.size() == 0; }
+ bool inHeap (int n) const { return n < indices.size() && indices[n] >= 0; }
+ int operator[](int index) const { assert(index < heap.size()); return heap[index].data(); }
+
+
+ void decrease (int n) { assert(inHeap(n)); percolateUp (indices[n]); }
+ void increase (int n) { assert(inHeap(n)); percolateDown(indices[n]); }
+ void prelocate (int ext_cap){ indices.prelocate(ext_cap); }
+ int data_attr (int n) const { return heap[indices[n]].attr(); }
+ // Safe variant of insert/decrease/increase:
+ void update(const Obj& x)
+ {
+ int n = x.data();
+ if (!inHeap(n))
+ insert(x);
+ else {
+ heap[indices[x.data()]] = x;
+ percolateUp(indices[n]);
+ percolateDown(indices[n]); }
+ }
+
+
+ void insert(const Obj& x)
+ {
+ int n = x.data();
+ indices.growTo(n+1, -1);
+ assert(!inHeap(n));
+
+ indices[n] = heap.size();
+ heap.push(x);
+ percolateUp(indices[n]);
+ }
+
+ //Obj prev;
+ int removeMin(int& _attr)
+ {
+ Obj x = heap[0];
+ heap[0] = heap.last();
+ indices[heap[0].data()] = 0;
+ indices[x.data()]= -1;
+ heap.pop();
+ if (heap.size() > 1) percolateDown(0);
+ //prev = x;
+ _attr = x.attr();
+ return x.data();
+ }
+
+
+ // Rebuild the heap from scratch, using the elements in 'ns':
+// void build(vec<int>& ns) {
+// int i;
+// for (i = 0; i < heap.size(); i++)
+// indices[heap[i]] = -1;
+// heap.clear();
+//
+// for (i = 0; i < ns.size(); i++){
+// indices[ns[i]] = i;
+// heap.push(ns[i]); }
+//
+// for (i = heap.size() / 2 - 1; i >= 0; i--)
+// percolateDown(i);
+// }
+
+ void clear(bool dealloc = false)
+ {
+ int i;
+ for (i = 0; i < heap.size(); i++)
+ indices[heap[i].data()] = -1;
+ heap.clear(dealloc);
+ }
+ void clear_(bool dealloc = false)
+ {
+ int i;
+ for (i = 0; i < heap.size(); i++)
+ indices[heap[i].data()] = -1;
+
+ if( ! dealloc ) heap.shrink_( heap.size() );
+ else heap.clear(true);
+ }
+};
+
+
+//=================================================================================================
+}
+
+ABC_NAMESPACE_CXX_HEADER_END
+
+#endif
diff --git a/src/sat/glucose2/IntTypes.h b/src/sat/glucose2/IntTypes.h
new file mode 100644
index 00000000..3f75862b
--- /dev/null
+++ b/src/sat/glucose2/IntTypes.h
@@ -0,0 +1,49 @@
+/**************************************************************************************[IntTypes.h]
+Copyright (c) 2009-2010, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#ifndef Glucose_IntTypes_h
+#define Glucose_IntTypes_h
+
+#ifdef __sun
+ // Not sure if there are newer versions that support C99 headers. The
+ // needed features are implemented in the headers below though:
+
+# include <sys/int_types.h>
+# include <sys/int_fmtio.h>
+# include <sys/int_limits.h>
+
+#else
+
+#define __STDC_LIMIT_MACROS
+# include "pstdint.h"
+//# include <inttypes.h>
+
+#endif
+
+#include <limits.h>
+
+#ifndef PRIu64
+#define PRIu64 "lu"
+#define PRIi64 "ld"
+#endif
+//=================================================================================================
+
+#include <misc/util/abc_namespaces.h>
+
+#endif
diff --git a/src/sat/glucose2/Map.h b/src/sat/glucose2/Map.h
new file mode 100644
index 00000000..d9c31aae
--- /dev/null
+++ b/src/sat/glucose2/Map.h
@@ -0,0 +1,197 @@
+/*******************************************************************************************[Map.h]
+Copyright (c) 2006-2010, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#ifndef Glucose_Map_h
+#define Glucose_Map_h
+
+#include "sat/glucose2/IntTypes.h"
+#include "sat/glucose2/Vec.h"
+
+ABC_NAMESPACE_CXX_HEADER_START
+
+namespace Gluco2 {
+
+//=================================================================================================
+// Default hash/equals functions
+//
+
+template<class K> struct Hash { uint32_t operator()(const K& k) const { return hash(k); } };
+template<class K> struct Equal { bool operator()(const K& k1, const K& k2) const { return k1 == k2; } };
+
+template<class K> struct DeepHash { uint32_t operator()(const K* k) const { return hash(*k); } };
+template<class K> struct DeepEqual { bool operator()(const K* k1, const K* k2) const { return *k1 == *k2; } };
+
+static inline uint32_t hash(uint32_t x){ return x; }
+static inline uint32_t hash(uint64_t x){ return (uint32_t)x; }
+static inline uint32_t hash(int32_t x) { return (uint32_t)x; }
+static inline uint32_t hash(int64_t x) { return (uint32_t)x; }
+
+
+//=================================================================================================
+// Some primes
+//
+
+static const int nprimes = 25;
+static const int primes [nprimes] = { 31, 73, 151, 313, 643, 1291, 2593, 5233, 10501, 21013, 42073, 84181, 168451, 337219, 674701, 1349473, 2699299, 5398891, 10798093, 21596719, 43193641, 86387383, 172775299, 345550609, 691101253 };
+
+//=================================================================================================
+// Hash table implementation of Maps
+//
+
+template<class K, class D, class H = Hash<K>, class E = Equal<K> >
+class Map {
+ public:
+ struct Pair { K key; D data; };
+
+ private:
+ H hash;
+ E equals;
+
+ vec<Pair>* table;
+ int cap;
+ int size;
+
+ // Don't allow copying (error prone):
+ Map<K,D,H,E>& operator = (Map<K,D,H,E>& other) { assert(0); }
+ Map (Map<K,D,H,E>& other) { assert(0); }
+
+ bool checkCap(int new_size) const { return new_size > cap; }
+
+ int32_t index (const K& k) const { return hash(k) % cap; }
+ void _insert (const K& k, const D& d) {
+ vec<Pair>& ps = table[index(k)];
+ ps.push(); ps.last().key = k; ps.last().data = d; }
+
+ void rehash () {
+ const vec<Pair>* old = table;
+
+ int old_cap = cap;
+ int newsize = primes[0];
+ for (int i = 1; newsize <= cap && i < nprimes; i++)
+ newsize = primes[i];
+
+ table = new vec<Pair>[newsize];
+ cap = newsize;
+
+ for (int i = 0; i < old_cap; i++){
+ for (int j = 0; j < old[i].size(); j++){
+ _insert(old[i][j].key, old[i][j].data); }}
+
+ delete [] old;
+
+ // printf(" --- rehashing, old-cap=%d, new-cap=%d\n", cap, newsize);
+ }
+
+
+ public:
+
+ Map () : table(NULL), cap(0), size(0) {}
+ Map (const H& h, const E& e) : hash(h), equals(e), table(NULL), cap(0), size(0){}
+ ~Map () { delete [] table; }
+
+ // PRECONDITION: the key must already exist in the map.
+ const D& operator [] (const K& k) const
+ {
+ assert(size != 0);
+ const D* res = NULL;
+ const vec<Pair>& ps = table[index(k)];
+ for (int i = 0; i < ps.size(); i++)
+ if (equals(ps[i].key, k))
+ res = &ps[i].data;
+ assert(res != NULL);
+ return *res;
+ }
+
+ // PRECONDITION: the key must already exist in the map.
+ D& operator [] (const K& k)
+ {
+ assert(size != 0);
+ D* res = NULL;
+ vec<Pair>& ps = table[index(k)];
+ for (int i = 0; i < ps.size(); i++)
+ if (equals(ps[i].key, k))
+ res = &ps[i].data;
+ assert(res != NULL);
+ return *res;
+ }
+
+ // PRECONDITION: the key must *NOT* exist in the map.
+ void insert (const K& k, const D& d) { if (checkCap(size+1)) rehash(); _insert(k, d); size++; }
+ bool peek (const K& k, D& d) const {
+ if (size == 0) return false;
+ const vec<Pair>& ps = table[index(k)];
+ for (int i = 0; i < ps.size(); i++)
+ if (equals(ps[i].key, k)){
+ d = ps[i].data;
+ return true; }
+ return false;
+ }
+
+ bool has (const K& k) const {
+ if (size == 0) return false;
+ const vec<Pair>& ps = table[index(k)];
+ for (int i = 0; i < ps.size(); i++)
+ if (equals(ps[i].key, k))
+ return true;
+ return false;
+ }
+
+ // PRECONDITION: the key must exist in the map.
+ void remove(const K& k) {
+ assert(table != NULL);
+ vec<Pair>& ps = table[index(k)];
+ int j = 0;
+ for (; j < ps.size() && !equals(ps[j].key, k); j++);
+ assert(j < ps.size());
+ ps[j] = ps.last();
+ ps.pop();
+ size--;
+ }
+
+ void clear () {
+ cap = size = 0;
+ delete [] table;
+ table = NULL;
+ }
+
+ int elems() const { return size; }
+ int bucket_count() const { return cap; }
+
+ // NOTE: the hash and equality objects are not moved by this method:
+ void moveTo(Map& other){
+ delete [] other.table;
+
+ other.table = table;
+ other.cap = cap;
+ other.size = size;
+
+ table = NULL;
+ size = cap = 0;
+ }
+
+ // NOTE: given a bit more time, I could make a more C++-style iterator out of this:
+ const vec<Pair>& bucket(int i) const { return table[i]; }
+};
+
+//=================================================================================================
+}
+
+ABC_NAMESPACE_CXX_HEADER_END
+
+#endif
diff --git a/src/sat/glucose2/Options.h b/src/sat/glucose2/Options.h
new file mode 100644
index 00000000..f2d4d493
--- /dev/null
+++ b/src/sat/glucose2/Options.h
@@ -0,0 +1,392 @@
+/***************************************************************************************[Options.h]
+Copyright (c) 2008-2010, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#ifndef Glucose_Options_h
+#define Glucose_Options_h
+
+#define __STDC_FORMAT_MACROS
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+
+#include "sat/glucose2/IntTypes.h"
+#include "sat/glucose2/Vec.h"
+#include "sat/glucose2/ParseUtils.h"
+
+ABC_NAMESPACE_CXX_HEADER_START
+
+namespace Gluco2 {
+
+//==================================================================================================
+// Top-level option parse/help functions:
+
+
+extern void parseOptions (int& argc, char** argv, bool strict = false);
+extern void printUsageAndExit(int argc, char** argv, bool verbose = false);
+extern void setUsageHelp (const char* str);
+extern void setHelpPrefixStr (const char* str);
+
+
+//==================================================================================================
+// Options is an abstract class that gives the interface for all types options:
+
+
+class Option
+{
+ public:
+ const char* name;
+ const char* description;
+ const char* category;
+ const char* type_name;
+
+ static vec<Option*>& getOptionList () { static vec<Option*> options; return options; }
+ static const char*& getUsageString() { static const char* usage_str; return usage_str; }
+ static const char*& getHelpPrefixString() { static const char* help_prefix_str = ""; return help_prefix_str; }
+
+ struct OptionLt {
+ bool operator()(const Option* x, const Option* y) {
+ int test1 = strcmp(x->category, y->category);
+ return test1 < 0 || (test1 == 0 && strcmp(x->type_name, y->type_name) < 0);
+ }
+ };
+
+ Option(const char* name_,
+ const char* desc_,
+ const char* cate_,
+ const char* type_) :
+ name (name_)
+ , description(desc_)
+ , category (cate_)
+ , type_name (type_)
+ {
+ getOptionList().push(this);
+ }
+
+ public:
+ virtual ~Option() {}
+
+ virtual bool parse (const char* str) = 0;
+ virtual void help (bool verbose = false) = 0;
+
+ friend void parseOptions (int& argc, char** argv, bool strict);
+ friend void printUsageAndExit (int argc, char** argv, bool verbose);
+ friend void setUsageHelp (const char* str);
+ friend void setHelpPrefixStr (const char* str);
+};
+
+
+//==================================================================================================
+// Range classes with specialization for floating types:
+
+
+struct IntRange {
+ int begin;
+ int end;
+ IntRange(int b, int e) : begin(b), end(e) {}
+};
+
+struct Int64Range {
+ int64_t begin;
+ int64_t end;
+ Int64Range(int64_t b, int64_t e) : begin(b), end(e) {}
+};
+
+struct DoubleRange {
+ double begin;
+ double end;
+ bool begin_inclusive;
+ bool end_inclusive;
+ DoubleRange(double b, bool binc, double e, bool einc) : begin(b), end(e), begin_inclusive(binc), end_inclusive(einc) {}
+};
+
+
+//==================================================================================================
+// Double options:
+
+
+class DoubleOption : public Option
+{
+ protected:
+ DoubleRange range;
+ double value;
+
+ public:
+ DoubleOption(const char* c, const char* n, const char* d, double def = double(), DoubleRange r = DoubleRange(-HUGE_VAL, false, HUGE_VAL, false))
+ : Option(n, d, c, "<double>"), range(r), value(def) {
+ // FIXME: set LC_NUMERIC to "C" to make sure that strtof/strtod parses decimal point correctly.
+ }
+
+ operator double (void) const { return value; }
+ operator double& (void) { return value; }
+ DoubleOption& operator=(double x) { value = x; return *this; }
+
+ virtual bool parse(const char* str){
+ const char* span = str;
+
+ if (!match(span, "-") || !match(span, name) || !match(span, "="))
+ return false;
+
+ char* end;
+ double tmp = strtod(span, &end);
+
+ if (end == NULL)
+ return false;
+ else if (tmp >= range.end && (!range.end_inclusive || tmp != range.end)){
+ fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name);
+ exit(1);
+ }else if (tmp <= range.begin && (!range.begin_inclusive || tmp != range.begin)){
+ fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name);
+ exit(1); }
+
+ value = tmp;
+ // fprintf(stderr, "READ VALUE: %g\n", value);
+
+ return true;
+ }
+
+ virtual void help (bool verbose = false){
+ fprintf(stderr, " -%-12s = %-8s %c%4.2g .. %4.2g%c (default: %g)\n",
+ name, type_name,
+ range.begin_inclusive ? '[' : '(',
+ range.begin,
+ range.end,
+ range.end_inclusive ? ']' : ')',
+ value);
+ if (verbose){
+ fprintf(stderr, "\n %s\n", description);
+ fprintf(stderr, "\n");
+ }
+ }
+};
+
+
+//==================================================================================================
+// Int options:
+
+
+class IntOption : public Option
+{
+ protected:
+ IntRange range;
+ int32_t value;
+
+ public:
+ IntOption(const char* c, const char* n, const char* d, int32_t def = int32_t(), IntRange r = IntRange(INT32_MIN, INT32_MAX))
+ : Option(n, d, c, "<int32>"), range(r), value(def) {}
+
+ operator int32_t (void) const { return value; }
+ operator int32_t& (void) { return value; }
+ IntOption& operator= (int32_t x) { value = x; return *this; }
+
+ virtual bool parse(const char* str){
+ const char* span = str;
+
+ if (!match(span, "-") || !match(span, name) || !match(span, "="))
+ return false;
+
+ char* end;
+ int32_t tmp = strtol(span, &end, 10);
+
+ if (end == NULL)
+ return false;
+ else if (tmp > range.end){
+ fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name);
+ exit(1);
+ }else if (tmp < range.begin){
+ fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name);
+ exit(1); }
+
+ value = tmp;
+
+ return true;
+ }
+
+ virtual void help (bool verbose = false){
+ fprintf(stderr, " -%-12s = %-8s [", name, type_name);
+ if (range.begin == INT32_MIN)
+ fprintf(stderr, "imin");
+ else
+ fprintf(stderr, "%4d", range.begin);
+
+ fprintf(stderr, " .. ");
+ if (range.end == INT32_MAX)
+ fprintf(stderr, "imax");
+ else
+ fprintf(stderr, "%4d", range.end);
+
+ fprintf(stderr, "] (default: %d)\n", value);
+ if (verbose){
+ fprintf(stderr, "\n %s\n", description);
+ fprintf(stderr, "\n");
+ }
+ }
+};
+
+
+// Leave this out for visual C++ until Microsoft implements C99 and gets support for strtoll.
+#ifndef _MSC_VER
+
+class Int64Option : public Option
+{
+ protected:
+ Int64Range range;
+ int64_t value;
+
+ public:
+ Int64Option(const char* c, const char* n, const char* d, int64_t def = int64_t(), Int64Range r = Int64Range(INT64_MIN, INT64_MAX))
+ : Option(n, d, c, "<int64>"), range(r), value(def) {}
+
+ operator int64_t (void) const { return value; }
+ operator int64_t& (void) { return value; }
+ Int64Option& operator= (int64_t x) { value = x; return *this; }
+
+ virtual bool parse(const char* str){
+ const char* span = str;
+
+ if (!match(span, "-") || !match(span, name) || !match(span, "="))
+ return false;
+
+ char* end;
+ int64_t tmp = strtoll(span, &end, 10);
+
+ if (end == NULL)
+ return false;
+ else if (tmp > range.end){
+ fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name);
+ exit(1);
+ }else if (tmp < range.begin){
+ fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name);
+ exit(1); }
+
+ value = tmp;
+
+ return true;
+ }
+
+ virtual void help (bool verbose = false){
+ fprintf(stderr, " -%-12s = %-8s [", name, type_name);
+ if (range.begin == INT64_MIN)
+ fprintf(stderr, "imin");
+ else
+ fprintf(stderr, "%4d", (int)range.begin);
+
+ fprintf(stderr, " .. ");
+ if (range.end == INT64_MAX)
+ fprintf(stderr, "imax");
+ else
+ fprintf(stderr, "%4d", (int)range.end);
+
+ fprintf(stderr, "] (default: %d)\n", (int)value);
+ if (verbose){
+ fprintf(stderr, "\n %s\n", description);
+ fprintf(stderr, "\n");
+ }
+ }
+};
+#endif
+
+//==================================================================================================
+// String option:
+
+
+class StringOption : public Option
+{
+ const char* value;
+ public:
+ StringOption(const char* c, const char* n, const char* d, const char* def = NULL)
+ : Option(n, d, c, "<string>"), value(def) {}
+
+ operator const char* (void) const { return value; }
+ operator const char*& (void) { return value; }
+ StringOption& operator= (const char* x) { value = x; return *this; }
+
+ virtual bool parse(const char* str){
+ const char* span = str;
+
+ if (!match(span, "-") || !match(span, name) || !match(span, "="))
+ return false;
+
+ value = span;
+ return true;
+ }
+
+ virtual void help (bool verbose = false){
+ fprintf(stderr, " -%-10s = %8s\n", name, type_name);
+ if (verbose){
+ fprintf(stderr, "\n %s\n", description);
+ fprintf(stderr, "\n");
+ }
+ }
+};
+
+
+//==================================================================================================
+// Bool option:
+
+
+class BoolOption : public Option
+{
+ bool value;
+
+ public:
+ BoolOption(const char* c, const char* n, const char* d, bool v)
+ : Option(n, d, c, "<bool>"), value(v) {}
+
+ operator bool (void) const { return value; }
+ operator bool& (void) { return value; }
+ BoolOption& operator=(bool b) { value = b; return *this; }
+
+ virtual bool parse(const char* str){
+ const char* span = str;
+
+ if (match(span, "-")){
+ bool b = !match(span, "no-");
+
+ if (strcmp(span, name) == 0){
+ value = b;
+ return true; }
+ }
+
+ return false;
+ }
+
+ virtual void help (bool verbose = false){
+
+ fprintf(stderr, " -%s, -no-%s", name, name);
+
+ for (uint32_t i = 0; i < 32 - strlen(name)*2; i++)
+ fprintf(stderr, " ");
+
+ fprintf(stderr, " ");
+ fprintf(stderr, "(default: %s)\n", value ? "on" : "off");
+ if (verbose){
+ fprintf(stderr, "\n %s\n", description);
+ fprintf(stderr, "\n");
+ }
+ }
+};
+
+//=================================================================================================
+}
+
+ABC_NAMESPACE_CXX_HEADER_END
+
+#endif
diff --git a/src/sat/glucose2/Options2.cpp b/src/sat/glucose2/Options2.cpp
new file mode 100644
index 00000000..b419e054
--- /dev/null
+++ b/src/sat/glucose2/Options2.cpp
@@ -0,0 +1,95 @@
+/**************************************************************************************[Options.cc]
+Copyright (c) 2008-2010, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#include "sat/glucose2/Sort.h"
+#include "sat/glucose2/Options.h"
+#include "sat/glucose2/ParseUtils.h"
+
+ABC_NAMESPACE_IMPL_START
+
+using namespace Gluco2;
+
+void Gluco2::parseOptions(int& argc, char** argv, bool strict)
+{
+ int i, j;
+ for (i = j = 1; i < argc; i++){
+ const char* str = argv[i];
+ if (match(str, "--") && match(str, Option::getHelpPrefixString()) && match(str, "help")){
+ if (*str == '\0')
+ printUsageAndExit(argc, argv);
+ else if (match(str, "-verb"))
+ printUsageAndExit(argc, argv, true);
+ } else {
+ bool parsed_ok = false;
+
+ for (int k = 0; !parsed_ok && k < Option::getOptionList().size(); k++){
+ parsed_ok = Option::getOptionList()[k]->parse(argv[i]);
+
+ // fprintf(stderr, "checking %d: %s against flag <%s> (%s)\n", i, argv[i], Option::getOptionList()[k]->name, parsed_ok ? "ok" : "skip");
+ }
+
+ if (!parsed_ok) {
+ if (strict && match(argv[i], "-"))
+ fprintf(stderr, "ERROR! Unknown flag \"%s\". Use '--%shelp' for help.\n", argv[i], Option::getHelpPrefixString()), exit(1);
+ else
+ argv[j++] = argv[i];
+ }
+ }
+ }
+
+ argc -= (i - j);
+}
+
+
+void Gluco2::setUsageHelp (const char* str){ Option::getUsageString() = str; }
+void Gluco2::setHelpPrefixStr (const char* str){ Option::getHelpPrefixString() = str; }
+void Gluco2::printUsageAndExit (int argc, char** argv, bool verbose)
+{
+ const char* usage = Option::getUsageString();
+ if (usage != NULL)
+ fprintf(stderr, usage, argv[0]);
+
+ sort(Option::getOptionList(), Option::OptionLt());
+
+ const char* prev_cat = NULL;
+ const char* prev_type = NULL;
+
+ for (int i = 0; i < Option::getOptionList().size(); i++){
+ const char* cat = Option::getOptionList()[i]->category;
+ const char* type = Option::getOptionList()[i]->type_name;
+
+ if (cat != prev_cat)
+ fprintf(stderr, "\n%s OPTIONS:\n\n", cat);
+ else if (type != prev_type)
+ fprintf(stderr, "\n");
+
+ Option::getOptionList()[i]->help(verbose);
+
+ prev_cat = Option::getOptionList()[i]->category;
+ prev_type = Option::getOptionList()[i]->type_name;
+ }
+
+ fprintf(stderr, "\nHELP OPTIONS:\n\n");
+ fprintf(stderr, " --%shelp Print help message.\n", Option::getHelpPrefixString());
+ fprintf(stderr, " --%shelp-verb Print verbose help message.\n", Option::getHelpPrefixString());
+ fprintf(stderr, "\n");
+ exit(0);
+}
+
+ABC_NAMESPACE_IMPL_END
diff --git a/src/sat/glucose2/ParseUtils.h b/src/sat/glucose2/ParseUtils.h
new file mode 100644
index 00000000..54a139b1
--- /dev/null
+++ b/src/sat/glucose2/ParseUtils.h
@@ -0,0 +1,155 @@
+/************************************************************************************[ParseUtils.h]
+Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
+Copyright (c) 2007-2010, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#ifndef Glucose2_ParseUtils_h
+#define Glucose2_ParseUtils_h
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "misc/zlib/zlib.h"
+
+ABC_NAMESPACE_CXX_HEADER_START
+
+namespace Gluco2 {
+
+//-------------------------------------------------------------------------------------------------
+// A simple buffered character stream class:
+
+static const int buffer_size = 1048576;
+
+
+class StreamBuffer {
+ gzFile in;
+ unsigned char buf[buffer_size];
+ int pos;
+ int size;
+
+ void assureLookahead() {
+ if (pos >= size) {
+ pos = 0;
+ size = gzread(in, buf, sizeof(buf)); } }
+
+public:
+ explicit StreamBuffer(gzFile i) : in(i), pos(0), size(0) { assureLookahead(); }
+
+ int operator * () const { return (pos >= size) ? EOF : buf[pos]; }
+ void operator ++ () { pos++; assureLookahead(); }
+ int position () const { return pos; }
+};
+
+
+//-------------------------------------------------------------------------------------------------
+// End-of-file detection functions for StreamBuffer and char*:
+
+
+static inline bool isEof(StreamBuffer& in) { return *in == EOF; }
+static inline bool isEof(const char* in) { return *in == '\0'; }
+
+//-------------------------------------------------------------------------------------------------
+// Generic parse functions parametrized over the input-stream type.
+
+
+template<class B>
+static void skipWhitespace(B& in) {
+ while ((*in >= 9 && *in <= 13) || *in == 32)
+ ++in; }
+
+
+template<class B>
+static void skipLine(B& in) {
+ for (;;){
+ if (isEof(in)) return;
+ if (*in == '\n') { ++in; return; }
+ ++in; } }
+
+template<class B>
+static double parseDouble(B& in) { // only in the form X.XXXXXe-XX
+ bool neg= false;
+ double accu = 0.0;
+ double currentExponent = 1;
+ int exponent;
+
+ skipWhitespace(in);
+ if(*in == EOF) return 0;
+ if (*in == '-') neg = true, ++in;
+ else if (*in == '+') ++in;
+ if (*in < '1' || *in > '9') printf("PARSE ERROR! Unexpected char: %c\n", *in), exit(3);
+ accu = (double)(*in - '0');
+ ++in;
+ if (*in != '.') printf("PARSE ERROR! Unexpected char: %c\n", *in),exit(3);
+ ++in; // skip dot
+ currentExponent = 0.1;
+ while (*in >= '0' && *in <= '9')
+ accu = accu + currentExponent * ((double)(*in - '0')),
+ currentExponent /= 10,
+ ++in;
+ if (*in != 'e') printf("PARSE ERROR! Unexpected char: %c\n", *in),exit(3);
+ ++in; // skip dot
+ exponent = parseInt(in); // read exponent
+ accu *= pow(10,exponent);
+ return neg ? -accu:accu;
+}
+
+
+template<class B>
+static int parseInt(B& in) {
+ int val = 0;
+ bool neg = false;
+ skipWhitespace(in);
+ if (*in == '-') neg = true, ++in;
+ else if (*in == '+') ++in;
+ if (*in < '0' || *in > '9') fprintf(stderr, "PARSE ERROR! Unexpected char: %c\n", *in), exit(3);
+ while (*in >= '0' && *in <= '9')
+ val = val*10 + (*in - '0'),
+ ++in;
+ return neg ? -val : val; }
+
+
+// String matching: in case of a match the input iterator will be advanced the corresponding
+// number of characters.
+template<class B>
+static bool match(B& in, const char* str) {
+ int i;
+ for (i = 0; str[i] != '\0'; i++)
+ if (in[i] != str[i])
+ return false;
+
+ in += i;
+
+ return true;
+}
+
+// String matching: consumes characters eagerly, but does not require random access iterator.
+template<class B>
+static bool eagerMatch(B& in, const char* str) {
+ for (; *str != '\0'; ++str, ++in)
+ if (*str != *in)
+ return false;
+ return true; }
+
+
+//=================================================================================================
+}
+
+ABC_NAMESPACE_CXX_HEADER_END
+
+#endif
diff --git a/src/sat/glucose2/Queue.h b/src/sat/glucose2/Queue.h
new file mode 100644
index 00000000..2328fdf9
--- /dev/null
+++ b/src/sat/glucose2/Queue.h
@@ -0,0 +1,73 @@
+/*****************************************************************************************[Queue.h]
+Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
+Copyright (c) 2007-2010, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#ifndef Glucose_Queue_h
+#define Glucose_Queue_h
+
+#include "sat/glucose2/Vec.h"
+
+ABC_NAMESPACE_CXX_HEADER_START
+
+namespace Gluco2 {
+
+//=================================================================================================
+
+template<class T>
+class Queue {
+ vec<T> buf;
+ int first;
+ int end;
+
+public:
+ typedef T Key;
+
+ Queue() : buf(1), first(0), end(0) {}
+
+ void clear (bool dealloc = false) { buf.clear(dealloc); buf.growTo(1); first = end = 0; }
+ int size () const { return (end >= first) ? end - first : end - first + buf.size(); }
+
+ const T& operator [] (int index) const { assert(index >= 0); assert(index < size()); return buf[(first + index) % buf.size()]; }
+ T& operator [] (int index) { assert(index >= 0); assert(index < size()); return buf[(first + index) % buf.size()]; }
+
+ T peek () const { assert(first != end); return buf[first]; }
+ void pop () { assert(first != end); first++; if (first == buf.size()) first = 0; }
+ void insert(T elem) { // INVARIANT: buf[end] is always unused
+ buf[end++] = elem;
+ if (end == buf.size()) end = 0;
+ if (first == end){ // Resize:
+ vec<T> tmp((buf.size()*3 + 1) >> 1);
+ //**/printf("queue alloc: %d elems (%.1f MB)\n", tmp.size(), tmp.size() * sizeof(T) / 1000000.0);
+ int j, i = 0;
+ for (j = first; j < buf.size(); j++) tmp[i++] = buf[j];
+ for (j = 0 ; j < end ; j++) tmp[i++] = buf[j];
+ first = 0;
+ end = buf.size();
+ tmp.moveTo(buf);
+ }
+ }
+};
+
+
+//=================================================================================================
+}
+
+ABC_NAMESPACE_CXX_HEADER_END
+
+#endif
diff --git a/src/sat/glucose2/SimpSolver.h b/src/sat/glucose2/SimpSolver.h
new file mode 100644
index 00000000..36d625e9
--- /dev/null
+++ b/src/sat/glucose2/SimpSolver.h
@@ -0,0 +1,230 @@
+/************************************************************************************[SimpSolver.h]
+Copyright (c) 2006, Niklas Een, Niklas Sorensson
+Copyright (c) 2007-2010, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#ifndef Glucose_SimpSolver_h
+#define Glucose_SimpSolver_h
+
+#include "sat/glucose2/Queue.h"
+#include "sat/glucose2/Solver.h"
+
+#include "sat/glucose2/CGlucose.h"
+
+ABC_NAMESPACE_CXX_HEADER_START
+
+namespace Gluco2 {
+
+//=================================================================================================
+
+
+class SimpSolver : public Solver {
+ public:
+ // Constructor/Destructor:
+ //
+ SimpSolver();
+ ~SimpSolver();
+
+ // Problem specification:
+ //
+ Var newVar (bool polarity = true, bool dvar = true);
+ void addVar (Var v);
+ bool addClause (const vec<Lit>& ps);
+ bool addEmptyClause(); // Add the empty clause to the solver.
+ bool addClause (Lit p); // Add a unit clause to the solver.
+ bool addClause (Lit p, Lit q); // Add a binary clause to the solver.
+ bool addClause (Lit p, Lit q, Lit r); // Add a ternary clause to the solver.
+ bool addClause_( vec<Lit>& ps);
+ bool substitute(Var v, Lit x); // Replace all occurences of v with x (may cause a contradiction).
+
+ // Variable mode:
+ //
+ void setFrozen (Var v, bool b); // If a variable is frozen it will not be eliminated.
+ bool isEliminated(Var v) const;
+
+ // Solving:
+ //
+ bool solve (const vec<Lit>& assumps, bool do_simp = true, bool turn_off_simp = false);
+ lbool solveLimited(const vec<Lit>& assumps, bool do_simp = true, bool turn_off_simp = false);
+ int solveLimited(int * lit0, int nlits, bool do_simp = false, bool turn_off_simp = false);
+ bool solve ( bool do_simp = true, bool turn_off_simp = false);
+ bool solve (Lit p , bool do_simp = true, bool turn_off_simp = false);
+ bool solve (Lit p, Lit q, bool do_simp = true, bool turn_off_simp = false);
+ bool solve (Lit p, Lit q, Lit r, bool do_simp = true, bool turn_off_simp = false);
+ bool eliminate (bool turn_off_elim = false); // Perform variable elimination based simplification.
+
+ void prelocate(int base_var_num){
+ Solver::prelocate(base_var_num);
+ frozen .prelocate( base_var_num );
+ eliminated.prelocate( base_var_num );
+
+ if (use_simplification){
+ n_occ .prelocate( base_var_num << 1 );
+ occurs .prelocate( base_var_num );
+ touched .prelocate( base_var_num );
+ elim_heap .prelocate( base_var_num );
+ }
+ }
+ // Memory managment:
+ //
+ virtual void reset();
+ virtual void garbageCollect();
+
+
+ // Generate a (possibly simplified) DIMACS file:
+ //
+#if 0
+ void toDimacs (const char* file, const vec<Lit>& assumps);
+ void toDimacs (const char* file);
+ void toDimacs (const char* file, Lit p);
+ void toDimacs (const char* file, Lit p, Lit q);
+ void toDimacs (const char* file, Lit p, Lit q, Lit r);
+#endif
+
+ // Mode of operation:
+ //
+ int parsing;
+ int grow; // Allow a variable elimination step to grow by a number of clauses (default to zero).
+ int clause_lim; // Variables are not eliminated if it produces a resolvent with a length above this limit.
+ // -1 means no limit.
+ int subsumption_lim; // Do not check if subsumption against a clause larger than this. -1 means no limit.
+ double simp_garbage_frac; // A different limit for when to issue a GC during simplification (Also see 'garbage_frac').
+
+ bool use_asymm; // Shrink clauses by asymmetric branching.
+ bool use_rcheck; // Check if a clause is already implied. Prett costly, and subsumes subsumptions :)
+ bool use_elim; // Perform variable elimination.
+
+ // Statistics:
+ //
+ int merges;
+ int asymm_lits;
+ int eliminated_vars;
+ int eliminated_clauses;
+
+ protected:
+
+ // Helper structures:
+ //
+ struct ElimLt {
+ const vec<int>& n_occ;
+ explicit ElimLt(const vec<int>& no) : n_occ(no) {}
+
+ // TODO: are 64-bit operations here noticably bad on 32-bit platforms? Could use a saturating
+ // 32-bit implementation instead then, but this will have to do for now.
+ uint64_t cost (Var x) const { return (uint64_t)n_occ[toInt(mkLit(x))] * (uint64_t)n_occ[toInt(~mkLit(x))]; }
+ bool operator()(Var x, Var y) const { return cost(x) < cost(y); }
+
+ // TODO: investigate this order alternative more.
+ // bool operator()(Var x, Var y) const {
+ // int c_x = cost(x);
+ // int c_y = cost(y);
+ // return c_x < c_y || c_x == c_y && x < y; }
+ };
+
+ struct ClauseDeleted {
+ const ClauseAllocator& ca;
+ explicit ClauseDeleted(const ClauseAllocator& _ca) : ca(_ca) {}
+ bool operator()(const CRef& cr) const { return ca[cr].mark() == 1; } };
+
+ // Solver state:
+ //
+ int elimorder;
+ bool use_simplification;
+ vec<uint32_t> elimclauses;
+ vec<char> touched;
+ OccLists<Var, vec<CRef>, ClauseDeleted>
+ occurs;
+ vec<int> n_occ;
+ Heap<ElimLt> elim_heap;
+ Queue<CRef> subsumption_queue;
+ vec<char> frozen;
+ vec<char> eliminated;
+ int bwdsub_assigns;
+ int n_touched;
+
+ // Temporaries:
+ //
+ CRef bwdsub_tmpunit;
+
+ // Main internal methods:
+ //
+ lbool solve_ (bool do_simp = true, bool turn_off_simp = false);
+ bool asymm (Var v, CRef cr);
+ bool asymmVar (Var v);
+ void updateElimHeap (Var v);
+ void gatherTouchedClauses ();
+ bool merge (const Clause& _ps, const Clause& _qs, Var v, vec<Lit>& out_clause);
+ bool merge (const Clause& _ps, const Clause& _qs, Var v, int& size);
+ bool backwardSubsumptionCheck (bool verbose = false);
+ bool eliminateVar (Var v);
+ void extendModel ();
+
+ void removeClause (CRef cr);
+ bool strengthenClause (CRef cr, Lit l);
+ void cleanUpClauses ();
+ bool implied (const vec<Lit>& c);
+ void relocAll (ClauseAllocator& to);
+};
+
+
+//=================================================================================================
+// Implementation of inline methods:
+
+
+//inline bool SimpSolver::isEliminated (Var v) const { return eliminated[v]; }
+inline bool SimpSolver::isEliminated (Var v) const { return eliminated.size() > 0 ? eliminated[v] != 0 : 0; }
+inline void SimpSolver::updateElimHeap(Var v) {
+ assert(use_simplification);
+ // if (!frozen[v] && !isEliminated(v) && value(v) == l_Undef)
+ if (elim_heap.inHeap(v) || (!frozen[v] && !isEliminated(v) && value(v) == l_Undef))
+ elim_heap.update(v); }
+
+
+inline bool SimpSolver::addClause (const vec<Lit>& ps) { ps.copyTo(add_tmp); return addClause_(add_tmp); }
+inline bool SimpSolver::addEmptyClause() { add_tmp.clear(); return addClause_(add_tmp); }
+inline bool SimpSolver::addClause (Lit p) { add_tmp.clear(); add_tmp.push(p); return addClause_(add_tmp); }
+inline bool SimpSolver::addClause (Lit p, Lit q) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); return addClause_(add_tmp); }
+inline bool SimpSolver::addClause (Lit p, Lit q, Lit r) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); add_tmp.push(r); return addClause_(add_tmp); }
+inline void SimpSolver::setFrozen (Var v, bool b) { frozen[v] = (char)b; if (use_simplification && !b) { updateElimHeap(v); } }
+
+inline bool SimpSolver::solve ( bool do_simp, bool turn_off_simp) { budgetOff(); assumptions.clear(); return solve_(do_simp, turn_off_simp) == l_True; }
+inline bool SimpSolver::solve (Lit p , bool do_simp, bool turn_off_simp) { budgetOff(); assumptions.clear(); assumptions.push(p); return solve_(do_simp, turn_off_simp) == l_True; }
+inline bool SimpSolver::solve (Lit p, Lit q, bool do_simp, bool turn_off_simp) { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); return solve_(do_simp, turn_off_simp) == l_True; }
+inline bool SimpSolver::solve (Lit p, Lit q, Lit r, bool do_simp, bool turn_off_simp) { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); assumptions.push(r); return solve_(do_simp, turn_off_simp) == l_True; }
+inline bool SimpSolver::solve (const vec<Lit>& assumps, bool do_simp, bool turn_off_simp){
+ budgetOff(); assumps.copyTo(assumptions); return solve_(do_simp, turn_off_simp) == l_True; }
+
+inline lbool SimpSolver::solveLimited (const vec<Lit>& assumps, bool do_simp, bool turn_off_simp){
+ assumps.copyTo(assumptions); return solve_(do_simp, turn_off_simp); }
+
+inline int SimpSolver::solveLimited(int * lit0, int nlits, bool do_simp, bool turn_off_simp){
+ assumptions.clear();
+ for(int i = 0; i < nlits; i ++)
+ assumptions.push(toLit(lit0[i]));
+ lbool res = solve_(do_simp, turn_off_simp);
+ return res == l_True ? 1 : (res == l_False ? -1 : 0);
+}
+
+inline void SimpSolver::addVar(Var v) { while (v >= nVars()) newVar(); }
+
+//=================================================================================================
+}
+
+ABC_NAMESPACE_CXX_HEADER_END
+
+#endif
diff --git a/src/sat/glucose2/SimpSolver2.cpp b/src/sat/glucose2/SimpSolver2.cpp
new file mode 100644
index 00000000..37093277
--- /dev/null
+++ b/src/sat/glucose2/SimpSolver2.cpp
@@ -0,0 +1,781 @@
+/***********************************************************************************[SimpSolver.cc]
+Copyright (c) 2006, Niklas Een, Niklas Sorensson
+Copyright (c) 2007-2010, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#include "sat/glucose2/Sort.h"
+#include "sat/glucose2/SimpSolver.h"
+#include "sat/glucose2/System.h"
+
+ABC_NAMESPACE_IMPL_START
+
+using namespace Gluco2;
+
+//=================================================================================================
+// Options:
+
+
+static const char* _cat = "SIMP";
+
+static BoolOption opt_use_asymm (_cat, "asymm", "Shrink clauses by asymmetric branching.", false);
+static BoolOption opt_use_rcheck (_cat, "rcheck", "Check if a clause is already implied. (costly)", false);
+static BoolOption opt_use_elim (_cat, "elim", "Perform variable elimination.", true);
+static IntOption opt_grow (_cat, "grow", "Allow a variable elimination step to grow by a number of clauses.", 0);
+static IntOption opt_clause_lim (_cat, "cl-lim", "Variables are not eliminated if it produces a resolvent with a length above this limit. -1 means no limit", 20, IntRange(-1, INT32_MAX));
+static IntOption opt_subsumption_lim (_cat, "sub-lim", "Do not check if subsumption against a clause larger than this. -1 means no limit.", 1000, IntRange(-1, INT32_MAX));
+static DoubleOption opt_simp_garbage_frac(_cat, "simp-gc-frac", "The fraction of wasted memory allowed before a garbage collection is triggered during simplification.", 0.5, DoubleRange(0, false, HUGE_VAL, false));
+
+
+//=================================================================================================
+// Constructor/Destructor:
+
+
+SimpSolver::SimpSolver() :
+ grow (opt_grow)
+ , clause_lim (opt_clause_lim)
+ , subsumption_lim (opt_subsumption_lim)
+ , simp_garbage_frac (opt_simp_garbage_frac)
+ , use_asymm (opt_use_asymm)
+ , use_rcheck (opt_use_rcheck)
+ , use_elim (opt_use_elim)
+ , merges (0)
+ , asymm_lits (0)
+ , eliminated_vars (0)
+ , eliminated_clauses (0)
+ , elimorder (1)
+ , use_simplification (true)
+ , occurs (ClauseDeleted(ca))
+ , elim_heap (ElimLt(n_occ))
+ , bwdsub_assigns (0)
+ , n_touched (0)
+{
+ vec<Lit> dummy(1,lit_Undef);
+ ca.extra_clause_field = true; // NOTE: must happen before allocating the dummy clause below.
+ bwdsub_tmpunit = ca.alloc(dummy);
+ remove_satisfied = false;
+ parsing = 0;
+}
+
+
+SimpSolver::~SimpSolver()
+{
+}
+
+
+Var SimpSolver::newVar(bool sign, bool dvar) {
+ Var v = Solver::newVar(sign, dvar);
+
+ frozen .push((char)false);
+ eliminated.push((char)false);
+
+ if (use_simplification){
+ n_occ .push(0);
+ n_occ .push(0);
+ occurs .init(v);
+ touched .push(0);
+ elim_heap .insert(v);
+ }
+ return v; }
+
+
+
+lbool SimpSolver::solve_(bool do_simp, bool turn_off_simp)
+{
+ vec<Var> extra_frozen;
+ lbool result = l_True;
+
+ do_simp &= use_simplification;
+
+ if (do_simp){
+ // Assumptions must be temporarily frozen to run variable elimination:
+ for (int i = 0; i < assumptions.size(); i++){
+ Var v = var(assumptions[i]);
+
+ // If an assumption has been eliminated, remember it.
+ assert(!isEliminated(v));
+
+ if (!frozen[v]){
+ // Freeze and store.
+ setFrozen(v, true);
+ extra_frozen.push(v);
+ } }
+
+ result = lbool(eliminate(turn_off_simp));
+ }
+
+ if (result == l_True)
+ result = Solver::solve_();
+ else if (verbosity >= 1)
+ printf("===============================================================================\n");
+
+ if (result == l_True)
+ extendModel();
+
+ if (do_simp)
+ // Unfreeze the assumptions that were frozen:
+ for (int i = 0; i < extra_frozen.size(); i++)
+ setFrozen(extra_frozen[i], false);
+
+ return result;
+}
+
+
+
+bool SimpSolver::addClause_(vec<Lit>& ps)
+{
+#ifndef NDEBUG
+ for (int i = 0; i < ps.size(); i++)
+ assert(!isEliminated(var(ps[i])));
+#endif
+ int nclauses = clauses.size();
+
+ if (use_rcheck && implied(ps))
+ return true;
+
+ if (!Solver::addClause_(ps))
+ return false;
+
+ if(!parsing && certifiedUNSAT) {
+ for (int i = 0; i < ps.size(); i++)
+ fprintf(certifiedOutput, "%i " , (var(ps[i]) + 1) * (-2 * sign(ps[i]) + 1) );
+ fprintf(certifiedOutput, "0\n");
+ }
+
+ if (use_simplification && clauses.size() == nclauses + 1){
+ CRef cr = clauses.last();
+ const Clause& c = ca[cr];
+
+ // NOTE: the clause is added to the queue immediately and then
+ // again during 'gatherTouchedClauses()'. If nothing happens
+ // in between, it will only be checked once. Otherwise, it may
+ // be checked twice unnecessarily. This is an unfortunate
+ // consequence of how backward subsumption is used to mimic
+ // forward subsumption.
+ subsumption_queue.insert(cr);
+ for (int i = 0; i < c.size(); i++){
+ occurs[var(c[i])].push(cr);
+ n_occ[toInt(c[i])]++;
+ touched[var(c[i])] = 1;
+ n_touched++;
+ if (elim_heap.inHeap(var(c[i])))
+ elim_heap.increase(var(c[i]));
+ }
+ }
+
+ return true;
+}
+
+
+void SimpSolver::removeClause(CRef cr)
+{
+ const Clause& c = ca[cr];
+
+ if (use_simplification)
+ for (int i = 0; i < c.size(); i++){
+ n_occ[toInt(c[i])]--;
+ updateElimHeap(var(c[i]));
+ occurs.smudge(var(c[i]));
+ }
+
+ Solver::removeClause(cr);
+}
+
+
+bool SimpSolver::strengthenClause(CRef cr, Lit l)
+{
+ Clause& c = ca[cr];
+ assert(decisionLevel() == 0);
+ assert(use_simplification);
+
+ // FIX: this is too inefficient but would be nice to have (properly implemented)
+ // if (!find(subsumption_queue, &c))
+ subsumption_queue.insert(cr);
+
+ if (certifiedUNSAT) {
+ for (int i = 0; i < c.size(); i++)
+ if (c[i] != l) fprintf(certifiedOutput, "%i " , (var(c[i]) + 1) * (-2 * sign(c[i]) + 1) );
+ fprintf(certifiedOutput, "0\n");
+ }
+
+ if (c.size() == 2){
+ removeClause(cr);
+ c.strengthen(l);
+ }else{
+ if (certifiedUNSAT) {
+ fprintf(certifiedOutput, "d ");
+ for (int i = 0; i < c.size(); i++)
+ fprintf(certifiedOutput, "%i " , (var(c[i]) + 1) * (-2 * sign(c[i]) + 1) );
+ fprintf(certifiedOutput, "0\n");
+ }
+
+ detachClause(cr, true);
+ c.strengthen(l);
+ attachClause(cr);
+ remove(occurs[var(l)], cr);
+ n_occ[toInt(l)]--;
+ updateElimHeap(var(l));
+ }
+
+ return c.size() == 1 ? enqueue(c[0]) && propagate() == CRef_Undef : true;
+}
+
+
+// Returns FALSE if clause is always satisfied ('out_clause' should not be used).
+bool SimpSolver::merge(const Clause& _ps, const Clause& _qs, Var v, vec<Lit>& out_clause)
+{
+ merges++;
+ out_clause.clear();
+
+ bool ps_smallest = _ps.size() < _qs.size();
+ const Clause& ps = ps_smallest ? _qs : _ps;
+ const Clause& qs = ps_smallest ? _ps : _qs;
+
+ int i, j;
+ for (i = 0; i < qs.size(); i++){
+ if (var(qs[i]) != v){
+ for (j = 0; j < ps.size(); j++)
+ if (var(ps[j]) == var(qs[i])) {
+ if (ps[j] == ~qs[i])
+ return false;
+ else
+ goto next;
+ }
+ out_clause.push(qs[i]);
+ }
+ next:;
+ }
+
+ for (i = 0; i < ps.size(); i++)
+ if (var(ps[i]) != v)
+ out_clause.push(ps[i]);
+
+ return true;
+}
+
+
+// Returns FALSE if clause is always satisfied.
+bool SimpSolver::merge(const Clause& _ps, const Clause& _qs, Var v, int& size)
+{
+ merges++;
+
+ bool ps_smallest = _ps.size() < _qs.size();
+ const Clause& ps = ps_smallest ? _qs : _ps;
+ const Clause& qs = ps_smallest ? _ps : _qs;
+ const Lit* __ps = (const Lit*)ps;
+ const Lit* __qs = (const Lit*)qs;
+
+ size = ps.size()-1;
+
+ for (int i = 0; i < qs.size(); i++){
+ if (var(__qs[i]) != v){
+ for (int j = 0; j < ps.size(); j++)
+ if (var(__ps[j]) == var(__qs[i])) {
+ if (__ps[j] == ~__qs[i])
+ return false;
+ else
+ goto next;
+ }
+ size++;
+ }
+ next:;
+ }
+
+ return true;
+}
+
+
+void SimpSolver::gatherTouchedClauses()
+{
+ if (n_touched == 0) return;
+
+ int i,j;
+ for (i = j = 0; i < subsumption_queue.size(); i++)
+ if (ca[subsumption_queue[i]].mark() == 0)
+ ca[subsumption_queue[i]].mark(2);
+
+ for (i = 0; i < touched.size(); i++)
+ if (touched[i]){
+ const vec<CRef>& cs = occurs.lookup(i);
+ for (j = 0; j < cs.size(); j++)
+ if (ca[cs[j]].mark() == 0){
+ subsumption_queue.insert(cs[j]);
+ ca[cs[j]].mark(2);
+ }
+ touched[i] = 0;
+ }
+
+ for (i = 0; i < subsumption_queue.size(); i++)
+ if (ca[subsumption_queue[i]].mark() == 2)
+ ca[subsumption_queue[i]].mark(0);
+
+ n_touched = 0;
+}
+
+
+bool SimpSolver::implied(const vec<Lit>& c)
+{
+ assert(decisionLevel() == 0);
+
+ trail_lim.push(trail.size());
+ for (int i = 0; i < c.size(); i++)
+ if (value(c[i]) == l_True){
+ cancelUntil(0);
+ return false;
+ }else if (value(c[i]) != l_False){
+ assert(value(c[i]) == l_Undef);
+ uncheckedEnqueue(~c[i]);
+ }
+
+ bool result = propagate() != CRef_Undef;
+ cancelUntil(0);
+ return result;
+}
+
+
+// Backward subsumption + backward subsumption resolution
+bool SimpSolver::backwardSubsumptionCheck(bool verbose)
+{
+ int cnt = 0;
+ int subsumed = 0;
+ int deleted_literals = 0;
+ assert(decisionLevel() == 0);
+
+ while (subsumption_queue.size() > 0 || bwdsub_assigns < trail.size()){
+
+ // Empty subsumption queue and return immediately on user-interrupt:
+ if (asynch_interrupt){
+ subsumption_queue.clear();
+ bwdsub_assigns = trail.size();
+ break; }
+
+ // Check top-level assignments by creating a dummy clause and placing it in the queue:
+ if (subsumption_queue.size() == 0 && bwdsub_assigns < trail.size()){
+ Lit l = trail[bwdsub_assigns++];
+ ca[bwdsub_tmpunit][0] = l;
+ ca[bwdsub_tmpunit].calcAbstraction();
+ subsumption_queue.insert(bwdsub_tmpunit); }
+
+ CRef cr = subsumption_queue.peek(); subsumption_queue.pop();
+ Clause& c = ca[cr];
+
+ if (c.mark()) continue;
+
+ if (verbose && verbosity >= 2 && cnt++ % 1000 == 0)
+ printf("subsumption left: %10d (%10d subsumed, %10d deleted literals)\r", subsumption_queue.size(), subsumed, deleted_literals);
+
+ assert(c.size() > 1 || value(c[0]) == l_True); // Unit-clauses should have been propagated before this point.
+
+ // Find best variable to scan:
+ Var best = var(c[0]);
+ for (int i = 1; i < c.size(); i++)
+ if (occurs[var(c[i])].size() < occurs[best].size())
+ best = var(c[i]);
+
+ // Search all candidates:
+ vec<CRef>& _cs = occurs.lookup(best);
+ CRef* cs = (CRef*)_cs;
+
+ for (int j = 0; j < _cs.size(); j++)
+ if (c.mark())
+ break;
+ else if (!ca[cs[j]].mark() && cs[j] != cr && (subsumption_lim == -1 || ca[cs[j]].size() < subsumption_lim)){
+ Lit l = c.subsumes(ca[cs[j]]);
+
+ if (l == lit_Undef)
+ subsumed++, removeClause(cs[j]);
+ else if (l != lit_Error){
+ deleted_literals++;
+
+ if (!strengthenClause(cs[j], ~l))
+ return false;
+
+ // Did current candidate get deleted from cs? Then check candidate at index j again:
+ if (var(l) == best)
+ j--;
+ }
+ }
+ }
+
+ return true;
+}
+
+
+bool SimpSolver::asymm(Var v, CRef cr)
+{
+ Clause& c = ca[cr];
+ assert(decisionLevel() == 0);
+
+ if (c.mark() || satisfied(c)) return true;
+
+ trail_lim.push(trail.size());
+ Lit l = lit_Undef;
+ for (int i = 0; i < c.size(); i++)
+ if (var(c[i]) != v && value(c[i]) != l_False)
+ uncheckedEnqueue(~c[i]);
+ else
+ l = c[i];
+
+ if (propagate() != CRef_Undef){
+ cancelUntil(0);
+ asymm_lits++;
+ if (!strengthenClause(cr, l))
+ return false;
+ }else
+ cancelUntil(0);
+
+ return true;
+}
+
+
+bool SimpSolver::asymmVar(Var v)
+{
+ assert(use_simplification);
+
+ const vec<CRef>& cls = occurs.lookup(v);
+
+ if (value(v) != l_Undef || cls.size() == 0)
+ return true;
+
+ for (int i = 0; i < cls.size(); i++)
+ if (!asymm(v, cls[i]))
+ return false;
+
+ return backwardSubsumptionCheck();
+}
+
+
+static void mkElimClause(vec<uint32_t>& elimclauses, Lit x)
+{
+ elimclauses.push(toInt(x));
+ elimclauses.push(1);
+}
+
+
+static void mkElimClause(vec<uint32_t>& elimclauses, Var v, Clause& c)
+{
+ int first = elimclauses.size();
+ int v_pos = -1;
+
+ // Copy clause to elimclauses-vector. Remember position where the
+ // variable 'v' occurs:
+ for (int i = 0; i < c.size(); i++){
+ elimclauses.push(toInt(c[i]));
+ if (var(c[i]) == v)
+ v_pos = i + first;
+ }
+ assert(v_pos != -1);
+
+ // Swap the first literal with the 'v' literal, so that the literal
+ // containing 'v' will occur first in the clause:
+ uint32_t tmp = elimclauses[v_pos];
+ elimclauses[v_pos] = elimclauses[first];
+ elimclauses[first] = tmp;
+
+ // Store the length of the clause last:
+ elimclauses.push(c.size());
+}
+
+
+
+bool SimpSolver::eliminateVar(Var v)
+{
+ int i, j;
+ assert(!frozen[v]);
+ assert(!isEliminated(v));
+ assert(value(v) == l_Undef);
+
+ // Split the occurrences into positive and negative:
+ //
+ const vec<CRef>& cls = occurs.lookup(v);
+ vec<CRef> pos, neg;
+ for (i = 0; i < cls.size(); i++)
+ (find(ca[cls[i]], mkLit(v)) ? pos : neg).push(cls[i]);
+
+ // Check wether the increase in number of clauses stays within the allowed ('grow'). Moreover, no
+ // clause must exceed the limit on the maximal clause size (if it is set):
+ //
+ int cnt = 0;
+ int clause_size = 0;
+
+ for (i = 0; i < pos.size(); i++)
+ for (j = 0; j < neg.size(); j++)
+ if (merge(ca[pos[i]], ca[neg[j]], v, clause_size) &&
+ (++cnt > cls.size() + grow || (clause_lim != -1 && clause_size > clause_lim)))
+ return true;
+
+ // Delete and store old clauses:
+ eliminated[v] = true;
+ setDecisionVar(v, false);
+ eliminated_vars++;
+
+ if (pos.size() > neg.size()){
+ for (i = 0; i < neg.size(); i++)
+ mkElimClause(elimclauses, v, ca[neg[i]]);
+ mkElimClause(elimclauses, mkLit(v));
+ eliminated_clauses += neg.size();
+ }else{
+ for (i = 0; i < pos.size(); i++)
+ mkElimClause(elimclauses, v, ca[pos[i]]);
+ mkElimClause(elimclauses, ~mkLit(v));
+ eliminated_clauses += pos.size();
+ }
+
+
+ // Produce clauses in cross product:
+ vec<Lit>& resolvent = add_tmp;
+ for (i = 0; i < pos.size(); i++)
+ for (j = 0; j < neg.size(); j++)
+ if (merge(ca[pos[i]], ca[neg[j]], v, resolvent) && !addClause_(resolvent))
+ return false;
+
+ for (i = 0; i < cls.size(); i++)
+ removeClause(cls[i]);
+
+ // Free occurs list for this variable:
+ occurs[v].clear(true);
+
+ // Free watchers lists for this variable, if possible:
+ if (watches[ mkLit(v)].size() == 0) watches[ mkLit(v)].clear(true);
+ if (watches[~mkLit(v)].size() == 0) watches[~mkLit(v)].clear(true);
+
+ return backwardSubsumptionCheck();
+}
+
+
+bool SimpSolver::substitute(Var v, Lit x)
+{
+ assert(!frozen[v]);
+ assert(!isEliminated(v));
+ assert(value(v) == l_Undef);
+
+ if (!ok) return false;
+
+ eliminated[v] = true;
+ setDecisionVar(v, false);
+ const vec<CRef>& cls = occurs.lookup(v);
+
+ vec<Lit>& subst_clause = add_tmp;
+ for (int i = 0; i < cls.size(); i++){
+ Clause& c = ca[cls[i]];
+
+ subst_clause.clear();
+ for (int j = 0; j < c.size(); j++){
+ Lit p = c[j];
+ subst_clause.push(var(p) == v ? x ^ sign(p) : p);
+ }
+
+
+ if (!addClause_(subst_clause))
+ return ok = false;
+
+ removeClause(cls[i]);
+
+ }
+
+ return true;
+}
+
+
+void SimpSolver::extendModel()
+{
+ int i, j;
+ Lit x;
+
+ for (i = elimclauses.size()-1; i > 0; i -= j){
+ for (j = elimclauses[i--]; j > 1; j--, i--)
+ if (modelValue(toLit(elimclauses[i])) != l_False)
+ goto next;
+
+ x = toLit(elimclauses[i]);
+ model[var(x)] = lbool(!sign(x));
+ next:;
+ }
+}
+
+
+bool SimpSolver::eliminate(bool turn_off_elim)
+{
+ //abctime clk = Abc_Clock();
+ if (!simplify())
+ return false;
+ else if (!use_simplification)
+ return true;
+
+ // Main simplification loop:
+ //
+
+ int toPerform = clauses.size()<=4800000;
+
+ if(!toPerform) {
+ printf("c Too many clauses... No preprocessing\n");
+ }
+
+ while (toPerform && (n_touched > 0 || bwdsub_assigns < trail.size() || elim_heap.size() > 0)){
+
+ gatherTouchedClauses();
+ // printf(" ## (time = %6.2f s) BWD-SUB: queue = %d, trail = %d\n", cpuTime(), subsumption_queue.size(), trail.size() - bwdsub_assigns);
+ if ((subsumption_queue.size() > 0 || bwdsub_assigns < trail.size()) &&
+ !backwardSubsumptionCheck(true)){
+ ok = false; goto cleanup; }
+
+ // Empty elim_heap and return immediately on user-interrupt:
+ if (asynch_interrupt){
+ assert(bwdsub_assigns == trail.size());
+ assert(subsumption_queue.size() == 0);
+ assert(n_touched == 0);
+ elim_heap.clear();
+ goto cleanup; }
+
+ // printf(" ## (time = %6.2f s) ELIM: vars = %d\n", cpuTime(), elim_heap.size());
+ for (int cnt = 0; !elim_heap.empty(); cnt++){
+ Var elim = elim_heap.removeMin();
+
+ if (asynch_interrupt) break;
+
+ if (isEliminated(elim) || value(elim) != l_Undef) continue;
+
+ if (verbosity >= 2 && cnt % 100 == 0)
+ printf("elimination left: %10d\r", elim_heap.size());
+
+ if (use_asymm){
+ // Temporarily freeze variable. Otherwise, it would immediately end up on the queue again:
+ bool was_frozen = frozen[elim] != 0;
+ frozen[elim] = true;
+ if (!asymmVar(elim)){
+ ok = false; goto cleanup; }
+ frozen[elim] = was_frozen; }
+
+ // At this point, the variable may have been set by assymetric branching, so check it
+ // again. Also, don't eliminate frozen variables:
+ if (use_elim && value(elim) == l_Undef && !frozen[elim] && !eliminateVar(elim)){
+ ok = false; goto cleanup; }
+
+ checkGarbage(simp_garbage_frac);
+ }
+
+ assert(subsumption_queue.size() == 0);
+ }
+ cleanup:
+
+ // If no more simplification is needed, free all simplification-related data structures:
+ if (turn_off_elim){
+ touched .clear(true);
+ occurs .clear(true);
+ n_occ .clear(true);
+ elim_heap.clear(true);
+ subsumption_queue.clear(true);
+
+ use_simplification = false;
+ remove_satisfied = true;
+ ca.extra_clause_field = false;
+
+ // Force full cleanup (this is safe and desirable since it only happens once):
+ rebuildOrderHeap();
+ garbageCollect();
+ }else{
+ // Cheaper cleanup:
+ cleanUpClauses(); // TODO: can we make 'cleanUpClauses()' not be linear in the problem size somehow?
+ checkGarbage();
+ }
+
+ if (verbosity >= 1 && elimclauses.size() > 0)
+ printf("c | Eliminated clauses: %10.2f Mb |\n",
+ double(elimclauses.size() * sizeof(uint32_t)) / (1024*1024));
+ return ok;
+}
+
+
+void SimpSolver::cleanUpClauses()
+{
+ occurs.cleanAll();
+ int i,j;
+ for (i = j = 0; i < clauses.size(); i++)
+ if (ca[clauses[i]].mark() == 0)
+ clauses[j++] = clauses[i];
+ clauses.shrink_(i - j);
+}
+
+
+//=================================================================================================
+// Garbage Collection methods:
+
+
+void SimpSolver::relocAll(ClauseAllocator& to)
+{
+ int i;
+ if (!use_simplification) return;
+
+ // All occurs lists:
+ //
+ for (i = 0; i < nVars(); i++){
+ vec<CRef>& cs = occurs[i];
+ for (int j = 0; j < cs.size(); j++)
+ ca.reloc(cs[j], to);
+ }
+
+ // Subsumption queue:
+ //
+ for (i = 0; i < subsumption_queue.size(); i++)
+ ca.reloc(subsumption_queue[i], to);
+
+ // Temporary clause:
+ //
+ ca.reloc(bwdsub_tmpunit, to);
+}
+
+
+void SimpSolver::garbageCollect()
+{
+ // Initialize the next region to a size corresponding to the estimated utilization degree. This
+ // is not precise but should avoid some unnecessary reallocations for the new region:
+ ClauseAllocator to(ca.size() - ca.wasted());
+
+ cleanUpClauses();
+ to.extra_clause_field = ca.extra_clause_field; // NOTE: this is important to keep (or lose) the extra fields.
+ relocAll(to);
+ Solver::relocAll(to);
+ if (verbosity >= 2)
+ printf("| Garbage collection: %12d bytes => %12d bytes |\n",
+ ca.size()*ClauseAllocator::Unit_Size, to.size()*ClauseAllocator::Unit_Size);
+ to.moveTo(ca);
+}
+
+void SimpSolver::reset()
+{
+ Solver::reset();
+ grow = opt_grow;
+ asymm_lits = eliminated_vars = bwdsub_assigns = n_touched = 0;
+
+ subsumption_queue.clear(false);
+ vec<Lit> dummy(1,lit_Undef);
+ ca.extra_clause_field = true; // NOTE: must happen before allocating the dummy clause below.
+ bwdsub_tmpunit = ca.alloc(dummy);
+ remove_satisfied = false;
+
+ occurs.clear(false);
+
+ touched .shrink_( touched .size() );
+ n_occ .shrink_( n_occ .size() );
+ eliminated .shrink_( eliminated .size() );
+ frozen .shrink_( frozen .size() );
+ elimclauses .shrink_( elimclauses .size() );
+
+ elim_heap .clear_(false);
+}
+
+ABC_NAMESPACE_IMPL_END
diff --git a/src/sat/glucose2/Solver.h b/src/sat/glucose2/Solver.h
new file mode 100644
index 00000000..b1d38d79
--- /dev/null
+++ b/src/sat/glucose2/Solver.h
@@ -0,0 +1,653 @@
+/****************************************************************************************[Solver.h]
+ Glucose -- Copyright (c) 2009, Gilles Audemard, Laurent Simon
+ CRIL - Univ. Artois, France
+ LRI - Univ. Paris Sud, France
+
+Glucose sources are based on MiniSat (see below MiniSat copyrights). Permissions and copyrights of
+Glucose are exactly the same as Minisat on which it is based on. (see below).
+
+---------------
+Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
+Copyright (c) 2007-2010, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#ifndef Glucose_Solver_h
+#define Glucose_Solver_h
+
+#include "sat/glucose2/Vec.h"
+#include "sat/glucose2/Heap.h"
+#include "sat/glucose2/Alg.h"
+#include "sat/glucose2/Options.h"
+#include "sat/glucose2/SolverTypes.h"
+#include "sat/glucose2/BoundedQueue.h"
+#include "sat/glucose2/Constants.h"
+
+#include "sat/glucose2/CGlucose.h"
+
+ABC_NAMESPACE_CXX_HEADER_START
+
+namespace Gluco2 {
+
+//=================================================================================================
+// Solver -- the main class:
+
+class Solver {
+public:
+
+ int SolverType; // ABC identifies Glucose's type as 0
+
+ // Constructor/Destructor:
+ //
+ Solver();
+ virtual ~Solver();
+
+ // ABC callbacks
+ void * pCnfMan; // external CNF manager
+ int(*pCnfFunc)(void * p, int, int*); // external callback. messages: 0: unsat; 1: sat; -1: still working
+ int nCallConfl; // callback will be called every this number of conflicts
+ bool terminate_search_early; // used to stop the solver early if it as instructed by an external caller
+ int * pstop; // another callback
+ uint64_t nRuntimeLimit; // runtime limit
+ vec<int> user_vec;
+ vec<Lit> user_lits;
+
+ // circuit-based solving
+ int jftr;
+ void sat_solver_set_var_fanin_lit(int, int, int);
+ void sat_solver_start_new_round();
+ void sat_solver_mark_cone(int);
+ void sat_solver_set_jftr(int);
+ int sat_solver_jftr();
+ void sat_solver_reset();
+
+ // Problem specification:
+ //
+ Var newVar (bool polarity = true, bool dvar = true); // Add a new variable with parameters specifying variable mode.
+ void addVar (Var v); // Add enough variables to make sure there is variable v.
+
+ bool addClause (const vec<Lit>& ps); // Add a clause to the solver.
+ bool addEmptyClause(); // Add the empty clause, making the solver contradictory.
+ bool addClause (Lit p); // Add a unit clause to the solver.
+ bool addClause (Lit p, Lit q); // Add a binary clause to the solver.
+ bool addClause (Lit p, Lit q, Lit r); // Add a ternary clause to the solver.
+ bool addClause_( vec<Lit>& ps); // Add a clause to the solver without making superflous internal copy. Will
+ // change the passed vector 'ps'.
+
+ // Solving:
+ //
+ bool simplify (); // Removes already satisfied clauses.
+ bool solve (const vec<Lit>& assumps); // Search for a model that respects a given set of assumptions.
+ lbool solveLimited (const vec<Lit>& assumps); // Search for a model that respects a given set of assumptions (With resource constraints).
+ bool solve (); // Search without assumptions.
+ bool solve (Lit p); // Search for a model that respects a single assumption.
+ bool solve (Lit p, Lit q); // Search for a model that respects two assumptions.
+ bool solve (Lit p, Lit q, Lit r); // Search for a model that respects three assumptions.
+ bool okay () const; // FALSE means solver is in a conflicting state
+
+ void toDimacs (FILE* f, const vec<Lit>& assumps); // Write CNF to file in DIMACS-format.
+ void toDimacs (const char *file, const vec<Lit>& assumps);
+ void toDimacs (FILE* f, Clause& c, vec<Var>& map, Var& max);
+ void printLit(Lit l);
+ void printClause(CRef c);
+ void printInitialClause(CRef c);
+ // Convenience versions of 'toDimacs()':
+ void toDimacs (const char* file);
+ void toDimacs (const char* file, Lit p);
+ void toDimacs (const char* file, Lit p, Lit q);
+ void toDimacs (const char* file, Lit p, Lit q, Lit r);
+
+ // Variable mode:
+ //
+ void setPolarity (Var v, bool b); // Declare which polarity the decision heuristic should use for a variable. Requires mode 'polarity_user'.
+ void setDecisionVar (Var v, bool b, bool use_oheap = true); // Declare if a variable should be eligible for selection in the decision heuristic.
+
+ // Read state:
+ //
+ lbool value (Var x) const; // The current value of a variable.
+ lbool value (Lit p) const; // The current value of a literal.
+ lbool modelValue (Var x) const; // The value of a variable in the last model. The last call to solve must have been satisfiable.
+ lbool modelValue (Lit p) const; // The value of a literal in the last model. The last call to solve must have been satisfiable.
+ int nAssigns () const; // The current number of assigned literals.
+ int nClauses () const; // The current number of original clauses.
+ int nLearnts () const; // The current number of learnt clauses.
+ int nVars () const; // The current number of variables.
+ int nFreeVars () const;
+ int * getCex () const;
+ int level (Var x) const; // moved level() to public to compile "struct JustOrderLt" -- alanmi
+
+ // Incremental mode
+ void setIncrementalMode();
+ void initNbInitialVars(int nb);
+ void printIncrementalStats();
+
+ // Resource contraints:
+ //
+ void setConfBudget(int64_t x);
+ void setPropBudget(int64_t x);
+ void budgetOff();
+ void interrupt(); // Trigger a (potentially asynchronous) interruption of the solver.
+ void clearInterrupt(); // Clear interrupt indicator flag.
+
+ // Memory managment:
+ //
+ virtual void reset();
+ virtual void garbageCollect(); // virtuality causes segfault for some reason
+ void checkGarbage(double gf);
+ void checkGarbage();
+
+
+
+
+ // Extra results: (read-only member variable)
+ //
+ vec<lbool> model; // If problem is satisfiable, this vector contains the model (if any).
+ vec<Lit> conflict; // If problem is unsatisfiable (possibly under assumptions),
+ // this vector represent the final conflict clause expressed in the assumptions.
+
+ // Mode of operation:
+ //
+ int verbosity;
+ int verbEveryConflicts;
+ int showModel;
+ // Constants For restarts
+ double K;
+ double R;
+ double sizeLBDQueue;
+ double sizeTrailQueue;
+
+ // Constants for reduce DB
+ int firstReduceDB;
+ int incReduceDB;
+ int specialIncReduceDB;
+ unsigned int lbLBDFrozenClause;
+
+ // Constant for reducing clause
+ int lbSizeMinimizingClause;
+ unsigned int lbLBDMinimizingClause;
+
+ double var_decay;
+ double clause_decay;
+ double random_var_freq;
+ double random_seed;
+ int ccmin_mode; // Controls conflict clause minimization (0=none, 1=basic, 2=deep).
+ int phase_saving; // Controls the level of phase saving (0=none, 1=limited, 2=full).
+ bool rnd_pol; // Use random polarities for branching heuristics.
+ bool rnd_init_act; // Initialize variable activities with a small random value.
+ double garbage_frac; // The fraction of wasted memory allowed before a garbage collection is triggered.
+
+ // Certified UNSAT ( Thanks to Marijn Heule)
+ FILE* certifiedOutput;
+ bool certifiedUNSAT;
+
+
+ // Statistics: (read-only member variable)
+ //
+ int64_t nbRemovedClauses,nbReducedClauses,nbDL2,nbBin,nbUn,nbReduceDB,solves, starts, decisions, rnd_decisions, propagations, conflicts,conflictsRestarts,nbstopsrestarts,nbstopsrestartssame,lastblockatrestart;
+ int64_t dec_vars, clauses_literals, learnts_literals, max_literals, tot_literals;
+
+protected:
+ long curRestart;
+ // Helper structures:
+ //
+ struct VarData { CRef reason; int level; };
+ static inline VarData mkVarData(CRef cr, int l){ VarData d = {cr, l}; return d; }
+
+ struct Watcher {
+ CRef cref;
+ Lit blocker;
+ Watcher(CRef cr, Lit p) : cref(cr), blocker(p) {}
+ bool operator==(const Watcher& w) const { return cref == w.cref; }
+ bool operator!=(const Watcher& w) const { return cref != w.cref; }
+ };
+
+ struct WatcherDeleted
+ {
+ const ClauseAllocator& ca;
+ WatcherDeleted(const ClauseAllocator& _ca) : ca(_ca) {}
+ bool operator()(const Watcher& w) const { return ca[w.cref].mark() == 1; }
+ };
+
+ struct VarOrderLt {
+ const vec<double>& activity;
+ bool operator () (Var x, Var y) const { return activity[x] > activity[y]; }
+ VarOrderLt(const vec<double>& act) : activity(act) { }
+ };
+
+
+ // Solver state:
+ //
+ int lastIndexRed;
+ bool ok; // If FALSE, the constraints are already unsatisfiable. No part of the solver state may be used!
+ double cla_inc; // Amount to bump next clause with.
+ vec<double> activity; // A heuristic measurement of the activity of a variable.
+ double var_inc; // Amount to bump next variable with.
+ OccLists<Lit, vec<Watcher>, WatcherDeleted>
+ watches; // 'watches[lit]' is a list of constraints watching 'lit' (will go there if literal becomes true).
+ OccLists<Lit, vec<Watcher>, WatcherDeleted>
+ watchesBin; // 'watches[lit]' is a list of constraints watching 'lit' (will go there if literal becomes true).
+ vec<CRef> clauses; // List of problem clauses.
+ vec<CRef> learnts; // List of learnt clauses.
+
+ vec<lbool> assigns; // The current assignments.
+ vec<char> polarity; // The preferred polarity of each variable.
+ vec<char> decision; // Declares if a variable is eligible for selection in the decision heuristic.
+ vec<Lit> trail; // Assignment stack; stores all assigments made in the order they were made.
+ vec<int> nbpos;
+ vec<int> trail_lim; // Separator indices for different decision levels in 'trail'.
+ vec<VarData> vardata; // Stores reason and level for each variable.
+ int qhead; // Head of queue (as index into the trail -- no more explicit propagation queue in MiniSat).
+ int simpDB_assigns; // Number of top-level assignments since last execution of 'simplify()'.
+ int64_t simpDB_props; // Remaining number of propagations that must be made before next execution of 'simplify()'.
+ vec<Lit> assumptions; // Current set of assumptions provided to solve by the user.
+ Heap<VarOrderLt> order_heap; // A priority queue of variables ordered with respect to the variable activity.
+ double progress_estimate;// Set by 'search()'.
+ bool remove_satisfied; // Indicates whether possibly inefficient linear scan for satisfied clauses should be performed in 'simplify'.
+ vec<unsigned int> permDiff; // permDiff[var] contains the current conflict number... Used to count the number of LBD
+
+#ifdef UPDATEVARACTIVITY
+ // UPDATEVARACTIVITY trick (see competition'09 companion paper)
+ vec<Lit> lastDecisionLevel;
+#endif
+
+ ClauseAllocator ca;
+
+ int nbclausesbeforereduce; // To know when it is time to reduce clause database
+
+ bqueue<unsigned int> trailQueue,lbdQueue; // Bounded queues for restarts.
+ float sumLBD; // used to compute the global average of LBD. Restarts...
+ int sumAssumptions;
+
+
+ // Temporaries (to reduce allocation overhead). Each variable is prefixed by the method in which it is
+ // used, exept 'seen' wich is used in several places.
+ //
+ vec<char> seen;
+ vec<Lit> analyze_stack;
+ vec<Lit> analyze_toclear;
+ vec<Lit> add_tmp;
+ unsigned int MYFLAG;
+
+
+ double max_learnts;
+ double learntsize_adjust_confl;
+ int learntsize_adjust_cnt;
+
+ // Resource contraints:
+ //
+ int64_t conflict_budget; // -1 means no budget.
+ int64_t propagation_budget; // -1 means no budget.
+ bool asynch_interrupt;
+
+
+ // Variables added for incremental mode
+ int incremental; // Use incremental SAT Solver
+ int nbVarsInitialFormula; // nb VAR in formula without assumptions (incremental SAT)
+ double totalTime4Sat,totalTime4Unsat;
+ int nbSatCalls,nbUnsatCalls;
+ vec<int> assumptionPositions,initialPositions;
+
+
+ // Main internal methods:
+ //
+ void insertVarOrder (Var x); // Insert a variable in the decision order priority queue.
+ Lit pickBranchLit (); // Return the next decision variable.
+ void newDecisionLevel (); // Begins a new decision level.
+ void uncheckedEnqueue (Lit p, CRef from = CRef_Undef); // Enqueue a literal. Assumes value of literal is undefined.
+ bool enqueue (Lit p, CRef from = CRef_Undef); // Test if fact 'p' contradicts current state, enqueue otherwise.
+ CRef propagate (); // Perform unit propagation. Returns possibly conflicting clause.
+ void cancelUntil (int level); // Backtrack until a certain level.
+ void analyze (CRef confl, vec<Lit>& out_learnt, vec<Lit> & selectors, int& out_btlevel,unsigned int &nblevels,unsigned int &szWithoutSelectors); // (bt = backtrack)
+ void analyzeFinal (Lit p, vec<Lit>& out_conflict); // COULD THIS BE IMPLEMENTED BY THE ORDINARIY "analyze" BY SOME REASONABLE GENERALIZATION?
+ bool litRedundant (Lit p, uint32_t abstract_levels); // (helper method for 'analyze()')
+ lbool search (int nof_conflicts); // Search for a given number of conflicts.
+ lbool solve_ (); // Main solve method (assumptions given in 'assumptions').
+ void reduceDB (); // Reduce the set of learnt clauses.
+ void removeSatisfied (vec<CRef>& cs); // Shrink 'cs' to contain only non-satisfied clauses.
+ void rebuildOrderHeap ();
+
+ // Maintaining Variable/Clause activity:
+ //
+ void varDecayActivity (); // Decay all variables with the specified factor. Implemented by increasing the 'bump' value instead.
+ void varBumpActivity (Var v, double inc); // Increase a variable with the current 'bump' value.
+ void varBumpActivity (Var v); // Increase a variable with the current 'bump' value.
+ void claDecayActivity (); // Decay all clauses with the specified factor. Implemented by increasing the 'bump' value instead.
+ void claBumpActivity (Clause& c); // Increase a clause with the current 'bump' value.
+
+ // Operations on clauses:
+ //
+ void attachClause (CRef cr); // Attach a clause to watcher lists.
+ void detachClause (CRef cr, bool strict = false); // Detach a clause to watcher lists.
+ void removeClause (CRef cr); // Detach and free a clause.
+ bool locked (const Clause& c) const; // Returns TRUE if a clause is a reason for some implication in the current state.
+ bool satisfied (const Clause& c) const; // Returns TRUE if a clause is satisfied in the current state.
+
+ unsigned int computeLBD(const vec<Lit> & lits,int end=-1);
+ unsigned int computeLBD(const Clause &c);
+ void minimisationWithBinaryResolution(vec<Lit> &out_learnt);
+
+ void relocAll (ClauseAllocator& to);
+
+ // Misc:
+ //
+ int decisionLevel () const; // Gives the current decisionlevel.
+ uint32_t abstractLevel (Var x) const; // Used to represent an abstraction of sets of decision levels.
+ CRef reason (Var x) const;
+ double progressEstimate () const; // DELETE THIS ?? IT'S NOT VERY USEFUL ...
+ bool withinBudget () const;
+ inline bool isSelector(Var v) {return (incremental && v>nbVarsInitialFormula);}
+
+ // Static helpers:
+ //
+
+ // Returns a random float 0 <= x < 1. Seed must never be 0.
+ static inline double drand(double& seed) {
+ seed *= 1389796;
+ int q = (int)(seed / 2147483647);
+ seed -= (double)q * 2147483647;
+ return seed / 2147483647; }
+
+ // Returns a random integer 0 <= x < size. Seed must never be 0.
+ static inline int irand(double& seed, int size) {
+ return (int)(drand(seed) * size); }
+
+
+ // circuit-based solver
+protected:
+ void uncheckedEnqueue2(Lit p, CRef from = CRef_Undef);
+ bool heap_rescale;
+
+ void addJwatch( Var host, Var member, int index );
+ //void delJwatch( Var member );
+
+ struct NodeData { Lit lit0; Lit lit1; unsigned sort:30; unsigned dir:1; unsigned now:1; };
+ static inline NodeData mkNodeData(){ NodeData w; w.lit0 = toLit(~0); w.lit1 = toLit(~0); w.sort = 0; w.dir = 0; w.now = 0; return w; }
+ vec<NodeData> var2NodeData;
+ //vec<Lit> var2FaninLits; // (~0): undefine
+ vec<unsigned> var2TravId;
+ vec<Lit> var2Fanout0, var2FanoutN;//, var2FanoutP;
+ CRef itpc; // the interpreted clause of a gate
+ void inplace_sort( Var v );
+
+ bool isTwoFanin ( Var v ) const ; // this var has two fanins
+ bool isAND ( Var v ) const { return getFaninVar0(v) < getFaninVar1(v); }
+ bool isJReason ( Var v ) const { return isTwoFanin(v) && ( l_False == value(v) || (!isAND(v) && l_Undef != value(v)) ); }
+ Lit getFaninLit0( Var v ) const { return var2NodeData[ v ].lit0; }
+ Lit getFaninLit1( Var v ) const { return var2NodeData[ v ].lit1; }
+ bool getFaninC0 ( Var v ) const { return sign(getFaninLit0(v)); }
+ bool getFaninC1 ( Var v ) const { return sign(getFaninLit1(v)); }
+ Var getFaninVar0( Var v ) const { return var(getFaninLit0(v)); }
+ Var getFaninVar1( Var v ) const { return var(getFaninLit1(v)); }
+ Lit getFaninPlt0( Var v ) const { return mkLit(getFaninVar0(v), 1 == polarity[getFaninVar0(v)]); }
+ Lit getFaninPlt1( Var v ) const { return mkLit(getFaninVar1(v), 1 == polarity[getFaninVar1(v)]); }
+ Lit maxActiveLit(Lit lit0, Lit lit1) const { return activity[var(lit0)] < activity[var(lit1)]? lit1: lit0; }
+
+ Lit gateJustFanin(Var v) const ; // l_Undef=satisfied, 0/1 = fanin0/fanin1 requires justify
+ void gateAddJwatch(Var v,int index);
+ CRef gatePropagateCheck( Var v, Var t );
+ CRef gatePropagateCheckThis( Var v );
+ CRef gatePropagateCheckFanout( Var v, Lit lfo );
+ void setItpcSize( int sz ); // sz <= 3
+
+ // directly call by original glucose functions
+ void updateJustActivity( Var v );
+ void ResetJustData(bool fCleanMemory);
+ Lit pickJustLit( int& index );
+ void justCheck();
+ void pushJustQueue(Var v, int index);
+ void restoreJustQueue(int level); // call with cancelUntil
+ void gateClearJwatch( Var v, int backtrack_level );
+
+ CRef gatePropagate( Lit p );
+
+ CRef interpret( Var v, Var t );
+ CRef castCRef( Lit p ); // interpret a gate into a clause
+ CRef getConfClause( CRef r );
+
+ CRef Var2CRef( Var v ) const { return v | (1<<(sizeof(CRef)*8-1)); }
+ Var CRef2Var( CRef cr ) const { return cr & ~(1<<(sizeof(CRef)*8-1)); }
+ bool isGateCRef( CRef cr ) const { return CRef_Undef != cr && 0 != (cr & (1<<(sizeof(CRef)*8-1))); }
+
+ unsigned travId_prev, travId;
+
+ //Heap<JustOrderLt> jheap;
+ int jhead;
+
+ struct JustKey {
+ typedef double Key;
+ typedef Var Data;
+ typedef int Attr;
+ Key _key;
+ Data _data;
+ Attr _attr;
+ Data data() const { return _data; }
+ Key key() const { return _key; }
+ Attr attr() const { return _attr; }
+ JustKey():_key(0),_data(0),_attr(0){}
+ JustKey( const Key& nkey, const Data& ndata, const Attr& nattr ): _key(nkey), _data(ndata), _attr(nattr) {}
+ };
+ struct JustOrderLt2 {
+ const Solver * pS;
+ bool operator () (const JustKey& x, const JustKey& y) const {
+ if( x.key() != y.key() ) return x.key() > y.key();
+ if( pS->level( x.data() ) != pS->level( y.data() ) )
+ return pS->level( x.data() ) < pS->level( y.data() );
+ return x.data() > y.data();
+ }
+ JustOrderLt2(const Solver * _pS) : pS(_pS) { }
+ };
+ Heap2<JustOrderLt2, JustKey> jheap;
+ vec<int> jlevel;
+ vec<int> jnext;
+public:
+ void prelocate( int var_num );
+ void setVarFaninLits( Var v, Lit lit1, Lit lit2 );
+ void setVarFaninLits( int v, int lit1, int lit2 ){ setVarFaninLits( Var(v), toLit(lit1), toLit(lit2) ); }
+ //void delVarFaninLits( Var v);
+
+ void setNewRound(){ travId ++ ; }
+ void markCone( Var v );
+ void setJust( int njftr ){ jftr = njftr; }
+ bool isRoundWatch( Var v ) const { return travId==var2TravId[v]; }
+ void justReset(){ jftr = 0; reset(); }
+
+
+ //const JustData& getJustData(int v) const { return jdata[v]; }
+ double varActivity(int v) const { return activity[v];}
+ //double justActivity(int v) const { return jdata[v].act_fanin;}
+ int varPolarity(int v){ return polarity[v]? 1: 0;}
+ vec<Lit> JustModel; // model obtained by justification enabled
+
+ int justUsage() const ;
+ int solveLimited( int * , int nlits );
+};
+
+
+//=================================================================================================
+// Implementation of inline methods:
+
+inline CRef Solver::reason(Var x) const { return vardata[x].reason; }
+inline int Solver::level (Var x) const { return vardata[x].level; }
+
+inline void Solver::insertVarOrder(Var x) {
+ #ifdef CGLUCOSE_EXP
+ if (!justUsage() && !order_heap.inHeap(x) && decision[x]) order_heap.insert(x);
+ #else
+ if (!order_heap.inHeap(x) && decision[x]) order_heap.insert(x);
+ #endif
+}
+
+inline void Solver::varDecayActivity() { var_inc *= (1 / var_decay); }
+inline void Solver::varBumpActivity(Var v) { varBumpActivity(v, var_inc); }
+inline void Solver::varBumpActivity(Var v, double inc) {
+ if ( (activity[v] += inc) > 1e100 ) {
+ heap_rescale = 1;
+ // Rescale:
+ for (int i = 0; i < nVars(); i++)
+ activity[i] *= 1e-100;
+ var_inc *= 1e-100; }
+
+ // Update order_heap with respect to new activity:
+ if (!justUsage() && order_heap.inHeap(v))
+ order_heap.decrease(v);
+}
+
+inline void Solver::claDecayActivity() { cla_inc *= (1 / clause_decay); }
+inline void Solver::claBumpActivity (Clause& c) {
+ if ( (c.activity() += cla_inc) > 1e20 ) {
+ // Rescale:
+ for (int i = 0; i < learnts.size(); i++)
+ ca[learnts[i]].activity() *= (float)1e-20;
+ cla_inc *= 1e-20; } }
+
+inline void Solver::checkGarbage(void){ checkGarbage(garbage_frac); }
+inline void Solver::checkGarbage(double gf){
+ if (ca.wasted() > ca.size() * gf)
+ garbageCollect();}
+
+// NOTE: enqueue does not set the ok flag! (only public methods do)
+inline bool Solver::enqueue (Lit p, CRef from) { return value(p) != l_Undef ? value(p) != l_False : (uncheckedEnqueue(p, from), true); }
+inline bool Solver::addClause (const vec<Lit>& ps) { ps.copyTo(add_tmp); return addClause_(add_tmp); }
+inline bool Solver::addEmptyClause () { add_tmp.clear(); return addClause_(add_tmp); }
+inline bool Solver::addClause (Lit p) { add_tmp.clear(); add_tmp.push(p); return addClause_(add_tmp); }
+inline bool Solver::addClause (Lit p, Lit q) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); return addClause_(add_tmp); }
+inline bool Solver::addClause (Lit p, Lit q, Lit r) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); add_tmp.push(r); return addClause_(add_tmp); }
+inline bool Solver::locked (const Clause& c) const {
+ #ifdef CGLUCOSE_EXP
+
+ if(c.size()>2)
+ return value(c[0]) == l_True && reason(var(c[0])) != CRef_Undef && !isGateCRef(reason(var(c[0]))) && ca.lea(reason(var(c[0]))) == &c;
+ return
+ (value(c[0]) == l_True && reason(var(c[0])) != CRef_Undef && !isGateCRef(reason(var(c[0]))) && ca.lea(reason(var(c[0]))) == &c)
+ ||
+ (value(c[1]) == l_True && reason(var(c[1])) != CRef_Undef && !isGateCRef(reason(var(c[1]))) && ca.lea(reason(var(c[1]))) == &c);
+
+ #else
+
+ if(c.size()>2)
+ return value(c[0]) == l_True && reason(var(c[0])) != CRef_Undef && ca.lea(reason(var(c[0]))) == &c;
+ return
+ (value(c[0]) == l_True && reason(var(c[0])) != CRef_Undef && ca.lea(reason(var(c[0]))) == &c)
+ ||
+ (value(c[1]) == l_True && reason(var(c[1])) != CRef_Undef && ca.lea(reason(var(c[1]))) == &c);
+
+ #endif
+ }
+inline void Solver::newDecisionLevel() {trail_lim.push(trail.size());}
+
+inline int Solver::decisionLevel () const { return trail_lim.size(); }
+inline uint32_t Solver::abstractLevel (Var x) const { return 1 << (level(x) & 31); }
+inline lbool Solver::value (Var x) const { return assigns[x]; }
+inline lbool Solver::value (Lit p) const { return assigns[var(p)] ^ sign(p); }
+inline lbool Solver::modelValue (Var x) const { return model[x]; }
+inline lbool Solver::modelValue (Lit p) const { return model[var(p)] ^ sign(p); }
+inline int Solver::nAssigns () const { return trail.size(); }
+inline int Solver::nClauses () const { return clauses.size(); }
+inline int Solver::nLearnts () const { return learnts.size(); }
+inline int Solver::nVars () const { return vardata.size(); }
+inline int Solver::nFreeVars () const { return (int)dec_vars - (trail_lim.size() == 0 ? trail.size() : trail_lim[0]); }
+inline int * Solver::getCex () const { return (int*) &JustModel[0]; }
+inline void Solver::setPolarity (Var v, bool b) { polarity[v] = b; }
+inline void Solver::setDecisionVar(Var v, bool b, bool use_oheap)
+{
+ if ( b && !decision[v]) dec_vars++;
+ else if (!b && decision[v]) dec_vars--;
+
+ decision[v] = b;
+ if( use_oheap ) insertVarOrder(v);
+}
+inline void Solver::setConfBudget(int64_t x){ conflict_budget = conflicts + x; }
+inline void Solver::setPropBudget(int64_t x){ propagation_budget = propagations + x; }
+inline void Solver::interrupt(){ asynch_interrupt = true; }
+inline void Solver::clearInterrupt(){ asynch_interrupt = false; }
+inline void Solver::budgetOff(){ conflict_budget = propagation_budget = -1; }
+inline bool Solver::withinBudget() const {
+ return !asynch_interrupt &&
+ (conflict_budget < 0 || conflicts < (uint64_t)conflict_budget) &&
+ (propagation_budget < 0 || propagations < (uint64_t)propagation_budget); }
+
+// FIXME: after the introduction of asynchronous interrruptions the solve-versions that return a
+// pure bool do not give a safe interface. Either interrupts must be possible to turn off here, or
+// all calls to solve must return an 'lbool'. I'm not yet sure which I prefer.
+inline bool Solver::solve () { budgetOff(); assumptions.clear(); return solve_() == l_True; }
+inline bool Solver::solve (Lit p) { budgetOff(); assumptions.clear(); assumptions.push(p); return solve_() == l_True; }
+inline bool Solver::solve (Lit p, Lit q) { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); return solve_() == l_True; }
+inline bool Solver::solve (Lit p, Lit q, Lit r) { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); assumptions.push(r); return solve_() == l_True; }
+inline bool Solver::solve (const vec<Lit>& assumps){ budgetOff(); assumps.copyTo(assumptions); return solve_() == l_True; }
+inline lbool Solver::solveLimited (const vec<Lit>& assumps){ assumps.copyTo(assumptions); return solve_(); }
+inline bool Solver::okay () const { return ok; }
+
+inline void Solver::toDimacs (const char* file){ vec<Lit> as; toDimacs(file, as); }
+inline void Solver::toDimacs (const char* file, Lit p){ vec<Lit> as; as.push(p); toDimacs(file, as); }
+inline void Solver::toDimacs (const char* file, Lit p, Lit q){ vec<Lit> as; as.push(p); as.push(q); toDimacs(file, as); }
+inline void Solver::toDimacs (const char* file, Lit p, Lit q, Lit r){ vec<Lit> as; as.push(p); as.push(q); as.push(r); toDimacs(file, as); }
+
+inline void Solver::addVar(Var v) { while (v >= nVars()) newVar(); }
+
+inline void Solver::sat_solver_set_var_fanin_lit(int v, int lit0, int lit1) { setVarFaninLits( Var(v), toLit(lit0), toLit(lit1) ); }
+inline void Solver::sat_solver_start_new_round() { setNewRound(); }
+inline void Solver::sat_solver_mark_cone(int v) { markCone(v); }
+inline void Solver::sat_solver_set_jftr( int njftr ){ setJust(njftr); }
+inline int Solver::sat_solver_jftr(){ return jftr; }
+inline void Solver::sat_solver_reset(){ justReset(); }
+inline int Solver::solveLimited( int * lit0, int nlits ){
+ assumptions.clear();
+ for(int i = 0; i < nlits; i ++)
+ assumptions.push(toLit(lit0[i]));
+ lbool res = solve_();
+ return res == l_True ? 1 : (res == l_False ? -1 : 0);
+}
+//=================================================================================================
+// Debug etc:
+
+
+inline void Solver::printLit(Lit l)
+{
+ printf("%s%d:%c", sign(l) ? "-" : "", var(l)+1, value(l) == l_True ? '1' : (value(l) == l_False ? '0' : 'X'));
+}
+
+
+inline void Solver::printClause(CRef cr)
+{
+ Clause &c = ca[cr];
+ for (int i = 0; i < c.size(); i++){
+ printLit(c[i]);
+ printf(" ");
+ }
+}
+
+inline void Solver::printInitialClause(CRef cr)
+{
+ Clause &c = ca[cr];
+ for (int i = 0; i < c.size(); i++){
+ if(!isSelector(var(c[i]))) {
+ printLit(c[i]);
+ printf(" ");
+ }
+ }
+}
+
+
+//=================================================================================================
+}
+
+
+ABC_NAMESPACE_CXX_HEADER_END
+
+#include "sat/glucose2/CGlucoseCore.h"
+
+#endif
diff --git a/src/sat/glucose2/SolverTypes.h b/src/sat/glucose2/SolverTypes.h
new file mode 100644
index 00000000..c0990226
--- /dev/null
+++ b/src/sat/glucose2/SolverTypes.h
@@ -0,0 +1,450 @@
+/***********************************************************************************[SolverTypes.h]
+ Glucose -- Copyright (c) 2009, Gilles Audemard, Laurent Simon
+ CRIL - Univ. Artois, France
+ LRI - Univ. Paris Sud, France
+
+Glucose sources are based on MiniSat (see below MiniSat copyrights). Permissions and copyrights of
+Glucose are exactly the same as Minisat on which it is based on. (see below).
+
+---------------
+Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
+Copyright (c) 2007-2010, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+
+#ifndef Glucose_SolverTypes_h
+#define Glucose_SolverTypes_h
+
+#include <assert.h>
+
+#include "sat/glucose2/IntTypes.h"
+#include "sat/glucose2/Alg.h"
+#include "sat/glucose2/Vec.h"
+#include "sat/glucose2/Map.h"
+#include "sat/glucose2/Alloc.h"
+
+#include "sat/glucose2/CGlucose.h"
+
+ABC_NAMESPACE_CXX_HEADER_START
+
+namespace Gluco2 {
+
+//=================================================================================================
+// Variables, literals, lifted booleans, clauses:
+
+
+// NOTE! Variables are just integers. No abstraction here. They should be chosen from 0..N,
+// so that they can be used as array indices.
+
+typedef int Var;
+#define var_Undef (-1)
+
+
+struct Lit {
+ int x;
+
+ // Use this as a constructor:
+ friend Lit mkLit(Var var, bool sign);
+ bool operator == (Lit p) const { return x == p.x; }
+ bool operator != (Lit p) const { return x != p.x; }
+ bool operator < (Lit p) const { return x < p.x; } // '<' makes p, ~p adjacent in the ordering.
+};
+
+
+inline Lit mkLit (Var var, bool sign = false) { Lit p; p.x = var + var + (int)sign; return p; }
+inline Lit operator ~(Lit p) { Lit q; q.x = p.x ^ 1; return q; }
+inline Lit operator ^(Lit p, bool b) { Lit q; q.x = p.x ^ (unsigned int)b; return q; }
+inline bool sign (Lit p) { return p.x & 1; }
+inline int var (Lit p) { return p.x >> 1; }
+
+// Mapping Literals to and from compact integers suitable for array indexing:
+inline int toInt (Var v) { return v; }
+inline int toInt (Lit p) { return p.x; }
+inline Lit toLit (int i) { Lit p; p.x = i; return p; }
+
+//const Lit lit_Undef = mkLit(var_Undef, false); // }- Useful special constants.
+//const Lit lit_Error = mkLit(var_Undef, true ); // }
+
+const Lit lit_Undef = { -2 }; // }- Useful special constants.
+const Lit lit_Error = { -1 }; // }
+
+
+//=================================================================================================
+// Lifted booleans:
+//
+// NOTE: this implementation is optimized for the case when comparisons between values are mostly
+// between one variable and one constant. Some care had to be taken to make sure that gcc
+// does enough constant propagation to produce sensible code, and this appears to be somewhat
+// fragile unfortunately.
+
+#define l_True (Gluco2::lbool((uint8_t)0)) // gcc does not do constant propagation if these are real constants.
+#define l_False (Gluco2::lbool((uint8_t)1))
+#define l_Undef (Gluco2::lbool((uint8_t)2))
+
+class lbool {
+ uint8_t value;
+
+public:
+ explicit lbool(uint8_t v) : value(v) { }
+
+ lbool() : value(0) { }
+ explicit lbool(bool x) : value(!x) { }
+
+ bool operator == (lbool b) const { return (((b.value&2) & (value&2)) | (!(b.value&2)&(value == b.value))) != 0; }
+ bool operator != (lbool b) const { return !(*this == b); }
+ lbool operator ^ (bool b) const { return lbool((uint8_t)(value^(uint8_t)b)); }
+
+ lbool operator && (lbool b) const {
+ uint8_t sel = (this->value << 1) | (b.value << 3);
+ uint8_t v = (0xF7F755F4 >> sel) & 3;
+ return lbool(v); }
+
+ lbool operator || (lbool b) const {
+ uint8_t sel = (this->value << 1) | (b.value << 3);
+ uint8_t v = (0xFCFCF400 >> sel) & 3;
+ return lbool(v); }
+
+ friend int toInt (lbool l);
+ friend lbool toLbool(int v);
+};
+inline int toInt (lbool l) { return l.value; }
+inline lbool toLbool(int v) { return lbool((uint8_t)v); }
+
+//=================================================================================================
+// Clause -- a simple class for representing a clause:
+
+class Clause;
+typedef RegionAllocator<uint32_t>::Ref CRef;
+
+class Clause {
+ struct {
+ unsigned mark : 2;
+ unsigned learnt : 1;
+ unsigned has_extra : 1;
+ unsigned reloced : 1;
+ unsigned lbd : 26;
+ unsigned canbedel : 1;
+ unsigned size : 32;
+ unsigned szWithoutSelectors : 32;
+
+ } header;
+ union { Lit lit; float act; uint32_t abs; CRef rel; } data[0];
+
+ friend class ClauseAllocator;
+
+ #ifdef CGLUCOSE_EXP
+ friend class Solver;
+ #endif
+
+ // NOTE: This constructor cannot be used directly (doesn't allocate enough memory).
+ template<class V>
+ Clause(const V& ps, bool use_extra, bool learnt) {
+ header.mark = 0;
+ header.learnt = learnt;
+ header.has_extra = use_extra;
+ header.reloced = 0;
+ header.size = ps.size();
+ header.lbd = 0;
+ header.canbedel = 1;
+ for (int i = 0; i < ps.size(); i++)
+ data[i].lit = ps[i];
+
+ if (header.has_extra){
+ if (header.learnt)
+ data[header.size].act = 0;
+ else
+ calcAbstraction(); }
+ }
+
+public:
+ void calcAbstraction() {
+ assert(header.has_extra);
+ uint32_t abstraction = 0;
+ for (int i = 0; i < size(); i++)
+ abstraction |= 1 << (var(data[i].lit) & 31);
+ data[header.size].abs = abstraction; }
+
+
+ int size () const { return header.size; }
+ void shrink (int i) { assert(i <= size()); if (header.has_extra) data[header.size-i] = data[header.size]; header.size -= i; }
+ void pop () { shrink(1); }
+ bool learnt () const { return header.learnt; }
+ bool has_extra () const { return header.has_extra; }
+ uint32_t mark () const { return header.mark; }
+ void mark (uint32_t m) { header.mark = m; }
+ const Lit& last () const { return data[header.size-1].lit; }
+
+ bool reloced () const { return header.reloced; }
+ CRef relocation () const { return data[0].rel; }
+ void relocate (CRef c) { header.reloced = 1; data[0].rel = c; }
+
+ // NOTE: somewhat unsafe to change the clause in-place! Must manually call 'calcAbstraction' afterwards for
+ // subsumption operations to behave correctly.
+ Lit& operator [] (int i) { return data[i].lit; }
+ Lit operator [] (int i) const { return data[i].lit; }
+ operator const Lit* (void) const { return (Lit*)data; }
+
+ float& activity () { assert(header.has_extra); return data[header.size].act; }
+ uint32_t abstraction () const { assert(header.has_extra); return data[header.size].abs; }
+
+ Lit subsumes (const Clause& other) const;
+ void strengthen (Lit p);
+ void setLBD(int i) {header.lbd = i;}
+ // unsigned int& lbd () { return header.lbd; }
+ unsigned int lbd () const { return header.lbd; }
+ void setCanBeDel(bool b) {header.canbedel = b;}
+ bool canBeDel() {return header.canbedel;}
+ void setSizeWithoutSelectors (unsigned int n) {header.szWithoutSelectors = n; }
+ unsigned int sizeWithoutSelectors () const { return header.szWithoutSelectors; }
+
+};
+
+
+//=================================================================================================
+// ClauseAllocator -- a simple class for allocating memory for clauses:
+
+
+const CRef CRef_Undef = RegionAllocator<uint32_t>::Ref_Undef;
+class ClauseAllocator : public RegionAllocator<uint32_t>
+{
+ static int clauseWord32Size(int size, bool has_extra){
+ return (sizeof(Clause) + (sizeof(Lit) * (size + (int)has_extra))) / sizeof(uint32_t); }
+ public:
+ bool extra_clause_field;
+
+ ClauseAllocator(uint32_t start_cap) : RegionAllocator<uint32_t>(start_cap), extra_clause_field(false){}
+ ClauseAllocator() : extra_clause_field(false){}
+
+ void moveTo(ClauseAllocator& to){
+ to.extra_clause_field = extra_clause_field;
+ RegionAllocator<uint32_t>::moveTo(to); }
+
+ template<class Lits>
+ CRef alloc(const Lits& ps, bool learnt = false)
+ {
+ assert(sizeof(Lit) == sizeof(uint32_t));
+ assert(sizeof(float) == sizeof(uint32_t));
+ bool use_extra = learnt | extra_clause_field;
+
+ CRef cid = RegionAllocator<uint32_t>::alloc(clauseWord32Size(ps.size(), use_extra));
+ new (lea(cid)) Clause(ps, use_extra, learnt);
+
+ return cid;
+ }
+
+ // Deref, Load Effective Address (LEA), Inverse of LEA (AEL):
+ Clause& operator[](Ref r) { return (Clause&)RegionAllocator<uint32_t>::operator[](r); }
+ const Clause& operator[](Ref r) const { return (Clause&)RegionAllocator<uint32_t>::operator[](r); }
+ Clause* lea (Ref r) { return (Clause*)RegionAllocator<uint32_t>::lea(r); }
+ const Clause* lea (Ref r) const { return (Clause*)RegionAllocator<uint32_t>::lea(r); }
+ Ref ael (const Clause* t){ return RegionAllocator<uint32_t>::ael((uint32_t*)t); }
+
+ void free_(CRef cid)
+ {
+ Clause& c = operator[](cid);
+ RegionAllocator<uint32_t>::free_(clauseWord32Size(c.size(), c.has_extra()));
+ }
+
+ void reloc(CRef& cr, ClauseAllocator& to)
+ {
+ Clause& c = operator[](cr);
+
+ if (c.reloced()) { cr = c.relocation(); return; }
+
+ cr = to.alloc(c, c.learnt());
+ c.relocate(cr);
+
+ // Copy extra data-fields:
+ // (This could be cleaned-up. Generalize Clause-constructor to be applicable here instead?)
+ to[cr].mark(c.mark());
+ if (to[cr].learnt()) {
+ to[cr].activity() = c.activity();
+ to[cr].setLBD(c.lbd());
+ to[cr].setSizeWithoutSelectors(c.sizeWithoutSelectors());
+ to[cr].setCanBeDel(c.canBeDel());
+ }
+ else if (to[cr].has_extra()) to[cr].calcAbstraction();
+ }
+};
+
+
+//=================================================================================================
+// OccLists -- a class for maintaining occurence lists with lazy deletion:
+
+template<class Idx, class Vec, class Deleted>
+class OccLists
+{
+ vec<Vec> occs;
+ vec<char> dirty;
+ vec<Idx> dirties;
+ Deleted deleted;
+
+ public:
+ OccLists(const Deleted& d) : deleted(d) {}
+
+ void init (const Idx& idx){ occs.growTo(toInt(idx)+1); dirty.growTo(toInt(idx)+1, 0); }
+ void prelocate (const int num){ occs.prelocate(num); dirty.prelocate(num); }
+ // Vec& operator[](const Idx& idx){ return occs[toInt(idx)]; }
+ Vec& operator[](const Idx& idx){ return occs[toInt(idx)]; }
+ Vec& lookup (const Idx& idx){ if (dirty[toInt(idx)]) clean(idx); return occs[toInt(idx)]; }
+
+ void cleanAll ();
+ void clean (const Idx& idx);
+ void smudge (const Idx& idx){
+ if (dirty[toInt(idx)] == 0){
+ dirty[toInt(idx)] = 1;
+ dirties.push(idx);
+ }
+ }
+
+ void clear(bool free = true){
+ if(free){
+ occs .clear(free);
+ dirty .clear(free);
+ dirties.clear(free);
+ } else {
+ occs .shrink (occs .size());
+ dirty .shrink_(dirty .size());
+ dirties.shrink_(dirties.size());
+ }
+ }
+};
+
+
+template<class Idx, class Vec, class Deleted>
+void OccLists<Idx,Vec,Deleted>::cleanAll()
+{
+ for (int i = 0; i < dirties.size(); i++)
+ // Dirties may contain duplicates so check here if a variable is already cleaned:
+ if (dirty[toInt(dirties[i])])
+ clean(dirties[i]);
+ dirties.shrink_( dirties.size() );
+}
+
+
+template<class Idx, class Vec, class Deleted>
+void OccLists<Idx,Vec,Deleted>::clean(const Idx& idx)
+{
+ Vec& vec = occs[toInt(idx)];
+ int i, j;
+ for (i = j = 0; i < vec.size(); i++)
+ if (!deleted(vec[i]))
+ vec[j++] = vec[i];
+ vec.shrink_(i - j);
+ dirty[toInt(idx)] = 0;
+}
+
+
+//=================================================================================================
+// CMap -- a class for mapping clauses to values:
+
+
+template<class T>
+class CMap
+{
+ struct CRefHash {
+ uint32_t operator()(CRef cr) const { return (uint32_t)cr; } };
+
+ typedef Map<CRef, T, CRefHash> HashTable;
+ HashTable map;
+
+ public:
+ // Size-operations:
+ void clear () { map.clear(); }
+ int size () const { return map.elems(); }
+
+
+ // Insert/Remove/Test mapping:
+ void insert (CRef cr, const T& t){ map.insert(cr, t); }
+ void growTo (CRef cr, const T& t){ map.insert(cr, t); } // NOTE: for compatibility
+ void remove (CRef cr) { map.remove(cr); }
+ bool has (CRef cr, T& t) { return map.peek(cr, t); }
+
+ // Vector interface (the clause 'c' must already exist):
+ const T& operator [] (CRef cr) const { return map[cr]; }
+ T& operator [] (CRef cr) { return map[cr]; }
+
+ // Iteration (not transparent at all at the moment):
+ int bucket_count() const { return map.bucket_count(); }
+ const vec<typename HashTable::Pair>& bucket(int i) const { return map.bucket(i); }
+
+ // Move contents to other map:
+ void moveTo(CMap& other){ map.moveTo(other.map); }
+
+ // TMP debug:
+ void debug(){
+ printf(" --- size = %d, bucket_count = %d\n", size(), map.bucket_count()); }
+};
+
+
+/*_________________________________________________________________________________________________
+|
+| subsumes : (other : const Clause&) -> Lit
+|
+| Description:
+| Checks if clause subsumes 'other', and at the same time, if it can be used to simplify 'other'
+| by subsumption resolution.
+|
+| Result:
+| lit_Error - No subsumption or simplification
+| lit_Undef - Clause subsumes 'other'
+| p - The literal p can be deleted from 'other'
+|________________________________________________________________________________________________@*/
+inline Lit Clause::subsumes(const Clause& other) const
+{
+ //if (other.size() < size() || (extra.abst & ~other.extra.abst) != 0)
+ //if (other.size() < size() || (!learnt() && !other.learnt() && (extra.abst & ~other.extra.abst) != 0))
+ assert(!header.learnt); assert(!other.header.learnt);
+ assert(header.has_extra); assert(other.header.has_extra);
+ if (other.header.size < header.size || (data[header.size].abs & ~other.data[other.header.size].abs) != 0)
+ return lit_Error;
+
+ Lit ret = lit_Undef;
+ const Lit* c = (const Lit*)(*this);
+ const Lit* d = (const Lit*)other;
+
+ for (unsigned i = 0; i < header.size; i++) {
+ // search for c[i] or ~c[i]
+ for (unsigned j = 0; j < other.header.size; j++)
+ if (c[i] == d[j])
+ goto ok;
+ else if (ret == lit_Undef && c[i] == ~d[j]){
+ ret = c[i];
+ goto ok;
+ }
+
+ // did not find it
+ return lit_Error;
+ ok:;
+ }
+
+ return ret;
+}
+
+inline void Clause::strengthen(Lit p)
+{
+ remove(*this, p);
+ calcAbstraction();
+}
+
+//=================================================================================================
+}
+
+ABC_NAMESPACE_CXX_HEADER_END
+
+#endif
diff --git a/src/sat/glucose2/Sort.h b/src/sat/glucose2/Sort.h
new file mode 100644
index 00000000..6be112ca
--- /dev/null
+++ b/src/sat/glucose2/Sort.h
@@ -0,0 +1,101 @@
+/******************************************************************************************[Sort.h]
+Copyright (c) 2003-2007, Niklas Een, Niklas Sorensson
+Copyright (c) 2007-2010, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#ifndef Glucose_Sort_h
+#define Glucose_Sort_h
+
+#include "sat/glucose2/Vec.h"
+
+//=================================================================================================
+// Some sorting algorithms for vec's
+
+ABC_NAMESPACE_CXX_HEADER_START
+
+namespace Gluco2 {
+
+template<class T>
+struct LessThan_default {
+ bool operator () (T x, T y) { return x < y; }
+};
+
+
+template <class T, class LessThan>
+void selectionSort(T* array, int size, LessThan lt)
+{
+ int i, j, best_i;
+ T tmp;
+
+ for (i = 0; i < size-1; i++){
+ best_i = i;
+ for (j = i+1; j < size; j++){
+ if (lt(array[j], array[best_i]))
+ best_i = j;
+ }
+ tmp = array[i]; array[i] = array[best_i]; array[best_i] = tmp;
+ }
+}
+template <class T> static inline void selectionSort(T* array, int size) {
+ selectionSort(array, size, LessThan_default<T>()); }
+
+template <class T, class LessThan>
+void sort(T* array, int size, LessThan lt)
+{
+ if (size <= 15)
+ selectionSort(array, size, lt);
+
+ else{
+ T pivot = array[size / 2];
+ T tmp;
+ int i = -1;
+ int j = size;
+
+ for(;;){
+ do i++; while(lt(array[i], pivot));
+ do j--; while(lt(pivot, array[j]));
+
+ if (i >= j) break;
+
+ tmp = array[i]; array[i] = array[j]; array[j] = tmp;
+ }
+
+ sort(array , i , lt);
+ sort(&array[i], size-i, lt);
+ }
+}
+template <class T> static inline void sort(T* array, int size) {
+ sort(array, size, LessThan_default<T>()); }
+
+
+//=================================================================================================
+// For 'vec's:
+
+
+template <class T, class LessThan> void sort(vec<T>& v, LessThan lt) {
+ sort((T*)v, v.size(), lt); }
+template <class T> void sort(vec<T>& v) {
+ sort(v, LessThan_default<T>()); }
+
+
+//=================================================================================================
+}
+
+ABC_NAMESPACE_CXX_HEADER_END
+
+#endif
diff --git a/src/sat/glucose2/System.h b/src/sat/glucose2/System.h
new file mode 100644
index 00000000..088bada5
--- /dev/null
+++ b/src/sat/glucose2/System.h
@@ -0,0 +1,73 @@
+/****************************************************************************************[System.h]
+Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
+Copyright (c) 2007-2010, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#ifndef Glucose_System_h
+#define Glucose_System_h
+
+#if defined(__linux__)
+//#include <fpu_control.h>
+#endif
+
+#include "sat/glucose2/IntTypes.h"
+
+ABC_NAMESPACE_CXX_HEADER_START
+
+//-------------------------------------------------------------------------------------------------
+
+namespace Gluco2 {
+
+static inline double cpuTime(void); // CPU-time in seconds.
+extern double memUsed(); // Memory in mega bytes (returns 0 for unsupported architectures).
+extern double memUsedPeak(); // Peak-memory in mega bytes (returns 0 for unsupported architectures).
+
+}
+
+ABC_NAMESPACE_CXX_HEADER_END
+
+//-------------------------------------------------------------------------------------------------
+// Implementation of inline functions:
+
+#if defined(_MSC_VER) || defined(__MINGW32__)
+#include <time.h>
+
+ABC_NAMESPACE_CXX_HEADER_START
+
+static inline double Gluco2::cpuTime(void) { return (double)clock() / CLOCKS_PER_SEC; }
+
+ABC_NAMESPACE_CXX_HEADER_END
+
+
+#else
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <unistd.h>
+
+ABC_NAMESPACE_CXX_HEADER_START
+
+static inline double Gluco2::cpuTime(void) {
+ struct rusage ru;
+ getrusage(RUSAGE_SELF, &ru);
+ return (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec / 1000000; }
+
+ABC_NAMESPACE_CXX_HEADER_END
+
+#endif
+
+#endif
diff --git a/src/sat/glucose2/System2.cpp b/src/sat/glucose2/System2.cpp
new file mode 100644
index 00000000..844220a0
--- /dev/null
+++ b/src/sat/glucose2/System2.cpp
@@ -0,0 +1,116 @@
+/***************************************************************************************[System.cc]
+Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
+Copyright (c) 2007-2010, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#include "sat/glucose2/System.h"
+
+#if defined(__linux__)
+
+#include <stdio.h>
+#include <stdlib.h>
+
+ABC_NAMESPACE_IMPL_START
+
+using namespace Gluco2;
+
+// TODO: split the memory reading functions into two: one for reading high-watermark of RSS, and
+// one for reading the current virtual memory size.
+
+static inline int memReadStat(int field)
+{
+ char name[256];
+ pid_t pid = getpid();
+ int value;
+
+ sprintf(name, "/proc/%d/statm", pid);
+ FILE* in = fopen(name, "rb");
+ if (in == NULL) return 0;
+
+ for (; field >= 0; field--)
+ if (fscanf(in, "%d", &value) != 1)
+ printf("ERROR! Failed to parse memory statistics from \"/proc\".\n"), exit(1);
+ fclose(in);
+ return value;
+}
+
+
+static inline int memReadPeak(void)
+{
+ char name[256];
+ pid_t pid = getpid();
+
+ sprintf(name, "/proc/%d/status", pid);
+ FILE* in = fopen(name, "rb");
+ if (in == NULL) return 0;
+
+ // Find the correct line, beginning with "VmPeak:":
+ int peak_kb = 0;
+ while (!feof(in) && fscanf(in, "VmPeak: %d kB", &peak_kb) != 1)
+ while (!feof(in) && fgetc(in) != '\n')
+ ;
+ fclose(in);
+
+ return peak_kb;
+}
+
+double Gluco2::memUsed() { return (double)memReadStat(0) * (double)getpagesize() / (1024*1024); }
+double Gluco2::memUsedPeak() {
+ double peak = memReadPeak() / 1024;
+ return peak == 0 ? memUsed() : peak; }
+
+ABC_NAMESPACE_IMPL_END
+
+#elif defined(__FreeBSD__)
+
+ABC_NAMESPACE_IMPL_START
+
+using namespace Gluco2;
+
+double Gluco2::memUsed(void) {
+ struct rusage ru;
+ getrusage(RUSAGE_SELF, &ru);
+ return (double)ru.ru_maxrss / 1024; }
+double memUsedPeak(void) { return memUsed(); }
+
+ABC_NAMESPACE_IMPL_END
+
+#elif defined(__APPLE__)
+
+#include <malloc/malloc.h>
+
+ABC_NAMESPACE_IMPL_START
+
+double Gluco2::memUsed(void) {
+ malloc_statistics_t t;
+ malloc_zone_statistics(NULL, &t);
+ return (double)t.max_size_in_use / (1024*1024); }
+
+ABC_NAMESPACE_IMPL_END
+
+#else
+
+ABC_NAMESPACE_IMPL_START
+
+double Gluco2::memUsed() {
+ return 0; }
+
+ABC_NAMESPACE_IMPL_END
+
+#endif
+
diff --git a/src/sat/glucose2/Vec.h b/src/sat/glucose2/Vec.h
new file mode 100644
index 00000000..eaeed207
--- /dev/null
+++ b/src/sat/glucose2/Vec.h
@@ -0,0 +1,152 @@
+/*******************************************************************************************[Vec.h]
+Copyright (c) 2003-2007, Niklas Een, Niklas Sorensson
+Copyright (c) 2007-2010, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#ifndef Glucose_Vec_h
+#define Glucose_Vec_h
+
+#include <assert.h>
+#include <new>
+
+#include "sat/glucose2/IntTypes.h"
+#include "sat/glucose2/XAlloc.h"
+
+ABC_NAMESPACE_CXX_HEADER_START
+
+namespace Gluco2 {
+
+//=================================================================================================
+// Automatically resizable arrays
+//
+// NOTE! Don't use this vector on datatypes that cannot be re-located in memory (with realloc)
+
+template<class T>
+class vec {
+ T* data;
+ int sz;
+ int cap;
+
+ // Don't allow copying (error prone):
+ vec<T>& operator = (vec<T>& other) { assert(0); return *this; }
+ vec (vec<T>& other) { assert(0); }
+
+ // Helpers for calculating next capacity:
+ static inline int imax (int x, int y) { int mask = (y-x) >> (sizeof(int)*8-1); return (x&mask) + (y&(~mask)); }
+ //static inline void nextCap(int& cap){ cap += ((cap >> 1) + 2) & ~1; }
+ static inline void nextCap(int& cap){ cap += ((cap >> 1) + 2) & ~1; }
+
+public:
+ // Constructors:
+ vec() : data(NULL) , sz(0) , cap(0) { }
+ explicit vec(int size) : data(NULL) , sz(0) , cap(0) { growTo(size); }
+ vec(int size, const T& pad) : data(NULL) , sz(0) , cap(0) { growTo(size, pad); }
+ ~vec() { clear(true); }
+
+ // Pointer to first element:
+ operator T* (void) { return data; }
+
+ // Size operations:
+ int size (void) const { return sz; }
+ void shrink (int nelems) { assert(nelems <= sz); for (int i = 0; i < nelems; i++) sz--, data[sz].~T(); }
+ void shrink_ (int nelems) { assert(nelems <= sz); sz -= nelems; }
+ int capacity (void) const { return cap; }
+ void capacity (int min_cap);
+ void prelocate(int ext_cap);
+ void growTo (int size);
+ void growTo_ (int size);
+ void growTo (int size, const T& pad);
+ void clear (bool dealloc = false);
+
+ // Stack interface:
+ void push (void) { if (sz == cap) capacity(sz+1); new (&data[sz]) T(); sz++; }
+ void push (const T& elem) { if (sz == cap) capacity(sz+1); data[sz++] = elem; }
+ void push_ (const T& elem) { assert(sz < cap); data[sz++] = elem; }
+ void pop (void) { assert(sz > 0); sz--, data[sz].~T(); }
+ // NOTE: it seems possible that overflow can happen in the 'sz+1' expression of 'push()', but
+ // in fact it can not since it requires that 'cap' is equal to INT_MAX. This in turn can not
+ // happen given the way capacities are calculated (below). Essentially, all capacities are
+ // even, but INT_MAX is odd.
+
+ const T& last (void) const { return data[sz-1]; }
+ T& last (void) { return data[sz-1]; }
+
+ // Vector interface:
+ const T& operator [] (int index) const { return data[index]; }
+ T& operator [] (int index) { return data[index]; }
+
+ // Duplicatation (preferred instead):
+ void copyTo (vec<T>& copy) const { copy.clear(); copy.growTo(sz); for (int i = 0; i < sz; i++) copy[i] = data[i]; }
+ void copyTo_(vec<T>& copy) const { copy.shrink_(copy.size()); copy.growTo_(sz); for (int i = 0; i < sz; i++) copy[i] = data[i]; }
+ void moveTo(vec<T>& dest) { dest.clear(true); dest.data = data; dest.sz = sz; dest.cap = cap; data = NULL; sz = 0; cap = 0; }
+};
+
+
+template<class T>
+void vec<T>::capacity(int min_cap) {
+ if (cap >= min_cap) return;
+ int add = imax((min_cap - cap + 1) & ~1, ((cap >> 1) + 2) & ~1); // NOTE: grow by approximately 3/2
+ if (add > INT_MAX - cap || (((data = (T*)::realloc(data, (cap += add) * sizeof(T))) == NULL) && errno == ENOMEM))
+ throw OutOfMemoryException();
+ }
+
+template<class T>
+void vec<T>::prelocate(int ext_cap) {
+ if (cap >= ext_cap) return;
+ if (ext_cap > INT_MAX || (((data = (T*)::realloc(data, ext_cap * sizeof(T))) == NULL) && errno == ENOMEM))
+ throw OutOfMemoryException();
+ cap = ext_cap;
+ }
+
+
+template<class T>
+void vec<T>::growTo(int size, const T& pad) {
+ if (sz >= size) return;
+ capacity(size);
+ for (int i = sz; i < size; i++) data[i] = pad;
+ sz = size; }
+
+
+template<class T>
+void vec<T>::growTo(int size) {
+ if (sz >= size) return;
+ capacity(size);
+ for (int i = sz; i < size; i++) new (&data[i]) T();
+ sz = size; }
+
+
+template<class T>
+void vec<T>::growTo_(int size) {
+ if (sz >= size) return;
+ capacity(size);
+ sz = size; }
+
+
+template<class T>
+void vec<T>::clear(bool dealloc) {
+ if (data != NULL){
+ for (int i = 0; i < sz; i++) data[i].~T();
+ sz = 0;
+ if (dealloc) free(data), data = NULL, cap = 0; } }
+
+//=================================================================================================
+}
+
+ABC_NAMESPACE_CXX_HEADER_END
+
+#endif
diff --git a/src/sat/glucose2/XAlloc.h b/src/sat/glucose2/XAlloc.h
new file mode 100644
index 00000000..716643ef
--- /dev/null
+++ b/src/sat/glucose2/XAlloc.h
@@ -0,0 +1,53 @@
+/****************************************************************************************[XAlloc.h]
+Copyright (c) 2009-2010, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+
+#ifndef Glucose_XAlloc_h
+#define Glucose_XAlloc_h
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <misc/util/abc_namespaces.h>
+
+ABC_NAMESPACE_CXX_HEADER_START
+
+namespace Gluco2 {
+
+//=================================================================================================
+// Simple layer on top of malloc/realloc to catch out-of-memory situtaions and provide some typing:
+
+class OutOfMemoryException{};
+static inline void* xrealloc(void *ptr, size_t size)
+{
+ void* mem = realloc(ptr, size);
+ if (mem == NULL && errno == ENOMEM){
+ throw OutOfMemoryException();
+ }else {
+ return mem;
+ }
+}
+
+//=================================================================================================
+}
+
+ABC_NAMESPACE_CXX_HEADER_END
+
+#endif
diff --git a/src/sat/glucose2/license b/src/sat/glucose2/license
new file mode 100644
index 00000000..04ed174b
--- /dev/null
+++ b/src/sat/glucose2/license
@@ -0,0 +1,32 @@
+---------------
+
+Glucose -- Copyright (c) 2013, Gilles Audemard, Laurent Simon
+ CRIL - Univ. Artois, France
+ LRI - Univ. Paris Sud, France
+
+Glucose sources are based on MiniSat (see below MiniSat copyrights). Permissions
+and copyrights of Glucose are exactly the same as Minisat on which it is based
+on. (see below).
+
+---------------
+
+Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
+Copyright (c) 2007-2010, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/ \ No newline at end of file
diff --git a/src/sat/glucose2/module.make b/src/sat/glucose2/module.make
new file mode 100644
index 00000000..c23cdc53
--- /dev/null
+++ b/src/sat/glucose2/module.make
@@ -0,0 +1,6 @@
+SRC += src/sat/glucose2/AbcGlucose2.cpp \
+ src/sat/glucose2/AbcGlucoseCmd2.cpp \
+ src/sat/glucose2/Glucose2.cpp \
+ src/sat/glucose2/Options2.cpp \
+ src/sat/glucose2/SimpSolver2.cpp \
+ src/sat/glucose2/System2.cpp
diff --git a/src/sat/glucose2/pstdint.h b/src/sat/glucose2/pstdint.h
new file mode 100644
index 00000000..989d0169
--- /dev/null
+++ b/src/sat/glucose2/pstdint.h
@@ -0,0 +1,919 @@
+/* A portable stdint.h
+ ****************************************************************************
+ * BSD License:
+ ****************************************************************************
+ *
+ * Copyright (c) 2005-2016 Paul Hsieh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************
+ *
+ * Version 0.1.16.0
+ *
+ * The ANSI C standard committee, for the C99 standard, specified the
+ * inclusion of a new standard include file called stdint.h. This is
+ * a very useful and long desired include file which contains several
+ * very precise definitions for integer scalar types that is critically
+ * important for making several classes of applications portable
+ * including cryptography, hashing, variable length integer libraries
+ * and so on. But for most developers its likely useful just for
+ * programming sanity.
+ *
+ * The problem is that some compiler vendors chose to ignore the C99
+ * standard and some older compilers have no opportunity to be updated.
+ * Because of this situation, simply including stdint.h in your code
+ * makes it unportable.
+ *
+ * So that's what this file is all about. It's an attempt to build a
+ * single universal include file that works on as many platforms as
+ * possible to deliver what stdint.h is supposed to. Even compilers
+ * that already come with stdint.h can use this file instead without
+ * any loss of functionality. A few things that should be noted about
+ * this file:
+ *
+ * 1) It is not guaranteed to be portable and/or present an identical
+ * interface on all platforms. The extreme variability of the
+ * ANSI C standard makes this an impossibility right from the
+ * very get go. Its really only meant to be useful for the vast
+ * majority of platforms that possess the capability of
+ * implementing usefully and precisely defined, standard sized
+ * integer scalars. Systems which are not intrinsically 2s
+ * complement may produce invalid constants.
+ *
+ * 2) There is an unavoidable use of non-reserved symbols.
+ *
+ * 3) Other standard include files are invoked.
+ *
+ * 4) This file may come in conflict with future platforms that do
+ * include stdint.h. The hope is that one or the other can be
+ * used with no real difference.
+ *
+ * 5) In the current version, if your platform can't represent
+ * int32_t, int16_t and int8_t, it just dumps out with a compiler
+ * error.
+ *
+ * 6) 64 bit integers may or may not be defined. Test for their
+ * presence with the test: #ifdef INT64_MAX or #ifdef UINT64_MAX.
+ * Note that this is different from the C99 specification which
+ * requires the existence of 64 bit support in the compiler. If
+ * this is not defined for your platform, yet it is capable of
+ * dealing with 64 bits then it is because this file has not yet
+ * been extended to cover all of your system's capabilities.
+ *
+ * 7) (u)intptr_t may or may not be defined. Test for its presence
+ * with the test: #ifdef PTRDIFF_MAX. If this is not defined
+ * for your platform, then it is because this file has not yet
+ * been extended to cover all of your system's capabilities, not
+ * because its optional.
+ *
+ * 8) The following might not been defined even if your platform is
+ * capable of defining it:
+ *
+ * WCHAR_MIN
+ * WCHAR_MAX
+ * (u)int64_t
+ * PTRDIFF_MIN
+ * PTRDIFF_MAX
+ * (u)intptr_t
+ *
+ * 9) The following have not been defined:
+ *
+ * WINT_MIN
+ * WINT_MAX
+ *
+ * 10) The criteria for defining (u)int_least(*)_t isn't clear,
+ * except for systems which don't have a type that precisely
+ * defined 8, 16, or 32 bit types (which this include file does
+ * not support anyways). Default definitions have been given.
+ *
+ * 11) The criteria for defining (u)int_fast(*)_t isn't something I
+ * would trust to any particular compiler vendor or the ANSI C
+ * committee. It is well known that "compatible systems" are
+ * commonly created that have very different performance
+ * characteristics from the systems they are compatible with,
+ * especially those whose vendors make both the compiler and the
+ * system. Default definitions have been given, but its strongly
+ * recommended that users never use these definitions for any
+ * reason (they do *NOT* deliver any serious guarantee of
+ * improved performance -- not in this file, nor any vendor's
+ * stdint.h).
+ *
+ * 12) The following macros:
+ *
+ * PRINTF_INTMAX_MODIFIER
+ * PRINTF_INT64_MODIFIER
+ * PRINTF_INT32_MODIFIER
+ * PRINTF_INT16_MODIFIER
+ * PRINTF_LEAST64_MODIFIER
+ * PRINTF_LEAST32_MODIFIER
+ * PRINTF_LEAST16_MODIFIER
+ * PRINTF_INTPTR_MODIFIER
+ *
+ * are strings which have been defined as the modifiers required
+ * for the "d", "u" and "x" printf formats to correctly output
+ * (u)intmax_t, (u)int64_t, (u)int32_t, (u)int16_t, (u)least64_t,
+ * (u)least32_t, (u)least16_t and (u)intptr_t types respectively.
+ * PRINTF_INTPTR_MODIFIER is not defined for some systems which
+ * provide their own stdint.h. PRINTF_INT64_MODIFIER is not
+ * defined if INT64_MAX is not defined. These are an extension
+ * beyond what C99 specifies must be in stdint.h.
+ *
+ * In addition, the following macros are defined:
+ *
+ * PRINTF_INTMAX_HEX_WIDTH
+ * PRINTF_INT64_HEX_WIDTH
+ * PRINTF_INT32_HEX_WIDTH
+ * PRINTF_INT16_HEX_WIDTH
+ * PRINTF_INT8_HEX_WIDTH
+ * PRINTF_INTMAX_DEC_WIDTH
+ * PRINTF_INT64_DEC_WIDTH
+ * PRINTF_INT32_DEC_WIDTH
+ * PRINTF_INT16_DEC_WIDTH
+ * PRINTF_UINT8_DEC_WIDTH
+ * PRINTF_UINTMAX_DEC_WIDTH
+ * PRINTF_UINT64_DEC_WIDTH
+ * PRINTF_UINT32_DEC_WIDTH
+ * PRINTF_UINT16_DEC_WIDTH
+ * PRINTF_UINT8_DEC_WIDTH
+ *
+ * Which specifies the maximum number of characters required to
+ * print the number of that type in either hexadecimal or decimal.
+ * These are an extension beyond what C99 specifies must be in
+ * stdint.h.
+ *
+ * Compilers tested (all with 0 warnings at their highest respective
+ * settings): Borland Turbo C 2.0, WATCOM C/C++ 11.0 (16 bits and 32
+ * bits), Microsoft Visual C++ 6.0 (32 bit), Microsoft Visual Studio
+ * .net (VC7), Intel C++ 4.0, GNU gcc v3.3.3
+ *
+ * This file should be considered a work in progress. Suggestions for
+ * improvements, especially those which increase coverage are strongly
+ * encouraged.
+ *
+ * Acknowledgements
+ *
+ * The following people have made significant contributions to the
+ * development and testing of this file:
+ *
+ * Chris Howie
+ * John Steele Scott
+ * Dave Thorup
+ * John Dill
+ * Florian Wobbe
+ * Christopher Sean Morrison
+ * Mikkel Fahnoe Jorgensen
+ *
+ */
+
+#include <stddef.h>
+#include <limits.h>
+#include <signal.h>
+
+/*
+ * For gcc with _STDINT_H, fill in the PRINTF_INT*_MODIFIER macros, and
+ * do nothing else. On the Mac OS X version of gcc this is _STDINT_H_.
+ */
+
+#if ((defined(__SUNPRO_C) && __SUNPRO_C >= 0x570) || (defined(_MSC_VER) && _MSC_VER >= 1600) || (defined(__STDC__) && __STDC__ && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (__GNUC__ > 3 || defined(_STDINT_H) || defined(_STDINT_H_) || defined (__UINT_FAST64_TYPE__)) )) && !defined (_PSTDINT_H_INCLUDED)
+#include <stdint.h>
+#define _PSTDINT_H_INCLUDED
+# if defined(__GNUC__) && (defined(__x86_64__) || defined(__ppc64__)) && !(defined(__APPLE__) && defined(__MACH__))
+# ifndef PRINTF_INT64_MODIFIER
+# define PRINTF_INT64_MODIFIER "l"
+# endif
+# ifndef PRINTF_INT32_MODIFIER
+# define PRINTF_INT32_MODIFIER ""
+# endif
+# else
+# ifndef PRINTF_INT64_MODIFIER
+# define PRINTF_INT64_MODIFIER "ll"
+# endif
+# ifndef PRINTF_INT32_MODIFIER
+# if (UINT_MAX == UINT32_MAX)
+# define PRINTF_INT32_MODIFIER ""
+# else
+# define PRINTF_INT32_MODIFIER "l"
+# endif
+# endif
+# endif
+# ifndef PRINTF_INT16_MODIFIER
+# define PRINTF_INT16_MODIFIER "h"
+# endif
+# ifndef PRINTF_INTMAX_MODIFIER
+# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
+# endif
+# ifndef PRINTF_INT64_HEX_WIDTH
+# define PRINTF_INT64_HEX_WIDTH "16"
+# endif
+# ifndef PRINTF_UINT64_HEX_WIDTH
+# define PRINTF_UINT64_HEX_WIDTH "16"
+# endif
+# ifndef PRINTF_INT32_HEX_WIDTH
+# define PRINTF_INT32_HEX_WIDTH "8"
+# endif
+# ifndef PRINTF_UINT32_HEX_WIDTH
+# define PRINTF_UINT32_HEX_WIDTH "8"
+# endif
+# ifndef PRINTF_INT16_HEX_WIDTH
+# define PRINTF_INT16_HEX_WIDTH "4"
+# endif
+# ifndef PRINTF_UINT16_HEX_WIDTH
+# define PRINTF_UINT16_HEX_WIDTH "4"
+# endif
+# ifndef PRINTF_INT8_HEX_WIDTH
+# define PRINTF_INT8_HEX_WIDTH "2"
+# endif
+# ifndef PRINTF_UINT8_HEX_WIDTH
+# define PRINTF_UINT8_HEX_WIDTH "2"
+# endif
+# ifndef PRINTF_INT64_DEC_WIDTH
+# define PRINTF_INT64_DEC_WIDTH "19"
+# endif
+# ifndef PRINTF_UINT64_DEC_WIDTH
+# define PRINTF_UINT64_DEC_WIDTH "20"
+# endif
+# ifndef PRINTF_INT32_DEC_WIDTH
+# define PRINTF_INT32_DEC_WIDTH "10"
+# endif
+# ifndef PRINTF_UINT32_DEC_WIDTH
+# define PRINTF_UINT32_DEC_WIDTH "10"
+# endif
+# ifndef PRINTF_INT16_DEC_WIDTH
+# define PRINTF_INT16_DEC_WIDTH "5"
+# endif
+# ifndef PRINTF_UINT16_DEC_WIDTH
+# define PRINTF_UINT16_DEC_WIDTH "5"
+# endif
+# ifndef PRINTF_INT8_DEC_WIDTH
+# define PRINTF_INT8_DEC_WIDTH "3"
+# endif
+# ifndef PRINTF_UINT8_DEC_WIDTH
+# define PRINTF_UINT8_DEC_WIDTH "3"
+# endif
+# ifndef PRINTF_INTMAX_HEX_WIDTH
+# define PRINTF_INTMAX_HEX_WIDTH PRINTF_UINT64_HEX_WIDTH
+# endif
+# ifndef PRINTF_UINTMAX_HEX_WIDTH
+# define PRINTF_UINTMAX_HEX_WIDTH PRINTF_UINT64_HEX_WIDTH
+# endif
+# ifndef PRINTF_INTMAX_DEC_WIDTH
+# define PRINTF_INTMAX_DEC_WIDTH PRINTF_UINT64_DEC_WIDTH
+# endif
+# ifndef PRINTF_UINTMAX_DEC_WIDTH
+# define PRINTF_UINTMAX_DEC_WIDTH PRINTF_UINT64_DEC_WIDTH
+# endif
+
+/*
+ * Something really weird is going on with Open Watcom. Just pull some of
+ * these duplicated definitions from Open Watcom's stdint.h file for now.
+ */
+
+# if defined (__WATCOMC__) && __WATCOMC__ >= 1250
+# if !defined (INT64_C)
+# define INT64_C(x) (x + (INT64_MAX - INT64_MAX))
+# endif
+# if !defined (UINT64_C)
+# define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX))
+# endif
+# if !defined (INT32_C)
+# define INT32_C(x) (x + (INT32_MAX - INT32_MAX))
+# endif
+# if !defined (UINT32_C)
+# define UINT32_C(x) (x + (UINT32_MAX - UINT32_MAX))
+# endif
+# if !defined (INT16_C)
+# define INT16_C(x) (x)
+# endif
+# if !defined (UINT16_C)
+# define UINT16_C(x) (x)
+# endif
+# if !defined (INT8_C)
+# define INT8_C(x) (x)
+# endif
+# if !defined (UINT8_C)
+# define UINT8_C(x) (x)
+# endif
+# if !defined (UINT64_MAX)
+# define UINT64_MAX 18446744073709551615ULL
+# endif
+# if !defined (INT64_MAX)
+# define INT64_MAX 9223372036854775807LL
+# endif
+# if !defined (UINT32_MAX)
+# define UINT32_MAX 4294967295UL
+# endif
+# if !defined (INT32_MAX)
+# define INT32_MAX 2147483647L
+# endif
+# if !defined (INTMAX_MAX)
+# define INTMAX_MAX INT64_MAX
+# endif
+# if !defined (INTMAX_MIN)
+# define INTMAX_MIN INT64_MIN
+# endif
+# endif
+#endif
+
+/*
+ * I have no idea what is the truly correct thing to do on older Solaris.
+ * From some online discussions, this seems to be what is being
+ * recommended. For people who actually are developing on older Solaris,
+ * what I would like to know is, does this define all of the relevant
+ * macros of a complete stdint.h? Remember, in pstdint.h 64 bit is
+ * considered optional.
+ */
+
+#if (defined(__SUNPRO_C) && __SUNPRO_C >= 0x420) && !defined(_PSTDINT_H_INCLUDED)
+#include <sys/inttypes.h>
+#define _PSTDINT_H_INCLUDED
+#endif
+
+#ifndef _PSTDINT_H_INCLUDED
+#define _PSTDINT_H_INCLUDED
+
+#ifndef SIZE_MAX
+# define SIZE_MAX ((size_t)-1)
+#endif
+
+/*
+ * Deduce the type assignments from limits.h under the assumption that
+ * integer sizes in bits are powers of 2, and follow the ANSI
+ * definitions.
+ */
+
+#ifndef UINT8_MAX
+# define UINT8_MAX 0xff
+#endif
+#if !defined(uint8_t) && !defined(_UINT8_T) && !defined(vxWorks)
+# if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S)
+ typedef unsigned char uint8_t;
+# define UINT8_C(v) ((uint8_t) v)
+# else
+# error "Platform not supported"
+# endif
+#endif
+
+#ifndef INT8_MAX
+# define INT8_MAX 0x7f
+#endif
+#ifndef INT8_MIN
+# define INT8_MIN INT8_C(0x80)
+#endif
+#if !defined(int8_t) && !defined(_INT8_T) && !defined(vxWorks)
+# if (SCHAR_MAX == INT8_MAX) || defined (S_SPLINT_S)
+ typedef signed char int8_t;
+# define INT8_C(v) ((int8_t) v)
+# else
+# error "Platform not supported"
+# endif
+#endif
+
+#ifndef UINT16_MAX
+# define UINT16_MAX 0xffff
+#endif
+#if !defined(uint16_t) && !defined(_UINT16_T) && !defined(vxWorks)
+#if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S)
+ typedef unsigned int uint16_t;
+# ifndef PRINTF_INT16_MODIFIER
+# define PRINTF_INT16_MODIFIER ""
+# endif
+# define UINT16_C(v) ((uint16_t) (v))
+#elif (USHRT_MAX == UINT16_MAX)
+ typedef unsigned short uint16_t;
+# define UINT16_C(v) ((uint16_t) (v))
+# ifndef PRINTF_INT16_MODIFIER
+# define PRINTF_INT16_MODIFIER "h"
+# endif
+#else
+#error "Platform not supported"
+#endif
+#endif
+
+#ifndef INT16_MAX
+# define INT16_MAX 0x7fff
+#endif
+#ifndef INT16_MIN
+# define INT16_MIN INT16_C(0x8000)
+#endif
+#if !defined(int16_t) && !defined(_INT16_T) && !defined(vxWorks)
+#if (INT_MAX == INT16_MAX) || defined (S_SPLINT_S)
+ typedef signed int int16_t;
+# define INT16_C(v) ((int16_t) (v))
+# ifndef PRINTF_INT16_MODIFIER
+# define PRINTF_INT16_MODIFIER ""
+# endif
+#elif (SHRT_MAX == INT16_MAX)
+ typedef signed short int16_t;
+# define INT16_C(v) ((int16_t) (v))
+# ifndef PRINTF_INT16_MODIFIER
+# define PRINTF_INT16_MODIFIER "h"
+# endif
+#else
+#error "Platform not supported"
+#endif
+#endif
+
+#ifndef UINT32_MAX
+# define UINT32_MAX (0xffffffffUL)
+#endif
+#if !defined(uint32_t) && !defined(_UINT32_T) && !defined(vxWorks)
+#if (ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S)
+ typedef unsigned long uint32_t;
+# define UINT32_C(v) v ## UL
+# ifndef PRINTF_INT32_MODIFIER
+# define PRINTF_INT32_MODIFIER "l"
+# endif
+#elif (UINT_MAX == UINT32_MAX)
+ typedef unsigned int uint32_t;
+# ifndef PRINTF_INT32_MODIFIER
+# define PRINTF_INT32_MODIFIER ""
+# endif
+# define UINT32_C(v) v ## U
+#elif (USHRT_MAX == UINT32_MAX)
+ typedef unsigned short uint32_t;
+# define UINT32_C(v) ((unsigned short) (v))
+# ifndef PRINTF_INT32_MODIFIER
+# define PRINTF_INT32_MODIFIER ""
+# endif
+#else
+#error "Platform not supported"
+#endif
+#endif
+
+#ifndef INT32_MAX
+# define INT32_MAX (0x7fffffffL)
+#endif
+#ifndef INT32_MIN
+# define INT32_MIN INT32_C(0x80000000)
+#endif
+#if !defined(int32_t) && !defined(_INT32_T) && !defined(vxWorks)
+#if (LONG_MAX == INT32_MAX) || defined (S_SPLINT_S)
+ typedef signed long int32_t;
+# define INT32_C(v) v ## L
+# ifndef PRINTF_INT32_MODIFIER
+# define PRINTF_INT32_MODIFIER "l"
+# endif
+#elif (INT_MAX == INT32_MAX)
+ typedef signed int int32_t;
+# define INT32_C(v) v
+# ifndef PRINTF_INT32_MODIFIER
+# define PRINTF_INT32_MODIFIER ""
+# endif
+#elif (SHRT_MAX == INT32_MAX)
+ typedef signed short int32_t;
+# define INT32_C(v) ((short) (v))
+# ifndef PRINTF_INT32_MODIFIER
+# define PRINTF_INT32_MODIFIER ""
+# endif
+#else
+#error "Platform not supported"
+#endif
+#endif
+
+/*
+ * The macro stdint_int64_defined is temporarily used to record
+ * whether or not 64 integer support is available. It must be
+ * defined for any 64 integer extensions for new platforms that are
+ * added.
+ */
+
+#undef stdint_int64_defined
+#if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S)
+# if (__STDC__ && __STDC_VERSION__ >= 199901L) || defined (S_SPLINT_S)
+# define stdint_int64_defined
+ typedef long long int64_t;
+ typedef unsigned long long uint64_t;
+# define UINT64_C(v) v ## ULL
+# define INT64_C(v) v ## LL
+# ifndef PRINTF_INT64_MODIFIER
+# define PRINTF_INT64_MODIFIER "ll"
+# endif
+# endif
+#endif
+
+#if !defined (stdint_int64_defined)
+# if defined(__GNUC__) && !defined(vxWorks)
+# define stdint_int64_defined
+ __extension__ typedef long long int64_t;
+ __extension__ typedef unsigned long long uint64_t;
+# define UINT64_C(v) v ## ULL
+# define INT64_C(v) v ## LL
+# ifndef PRINTF_INT64_MODIFIER
+# define PRINTF_INT64_MODIFIER "ll"
+# endif
+# elif defined(__MWERKS__) || defined (__SUNPRO_C) || defined (__SUNPRO_CC) || defined (__APPLE_CC__) || defined (_LONG_LONG) || defined (_CRAYC) || defined (S_SPLINT_S)
+# define stdint_int64_defined
+ typedef long long int64_t;
+ typedef unsigned long long uint64_t;
+# define UINT64_C(v) v ## ULL
+# define INT64_C(v) v ## LL
+# ifndef PRINTF_INT64_MODIFIER
+# define PRINTF_INT64_MODIFIER "ll"
+# endif
+# elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined (__BORLANDC__) && __BORLANDC__ > 0x460) || defined (__alpha) || defined (__DECC)
+# define stdint_int64_defined
+ typedef __int64 int64_t;
+ typedef unsigned __int64 uint64_t;
+# define UINT64_C(v) v ## UI64
+# define INT64_C(v) v ## I64
+# ifndef PRINTF_INT64_MODIFIER
+# define PRINTF_INT64_MODIFIER "I64"
+# endif
+# endif
+#endif
+
+#if !defined (LONG_LONG_MAX) && defined (INT64_C)
+# define LONG_LONG_MAX INT64_C (9223372036854775807)
+#endif
+#ifndef ULONG_LONG_MAX
+# define ULONG_LONG_MAX UINT64_C (18446744073709551615)
+#endif
+
+#if !defined (INT64_MAX) && defined (INT64_C)
+# define INT64_MAX INT64_C (9223372036854775807)
+#endif
+#if !defined (INT64_MIN) && defined (INT64_C)
+# define INT64_MIN INT64_C (-9223372036854775808)
+#endif
+#if !defined (UINT64_MAX) && defined (INT64_C)
+# define UINT64_MAX UINT64_C (18446744073709551615)
+#endif
+
+/*
+ * Width of hexadecimal for number field.
+ */
+
+#ifndef PRINTF_INT64_HEX_WIDTH
+# define PRINTF_INT64_HEX_WIDTH "16"
+#endif
+#ifndef PRINTF_INT32_HEX_WIDTH
+# define PRINTF_INT32_HEX_WIDTH "8"
+#endif
+#ifndef PRINTF_INT16_HEX_WIDTH
+# define PRINTF_INT16_HEX_WIDTH "4"
+#endif
+#ifndef PRINTF_INT8_HEX_WIDTH
+# define PRINTF_INT8_HEX_WIDTH "2"
+#endif
+#ifndef PRINTF_INT64_DEC_WIDTH
+# define PRINTF_INT64_DEC_WIDTH "19"
+#endif
+#ifndef PRINTF_INT32_DEC_WIDTH
+# define PRINTF_INT32_DEC_WIDTH "10"
+#endif
+#ifndef PRINTF_INT16_DEC_WIDTH
+# define PRINTF_INT16_DEC_WIDTH "5"
+#endif
+#ifndef PRINTF_INT8_DEC_WIDTH
+# define PRINTF_INT8_DEC_WIDTH "3"
+#endif
+#ifndef PRINTF_UINT64_DEC_WIDTH
+# define PRINTF_UINT64_DEC_WIDTH "20"
+#endif
+#ifndef PRINTF_UINT32_DEC_WIDTH
+# define PRINTF_UINT32_DEC_WIDTH "10"
+#endif
+#ifndef PRINTF_UINT16_DEC_WIDTH
+# define PRINTF_UINT16_DEC_WIDTH "5"
+#endif
+#ifndef PRINTF_UINT8_DEC_WIDTH
+# define PRINTF_UINT8_DEC_WIDTH "3"
+#endif
+
+/*
+ * Ok, lets not worry about 128 bit integers for now. Moore's law says
+ * we don't need to worry about that until about 2040 at which point
+ * we'll have bigger things to worry about.
+ */
+
+#ifdef stdint_int64_defined
+ typedef int64_t intmax_t;
+ typedef uint64_t uintmax_t;
+# define INTMAX_MAX INT64_MAX
+# define INTMAX_MIN INT64_MIN
+# define UINTMAX_MAX UINT64_MAX
+# define UINTMAX_C(v) UINT64_C(v)
+# define INTMAX_C(v) INT64_C(v)
+# ifndef PRINTF_INTMAX_MODIFIER
+# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
+# endif
+# ifndef PRINTF_INTMAX_HEX_WIDTH
+# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH
+# endif
+# ifndef PRINTF_INTMAX_DEC_WIDTH
+# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH
+# endif
+#else
+ typedef int32_t intmax_t;
+ typedef uint32_t uintmax_t;
+# define INTMAX_MAX INT32_MAX
+# define UINTMAX_MAX UINT32_MAX
+# define UINTMAX_C(v) UINT32_C(v)
+# define INTMAX_C(v) INT32_C(v)
+# ifndef PRINTF_INTMAX_MODIFIER
+# define PRINTF_INTMAX_MODIFIER PRINTF_INT32_MODIFIER
+# endif
+# ifndef PRINTF_INTMAX_HEX_WIDTH
+# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT32_HEX_WIDTH
+# endif
+# ifndef PRINTF_INTMAX_DEC_WIDTH
+# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT32_DEC_WIDTH
+# endif
+#endif
+
+/*
+ * Because this file currently only supports platforms which have
+ * precise powers of 2 as bit sizes for the default integers, the
+ * least definitions are all trivial. Its possible that a future
+ * version of this file could have different definitions.
+ */
+
+#ifndef stdint_least_defined
+ typedef int8_t int_least8_t;
+ typedef uint8_t uint_least8_t;
+ typedef int16_t int_least16_t;
+ typedef uint16_t uint_least16_t;
+ typedef int32_t int_least32_t;
+ typedef uint32_t uint_least32_t;
+# define PRINTF_LEAST32_MODIFIER PRINTF_INT32_MODIFIER
+# define PRINTF_LEAST16_MODIFIER PRINTF_INT16_MODIFIER
+# define UINT_LEAST8_MAX UINT8_MAX
+# define INT_LEAST8_MAX INT8_MAX
+# define UINT_LEAST16_MAX UINT16_MAX
+# define INT_LEAST16_MAX INT16_MAX
+# define UINT_LEAST32_MAX UINT32_MAX
+# define INT_LEAST32_MAX INT32_MAX
+# define INT_LEAST8_MIN INT8_MIN
+# define INT_LEAST16_MIN INT16_MIN
+# define INT_LEAST32_MIN INT32_MIN
+# ifdef stdint_int64_defined
+ typedef int64_t int_least64_t;
+ typedef uint64_t uint_least64_t;
+# define PRINTF_LEAST64_MODIFIER PRINTF_INT64_MODIFIER
+# define UINT_LEAST64_MAX UINT64_MAX
+# define INT_LEAST64_MAX INT64_MAX
+# define INT_LEAST64_MIN INT64_MIN
+# endif
+#endif
+#undef stdint_least_defined
+
+/*
+ * The ANSI C committee has defined *int*_fast*_t types as well. This,
+ * of course, defies rationality -- you can't know what will be fast
+ * just from the type itself. Even for a given architecture, compatible
+ * implementations might have different performance characteristics.
+ * Developers are warned to stay away from these types when using this
+ * or any other stdint.h.
+ */
+
+typedef int_least8_t int_fast8_t;
+typedef uint_least8_t uint_fast8_t;
+typedef int_least16_t int_fast16_t;
+typedef uint_least16_t uint_fast16_t;
+typedef int_least32_t int_fast32_t;
+typedef uint_least32_t uint_fast32_t;
+#define UINT_FAST8_MAX UINT_LEAST8_MAX
+#define INT_FAST8_MAX INT_LEAST8_MAX
+#define UINT_FAST16_MAX UINT_LEAST16_MAX
+#define INT_FAST16_MAX INT_LEAST16_MAX
+#define UINT_FAST32_MAX UINT_LEAST32_MAX
+#define INT_FAST32_MAX INT_LEAST32_MAX
+#define INT_FAST8_MIN INT_LEAST8_MIN
+#define INT_FAST16_MIN INT_LEAST16_MIN
+#define INT_FAST32_MIN INT_LEAST32_MIN
+#ifdef stdint_int64_defined
+ typedef int_least64_t int_fast64_t;
+ typedef uint_least64_t uint_fast64_t;
+# define UINT_FAST64_MAX UINT_LEAST64_MAX
+# define INT_FAST64_MAX INT_LEAST64_MAX
+# define INT_FAST64_MIN INT_LEAST64_MIN
+#endif
+
+#undef stdint_int64_defined
+
+/*
+ * Whatever piecemeal, per compiler thing we can do about the wchar_t
+ * type limits.
+ */
+
+#if defined(__WATCOMC__) || defined(_MSC_VER) || defined (__GNUC__) && !defined(vxWorks)
+# include <wchar.h>
+# ifndef WCHAR_MIN
+# define WCHAR_MIN 0
+# endif
+# ifndef WCHAR_MAX
+# define WCHAR_MAX ((wchar_t)-1)
+# endif
+#endif
+
+/*
+ * Whatever piecemeal, per compiler/platform thing we can do about the
+ * (u)intptr_t types and limits.
+ */
+
+#if (defined (_MSC_VER) && defined (_UINTPTR_T_DEFINED)) || defined (_UINTPTR_T)
+# define STDINT_H_UINTPTR_T_DEFINED
+#endif
+
+#ifndef STDINT_H_UINTPTR_T_DEFINED
+# if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (_WIN64) || defined (__ppc64__)
+# define stdint_intptr_bits 64
+# elif defined (__WATCOMC__) || defined (__TURBOC__)
+# if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__)
+# define stdint_intptr_bits 16
+# else
+# define stdint_intptr_bits 32
+# endif
+# elif defined (__i386__) || defined (_WIN32) || defined (WIN32) || defined (__ppc64__)
+# define stdint_intptr_bits 32
+# elif defined (__INTEL_COMPILER)
+/* TODO -- what did Intel do about x86-64? */
+# else
+/* #error "This platform might not be supported yet" */
+# endif
+
+# ifdef stdint_intptr_bits
+# define stdint_intptr_glue3_i(a,b,c) a##b##c
+# define stdint_intptr_glue3(a,b,c) stdint_intptr_glue3_i(a,b,c)
+# ifndef PRINTF_INTPTR_MODIFIER
+# define PRINTF_INTPTR_MODIFIER stdint_intptr_glue3(PRINTF_INT,stdint_intptr_bits,_MODIFIER)
+# endif
+# ifndef PTRDIFF_MAX
+# define PTRDIFF_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
+# endif
+# ifndef PTRDIFF_MIN
+# define PTRDIFF_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
+# endif
+# ifndef UINTPTR_MAX
+# define UINTPTR_MAX stdint_intptr_glue3(UINT,stdint_intptr_bits,_MAX)
+# endif
+# ifndef INTPTR_MAX
+# define INTPTR_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
+# endif
+# ifndef INTPTR_MIN
+# define INTPTR_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
+# endif
+# ifndef INTPTR_C
+# define INTPTR_C(x) stdint_intptr_glue3(INT,stdint_intptr_bits,_C)(x)
+# endif
+# ifndef UINTPTR_C
+# define UINTPTR_C(x) stdint_intptr_glue3(UINT,stdint_intptr_bits,_C)(x)
+# endif
+ typedef stdint_intptr_glue3(uint,stdint_intptr_bits,_t) uintptr_t;
+ typedef stdint_intptr_glue3( int,stdint_intptr_bits,_t) intptr_t;
+# else
+/* TODO -- This following is likely wrong for some platforms, and does
+ nothing for the definition of uintptr_t. */
+ typedef ptrdiff_t intptr_t;
+# endif
+# define STDINT_H_UINTPTR_T_DEFINED
+#endif
+
+/*
+ * Assumes sig_atomic_t is signed and we have a 2s complement machine.
+ */
+
+#ifndef SIG_ATOMIC_MAX
+# define SIG_ATOMIC_MAX ((((sig_atomic_t) 1) << (sizeof (sig_atomic_t)*CHAR_BIT-1)) - 1)
+#endif
+
+#endif
+
+#if defined (__TEST_PSTDINT_FOR_CORRECTNESS)
+
+/*
+ * Please compile with the maximum warning settings to make sure macros are
+ * not defined more than once.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define glue3_aux(x,y,z) x ## y ## z
+#define glue3(x,y,z) glue3_aux(x,y,z)
+
+#define DECLU(bits) glue3(uint,bits,_t) glue3(u,bits,) = glue3(UINT,bits,_C) (0);
+#define DECLI(bits) glue3(int,bits,_t) glue3(i,bits,) = glue3(INT,bits,_C) (0);
+
+#define DECL(us,bits) glue3(DECL,us,) (bits)
+
+#define TESTUMAX(bits) glue3(u,bits,) = ~glue3(u,bits,); if (glue3(UINT,bits,_MAX) != glue3(u,bits,)) printf ("Something wrong with UINT%d_MAX\n", bits)
+
+#define REPORTERROR(msg) { err_n++; if (err_first <= 0) err_first = __LINE__; printf msg; }
+
+#define X_SIZE_MAX ((size_t)-1)
+
+int main () {
+ int err_n = 0;
+ int err_first = 0;
+ DECL(I,8)
+ DECL(U,8)
+ DECL(I,16)
+ DECL(U,16)
+ DECL(I,32)
+ DECL(U,32)
+#ifdef INT64_MAX
+ DECL(I,64)
+ DECL(U,64)
+#endif
+ intmax_t imax = INTMAX_C(0);
+ uintmax_t umax = UINTMAX_C(0);
+ char str0[256], str1[256];
+
+ sprintf (str0, "%" PRINTF_INT32_MODIFIER "d", INT32_C(2147483647));
+ if (0 != strcmp (str0, "2147483647")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str0));
+ if (atoi(PRINTF_INT32_DEC_WIDTH) != (int) strlen(str0)) REPORTERROR (("Something wrong with PRINTF_INT32_DEC_WIDTH : %s\n", PRINTF_INT32_DEC_WIDTH));
+ sprintf (str0, "%" PRINTF_INT32_MODIFIER "u", UINT32_C(4294967295));
+ if (0 != strcmp (str0, "4294967295")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str0));
+ if (atoi(PRINTF_UINT32_DEC_WIDTH) != (int) strlen(str0)) REPORTERROR (("Something wrong with PRINTF_UINT32_DEC_WIDTH : %s\n", PRINTF_UINT32_DEC_WIDTH));
+#ifdef INT64_MAX
+ sprintf (str1, "%" PRINTF_INT64_MODIFIER "d", INT64_C(9223372036854775807));
+ if (0 != strcmp (str1, "9223372036854775807")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str1));
+ if (atoi(PRINTF_INT64_DEC_WIDTH) != (int) strlen(str1)) REPORTERROR (("Something wrong with PRINTF_INT64_DEC_WIDTH : %s, %d\n", PRINTF_INT64_DEC_WIDTH, (int) strlen(str1)));
+ sprintf (str1, "%" PRINTF_INT64_MODIFIER "u", UINT64_C(18446744073709550591));
+ if (0 != strcmp (str1, "18446744073709550591")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str1));
+ if (atoi(PRINTF_UINT64_DEC_WIDTH) != (int) strlen(str1)) REPORTERROR (("Something wrong with PRINTF_UINT64_DEC_WIDTH : %s, %d\n", PRINTF_UINT64_DEC_WIDTH, (int) strlen(str1)));
+#endif
+
+ sprintf (str0, "%d %x\n", 0, ~0);
+
+ sprintf (str1, "%d %x\n", i8, ~0);
+ if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i8 : %s\n", str1));
+ sprintf (str1, "%u %x\n", u8, ~0);
+ if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u8 : %s\n", str1));
+ sprintf (str1, "%d %x\n", i16, ~0);
+ if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i16 : %s\n", str1));
+ sprintf (str1, "%u %x\n", u16, ~0);
+ if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u16 : %s\n", str1));
+ sprintf (str1, "%" PRINTF_INT32_MODIFIER "d %x\n", i32, ~0);
+ if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i32 : %s\n", str1));
+ sprintf (str1, "%" PRINTF_INT32_MODIFIER "u %x\n", u32, ~0);
+ if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u32 : %s\n", str1));
+#ifdef INT64_MAX
+ sprintf (str1, "%" PRINTF_INT64_MODIFIER "d %x\n", i64, ~0);
+ if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i64 : %s\n", str1));
+#endif
+ sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "d %x\n", imax, ~0);
+ if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with imax : %s\n", str1));
+ sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "u %x\n", umax, ~0);
+ if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with umax : %s\n", str1));
+
+ TESTUMAX(8);
+ TESTUMAX(16);
+ TESTUMAX(32);
+#ifdef INT64_MAX
+ TESTUMAX(64);
+#endif
+
+#define STR(v) #v
+#define Q(v) printf ("sizeof " STR(v) " = %u\n", (unsigned) sizeof (v));
+ if (err_n) {
+ printf ("pstdint.h is not correct. Please use sizes below to correct it:\n");
+ }
+
+ Q(int)
+ Q(unsigned)
+ Q(long int)
+ Q(short int)
+ Q(int8_t)
+ Q(int16_t)
+ Q(int32_t)
+#ifdef INT64_MAX
+ Q(int64_t)
+#endif
+
+#if UINT_MAX < X_SIZE_MAX
+ printf ("UINT_MAX < X_SIZE_MAX\n");
+#else
+ printf ("UINT_MAX >= X_SIZE_MAX\n");
+#endif
+ printf ("%" PRINTF_INT64_MODIFIER "u vs %" PRINTF_INT64_MODIFIER "u\n", UINT_MAX, X_SIZE_MAX);
+
+ return EXIT_SUCCESS;
+}
+
+#endif
diff --git a/src/sat/satoko/utils/sdbl.h b/src/sat/satoko/utils/sdbl.h
index 9f90ba02..a26794c7 100644
--- a/src/sat/satoko/utils/sdbl.h
+++ b/src/sat/satoko/utils/sdbl.h
@@ -121,8 +121,8 @@ static inline void sdbl_test()
{
sdbl_t ten100_ = ABC_CONST(0x014c924d692ca61b);
printf("%f\n", sdbl2double(ten100_));
- printf("%016lX\n", double2sdbl(1 /0.95));
- printf("%016lX\n", SDBL_CONST1);
+ //printf("%016lX\n", double2sdbl(1 /0.95));
+ //printf("%016lX\n", SDBL_CONST1);
printf("%f\n", sdbl2double(SDBL_CONST1));
printf("%f\n", sdbl2double(ABC_CONST(0x000086BCA1AF286B)));