summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathias Soeken <mathias.soeken@gmail.com>2017-02-22 19:00:28 -0800
committerMathias Soeken <mathias.soeken@gmail.com>2017-02-22 19:00:28 -0800
commit28e8e7f3e79d1391a2f3a31cefe3afe234aa3b8e (patch)
tree6b7962dc72653e3bf615c5901854774eca9d23c8
parent5af44731bff0061c724912cf76e86dddbb4f2c7a (diff)
parentdd8cc7e9a27e2bd962d612911c6fd9508c6c1e0d (diff)
downloadabc-28e8e7f3e79d1391a2f3a31cefe3afe234aa3b8e.tar.gz
abc-28e8e7f3e79d1391a2f3a31cefe3afe234aa3b8e.tar.bz2
abc-28e8e7f3e79d1391a2f3a31cefe3afe234aa3b8e.zip
Merged alanmi/abc into default
-rw-r--r--.hgignore5
-rw-r--r--Makefile10
-rw-r--r--abclib.dsp216
-rw-r--r--readme.md7
-rw-r--r--src/aig/aig/aigShow.c5
-rw-r--r--src/aig/gia/gia.h75
-rw-r--r--src/aig/gia/giaAig.c11
-rw-r--r--src/aig/gia/giaDup.c304
-rw-r--r--src/aig/gia/giaEquiv.c29
-rw-r--r--src/aig/gia/giaIf.c42
-rw-r--r--src/aig/gia/giaJf.c30
-rw-r--r--src/aig/gia/giaKf.c14
-rw-r--r--src/aig/gia/giaLf.c21
-rw-r--r--src/aig/gia/giaMf.c73
-rw-r--r--src/aig/gia/giaMfs.c1
-rw-r--r--src/aig/gia/giaMini.c41
-rw-r--r--src/aig/gia/giaNf.c17
-rw-r--r--src/aig/gia/giaQbf.c12
-rw-r--r--src/aig/gia/giaSatoko.c205
-rw-r--r--src/aig/gia/giaShow.c1045
-rw-r--r--src/aig/gia/giaTim.c2
-rw-r--r--src/aig/gia/giaTruth.c53
-rw-r--r--src/aig/gia/giaUtil.c4
-rw-r--r--src/aig/gia/module.make1
-rw-r--r--src/aig/ivy/ivyFraig.c2
-rw-r--r--src/aig/miniaig/abcapis.h8
-rw-r--r--src/aig/saig/saigMiter.c4
-rw-r--r--src/base/abc/abcUtil.c161
-rw-r--r--src/base/abci/abc.c1059
-rw-r--r--src/base/abci/abcCollapse.c4
-rw-r--r--src/base/abci/abcDar.c12
-rw-r--r--src/base/abci/abcDetect.c3
-rw-r--r--src/base/abci/abcDress3.c30
-rw-r--r--src/base/abci/abcExact.c2
-rw-r--r--src/base/abci/abcMfs.c2
-rw-r--r--src/base/abci/abcVerify.c14
-rw-r--r--src/base/cmd/cmd.c135
-rw-r--r--src/base/cmd/cmdAuto.c684
-rw-r--r--src/base/cmd/cmdLoad.c21
-rw-r--r--src/base/cmd/module.make1
-rw-r--r--src/base/io/io.c4
-rw-r--r--src/base/io/ioWriteDot.c4
-rw-r--r--src/base/main/mainFrame.c4
-rw-r--r--src/base/main/mainInt.h2
-rw-r--r--src/base/main/mainReal.c4
-rw-r--r--src/base/wlc/module.make3
-rw-r--r--src/base/wlc/wlc.h58
-rw-r--r--src/base/wlc/wlcAbc.c181
-rw-r--r--src/base/wlc/wlcAbs.c701
-rw-r--r--src/base/wlc/wlcAbs2.c410
-rw-r--r--src/base/wlc/wlcBlast.c51
-rw-r--r--src/base/wlc/wlcCom.c949
-rw-r--r--src/base/wlc/wlcNtk.c570
-rw-r--r--src/base/wlc/wlcReadSmt.c336
-rw-r--r--src/base/wlc/wlcReadVer.c5
-rw-r--r--src/base/wlc/wlcShow.c337
-rw-r--r--src/base/wlc/wlcSim.c22
-rw-r--r--src/base/wlc/wlcUif.c290
-rw-r--r--src/base/wlc/wlcWriteVer.c2
-rw-r--r--src/bdd/extrab/extraBddMisc.c249
-rw-r--r--src/map/if/ifDec16.c2
-rw-r--r--src/map/if/ifLibLut.c4
-rw-r--r--src/map/mio/mioUtils.c4
-rw-r--r--src/map/scl/scl.c2
-rw-r--r--src/map/scl/sclLiberty.c14
-rw-r--r--src/misc/extra/extraUtilUtil.c54
-rw-r--r--src/misc/util/abc_global.h2
-rw-r--r--src/misc/util/utilCex.c25
-rw-r--r--src/misc/util/utilDouble.h222
-rw-r--r--src/misc/util/utilFloat.h226
-rw-r--r--src/misc/util/utilTruth.h22
-rw-r--r--src/misc/vec/vecInt.h18
-rw-r--r--src/misc/vec/vecPtr.h2
-rw-r--r--src/misc/vec/vecWec.h29
-rw-r--r--src/misc/zlib/inflate.c2
-rw-r--r--src/opt/dau/dauGia.c6
-rw-r--r--src/opt/dsc/dsc.c14
-rw-r--r--src/opt/lpk/lpkCore.c6
-rw-r--r--src/opt/lpk/lpkCut.c6
-rw-r--r--src/opt/sbd/module.make4
-rw-r--r--src/opt/sbd/sbd.h7
-rw-r--r--src/opt/sbd/sbdCnf.c4
-rw-r--r--src/opt/sbd/sbdCore.c951
-rw-r--r--src/opt/sbd/sbdCut.c872
-rw-r--r--src/opt/sbd/sbdCut2.c431
-rw-r--r--src/opt/sbd/sbdInt.h49
-rw-r--r--src/opt/sbd/sbdLut.c311
-rw-r--r--src/opt/sbd/sbdPath.c197
-rw-r--r--src/opt/sbd/sbdSat.c4
-rw-r--r--src/opt/sbd/sbdWin.c213
-rw-r--r--src/opt/sfm/sfmCnf.c4
-rw-r--r--src/proof/acec/acec.h27
-rw-r--r--src/proof/acec/acecBo.c216
-rw-r--r--src/proof/acec/acecCl.c390
-rw-r--r--src/proof/acec/acecCo.c2
-rw-r--r--src/proof/acec/acecCore.c509
-rw-r--r--src/proof/acec/acecInt.h37
-rw-r--r--src/proof/acec/acecMult.c617
-rw-r--r--src/proof/acec/acecNorm.c226
-rw-r--r--src/proof/acec/acecPa.c5
-rw-r--r--src/proof/acec/acecPool.c17
-rw-r--r--src/proof/acec/acecRe.c47
-rw-r--r--src/proof/acec/acecSt.c2
-rw-r--r--src/proof/acec/acecStruct.c271
-rw-r--r--src/proof/acec/acecTree.c783
-rw-r--r--src/proof/acec/acecUtil.c23
-rw-r--r--src/proof/acec/acecXor.c434
-rw-r--r--src/proof/acec/module.make7
-rw-r--r--src/proof/cec/cecCec.c9
-rw-r--r--src/proof/cec/cecSat.c1003
-rw-r--r--src/proof/cec/cecSimBack.c194
-rw-r--r--src/proof/cec/module.make1
-rw-r--r--src/proof/fra/fraCec.c6
-rw-r--r--src/proof/fra/fraSec.c4
-rw-r--r--src/proof/pdr/module.make4
-rw-r--r--src/proof/pdr/pdr.h9
-rw-r--r--src/proof/pdr/pdrCore.c502
-rw-r--r--src/proof/pdr/pdrIncr.c760
-rw-r--r--src/proof/pdr/pdrInt.h32
-rw-r--r--src/proof/pdr/pdrInv.c376
-rw-r--r--src/proof/pdr/pdrMan.c341
-rw-r--r--src/proof/pdr/pdrSat.c39
-rw-r--r--src/proof/pdr/pdrTsim.c134
-rw-r--r--src/proof/pdr/pdrTsim2.c550
-rw-r--r--src/proof/pdr/pdrUtil.c137
-rw-r--r--src/sat/bmc/bmc.h5
-rw-r--r--src/sat/bmc/bmcBmcAnd.c3
-rw-r--r--src/sat/bmc/bmcCexCare.c266
-rw-r--r--src/sat/bmc/bmcCexTools.c6
-rw-r--r--src/sat/bmc/bmcChain.c3
-rw-r--r--src/sat/bmc/bmcClp.c10
-rw-r--r--src/sat/bmc/bmcEnum.c223
-rw-r--r--src/sat/bmc/bmcExpand.c4
-rw-r--r--src/sat/bmc/bmcFault.c2
-rw-r--r--src/sat/bmc/bmcFx.c6
-rw-r--r--src/sat/bmc/bmcGen.c22
-rw-r--r--src/sat/bmc/bmcICheck.c3
-rw-r--r--src/sat/bsat/satSolver.c510
-rw-r--r--src/sat/bsat/satSolver.h61
-rw-r--r--src/sat/cnf/cnfUtil.c2
-rw-r--r--src/sat/satoko/LICENSE22
-rw-r--r--src/sat/satoko/act_clause.h43
-rw-r--r--src/sat/satoko/act_var.h53
-rw-r--r--src/sat/satoko/cdb.h106
-rw-r--r--src/sat/satoko/clause.h63
-rw-r--r--src/sat/satoko/cnf_reader.c156
-rw-r--r--src/sat/satoko/module.make3
-rw-r--r--src/sat/satoko/satoko.h114
-rw-r--r--src/sat/satoko/solver.c718
-rw-r--r--src/sat/satoko/solver.h254
-rw-r--r--src/sat/satoko/solver_api.c445
-rw-r--r--src/sat/satoko/types.h39
-rw-r--r--src/sat/satoko/utils/b_queue.h81
-rw-r--r--src/sat/satoko/utils/heap.h178
-rwxr-xr-xsrc/sat/satoko/utils/mem.h23
-rwxr-xr-xsrc/sat/satoko/utils/misc.h35
-rw-r--r--src/sat/satoko/utils/sdbl.h133
-rw-r--r--src/sat/satoko/utils/sort.h65
-rw-r--r--src/sat/satoko/utils/vec/vec_char.h260
-rw-r--r--src/sat/satoko/utils/vec/vec_flt.h246
-rwxr-xr-xsrc/sat/satoko/utils/vec/vec_int.h240
-rwxr-xr-xsrc/sat/satoko/utils/vec/vec_sdbl.h253
-rwxr-xr-xsrc/sat/satoko/utils/vec/vec_uint.h268
-rw-r--r--src/sat/satoko/watch_list.h203
-rw-r--r--src/sat/xsat/license39
-rw-r--r--src/sat/xsat/module.make3
-rw-r--r--src/sat/xsat/xsat.h59
-rw-r--r--src/sat/xsat/xsatBQueue.h190
-rw-r--r--src/sat/xsat/xsatClause.h109
-rw-r--r--src/sat/xsat/xsatCnfReader.c236
-rw-r--r--src/sat/xsat/xsatHeap.h330
-rw-r--r--src/sat/xsat/xsatMemory.h222
-rw-r--r--src/sat/xsat/xsatSolver.c1003
-rw-r--r--src/sat/xsat/xsatSolver.h248
-rw-r--r--src/sat/xsat/xsatSolverAPI.c346
-rw-r--r--src/sat/xsat/xsatUtils.h106
-rw-r--r--src/sat/xsat/xsatWatchList.h269
177 files changed, 26306 insertions, 1949 deletions
diff --git a/.hgignore b/.hgignore
index b5fedc7a..f5d4784c 100644
--- a/.hgignore
+++ b/.hgignore
@@ -52,9 +52,14 @@ build/
*.rej
*.orig
+tags
+
syntax: regexp
^libabc.a$
^abc$
^arch_flags$
+
+^cmake
+^cscope
diff --git a/Makefile b/Makefile
index 6010aaac..4142e1b2 100644
--- a/Makefile
+++ b/Makefile
@@ -23,7 +23,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/csat src/sat/msat src/sat/psat src/sat/cnf src/sat/bmc \
+ 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/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 \
@@ -139,6 +139,8 @@ OBJ := \
$(patsubst %.c, %.o, $(filter %.c, $(SRC))) \
$(patsubst %.y, %.o, $(filter %.y, $(SRC)))
+LIBOBJ := $(filter-out src/base/main/main.o,$(OBJ))
+
DEP := $(OBJ:.o=.d)
# implicit rules
@@ -186,11 +188,15 @@ $(PROG): $(OBJ)
@echo "$(MSG_PREFIX)\`\` Building binary:" $(notdir $@)
$(VERBOSE)$(LD) -o $@ $^ $(LIBS)
-lib$(PROG).a: $(OBJ)
+lib$(PROG).a: $(LIBOBJ)
@echo "$(MSG_PREFIX)\`\` Linking:" $(notdir $@)
$(VERBOSE)ar rv $@ $?
$(VERBOSE)ranlib $@
+lib$(PROG).so: $(LIBOBJ)
+ @echo "$(MSG_PREFIX)\`\` Linking:" $(notdir $@)
+ $(VERBOSE)$(CXX) -shared -o $@ $^ $(LIBS)
+
docs:
@echo "$(MSG_PREFIX)\`\` Building documentation." $(notdir $@)
$(VERBOSE)doxygen doxygen.conf
diff --git a/abclib.dsp b/abclib.dsp
index 3ffe0e44..b852551d 100644
--- a/abclib.dsp
+++ b/abclib.dsp
@@ -523,6 +523,10 @@ SOURCE=.\src\base\cmd\cmdApi.c
# End Source File
# Begin Source File
+SOURCE=.\src\base\cmd\cmdAuto.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\base\cmd\cmdFlag.c
# End Source File
# Begin Source File
@@ -775,6 +779,10 @@ SOURCE=.\src\base\wlc\wlcAbs.c
# End Source File
# Begin Source File
+SOURCE=.\src\base\wlc\wlcAbs2.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\base\wlc\wlcBlast.c
# End Source File
# Begin Source File
@@ -799,6 +807,10 @@ SOURCE=.\src\base\wlc\wlcReadVer.c
# End Source File
# Begin Source File
+SOURCE=.\src\base\wlc\wlcShow.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\base\wlc\wlcSim.c
# End Source File
# Begin Source File
@@ -807,6 +819,10 @@ SOURCE=.\src\base\wlc\wlcStdin.c
# End Source File
# Begin Source File
+SOURCE=.\src\base\wlc\wlcUif.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\base\wlc\wlcWin.c
# End Source File
# Begin Source File
@@ -1938,6 +1954,142 @@ SOURCE=.\src\sat\bmc\bmcUnroll.c
# PROP Default_Filter ""
# End Group
+# Begin Group "xsat"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\src\sat\xsat\xsat.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\xsat\xsatBQueue.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\xsat\xsatClause.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\xsat\xsatCnfReader.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\xsat\xsatHeap.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\xsat\xsatMemory.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\xsat\xsatSolver.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\xsat\xsatSolver.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\xsat\xsatSolverAPI.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\xsat\xsatUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\xsat\xsatWatchList.h
+# End Source File
+# End Group
+# Begin Group "satoko"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\src\sat\satoko\act_clause.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\satoko\act_var.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\satoko\utils\b_queue.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\satoko\cdb.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\satoko\clause.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\satoko\cnf_reader.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\satoko\utils\heap.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\satoko\utils\mem.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\satoko\utils\misc.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\satoko\satoko.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\satoko\utils\sdbl.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\satoko\solver.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\satoko\solver.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\satoko\solver_api.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\satoko\utils\sort.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\satoko\types.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\satoko\utils\vec\vec_char.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\satoko\utils\vec\vec_flt.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\satoko\utils\vec\vec_int.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\satoko\utils\vec\vec_uint.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\sat\satoko\watch_list.h
+# End Source File
+# End Group
# End Group
# Begin Group "opt"
@@ -2711,10 +2863,26 @@ SOURCE=.\src\opt\sbd\sbdCore.c
# End Source File
# Begin Source File
+SOURCE=.\src\opt\sbd\sbdCut.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\opt\sbd\sbdCut2.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\opt\sbd\sbdInt.h
# End Source File
# Begin Source File
+SOURCE=.\src\opt\sbd\sbdLut.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\opt\sbd\sbdPath.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\opt\sbd\sbdSat.c
# End Source File
# Begin Source File
@@ -3487,10 +3655,18 @@ SOURCE=.\src\misc\util\utilColor.c
# End Source File
# Begin Source File
+SOURCE=.\src\misc\util\utilDouble.h
+# End Source File
+# Begin Source File
+
SOURCE=.\src\misc\util\utilFile.c
# End Source File
# Begin Source File
+SOURCE=.\src\misc\util\utilFloat.h
+# End Source File
+# Begin Source File
+
SOURCE=.\src\misc\util\utilIsop.c
# End Source File
# Begin Source File
@@ -4483,6 +4659,10 @@ SOURCE=.\src\aig\gia\giaSatMap.c
# End Source File
# Begin Source File
+SOURCE=.\src\aig\gia\giaSatoko.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\aig\gia\giaScl.c
# End Source File
# Begin Source File
@@ -4847,6 +5027,10 @@ SOURCE=.\src\proof\cec\cecPat.c
# End Source File
# Begin Source File
+SOURCE=.\src\proof\cec\cecSat.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\proof\cec\cecSeq.c
# End Source File
# Begin Source File
@@ -5171,6 +5355,10 @@ SOURCE=.\src\proof\pdr\pdrCore.c
# End Source File
# Begin Source File
+SOURCE=.\src\proof\pdr\pdrIncr.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\proof\pdr\pdrInt.h
# End Source File
# Begin Source File
@@ -5191,6 +5379,10 @@ SOURCE=.\src\proof\pdr\pdrTsim.c
# End Source File
# Begin Source File
+SOURCE=.\src\proof\pdr\pdrTsim2.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\proof\pdr\pdrUtil.c
# End Source File
# End Group
@@ -5415,6 +5607,10 @@ SOURCE=.\src\proof\acec\acec.h
# End Source File
# Begin Source File
+SOURCE=.\src\proof\acec\acecBo.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\proof\acec\acecCl.c
# End Source File
# Begin Source File
@@ -5439,6 +5635,14 @@ SOURCE=.\src\proof\acec\acecInt.h
# End Source File
# Begin Source File
+SOURCE=.\src\proof\acec\acecMult.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\proof\acec\acecNorm.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\proof\acec\acecOrder.c
# End Source File
# Begin Source File
@@ -5467,8 +5671,20 @@ SOURCE=.\src\proof\acec\acecSt.c
# End Source File
# Begin Source File
+SOURCE=.\src\proof\acec\acecStruct.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\proof\acec\acecTree.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\proof\acec\acecUtil.c
# End Source File
+# Begin Source File
+
+SOURCE=.\src\proof\acec\acecXor.c
+# End Source File
# End Group
# End Group
# End Group
diff --git a/readme.md b/readme.md
index c7a6816d..ca9a90ba 100644
--- a/readme.md
+++ b/readme.md
@@ -53,6 +53,13 @@ The current version of ABC can be compiled with C compiler or C++ compiler.
* To compile as C++ code with namespaces: make sure that `CC=g++` and `ABC_NAMESPACE` is set to
the name of the requested namespace. For example, add `-DABC_NAMESPACE=xxx` to OPTFLAGS.
+## Building a shared library
+
+ * Compile the code as position-independent by adding `ABC_USE_PIC=1`.
+ * Build the `libabc.so` target:
+
+ make ABC_USE_PIC=1 libabc.so
+
## Bug reporting:
Please try to reproduce all the reported bugs and unexpected features using the latest
diff --git a/src/aig/aig/aigShow.c b/src/aig/aig/aigShow.c
index eac2a510..d983602a 100644
--- a/src/aig/aig/aigShow.c
+++ b/src/aig/aig/aigShow.c
@@ -19,6 +19,7 @@
***********************************************************************/
#include "aig.h"
+#include "misc/extra/extra.h"
ABC_NAMESPACE_IMPL_START
@@ -340,12 +341,10 @@ void Aig_WriteDotAig( Aig_Man_t * pMan, char * pFileName, int fHaig, Vec_Ptr_t *
void Aig_ManShow( Aig_Man_t * pMan, int fHaig, Vec_Ptr_t * vBold )
{
extern void Abc_ShowFile( char * FileNameDot );
- static int Counter = 0;
char FileNameDot[200];
FILE * pFile;
// create the file name
-// Aig_ShowGetFileName( pMan->pName, FileNameDot );
- sprintf( FileNameDot, "temp%02d.dot", Counter++ );
+ sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(pMan->pName, ".dot") );
// check that the file can be opened
if ( (pFile = fopen( FileNameDot, "w" )) == NULL )
{
diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h
index bf7bf349..5ad87008 100644
--- a/src/aig/gia/gia.h
+++ b/src/aig/gia/gia.h
@@ -194,6 +194,7 @@ struct Gia_Man_t_
int MappedDelay; // delay after mapping
// bit-parallel simulation
int iPatsPi;
+ int nSimWords;
Vec_Wrd_t * vSims;
Vec_Wrd_t * vSimsPi;
Vec_Int_t * vClassOld;
@@ -311,6 +312,7 @@ struct Jf_Par_t_
int fGenCnf;
int fCnfObjIds;
int fAddOrCla;
+ int fCnfMapping;
int fPureAig;
int fDoAverage;
int fCutHashing;
@@ -665,21 +667,6 @@ static inline int Gia_ManAppendAnd( Gia_Man_t * p, int iLit0, int iLit1 )
}
return Gia_ObjId( p, pObj ) << 1;
}
-static inline int Gia_ManAppendAnd2( Gia_Man_t * p, int iLit0, int iLit1 )
-{
- if ( !p->fGiaSimple )
- {
- if ( iLit0 < 2 )
- return iLit0 ? iLit1 : 0;
- if ( iLit1 < 2 )
- return iLit1 ? iLit0 : 0;
- if ( iLit0 == iLit1 )
- return iLit1;
- if ( iLit0 == Abc_LitNot(iLit1) )
- return 0;
- }
- return Gia_ManAppendAnd( p, iLit0, iLit1 );
-}
static inline int Gia_ManAppendXorReal( Gia_Man_t * p, int iLit0, int iLit1 )
{
Gia_Obj_t * pObj = Gia_ManAppendObj( p );
@@ -780,6 +767,44 @@ static inline int Gia_ManAppendXor( Gia_Man_t * p, int iLit0, int iLit1 )
{
return Gia_ManAppendMux( p, iLit0, Abc_LitNot(iLit1), iLit1 );
}
+
+static inline int Gia_ManAppendAnd2( Gia_Man_t * p, int iLit0, int iLit1 )
+{
+ if ( !p->fGiaSimple )
+ {
+ if ( iLit0 < 2 )
+ return iLit0 ? iLit1 : 0;
+ if ( iLit1 < 2 )
+ return iLit1 ? iLit0 : 0;
+ if ( iLit0 == iLit1 )
+ return iLit1;
+ if ( iLit0 == Abc_LitNot(iLit1) )
+ return 0;
+ }
+ return Gia_ManAppendAnd( p, iLit0, iLit1 );
+}
+static inline int Gia_ManAppendOr2( Gia_Man_t * p, int iLit0, int iLit1 )
+{
+ return Abc_LitNot(Gia_ManAppendAnd2( p, Abc_LitNot(iLit0), Abc_LitNot(iLit1) ));
+}
+static inline int Gia_ManAppendMux2( Gia_Man_t * p, int iCtrl, int iData1, int iData0 )
+{
+ int iTemp0 = Gia_ManAppendAnd2( p, Abc_LitNot(iCtrl), iData0 );
+ int iTemp1 = Gia_ManAppendAnd2( p, iCtrl, iData1 );
+ return Abc_LitNotCond( Gia_ManAppendAnd2( p, Abc_LitNot(iTemp0), Abc_LitNot(iTemp1) ), 1 );
+}
+static inline int Gia_ManAppendMaj2( Gia_Man_t * p, int iData0, int iData1, int iData2 )
+{
+ int iTemp0 = Gia_ManAppendOr2( p, iData1, iData2 );
+ int iTemp1 = Gia_ManAppendAnd2( p, iData0, iTemp0 );
+ int iTemp2 = Gia_ManAppendAnd2( p, iData1, iData2 );
+ return Gia_ManAppendOr2( p, iTemp1, iTemp2 );
+}
+static inline int Gia_ManAppendXor2( Gia_Man_t * p, int iLit0, int iLit1 )
+{
+ return Gia_ManAppendMux2( p, iLit0, Abc_LitNot(iLit1), iLit1 );
+}
+
static inline void Gia_ManPatchCoDriver( Gia_Man_t * p, int iCoIndex, int iLit0 )
{
Gia_Obj_t * pObjCo = Gia_ManCo( p, iCoIndex );
@@ -958,24 +983,26 @@ static inline void Gia_ObjSetNext( Gia_Man_t * p, int Id, int Num ) { p
static inline int Gia_ObjIsConst( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == 0; }
static inline int Gia_ObjIsHead( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == GIA_VOID && Gia_ObjNext(p, Id) > 0; }
-static inline int Gia_ObjIsNone( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == GIA_VOID && Gia_ObjNext(p, Id) == 0; }
-static inline int Gia_ObjIsTail( Gia_Man_t * p, int Id ) { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) && Gia_ObjNext(p, Id) == 0; }
+static inline int Gia_ObjIsNone( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == GIA_VOID && Gia_ObjNext(p, Id) <= 0; }
+static inline int Gia_ObjIsTail( Gia_Man_t * p, int Id ) { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) && Gia_ObjNext(p, Id) <= 0; }
static inline int Gia_ObjIsClass( Gia_Man_t * p, int Id ) { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) || Gia_ObjNext(p, Id) > 0; }
static inline int Gia_ObjHasSameRepr( Gia_Man_t * p, int i, int k ) { assert( k ); return i? (Gia_ObjRepr(p, i) == Gia_ObjRepr(p, k) && Gia_ObjRepr(p, i) != GIA_VOID) : Gia_ObjRepr(p, k) == 0; }
static inline int Gia_ObjIsFailedPair( Gia_Man_t * p, int i, int k ) { assert( k ); return i? (Gia_ObjFailed(p, i) || Gia_ObjFailed(p, k)) : Gia_ObjFailed(p, k); }
-static inline int Gia_ClassIsPair( Gia_Man_t * p, int i ) { assert( Gia_ObjIsHead(p, i) ); assert( Gia_ObjNext(p, i) ); return Gia_ObjNext(p, Gia_ObjNext(p, i)) == 0; }
+static inline int Gia_ClassIsPair( Gia_Man_t * p, int i ) { assert( Gia_ObjIsHead(p, i) ); assert( Gia_ObjNext(p, i) ); return Gia_ObjNext(p, Gia_ObjNext(p, i)) <= 0; }
static inline void Gia_ClassUndoPair( Gia_Man_t * p, int i ) { assert( Gia_ClassIsPair(p,i) ); Gia_ObjSetRepr(p, Gia_ObjNext(p, i), GIA_VOID); Gia_ObjSetNext(p, i, 0); }
#define Gia_ManForEachConst( p, i ) \
for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsConst(p, i) ) {} else
#define Gia_ManForEachClass( p, i ) \
for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsHead(p, i) ) {} else
+#define Gia_ManForEachClass0( p, i ) \
+ for ( i = 0; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsHead(p, i) ) {} else
#define Gia_ManForEachClassReverse( p, i ) \
for ( i = Gia_ManObjNum(p) - 1; i > 0; i-- ) if ( !Gia_ObjIsHead(p, i) ) {} else
#define Gia_ClassForEachObj( p, i, iObj ) \
- for ( assert(Gia_ObjIsHead(p, i)), iObj = i; iObj; iObj = Gia_ObjNext(p, iObj) )
+ for ( assert(Gia_ObjIsHead(p, i)), iObj = i; iObj > 0; iObj = Gia_ObjNext(p, iObj) )
#define Gia_ClassForEachObj1( p, i, iObj ) \
- for ( assert(Gia_ObjIsHead(p, i)), iObj = Gia_ObjNext(p, i); iObj; iObj = Gia_ObjNext(p, iObj) )
+ for ( assert(Gia_ObjIsHead(p, i)), iObj = Gia_ObjNext(p, i); iObj > 0; iObj = Gia_ObjNext(p, iObj) )
static inline int Gia_ObjFoffsetId( Gia_Man_t * p, int Id ) { return Vec_IntEntry( p->vFanout, Id ); }
@@ -1205,6 +1232,7 @@ extern Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p, int fTrimCis, int f
extern Gia_Man_t * Gia_ManDupOntop( Gia_Man_t * p, Gia_Man_t * p2 );
extern Gia_Man_t * Gia_ManDupWithNewPo( Gia_Man_t * p1, Gia_Man_t * p2 );
extern Gia_Man_t * Gia_ManDupDfsCiMap( Gia_Man_t * p, int * pCi2Lit, Vec_Int_t * vLits );
+extern Gia_Man_t * Gia_ManPermuteInputs( Gia_Man_t * p, int nPpis, int nExtra );
extern Gia_Man_t * Gia_ManDupDfsClasses( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupTopAnd( Gia_Man_t * p, int fVerbose );
extern Gia_Man_t * Gia_ManMiter( Gia_Man_t * pAig0, Gia_Man_t * pAig1, int nInsDup, int fDualOut, int fSeq, int fImplic, int fVerbose );
@@ -1219,6 +1247,8 @@ extern Gia_Man_t * Gia_ManChoiceMiter( Vec_Ptr_t * vGias );
extern Gia_Man_t * Gia_ManDupWithConstraints( Gia_Man_t * p, Vec_Int_t * vPoTypes );
extern Gia_Man_t * Gia_ManDupCones( Gia_Man_t * p, int * pPos, int nPos, int fTrimPis );
extern Gia_Man_t * Gia_ManDupAndCones( Gia_Man_t * p, int * pAnds, int nAnds, int fTrimPis );
+extern Gia_Man_t * Gia_ManDupAndConesLimit( Gia_Man_t * p, int * pAnds, int nAnds, int Level );
+extern Gia_Man_t * Gia_ManDupAndConesLimit2( Gia_Man_t * p, int * pAnds, int nAnds, int Level );
extern Gia_Man_t * Gia_ManDupOneHot( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupLevelized( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupFromVecs( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos, int nRegs );
@@ -1247,6 +1277,7 @@ extern void Gia_ManOrigIdsInit( Gia_Man_t * p );
extern void Gia_ManOrigIdsStart( Gia_Man_t * p );
extern void Gia_ManOrigIdsRemap( Gia_Man_t * p, Gia_Man_t * pNew );
extern Gia_Man_t * Gia_ManOrigIdsReduce( Gia_Man_t * p, Vec_Int_t * vPairs );
+extern Gia_Man_t * Gia_ManComputeGiaEquivs( Gia_Man_t * pGia, int nConfs, int fVerbose );
extern void Gia_ManEquivFixOutputPairs( Gia_Man_t * p );
extern int Gia_ManCheckTopoOrder( Gia_Man_t * p );
extern int * Gia_ManDeriveNexts( Gia_Man_t * p );
@@ -1379,6 +1410,7 @@ extern int Gia_MmStepReadMemUsage( Gia_MmStep_t * p );
/*=== giaMf.c ===========================================================*/
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 void Gia_ManWriteMiniAig( Gia_Man_t * pGia, char * pFileName );
@@ -1403,7 +1435,7 @@ extern Gia_Man_t * Gia_ManCleanupOutputs( Gia_Man_t * p, int nOutputs );
extern Gia_Man_t * Gia_ManSeqCleanup( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManSeqStructSweep( Gia_Man_t * p, int fConst, int fEquiv, int fVerbose );
/*=== giaShow.c ===========================================================*/
-extern void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders );
+extern void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds, int fPath );
/*=== giaShrink.c ===========================================================*/
extern Gia_Man_t * Gia_ManMapShrink4( Gia_Man_t * p, int fKeepLevel, int fVerbose );
extern Gia_Man_t * Gia_ManMapShrink6( Gia_Man_t * p, int nFanoutMax, int fKeepLevel, int fVerbose );
@@ -1491,6 +1523,7 @@ extern int Gia_ManVerifyWithBoxes( Gia_Man_t * pGia, int nBTLimi
extern word Gia_LutComputeTruth6( Gia_Man_t * p, int iObj, Vec_Wrd_t * vTruths );
extern word Gia_ObjComputeTruthTable6Lut( Gia_Man_t * p, int iObj, Vec_Wrd_t * vTemp );
extern word Gia_ObjComputeTruthTable6( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp, Vec_Wrd_t * vTruths );
+extern word Gia_ObjComputeTruth6Cis( Gia_Man_t * p, int iLit, Vec_Int_t * vSupp, Vec_Wrd_t * vTemp );
extern void Gia_ObjCollectInternal( Gia_Man_t * p, Gia_Obj_t * pObj );
extern word * Gia_ObjComputeTruthTable( Gia_Man_t * p, Gia_Obj_t * pObj );
extern void Gia_ObjComputeTruthTableStart( Gia_Man_t * p, int nVarsMax );
diff --git a/src/aig/gia/giaAig.c b/src/aig/gia/giaAig.c
index 3cf01c70..dfd4a467 100644
--- a/src/aig/gia/giaAig.c
+++ b/src/aig/gia/giaAig.c
@@ -22,6 +22,7 @@
#include "proof/fra/fra.h"
#include "proof/dch/dch.h"
#include "opt/dar/dar.h"
+#include "opt/dau/dau.h"
ABC_NAMESPACE_IMPL_START
@@ -576,11 +577,17 @@ Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p, int fUpdateLevel, int fVerbose )
***********************************************************************/
Gia_Man_t * Gia_ManPerformDch( Gia_Man_t * p, void * pPars )
{
- Gia_Man_t * pGia;
+ int fUseMapping = 0;
+ Gia_Man_t * pGia, * pGia1;
Aig_Man_t * pNew;
if ( p->pManTime && p->vLevels == NULL )
Gia_ManLevelWithBoxes( p );
- pNew = Gia_ManToAig( p, 0 );
+ if ( fUseMapping && Gia_ManHasMapping(p) )
+ pGia1 = (Gia_Man_t *)Dsm_ManDeriveGia( p, 0 );
+ else
+ pGia1 = Gia_ManDup( p );
+ pNew = Gia_ManToAig( pGia1, 0 );
+ Gia_ManStop( pGia1 );
pNew = Dar_ManChoiceNew( pNew, (Dch_Pars_t *)pPars );
// pGia = Gia_ManFromAig( pNew );
pGia = Gia_ManFromAigChoices( pNew );
diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c
index 7ced54a4..ee709df4 100644
--- a/src/aig/gia/giaDup.c
+++ b/src/aig/gia/giaDup.c
@@ -231,6 +231,80 @@ Gia_Man_t * Gia_ManDupOrderDfs( Gia_Man_t * p )
SeeAlso []
***********************************************************************/
+Gia_Man_t * Gia_ManDupAbs( Gia_Man_t * p, Vec_Int_t * vMapPpi2Ff, Vec_Int_t * vMapFf2Ppi )
+{
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj;
+ int k, Flop, Used;
+ assert( Vec_IntSize(vMapFf2Ppi) == Vec_IntSize(vMapPpi2Ff) + Vec_IntCountEntry(vMapFf2Ppi, -1) );
+ 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;
+ // create inputs
+ Gia_ManForEachPi( p, pObj, k )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Vec_IntForEachEntry( vMapPpi2Ff, Flop, k )
+ {
+ pObj = Gia_ManCi( p, Gia_ManPiNum(p) + Flop );
+ pObj->Value = Gia_ManAppendCi(pNew);
+ }
+ Vec_IntForEachEntry( vMapFf2Ppi, Used, Flop )
+ {
+ pObj = Gia_ManCi( p, Gia_ManPiNum(p) + Flop );
+ if ( Used >= 0 )
+ {
+ assert( pObj->Value != ~0 );
+ continue;
+ }
+ assert( pObj->Value == ~0 );
+ pObj->Value = Gia_ManAppendCi(pNew);
+ }
+ Gia_ManForEachCi( p, pObj, k )
+ assert( pObj->Value != ~0 );
+ // create nodes
+ Gia_ManForEachPo( p, pObj, k )
+ Gia_ManDupOrderDfs_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Vec_IntForEachEntry( vMapFf2Ppi, Used, Flop )
+ {
+ if ( Used >= 0 )
+ continue;
+ pObj = Gia_ManCi( p, Gia_ManPiNum(p) + Flop );
+ pObj = Gia_ObjRoToRi( p, pObj );
+ Gia_ManDupOrderDfs_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ }
+ // create outputs
+ Gia_ManForEachPo( p, pObj, k )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Vec_IntForEachEntry( vMapFf2Ppi, Used, Flop )
+ {
+ if ( Used >= 0 )
+ continue;
+ pObj = Gia_ManCi( p, Gia_ManPiNum(p) + Flop );
+ pObj = Gia_ObjRoToRi( p, pObj );
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ }
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) - Vec_IntSize(vMapPpi2Ff) );
+ assert( Gia_ManPiNum(pNew) == Gia_ManPiNum(p) + Vec_IntSize(vMapPpi2Ff) );
+ assert( Gia_ManCiNum(pNew) == Gia_ManCiNum(p) );
+ assert( Gia_ManPoNum(pNew) == Gia_ManPoNum(p) );
+ assert( Gia_ManCoNum(pNew) == Gia_ManCoNum(p) - Vec_IntSize(vMapPpi2Ff) );
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates AIG while putting objects in the DFS order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
Gia_Man_t * Gia_ManDupOutputGroup( Gia_Man_t * p, int iOutStart, int iOutStop )
{
Gia_Man_t * pNew;
@@ -2097,6 +2171,43 @@ Gia_Man_t * Gia_ManDupDfsCiMap( Gia_Man_t * p, int * pCi2Lit, Vec_Int_t * vLits
/**Function*************************************************************
+ Synopsis [Permute inputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManPermuteInputs( Gia_Man_t * p, int nPpis, int nExtra )
+{
+ 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_ManConst0(p)->Value = 0;
+ for ( i = 0; i < Gia_ManPiNum(p) - nPpis - nExtra; i++ ) // regular PIs
+ Gia_ManCi(p, i)->Value = Gia_ManAppendCi( pNew );
+ for ( i = Gia_ManPiNum(p) - nExtra; i < Gia_ManPiNum(p); i++ ) // extra PIs due to DC values
+ Gia_ManCi(p, i)->Value = Gia_ManAppendCi( pNew );
+ for ( i = Gia_ManPiNum(p) - nPpis - nExtra; i < Gia_ManPiNum(p) - nExtra; i++ ) // pseudo-PIs
+ Gia_ManCi(p, i)->Value = Gia_ManAppendCi( pNew );
+ for ( i = Gia_ManPiNum(p); i < Gia_ManCiNum(p); i++ ) // flop outputs
+ Gia_ManCi(p, i)->Value = Gia_ManAppendCi( pNew );
+ assert( Gia_ManCiNum(pNew) == Gia_ManCiNum(p) );
+ 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) );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ return pNew;
+}
+
+/**Function*************************************************************
+
Synopsis [Duplicates AIG in the DFS order.]
Description []
@@ -3046,6 +3157,71 @@ Gia_Man_t * Gia_ManDupAndCones( Gia_Man_t * p, int * pAnds, int nAnds, int fTrim
return pNew;
}
+void Gia_ManDupAndConesLimit_rec( Gia_Man_t * pNew, Gia_Man_t * p, int iObj, int Level )
+{
+ Gia_Obj_t * pObj = Gia_ManObj(p, iObj);
+ if ( ~pObj->Value )
+ return;
+ if ( !Gia_ObjIsAnd(pObj) || Gia_ObjLevel(p, pObj) < Level )
+ {
+ pObj->Value = Gia_ManAppendCi( pNew );
+ //printf( "PI %d for %d.\n", Abc_Lit2Var(pObj->Value), iObj );
+ return;
+ }
+ Gia_ManDupAndConesLimit_rec( pNew, p, Gia_ObjFaninId0(pObj, iObj), Level );
+ Gia_ManDupAndConesLimit_rec( pNew, p, Gia_ObjFaninId1(pObj, iObj), Level );
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ //printf( "Obj %d for %d.\n", Abc_Lit2Var(pObj->Value), iObj );
+}
+Gia_Man_t * Gia_ManDupAndConesLimit( Gia_Man_t * p, int * pAnds, int nAnds, int Level )
+{
+ Gia_Man_t * pNew;
+ int i;
+ pNew = Gia_ManStart( 1000 );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManLevelNum( p );
+ Gia_ManFillValue( p );
+ Gia_ManConst0(p)->Value = 0;
+ for ( i = 0; i < nAnds; i++ )
+ Gia_ManDupAndConesLimit_rec( pNew, p, pAnds[i], Level );
+ for ( i = 0; i < nAnds; i++ )
+ Gia_ManAppendCo( pNew, Gia_ManObj(p, pAnds[i])->Value );
+ return pNew;
+}
+
+void Gia_ManDupAndConesLimit2_rec( Gia_Man_t * pNew, Gia_Man_t * p, int iObj, int Level )
+{
+ Gia_Obj_t * pObj = Gia_ManObj(p, iObj);
+ if ( ~pObj->Value )
+ return;
+ if ( !Gia_ObjIsAnd(pObj) || Level <= 0 )
+ {
+ pObj->Value = Gia_ManAppendCi( pNew );
+ //printf( "PI %d for %d.\n", Abc_Lit2Var(pObj->Value), iObj );
+ return;
+ }
+ Gia_ManDupAndConesLimit2_rec( pNew, p, Gia_ObjFaninId0(pObj, iObj), Level-1 );
+ Gia_ManDupAndConesLimit2_rec( pNew, p, Gia_ObjFaninId1(pObj, iObj), Level-1 );
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ //printf( "Obj %d for %d.\n", Abc_Lit2Var(pObj->Value), iObj );
+}
+Gia_Man_t * Gia_ManDupAndConesLimit2( Gia_Man_t * p, int * pAnds, int nAnds, int Level )
+{
+ Gia_Man_t * pNew;
+ int i;
+ pNew = Gia_ManStart( 1000 );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManFillValue( p );
+ Gia_ManConst0(p)->Value = 0;
+ for ( i = 0; i < nAnds; i++ )
+ Gia_ManDupAndConesLimit2_rec( pNew, p, pAnds[i], Level );
+ for ( i = 0; i < nAnds; i++ )
+ Gia_ManAppendCo( pNew, Gia_ManObj(p, pAnds[i])->Value );
+ return pNew;
+
+}
/**Function*************************************************************
@@ -3377,6 +3553,26 @@ Gia_Man_t * Gia_ManDupOuts( Gia_Man_t * p )
SeeAlso []
***********************************************************************/
+Vec_Wec_t * Gia_ManCreateNodeSupps( Gia_Man_t * p, Vec_Int_t * vNodes, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ Gia_Obj_t * pObj; int i, Id;
+ Vec_Wec_t * vSuppsNo = Vec_WecStart( Vec_IntSize(vNodes) );
+ Vec_Wec_t * vSupps = Vec_WecStart( Gia_ManObjNum(p) );
+ Gia_ManForEachCiId( p, Id, i )
+ Vec_IntPush( Vec_WecEntry(vSupps, Id), i );
+ Gia_ManForEachAnd( p, pObj, Id )
+ Vec_IntTwoMerge2( Vec_WecEntry(vSupps, Gia_ObjFaninId0(pObj, Id)),
+ Vec_WecEntry(vSupps, Gia_ObjFaninId1(pObj, Id)),
+ Vec_WecEntry(vSupps, Id) );
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ Vec_IntAppend( Vec_WecEntry(vSuppsNo, i), Vec_WecEntry(vSupps, Gia_ObjId(p, pObj)) );
+ Vec_WecFree( vSupps );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Support computation", Abc_Clock() - clk );
+ return vSuppsNo;
+}
+
Vec_Wec_t * Gia_ManCreateCoSupps( Gia_Man_t * p, int fVerbose )
{
abctime clk = Abc_Clock();
@@ -3690,6 +3886,81 @@ Gia_Man_t * Gia_ManDupDemiter( Gia_Man_t * p, int fVerbose )
SeeAlso []
***********************************************************************/
+void Gia_ManDupDemiterOrderXors2( Gia_Man_t * p, Vec_Int_t * vXors )
+{
+ int i, iObj, * pPerm;
+ Vec_Int_t * vSizes = Vec_IntAlloc( 100 );
+ Vec_IntForEachEntry( vXors, iObj, i )
+ Vec_IntPush( vSizes, Gia_ManSuppSize(p, &iObj, 1) );
+ pPerm = Abc_MergeSortCost( Vec_IntArray(vSizes), Vec_IntSize(vSizes) );
+ Vec_IntClear( vSizes );
+ for ( i = 0; i < Vec_IntSize(vXors); i++ )
+ Vec_IntPush( vSizes, Vec_IntEntry(vXors, pPerm[i]) );
+ ABC_FREE( pPerm );
+ Vec_IntClear( vXors );
+ Vec_IntAppend( vXors, vSizes );
+ Vec_IntFree( vSizes );
+}
+int Gia_ManDupDemiterFindMin( Vec_Wec_t * vSupps, Vec_Int_t * vTakenIns, Vec_Int_t * vTakenOuts )
+{
+ Vec_Int_t * vLevel;
+ int i, k, iObj, iObjBest = -1;
+ int Count, CountBest = ABC_INFINITY;
+ Vec_WecForEachLevel( vSupps, vLevel, i )
+ {
+ if ( Vec_IntEntry(vTakenOuts, i) )
+ continue;
+ Count = 0;
+ Vec_IntForEachEntry( vLevel, iObj, k )
+ Count += !Vec_IntEntry(vTakenIns, iObj);
+ if ( CountBest > Count )
+ {
+ CountBest = Count;
+ iObjBest = i;
+ }
+ }
+ return iObjBest;
+}
+void Gia_ManDupDemiterOrderXors( Gia_Man_t * p, Vec_Int_t * vXors )
+{
+ extern Vec_Wec_t * Gia_ManCreateNodeSupps( Gia_Man_t * p, Vec_Int_t * vNodes, int fVerbose );
+ Vec_Wec_t * vSupps = Gia_ManCreateNodeSupps( p, vXors, 0 );
+ Vec_Int_t * vTakenIns = Vec_IntStart( Gia_ManCiNum(p) );
+ Vec_Int_t * vTakenOuts = Vec_IntStart( Vec_IntSize(vXors) );
+ Vec_Int_t * vOrder = Vec_IntAlloc( Vec_IntSize(vXors) );
+ int i, k, iObj;
+ // add outputs in the order of increasing supports
+ for ( i = 0; i < Vec_IntSize(vXors); i++ )
+ {
+ int Index = Gia_ManDupDemiterFindMin( vSupps, vTakenIns, vTakenOuts );
+ assert( Index >= 0 && Index < Vec_IntSize(vXors) );
+ Vec_IntPush( vOrder, Vec_IntEntry(vXors, Index) );
+ assert( !Vec_IntEntry( vTakenOuts, Index ) );
+ Vec_IntWriteEntry( vTakenOuts, Index, 1 );
+ Vec_IntForEachEntry( Vec_WecEntry(vSupps, Index), iObj, k )
+ Vec_IntWriteEntry( vTakenIns, iObj, 1 );
+ }
+ Vec_WecFree( vSupps );
+ Vec_IntFree( vTakenIns );
+ Vec_IntFree( vTakenOuts );
+ // reload
+ Vec_IntClear( vXors );
+ Vec_IntAppend( vXors, vOrder );
+ Vec_IntFree( vOrder );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
void Gia_ManSetMark0Dfs_rec( Gia_Man_t * p, int iObj )
{
Gia_Obj_t * pObj;
@@ -3781,27 +4052,26 @@ void Gia_ManCollectTopXors_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vXo
}
Vec_Int_t * Gia_ManCollectTopXors( Gia_Man_t * p )
{
- int i, iObj, iObj2, fFlip, * pPerm, Count1 = 0;
- Vec_Int_t * vXors, * vSizes, * vPart[2], * vOrder;
+ int i, iObj, iObj2, fFlip, Count1 = 0;
+ Vec_Int_t * vXors, * vPart[2], * vOrder;
Gia_Obj_t * pFan[2], * pObj = Gia_ManCo(p, 0);
- assert( Gia_ManCoNum(p) == 1 );
vXors = Vec_IntAlloc( 100 );
- if ( Gia_ObjFaninC0(pObj) )
- Gia_ManCollectTopXors_rec( p, Gia_ObjFanin0(pObj), vXors );
+ if ( Gia_ManCoNum(p) == 1 )
+ {
+ if ( Gia_ObjFaninC0(pObj) )
+ Gia_ManCollectTopXors_rec( p, Gia_ObjFanin0(pObj), vXors );
+ else
+ Vec_IntPush( vXors, Gia_ObjId(p, Gia_ObjFanin0(pObj)) );
+ }
else
- Vec_IntPush( vXors, Gia_ObjId(p, Gia_ObjFanin0(pObj)) );
+ {
+ Gia_ManForEachCo( p, pObj, i )
+ if ( Gia_ObjFaninId0p(p, pObj) > 0 )
+ Vec_IntPush( vXors, Gia_ObjFaninId0p(p, pObj) );
+ }
// order by support size
- vSizes = Vec_IntAlloc( 100 );
- Vec_IntForEachEntry( vXors, iObj, i )
- Vec_IntPush( vSizes, Gia_ManSuppSize(p, &iObj, 1) );
- pPerm = Abc_MergeSortCost( Vec_IntArray(vSizes), Vec_IntSize(vSizes) );
- Vec_IntClear( vSizes );
- for ( i = 0; i < Vec_IntSize(vXors); i++ )
- Vec_IntPush( vSizes, Vec_IntEntry(vXors, pPerm[i]) );
- ABC_FREE( pPerm );
- Vec_IntClear( vXors );
- Vec_IntAppend( vXors, vSizes );
- Vec_IntFree( vSizes );
+ Gia_ManDupDemiterOrderXors( p, vXors );
+ //Vec_IntPrint( vXors );
Vec_IntReverseOrder( vXors ); // from MSB to LSB
// divide into groups
Gia_ManCleanMark01(p);
diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c
index 584be4cd..f41db898 100644
--- a/src/aig/gia/giaEquiv.c
+++ b/src/aig/gia/giaEquiv.c
@@ -129,7 +129,7 @@ Gia_Man_t * Gia_ManOrigIdsReduce( Gia_Man_t * p, Vec_Int_t * vPairs )
}
Gia_ManHashStop( pNew );
Gia_ManForEachCo( p, pObj, i )
- Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
Vec_IntFree( vMap );
// compute equivalences
assert( !p->pReprs && !p->pNexts );
@@ -171,6 +171,31 @@ Gia_Man_t * Gia_ManOrigIdsReduceTest( Gia_Man_t * p, Vec_Int_t * vPairs )
/**Function*************************************************************
+ Synopsis [Compute equivalence classes of nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManComputeGiaEquivs( Gia_Man_t * pGia, int nConfs, int fVerbose )
+{
+ Gia_Man_t * pTemp;
+ Cec_ParFra_t ParsFra, * pPars = &ParsFra;
+ Cec_ManFraSetDefaultParams( pPars );
+ pPars->fUseOrigIds = 1;
+ pPars->fSatSweeping = 1;
+ pPars->nBTLimit = nConfs;
+ pPars->fVerbose = fVerbose;
+ pTemp = Cec_ManSatSweeping( pGia, pPars, 0 );
+ Gia_ManStop( pTemp );
+ return Gia_ManOrigIdsReduce( pGia, pGia->vIdsEquiv );
+}
+
+/**Function*************************************************************
+
Synopsis [Returns 1 if AIG is not in the required topo order.]
Description []
@@ -460,7 +485,7 @@ void Gia_ManEquivPrintClasses( Gia_Man_t * p, int fVerbose, float Mem )
if ( fVerbose )
{
// int Ent;
- Abc_Print( 1, "Const0 = " );
+ Abc_Print( 1, "Const0 (%d) = ", Counter0 );
Gia_ManForEachConst( p, i )
Abc_Print( 1, "%d ", i );
Abc_Print( 1, "\n" );
diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c
index 26f549d0..ab80a762 100644
--- a/src/aig/gia/giaIf.c
+++ b/src/aig/gia/giaIf.c
@@ -539,33 +539,25 @@ void Gia_ManPrintMappingStats( Gia_Man_t * p, char * pDumpFile )
{
sprintf( FileNameOld, "%s", p->pName );
fprintf( pTable, "\n" );
- fprintf( pTable, "%s ", p->pName );
-// fprintf( pTable, "%d ", Gia_ManCiNum(p) );
-// fprintf( pTable, "%d ", Gia_ManCoNum(p) );
-// fprintf( pTable, "%d ", Gia_ManAndNum(p) );
-// fprintf( pTable, "%d ", Gia_ManPiNum(p) - Gia_ManBoxCiNum(p) - Gia_ManRegBoxNum(p) );
-// fprintf( pTable, "%d ", Gia_ManPoNum(p) - Gia_ManBoxCoNum(p) - Gia_ManRegBoxNum(p) );
-// fprintf( pTable, "%d ", Gia_ManClockDomainNum(p) );
-
+ fprintf( pTable, "%s ", p->pName );
fprintf( pTable, " " );
- fprintf( pTable, "%d ", p->MappedDelay );
- fprintf( pTable, "%d ", p->MappedArea );
- fprintf( pTable, "%d ", nFanins );
- fprintf( pTable, "%d ", LevelMax );
+ fprintf( pTable, "%d ", Gia_ManAndNum(p) );
fprintf( pTable, "%d ", nLuts );
-// fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) );
-// fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) );
+ fprintf( pTable, "%d ", Gia_ManLutLevelWithBoxes(p) );
+ //fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) );
+ //fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) );
+ //fprintf( pTable, "%.2f", 1.0*(Abc_Clock() - clk)/CLOCKS_PER_SEC );
clk = Abc_Clock();
}
else
{
- printf( "This part of the code is currently not used.\n" );
- assert( 0 );
+ //printf( "This part of the code is currently not used.\n" );
+ //assert( 0 );
fprintf( pTable, " " );
fprintf( pTable, "%d ", nLuts );
- fprintf( pTable, "%d ", LevelMax );
- fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) );
- fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) );
+ fprintf( pTable, "%d ", Gia_ManLutLevelWithBoxes(p) );
+ //fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) );
+ //fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) );
fprintf( pTable, "%.2f", 1.0*(Abc_Clock() - clk)/CLOCKS_PER_SEC );
clk = Abc_Clock();
}
@@ -2014,7 +2006,7 @@ void Gia_ManMappingVerify( Gia_Man_t * p )
void Gia_ManTransferMapping( Gia_Man_t * p, Gia_Man_t * pGia )
{
Gia_Obj_t * pObj;
- int i, k, iFan;
+ int i, k, iFan, iPlace;
if ( !Gia_ManHasMapping(pGia) )
return;
Gia_ManMappingVerify( pGia );
@@ -2023,12 +2015,20 @@ void Gia_ManTransferMapping( Gia_Man_t * p, Gia_Man_t * pGia )
Vec_IntFill( p->vMapping, Gia_ManObjNum(p), 0 );
Gia_ManForEachLut( pGia, i )
{
+ if ( Gia_ObjValue(Gia_ManObj(pGia, i)) == ~0 ) // handle dangling LUT
+ continue;
assert( !Abc_LitIsCompl(Gia_ObjValue(Gia_ManObj(pGia, i))) );
pObj = Gia_ManObj( p, Abc_Lit2Var(Gia_ObjValue(Gia_ManObj(pGia, i))) );
Vec_IntWriteEntry( p->vMapping, Gia_ObjId(p, pObj), Vec_IntSize(p->vMapping) );
+ iPlace = Vec_IntSize( p->vMapping );
Vec_IntPush( p->vMapping, Gia_ObjLutSize(pGia, i) );
Gia_LutForEachFanin( pGia, i, iFan, k )
- Vec_IntPush( p->vMapping, Abc_Lit2Var(Gia_ObjValue(Gia_ManObj(pGia, iFan))) );
+ {
+ if ( Gia_ObjValue(Gia_ManObj(pGia, iFan)) == ~0 ) // handle dangling LUT fanin
+ Vec_IntAddToEntry( p->vMapping, iPlace, -1 );
+ else
+ Vec_IntPush( p->vMapping, Abc_Lit2Var(Gia_ObjValue(Gia_ManObj(pGia, iFan))) );
+ }
iFan = Abc_Lit2Var( Gia_ObjValue(Gia_ManObj(pGia, Abc_AbsInt(Gia_ObjLutMuxId(pGia, i)))) );
Vec_IntPush( p->vMapping, Gia_ObjLutIsMux(pGia, i) ? -iFan : iFan );
}
diff --git a/src/aig/gia/giaJf.c b/src/aig/gia/giaJf.c
index 93dac301..205ab408 100644
--- a/src/aig/gia/giaJf.c
+++ b/src/aig/gia/giaJf.c
@@ -36,6 +36,7 @@ ABC_NAMESPACE_IMPL_START
#define JF_LEAF_MAX 8
#define JF_WORD_MAX ((JF_LEAF_MAX > 6) ? 1 << (JF_LEAF_MAX-6) : 1)
#define JF_CUT_MAX 16
+#define JF_EPSILON 0.005
typedef struct Jf_Cut_t_ Jf_Cut_t;
struct Jf_Cut_t_
@@ -940,15 +941,16 @@ float Jf_CutCompareDelay( Jf_Cut_t * pOld, Jf_Cut_t * pNew )
{
if ( pOld->Time != pNew->Time ) return pOld->Time - pNew->Time;
if ( pOld->pCut[0] != pNew->pCut[0] ) return pOld->pCut[0] - pNew->pCut[0];
- if ( pOld->Flow != pNew->Flow ) return pOld->Flow - pNew->Flow;
+// if ( pOld->Flow != pNew->Flow ) return pOld->Flow - pNew->Flow;
+ if ( pOld->Flow < pNew->Flow - JF_EPSILON ) return -1;
+ if ( pOld->Flow > pNew->Flow + JF_EPSILON ) return 1;
return 0;
}
float Jf_CutCompareArea( Jf_Cut_t * pOld, Jf_Cut_t * pNew )
{
-// float Epsilon = (float)0.001;
-// if ( pOld->Flow > pNew->Flow + Epsilon ) return 1;
-// if ( pOld->Flow < pNew->Flow - Epsilon ) return -1;
- if ( pOld->Flow != pNew->Flow ) return pOld->Flow - pNew->Flow;
+// if ( pOld->Flow != pNew->Flow ) return pOld->Flow - pNew->Flow;
+ if ( pOld->Flow < pNew->Flow - JF_EPSILON ) return -1;
+ if ( pOld->Flow > pNew->Flow + JF_EPSILON ) return 1;
if ( pOld->pCut[0] != pNew->pCut[0] ) return pOld->pCut[0] - pNew->pCut[0];
if ( pOld->Time != pNew->Time ) return pOld->Time - pNew->Time;
return 0;
@@ -1256,10 +1258,10 @@ void Jf_ManComputeCuts( Jf_Man_t * p, int fEdge )
}
if ( p->pPars->fVerbose )
{
- printf( "CutPair = %lu ", p->CutCount[0] );
- printf( "Merge = %lu ", p->CutCount[1] );
- printf( "Eval = %lu ", p->CutCount[2] );
- printf( "Cut = %lu ", p->CutCount[3] );
+ printf( "CutPair = %lu ", (long)p->CutCount[0] );
+ printf( "Merge = %lu ", (long)p->CutCount[1] );
+ printf( "Eval = %lu ", (long)p->CutCount[2] );
+ printf( "Cut = %lu ", (long)p->CutCount[3] );
Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
printf( "Memory: " );
printf( "Gia = %.2f MB ", Gia_ManMemory(p->pGia) / (1<<20) );
@@ -1367,7 +1369,7 @@ void Jf_ObjComputeBestCut( Jf_Man_t * p, Gia_Obj_t * pObj, int fEdge, int fEla )
if ( fEdge && !fEla )
Jf_CutSetCost(pCut, Jf_CutSize(pCut));
Area = fEla ? Jf_CutArea(p, pCut, fEdge) : Jf_CutFlow(p, pCut) + Jf_CutCost(pCut);
- if ( pCutBest == NULL || AreaBest > Area || (AreaBest == Area && TimeBest > (Time = Jf_CutArr(p, pCut))) )
+ if ( pCutBest == NULL || AreaBest > Area + JF_EPSILON || (AreaBest > Area - JF_EPSILON && TimeBest > (Time = Jf_CutArr(p, pCut))) )
pCutBest = pCut, AreaBest = Area, TimeBest = Time;
}
Vec_IntWriteEntry( &p->vArr, iObj, Jf_CutArr(p, pCutBest) );
@@ -1702,11 +1704,11 @@ void Jf_ManPrintStats( Jf_Man_t * p, char * pTitle )
if ( !p->pPars->fVerbose )
return;
printf( "%s : ", pTitle );
- printf( "Level =%6lu ", p->pPars->Delay );
- printf( "Area =%9lu ", p->pPars->Area );
- printf( "Edge =%9lu ", p->pPars->Edge );
+ printf( "Level =%6lu ", (long)p->pPars->Delay );
+ printf( "Area =%9lu ", (long)p->pPars->Area );
+ printf( "Edge =%9lu ", (long)p->pPars->Edge );
if ( p->pPars->fGenCnf )
- printf( "Cnf =%9lu ", p->pPars->Clause );
+ printf( "Cnf =%9lu ", (long)p->pPars->Clause );
Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
fflush( stdout );
}
diff --git a/src/aig/gia/giaKf.c b/src/aig/gia/giaKf.c
index caa88bfc..a823f726 100644
--- a/src/aig/gia/giaKf.c
+++ b/src/aig/gia/giaKf.c
@@ -1125,9 +1125,9 @@ void Kf_ManPrintStats( Kf_Man_t * p, char * pTitle )
if ( !p->pPars->fVerbose )
return;
printf( "%s : ", pTitle );
- printf( "Level =%6lu ", p->pPars->Delay );
- printf( "Area =%9lu ", p->pPars->Area );
- printf( "Edge =%9lu ", p->pPars->Edge );
+ printf( "Level =%6lu ", (long)p->pPars->Delay );
+ printf( "Area =%9lu ", (long)p->pPars->Area );
+ printf( "Edge =%9lu ", (long)p->pPars->Edge );
Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
fflush( stdout );
}
@@ -1173,10 +1173,10 @@ void Kf_ManComputeMapping( Kf_Man_t * p )
Kf_ManComputeRefs( p );
if ( p->pPars->fVerbose )
{
- printf( "CutPair = %lu ", p->pSett->CutCount[0] );
- printf( "Merge = %lu ", p->pSett->CutCount[1] );
- printf( "Eval = %lu ", p->pSett->CutCount[2] );
- printf( "Cut = %lu ", p->pSett->CutCount[3] );
+ printf( "CutPair = %lu ", (long)p->pSett->CutCount[0] );
+ printf( "Merge = %lu ", (long)p->pSett->CutCount[1] );
+ printf( "Eval = %lu ", (long)p->pSett->CutCount[2] );
+ printf( "Cut = %lu ", (long)p->pSett->CutCount[3] );
Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
printf( "Memory: " );
printf( "Gia = %.2f MB ", Gia_ManMemory(p->pGia) / (1<<20) );
diff --git a/src/aig/gia/giaLf.c b/src/aig/gia/giaLf.c
index 082b1928..2c216a9b 100644
--- a/src/aig/gia/giaLf.c
+++ b/src/aig/gia/giaLf.c
@@ -36,6 +36,7 @@ ABC_NAMESPACE_IMPL_START
#define LF_NO_LEAF 255
#define LF_CUT_WORDS (4+LF_LEAF_MAX/2)
#define LF_TT_WORDS ((LF_LEAF_MAX > 6) ? 1 << (LF_LEAF_MAX-6) : 1)
+#define LF_EPSILON 0.005
typedef struct Lf_Cut_t_ Lf_Cut_t;
struct Lf_Cut_t_
@@ -847,16 +848,16 @@ static inline int Lf_CutCompareDelay( Lf_Cut_t * pCut0, Lf_Cut_t * pCut1 )
if ( pCut0->Delay > pCut1->Delay ) return 1;
if ( pCut0->nLeaves < pCut1->nLeaves ) return -1;
if ( pCut0->nLeaves > pCut1->nLeaves ) return 1;
- if ( pCut0->Flow < pCut1->Flow ) return -1;
- if ( pCut0->Flow > pCut1->Flow ) return 1;
+ if ( pCut0->Flow < pCut1->Flow - LF_EPSILON ) return -1;
+ if ( pCut0->Flow > pCut1->Flow + LF_EPSILON ) return 1;
return 0;
}
static inline int Lf_CutCompareArea( Lf_Cut_t * pCut0, Lf_Cut_t * pCut1 )
{
if ( pCut0->fLate < pCut1->fLate ) return -1;
if ( pCut0->fLate > pCut1->fLate ) return 1;
- if ( pCut0->Flow < pCut1->Flow ) return -1;
- if ( pCut0->Flow > pCut1->Flow ) return 1;
+ if ( pCut0->Flow < pCut1->Flow - LF_EPSILON ) return -1;
+ if ( pCut0->Flow > pCut1->Flow + LF_EPSILON ) return 1;
if ( pCut0->Delay < pCut1->Delay ) return -1;
if ( pCut0->Delay > pCut1->Delay ) return 1;
if ( pCut0->nLeaves < pCut1->nLeaves ) return -1;
@@ -1304,7 +1305,7 @@ void Lf_ObjMergeOrder( Lf_Man_t * p, int iObj )
p->nCutEqual++;
// area cut
iCutUsed = 0;
- if ( nCutsR > 1 && pCutsR[0]->Flow > pCutsR[1]->Flow )//&& !pCutsR[1]->fLate ) // can remove !fLate
+ if ( nCutsR > 1 && pCutsR[0]->Flow > pCutsR[1]->Flow + LF_EPSILON )//&& !pCutsR[1]->fLate ) // can remove !fLate
{
pBest->Cut[1].Handle = Lf_MemSaveCut(&p->vStoreNew, pCutsR[1], iObj);
pBest->Delay[1] = pCutsR[1]->Delay;
@@ -2012,14 +2013,14 @@ void Lf_ManPrintStats( Lf_Man_t * p, char * pTitle )
if ( !p->pPars->fVerbose )
return;
printf( "%s : ", pTitle );
- printf( "Level =%6lu ", p->pPars->Delay );
- printf( "Area =%9lu ", p->pPars->Area );
- printf( "Edge =%9lu ", p->pPars->Edge );
- printf( "LUT =%9lu ", p->pPars->Area+p->nInverters );
+ printf( "Level =%6lu ", (long)p->pPars->Delay );
+ printf( "Area =%9lu ", (long)p->pPars->Area );
+ printf( "Edge =%9lu ", (long)p->pPars->Edge );
+ printf( "LUT =%9lu ", (long)p->pPars->Area+p->nInverters );
if ( Vec_FltSize(&p->vSwitches) )
printf( "Swt =%8.1f ", p->Switches );
if ( p->pPars->fUseMux7 )
- printf( "Mux7 =%7lu ", p->pPars->Mux7 );
+ printf( "Mux7 =%7lu ", (long)p->pPars->Mux7 );
Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
fflush( stdout );
}
diff --git a/src/aig/gia/giaMf.c b/src/aig/gia/giaMf.c
index 591f5bc5..24c1e6a0 100644
--- a/src/aig/gia/giaMf.c
+++ b/src/aig/gia/giaMf.c
@@ -37,6 +37,7 @@ ABC_NAMESPACE_IMPL_START
#define MF_NO_LEAF 31
#define MF_TT_WORDS ((MF_LEAF_MAX > 6) ? 1 << (MF_LEAF_MAX-6) : 1)
#define MF_NO_FUNC 134217727 // (1<<27)-1
+#define MF_EPSILON 0.005
typedef struct Mf_Cut_t_ Mf_Cut_t;
struct Mf_Cut_t_
@@ -387,6 +388,8 @@ Cnf_Dat_t * Mf_ManDeriveCnf( Mf_Man_t * p, int fCnfObjIds, int fAddOrCla )
Gia_ManForEachCoId( p->pGia, Id, i )
pCnf->pClauses[0][iLit++] = Abc_Var2Lit(pCnfIds[Id], 0);
}
+ if ( p->pPars->fCnfMapping )
+ pCnf->vMapping = Vec_IntStart( nVars );
// add clauses for the COs
Gia_ManForEachCo( p->pGia, pObj, i )
{
@@ -400,6 +403,14 @@ Cnf_Dat_t * Mf_ManDeriveCnf( Mf_Man_t * p, int fCnfObjIds, int fAddOrCla )
pCnf->pClauses[iCla++] = pCnf->pClauses[0] + iLit;
pCnf->pClauses[0][iLit++] = Abc_Var2Lit(pCnfIds[Id], 1);
pCnf->pClauses[0][iLit++] = Abc_Var2Lit(pCnfIds[DriId], Gia_ObjFaninC0(pObj));
+ // generate mapping
+ if ( pCnf->vMapping )
+ {
+ Vec_IntWriteEntry( pCnf->vMapping, pCnfIds[Id], Vec_IntSize(pCnf->vMapping) );
+ Vec_IntPush( pCnf->vMapping, 1 );
+ Vec_IntPush( pCnf->vMapping, pCnfIds[DriId] );
+ Vec_IntPush( pCnf->vMapping, Gia_ObjFaninC0(pObj) ? 0x55555555 : 0xAAAAAAAA );
+ }
}
// add clauses for the mapping
Gia_ManForEachAndReverseId( p->pGia, Id )
@@ -426,6 +437,35 @@ Cnf_Dat_t * Mf_ManDeriveCnf( Mf_Man_t * p, int fCnfObjIds, int fAddOrCla )
if ( Mf_CubeLit(pCubes[c], k) )
pCnf->pClauses[0][iLit++] = Abc_Var2Lit( pFanins[k], Mf_CubeLit(pCubes[c], k) == 2 );
}
+ // generate mapping
+ if ( pCnf->vMapping )
+ {
+ word pTruth[4], * pTruthP = Vec_MemReadEntry(p->vTtMem, iFunc);
+ assert( p->pPars->nLutSize <= 8 );
+ Abc_TtCopy( pTruth, pTruthP, Abc_Truth6WordNum(p->pPars->nLutSize), Abc_LitIsCompl(iFunc) );
+ assert( pCnfIds[Id] >= 0 && pCnfIds[Id] < nVars );
+ Vec_IntWriteEntry( pCnf->vMapping, pCnfIds[Id], Vec_IntSize(pCnf->vMapping) );
+ Vec_IntPush( pCnf->vMapping, Mf_CutSize(pCut) );
+ for ( k = 0; k < Mf_CutSize(pCut); k++ )
+ Vec_IntPush( pCnf->vMapping, pCnfIds[pCut[k+1]] );
+ Vec_IntPush( pCnf->vMapping, (unsigned)pTruth[0] );
+ if ( Mf_CutSize(pCut) >= 6 )
+ {
+ Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[0] >> 32) );
+ if ( Mf_CutSize(pCut) >= 7 )
+ {
+ Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[1]) );
+ Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[1] >> 32) );
+ }
+ if ( Mf_CutSize(pCut) >= 8 )
+ {
+ Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[2]) );
+ Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[2] >> 32) );
+ Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[3]) );
+ Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[3] >> 32) );
+ }
+ }
+ }
}
// constant clause
pCnf->pClauses[iCla++] = pCnf->pClauses[0] + iLit;
@@ -920,8 +960,8 @@ static inline int Mf_SetLastCutContainsArea( Mf_Cut_t ** pCuts, int nCuts )
}
static inline int Mf_CutCompareArea( Mf_Cut_t * pCut0, Mf_Cut_t * pCut1 )
{
- if ( pCut0->Flow < pCut1->Flow ) return -1;
- if ( pCut0->Flow > pCut1->Flow ) return 1;
+ if ( pCut0->Flow < pCut1->Flow - MF_EPSILON ) return -1;
+ if ( pCut0->Flow > pCut1->Flow + MF_EPSILON ) return 1;
if ( pCut0->Delay < pCut1->Delay ) return -1;
if ( pCut0->Delay > pCut1->Delay ) return 1;
if ( pCut0->nLeaves < pCut1->nLeaves ) return -1;
@@ -1415,11 +1455,11 @@ void Mf_ManPrintStats( Mf_Man_t * p, char * pTitle )
if ( !p->pPars->fVerbose )
return;
printf( "%s : ", pTitle );
- printf( "Level =%6lu ", p->pPars->Delay );
- printf( "Area =%9lu ", p->pPars->Area );
- printf( "Edge =%9lu ", p->pPars->Edge );
+ printf( "Level =%6lu ", (long)p->pPars->Delay );
+ printf( "Area =%9lu ", (long)p->pPars->Area );
+ printf( "Edge =%9lu ", (long)p->pPars->Edge );
if ( p->pPars->fGenCnf )
- printf( "CNF =%9lu ", p->pPars->Clause );
+ printf( "CNF =%9lu ", (long)p->pPars->Clause );
Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
fflush( stdout );
}
@@ -1544,7 +1584,7 @@ static inline void Mf_ObjComputeBestCut( Mf_Man_t * p, int iObj )
assert( !Mf_CutIsTriv(pCut, iObj) );
assert( Mf_CutSize(pCut) <= p->pPars->nLutSize );
Flow = p->fUseEla ? Mf_CutAreaDerefed(p, pCut) : Mf_CutFlow(p, pCut, &Time);
- if ( pCutBest == NULL || FlowBest > Flow || (FlowBest == Flow && TimeBest > Time) )
+ if ( pCutBest == NULL || FlowBest > Flow + MF_EPSILON || (FlowBest > Flow - MF_EPSILON && TimeBest > Time) )
pCutBest = pCut, FlowBest = Flow, TimeBest = Time;
}
assert( pCutBest != NULL );
@@ -1635,28 +1675,29 @@ Gia_Man_t * Mf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars )
SeeAlso []
***********************************************************************/
-Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose )
+void * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fMapping, int fVerbose )
{
Gia_Man_t * pNew;
Jf_Par_t Pars, * pPars = &Pars;
assert( nLutSize >= 3 && nLutSize <= 8 );
Mf_ManSetDefaultPars( pPars );
- pPars->fGenCnf = 1;
- pPars->fCoarsen = !fCnfObjIds;
- pPars->nLutSize = nLutSize;
- pPars->fCnfObjIds = fCnfObjIds;
- pPars->fAddOrCla = fAddOrCla;
- pPars->fVerbose = fVerbose;
+ pPars->fGenCnf = 1;
+ pPars->fCoarsen = !fCnfObjIds;
+ pPars->nLutSize = nLutSize;
+ pPars->fCnfObjIds = fCnfObjIds;
+ pPars->fAddOrCla = fAddOrCla;
+ pPars->fCnfMapping = fMapping;
+ pPars->fVerbose = fVerbose;
pNew = Mf_ManPerformMapping( pGia, pPars );
Gia_ManStopP( &pNew );
// Cnf_DataPrint( (Cnf_Dat_t *)pGia->pData, 1 );
- return (Cnf_Dat_t*)pGia->pData;
+ return pGia->pData;
}
void Mf_ManDumpCnf( Gia_Man_t * p, char * pFileName, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose )
{
abctime clk = Abc_Clock();
Cnf_Dat_t * pCnf;
- pCnf = Mf_ManGenerateCnf( p, nLutSize, fCnfObjIds, fAddOrCla, fVerbose );
+ pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, nLutSize, fCnfObjIds, fAddOrCla, 0, fVerbose );
Cnf_DataWriteIntoFile( pCnf, pFileName, 0, NULL, NULL );
// if ( fVerbose )
{
diff --git a/src/aig/gia/giaMfs.c b/src/aig/gia/giaMfs.c
index 3ff16978..3229e0d0 100644
--- a/src/aig/gia/giaMfs.c
+++ b/src/aig/gia/giaMfs.c
@@ -451,6 +451,7 @@ Gia_Man_t * Gia_ManPerformMfs( Gia_Man_t * p, Sfm_Par_t * pPars )
nNodes = Sfm_NtkPerform( pNtk, pPars );
if ( nNodes == 0 )
{
+ if ( p->pManTime )
Abc_Print( 1, "The network is not changed by \"&mfs\".\n" );
pNew = Gia_ManDup( p );
pNew->vMapping = Vec_IntDup( p->vMapping );
diff --git a/src/aig/gia/giaMini.c b/src/aig/gia/giaMini.c
index a886311f..67805d44 100644
--- a/src/aig/gia/giaMini.c
+++ b/src/aig/gia/giaMini.c
@@ -21,6 +21,7 @@
#include "gia.h"
#include "opt/dau/dau.h"
#include "base/main/main.h"
+#include "misc/util/utilTruth.h"
#include "aig/miniaig/miniaig.h"
#include "aig/miniaig/minilut.h"
@@ -247,6 +248,34 @@ Gia_Man_t * Gia_ManFromMiniLut( Mini_Lut_t * p )
/**Function*************************************************************
+ Synopsis [Marks LUTs that should be complemented.]
+
+ Description [These are LUTs whose all PO fanouts require them
+ in negative polarity. Other fanouts may require them in
+ positive polarity.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Bit_t * Gia_ManFindComplLuts( Gia_Man_t * pGia )
+{
+ Gia_Obj_t * pObj; int i;
+ // mark objects pointed by COs in negative polarity
+ Vec_Bit_t * vMarks = Vec_BitStart( Gia_ManObjNum(pGia) );
+ Gia_ManForEachCo( pGia, pObj, i )
+ if ( Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) && Gia_ObjFaninC0(pObj) )
+ Vec_BitWriteEntry( vMarks, Gia_ObjFaninId0p(pGia, pObj), 1 );
+ // unmark objects pointed by COs in positive polarity
+ Gia_ManForEachCo( pGia, pObj, i )
+ if ( Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) && !Gia_ObjFaninC0(pObj) )
+ Vec_BitWriteEntry( vMarks, Gia_ObjFaninId0p(pGia, pObj), 0 );
+ return vMarks;
+}
+
+/**Function*************************************************************
+
Synopsis [Converts GIA into MiniLUT.]
Description []
@@ -260,11 +289,13 @@ Mini_Lut_t * Gia_ManToMiniLut( Gia_Man_t * pGia )
{
Mini_Lut_t * p;
Vec_Wrd_t * vTruths;
+ Vec_Bit_t * vMarks;
Gia_Obj_t * pObj, * pFanin;
- int i, k, LutSize, pVars[16];
+ int i, k, iFanin, LutSize, pVars[16];
word Truth;
assert( Gia_ManHasMapping(pGia) );
LutSize = Gia_ManLutSizeMax( pGia );
+ LutSize = Abc_MaxInt( LutSize, 2 );
assert( LutSize >= 2 );
// create the manager
p = Mini_LutStart( LutSize );
@@ -274,12 +305,17 @@ Mini_Lut_t * Gia_ManToMiniLut( Gia_Man_t * pGia )
pObj->Value = Mini_LutCreatePi(p);
// create internal nodes
vTruths = Vec_WrdStart( Gia_ManObjNum(pGia) );
+ vMarks = Gia_ManFindComplLuts( pGia );
Gia_ManForEachLut( pGia, i )
{
pObj = Gia_ManObj( pGia, i );
Gia_LutForEachFaninObj( pGia, i, pFanin, k )
pVars[k] = pFanin->Value;
Truth = Gia_LutComputeTruth6( pGia, i, vTruths );
+ Truth = Vec_BitEntry(vMarks, i) ? ~Truth : Truth;
+ Gia_LutForEachFanin( pGia, i, iFanin, k )
+ if ( Vec_BitEntry(vMarks, iFanin) )
+ Truth = Abc_Tt6Flip( Truth, k );
pObj->Value = Mini_LutCreateNode( p, Gia_ObjLutSize(pGia, i), pVars, (unsigned *)&Truth );
}
Vec_WrdFree( vTruths );
@@ -288,7 +324,7 @@ Mini_Lut_t * Gia_ManToMiniLut( Gia_Man_t * pGia )
{
if ( Gia_ObjFanin0(pObj) == Gia_ManConst0(pGia) )
pObj->Value = Mini_LutCreatePo( p, Gia_ObjFaninC0(pObj) );
- else if ( !Gia_ObjFaninC0(pObj) )
+ else if ( Gia_ObjFaninC0(pObj) == Vec_BitEntry(vMarks, Gia_ObjFaninId0p(pGia, pObj)) )
pObj->Value = Mini_LutCreatePo( p, Gia_ObjFanin0(pObj)->Value );
else // add inverter LUT
{
@@ -298,6 +334,7 @@ Mini_Lut_t * Gia_ManToMiniLut( Gia_Man_t * pGia )
pObj->Value = Mini_LutCreatePo( p, LutInv );
}
}
+ Vec_BitFree( vMarks );
// set registers
Mini_LutSetRegNum( p, Gia_ManRegNum(pGia) );
//Mini_LutPrintStats( p );
diff --git a/src/aig/gia/giaNf.c b/src/aig/gia/giaNf.c
index 6761b617..6f1d0c8d 100644
--- a/src/aig/gia/giaNf.c
+++ b/src/aig/gia/giaNf.c
@@ -41,6 +41,7 @@ ABC_NAMESPACE_IMPL_START
#define NF_CUT_MAX 32
#define NF_NO_LEAF 31
#define NF_NO_FUNC 0x3FFFFFF
+#define NF_EPSILON 0.001
typedef struct Nf_Cut_t_ Nf_Cut_t;
struct Nf_Cut_t_
@@ -171,7 +172,7 @@ static inline int Nf_CfgCompl( Nf_Cfg_t Cfg, int i )
int Nf_StoCellIsDominated( Mio_Cell2_t * pCell, int * pFans, int * pProf )
{
int k;
- if ( pCell->AreaF < Abc_Int2Float(pProf[0]) )
+ if ( pCell->AreaF + NF_EPSILON < Abc_Int2Float(pProf[0]) )
return 0;
for ( k = 0; k < (int)pCell->nFanins; k++ )
if ( pCell->iDelays[Abc_Lit2Var(pFans[k])] < pProf[k+1] )
@@ -802,8 +803,8 @@ static inline int Nf_CutCompareArea( Nf_Cut_t * pCut0, Nf_Cut_t * pCut1 )
{
if ( pCut0->Useless < pCut1->Useless ) return -1;
if ( pCut0->Useless > pCut1->Useless ) return 1;
- if ( pCut0->Flow < pCut1->Flow ) return -1;
- if ( pCut0->Flow > pCut1->Flow ) return 1;
+ if ( pCut0->Flow < pCut1->Flow - NF_EPSILON ) return -1;
+ if ( pCut0->Flow > pCut1->Flow + NF_EPSILON ) return 1;
if ( pCut0->Delay < pCut1->Delay ) return -1;
if ( pCut0->Delay > pCut1->Delay ) return 1;
if ( pCut0->nLeaves < pCut1->nLeaves ) return -1;
@@ -1162,7 +1163,7 @@ void Nf_ManCutMatchOne( Nf_Man_t * p, int iObj, int * pCut, int * pCutSet )
pD->Cfg.fCompl = 0;
}
- if ( pA->F > AreaF )
+ if ( pA->F > AreaF + NF_EPSILON )
{
pA->D = Delay;
pA->F = AreaF;
@@ -1310,7 +1311,7 @@ void Nf_ManCutMatch( Nf_Man_t * p, int iObj )
}
//assert( pAp->F < FLT_MAX || pAn->F < FLT_MAX );
// try replacing pos with neg
- if ( pAp->D == SCL_INFINITY || (pAp->F > pAn->F + p->InvAreaF && pAn->D + p->InvDelayI <= Required[0]) )
+ if ( pAp->D == SCL_INFINITY || (pAp->F > pAn->F + p->InvAreaF + NF_EPSILON && pAn->D + p->InvDelayI <= Required[0]) )
{
assert( p->Iter > 0 );
*pAp = *pAn;
@@ -1322,7 +1323,7 @@ void Nf_ManCutMatch( Nf_Man_t * p, int iObj )
//printf( "Using inverter to improve area at node %d in phase %d.\n", iObj, 1 );
}
// try replacing neg with pos
- else if ( pAn->D == SCL_INFINITY || (pAn->F > pAp->F + p->InvAreaF && pAp->D + p->InvDelayI <= Required[1]) )
+ else if ( pAn->D == SCL_INFINITY || (pAn->F > pAp->F + p->InvAreaF + NF_EPSILON && pAp->D + p->InvDelayI <= Required[1]) )
{
assert( p->Iter > 0 );
*pAn = *pAp;
@@ -1778,7 +1779,7 @@ void Nf_ManElaBestMatchOne( Nf_Man_t * p, int iObj, int c, int * pCut, int * pCu
pMb->Cfg = Nf_Int2Cfg(0);
pMb->fBest = 1;
// compare
- if ( pRes->F > pMb->F || (pRes->F == pMb->F && pRes->D > pMb->D) )
+ if ( pRes->F > pMb->F + NF_EPSILON || (pRes->F > pMb->F - NF_EPSILON && pRes->D > pMb->D) )
*pRes = *pMb;
return;
}
@@ -1814,7 +1815,7 @@ void Nf_ManElaBestMatchOne( Nf_Man_t * p, int iObj, int c, int * pCut, int * pCu
// compute area
pMb->F = Scl_Int2Flt((int)Nf_MatchRefArea(p, iObj, c, pMb, Required));
// compare
- if ( pRes->F > pMb->F || (pRes->F == pMb->F && pRes->D > pMb->D) )
+ if ( pRes->F > pMb->F + NF_EPSILON || (pRes->F > pMb->F - NF_EPSILON && pRes->D > pMb->D) )
*pRes = *pMb;
}
}
diff --git a/src/aig/gia/giaQbf.c b/src/aig/gia/giaQbf.c
index 4ca0bac3..2dfd83fc 100644
--- a/src/aig/gia/giaQbf.c
+++ b/src/aig/gia/giaQbf.c
@@ -48,8 +48,6 @@ struct Qbf_Man_t_
abctime clkSat; // SAT solver time
};
-extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
-
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -192,7 +190,7 @@ int Gia_ManSatEnum( Gia_Man_t * pGia, int nConfLimit, int nTimeOut, int fVerbose
int i, iLit, iParVarBeg, Iter;
int nSolutions = 0, RetValue = 0;
abctime clkStart = Abc_Clock();
- pCnf = Mf_ManGenerateCnf( pGia, 8, 0, 1, 0 );
+ pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pGia, 8, 0, 1, 0, 0 );
pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
iParVarBeg = pCnf->nVars - Gia_ManPiNum(pGia);// - 1;
Cnf_DataFree( pCnf );
@@ -247,7 +245,7 @@ void Gia_QbfDumpFile( Gia_Man_t * pGia, int nPars )
{
// original problem: \exists p \forall x \exists y. M(p,x,y)
// negated problem: \forall p \exists x \exists y. !M(p,x,y)
- Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( pGia, 8, 0, 1, 0 );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pGia, 8, 0, 1, 0, 0 );
Vec_Int_t * vVarMap, * vForAlls, * vExists;
Gia_Obj_t * pObj;
char * pFileName;
@@ -291,7 +289,7 @@ Qbf_Man_t * Gia_QbfAlloc( Gia_Man_t * pGia, int nPars, int fVerbose )
Qbf_Man_t * p;
Cnf_Dat_t * pCnf;
Gia_ObjFlipFaninC0( Gia_ManPo(pGia, 0) );
- pCnf = Mf_ManGenerateCnf( pGia, 8, 0, 1, 0 );
+ pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pGia, 8, 0, 1, 0, 0 );
Gia_ObjFlipFaninC0( Gia_ManPo(pGia, 0) );
p = ABC_CALLOC( Qbf_Man_t, 1 );
p->clkStart = Abc_Clock();
@@ -426,7 +424,7 @@ Gia_Man_t * Gia_QbfCofactor( Gia_Man_t * p, int nPars, Vec_Int_t * vValues, Vec_
/*
int Gia_QbfAddCofactor( Qbf_Man_t * p, Gia_Man_t * pCof )
{
- Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( pCof, 8, 0, 1, 0 );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pCof, 8, 0, 1, 0, 0 );
int i, iFirstVar = sat_solver_nvars(p->pSatSyn) + pCnf->nVars - Gia_ManPiNum(pCof);// - 1;
pCnf->pMan = NULL;
Cnf_DataLift( pCnf, sat_solver_nvars(p->pSatSyn) );
@@ -459,7 +457,7 @@ void Cnf_SpecialDataLift( Cnf_Dat_t * p, int nVarsPlus, int firstPiVar, int last
int Gia_QbfAddCofactor( Qbf_Man_t * p, Gia_Man_t * pCof )
{
- Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( pCof, 8, 0, 1, 0 );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pCof, 8, 0, 1, 0, 0 );
int i, useold = 0;
int iFirstVar = useold ? sat_solver_nvars(p->pSatSyn) + pCnf->nVars - Gia_ManPiNum(pCof) : pCnf->nVars - Gia_ManPiNum(pCof); //-1
pCnf->pMan = NULL;
diff --git a/src/aig/gia/giaSatoko.c b/src/aig/gia/giaSatoko.c
new file mode 100644
index 00000000..5e04502d
--- /dev/null
+++ b/src/aig/gia/giaSatoko.c
@@ -0,0 +1,205 @@
+/**CFile****************************************************************
+
+ FileName [giaSatoko.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Interface to Satoko solver.]
+
+ Author [Alan Mishchenko, Bruno Schmitt]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaSatoko.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+#include "sat/cnf/cnf.h"
+#include "sat/satoko/satoko.h"
+#include "sat/satoko/solver.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManCollectVars_rec( int Var, Vec_Int_t * vMapping, Vec_Int_t * vRes, Vec_Bit_t * vVisit )
+{
+ int * pCut, i;
+ if ( Vec_BitEntry(vVisit, Var) )
+ return;
+ Vec_BitWriteEntry(vVisit, Var, 1);
+ if ( Vec_IntEntry(vMapping, Var) ) // primary input or constant 0
+ {
+ pCut = Vec_IntEntryP( vMapping, Vec_IntEntry(vMapping, Var) );
+ for ( i = 1; i <= pCut[0]; i++ )
+ Gia_ManCollectVars_rec( pCut[i], vMapping, vRes, vVisit );
+ }
+ Vec_IntPush( vRes, Var );
+}
+Vec_Int_t * Gia_ManCollectVars( int Root, Vec_Int_t * vMapping, int nVars )
+{
+ Vec_Int_t * vRes = Vec_IntAlloc( 100 );
+ Vec_Bit_t * vVisit = Vec_BitStart( nVars );
+ assert( Vec_IntEntry(vMapping, Root) );
+ Gia_ManCollectVars_rec( Root, vMapping, vRes, vVisit );
+ Vec_BitFree( vVisit );
+ return vRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+satoko_t * Gia_ManSatokoInit( Cnf_Dat_t * pCnf, satoko_opts_t * opts )
+{
+ satoko_t * pSat = satoko_create();
+ int i;
+ //sat_solver_setnvars( pSat, p->nVars );
+ for ( i = 0; i < pCnf->nClauses; i++ )
+ {
+ if ( !satoko_add_clause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1]-pCnf->pClauses[i] ) )
+ {
+ satoko_destroy( pSat );
+ return NULL;
+ }
+ }
+ satoko_configure(pSat, opts);
+ return pSat;
+}
+void Gia_ManSatokoReport( int iOutput, int status, abctime clk )
+{
+ if ( iOutput >= 0 )
+ Abc_Print( 1, "Output %6d : ", iOutput );
+ else
+ Abc_Print( 1, "Total: " );
+
+ if ( status == SATOKO_UNDEC )
+ Abc_Print( 1, "UNDECIDED " );
+ else if ( status == SATOKO_SAT )
+ Abc_Print( 1, "SATISFIABLE " );
+ else
+ Abc_Print( 1, "UNSATISFIABLE " );
+
+ Abc_PrintTime( 1, "Time", clk );
+}
+satoko_t * Gia_ManSatokoCreate( Gia_Man_t * p, satoko_opts_t * opts )
+{
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 1, 0, 0 );
+ satoko_t * pSat = Gia_ManSatokoInit( pCnf, opts );
+ int status = pSat ? satoko_simplify(pSat) : SATOKO_OK;
+ Cnf_DataFree( pCnf );
+ if ( status == SATOKO_OK )
+ return pSat;
+ satoko_destroy( pSat );
+ return NULL;
+}
+int Gia_ManSatokoCallOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput )
+{
+ abctime clk = Abc_Clock();
+ satoko_t * pSat;
+ int status, Cost = 0;
+
+ pSat = Gia_ManSatokoCreate( p, opts );
+ if ( pSat )
+ {
+ status = satoko_solve( pSat );
+ Cost = (unsigned)pSat->stats.n_conflicts;
+ satoko_destroy( pSat );
+ }
+ else
+ status = SATOKO_UNSAT;
+
+ Gia_ManSatokoReport( iOutput, status, Abc_Clock() - clk );
+ return Cost;
+}
+void Gia_ManSatokoCall( Gia_Man_t * p, satoko_opts_t * opts, int fSplit, int fIncrem )
+{
+ int fUseCone = 1;
+ Gia_Man_t * pOne;
+ Gia_Obj_t * pRoot;
+ Vec_Int_t * vCone;
+ int i, iLit, status;
+ if ( fIncrem )
+ {
+ abctime clk = Abc_Clock();
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, fUseCone, 0 );
+ satoko_t * pSat = Gia_ManSatokoInit( pCnf, opts );
+ Gia_ManForEachCo( p, pRoot, i )
+ {
+ abctime clk = Abc_Clock();
+ iLit = Abc_Var2Lit( i+1, 0 );
+ satoko_assump_push( pSat, iLit );
+ if ( fUseCone )
+ {
+ vCone = Gia_ManCollectVars( i+1, pCnf->vMapping, pCnf->nVars );
+ satoko_mark_cone( pSat, Vec_IntArray(vCone), Vec_IntSize(vCone) );
+ printf( "Cone has %6d vars (out of %6d). ", Vec_IntSize(vCone), pCnf->nVars );
+ status = satoko_solve( pSat );
+ satoko_unmark_cone( pSat, Vec_IntArray(vCone), Vec_IntSize(vCone) );
+ Vec_IntFree( vCone );
+ }
+ else
+ {
+ status = satoko_solve( pSat );
+ }
+ satoko_assump_pop( pSat );
+ Gia_ManSatokoReport( i, status, Abc_Clock() - clk );
+ }
+ Cnf_DataFree( pCnf );
+ satoko_destroy( pSat );
+ Abc_PrintTime( 1, "Total time", Abc_Clock() - clk );
+ return;
+ }
+ if ( fSplit )
+ {
+ abctime clk = Abc_Clock();
+ Gia_ManForEachCo( p, pRoot, i )
+ {
+ pOne = Gia_ManDupDfsCone( p, pRoot );
+ Gia_ManSatokoCallOne( pOne, opts, i );
+ Gia_ManStop( pOne );
+ }
+ Abc_PrintTime( 1, "Total time", Abc_Clock() - clk );
+ return;
+ }
+ Gia_ManSatokoCallOne( p, opts, -1 );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c
index 872ba6ec..3ca31d55 100644
--- a/src/aig/gia/giaShow.c
+++ b/src/aig/gia/giaShow.c
@@ -21,6 +21,7 @@
#include "gia.h"
#include "proof/cec/cec.h"
#include "proof/acec/acec.h"
+#include "misc/extra/extra.h"
ABC_NAMESPACE_IMPL_START
@@ -29,155 +30,300 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+#define NODE_MAX 2000
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
- Synopsis []
+ Synopsis [Writes the graph structure of AIG for DOT.]
- Description []
+ Description [Useful for graph visualization using tools such as GraphViz:
+ http://www.graphviz.org/]
SideEffects []
SeeAlso []
***********************************************************************/
-/*
-Vec_Int_t * Gia_WriteDotAigMarks( Gia_Man_t * p, Vec_Int_t * vFadds, Vec_Int_t * vHadds )
+void Gia_ShowPath( Gia_Man_t * p, char * pFileName )
{
- int i;
- Vec_Int_t * vMarks = Vec_IntStart( Gia_ManObjNum(p) );
- for ( i = 0; i < Vec_IntSize(vHadds)/2; i++ )
+ FILE * pFile;
+ Gia_Obj_t * pNode;
+ Vec_Bit_t * vPath = Vec_BitStart( Gia_ManObjNum(p) );
+ int i, k, iFan, LevelMax, nLevels, * pLevels, Level, Prev;
+ int nLuts = 0, nNodes = 0, nEdges = 0;
+ assert( Gia_ManHasMapping(p) );
+
+ // set critical CO drivers
+ nLevels = Gia_ManLutLevel( p, &pLevels );
+ Gia_ManForEachCoDriverId( p, iFan, i )
+ if ( pLevels[iFan] == nLevels )
+ Vec_BitWriteEntry( vPath, iFan, 1 );
+
+ // set critical internal nodes
+ Gia_ManForEachLutReverse( p, i )
+ {
+ nLuts++;
+ if ( !Vec_BitEntry(vPath, i) )
+ continue;
+ nNodes++;
+ Gia_LutForEachFanin( p, i, iFan, k )
+ {
+ if ( pLevels[iFan] +1 < pLevels[i] )
+ continue;
+ assert( pLevels[iFan] + 1 == pLevels[i] );
+ Vec_BitWriteEntry( vPath, iFan, 1 );
+ nEdges++;
+ //printf( "%d -> %d\n", i, iFan );
+ }
+ }
+
+ if ( nNodes > NODE_MAX )
{
- Vec_IntWriteEntry( vMarks, Vec_IntEntry(vHadds, 2*i+0), Abc_Var2Lit(i+1, 0) );
- Vec_IntWriteEntry( vMarks, Vec_IntEntry(vHadds, 2*i+1), Abc_Var2Lit(i+1, 0) );
+ ABC_FREE( pLevels );
+ Vec_BitFree( vPath );
+ fprintf( stdout, "Cannot visualize AIG with more than %d critical nodes.\n", NODE_MAX );
+ return;
}
- for ( i = 0; i < Vec_IntSize(vFadds)/5; i++ )
+ if ( (pFile = fopen( pFileName, "w" )) == NULL )
{
- Vec_IntWriteEntry( vMarks, Vec_IntEntry(vFadds, 5*i+3), Abc_Var2Lit(i+1, 1) );
- Vec_IntWriteEntry( vMarks, Vec_IntEntry(vFadds, 5*i+4), Abc_Var2Lit(i+1, 1) );
+ ABC_FREE( pLevels );
+ Vec_BitFree( vPath );
+ fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName );
+ return;
}
- return vMarks;
-}
-int Gia_WriteDotAigLevel_rec( Gia_Man_t * p, Vec_Int_t * vMarks, Vec_Int_t * vFadds, Vec_Int_t * vHadds, int Id, Vec_Int_t * vLevel )
-{
- int Level = Vec_IntEntry(vLevel, Id), Mark = Vec_IntEntry(vMarks, Id);
- if ( Level || Mark == -1 )
- return Level;
- if ( Mark == 0 )
- {
- Gia_Obj_t * pObj = Gia_ManObj( p, Id );
- int Level0 = Gia_WriteDotAigLevel_rec( p, vMarks, vFadds, vHadds, Gia_ObjFaninId0(pObj, Id), vLevel );
- int Level1 = Gia_WriteDotAigLevel_rec( p, vMarks, vFadds, vHadds, Gia_ObjFaninId1(pObj, Id), vLevel );
- Level = Abc_MaxInt(Level0, Level1) + 1;
- Vec_IntWriteEntry( vLevel, Id, Level );
- Vec_IntWriteEntry( vMarks, Id, -1 );
- }
- else if ( Abc_LitIsCompl(Mark) ) // FA
- {
- int i, * pFanins = Vec_IntEntryP( vFadds, 5*(Abc_Lit2Var(Mark)-1) );
- assert( pFanins[3] == Id || pFanins[4] == Id );
- for ( i = 0; i < 3; i++ )
- Level = Abc_MaxInt( Level, Gia_WriteDotAigLevel_rec( p, vMarks, vFadds, vHadds, pFanins[i], vLevel ) );
- Vec_IntWriteEntry( vLevel, pFanins[3], Level+1 );
- Vec_IntWriteEntry( vLevel, pFanins[4], Level+1 );
- }
- else // HA
- {
- int * pFanins = Vec_IntEntryP( vHadds, 2*(Abc_Lit2Var(Mark)-1) );
- Gia_Obj_t * pObj = Gia_ManObj( p, pFanins[1] );
- int Level0 = Gia_WriteDotAigLevel_rec( p, vMarks, vFadds, vHadds, Gia_ObjFaninId0(pObj, Id), vLevel );
- int Level1 = Gia_WriteDotAigLevel_rec( p, vMarks, vFadds, vHadds, Gia_ObjFaninId1(pObj, Id), vLevel );
- assert( pFanins[0] == Id || pFanins[1] == Id );
- Level = Abc_MaxInt(Level0, Level1) + 1;
- Vec_IntWriteEntry( vLevel, pFanins[0], Level );
- Vec_IntWriteEntry( vLevel, pFanins[1], Level );
+
+ Vec_IntFreeP( &p->vLevels );
+ p->vLevels = Vec_IntAllocArray( pLevels, Gia_ManObjNum(p) );
+
+ // compute CO levels
+ LevelMax = 1 + nLevels;
+ Gia_ManForEachCo( p, pNode, i )
+ Vec_IntWriteEntry( p->vLevels, Gia_ObjId(p, pNode), LevelMax );
+
+ // write the DOT header
+ fprintf( pFile, "# %s\n", "AIG structure generated by GIA package" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "digraph AIG {\n" );
+ fprintf( pFile, "size = \"7.5,10\";\n" );
+// fprintf( pFile, "ranksep = 0.5;\n" );
+// fprintf( pFile, "nodesep = 0.5;\n" );
+ fprintf( pFile, "center = true;\n" );
+// fprintf( pFile, "orientation = landscape;\n" );
+// fprintf( pFile, "edge [fontsize = 10];\n" );
+// fprintf( pFile, "edge [dir = none];\n" );
+ fprintf( pFile, "edge [dir = back];\n" );
+ fprintf( pFile, "\n" );
+
+ // labels on the left of the picture
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " node [shape = plaintext];\n" );
+ fprintf( pFile, " edge [style = invis];\n" );
+ fprintf( pFile, " LevelTitle1 [label=\"\"];\n" );
+ fprintf( pFile, " LevelTitle2 [label=\"\"];\n" );
+ // generate node names with labels
+ for ( Level = LevelMax; Level >= 0; Level-- )
+ {
+ // the visible node name
+ fprintf( pFile, " Level%d", Level );
+ fprintf( pFile, " [label = " );
+ // label name
+ fprintf( pFile, "\"" );
+ fprintf( pFile, "\"" );
+ fprintf( pFile, "];\n" );
}
- return Level;
-}
-int Gia_WriteDotAigLevel( Gia_Man_t * p, Vec_Int_t * vFadds, Vec_Int_t * vHadds, Vec_Int_t ** pvMarks, Vec_Int_t ** pvLevel )
-{
- Vec_Int_t * vMarks = Gia_WriteDotAigMarks( p, vFadds, vHadds );
- Vec_Int_t * vLevel = Vec_IntStart( Gia_ManObjNum(p) );
- int i, Id, Level = 0;
- Vec_IntWriteEntry( vMarks, 0, -1 );
- Gia_ManForEachCiId( p, Id, i )
- Vec_IntWriteEntry( vMarks, Id, -1 );
- Gia_ManForEachCoDriverId( p, Id, i )
- Level = Abc_MaxInt( Level, Gia_WriteDotAigLevel_rec(p, vMarks, vFadds, vHadds, Id, vLevel) );
- Gia_ManForEachCoId( p, Id, i )
- Vec_IntWriteEntry( vMarks, Id, -1 );
- *pvMarks = vMarks;
- *pvLevel = vLevel;
- return Level;
-}
-*/
-int Gia_WriteDotAigLevel( Gia_Man_t * p, Vec_Int_t * vFadds, Vec_Int_t * vHadds, Vec_Int_t * vRecord, Vec_Int_t ** pvLevel, Vec_Int_t ** pvMarks, Vec_Int_t ** pvRemap, Vec_Int_t ** pvRemap2 )
-{
- Vec_Int_t * vLevel = Vec_IntStart( Gia_ManObjNum(p) );
- Vec_Int_t * vMarks = Vec_IntStart( Gia_ManObjNum(p) );
- Vec_Int_t * vRemap = Vec_IntStartNatural( Gia_ManObjNum(p) );
- Vec_Int_t * vRemap2 = Vec_IntStartNatural( Gia_ManObjNum(p) );
- int i, k, Id, Entry, LevelMax = 0;
-
- Vec_IntWriteEntry( vMarks, 0, -1 );
- Gia_ManForEachCiId( p, Id, i )
- Vec_IntWriteEntry( vMarks, Id, -1 );
- Gia_ManForEachCoId( p, Id, i )
- Vec_IntWriteEntry( vMarks, Id, -1 );
-
- Vec_IntForEachEntry( vRecord, Entry, i )
- {
- int Level = 0;
- int Node = Abc_Lit2Var2(Entry);
- int Attr = Abc_Lit2Att2(Entry);
- if ( Attr == 2 )
+
+ // genetate the sequence of visible/invisible nodes to mark levels
+ fprintf( pFile, " LevelTitle1 -> LevelTitle2 ->" );
+ for ( Level = LevelMax; Level >= 0; Level-- )
+ {
+ // the visible node name
+ fprintf( pFile, " Level%d", Level );
+ // the connector
+ if ( Level != 0 )
+ fprintf( pFile, " ->" );
+ else
+ fprintf( pFile, ";" );
+ }
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate title box on top
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ fprintf( pFile, " LevelTitle1;\n" );
+ fprintf( pFile, " title1 [shape=plaintext,\n" );
+ fprintf( pFile, " fontsize=20,\n" );
+ fprintf( pFile, " fontname = \"Times-Roman\",\n" );
+ fprintf( pFile, " label=\"" );
+ fprintf( pFile, "%s", "AIG structure visualized by ABC" );
+ fprintf( pFile, "\\n" );
+ fprintf( pFile, "Benchmark \\\"%s\\\". ", "aig" );
+// fprintf( pFile, "Time was %s. ", Extra_TimeStamp() );
+ fprintf( pFile, "\"\n" );
+ fprintf( pFile, " ];\n" );
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate statistics box
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ fprintf( pFile, " LevelTitle2;\n" );
+ fprintf( pFile, " title2 [shape=plaintext,\n" );
+ fprintf( pFile, " fontsize=18,\n" );
+ fprintf( pFile, " fontname = \"Times-Roman\",\n" );
+ fprintf( pFile, " label=\"" );
+ fprintf( pFile, "The critical path contains %d LUTs with %d critical edges and spans %d levels.", nNodes, nEdges, nLevels );
+ fprintf( pFile, "\\n" );
+ fprintf( pFile, "\"\n" );
+ fprintf( pFile, " ];\n" );
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate the COs
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ // the labeling node of this level
+ fprintf( pFile, " Level%d;\n", LevelMax );
+ // generate the CO nodes
+ Gia_ManForEachCo( p, pNode, i )
+ {
+ if ( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) < nLevels )
+ continue;
+ assert( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) == nLevels );
+ fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(p, pNode), Gia_ObjId(p, pNode) );
+ fprintf( pFile, ", shape = %s", "invtriangle" );
+ fprintf( pFile, ", color = coral, fillcolor = coral" );
+ fprintf( pFile, "];\n" );
+ }
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate nodes of each rank
+ for ( Level = LevelMax - 1; Level > 0; Level-- )
+ {
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ // the labeling node of this level
+ fprintf( pFile, " Level%d;\n", Level );
+ Gia_ManForEachObj( p, pNode, i )
{
- int * pFanins = Vec_IntEntryP( vFadds, 5*Node );
- for ( k = 0; k < 3; k++ )
- Level = Abc_MaxInt( Level, Vec_IntEntry(vLevel, pFanins[k]) );
- Vec_IntWriteEntry( vLevel, pFanins[3], Level+1 );
- Vec_IntWriteEntry( vLevel, pFanins[4], Level+1 );
- Vec_IntWriteEntry( vMarks, pFanins[4], Entry );
- Vec_IntWriteEntry( vRemap, pFanins[3], pFanins[4] );
- Vec_IntWriteEntry( vRemap2, pFanins[4], pFanins[3] );
- //printf( "Making FA output %d.\n", pFanins[4] );
+ if ( (int)Gia_ObjLevel(p, pNode) != Level || !Vec_BitEntry(vPath, i) )
+ continue;
+ fprintf( pFile, " Node%d [label = \"%d:%d\"", i, i, Gia_ObjIsAnd(pNode)? Gia_ObjLutSize(p, i) : 0 );
+ fprintf( pFile, ", shape = ellipse" );
+ if ( pNode->fMark0 )
+ fprintf( pFile, ", style = filled" );
+ fprintf( pFile, "];\n" );
}
- else if ( Attr == 1 )
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+ }
+
+ // generate the CI nodes
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ // the labeling node of this level
+ fprintf( pFile, " Level%d;\n", 0 );
+ // generate the CI nodes
+ Gia_ManForEachCi( p, pNode, i )
+ {
+ if ( !Vec_BitEntry(vPath, Gia_ObjId(p, pNode)) )
+ continue;
+ fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(p, pNode), Gia_ObjId(p, pNode) );
+ fprintf( pFile, ", shape = %s", "triangle" );
+ fprintf( pFile, ", color = coral, fillcolor = coral" );
+ fprintf( pFile, "];\n" );
+ }
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate invisible edges from the square down
+ fprintf( pFile, "title1 -> title2 [style = invis];\n" );
+ Gia_ManForEachCo( p, pNode, i )
+ {
+ if ( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) < nLevels )
+ continue;
+ fprintf( pFile, "title2 -> Node%d [style = invis];\n", Gia_ObjId(p, pNode) );
+ }
+ // generate invisible edges among the COs
+ Prev = -1;
+ Gia_ManForEachCo( p, pNode, i )
+ {
+ if ( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) < nLevels )
+ continue;
+ assert( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) == nLevels );
+ if ( Prev >= 0 )
+ fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Gia_ObjId(p, pNode) );
+ Prev = Gia_ObjId(p, pNode);
+ }
+ // generate invisible edges among the CIs
+ Prev = -1;
+ Gia_ManForEachCi( p, pNode, i )
+ {
+ if ( !Vec_BitEntry(vPath, Gia_ObjId(p, pNode)) )
+ continue;
+ if ( Prev >= 0 )
+ fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Gia_ObjId(p, pNode) );
+ Prev = Gia_ObjId(p, pNode);
+ }
+
+ // generate edges
+ Gia_ManForEachObj( p, pNode, i )
+ {
+ if ( Gia_ObjIsCo(pNode) )
{
- int * pFanins = Vec_IntEntryP( vHadds, 2*Node );
- Gia_Obj_t * pObj = Gia_ManObj( p, pFanins[1] );
- int pFaninsIn[2] = { Gia_ObjFaninId0(pObj, pFanins[1]), Gia_ObjFaninId1(pObj, pFanins[1]) };
- for ( k = 0; k < 2; k++ )
- Level = Abc_MaxInt( Level, Vec_IntEntry(vLevel, pFaninsIn[k]) );
- Vec_IntWriteEntry( vLevel, pFanins[0], Level+1 );
- Vec_IntWriteEntry( vLevel, pFanins[1], Level+1 );
- Vec_IntWriteEntry( vMarks, pFanins[1], Entry );
- Vec_IntWriteEntry( vRemap, pFanins[0], pFanins[1] );
- Vec_IntWriteEntry( vRemap2, pFanins[1], pFanins[0] );
- //printf( "Making HA output %d %d.\n", pFanins[0], pFanins[1] );
+ if ( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) == nLevels )
+ {
+ // generate the edge from this node to the next
+ fprintf( pFile, "Node%d", i );
+ fprintf( pFile, " -> " );
+ fprintf( pFile, "Node%d", Gia_ObjFaninId0p(p, pNode) );
+ fprintf( pFile, " [" );
+ fprintf( pFile, "style = %s", "solid" );
+ fprintf( pFile, "]" );
+ fprintf( pFile, ";\n" );
+ }
+ continue;
}
- else // if ( Attr == 3 || Attr == 0 )
+ if ( !Gia_ObjIsAnd(pNode) || !Vec_BitEntry(vPath, i) )
+ continue;
+ Gia_LutForEachFanin( p, i, iFan, k )
{
- Gia_Obj_t * pObj = Gia_ManObj( p, Node );
- int pFaninsIn[2] = { Gia_ObjFaninId0(pObj, Node), Gia_ObjFaninId1(pObj, Node) };
- for ( k = 0; k < 2; k++ )
- Level = Abc_MaxInt( Level, Vec_IntEntry(vLevel, pFaninsIn[k]) );
- Vec_IntWriteEntry( vLevel, Node, Level+1 );
- Vec_IntWriteEntry( vMarks, Node, -1 );
- //printf( "Making node %d.\n", Node );
+ if ( pLevels[iFan] + 1 < pLevels[i] )
+ continue;
+ assert( pLevels[iFan] + 1 == pLevels[i] );
+ // generate the edge from this node to the next
+ fprintf( pFile, "Node%d", i );
+ fprintf( pFile, " -> " );
+ fprintf( pFile, "Node%d", iFan );
+ fprintf( pFile, " [" );
+ fprintf( pFile, "style = %s", "solid" );
+ fprintf( pFile, "]" );
+ fprintf( pFile, ";\n" );
}
- LevelMax = Abc_MaxInt( LevelMax, Level+1 );
}
- *pvLevel = vLevel;
- *pvMarks = vMarks;
- *pvRemap = vRemap;
- *pvRemap2 = vRemap2;
- return LevelMax;
+
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+ fclose( pFile );
+
+ Vec_IntFreeP( &p->vLevels );
+ Vec_BitFree( vPath );
}
+
/**Function*************************************************************
Synopsis [Writes the graph structure of AIG for DOT.]
@@ -190,17 +336,16 @@ int Gia_WriteDotAigLevel( Gia_Man_t * p, Vec_Int_t * vFadds, Vec_Int_t * vHadds,
SeeAlso []
***********************************************************************/
-void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int fAdders )
+void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold )
{
- Vec_Int_t * vFadds = NULL, * vHadds = NULL, * vRecord = NULL, * vMarks = NULL, * vRemap = NULL, * vRemap2 = NULL;
FILE * pFile;
Gia_Obj_t * pNode;//, * pTemp, * pPrev;
int LevelMax, Prev, Level, i;
int fConstIsUsed = 0;
- if ( Gia_ManAndNum(pMan) > 1000 )
+ if ( Gia_ManAndNum(p) > NODE_MAX )
{
- fprintf( stdout, "Cannot visualize AIG with more than 1000 nodes.\n" );
+ fprintf( stdout, "Cannot visualize AIG with more than %d nodes.\n", NODE_MAX );
return;
}
if ( (pFile = fopen( pFileName, "w" )) == NULL )
@@ -211,31 +356,20 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int
// mark the nodes
if ( vBold )
- Gia_ManForEachObjVec( vBold, pMan, pNode, i )
+ Gia_ManForEachObjVec( vBold, p, pNode, i )
pNode->fMark0 = 1;
- else if ( pMan->nXors || pMan->nMuxes )
- Gia_ManForEachObj( pMan, pNode, i )
- if ( Gia_ObjIsXor(pNode) || Gia_ObjIsMux(pMan, pNode) )
+ else if ( p->nXors || p->nMuxes )
+ Gia_ManForEachObj( p, pNode, i )
+ if ( Gia_ObjIsXor(pNode) || Gia_ObjIsMux(p, pNode) )
pNode->fMark0 = 1;
// compute levels
- if ( fAdders )
- {
- Vec_IntFreeP( &pMan->vLevels );
- vFadds = Gia_ManDetectFullAdders( pMan, 0, NULL );
- vHadds = Gia_ManDetectHalfAdders( pMan, 0 );
- vRecord = Gia_PolynFindOrder( pMan, vFadds, vHadds, 0, 0 );
- LevelMax = 1 + Gia_WriteDotAigLevel( pMan, vFadds, vHadds, vRecord, &pMan->vLevels, &vMarks, &vRemap, &vRemap2 );
- }
- else
- LevelMax = 1 + Gia_ManLevelNum( pMan );
-
- // set output levels
- Gia_ManForEachCo( pMan, pNode, i )
- Vec_IntWriteEntry( pMan->vLevels, Gia_ObjId(pMan, pNode), LevelMax );
+ LevelMax = 1 + Gia_ManLevelNum( p );
+ Gia_ManForEachCo( p, pNode, i )
+ Vec_IntWriteEntry( p->vLevels, Gia_ObjId(p, pNode), LevelMax );
// write the DOT header
- fprintf( pFile, "# %s\n", "AIG structure generated by IVY package" );
+ fprintf( pFile, "# %s\n", "AIG structure generated by GIA package" );
fprintf( pFile, "\n" );
fprintf( pFile, "digraph AIG {\n" );
fprintf( pFile, "size = \"7.5,10\";\n" );
@@ -309,7 +443,7 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int
fprintf( pFile, " fontsize=18,\n" );
fprintf( pFile, " fontname = \"Times-Roman\",\n" );
fprintf( pFile, " label=\"" );
- fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Gia_ManAndNum(pMan), LevelMax );
+ fprintf( pFile, "The AIG contains %d nodes and spans %d levels.", Gia_ManAndNum(p), LevelMax-1 );
fprintf( pFile, "\\n" );
fprintf( pFile, "\"\n" );
fprintf( pFile, " ];\n" );
@@ -323,9 +457,9 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int
// the labeling node of this level
fprintf( pFile, " Level%d;\n", LevelMax );
// generate the CO nodes
- Gia_ManForEachCo( pMan, pNode, i )
+ Gia_ManForEachCo( p, pNode, i )
{
- if ( Gia_ObjFaninId0p(pMan, pNode) == 0 )
+ if ( Gia_ObjFaninId0p(p, pNode) == 0 )
fConstIsUsed = 1;
/*
if ( fHaig || pNode->pEquiv == NULL )
@@ -336,7 +470,7 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int
(Gia_ObjIsLatch(pNode)? "_in":""), pNode->Id, (Gia_ObjIsLatch(pNode)? "_in":""),
Gia_Regular(pNode->pEquiv)->Id, Gia_IsComplement(pNode->pEquiv)? "\'":"" );
*/
- fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(pMan, pNode), Gia_ObjId(pMan, pNode) );
+ fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(p, pNode), Gia_ObjId(p, pNode) );
fprintf( pFile, ", shape = %s", "invtriangle" );
fprintf( pFile, ", color = coral, fillcolor = coral" );
@@ -353,11 +487,9 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int
fprintf( pFile, " rank = same;\n" );
// the labeling node of this level
fprintf( pFile, " Level%d;\n", Level );
- Gia_ManForEachObj( pMan, pNode, i )
+ Gia_ManForEachObj( p, pNode, i )
{
- if ( vMarks && Vec_IntEntry(vMarks, i) == 0 )
- continue;
- if ( (int)Gia_ObjLevel(pMan, pNode) != Level )
+ if ( (int)Gia_ObjLevel(p, pNode) != Level )
continue;
/*
if ( fHaig || pNode->pEquiv == NULL )
@@ -366,29 +498,14 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int
fprintf( pFile, " Node%d [label = \"%d(%d%s)\"", pNode->Id, pNode->Id,
Gia_Regular(pNode->pEquiv)->Id, Gia_IsComplement(pNode->pEquiv)? "\'":"" );
*/
- if ( vMarks && Vec_IntEntry(vMarks, i) > 0 )
- {
- fprintf( pFile, " Node%d [label = \"%d_%d\"", i, Vec_IntEntry(vRemap2, i), i );
- if ( Abc_Lit2Att2(Vec_IntEntry(vMarks, i)) == 2 )
- fprintf( pFile, ", shape = doubleoctagon" );
- else
- fprintf( pFile, ", shape = octagon" );
- }
- else if ( Gia_ObjIsXor(pNode) )
- {
- fprintf( pFile, " Node%d [label = \"%d\"", i, i );
+ fprintf( pFile, " Node%d [label = \"%d\"", i, i );
+
+ if ( Gia_ObjIsXor(pNode) )
fprintf( pFile, ", shape = doublecircle" );
- }
- else if ( Gia_ObjIsMux(pMan, pNode) )
- {
- fprintf( pFile, " Node%d [label = \"%d\"", i, i );
+ else if ( Gia_ObjIsMux(p, pNode) )
fprintf( pFile, ", shape = trapezium" );
- }
else
- {
- fprintf( pFile, " Node%d [label = \"%d\"", i, i );
fprintf( pFile, ", shape = ellipse" );
- }
if ( pNode->fMark0 )
fprintf( pFile, ", style = filled" );
@@ -405,7 +522,7 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int
// the labeling node of this level
fprintf( pFile, " Level%d;\n", 0 );
// generate constant node
- if ( fConstIsUsed || pMan->fGiaSimple )
+ if ( fConstIsUsed )
{
// check if the costant node is present
fprintf( pFile, " Node%d [label = \"Const0\"", 0 );
@@ -414,7 +531,7 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int
fprintf( pFile, "];\n" );
}
// generate the CI nodes
- Gia_ManForEachCi( pMan, pNode, i )
+ Gia_ManForEachCi( p, pNode, i )
{
/*
if ( fHaig || pNode->pEquiv == NULL )
@@ -425,7 +542,7 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int
(Gia_ObjIsLatch(pNode)? "_out":""), pNode->Id, (Gia_ObjIsLatch(pNode)? "_out":""),
Gia_Regular(pNode->pEquiv)->Id, Gia_IsComplement(pNode->pEquiv)? "\'":"" );
*/
- fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(pMan, pNode), Gia_ObjId(pMan, pNode) );
+ fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(p, pNode), Gia_ObjId(p, pNode) );
fprintf( pFile, ", shape = %s", "triangle" );
fprintf( pFile, ", color = coral, fillcolor = coral" );
@@ -437,73 +554,37 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int
// generate invisible edges from the square down
fprintf( pFile, "title1 -> title2 [style = invis];\n" );
- Gia_ManForEachCo( pMan, pNode, i )
- fprintf( pFile, "title2 -> Node%d [style = invis];\n", Gia_ObjId(pMan, pNode) );
+ Gia_ManForEachCo( p, pNode, i )
+ fprintf( pFile, "title2 -> Node%d [style = invis];\n", Gia_ObjId(p, pNode) );
// generate invisible edges among the COs
Prev = -1;
- Gia_ManForEachCo( pMan, pNode, i )
+ Gia_ManForEachCo( p, pNode, i )
{
if ( i > 0 )
- fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Gia_ObjId(pMan, pNode) );
- Prev = Gia_ObjId(pMan, pNode);
+ fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Gia_ObjId(p, pNode) );
+ Prev = Gia_ObjId(p, pNode);
+ }
+ // generate invisible edges among the CIs
+ Prev = -1;
+ Gia_ManForEachCi( p, pNode, i )
+ {
+ if ( i > 0 )
+ fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Gia_ObjId(p, pNode) );
+ Prev = Gia_ObjId(p, pNode);
}
// generate edges
- Gia_ManForEachObj( pMan, pNode, i )
+ Gia_ManForEachObj( p, pNode, i )
{
if ( !Gia_ObjIsAnd(pNode) && !Gia_ObjIsCo(pNode) && !Gia_ObjIsBuf(pNode) )
continue;
- if ( vMarks && Vec_IntEntry(vMarks, i) == 0 )
- continue;
- // consider half/full-adder
- if ( vMarks && Vec_IntEntry(vMarks, i) > 0 )
- {
- int k, Mark = Vec_IntEntry(vMarks, i);
- if ( Abc_Lit2Att2(Mark) == 2 ) // FA
- {
- int * pFanins = Vec_IntEntryP( vFadds, 5*Abc_Lit2Var2(Mark) );
- if ( pFanins[3] == i )
- continue;
- assert( pFanins[4] == i );
- // generate the edge from this node to the next
- for ( k = 0; k < 3; k++ )
- {
- fprintf( pFile, "Node%d", i );
- fprintf( pFile, " -> " );
- fprintf( pFile, "Node%d", Vec_IntEntry(vRemap, pFanins[k]) );
- fprintf( pFile, " [" );
- fprintf( pFile, "style = %s", "bold" );
- fprintf( pFile, "]" );
- fprintf( pFile, ";\n" );
- }
- }
- else // HA
- {
- int * pFanins = Vec_IntEntryP( vHadds, 2*Abc_Lit2Var2(Mark) );
- int pFaninsIn[2] = { Vec_IntEntry(vRemap, Gia_ObjFaninId0(pNode, i)), Vec_IntEntry(vRemap, Gia_ObjFaninId1(pNode, i)) };
- if ( pFanins[0] == i )
- continue;
- assert( pFanins[1] == i );
- for ( k = 0; k < 2; k++ )
- {
- fprintf( pFile, "Node%d", i );
- fprintf( pFile, " -> " );
- fprintf( pFile, "Node%d", Vec_IntEntry(vRemap, pFaninsIn[k]) );
- fprintf( pFile, " [" );
- fprintf( pFile, "style = %s", "bold" );
- fprintf( pFile, "]" );
- fprintf( pFile, ";\n" );
- }
- }
- continue;
- }
// generate the edge from this node to the next
fprintf( pFile, "Node%d", i );
fprintf( pFile, " -> " );
- fprintf( pFile, "Node%d", vRemap ? Vec_IntEntry(vRemap, Gia_ObjFaninId0(pNode, i)) : Gia_ObjFaninId0(pNode, i) );
+ fprintf( pFile, "Node%d", Gia_ObjFaninId0(pNode, i) );
fprintf( pFile, " [" );
- fprintf( pFile, "style = %s", Gia_ObjFaninC0(pNode)? "dotted" : "bold" );
-// if ( Gia_NtkIsSeq(pNode->pMan) && Seq_ObjFaninL0(pNode) > 0 )
+ fprintf( pFile, "style = %s", Gia_ObjFaninC0(pNode)? "dotted" : "solid" );
+// if ( Gia_NtkIsSeq(pNode->p) && Seq_ObjFaninL0(pNode) > 0 )
// fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,0) );
fprintf( pFile, "]" );
fprintf( pFile, ";\n" );
@@ -512,23 +593,23 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int
// generate the edge from this node to the next
fprintf( pFile, "Node%d", i );
fprintf( pFile, " -> " );
- fprintf( pFile, "Node%d", vRemap ? Vec_IntEntry(vRemap, Gia_ObjFaninId1(pNode, i)) : Gia_ObjFaninId1(pNode, i) );
+ fprintf( pFile, "Node%d", Gia_ObjFaninId1(pNode, i) );
fprintf( pFile, " [" );
- fprintf( pFile, "style = %s", Gia_ObjFaninC1(pNode)? "dotted" : "bold" );
-// if ( Gia_NtkIsSeq(pNode->pMan) && Seq_ObjFaninL1(pNode) > 0 )
+ fprintf( pFile, "style = %s", Gia_ObjFaninC1(pNode)? "dotted" : "solid" );
+// if ( Gia_NtkIsSeq(pNode->p) && Seq_ObjFaninL1(pNode) > 0 )
// fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,1) );
fprintf( pFile, "]" );
fprintf( pFile, ";\n" );
- if ( !Gia_ObjIsMux(pMan, pNode) )
+ if ( !Gia_ObjIsMux(p, pNode) )
continue;
// generate the edge from this node to the next
fprintf( pFile, "Node%d", i );
fprintf( pFile, " -> " );
- fprintf( pFile, "Node%d", vRemap ? Vec_IntEntry(vRemap, Gia_ObjFaninId2(pMan, i)) : Gia_ObjFaninId2(pMan, i) );
+ fprintf( pFile, "Node%d", Gia_ObjFaninId2(p, i) );
fprintf( pFile, " [" );
- fprintf( pFile, "style = %s", Gia_ObjFaninC2(pMan, pNode)? "dotted" : "bold" );
-// if ( Gia_NtkIsSeq(pNode->pMan) && Seq_ObjFaninL1(pNode) > 0 )
+ fprintf( pFile, "style = %s", Gia_ObjFaninC2(p, pNode)? "dotted" : "bold" );
+// if ( Gia_NtkIsSeq(pNode->p) && Seq_ObjFaninL1(pNode) > 0 )
// fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,1) );
fprintf( pFile, "]" );
fprintf( pFile, ";\n" );
@@ -543,7 +624,7 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int
fprintf( pFile, "Node%d", pPrev->Id );
fprintf( pFile, " -> " );
fprintf( pFile, "Node%d", pTemp->Id );
- fprintf( pFile, " [style = %s]", Gia_IsComplement(pTemp->pEquiv)? "dotted" : "bold" );
+ fprintf( pFile, " [style = %s]", Gia_IsComplement(pTemp->pEquiv)? "dotted" : "solid" );
fprintf( pFile, ";\n" );
pPrev = pTemp;
}
@@ -551,7 +632,7 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int
fprintf( pFile, "Node%d", pPrev->Id );
fprintf( pFile, " -> " );
fprintf( pFile, "Node%d", pNode->Id );
- fprintf( pFile, " [style = %s]", Gia_IsComplement(pPrev->pEquiv)? "dotted" : "bold" );
+ fprintf( pFile, " [style = %s]", Gia_IsComplement(pPrev->pEquiv)? "dotted" : "solid" );
fprintf( pFile, ";\n" );
}
*/
@@ -564,18 +645,461 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int
// unmark nodes
if ( vBold )
- Gia_ManForEachObjVec( vBold, pMan, pNode, i )
+ Gia_ManForEachObjVec( vBold, p, pNode, i )
pNode->fMark0 = 0;
- else if ( pMan->nXors || pMan->nMuxes )
- Gia_ManCleanMark0( pMan );
+ else if ( p->nXors || p->nMuxes )
+ Gia_ManCleanMark0( p );
+
+ Vec_IntFreeP( &p->vLevels );
+}
- Vec_IntFreeP( &vFadds );
- Vec_IntFreeP( &vHadds );
- Vec_IntFreeP( &vRecord );
+/**Function*************************************************************
+
+ Synopsis [Writes the graph structure of AIG for DOT.]
- Vec_IntFreeP( &pMan->vLevels );
- Vec_IntFreeP( &vMarks );
- Vec_IntFreeP( &vRemap );
+ Description [Useful for graph visualization using tools such as GraphViz:
+ http://www.graphviz.org/]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ShowAddOut( Vec_Int_t * vAdds, Vec_Int_t * vMapAdds, int Node )
+{
+ int iBox = Vec_IntEntry( vMapAdds, Node );
+ if ( iBox >= 0 )
+ return Vec_IntEntry( vAdds, 6*iBox+4 );
+ return Node;
+}
+void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_Int_t * vAdds, Vec_Int_t * vXors, Vec_Int_t * vMapAdds, Vec_Int_t * vMapXors, Vec_Int_t * vOrder )
+{
+ FILE * pFile;
+ Gia_Obj_t * pNode;//, * pTemp, * pPrev;
+ int LevelMax, Prev, Level, i;
+ int fConstIsUsed = 0;
+ int nFadds = Ree_ManCountFadds( vAdds );
+
+ if ( Gia_ManAndNum(p) > NODE_MAX )
+ {
+ fprintf( stdout, "Cannot visualize AIG with more than %d nodes.\n", NODE_MAX );
+ return;
+ }
+ if ( (pFile = fopen( pFileName, "w" )) == NULL )
+ {
+ fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName );
+ return;
+ }
+
+ // mark the nodes
+ if ( vBold )
+ Gia_ManForEachObjVec( vBold, p, pNode, i )
+ pNode->fMark0 = 1;
+
+ // compute levels
+ LevelMax = 1 + p->nLevels;
+ Gia_ManForEachCo( p, pNode, i )
+ Vec_IntWriteEntry( p->vLevels, Gia_ObjId(p, pNode), LevelMax );
+
+ // write the DOT header
+ fprintf( pFile, "# %s\n", "AIG structure generated by GIA package" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "digraph AIG {\n" );
+ fprintf( pFile, "size = \"7.5,10\";\n" );
+// fprintf( pFile, "ranksep = 0.5;\n" );
+// fprintf( pFile, "nodesep = 0.5;\n" );
+ fprintf( pFile, "center = true;\n" );
+// fprintf( pFile, "orientation = landscape;\n" );
+// fprintf( pFile, "edge [fontsize = 10];\n" );
+// fprintf( pFile, "edge [dir = none];\n" );
+ fprintf( pFile, "edge [dir = back];\n" );
+ fprintf( pFile, "\n" );
+
+ // labels on the left of the picture
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " node [shape = plaintext];\n" );
+ fprintf( pFile, " edge [style = invis];\n" );
+ fprintf( pFile, " LevelTitle1 [label=\"\"];\n" );
+ fprintf( pFile, " LevelTitle2 [label=\"\"];\n" );
+ // generate node names with labels
+ for ( Level = LevelMax; Level >= 0; Level-- )
+ {
+ // the visible node name
+ fprintf( pFile, " Level%d", Level );
+ fprintf( pFile, " [label = " );
+ // label name
+ fprintf( pFile, "\"" );
+ fprintf( pFile, "\"" );
+ fprintf( pFile, "];\n" );
+ }
+
+ // genetate the sequence of visible/invisible nodes to mark levels
+ fprintf( pFile, " LevelTitle1 -> LevelTitle2 ->" );
+ for ( Level = LevelMax; Level >= 0; Level-- )
+ {
+ // the visible node name
+ fprintf( pFile, " Level%d", Level );
+ // the connector
+ if ( Level != 0 )
+ fprintf( pFile, " ->" );
+ else
+ fprintf( pFile, ";" );
+ }
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate title box on top
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ fprintf( pFile, " LevelTitle1;\n" );
+ fprintf( pFile, " title1 [shape=plaintext,\n" );
+ fprintf( pFile, " fontsize=20,\n" );
+ fprintf( pFile, " fontname = \"Times-Roman\",\n" );
+ fprintf( pFile, " label=\"" );
+ fprintf( pFile, "%s", "AIG structure visualized by ABC" );
+ fprintf( pFile, "\\n" );
+ fprintf( pFile, "Benchmark \\\"%s\\\". ", "aig" );
+// fprintf( pFile, "Time was %s. ", Extra_TimeStamp() );
+ fprintf( pFile, "\"\n" );
+ fprintf( pFile, " ];\n" );
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate statistics box
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ fprintf( pFile, " LevelTitle2;\n" );
+ fprintf( pFile, " title2 [shape=plaintext,\n" );
+ fprintf( pFile, " fontsize=18,\n" );
+ fprintf( pFile, " fontname = \"Times-Roman\",\n" );
+ fprintf( pFile, " label=\"" );
+ fprintf( pFile, "The AIG contains %d nodes, %d full-adders, and %d half-adders, and spans %d levels.",
+ Gia_ManAndNum(p), nFadds, Vec_IntSize(vAdds)/6-nFadds, LevelMax-1 );
+ fprintf( pFile, "\\n" );
+ fprintf( pFile, "\"\n" );
+ fprintf( pFile, " ];\n" );
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate the COs
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ // the labeling node of this level
+ fprintf( pFile, " Level%d;\n", LevelMax );
+ // generate the CO nodes
+ Gia_ManForEachCo( p, pNode, i )
+ {
+ if ( Gia_ObjFaninId0p(p, pNode) == 0 )
+ fConstIsUsed = 1;
+ fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(p, pNode), Gia_ObjId(p, pNode) );
+
+ fprintf( pFile, ", shape = %s", "invtriangle" );
+ fprintf( pFile, ", color = coral, fillcolor = coral" );
+ fprintf( pFile, "];\n" );
+ }
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate nodes of each rank
+ for ( Level = LevelMax - 1; Level > 0; Level-- )
+ {
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ // the labeling node of this level
+ fprintf( pFile, " Level%d;\n", Level );
+ Gia_ManForEachObjVec( vOrder, p, pNode, i )
+ {
+ int iNode = Gia_ObjId( p, pNode );
+ if ( (int)Gia_ObjLevel(p, pNode) != Level )
+ continue;
+/*
+ fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(p, pNode), Gia_ObjId(p, pNode) );
+ if ( Gia_ObjIsXor(pNode) )
+ fprintf( pFile, ", shape = doublecircle" );
+ else if ( Gia_ObjIsMux(p, pNode) )
+ fprintf( pFile, ", shape = trapezium" );
+ else
+ fprintf( pFile, ", shape = ellipse" );
+*/
+ if ( !pNode->fMark0 && Vec_IntEntry(vMapAdds, iNode) >= 0 )
+ {
+ int iBox = Vec_IntEntry(vMapAdds, iNode);
+ fprintf( pFile, " Node%d [label = \"%d_%d\"", Gia_ShowAddOut(vAdds, vMapAdds, iNode), Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) );
+ if ( Vec_IntEntry(vAdds, 6*iBox+2) == 0 )
+ fprintf( pFile, ", shape = octagon" );
+ else
+ fprintf( pFile, ", shape = doubleoctagon" );
+ }
+ else if ( Vec_IntEntry(vMapXors, iNode) >= 0 )
+ {
+ fprintf( pFile, " Node%d [label = \"%d\"", iNode, iNode );
+ fprintf( pFile, ", shape = doublecircle" );
+ }
+ else if ( Gia_ObjIsXor(pNode) )
+ {
+ fprintf( pFile, " Node%d [label = \"%d\"", iNode, iNode );
+ fprintf( pFile, ", shape = doublecircle" );
+ }
+ else if ( Gia_ObjIsMux(p, pNode) )
+ {
+ fprintf( pFile, " Node%d [label = \"%d\"", iNode, iNode );
+ fprintf( pFile, ", shape = trapezium" );
+ }
+ else
+ {
+ fprintf( pFile, " Node%d [label = \"%d\"", iNode, iNode );
+ fprintf( pFile, ", shape = ellipse" );
+ }
+ if ( pNode->fMark0 )
+ fprintf( pFile, ", style = filled" );
+ fprintf( pFile, "];\n" );
+ }
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+ }
+
+ // generate the CI nodes
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ // the labeling node of this level
+ fprintf( pFile, " Level%d;\n", 0 );
+ // generate constant node
+ if ( fConstIsUsed )
+ {
+ // check if the costant node is present
+ fprintf( pFile, " Node%d [label = \"Const0\"", 0 );
+ fprintf( pFile, ", shape = ellipse" );
+ fprintf( pFile, ", color = coral, fillcolor = coral" );
+ fprintf( pFile, "];\n" );
+ }
+ // generate the CI nodes
+ Gia_ManForEachCi( p, pNode, i )
+ {
+ fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(p, pNode), Gia_ObjId(p, pNode) );
+
+ fprintf( pFile, ", shape = %s", "triangle" );
+ fprintf( pFile, ", color = coral, fillcolor = coral" );
+ fprintf( pFile, "];\n" );
+ }
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate invisible edges from the square down
+ fprintf( pFile, "title1 -> title2 [style = invis];\n" );
+ Gia_ManForEachCo( p, pNode, i )
+ fprintf( pFile, "title2 -> Node%d [style = invis];\n", Gia_ObjId(p, pNode) );
+ // generate invisible edges among the COs
+ Prev = -1;
+ Gia_ManForEachCo( p, pNode, i )
+ {
+ if ( i > 0 )
+ fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Gia_ObjId(p, pNode) );
+ Prev = Gia_ObjId(p, pNode);
+ }
+ // generate invisible edges among the CIs
+ Prev = -1;
+ Gia_ManForEachCi( p, pNode, i )
+ {
+ if ( i > 0 )
+ fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Gia_ObjId(p, pNode) );
+ Prev = Gia_ObjId(p, pNode);
+ }
+
+ // generate edges
+ Gia_ManForEachCo( p, pNode, i )
+ {
+ int iNode = Gia_ObjId( p, pNode );
+ fprintf( pFile, "Node%d", iNode );
+ fprintf( pFile, " -> " );
+ fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Gia_ObjFaninId0(pNode, iNode)) );
+ fprintf( pFile, " [" );
+ fprintf( pFile, "style = %s", Gia_ObjFaninC0(pNode)? "dotted" : "solid" );
+ fprintf( pFile, "]" );
+ fprintf( pFile, ";\n" );
+ }
+ Gia_ManForEachObjVec( vOrder, p, pNode, i )
+ {
+ int iNode = Gia_ObjId( p, pNode );
+ if ( Vec_IntEntry(vMapAdds, Gia_ObjId(p, pNode)) >= 0 )
+ {
+ int k, iBox = Vec_IntEntry(vMapAdds, iNode);
+ for ( k = 0; k < 3; k++ )
+ if ( Vec_IntEntry(vAdds, 6*iBox+k) )
+ {
+ int iBox2 = Vec_IntEntry(vMapAdds, Vec_IntEntry(vAdds, 6*iBox+k));
+ int fXor2 = iBox2 >= 0 ? (int)(Vec_IntEntry(vAdds, 6*iBox2+3) == Vec_IntEntry(vAdds, 6*iBox+k)) : 0;
+ fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, iNode) );
+ fprintf( pFile, " -> " );
+ fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Vec_IntEntry(vAdds, 6*iBox+k)) );
+ fprintf( pFile, " [" );
+ fprintf( pFile, "style = %s", fXor2? "bold" : "solid" );
+ fprintf( pFile, "]" );
+ fprintf( pFile, ";\n" );
+ }
+ continue;
+ }
+ if ( Vec_IntEntry(vMapXors, Gia_ObjId(p, pNode)) >= 0 )
+ {
+ int k, iXor = Vec_IntEntry(vMapXors, iNode);
+ for ( k = 1; k < 4; k++ )
+ if ( Vec_IntEntry(vXors, 4*iXor+k) )
+ {
+ int iXor2 = Vec_IntEntry(vMapXors, Vec_IntEntry(vXors, 4*iXor+k));
+ fprintf( pFile, "Node%d", iNode );
+ fprintf( pFile, " -> " );
+ fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Vec_IntEntry(vXors, 4*iXor+k)) );
+ fprintf( pFile, " [" );
+ fprintf( pFile, "style = %s", iXor2 >= 0? "bold" : "solid" );
+ fprintf( pFile, "]" );
+ fprintf( pFile, ";\n" );
+ }
+ continue;
+ }
+ // generate the edge from this node to the next
+ fprintf( pFile, "Node%d", iNode );
+ fprintf( pFile, " -> " );
+ fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Gia_ObjFaninId0(pNode, iNode)) );
+ fprintf( pFile, " [" );
+ fprintf( pFile, "style = %s", Gia_ObjFaninC0(pNode)? "dotted" : "solid" );
+ fprintf( pFile, "]" );
+ fprintf( pFile, ";\n" );
+ if ( !Gia_ObjIsAnd(pNode) )
+ continue;
+ // generate the edge from this node to the next
+ fprintf( pFile, "Node%d", iNode );
+ fprintf( pFile, " -> " );
+ fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Gia_ObjFaninId1(pNode, iNode)) );
+ fprintf( pFile, " [" );
+ fprintf( pFile, "style = %s", Gia_ObjFaninC1(pNode)? "dotted" : "solid" );
+ fprintf( pFile, "]" );
+ fprintf( pFile, ";\n" );
+
+ if ( !Gia_ObjIsMux(p, pNode) )
+ continue;
+ // generate the edge from this node to the next
+ fprintf( pFile, "Node%d", iNode );
+ fprintf( pFile, " -> " );
+ fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Gia_ObjFaninId2(p, iNode)) );
+ fprintf( pFile, " [" );
+ fprintf( pFile, "style = %s", Gia_ObjFaninC2(p, pNode)? "dotted" : "solid" );
+ fprintf( pFile, "]" );
+ fprintf( pFile, ";\n" );
+ }
+
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+ fclose( pFile );
+
+ // unmark nodes
+ if ( vBold )
+ Gia_ManForEachObjVec( vBold, p, pNode, i )
+ pNode->fMark0 = 0;
+
+ Vec_IntFreeP( &p->vLevels );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns DFS ordered array of objects and their levels.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ShowMapAdds( Gia_Man_t * p, Vec_Int_t * vAdds, int fFadds, Vec_Int_t * vBold )
+{
+ Vec_Bit_t * vIsBold = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vMapAdds = Vec_IntStartFull( Gia_ManObjNum(p) ); int i, Entry;
+ if ( vBold )
+ Vec_IntForEachEntry( vBold, Entry, i )
+ Vec_BitWriteEntry( vIsBold, Entry, 1 );
+ for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ )
+ {
+ if ( fFadds && Vec_IntEntry(vAdds, 6*i+2) == 0 )
+ continue;
+ if ( Vec_BitEntry(vIsBold, Vec_IntEntry(vAdds, 6*i+3)) || Vec_BitEntry(vIsBold, Vec_IntEntry(vAdds, 6*i+4)) )
+ continue;
+ Vec_IntWriteEntry( vMapAdds, Vec_IntEntry(vAdds, 6*i+3), i );
+ Vec_IntWriteEntry( vMapAdds, Vec_IntEntry(vAdds, 6*i+4), i );
+ }
+ Vec_BitFree( vIsBold );
+ return vMapAdds;
+}
+Vec_Int_t * Gia_ShowMapXors( Gia_Man_t * p, Vec_Int_t * vXors )
+{
+ Vec_Int_t * vMapXors = Vec_IntStartFull( Gia_ManObjNum(p) ); int i;
+ for ( i = 0; 4*i < Vec_IntSize(vXors); i++ )
+ Vec_IntWriteEntry( vMapXors, Vec_IntEntry(vXors, 4*i), i );
+ return vMapXors;
+}
+int Gia_ShowCollectObjs_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vAdds, Vec_Int_t * vXors, Vec_Int_t * vMapAdds, Vec_Int_t * vMapXors, Vec_Int_t * vOrder )
+{
+ int Level0, Level1, Level2 = 0, Level = 0;
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return Gia_ObjLevel(p, pObj);
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ if ( Gia_ObjIsCi(pObj) )
+ return 0;
+ if ( Vec_IntEntry(vMapAdds, Gia_ObjId(p, pObj)) >= 0 )
+ {
+ int iBox = Vec_IntEntry(vMapAdds, Gia_ObjId(p, pObj));
+ Gia_ObjSetTravIdCurrentId(p, Vec_IntEntry(vAdds, 6*iBox+3) );
+ Gia_ObjSetTravIdCurrentId(p, Vec_IntEntry(vAdds, 6*iBox+4) );
+ Level0 = Gia_ShowCollectObjs_rec( p, Gia_ManObj( p, Vec_IntEntry(vAdds, 6*iBox+0) ), vAdds, vXors, vMapAdds, vMapXors, vOrder );
+ Level1 = Gia_ShowCollectObjs_rec( p, Gia_ManObj( p, Vec_IntEntry(vAdds, 6*iBox+1) ), vAdds, vXors, vMapAdds, vMapXors, vOrder );
+ if ( Vec_IntEntry(vAdds, 6*iBox+2) )
+ Level2 = Gia_ShowCollectObjs_rec( p, Gia_ManObj( p, Vec_IntEntry(vAdds, 6*iBox+2) ), vAdds, vXors, vMapAdds, vMapXors, vOrder );
+ Level = 1 + Abc_MaxInt( Abc_MaxInt(Level0, Level1), Level2 );
+ Gia_ObjSetLevelId( p, Vec_IntEntry(vAdds, 6*iBox+3), Level );
+ Gia_ObjSetLevelId( p, Vec_IntEntry(vAdds, 6*iBox+4), Level );
+ pObj = Gia_ManObj( p, Vec_IntEntry(vAdds, 6*iBox+4) );
+ }
+ else if ( Vec_IntEntry(vMapXors, Gia_ObjId(p, pObj)) >= 0 )
+ {
+ int iXor = Vec_IntEntry(vMapXors, Gia_ObjId(p, pObj));
+ Level0 = Gia_ShowCollectObjs_rec( p, Gia_ManObj( p, Vec_IntEntry(vXors, 4*iXor+1) ), vAdds, vXors, vMapAdds, vMapXors, vOrder );
+ Level1 = Gia_ShowCollectObjs_rec( p, Gia_ManObj( p, Vec_IntEntry(vXors, 4*iXor+2) ), vAdds, vXors, vMapAdds, vMapXors, vOrder );
+ if ( Vec_IntEntry(vXors, 4*iXor+3) )
+ Level2 = Gia_ShowCollectObjs_rec( p, Gia_ManObj( p, Vec_IntEntry(vXors, 4*iXor+3) ), vAdds, vXors, vMapAdds, vMapXors, vOrder );
+ Level = 1 + Abc_MaxInt( Abc_MaxInt(Level0, Level1), Level2 );
+ Gia_ObjSetLevel( p, pObj, Level );
+ }
+ else
+ {
+ assert( !Gia_ObjIsMux(p, pObj) );
+ Level0 = Gia_ShowCollectObjs_rec( p, Gia_ObjFanin0(pObj), vAdds, vXors, vMapAdds, vMapXors, vOrder );
+ Level1 = Gia_ShowCollectObjs_rec( p, Gia_ObjFanin1(pObj), vAdds, vXors, vMapAdds, vMapXors, vOrder );
+ Level = 1 + Abc_MaxInt(Level0, Level1);
+ Gia_ObjSetLevel( p, pObj, Level );
+ }
+ Vec_IntPush( vOrder, Gia_ObjId(p, pObj) );
+ p->nLevels = Abc_MaxInt( p->nLevels, Level );
+ return Level;
+}
+Vec_Int_t * Gia_ShowCollectObjs( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vXors, Vec_Int_t * vMapAdds, Vec_Int_t * vMapXors )
+{
+ Gia_Obj_t * pObj; int i;
+ Vec_Int_t * vOrder = Vec_IntAlloc( 100 );
+ Gia_ManCleanLevels( p, Gia_ManObjNum(p) );
+ p->nLevels = 0;
+ Gia_ManIncrementTravId( p );
+ Gia_ObjSetTravIdCurrent(p, Gia_ManConst0(p));
+ Gia_ManForEachCi( p, pObj, i )
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ShowCollectObjs_rec( p, Gia_ObjFanin0(pObj), vAdds, vXors, vMapAdds, vMapXors, vOrder );
+ return vOrder;
}
/**Function*************************************************************
@@ -589,15 +1113,23 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int
SeeAlso []
***********************************************************************/
-void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders )
+void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_Int_t * vAdds, Vec_Int_t * vXors, int fFadds )
+{
+ Vec_Int_t * vMapAdds = Gia_ShowMapAdds( p, vAdds, fFadds, vBold );
+ Vec_Int_t * vMapXors = Gia_ShowMapXors( p, vXors );
+ Vec_Int_t * vOrder = Gia_ShowCollectObjs( p, vAdds, vXors, vMapAdds, vMapXors );
+ Gia_WriteDotAig( p, pFileName, vBold, vAdds, vXors, vMapAdds, vMapXors, vOrder );
+ Vec_IntFree( vMapAdds );
+ Vec_IntFree( vMapXors );
+ Vec_IntFree( vOrder );
+}
+void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds, int fPath )
{
extern void Abc_ShowFile( char * FileNameDot );
- static int Counter = 0;
char FileNameDot[200];
FILE * pFile;
- // create the file name
-// Gia_ShowGetFileName( pMan->pName, FileNameDot );
- sprintf( FileNameDot, "temp%02d.dot", Counter++ );
+ Vec_Int_t * vXors = NULL, * vAdds = fAdders ? Ree_ManComputeCuts( pMan, &vXors, 0 ) : NULL;
+ sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(pMan->pName, ".dot") );
// check that the file can be opened
if ( (pFile = fopen( FileNameDot, "w" )) == NULL )
{
@@ -606,12 +1138,23 @@ void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders )
}
fclose( pFile );
// generate the file
- Gia_WriteDotAig( pMan, FileNameDot, vBold, fAdders );
+ if ( fPath )
+ Gia_ShowPath( pMan, FileNameDot );
+ else if ( fAdders )
+ Gia_ShowProcess( pMan, FileNameDot, vBold, vAdds, vXors, fFadds );
+ else
+ Gia_WriteDotAigSimple( pMan, FileNameDot, vBold );
// visualize the file
Abc_ShowFile( FileNameDot );
+
+ Vec_IntFreeP( &vAdds );
+ Vec_IntFreeP( &vXors );
}
+
+
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaTim.c b/src/aig/gia/giaTim.c
index 71b9a475..29aa93f8 100644
--- a/src/aig/gia/giaTim.c
+++ b/src/aig/gia/giaTim.c
@@ -584,6 +584,8 @@ int Gia_ManLutLevelWithBoxes( Gia_Man_t * p )
Gia_Obj_t * pObj, * pObjIn;
int i, k, j, curCi, curCo, LevelMax;
assert( Gia_ManRegNum(p) == 0 );
+ if ( pManTime == NULL )
+ return Gia_ManLutLevel(p, NULL);
// copy const and real PIs
Gia_ManCleanLevels( p, Gia_ManObjNum(p) );
Gia_ObjSetLevel( p, Gia_ManConst0(p), 0 );
diff --git a/src/aig/gia/giaTruth.c b/src/aig/gia/giaTruth.c
index ce06fa0b..ab5f569e 100644
--- a/src/aig/gia/giaTruth.c
+++ b/src/aig/gia/giaTruth.c
@@ -139,6 +139,59 @@ word Gia_ObjComputeTruthTable6Lut( Gia_Man_t * p, int iObj, Vec_Wrd_t * vTemp )
/**Function*************************************************************
+ Synopsis [Computes truth table up to 6 inputs in terms of CIs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+word Gia_ObjComputeTruth6( Gia_Man_t * p, int iObj, Vec_Int_t * vSupp, Vec_Wrd_t * vTemp )
+{
+ int i, Fanin;
+ assert( Vec_WrdSize(vTemp) == Gia_ManObjNum(p) );
+ assert( Vec_IntSize(vSupp) <= 6 );
+ Gia_ManIncrementTravId( p );
+ Vec_IntForEachEntry( vSupp, Fanin, i )
+ {
+ Gia_ObjSetTravIdCurrentId( p, Fanin );
+ Vec_WrdWriteEntry( vTemp, Fanin, s_Truth6[i] );
+ }
+ Gia_ObjComputeTruthTable6Lut_rec( p, iObj, vTemp );
+ return Vec_WrdEntry( vTemp, iObj );
+}
+void Gia_ObjComputeTruth6CisSupport_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vSupp )
+{
+ Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
+ if ( Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ Vec_IntPushOrder( vSupp, iObj );
+ return;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ObjComputeTruth6CisSupport_rec( p, Gia_ObjFaninId0p(p, pObj), vSupp );
+ Gia_ObjComputeTruth6CisSupport_rec( p, Gia_ObjFaninId1p(p, pObj), vSupp );
+}
+word Gia_ObjComputeTruth6Cis( Gia_Man_t * p, int iLit, Vec_Int_t * vSupp, Vec_Wrd_t * vTemp )
+{
+ int iObj = Abc_Lit2Var(iLit);
+ Vec_IntClear( vSupp );
+ if ( !iObj ) return Abc_LitIsCompl(iLit) ? ~(word)0 : (word)0;
+ Gia_ManIncrementTravId( p );
+ Gia_ObjComputeTruth6CisSupport_rec( p, iObj, vSupp );
+ if ( Vec_IntSize(vSupp) > 6 )
+ return 0;
+ Gia_ObjComputeTruth6( p, iObj, vSupp, vTemp );
+ return Abc_LitIsCompl(iLit) ? ~Vec_WrdEntry(vTemp, iObj) : Vec_WrdEntry(vTemp, iObj);
+}
+
+/**Function*************************************************************
+
Synopsis [Computes truth table up to 6 inputs.]
Description []
diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c
index eccdbc73..c7af642e 100644
--- a/src/aig/gia/giaUtil.c
+++ b/src/aig/gia/giaUtil.c
@@ -937,8 +937,8 @@ int Gia_ObjRecognizeExor( Gia_Obj_t * pObj, Gia_Obj_t ** ppFan0, Gia_Obj_t ** pp
return 0;
if ( Gia_ObjFaninC0(p0) == Gia_ObjFaninC0(p1) || Gia_ObjFaninC1(p0) == Gia_ObjFaninC1(p1) )
return 0;
- *ppFan0 = Gia_ObjChild0(p0);
- *ppFan1 = Gia_ObjChild1(p0);
+ if ( ppFan0 ) *ppFan0 = Gia_ObjChild0(p0);
+ if ( ppFan1 ) *ppFan1 = Gia_ObjChild1(p0);
return 1;
}
diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make
index 0066bfd2..0ddf9833 100644
--- a/src/aig/gia/module.make
+++ b/src/aig/gia/module.make
@@ -59,6 +59,7 @@ SRC += src/aig/gia/giaAig.c \
src/aig/gia/giaSatLE.c \
src/aig/gia/giaSatLut.c \
src/aig/gia/giaSatMap.c \
+ src/aig/gia/giaSatoko.c \
src/aig/gia/giaScl.c \
src/aig/gia/giaScript.c \
src/aig/gia/giaShow.c \
diff --git a/src/aig/ivy/ivyFraig.c b/src/aig/ivy/ivyFraig.c
index 059f4c0e..d9887d74 100644
--- a/src/aig/ivy/ivyFraig.c
+++ b/src/aig/ivy/ivyFraig.c
@@ -2081,7 +2081,7 @@ void Ivy_FraigPrintActivity( Ivy_FraigMan_t * p )
{
int i;
for ( i = 0; i < p->nSatVars; i++ )
- printf( "%d %d ", i, p->pSat->activity[i] );
+ printf( "%d %d ", i, (int)p->pSat->activity[i] );
printf( "\n" );
}
diff --git a/src/aig/miniaig/abcapis.h b/src/aig/miniaig/abcapis.h
index 38c0591d..eb8586fe 100644
--- a/src/aig/miniaig/abcapis.h
+++ b/src/aig/miniaig/abcapis.h
@@ -52,11 +52,13 @@ extern int Cmd_CommandExecute( void * pAbc, char * pCommandLine );
// procedures to input/output 'mini AIG'
extern void Abc_NtkInputMiniAig( void * pAbc, void * pMiniAig );
extern void * Abc_NtkOutputMiniAig( void * pAbc );
+extern void Abc_FrameGiaInputMiniAig( void * pAbc, void * p );
+extern void * Abc_FrameGiaOutputMiniAig( void * pAbc );
extern void Abc_NtkSetFlopNum( void * pAbc, int nFlops );
-// procedures to input/output 'mini AIG'
-extern void Abc_NtkInputMiniLut( void * pAbc, void * pMiniLut );
-extern void * Abc_NtkOutputMiniLut( void * pAbc );
+// procedures to input/output 'mini LUT'
+extern void Abc_FrameGiaInputMiniLut( void * pAbc, void * pMiniLut );
+extern void * Abc_FrameGiaOutputMiniLut( void * pAbc );
// procedures to set CI/CO arrival/required times
extern void Abc_NtkSetCiArrivalTime( void * pAbc, int iCi, float Rise, float Fall );
diff --git a/src/aig/saig/saigMiter.c b/src/aig/saig/saigMiter.c
index 67aed490..598103de 100644
--- a/src/aig/saig/saigMiter.c
+++ b/src/aig/saig/saigMiter.c
@@ -1111,12 +1111,12 @@ int Ssw_SecSpecial( Aig_Man_t * pPart0, Aig_Man_t * pPart1, int nFrames, int fVe
// report the miter
if ( RetValue == 1 )
{
- printf( "Networks are equivalent. " );
+ printf( "Networks are equivalent. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
else if ( RetValue == 0 )
{
- printf( "Networks are NOT EQUIVALENT. " );
+ printf( "Networks are NOT EQUIVALENT. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
if ( pMiterCec->pData == NULL )
printf( "Counter-example is not available.\n" );
diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c
index f01ef07a..77b55bb3 100644
--- a/src/base/abc/abcUtil.c
+++ b/src/base/abc/abcUtil.c
@@ -1077,6 +1077,7 @@ void Abc_NtkLogicMakeSimpleCosTest( Abc_Ntk_t * pNtk, int fDuplicate )
***********************************************************************/
int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, int fDuplicate )
{
+ int fAddBuffers = 1;
Vec_Ptr_t * vDrivers, * vCoTerms;
Abc_Obj_t * pNode, * pDriver, * pDriverNew, * pFanin;
int i, k, LevelMax, nTotal = 0;
@@ -1191,6 +1192,12 @@ int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, int fDuplicate )
// collect COs that needs fixing by adding buffers or duplicating
vCoTerms = Vec_PtrAlloc( 100 );
Abc_NtkIncrementTravId( pNtk );
+
+ // The following cases should be addressed only if the network is written
+ // into a BLIF file. Otherwise, it is possible to skip them:
+ // (1) if a CO points to a CI with a different name
+ // (2) if an internal node drives more than one CO
+ if ( fAddBuffers )
Abc_NtkForEachCo( pNtk, pNode, i )
{
// if the driver is a CI and has different name, this is an error
@@ -2926,6 +2933,160 @@ void Abc_NtkTransferPhases( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk )
Vec_IntWriteEntry( pNtkNew->vPhases, Abc_ObjId( (Abc_Obj_t *)pObj->pCopy ), Vec_IntEntry(pNtk->vPhases, i) );
}
+/**Function*************************************************************
+
+ Synopsis [Starts a new network using existing network as a model.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkDeriveWithOnePo( Abc_Ntk_t * pNtk, Vec_Int_t * vNodeIds, Vec_Int_t * vNodeValues )
+{
+ int fCopyNames = 1;
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pObj, * pFanin, * pObjNew, * pOutputNew;
+ Vec_Ptr_t * vFanins = Vec_PtrAlloc( 100 );
+ int i, k, Id, Value;
+ // start the network
+ pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 );
+ // duplicate the name and the spec
+ pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
+ pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec);
+ // clean the node copy fields
+ Abc_NtkCleanCopy( pNtk );
+ // map the constant nodes
+ if ( Abc_NtkIsStrash(pNtk) && Abc_NtkIsStrash(pNtkNew) )
+ Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
+ // clone CIs/CIs/boxes
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ Abc_NtkDupObj( pNtkNew, pObj, fCopyNames );
+ //Abc_NtkForEachPo( pNtk, pObj, i )
+ // Abc_NtkDupObj( pNtkNew, pObj, fCopyNames );
+ // create one PO
+ pObjNew = Abc_NtkCreateObj( pNtkNew, ABC_OBJ_PO );
+ Abc_ObjAssignName( pObjNew, "monitor", NULL );
+ // create boxes
+ Abc_NtkForEachBox( pNtk, pObj, i )
+ Abc_NtkDupBox( pNtkNew, pObj, fCopyNames );
+
+ // duplicate nodes (CIs/COs/latches are already duplicated)
+ Abc_NtkForEachObj( pNtk, pObj, i )
+ if ( pObj->pCopy == NULL && !Abc_ObjIsPo(pObj) )
+ Abc_NtkDupObj(pNtkNew, pObj, 0);
+ // reconnect all objects except boxes (they are already connected) and POs (they will be connected later)
+ Abc_NtkForEachObj( pNtk, pObj, i )
+ if ( !Abc_ObjIsPo(pObj) && !Abc_ObjIsBox(pObj) && !Abc_ObjIsBo(pObj) )
+ Abc_ObjForEachFanin( pObj, pFanin, k )
+ Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
+
+ // AND nodes (with interters if needed)
+ pOutputNew = NULL;
+ Vec_IntForEachEntryTwo( vNodeIds, vNodeValues, Id, Value, i )
+ {
+ pObjNew = Abc_NtkObj( pNtk, Id )->pCopy;
+ if ( Value == 0 ) // negative polarity - add inverter
+ pObjNew = Abc_NtkCreateNodeInv( pNtkNew, pObjNew );
+ if ( pOutputNew == NULL )
+ pOutputNew = pObjNew;
+ else
+ {
+ Vec_PtrFillTwo( vFanins, 2, pOutputNew, pObjNew );
+ pOutputNew = Abc_NtkCreateNodeAnd( pNtkNew, vFanins );
+ }
+ }
+ Vec_PtrFree( vFanins );
+ // create the only POs, which is the AND of the corresponding nodes
+ Abc_ObjAddFanin( Abc_NtkPo(pNtkNew, 0), pOutputNew );
+
+ // check that the CI/CO/latches are copied correctly
+ assert( Abc_NtkPoNum(pNtkNew) == 1 );
+ assert( Abc_NtkCiNum(pNtkNew) == Abc_NtkCiNum(pNtk) );
+ assert( Abc_NtkLatchNum(pNtkNew) == Abc_NtkLatchNum(pNtk) );
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the AIG representing a property.]
+
+ Description [Given is a sequential logic network (Abc_Ntk_t) and
+ an array of nodes (vector of object IDs) and their values (vector of 0s or 1s).
+ This procedure creates a sequential AIG (Abc_Ntk_t), which can be given to a
+ sequential model checker (in particular "pdr") to prove that the given
+ combination of values never appears at the intenal nodes of the network,
+ or produce a counter-example showing that it can appear.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkCreatePropertyMonitor( Abc_Ntk_t * p, Vec_Int_t * vNodeIds, Vec_Int_t * vNodeValues )
+{
+ Abc_Ntk_t * pMonitor, * pStrashed, * pResult;
+ // sequential cleanup parameters
+ int fLatchConst = 1;
+ int fLatchEqual = 1;
+ int fSaveNames = 1;
+ int fUseMvSweep = 0;
+ int nFramesSymb = 1;
+ int nFramesSatur = 512;
+ int fVerbose = 0;
+ int fVeryVerbose = 0;
+ // expecting sequential logic network
+ assert( Abc_NtkIsLogic(p) );
+ assert( Abc_NtkLatchNum(p) > 0 );
+ assert( Vec_IntSize(vNodeIds) > 0 );
+ assert( Vec_IntSize(vNodeIds) == Vec_IntSize(vNodeValues) );
+ // derive ABC network whose only output is 1 iff the given nodes have the given values
+ pMonitor = Abc_NtkDeriveWithOnePo( p, vNodeIds, vNodeValues );
+ // perform structural hashing
+ pStrashed = Abc_NtkStrash( pMonitor, 0, 1, 0 );
+ Abc_NtkDelete( pMonitor );
+ // it is a good idea to run sequential cleanup before giving the network to PDR
+ pResult = Abc_NtkDarLatchSweep( pStrashed, fLatchConst, fLatchEqual, fSaveNames, fUseMvSweep, nFramesSymb, nFramesSatur, fVerbose, fVeryVerbose );
+ Abc_NtkDelete( pStrashed );
+ return pResult;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Testbench.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkCreatePropertyMonitorTest( Abc_Ntk_t * p )
+{
+ Abc_Ntk_t * pNtk;
+ Vec_Int_t * vNodeIds = Vec_IntAlloc( 100 );
+ Vec_Int_t * vNodeValues = Vec_IntAlloc( 100 );
+
+ // this test will only work for the network, which has nodes with internal IDs such as these
+ Vec_IntPush( vNodeIds, 90 );
+ Vec_IntPush( vNodeIds, 80 );
+ Vec_IntPush( vNodeIds, 100 );
+
+ Vec_IntPush( vNodeValues, 1 );
+ Vec_IntPush( vNodeValues, 0 );
+ Vec_IntPush( vNodeValues, 1 );
+
+ pNtk = Abc_NtkCreatePropertyMonitor( p, vNodeIds, vNodeValues );
+
+ Vec_IntFree( vNodeIds );
+ Vec_IntFree( vNodeValues );
+
+ return pNtk;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c
index 7da88d3c..466af66a 100644
--- a/src/base/abci/abc.c
+++ b/src/base/abci/abc.c
@@ -1,15 +1,15 @@
/**CFile****************************************************************
-
- FileName [abc.c]
+
+ FileName [abc.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
-
+
Synopsis [Command file.]
Author [Alan Mishchenko]
-
+
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
@@ -42,6 +42,8 @@
#include "bool/kit/kit.h"
#include "map/amap/amap.h"
#include "opt/ret/retInt.h"
+#include "sat/xsat/xsat.h"
+#include "sat/satoko/satoko.h"
#include "sat/cnf/cnf.h"
#include "proof/cec/cec.h"
#include "proof/acec/acec.h"
@@ -306,6 +308,9 @@ static int Abc_CommandDCec ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandDSec ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandSat ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandDSat ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandXSat ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandSatoko ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9Satoko ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPSat ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandProve ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandIProve ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -479,6 +484,8 @@ static int Abc_CommandAbc9Fadds ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandAbc9ATree ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Polyn ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Acec ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9Anorm ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9Decla ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Esop ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Exorcism ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Mfs ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -520,7 +527,7 @@ extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan );
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
@@ -545,7 +552,7 @@ void Abc_FrameReplaceCex( Abc_Frame_t * pAbc, Abc_Cex_t ** ppCex )
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
@@ -623,7 +630,7 @@ Vec_Int_t * Abc_FrameDeriveStatusArray( Vec_Ptr_t * vCexes )
Vec_PtrForEachEntry( Abc_Cex_t *, vCexes, pCex, i )
if ( pCex != NULL )
Vec_IntWriteEntry( vStatuses, i, 0 ); // set this output as SAT
- return vStatuses;
+ return vStatuses;
}
/**Function*************************************************************
@@ -951,6 +958,9 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Verification", "match", Abc_CommandMatch, 0 );
Cmd_CommandAdd( pAbc, "Verification", "sat", Abc_CommandSat, 0 );
Cmd_CommandAdd( pAbc, "Verification", "dsat", Abc_CommandDSat, 0 );
+ Cmd_CommandAdd( pAbc, "Verification", "xsat", Abc_CommandXSat, 0 );
+ Cmd_CommandAdd( pAbc, "Verification", "satoko", Abc_CommandSatoko, 0 );
+ Cmd_CommandAdd( pAbc, "Verification", "&satoko", Abc_CommandAbc9Satoko, 0 );
Cmd_CommandAdd( pAbc, "Verification", "psat", Abc_CommandPSat, 0 );
Cmd_CommandAdd( pAbc, "Verification", "prove", Abc_CommandProve, 1 );
Cmd_CommandAdd( pAbc, "Verification", "iprove", Abc_CommandIProve, 1 );
@@ -966,8 +976,8 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Verification", "constr", Abc_CommandConstr, 0 );
Cmd_CommandAdd( pAbc, "Verification", "unfold", Abc_CommandUnfold, 1 );
Cmd_CommandAdd( pAbc, "Verification", "fold", Abc_CommandFold, 1 );
- Cmd_CommandAdd( pAbc, "Verification", "unfold2", Abc_CommandUnfold2, 1 ); // jlong
- Cmd_CommandAdd( pAbc, "Verification", "fold2", Abc_CommandFold2, 1 ); // jlong
+ Cmd_CommandAdd( pAbc, "Verification", "unfold2", Abc_CommandUnfold2, 1 ); // jlong
+ Cmd_CommandAdd( pAbc, "Verification", "fold2", Abc_CommandFold2, 1 ); // jlong
Cmd_CommandAdd( pAbc, "Verification", "bm", Abc_CommandBm, 1 );
Cmd_CommandAdd( pAbc, "Verification", "bm2", Abc_CommandBm2, 1 );
Cmd_CommandAdd( pAbc, "Verification", "saucy3", Abc_CommandSaucy, 1 );
@@ -1121,6 +1131,8 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "ABC9", "&atree", Abc_CommandAbc9ATree, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&polyn", Abc_CommandAbc9Polyn, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&acec", Abc_CommandAbc9Acec, 0 );
+ Cmd_CommandAdd( pAbc, "ABC9", "&anorm", Abc_CommandAbc9Anorm, 0 );
+ Cmd_CommandAdd( pAbc, "ABC9", "&decla", Abc_CommandAbc9Decla, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&esop", Abc_CommandAbc9Esop, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&exorcism", Abc_CommandAbc9Exorcism, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&mfs", Abc_CommandAbc9Mfs, 0 );
@@ -2717,8 +2729,8 @@ int Abc_CommandPrintStatus( Abc_Frame_t * pAbc, int argc, char ** argv )
{
if ( fShort )
{
- printf( "Status array contains %d SAT, %d UNSAT, and %d UNDEC entries (out of %d).",
- Vec_IntCountEntry(pAbc->vStatuses, 0), Vec_IntCountEntry(pAbc->vStatuses, 1),
+ printf( "Status array contains %d SAT, %d UNSAT, and %d UNDEC entries (out of %d).",
+ Vec_IntCountEntry(pAbc->vStatuses, 0), Vec_IntCountEntry(pAbc->vStatuses, 1),
Vec_IntCountEntry(pAbc->vStatuses, -1), Vec_IntSize(pAbc->vStatuses) );
}
else
@@ -5296,7 +5308,7 @@ int Abc_CommandMfs2( Abc_Frame_t * pAbc, int argc, char ** argv )
}
if ( Vec_IntSize(pAbc->vIndFlops) != Abc_NtkLatchNum(pNtk) )
{
- Abc_Print( -1, "The saved flop count (%d) does not match that of the current network (%d).\n",
+ Abc_Print( -1, "The saved flop count (%d) does not match that of the current network (%d).\n",
Vec_IntSize(pAbc->vIndFlops), Abc_NtkLatchNum(pNtk) );
return 0;
}
@@ -6380,7 +6392,7 @@ int Abc_CommandTestRPO(Abc_Frame_t * pAbc, int argc, char ** argv) {
goto usage;
}
}
- if (argc != globalUtilOptind + 1)
+ if (argc != globalUtilOptind + 1)
{
Abc_Print(1, "Input file is not given.\n");
goto usage;
@@ -12007,7 +12019,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
}
*/
// if ( pNtk )
-// Abc_NtkMakeLegit( pNtk );
+// Abc_NtkMakeLegit( pNtk );
{
// extern void Ifd_ManDsdTest();
// Ifd_ManDsdTest();
@@ -14270,7 +14282,7 @@ usage:
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
@@ -14311,7 +14323,7 @@ usage:
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
@@ -14390,7 +14402,7 @@ usage:
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
@@ -15765,7 +15777,7 @@ int Abc_CommandMap( Abc_Frame_t * pAbc, int argc, char ** argv )
}
nGatesMin = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( nGatesMin < 0 )
+ if ( nGatesMin < 0 )
goto usage;
break;
case 'a':
@@ -16468,7 +16480,7 @@ usage:
SeeAlso []
***********************************************************************/
-#if 0
+#if 0
int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv )
{
char Buffer[100];
@@ -16839,7 +16851,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nRelaxRatio = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nRelaxRatio < 0 )
+ if ( pPars->nRelaxRatio < 0 )
goto usage;
break;
case 'N':
@@ -17213,7 +17225,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
}
}
-
+
// complain if truth tables are requested but the cut size is too large
if ( pPars->fTruth && pPars->nLutSize > IF_MAX_FUNC_LUTSIZE )
{
@@ -18120,7 +18132,7 @@ int Abc_CommandInit( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_LatchSetInit0( pObj );
else if ( pInitStr[i] == '1' )
Abc_LatchSetInit1( pObj );
- else
+ else
Abc_LatchSetInitDc( pObj );
return 0;
}
@@ -18302,7 +18314,7 @@ int Abc_CommandUndc( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( fUseCex )
{
- char * pInit;
+ char * pInit;
Abc_Cex_t * pTemp;
int k, nFlopsX = 0;
if ( pAbc->pCex == NULL )
@@ -18317,7 +18329,7 @@ int Abc_CommandUndc( Abc_Frame_t * pAbc, int argc, char ** argv )
// compare this value
if ( Abc_NtkPiNum(pNtk) + nFlopsX != pAbc->pCex->nPis )
{
- Abc_Print( -1, "The number of PIs (%d) plus X-valued flops (%d) in the original network does not match the number of PIs in the current CEX (%d).\n",
+ Abc_Print( -1, "The number of PIs (%d) plus X-valued flops (%d) in the original network does not match the number of PIs in the current CEX (%d).\n",
Abc_NtkPiNum(pNtk), Abc_NtkLatchNum(pNtk), pAbc->pCex->nPis );
return 1;
}
@@ -19529,7 +19541,7 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( Abc_NtkIsComb(pNtk) )
{
- Abc_Print( -1, "The network is combinational (run \"fraig\" or \"fraig_sweep\").\n" );
+ Abc_Print( 0, "The network is combinational (run \"fraig\" or \"fraig_sweep\").\n" );
return 0;
}
@@ -20701,7 +20713,7 @@ int Abc_CommandSim3( Abc_Frame_t * pAbc, int argc, char ** argv )
extern int Abc_NtkDarSeqSim3( Abc_Ntk_t * pNtk, Ssw_RarPars_t * pPars );
Ssw_RarPars_t Pars, * pPars = &Pars;
Abc_Ntk_t * pNtkRes, * pNtk = Abc_FrameReadNtk(pAbc);
- Vec_Ptr_t * vSeqModelVec;
+ Vec_Ptr_t * vSeqModelVec;
int c;
Ssw_RarSetDefaultParams( pPars );
Extra_UtilGetoptReset();
@@ -23168,6 +23180,302 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandXSat( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ abctime clk;
+ int c;
+ int fVerbose = 0;
+ int nConfLimit = 0;
+ int nInsLimit = 0;
+ int nLearnedStart = 0;
+ int nLearnedDelta = 0;
+ int nLearnedPerce = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "CILDEhv" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'C':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nConfLimit = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nConfLimit < 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;
+ }
+ nInsLimit = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nInsLimit < 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;
+ }
+ nLearnedStart = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nLearnedStart < 0 )
+ goto usage;
+ break;
+ case 'D':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-D\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nLearnedDelta = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nLearnedDelta < 0 )
+ goto usage;
+ break;
+ case 'E':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-E\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nLearnedPerce = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nLearnedPerce < 0 )
+ goto usage;
+ break;
+ case 'h':
+ goto usage;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+
+ default:
+ goto usage;
+ }
+ }
+
+ if ( argc == globalUtilOptind + 1 )
+ {
+ char * pFileName = argv[globalUtilOptind];
+ xSAT_Solver_t * p;
+ int status;
+
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for writing.\n", pFileName );
+ return 0;
+ }
+ xSAT_SolverParseDimacs( pFile, &p );
+
+ clk = Abc_Clock();
+ status = xSAT_SolverSolve( p );
+ fclose( pFile );
+
+ xSAT_SolverPrintStats( p );
+ if ( status == 0 )
+ Abc_Print( 1, "UNDECIDED " );
+ else if ( status == 1 )
+ Abc_Print( 1, "SATISFIABLE " );
+ else
+ Abc_Print( 1, "UNSATISFIABLE " );
+
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+
+ xSAT_SolverDestroy( p );
+ return 0;
+ }
+
+usage:
+ Abc_Print( -2, "usage: xsat [-CILDE num] [-hv]<file>.cnf\n" );
+ Abc_Print( -2, "\t solves the combinational miter using SAT solver MiniSat-1.14\n" );
+ Abc_Print( -2, "\t derives CNF from the current network and leaves it unchanged\n" );
+ Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfLimit );
+ Abc_Print( -2, "\t-I num : limit on the number of inspections [default = %d]\n", nInsLimit );
+ Abc_Print( -2, "\t-L num : starting value for learned clause removal [default = %d]\n", nLearnedStart );
+ Abc_Print( -2, "\t-D num : delta value for learned clause removal [default = %d]\n", nLearnedDelta );
+ Abc_Print( -2, "\t-E num : ratio percentage for learned clause removal [default = %d]\n", nLearnedPerce );
+ Abc_Print( -2, "\t-v : prints 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_CommandSatoko( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern satoko_opts_t * Cmd_DeriveOptionFromSettings( int argc, char ** argv );
+
+ // create default options
+ satoko_opts_t opts, * popts;
+ satoko_default_opts(&opts);
+
+ // override default options
+ popts = Cmd_DeriveOptionFromSettings( argc, argv );
+ if ( popts == NULL )
+ goto usage;
+ memcpy( &opts, popts, sizeof(satoko_opts_t) );
+ ABC_FREE( popts );
+
+ if ( argc == globalUtilOptind + 1 )
+ {
+ abctime clk;
+ char * pFileName = argv[globalUtilOptind];
+ satoko_t * p;
+ int status;
+
+ status = satoko_parse_dimacs( pFileName, &p );
+ satoko_configure(p, &opts);
+
+ clk = Abc_Clock();
+ if ( status == SATOKO_OK )
+ status = satoko_solve( p );
+
+ if ( status == SATOKO_UNDEC )
+ Abc_Print( 1, "UNDECIDED " );
+ else if ( status == SATOKO_SAT )
+ Abc_Print( 1, "SATISFIABLE " );
+ else
+ Abc_Print( 1, "UNSATISFIABLE " );
+
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+
+ satoko_destroy( p );
+ return 0;
+ }
+
+usage:
+#ifdef SATOKO_ACT_VAR_FIXED
+ Abc_Print( -2, "usage: satoko [-CPDEFGHIJKLMNOQRSTU num] [-hv]<file>.cnf\n" );
+#else
+ Abc_Print( -2, "usage: satoko [-CPDEFGHIJKLMNOQRS num] [-hv]<file>.cnf\n" );
+#endif
+ Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", opts.conf_limit );
+ Abc_Print( -2, "\t-P num : limit on the number of propagations [default = %d]\n", opts.conf_limit );
+ Abc_Print( -2, "\n\tConstants used for restart heuristic:\n");
+ Abc_Print( -2, "\t-D num : Constant value used by restart heuristics in forcing restarts [default = %f]\n", opts.f_rst );
+ Abc_Print( -2, "\t-E num : Constant value used by restart heuristics in blocking restarts [default = %f]\n", opts.b_rst );
+ Abc_Print( -2, "\t-F num : Lower bound n.of conflicts for start blocking restarts [default = %d]\n", opts.fst_block_rst );
+ Abc_Print( -2, "\t-G num : Size of the moving avarege queue for LBD (force restart) [default = %d]\n", opts.sz_lbd_bqueue );
+ Abc_Print( -2, "\t-H num : Size of the moving avarege queue for Trail size (block restart) [default = %d]\n", opts.sz_trail_bqueue );
+ Abc_Print( -2, "\n\tConstants used for clause database reduction heuristic:\n");
+ Abc_Print( -2, "\t-I num : N.of conflicts before first clause databese reduction [default = %d]\n", opts.n_conf_fst_reduce );
+ Abc_Print( -2, "\t-J num : Increment to reduce [default = %d]\n", opts.inc_reduce );
+ Abc_Print( -2, "\t-K num : Special increment to reduce [default = %d]\n", opts.inc_special_reduce );
+ Abc_Print( -2, "\t-L num : Protecs clauses from deletion for one turn if its LBD is lower [default = %d]\n", opts.lbd_freeze_clause );
+ Abc_Print( -2, "\t-M num : Percentage of learned clauses to remove [default = %d]\n", ( int )( 100 * opts.learnt_ratio ) );
+ Abc_Print( -2, "\t-N num : Max percentage of garbage in clause database [default = %d]\n", ( int )( 100 * opts.garbage_max_ratio ) );
+ Abc_Print( -2, "\n\tConstants used for binary resolution (clause minimization):\n");
+ Abc_Print( -2, "\t-O num : Max clause size for binary resolution [default = %d]\n", opts.clause_max_sz_bin_resol );
+ Abc_Print( -2, "\t-Q num : Min clause LBD for binary resolution [default = %d]\n", opts.clause_min_lbd_bin_resol );
+ Abc_Print( -2, "\n\tConstants used for branching (VSIDS heuristic):\n");
+ Abc_Print( -2, "\t-R num : Clause activity decay factor (when using float clause activity) [default = %f]\n", opts.clause_decay );
+ Abc_Print( -2, "\t-S num : Varibale activity decay factor [default = %f]\n", opts.var_decay );
+#ifdef SATOKO_ACT_VAR_FIXED
+ Abc_Print( -2, "\t-T num : Variable activity limit valeu [default = 0x%08X]\n", opts.var_act_limit );
+ Abc_Print( -2, "\t-U num : Variable activity re-scale factor [default = 0x%08X]\n", opts.var_act_rescale );
+#endif
+ Abc_Print( -2, "\n\t-v : prints verbose information [default = %s]\n", opts.verbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandAbc9Satoko( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Gia_ManSatokoCall( Gia_Man_t * p, satoko_opts_t * opts, int fSplit, int fIncrem );
+ int c, fSplit = 0, fIncrem = 0;
+
+ satoko_opts_t opts;
+ satoko_default_opts(&opts);
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Csivh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'C':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ opts.conf_limit = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( opts.conf_limit < 0 )
+ goto usage;
+ break;
+ case 's':
+ fSplit ^= 1;
+ break;
+ case 'i':
+ fIncrem ^= 1;
+ break;
+ case 'v':
+ opts.verbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+
+ default:
+ goto usage;
+ }
+ }
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Satoko(): There is no AIG.\n" );
+ return 1;
+ }
+ Gia_ManSatokoCall( pAbc->pGia, &opts, fSplit, fIncrem );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &satoko [-C num] [-sivh]\n" );
+ Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", opts.conf_limit );
+ Abc_Print( -2, "\t-s : split multi-output miter into individual outputs [default = %s]\n", fSplit? "yes": "no" );
+ Abc_Print( -2, "\t-i : split multi-output miter and solve incrementally [default = %s]\n", fIncrem? "yes": "no" );
+ Abc_Print( -2, "\t-v : prints verbose information [default = %s]\n", opts.verbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandPSat( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
@@ -24155,7 +24463,7 @@ int Abc_CommandBmc3( Abc_Frame_t * pAbc, int argc, char ** argv )
}
}
vStatuses = Abc_FrameDeriveStatusArray( vSeqModelVec );
- Abc_FrameReplacePoStatuses( pAbc, &vStatuses );
+ Abc_FrameReplacePoStatuses( pAbc, &vStatuses );
if ( vSeqModelVec )
Abc_FrameReplaceCexVec( pAbc, &vSeqModelVec );
else
@@ -25483,47 +25791,47 @@ usage:
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandBm2( Abc_Frame_t * pAbc, int argc, char ** argv )
-{
+{
FILE * pOut, * pErr;
Abc_Ntk_t *pNtk, *pNtk1, *pNtk2;
- int fDelete1, fDelete2;
+ int fDelete1, fDelete2;
Abc_Obj_t * pObj;
char ** pArgvNew;
- int c, nArgcNew, i;
+ int c, nArgcNew, i;
extern void saucyGateWay( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodePo, FILE * gFile, int fBooleanMatching,
int fLookForSwaps, int fFixOutputs, int fFixInputs, int fQuiet, int fPrintTree);
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
- pErr = Abc_FrameReadErr(pAbc);
-
+ pErr = Abc_FrameReadErr(pAbc);
+
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
{
switch ( c )
{
case 'h':
- goto usage;
+ goto usage;
default:
Abc_Print( -2, "Unknown switch.\n");
goto usage;
}
}
-
+
pArgvNew = argv + globalUtilOptind;
nArgcNew = argc - globalUtilOptind;
if ( !Abc_NtkPrepareTwoNtks( pErr, pNtk, pArgvNew, nArgcNew , &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) )
return 1;
-
- if( (unsigned)Abc_NtkPiNum(pNtk1) != (unsigned)Abc_NtkPiNum(pNtk2) ||
+
+ if( (unsigned)Abc_NtkPiNum(pNtk1) != (unsigned)Abc_NtkPiNum(pNtk2) ||
(unsigned)Abc_NtkPoNum(pNtk1) != (unsigned)Abc_NtkPoNum(pNtk2) )
{
Abc_Print( -2, "Mismatch in the number of inputs or outputs\n");
@@ -25532,7 +25840,7 @@ int Abc_CommandBm2( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( fDelete2 ) Abc_NtkDelete( pNtk2 );
return 1;
}
-
+
Abc_NtkPermute(pNtk2, 1, 1, 0, NULL );
Abc_NtkShortNames(pNtk2);
@@ -25562,7 +25870,7 @@ int Abc_CommandBm2( Abc_Frame_t * pAbc, int argc, char ** argv )
saucyGateWay( pNtk1, NULL, NULL, 1, 0, 0, 0, 0, 0);
if ( fDelete1 ) Abc_NtkDelete( pNtk1 );
- if ( fDelete2 ) Abc_NtkDelete( pNtk2 );
+ if ( fDelete2 ) Abc_NtkDelete( pNtk2 );
return 0;
usage:
@@ -25570,8 +25878,8 @@ usage:
Abc_Print( -2, "\t performs Boolean matching (PP-equivalence)\n" );
Abc_Print( -2, "\t for equivalent circuits, permutation that maps one circuit\n" );
Abc_Print( -2, "\t to another is printed to standard output (PIs and POs of the\n" );
- Abc_Print( -2, "\t first network have prefix \"N1:\", while PIs and POs of the\n" );
- Abc_Print( -2, "\t second network have prefix \"N2:\")\n" );
+ Abc_Print( -2, "\t first network have prefix \"N1:\", while PIs and POs of the\n" );
+ Abc_Print( -2, "\t second network have prefix \"N2:\")\n" );
Abc_Print( -2, "\t-h : print the command usage\n");
Abc_Print( -2, "\tfile1 : the file with the first network\n");
Abc_Print( -2, "\tfile2 : the file with the second network\n");
@@ -25593,14 +25901,14 @@ usage:
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandSaucy( Abc_Frame_t * pAbc, int argc, char ** argv )
-{
+{
Abc_Ntk_t *pNtk;
char * outputName = NULL;
FILE * gFile = NULL;
@@ -25629,20 +25937,20 @@ int Abc_CommandSaucy( Abc_Frame_t * pAbc, int argc, char ** argv )
outputName = argv[globalUtilOptind];
if ( !strcmp(argv[globalUtilOptind], "all") )
fOutputsOneAtTime ^= 1;
- globalUtilOptind++;
+ globalUtilOptind++;
break;
case 'F':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-F\" should be followed by a file name.\n" );
goto usage;
- }
+ }
if ( (gFile = fopen( argv[globalUtilOptind], "w" )) == NULL )
{
- Abc_Print( -1, "Cannot create output file \"%s\". ", argv[globalUtilOptind] );
+ Abc_Print( -1, "Cannot create output file \"%s\". ", argv[globalUtilOptind] );
return 1;
}
- globalUtilOptind++;
+ globalUtilOptind++;
break;
case 'i':
fFixOutputs ^= 1;
@@ -25665,9 +25973,9 @@ int Abc_CommandSaucy( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -2, "Unknown switch.\n");
goto usage;
}
- }
-
- pNtk = Abc_FrameReadNtk(pAbc);
+ }
+
+ pNtk = Abc_FrameReadNtk(pAbc);
if ( pNtk == NULL )
{
@@ -25690,21 +25998,21 @@ int Abc_CommandSaucy( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_NtkForEachPo( pNtk, pNodePo, i ) {
printf("Ouput %s\n\n", Abc_ObjName(pNodePo));
saucyGateWay( pNtk, pNodePo, gFile, 0, fLookForSwaps, fFixOutputs, fFixInputs, fQuiet, fPrintTree );
- printf("----------------------------------------\n");
+ printf("----------------------------------------\n");
}
fclose(hadi);
} else if (outputName != NULL) {
int i;
- Abc_Obj_t * pNodePo;
+ Abc_Obj_t * pNodePo;
Abc_NtkForEachPo( pNtk, pNodePo, i ) {
if (!strcmp(Abc_ObjName(pNodePo), outputName)) {
saucyGateWay( pNtk, pNodePo, gFile, 0, fLookForSwaps, fFixOutputs, fFixInputs, fQuiet, fPrintTree );
Abc_NtkDelete( pNtk );
return 0;
- }
+ }
}
Abc_Print( -1, "Output not found\n" );
- return 1;
+ return 1;
} else
saucyGateWay( pNtk, NULL, gFile, 0, fLookForSwaps, fFixOutputs, fFixInputs, fQuiet, fPrintTree );
@@ -25715,9 +26023,9 @@ int Abc_CommandSaucy( Abc_Frame_t * pAbc, int argc, char ** argv )
usage:
Abc_Print( -2, "usage: saucy3 [-O <name>] [-F <file>] [-iosqvh]\n\n" );
Abc_Print( -2, "\t computes functional symmetries of the netowrk\n" );
- Abc_Print( -2, "\t prints symmetry generators to the standard output\n" );
+ Abc_Print( -2, "\t prints symmetry generators to the standard output\n" );
Abc_Print( -2, "\t-O <name> : (optional) compute symmetries only for output given by name\n");
- Abc_Print( -2, "\t only inputs in the output cone are permuted\n");
+ Abc_Print( -2, "\t only inputs in the output cone are permuted\n");
Abc_Print( -2, "\t (special case) name=all, compute symmetries for each\n" );
Abc_Print( -2, "\t output, but only one output at a time\n" );
Abc_Print( -2, "\t [default = compute symmetries by permuting all I/Os]\n" );
@@ -25726,8 +26034,8 @@ usage:
Abc_Print( -2, "\t-o : permute just the outputs (fix the inputs) [default = no]\n");
Abc_Print( -2, "\t-s : only look for swaps of inputs [default = no]\n");
Abc_Print( -2, "\t-q : quiet (do not print symmetry generators) [default = no]\n");
- Abc_Print( -2, "\t-v : verbose (print the search tree) [default = no]\n");
- Abc_Print( -2, "\t-h : print the command usage\n");
+ Abc_Print( -2, "\t-v : verbose (print the search tree) [default = no]\n");
+ Abc_Print( -2, "\t-h : print the command usage\n");
Abc_Print( -2, "\t \n" );
Abc_Print( -2, "\t This command was contributed by Hadi Katebi from U Michigan.\n" );
@@ -25863,7 +26171,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv )
int c;
Pdr_ManSetDefaultParams( pPars );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGaxrmsipdegovwzh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDQTHGSaxrmuyfsipdegjonctkvwzh" ) ) != EOF )
{
switch ( c )
{
@@ -25911,10 +26219,10 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->nConfGenLimit < 0 )
goto usage;
break;
- case 'R':
+ case 'Q':
if ( globalUtilOptind >= argc )
{
- Abc_Print( -1, "Command line switch \"-R\" should be followed by an integer.\n" );
+ Abc_Print( -1, "Command line switch \"-Q\" should be followed by an integer.\n" );
goto usage;
}
pPars->nRestLimit = atoi(argv[globalUtilOptind]);
@@ -25955,6 +26263,17 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->nTimeOutGap < 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;
+ }
+ pPars->nRandomSeed = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nRandomSeed < 0 )
+ goto usage;
+ break;
case 'a':
pPars->fSolveAll ^= 1;
break;
@@ -25967,6 +26286,15 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'm':
pPars->fMonoCnf ^= 1;
break;
+ case 'u':
+ pPars->fNewXSim ^= 1;
+ break;
+ case 'y':
+ pPars->fFlopPrio ^= 1;
+ break;
+ case 'f':
+ pPars->fFlopOrder ^= 1;
+ break;
case 's':
pPars->fShortest ^= 1;
break;
@@ -25985,9 +26313,24 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'g':
pPars->fSkipGeneral ^= 1;
break;
+ case 'j':
+ pPars->fSimpleGeneral ^= 1;
+ break;
case 'o':
pPars->fUsePropOut ^= 1;
break;
+ case 'n':
+ pPars->fSkipDown ^= 1;
+ break;
+ case 'c':
+ pPars->fCtgs ^= 1;
+ break;
+ case 't':
+ pPars->fUseAbs ^= 1;
+ break;
+ case 'k':
+ pPars->fUseSimpleRef ^= 1;
+ break;
case 'v':
pPars->fVerbose ^= 1;
break;
@@ -26029,33 +26372,49 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: pdr [-MFCDRTHG <num>] [-axrmsipdegovwzh]\n" );
+ Abc_Print( -2, "usage: pdr [-MFCDQTHGS <num>] [-axrmuyfsipdegjonctkvwzh]\n" );
Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" );
- Abc_Print( -2, "\t pioneered by Aaron Bradley (http://ecee.colorado.edu/~bradleya/ic3/)\n" );
+ Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" );
Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" );
Abc_Print( -2, "\t-M num : limit on unused vars to trigger SAT solver recycling [default = %d]\n", pPars->nRecycle );
Abc_Print( -2, "\t-F num : limit on timeframes explored to stop computation [default = %d]\n", pPars->nFrameMax );
Abc_Print( -2, "\t-C num : limit on conflicts in one SAT call (0 = no limit) [default = %d]\n", pPars->nConfLimit );
Abc_Print( -2, "\t-D num : limit on conflicts during ind-generalization (0 = no limit) [default = %d]\n",pPars->nConfGenLimit );
- Abc_Print( -2, "\t-R num : limit on proof obligations before a restart (0 = no limit) [default = %d]\n", pPars->nRestLimit );
+ Abc_Print( -2, "\t-Q num : limit on proof obligations before a restart (0 = no limit) [default = %d]\n", pPars->nRestLimit );
Abc_Print( -2, "\t-T num : runtime limit, in seconds (0 = no limit) [default = %d]\n", pPars->nTimeOut );
Abc_Print( -2, "\t-H num : runtime limit per output, in miliseconds (with \"-a\") [default = %d]\n", pPars->nTimeOutOne );
Abc_Print( -2, "\t-G num : runtime gap since the last CEX (0 = no limit) [default = %d]\n", pPars->nTimeOutGap );
+ Abc_Print( -2, "\t-S num : * value to seed the SAT solver with [default = %d]\n", pPars->nRandomSeed );
Abc_Print( -2, "\t-a : toggle solving all outputs even if one of them is SAT [default = %s]\n", pPars->fSolveAll? "yes": "no" );
Abc_Print( -2, "\t-x : toggle storing CEXes when solving all outputs [default = %s]\n", pPars->fStoreCex? "yes": "no" );
Abc_Print( -2, "\t-r : toggle using more effort in generalization [default = %s]\n", pPars->fTwoRounds? "yes": "no" );
Abc_Print( -2, "\t-m : toggle using monolythic CNF computation [default = %s]\n", pPars->fMonoCnf? "yes": "no" );
+ Abc_Print( -2, "\t-u : toggle updated X-valued simulation [default = %s]\n", pPars->fNewXSim? "yes": "no" );
+ Abc_Print( -2, "\t-y : toggle using structural flop priorities [default = %s]\n", pPars->fFlopPrio? "yes": "no" );
+ Abc_Print( -2, "\t-f : toggle ordering flops by cost before generalization [default = %s]\n", pPars->fFlopOrder? "yes": "no" );
Abc_Print( -2, "\t-s : toggle creating only shortest counter-examples [default = %s]\n", pPars->fShortest? "yes": "no" );
Abc_Print( -2, "\t-i : toggle clause pushing from an intermediate timeframe [default = %s]\n", pPars->fShiftStart? "yes": "no" );
Abc_Print( -2, "\t-p : toggle reusing proof-obligations in the last timeframe [default = %s]\n", pPars->fReuseProofOblig? "yes": "no" );
Abc_Print( -2, "\t-d : toggle dumping invariant (valid if init state is all-0) [default = %s]\n", pPars->fDumpInv? "yes": "no" );
Abc_Print( -2, "\t-e : toggle using only support variables in the invariant [default = %s]\n", pPars->fUseSupp? "yes": "no" );
Abc_Print( -2, "\t-g : toggle skipping expensive generalization step [default = %s]\n", pPars->fSkipGeneral? "yes": "no" );
+ Abc_Print( -2, "\t-j : toggle using simplified generalization step [default = %s]\n", pPars->fSimpleGeneral? "yes": "no" );
Abc_Print( -2, "\t-o : toggle using property output as inductive hypothesis [default = %s]\n", pPars->fUsePropOut? "yes": "no" );
+ Abc_Print( -2, "\t-n : * toggle skipping \'down\' in generalization [default = %s]\n", pPars->fSkipDown? "yes": "no" );
+ Abc_Print( -2, "\t-c : * toggle handling CTGs in \'down\' [default = %s]\n", pPars->fCtgs? "yes": "no" );
+ Abc_Print( -2, "\t-t : toggle using abstraction [default = %s]\n", pPars->fUseAbs? "yes": "no" );
+ Abc_Print( -2, "\t-k : toggle using simplified refinement [default = %s]\n", pPars->fUseSimpleRef? "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 default = %s]\n", pPars->fVeryVerbose? "yes": "no" );
Abc_Print( -2, "\t-z : toggle suppressing report about solved outputs [default = %s]\n", pPars->fNotVerbose? "yes": "no" );
- Abc_Print( -2, "\t-h : print the command usage\n");
+ Abc_Print( -2, "\t-h : print the command usage\n\n");
+ Abc_Print( -2, "\t* Implementation of switches -S, -n, and -c is contributed by Zyad Hassan.\n");
+ Abc_Print( -2, "\t The theory and experiments supporting this work can be found in the following paper:\n");
+ Abc_Print( -2, "\t Zyad Hassan, Aaron R. Bradley, Fabio Somenzi, \"Better Generalization in IC3\", FMCAD 2013.\n");
+ Abc_Print( -2, "\t (http://www.cs.utexas.edu/users/hunt/FMCAD/FMCAD13/papers/85-Better-Generalization-IC3.pdf)\n");
+
+
+
return 1;
}
@@ -27055,7 +27414,7 @@ int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv )
pAig = Gia_ManReadMiniLut( FileName );
// else if ( Extra_FileIsType( FileName, ".v", NULL, NULL ) )
// Abc3_ReadShowHie( FileName, fSkipStrash );
- else
+ else
pAig = Gia_AigerRead( FileName, fGiaSimple, fSkipStrash, 0 );
if ( pAig )
Abc_FrameUpdateGia( pAbc, pAig );
@@ -27466,8 +27825,8 @@ int Abc_CommandAbc9Get( Abc_Frame_t * pAbc, int argc, char ** argv )
Vec_FltFreeP( &pGia->vOutReqs );
pGia->DefInArrs = Abc_NtkReadDefaultArrivalWorst(pNtk);
pGia->DefOutReqs = Abc_NtkReadDefaultRequiredWorst(pNtk);
- pGia->vInArrs = Vec_FltAllocArray( Abc_NtkGetCiArrivalFloats(pNtk), Abc_NtkCiNum(pNtk) );
- pGia->vOutReqs = Vec_FltAllocArray( Abc_NtkGetCoRequiredFloats(pNtk), Abc_NtkCoNum(pNtk) );
+ pGia->vInArrs = Vec_FltAllocArray( Abc_NtkGetCiArrivalFloats(pNtk), Abc_NtkCiNum(pNtk) );
+ pGia->vOutReqs = Vec_FltAllocArray( Abc_NtkGetCoRequiredFloats(pNtk), Abc_NtkCoNum(pNtk) );
}
Abc_FrameUpdateGia( pAbc, pGia );
return 0;
@@ -27626,7 +27985,7 @@ usage:
Synopsis [Compares to versions of the design and finds the best.]
Description []
-
+
SideEffects []
SeeAlso []
@@ -27637,11 +27996,11 @@ static inline int Gia_ManCompareWithBest( Gia_Man_t * pBest, Gia_Man_t * p, int
int nCurLuts, nCurEdges, nCurLevels;
Gia_ManLutParams( p, &nCurLuts, &nCurEdges, &nCurLevels );
if ( pBest == NULL ||
- Gia_ManPiNum(pBest) != Gia_ManPiNum(p) ||
- Gia_ManPoNum(pBest) != Gia_ManPoNum(p) ||
+ Gia_ManPiNum(pBest) != Gia_ManPiNum(p) ||
+ Gia_ManPoNum(pBest) != Gia_ManPoNum(p) ||
Gia_ManRegNum(pBest) != Gia_ManRegNum(p) ||
strcmp(Gia_ManName(pBest), Gia_ManName(p)) ||
- (!fArea && (*pnBestLevels > nCurLevels || (*pnBestLevels == nCurLevels && 2*(*pnBestLuts) + *pnBestEdges > 2*nCurLuts + nCurEdges))) ||
+ (!fArea && (*pnBestLevels > nCurLevels || (*pnBestLevels == nCurLevels && 2*(*pnBestLuts) + *pnBestEdges > 2*nCurLuts + nCurEdges))) ||
( fArea && (*pnBestLuts > nCurLuts || (*pnBestLuts == nCurLuts && *pnBestLevels > nCurLevels)))
)
{
@@ -27659,7 +28018,7 @@ static inline int Gia_ManCompareWithBest( Gia_Man_t * pBest, Gia_Man_t * p, int
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
@@ -27697,7 +28056,7 @@ int Abc_CommandAbc9Save( Abc_Frame_t * pAbc, int argc, char ** argv )
// save the design as best
Gia_ManStopP( &pAbc->pGiaBest );
pAbc->pGiaBest = Gia_ManDupWithAttributes( pAbc->pGia );
- return 0;
+ return 0;
usage:
Abc_Print( -2, "usage: &save [-ah]\n" );
@@ -27712,7 +28071,7 @@ usage:
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
@@ -28451,15 +28810,21 @@ usage:
int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Vec_Int_t * vBold = NULL;
- int c, fAdders = 0;
+ int c, fAdders = 0, fFadds = 0, fPath = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "ah" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "afph" ) ) != EOF )
{
switch ( c )
{
case 'a':
fAdders ^= 1;
break;
+ case 'f':
+ fFadds ^= 1;
+ break;
+ case 'p':
+ fPath ^= 1;
+ break;
case 'h':
goto usage;
default:
@@ -28482,14 +28847,16 @@ int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv )
Gia_ManForEachLut( pAbc->pGia, c )
Vec_IntPush( vBold, c );
}
- Gia_ManShow( pAbc->pGia, vBold, fAdders );
+ Gia_ManShow( pAbc->pGia, vBold, fAdders, fFadds, fPath );
Vec_IntFreeP( &vBold );
return 0;
usage:
- Abc_Print( -2, "usage: &show [-ah]\n" );
+ Abc_Print( -2, "usage: &show [-afph]\n" );
Abc_Print( -2, "\t shows the current GIA using GSView\n" );
Abc_Print( -2, "\t-a : toggle visualazing adders [default = %s]\n", fAdders? "yes": "no" );
+ Abc_Print( -2, "\t-f : toggle showing only full-adders with \"-a\" [default = %s]\n", fFadds? "yes": "no" );
+ Abc_Print( -2, "\t-p : toggle showing the critical path of a LUT mapping [default = %s]\n", fPath? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
}
@@ -30868,7 +31235,7 @@ int Abc_CommandAbc9Syn2( Abc_Frame_t * pAbc, int argc, char ** argv )
}
nRelaxRatio = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( nRelaxRatio < 0 )
+ if ( nRelaxRatio < 0 )
goto usage;
break;
case 'a':
@@ -30908,7 +31275,7 @@ int Abc_CommandAbc9Syn2( Abc_Frame_t * pAbc, int argc, char ** argv )
printf( "DSD manager has incompatible number of variables. Delay minimization is not performed.\n" );
fDelayMin = 0;
}
- }
+ }
pTemp = Gia_ManAigSyn2( pAbc->pGia, fOldAlgo, fCoarsen, fCutMin, nRelaxRatio, fDelayMin, fVerbose, fVeryVerbose );
Abc_FrameUpdateGia( pAbc, pTemp );
return 0;
@@ -31005,7 +31372,7 @@ int Abc_CommandAbc9Synch2( Abc_Frame_t * pAbc, int argc, char ** argv )
}
nRelaxRatio = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( nRelaxRatio < 0 )
+ if ( nRelaxRatio < 0 )
goto usage;
break;
case 'f':
@@ -31813,7 +32180,7 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv )
}
if ( Gia_ManRegNum(pAbc->pGia) == 0 )
{
- Abc_Print( -1, "The network is combinational.\n" );
+ Abc_Print( 0, "The network is combinational.\n" );
return 0;
}
pTemp = Cec_ManLSCorrespondence( pAbc->pGia, pPars );
@@ -32774,8 +33141,7 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Cec_ParCec_t ParsCec, * pPars = &ParsCec;
FILE * pFile;
- Gia_Man_t * pSecond, * pMiter;
- char * FileName, * pTemp;
+ Gia_Man_t * pGias[2] = {NULL, NULL}, * pMiter;
char ** pArgvNew;
int c, nArgcNew, fMiter = 0, fDualOutput = 0, fDumpMiter = 0;
Cec_ManCecSetDefaultParams( pPars );
@@ -32830,13 +33196,15 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
}
}
- if ( pAbc->pGia == NULL )
- {
- Abc_Print( -1, "Abc_CommandAbc9Cec(): There is no AIG.\n" );
- return 1;
- }
+ pArgvNew = argv + globalUtilOptind;
+ nArgcNew = argc - globalUtilOptind;
if ( fMiter )
{
+ if ( pAbc->pGia == NULL || nArgcNew != 0 )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Cec(): A miter cannot be given as an argument of command &cec and should be entered using &r.\n" );
+ return 1;
+ }
if ( fDualOutput )
{
if ( Gia_ManPoNum(pAbc->pGia) & 1 )
@@ -32845,57 +33213,97 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
if ( !pPars->fSilent )
- Abc_Print( 1, "Assuming the current network is a double-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit );
+ Abc_Print( 1, "Assuming the current network is a double-output miter.\n" );
pAbc->Status = Cec_ManVerify( pAbc->pGia, pPars );
}
else
{
Gia_Man_t * pTemp;
if ( !pPars->fSilent )
- Abc_Print( 1, "Assuming the current network is a single-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit );
+ 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 );
- }
+ }
Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb );
return 0;
}
-
- pArgvNew = argv + globalUtilOptind;
- nArgcNew = argc - globalUtilOptind;
- if ( nArgcNew != 1 )
+ if ( nArgcNew > 2 )
{
- if ( pAbc->pGia->pSpec == NULL )
+ 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++ )
{
- Abc_Print( -1, "File name is not given on the command line.\n" );
- return 1;
+ // 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;
+ }
}
- FileName = pAbc->pGia->pSpec;
}
else
- FileName = pArgvNew[0];
- // 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 );
- pSecond = Gia_AigerRead( FileName, 0, 0, 0 );
- if ( pSecond == NULL )
{
- Abc_Print( -1, "Reading AIGER has failed.\n" );
- return 0;
+ 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;
+ }
}
// compute the miter
- pMiter = Gia_ManMiter( pAbc->pGia, pSecond, 0, 1, 0, 0, pPars->fVerbose );
+ pMiter = Gia_ManMiter( pGias[0], pGias[1], 0, 1, 0, 0, pPars->fVerbose );
if ( pMiter )
{
if ( fDumpMiter )
@@ -32904,10 +33312,12 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
Gia_AigerWrite( pMiter, "cec_miter.aig", 0, 0 );
}
pAbc->Status = Cec_ManVerify( pMiter, pPars );
- Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb );
+ Abc_FrameReplaceCex( pAbc, &pGias[0]->pCexComb );
Gia_ManStop( pMiter );
}
- Gia_ManStop( pSecond );
+ if ( pGias[0] != pAbc->pGia )
+ Gia_ManStop( pGias[0] );
+ Gia_ManStop( pGias[1] );
return 0;
usage:
@@ -33749,7 +34159,7 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nRelaxRatio = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nRelaxRatio < 0 )
+ if ( pPars->nRelaxRatio < 0 )
goto usage;
break;
case 'T':
@@ -34867,7 +35277,7 @@ int Abc_CommandAbc9Lf( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nRelaxRatio = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nRelaxRatio < 0 )
+ if ( pPars->nRelaxRatio < 0 )
goto usage;
break;
case 'L':
@@ -34878,7 +35288,7 @@ int Abc_CommandAbc9Lf( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nCoarseLimit = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nCoarseLimit < 0 )
+ if ( pPars->nCoarseLimit < 0 )
goto usage;
break;
case 'E':
@@ -34889,7 +35299,7 @@ int Abc_CommandAbc9Lf( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nAreaTuner = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nAreaTuner < 0 )
+ if ( pPars->nAreaTuner < 0 )
goto usage;
break;
case 'D':
@@ -35099,7 +35509,7 @@ int Abc_CommandAbc9Mf( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nRelaxRatio = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nRelaxRatio < 0 )
+ if ( pPars->nRelaxRatio < 0 )
goto usage;
break;
case 'L':
@@ -35110,7 +35520,7 @@ int Abc_CommandAbc9Mf( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nCoarseLimit = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nCoarseLimit < 0 )
+ if ( pPars->nCoarseLimit < 0 )
goto usage;
break;
case 'E':
@@ -35121,7 +35531,7 @@ int Abc_CommandAbc9Mf( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nAreaTuner = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nAreaTuner < 0 )
+ if ( pPars->nAreaTuner < 0 )
goto usage;
break;
case 'D':
@@ -35303,7 +35713,7 @@ int Abc_CommandAbc9Nf( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nRelaxRatio = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nRelaxRatio < 0 )
+ if ( pPars->nRelaxRatio < 0 )
goto usage;
break;
case 'L':
@@ -35314,7 +35724,7 @@ int Abc_CommandAbc9Nf( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nCoarseLimit = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nCoarseLimit < 0 )
+ if ( pPars->nCoarseLimit < 0 )
goto usage;
break;
case 'E':
@@ -35325,7 +35735,7 @@ int Abc_CommandAbc9Nf( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nAreaTuner = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nAreaTuner < 0 )
+ if ( pPars->nAreaTuner < 0 )
goto usage;
break;
case 'D':
@@ -35518,7 +35928,7 @@ int Abc_CommandAbc9Of( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nRelaxRatio = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nRelaxRatio < 0 )
+ if ( pPars->nRelaxRatio < 0 )
goto usage;
break;
case 'L':
@@ -35529,7 +35939,7 @@ int Abc_CommandAbc9Of( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nCoarseLimit = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nCoarseLimit < 0 )
+ if ( pPars->nCoarseLimit < 0 )
goto usage;
break;
case 'E':
@@ -35540,7 +35950,7 @@ int Abc_CommandAbc9Of( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nAreaTuner = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nAreaTuner < 0 )
+ if ( pPars->nAreaTuner < 0 )
goto usage;
break;
case 'D':
@@ -35886,7 +36296,7 @@ int Abc_CommandAbc9Edge( Abc_Frame_t * pAbc, int argc, char ** argv )
{
//Edg_ManAssignEdgeNew( pAbc->pGia, nEdges, fVerbose );
Seg_ManComputeDelay( pAbc->pGia, DelayMax, nFanouts, nEdges==2, fVerbose );
- return 0;
+ return 0;
}
if ( pAbc->pGia->pManTime && fReverse )
{
@@ -35895,7 +36305,7 @@ int Abc_CommandAbc9Edge( Abc_Frame_t * pAbc, int argc, char ** argv )
}
if ( fReverse )
DelayMax = Gia_ManComputeEdgeDelay2( pAbc->pGia );
- else
+ else
DelayMax = Gia_ManComputeEdgeDelay( pAbc->pGia, nEdges == 2 );
//printf( "The number of edges = %d. Delay = %d.\n", Gia_ManEvalEdgeCount(pAbc->pGia), DelayMax );
return 0;
@@ -36025,7 +36435,7 @@ int Abc_CommandAbc9SatLut( Abc_Frame_t * pAbc, int argc, char ** argv )
usage:
Abc_Print( -2, "usage: &satlut [-NICDQ num] [-drwvh]\n" );
- Abc_Print( -2, "\t performs SAT-based remapping of the 4-LUT network\n" );
+ Abc_Print( -2, "\t performs SAT-based remapping of the LUT-mapped network\n" );
Abc_Print( -2, "\t-N num : the limit on AIG nodes in the window (num <= 128) [default = %d]\n", nNumber );
Abc_Print( -2, "\t-I num : the limit on the number of improved windows [default = %d]\n", nImproves );
Abc_Print( -2, "\t-C num : the limit on the number of conflicts [default = %d]\n", nBTLimit );
@@ -37751,9 +38161,9 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Gia_Man_t * pTemp;
Vec_Int_t * vPos;
- int c, iOutNum = -1, nOutRange = 1, iPartNum = -1, nLevelMax = 0, nTimeWindow = 0, fUseAllCis = 0, fVerbose = 0;
+ int c, iOutNum = -1, nOutRange = 1, iPartNum = -1, nLevelMax = 0, nTimeWindow = 0, fUseAllCis = 0, fExtractAll = 0, fVerbose = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "ORPLWavh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ORPLWaevh" ) ) != EOF )
{
switch ( c )
{
@@ -37815,6 +38225,9 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'a':
fUseAllCis ^= 1;
break;
+ case 'e':
+ fExtractAll ^= 1;
+ break;
case 'v':
fVerbose ^= 1;
break;
@@ -37829,6 +38242,21 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -1, "Abc_CommandAbc9Cone(): There is no AIG.\n" );
return 1;
}
+ if ( fExtractAll )
+ {
+ char Buffer[1000];
+ Gia_Obj_t * pObj;
+ int i, nDigits = Abc_Base10Log(Gia_ManPoNum(pAbc->pGia));
+ Gia_ManForEachPo( pAbc->pGia, pObj, i )
+ {
+ Gia_Man_t * pOne = Gia_ManDupDfsCone( pAbc->pGia, pObj );
+ sprintf( Buffer, "%s_%0*d.aig", Extra_FileNameGeneric(pAbc->pGia->pSpec), nDigits, i );
+ Gia_AigerWrite( pOne, Buffer, 0, 0 );
+ Gia_ManStop( pOne );
+ }
+ printf( "Dumped all outputs into individual AIGER files.\n" );
+ return 0;
+ }
if ( nLevelMax || nTimeWindow )
{
if ( nLevelMax && nTimeWindow )
@@ -37876,7 +38304,7 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: &cone [-ORPLW num] [-avh]\n" );
+ Abc_Print( -2, "usage: &cone [-ORPLW num] [-aevh]\n" );
Abc_Print( -2, "\t extracting multi-output sequential logic cones\n" );
Abc_Print( -2, "\t-O num : the index of first PO to extract [default = %d]\n", iOutNum );
Abc_Print( -2, "\t-R num : (optional) the number of outputs to extract [default = %d]\n", nOutRange );
@@ -37884,6 +38312,7 @@ usage:
Abc_Print( -2, "\t-L num : (optional) extract cones with higher level [default = %d]\n", nLevelMax );
Abc_Print( -2, "\t-W num : (optional) extract cones falling into this window [default = %d]\n", nTimeWindow );
Abc_Print( -2, "\t-a : toggle keeping all CIs or structral support only [default = %s]\n", fUseAllCis? "all": "structural" );
+ Abc_Print( -2, "\t-e : toggle writing all outputs into individual files [default = %s]\n", fExtractAll? "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;
@@ -38307,7 +38736,7 @@ int Abc_CommandAbc9MultiProve( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pAbc->Status = Gia_ManMultiProve( pAbc->pGia, pPars );
vStatuses = Abc_FrameDeriveStatusArray( pAbc->pGia->vSeqModelVec );
- Abc_FrameReplacePoStatuses( pAbc, &vStatuses );
+ Abc_FrameReplacePoStatuses( pAbc, &vStatuses );
Abc_FrameReplaceCexVec( pAbc, &pAbc->pGia->vSeqModelVec );
return 0;
@@ -38454,7 +38883,7 @@ int Abc_CommandAbc9Bmc( Abc_Frame_t * pAbc, int argc, char ** argv )
Bmc_AndPar_t Pars, * pPars = &Pars;
memset( pPars, 0, sizeof(Bmc_AndPar_t) );
pPars->nStart = 0; // starting timeframe
- pPars->nFramesMax = 0; // maximum number of timeframes
+ pPars->nFramesMax = 0; // maximum number of timeframes
pPars->nFramesAdd = 50; // the number of additional frames
pPars->nConfLimit = 0; // maximum number of conflicts at a node
pPars->nTimeOut = 0; // timeout in seconds
@@ -38463,9 +38892,9 @@ int Abc_CommandAbc9Bmc( Abc_Frame_t * pAbc, int argc, char ** argv )
pPars->fDumpFrames = 0; // dump unrolled timeframes
pPars->fUseSynth = 0; // use synthesis
pPars->fUseOldCnf = 0; // use old CNF construction
- pPars->fVerbose = 0; // verbose
- pPars->fVeryVerbose = 0; // very verbose
- pPars->fNotVerbose = 0; // skip line-by-line print-out
+ pPars->fVerbose = 0; // verbose
+ pPars->fVeryVerbose = 0; // very verbose
+ pPars->fNotVerbose = 0; // skip line-by-line print-out
pPars->iFrame = 0; // explored up to this frame
pPars->nFailOuts = 0; // the number of failed outputs
pPars->nDropOuts = 0; // the number of dropped outputs
@@ -39166,7 +39595,7 @@ usage:
Abc_Print( -2, "\t ((a&b)^p) complement at the output\n");
Abc_Print( -2, "\t (((a^p)&(b^q))^r) complement at the inputs and at the output\n");
Abc_Print( -2, "\t (a?(b?~s:r):(b?q:p)) functionally observable fault at the output\n");
- Abc_Print( -2, "\t (p?(a|b):(a&b)) replace AND by OR\n");
+ Abc_Print( -2, "\t (p?(a|b):(a&b)) replace AND by OR\n");
return 1;
}
@@ -40039,7 +40468,7 @@ int Abc_CommandAbc9Demiter( Abc_Frame_t * pAbc, int argc, char ** argv )
{
char pName0[1000] = "miter_part0.aig";
char pName1[1000] = "miter_part1.aig";
- Gia_Man_t * pPart1, * pPart2;
+ Gia_Man_t * pPart1, * pPart2;
if ( Gia_ManPoNum(pAbc->pGia) % 2 != 0 )
{
Abc_Print( -1, "Abc_CommandAbc9Demiter(): Does not look like a dual-output miter.\n" );
@@ -40387,14 +40816,12 @@ usage:
int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pFile;
- Cec_ParCec_t ParsCec, * pPars = &ParsCec;
- Gia_Man_t * pSecond;
- char * FileName, * pTemp;
+ Acec_ParCec_t ParsCec, * pPars = &ParsCec;
char ** pArgvNew;
- int c, nArgcNew, fMiter = 0, fDualOutput = 0, fTwoOutput = 0;
- Cec_ManCecSetDefaultParams( pPars );
+ int c, nArgcNew;
+ Acec_ManCecSetDefaultParams( pPars );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "CTnmdtvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "CTmdtbvh" ) ) != EOF )
{
switch ( c )
{
@@ -40420,17 +40847,17 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->TimeLimit < 0 )
goto usage;
break;
- case 'n':
- pPars->fNaive ^= 1;
- break;
case 'm':
- fMiter ^= 1;
+ pPars->fMiter ^= 1;
break;
case 'd':
- fDualOutput ^= 1;
+ pPars->fDualOutput ^= 1;
break;
case 't':
- fTwoOutput ^= 1;
+ pPars->fTwoOutput ^= 1;
+ break;
+ case 'b':
+ pPars->fBooth ^= 1;
break;
case 'v':
pPars->fVerbose ^= 1;
@@ -40441,15 +40868,20 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
}
}
- if ( fMiter )
+ if ( pPars->fMiter )
{
Gia_Man_t * pGia0, * pGia1, * pDual;
+ if ( argc != globalUtilOptind )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Acec(): If the input is a miter, it cannot be given on the command line.\n" );
+ return 1;
+ }
if ( pAbc->pGia == NULL )
{
Abc_Print( -1, "Abc_CommandAbc9Acec(): There is no AIG.\n" );
return 1;
}
- if ( fDualOutput )
+ if ( pPars->fDualOutput )
{
if ( Gia_ManPoNum(pAbc->pGia) & 1 )
{
@@ -40459,29 +40891,29 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( !pPars->fSilent )
Abc_Print( 1, "Assuming the current network is a double-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit );
Gia_ManDemiterDual( pAbc->pGia, &pGia0, &pGia1 );
- pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars );
+ pAbc->Status = Acec_Solve( pGia0, pGia1, pPars );
}
- else if ( fTwoOutput )
+ else if ( pPars->fTwoOutput )
{
if ( Gia_ManPoNum(pAbc->pGia) & 1 )
{
- Abc_Print( -1, "The dual-output miter should have an even number of outputs.\n" );
+ Abc_Print( -1, "The two-output miter should have an even number of outputs.\n" );
return 1;
}
if ( !pPars->fSilent )
Abc_Print( 1, "Assuming the current network is a two-word miter. (Conflict limit = %d.)\n", pPars->nBTLimit );
Gia_ManDemiterTwoWords( pAbc->pGia, &pGia0, &pGia1 );
- pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars );
+ pAbc->Status = Acec_Solve( pGia0, pGia1, pPars );
}
- else
+ else // regular single- or multi-output miter
{
if ( !pPars->fSilent )
- Abc_Print( 1, "Assuming the current network is a single-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit );
+ Abc_Print( 1, "Assuming the current network is a regular single- or multi-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit );
pDual = Gia_ManDemiterToDual( pAbc->pGia );
Gia_ManDemiterDual( pDual, &pGia0, &pGia1 );
Gia_ManStop( pDual );
- pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars );
- }
+ pAbc->Status = Acec_Solve( pGia0, pGia1, pPars );
+ }
Abc_FrameReplaceCex( pAbc, &pGia0->pCexComb );
Gia_ManStop( pGia0 );
Gia_ManStop( pGia1 );
@@ -40490,55 +40922,201 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv )
pArgvNew = argv + globalUtilOptind;
nArgcNew = argc - globalUtilOptind;
- if ( nArgcNew != 1 )
+ if ( nArgcNew == 0 || nArgcNew == 1 )
{
- if ( pAbc->pGia->pSpec == NULL )
+ Gia_Man_t * pSecond;
+ char * pTemp, * FileName = NULL;
+ if ( nArgcNew == 0 )
{
- Abc_Print( -1, "File name is not given on the command line.\n" );
- return 1;
+ FileName = pAbc->pGia->pSpec;
+ if ( FileName == NULL )
+ {
+ Abc_Print( -1, "File name is not given on the command line.\n" );
+ return 1;
+ }
+ }
+ else // if ( nArgcNew == 1 )
+ {
+ FileName = pArgvNew[0];
+ // 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 );
}
- FileName = pAbc->pGia->pSpec;
+ pSecond = Gia_AigerRead( FileName, 0, 0, 0 );
+ if ( pSecond == NULL )
+ {
+ Abc_Print( -1, "Reading AIGER has failed.\n" );
+ return 0;
+ }
+ pAbc->Status = Acec_Solve( pAbc->pGia, pSecond, pPars );
+ Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb );
+ Gia_ManStop( pSecond );
}
- else
- FileName = pArgvNew[0];
- // fix the wrong symbol
- for ( pTemp = FileName; *pTemp; pTemp++ )
- if ( *pTemp == '>' )
- *pTemp = '\\';
- if ( (pFile = fopen( FileName, "r" )) == NULL )
+ else if ( nArgcNew == 2 )
{
- 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;
+ Gia_Man_t * pGias[2] = {NULL}; int i;
+ char * pTemp, * FileName[2] = { pArgvNew[0], pArgvNew[1] };
+ for ( i = 0; i < 2; i++ )
+ {
+ // fix the wrong symbol
+ for ( pTemp = FileName[i]; *pTemp; pTemp++ )
+ if ( *pTemp == '>' )
+ *pTemp = '\\';
+ if ( (pFile = fopen( FileName[i], "r" )) == NULL )
+ {
+ Abc_Print( -1, "Cannot open input file \"%s\". ", FileName[i] );
+ if ( (FileName[i] = Extra_FileGetSimilarName( FileName[i], ".aig", NULL, NULL, NULL, NULL )) )
+ Abc_Print( 1, "Did you mean \"%s\"?", FileName[i] );
+ Abc_Print( 1, "\n" );
+ return 1;
+ }
+ fclose( pFile );
+ pGias[i] = Gia_AigerRead( FileName[i], 0, 0, 0 );
+ if ( pGias[i] == NULL )
+ {
+ Abc_Print( -1, "Reading AIGER has failed.\n" );
+ return 0;
+ }
+ }
+ pAbc->Status = Acec_Solve( pGias[0], pGias[1], pPars );
+ Abc_FrameReplaceCex( pAbc, &pGias[0]->pCexComb );
+ Gia_ManStop( pGias[0] );
+ Gia_ManStop( pGias[1] );
}
- fclose( pFile );
- pSecond = Gia_AigerRead( FileName, 0, 0, 0 );
- if ( pSecond == NULL )
+ else
{
- Abc_Print( -1, "Reading AIGER has failed.\n" );
- return 0;
+ Abc_Print( -1, "Too many command-line arguments.\n" );
+ return 1;
}
- pAbc->Status = Gia_PolynCec( pAbc->pGia, pSecond, pPars );
- Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb );
- Gia_ManStop( pSecond );
return 0;
usage:
- Abc_Print( -2, "usage: &acec [-CT num] [-nmdtvh]\n" );
+ Abc_Print( -2, "usage: &acec [-CT num] [-mdtbvh] <file1> <file2>\n" );
Abc_Print( -2, "\t combinational equivalence checking for arithmetic circuits\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 );
- Abc_Print( -2, "\t-n : toggle using naive SAT-based checking [default = %s]\n", pPars->fNaive? "yes":"no");
- Abc_Print( -2, "\t-m : toggle miter vs. two circuits [default = %s]\n", fMiter? "miter":"two circuits");
- Abc_Print( -2, "\t-d : toggle using dual output miter [default = %s]\n", fDualOutput? "yes":"no");
- Abc_Print( -2, "\t-t : toggle using two-word miter [default = %s]\n", fTwoOutput? "yes":"no");
+ Abc_Print( -2, "\t-m : toggle miter vs. two circuits [default = %s]\n", pPars->fMiter? "miter":"two circuits");
+ Abc_Print( -2, "\t-d : toggle using dual output miter [default = %s]\n", pPars->fDualOutput? "yes":"no");
+ Abc_Print( -2, "\t-t : toggle using two-word miter [default = %s]\n", pPars->fTwoOutput? "yes":"no");
+ Abc_Print( -2, "\t-b : toggle working with Booth multipliers [default = %s]\n", pPars->fBooth? "yes":"no");
Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes":"no");
Abc_Print( -2, "\t-h : print the command usage\n");
+ Abc_Print( -2, "\tfile1 : (optional) the file with the first network\n");
+ Abc_Print( -2, "\tfile2 : (optional) the file with the second network\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandAbc9Anorm( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Gia_Man_t * pTemp;
+ int c, fBooth = 0, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "bvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'b':
+ fBooth ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Anorm(): There is no AIG.\n" );
+ return 0;
+ }
+ pTemp = Acec_Normalize( pAbc->pGia, fBooth, fVerbose );
+ Abc_FrameUpdateGia( pAbc, pTemp );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &anorm [-bvh]\n" );
+ Abc_Print( -2, "\t normalize adder trees in the current AIG\n" );
+ Abc_Print( -2, "\t-b : toggles working with Booth multipliers [default = %s]\n", fBooth? "yes": "no" );
+ Abc_Print( -2, "\t-v : toggles 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_CommandAbc9Decla( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Gia_Man_t * pTemp;
+ int c, fBooth = 0, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "bvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'b':
+ fBooth ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Decla(): There is no AIG.\n" );
+ return 0;
+ }
+ pTemp = Acec_ManDecla( pAbc->pGia, fBooth, fVerbose );
+ Abc_FrameUpdateGia( pAbc, pTemp );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &decla [-bvh]\n" );
+ Abc_Print( -2, "\t removes carry look ahead adders\n" );
+ Abc_Print( -2, "\t-b : toggles working with Booth multipliers [default = %s]\n", fBooth? "yes": "no" );
+ Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
}
+
/**Function*************************************************************
Synopsis []
@@ -40687,7 +41265,7 @@ usage:
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
@@ -40701,7 +41279,7 @@ int Abc_CommandAbc9Mfs( Abc_Frame_t * pAbc, int argc, char ** argv )
Sfm_ParSetDefault( pPars );
pPars->nTfoLevMax = 5;
pPars->nDepthMax = 100;
- pPars->nWinSizeMax = 2000;
+ pPars->nWinSizeMax = 2000;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "WFDMLCNdaebvwh" ) ) != EOF )
{
@@ -40852,7 +41430,7 @@ usage:
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
@@ -40865,7 +41443,7 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv )
Sbd_Par_t Pars, * pPars = &Pars;
Sbd_ParSetDefault( pPars );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "KWFMCacvwh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "KSNPWFMCmcdpvwh" ) ) != EOF )
{
switch ( c )
{
@@ -40880,6 +41458,39 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->nLutSize < 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;
+ }
+ pPars->nLutNum = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nLutNum < 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->nCutSize = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nCutSize < 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->nCutNum = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nCutNum < 0 )
+ goto usage;
+ break;
case 'W':
if ( globalUtilOptind >= argc )
{
@@ -40924,11 +41535,17 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->nBTLimit < 0 )
goto usage;
break;
- case 'a':
- pPars->fArea ^= 1;
+ case 'm':
+ pPars->fMapping ^= 1;
break;
case 'c':
- pPars->fCover ^= 1;
+ pPars->fMoreCuts ^= 1;
+ break;
+ case 'd':
+ pPars->fFindDivs ^= 1;
+ break;
+ case 'p':
+ pPars->fUsePath ^= 1;
break;
case 'v':
pPars->fVerbose ^= 1;
@@ -40944,33 +41561,35 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv )
}
if ( pAbc->pGia == NULL )
{
- Abc_Print( -1, "Abc_CommandAbc9Mfs(): There is no AIG.\n" );
+ Abc_Print( -1, "Abc_CommandAbc9Mfsd(): There is no AIG.\n" );
return 0;
}
if ( Gia_ManBufNum(pAbc->pGia) )
{
- Abc_Print( -1, "Abc_CommandAbc9Mfs(): This command does not work with barrier buffers.\n" );
+ Abc_Print( -1, "Abc_CommandAbc9Mfsd(): This command does not work with barrier buffers.\n" );
return 1;
}
if ( Gia_ManHasMapping(pAbc->pGia) )
- {
- Abc_Print( -1, "Abc_CommandAbc9Mfs(): The current AIG has mapping (run &st to unmap).\n" );
- return 0;
- }
+ Abc_Print( 1, "The current AIG has mapping, which can be used to determine critical path if \"-p\" is selected.\n" );
pTemp = Sbd_NtkPerform( pAbc->pGia, pPars );
Abc_FrameUpdateGia( pAbc, pTemp );
return 0;
usage:
- Abc_Print( -2, "usage: &mfsd [-KWFMC <num>] [-acvwh]\n" );
+ Abc_Print( -2, "usage: &mfsd [-KSNPWFMC <num>] [-mcdpvwh]\n" );
Abc_Print( -2, "\t performs SAT-based delay-oriented AIG optimization\n" );
Abc_Print( -2, "\t-K <num> : the LUT size for delay minimization (2 <= num <= 6) [default = %d]\n", pPars->nLutSize );
+ Abc_Print( -2, "\t-S <num> : the LUT structure size (1 <= num <= 2) [default = %d]\n", pPars->nLutNum );
+ Abc_Print( -2, "\t-N <num> : the cut size considered for optimization (2 <= num <= 10) [default = %d]\n", pPars->nCutSize );
+ Abc_Print( -2, "\t-P <num> : the number of cuts computed at a node (1 <= num <= 500) [default = %d]\n", pPars->nCutNum );
Abc_Print( -2, "\t-W <num> : the number of levels in the TFO cone (0 <= num) [default = %d]\n", pPars->nTfoLevels );
Abc_Print( -2, "\t-F <num> : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nTfoFanMax );
Abc_Print( -2, "\t-M <num> : the max node count of windows to consider (0 = no limit) [default = %d]\n", pPars->nWinSizeMax );
Abc_Print( -2, "\t-C <num> : the max number of conflicts in one SAT run (0 = no limit) [default = %d]\n", pPars->nBTLimit );
- Abc_Print( -2, "\t-a : toggle minimizing area or area+edges [default = %s]\n", pPars->fArea? "area": "area+edges" );
- Abc_Print( -2, "\t-c : toggle using complete slow covering procedure [default = %s]\n", pPars->fCover? "yes": "no" );
+ Abc_Print( -2, "\t-m : toggle generating delay-oriented mapping [default = %s]\n", pPars->fMapping? "yes": "no" );
+ Abc_Print( -2, "\t-c : toggle using several cuts at each node [default = %s]\n", pPars->fMoreCuts? "yes": "no" );
+ Abc_Print( -2, "\t-d : toggle additional search for good divisors [default = %s]\n", pPars->fFindDivs? "yes": "no" );
+ Abc_Print( -2, "\t-p : toggle optimizing critical path only [default = %s]\n", pPars->fUsePath? "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");
@@ -41324,7 +41943,7 @@ usage:
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
@@ -41385,7 +42004,7 @@ usage:
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
@@ -42400,9 +43019,7 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv )
// Jf_ManTestCnf( pAbc->pGia );
// Gia_ManCheckFalseTest( pAbc->pGia, nFrames );
// Gia_ParTest( pAbc->pGia, nWords, nProcs );
-// Gia_PolynExplore( pAbc->pGia );
-// Gia_ManTestSatEnum( pAbc->pGia );
-
+//Cec2_ManSimulateTest( pAbc->pGia );
// printf( "\nThis command is currently disabled.\n\n" );
return 0;
usage:
diff --git a/src/base/abci/abcCollapse.c b/src/base/abci/abcCollapse.c
index 8c2b3b39..1542c25a 100644
--- a/src/base/abci/abcCollapse.c
+++ b/src/base/abci/abcCollapse.c
@@ -537,8 +537,6 @@ extern Vec_Wec_t * Gia_ManCreateCoSupps( Gia_Man_t * p, int fVerbose );
extern int Gia_ManCoLargestSupp( Gia_Man_t * p, Vec_Wec_t * vSupps );
extern Vec_Wec_t * Gia_ManIsoStrashReduceInt( Gia_Man_t * p, Vec_Wec_t * vSupps, int fVerbose );
-extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
-
/**Function*************************************************************
Synopsis [Derives GIA for the network.]
@@ -802,7 +800,7 @@ Vec_Ptr_t * Abc_GiaDeriveSops( Abc_Ntk_t * pNtkNew, Gia_Man_t * p, Vec_Wec_t * v
if ( fCnfShared )
{
vMap = Vec_IntStartFull( Gia_ManObjNum(p) );
- pCnf = Mf_ManGenerateCnf( p, 8, 1, 0, 0 );
+ pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 1, 0, 0, 0 );
}
vSopsRepr = Vec_PtrStart( Vec_IntSize(vReprs) );
pProgress = Extra_ProgressBarStart( stdout, Vec_IntSize(vReprs) );
diff --git a/src/base/abci/abcDar.c b/src/base/abci/abcDar.c
index 9f672485..147f7c2f 100644
--- a/src/base/abci/abcDar.c
+++ b/src/base/abci/abcDar.c
@@ -1946,17 +1946,17 @@ finish:
// report the miter
if ( RetValue == 1 )
{
- Abc_Print( 1, "Networks are equivalent. " );
+ Abc_Print( 1, "Networks are equivalent. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
else if ( RetValue == 0 )
{
- Abc_Print( 1, "Networks are NOT EQUIVALENT. " );
+ Abc_Print( 1, "Networks are NOT EQUIVALENT. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
else
{
- Abc_Print( 1, "Networks are UNDECIDED. " );
+ Abc_Print( 1, "Networks are UNDECIDED. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
fflush( stdout );
@@ -3695,17 +3695,17 @@ int Abc_NtkDarInduction( Abc_Ntk_t * pNtk, int nTimeOut, int nFramesMax, int nCo
RetValue = Saig_ManInduction( pMan, nTimeOut, nFramesMax, nConfMax, fUnique, fUniqueAll, fGetCex, fVerbose, fVeryVerbose );
if ( RetValue == 1 )
{
- Abc_Print( 1, "Networks are equivalent. " );
+ Abc_Print( 1, "Networks are equivalent. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
else if ( RetValue == 0 )
{
- Abc_Print( 1, "Networks are NOT EQUIVALENT. " );
+ Abc_Print( 1, "Networks are NOT EQUIVALENT. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
else
{
- Abc_Print( 1, "Networks are UNDECIDED. " );
+ Abc_Print( 1, "Networks are UNDECIDED. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
if ( fGetCex )
diff --git a/src/base/abci/abcDetect.c b/src/base/abci/abcDetect.c
index 8b8bba64..7adbed5d 100644
--- a/src/base/abci/abcDetect.c
+++ b/src/base/abci/abcDetect.c
@@ -901,8 +901,7 @@ Vec_Int_t * Abc_NtkFinCheckPair( Abc_Ntk_t * pNtk, Vec_Int_t * vTypes, Vec_Int_t
}
else
{
- extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
- Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( pGia, 8, 0, 1, 0 );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pGia, 8, 0, 1, 0, 0 );
sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
if ( pSat == NULL )
{
diff --git a/src/base/abci/abcDress3.c b/src/base/abci/abcDress3.c
index 33545f0a..ce0cb7f5 100644
--- a/src/base/abci/abcDress3.c
+++ b/src/base/abci/abcDress3.c
@@ -35,32 +35,6 @@ ABC_NAMESPACE_IMPL_START
/**Function*************************************************************
- Synopsis [Compute equivalence classes of nodes.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Abc_NtkComputeGiaEquivs( Gia_Man_t * pGia, int nConfs, int fVerbose )
-{
- Gia_Man_t * pTemp;
- Cec_ParFra_t ParsFra, * pPars = &ParsFra;
- Cec_ManFraSetDefaultParams( pPars );
- pPars->fUseOrigIds = 1;
- pPars->fSatSweeping = 1;
- pPars->nBTLimit = nConfs;
- pPars->fVerbose = fVerbose;
- pTemp = Cec_ManSatSweeping( pGia, pPars, 0 );
- Gia_ManStop( pTemp );
- pTemp = Gia_ManOrigIdsReduce( pGia, pGia->vIdsEquiv );
- Gia_ManStop( pTemp );
-}
-
-/**Function*************************************************************
-
Synopsis [Converts AIG from HOP to GIA.]
Description []
@@ -315,13 +289,15 @@ void Abc_NtkDumpEquivFile( char * pFileName, Vec_Int_t * vClasses, Abc_Ntk_t * p
void Abc_NtkDumpEquiv( Abc_Ntk_t * pNtks[2], char * pFileName, int nConfs, int fByName, int fVerbose )
{
//abctime clk = Abc_Clock();
+ Gia_Man_t * pTemp;
Vec_Int_t * vClasses;
// derive shared AIG for the two networks
Gia_Man_t * pGia = Abc_NtkAigToGiaTwo( pNtks[0], pNtks[1], fByName );
if ( fVerbose )
printf( "Computing equivalences for networks \"%s\" and \"%s\" with conflict limit %d.\n", Abc_NtkName(pNtks[0]), Abc_NtkName(pNtks[1]), nConfs );
// compute equivalences in this AIG
- Abc_NtkComputeGiaEquivs( pGia, nConfs, fVerbose );
+ pTemp = Gia_ManComputeGiaEquivs( pGia, nConfs, fVerbose );
+ Gia_ManStop( pTemp );
//if ( fVerbose )
// Abc_PrintTime( 1, "Equivalence computation time", Abc_Clock() - clk );
if ( fVerbose )
diff --git a/src/base/abci/abcExact.c b/src/base/abci/abcExact.c
index 9ab1c3ac..2064873a 100644
--- a/src/base/abci/abcExact.c
+++ b/src/base/abci/abcExact.c
@@ -873,7 +873,7 @@ static void Ses_StoreRead( Ses_Store_t * pStore, const char * pFilename, int fSy
fclose( pFile );
- printf( "read %lu entries from file\n", nEntries );
+ printf( "read %lu entries from file\n", (long)nEntries );
}
// computes top decomposition of variables wrt. to AND and OR
diff --git a/src/base/abci/abcMfs.c b/src/base/abci/abcMfs.c
index e33d6c73..d44ca1a0 100644
--- a/src/base/abci/abcMfs.c
+++ b/src/base/abci/abcMfs.c
@@ -259,7 +259,7 @@ int Abc_NtkPerformMfs( Abc_Ntk_t * pNtk, Sfm_Par_t * pPars )
if ( nFaninMax > 6 )
{
Abc_Print( 1, "Currently \"mfs\" cannot process the network containing nodes with more than 6 fanins.\n" );
- return 0;
+ return 1;
}
if ( !Abc_NtkHasSop(pNtk) )
if ( !Abc_NtkToSop( pNtk, -1, ABC_INFINITY ) )
diff --git a/src/base/abci/abcVerify.c b/src/base/abci/abcVerify.c
index 25d1d113..7199c529 100644
--- a/src/base/abci/abcVerify.c
+++ b/src/base/abci/abcVerify.c
@@ -122,6 +122,7 @@ void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nI
***********************************************************************/
void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fVerbose )
{
+ abctime clk = Abc_Clock();
Prove_Params_t Params, * pParams = &Params;
// Fraig_Params_t Params;
// Fraig_Man_t * pMan;
@@ -170,18 +171,20 @@ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fV
RetValue = Abc_NtkMiterIsConstant( pMiter );
if ( RetValue == 0 )
{
- printf( "Networks are NOT EQUIVALENT after structural hashing.\n" );
+ printf( "Networks are NOT EQUIVALENT after structural hashing. " );
// report the error
pMiter->pModel = Abc_NtkVerifyGetCleanModel( pMiter, 1 );
Abc_NtkVerifyReportError( pNtk1, pNtk2, pMiter->pModel );
ABC_FREE( pMiter->pModel );
Abc_NtkDelete( pMiter );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
return;
}
if ( RetValue == 1 )
{
- printf( "Networks are equivalent after structural hashing.\n" );
+ printf( "Networks are equivalent after structural hashing. " );
Abc_NtkDelete( pMiter );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
return;
}
/*
@@ -220,18 +223,19 @@ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fV
// pParams->fVerbose = 1;
RetValue = Abc_NtkIvyProve( &pMiter, pParams );
if ( RetValue == -1 )
- printf( "Networks are undecided (resource limits is reached).\n" );
+ printf( "Networks are undecided (resource limits is reached). " );
else if ( RetValue == 0 )
{
int * pSimInfo = Abc_NtkVerifySimulatePattern( pMiter, pMiter->pModel );
if ( pSimInfo[0] != 1 )
printf( "ERROR in Abc_NtkMiterProve(): Generated counter-example is invalid.\n" );
else
- printf( "Networks are NOT EQUIVALENT.\n" );
+ printf( "Networks are NOT EQUIVALENT. " );
ABC_FREE( pSimInfo );
}
else
- printf( "Networks are equivalent.\n" );
+ printf( "Networks are equivalent. " );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
if ( pMiter->pModel )
Abc_NtkVerifyReportError( pNtk1, pNtk2, pMiter->pModel );
Abc_NtkDelete( pMiter );
diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c
index 0b7c1788..853f5710 100644
--- a/src/base/cmd/cmd.c
+++ b/src/base/cmd/cmd.c
@@ -60,6 +60,7 @@ static int CmdCommandSis ( Abc_Frame_t * pAbc, int argc, char ** argv
static int CmdCommandMvsis ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int CmdCommandCapo ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int CmdCommandStarter ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandAutoTuner ( Abc_Frame_t * pAbc, int argc, char ** argv );
extern int Cmd_CommandAbcLoadPlugIn( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -110,6 +111,7 @@ void Cmd_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Various", "mvsis", CmdCommandMvsis, 1 );
Cmd_CommandAdd( pAbc, "Various", "capo", CmdCommandCapo, 0 );
Cmd_CommandAdd( pAbc, "Various", "starter", CmdCommandStarter, 0 );
+ Cmd_CommandAdd( pAbc, "Various", "autotuner", CmdCommandAutoTuner, 0 );
Cmd_CommandAdd( pAbc, "Various", "load_plugin", Cmd_CommandAbcLoadPlugIn, 0 );
}
@@ -1147,26 +1149,7 @@ usage:
#if defined(WIN32) && !defined(__cplusplus)
#include <direct.h>
-
-// these structures are defined in <io.h> but are for some reason invisible
-typedef unsigned long _fsize_t; // Could be 64 bits for Win32
-
-struct _finddata_t {
- unsigned attrib;
- time_t time_create; // -1 for FAT file systems
- time_t time_access; // -1 for FAT file systems
- time_t time_write;
- _fsize_t size;
- char name[260];
-};
-
-extern long _findfirst( char *filespec, struct _finddata_t *fileinfo );
-extern int _findnext( long handle, struct _finddata_t *fileinfo );
-extern int _findclose( long handle );
-
-//extern char * _getcwd( char * buffer, int maxlen );
-//extern int _chdir( const char *dirname );
-
+#include <io.h>
/**Function*************************************************************
@@ -2476,6 +2459,118 @@ usage:
return 1;
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int CmdCommandAutoTuner( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Cmd_RunAutoTuner( char * pConfig, char * pFileList, int nCores );
+ FILE * pFile;
+ char * pFileConf = NULL;
+ char * pFileList = NULL;
+ char * pFileName;
+ int c, nCores = 3;
+ int fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "NCFvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'N':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nCores = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nCores < 0 )
+ goto usage;
+ break;
+ case 'C':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-C\" should be followed by a string (possibly in quotes).\n" );
+ goto usage;
+ }
+ pFileConf = argv[globalUtilOptind];
+ globalUtilOptind++;
+ break;
+ case 'F':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-F\" should be followed by a string (possibly in quotes).\n" );
+ goto usage;
+ }
+ pFileList = argv[globalUtilOptind];
+ globalUtilOptind++;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pFileConf == NULL )
+ {
+ Abc_Print( -2, "File containing configuration for autotuning is not given.\n" );
+ return 1;
+ }
+ if ( pFileList == NULL )
+ {
+ Abc_Print( -2, "File contining list of files for autotuning is not given.\n" );
+ return 1;
+ }
+ // get the input file name
+ pFileName = pFileConf;
+ if ( (pFile = Io_FileOpen( pFileName, "open_path", "rb", 0 )) == NULL )
+// if ( (pFile = fopen( pFileName, "rb" )) == NULL )
+ {
+ Abc_Print( -2, "Cannot open configuration file \"%s\". ", pFileName );
+ if (( pFileName = Extra_FileGetSimilarName( pFileName, ".c", ".s", ".scr", ".script", NULL ) ))
+ Abc_Print( -2, "Did you mean \"%s\"?", pFileName );
+ Abc_Print( -2, "\n" );
+ return 1;
+ }
+ fclose( pFile );
+ // get the input file name
+ pFileName = pFileList;
+ if ( (pFile = Io_FileOpen( pFileName, "open_path", "rb", 0 )) == NULL )
+// if ( (pFile = fopen( pFileName, "rb" )) == NULL )
+ {
+ Abc_Print( -2, "Cannot open the file list \"%s\". ", pFileName );
+ if (( pFileName = Extra_FileGetSimilarName( pFileName, ".c", ".s", ".scr", ".script", NULL ) ))
+ Abc_Print( -2, "Did you mean \"%s\"?", pFileName );
+ Abc_Print( -2, "\n" );
+ return 1;
+ }
+ fclose( pFile );
+ // run commands
+ Cmd_RunAutoTuner( pFileConf, pFileList, nCores );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: autotuner [-N num] [-C file] [-F file] [-vh]\n" );
+ Abc_Print( -2, "\t performs autotuning\n" );
+ Abc_Print( -2, "\t-N num : the number of concurrent jobs including the controler [default = %d]\n", nCores );
+ Abc_Print( -2, "\t-C cmd : configuration file with settings for autotuning\n" );
+ Abc_Print( -2, "\t-F cmd : list of AIGER files to be used for autotuning\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 [Print the version string.]
diff --git a/src/base/cmd/cmdAuto.c b/src/base/cmd/cmdAuto.c
new file mode 100644
index 00000000..8151c2e5
--- /dev/null
+++ b/src/base/cmd/cmdAuto.c
@@ -0,0 +1,684 @@
+/**CFile****************************************************************
+
+ FileName [cmdAuto.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Autotuner.]
+
+ Author [Alan Mishchenko, Bruno Schmitt]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cmdAuto.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "misc/util/abc_global.h"
+#include "misc/extra/extra.h"
+#include "aig/gia/gia.h"
+#include "sat/satoko/satoko.h"
+
+#ifdef ABC_USE_PTHREADS
+
+#ifdef _WIN32
+#include "../lib/pthread.h"
+#else
+#include <pthread.h>
+#include <unistd.h>
+#endif
+
+#endif
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define CMD_AUTO_LINE_MAX 1000 // max number of chars in the string
+#define CMD_AUTO_ARG_MAX 100 // max number of arguments in the call
+
+extern int Gia_ManSatokoCallOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Printing option structure.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cmd_RunAutoTunerPrintOptions( satoko_opts_t * pOpts )
+{
+ printf( "-C %d ", (int)pOpts->conf_limit );
+ printf( "-V %.3f ", (float)pOpts->var_decay );
+ printf( "-W %.3f ", (float)pOpts->clause_decay );
+ if ( pOpts->verbose )
+ printf( "-v" );
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [The main evaluation procedure for an array of AIGs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cmd_RunAutoTunerEvalSimple( Vec_Ptr_t * vAigs, satoko_opts_t * pOpts )
+{
+ Gia_Man_t * pGia;
+ int i, TotalCost = 0;
+ //printf( "Tuning with options: " );
+ //Cmd_RunAutoTunerPrintOptions( pOpts );
+ Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, i )
+ TotalCost += Gia_ManSatokoCallOne( pGia, pOpts, -1 );
+ return TotalCost;
+}
+
+/**Function*************************************************************
+
+ Synopsis [The main evaluation procedure for the set of AIGs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+#ifndef ABC_USE_PTHREADS
+
+int Cmd_RunAutoTunerEval( Vec_Ptr_t * vAigs, satoko_opts_t * pOpts, int nCores )
+{
+ return Cmd_RunAutoTunerEvalSimple( vAigs, pOpts );
+}
+
+#else // pthreads are used
+
+
+#define CMD_THR_MAX 100
+typedef struct Cmd_AutoData_t_
+{
+ Gia_Man_t * pGia;
+ satoko_opts_t * pOpts;
+ int iThread;
+ int nTimeOut;
+ int fWorking;
+ int Result;
+} Cmd_AutoData_t;
+
+void * Cmd_RunAutoTunerEvalWorkerThread( void * pArg )
+{
+ Cmd_AutoData_t * pThData = (Cmd_AutoData_t *)pArg;
+ volatile int * pPlace = &pThData->fWorking;
+ while ( 1 )
+ {
+ while ( *pPlace == 0 );
+ assert( pThData->fWorking );
+ if ( pThData->pGia == NULL ) // kills itself when there is nothing to do
+ {
+ pthread_exit( NULL );
+ assert( 0 );
+ return NULL;
+ }
+ pThData->Result = Gia_ManSatokoCallOne( pThData->pGia, pThData->pOpts, -1 );
+ pThData->fWorking = 0;
+ }
+ assert( 0 );
+ return NULL;
+}
+int Cmd_RunAutoTunerEval( Vec_Ptr_t * vAigs, satoko_opts_t * pOpts, int nProcs )
+{
+ Cmd_AutoData_t ThData[CMD_THR_MAX];
+ pthread_t WorkerThread[CMD_THR_MAX];
+ int i, status, fWorkToDo = 1, TotalCost = 0;
+ Vec_Ptr_t * vStack;
+ if ( nProcs == 1 )
+ return Cmd_RunAutoTunerEvalSimple( vAigs, pOpts );
+ // subtract manager thread
+ nProcs--;
+ assert( nProcs >= 1 && nProcs <= CMD_THR_MAX );
+ // start threads
+ for ( i = 0; i < nProcs; i++ )
+ {
+ ThData[i].pGia = NULL;
+ ThData[i].pOpts = pOpts;
+ ThData[i].iThread = i;
+ ThData[i].nTimeOut = -1;
+ ThData[i].fWorking = 0;
+ ThData[i].Result = -1;
+ status = pthread_create( WorkerThread + i, NULL,Cmd_RunAutoTunerEvalWorkerThread, (void *)(ThData + i) ); assert( status == 0 );
+ }
+ // look at the threads
+ vStack = Vec_PtrDup(vAigs);
+ while ( fWorkToDo )
+ {
+ fWorkToDo = (int)(Vec_PtrSize(vStack) > 0);
+ for ( i = 0; i < nProcs; i++ )
+ {
+ // check if this thread is working
+ if ( ThData[i].fWorking )
+ {
+ fWorkToDo = 1;
+ continue;
+ }
+ // check if this thread has recently finished
+ if ( ThData[i].pGia != NULL )
+ {
+ assert( ThData[i].Result >= 0 );
+ TotalCost += ThData[i].Result;
+ ThData[i].pGia = NULL;
+ }
+ if ( Vec_PtrSize(vStack) == 0 )
+ continue;
+ // give this thread a new job
+ assert( ThData[i].pGia == NULL );
+ ThData[i].pGia = (Gia_Man_t *)Vec_PtrPop( vStack );
+ ThData[i].fWorking = 1;
+ }
+ }
+ Vec_PtrFree( vStack );
+ // stop threads
+ for ( i = 0; i < nProcs; i++ )
+ {
+ assert( !ThData[i].fWorking );
+ // stop
+ ThData[i].pGia = NULL;
+ ThData[i].fWorking = 1;
+ }
+ return TotalCost;
+}
+
+#endif // pthreads are used
+
+
+/**Function*************************************************************
+
+ Synopsis [Derives all possible param stucts according to the config file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Cmd_DeriveConvertIntoString( int argc, char ** argv )
+{
+ char pBuffer[CMD_AUTO_LINE_MAX] = {0};
+ int i;
+ for ( i = 0; i < argc; i++ )
+ {
+ strcat( pBuffer, argv[i] );
+ strcat( pBuffer, " " );
+ }
+ return Abc_UtilStrsav(pBuffer);
+}
+satoko_opts_t * Cmd_DeriveOptionFromSettings( int argc, char ** argv )
+{
+ int c;
+ satoko_opts_t opts, * pOpts;
+ satoko_default_opts(&opts);
+ Extra_UtilGetoptReset();
+#ifdef SATOKO_ACT_VAR_FIXED
+ while ( ( c = Extra_UtilGetopt( argc, argv, "CPDEFGHIJKLMNOQRSTUhv" ) ) != EOF )
+#else
+ while ( ( c = Extra_UtilGetopt( argc, argv, "CPDEFGHIJKLMNOQRShv" ) ) != EOF )
+#endif
+ {
+ switch ( c )
+ {
+ case 'C':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.conf_limit = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( opts.conf_limit < 0 )
+ return NULL;
+ break;
+ case 'P':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-P\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.prop_limit = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( opts.prop_limit < 0 )
+ return NULL;
+ break;
+ case 'D':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-D\" should be followed by an float.\n" );
+ return NULL;
+ }
+ opts.f_rst = atof(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( opts.f_rst < 0 )
+ return NULL;
+ break;
+ case 'E':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-E\" should be followed by an float.\n" );
+ return NULL;
+ }
+ opts.b_rst = atof(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( opts.b_rst < 0 )
+ return NULL;
+ break;
+ case 'F':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.fst_block_rst = (unsigned)atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
+ case 'G':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-G\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.sz_lbd_bqueue = (unsigned)atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
+ case 'H':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-H\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.sz_trail_bqueue = (unsigned)atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
+ case 'I':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.n_conf_fst_reduce = (unsigned)atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
+ case 'J':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-J\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.inc_reduce = (unsigned)atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
+ case 'K':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-K\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.inc_special_reduce = (unsigned)atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
+ case 'L':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-L\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.lbd_freeze_clause = (unsigned)atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
+ case 'M':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.learnt_ratio = atof(argv[globalUtilOptind]) / 100;
+ globalUtilOptind++;
+ if ( opts.learnt_ratio < 0 )
+ return NULL;
+ break;
+ case 'N':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.garbage_max_ratio = atof(argv[globalUtilOptind]) / 100;
+ globalUtilOptind++;
+ if ( opts.garbage_max_ratio < 0 )
+ return NULL;
+ break;
+ case 'O':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.clause_max_sz_bin_resol = (unsigned)atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
+ case 'Q':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.clause_min_lbd_bin_resol = (unsigned)atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
+ case 'R':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-R\" should be followed by an float.\n" );
+ return NULL;
+ }
+ opts.clause_decay = atof(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( opts.clause_decay < 0 )
+ return NULL;
+ break;
+ case 'S':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-S\" should be followed by an float.\n" );
+ return NULL;
+ }
+ opts.var_decay = atof(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( opts.var_decay < 0 )
+ return NULL;
+ break;
+#ifdef SATOKO_ACT_VAR_FIXED
+ case 'T':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-T\" should be followed by an float.\n" );
+ return NULL;
+ }
+ opts.var_act_limit = (unsigned)strtol(argv[globalUtilOptind], NULL, 16);
+ globalUtilOptind++;
+ break;
+ case 'U':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-U\" should be followed by an float.\n" );
+ return NULL;
+ }
+ opts.var_act_rescale = (unsigned)strtol(argv[globalUtilOptind], NULL, 16);
+ globalUtilOptind++;
+ break;
+#endif
+ case 'h':
+ return NULL;
+ case 'v':
+ opts.verbose ^= 1;
+ break;
+
+ default:
+ return NULL;
+ }
+ }
+ // return a copy of this parameter structure
+ pOpts = ABC_ALLOC( satoko_opts_t, 1 );
+ memcpy( pOpts, &opts, sizeof(satoko_opts_t) );
+ return pOpts;
+}
+void Cmf_CreateOptions_rec( Vec_Wec_t * vPars, int iPar, char Argv[CMD_AUTO_ARG_MAX][20], int Argc, Vec_Ptr_t * vOpts )
+{
+ Vec_Int_t * vLine;
+ int Symb, Num, i;
+ assert( Argc <= CMD_AUTO_ARG_MAX );
+ if ( Vec_WecSize(vPars) == iPar )
+ {
+ satoko_opts_t * pOpts;
+ char * pArgv[CMD_AUTO_ARG_MAX];
+ for ( i = 0; i < Argc; i++ )
+ pArgv[i] = Argv[i];
+ pOpts = Cmd_DeriveOptionFromSettings( Argc, pArgv );
+ if ( pOpts == NULL )
+ printf( "Cannot parse command line options...\n" );
+ else
+ {
+ Vec_PtrPush( vOpts, pOpts );
+ Vec_PtrPush( vOpts, Cmd_DeriveConvertIntoString(Argc, pArgv) );
+ printf( "Adding settings %s\n", (char *)Vec_PtrEntryLast(vOpts) );
+ }
+ return;
+ }
+ vLine = Vec_WecEntry( vPars, iPar );
+ // consider binary option
+ if ( Vec_IntSize(vLine) == 2 )
+ {
+ Symb = Vec_IntEntry( vLine, 0 );
+ Num = Vec_IntEntry( vLine, 1 );
+ assert( Abc_Int2Float(Num) == -1.0 );
+ // create one setting without this option
+ Cmf_CreateOptions_rec( vPars, iPar+1, Argv, Argc, vOpts );
+ // create another setting with this option
+ sprintf( Argv[Argc], "-%c", Symb );
+ Cmf_CreateOptions_rec( vPars, iPar+1, Argv, Argc+1, vOpts );
+ return;
+ }
+ // consider numeric option
+ Vec_IntForEachEntryDouble( vLine, Symb, Num, i )
+ {
+ float NumF = Abc_Int2Float(Num);
+ // create setting with this option
+ assert( NumF >= 0 );
+ sprintf( Argv[Argc], "-%c", Symb );
+ if ( NumF == (float)(int)NumF )
+ sprintf( Argv[Argc+1], "%d", (int)NumF );
+ else
+ sprintf( Argv[Argc+1], "%.3f", NumF );
+ Cmf_CreateOptions_rec( vPars, iPar+1, Argv, Argc+2, vOpts );
+ }
+}
+Vec_Ptr_t * Cmf_CreateOptions( Vec_Wec_t * vPars )
+{
+ char Argv[CMD_AUTO_ARG_MAX][20];
+ int Symb, Num, i, Argc = 0;
+ Vec_Ptr_t * vOpts = Vec_PtrAlloc( 100 );
+ Vec_Int_t * vLine = Vec_WecEntry( vPars, 0 );
+ printf( "Creating all possible settings to be used by the autotuner:\n" );
+ sprintf( Argv[Argc++], "autotuner" );
+ Vec_IntForEachEntryDouble( vLine, Symb, Num, i )
+ {
+ float NumF = Abc_Int2Float(Num);
+ sprintf( Argv[Argc++], "-%c", Symb );
+ if ( NumF < 0.0 )
+ continue;
+ if ( NumF == (float)(int)NumF )
+ sprintf( Argv[Argc++], "%d", (int)NumF );
+ else
+ sprintf( Argv[Argc++], "%.3f", NumF );
+ }
+ Cmf_CreateOptions_rec( vPars, 1, Argv, Argc, vOpts );
+ printf( "Finished creating %d settings.\n\n", Vec_PtrSize(vOpts)/2 );
+ return vOpts;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Parses config file and derives AIGs listed in file list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cmf_IsSpace( char p ) { return p == ' ' || p == '\t' || p == '\n' || p == '\r'; }
+static inline int Cmf_IsLowerCaseChar( char p ) { return p >= 'a' && p <= 'z'; }
+static inline int Cmf_IsUpperCaseChar( char p ) { return p >= 'A' && p <= 'Z'; }
+static inline int Cmf_IsDigit( char p ) { return (p >= '0' && p <= '9') || p == '.'; }
+
+Vec_Wec_t * Cmd_ReadParamChoices( char * pConfig )
+{
+ Vec_Wec_t * vPars;
+ Vec_Int_t * vLine;
+ char * pThis, pBuffer[CMD_AUTO_LINE_MAX];
+ FILE * pFile = fopen( pConfig, "rb" );
+ if ( pFile == NULL )
+ { printf( "File containing list of files \"%s\" cannot be opened.\n", pConfig ); return NULL; }
+ vPars = Vec_WecAlloc( 100 );
+ while ( fgets( pBuffer, CMD_AUTO_LINE_MAX, pFile ) != NULL )
+ {
+ // get the command from the file
+ if ( Cmf_IsSpace(pBuffer[0]) || pBuffer[0] == '#')
+ continue;
+ // skip trailing spaces
+ while ( Cmf_IsSpace(pBuffer[strlen(pBuffer)-1]) )
+ pBuffer[strlen(pBuffer)-1] = 0;
+ // read the line
+ vLine = Vec_WecPushLevel( vPars );
+ for ( pThis = pBuffer; *pThis; )
+ {
+ if ( Cmf_IsLowerCaseChar(*pThis) )
+ {
+ Vec_IntPushTwo( vLine, (int)*pThis, Abc_Float2Int((float)-1.0) );
+ pThis++;
+ while ( Cmf_IsSpace(*pThis) )
+ pThis++;
+ continue;
+ }
+ if ( Cmf_IsUpperCaseChar(*pThis) )
+ {
+ char Param = *pThis++;
+ if ( !Cmf_IsDigit(*pThis) )
+ { printf( "Upper-case character (%c) should be followed by a number without space in line \"%s\".\n", Param, pBuffer ); return NULL; }
+ Vec_IntPushTwo( vLine, (int)Param, Abc_Float2Int(atof(pThis)) );
+ while ( Cmf_IsDigit(*pThis) )
+ pThis++;
+ while ( Cmf_IsSpace(*pThis) )
+ pThis++;
+ continue;
+ }
+ printf( "Expecting a leading lower-case or upper-case digit in line \"%s\".\n", pBuffer );
+ return NULL;
+ }
+ }
+ fclose( pFile );
+ return vPars;
+}
+Vec_Ptr_t * Cmd_ReadFiles( char * pFileList )
+{
+ Gia_Man_t * pGia;
+ Vec_Ptr_t * vAigs;
+ char pBuffer[CMD_AUTO_LINE_MAX];
+ FILE * pFile = fopen( pFileList, "rb" );
+ if ( pFile == NULL )
+ { printf( "File containing list of files \"%s\" cannot be opened.\n", pFileList ); return NULL; }
+ vAigs = Vec_PtrAlloc( 100 );
+ while ( fgets( pBuffer, CMD_AUTO_LINE_MAX, pFile ) != NULL )
+ {
+ // get the command from the file
+ if ( Cmf_IsSpace(pBuffer[0]) || pBuffer[0] == '#')
+ continue;
+ // skip trailing spaces
+ while ( Cmf_IsSpace(pBuffer[strlen(pBuffer)-1]) )
+ pBuffer[strlen(pBuffer)-1] = 0;
+ // read the file
+ pGia = Gia_AigerRead( pBuffer, 0, 0, 0 );
+ if ( pGia == NULL )
+ {
+ printf( "Cannot read AIG from file \"%s\".\n", pBuffer );
+ continue;
+ }
+ Vec_PtrPush( vAigs, pGia );
+ }
+ fclose( pFile );
+ return vAigs;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Autotuner for SAT solver "satoko".]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cmd_RunAutoTuner( char * pConfig, char * pFileList, int nCores )
+{
+ abctime clk = Abc_Clock();
+ Vec_Wec_t * vPars = Cmd_ReadParamChoices( pConfig );
+ Vec_Ptr_t * vAigs = Cmd_ReadFiles( pFileList );
+ Vec_Ptr_t * vOpts = vPars ? Cmf_CreateOptions( vPars ) : NULL;
+ int i; char * pString, * pStringBest = NULL;
+ satoko_opts_t * pOpts, * pOptsBest = NULL;
+ int Result, ResultBest = 0x7FFFFFFF;
+ Gia_Man_t * pGia;
+ // iterate through all possible option settings
+ if ( vAigs && vOpts )
+ {
+ Vec_PtrForEachEntryDouble( satoko_opts_t *, char *, vOpts, pOpts, pString, i )
+ {
+ abctime clk = Abc_Clock();
+ printf( "Evaluating settings: %20s... \n", pString );
+ Result = Cmd_RunAutoTunerEval( vAigs, pOpts, nCores );
+ printf( "Cost = %6d. ", Result );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ if ( ResultBest > Result )
+ {
+ ResultBest = Result;
+ pStringBest = pString;
+ pOptsBest = pOpts;
+ }
+ }
+ printf( "The best settings are: %20s \n", pStringBest );
+ printf( "Best cost = %6d. ", ResultBest );
+ Abc_PrintTime( 1, "Total time", Abc_Clock() - clk );
+ }
+ // cleanup
+ if ( vPars ) Vec_WecFree( vPars );
+ if ( vOpts ) Vec_PtrFreeFree( vOpts );
+ if ( vAigs )
+ {
+ Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, i )
+ Gia_ManStop( pGia );
+ Vec_PtrFree( vAigs );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/base/cmd/cmdLoad.c b/src/base/cmd/cmdLoad.c
index 7f7c1b60..accd9440 100644
--- a/src/base/cmd/cmdLoad.c
+++ b/src/base/cmd/cmdLoad.c
@@ -97,26 +97,7 @@ int CmdCommandLoad( Abc_Frame_t * pAbc, int argc, char ** argv )
#if defined(WIN32) && !defined(__cplusplus)
#include <direct.h>
-
-
-// these structures are defined in <io.h> but are for some reason invisible
-typedef unsigned long _fsize_t; // Could be 64 bits for Win32
-
-struct _finddata_t {
- unsigned attrib;
- time_t time_create; // -1 for FAT file systems
- time_t time_access; // -1 for FAT file systems
- time_t time_write;
- _fsize_t size;
- char name[260];
-};
-
-extern long _findfirst( char *filespec, struct _finddata_t *fileinfo );
-extern int _findnext( long handle, struct _finddata_t *fileinfo );
-extern int _findclose( long handle );
-
-//extern char * _getcwd( char * buffer, int maxlen );
-//extern int _chdir( const char *dirname );
+#include <io.h>
/**Function*************************************************************
diff --git a/src/base/cmd/module.make b/src/base/cmd/module.make
index b09ffa81..1042fbb0 100644
--- a/src/base/cmd/module.make
+++ b/src/base/cmd/module.make
@@ -1,6 +1,7 @@
SRC += src/base/cmd/cmd.c \
src/base/cmd/cmdAlias.c \
src/base/cmd/cmdApi.c \
+ src/base/cmd/cmdAuto.c \
src/base/cmd/cmdFlag.c \
src/base/cmd/cmdHist.c \
src/base/cmd/cmdLoad.c \
diff --git a/src/base/io/io.c b/src/base/io/io.c
index 093eccca..2e1ae591 100644
--- a/src/base/io/io.c
+++ b/src/base/io/io.c
@@ -2150,7 +2150,7 @@ int IoCommandWriteCnf2( Abc_Frame_t * pAbc, int argc, char **argv )
extern void Mf_ManDumpCnf( Gia_Man_t * p, char * pFileName, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
FILE * pFile;
char * pFileName;
- int nLutSize = 6;
+ int nLutSize = 8;
int fNewAlgo = 1;
int fCnfObjIds = 0;
int fAddOrCla = 1;
@@ -2420,7 +2420,7 @@ int IoCommandWriteCex( Abc_Frame_t * pAbc, int argc, char **argv )
Bmc_CexCareVerify( pAig, pCex, pCare, fVerbose );
}
else
- pCare = Bmc_CexCareMinimize( pAig, pCex, fCheckCex, fVerbose );
+ pCare = Bmc_CexCareMinimize( pAig, Saig_ManPiNum(pAig), pCex, 4, fCheckCex, fVerbose );
Aig_ManStop( pAig );
}
// output flop values (unaffected by the minimization)
diff --git a/src/base/io/ioWriteDot.c b/src/base/io/ioWriteDot.c
index 3431c761..d9687c6e 100644
--- a/src/base/io/ioWriteDot.c
+++ b/src/base/io/ioWriteDot.c
@@ -394,7 +394,7 @@ void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
fprintf( pFile, "Node%d", pNode->Id );
fprintf( pFile, " -> " );
fprintf( pFile, "Node%d", pFanin->Id );
- fprintf( pFile, " [style = %s", fCompl? "dotted" : "bold" );
+ fprintf( pFile, " [style = %s", fCompl? "dotted" : "solid" );
// fprintf( pFile, ", label = \"%c\"", 'a' + k );
fprintf( pFile, "]" );
fprintf( pFile, ";\n" );
@@ -764,7 +764,7 @@ void Io_WriteDotSeq( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
fprintf( pFile, "Node%d", pNode->Id );
fprintf( pFile, " -> " );
fprintf( pFile, "Node%d", pFanin->Id );
- fprintf( pFile, " [style = %s", fCompl? "dotted" : "bold" );
+ fprintf( pFile, " [style = %s", fCompl? "dotted" : "solid" );
// fprintf( pFile, ", label = \"%c\"", 'a' + k );
fprintf( pFile, "]" );
fprintf( pFile, ";\n" );
diff --git a/src/base/main/mainFrame.c b/src/base/main/mainFrame.c
index 05cb09c1..9647d020 100644
--- a/src/base/main/mainFrame.c
+++ b/src/base/main/mainFrame.c
@@ -95,8 +95,6 @@ void Abc_FrameSetStatus( int Status ) { ABC_FREE( s_Globa
void Abc_FrameSetManDsd( void * pMan ) { if (s_GlobalFrame->pManDsd && s_GlobalFrame->pManDsd != pMan) If_DsdManFree((If_DsdMan_t *)s_GlobalFrame->pManDsd, 0); s_GlobalFrame->pManDsd = pMan; }
void Abc_FrameSetManDsd2( void * pMan ) { if (s_GlobalFrame->pManDsd2 && s_GlobalFrame->pManDsd2 != pMan) If_DsdManFree((If_DsdMan_t *)s_GlobalFrame->pManDsd2, 0); s_GlobalFrame->pManDsd2 = pMan; }
void Abc_FrameSetInv( Vec_Int_t * vInv ) { Vec_IntFreeP(&s_GlobalFrame->pAbcWlcInv); s_GlobalFrame->pAbcWlcInv = vInv; }
-void Abc_FrameSetCnf( Vec_Int_t * vCnf ) { Vec_IntFreeP(&s_GlobalFrame->pAbcWlcCnf); s_GlobalFrame->pAbcWlcCnf = vCnf; }
-void Abc_FrameSetStr( Vec_Str_t * vStr ) { Vec_StrFreeP(&s_GlobalFrame->pAbcWlcStr); s_GlobalFrame->pAbcWlcStr = vStr; }
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; }
@@ -227,8 +225,6 @@ void Abc_FrameDeallocate( Abc_Frame_t * p )
ABC_FREE( p->pCex2 );
ABC_FREE( p->pCex );
Vec_IntFreeP( &p->pAbcWlcInv );
- Vec_IntFreeP( &p->pAbcWlcCnf );
- Vec_StrFreeP( &p->pAbcWlcStr );
Abc_NamDeref( s_GlobalFrame->pJsonStrs );
Vec_WecFreeP(&s_GlobalFrame->vJsonObjs );
ABC_FREE( p );
diff --git a/src/base/main/mainInt.h b/src/base/main/mainInt.h
index ff59b81a..278a9191 100644
--- a/src/base/main/mainInt.h
+++ b/src/base/main/mainInt.h
@@ -129,8 +129,6 @@ struct Abc_Frame_t_
void * pAbc85Delay;
void * pAbcWlc;
Vec_Int_t * pAbcWlcInv;
- Vec_Int_t * pAbcWlcCnf;
- Vec_Str_t * pAbcWlcStr;
void * pAbcBac;
void * pAbcCba;
void * pAbcPla;
diff --git a/src/base/main/mainReal.c b/src/base/main/mainReal.c
index ee43d38d..31bfef75 100644
--- a/src/base/main/mainReal.c
+++ b/src/base/main/mainReal.c
@@ -196,7 +196,7 @@ int Abc_RealMain( int argc, char * argv[] )
case 't':
if ( TypeCheck( pAbc, globalUtilOptarg ) )
{
- if ( !strcmp(globalUtilOptarg, "none") == 0 )
+ if ( (!strcmp(globalUtilOptarg, "none")) == 0 )
{
fInitRead = 1;
sprintf( sReadCmd, "read_%s", globalUtilOptarg );
@@ -211,7 +211,7 @@ int Abc_RealMain( int argc, char * argv[] )
case 'T':
if ( TypeCheck( pAbc, globalUtilOptarg ) )
{
- if (!strcmp(globalUtilOptarg, "none") == 0)
+ if ( (!strcmp(globalUtilOptarg, "none")) == 0)
{
fFinalWrite = 1;
sprintf( sWriteCmd, "write_%s", globalUtilOptarg);
diff --git a/src/base/wlc/module.make b/src/base/wlc/module.make
index 5a95a63f..c4330264 100644
--- a/src/base/wlc/module.make
+++ b/src/base/wlc/module.make
@@ -1,4 +1,5 @@
SRC += src/base/wlc/wlcAbs.c \
+ src/base/wlc/wlcAbs2.c \
src/base/wlc/wlcAbc.c \
src/base/wlc/wlcBlast.c \
src/base/wlc/wlcCom.c \
@@ -7,6 +8,8 @@ SRC += src/base/wlc/wlcAbs.c \
src/base/wlc/wlcReadSmt.c \
src/base/wlc/wlcReadVer.c \
src/base/wlc/wlcSim.c \
+ src/base/wlc/wlcShow.c \
src/base/wlc/wlcStdin.c \
+ src/base/wlc/wlcUif.c \
src/base/wlc/wlcWin.c \
src/base/wlc/wlcWriteVer.c
diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h
index 1df3e5e9..686d9f00 100644
--- a/src/base/wlc/wlc.h
+++ b/src/base/wlc/wlc.h
@@ -140,6 +140,7 @@ struct Wlc_Ntk_t_
int nObjs[WLC_OBJ_NUMBER]; // counter of objects of each type
int nAnds[WLC_OBJ_NUMBER]; // counter of AND gates after blasting
int fSmtLib; // the network comes from an SMT-LIB file
+ int nAssert; // the number of asserts
// memory for objects
Wlc_Obj_t * pObjs;
int iObj;
@@ -156,6 +157,23 @@ struct Wlc_Ntk_t_
Vec_Int_t vTravIds; // trav IDs of the objects
Vec_Int_t vCopies; // object first bits
Vec_Int_t vBits; // object mapping into AIG nodes
+ Vec_Int_t vLevels; // object levels
+ Vec_Int_t vRefs; // object reference counters
+};
+
+typedef struct Wlc_Par_t_ Wlc_Par_t;
+struct Wlc_Par_t_
+{
+ int nBitsAdd; // adder bit-width
+ int nBitsMul; // multiplier bit-widht
+ int nBitsMux; // MUX bit-width
+ int nBitsFlop; // flop bit-width
+ int nIterMax; // the max number of iterations
+ int fXorOutput; // XOR outputs of word-level miter
+ int fCheckClauses; // Check clauses in the reloaded trace
+ int fPushClauses; // Push clauses in the reloaded trace
+ int fVerbose; // verbose output
+ int fPdrVerbose; // verbose output
};
static inline int Wlc_NtkObjNum( Wlc_Ntk_t * p ) { return p->iObj - 1; }
@@ -205,6 +223,8 @@ static inline int Wlc_ObjSign( Wlc_Obj_t * p )
static inline int * Wlc_ObjConstValue( Wlc_Obj_t * p ) { assert(p->Type == WLC_OBJ_CONST); return Wlc_ObjFanins(p); }
static inline int Wlc_ObjTableId( Wlc_Obj_t * p ) { assert(p->Type == WLC_OBJ_TABLE); return p->Fanins[1]; }
static inline word * Wlc_ObjTable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { return (word *)Vec_PtrEntry( p->vTables, Wlc_ObjTableId(pObj) ); }
+static inline int Wlc_ObjLevelId( Wlc_Ntk_t * p, int iObj ) { return Vec_IntEntry( &p->vLevels, iObj ); }
+static inline int Wlc_ObjLevel( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { return Wlc_ObjLevelId( p, Wlc_ObjId(p, pObj) ); }
static inline void Wlc_NtkCleanCopy( Wlc_Ntk_t * p ) { Vec_IntFill( &p->vCopies, p->nObjsAlloc, 0 ); }
static inline int Wlc_NtkHasCopy( Wlc_Ntk_t * p ) { return Vec_IntSize( &p->vCopies ) > 0; }
@@ -217,7 +237,8 @@ static inline int Wlc_NtkHasNameId( Wlc_Ntk_t * p )
static inline void Wlc_ObjSetNameId( Wlc_Ntk_t * p, int iObj, int i ) { Vec_IntWriteEntry( &p->vNameIds, iObj, i ); }
static inline int Wlc_ObjNameId( Wlc_Ntk_t * p, int iObj ) { return Vec_IntEntry( &p->vNameIds, iObj ); }
-static inline Wlc_Obj_t * Wlc_ObjFoToFi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { assert( pObj->Type == WLC_OBJ_FO ); return Wlc_NtkCo(p, Wlc_NtkCoNum(p) - Wlc_NtkCiNum(p) + Wlc_ObjCiId(pObj)); }
+static inline Wlc_Obj_t * Wlc_ObjFo2Fi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { assert( pObj->Type == WLC_OBJ_FO ); return Wlc_NtkCo(p, Wlc_NtkPoNum(p) + Wlc_ObjCiId(pObj) - Wlc_NtkPiNum(p)); }
+static inline Wlc_Obj_t * Wlc_ObjCo2PoFo( Wlc_Ntk_t * p, int iCoId ) { return iCoId < Wlc_NtkPoNum(p) ? Wlc_NtkPo(p, iCoId) : Wlc_NtkCi(p, Wlc_NtkPiNum(p) + iCoId - Wlc_NtkPoNum(p)); }
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
@@ -229,6 +250,8 @@ static inline Wlc_Obj_t * Wlc_ObjFoToFi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj )
#define Wlc_NtkForEachObj( p, pObj, i ) \
for ( i = 1; (i < Wlc_NtkObjNumMax(p)) && (((pObj) = Wlc_NtkObj(p, i)), 1); i++ )
+#define Wlc_NtkForEachObjReverse( p, pObj, i ) \
+ for ( i = Wlc_NtkObjNumMax(p) - 1; (i > 0) && (((pObj) = Wlc_NtkObj(p, i)), 1); i-- )
#define Wlc_NtkForEachObjVec( vVec, p, pObj, i ) \
for ( i = 0; (i < Vec_IntSize(vVec)) && (((pObj) = Wlc_NtkObj(p, Vec_IntEntry(vVec, i))), 1); i++ )
#define Wlc_NtkForEachPi( p, pPi, i ) \
@@ -255,16 +278,17 @@ static inline Wlc_Obj_t * Wlc_ObjFoToFi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj )
////////////////////////////////////////////////////////////////////////
/*=== wlcAbs.c ========================================================*/
-extern int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 );
-extern Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p );
-extern Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p );
-extern Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * pNtk, Vec_Int_t * vNodes );
-extern Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * pNtk, Vec_Int_t * vPairs );
+extern int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars );
+extern int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars );
+/*=== wlcAbs2.c ========================================================*/
+extern int Wlc_NtkAbsCore2( Wlc_Ntk_t * p, Wlc_Par_t * pPars );
/*=== wlcBlast.c ========================================================*/
extern Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, int nRange, int fGiaSimple, int fAddOutputs, int fBooth );
/*=== wlcCom.c ========================================================*/
extern void Wlc_SetNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk );
/*=== wlcNtk.c ========================================================*/
+extern void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars );
+extern char * Wlc_ObjTypeName( Wlc_Obj_t * p );
extern Wlc_Ntk_t * Wlc_NtkAlloc( char * pName, int nObjsAlloc );
extern int Wlc_ObjAlloc( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg );
extern int Wlc_ObjCreate( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg, Vec_Int_t * vFanins );
@@ -274,13 +298,25 @@ extern char * Wlc_ObjName( Wlc_Ntk_t * p, int iObj );
extern void Wlc_ObjUpdateType( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, int Type );
extern void Wlc_ObjAddFanins( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFanins );
extern void Wlc_NtkFree( Wlc_Ntk_t * p );
+extern int Wlc_NtkCreateLevels( Wlc_Ntk_t * p );
+extern int Wlc_NtkCreateLevelsRev( Wlc_Ntk_t * p );
+extern int Wlc_NtkCountRealPis( Wlc_Ntk_t * p );
extern void Wlc_NtkPrintNode( Wlc_Ntk_t * p, Wlc_Obj_t * pObj );
extern void Wlc_NtkPrintNodeArray( Wlc_Ntk_t * p, Vec_Int_t * vArray );
extern void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type );
-extern void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose );
-extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p );
+extern void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fTwoSides, int fVerbose );
extern void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p );
+extern char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq );
+extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq );
+extern Wlc_Ntk_t * Wlc_NtkDupDfsAbs( Wlc_Ntk_t * p, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops );
+extern void Wlc_NtkCleanMarks( Wlc_Ntk_t * p );
+extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int Range, int fSeq, int fAllPis );
+extern void Wlc_NtkProfileCones( Wlc_Ntk_t * p );
extern Wlc_Ntk_t * Wlc_NtkDupSingleNodes( Wlc_Ntk_t * p );
+extern void Wlc_NtkShortNames( Wlc_Ntk_t * p );
+extern int Wlc_NtkDcFlopNum( Wlc_Ntk_t * p );
+extern void Wlc_NtkSetRefs( Wlc_Ntk_t * p );
+extern int Wlc_NtkCountObjBits( Wlc_Ntk_t * p, Vec_Int_t * vPisNew );
/*=== wlcReadSmt.c ========================================================*/
extern Wlc_Ntk_t * Wlc_ReadSmtBuffer( char * pFileName, char * pBuffer, char * pLimit, int fOldParser, int fPrintTree );
extern Wlc_Ntk_t * Wlc_ReadSmt( char * pFileName, int fOldParser, int fPrintTree );
@@ -291,6 +327,12 @@ extern void Wlc_NtkDeleteSim( Vec_Ptr_t * p );
extern int Wlc_StdinProcessSmt( Abc_Frame_t * pAbc, char * pCmd );
/*=== wlcReadVer.c ========================================================*/
extern Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr );
+/*=== wlcUif.c ========================================================*/
+extern int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 );
+extern Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p );
+extern Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p );
+extern Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * pNtk, Vec_Int_t * vNodes );
+extern Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * pNtk, Vec_Int_t * vPairs );
/*=== wlcWin.c =============================================================*/
extern void Wlc_WinProfileArith( Wlc_Ntk_t * p );
/*=== wlcWriteVer.c ========================================================*/
diff --git a/src/base/wlc/wlcAbc.c b/src/base/wlc/wlcAbc.c
index 0bf27f7b..1836f4ed 100644
--- a/src/base/wlc/wlcAbc.c
+++ b/src/base/wlc/wlcAbc.c
@@ -42,7 +42,7 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
-void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose )
+void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vCounts, int fVerbose )
{
Wlc_Obj_t * pObj;
int i, k, nNum, nRange, nBits = 0;
@@ -53,7 +53,7 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose )
nRange = Wlc_ObjRange(pObj);
for ( k = 0; k < nRange; k++ )
{
- nNum = Vec_IntEntry(vInv, nBits + k);
+ nNum = Vec_IntEntry(vCounts, nBits + k);
if ( nNum )
break;
}
@@ -65,7 +65,7 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose )
printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg );
for ( k = 0; k < nRange; k++ )
{
- nNum = Vec_IntEntry( vInv, nBits + k );
+ nNum = Vec_IntEntry( vCounts, nBits + k );
if ( nNum == 0 )
continue;
printf( " [%d] -> %d", k, nNum );
@@ -73,8 +73,8 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose )
printf( "\n");
nBits += nRange;
}
- //printf( "%d %d\n", Vec_IntSize(vInv), nBits );
- assert( Vec_IntSize(vInv) == nBits );
+ //printf( "%d %d\n", Vec_IntSize(vCounts), nBits );
+ assert( Vec_IntSize(vCounts) == nBits );
}
/**Function*************************************************************
@@ -88,8 +88,14 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose )
SeeAlso []
***********************************************************************/
-Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop, int fVerbose )
+Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv )
{
+ extern Vec_Int_t * Pdr_InvCounts( Vec_Int_t * vInv );
+ extern Vec_Str_t * Pdr_InvPrintStr( Vec_Int_t * vInv, Vec_Int_t * vCounts );
+
+ Vec_Int_t * vCounts = Pdr_InvCounts( vInv );
+ Vec_Str_t * vSop = Pdr_InvPrintStr( vInv, vCounts );
+
Wlc_Obj_t * pObj;
int i, k, nNum, nRange, nBits = 0;
Abc_Ntk_t * pMainNtk = NULL;
@@ -98,46 +104,69 @@ Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop,
// start the network
pMainNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 );
// duplicate the name and the spec
- pMainNtk->pName = Extra_UtilStrsav(pNtk->pName);
+ pMainNtk->pName = Extra_UtilStrsav(pNtk ? pNtk->pName : "inv");
// create primary inputs
- Wlc_NtkForEachCi( pNtk, pObj, i )
+ if ( pNtk == NULL )
{
- if ( pObj->Type != WLC_OBJ_FO )
- continue;
- nRange = Wlc_ObjRange(pObj);
- for ( k = 0; k < nRange; k++ )
+ int Entry, nInputs = Abc_SopGetVarNum( Vec_StrArray(vSop) );
+ Vec_IntForEachEntry( vCounts, Entry, i )
{
- nNum = Vec_IntEntry(vInv, nBits + k);
- if ( nNum )
- break;
+ if ( Entry == 0 )
+ continue;
+ pMainObj = Abc_NtkCreatePi( pMainNtk );
+ sprintf( Buffer, "pi%d", i );
+ Abc_ObjAssignName( pMainObj, Buffer, NULL );
}
- if ( k == nRange )
+ if ( Abc_NtkPiNum(pMainNtk) != nInputs )
{
- nBits += nRange;
- continue;
+ printf( "Mismatch between number of inputs and the number of literals in the invariant.\n" );
+ Abc_NtkDelete( pMainNtk );
+ return NULL;
}
- //printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg );
- for ( k = 0; k < nRange; k++ )
+ }
+ else
+ {
+ Wlc_NtkForEachCi( pNtk, pObj, i )
{
- nNum = Vec_IntEntry( vInv, nBits + k );
- if ( nNum == 0 )
+ if ( pObj->Type != WLC_OBJ_FO )
continue;
- //printf( " [%d] -> %d", k, nNum );
- pMainObj = Abc_NtkCreatePi( pMainNtk );
- sprintf( Buffer, "%s[%d]", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), k );
- Abc_ObjAssignName( pMainObj, Buffer, NULL );
+ nRange = Wlc_ObjRange(pObj);
+ for ( k = 0; k < nRange; k++ )
+ {
+ nNum = Vec_IntEntry(vCounts, nBits + k);
+ if ( nNum )
+ break;
+ }
+ if ( k == nRange )
+ {
+ nBits += nRange;
+ continue;
+ }
+ //printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg );
+ for ( k = 0; k < nRange; k++ )
+ {
+ nNum = Vec_IntEntry( vCounts, nBits + k );
+ if ( nNum == 0 )
+ continue;
+ //printf( " [%d] -> %d", k, nNum );
+ pMainObj = Abc_NtkCreatePi( pMainNtk );
+ sprintf( Buffer, "%s[%d]", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), k );
+ Abc_ObjAssignName( pMainObj, Buffer, NULL );
+ }
+ //printf( "\n");
+ nBits += nRange;
}
- //printf( "\n");
- nBits += nRange;
}
- //printf( "%d %d\n", Vec_IntSize(vInv), nBits );
- assert( Vec_IntSize(vInv) == nBits );
+ //printf( "%d %d\n", Vec_IntSize(vCounts), nBits );
+ assert( pNtk == NULL || Vec_IntSize(vCounts) == nBits );
// create node
pMainObj = Abc_NtkCreateNode( pMainNtk );
Abc_NtkForEachPi( pMainNtk, pMainTemp, i )
Abc_ObjAddFanin( pMainObj, pMainTemp );
pMainObj->pData = Abc_SopRegister( (Mem_Flex_t *)pMainNtk->pManFunc, Vec_StrArray(vSop) );
+ Vec_IntFree( vCounts );
+ Vec_StrFree( vSop );
// create PO
pMainTemp = Abc_NtkCreatePo( pMainNtk );
Abc_ObjAddFanin( pMainTemp, pMainObj );
@@ -145,6 +174,98 @@ Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop,
return pMainNtk;
}
+/**Function*************************************************************
+
+ Synopsis [Translate current network into an invariant.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, Gia_Man_t * pGia )
+{
+ int nRegs = Gia_ManRegNum(pGia);
+ Vec_Int_t * vRes = NULL;
+ if ( Abc_NtkPoNum(pNtk) != 1 )
+ printf( "The number of outputs is other than 1.\n" );
+ else if ( Abc_NtkNodeNum(pNtk) != 1 )
+ printf( "The number of internal nodes is other than 1.\n" );
+ else
+ {
+ Abc_Nam_t * pNames = NULL;
+ Abc_Obj_t * pFanin, * pNode = Abc_ObjFanin0( Abc_NtkCo(pNtk, 0) );
+ char * pName, * pCube, * pSop = (char *)pNode->pData;
+ Vec_Int_t * vFanins = Vec_IntAlloc( Abc_ObjFaninNum(pNode) );
+ int i, k, Value, nLits, Counter = 0;
+ if ( pGia->vNamesIn )
+ {
+ // hash the names
+ pNames = Abc_NamStart( 100, 16 );
+ Vec_PtrForEachEntry( char *, pGia->vNamesIn, pName, i )
+ {
+ Value = Abc_NamStrFindOrAdd( pNames, pName, NULL );
+ assert( Value == i+1 );
+ //printf( "%s(%d) ", pName, i );
+ }
+ //printf( "\n" );
+ }
+ Abc_ObjForEachFanin( pNode, pFanin, i )
+ {
+ assert( Abc_ObjIsCi(pFanin) );
+ pName = Abc_ObjName(pFanin);
+ if ( pNames )
+ {
+ Value = Abc_NamStrFind(pNames, pName) - 1 - Gia_ManPiNum(pGia);
+ if ( Value < 0 )
+ {
+ if ( Counter++ == 0 )
+ printf( "Cannot read input name \"%s\" of fanin %d.\n", pName, i );
+ Value = i;
+ }
+ }
+ else
+ {
+ for ( k = (int)strlen(pName)-1; k >= 0; k-- )
+ if ( pName[k] < '0' || pName[k] > '9' )
+ break;
+ if ( k == (int)strlen(pName)-1 )
+ {
+ if ( Counter++ == 0 )
+ printf( "Cannot read input name \"%s\" of fanin %d.\n", pName, i );
+ Value = i;
+ }
+ else
+ Value = atoi(pName + k + 1);
+ }
+ Vec_IntPush( vFanins, Value );
+ }
+ if ( Counter )
+ printf( "Cannot read names for %d inputs of the invariant.\n", Counter );
+ if ( pNames )
+ Abc_NamStop( pNames );
+ assert( Vec_IntSize(vFanins) == Abc_ObjFaninNum(pNode) );
+ vRes = Vec_IntAlloc( 1000 );
+ Vec_IntPush( vRes, Abc_SopGetCubeNum(pSop) );
+ Abc_SopForEachCube( pSop, Abc_ObjFaninNum(pNode), pCube )
+ {
+ nLits = 0;
+ Abc_CubeForEachVar( pCube, Value, k )
+ if ( Value != '-' )
+ nLits++;
+ Vec_IntPush( vRes, nLits );
+ Abc_CubeForEachVar( pCube, Value, k )
+ if ( Value != '-' )
+ Vec_IntPush( vRes, Abc_Var2Lit(Vec_IntEntry(vFanins, k), (int)Value == '0') );
+ }
+ Vec_IntPush( vRes, nRegs );
+ Vec_IntFree( vFanins );
+ }
+ return vRes;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c
index 73ff7328..e33424f7 100644
--- a/src/base/wlc/wlcAbs.c
+++ b/src/base/wlc/wlcAbs.c
@@ -8,7 +8,7 @@
Synopsis [Abstraction for word-level networks.]
- Author [Alan Mishchenko]
+ Author [Yen-Sheng Ho, Alan Mishchenko]
Affiliation [UC Berkeley]
@@ -19,6 +19,10 @@
***********************************************************************/
#include "wlc.h"
+#include "proof/pdr/pdr.h"
+#include "proof/pdr/pdrInt.h"
+#include "aig/gia/giaAig.h"
+#include "sat/bmc/bmc.h"
ABC_NAMESPACE_IMPL_START
@@ -26,161 +30,330 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+extern Vec_Vec_t * IPdr_ManSaveClauses( Pdr_Man_t * p, int fDropLast );
+extern int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses, Vec_Int_t * vMap );
+extern int IPdr_ManSolveInt( Pdr_Man_t * p, int fCheckClauses, int fPushClauses );
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
- Synopsis [Check if two objects have the same input/output signatures.]
+ Synopsis [Mark operators that meet the abstraction criteria.]
- Description []
+ Description [This procedure returns the array of objects (vLeaves) that
+ should be abstracted because of their high bit-width. It uses input array (vUnmark)
+ to not abstract those objects that have been refined in the previous rounds.]
SideEffects []
SeeAlso []
***********************************************************************/
-int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 )
+static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose )
{
- Wlc_Obj_t * pFanin, * pFanin2; int k;
- if ( Wlc_ObjRange(pObj) != Wlc_ObjRange(pObj2) )
- return 0;
- if ( Wlc_ObjIsSigned(pObj) != Wlc_ObjIsSigned(pObj2) )
- return 0;
- if ( Wlc_ObjFaninNum(pObj) != Wlc_ObjFaninNum(pObj2) )
- return 0;
- for ( k = 0; k < Wlc_ObjFaninNum(pObj); k++ )
+ Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) );
+ Wlc_Obj_t * pObj; int i, Count[4] = {0};
+ Wlc_NtkForEachObj( p, pObj, i )
{
- pFanin = Wlc_ObjFanin(p, pObj, k);
- pFanin2 = Wlc_ObjFanin(p, pObj2, k);
- if ( Wlc_ObjRange(pFanin) != Wlc_ObjRange(pFanin2) )
- return 0;
- if ( Wlc_ObjIsSigned(pFanin) != Wlc_ObjIsSigned(pFanin2) )
- return 0;
+ if ( vUnmark && Vec_BitEntry(vUnmark, i) ) // not allow this object to be abstracted away
+ continue;
+ if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || pObj->Type == WLC_OBJ_ARI_MINUS )
+ {
+ if ( Wlc_ObjRange(pObj) >= pPars->nBitsAdd )
+ Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[0]++;
+ continue;
+ }
+ if ( pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_DIVIDE || pObj->Type == WLC_OBJ_ARI_REM || pObj->Type == WLC_OBJ_ARI_MODULUS )
+ {
+ if ( Wlc_ObjRange(pObj) >= pPars->nBitsMul )
+ Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[1]++;
+ continue;
+ }
+ if ( pObj->Type == WLC_OBJ_MUX )
+ {
+ if ( Wlc_ObjRange(pObj) >= pPars->nBitsMux )
+ Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[2]++;
+ continue;
+ }
+ if ( Wlc_ObjIsCi(pObj) && !Wlc_ObjIsPi(pObj) )
+ {
+ if ( Wlc_ObjRange(pObj) >= pPars->nBitsFlop )
+ Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[3]++;
+ continue;
+ }
}
- return 1;
+ if ( fVerbose )
+ printf( "Abstraction engine marked %d adds/subs, %d muls/divs, %d muxes, and %d flops to be abstracted away.\n", Count[0], Count[1], Count[2], Count[3] );
+ return vLeaves;
}
/**Function*************************************************************
- Synopsis [Collect IDs of the multipliers.]
+ Synopsis [Marks nodes to be included in the abstracted network.]
- Description []
+ Description [Marks all objects that will be included in the abstracted model.
+ Stops at the objects (vLeaves) that are abstracted away. Returns three arrays:
+ a subset of original PIs (vPisOld), a subset of pseudo-PIs (vPisNew) and the
+ set of flops present as flops in the abstracted network.]
SideEffects []
SeeAlso []
***********************************************************************/
-Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p )
+static void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops )
{
- Wlc_Obj_t * pObj; int i;
- Vec_Int_t * vBoxIds = Vec_IntAlloc( 100 );
+ int i, iFanin;
+ if ( pObj->Mark )
+ return;
+ pObj->Mark = 1;
+ if ( Vec_BitEntry(vLeaves, Wlc_ObjId(p, pObj)) )
+ {
+ assert( !Wlc_ObjIsPi(pObj) );
+ Vec_IntPush( vPisNew, Wlc_ObjId(p, pObj) );
+ return;
+ }
+ if ( Wlc_ObjIsCi(pObj) )
+ {
+ if ( Wlc_ObjIsPi(pObj) )
+ Vec_IntPush( vPisOld, Wlc_ObjId(p, pObj) );
+ else
+ Vec_IntPush( vFlops, Wlc_ObjId(p, pObj) );
+ return;
+ }
+ Wlc_ObjForEachFanin( pObj, iFanin, i )
+ Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkObj(p, iFanin), vLeaves, vPisOld, vPisNew, vFlops );
+}
+static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops )
+{
+ Wlc_Obj_t * pObj;
+ int i, Count = 0;
+ Wlc_NtkCleanMarks( p );
+ Wlc_NtkForEachCo( p, pObj, i )
+ Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vPisOld, vPisNew, vFlops );
+
+/*
+ Vec_IntClear(vFlops);
+ Wlc_NtkForEachCi( p, pObj, i ) {
+ if ( !Wlc_ObjIsPi(pObj) ) {
+ Vec_IntPush( vFlops, Wlc_ObjId(p, pObj) );
+ pObj->Mark = 1;
+ }
+ }
+*/
+
+ Wlc_NtkForEachObjVec( vFlops, p, pObj, i )
+ Wlc_NtkAbsMarkNodes_rec( p, Wlc_ObjFo2Fi(p, pObj), vLeaves, vPisOld, vPisNew, vFlops );
Wlc_NtkForEachObj( p, pObj, i )
- if ( pObj->Type == WLC_OBJ_ARI_MULTI )
- Vec_IntPush( vBoxIds, i );
- if ( Vec_IntSize( vBoxIds ) > 0 )
- return vBoxIds;
- Vec_IntFree( vBoxIds );
- return NULL;
+ Count += pObj->Mark;
+// printf( "Collected %d old PIs, %d new PIs, %d flops, and %d other objects.\n",
+// Vec_IntSize(vPisOld), Vec_IntSize(vPisNew), Vec_IntSize(vFlops),
+// Count - Vec_IntSize(vPisOld) - Vec_IntSize(vPisNew) - Vec_IntSize(vFlops) );
+ Vec_IntSort( vPisOld, 0 );
+ Vec_IntSort( vPisNew, 0 );
+ Vec_IntSort( vFlops, 0 );
+ Wlc_NtkCleanMarks( p );
}
/**Function*************************************************************
- Synopsis [Returns all pairs of uifable multipliers.]
+ Synopsis [Derive word-level abstracted model based on the parameter values.]
- Description []
+ Description [Retuns the word-level abstracted network and the set of pseudo-PIs
+ (vPisNew), which were created during abstraction. If the abstraction is
+ satisfiable, some of the pseudo-PIs will be un-abstracted. These pseudo-PIs
+ and their MFFC cones will be listed in the array (vUnmark), which will
+ force the abstraction to not stop at these pseudo-PIs in the future.]
SideEffects []
SeeAlso []
***********************************************************************/
-Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p )
+static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, Vec_Int_t ** pvFlops, int fVerbose )
{
- Vec_Int_t * vMultis = Wlc_NtkCollectMultipliers( p );
- Vec_Int_t * vPairs = Vec_IntAlloc( 2 );
- Wlc_Obj_t * pObj, * pObj2; int i, k;
- // iterate through unique pairs
- Wlc_NtkForEachObjVec( vMultis, p, pObj, i )
- Wlc_NtkForEachObjVec( vMultis, p, pObj2, k )
- {
- if ( k == i )
- break;
- if ( Wlc_NtkPairIsUifable( p, pObj, pObj2 ) )
- {
- Vec_IntPush( vPairs, Wlc_ObjId(p, pObj) );
- Vec_IntPush( vPairs, Wlc_ObjId(p, pObj2) );
- }
- }
- Vec_IntFree( vMultis );
- if ( Vec_IntSize( vPairs ) > 0 )
- return vPairs;
- Vec_IntFree( vPairs );
- return NULL;
+ Wlc_Ntk_t * pNtkNew = NULL;
+ Vec_Int_t * vPisOld = Vec_IntAlloc( 100 );
+ Vec_Int_t * vPisNew = Vec_IntAlloc( 100 );
+ Vec_Int_t * vFlops = Vec_IntAlloc( 100 );
+ Vec_Bit_t * vLeaves = Wlc_NtkAbsMarkOpers( p, pPars, vUnmark, fVerbose );
+ Wlc_NtkAbsMarkNodes( p, vLeaves, vPisOld, vPisNew, vFlops );
+ Vec_BitFree( vLeaves );
+ pNtkNew = Wlc_NtkDupDfsAbs( p, vPisOld, vPisNew, vFlops );
+ Vec_IntFree( vPisOld );
+ if ( pvFlops )
+ *pvFlops = vFlops;
+ else
+ Vec_IntFree( vFlops );
+ if ( pvPisNew )
+ *pvPisNew = vPisNew;
+ else
+ Vec_IntFree( vPisNew );
+ return pNtkNew;
}
+/**Function*************************************************************
+
+ Synopsis [Find what objects need to be un-abstracted.]
+
+ Description [Returns a subset of pseudo-PIs (vPisNew), which will be
+ prevented from being abstracted in the future rounds of abstraction.
+ The AIG manager (pGia) is a bit-level view of the abstracted model.
+ The counter-example (pCex) is used to find waht PPIs to refine.]
+
+ SideEffects []
+ SeeAlso []
+
+***********************************************************************/
+static Vec_Int_t * Wlc_NtkAbsRefinement( Wlc_Ntk_t * p, Gia_Man_t * pGia, Abc_Cex_t * pCex, Vec_Int_t * vPisNew )
+{
+ Vec_Int_t * vRefine = Vec_IntAlloc( 100 );
+ Abc_Cex_t * pCexCare;
+ Wlc_Obj_t * pObj;
+ // count the number of bit-level PPIs and map them into word-level objects they were derived from
+ int f, i, b, nRealPis, nPpiBits = 0;
+ Vec_Int_t * vMap = Vec_IntStartFull( pCex->nPis );
+ Wlc_NtkForEachObjVec( vPisNew, p, pObj, i )
+ for ( b = 0; b < Wlc_ObjRange(pObj); b++ )
+ Vec_IntWriteEntry( vMap, nPpiBits++, Wlc_ObjId(p, pObj) );
+ // since PPIs are ordered last, the previous bits are real PIs
+ nRealPis = pCex->nPis - nPpiBits;
+ // find the care-set
+ pCexCare = Bmc_CexCareMinimizeAig( pGia, nRealPis, pCex, 1, 0, 0 );
+ assert( pCexCare->nPis == pCex->nPis );
+ // detect care PPIs
+ for ( f = 0; f <= pCexCare->iFrame; f++ )
+ for ( i = nRealPis; i < pCexCare->nPis; i++ )
+ if ( Abc_InfoHasBit(pCexCare->pData, pCexCare->nRegs + pCexCare->nPis * f + i) )
+ Vec_IntPushUniqueOrder( vRefine, Vec_IntEntry(vMap, i-nRealPis) );
+ Abc_CexFree( pCexCare );
+ Vec_IntFree( vMap );
+ if ( Vec_IntSize(vRefine) == 0 )// real CEX
+ Vec_IntFreeP( &vRefine );
+ return vRefine;
+}
/**Function*************************************************************
- Synopsis [Abstracts nodes by replacing their outputs with new PIs.]
+ Synopsis [Mark MFFC cones of the un-abstracted objects.]
- Description [If array is NULL, abstract all multipliers.]
+ Description [The MFFC cones of the objects in vRefine are traversed
+ and all their nodes are marked in vUnmark.]
SideEffects []
SeeAlso []
***********************************************************************/
-Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit )
+static int Wlc_NtkNodeDeref_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark )
{
- Vec_Int_t * vNodes = vNodesInit;
- Wlc_Ntk_t * pNew;
- Wlc_Obj_t * pObj;
- int i, k, iObj, iFanin;
- // get multipliers if not given
- if ( vNodes == NULL )
- vNodes = Wlc_NtkCollectMultipliers( p );
- if ( vNodes == NULL )
- return NULL;
- // mark nodes
- Wlc_NtkForEachObjVec( vNodes, p, pObj, i )
- pObj->Mark = 1;
- // iterate through the nodes in the DFS order
- Wlc_NtkCleanCopy( p );
- Wlc_NtkForEachObj( p, pObj, i )
+ int i, Fanin, Counter = 1;
+ if ( Wlc_ObjIsCi(pNode) )
+ return 0;
+ Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 );
+ Wlc_ObjForEachFanin( pNode, Fanin, i )
{
- if ( i == Vec_IntSize(&p->vCopies) )
- break;
- if ( pObj->Mark ) {
- // clean
- pObj->Mark = 0;
- // add fresh PI with the same number of bits
- iObj = Wlc_ObjAlloc( p, WLC_OBJ_PI, Wlc_ObjIsSigned(pObj), Wlc_ObjRange(pObj) - 1, 0 );
- }
- else {
- // update fanins
- Wlc_ObjForEachFanin( pObj, iFanin, k )
- Wlc_ObjFanins(pObj)[k] = Wlc_ObjCopy(p, iFanin);
- // node to remain
- iObj = i;
- }
- Wlc_ObjSetCopy( p, i, iObj );
+ Vec_IntAddToEntry( &p->vRefs, Fanin, -1 );
+ if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 )
+ Counter += Wlc_NtkNodeDeref_rec( p, Wlc_NtkObj(p, Fanin), vUnmark );
}
- // POs do not change in this procedure
- if ( vNodes != vNodesInit )
- Vec_IntFree( vNodes );
- // reconstruct topological order
- pNew = Wlc_NtkDupDfs( p );
- Wlc_NtkTransferNames( pNew, p );
- return pNew;
+ return Counter;
+}
+static int Wlc_NtkNodeRef_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode )
+{
+ int i, Fanin, Counter = 1;
+ if ( Wlc_ObjIsCi(pNode) )
+ return 0;
+ Wlc_ObjForEachFanin( pNode, Fanin, i )
+ {
+ if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 )
+ Counter += Wlc_NtkNodeRef_rec( p, Wlc_NtkObj(p, Fanin) );
+ Vec_IntAddToEntry( &p->vRefs, Fanin, 1 );
+ }
+ return Counter;
+}
+static int Wlc_NtkMarkMffc( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark )
+{
+ int Count1, Count2;
+ // if this is a flop output, compute MFFC of the corresponding flop input
+ while ( Wlc_ObjIsCi(pNode) )
+ {
+ Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 );
+ pNode = Wlc_ObjFo2Fi(p, pNode);
+ }
+ assert( !Wlc_ObjIsCi(pNode) );
+ // dereference the node (and set the bits in vUnmark)
+ Count1 = Wlc_NtkNodeDeref_rec( p, pNode, vUnmark );
+ // reference it back
+ Count2 = Wlc_NtkNodeRef_rec( p, pNode );
+ assert( Count1 == Count2 );
+ return Count1;
+}
+static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec_Bit_t * vUnmark )
+{
+ Wlc_Obj_t * pObj; int i, nNodes = 0;
+ if ( Vec_IntSize(&p->vRefs) == 0 )
+ Wlc_NtkSetRefs( p );
+ Wlc_NtkForEachObjVec( vRefine, p, pObj, i )
+ nNodes += Wlc_NtkMarkMffc( p, pObj, vUnmark );
+ return nNodes;
}
/**Function*************************************************************
- Synopsis [Adds UIF constraints to node pairs and updates POs.]
+ Synopsis [Computes the map for remapping flop IDs used in the clauses.]
+
+ Description [Takes the original network (Wlc_Ntk_t) and the array of word-level
+ flops used in the old abstraction (vFfOld) and those used in the new abstraction
+ (vFfNew). Returns the integer map, which remaps every binary flop found
+ in the old abstraction into a binary flop found in the new abstraction.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Wlc_NtkFlopsRemap( Wlc_Ntk_t * p, Vec_Int_t * vFfOld, Vec_Int_t * vFfNew )
+{
+ Vec_Int_t * vMap = Vec_IntAlloc( 1000 ); // the resulting map
+ Vec_Int_t * vMapFfNew2Bit1 = Vec_IntAlloc( 1000 ); // first binary bit of each new word-level flop
+ int i, b, iFfOld, iFfNew, iBit1New, nBits = 0;
+ // map object IDs of old flops into their flop indexes
+ Vec_Int_t * vMapFfObj2FfId = Vec_IntStartFull( Wlc_NtkObjNumMax(p) );
+ Vec_IntForEachEntry( vFfNew, iFfNew, i )
+ Vec_IntWriteEntry( vMapFfObj2FfId, iFfNew, i );
+ // map each new flop index into its first bit
+ Vec_IntForEachEntry( vFfNew, iFfNew, i )
+ {
+ Wlc_Obj_t * pObj = Wlc_NtkObj( p, iFfNew );
+ int nRange = Wlc_ObjRange( pObj );
+ Vec_IntPush( vMapFfNew2Bit1, nBits );
+ nBits += nRange;
+ }
+ assert( Vec_IntSize(vMapFfNew2Bit1) == Vec_IntSize(vFfNew) );
+ // remap old binary flops into new binary flops
+ Vec_IntForEachEntry( vFfOld, iFfOld, i )
+ {
+ Wlc_Obj_t * pObj = Wlc_NtkObj( p, iFfOld );
+ int nRange = Wlc_ObjRange( pObj );
+ iFfNew = Vec_IntEntry( vMapFfObj2FfId, iFfOld );
+ assert( iFfNew >= 0 ); // every old flop should be present in the new abstraction
+ // find the first bit of this new flop
+ iBit1New = Vec_IntEntry( vMapFfNew2Bit1, iFfNew );
+ for ( b = 0; b < nRange; b++ )
+ Vec_IntPush( vMap, iBit1New + b );
+ }
+ Vec_IntFree( vMapFfNew2Bit1 );
+ Vec_IntFree( vMapFfObj2FfId );
+ return vMap;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs PDR with word-level abstraction.]
Description []
@@ -189,98 +362,266 @@ Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit )
SeeAlso []
***********************************************************************/
-Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * p, Vec_Int_t * vPairsInit )
+int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars )
{
- Vec_Int_t * vPairs = vPairsInit;
- Wlc_Ntk_t * pNew;
- Wlc_Obj_t * pObj, * pObj2;
- Vec_Int_t * vUifConstrs, * vCompares, * vFanins;
- int i, k, iObj, iObj2, iObjNew, iObjNew2;
- int iFanin, iFanin2, iFaninNew;
- // get multiplier pairs if not given
- if ( vPairs == NULL )
- vPairs = Wlc_NtkFindUifableMultiplierPairs( p );
- if ( vPairs == NULL )
- return NULL;
- // sanity checks
- assert( Vec_IntSize(vPairs) > 0 && Vec_IntSize(vPairs) % 2 == 0 );
- // iterate through node pairs
- vFanins = Vec_IntAlloc( 100 );
- vCompares = Vec_IntAlloc( 100 );
- vUifConstrs = Vec_IntAlloc( 100 );
- Vec_IntForEachEntryDouble( vPairs, iObj, iObj2, i )
+ abctime clk = Abc_Clock();
+ abctime pdrClk;
+ Pdr_Man_t * pPdr;
+ Vec_Vec_t * vClauses = NULL;
+ Vec_Int_t * vFfOld = NULL, * vFfNew = NULL, * vMap = NULL;
+ int nIters, nNodes, nDcFlops, RetValue = -1, nGiaFfNumOld = -1;
+ // start the bitmap to mark objects that cannot be abstracted because of refinement
+ // currently, this bitmap is empty because abstraction begins without refinement
+ Vec_Bit_t * vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(p) );
+ // set up parameters to run PDR
+ Pdr_Par_t PdrPars, * pPdrPars = &PdrPars;
+ Pdr_ManSetDefaultParams( pPdrPars );
+ pPdrPars->fVerbose = pPars->fPdrVerbose;
+ pPdrPars->fVeryVerbose = 0;
+
+ // perform refinement iterations
+ for ( nIters = 1; nIters < pPars->nIterMax; nIters++ )
{
- // get two nodes
- pObj = Wlc_NtkObj( p, iObj );
- pObj2 = Wlc_NtkObj( p, iObj2 );
- assert( Wlc_NtkPairIsUifable(p, pObj, pObj2) );
- // create fanin comparator nodes
- Vec_IntClear( vCompares );
- Wlc_ObjForEachFanin( pObj, iFanin, k )
+ Aig_Man_t * pAig;
+ Abc_Cex_t * pCex;
+ Vec_Int_t * vPisNew, * vRefine;
+ Gia_Man_t * pGia, * pTemp;
+ Wlc_Ntk_t * pAbs;
+
+ if ( pPars->fVerbose )
+ printf( "\nIteration %d:\n", nIters );
+
+ // get abstracted GIA and the set of pseudo-PIs (vPisNew)
+ pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, &vFfNew, pPars->fVerbose );
+ pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 );
+
+ // map old flops into new flops
+ if ( vFfOld )
{
- iFanin2 = Wlc_ObjFaninId( pObj2, k );
- Vec_IntFillTwo( vFanins, 2, iFanin, iFanin2 );
- iFaninNew = Wlc_ObjCreate( p, WLC_OBJ_COMP_NOTEQU, 0, 0, 0, vFanins );
- Vec_IntPush( vCompares, iFaninNew );
- // note that a pointer to Wlc_Obj_t (for example, pObj) can be invalidated after a call to
- // Wlc_ObjCreate() due to a possible realloc of the internal array of objects...
- pObj = Wlc_NtkObj( p, iObj );
+ assert( nGiaFfNumOld >= 0 );
+ vMap = Wlc_NtkFlopsRemap( p, vFfOld, vFfNew );
+ //Vec_IntPrint( vMap );
+ // if reset flop was added in the previous iteration, it will be added again in this iteration
+ // remap the last flop (reset flop) into the last flop (reset flop) of the current AIG
+ if ( Vec_IntSize(vMap) + 1 == nGiaFfNumOld )
+ Vec_IntPush( vMap, Gia_ManRegNum(pGia)-1 );
+ assert( Vec_IntSize(vMap) == nGiaFfNumOld );
+ Vec_IntFreeP( &vFfOld );
}
- // concatenate fanin comparators
- iObjNew = Wlc_ObjCreate( p, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vCompares) - 1, 0, vCompares );
- // create reduction-OR node
- Vec_IntFill( vFanins, 1, iObjNew );
- iObjNew = Wlc_ObjCreate( p, WLC_OBJ_REDUCT_OR, 0, 0, 0, vFanins );
- // craete output comparator node
- Vec_IntFillTwo( vFanins, 2, iObj, iObj2 );
- iObjNew2 = Wlc_ObjCreate( p, WLC_OBJ_COMP_EQU, 0, 0, 0, vFanins );
- // create implication node (iObjNew is already complemented above)
- Vec_IntFillTwo( vFanins, 2, iObjNew, iObjNew2 );
- iObjNew = Wlc_ObjCreate( p, WLC_OBJ_LOGIC_OR, 0, 0, 0, vFanins );
- // save the constraint
- Vec_IntPush( vUifConstrs, iObjNew );
- }
- // derive the AND of the UIF contraints
- assert( Vec_IntSize(vUifConstrs) > 0 );
- if ( Vec_IntSize(vUifConstrs) == 1 )
- iObjNew = Vec_IntEntry( vUifConstrs, 0 );
- else
- {
- // concatenate
- iObjNew = Wlc_ObjCreate( p, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vUifConstrs) - 1, 0, vUifConstrs );
- // create reduction-AND node
- Vec_IntFill( vFanins, 1, iObjNew );
- iObjNew = Wlc_ObjCreate( p, WLC_OBJ_REDUCT_AND, 0, 0, 0, vFanins );
+ ABC_SWAP( Vec_Int_t *, vFfOld, vFfNew );
+ nGiaFfNumOld = Gia_ManRegNum(pGia);
+
+ // if the abstraction has flops with DC-init state,
+ // new PIs were introduced by bit-blasting at the end of the PI list
+ // here we move these variables to be *before* PPIs, because
+ // PPIs are supposed to be at the end of the PI list for refinement
+ nDcFlops = Wlc_NtkDcFlopNum(pAbs);
+ if ( nDcFlops > 0 ) // DC-init flops are present
+ {
+ pGia = Gia_ManPermuteInputs( pTemp = pGia, Wlc_NtkCountObjBits(p, vPisNew), nDcFlops );
+ Gia_ManStop( pTemp );
+ }
+ // if the word-level outputs have to be XORs, this is a place to do it
+ if ( pPars->fXorOutput )
+ {
+ pGia = Gia_ManTransformMiter2( pTemp = pGia );
+ Gia_ManStop( pTemp );
+ }
+ if ( pPars->fVerbose )
+ {
+ printf( "Derived abstraction with %d objects and %d PPIs. Bit-blasted AIG stats are:\n", Wlc_NtkObjNum(pAbs), Vec_IntSize(vPisNew) );
+ Gia_ManPrintStats( pGia, NULL );
+ }
+ Wlc_NtkFree( pAbs );
+
+ // try to prove abstracted GIA by converting it to AIG and calling PDR
+ pAig = Gia_ManToAigSimple( pGia );
+
+ pPdr = Pdr_ManStart( pAig, pPdrPars, NULL );
+ pdrClk = Abc_Clock();
+
+ if ( vClauses ) {
+ assert( Vec_VecSize( vClauses) >= 2 );
+ IPdr_ManRestore( pPdr, vClauses, vMap );
+ }
+ Vec_IntFreeP( &vMap );
+
+ RetValue = IPdr_ManSolveInt( pPdr, pPars->fCheckClauses, pPars->fPushClauses );
+ pPdr->tTotal += Abc_Clock() - pdrClk;
+
+ pCex = pAig->pSeqModel; pAig->pSeqModel = NULL;
+
+ // consider outcomes
+ if ( pCex == NULL )
+ {
+ assert( RetValue ); // proved or undecided
+ Gia_ManStop( pGia );
+ Vec_IntFree( vPisNew );
+ Pdr_ManStop( pPdr );
+ Aig_ManStop( pAig );
+ break;
+ }
+
+ // perform refinement
+ vRefine = Wlc_NtkAbsRefinement( p, pGia, pCex, vPisNew );
+ Gia_ManStop( pGia );
+ Vec_IntFree( vPisNew );
+ if ( vRefine == NULL ) // real CEX
+ {
+ Abc_CexFree( pCex ); // return CEX in the future
+ Pdr_ManStop( pPdr );
+ Aig_ManStop( pAig );
+ break;
+ }
+
+ // spurious CEX, continue solving
+ vClauses = IPdr_ManSaveClauses( pPdr, 0 );
+
+ Pdr_ManStop( pPdr );
+
+ // update the set of objects to be un-abstracted
+ nNodes = Wlc_NtkRemoveFromAbstraction( p, vRefine, vUnmark );
+ if ( pPars->fVerbose )
+ printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs, whose MFFCs include %d objects.\n", pCex->iFrame, Vec_IntSize(vRefine), nNodes );
+ Vec_IntFree( vRefine );
+ Abc_CexFree( pCex );
+ Aig_ManStop( pAig );
}
- // update each PO to point to the new node
- Wlc_NtkForEachPo( p, pObj, i )
+
+ Vec_IntFreeP( &vFfOld );
+ Vec_BitFree( vUnmark );
+ // report the result
+ if ( pPars->fVerbose )
+ printf( "\n" );
+ printf( "Abstraction " );
+ if ( RetValue == 0 )
+ printf( "resulted in a real CEX" );
+ else if ( RetValue == 1 )
+ printf( "is successfully proved" );
+ else
+ printf( "timed out" );
+ printf( " after %d iterations. ", nIters );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs abstraction.]
+
+ Description [Derives initial abstraction based on user-specified
+ parameter values, which tell what is the smallest bit-width of a
+ primitive that is being abstracted away. Currently only add/sub,
+ mul/div, mux, and flop are supported with individual parameters.
+ The second step is to refine the initial abstraction until the
+ point when the property is proved.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars )
+{
+ abctime clk = Abc_Clock();
+ int nIters, nNodes, nDcFlops, RetValue = -1;
+ // start the bitmap to mark objects that cannot be abstracted because of refinement
+ // currently, this bitmap is empty because abstraction begins without refinement
+ Vec_Bit_t * vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(p) );
+ // set up parameters to run PDR
+ Pdr_Par_t PdrPars, * pPdrPars = &PdrPars;
+ Pdr_ManSetDefaultParams( pPdrPars );
+ //pPdrPars->fUseAbs = 1; // use 'pdr -t' (on-the-fly abstraction)
+ //pPdrPars->fCtgs = 1; // use 'pdr -nc' (improved generalization)
+ //pPdrPars->fSkipDown = 0; // use 'pdr -nc' (improved generalization)
+ //pPdrPars->nRestLimit = 500; // reset queue or proof-obligations when it gets larger than this
+ pPdrPars->fVerbose = pPars->fPdrVerbose;
+ pPdrPars->fVeryVerbose = 0;
+ // perform refinement iterations
+ for ( nIters = 1; nIters < pPars->nIterMax; nIters++ )
{
- iObj = Wlc_ObjId(p, pObj);
- Vec_IntFillTwo( vFanins, 2, iObj, iObjNew );
- iObjNew = Wlc_ObjCreate( p, WLC_OBJ_LOGIC_AND, 0, 0, 0, vFanins );
- // note that a pointer to Wlc_Obj_t (for example, pObj) can be invalidated after a call to
- // Wlc_ObjCreate() due to a possible realloc of the internal array of objects...
- pObj = Wlc_NtkObj( p, iObj );
- // update PO/CO arrays
- assert( Vec_IntEntry(&p->vPos, i) == iObj );
- assert( Vec_IntEntry(&p->vCos, i) == iObj );
- Vec_IntWriteEntry( &p->vPos, i, iObjNew );
- Vec_IntWriteEntry( &p->vCos, i, iObjNew );
- // transfer the PO attribute
- Wlc_NtkObj(p, iObjNew)->fIsPo = 1;
- assert( pObj->fIsPo );
- pObj->fIsPo = 0;
+ Aig_Man_t * pAig;
+ Abc_Cex_t * pCex;
+ Vec_Int_t * vPisNew, * vRefine;
+ Gia_Man_t * pGia, * pTemp;
+ Wlc_Ntk_t * pAbs;
+
+ if ( pPars->fVerbose )
+ printf( "\nIteration %d:\n", nIters );
+
+ // get abstracted GIA and the set of pseudo-PIs (vPisNew)
+ pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, NULL, pPars->fVerbose );
+ pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 );
+
+ // if the abstraction has flops with DC-init state,
+ // new PIs were introduced by bit-blasting at the end of the PI list
+ // here we move these variables to be *before* PPIs, because
+ // PPIs are supposed to be at the end of the PI list for refinement
+ nDcFlops = Wlc_NtkDcFlopNum(pAbs);
+ if ( nDcFlops > 0 ) // DC-init flops are present
+ {
+ pGia = Gia_ManPermuteInputs( pTemp = pGia, Wlc_NtkCountObjBits(p, vPisNew), nDcFlops );
+ Gia_ManStop( pTemp );
+ }
+ // if the word-level outputs have to be XORs, this is a place to do it
+ if ( pPars->fXorOutput )
+ {
+ pGia = Gia_ManTransformMiter2( pTemp = pGia );
+ Gia_ManStop( pTemp );
+ }
+ if ( pPars->fVerbose )
+ {
+ printf( "Derived abstraction with %d objects and %d PPIs. Bit-blasted AIG stats are:\n", Wlc_NtkObjNum(pAbs), Vec_IntSize(vPisNew) );
+ Gia_ManPrintStats( pGia, NULL );
+ }
+ Wlc_NtkFree( pAbs );
+
+ // try to prove abstracted GIA by converting it to AIG and calling PDR
+ pAig = Gia_ManToAigSimple( pGia );
+ RetValue = Pdr_ManSolve( pAig, pPdrPars );
+ pCex = pAig->pSeqModel; pAig->pSeqModel = NULL;
+ Aig_ManStop( pAig );
+
+ // consider outcomes
+ if ( pCex == NULL )
+ {
+ assert( RetValue ); // proved or undecided
+ Gia_ManStop( pGia );
+ Vec_IntFree( vPisNew );
+ break;
+ }
+
+ // perform refinement
+ vRefine = Wlc_NtkAbsRefinement( p, pGia, pCex, vPisNew );
+ Gia_ManStop( pGia );
+ Vec_IntFree( vPisNew );
+ if ( vRefine == NULL ) // real CEX
+ {
+ Abc_CexFree( pCex ); // return CEX in the future
+ break;
+ }
+
+ // update the set of objects to be un-abstracted
+ nNodes = Wlc_NtkRemoveFromAbstraction( p, vRefine, vUnmark );
+ if ( pPars->fVerbose )
+ printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs, whose MFFCs include %d objects.\n", pCex->iFrame, Vec_IntSize(vRefine), nNodes );
+ Vec_IntFree( vRefine );
+ Abc_CexFree( pCex );
}
- // cleanup
- Vec_IntFree( vUifConstrs );
- Vec_IntFree( vCompares );
- Vec_IntFree( vFanins );
- if ( vPairs != vPairsInit )
- Vec_IntFree( vPairs );
- // reconstruct topological order
- pNew = Wlc_NtkDupDfs( p );
- Wlc_NtkTransferNames( pNew, p );
- return pNew;
+ Vec_BitFree( vUnmark );
+ // report the result
+ if ( pPars->fVerbose )
+ printf( "\n" );
+ printf( "Abstraction " );
+ if ( RetValue == 0 )
+ printf( "resulted in a real CEX" );
+ else if ( RetValue == 1 )
+ printf( "is successfully proved" );
+ else
+ printf( "timed out" );
+ printf( " after %d iterations. ", nIters );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ return RetValue;
}
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/wlc/wlcAbs2.c b/src/base/wlc/wlcAbs2.c
new file mode 100644
index 00000000..9bccdf62
--- /dev/null
+++ b/src/base/wlc/wlcAbs2.c
@@ -0,0 +1,410 @@
+/**CFile****************************************************************
+
+ FileName [wlcAbs2.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Verilog parser.]
+
+ Synopsis [Abstraction for word-level networks.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - August 22, 2014.]
+
+ Revision [$Id: wlcAbs2.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "wlc.h"
+#include "proof/pdr/pdr.h"
+#include "aig/gia/giaAig.h"
+#include "sat/bmc/bmc.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Mark operators that meet the abstraction criteria.]
+
+ Description [This procedure returns the array of objects (vLeaves) that
+ should be abstracted because of their high bit-width. It uses input array (vUnmark)
+ to not abstract those objects that have been refined in the previous rounds.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose )
+{
+ Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) );
+ Wlc_Obj_t * pObj; int i, Count[4] = {0};
+ Wlc_NtkForEachObj( p, pObj, i )
+ {
+ if ( vUnmark && Vec_BitEntry(vUnmark, i) ) // not allow this object to be abstracted away
+ continue;
+ if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || pObj->Type == WLC_OBJ_ARI_MINUS )
+ {
+ if ( Wlc_ObjRange(pObj) >= pPars->nBitsAdd )
+ Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[0]++;
+ continue;
+ }
+ if ( pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_DIVIDE || pObj->Type == WLC_OBJ_ARI_REM || pObj->Type == WLC_OBJ_ARI_MODULUS )
+ {
+ if ( Wlc_ObjRange(pObj) >= pPars->nBitsMul )
+ Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[1]++;
+ continue;
+ }
+ if ( pObj->Type == WLC_OBJ_MUX )
+ {
+ if ( Wlc_ObjRange(pObj) >= pPars->nBitsMux )
+ Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[2]++;
+ continue;
+ }
+ if ( Wlc_ObjIsCi(pObj) && !Wlc_ObjIsPi(pObj) )
+ {
+ if ( Wlc_ObjRange(pObj) >= pPars->nBitsFlop )
+ Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[3]++;
+ continue;
+ }
+ }
+ if ( fVerbose )
+ printf( "Abstraction engine marked %d adds/subs, %d muls/divs, %d muxes, and %d flops to be abstracted away.\n", Count[0], Count[1], Count[2], Count[3] );
+ return vLeaves;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Marks nodes to be included in the abstracted network.]
+
+ Description [Marks all objects that will be included in the abstracted model.
+ Stops at the objects (vLeaves) that are abstracted away. Returns three arrays:
+ a subset of original PIs (vPisOld), a subset of pseudo-PIs (vPisNew) and the
+ set of flops present as flops in the abstracted network.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops )
+{
+ int i, iFanin;
+ if ( pObj->Mark )
+ return;
+ pObj->Mark = 1;
+ if ( Vec_BitEntry(vLeaves, Wlc_ObjId(p, pObj)) )
+ {
+ assert( !Wlc_ObjIsPi(pObj) );
+ Vec_IntPush( vPisNew, Wlc_ObjId(p, pObj) );
+ return;
+ }
+ if ( Wlc_ObjIsCi(pObj) )
+ {
+ if ( Wlc_ObjIsPi(pObj) )
+ Vec_IntPush( vPisOld, Wlc_ObjId(p, pObj) );
+ else
+ Vec_IntPush( vFlops, Wlc_ObjId(p, pObj) );
+ return;
+ }
+ Wlc_ObjForEachFanin( pObj, iFanin, i )
+ Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkObj(p, iFanin), vLeaves, vPisOld, vPisNew, vFlops );
+}
+static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops )
+{
+ Wlc_Obj_t * pObj;
+ int i, Count = 0;
+ Wlc_NtkCleanMarks( p );
+ Wlc_NtkForEachCo( p, pObj, i )
+ Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vPisOld, vPisNew, vFlops );
+ Wlc_NtkForEachObjVec( vFlops, p, pObj, i )
+ Wlc_NtkAbsMarkNodes_rec( p, Wlc_ObjFo2Fi(p, pObj), vLeaves, vPisOld, vPisNew, vFlops );
+ Wlc_NtkForEachObj( p, pObj, i )
+ Count += pObj->Mark;
+// printf( "Collected %d old PIs, %d new PIs, %d flops, and %d other objects.\n",
+// Vec_IntSize(vPisOld), Vec_IntSize(vPisNew), Vec_IntSize(vFlops),
+// Count - Vec_IntSize(vPisOld) - Vec_IntSize(vPisNew) - Vec_IntSize(vFlops) );
+ Vec_IntSort( vPisOld, 0 );
+ Vec_IntSort( vPisNew, 0 );
+ Vec_IntSort( vFlops, 0 );
+ Wlc_NtkCleanMarks( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derive word-level abstracted model based on the parameter values.]
+
+ Description [Retuns the word-level abstracted network and the set of pseudo-PIs
+ (vPisNew), which were created during abstraction. If the abstraction is
+ satisfiable, some of the pseudo-PIs will be un-abstracted. These pseudo-PIs
+ and their MFFC cones will be listed in the array (vUnmark), which will
+ force the abstraction to not stop at these pseudo-PIs in the future.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose )
+{
+ Wlc_Ntk_t * pNtkNew = NULL;
+ Vec_Int_t * vPisOld = Vec_IntAlloc( 100 );
+ Vec_Int_t * vPisNew = Vec_IntAlloc( 100 );
+ Vec_Int_t * vFlops = Vec_IntAlloc( 100 );
+ Vec_Bit_t * vLeaves = Wlc_NtkAbsMarkOpers( p, pPars, vUnmark, fVerbose );
+ Wlc_NtkAbsMarkNodes( p, vLeaves, vPisOld, vPisNew, vFlops );
+ Vec_BitFree( vLeaves );
+ pNtkNew = Wlc_NtkDupDfsAbs( p, vPisOld, vPisNew, vFlops );
+ Vec_IntFree( vPisOld );
+ Vec_IntFree( vFlops );
+ if ( pvPisNew )
+ *pvPisNew = vPisNew;
+ else
+ Vec_IntFree( vPisNew );
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find what objects need to be un-abstracted.]
+
+ Description [Returns a subset of pseudo-PIs (vPisNew), which will be
+ prevented from being abstracted in the future rounds of abstraction.
+ The AIG manager (pGia) is a bit-level view of the abstracted model.
+ The counter-example (pCex) is used to find waht PPIs to refine.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static Vec_Int_t * Wlc_NtkAbsRefinement( Wlc_Ntk_t * p, Gia_Man_t * pGia, Abc_Cex_t * pCex, Vec_Int_t * vPisNew )
+{
+ Vec_Int_t * vRefine = Vec_IntAlloc( 100 );
+ Abc_Cex_t * pCexCare;
+ Wlc_Obj_t * pObj;
+ // count the number of bit-level PPIs and map them into word-level objects they were derived from
+ int f, i, b, nRealPis, nPpiBits = 0;
+ Vec_Int_t * vMap = Vec_IntStartFull( pCex->nPis );
+ Wlc_NtkForEachObjVec( vPisNew, p, pObj, i )
+ for ( b = 0; b < Wlc_ObjRange(pObj); b++ )
+ Vec_IntWriteEntry( vMap, nPpiBits++, Wlc_ObjId(p, pObj) );
+ // since PPIs are ordered last, the previous bits are real PIs
+ nRealPis = pCex->nPis - nPpiBits;
+ // find the care-set
+ pCexCare = Bmc_CexCareMinimizeAig( pGia, nRealPis, pCex, 1, 0, 0 );
+ assert( pCexCare->nPis == pCex->nPis );
+ // detect care PPIs
+ for ( f = 0; f <= pCexCare->iFrame; f++ )
+ for ( i = nRealPis; i < pCexCare->nPis; i++ )
+ if ( Abc_InfoHasBit(pCexCare->pData, pCexCare->nRegs + pCexCare->nPis * f + i) )
+ Vec_IntPushUniqueOrder( vRefine, Vec_IntEntry(vMap, i-nRealPis) );
+ Abc_CexFree( pCexCare );
+ Vec_IntFree( vMap );
+ if ( Vec_IntSize(vRefine) == 0 )// real CEX
+ Vec_IntFreeP( &vRefine );
+ return vRefine;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Mark MFFC cones of the un-abstracted objects.]
+
+ Description [The MFFC cones of the objects in vRefine are traversed
+ and all their nodes are marked in vUnmark.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int Wlc_NtkNodeDeref_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark )
+{
+ int i, Fanin, Counter = 1;
+ if ( Wlc_ObjIsCi(pNode) )
+ return 0;
+ Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 );
+ Wlc_ObjForEachFanin( pNode, Fanin, i )
+ {
+ Vec_IntAddToEntry( &p->vRefs, Fanin, -1 );
+ if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 )
+ Counter += Wlc_NtkNodeDeref_rec( p, Wlc_NtkObj(p, Fanin), vUnmark );
+ }
+ return Counter;
+}
+static int Wlc_NtkNodeRef_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode )
+{
+ int i, Fanin, Counter = 1;
+ if ( Wlc_ObjIsCi(pNode) )
+ return 0;
+ Wlc_ObjForEachFanin( pNode, Fanin, i )
+ {
+ if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 )
+ Counter += Wlc_NtkNodeRef_rec( p, Wlc_NtkObj(p, Fanin) );
+ Vec_IntAddToEntry( &p->vRefs, Fanin, 1 );
+ }
+ return Counter;
+}
+static int Wlc_NtkMarkMffc( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark )
+{
+ int Count1, Count2;
+ // if this is a flop output, compute MFFC of the corresponding flop input
+ while ( Wlc_ObjIsCi(pNode) )
+ {
+ Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 );
+ pNode = Wlc_ObjFo2Fi(p, pNode);
+ }
+ assert( !Wlc_ObjIsCi(pNode) );
+ // dereference the node (and set the bits in vUnmark)
+ Count1 = Wlc_NtkNodeDeref_rec( p, pNode, vUnmark );
+ // reference it back
+ Count2 = Wlc_NtkNodeRef_rec( p, pNode );
+ assert( Count1 == Count2 );
+ return Count1;
+}
+static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec_Bit_t * vUnmark )
+{
+ Wlc_Obj_t * pObj; int i, nNodes = 0;
+ if ( Vec_IntSize(&p->vRefs) == 0 )
+ Wlc_NtkSetRefs( p );
+ Wlc_NtkForEachObjVec( vRefine, p, pObj, i )
+ nNodes += Wlc_NtkMarkMffc( p, pObj, vUnmark );
+ return nNodes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs abstraction.]
+
+ Description [Derives initial abstraction based on user-specified
+ parameter values, which tell what is the smallest bit-width of a
+ primitive that is being abstracted away. Currently only add/sub,
+ mul/div, mux, and flop are supported with individual parameters.
+ The second step is to refine the initial abstraction until the
+ point when the property is proved.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Wlc_NtkAbsCore2( Wlc_Ntk_t * p, Wlc_Par_t * pPars )
+{
+ abctime clk = Abc_Clock();
+ int nIters, nNodes, nDcFlops, RetValue = -1;
+ // start the bitmap to mark objects that cannot be abstracted because of refinement
+ // currently, this bitmap is empty because abstraction begins without refinement
+ Vec_Bit_t * vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(p) );
+ // set up parameters to run PDR
+ Pdr_Par_t PdrPars, * pPdrPars = &PdrPars;
+ Pdr_ManSetDefaultParams( pPdrPars );
+ pPdrPars->fUseAbs = 1; // use 'pdr -t' (on-the-fly abstraction)
+ pPdrPars->fCtgs = 1; // use 'pdr -nc' (improved generalization)
+ pPdrPars->fSkipDown = 0; // use 'pdr -nc' (improved generalization)
+ //pPdrPars->nRestLimit = 500; // reset queue or proof-obligations when it gets larger than this
+ pPdrPars->fVerbose = pPars->fPdrVerbose;
+ // perform refinement iterations
+ for ( nIters = 1; nIters < pPars->nIterMax; nIters++ )
+ {
+ Aig_Man_t * pAig;
+ Abc_Cex_t * pCex;
+ Vec_Int_t * vPisNew, * vRefine;
+ Gia_Man_t * pGia, * pTemp;
+ Wlc_Ntk_t * pAbs;
+
+ if ( pPars->fVerbose )
+ printf( "\nIteration %d:\n", nIters );
+
+ // get abstracted GIA and the set of pseudo-PIs (vPisNew)
+ pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, pPars->fVerbose );
+ pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 );
+
+ // if the abstraction has flops with DC-init state,
+ // new PIs were introduced by bit-blasting at the end of the PI list
+ // here we move these variables to be *before* PPIs, because
+ // PPIs are supposed to be at the end of the PI list for refinement
+ nDcFlops = Wlc_NtkDcFlopNum(pAbs);
+ if ( nDcFlops > 0 ) // DC-init flops are present
+ {
+ pGia = Gia_ManPermuteInputs( pTemp = pGia, Wlc_NtkCountObjBits(p, vPisNew), nDcFlops );
+ Gia_ManStop( pTemp );
+ }
+ // if the word-level outputs have to be XORs, this is a place to do it
+ if ( pPars->fXorOutput )
+ {
+ pGia = Gia_ManTransformMiter2( pTemp = pGia );
+ Gia_ManStop( pTemp );
+ }
+ if ( pPars->fVerbose )
+ {
+ printf( "Derived abstraction with %d objects and %d PPIs. Bit-blasted AIG stats are:\n", Wlc_NtkObjNum(pAbs), Vec_IntSize(vPisNew) );
+ Gia_ManPrintStats( pGia, NULL );
+ }
+ Wlc_NtkFree( pAbs );
+
+ // try to prove abstracted GIA by converting it to AIG and calling PDR
+ pAig = Gia_ManToAigSimple( pGia );
+ RetValue = Pdr_ManSolve( pAig, pPdrPars );
+ pCex = pAig->pSeqModel; pAig->pSeqModel = NULL;
+ Aig_ManStop( pAig );
+
+ // consider outcomes
+ if ( pCex == NULL )
+ {
+ assert( RetValue ); // proved or undecided
+ Gia_ManStop( pGia );
+ Vec_IntFree( vPisNew );
+ break;
+ }
+
+ // perform refinement
+ vRefine = Wlc_NtkAbsRefinement( p, pGia, pCex, vPisNew );
+ Gia_ManStop( pGia );
+ Vec_IntFree( vPisNew );
+ if ( vRefine == NULL ) // real CEX
+ {
+ Abc_CexFree( pCex ); // return CEX in the future
+ break;
+ }
+
+ // update the set of objects to be un-abstracted
+ nNodes = Wlc_NtkRemoveFromAbstraction( p, vRefine, vUnmark );
+ if ( pPars->fVerbose )
+ printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs, whose MFFCs include %d objects.\n", pCex->iFrame, Vec_IntSize(vRefine), nNodes );
+ Vec_IntFree( vRefine );
+ Abc_CexFree( pCex );
+ }
+ Vec_BitFree( vUnmark );
+ // report the result
+ if ( pPars->fVerbose )
+ printf( "\n" );
+ printf( "Abstraction " );
+ if ( RetValue == 0 )
+ printf( "resulted in a real CEX" );
+ else if ( RetValue == 1 )
+ printf( "is successfully proved" );
+ else
+ printf( "timed out" );
+ printf( " after %d iterations. ", nIters );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ return RetValue;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c
index ec3b040d..f4de8ee6 100644
--- a/src/base/wlc/wlcBlast.c
+++ b/src/base/wlc/wlcBlast.c
@@ -643,6 +643,41 @@ void Wlc_IntInsert( Vec_Int_t * vProd, Vec_Int_t * vLevel, int Node, int Level )
Vec_IntInsert( vProd, i + 1, Node );
Vec_IntInsert( vLevel, i + 1, Level );
}
+void Wlc_BlastPrintMatrix( Gia_Man_t * p, Vec_Wec_t * vProds )
+{
+ int fVerbose = 0;
+ Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
+ Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vLevel; word Truth;
+ int i, k, iLit;
+ Vec_WecForEachLevel( vProds, vLevel, i )
+ Vec_IntForEachEntry( vLevel, iLit, k )
+ if ( Gia_ObjIsAnd(Gia_ManObj(p, Abc_Lit2Var(iLit))) )
+ Vec_IntPushUnique( vSupp, Abc_Lit2Var(iLit) );
+ printf( "Booth partial products: %d pps, %d unique, %d nodes.\n",
+ Vec_WecSizeSize(vProds), Vec_IntSize(vSupp), Gia_ManAndNum(p) );
+ Vec_IntPrint( vSupp );
+
+ if ( fVerbose )
+ Vec_WecForEachLevel( vProds, vLevel, i )
+ Vec_IntForEachEntry( vLevel, iLit, k )
+ {
+ printf( "Obj = %4d : ", Abc_Lit2Var(iLit) );
+ printf( "Compl = %d ", Abc_LitIsCompl(iLit) );
+ printf( "Rank = %2d ", i );
+ Truth = Gia_ObjComputeTruth6Cis( p, iLit, vSupp, vTemp );
+ Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) );
+ if ( Vec_IntSize(vSupp) == 4 ) printf( " " );
+ if ( Vec_IntSize(vSupp) == 3 ) printf( " " );
+ if ( Vec_IntSize(vSupp) <= 2 ) printf( " " );
+ printf( " " );
+ Vec_IntPrint( vSupp );
+ if ( k == Vec_IntSize(vLevel)-1 )
+ printf( "\n" );
+ }
+ Vec_IntFree( vSupp );
+ Vec_WrdFree( vTemp );
+}
void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vLevels, Vec_Int_t * vRes )
{
Vec_Int_t * vLevel, * vProd;
@@ -812,6 +847,7 @@ void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int
Vec_WecPush( vLevels, k, 0 );
}
//Vec_WecPrint( vProds, 0 );
+ //Wlc_BlastPrintMatrix( pNew, vProds );
//printf( "Cutoff ID for partial products = %d.\n", Gia_ManObjNum(pNew) );
Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes );
@@ -836,6 +872,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
{
int fVerbose = 0;
int fUseOldMultiplierBlasting = 0;
+ int fSkipBitRange = 0;
Tim_Man_t * pManTime = NULL;
Gia_Man_t * pTemp, * pNew, * pExtra = NULL;
Wlc_Obj_t * pObj;
@@ -1381,7 +1418,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
}
else
{
- pNew = Gia_ManDupZeroUndc( pTemp = pNew, p->pInits, fGiaSimple, 1 );
+ pNew = Gia_ManDupZeroUndc( pTemp = pNew, p->pInits, fGiaSimple, 0 );
Gia_ManDupRemapLiterals( vBits, pTemp );
Gia_ManStop( pTemp );
}
@@ -1412,7 +1449,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
{
char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
nRange = Wlc_ObjRange( pObj );
- if ( nRange == 1 )
+ if ( fSkipBitRange && nRange == 1 )
Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(pName) );
else
for ( k = 0; k < nRange; k++ )
@@ -1439,7 +1476,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
{
char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
nRange = Wlc_ObjRange( pObj );
- if ( nRange == 1 )
+ if ( fSkipBitRange && nRange == 1 )
Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(pName) );
else
for ( k = 0; k < nRange; k++ )
@@ -1462,7 +1499,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
{
char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
nRange = Wlc_ObjRange( pObj );
- if ( nRange == 1 )
+ if ( fSkipBitRange && nRange == 1 )
Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) );
else
for ( k = 0; k < nRange; k++ )
@@ -1477,7 +1514,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
{
char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
nRange = Wlc_ObjRange( pObj );
- if ( nRange == 1 )
+ if ( fSkipBitRange && nRange == 1 )
Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) );
else
for ( k = 0; k < nRange; k++ )
@@ -1496,7 +1533,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
{
char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
nRange = Wlc_ObjRange( pObj );
- if ( nRange == 1 )
+ if ( fSkipBitRange && nRange == 1 )
Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) );
else
for ( k = 0; k < nRange; k++ )
@@ -1509,7 +1546,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
assert( Vec_PtrSize(pNew->vNamesOut) == Gia_ManCoNum(pNew) );
}
- pNew->pSpec = Abc_UtilStrsav( p->pSpec ? p->pSpec : p->pName );
+ //pNew->pSpec = Abc_UtilStrsav( p->pSpec ? p->pSpec : p->pName );
// dump the miter parts
if ( 0 )
{
diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c
index f3eb6dd7..df736e70 100644
--- a/src/base/wlc/wlcCom.c
+++ b/src/base/wlc/wlcCom.c
@@ -28,22 +28,31 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-static int Abc_CommandReadWlc ( Abc_Frame_t * pAbc, int argc, char ** argv );
-static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv );
-static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv );
-static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv );
-static int Abc_CommandPsInv ( Abc_Frame_t * pAbc, int argc, char ** argv );
-static int Abc_CommandGetInv ( Abc_Frame_t * pAbc, int argc, char ** argv );
-static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv );
-static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandReadWlc ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbs ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandPdrAbs ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbs2 ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandShortNames ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandShow ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
+static int Abc_CommandInvPs ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandInvPrint ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandInvCheck ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandInvGet ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandInvPut ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandInvMin ( Abc_Frame_t * pAbc, int argc, char ** argv );
static inline Wlc_Ntk_t * Wlc_AbcGetNtk( Abc_Frame_t * pAbc ) { return (Wlc_Ntk_t *)pAbc->pAbcWlc; }
static inline void Wlc_AbcFreeNtk( Abc_Frame_t * pAbc ) { if ( pAbc->pAbcWlc ) Wlc_NtkFree(Wlc_AbcGetNtk(pAbc)); }
static inline void Wlc_AbcUpdateNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk ) { Wlc_AbcFreeNtk(pAbc); pAbc->pAbcWlc = pNtk; }
static inline Vec_Int_t * Wlc_AbcGetInv( Abc_Frame_t * pAbc ) { return pAbc->pAbcWlcInv; }
-static inline Vec_Int_t * Wlc_AbcGetCnf( Abc_Frame_t * pAbc ) { return pAbc->pAbcWlcCnf; }
-static inline Vec_Str_t * Wlc_AbcGetStr( Abc_Frame_t * pAbc ) { return pAbc->pAbcWlcStr; }
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@@ -62,14 +71,25 @@ static inline Vec_Str_t * Wlc_AbcGetStr( Abc_Frame_t * pAbc )
******************************************************************************/
void Wlc_Init( Abc_Frame_t * pAbc )
{
- Cmd_CommandAdd( pAbc, "Word level", "%read", Abc_CommandReadWlc, 0 );
- Cmd_CommandAdd( pAbc, "Word level", "%write", Abc_CommandWriteWlc, 0 );
- Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 );
- Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 );
- Cmd_CommandAdd( pAbc, "Word level", "%psinv", Abc_CommandPsInv, 0 );
- Cmd_CommandAdd( pAbc, "Word level", "%getinv", Abc_CommandGetInv, 0 );
- Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 );
- Cmd_CommandAdd( pAbc, "Word level", "%test", Abc_CommandTest, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%read", Abc_CommandReadWlc, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%write", Abc_CommandWriteWlc, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%cone", Abc_CommandCone, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%abs", Abc_CommandAbs, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%pdra", Abc_CommandPdrAbs, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%abs2", Abc_CommandAbs2, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%short_names", Abc_CommandShortNames, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%show", Abc_CommandShow, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%test", Abc_CommandTest, 0 );
+
+ Cmd_CommandAdd( pAbc, "Word level", "inv_ps", Abc_CommandInvPs, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "inv_print", Abc_CommandInvPrint, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "inv_check", Abc_CommandInvCheck, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "inv_get", Abc_CommandInvGet, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "inv_put", Abc_CommandInvPut, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "inv_min", Abc_CommandInvMin, 0 );
}
/**Function********************************************************************
@@ -275,15 +295,20 @@ usage:
int Abc_CommandPs( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
+ int fShowCones = 0;
int fShowMulti = 0;
int fShowAdder = 0;
int fDistrib = 0;
+ int fTwoSides = 0;
int c, fVerbose = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "madvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "cmadtvh" ) ) != EOF )
{
switch ( c )
{
+ case 'c':
+ fShowCones ^= 1;
+ break;
case 'm':
fShowMulti ^= 1;
break;
@@ -293,6 +318,9 @@ int Abc_CommandPs( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'd':
fDistrib ^= 1;
break;
+ case 't':
+ fTwoSides ^= 1;
+ break;
case 'v':
fVerbose ^= 1;
break;
@@ -307,18 +335,110 @@ int Abc_CommandPs( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( 1, "Abc_CommandPs(): There is no current design.\n" );
return 0;
}
- Wlc_NtkPrintStats( pNtk, fDistrib, fVerbose );
+ Wlc_NtkPrintStats( pNtk, fDistrib, fTwoSides, fVerbose );
+ if ( fShowCones )
+ Wlc_NtkProfileCones( pNtk );
if ( fShowMulti )
Wlc_NtkPrintNodes( pNtk, WLC_OBJ_ARI_MULTI );
if ( fShowAdder )
Wlc_NtkPrintNodes( pNtk, WLC_OBJ_ARI_ADD );
return 0;
usage:
- Abc_Print( -2, "usage: %%ps [-madvh]\n" );
+ Abc_Print( -2, "usage: %%ps [-cmadtvh]\n" );
Abc_Print( -2, "\t prints statistics\n" );
- Abc_Print( -2, "\t-m : toggle printing multipliers [default = %s]\n", fShowMulti? "yes": "no" );
- Abc_Print( -2, "\t-a : toggle printing adders [default = %s]\n", fShowAdder? "yes": "no" );
- Abc_Print( -2, "\t-d : toggle printing distrubition [default = %s]\n", fDistrib? "yes": "no" );
+ Abc_Print( -2, "\t-c : toggle printing cones [default = %s]\n", fShowCones? "yes": "no" );
+ Abc_Print( -2, "\t-m : toggle printing multipliers [default = %s]\n", fShowMulti? "yes": "no" );
+ Abc_Print( -2, "\t-a : toggle printing adders [default = %s]\n", fShowAdder? "yes": "no" );
+ Abc_Print( -2, "\t-d : toggle printing distrubition [default = %s]\n", fDistrib? "yes": "no" );
+ Abc_Print( -2, "\t-t : toggle printing stats for LHS and RHS [default = %s]\n", fTwoSides? "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;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
+ int c, iOutput = -1, Range = 1, fAllPis = 0, fSeq = 0, fVerbose = 0;
+ char * pName;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ORisvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'O':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ iOutput = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( iOutput < 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;
+ }
+ Range = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( Range < 0 )
+ goto usage;
+ break;
+ case 'i':
+ fAllPis ^= 1;
+ break;
+ case 's':
+ fSeq ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pNtk == NULL )
+ {
+ Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" );
+ return 0;
+ }
+ if ( iOutput < 0 || iOutput >= Wlc_NtkCoNum(pNtk) )
+ {
+ Abc_Print( 1, "Abc_CommandCone(): Illegal output index (%d) (should be 0 <= num < %d).\n", iOutput, Wlc_NtkCoNum(pNtk) );
+ return 0;
+ }
+ printf( "Extracting output %d as a %s word-level network.\n", iOutput, fSeq ? "sequential" : "combinational" );
+ pName = Wlc_NtkNewName( pNtk, iOutput, fSeq );
+ Wlc_NtkMarkCone( pNtk, iOutput, Range, fSeq, fAllPis );
+ pNtk = Wlc_NtkDupDfs( pNtk, 1, fSeq );
+ ABC_FREE( pNtk->pName );
+ pNtk->pName = Abc_UtilStrsav( pName );
+ Wlc_AbcUpdateNtk( pAbc, pNtk );
+ return 0;
+usage:
+ Abc_Print( -2, "usage: %%cone [-OR num] [-isvh]\n" );
+ Abc_Print( -2, "\t extracts logic cone of one or more word-level outputs\n" );
+ Abc_Print( -2, "\t-O num : zero-based index of the first word-level output to extract [default = %d]\n", iOutput );
+ Abc_Print( -2, "\t-R num : total number of word-level outputs to extract [default = %d]\n", Range );
+ Abc_Print( -2, "\t-i : toggle using support composed of all primary inputs [default = %s]\n", fAllPis? "yes": "no" );
+ Abc_Print( -2, "\t-s : toggle performing extracting sequential cones [default = %s]\n", fSeq? "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;
@@ -335,6 +455,357 @@ usage:
SeeAlso []
******************************************************************************/
+int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
+ Wlc_Par_t Pars, * pPars = &Pars;
+ int c;
+ Wlc_ManSetDefaultParams( pPars );
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIcpxvwh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'A':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-A\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nBitsAdd = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBitsAdd < 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;
+ }
+ pPars->nBitsMul = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBitsMul < 0 )
+ goto usage;
+ break;
+ case 'X':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nBitsMux = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBitsMux < 0 )
+ goto usage;
+ break;
+ case 'F':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nBitsFlop = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBitsFlop < 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;
+ }
+ pPars->nIterMax = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nIterMax < 0 )
+ goto usage;
+ break;
+ case 'x':
+ pPars->fXorOutput ^= 1;
+ break;
+ case 'c':
+ pPars->fCheckClauses ^= 1;
+ break;
+ case 'p':
+ pPars->fPushClauses ^= 1;
+ break;
+ case 'v':
+ pPars->fVerbose ^= 1;
+ break;
+ case 'w':
+ pPars->fPdrVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pNtk == NULL )
+ {
+ Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" );
+ return 0;
+ }
+ Wlc_NtkPdrAbs( pNtk, pPars );
+ return 0;
+usage:
+ Abc_Print( -2, "usage: %%pdra [-AMXFI num] [-cpxvwh]\n" );
+ Abc_Print( -2, "\t abstraction for word-level networks\n" );
+ Abc_Print( -2, "\t-A num : minimum bit-width of an adder/subtractor to abstract [default = %d]\n", pPars->nBitsAdd );
+ Abc_Print( -2, "\t-M num : minimum bit-width of a multiplier to abstract [default = %d]\n", pPars->nBitsMul );
+ Abc_Print( -2, "\t-X num : minimum bit-width of a MUX operator to abstract [default = %d]\n", pPars->nBitsMux );
+ Abc_Print( -2, "\t-F num : minimum bit-width of a flip-flop to abstract [default = %d]\n", pPars->nBitsFlop );
+ Abc_Print( -2, "\t-I num : maximum number of CEGAR iterations [default = %d]\n", pPars->nIterMax );
+ Abc_Print( -2, "\t-x : toggle XORing outputs of word-level miter [default = %s]\n", pPars->fXorOutput? "yes": "no" );
+ Abc_Print( -2, "\t-c : toggle checking clauses in the reloaded trace [default = %s]\n", pPars->fCheckClauses? "yes": "no" );
+ Abc_Print( -2, "\t-p : toggle pushing clauses in the reloaded trace [default = %s]\n", pPars->fPushClauses? "yes": "no" );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-w : toggle printing verbose PDR output [default = %s]\n", pPars->fPdrVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int Abc_CommandAbs( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
+ Wlc_Par_t Pars, * pPars = &Pars;
+ int c;
+ Wlc_ManSetDefaultParams( pPars );
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIxvwh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'A':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-A\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nBitsAdd = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBitsAdd < 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;
+ }
+ pPars->nBitsMul = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBitsMul < 0 )
+ goto usage;
+ break;
+ case 'X':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nBitsMux = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBitsMux < 0 )
+ goto usage;
+ break;
+ case 'F':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nBitsFlop = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBitsFlop < 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;
+ }
+ pPars->nIterMax = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nIterMax < 0 )
+ goto usage;
+ break;
+ case 'x':
+ pPars->fXorOutput ^= 1;
+ break;
+ case 'v':
+ pPars->fVerbose ^= 1;
+ break;
+ case 'w':
+ pPars->fPdrVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pNtk == NULL )
+ {
+ Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" );
+ return 0;
+ }
+ Wlc_NtkAbsCore( pNtk, pPars );
+ return 0;
+usage:
+ Abc_Print( -2, "usage: %%abs [-AMXFI num] [-xvwh]\n" );
+ Abc_Print( -2, "\t abstraction for word-level networks\n" );
+ Abc_Print( -2, "\t-A num : minimum bit-width of an adder/subtractor to abstract [default = %d]\n", pPars->nBitsAdd );
+ Abc_Print( -2, "\t-M num : minimum bit-width of a multiplier to abstract [default = %d]\n", pPars->nBitsMul );
+ Abc_Print( -2, "\t-X num : minimum bit-width of a MUX operator to abstract [default = %d]\n", pPars->nBitsMux );
+ Abc_Print( -2, "\t-F num : minimum bit-width of a flip-flop to abstract [default = %d]\n", pPars->nBitsFlop );
+ Abc_Print( -2, "\t-I num : maximum number of CEGAR iterations [default = %d]\n", pPars->nIterMax );
+ Abc_Print( -2, "\t-x : toggle XORing outputs of word-level miter [default = %s]\n", pPars->fXorOutput? "yes": "no" );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-w : toggle printing verbose PDR output [default = %s]\n", pPars->fPdrVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int Abc_CommandAbs2( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
+ Wlc_Par_t Pars, * pPars = &Pars;
+ int c;
+ Wlc_ManSetDefaultParams( pPars );
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIxvwh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'A':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-A\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nBitsAdd = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBitsAdd < 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;
+ }
+ pPars->nBitsMul = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBitsMul < 0 )
+ goto usage;
+ break;
+ case 'X':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nBitsMux = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBitsMux < 0 )
+ goto usage;
+ break;
+ case 'F':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nBitsFlop = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBitsFlop < 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;
+ }
+ pPars->nIterMax = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nIterMax < 0 )
+ goto usage;
+ break;
+ case 'x':
+ pPars->fXorOutput ^= 1;
+ break;
+ case 'v':
+ pPars->fVerbose ^= 1;
+ break;
+ case 'w':
+ pPars->fPdrVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pNtk == NULL )
+ {
+ Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" );
+ return 0;
+ }
+ Wlc_NtkAbsCore2( pNtk, pPars );
+ return 0;
+usage:
+ Abc_Print( -2, "usage: %%abs2 [-AMXFI num] [-xvwh]\n" );
+ Abc_Print( -2, "\t abstraction for word-level networks\n" );
+ Abc_Print( -2, "\t-A num : minimum bit-width of an adder/subtractor to abstract [default = %d]\n", pPars->nBitsAdd );
+ Abc_Print( -2, "\t-M num : minimum bit-width of a multiplier to abstract [default = %d]\n", pPars->nBitsMul );
+ Abc_Print( -2, "\t-X num : minimum bit-width of a MUX operator to abstract [default = %d]\n", pPars->nBitsMux );
+ Abc_Print( -2, "\t-F num : minimum bit-width of a flip-flop to abstract [default = %d]\n", pPars->nBitsFlop );
+ Abc_Print( -2, "\t-I num : maximum number of CEGAR iterations [default = %d]\n", pPars->nIterMax );
+ Abc_Print( -2, "\t-x : toggle XORing outputs of word-level miter [default = %s]\n", pPars->fXorOutput? "yes": "no" );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-w : toggle printing verbose PDR output [default = %s]\n", pPars->fPdrVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
@@ -440,10 +911,200 @@ usage:
SeeAlso []
******************************************************************************/
-int Abc_CommandPsInv( Abc_Frame_t * pAbc, int argc, char ** argv )
+int Abc_CommandProfile( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
+ 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 ( pNtk == NULL )
+ {
+ Abc_Print( 1, "Abc_CommandProfile(): There is no current design.\n" );
+ return 0;
+ }
+ Wlc_WinProfileArith( pNtk );
+ return 0;
+usage:
+ Abc_Print( -2, "usage: %%profile [-vh]\n" );
+ Abc_Print( -2, "\t profiles arithmetic components in the word-level networks\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_CommandShortNames( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
+ 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 ( pNtk == NULL )
+ {
+ Abc_Print( 1, "Abc_CommandProfile(): There is no current design.\n" );
+ return 0;
+ }
+ Wlc_NtkShortNames( pNtk );
+ return 0;
+usage:
+ Abc_Print( -2, "usage: %%short_names [-vh]\n" );
+ Abc_Print( -2, "\t derives short names for all objects of the network\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_CommandShow( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Wlc_NtkShow( Wlc_Ntk_t * p, Vec_Int_t * vBold );
+ Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
+ int c, fVerbose = 0;
+ // set defaults
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ default:
+ goto usage;
+ }
+ }
+ if ( pNtk == NULL )
+ {
+ Abc_Print( -1, "Empty network.\n" );
+ return 1;
+ }
+ Wlc_NtkShow( pNtk, NULL );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: %%show [-h]\n" );
+ Abc_Print( -2, " visualizes the network structure using DOT and GSVIEW\n" );
+#ifdef WIN32
+ Abc_Print( -2, " \"dot.exe\" and \"gsview32.exe\" should be set in the paths\n" );
+ Abc_Print( -2, " (\"gsview32.exe\" may be in \"C:\\Program Files\\Ghostgum\\gsview\\\")\n" );
+#endif
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Wlc_NtkSimulateTest( Wlc_Ntk_t * p );
+ Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
+ 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 ( pNtk == NULL )
+ {
+ Abc_Print( 1, "Abc_CommandTest(): There is no current design.\n" );
+ return 0;
+ }
+ // transform
+ //pNtk = Wlc_NtkUifNodePairs( pNtk, NULL );
+ //pNtk = Wlc_NtkAbstractNodes( pNtk, NULL );
+ //Wlc_AbcUpdateNtk( pAbc, pNtk );
+ //Wlc_GenerateSmtStdout( pAbc );
+ //Wlc_NtkSimulateTest( (Wlc_Ntk_t *)pAbc->pAbcWlc );
+ pNtk = Wlc_NtkDupSingleNodes( pNtk );
+ Wlc_AbcUpdateNtk( pAbc, pNtk );
+ return 0;
+usage:
+ Abc_Print( -2, "usage: %%test [-vh]\n" );
+ Abc_Print( -2, "\t experiments with word-level networks\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_CommandInvPs( Abc_Frame_t * pAbc, int argc, char ** argv )
{
+ extern Vec_Int_t * Pdr_InvCounts( Vec_Int_t * vInv );
extern void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose );
Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
+ Vec_Int_t * vCounts;
int c, fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
@@ -461,24 +1122,66 @@ int Abc_CommandPsInv( Abc_Frame_t * pAbc, int argc, char ** argv )
}
if ( pNtk == NULL )
{
- Abc_Print( 1, "Abc_CommandPsInv(): There is no current design.\n" );
+ Abc_Print( 1, "Abc_CommandInvPs(): There is no current design.\n" );
return 0;
}
- if ( Wlc_AbcGetNtk(pAbc) == NULL )
+ if ( Wlc_AbcGetInv(pAbc) == NULL )
{
- Abc_Print( 1, "Abc_CommandPsInv(): There is no saved invariant.\n" );
+ Abc_Print( 1, "Abc_CommandInvPs(): Invariant is not available.\n" );
return 0;
}
+ vCounts = Pdr_InvCounts( Wlc_AbcGetInv(pAbc) );
+ Wlc_NtkPrintInvStats( pNtk, vCounts, fVerbose );
+ Vec_IntFree( vCounts );
+ return 0;
+usage:
+ Abc_Print( -2, "usage: inv_ps [-vh]\n" );
+ Abc_Print( -2, "\t prints statistics for inductive invariant\n" );
+ Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\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_CommandInvPrint( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Pdr_InvPrint( Vec_Int_t * vInv, 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':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
if ( Wlc_AbcGetInv(pAbc) == NULL )
{
- Abc_Print( 1, "Abc_CommandPsInv(): Invariant is not available.\n" );
+ Abc_Print( 1, "Abc_CommandInvPs(): Invariant is not available.\n" );
return 0;
}
- Wlc_NtkPrintInvStats( pNtk, Wlc_AbcGetInv(pAbc), fVerbose );
+ Pdr_InvPrint( Wlc_AbcGetInv(pAbc), fVerbose );
return 0;
- usage:
- Abc_Print( -2, "usage: %%psinv [-vh]\n" );
- Abc_Print( -2, "\t prints statistics for inductive invariant\n" );
+usage:
+ Abc_Print( -2, "usage: inv_print [-vh]\n" );
+ Abc_Print( -2, "\t prints the current inductive invariant\n" );
Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\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");
@@ -496,12 +1199,11 @@ int Abc_CommandPsInv( Abc_Frame_t * pAbc, int argc, char ** argv )
SeeAlso []
******************************************************************************/
-int Abc_CommandGetInv( Abc_Frame_t * pAbc, int argc, char ** argv )
+int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- extern Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop, int fVerbose );
- Abc_Ntk_t * pMainNtk;
- Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
- int c, fVerbose = 0;
+ abctime clk = Abc_Clock();
+ extern int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose );
+ int c, nFailed, fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
{
@@ -516,28 +1218,81 @@ int Abc_CommandGetInv( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
}
}
- if ( pNtk == NULL )
+ if ( pAbc->pGia == NULL )
{
- Abc_Print( 1, "Abc_CommandGetInv(): There is no current design.\n" );
+ Abc_Print( 1, "Abc_CommandInvMin(): There is no current design.\n" );
return 0;
}
- if ( Wlc_AbcGetNtk(pAbc) == NULL )
+ if ( Wlc_AbcGetInv(pAbc) == NULL )
{
- Abc_Print( 1, "Abc_CommandGetInv(): There is no saved invariant.\n" );
+ Abc_Print( 1, "Abc_CommandInvMin(): There is no saved invariant.\n" );
return 0;
}
+ if ( Gia_ManRegNum(pAbc->pGia) != Vec_IntEntryLast(Wlc_AbcGetInv(pAbc)) )
+ {
+ Abc_Print( 1, "Abc_CommandInvMin(): The number of flops in the invariant and in GIA should be the same.\n" );
+ return 0;
+ }
+ nFailed = Pdr_InvCheck( pAbc->pGia, Wlc_AbcGetInv(pAbc), fVerbose );
+ if ( nFailed )
+ printf( "Invariant verification failed for %d clauses (out of %d). ", nFailed, Vec_IntEntry(Wlc_AbcGetInv(pAbc),0) );
+ else
+ printf( "Invariant verification succeeded. " );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ return 0;
+usage:
+ Abc_Print( -2, "usage: inv_check [-vh]\n" );
+ Abc_Print( -2, "\t checks that the invariant is indeed an inductive invariant\n" );
+ Abc_Print( -2, "\t (AIG representing the design should be in the &-space)\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_CommandInvGet( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv );
+ Abc_Ntk_t * pMainNtk;
+ Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
+ 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 ( Wlc_AbcGetInv(pAbc) == NULL )
{
- Abc_Print( 1, "Abc_CommandGetInv(): Invariant is not available.\n" );
+ Abc_Print( 1, "Abc_CommandInvGet(): Invariant is not available.\n" );
return 0;
}
// derive the network
- pMainNtk = Wlc_NtkGetInv( pNtk, Wlc_AbcGetInv(pAbc), Wlc_AbcGetStr(pAbc), fVerbose );
+ pMainNtk = Wlc_NtkGetInv( pNtk, Wlc_AbcGetInv(pAbc) );
// replace the current network
- Abc_FrameReplaceCurrentNetwork( pAbc, pMainNtk );
+ if ( pMainNtk )
+ Abc_FrameReplaceCurrentNetwork( pAbc, pMainNtk );
return 0;
- usage:
- Abc_Print( -2, "usage: %%getinv [-vh]\n" );
+usage:
+ Abc_Print( -2, "usage: inv_get [-vh]\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-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
@@ -556,34 +1311,45 @@ int Abc_CommandGetInv( Abc_Frame_t * pAbc, int argc, char ** argv )
SeeAlso []
******************************************************************************/
-int Abc_CommandProfile( Abc_Frame_t * pAbc, int argc, char ** argv )
+int Abc_CommandInvPut( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
+ extern Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, Gia_Man_t * pGia );
+ Vec_Int_t * vInv = NULL;
+ Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
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;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
}
}
if ( pNtk == NULL )
{
- Abc_Print( 1, "Abc_CommandProfile(): There is no current design.\n" );
+ Abc_Print( 1, "Abc_CommandInvPut(): There is no current design.\n" );
return 0;
}
- Wlc_WinProfileArith( pNtk );
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( 1, "Abc_CommandInvPut(): There is no current AIG.\n" );
+ return 0;
+ }
+ // derive the network
+ vInv = Wlc_NtkGetPut( pNtk, pAbc->pGia );
+ if ( vInv )
+ Abc_FrameSetInv( vInv );
return 0;
usage:
- Abc_Print( -2, "usage: %%profile [-vh]\n" );
- Abc_Print( -2, "\t profiles arithmetic components in the word-level networks\n" );
+ Abc_Print( -2, "usage: inv_put [-vh]\n" );
+ Abc_Print( -2, "\t inputs the current network in the main-space as an invariant\n" );
+ Abc_Print( -2, "\t (AIG representing the design should be in the &-space)\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;
@@ -600,42 +1366,57 @@ usage:
SeeAlso []
******************************************************************************/
-int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
+int Abc_CommandInvMin( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- extern void Wlc_NtkSimulateTest( Wlc_Ntk_t * p );
- Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
- int c, fVerbose = 0;
+ extern Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose );
+ extern Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose );
+ Vec_Int_t * vInv, * vInv2;
+ int c, fLits = 0, fVerbose = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "lvh" ) ) != EOF )
{
switch ( c )
{
- case 'v':
- fVerbose ^= 1;
- break;
- case 'h':
- goto usage;
- default:
- goto usage;
+ case 'l':
+ fLits ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
}
}
- if ( pNtk == NULL )
+ if ( pAbc->pGia == NULL )
{
- Abc_Print( 1, "Abc_CommandTest(): There is no current design.\n" );
+ Abc_Print( 1, "Abc_CommandInvMin(): There is no current design.\n" );
return 0;
}
- // transform
- //pNtk = Wlc_NtkUifNodePairs( pNtk, NULL );
- //pNtk = Wlc_NtkAbstractNodes( pNtk, NULL );
- //Wlc_AbcUpdateNtk( pAbc, pNtk );
- //Wlc_GenerateSmtStdout( pAbc );
- //Wlc_NtkSimulateTest( (Wlc_Ntk_t *)pAbc->pAbcWlc );
- pNtk = Wlc_NtkDupSingleNodes( pNtk );
- Wlc_AbcUpdateNtk( pAbc, pNtk );
+ if ( Wlc_AbcGetInv(pAbc) == NULL )
+ {
+ Abc_Print( 1, "Abc_CommandInvMin(): Invariant is not available.\n" );
+ return 0;
+ }
+ vInv = Wlc_AbcGetInv(pAbc);
+ if ( Gia_ManRegNum(pAbc->pGia) != Vec_IntEntryLast(vInv) )
+ {
+ Abc_Print( 1, "Abc_CommandInvMin(): The number of flops in the invariant and in GIA should be the same.\n" );
+ return 0;
+ }
+ if ( fLits )
+ vInv2 = Pdr_InvMinimizeLits( pAbc->pGia, vInv, fVerbose );
+ else
+ vInv2 = Pdr_InvMinimize( pAbc->pGia, vInv, fVerbose );
+ if ( vInv2 )
+ Abc_FrameSetInv( vInv2 );
return 0;
usage:
- Abc_Print( -2, "usage: %%test [-vh]\n" );
- Abc_Print( -2, "\t experiments with word-level networks\n" );
+ Abc_Print( -2, "usage: inv_min [-lvh]\n" );
+ Abc_Print( -2, "\t performs minimization of the current invariant\n" );
+ Abc_Print( -2, "\t (AIG representing the design should be in the &-space)\n" );
+ Abc_Print( -2, "\t-l : toggle minimizing literals rather than clauses [default = %s]\n", fLits? "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/wlcNtk.c b/src/base/wlc/wlcNtk.c
index 6f396771..c8fc15a7 100644
--- a/src/base/wlc/wlcNtk.c
+++ b/src/base/wlc/wlcNtk.c
@@ -88,12 +88,40 @@ static char * Wlc_Names[WLC_OBJ_NUMBER+1] = {
NULL // 54: unused
};
+char * Wlc_ObjTypeName( Wlc_Obj_t * p ) { return Wlc_Names[p->Type]; }
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars )
+{
+ memset( pPars, 0, sizeof(Wlc_Par_t) );
+ pPars->nBitsAdd = ABC_INFINITY; // adder bit-width
+ pPars->nBitsMul = ABC_INFINITY; // multiplier bit-widht
+ pPars->nBitsMux = ABC_INFINITY; // MUX bit-width
+ pPars->nBitsFlop = ABC_INFINITY; // flop bit-width
+ pPars->nIterMax = 1000; // the max number of iterations
+ pPars->fXorOutput = 1; // XOR outputs of word-level miter
+ pPars->fCheckClauses = 1; // Check clauses in the reloaded trace
+ pPars->fPushClauses = 0; // Push clauses in the reloaded trace
+ pPars->fVerbose = 0; // verbose output`
+ pPars->fPdrVerbose = 0; // show verbose PDR output
+}
+
+/**Function*************************************************************
+
Synopsis [Working with models.]
Description []
@@ -195,14 +223,14 @@ void Wlc_ObjAddFanins( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFanins )
{
assert( pObj->nFanins == 0 );
pObj->nFanins = Vec_IntSize(vFanins);
- if ( Wlc_ObjHasArray(pObj) )
- pObj->pFanins[0] = (int *)Mem_FlexEntryFetch( p->pMemFanin, Vec_IntSize(vFanins) * sizeof(int) );
- memcpy( Wlc_ObjFanins(pObj), Vec_IntArray(vFanins), sizeof(int) * Vec_IntSize(vFanins) );
// special treatment of CONST, SELECT and TABLE
if ( pObj->Type == WLC_OBJ_CONST )
pObj->nFanins = 0;
else if ( pObj->Type == WLC_OBJ_BIT_SELECT || pObj->Type == WLC_OBJ_TABLE )
pObj->nFanins = 1;
+ if ( Wlc_ObjHasArray(pObj) )
+ pObj->pFanins[0] = (int *)Mem_FlexEntryFetch( p->pMemFanin, Vec_IntSize(vFanins) * sizeof(int) );
+ memcpy( Wlc_ObjFanins(pObj), Vec_IntArray(vFanins), sizeof(int) * Vec_IntSize(vFanins) );
}
void Wlc_NtkFree( Wlc_Ntk_t * p )
{
@@ -224,6 +252,8 @@ void Wlc_NtkFree( Wlc_Ntk_t * p )
ABC_FREE( p->vValues.pArray );
ABC_FREE( p->vCopies.pArray );
ABC_FREE( p->vBits.pArray );
+ ABC_FREE( p->vLevels.pArray );
+ ABC_FREE( p->vRefs.pArray );
ABC_FREE( p->pInits );
ABC_FREE( p->pObjs );
ABC_FREE( p->pName );
@@ -246,6 +276,91 @@ int Wlc_NtkMemUsage( Wlc_Ntk_t * p )
/**Function*************************************************************
+ Synopsis [Assigns object levels.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Wlc_NtkCreateLevels( Wlc_Ntk_t * p )
+{
+ Wlc_Obj_t * pObj;
+ int i, k, iFanin, Level, LevelMax = 0;
+ Vec_IntFill( &p->vLevels, Wlc_NtkObjNumMax(p), 0 );
+ Wlc_NtkForEachObj( p, pObj, i )
+ {
+ Level = 0;
+ Wlc_ObjForEachFanin( pObj, iFanin, k )
+ Level = Abc_MaxInt( Level, Wlc_ObjLevelId(p, iFanin) + 1 );
+ Vec_IntWriteEntry( &p->vLevels, i, Level );
+ LevelMax = Abc_MaxInt( LevelMax, Level );
+ }
+ return LevelMax;
+}
+int Wlc_NtkCreateLevelsRev( Wlc_Ntk_t * p )
+{
+ Wlc_Obj_t * pObj;
+ int i, k, iFanin, Level, LevelMax = 0;
+ Vec_IntFill( &p->vLevels, Wlc_NtkObjNumMax(p), 0 );
+ Wlc_NtkForEachObjReverse( p, pObj, i )
+ {
+ if ( Wlc_ObjIsCi(pObj) )
+ continue;
+ Level = Wlc_ObjLevel(p, pObj) + 1;
+ Wlc_ObjForEachFanin( pObj, iFanin, k )
+ Vec_IntUpdateEntry( &p->vLevels, iFanin, Level );
+ LevelMax = Abc_MaxInt( LevelMax, Level );
+ }
+ // reverse the values
+ Wlc_NtkForEachObj( p, pObj, i )
+ Vec_IntWriteEntry( &p->vLevels, i, LevelMax - Wlc_ObjLevelId(p, i) );
+ Wlc_NtkForEachCi( p, pObj, i )
+ Vec_IntWriteEntry( &p->vLevels, Wlc_ObjId(p, pObj), 0 );
+ return LevelMax;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects statistics for each side of the miter.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wlc_NtkCollectStats( Wlc_Ntk_t * p, int nObjs[2][WLC_OBJ_NUMBER] )
+{
+ Wlc_Obj_t * pObj;
+ int n, i;
+ if ( Wlc_NtkPoNum(p) != 2 )
+ return;
+ for ( n = 0; n < 2; n++ )
+ {
+ Wlc_NtkMarkCone( p, n, 1, 1, 0 );
+ Wlc_NtkForEachObj( p, pObj, i )
+ if ( pObj->Mark )
+ nObjs[n][pObj->Type]++;
+ }
+ Wlc_NtkCleanMarks( p );
+}
+int Wlc_NtkCountRealPis( Wlc_Ntk_t * p )
+{
+ Wlc_Obj_t * pObj;
+ int i, Count = 0;
+ Wlc_NtkMarkCone( p, -1, -1, 1, 0 );
+ Wlc_NtkForEachPi( p, pObj, i )
+ Count += pObj->Mark;
+ Wlc_NtkCleanMarks( p );
+ return Count;
+}
+
+/**Function*************************************************************
+
Synopsis [Prints distribution of operator types.]
Description []
@@ -298,13 +413,18 @@ void Wlc_NtkPrintDistribSortOne( Vec_Ptr_t * vTypes, Vec_Ptr_t * vOccurs, int Ty
Vec_WrdReverseOrder( vType );
Vec_WrdReverseOrder( vOccur );
}
-void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose )
+void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fTwoSides, int fVerbose )
{
+ int nObjs[2][WLC_OBJ_NUMBER] = {{0}}; // counter of objects of each type
Wlc_Obj_t * pObj, * pObjRange = NULL; int nCountRange = 0;
Vec_Ptr_t * vTypes, * vOccurs;
Vec_Int_t * vAnds = Vec_IntStart( WLC_OBJ_NUMBER );
word Sign;
int i, k, s, s0, s1;
+ if ( Wlc_NtkPoNum(p) != 2 )
+ fTwoSides = 0;
+ if ( fTwoSides )
+ Wlc_NtkCollectStats( p, nObjs );
// allocate statistics arrays
vTypes = Vec_PtrStart( WLC_OBJ_NUMBER );
vOccurs = Vec_PtrStart( WLC_OBJ_NUMBER );
@@ -409,11 +529,11 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose )
else if ( pObj->Type == WLC_OBJ_REDUCT_XOR )
Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_XOR, 3 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 3 );
else if ( pObj->Type == WLC_OBJ_REDUCT_NAND )
- Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NAND, Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 );
+ Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NAND, Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 );
else if ( pObj->Type == WLC_OBJ_REDUCT_NOR )
- Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NOR, Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 );
+ Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NOR, Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 );
else if ( pObj->Type == WLC_OBJ_REDUCT_NXOR )
- Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NXOR, 3 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 3 );
+ Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NXOR, 3 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 3 );
else if ( pObj->Type == WLC_OBJ_ARI_ADD )
Vec_IntAddToEntry( vAnds, WLC_OBJ_ARI_ADD, 9 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) );
else if ( pObj->Type == WLC_OBJ_ARI_SUB )
@@ -435,28 +555,41 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose )
else if ( pObj->Type == WLC_OBJ_ARI_SQUARE )
Vec_IntAddToEntry( vAnds, WLC_OBJ_ARI_SQUARE, 5 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) * Wlc_ObjRange(Wlc_ObjFanin1(p, pObj)) );
}
- if ( nCountRange )
+ if ( nCountRange && Vec_IntSize(&p->vNameIds) > 0 )
{
printf( "Warning: %d objects of the design have non-zero-based ranges.\n", nCountRange );
printf( "In particular, object %6d with name \"%s\" has range %d=[%d:%d]\n", Wlc_ObjId(p, pObjRange),
Abc_NamStr(p->pManName, Wlc_ObjNameId(p, Wlc_ObjId(p, pObjRange))), Wlc_ObjRange(pObjRange), pObjRange->End, pObjRange->Beg );
}
// print by occurrence
- printf( "ID : name occurrence and2 (occurrence)<output_range>=<input_range>.<input_range> ...\n" );
+ printf( "ID : name occurrence%s and2 (occurrence)<output_range>=<input_range>.<input_range> ...\n", fTwoSides ? " Left Share Right":"" );
for ( i = 0; i < WLC_OBJ_NUMBER; i++ )
{
Vec_Wrd_t * vType = (Vec_Wrd_t *)Vec_PtrEntry( vTypes, i );
Vec_Wrd_t * vOccur = (Vec_Wrd_t *)Vec_PtrEntry( vOccurs, i );
if ( p->nObjs[i] == 0 )
continue;
- printf( "%2d : %-8s %6d%8d ", i, Wlc_Names[i], p->nObjs[i], Vec_IntEntry(vAnds, i) );
+ printf( "%2d : %-8s %6d", i, Wlc_Names[i], p->nObjs[i] );
+ if ( fTwoSides )
+ {
+ int nTotal = i == WLC_OBJ_PI ? Wlc_NtkCountRealPis(p) : p->nObjs[i];
+ printf( " " );
+ printf( "%6d", nObjs[0][i] );
+ printf( "%6d", nObjs[0][i]+nObjs[1][i]-nTotal );
+ printf( "%6d", nObjs[1][i] );
+ }
+ printf( "%8d ", Vec_IntEntry(vAnds, i) );
// sort by occurence
Wlc_NtkPrintDistribSortOne( vTypes, vOccurs, i );
Vec_WrdForEachEntry( vType, Sign, k )
{
Wlc_NtkPrintDistribFromSign( Sign, &s, &s0, &s1 );
if ( ((k % 6) == 5 && s1) || ((k % 8) == 7 && !s1) )
+ {
printf( "\n " );
+ if ( fTwoSides )
+ printf( " " );
+ }
printf( "(%d)", (int)Vec_WrdEntry( vOccur, k ) );
printf( "%s%d", Abc_LitIsCompl(s)?"-":"", Abc_Lit2Var(s) );
if ( s0 )
@@ -535,19 +668,19 @@ void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type )
Wlc_NtkPrintNode( p, pObj );
}
}
-void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose )
+void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fTwoSides, int fVerbose )
{
int i;
printf( "%-20s : ", p->pName );
- printf( "PI = %4d ", Wlc_NtkPiNum(p) );
+ printf( "PI = %4d ", Wlc_NtkCountRealPis(p) ); //Wlc_NtkPiNum(p) );
printf( "PO = %4d ", Wlc_NtkPoNum(p) );
printf( "FF = %4d ", Wlc_NtkFfNum(p) );
- printf( "Obj = %6d ", Wlc_NtkObjNum(p) );
+ printf( "Obj = %6d ", Wlc_NtkObjNum(p) - Wlc_NtkPiNum(p) - Wlc_NtkPoNum(p) - Wlc_NtkFfNum(p) );
printf( "Mem = %.3f MB", 1.0*Wlc_NtkMemUsage(p)/(1<<20) );
printf( "\n" );
if ( fDistrib )
{
- Wlc_NtkPrintDistrib( p, fVerbose );
+ Wlc_NtkPrintDistrib( p, fTwoSides, fVerbose );
return;
}
if ( !fVerbose )
@@ -566,6 +699,80 @@ void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose )
/**Function*************************************************************
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p )
+{
+ int i;
+ assert( !Wlc_NtkHasCopy(pNew) && Wlc_NtkHasCopy(p) );
+ assert( !Wlc_NtkHasNameId(pNew) && Wlc_NtkHasNameId(p) );
+ assert( pNew->pManName == NULL && p->pManName != NULL );
+ Wlc_NtkCleanNameId( pNew );
+ for ( i = 0; i < p->nObjsAlloc; i++ )
+ if ( Wlc_ObjCopy(p, i) && i < Vec_IntSize(&p->vNameIds) && Wlc_ObjNameId(p, i) )
+ Wlc_ObjSetNameId( pNew, Wlc_ObjCopy(p, i), Wlc_ObjNameId(p, i) );
+ pNew->pManName = p->pManName;
+ p->pManName = NULL;
+ Vec_IntErase( &p->vNameIds );
+ // transfer table
+ pNew->pMemTable = p->pMemTable; p->pMemTable = NULL;
+ pNew->vTables = p->vTables; p->vTables = NULL;
+}
+char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq )
+{
+ static char pBuffer[1000];
+ sprintf( pBuffer, "%s_o%d_%s", p->pName, iCoId, fSeq ? "seq": "comb" );
+ return pBuffer;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reduce init vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Wlc_ReduceMarkedInitVec( Wlc_Ntk_t * p, Vec_Int_t * vInit )
+{
+ Vec_Int_t * vInitNew = Vec_IntDup( vInit );
+ Wlc_Obj_t * pObj; int i, k = 0;
+ assert( Vec_IntSize(vInit) == Wlc_NtkCiNum(p) - Wlc_NtkPiNum(p) );
+ Wlc_NtkForEachCi( p, pObj, i )
+ if ( !Wlc_ObjIsPi(pObj) && pObj->Mark )
+ Vec_IntWriteEntry( vInitNew, k++, Vec_IntEntry(vInit, i - Wlc_NtkPiNum(p)) );
+ Vec_IntShrink( vInitNew, k );
+ return vInitNew;
+}
+char * Wlc_ReduceMarkedInitStr( Wlc_Ntk_t * p, char * pInit )
+{
+ char * pInitNew = Abc_UtilStrsav( pInit );
+ Wlc_Obj_t * pObj; int i, b, nBits = 0, k = 0;
+ Wlc_NtkForEachCi( p, pObj, i )
+ {
+ if ( !Wlc_ObjIsPi(pObj) && pObj->Mark )
+ for ( b = 0; b < Wlc_ObjRange(pObj); b++ )
+ pInitNew[k++] = pInitNew[nBits+b];
+ if ( !Wlc_ObjIsPi(pObj) )
+ nBits += Wlc_ObjRange(pObj);
+ }
+ pInitNew[k] = '\0';
+ assert( nBits == (int)strlen(pInit) );
+ return pInitNew;
+}
+
+/**Function*************************************************************
+
Synopsis [Duplicates the network in a topological order.]
Description []
@@ -623,47 +830,214 @@ void Wlc_NtkDupDfs_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * v
Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins );
Wlc_ObjDup( pNew, p, iObj, vFanins );
}
-Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p )
+Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq )
{
Wlc_Ntk_t * pNew;
Wlc_Obj_t * pObj;
Vec_Int_t * vFanins;
int i;
- Wlc_NtkCleanCopy( p );
vFanins = Vec_IntAlloc( 100 );
+ Wlc_NtkCleanCopy( p );
pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc );
pNew->fSmtLib = p->fSmtLib;
Wlc_NtkForEachCi( p, pObj, i )
- Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins );
+ if ( !fMarked || pObj->Mark )
+ {
+ unsigned Type = pObj->Type;
+ if ( !fSeq ) pObj->Type = WLC_OBJ_PI;
+ Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins );
+ pObj->Type = Type;
+ }
Wlc_NtkForEachCo( p, pObj, i )
- Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins );
+ if ( !fMarked || pObj->Mark )
+ Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins );
Wlc_NtkForEachCo( p, pObj, i )
- Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), pObj->fIsFi );
+ if ( !fMarked || pObj->Mark )
+ Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), fSeq ? pObj->fIsFi : 0 );
+ Vec_IntFree( vFanins );
+ if ( fSeq )
+ {
+ if ( fMarked )
+ {
+ if ( p->vInits )
+ pNew->vInits = Wlc_ReduceMarkedInitVec( p, p->vInits );
+ if ( p->pInits )
+ pNew->pInits = Wlc_ReduceMarkedInitStr( p, p->pInits );
+ }
+ else
+ {
+ if ( p->vInits )
+ pNew->vInits = Vec_IntDup( p->vInits );
+ if ( p->pInits )
+ pNew->pInits = Abc_UtilStrsav( p->pInits );
+ }
+ }
+ if ( p->pSpec )
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Wlc_NtkTransferNames( pNew, p );
+ return pNew;
+}
+Wlc_Ntk_t * Wlc_NtkDupDfsAbs( Wlc_Ntk_t * p, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops )
+{
+ Wlc_Ntk_t * pNew;
+ Wlc_Obj_t * pObj;
+ Vec_Int_t * vFanins;
+ int i;
+ Wlc_NtkCleanCopy( p );
+ pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc );
+ pNew->fSmtLib = p->fSmtLib;
+
+ // duplicate marked PIs
+ vFanins = Vec_IntAlloc( 100 );
+ Wlc_NtkForEachObjVec( vPisOld, p, pObj, i )
+ {
+ assert( Wlc_ObjIsPi(pObj) );
+ Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins );
+ }
+ // duplicate additional PIs
+ Wlc_NtkForEachObjVec( vPisNew, p, pObj, i )
+ {
+ unsigned Type = pObj->Type;
+ int nFanins = Wlc_ObjFaninNum(pObj);
+ assert( !Wlc_ObjIsPi(pObj) );
+ pObj->Type = WLC_OBJ_PI;
+ pObj->nFanins = 0;
+ Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins );
+ pObj->Type = Type;
+ pObj->nFanins = (unsigned)nFanins;
+ }
+ // duplicate flop outputs
+ Wlc_NtkForEachObjVec( vFlops, p, pObj, i )
+ {
+ assert( !Wlc_ObjIsPi(pObj) && Wlc_ObjIsCi(pObj) );
+ Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins );
+ }
+
+ // duplicate logic cones of primary outputs
+ Wlc_NtkForEachPo( p, pObj, i )
+ Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins );
+ // duplidate logic cone of flop inputs
+ Wlc_NtkForEachObjVec( vFlops, p, pObj, i )
+ Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, Wlc_ObjFo2Fi(p, pObj)), vFanins );
+
+ // duplicate POs
+ Wlc_NtkForEachPo( p, pObj, i )
+ Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), 0 );
+ // duplicate flop inputs
+ Wlc_NtkForEachObjVec( vFlops, p, pObj, i )
+ Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, Wlc_ObjFo2Fi(p, pObj)), 1 );
+ Vec_IntFree( vFanins );
+
+ // mark flop outputs
+ Wlc_NtkForEachObjVec( vFlops, p, pObj, i )
+ pObj->Mark = 1;
if ( p->vInits )
- pNew->vInits = Vec_IntDup( p->vInits );
+ pNew->vInits = Wlc_ReduceMarkedInitVec( p, p->vInits );
if ( p->pInits )
- pNew->pInits = Abc_UtilStrsav( p->pInits );
- Vec_IntFree( vFanins );
+ pNew->pInits = Wlc_ReduceMarkedInitStr( p, p->pInits );
+ Wlc_NtkCleanMarks( p );
+
if ( p->pSpec )
- pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ //Wlc_NtkTransferNames( pNew, p );
return pNew;
}
-void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p )
+
+/**Function*************************************************************
+
+ Synopsis [Select the cone of the given output.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wlc_NtkCleanMarks( Wlc_Ntk_t * p )
{
+ Wlc_Obj_t * pObj;
int i;
- assert( !Wlc_NtkHasCopy(pNew) && Wlc_NtkHasCopy(p) );
- assert( !Wlc_NtkHasNameId(pNew) && Wlc_NtkHasNameId(p) );
- assert( pNew->pManName == NULL && p->pManName != NULL );
- Wlc_NtkCleanNameId( pNew );
- for ( i = 0; i < p->nObjsAlloc; i++ )
- if ( Wlc_ObjCopy(p, i) && i < Vec_IntSize(&p->vNameIds) && Wlc_ObjNameId(p, i) )
- Wlc_ObjSetNameId( pNew, Wlc_ObjCopy(p, i), Wlc_ObjNameId(p, i) );
- pNew->pManName = p->pManName;
- p->pManName = NULL;
- Vec_IntErase( &p->vNameIds );
- // transfer table
- pNew->pMemTable = p->pMemTable; p->pMemTable = NULL;
- pNew->vTables = p->vTables; p->vTables = NULL;
+ Wlc_NtkForEachObj( p, pObj, i )
+ pObj->Mark = 0;
+}
+int Wlc_NtkCountMarked( Wlc_Ntk_t * p, int * pnPis, int * pnFos, int * pnAdders, int * pnMults )
+{
+ Wlc_Obj_t * pObj;
+ int i, nNodes = 0;
+ *pnPis = *pnFos = *pnAdders = *pnMults = 0;
+ Wlc_NtkForEachObj( p, pObj, i )
+ {
+ if ( !pObj->Mark )
+ continue;
+ if ( Wlc_ObjIsPi(pObj) )
+ (*pnPis)++;
+ else if ( Wlc_ObjIsCi(pObj) )
+ (*pnFos)++;
+ else if ( pObj->Mark )
+ {
+ nNodes++;
+ if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB )
+ (*pnAdders)++;
+ else if ( pObj->Type == WLC_OBJ_ARI_MULTI )
+ (*pnMults)++;
+ }
+ }
+ return nNodes;
+}
+void Wlc_NtkMarkCone_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFlops )
+{
+ int i, iFanin;
+ if ( pObj->Mark )
+ return;
+ pObj->Mark = 1;
+ if ( Wlc_ObjIsCi(pObj) )
+ {
+ if ( !Wlc_ObjIsPi(pObj) )
+ Vec_IntPush( vFlops, Wlc_ObjCiId(pObj) );
+ return;
+ }
+ Wlc_ObjForEachFanin( pObj, iFanin, i )
+ Wlc_NtkMarkCone_rec( p, Wlc_NtkObj(p, iFanin), vFlops );
+}
+void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int Range, int fSeq, int fAllPis )
+{
+ Vec_Int_t * vFlops;
+ Wlc_Obj_t * pObj;
+ int i, CiId, CoId;
+ Wlc_NtkCleanMarks( p );
+ if ( fAllPis )
+ Wlc_NtkForEachPi( p, pObj, i )
+ pObj->Mark = 1;
+ vFlops = Vec_IntAlloc( 100 );
+ Wlc_NtkForEachCo( p, pObj, i )
+ if ( iCoId == -1 || (i >= iCoId && i < iCoId + Range) )
+ Wlc_NtkMarkCone_rec( p, pObj, vFlops );
+ if ( fSeq )
+ Vec_IntForEachEntry( vFlops, CiId, i )
+ {
+ CoId = Wlc_NtkPoNum(p) + CiId - Wlc_NtkPiNum(p);
+ Wlc_NtkMarkCone_rec( p, Wlc_NtkCo(p, CoId), vFlops );
+ }
+ Vec_IntFree( vFlops );
+}
+void Wlc_NtkProfileCones( Wlc_Ntk_t * p )
+{
+ Wlc_Obj_t * pObj;
+ int i, nPis, nFos, nNodes, nAdders, nMults;
+ Wlc_NtkForEachCo( p, pObj, i )
+ {
+ Wlc_NtkMarkCone( p, i, 1, 0, 0 );
+ nNodes = Wlc_NtkCountMarked( p, &nPis, &nFos, &nAdders, &nMults );
+ printf( "Cone %5d : ", i );
+ printf( "PI = %4d ", nPis );
+ printf( "FO = %4d ", nFos );
+ printf( "Node = %6d ", nNodes );
+ printf( "Add/Sub = %4d ", nAdders );
+ printf( "Mult = %4d ", nMults );
+ printf( "\n" );
+ }
+ Wlc_NtkCleanMarks( p );
}
/**Function*************************************************************
@@ -723,6 +1097,128 @@ Wlc_Ntk_t * Wlc_NtkDupSingleNodes( Wlc_Ntk_t * p )
return pNew;
}
+/**Function*************************************************************
+
+ Synopsis [Creates short names for all objects.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wlc_NtkShortNames( Wlc_Ntk_t * p )
+{
+ Wlc_Obj_t * pObj;
+ char pBuffer[100];
+ int nDigits, NameId, fFound, i;
+ int nFlops = Wlc_NtkCoNum(p) - Wlc_NtkPoNum(p);
+ nDigits = Abc_Base10Log( nFlops );
+ Wlc_NtkForEachCo( p, pObj, i )
+ {
+ if ( Wlc_ObjIsPo(pObj) )
+ continue;
+ sprintf( pBuffer, "%s%0*d", "fi", nDigits, i - Wlc_NtkPoNum(p) );
+ NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound );
+ Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId );
+ }
+ Wlc_NtkForEachCi( p, pObj, i )
+ {
+ if ( Wlc_ObjIsPi(pObj) )
+ continue;
+ sprintf( pBuffer, "%s%0*d", "fo", nDigits, i - Wlc_NtkPiNum(p) );
+ NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound );
+ Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId );
+ }
+ nDigits = Abc_Base10Log( Wlc_NtkPoNum(p) );
+ Wlc_NtkForEachPo( p, pObj, i )
+ {
+ sprintf( pBuffer, "%s%0*d", "po", nDigits, i );
+ NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound );
+ Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId );
+ }
+ nDigits = Abc_Base10Log( Wlc_NtkPiNum(p) );
+ Wlc_NtkForEachPi( p, pObj, i )
+ {
+ sprintf( pBuffer, "%s%0*d", "pi", nDigits, i );
+ NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound );
+ Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId );
+ }
+ nDigits = Abc_Base10Log( Wlc_NtkObjNum(p) );
+ Wlc_NtkForEachObj( p, pObj, i )
+ {
+ if ( Wlc_ObjIsCi(pObj) || Wlc_ObjIsCo(pObj) )
+ continue;
+ sprintf( pBuffer, "%s%0*d", "n", nDigits, i );
+ NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound );
+ Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Count the number of flops initialized to DC value.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Wlc_NtkDcFlopNum( Wlc_Ntk_t * p )
+{
+ int i, nFlops, Count = 0;
+ if ( p->pInits == NULL )
+ return 0;
+ nFlops = strlen(p->pInits);
+ for ( i = 0; i < nFlops; i++ )
+ Count += (p->pInits[i] == 'x' || p->pInits[i] == 'X');
+ return Count;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Create references.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wlc_NtkSetRefs( Wlc_Ntk_t * p )
+{
+ Wlc_Obj_t * pObj; int i, k, Fanin;
+ Vec_IntFill( &p->vRefs, Wlc_NtkObjNumMax(p), 0 );
+ Wlc_NtkForEachObj( p, pObj, i )
+ Wlc_ObjForEachFanin( pObj, Fanin, k )
+ Vec_IntAddToEntry( &p->vRefs, Fanin, 1 );
+ Wlc_NtkForEachCo( p, pObj, i )
+ Vec_IntAddToEntry( &p->vRefs, Wlc_ObjId(p, pObj), 1 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [This procedure simply count the number of PPI bits.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Wlc_NtkCountObjBits( Wlc_Ntk_t * p, Vec_Int_t * vPisNew )
+{
+ Wlc_Obj_t * pObj;
+ int i, Count = 0;
+ Wlc_NtkForEachObjVec( vPisNew, p, pObj, i )
+ Count += Wlc_ObjRange(pObj);
+ return Count;
+}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/base/wlc/wlcReadSmt.c b/src/base/wlc/wlcReadSmt.c
index d07a54c4..69a01ab0 100644
--- a/src/base/wlc/wlcReadSmt.c
+++ b/src/base/wlc/wlcReadSmt.c
@@ -48,6 +48,9 @@ struct Smt_Prs_t_
char ErrorStr[1000];
};
+//#define SMT_GLO_SUFFIX "_glb"
+#define SMT_GLO_SUFFIX ""
+
// parser name types
typedef enum {
SMT_PRS_NONE = 0,
@@ -219,6 +222,8 @@ static inline int Smt_StrToType( char * pName, int * pfSigned )
Type = WLC_OBJ_ARI_REM, *pfSigned = 1; // 40: arithmetic remainder
else if ( !strcmp(pName, "bvsmod") )
Type = WLC_OBJ_ARI_MODULUS, *pfSigned = 1; // 40: arithmetic modulus
+ else if ( !strcmp(pName, "=") )
+ Type = WLC_OBJ_COMP_EQU; // 40: arithmetic modulus
// else if ( !strcmp(pName, "") )
// Type = WLC_OBJ_ARI_POWER; // 41: arithmetic power
else if ( !strcmp(pName, "bvneg") )
@@ -255,6 +260,8 @@ static inline int Smt_PrsReadType( Smt_Prs_t * p, int iSig, int * pfSigned, int
}
}
+static inline int Smt_StrType( char * str ) { return Smt_StrToType(str, NULL); }
+
/**Function*************************************************************
Synopsis []
@@ -274,20 +281,27 @@ static inline int Smt_PrsCreateNodeOld( Wlc_Ntk_t * pNtk, int Type, int fSigned,
assert( Type > 0 );
assert( Range >= 0 );
assert( fSigned >= 0 );
- Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj), vFanins );
- if ( fSigned )
- Wlc_NtkObj(pNtk, iObj)->Signed = fSigned;
- if ( Type == WLC_OBJ_SHIFT_RA )
- Wlc_NtkObj(pNtk, iObj)->Signed = 1;
+
+ // add node's name
if ( pName == NULL )
{
sprintf( Buffer, "_n%d_", iObj );
pName = Buffer;
}
- // add node's name
NameId = Abc_NamStrFindOrAdd( pNtk->pManName, pName, &fFound );
assert( !fFound );
assert( iObj == NameId );
+
+ Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj), vFanins );
+ if ( fSigned )
+ {
+ Wlc_NtkObj(pNtk, iObj)->Signed = fSigned;
+// if ( Vec_IntSize(vFanins) > 0 )
+// Wlc_NtkObj(pNtk, Vec_IntEntry(vFanins, 0))->Signed = fSigned;
+// if ( Vec_IntSize(vFanins) > 1 )
+// Wlc_NtkObj(pNtk, Vec_IntEntry(vFanins, 1))->Signed = fSigned;
+ }
+
return iObj;
}
static inline int Smt_PrsCreateNode( Wlc_Ntk_t * pNtk, int Type, int fSigned, int Range, Vec_Int_t * vFanins, char * pName )
@@ -302,8 +316,7 @@ static inline int Smt_PrsCreateNode( Wlc_Ntk_t * pNtk, int Type, int fSigned, in
assert( Range >= 0 );
assert( fSigned >= 0 );
- // allow more than 2 fanins for specific operators
- // if (Vec_IntSize(vFanins)<=2 || Type == WLC_OBJ_BIT_CONCAT || Type == WLC_OBJ_MUX )
+ //if (Vec_IntSize(vFanins)<=2 || Type == WLC_OBJ_BIT_CONCAT || Type == WLC_OBJ_MUX )
// explicitely secify allowed multi operators
if (Vec_IntSize(vFanins)<=2 ||
!( Type == WLC_OBJ_BIT_AND || // 16:`` bitwise AND
@@ -362,17 +375,17 @@ FINISHED_WITH_FANINS:
Vec_IntFree(v2Fanins);
- // to deal with long shifts create extra bit select (ROTATE as well ??)
+ //added to deal with long shifts create extra bit select (ROTATE as well ??)
// this is a temporary hack
- // basically we keep only 32 bits.
- // bits 0 - 30 are kept same as original
- // bit 31 will be the reduction or of all bits from 31 to Range-1
+ // basically we keep only 32 bits.
+ // bit[31] will be the copy of original MSB (sign bit, just in case) UPDATE: assume it is unsigned first????
+ // bit[31] will be the reduction or of any bits from [31] to Range
if (Type == WLC_OBJ_SHIFT_R || Type == WLC_OBJ_SHIFT_RA || Type == WLC_OBJ_SHIFT_L)
{
- int iFanin1 = Vec_IntEntry(vFanins,1);
- int range1 = Wlc_ObjRange( Wlc_NtkObj(pNtk, iFanin1) );
- int iObj1, iObj2, iObj3;
+ int range1, iObj1, iObj2, iObj3;
assert(Vec_IntSize(vFanins)>=2);
+ iFanin1 = Vec_IntEntry(vFanins,1);
+ range1 = Wlc_ObjRange( Wlc_NtkObj(pNtk, iFanin1) );
if (range1>32)
{
Vec_Int_t * newFanins = Vec_IntAlloc(10);
@@ -389,6 +402,8 @@ FINISHED_WITH_FANINS:
Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj1), newFanins );
+ //printf("obj1: %d\n",iObj1);
+
// bit select of larger bits
Vec_IntPop(newFanins);
Vec_IntPop(newFanins);
@@ -402,6 +417,7 @@ FINISHED_WITH_FANINS:
assert( iObj2 == NameId );
Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj2), newFanins );
+ //printf("obj2: %d\n",iObj2);
// reduction or
Vec_IntPop( newFanins );
@@ -416,6 +432,7 @@ FINISHED_WITH_FANINS:
assert( iObj3 == NameId );
Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj3), newFanins );
+ //printf("obj3: %d\n",iObj3);
// concat all together
Vec_IntWriteEntry( newFanins, 0, iObj3 );
@@ -429,6 +446,7 @@ FINISHED_WITH_FANINS:
assert( iObj == NameId );
Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj), newFanins );
+ //printf("obj: %d\n",iObj);
// pushing the new node
Vec_IntWriteEntry(vFanins, 1, iObj);
@@ -461,34 +479,22 @@ FINISHED_WITH_FANINS:
return iObj;
}
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
static inline char * Smt_GetHexFromDecimalString(char * pStr)
{
int i,k=0, nDigits = strlen(pStr);
int digit, carry = 0;
- int metNonZeroBit;
- int nBits;
- char * hex;
+ int metNonZeroBit = 0;
Vec_Int_t * decimal = Vec_IntAlloc(nDigits);
Vec_Int_t * rev;
+ int nBits;
+ char * hex;
for (i=0;i<nDigits;i++)
Vec_IntPush(decimal,pStr[i]-'0');
- // firstly fill-in the reversed vector
+ // firstly fillin the reversed vector
rev = Vec_IntAlloc(10);
- metNonZeroBit = 0;
while(k<nDigits)
{
digit = Vec_IntEntry(decimal,k);
@@ -501,7 +507,7 @@ static inline char * Smt_GetHexFromDecimalString(char * pStr)
break;
else
{
- Vec_IntPush(rev,carry);
+ Vec_IntPush(rev,carry);
carry = 0;
k = 0;
metNonZeroBit = 0;
@@ -564,12 +570,17 @@ static inline char * Smt_GetHexFromDecimalString(char * pStr)
default: assert(0);
}
hex[nBits/4-1-k] = letter;
+ //if (k<Vec_IntSize(rev))
+ // Vec_IntPush(vFanins,Vec_IntEntry(rev,k));
+ //else
+ // Vec_IntPush(vFanins,0);
}
hex[nBits/4] = '\0';
Vec_IntFree(rev);
return hex;
-}
+}
+
static inline int Smt_PrsBuildConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits, char * pName )
{
int i, nDigits, iObj;
@@ -578,6 +589,25 @@ static inline int Smt_PrsBuildConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits
{
if ( pStr[0] >= '0' && pStr[0] <= '9' )
{
+ // added: sanity check for large constants
+ /*
+ Vec_Int_t * temp = Vec_IntAlloc(10);
+ int fullBits = -1;
+ Smt_GetBinaryFromDecimalString(pStr,temp,&fullBits);
+ Vec_IntFree(temp);
+ assert(fullBits < 32);*/
+
+ char * pHex = Smt_GetHexFromDecimalString(pStr);
+
+ if ( nBits == -1 )
+ nBits = strlen(pHex)*4;
+
+ //printf("nbits: %d\n",nBits);
+
+ Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 );
+ nDigits = Abc_TtReadHexNumber( (word *)Vec_IntArray(vFanins), pHex );
+ ABC_FREE( pHex );
+
/*
int w, nWords, Number = atoi( pStr );
if ( nBits == -1 )
@@ -589,15 +619,6 @@ static inline int Smt_PrsBuildConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits
for ( w = 0; w < nWords; w++ )
Vec_IntPush( vFanins, w ? 0 : Number );
*/
-
- // convert decimal to hex to parse large constants
- char * pHex = Smt_GetHexFromDecimalString(pStr);
-
- if ( nBits == -1 )
- nBits = strlen(pHex)*4;
-
- Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 );
- nDigits = Abc_TtReadHexNumber( (word *)Vec_IntArray(vFanins), pHex );
}
else
{
@@ -616,7 +637,10 @@ static inline int Smt_PrsBuildConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits
if ( pStr[2+i] == '1' )
Abc_InfoSetBit( (unsigned *)Vec_IntArray(vFanins), nBits-1-i );
else if ( pStr[2+i] != '0' )
+ {
+ Vec_IntFree( vFanins );
return 0;
+ }
}
else if ( pStr[1] == 'x' ) // hexadecimal
{
@@ -625,9 +649,16 @@ static inline int Smt_PrsBuildConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits
Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 );
nDigits = Abc_TtReadHexNumber( (word *)Vec_IntArray(vFanins), pStr+2 );
if ( nDigits != (nBits + 3)/4 )
+ {
+ Vec_IntFree( vFanins );
return 0;
+ }
+ }
+ else
+ {
+ Vec_IntFree( vFanins );
+ return 0;
}
- else return 0;
// create constant node
iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_CONST, 0, nBits, vFanins, pName );
Vec_IntFree( vFanins );
@@ -648,12 +679,6 @@ int Smt_PrsBuildNode( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int RangeOut,
// s3087
int fFound, iObj = Abc_NamStrFindOrAdd( pNtk->pManName, pStr, &fFound );
assert( fFound );
- // create buffer if the name of the fanin has different name
- if ( pName && strcmp(pStr, pName) )
- {
- Vec_IntFill( &p->vTempFans, 1, iObj );
- iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BUF, 0, RangeOut, &p->vTempFans, pName );
- }
return iObj;
}
}
@@ -804,13 +829,6 @@ Wlc_Ntk_t * Smt_PrsBuild( Smt_Prs_t * p )
// skip ()
Fan = Vec_IntEntry(vFans, 2);
assert( !Smt_EntryIsName(Fan) );
- vFans2 = Smt_VecEntryNode(p, vFans, 2);
- if ( Vec_IntSize(vFans2) > 0 )
- {
- printf( "File parsing error: Uninterpreted functions are not supported.\n" );
- Wlc_NtkFree( pNtk ); pNtk = NULL;
- goto finish;
- }
// check type (Bool or BitVec)
Fan = Vec_IntEntry(vFans, 3);
if ( Smt_EntryIsName(Fan) )
@@ -1006,6 +1024,14 @@ char * Smt_PrsGenName( Smt_Prs_t * p )
}
int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, char * pName )
{
+ char suffix[100];
+ sprintf(suffix,"_as%d",pNtk->nAssert);
+
+ //char * prepStr = Abc_NamStr(p->pStrs, Abc_Lit2Var(iNode));
+ //printf("prestr: %s\n",prepStr);
+
+ //printf("inode: %d %d\n",iNode,Smt_EntryIsName(iNode));
+
if ( Smt_EntryIsName(iNode) )
{
char * pStr = Abc_NamStr(p->pStrs, Abc_Lit2Var(iNode));
@@ -1018,7 +1044,27 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev,
return Smt_PrsBuildConstant( pNtk, pStr, -1, pName ? pName : Smt_PrsGenName(p) );
else
{
- int fFound, iObj = Abc_NamStrFindOrAdd( pNtk->pManName, pStr, &fFound );
+ int fFound, iObj;
+ // look either for global DECLARE-FUN variable or local LET
+ char * pStr_glb = (char *)malloc(strlen(pStr) + 4 +1); //glb
+ char * pStr_loc = (char *)malloc(strlen(pStr) + strlen(suffix) +1);
+ strcpy(pStr_glb,pStr);
+ strcat(pStr_glb,SMT_GLO_SUFFIX);
+ strcpy(pStr_loc,pStr);
+ strcat(pStr_loc,suffix);
+
+ fFound = Abc_NamStrFind( pNtk->pManName, pStr_glb );
+
+ if (fFound)
+ pStr = pStr_glb;
+ else
+ {
+ assert( Abc_NamStrFind( pNtk->pManName, pStr_loc ));
+ pStr = pStr_loc;
+ }
+ // FIXME: delete memory of pStr
+
+ iObj = Abc_NamStrFindOrAdd( pNtk->pManName, pStr, &fFound );
assert( fFound );
// create buffer if the name of the fanin has different name
if ( pName && strcmp(Wlc_ObjName(pNtk, iObj), pName) )
@@ -1026,9 +1072,11 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev,
Vec_IntFill( &p->vTempFans, 1, iObj );
iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BUF, 0, Wlc_ObjRange(Wlc_NtkObj(pNtk, iObj)), &p->vTempFans, pName );
}
+ ABC_FREE( pStr_glb );
+ ABC_FREE( pStr_loc );
return iObj;
}
- }
+ }
else
{
Vec_Int_t * vRoots, * vRoots1, * vFans3;
@@ -1039,7 +1087,7 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev,
if ( Smt_EntryIsName(iRoot0) )
{
char * pName2, * pStr0 = Abc_NamStr(p->pStrs, Abc_Lit2Var(iRoot0));
- if ( Abc_Lit2Var(iRoot0) == SMT_PRS_LET )
+ if ( Abc_Lit2Var(iRoot0) == SMT_PRS_LET || Abc_Lit2Var(iRoot0) == SMT_PRS_DEFINE_FUN) //added define-fun is similar to let
{
// let ((s35550 (bvor s48 s35549)))
assert( Vec_IntSize(vRoots) == 3 );
@@ -1051,6 +1099,7 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev,
// iterate through the parts
Vec_IntForEachEntry( vRoots1, Fan, k )
{
+ char * temp;
// s35550 (bvor s48 s35549)
assert( !Smt_EntryIsName(Fan) );
vFans3 = Smt_EntryNode(p, Fan);
@@ -1059,11 +1108,26 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev,
Fan3 = Vec_IntEntry(vFans3, 0);
assert( Smt_EntryIsName(Fan3) );
pName2 = Smt_EntryName(p, Fan3);
+ // create a local name with suffix
+ if ( Abc_Lit2Var(iRoot0) == SMT_PRS_LET )
+ {
+ temp = (char *)malloc(strlen(pName2) + strlen(suffix) + 1);
+ strcpy(temp, pName2);
+ strcat(temp,suffix);
+ }
+ else
+ { temp = (char *)malloc(strlen(pName2) + 4 + 1);
+ strcpy(temp, pName2);
+ strcat(temp,SMT_GLO_SUFFIX);
+ }
+ // FIXME: need to delete memory of pName2
+ pName2 = temp;
// get function
Fan3 = Vec_IntEntry(vFans3, 1);
//assert( !Smt_EntryIsName(Fan3) );
// solve the problem
iObj = Smt_PrsBuild2_rec( pNtk, p, Fan3, -1, pName2 ); // NULL ); //pName2 );
+ ABC_FREE( temp );
if ( iObj == 0 )
return 0;
// create buffer
@@ -1133,7 +1197,6 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev,
int iObj = Abc_NamStrFind( pNtk->pManName, pStr0 );
if ( iObj )
return iObj;
-
Type0 = Smt_StrToType( pStr0, &fSigned );
if ( Type0 == 0 )
return 0;
@@ -1151,7 +1214,6 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev,
}
Vec_IntPush( vFanins, iObj );
}
-
// find range
Range = 0;
if ( Type0 >= WLC_OBJ_LOGIC_NOT && Type0 <= WLC_OBJ_REDUCT_XOR )
@@ -1197,7 +1259,7 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
Wlc_Ntk_t * pNtk;
Vec_Int_t * vFansRoot, * vFans, * vFans2;
Vec_Int_t * vAsserts = Vec_IntAlloc(100);
- int i, Root, Fan, iObj, NameId, Range, Status, nBits = 0;
+ int i, Root, Fan, iObj, NameId, Range, nBits = 0;
char * pName, * pRange;
// start network and create primary inputs
pNtk = Wlc_NtkAlloc( p->pName, 1000 );
@@ -1214,22 +1276,22 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
// create variables
if ( Abc_Lit2Var(Fan) == SMT_PRS_DECLARE_FUN )
{
+ char * pName_glb;
assert( Vec_IntSize(vFans) == 4 );
assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_DECLARE_FUN) );
// get name
Fan = Vec_IntEntry(vFans, 1);
assert( Smt_EntryIsName(Fan) );
pName = Smt_EntryName(p, Fan);
+ // added: giving a global suffix
+ pName_glb = (char *) malloc(strlen(pName) + 4 + 1);
+ strcpy(pName_glb,pName);
+ strcat(pName_glb,SMT_GLO_SUFFIX);
+ // FIXME: delete memory of pName
+ pName = pName_glb;
// skip ()
Fan = Vec_IntEntry(vFans, 2);
assert( !Smt_EntryIsName(Fan) );
- vFans2 = Smt_VecEntryNode(p, vFans, 2);
- if ( Vec_IntSize(vFans2) > 0 )
- {
- printf( "File parsing error: Uninterpreted functions are not supported.\n" );
- Wlc_NtkFree( pNtk ); pNtk = NULL;
- goto finish;
- }
// check type (Bool or BitVec)
Fan = Vec_IntEntry(vFans, 3);
if ( Smt_EntryIsName(Fan) )
@@ -1259,9 +1321,11 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
Vec_IntPush( &pNtk->vValues, nBits );
Vec_IntPush( &pNtk->vValues, Range );
nBits += Range;
+ ABC_FREE( pName_glb );
}
// create constants
- else if ( Abc_Lit2Var(Fan) == SMT_PRS_DEFINE_FUN )
+ /*
+ else if ( Abc_Lit2Var(Fan) == SMT_PRS_DEFINE_FUN ) // added: we parse DEFINE_FUN in LET
{
assert( Vec_IntSize(vFans) == 5 );
assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_DEFINE_FUN) );
@@ -1269,6 +1333,14 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
Fan = Vec_IntEntry(vFans, 1);
assert( Smt_EntryIsName(Fan) );
pName = Smt_EntryName(p, Fan);
+
+ // added: giving a global suffix
+ char * pName_glb = (char *) malloc(strlen(pName) + 4 + 1);
+ strcpy(pName_glb,pName);
+ strcat(pName_glb,SMT_GLO_SUFFIX);
+ // FIXME: delete memory of pName
+ pName = pName_glb;
+
// skip ()
Fan = Vec_IntEntry(vFans, 2);
assert( !Smt_EntryIsName(Fan) );
@@ -1278,13 +1350,17 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
{
// (define-fun s_2 () Bool false)
assert( !strcmp("Bool", Smt_VecEntryName(p, vFans, 3)) );
- iObj = Smt_PrsBuild2_rec( pNtk, p, Vec_IntEntry(vFans, 4), -1, pName );
- if ( iObj == 0 )
- {
- Wlc_NtkFree( pNtk ); pNtk = NULL;
- goto finish;
- }
- continue;
+ Range = 1;
+ pValue = Smt_VecEntryName(p, vFans, 4);
+
+ //printf("value: %s\n",pValue);
+
+ if ( !strcmp("false", pValue) )
+ pValue = "#b0";
+ else if ( !strcmp("true", pValue) )
+ pValue = "#b1";
+ else assert( 0 );
+ Status = Smt_PrsBuildConstant( pNtk, pValue, Range, pName );
}
else
{
@@ -1292,6 +1368,7 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
// (define-fun s1 () (_ BitVec 8) (bvneg #x7f))
// get range
Fan = Vec_IntEntry(vFans, 3);
+
assert( !Smt_EntryIsName(Fan) );
vFans2 = Smt_VecEntryNode(p, vFans, 3);
assert( Vec_IntSize(vFans2) == 3 );
@@ -1299,11 +1376,24 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
assert( !strcmp("BitVec", Smt_VecEntryName(p, vFans2, 1)) );
// get range
Fan = Vec_IntEntry(vFans2, 2);
+
assert( Smt_EntryIsName(Fan) );
pRange = Smt_EntryName(p, Fan);
Range = atoi(pRange);
+
+ // added: can parse functions too
+ Vec_Int_t * vFans3 = Smt_VecEntryNode(p, vFans, 4);
+ Fan = Vec_IntEntry(vFans3, 0);
+
// get constant
- Fan = Vec_IntEntry(vFans, 4);
+ //Fan = Vec_IntEntry(vFans, 4);
+
+ //printf("fan3: %s\n",Fan);
+ //printf("fan0: %s\n",Smt_VecEntryName(p, vFans3, 0));
+ //printf("fan1: %s\n",Smt_VecEntryName(p, vFans3, 1));
+ //printf("fan2: %s\n",Smt_VecEntryName(p, vFans3, 2));
+ //printf("fan3: %s\n",Smt_VecEntryName(p, vFans3, 3));
+
Status = Smt_PrsBuildNode( pNtk, p, Fan, Range, pName );
}
if ( !Status )
@@ -1312,6 +1402,57 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
goto finish;
}
}
+ */
+ // added: new way to parse define-fun
+ // create constants
+ else if ( Abc_Lit2Var(Fan) == SMT_PRS_DEFINE_FUN )
+ {
+ char * pName_glb;
+ // (define-fun def_16001 () Bool (or def_15999 def_16000))
+ // (define-fun def_15990 () (_ BitVec 24) (concat def_15988 def_15989))
+ assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_DEFINE_FUN) );
+ assert( Vec_IntSize(vFans) == 5 ); // const or definition
+
+ // get name
+ Fan = Vec_IntEntry(vFans, 1);
+ assert( Smt_EntryIsName(Fan) );
+ pName = Smt_EntryName(p, Fan);
+ // added: giving a global suffix
+ pName_glb = (char *) malloc(strlen(pName) + 4 + 1);
+ strcpy(pName_glb,pName);
+ strcat(pName_glb,SMT_GLO_SUFFIX);
+ // FIXME: delete memory of pName
+ pName = pName_glb;
+
+ //get range
+ Fan = Vec_IntEntry(vFans, 3);
+ if ( Smt_EntryIsName(Fan) )
+ {
+ // (define-fun s_2 () Bool false)
+ assert( !strcmp("Bool", Smt_VecEntryName(p, vFans, 3)) );
+ Range = 1;
+ }
+ else
+ {
+ // (define-fun s702 () (_ BitVec 4) #xe)
+ // (define-fun s1 () (_ BitVec 8) (bvneg #x7f))
+ assert( !Smt_EntryIsName(Fan) );
+ vFans2 = Smt_VecEntryNode(p, vFans, 3);
+ assert( Vec_IntSize(vFans2) == 3 );
+ assert( !strcmp("_", Smt_VecEntryName(p, vFans2, 0)) );
+ assert( !strcmp("BitVec", Smt_VecEntryName(p, vFans2, 1)) );
+ // get range
+ Fan = Vec_IntEntry(vFans2, 2);
+ assert( Smt_EntryIsName(Fan) );
+ pRange = Smt_EntryName(p, Fan);
+ Range = atoi(pRange);
+ }
+
+ iObj = Smt_PrsBuild2_rec( pNtk, p, Vec_IntEntry(vFans, 4), Range, pName );
+ assert( iObj );
+ ABC_FREE( pName_glb );
+ }
+
// collect assertion outputs
else if ( Abc_Lit2Var(Fan) == SMT_PRS_ASSERT )
{
@@ -1321,6 +1462,7 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
//(assert (not (= s0 #x00)))
assert( Vec_IntSize(vFans) == 2 );
assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_ASSERT) );
+ pNtk->nAssert++; // added
iObj = Smt_PrsBuild2_rec( pNtk, p, Vec_IntEntry(vFans, 1), -1, NULL );
if ( iObj == 0 )
{
@@ -1336,6 +1478,9 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
// build AND of asserts
if ( Vec_IntSize(vAsserts) == 1 )
iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BUF, 0, 1, vAsserts, "miter" );
+ // added: 0 asserts
+ else if ( Vec_IntSize(vAsserts) == 0 )
+ iObj = Smt_PrsBuildConstant( pNtk, "#b1", 1, "miter" );
else
{
iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vAsserts), vAsserts, NULL );
@@ -1413,18 +1558,35 @@ static inline char * Smt_PrsLoadFile( char * pFileName, char ** ppLimit )
static inline int Smt_PrsRemoveComments( char * pBuffer, char * pLimit )
{
char * pTemp; int nCount1 = 0, nCount2 = 0, fHaveBar = 0;
+ int backslash = 0;
for ( pTemp = pBuffer; pTemp < pLimit; pTemp++ )
{
if ( *pTemp == '(' )
- nCount1++;
+ { if ( !fHaveBar ) nCount1++; }
else if ( *pTemp == ')' )
- nCount2++;
+ { if ( !fHaveBar ) nCount2++; }
else if ( *pTemp == '|' )
fHaveBar ^= 1;
else if ( *pTemp == ';' && !fHaveBar )
while ( *pTemp && *pTemp != '\n' )
*pTemp++ = ' ';
+ // added: hack to remove quotes
+ else if ( *pTemp == '\"' && *(pTemp-1) != '\\' && !fHaveBar )
+ {
+ *pTemp++ = ' ';
+ while ( *pTemp && (*pTemp != '\"' || backslash))
+ {
+ if (*pTemp == '\\')
+ backslash = 1;
+ else
+ backslash = 0;
+ *pTemp++ = ' ';
+ }
+ // remove the last quote symbol
+ *pTemp = ' ';
+ }
}
+
if ( nCount1 != nCount2 )
printf( "The input SMTLIB file has different number of opening and closing parentheses (%d and %d).\n", nCount1, nCount2 );
else if ( nCount1 == 0 )
@@ -1486,6 +1648,7 @@ static inline void Smt_PrsSkipNonSpaces( Smt_Prs_t * p )
}
void Smt_PrsReadLines( Smt_Prs_t * p )
{
+ int fFirstTime = 1;
assert( Vec_IntSize(&p->vStack) == 0 );
//assert( Vec_WecSize(&p->vDepth) == 0 );
assert( Vec_WecSize(&p->vObjs) == 0 );
@@ -1499,6 +1662,16 @@ void Smt_PrsReadLines( Smt_Prs_t * p )
for ( p->pCur = p->pBuffer; p->pCur < p->pLimit; p->pCur++ )
{
Smt_PrsSkipSpaces( p );
+ if ( fFirstTime && *p->pCur == '|' )
+ {
+ fFirstTime = 0;
+ *p->pCur = ' ';
+ while ( *p->pCur && *p->pCur != '|' )
+ *p->pCur++ = ' ';
+ if ( *p->pCur == '|' )
+ *p->pCur = ' ';
+ continue;
+ }
if ( *p->pCur == '(' )
{
// add new node at this depth
@@ -1524,12 +1697,13 @@ void Smt_PrsReadLines( Smt_Prs_t * p )
{
// remove strange characters (this can lead to name clashes)
int iToken;
+ /* commented out for SMT comp
char * pTemp;
if ( *pStart == '?' )
*pStart = '_';
for ( pTemp = pStart; pTemp < p->pCur; pTemp++ )
if ( *pTemp == '.' )
- *pTemp = '_';
+ *pTemp = '_';*/
// create and save token for this string
iToken = Abc_NamStrFindOrAddLim( p->pStrs, pStart, p->pCur--, NULL );
Vec_IntPush( Vec_WecEntry(&p->vObjs, Vec_IntEntryLast(&p->vStack)), Abc_Var2Lit(iToken, 1) );
diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c
index fa3efacd..e4a65ecf 100644
--- a/src/base/wlc/wlcReadVer.c
+++ b/src/base/wlc/wlcReadVer.c
@@ -28,7 +28,7 @@ ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
// Word-level Verilog file parser
-#define WLV_PRS_MAX_LINE 1000
+#define WLV_PRS_MAX_LINE 10000
typedef struct Wlc_Prs_t_ Wlc_Prs_t;
struct Wlc_Prs_t_
@@ -1265,8 +1265,7 @@ Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr )
if ( !Wlc_PrsDerive( p ) )
goto finish;
// derive topological order
- pNtk = Wlc_NtkDupDfs( p->pNtk );
- Wlc_NtkTransferNames( pNtk, p->pNtk );
+ pNtk = Wlc_NtkDupDfs( p->pNtk, 0, 1 );
pNtk->pSpec = Abc_UtilStrsav( pFileName );
finish:
Wlc_PrsPrintErrorMessage( p );
diff --git a/src/base/wlc/wlcShow.c b/src/base/wlc/wlcShow.c
new file mode 100644
index 00000000..1601d602
--- /dev/null
+++ b/src/base/wlc/wlcShow.c
@@ -0,0 +1,337 @@
+/**CFile****************************************************************
+
+ FileName [wlcShow.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Verilog parser.]
+
+ Synopsis [Parses several flavors of word-level Verilog.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - August 22, 2014.]
+
+ Revision [$Id: wlcShow.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "wlc.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+
+/**Function*************************************************************
+
+ Synopsis [Writes the graph structure of WLC for DOT.]
+
+ Description [Useful for graph visualization using tools such as GraphViz:
+ http://www.graphviz.org/]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold )
+{
+ FILE * pFile;
+ Wlc_Obj_t * pNode;
+ int LevelMax, Prev, Level, i;
+
+ if ( Wlc_NtkObjNum(p) > 2000 )
+ {
+ fprintf( stdout, "Cannot visualize WLC with more than %d nodes.\n", 2000 );
+ return;
+ }
+ if ( (pFile = fopen( pFileName, "w" )) == NULL )
+ {
+ fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName );
+ return;
+ }
+
+ // mark the nodes
+ if ( vBold )
+ Wlc_NtkForEachObjVec( vBold, p, pNode, i )
+ pNode->Mark = 1;
+
+ // compute levels
+ LevelMax = 1 + Wlc_NtkCreateLevelsRev( p );
+
+ // write the DOT header
+ fprintf( pFile, "# %s\n", "WLC structure generated by ABC" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "digraph WLC {\n" );
+ fprintf( pFile, "size = \"7.5,10\";\n" );
+// fprintf( pFile, "ranksep = 0.5;\n" );
+// fprintf( pFile, "nodesep = 0.5;\n" );
+ fprintf( pFile, "center = true;\n" );
+// fprintf( pFile, "orientation = landscape;\n" );
+// fprintf( pFile, "edge [fontsize = 10];\n" );
+// fprintf( pFile, "edge [dir = none];\n" );
+ fprintf( pFile, "edge [dir = back];\n" );
+ fprintf( pFile, "\n" );
+
+ // labels on the left of the picture
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " node [shape = plaintext];\n" );
+ fprintf( pFile, " edge [style = invis];\n" );
+ fprintf( pFile, " LevelTitle1 [label=\"\"];\n" );
+ fprintf( pFile, " LevelTitle2 [label=\"\"];\n" );
+ // generate node names with labels
+ for ( Level = LevelMax; Level >= 0; Level-- )
+ {
+ // the visible node name
+ fprintf( pFile, " Level%d", Level );
+ fprintf( pFile, " [label = " );
+ // label name
+ fprintf( pFile, "\"" );
+ fprintf( pFile, "\"" );
+ fprintf( pFile, "];\n" );
+ }
+
+ // genetate the sequence of visible/invisible nodes to mark levels
+ fprintf( pFile, " LevelTitle1 -> LevelTitle2 ->" );
+ for ( Level = LevelMax; Level >= 0; Level-- )
+ {
+ // the visible node name
+ fprintf( pFile, " Level%d", Level );
+ // the connector
+ if ( Level != 0 )
+ fprintf( pFile, " ->" );
+ else
+ fprintf( pFile, ";" );
+ }
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate title box on top
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ fprintf( pFile, " LevelTitle1;\n" );
+ fprintf( pFile, " title1 [shape=plaintext,\n" );
+ fprintf( pFile, " fontsize=20,\n" );
+ fprintf( pFile, " fontname = \"Times-Roman\",\n" );
+ fprintf( pFile, " label=\"" );
+ fprintf( pFile, "%s", "WLC structure generated by ABC" );
+ fprintf( pFile, "\\n" );
+ fprintf( pFile, "Benchmark \\\"%s\\\". ", p->pName );
+// fprintf( pFile, "Time was %s. ", Extra_TimeStamp() );
+ fprintf( pFile, "\"\n" );
+ fprintf( pFile, " ];\n" );
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate statistics box
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ fprintf( pFile, " LevelTitle2;\n" );
+ fprintf( pFile, " title2 [shape=plaintext,\n" );
+ fprintf( pFile, " fontsize=18,\n" );
+ fprintf( pFile, " fontname = \"Times-Roman\",\n" );
+ fprintf( pFile, " label=\"" );
+ fprintf( pFile, "The word-level network contains %d nodes and spans %d levels.", Wlc_NtkObjNum(p)-Wlc_NtkCiNum(p), LevelMax-1 );
+ fprintf( pFile, "\\n" );
+ fprintf( pFile, "\"\n" );
+ fprintf( pFile, " ];\n" );
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate the COs
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ // the labeling node of this level
+ fprintf( pFile, " Level%d;\n", LevelMax );
+ // generate the CO nodes
+ Wlc_NtkForEachCo( p, pNode, i )
+ {
+ pNode = Wlc_ObjCo2PoFo(p, i);
+ fprintf( pFile, " NodePo%d [label = \"%s_in %d\"", Wlc_ObjId(p, pNode), Wlc_ObjName(p, Wlc_ObjId(p, pNode)), Wlc_ObjRange(pNode) );
+ fprintf( pFile, ", shape = %s", i < Wlc_NtkPoNum(p) ? "invtriangle" : "box" );
+ fprintf( pFile, ", color = coral, fillcolor = coral" );
+ fprintf( pFile, "];\n" );
+ }
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate nodes of each rank
+ for ( Level = LevelMax - 1; Level > 0; Level-- )
+ {
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ // the labeling node of this level
+ fprintf( pFile, " Level%d;\n", Level );
+ Wlc_NtkForEachObj( p, pNode, i )
+ {
+ if ( (int)Wlc_ObjLevel(p, pNode) != Level )
+ continue;
+
+ if ( pNode->Type == WLC_OBJ_CONST )
+ {
+ fprintf( pFile, " Node%d [label = \"0x", i );
+ Abc_TtPrintHexArrayRev( pFile, (word *)Wlc_ObjConstValue(pNode), (Wlc_ObjRange(pNode) + 3) / 4 );
+ fprintf( pFile, "\"" );
+ }
+ else if ( pNode->Type == WLC_OBJ_BUF || pNode->Type == WLC_OBJ_MUX )
+ fprintf( pFile, " Node%d [label = \"%d\"", i, Wlc_ObjRange(pNode) );
+ else if ( pNode->Type >= WLC_OBJ_LOGIC_NOT && pNode->Type <= WLC_OBJ_COMP_MOREEQU )
+ fprintf( pFile, " Node%d [label = \"%s\"", i, Wlc_ObjTypeName(pNode) );
+ else
+ fprintf( pFile, " Node%d [label = \"%s %d\"", i, Wlc_ObjTypeName(pNode), Wlc_ObjRange(pNode) );
+
+ if ( pNode->Type == WLC_OBJ_ARI_MULTI )
+ fprintf( pFile, ", shape = doublecircle" );
+ else if ( pNode->Type >= WLC_OBJ_COMP_EQU && pNode->Type <= WLC_OBJ_COMP_MOREEQU )
+ fprintf( pFile, ", shape = diamond" );
+ else if ( pNode->Type == WLC_OBJ_BIT_SELECT || pNode->Type == WLC_OBJ_BIT_CONCAT )
+ fprintf( pFile, ", shape = box" );
+ else if ( pNode->Type == WLC_OBJ_BUF || pNode->Type == WLC_OBJ_BIT_ZEROPAD || pNode->Type == WLC_OBJ_BIT_SIGNEXT )
+ fprintf( pFile, ", shape = triangle" );
+ else if ( pNode->Type == WLC_OBJ_MUX )
+ fprintf( pFile, ", shape = trapezium" );
+ else
+ fprintf( pFile, ", shape = ellipse" );
+
+ if ( vBold ? pNode->Mark : ((pNode->Type >= WLC_OBJ_ARI_ADD && pNode->Type <= WLC_OBJ_ARI_SQUARE) || pNode->Type == WLC_OBJ_BIT_NOT) )
+ fprintf( pFile, ", style = filled" );
+ fprintf( pFile, "];\n" );
+ }
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+ }
+
+ // generate the CI nodes
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ // the labeling node of this level
+ fprintf( pFile, " Level%d;\n", 0 );
+ // generate the CI nodes
+ Wlc_NtkForEachCi( p, pNode, i )
+ {
+ fprintf( pFile, " Node%d [label = \"%s %d\"", Wlc_ObjId(p, pNode), Wlc_ObjName(p, Wlc_ObjId(p, pNode)), Wlc_ObjRange(pNode) );
+ fprintf( pFile, ", shape = %s", i < Wlc_NtkPiNum(p) ? "triangle" : "box" );
+ fprintf( pFile, ", color = coral, fillcolor = coral" );
+ fprintf( pFile, "];\n" );
+ }
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate invisible edges from the square down
+ fprintf( pFile, "title1 -> title2 [style = invis];\n" );
+ Wlc_NtkForEachCo( p, pNode, i )
+ {
+ pNode = Wlc_ObjCo2PoFo( p, i );
+ fprintf( pFile, "title2 -> NodePo%d [style = invis];\n", Wlc_ObjId(p, pNode) );
+ }
+ // generate invisible edges among the COs
+ Prev = -1;
+ Wlc_NtkForEachCo( p, pNode, i )
+ {
+ pNode = Wlc_ObjCo2PoFo( p, i );
+ if ( i > 0 )
+ fprintf( pFile, "NodePo%d -> NodePo%d [style = invis];\n", Prev, Wlc_ObjId(p, pNode) );
+ Prev = Wlc_ObjId(p, pNode);
+ }
+ // generate invisible edges among the CIs
+ Prev = -1;
+ Wlc_NtkForEachCi( p, pNode, i )
+ {
+ if ( i > 0 )
+ fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Wlc_ObjId(p, pNode) );
+ Prev = Wlc_ObjId(p, pNode);
+ }
+
+ // generate edges
+ Wlc_NtkForEachCo( p, pNode, i )
+ {
+ fprintf( pFile, "NodePo%d", Wlc_ObjId(p, Wlc_ObjCo2PoFo(p, i)) );
+ fprintf( pFile, " -> " );
+ fprintf( pFile, "Node%d", Wlc_ObjId(p, pNode) );
+ fprintf( pFile, " [" );
+ fprintf( pFile, "style = %s", pNode->Signed? "dotted" : "solid" );
+ fprintf( pFile, "]" );
+ fprintf( pFile, ";\n" );
+ }
+ Wlc_NtkForEachObj( p, pNode, i )
+ {
+ int k, iFanin;
+ if ( Wlc_ObjIsCi(pNode) )
+ continue;
+ // generate the edge from this node to the next
+ Wlc_ObjForEachFanin( pNode, iFanin, k )
+ {
+ fprintf( pFile, "Node%d", i );
+ fprintf( pFile, " -> " );
+ fprintf( pFile, "Node%d", iFanin );
+ fprintf( pFile, " [" );
+ fprintf( pFile, "style = %s", Wlc_NtkObj(p, iFanin)->Signed? "dotted" : "solid" );
+ if ( pNode->Type == WLC_OBJ_MUX && k == 0 )
+ fprintf( pFile, ", style = %s", "bold" );
+ fprintf( pFile, "]" );
+ fprintf( pFile, ";\n" );
+ }
+ }
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+ fclose( pFile );
+
+ // unmark nodes
+ if ( vBold )
+ Wlc_NtkCleanMarks( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wlc_NtkShow( Wlc_Ntk_t * p, Vec_Int_t * vBold )
+{
+ extern void Abc_ShowFile( char * FileNameDot );
+ FILE * pFile;
+ char FileNameDot[200];
+ sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(p->pName, ".dot") );
+ // check that the file can be opened
+ if ( (pFile = fopen( FileNameDot, "w" )) == NULL )
+ {
+ fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", FileNameDot );
+ return;
+ }
+ fclose( pFile );
+ // generate the file
+ Wlc_NtkDumpDot( p, FileNameDot, vBold );
+ // visualize the file
+ Abc_ShowFile( FileNameDot );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/base/wlc/wlcSim.c b/src/base/wlc/wlcSim.c
index 20ac8c61..e2fcd1f8 100644
--- a/src/base/wlc/wlcSim.c
+++ b/src/base/wlc/wlcSim.c
@@ -43,13 +43,13 @@ ABC_NAMESPACE_IMPL_START
***********************************************************************/
static inline word * Wlc_ObjSim( Gia_Man_t * p, int iObj )
{
- return Vec_WrdEntryP( p->vSims, p->iPatsPi * iObj );
+ return Vec_WrdEntryP( p->vSims, p->nSimWords * iObj );
}
static inline void Wlc_ObjSimPi( Gia_Man_t * p, int iObj )
{
int w;
word * pSim = Wlc_ObjSim( p, iObj );
- for ( w = 0; w < p->iPatsPi; w++ )
+ for ( w = 0; w < p->nSimWords; w++ )
pSim[w] = Gia_ManRandomW( 0 );
}
static inline void Wlc_ObjSimRo( Gia_Man_t * p, int iObj )
@@ -57,7 +57,7 @@ static inline void Wlc_ObjSimRo( Gia_Man_t * p, int iObj )
int w;
word * pSimRo = Wlc_ObjSim( p, iObj );
word * pSimRi = Wlc_ObjSim( p, Gia_ObjRoToRiId(p, iObj) );
- for ( w = 0; w < p->iPatsPi; w++ )
+ for ( w = 0; w < p->nSimWords; w++ )
pSimRo[w] = pSimRi[w];
}
static inline void Wlc_ObjSimCo( Gia_Man_t * p, int iObj )
@@ -67,10 +67,10 @@ static inline void Wlc_ObjSimCo( Gia_Man_t * p, int iObj )
word * pSimCo = Wlc_ObjSim( p, iObj );
word * pSimDri = Wlc_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) );
if ( Gia_ObjFaninC0(pObj) )
- for ( w = 0; w < p->iPatsPi; w++ )
+ for ( w = 0; w < p->nSimWords; w++ )
pSimCo[w] = ~pSimDri[w];
else
- for ( w = 0; w < p->iPatsPi; w++ )
+ for ( w = 0; w < p->nSimWords; w++ )
pSimCo[w] = pSimDri[w];
}
static inline void Wlc_ObjSimAnd( Gia_Man_t * p, int iObj )
@@ -81,16 +81,16 @@ static inline void Wlc_ObjSimAnd( Gia_Man_t * p, int iObj )
word * pSim0 = Wlc_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) );
word * pSim1 = Wlc_ObjSim( p, Gia_ObjFaninId1(pObj, iObj) );
if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) )
- for ( w = 0; w < p->iPatsPi; w++ )
+ for ( w = 0; w < p->nSimWords; w++ )
pSim[w] = ~pSim0[w] & ~pSim1[w];
else if ( Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) )
- for ( w = 0; w < p->iPatsPi; w++ )
+ for ( w = 0; w < p->nSimWords; w++ )
pSim[w] = ~pSim0[w] & pSim1[w];
else if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) )
- for ( w = 0; w < p->iPatsPi; w++ )
+ for ( w = 0; w < p->nSimWords; w++ )
pSim[w] = pSim0[w] & ~pSim1[w];
else
- for ( w = 0; w < p->iPatsPi; w++ )
+ for ( w = 0; w < p->nSimWords; w++ )
pSim[w] = pSim0[w] & pSim1[w];
}
@@ -135,7 +135,7 @@ Vec_Ptr_t * Wlc_NtkSimulate( Wlc_Ntk_t * p, Vec_Int_t * vNodes, int nWords, int
// allocate simulation info for one timeframe
Vec_WrdFreeP( &pGia->vSims );
pGia->vSims = Vec_WrdStart( Gia_ManObjNum(pGia) * nWords );
- pGia->iPatsPi = nWords;
+ pGia->nSimWords = nWords;
// allocate resulting simulation info
vRes = Vec_PtrAlloc( Vec_IntSize(vNodes) );
Wlc_NtkForEachObjVec( vNodes, p, pWlcObj, i )
@@ -188,7 +188,7 @@ Vec_Ptr_t * Wlc_NtkSimulate( Wlc_Ntk_t * p, Vec_Int_t * vNodes, int nWords, int
printf( "Replaced %d dangling internal bits with constant 0.\n", Counter );
}
Vec_WrdFreeP( &pGia->vSims );
- pGia->iPatsPi = 0;
+ pGia->nSimWords = 0;
Gia_ManStop( pGia );
return vRes;
}
diff --git a/src/base/wlc/wlcUif.c b/src/base/wlc/wlcUif.c
new file mode 100644
index 00000000..78451c17
--- /dev/null
+++ b/src/base/wlc/wlcUif.c
@@ -0,0 +1,290 @@
+/**CFile****************************************************************
+
+ FileName [wlcUif.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Verilog parser.]
+
+ Synopsis [Abstraction for word-level networks.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - August 22, 2014.]
+
+ Revision [$Id: wlcUif.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "wlc.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Check if two objects have the same input/output signatures.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 )
+{
+ Wlc_Obj_t * pFanin, * pFanin2; int k;
+ if ( Wlc_ObjRange(pObj) != Wlc_ObjRange(pObj2) )
+ return 0;
+ if ( Wlc_ObjIsSigned(pObj) != Wlc_ObjIsSigned(pObj2) )
+ return 0;
+ if ( Wlc_ObjFaninNum(pObj) != Wlc_ObjFaninNum(pObj2) )
+ return 0;
+ for ( k = 0; k < Wlc_ObjFaninNum(pObj); k++ )
+ {
+ pFanin = Wlc_ObjFanin(p, pObj, k);
+ pFanin2 = Wlc_ObjFanin(p, pObj2, k);
+ if ( Wlc_ObjRange(pFanin) != Wlc_ObjRange(pFanin2) )
+ return 0;
+ if ( Wlc_ObjIsSigned(pFanin) != Wlc_ObjIsSigned(pFanin2) )
+ return 0;
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collect IDs of the multipliers.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p )
+{
+ Wlc_Obj_t * pObj; int i;
+ Vec_Int_t * vBoxIds = Vec_IntAlloc( 100 );
+ Wlc_NtkForEachObj( p, pObj, i )
+ if ( pObj->Type == WLC_OBJ_ARI_MULTI )
+ Vec_IntPush( vBoxIds, i );
+ if ( Vec_IntSize( vBoxIds ) > 0 )
+ return vBoxIds;
+ Vec_IntFree( vBoxIds );
+ return NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns all pairs of uifable multipliers.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p )
+{
+ Vec_Int_t * vMultis = Wlc_NtkCollectMultipliers( p );
+ Vec_Int_t * vPairs = Vec_IntAlloc( 2 );
+ Wlc_Obj_t * pObj, * pObj2; int i, k;
+ // iterate through unique pairs
+ Wlc_NtkForEachObjVec( vMultis, p, pObj, i )
+ Wlc_NtkForEachObjVec( vMultis, p, pObj2, k )
+ {
+ if ( k == i )
+ break;
+ if ( Wlc_NtkPairIsUifable( p, pObj, pObj2 ) )
+ {
+ Vec_IntPush( vPairs, Wlc_ObjId(p, pObj) );
+ Vec_IntPush( vPairs, Wlc_ObjId(p, pObj2) );
+ }
+ }
+ Vec_IntFree( vMultis );
+ if ( Vec_IntSize( vPairs ) > 0 )
+ return vPairs;
+ Vec_IntFree( vPairs );
+ return NULL;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Abstracts nodes by replacing their outputs with new PIs.]
+
+ Description [If array is NULL, abstract all multipliers.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit )
+{
+ Vec_Int_t * vNodes = vNodesInit;
+ Wlc_Ntk_t * pNew;
+ Wlc_Obj_t * pObj;
+ int i, k, iObj, iFanin;
+ // get multipliers if not given
+ if ( vNodes == NULL )
+ vNodes = Wlc_NtkCollectMultipliers( p );
+ if ( vNodes == NULL )
+ return NULL;
+ // mark nodes
+ Wlc_NtkForEachObjVec( vNodes, p, pObj, i )
+ pObj->Mark = 1;
+ // iterate through the nodes in the DFS order
+ Wlc_NtkCleanCopy( p );
+ Wlc_NtkForEachObj( p, pObj, i )
+ {
+ if ( i == Vec_IntSize(&p->vCopies) )
+ break;
+ if ( pObj->Mark ) {
+ // clean
+ pObj->Mark = 0;
+ // add fresh PI with the same number of bits
+ iObj = Wlc_ObjAlloc( p, WLC_OBJ_PI, Wlc_ObjIsSigned(pObj), Wlc_ObjRange(pObj) - 1, 0 );
+ }
+ else {
+ // update fanins
+ Wlc_ObjForEachFanin( pObj, iFanin, k )
+ Wlc_ObjFanins(pObj)[k] = Wlc_ObjCopy(p, iFanin);
+ // node to remain
+ iObj = i;
+ }
+ Wlc_ObjSetCopy( p, i, iObj );
+ }
+ // POs do not change in this procedure
+ if ( vNodes != vNodesInit )
+ Vec_IntFree( vNodes );
+ // reconstruct topological order
+ pNew = Wlc_NtkDupDfs( p, 0, 1 );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds UIF constraints to node pairs and updates POs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * p, Vec_Int_t * vPairsInit )
+{
+ Vec_Int_t * vPairs = vPairsInit;
+ Wlc_Ntk_t * pNew;
+ Wlc_Obj_t * pObj, * pObj2;
+ Vec_Int_t * vUifConstrs, * vCompares, * vFanins;
+ int i, k, iObj, iObj2, iObjNew, iObjNew2;
+ int iFanin, iFanin2, iFaninNew;
+ // get multiplier pairs if not given
+ if ( vPairs == NULL )
+ vPairs = Wlc_NtkFindUifableMultiplierPairs( p );
+ if ( vPairs == NULL )
+ return NULL;
+ // sanity checks
+ assert( Vec_IntSize(vPairs) > 0 && Vec_IntSize(vPairs) % 2 == 0 );
+ // iterate through node pairs
+ vFanins = Vec_IntAlloc( 100 );
+ vCompares = Vec_IntAlloc( 100 );
+ vUifConstrs = Vec_IntAlloc( 100 );
+ Vec_IntForEachEntryDouble( vPairs, iObj, iObj2, i )
+ {
+ // get two nodes
+ pObj = Wlc_NtkObj( p, iObj );
+ pObj2 = Wlc_NtkObj( p, iObj2 );
+ assert( Wlc_NtkPairIsUifable(p, pObj, pObj2) );
+ // create fanin comparator nodes
+ Vec_IntClear( vCompares );
+ Wlc_ObjForEachFanin( pObj, iFanin, k )
+ {
+ iFanin2 = Wlc_ObjFaninId( pObj2, k );
+ Vec_IntFillTwo( vFanins, 2, iFanin, iFanin2 );
+ iFaninNew = Wlc_ObjCreate( p, WLC_OBJ_COMP_NOTEQU, 0, 0, 0, vFanins );
+ Vec_IntPush( vCompares, iFaninNew );
+ // note that a pointer to Wlc_Obj_t (for example, pObj) can be invalidated after a call to
+ // Wlc_ObjCreate() due to a possible realloc of the internal array of objects...
+ pObj = Wlc_NtkObj( p, iObj );
+ }
+ // concatenate fanin comparators
+ iObjNew = Wlc_ObjCreate( p, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vCompares) - 1, 0, vCompares );
+ // create reduction-OR node
+ Vec_IntFill( vFanins, 1, iObjNew );
+ iObjNew = Wlc_ObjCreate( p, WLC_OBJ_REDUCT_OR, 0, 0, 0, vFanins );
+ // craete output comparator node
+ Vec_IntFillTwo( vFanins, 2, iObj, iObj2 );
+ iObjNew2 = Wlc_ObjCreate( p, WLC_OBJ_COMP_EQU, 0, 0, 0, vFanins );
+ // create implication node (iObjNew is already complemented above)
+ Vec_IntFillTwo( vFanins, 2, iObjNew, iObjNew2 );
+ iObjNew = Wlc_ObjCreate( p, WLC_OBJ_LOGIC_OR, 0, 0, 0, vFanins );
+ // save the constraint
+ Vec_IntPush( vUifConstrs, iObjNew );
+ }
+ // derive the AND of the UIF contraints
+ assert( Vec_IntSize(vUifConstrs) > 0 );
+ if ( Vec_IntSize(vUifConstrs) == 1 )
+ iObjNew = Vec_IntEntry( vUifConstrs, 0 );
+ else
+ {
+ // concatenate
+ iObjNew = Wlc_ObjCreate( p, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vUifConstrs) - 1, 0, vUifConstrs );
+ // create reduction-AND node
+ Vec_IntFill( vFanins, 1, iObjNew );
+ iObjNew = Wlc_ObjCreate( p, WLC_OBJ_REDUCT_AND, 0, 0, 0, vFanins );
+ }
+ // update each PO to point to the new node
+ Wlc_NtkForEachPo( p, pObj, i )
+ {
+ iObj = Wlc_ObjId(p, pObj);
+ Vec_IntFillTwo( vFanins, 2, iObj, iObjNew );
+ iObjNew = Wlc_ObjCreate( p, WLC_OBJ_LOGIC_AND, 0, 0, 0, vFanins );
+ // note that a pointer to Wlc_Obj_t (for example, pObj) can be invalidated after a call to
+ // Wlc_ObjCreate() due to a possible realloc of the internal array of objects...
+ pObj = Wlc_NtkObj( p, iObj );
+ // update PO/CO arrays
+ assert( Vec_IntEntry(&p->vPos, i) == iObj );
+ assert( Vec_IntEntry(&p->vCos, i) == iObj );
+ Vec_IntWriteEntry( &p->vPos, i, iObjNew );
+ Vec_IntWriteEntry( &p->vCos, i, iObjNew );
+ // transfer the PO attribute
+ Wlc_NtkObj(p, iObjNew)->fIsPo = 1;
+ assert( pObj->fIsPo );
+ pObj->fIsPo = 0;
+ }
+ // cleanup
+ Vec_IntFree( vUifConstrs );
+ Vec_IntFree( vCompares );
+ Vec_IntFree( vFanins );
+ if ( vPairs != vPairsInit )
+ Vec_IntFree( vPairs );
+ // reconstruct topological order
+ pNew = Wlc_NtkDupDfs( p, 0, 1 );
+ return pNew;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/base/wlc/wlcWriteVer.c b/src/base/wlc/wlcWriteVer.c
index cf0e528f..c4dee094 100644
--- a/src/base/wlc/wlcWriteVer.c
+++ b/src/base/wlc/wlcWriteVer.c
@@ -409,7 +409,7 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops )
fprintf( pFile, " reg%d (", i );
fprintf( pFile, " .q( %s ),", Wlc_ObjName(p, Wlc_ObjId(p, pObj)) );
fprintf( pFile, " .qbar()," );
- fprintf( pFile, " .d( %s ),", Wlc_ObjName(p, Wlc_ObjId(p, Wlc_ObjFoToFi(p, pObj))) );
+ fprintf( pFile, " .d( %s ),", Wlc_ObjName(p, Wlc_ObjId(p, Wlc_ObjFo2Fi(p, pObj))) );
fprintf( pFile, " .clk( %s ),", "1\'b0" );
fprintf( pFile, " .arst( %s ),", "1\'b0" );
if ( p->vInits )
diff --git a/src/bdd/extrab/extraBddMisc.c b/src/bdd/extrab/extraBddMisc.c
index a2ba4036..bc4d8a7a 100644
--- a/src/bdd/extrab/extraBddMisc.c
+++ b/src/bdd/extrab/extraBddMisc.c
@@ -2333,6 +2333,255 @@ void Extra_zddDumpPla( DdManager * dd, DdNode * F, int nVars, char * pFileName )
ABC_FREE( pCube );
}
+/**Function*************************************************************
+
+ Synopsis [Constructing ZDD of a graph.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Extra_GraphExperiment()
+{
+ int Edges[5][5] = {
+ {1, 3, 4},
+ {1, 5},
+ {2, 3, 5},
+ {2, 4}
+ };
+ int e, n;
+
+ DdManager * dd = Cudd_Init( 0, 6, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
+
+ // create the edges
+ DdNode * zGraph, * zEdge, * zVar, * zTemp;
+ zGraph = DD_ZERO(dd); Cudd_Ref( zGraph );
+ for ( e = 0; Edges[e][0]; e++ )
+ {
+ zEdge = DD_ONE(dd); Cudd_Ref( zEdge );
+ for ( n = 0; Edges[e][n]; n++ )
+ {
+ zVar = cuddZddGetNode( dd, Edges[e][n], DD_ONE(dd), DD_ZERO(dd) ); Cudd_Ref( zVar );
+ zEdge = Cudd_zddUnateProduct( dd, zTemp = zEdge, zVar ); Cudd_Ref( zEdge );
+ Cudd_RecursiveDerefZdd( dd, zTemp );
+ Cudd_RecursiveDerefZdd( dd, zVar );
+ }
+ zGraph = Cudd_zddUnion( dd, zTemp = zGraph, zEdge ); Cudd_Ref( zGraph );
+ Cudd_RecursiveDerefZdd( dd, zTemp );
+ Cudd_RecursiveDerefZdd( dd, zEdge );
+ }
+
+ Cudd_zddPrintMinterm( dd, zGraph );
+
+ Cudd_RecursiveDerefZdd( dd, zGraph );
+ Cudd_Quit(dd);
+}
+
+
+
+
+/**Function********************************************************************
+
+ Synopsis [Performs the reordering-sensitive step of Extra_zddCombination().]
+
+ Description [Generates in a bottom-up fashion ZDD for one combination
+ whose var values are given in the array VarValues. If necessary,
+ creates new variables on the fly.]
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+DdNode * extraZddCombination(
+ DdManager* dd,
+ int* VarValues,
+ int nVars )
+{
+ int lev, index;
+ DdNode *zRes, *zTemp;
+
+ /* transform the combination from the array VarValues into a ZDD cube. */
+ zRes = dd->one;
+ cuddRef(zRes);
+
+ /* go through levels starting bottom-up and create nodes
+ * if these variables are present in the comb
+ */
+ for (lev = nVars - 1; lev >= 0; lev--)
+ {
+ index = (lev >= dd->sizeZ) ? lev : dd->invpermZ[lev];
+ if (VarValues[index] == 1)
+ {
+ /* compose zRes with ZERO for the given ZDD variable */
+ zRes = cuddZddGetNode( dd, index, zTemp = zRes, dd->zero );
+ if ( zRes == NULL )
+ {
+ Cudd_RecursiveDerefZdd( dd, zTemp );
+ return NULL;
+ }
+ cuddRef( zRes );
+ cuddDeref( zTemp );
+ }
+ }
+ cuddDeref( zRes );
+ return zRes;
+
+} /* end of extraZddCombination */
+
+/**Function********************************************************************
+
+ Synopsis [Creates ZDD of the combination containing given variables.]
+
+ Description [Creates ZDD of the combination containing given variables.
+ VarValues contains 1 for a variable that belongs to the
+ combination and 0 for a varible that does not belong.
+ nVars is number of ZDD variables in the array.]
+
+ SideEffects [New ZDD variables are created if indices of the variables
+ present in the combination are larger than the currently
+ allocated number of ZDD variables.]
+
+ SeeAlso []
+
+******************************************************************************/
+DdNode * Extra_zddCombination(
+ DdManager *dd,
+ int* VarValues,
+ int nVars )
+{
+ DdNode *res;
+ do {
+ dd->reordered = 0;
+ res = extraZddCombination(dd, VarValues, nVars);
+ } while (dd->reordered == 1);
+ return(res);
+
+} /* end of Extra_zddCombination */
+
+/**Function********************************************************************
+
+ Synopsis [Generates a random set of combinations.]
+
+ Description [Given a set of n elements, each of which is encoded using one
+ ZDD variable, this function generates a random set of k subsets
+ (combinations of elements) with density d. Assumes that k and n
+ are positive integers. Returns NULL if density is less than 0.0
+ or more than 1.0.]
+
+ SideEffects [Allocates new ZDD variables if their current number is less than n.]
+
+ SeeAlso []
+
+******************************************************************************/
+DdNode* Extra_zddRandomSet(
+ DdManager * dd, /* the DD manager */
+ int n, /* the number of elements */
+ int k, /* the number of combinations (subsets) */
+ double d) /* average density of elements in combinations */
+{
+ DdNode *Result, *TempComb, *Aux;
+ int c, v, Limit, *VarValues;
+
+ /* sanity check the parameters */
+ if ( n <= 0 || k <= 0 || d < 0.0 || d > 1.0 )
+ return NULL;
+
+ /* allocate temporary storage for variable values */
+ VarValues = ABC_ALLOC( int, n );
+ if (VarValues == NULL)
+ {
+ dd->errorCode = CUDD_MEMORY_OUT;
+ return NULL;
+ }
+
+ /* start the new set */
+ Result = dd->zero;
+ Cudd_Ref( Result );
+
+ /* seed random number generator */
+ Cudd_Srandom( time(NULL) );
+// Cudd_Srandom( 4 );
+ /* determine the limit below which var belongs to the combination */
+ Limit = (int)(d * 2147483561.0);
+
+ /* add combinations one by one */
+ for ( c = 0; c < k; c++ )
+ {
+ for ( v = 0; v < n; v++ )
+ if ( Cudd_Random() <= Limit )
+ VarValues[v] = 1;
+ else
+ VarValues[v] = 0;
+
+ TempComb = Extra_zddCombination( dd, VarValues, n );
+ Cudd_Ref( TempComb );
+
+ /* make sure that this combination is not already in the set */
+ if ( c )
+ { /* at least one combination is already included */
+
+ Aux = Cudd_zddDiff( dd, Result, TempComb );
+ Cudd_Ref( Aux );
+ if ( Aux != Result )
+ {
+ Cudd_RecursiveDerefZdd( dd, Aux );
+ Cudd_RecursiveDerefZdd( dd, TempComb );
+ c--;
+ continue;
+ }
+ else
+ { /* Aux is the same node as Result */
+ Cudd_Deref( Aux );
+ }
+ }
+
+ Result = Cudd_zddUnion( dd, Aux = Result, TempComb );
+ Cudd_Ref( Result );
+ Cudd_RecursiveDerefZdd( dd, Aux );
+ Cudd_RecursiveDerefZdd( dd, TempComb );
+ }
+
+ ABC_FREE( VarValues );
+ Cudd_Deref( Result );
+ return Result;
+
+} /* end of Extra_zddRandomSet */
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+void Extra_ZddTest()
+{
+ int N = 64;
+ int K0 = 1000;
+ int i, Size;
+ DdManager * dd = Cudd_Init( 0, 32, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
+ for ( i = 1; i <= 10; i++ )
+ {
+ int K = K0 * i;
+ DdNode * zRandSet = Extra_zddRandomSet( dd, N, K, 0.5 ); Cudd_Ref(zRandSet);
+ Size = Cudd_zddDagSize(zRandSet);
+ //Cudd_zddPrintMinterm( dd, zRandSet );
+ printf( "N = %5d K = %5d BddSize = %6d MemBdd = %8.3f MB MemBit = %8.3f MB Ratio = %8.3f %%\n",
+ N, K, Size, 20.0*Size/(1<<20), 0.125 * N * K /(1<<20), 100.0*(0.125 * N * K)/(20.0*Size) );
+ Cudd_RecursiveDerefZdd( dd, zRandSet );
+ }
+ Cudd_Quit(dd);
+}
+
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/map/if/ifDec16.c b/src/map/if/ifDec16.c
index 22de91ba..4b555bf8 100644
--- a/src/map/if/ifDec16.c
+++ b/src/map/if/ifDec16.c
@@ -902,7 +902,7 @@ void If_CluReverseOrder_old( word * pF, int nVars, int * V2P, int * P2V, int iVa
// return the number of cofactors w.r.t. the topmost vars (nBSsize)
int If_CluCountCofs( word * pF, int nVars, int nBSsize, int iShift, word pCofs[3][CLU_WRD_MAX/4] )
{
- word iCofs[128], iCof, Result = 0;
+ word iCofs[128] = {0}, iCof, Result = 0;
word * pCofA, * pCofB;
int nMints = (1 << nBSsize);
int i, c, w, nCofs;
diff --git a/src/map/if/ifLibLut.c b/src/map/if/ifLibLut.c
index 26fa137b..1033cc1f 100644
--- a/src/map/if/ifLibLut.c
+++ b/src/map/if/ifLibLut.c
@@ -75,6 +75,7 @@ If_LibLut_t * If_LibLutRead( char * FileName )
Abc_Print( 1, "Error in the LUT library file \"%s\".\n", FileName );
ABC_FREE( p->pName );
ABC_FREE( p );
+ fclose( pFile );
return NULL;
}
@@ -93,6 +94,7 @@ If_LibLut_t * If_LibLutRead( char * FileName )
ABC_FREE( p->pName );
ABC_FREE( p );
Abc_Print( 1, "LUT %d has too many pins (%d). Max allowed is %d.\n", i, k, i );
+ fclose( pFile );
return NULL;
}
@@ -105,6 +107,7 @@ If_LibLut_t * If_LibLutRead( char * FileName )
ABC_FREE( p->pName );
ABC_FREE( p );
Abc_Print( 1, "Skipping LUTs of size more than %d.\n", i );
+ fclose( pFile );
return NULL;
}
i++;
@@ -136,6 +139,7 @@ If_LibLut_t * If_LibLutRead( char * FileName )
}
}
+ fclose( pFile );
return p;
}
diff --git a/src/map/mio/mioUtils.c b/src/map/mio/mioUtils.c
index 7572b27c..428eb92b 100644
--- a/src/map/mio/mioUtils.c
+++ b/src/map/mio/mioUtils.c
@@ -569,7 +569,7 @@ Mio_Cell_t * Mio_CollectRootsNew( Mio_Library_t * pLib, int nInputs, int * pnGat
if ( ppCells[3].pName == NULL )
{ printf( "Error: Cannot find inverter gate in the library.\n" ); return NULL; }
// sort by delay
- if ( iCell > 1 )
+ if ( iCell > 5 )
{
qsort( (void *)(ppCells + 4), iCell - 4, sizeof(Mio_Cell_t),
(int (*)(const void *, const void *)) Mio_AreaCompare );
@@ -726,7 +726,7 @@ Mio_Cell2_t * Mio_CollectRootsNew2( Mio_Library_t * pLib, int nInputs, int * pnG
if ( ppCells[3].pName == NULL )
{ printf( "Error: Cannot find inverter gate in the library.\n" ); return NULL; }
// sort by delay
- if ( iCell > 1 )
+ if ( iCell > 5 )
{
qsort( (void *)(ppCells + 4), iCell - 4, sizeof(Mio_Cell2_t),
(int (*)(const void *, const void *)) Mio_AreaCompare2 );
diff --git a/src/map/scl/scl.c b/src/map/scl/scl.c
index bd6d1cea..9d4653a7 100644
--- a/src/map/scl/scl.c
+++ b/src/map/scl/scl.c
@@ -259,7 +259,7 @@ usage:
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-v : toggle writing verbose information [default = %s]\n", fVerbose? "yes": "no" );
- fprintf( pAbc->Err, "\t-v : toggle writing information about skipped gates [default = %s]\n", fVeryVerbose? "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" );
fprintf( pAbc->Err, "\t<file> : the name of a file to read\n" );
return 1;
diff --git a/src/map/scl/sclLiberty.c b/src/map/scl/sclLiberty.c
index 50e69d08..b48cfbe1 100644
--- a/src/map/scl/sclLiberty.c
+++ b/src/map/scl/sclLiberty.c
@@ -509,7 +509,7 @@ char * Scl_LibertyFileContents( char * pFileName, int nContents )
{
FILE * pFile = fopen( pFileName, "rb" );
char * pContents = ABC_ALLOC( char, nContents+1 );
- int RetValue;
+ int RetValue = 0;
RetValue = fread( pContents, nContents, 1, pFile );
fclose( pFile );
pContents[nContents] = 0;
@@ -518,7 +518,7 @@ char * Scl_LibertyFileContents( char * pFileName, int nContents )
void Scl_LibertyStringDump( char * pFileName, Vec_Str_t * vStr )
{
FILE * pFile = fopen( pFileName, "wb" );
- int RetValue;
+ int RetValue = 0;
if ( pFile == NULL )
{
printf( "Scl_LibertyStringDump(): The output file is unavailable.\n" );
@@ -583,7 +583,7 @@ Scl_Tree_t * Scl_LibertyParse( char * pFileName, int fVerbose )
return NULL;
pPos = p->pContents;
Scl_LibertyWipeOutComments( p->pContents, p->pContents+p->nContents );
- if ( !Scl_LibertyBuildItem( p, &pPos, p->pContents + p->nContents ) == 0 )
+ if ( (!Scl_LibertyBuildItem( p, &pPos, p->pContents + p->nContents )) == 0 )
{
if ( p->pError ) printf( "%s", p->pError );
printf( "Parsing failed. " );
@@ -765,10 +765,10 @@ Vec_Str_t * Scl_LibertyParseGenlibStr( char * pFileName, int fVerbose )
***********************************************************************/
//#define SCL_DEBUG
#ifdef SCL_DEBUG
-static inline void Vec_StrPutI_( Vec_Str_t * vOut, int Val ) { printf( "%d ", Val ); Vec_StrPutI( vOut, Val ); }
-static inline void Vec_StrPutW_( Vec_Str_t * vOut, word Val ) { printf( "%lu ", Val ); Vec_StrPutW( vOut, Val ); }
-static inline void Vec_StrPutF_( Vec_Str_t * vOut, float Val ) { printf( "%f ", Val ); Vec_StrPutF( vOut, Val ); }
-static inline void Vec_StrPutS_( Vec_Str_t * vOut, char * Val ) { printf( "%s ", Val ); Vec_StrPutS( vOut, Val ); }
+static inline void Vec_StrPutI_( Vec_Str_t * vOut, int Val ) { printf( "%d ", Val ); Vec_StrPutI( vOut, Val ); }
+static inline void Vec_StrPutW_( Vec_Str_t * vOut, word Val ) { printf( "%lu ", (long)Val ); Vec_StrPutW( vOut, Val ); }
+static inline void Vec_StrPutF_( Vec_Str_t * vOut, float Val ) { printf( "%f ", Val ); Vec_StrPutF( vOut, Val ); }
+static inline void Vec_StrPutS_( Vec_Str_t * vOut, char * Val ) { printf( "%s ", Val ); Vec_StrPutS( vOut, Val ); }
static inline void Vec_StrPut_( Vec_Str_t * vOut ) { printf( "\n" ); }
#else
static inline void Vec_StrPutI_( Vec_Str_t * vOut, int Val ) { Vec_StrPutI( vOut, Val ); }
diff --git a/src/misc/extra/extraUtilUtil.c b/src/misc/extra/extraUtilUtil.c
index 253d9e3c..2f0f4559 100644
--- a/src/misc/extra/extraUtilUtil.c
+++ b/src/misc/extra/extraUtilUtil.c
@@ -102,35 +102,45 @@ int Extra_UtilGetopt( int argc, char *argv[], const char *optstring )
globalUtilOptarg = NULL;
- if (pScanStr == NULL || *pScanStr == '\0') {
- if (globalUtilOptind == 0) globalUtilOptind++;
- if (globalUtilOptind >= argc) return EOF;
- place = argv[globalUtilOptind];
- if (place[0] != '-' || place[1] == '\0') return EOF;
- globalUtilOptind++;
- if (place[1] == '-' && place[2] == '\0') return EOF;
- pScanStr = place+1;
+ if (pScanStr == NULL || *pScanStr == '\0')
+ {
+ if (globalUtilOptind == 0)
+ globalUtilOptind++;
+ if (globalUtilOptind >= argc)
+ return EOF;
+ place = argv[globalUtilOptind];
+ if (place[0] != '-' || place[1] == '\0')
+ return EOF;
+ globalUtilOptind++;
+ if (place[1] == '-' && place[2] == '\0')
+ return EOF;
+ pScanStr = place+1;
}
c = *pScanStr++;
place = strchr(optstring, c);
if (place == NULL || c == ':') {
- (void) fprintf(stderr, "%s: unknown option %c\n", argv[0], c);
- return '?';
- }
- if (*++place == ':') {
- if (*pScanStr != '\0') {
- globalUtilOptarg = pScanStr;
- pScanStr = NULL;
- } else {
- if (globalUtilOptind >= argc) {
- (void) fprintf(stderr, "%s: %c requires an argument\n",
- argv[0], c);
+ (void) fprintf(stderr, "%s: unknown option %c\n", argv[0], c);
return '?';
- }
- globalUtilOptarg = argv[globalUtilOptind];
- globalUtilOptind++;
}
+ if (*++place == ':')
+ {
+ if (*pScanStr != '\0')
+ {
+ globalUtilOptarg = pScanStr;
+ pScanStr = NULL;
+ }
+ else
+ {
+ if (globalUtilOptind >= argc)
+ {
+ (void) fprintf(stderr, "%s: %c requires an argument\n",
+ argv[0], c);
+ return '?';
+ }
+ globalUtilOptarg = argv[globalUtilOptind];
+ globalUtilOptind++;
+ }
}
return c;
}
diff --git a/src/misc/util/abc_global.h b/src/misc/util/abc_global.h
index 00d5d514..9e906816 100644
--- a/src/misc/util/abc_global.h
+++ b/src/misc/util/abc_global.h
@@ -225,6 +225,8 @@ static inline double Abc_MinDouble( double a, double b ) { return a < b ?
static inline int Abc_Float2Int( float Val ) { union { int x; float y; } v; v.y = Val; return v.x; }
static inline float Abc_Int2Float( int Num ) { union { int x; float y; } v; v.x = Num; return v.y; }
+static inline word Abc_Dbl2Word( double Dbl ) { union { word x; double y; } v; v.y = Dbl; return v.x; }
+static inline double Abc_Word2Dbl( word Num ) { union { word x; double y; } v; v.x = Num; return v.y; }
static inline int Abc_Base2Log( unsigned n ) { int r; if ( n < 2 ) return n; for ( r = 0, n--; n; n >>= 1, r++ ) {}; return r; }
static inline int Abc_Base10Log( unsigned n ) { int r; if ( n < 2 ) return n; for ( r = 0, n--; n; n /= 10, r++ ) {}; return r; }
static inline int Abc_Base16Log( unsigned n ) { int r; if ( n < 2 ) return n; for ( r = 0, n--; n; n /= 16, r++ ) {}; return r; }
diff --git a/src/misc/util/utilCex.c b/src/misc/util/utilCex.c
index 3acd7f77..59107dc9 100644
--- a/src/misc/util/utilCex.c
+++ b/src/misc/util/utilCex.c
@@ -272,9 +272,9 @@ void Abc_CexPrintStats( Abc_Cex_t * p )
p->iPo, p->iFrame, p->nRegs, p->nPis, p->nBits,
Counter, 100.0 * Counter / (p->nBits - p->nRegs) );
}
-void Abc_CexPrintStatsInputs( Abc_Cex_t * p, int nInputs )
+void Abc_CexPrintStatsInputs( Abc_Cex_t * p, int nRealPis )
{
- int k, Counter = 0, Counter2 = 0;
+ int k, Counter = 0, CounterPi = 0, CounterPpi = 0;
if ( p == NULL )
{
printf( "The counter example is NULL.\n" );
@@ -285,16 +285,27 @@ void Abc_CexPrintStatsInputs( Abc_Cex_t * p, int nInputs )
printf( "The counter example is present but not available (pointer has value \"1\").\n" );
return;
}
+ assert( nRealPis <= p->nPis );
for ( k = 0; k < p->nBits; k++ )
{
Counter += Abc_InfoHasBit(p->pData, k);
- if ( (k - p->nRegs) % p->nPis < nInputs )
- Counter2 += Abc_InfoHasBit(p->pData, k);
+ if ( nRealPis == p->nPis )
+ continue;
+ if ( (k - p->nRegs) % p->nPis < nRealPis )
+ CounterPi += Abc_InfoHasBit(p->pData, k);
+ else
+ CounterPpi += Abc_InfoHasBit(p->pData, k);
}
- printf( "CEX: Po =%4d Frame =%4d FF = %d PI = %d Bit =%8d 1s =%8d (%5.2f %%) 1sIn =%8d (%5.2f %%)\n",
+ printf( "CEX: Po =%4d Fr =%4d FF = %d PI = %d Bit =%7d 1 =%8d (%5.2f %%)",
p->iPo, p->iFrame, p->nRegs, p->nPis, p->nBits,
- Counter, 100.0 * Counter / (p->nBits - p->nRegs),
- Counter2, 100.0 * Counter2 / (p->nBits - p->nRegs - (p->iFrame + 1) * (p->nPis - nInputs)) );
+ Counter, 100.0 * Counter / ((p->iFrame + 1) * p->nPis ) );
+ if ( nRealPis < p->nPis )
+ {
+ printf( " 1pi =%8d (%5.2f %%) 1ppi =%8d (%5.2f %%)",
+ CounterPi, 100.0 * CounterPi / ((p->iFrame + 1) * nRealPis ),
+ CounterPpi, 100.0 * CounterPpi / ((p->iFrame + 1) * (p->nPis - nRealPis)) );
+ }
+ printf( "\n" );
}
/**Function*************************************************************
diff --git a/src/misc/util/utilDouble.h b/src/misc/util/utilDouble.h
new file mode 100644
index 00000000..0d023781
--- /dev/null
+++ b/src/misc/util/utilDouble.h
@@ -0,0 +1,222 @@
+/**CFile****************************************************************
+
+ FileName [utilDouble.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName []
+
+ Synopsis [Double floating point number implementation.]
+
+ Author [Alan Mishchenko, Bruno Schmitt]
+
+ Affiliation [UC Berkeley / UFRGS]
+
+ Date [Ver. 1.0. Started - February 11, 2017.]
+
+ Revision []
+
+***********************************************************************/
+
+#ifndef ABC__sat__Xdbl__Xdbl_h
+#define ABC__sat__Xdbl__Xdbl_h
+
+#include "misc/util/abc_global.h"
+
+ABC_NAMESPACE_HEADER_START
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*
+ The xdbl floating-point number is represented as a 64-bit unsigned int.
+ The number is (2^Exp)*Mnt, where Exp is a 16-bit exponent and Mnt is a
+ 48-bit mantissa. The decimal point is located between the MSB of Mnt,
+ which is always 1, and the remaining 15 digits of Mnt.
+
+ Currently, only positive numbers are represented.
+
+ The range of possible values is [1.0; 2^(2^16-1)*1.111111111111111]
+ that is, the smallest possible number is 1.0 and the largest possible
+ number is 2^(---16 ones---).(1.---47 ones---)
+
+ Comparison of numbers can be done by comparing the underlying unsigned ints.
+
+ Only addition, multiplication, and division by 2^n are currently implemented.
+*/
+
+typedef word xdbl;
+
+static inline word Xdbl_Exp( xdbl a ) { return a >> 48; }
+static inline word Xdbl_Mnt( xdbl a ) { return (a << 16) >> 16; }
+
+static inline xdbl Xdbl_Create( word Exp, word Mnt ) { assert(!(Exp>>16) && (Mnt>>47)==(word)1); return (Exp<<48) | Mnt; }
+
+static inline xdbl Xdbl_Const1() { return Xdbl_Create( (word)0, (word)1 << 47 ); }
+static inline xdbl Xdbl_Const2() { return Xdbl_Create( (word)1, (word)1 << 47 ); }
+static inline xdbl Xdbl_Const3() { return Xdbl_Create( (word)1, (word)3 << 46 ); }
+static inline xdbl Xdbl_Const12() { return Xdbl_Create( (word)3, (word)3 << 46 ); }
+static inline xdbl Xdbl_Const1point5() { return Xdbl_Create( (word)0, (word)3 << 46 ); }
+static inline xdbl Xdbl_Const2point5() { return Xdbl_Create( (word)1, (word)5 << 45 ); }
+static inline xdbl Xdbl_Maximum() { return ~(word)0; }
+
+static inline double Xdbl_ToDouble( xdbl a ) { assert(Xdbl_Exp(a) < 1023); return Abc_Word2Dbl(((Xdbl_Exp(a) + 1023) << 52) | (((a<<17)>>17) << 5)); }
+static inline xdbl Xdbl_FromDouble( double a ) { word A = Abc_Dbl2Word(a); assert(a >= 1.0); return Xdbl_Create((A >> 52)-1023, (((word)1) << 47) | ((A << 12) >> 17)); }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Adding two floating-point numbers.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline xdbl Xdbl_Add( xdbl a, xdbl b )
+{
+ word Exp, Mnt;
+ if ( a < b ) a ^= b, b ^= a, a ^= b;
+ assert( a >= b );
+ Mnt = Xdbl_Mnt(a) + (Xdbl_Mnt(b) >> (Xdbl_Exp(a) - Xdbl_Exp(b)));
+ Exp = Xdbl_Exp(a);
+ if ( Mnt >> 48 ) // new MSB is created
+ Exp++, Mnt >>= 1;
+ if ( Exp >> 16 ) // overflow
+ return Xdbl_Maximum();
+ return Xdbl_Create( Exp, Mnt );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Multiplying two floating-point numbers.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline xdbl Xdbl_Mul( xdbl a, xdbl b )
+{
+ word Exp, Mnt, MntA, MntB, MntAh, MntBh, MntAl, MntBl;
+ if ( a < b ) a ^= b, b ^= a, a ^= b;
+ assert( a >= b );
+ MntA = Xdbl_Mnt(a);
+ MntB = Xdbl_Mnt(b);
+ MntAh = MntA>>32;
+ MntBh = MntB>>32;
+ MntAl = (MntA<<32)>>32;
+ MntBl = (MntB<<32)>>32;
+ Mnt = ((MntAh * MntBh) << 17) + ((MntAl * MntBl) >> 47) + ((MntAl * MntBh) >> 15) + ((MntAh * MntBl) >> 15);
+ Exp = Xdbl_Exp(a) + Xdbl_Exp(b);
+ if ( Mnt >> 48 ) // new MSB is created
+ Exp++, Mnt >>= 1;
+ if ( Exp >> 16 ) // overflow
+ return Xdbl_Maximum();
+ return Xdbl_Create( Exp, Mnt );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Dividing floating point number by a degree of 2.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline xdbl Xdbl_Div( xdbl a, unsigned Deg2 )
+{
+ if ( Xdbl_Exp(a) >= (word)Deg2 )
+ return Xdbl_Create( Xdbl_Exp(a) - Deg2, Xdbl_Mnt(a) );
+ return Xdbl_Const1(); // underflow
+}
+
+/**Function*************************************************************
+
+ Synopsis [Testing procedure.]
+
+ Description [Helpful link https://www.h-schmidt.net/FloatConverter/IEEE754.html]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Xdbl_Test()
+{
+ xdbl c1 = Xdbl_Const1();
+ xdbl c2 = Xdbl_Const2();
+ xdbl c3 = Xdbl_Const3();
+ xdbl c12 = Xdbl_Const12();
+ xdbl c1p5 = Xdbl_Const1point5();
+ xdbl c2p5 = Xdbl_Const2point5();
+
+ xdbl c1_ = Xdbl_FromDouble(1.0);
+ xdbl c2_ = Xdbl_FromDouble(2.0);
+ xdbl c3_ = Xdbl_FromDouble(3.0);
+ xdbl c12_ = Xdbl_FromDouble(12.0);
+ xdbl c1p5_ = Xdbl_FromDouble(1.5);
+ xdbl c2p5_ = Xdbl_FromDouble(2.5);
+
+ xdbl sum1 = Xdbl_Add(c1, c1p5);
+ xdbl mul1 = Xdbl_Mul(c2, c1p5);
+
+ xdbl sum2 = Xdbl_Add(c1p5, c2p5);
+ xdbl mul2 = Xdbl_Mul(c1p5, c2p5);
+
+ xdbl a = Xdbl_FromDouble(1.2929725);
+ xdbl b = Xdbl_FromDouble(10.28828287);
+ xdbl ab = Xdbl_Mul(a, b);
+
+ xdbl ten100 = Xdbl_FromDouble( 1e100 );
+ xdbl ten100_ = ABC_CONST(0x014c924d692ca61b);
+
+ assert( ten100 == ten100_ );
+
+// float f1 = Xdbl_ToDouble(c1);
+// Extra_PrintBinary( stdout, (int *)&c1, 32 ); printf( "\n" );
+// Extra_PrintBinary( stdout, (int *)&f1, 32 ); printf( "\n" );
+
+ printf( "1 = %lf\n", Xdbl_ToDouble(c1) );
+ printf( "2 = %lf\n", Xdbl_ToDouble(c2) );
+ printf( "3 = %lf\n", Xdbl_ToDouble(c3) );
+ printf( "12 = %lf\n", Xdbl_ToDouble(c12) );
+ printf( "1.5 = %lf\n", Xdbl_ToDouble(c1p5) );
+ printf( "2.5 = %lf\n", Xdbl_ToDouble(c2p5) );
+
+ printf( "Converted 1 = %lf\n", Xdbl_ToDouble(c1_) );
+ printf( "Converted 2 = %lf\n", Xdbl_ToDouble(c2_) );
+ printf( "Converted 3 = %lf\n", Xdbl_ToDouble(c3_) );
+ printf( "Converted 12 = %lf\n", Xdbl_ToDouble(c12_) );
+ printf( "Converted 1.5 = %lf\n", Xdbl_ToDouble(c1p5_) );
+ printf( "Converted 2.5 = %lf\n", Xdbl_ToDouble(c2p5_) );
+
+ printf( "1.0 + 1.5 = %lf\n", Xdbl_ToDouble(sum1) );
+ printf( "2.0 * 1.5 = %lf\n", Xdbl_ToDouble(mul1) );
+
+ printf( "1.5 + 2.5 = %lf\n", Xdbl_ToDouble(sum2) );
+ printf( "1.5 * 2.5 = %lf\n", Xdbl_ToDouble(mul2) );
+ printf( "12 / 2^2 = %lf\n", Xdbl_ToDouble(Xdbl_Div(c12, 2)) );
+
+ printf( "12 / 2^2 = %lf\n", Xdbl_ToDouble(Xdbl_Div(c12, 2)) );
+
+ printf( "%.16lf * %.16lf = %.16lf (%.16lf)\n", Xdbl_ToDouble(a), Xdbl_ToDouble(b), Xdbl_ToDouble(ab), 1.2929725 * 10.28828287 );
+
+ assert( sum1 == c2p5 );
+ assert( mul1 == c3 );
+}
+
+ABC_NAMESPACE_HEADER_END
+
+#endif
diff --git a/src/misc/util/utilFloat.h b/src/misc/util/utilFloat.h
new file mode 100644
index 00000000..f0739a92
--- /dev/null
+++ b/src/misc/util/utilFloat.h
@@ -0,0 +1,226 @@
+/**CFile****************************************************************
+
+ FileName [utilFloat.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName []
+
+ Synopsis [Floating point number implementation.]
+
+ Author [Alan Mishchenko, Bruno Schmitt]
+
+ Affiliation [UC Berkeley / UFRGS]
+
+ Date [Ver. 1.0. Started - January 28, 2017.]
+
+ Revision []
+
+***********************************************************************/
+#ifndef ABC__sat__xSAT__xsatFloat_h
+#define ABC__sat__xSAT__xsatFloat_h
+
+#include "misc/util/abc_global.h"
+
+ABC_NAMESPACE_HEADER_START
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*
+ The xFloat_t floating-point number is represented as a 32-bit unsigned int.
+ The number is (2^Exp)*Mnt, where Exp is a 16-bit exponent and Mnt is a
+ 16-bit mantissa. The decimal point is located between the MSB of Mnt,
+ which is always 1, and the remaining 15 digits of Mnt.
+
+ Currently, only positive numbers are represented.
+
+ The range of possible values is [1.0; 2^(2^16-1)*1.111111111111111]
+ that is, the smallest possible number is 1.0 and the largest possible
+ number is 2^(---16 ones---).(1.---15 ones---)
+
+ Comparison of numbers can be done by comparing the underlying unsigned ints.
+
+ Only addition, multiplication, and division by 2^n are currently implemented.
+*/
+
+typedef struct xFloat_t_ xFloat_t;
+struct xFloat_t_
+{
+ unsigned Mnt : 16;
+ unsigned Exp : 16;
+};
+
+static inline unsigned xSat_Float2Uint( xFloat_t f ) { union { xFloat_t f; unsigned u; } temp; temp.f = f; return temp.u; }
+static inline xFloat_t xSat_Uint2Float( unsigned u ) { union { xFloat_t f; unsigned u; } temp; temp.u = u; return temp.f; }
+static inline int xSat_LessThan( xFloat_t a, xFloat_t b ) { return a.Exp < b.Exp || (a.Exp == b.Exp && a.Mnt < b.Mnt); }
+static inline int xSat_Equal( xFloat_t a, xFloat_t b ) { return a.Exp == b.Exp && a.Mnt == b.Mnt; }
+
+static inline xFloat_t xSat_FloatCreate( unsigned Exp, unsigned Mnt ) { xFloat_t res; res.Exp = Exp; res.Mnt = Mnt; return res; }
+
+static inline xFloat_t xSat_FloatCreateConst1() { return xSat_FloatCreate( 0, 1 << 15 ); }
+static inline xFloat_t xSat_FloatCreateConst2() { return xSat_FloatCreate( 1, 1 << 15 ); }
+static inline xFloat_t xSat_FloatCreateConst3() { return xSat_FloatCreate( 1, 3 << 14 ); }
+static inline xFloat_t xSat_FloatCreateConst12() { return xSat_FloatCreate( 3, 3 << 14 ); }
+static inline xFloat_t xSat_FloatCreateConst1point5() { return xSat_FloatCreate( 0, 3 << 14 ); }
+static inline xFloat_t xSat_FloatCreateConst2point5() { return xSat_FloatCreate( 1, 5 << 13 ); }
+static inline xFloat_t xSat_FloatCreateMaximum() { return xSat_Uint2Float( 0xFFFFFFFF ); }
+
+static inline float xSat_Float2Float( xFloat_t a ) { assert(a.Exp < 127); return Abc_Int2Float(((a.Exp + 127) << 23) | ((a.Mnt & 0x7FFF) << 8)); }
+static inline xFloat_t xSat_FloatFromFloat( float a ) { int A = Abc_Float2Int(a); assert(a >= 1.0); return xSat_FloatCreate((A >> 23)-127, 0x8000 | ((A >> 8) & 0x7FFF)); }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Adding two floating-point numbers.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline xFloat_t xSat_FloatAdd( xFloat_t a, xFloat_t b )
+{
+ unsigned Exp, Mnt;
+ if ( a.Exp < b.Exp )
+ return xSat_FloatAdd(b, a);
+ assert( a.Exp >= b.Exp );
+ // compute new mantissa
+ Mnt = a.Mnt + (b.Mnt >> (a.Exp - b.Exp));
+ // compute new exponent
+ Exp = a.Exp;
+ // update exponent and mantissa if new MSB is created
+ if ( Mnt & 0xFFFF0000 ) // new MSB bit is created
+ Exp++, Mnt >>= 1;
+ // check overflow
+ if ( Exp & 0xFFFF0000 ) // overflow
+ return xSat_Uint2Float( 0xFFFFFFFF );
+ assert( (Exp & 0xFFFF0000) == 0 );
+ assert( (Mnt & 0xFFFF0000) == 0 );
+ assert( Mnt & 0x00008000 );
+ return xSat_FloatCreate( Exp, Mnt );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Multiplying two floating-point numbers.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline xFloat_t xSat_FloatMul( xFloat_t a, xFloat_t b )
+{
+ unsigned Exp, Mnt;
+ if ( a.Exp < b.Exp )
+ return xSat_FloatMul(b, a);
+ assert( a.Exp >= b.Exp );
+ // compute new mantissa
+ Mnt = (a.Mnt * b.Mnt) >> 15;
+ // compute new exponent
+ Exp = a.Exp + b.Exp;
+ // update exponent and mantissa if new MSB is created
+ if ( Mnt & 0xFFFF0000 ) // new MSB bit is created
+ Exp++, Mnt >>= 1;
+ // check overflow
+ if ( Exp & 0xFFFF0000 ) // overflow
+ return xSat_Uint2Float( 0xFFFFFFFF );
+ assert( (Exp & 0xFFFF0000) == 0 );
+ assert( (Mnt & 0xFFFF0000) == 0 );
+ assert( Mnt & 0x00008000 );
+ return xSat_FloatCreate( Exp, Mnt );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Dividing floating point number by a degree of 2.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline xFloat_t xSat_FloatDiv( xFloat_t a, unsigned Deg2 )
+{
+ assert( Deg2 < 0xFFFF );
+ if ( a.Exp >= Deg2 )
+ return xSat_FloatCreate( a.Exp - Deg2, a.Mnt );
+ return xSat_FloatCreateConst1(); // underflow
+}
+
+/**Function*************************************************************
+
+ Synopsis [Testing procedure.]
+
+ Description [Helpful link https://www.h-schmidt.net/FloatConverter/IEEE754.html]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSat_FloatTest()
+{
+ xFloat_t c1 = xSat_FloatCreateConst1();
+ xFloat_t c2 = xSat_FloatCreateConst2();
+ xFloat_t c3 = xSat_FloatCreateConst3();
+ xFloat_t c12 = xSat_FloatCreateConst12();
+ xFloat_t c1p5 = xSat_FloatCreateConst1point5();
+ xFloat_t c2p5 = xSat_FloatCreateConst2point5();
+
+ xFloat_t c1_ = xSat_FloatFromFloat(1.0);
+ xFloat_t c2_ = xSat_FloatFromFloat(2.0);
+ xFloat_t c3_ = xSat_FloatFromFloat(3.0);
+ xFloat_t c12_ = xSat_FloatFromFloat(12.0);
+ xFloat_t c1p5_ = xSat_FloatFromFloat(1.5);
+ xFloat_t c2p5_ = xSat_FloatFromFloat(2.5);
+
+ xFloat_t sum1 = xSat_FloatAdd(c1, c1p5);
+ xFloat_t mul1 = xSat_FloatMul(c2, c1p5);
+
+ xFloat_t sum2 = xSat_FloatAdd(c1p5, c2p5);
+ xFloat_t mul2 = xSat_FloatMul(c1p5, c2p5);
+
+// float f1 = xSat_Float2Float(c1);
+// Extra_PrintBinary( stdout, (int *)&c1, 32 ); printf( "\n" );
+// Extra_PrintBinary( stdout, (int *)&f1, 32 ); printf( "\n" );
+
+ printf( "1 = %f\n", xSat_Float2Float(c1) );
+ printf( "2 = %f\n", xSat_Float2Float(c2) );
+ printf( "3 = %f\n", xSat_Float2Float(c3) );
+ printf( "12 = %f\n", xSat_Float2Float(c12) );
+ printf( "1.5 = %f\n", xSat_Float2Float(c1p5) );
+ printf( "2.5 = %f\n", xSat_Float2Float(c2p5) );
+
+ printf( "Converted 1 = %f\n", xSat_Float2Float(c1_) );
+ printf( "Converted 2 = %f\n", xSat_Float2Float(c2_) );
+ printf( "Converted 3 = %f\n", xSat_Float2Float(c3_) );
+ printf( "Converted 12 = %f\n", xSat_Float2Float(c12_) );
+ printf( "Converted 1.5 = %f\n", xSat_Float2Float(c1p5_) );
+ printf( "Converted 2.5 = %f\n", xSat_Float2Float(c2p5_) );
+
+ printf( "1.0 + 1.5 = %f\n", xSat_Float2Float(sum1) );
+ printf( "2.0 * 1.5 = %f\n", xSat_Float2Float(mul1) );
+
+ printf( "1.5 + 2.5 = %f\n", xSat_Float2Float(sum2) );
+ printf( "1.5 * 2.5 = %f\n", xSat_Float2Float(mul2) );
+ printf( "12 / 2^2 = %f\n", xSat_Float2Float(xSat_FloatDiv(c12, 2)) );
+
+ assert( xSat_Equal(sum1, c2p5) );
+ assert( xSat_Equal(mul1, c3) );
+}
+
+ABC_NAMESPACE_HEADER_END
+
+#endif
diff --git a/src/misc/util/utilTruth.h b/src/misc/util/utilTruth.h
index b8a34da7..e04ffbc9 100644
--- a/src/misc/util/utilTruth.h
+++ b/src/misc/util/utilTruth.h
@@ -1631,6 +1631,14 @@ static inline int Abc_TtFindFirstBit( word * pIn, int nVars )
return 64*w + Abc_Tt6FirstBit(pIn[w]);
return -1;
}
+static inline int Abc_TtFindFirstBit2( word * pIn, int nWords )
+{
+ int w;
+ for ( w = 0; w < nWords; w++ )
+ if ( pIn[w] )
+ return 64*w + Abc_Tt6FirstBit(pIn[w]);
+ return -1;
+}
static inline int Abc_TtFindFirstDiffBit( word * pIn1, word * pIn2, int nVars )
{
int w, nWords = Abc_TtWordNum(nVars);
@@ -1639,6 +1647,14 @@ static inline int Abc_TtFindFirstDiffBit( word * pIn1, word * pIn2, int nVars )
return 64*w + Abc_Tt6FirstBit(pIn1[w] ^ pIn2[w]);
return -1;
}
+static inline int Abc_TtFindFirstDiffBit2( word * pIn1, word * pIn2, int nWords )
+{
+ int w;
+ for ( w = 0; w < nWords; w++ )
+ if ( pIn1[w] ^ pIn2[w] )
+ return 64*w + Abc_Tt6FirstBit(pIn1[w] ^ pIn2[w]);
+ return -1;
+}
static inline int Abc_TtFindFirstZero( word * pIn, int nVars )
{
int w, nWords = Abc_TtWordNum(nVars);
@@ -2612,7 +2628,7 @@ static inline int Abc_TtProcessBiDec( word * pTruth, int nVars, int nSuppLim )
static inline void Abc_TtProcessBiDecTest( word * pTruth, int nVars, int nSuppLim )
{
word This, That, pTemp[64];
- int Res, resThis, resThat, nThis, nThat;
+ int Res, resThis, resThat;//, nThis, nThat;
int nWords = Abc_TtWordNum(nVars);
Abc_TtCopy( pTemp, pTruth, nWords, 0 );
Res = Abc_TtProcessBiDec( pTemp, nVars, nSuppLim );
@@ -2634,8 +2650,8 @@ static inline void Abc_TtProcessBiDecTest( word * pTruth, int nVars, int nSuppLi
// Dau_DsdPrintFromTruth( pTemp, nVars );
- nThis = Abc_TtBitCount16(resThis);
- nThat = Abc_TtBitCount16(resThat);
+ //nThis = Abc_TtBitCount16(resThis);
+ //nThat = Abc_TtBitCount16(resThat);
printf( "Variable sets: " );
Abc_TtPrintVarSet( resThis, nVars );
diff --git a/src/misc/vec/vecInt.h b/src/misc/vec/vecInt.h
index f09b8783..d952518f 100644
--- a/src/misc/vec/vecInt.h
+++ b/src/misc/vec/vecInt.h
@@ -1692,6 +1692,24 @@ static inline int Vec_IntTwoFindCommon( Vec_Int_t * vArr1, Vec_Int_t * vArr2, Ve
}
return Vec_IntSize(vArr);
}
+static inline int Vec_IntTwoFindCommonReverse( Vec_Int_t * vArr1, Vec_Int_t * vArr2, Vec_Int_t * vArr )
+{
+ int * pBeg1 = vArr1->pArray;
+ int * pBeg2 = vArr2->pArray;
+ int * pEnd1 = vArr1->pArray + vArr1->nSize;
+ int * pEnd2 = vArr2->pArray + vArr2->nSize;
+ Vec_IntClear( vArr );
+ while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 )
+ {
+ if ( *pBeg1 == *pBeg2 )
+ Vec_IntPush( vArr, *pBeg1 ), pBeg1++, pBeg2++;
+ else if ( *pBeg1 > *pBeg2 )
+ pBeg1++;
+ else
+ pBeg2++;
+ }
+ return Vec_IntSize(vArr);
+}
/**Function*************************************************************
diff --git a/src/misc/vec/vecPtr.h b/src/misc/vec/vecPtr.h
index 5b40665f..015aa1be 100644
--- a/src/misc/vec/vecPtr.h
+++ b/src/misc/vec/vecPtr.h
@@ -65,7 +65,7 @@ struct Vec_Ptr_t_
#define Vec_PtrForEachEntryTwo( Type1, vVec1, Type2, vVec2, pEntry1, pEntry2, i ) \
for ( i = 0; (i < Vec_PtrSize(vVec1)) && (((pEntry1) = (Type1)Vec_PtrEntry(vVec1, i)), 1) && (((pEntry2) = (Type2)Vec_PtrEntry(vVec2, i)), 1); i++ )
#define Vec_PtrForEachEntryDouble( Type1, Type2, vVec, Entry1, Entry2, i ) \
- for ( i = 0; (i+1 < Vec_IntSize(vVec)) && (((Entry1) = (Type1)Vec_PtrEntry(vVec, i)), 1) && (((Entry2) = (Type2)Vec_PtrEntry(vVec, i+1)), 1); i += 2 )
+ for ( i = 0; (i+1 < Vec_PtrSize(vVec)) && (((Entry1) = (Type1)Vec_PtrEntry(vVec, i)), 1) && (((Entry2) = (Type2)Vec_PtrEntry(vVec, i+1)), 1); i += 2 )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
diff --git a/src/misc/vec/vecWec.h b/src/misc/vec/vecWec.h
index e4e92503..c8c89701 100644
--- a/src/misc/vec/vecWec.h
+++ b/src/misc/vec/vecWec.h
@@ -303,6 +303,23 @@ static inline Vec_Int_t * Vec_WecPushLevel( Vec_Wec_t * p )
++p->nSize;
return Vec_WecEntryLast( p );
}
+static inline Vec_Int_t * Vec_WecInsertLevel( Vec_Wec_t * p, int i )
+{
+ Vec_Int_t * pTemp;
+ if ( p->nSize == p->nCap )
+ {
+ if ( p->nCap < 16 )
+ Vec_WecGrow( p, 16 );
+ else
+ Vec_WecGrow( p, 2 * p->nCap );
+ }
+ ++p->nSize;
+ assert( i >= 0 && i < p->nSize );
+ for ( pTemp = p->pArray + p->nSize - 2; pTemp >= p->pArray + i; pTemp-- )
+ pTemp[1] = pTemp[0];
+ Vec_IntZero( p->pArray + i );
+ return p->pArray + i;
+}
/**Function*************************************************************
@@ -544,6 +561,18 @@ static inline void Vec_WecPrint( Vec_Wec_t * p, int fSkipSingles )
printf( " }\n" );
}
}
+static inline void Vec_WecPrintLits( Vec_Wec_t * p )
+{
+ Vec_Int_t * vVec;
+ int i, k, iLit;
+ Vec_WecForEachLevel( p, vVec, i )
+ {
+ printf( " %4d : %2d {", i, Vec_IntSize(vVec) );
+ Vec_IntForEachEntry( vVec, iLit, k )
+ printf( " %c%d", Abc_LitIsCompl(iLit) ? '-' : '+', Abc_Lit2Var(iLit) );
+ printf( " }\n" );
+ }
+}
/**Function*************************************************************
diff --git a/src/misc/zlib/inflate.c b/src/misc/zlib/inflate.c
index 449779a9..9fae7045 100644
--- a/src/misc/zlib/inflate.c
+++ b/src/misc/zlib/inflate.c
@@ -1445,7 +1445,7 @@ long ZEXPORT inflateMark(z_streamp strm)
{
struct inflate_state FAR *state;
- if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16;
+ if (strm == Z_NULL || strm->state == Z_NULL) return -(1L << 16);
state = (struct inflate_state FAR *)strm->state;
return ((long)(state->back) << 16) +
(state->mode == COPY ? state->length :
diff --git a/src/opt/dau/dauGia.c b/src/opt/dau/dauGia.c
index 5e74ad21..fa757e62 100644
--- a/src/opt/dau/dauGia.c
+++ b/src/opt/dau/dauGia.c
@@ -241,7 +241,7 @@ int Dau_DsdBalance( Gia_Man_t * pGia, int * pFans, int nFans, int fAnd )
if ( pGia->pHTable == NULL )
{
if ( fAnd )
- iFan = Gia_ManAppendAnd( pGia, iFan0, iFan1 );
+ iFan = Gia_ManAppendAnd2( pGia, iFan0, iFan1 );
else if ( pGia->pMuxes )
{
int fCompl = Abc_LitIsCompl(iFan0) ^ Abc_LitIsCompl(iFan1);
@@ -249,7 +249,7 @@ int Dau_DsdBalance( Gia_Man_t * pGia, int * pFans, int nFans, int fAnd )
iFan = Abc_LitNotCond( iFan, fCompl );
}
else
- iFan = Gia_ManAppendXor( pGia, iFan0, iFan1 );
+ iFan = Gia_ManAppendXor2( pGia, iFan0, iFan1 );
}
else
{
@@ -361,7 +361,7 @@ int Dau_DsdToGia_rec( Gia_Man_t * pGia, char * pStr, char ** p, int * pMatches,
if ( pGia->pMuxes )
Res = Gia_ManAppendMux( pGia, Temp[0], Temp[1], Temp[2] );
else
- Res = Gia_ManAppendMux( pGia, Temp[0], Temp[1], Temp[2] );
+ Res = Gia_ManAppendMux2( pGia, Temp[0], Temp[1], Temp[2] );
}
else
{
diff --git a/src/opt/dsc/dsc.c b/src/opt/dsc/dsc.c
index ce180fe3..7ddeeed9 100644
--- a/src/opt/dsc/dsc.c
+++ b/src/opt/dsc/dsc.c
@@ -51,14 +51,14 @@ struct Dsc_node_t_
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
-inline void xorInPlace( word * pOut, word * pIn2, int nWords)
+static inline void xorInPlace( word * pOut, word * pIn2, int nWords)
{
int w;
for ( w = 0; w < nWords; w++ )
pOut[w] ^= pIn2[w];
}
-void dsc_debug_node(Dsc_node_t * pNode, int nVars, const int TRUTH_WORDS) {
+static inline void dsc_debug_node(Dsc_node_t * pNode, int nVars, const int TRUTH_WORDS) {
int i;
printf("Node:\t%s\n",pNode->exp);
printf("\tneg cof:\t");Abc_TtPrintHexRev(stdout, pNode->pNegCof, nVars);
@@ -75,7 +75,7 @@ void dsc_debug_node(Dsc_node_t * pNode, int nVars, const int TRUTH_WORDS) {
printf("\n");
}
-inline int dsc_and_test(Dsc_node_t *ni, Dsc_node_t *nj, const int TRUTH_WORDS, int* ci, int* cj) {
+static inline int dsc_and_test(Dsc_node_t *ni, Dsc_node_t *nj, const int TRUTH_WORDS, int* ci, int* cj) {
if (Abc_TtEqual(ni->pNegCof, nj->pNegCof, TRUTH_WORDS)) {*ci=1; *cj=1; return 1;}
else if (Abc_TtEqual(ni->pNegCof, nj->pPosCof, TRUTH_WORDS)) {*ci=1; *cj=0; return 1;}
else if (Abc_TtEqual(ni->pPosCof, nj->pNegCof, TRUTH_WORDS)) {*ci=0; *cj=1; return 1;}
@@ -83,11 +83,11 @@ inline int dsc_and_test(Dsc_node_t *ni, Dsc_node_t *nj, const int TRUTH_WORDS, i
return 0;
}
-inline int dsc_xor_test(Dsc_node_t *ni, Dsc_node_t *nj, const int TRUTH_WORDS) {
+static inline int dsc_xor_test(Dsc_node_t *ni, Dsc_node_t *nj, const int TRUTH_WORDS) {
return Abc_TtEqual(ni->pBoolDiff, nj->pBoolDiff, TRUTH_WORDS);
}
-void concat(char* target, char begin, char end, char* s1, int s1Polarity, char* s2, int s2Polarity) {
+static inline void concat(char* target, char begin, char end, char* s1, int s1Polarity, char* s2, int s2Polarity) {
*target++ = begin;
//s1
if (!s1Polarity)
@@ -104,7 +104,7 @@ void concat(char* target, char begin, char end, char* s1, int s1Polarity, char*
*target = '\0';
}
-void cubeCofactor(word * const pTruth, const unsigned int * const cubeCof, const int TRUTH_WORDS) {
+static inline void cubeCofactor(word * const pTruth, const unsigned int * const cubeCof, const int TRUTH_WORDS) {
int size = cubeCof[0];
int i;
for (i = 1; i <= size; i++) {
@@ -117,7 +117,7 @@ void cubeCofactor(word * const pTruth, const unsigned int * const cubeCof, const
}
}
-void merge(unsigned int * const pOut, const unsigned int * const pIn) {
+static inline void merge(unsigned int * const pOut, const unsigned int * const pIn) {
const int elementsToCopy = pIn[0];
int i, j;
for (i = pOut[0]+1, j = 1; j <= elementsToCopy; i++, j++) {
diff --git a/src/opt/lpk/lpkCore.c b/src/opt/lpk/lpkCore.c
index a9088d10..6595b365 100644
--- a/src/opt/lpk/lpkCore.c
+++ b/src/opt/lpk/lpkCore.c
@@ -96,12 +96,12 @@ void Lpk_IfManStart( Lpk_Man_t * p )
int Lpk_NodeHasChanged( Lpk_Man_t * p, int iNode )
{
Vec_Ptr_t * vNodes;
- Abc_Obj_t * pTemp;
+ Abc_Obj_t * pTemp, * pTemp2;
int i;
vNodes = Vec_VecEntry( p->vVisited, iNode );
if ( Vec_PtrSize(vNodes) == 0 )
return 1;
- Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pTemp, i )
+ Vec_PtrForEachEntryDouble( Abc_Obj_t *, Abc_Obj_t *, vNodes, pTemp, pTemp2, i )
{
// check if the node has changed
pTemp = Abc_NtkObj( p->pNtk, (int)(ABC_PTRUINT_T)pTemp );
@@ -110,7 +110,7 @@ int Lpk_NodeHasChanged( Lpk_Man_t * p, int iNode )
// check if the number of fanouts has changed
// if ( Abc_ObjFanoutNum(pTemp) != (int)Vec_PtrEntry(vNodes, i+1) )
// return 1;
- i++;
+// i++;
}
return 0;
}
diff --git a/src/opt/lpk/lpkCut.c b/src/opt/lpk/lpkCut.c
index 73711f2b..208facf2 100644
--- a/src/opt/lpk/lpkCut.c
+++ b/src/opt/lpk/lpkCut.c
@@ -234,7 +234,7 @@ void Lpk_NodeRecordImpact( Lpk_Man_t * p )
{
Lpk_Cut_t * pCut;
Vec_Ptr_t * vNodes = Vec_VecEntry( p->vVisited, p->pObj->Id );
- Abc_Obj_t * pNode;
+ Abc_Obj_t * pNode, * pNode2;
int i, k;
// collect the nodes that impact the given node
Vec_PtrClear( vNodes );
@@ -252,11 +252,11 @@ void Lpk_NodeRecordImpact( Lpk_Man_t * p )
}
}
// clear the marks
- Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
+ Vec_PtrForEachEntryDouble( Abc_Obj_t *, Abc_Obj_t *, vNodes, pNode, pNode2, i )
{
pNode = Abc_NtkObj( p->pNtk, (int)(ABC_PTRUINT_T)pNode );
pNode->fMarkC = 0;
- i++;
+// i++;
}
//printf( "%d ", Vec_PtrSize(vNodes) );
}
diff --git a/src/opt/sbd/module.make b/src/opt/sbd/module.make
index d966e577..fc176715 100644
--- a/src/opt/sbd/module.make
+++ b/src/opt/sbd/module.make
@@ -1,5 +1,9 @@
SRC += src/opt/sbd/sbd.c \
src/opt/sbd/sbdCnf.c \
src/opt/sbd/sbdCore.c \
+ src/opt/sbd/sbdCut.c \
+ src/opt/sbd/sbdCut2.c \
+ src/opt/sbd/sbdLut.c \
+ src/opt/sbd/sbdPath.c \
src/opt/sbd/sbdSat.c \
src/opt/sbd/sbdWin.c
diff --git a/src/opt/sbd/sbd.h b/src/opt/sbd/sbd.h
index 89d29958..9c419b16 100644
--- a/src/opt/sbd/sbd.h
+++ b/src/opt/sbd/sbd.h
@@ -39,11 +39,18 @@ typedef struct Sbd_Par_t_ Sbd_Par_t;
struct Sbd_Par_t_
{
int nLutSize; // target LUT size
+ int nLutNum; // target LUT count
+ int nCutSize; // target cut size
+ int nCutNum; // target cut count
int nTfoLevels; // the number of TFO levels (windowing)
int nTfoFanMax; // the max number of fanouts (windowing)
int nWinSizeMax; // maximum window size (windowing)
int nBTLimit; // maximum number of SAT conflicts
int nWords; // simulation word count
+ int fMapping; // generate mapping
+ int fMoreCuts; // use several cuts
+ int fFindDivs; // perform divisor search
+ int fUsePath; // optimize only critical path
int fArea; // area-oriented optimization
int fCover; // use complete cover procedure
int fVerbose; // verbose flag
diff --git a/src/opt/sbd/sbdCnf.c b/src/opt/sbd/sbdCnf.c
index 6291baed..8705858e 100644
--- a/src/opt/sbd/sbdCnf.c
+++ b/src/opt/sbd/sbdCnf.c
@@ -44,7 +44,7 @@ ABC_NAMESPACE_IMPL_START
***********************************************************************/
void Sbd_PrintCnf( Vec_Str_t * vCnf )
{
- char Entry;
+ signed char Entry;
int i, Lit;
Vec_StrForEachEntry( vCnf, Entry, i )
{
@@ -121,7 +121,7 @@ int Sbd_TruthToCnf( word Truth, int nVars, Vec_Int_t * vCover, Vec_Str_t * vCnf
void Sbd_TranslateCnf( Vec_Wec_t * vRes, Vec_Str_t * vCnf, Vec_Int_t * vFaninMap, int iPivotVar )
{
Vec_Int_t * vClause;
- char Entry;
+ signed char Entry;
int i, Lit;
Vec_WecClear( vRes );
vClause = Vec_WecPushLevel( vRes );
diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c
index b6ec70f9..4f560a0a 100644
--- a/src/opt/sbd/sbdCore.c
+++ b/src/opt/sbd/sbdCore.c
@@ -1,12 +1,12 @@
/**CFile****************************************************************
- FileName [sbd.c]
+ FileName [sbdCore.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [SAT-based optimization using internal don't-cares.]
- Synopsis []
+ Synopsis [Core procedures.]
Author [Alan Mishchenko]
@@ -14,7 +14,7 @@
Date [Ver. 1.0. Started - June 20, 2005.]
- Revision [$Id: sbd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+ Revision [$Id: sbdCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
@@ -30,7 +30,6 @@ ABC_NAMESPACE_IMPL_START
#define SBD_MAX_LUTSIZE 6
-
typedef struct Sbd_Man_t_ Sbd_Man_t;
struct Sbd_Man_t_
{
@@ -39,25 +38,34 @@ struct Sbd_Man_t_
Vec_Wec_t * vTfos; // TFO for each node (roots are marked) (windowing)
Vec_Int_t * vLutLevs; // LUT level for each node after resynthesis
Vec_Int_t * vLutCuts; // LUT cut for each nodes after resynthesis
+ Vec_Int_t * vLutCuts2; // LUT cut for each nodes after resynthesis
Vec_Int_t * vMirrors; // alternative node
Vec_Wrd_t * vSims[4]; // simulation information (main, backup, controlability)
Vec_Int_t * vCover; // temporary
Vec_Int_t * vLits; // temporary
- int nConsts; // constants
- int nChanges; // changes
+ Vec_Int_t * vLits2; // temporary
+ int nLuts[6]; // 0=const, 1=1lut, 2=2lut, 3=3lut
+ int nTried;
+ int nUsed;
abctime timeWin;
+ abctime timeCut;
+ abctime timeCov;
abctime timeCnf;
abctime timeSat;
- abctime timeCov;
- abctime timeEnu;
+ abctime timeQbf;
+ abctime timeNew;
abctime timeOther;
abctime timeTotal;
+ Sbd_Sto_t * pSto;
+ Sbd_Srv_t * pSrv;
// target node
int Pivot; // target node
+ int DivCutoff; // the place where D-2 divisors begin
Vec_Int_t * vTfo; // TFO (excludes node, includes roots) - precomputed
Vec_Int_t * vRoots; // TFO root nodes
Vec_Int_t * vWinObjs; // TFI + Pivot + sideTFI + TFO (including roots)
Vec_Int_t * vObj2Var; // SAT variables for the window (indexes of objects in vWinObjs)
+ Vec_Int_t * vDivSet; // divisor variables
Vec_Int_t * vDivVars; // divisor variables
Vec_Int_t * vDivValues; // SAT variables values for the divisor variables
Vec_Wec_t * vDivLevels; // divisors collected by levels
@@ -66,7 +74,8 @@ struct Sbd_Man_t_
sat_solver * pSat; // SAT solver
};
-static inline int * Sbd_ObjCut( Sbd_Man_t * p, int i ) { return Vec_IntEntryP( p->vLutCuts, (p->pPars->nLutSize + 1) * i ); }
+static inline int * Sbd_ObjCut( Sbd_Man_t * p, int i ) { return Vec_IntEntryP( p->vLutCuts, (p->pPars->nLutSize + 1) * i ); }
+static inline int * Sbd_ObjCut2( Sbd_Man_t * p, int i ) { return Vec_IntEntryP( p->vLutCuts2, (p->pPars->nLutSize + 1) * i ); }
static inline word * Sbd_ObjSim0( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSims[0], p->pPars->nWords * i ); }
static inline word * Sbd_ObjSim1( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSims[1], p->pPars->nWords * i ); }
@@ -91,16 +100,23 @@ static inline word * Sbd_ObjSim3( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP(
void Sbd_ParSetDefault( Sbd_Par_t * pPars )
{
memset( pPars, 0, sizeof(Sbd_Par_t) );
- pPars->nLutSize = 4; // target LUT size
- pPars->nTfoLevels = 2; // the number of TFO levels (windowing)
- pPars->nTfoFanMax = 4; // the max number of fanouts (windowing)
- pPars->nWinSizeMax = 0; // maximum window size (windowing)
- pPars->nBTLimit = 0; // maximum number of SAT conflicts
- pPars->nWords = 1; // simulation word count
- pPars->fArea = 0; // area-oriented optimization
- pPars->fCover = 0; // use complete cover procedure
- pPars->fVerbose = 0; // verbose flag
- pPars->fVeryVerbose = 0; // verbose flag
+ pPars->nLutSize = 4; // target LUT size
+ pPars->nLutNum = 3; // target LUT count
+ pPars->nCutSize = (pPars->nLutSize - 1) * pPars->nLutNum + 1; // target cut size
+ pPars->nCutNum = 128; // target cut count
+ pPars->nTfoLevels = 5; // the number of TFO levels (windowing)
+ pPars->nTfoFanMax = 4; // the max number of fanouts (windowing)
+ pPars->nWinSizeMax = 2000; // maximum window size (windowing)
+ pPars->nBTLimit = 0; // maximum number of SAT conflicts
+ pPars->nWords = 1; // simulation word count
+ pPars->fMapping = 1; // generate mapping
+ pPars->fMoreCuts = 0; // use several cuts
+ pPars->fFindDivs = 0; // perform divisor search
+ pPars->fUsePath = 0; // optimize only critical path
+ pPars->fArea = 0; // area-oriented optimization
+ pPars->fCover = 0; // use complete cover procedure
+ pPars->fVerbose = 0; // verbose flag
+ pPars->fVeryVerbose = 0; // verbose flag
}
/**Function*************************************************************
@@ -197,9 +213,11 @@ Sbd_Man_t * Sbd_ManStart( Gia_Man_t * pGia, Sbd_Par_t * pPars )
// target node
p->vCover = Vec_IntAlloc( 100 );
p->vLits = Vec_IntAlloc( 100 );
+ p->vLits2 = Vec_IntAlloc( 100 );
p->vRoots = Vec_IntAlloc( 100 );
p->vWinObjs = Vec_IntAlloc( Gia_ManObjNum(pGia) );
p->vObj2Var = Vec_IntStart( Gia_ManObjNum(pGia) );
+ p->vDivSet = Vec_IntAlloc( 100 );
p->vDivVars = Vec_IntAlloc( 100 );
p->vDivValues = Vec_IntAlloc( 100 );
p->vDivLevels = Vec_WecAlloc( 100 );
@@ -218,6 +236,14 @@ Sbd_Man_t * Sbd_ManStart( Gia_Man_t * pGia, Sbd_Par_t * pPars )
Gia_ManForEachCiId( pGia, Id, i )
for ( w = 0; w < p->pPars->nWords; w++ )
Sbd_ObjSim0(p, Id)[w] = Gia_ManRandomW( 0 );
+ // cut enumeration
+ if ( pPars->fMoreCuts )
+ p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, pPars->nCutSize, pPars->nCutNum, !pPars->fMapping, 1 );
+ else
+ {
+ p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, pPars->nLutSize, pPars->nCutNum, !pPars->fMapping, 1 );
+ p->pSrv = Sbd_ManCutServerStart( pGia, p->vMirrors, p->vLutLevs, NULL, NULL, pPars->nLutSize, pPars->nCutSize, pPars->nCutNum, 0 );
+ }
return p;
}
void Sbd_ManStop( Sbd_Man_t * p )
@@ -231,16 +257,20 @@ void Sbd_ManStop( Sbd_Man_t * p )
Vec_WrdFree( p->vSims[i] );
Vec_IntFree( p->vCover );
Vec_IntFree( p->vLits );
+ Vec_IntFree( p->vLits2 );
Vec_IntFree( p->vRoots );
Vec_IntFree( p->vWinObjs );
Vec_IntFree( p->vObj2Var );
+ Vec_IntFree( p->vDivSet );
Vec_IntFree( p->vDivVars );
Vec_IntFree( p->vDivValues );
Vec_WecFree( p->vDivLevels );
Vec_IntFree( p->vCounts[0] );
Vec_IntFree( p->vCounts[1] );
Vec_WrdFree( p->vMatrix );
- if ( p->pSat ) sat_solver_delete( p->pSat );
+ sat_solver_delete_p( &p->pSat );
+ if ( p->pSto ) Sbd_StoFree( p->pSto );
+ if ( p->pSrv ) Sbd_ManCutServerStop( p->pSrv );
ABC_FREE( p );
}
@@ -318,12 +348,11 @@ void Sbd_ManUpdateOrder( Sbd_Man_t * p, int Pivot )
Vec_WecInit( p->vDivLevels, LevelMax + 1 );
Vec_IntForEachEntry( p->vWinObjs, Node, i )
Vec_WecPush( p->vDivLevels, Vec_IntEntry(p->vLutLevs, Node), Node );
- // sort primary inputs
- Vec_IntSort( Vec_WecEntry(p->vDivLevels, 0), 0 );
// reload divisors
Vec_IntClear( p->vWinObjs );
Vec_WecForEachLevel( p->vDivLevels, vLevel, i )
{
+ Vec_IntSort( vLevel, 0 );
Vec_IntForEachEntry( vLevel, Node, k )
{
Vec_IntWriteEntry( p->vObj2Var, Node, Vec_IntSize(p->vWinObjs) );
@@ -334,8 +363,28 @@ void Sbd_ManUpdateOrder( Sbd_Man_t * p, int Pivot )
nTimeValidDivs = Vec_IntSize(p->vWinObjs);
}
assert( nTimeValidDivs > 0 );
- Vec_IntFill( p->vDivValues, Abc_MinInt(63, nTimeValidDivs), 0 );
- //printf( "%d ", Abc_MinInt(63, nTimeValidDivs) );
+ Vec_IntClear( p->vDivVars );
+ p->DivCutoff = -1;
+ Vec_IntForEachEntryStartStop( p->vWinObjs, Node, i, Abc_MaxInt(0, nTimeValidDivs-63), nTimeValidDivs )
+ {
+ if ( p->DivCutoff == -1 && Vec_IntEntry(p->vLutLevs, Node) == LevelMax - 2 )
+ p->DivCutoff = Vec_IntSize(p->vDivVars);
+ Vec_IntPush( p->vDivVars, i );
+ }
+ if ( p->DivCutoff == -1 )
+ p->DivCutoff = 0;
+ // verify
+/*
+ assert( Vec_IntSize(p->vDivVars) < 64 );
+ Vec_IntForEachEntryStart( p->vDivVars, Node, i, p->DivCutoff )
+ assert( Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Node)) == LevelMax - 2 );
+ Vec_IntForEachEntryStop( p->vDivVars, Node, i, p->DivCutoff )
+ assert( Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Node)) < LevelMax - 2 );
+*/
+ Vec_IntFill( p->vDivValues, Vec_IntSize(p->vDivVars), 0 );
+ //printf( "%d ", Vec_IntSize(p->vDivVars) );
+// printf( "Node %4d : Win = %5d. Divs = %5d. D1 = %5d. D2 = %5d.\n",
+// Pivot, Vec_IntSize(p->vWinObjs), Vec_IntSize(p->vDivVars), Vec_IntSize(p->vDivVars)-p->DivCutoff, p->DivCutoff );
}
void Sbd_ManWindowSim_rec( Sbd_Man_t * p, int NodeInit )
{
@@ -407,7 +456,14 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot )
Gia_ManIncrementTravId( p->pGia );
Gia_ObjSetTravIdCurrentId(p->pGia, 0);
Sbd_ManWindowSim_rec( p, Pivot );
+ if ( p->pPars->nWinSizeMax && Vec_IntSize(p->vWinObjs) > p->pPars->nWinSizeMax )
+ {
+ p->timeWin += Abc_Clock() - clk;
+ return 0;
+ }
Sbd_ManUpdateOrder( p, Pivot );
+ assert( Vec_IntSize(p->vDivVars) == Vec_IntSize(p->vDivValues) );
+ assert( Vec_IntSize(p->vDivVars) < Vec_IntSize(p->vWinObjs) );
// simulate node
Gia_ManObj(p->pGia, Pivot)->fMark0 = 1;
Abc_TtCopy( Sbd_ObjSim1(p, Pivot), Sbd_ObjSim0(p, Pivot), p->pPars->nWords, 1 );
@@ -429,6 +485,11 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot )
Vec_IntWriteEntry( p->vObj2Var, Abc_Lit2Var(Node), Vec_IntSize(p->vWinObjs) );
Vec_IntPush( p->vWinObjs, Abc_Lit2Var(Node) );
}
+ if ( p->pPars->nWinSizeMax && Vec_IntSize(p->vWinObjs) > p->pPars->nWinSizeMax )
+ {
+ p->timeWin += Abc_Clock() - clk;
+ return 0;
+ }
// compute controlability for node
if ( Vec_IntSize(p->vTfo) == 0 )
Abc_TtFill( Sbd_ObjSim2(p, Pivot), p->pPars->nWords );
@@ -440,8 +501,8 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot )
p->timeWin += Abc_Clock() - clk;
// propagate controlability to fanins for the TFI nodes starting from the pivot
Sbd_ManPropagateControl( p, Pivot );
- assert( Vec_IntSize(p->vDivValues) < 64 );
- return (int)(Vec_IntSize(p->vDivValues) >= 64);
+ assert( Vec_IntSize(p->vDivValues) <= 64 );
+ return (int)(Vec_IntSize(p->vDivValues) <= 64);
}
/**Function*************************************************************
@@ -457,24 +518,22 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot )
***********************************************************************/
int Sbd_ManCheckConst( Sbd_Man_t * p, int Pivot )
{
- extern void Sbd_ManPrintObj( Sbd_Man_t * p, int Pivot );
int nMintCount = 1;
Vec_Ptr_t * vSims;
word * pSims = Sbd_ObjSim0( p, Pivot );
word * pCtrl = Sbd_ObjSim2( p, Pivot );
int PivotVar = Vec_IntEntry(p->vObj2Var, Pivot);
int RetValue, i, iObj, Ind, fFindOnset, nCares[2] = {0};
+
abctime clk = Abc_Clock();
- extern int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, word * pVarSims[], Vec_Int_t * vInds );
- extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots );
- p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots );
+ p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 );
p->timeCnf += Abc_Clock() - clk;
if ( p->pSat == NULL )
{
- if ( p->pPars->fVerbose )
- printf( "Found stuck-at-%d node %d.\n", 0, Pivot );
+ //if ( p->pPars->fVerbose )
+ // printf( "Found stuck-at-%d node %d.\n", 0, Pivot );
Vec_IntWriteEntry( p->vLutLevs, Pivot, 0 );
- p->nConsts++;
+ p->nLuts[0]++;
return 0;
}
//return -1;
@@ -494,7 +553,7 @@ int Sbd_ManCheckConst( Sbd_Man_t * p, int Pivot )
nCares[0] = nCares[0] < nMintCount ? nMintCount - nCares[0] : 0;
nCares[1] = nCares[1] < nMintCount ? nMintCount - nCares[1] : 0;
- if ( p->pPars->fVerbose )
+ if ( p->pPars->fVeryVerbose )
printf( "Computing %d offset and %d onset minterms for node %d.\n", nCares[0], nCares[1], Pivot );
if ( Vec_IntSize(p->vLits) >= nCares[0] + nCares[1] )
@@ -533,10 +592,10 @@ int Sbd_ManCheckConst( Sbd_Man_t * p, int Pivot )
Vec_PtrFree( vSims );
if ( RetValue >= 0 )
{
- if ( p->pPars->fVerbose )
+ if ( p->pPars->fVeryVerbose )
printf( "Found stuck-at-%d node %d.\n", RetValue, Pivot );
Vec_IntWriteEntry( p->vLutLevs, Pivot, 0 );
- p->nConsts++;
+ p->nLuts[0]++;
return RetValue;
}
// set controlability of these minterms
@@ -754,15 +813,15 @@ void Sbd_ManPrintObj( Sbd_Man_t * p, int Pivot )
}
}
-void Sbd_ManMatrPrint( word Cover[64], int nCol, int nRows )
+void Sbd_ManMatrPrint( Sbd_Man_t * p, word Cover[], int nCol, int nRows )
{
int i, k;
for ( i = 0; i <= nCol; i++ )
{
printf( "%2d : ", i );
+ printf( "%d ", i == nCol ? Vec_IntEntry(p->vLutLevs, p->Pivot) : Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Vec_IntEntry(p->vDivVars, i))) );
for ( k = 0; k < nRows; k++ )
- for ( k = 0; k < nRows; k++ )
- printf( "%d", (int)((Cover[i] >> k) & 1) );
+ printf( "%d", (int)((Cover[i] >> k) & 1) );
printf( "\n");
}
printf( "\n");
@@ -778,18 +837,18 @@ static inline void Sbd_ManCoverReverseOrder( word Cover[64] )
}
}
-static inline int Sbd_ManAddCube1( word Cover[64], int nRows, word Cube )
+static inline int Sbd_ManAddCube1( int nRowLimit, word Cover[], int nRows, word Cube )
{
int n, m;
if ( 0 )
{
printf( "Adding cube: " );
- for ( n = 0; n < 64; n++ )
+ for ( n = 0; n < nRowLimit; n++ )
printf( "%d", (int)((Cube >> n) & 1) );
printf( "\n" );
}
// do not add contained Cube
- assert( nRows <= 64 );
+ assert( nRows <= nRowLimit );
for ( n = 0; n < nRows; n++ )
if ( (Cover[n] & Cube) == Cover[n] ) // Cube is contained
return nRows;
@@ -797,7 +856,7 @@ static inline int Sbd_ManAddCube1( word Cover[64], int nRows, word Cube )
for ( n = m = 0; n < nRows; n++ )
if ( (Cover[n] & Cube) != Cube ) // Cover[n] is not contained
Cover[m++] = Cover[n];
- if ( m < 64 )
+ if ( m < nRowLimit )
Cover[m++] = Cube;
for ( n = m; n < nRows; n++ )
Cover[n] = 0;
@@ -832,15 +891,15 @@ static inline int Sbd_ManAddCube2( word Cover[2][64], int nRows, word Cube[2] )
return nRows;
}
-static inline int Sbd_ManFindCandsSimple( Sbd_Man_t * p, word Cover[64], int nDivs )
+static inline int Sbd_ManFindCandsSimple( Sbd_Man_t * p, word Cover[], int nDivs )
{
int c0, c1, c2, c3;
word Target = Cover[nDivs];
- Vec_IntClear( p->vDivVars );
+ Vec_IntClear( p->vDivSet );
for ( c0 = 0; c0 < nDivs; c0++ )
if ( Cover[c0] == Target )
{
- Vec_IntPush( p->vDivVars, c0 );
+ Vec_IntPush( p->vDivSet, c0 );
return 1;
}
@@ -848,8 +907,8 @@ static inline int Sbd_ManFindCandsSimple( Sbd_Man_t * p, word Cover[64], int nDi
for ( c1 = c0+1; c1 < nDivs; c1++ )
if ( (Cover[c0] | Cover[c1]) == Target )
{
- Vec_IntPush( p->vDivVars, c0 );
- Vec_IntPush( p->vDivVars, c1 );
+ Vec_IntPush( p->vDivSet, c0 );
+ Vec_IntPush( p->vDivSet, c1 );
return 1;
}
@@ -858,9 +917,9 @@ static inline int Sbd_ManFindCandsSimple( Sbd_Man_t * p, word Cover[64], int nDi
for ( c2 = c1+1; c2 < nDivs; c2++ )
if ( (Cover[c0] | Cover[c1] | Cover[c2]) == Target )
{
- Vec_IntPush( p->vDivVars, c0 );
- Vec_IntPush( p->vDivVars, c1 );
- Vec_IntPush( p->vDivVars, c2 );
+ Vec_IntPush( p->vDivSet, c0 );
+ Vec_IntPush( p->vDivSet, c1 );
+ Vec_IntPush( p->vDivSet, c2 );
return 1;
}
@@ -871,10 +930,10 @@ static inline int Sbd_ManFindCandsSimple( Sbd_Man_t * p, word Cover[64], int nDi
{
if ( (Cover[c0] | Cover[c1] | Cover[c2] | Cover[c3]) == Target )
{
- Vec_IntPush( p->vDivVars, c0 );
- Vec_IntPush( p->vDivVars, c1 );
- Vec_IntPush( p->vDivVars, c2 );
- Vec_IntPush( p->vDivVars, c3 );
+ Vec_IntPush( p->vDivSet, c0 );
+ Vec_IntPush( p->vDivSet, c1 );
+ Vec_IntPush( p->vDivSet, c2 );
+ Vec_IntPush( p->vDivSet, c3 );
return 1;
}
}
@@ -891,11 +950,11 @@ static inline int Sbd_ManFindCands( Sbd_Man_t * p, word Cover[64], int nDivs )
if ( nDivs < 8 || p->pPars->fCover )
return Sbd_ManFindCandsSimple( p, Cover, nDivs );
- Vec_IntClear( p->vDivVars );
+ Vec_IntClear( p->vDivSet );
for ( c0 = 0; c0 < nDivs; c0++ )
if ( Cover[c0] == Target )
{
- Vec_IntPush( p->vDivVars, c0 );
+ Vec_IntPush( p->vDivSet, c0 );
return 1;
}
@@ -903,8 +962,8 @@ static inline int Sbd_ManFindCands( Sbd_Man_t * p, word Cover[64], int nDivs )
for ( c1 = c0+1; c1 < nDivs; c1++ )
if ( (Cover[c0] | Cover[c1]) == Target )
{
- Vec_IntPush( p->vDivVars, c0 );
- Vec_IntPush( p->vDivVars, c1 );
+ Vec_IntPush( p->vDivSet, c0 );
+ Vec_IntPush( p->vDivSet, c1 );
return 1;
}
@@ -923,9 +982,9 @@ static inline int Sbd_ManFindCands( Sbd_Man_t * p, word Cover[64], int nDivs )
for ( c2 = c1+1; c2 < Limits[2]; c2++ )
if ( (Cover[Order[c0]] | Cover[Order[c1]] | Cover[Order[c2]]) == Target )
{
- Vec_IntPush( p->vDivVars, Order[c0] );
- Vec_IntPush( p->vDivVars, Order[c1] );
- Vec_IntPush( p->vDivVars, Order[c2] );
+ Vec_IntPush( p->vDivSet, Order[c0] );
+ Vec_IntPush( p->vDivSet, Order[c1] );
+ Vec_IntPush( p->vDivSet, Order[c2] );
return 1;
}
@@ -936,10 +995,10 @@ static inline int Sbd_ManFindCands( Sbd_Man_t * p, word Cover[64], int nDivs )
{
if ( (Cover[Order[c0]] | Cover[Order[c1]] | Cover[Order[c2]] | Cover[Order[c3]]) == Target )
{
- Vec_IntPush( p->vDivVars, Order[c0] );
- Vec_IntPush( p->vDivVars, Order[c1] );
- Vec_IntPush( p->vDivVars, Order[c2] );
- Vec_IntPush( p->vDivVars, Order[c3] );
+ Vec_IntPush( p->vDivSet, Order[c0] );
+ Vec_IntPush( p->vDivSet, Order[c1] );
+ Vec_IntPush( p->vDivSet, Order[c2] );
+ Vec_IntPush( p->vDivSet, Order[c3] );
return 1;
}
}
@@ -950,12 +1009,11 @@ static inline int Sbd_ManFindCands( Sbd_Man_t * p, word Cover[64], int nDivs )
int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth )
{
int fVerbose = 0;
- abctime clk, clkSat = 0, clkEnu = 0, clkAll = Abc_Clock();
+ abctime clk;
int nIters, nItersMax = 32;
- extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivVars, Vec_Int_t * vValues, Vec_Int_t * vTemp );
word MatrS[64] = {0}, MatrC[2][64] = {{0}}, Cubes[2][2][64] = {{{0}}}, Cover[64] = {0}, Cube, CubeNew[2];
- int i, k, n, Index, nCubes[2] = {0}, nRows = 0, nRowsOld;
+ int i, k, n, Node, Index, nCubes[2] = {0}, nRows = 0, nRowsOld;
int nDivs = Vec_IntSize(p->vDivValues);
int PivotVar = Vec_IntEntry(p->vObj2Var, Pivot);
@@ -969,11 +1027,11 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth )
Sbd_ManPrintObj( p, Pivot );
// collect bit-matrices
- for ( i = 0; i < nDivs; i++ )
+ Vec_IntForEachEntry( p->vDivVars, Node, i )
{
- MatrS[63-i] = *Sbd_ObjSim0( p, Vec_IntEntry(p->vWinObjs, i) );
- MatrC[0][63-i] = *Sbd_ObjSim2( p, Vec_IntEntry(p->vWinObjs, i) );
- MatrC[1][63-i] = *Sbd_ObjSim3( p, Vec_IntEntry(p->vWinObjs, i) );
+ MatrS[63-i] = *Sbd_ObjSim0( p, Vec_IntEntry(p->vWinObjs, Node) );
+ MatrC[0][63-i] = *Sbd_ObjSim2( p, Vec_IntEntry(p->vWinObjs, Node) );
+ MatrC[1][63-i] = *Sbd_ObjSim3( p, Vec_IntEntry(p->vWinObjs, Node) );
}
MatrS[63-i] = *Sbd_ObjSim0( p, Pivot );
MatrC[0][63-i] = *Sbd_ObjSim2( p, Pivot );
@@ -1029,7 +1087,7 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth )
{
Cube = (Cubes[0][1][i] & Cubes[1][0][k]) | (Cubes[0][0][i] & Cubes[1][1][k]);
assert( Cube );
- nRows = Sbd_ManAddCube1( Cover, nRows, Cube );
+ nRows = Sbd_ManAddCube1( 64, Cover, nRows, Cube );
}
Sbd_ManCoverReverseOrder( Cover );
@@ -1049,29 +1107,25 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth )
for ( nIters = 0; nIters < nItersMax && nRows < 64; nIters++ )
{
if ( p->pPars->fVerbose )
- Sbd_ManMatrPrint( Cover, nDivs, nRows );
+ Sbd_ManMatrPrint( p, Cover, nDivs, nRows );
clk = Abc_Clock();
if ( !Sbd_ManFindCands( p, Cover, nDivs ) )
{
if ( p->pPars->fVerbose )
printf( "Cannot find a feasible cover.\n" );
- clkEnu += Abc_Clock() - clk;
- clkAll = Abc_Clock() - clkAll - clkSat - clkEnu;
- p->timeSat += clkSat;
- p->timeCov += clkAll;
- p->timeEnu += clkEnu;
+ p->timeCov += Abc_Clock() - clk;
return RetValue;
}
- clkEnu += Abc_Clock() - clk;
+ p->timeCov += Abc_Clock() - clk;
if ( p->pPars->fVerbose )
printf( "Candidate support: " ),
- Vec_IntPrint( p->vDivVars );
+ Vec_IntPrint( p->vDivSet );
clk = Abc_Clock();
- *pTruth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivVars, p->vDivValues, p->vLits );
- clkSat += Abc_Clock() - clk;
+ *pTruth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits );
+ p->timeSat += Abc_Clock() - clk;
if ( *pTruth == SBD_SAT_UNDEC )
printf( "Node %d: Undecided.\n", Pivot );
@@ -1103,21 +1157,445 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth )
if ( p->pPars->fVerbose )
{
printf( "Node %d: UNSAT.\n", Pivot );
- Extra_PrintBinary( stdout, (unsigned *)pTruth, 1 << Vec_IntSize(p->vDivVars) ), printf( "\n" );
+ Extra_PrintBinary( stdout, (unsigned *)pTruth, 1 << Vec_IntSize(p->vDivSet) ), printf( "\n" );
}
RetValue = 1;
break;
}
//break;
}
- //printf( "Node %4d : Iter = %4d Start table = %4d Final table = %4d\n", Pivot, nIters, nRowsOld, nRows );
- clkAll = Abc_Clock() - clkAll - clkSat - clkEnu;
- p->timeSat += clkSat;
- p->timeCov += clkAll;
- p->timeEnu += clkEnu;
return RetValue;
}
+int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth )
+{
+ abctime clk;
+ word Onset[64] = {0}, Offset[64] = {0}, Cube;
+ word CoverRows[64] = {0}, CoverCols[64] = {0};
+ int nIters, nItersMax = 32;
+ int i, k, nRows = 0;
+
+ int PivotVar = Vec_IntEntry(p->vObj2Var, Pivot);
+ int FreeVar = Vec_IntSize(p->vWinObjs) + Vec_IntSize(p->vTfo) + Vec_IntSize(p->vRoots);
+ int nDivs = Vec_IntSize( p->vDivVars );
+ int nConsts = 4;
+ int RetValue;
+
+ clk = Abc_Clock();
+ //sat_solver_delete_p( &p->pSat );
+ p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 );
+ p->timeCnf += Abc_Clock() - clk;
+
+ assert( nConsts <= 8 );
+ clk = Abc_Clock();
+ RetValue = Sbd_ManCollectConstantsNew( p->pSat, p->vDivVars, nConsts, PivotVar, Onset, Offset );
+ p->timeSat += Abc_Clock() - clk;
+ if ( RetValue >= 0 )
+ {
+ if ( p->pPars->fVeryVerbose )
+ printf( "Found stuck-at-%d node %d.\n", RetValue, Pivot );
+ Vec_IntWriteEntry( p->vLutLevs, Pivot, 0 );
+ p->nLuts[0]++;
+ return RetValue;
+ }
+ RetValue = 0;
+
+ // create rows of the table
+ nRows = 0;
+ for ( i = 0; i < nConsts; i++ )
+ for ( k = 0; k < nConsts; k++ )
+ {
+ Cube = Onset[i] ^ Offset[k];
+ assert( Cube );
+ nRows = Sbd_ManAddCube1( 256, CoverRows, nRows, Cube );
+ }
+ assert( nRows <= 64 );
+
+ // create columns of the table
+ for ( i = 0; i < nRows; i++ )
+ for ( k = 0; k <= nDivs; k++ )
+ if ( (CoverRows[i] >> k) & 1 )
+ Abc_TtXorBit(&CoverCols[k], i);
+
+ // solve the covering problem
+ for ( nIters = 0; nIters < nItersMax && nRows < 64; nIters++ )
+ {
+ if ( p->pPars->fVeryVerbose )
+ Sbd_ManMatrPrint( p, CoverCols, nDivs, nRows );
+
+ clk = Abc_Clock();
+ if ( !Sbd_ManFindCands( p, CoverCols, nDivs ) )
+ {
+ if ( p->pPars->fVeryVerbose )
+ printf( "Cannot find a feasible cover.\n" );
+ p->timeCov += Abc_Clock() - clk;
+ return 0;
+ }
+ p->timeCov += Abc_Clock() - clk;
+
+ if ( p->pPars->fVeryVerbose )
+ printf( "Candidate support: " ),
+ Vec_IntPrint( p->vDivSet );
+
+ clk = Abc_Clock();
+ *pTruth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits );
+ p->timeSat += Abc_Clock() - clk;
+
+ if ( *pTruth == SBD_SAT_UNDEC )
+ printf( "Node %d: Undecided.\n", Pivot );
+ else if ( *pTruth == SBD_SAT_SAT )
+ {
+ if ( p->pPars->fVeryVerbose )
+ {
+ int i;
+ printf( "Node %d: SAT.\n", Pivot );
+ for ( i = 0; i < nDivs; i++ )
+ printf( "%d", Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Vec_IntEntry(p->vDivVars, i))) );
+ printf( "\n" );
+ for ( i = 0; i < nDivs; i++ )
+ printf( "%d", i % 10 );
+ printf( "\n" );
+ for ( i = 0; i < nDivs; i++ )
+ printf( "%c", (Vec_IntEntry(p->vDivValues, i) & 0x4) ? '0' + (Vec_IntEntry(p->vDivValues, i) & 1) : 'x' );
+ printf( "\n" );
+ for ( i = 0; i < nDivs; i++ )
+ printf( "%c", (Vec_IntEntry(p->vDivValues, i) & 0x8) ? '0' + ((Vec_IntEntry(p->vDivValues, i) >> 1) & 1) : 'x' );
+ printf( "\n" );
+ }
+ // add row to the covering table
+ for ( i = 0; i < nDivs; i++ )
+ if ( Vec_IntEntry(p->vDivValues, i) == 0xE || Vec_IntEntry(p->vDivValues, i) == 0xD )
+ CoverCols[i] |= ((word)1 << nRows);
+ CoverCols[nDivs] |= ((word)1 << nRows);
+ nRows++;
+ }
+ else
+ {
+ if ( p->pPars->fVeryVerbose )
+ {
+ printf( "Node %d: UNSAT. ", Pivot );
+ Extra_PrintBinary( stdout, (unsigned *)pTruth, 1 << Vec_IntSize(p->vDivSet) ), printf( "\n" );
+ }
+ p->nLuts[1]++;
+ RetValue = 1;
+ break;
+ }
+ }
+ return RetValue;
+}
+
+int Sbd_ManExploreCut( Sbd_Man_t * p, int Pivot, int nLeaves, int * pLeaves, int * pnStrs, Sbd_Str_t * Strs, int * pFreeVar )
+{
+ abctime clk = Abc_Clock();
+ int PivotVar = Vec_IntEntry(p->vObj2Var, Pivot);
+ int Delay = Vec_IntEntry( p->vLutLevs, Pivot );
+ int pNodesTop[SBD_DIV_MAX], pNodesBot[SBD_DIV_MAX], pNodesBot1[SBD_DIV_MAX], pNodesBot2[SBD_DIV_MAX];
+ int nNodesTop = 0, nNodesBot = 0, nNodesBot1 = 0, nNodesBot2 = 0, nNodesDiff = 0, nNodesDiff1 = 0, nNodesDiff2 = 0;
+ int i, k, iObj, nIters, RetValue = 0;
+
+ // try to remove fanins
+ for ( nIters = 0; nIters < nLeaves; nIters++ )
+ {
+ word Truth;
+ // try to remove one variable from divisors
+ Vec_IntClear( p->vDivSet );
+ for ( i = 0; i < nLeaves; i++ )
+ if ( i != nLeaves-1-nIters && pLeaves[i] != -1 )
+ Vec_IntPush( p->vDivSet, Vec_IntEntry(p->vObj2Var, pLeaves[i]) );
+ assert( Vec_IntSize(p->vDivSet) < nLeaves );
+ // compute truth table
+ clk = Abc_Clock();
+ Truth = Sbd_ManSolve( p->pSat, PivotVar, (*pFreeVar)++, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits );
+ p->timeSat += Abc_Clock() - clk;
+ if ( Truth == SBD_SAT_UNDEC )
+ printf( "Node %d: Undecided.\n", Pivot );
+ else if ( Truth == SBD_SAT_SAT )
+ {
+ int DelayDiff = Vec_IntEntry(p->vLutLevs, pLeaves[nLeaves-1-nIters]) - Delay;
+ if ( DelayDiff > -2 )
+ return 0;
+ }
+ else
+ pLeaves[nLeaves-1-nIters] = -1;
+ }
+ Vec_IntClear( p->vDivSet );
+ for ( i = 0; i < nLeaves; i++ )
+ if ( pLeaves[i] != -1 )
+ Vec_IntPush( p->vDivSet, pLeaves[i] );
+ //printf( "Reduced %d -> %d\n", nLeaves, Vec_IntSize(p->vDivSet) );
+ if ( Vec_IntSize(p->vDivSet) <= p->pPars->nLutSize )
+ {
+ word Truth;
+ *pnStrs = 1;
+ // remap divisors
+ Vec_IntForEachEntry( p->vDivSet, iObj, i )
+ Vec_IntWriteEntry( p->vDivSet, i, Vec_IntEntry(p->vObj2Var, iObj) );
+ // compute truth table
+ clk = Abc_Clock();
+ Truth = Sbd_ManSolve( p->pSat, PivotVar, (*pFreeVar)++, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits );
+ p->timeSat += Abc_Clock() - clk;
+ if ( Truth == SBD_SAT_SAT )
+ {
+ printf( "The cut at node %d is not topological.\n", p->Pivot );
+ return 0;
+ }
+ assert( Truth != SBD_SAT_UNDEC && Truth != SBD_SAT_SAT );
+ // create structure
+ Strs->fLut = 1;
+ Strs->nVarIns = Vec_IntSize( p->vDivSet );
+ for ( i = 0; i < Strs->nVarIns; i++ )
+ Strs->VarIns[i] = i;
+ Strs->Res = Truth;
+ p->nLuts[1]++;
+ //Extra_PrintBinary( stdout, (unsigned *)&Truth, 1 << Strs->nVarIns ), printf( "\n" );
+ return 1;
+ }
+ assert( Vec_IntSize(p->vDivSet) > p->pPars->nLutSize );
+
+ // count number of nodes on each level
+ nNodesTop = nNodesBot = nNodesBot1 = nNodesBot2 = 0;
+ Vec_IntForEachEntry( p->vDivSet, iObj, i )
+ {
+ int DelayDiff = Vec_IntEntry(p->vLutLevs, iObj) - Delay;
+ if ( DelayDiff > -2 )
+ break;
+ if ( DelayDiff == -2 )
+ pNodesTop[nNodesTop++] = i;
+ else // if ( DelayDiff < -2 )
+ {
+ pNodesBot[nNodesBot++] = i;
+ if ( DelayDiff == -3 )
+ pNodesBot1[nNodesBot1++] = i;
+ else // if ( DelayDiff < -3 )
+ pNodesBot2[nNodesBot2++] = i;
+ }
+ Vec_IntWriteEntry( p->vDivSet, i, Vec_IntEntry(p->vObj2Var, iObj) );
+ }
+ assert( nNodesBot == nNodesBot1 + nNodesBot2 );
+ if ( i < Vec_IntSize(p->vDivSet) )
+ return 0;
+ if ( nNodesTop > p->pPars->nLutSize-1 )
+ return 0;
+
+ // try 44
+ if ( Vec_IntSize(p->vDivSet) <= 2*p->pPars->nLutSize-1 )
+ {
+ int nMoved = 0;
+ if ( nNodesBot > p->pPars->nLutSize ) // need to move bottom left-over to the top
+ {
+ while ( nNodesBot > p->pPars->nLutSize )
+ pNodesTop[nNodesTop++] = pNodesBot[--nNodesBot], nMoved++;
+ assert( nNodesBot == p->pPars->nLutSize );
+ }
+ assert( nNodesBot <= p->pPars->nLutSize );
+ assert( nNodesTop <= p->pPars->nLutSize-1 );
+
+ Strs[0].fLut = 1;
+ Strs[0].nVarIns = p->pPars->nLutSize;
+ for ( i = 0; i < nNodesTop; i++ )
+ Strs[0].VarIns[i] = pNodesTop[i];
+ for ( ; i < p->pPars->nLutSize; i++ )
+ Strs[0].VarIns[i] = Vec_IntSize(p->vDivSet)+1 + i-nNodesTop;
+ Strs[0].Res = 0;
+
+ Strs[1].fLut = 1;
+ Strs[1].nVarIns = nNodesBot;
+ for ( i = 0; i < nNodesBot; i++ )
+ Strs[1].VarIns[i] = pNodesBot[i];
+ Strs[1].Res = 0;
+
+ nNodesDiff = p->pPars->nLutSize-1 - nNodesTop;
+ assert( nNodesDiff >= 0 && nNodesDiff <= 3 );
+ for ( k = 0; k < nNodesDiff; k++ )
+ {
+ Strs[2+k].fLut = 0;
+ Strs[2+k].nVarIns = nNodesBot;
+ for ( i = 0; i < nNodesBot; i++ )
+ Strs[2+k].VarIns[i] = pNodesBot[i];
+ Strs[2+k].Res = 0;
+ }
+
+ *pnStrs = 2 + nNodesDiff;
+ clk = Abc_Clock();
+ RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, p->vDivSet, *pnStrs, Strs );
+ p->timeQbf += Abc_Clock() - clk;
+ if ( RetValue )
+ p->nLuts[2]++;
+
+ while ( nMoved-- )
+ pNodesBot[nNodesBot++] = pNodesTop[--nNodesTop];
+ }
+
+ if ( RetValue )
+ return RetValue;
+ if ( p->pPars->nLutNum < 3 )
+ return 0;
+ if ( Vec_IntSize(p->vDivSet) < 2*p->pPars->nLutSize-1 )
+ return 0;
+
+ // try 444 -- LUT(LUT, LUT)
+ if ( nNodesTop <= p->pPars->nLutSize-2 )
+ {
+ int nMoved = 0;
+ if ( nNodesBot > 2*p->pPars->nLutSize ) // need to move bottom left-over to the top
+ {
+ while ( nNodesBot > 2*p->pPars->nLutSize )
+ pNodesTop[nNodesTop++] = pNodesBot[--nNodesBot], nMoved++;
+ assert( nNodesBot == 2*p->pPars->nLutSize );
+ }
+ assert( nNodesBot > p->pPars->nLutSize );
+ assert( nNodesBot <= 2*p->pPars->nLutSize );
+ assert( nNodesTop <= p->pPars->nLutSize-2 );
+
+ Strs[0].fLut = 1;
+ Strs[0].nVarIns = p->pPars->nLutSize;
+ for ( i = 0; i < nNodesTop; i++ )
+ Strs[0].VarIns[i] = pNodesTop[i];
+ for ( ; i < p->pPars->nLutSize; i++ )
+ Strs[0].VarIns[i] = Vec_IntSize(p->vDivSet)+1 + i-nNodesTop;
+ Strs[0].Res = 0;
+
+ Strs[1].fLut = 1;
+ Strs[1].nVarIns = p->pPars->nLutSize;
+ for ( i = 0; i < Strs[1].nVarIns; i++ )
+ Strs[1].VarIns[i] = pNodesBot[i];
+ Strs[1].Res = 0;
+
+ Strs[2].fLut = 1;
+ Strs[2].nVarIns = p->pPars->nLutSize;
+ for ( i = 0; i < Strs[2].nVarIns; i++ )
+ Strs[2].VarIns[i] = pNodesBot[nNodesBot-p->pPars->nLutSize+i];
+ Strs[2].Res = 0;
+
+ nNodesDiff = p->pPars->nLutSize-2 - nNodesTop;
+ assert( nNodesDiff >= 0 && nNodesDiff <= 2 );
+ for ( k = 0; k < nNodesDiff; k++ )
+ {
+ Strs[3+k].fLut = 0;
+ Strs[3+k].nVarIns = nNodesBot;
+ for ( i = 0; i < nNodesBot; i++ )
+ Strs[3+k].VarIns[i] = pNodesBot[i];
+ Strs[3+k].Res = 0;
+ }
+
+ *pnStrs = 3 + nNodesDiff;
+ clk = Abc_Clock();
+ RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, p->vDivSet, *pnStrs, Strs );
+ p->timeQbf += Abc_Clock() - clk;
+ if ( RetValue )
+ p->nLuts[3]++;
+
+ while ( nMoved-- )
+ pNodesBot[nNodesBot++] = pNodesTop[--nNodesTop];
+ }
+ if ( RetValue )
+ return RetValue;
+
+ // try 444 -- LUT(LUT(LUT))
+ if ( nNodesBot1 + nNodesTop <= 2*p->pPars->nLutSize-2 )
+ {
+ if ( nNodesBot2 > p->pPars->nLutSize ) // need to move bottom left-over to the top
+ {
+ while ( nNodesBot2 > p->pPars->nLutSize )
+ pNodesBot1[nNodesBot1++] = pNodesBot2[--nNodesBot2];
+ assert( nNodesBot2 == p->pPars->nLutSize );
+ }
+ if ( nNodesBot1 > p->pPars->nLutSize-1 ) // need to move bottom left-over to the top
+ {
+ while ( nNodesBot1 > p->pPars->nLutSize-1 )
+ pNodesTop[nNodesTop++] = pNodesBot1[--nNodesBot1];
+ assert( nNodesBot1 == p->pPars->nLutSize-1 );
+ }
+ assert( nNodesBot2 <= p->pPars->nLutSize );
+ assert( nNodesBot1 <= p->pPars->nLutSize-1 );
+ assert( nNodesTop <= p->pPars->nLutSize-1 );
+
+ Strs[0].fLut = 1;
+ Strs[0].nVarIns = p->pPars->nLutSize;
+ for ( i = 0; i < nNodesTop; i++ )
+ Strs[0].VarIns[i] = pNodesTop[i];
+ Strs[0].VarIns[i++] = Vec_IntSize(p->vDivSet)+1;
+ for ( ; i < p->pPars->nLutSize; i++ )
+ Strs[0].VarIns[i] = Vec_IntSize(p->vDivSet)+2 + i-nNodesTop;
+ Strs[0].Res = 0;
+ nNodesDiff1 = p->pPars->nLutSize-1 - nNodesTop;
+
+ Strs[1].fLut = 1;
+ Strs[1].nVarIns = p->pPars->nLutSize;
+ for ( i = 0; i < nNodesBot1; i++ )
+ Strs[1].VarIns[i] = pNodesBot1[i];
+ Strs[1].VarIns[i++] = Vec_IntSize(p->vDivSet)+2;
+ for ( ; i < p->pPars->nLutSize; i++ )
+ Strs[1].VarIns[i] = Vec_IntSize(p->vDivSet)+2+nNodesDiff1 + i-nNodesBot1;
+ Strs[1].Res = 0;
+ nNodesDiff2 = p->pPars->nLutSize-1 - nNodesBot1;
+
+ Strs[2].fLut = 1;
+ Strs[2].nVarIns = nNodesBot2;
+ for ( i = 0; i < Strs[2].nVarIns; i++ )
+ Strs[2].VarIns[i] = pNodesBot2[i];
+ Strs[2].Res = 0;
+
+ nNodesDiff = nNodesDiff1 + nNodesDiff2;
+ assert( nNodesDiff >= 0 && nNodesDiff <= 3 );
+ for ( k = 0; k < nNodesDiff; k++ )
+ {
+ Strs[3+k].fLut = 0;
+ Strs[3+k].nVarIns = nNodesBot2;
+ for ( i = 0; i < nNodesBot2; i++ )
+ Strs[3+k].VarIns[i] = pNodesBot2[i];
+ Strs[3+k].Res = 0;
+ if ( k >= nNodesDiff1 )
+ continue;
+ Strs[3+k].nVarIns += nNodesBot1;
+ for ( i = 0; i < nNodesBot1; i++ )
+ Strs[3+k].VarIns[nNodesBot2 + i] = pNodesBot1[i];
+ }
+
+ *pnStrs = 3 + nNodesDiff;
+ clk = Abc_Clock();
+ RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, p->vDivSet, *pnStrs, Strs );
+ p->timeQbf += Abc_Clock() - clk;
+ if ( RetValue )
+ p->nLuts[4]++;
+ }
+ return RetValue;
+}
+int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs )
+{
+ int FreeVar = Vec_IntSize(p->vWinObjs) + Vec_IntSize(p->vTfo) + Vec_IntSize(p->vRoots);
+ int FreeVarStart = FreeVar;
+ int nSize, nLeaves, pLeaves[SBD_DIV_MAX];
+ //sat_solver_delete_p( &p->pSat );
+ abctime clk = Abc_Clock();
+ p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 );
+ p->timeCnf += Abc_Clock() - clk;
+ // extract one cut
+ if ( p->pSrv )
+ {
+ nLeaves = Sbd_ManCutServerFirst( p->pSrv, Pivot, pLeaves );
+ if ( nLeaves == -1 )
+ return 0;
+ assert( nLeaves <= p->pPars->nCutSize );
+ if ( Sbd_ManExploreCut( p, Pivot, nLeaves, pLeaves, pnStrs, Strs, &FreeVar ) )
+ return 1;
+ return 0;
+ }
+ // extract one cut
+ for ( nSize = p->pPars->nLutSize + 1; nSize <= p->pPars->nCutSize; nSize++ )
+ {
+ nLeaves = Sbd_StoObjBestCut( p->pSto, Pivot, nSize, pLeaves );
+ if ( nLeaves == -1 )
+ continue;
+ assert( nLeaves == nSize );
+ if ( Sbd_ManExploreCut( p, Pivot, nLeaves, pLeaves, pnStrs, Strs, &FreeVar ) )
+ return 1;
+ }
+ assert( FreeVar - FreeVarStart <= SBD_FVAR_MAX );
+ return 0;
+}
+
+
/**Function*************************************************************
Synopsis [Computes delay-oriented k-feasible cut at the node.]
@@ -1231,9 +1709,10 @@ int Sbd_ManMergeCuts( Sbd_Man_t * p, int Node )
assert( iFan0 != iFan1 );
assert( Vec_IntEntry(p->vLutLevs, Node) == 0 );
Vec_IntWriteEntry( p->vLutLevs, Node, LevCur );
+ //Vec_IntWriteEntry( p->vLevs, Node, 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, iFan0), Vec_IntEntry(p->vLevs, iFan1)) );
assert( pCutRes[0] <= p->pPars->nLutSize );
memcpy( Sbd_ObjCut(p, Node), pCutRes, sizeof(int) * (pCutRes[0] + 1) );
- //printf( "Setting node %d with delay %d.\n", Node, LevCur );
+//printf( "Setting node %d with delay %d.\n", Node, LevCur );
return LevCur == 1; // LevCur == Abc_MaxInt(Level0, Level1);
}
int Sbd_ManDelay( Sbd_Man_t * p )
@@ -1294,6 +1773,7 @@ void Sbd_ManFindCut( Sbd_Man_t * p, int Node, Vec_Int_t * vCutLits )
// create cut
assert( Vec_IntEntry(p->vLutLevs, Node) == 0 );
Vec_IntWriteEntry( p->vLutLevs, Node, LevelMax+1 );
+ //Vec_IntWriteEntry( p->vLevs, Node, 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, Gia_ObjFaninId0(pObj, Node)), Vec_IntEntry(p->vLevs, Gia_ObjFaninId1(pObj, Node))) );
memcpy( Sbd_ObjCut(p, Node), pCut, sizeof(int) * (pCut[0] + 1) );
}
@@ -1306,7 +1786,7 @@ int Sbd_ManImplement( Sbd_Man_t * p, int Pivot, word Truth )
int iNewLev;
// collect leaf literals
Vec_IntClear( p->vLits );
- Vec_IntForEachEntry( p->vDivVars, Node, i )
+ Vec_IntForEachEntry( p->vDivSet, Node, i )
{
Node = Vec_IntEntry( p->vWinObjs, Node );
if ( Vec_IntEntry(p->vMirrors, Node) >= 0 )
@@ -1355,7 +1835,99 @@ int Sbd_ManImplement( Sbd_Man_t * p, int Pivot, word Truth )
// update delay of the initial node
assert( Vec_IntEntry(p->vLutLevs, Pivot) == iCurLev );
Vec_IntWriteEntry( p->vLutLevs, Pivot, iNewLev );
- p->nChanges++;
+ //Vec_IntWriteEntry( p->vLevs, Pivot, 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, Gia_ObjFaninId0(pObj, Pivot)), Vec_IntEntry(p->vLevs, Gia_ObjFaninId1(pObj, Pivot))) );
+ return 0;
+}
+
+int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs )
+{
+ //Gia_Obj_t * pObj = NULL;
+ int i, k, w, iLit, Node;
+ int iObjLast = Gia_ManObjNum(p->pGia);
+ int iCurLev = Vec_IntEntry(p->vLutLevs, Pivot);
+ int iNewLev;
+ // collect leaf literals
+ Vec_IntClear( p->vLits );
+ Vec_IntForEachEntry( p->vDivSet, Node, i )
+ {
+ Node = Vec_IntEntry( p->vWinObjs, Node );
+ if ( Vec_IntEntry(p->vMirrors, Node) >= 0 )
+ Vec_IntPush( p->vLits, Vec_IntEntry(p->vMirrors, Node) );
+ else
+ Vec_IntPush( p->vLits, Abc_Var2Lit(Node, 0) );
+ }
+ // collect structure nodes
+ for ( i = 0; i < nStrs; i++ )
+ Vec_IntPush( p->vLits, -1 );
+ // implement structures
+ for ( i = nStrs-1; i >= 0; i-- )
+ {
+ if ( pStrs[i].fLut )
+ {
+ // collect local literals
+ Vec_IntClear( p->vLits2 );
+ for ( k = 0; k < (int)pStrs[i].nVarIns; k++ )
+ Vec_IntPush( p->vLits2, Vec_IntEntry(p->vLits, pStrs[i].VarIns[k]) );
+ // pretend to have MUXes
+ // assert( p->pGia->pMuxes == NULL );
+ if ( p->pGia->nXors && p->pGia->pMuxes == NULL )
+ p->pGia->pMuxes = (unsigned *)p;
+ // derive new function of the node
+ iLit = Dsm_ManTruthToGia( p->pGia, &pStrs[i].Res, p->vLits2, p->vCover );
+ if ( p->pGia->pMuxes == (unsigned *)p )
+ p->pGia->pMuxes = NULL;
+ }
+ else
+ {
+ iLit = Vec_IntEntry( p->vLits, (int)pStrs[i].Res );
+ assert( iLit > 0 );
+ }
+ // update literal
+ assert( Vec_IntEntry(p->vLits, Vec_IntSize(p->vLits)-nStrs+i) == -1 );
+ Vec_IntWriteEntry( p->vLits, Vec_IntSize(p->vLits)-nStrs+i, iLit );
+ }
+ iLit = Vec_IntEntry( p->vLits, Vec_IntSize(p->vDivSet) );
+ //assert( iObjLast == Gia_ManObjNum(p->pGia) || Abc_Lit2Var(iLit) == Gia_ManObjNum(p->pGia)-1 );
+ // remember this function
+ assert( Vec_IntEntry(p->vMirrors, Pivot) == -1 );
+ Vec_IntWriteEntry( p->vMirrors, Pivot, iLit );
+ if ( p->pPars->fVeryVerbose )
+ printf( "Replacing node %d by literal %d.\n", Pivot, iLit );
+
+ // extend data-structure to accommodate new nodes
+ assert( Vec_IntSize(p->vLutLevs) == iObjLast );
+ for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ )
+ {
+ assert( i == Vec_IntSize(p->vMirrors) );
+ Vec_IntPush( p->vMirrors, -1 );
+ Sbd_StoRefObj( p->pSto, i, i == Gia_ManObjNum(p->pGia)-1 ? Pivot : -1 );
+ }
+ Sbd_StoDerefObj( p->pSto, Pivot );
+ for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ )
+ {
+ //Gia_Obj_t * pObjI = Gia_ManObj( p->pGia, i );
+ abctime clk = Abc_Clock();
+ int Delay = Sbd_StoComputeCutsNode( p->pSto, i );
+ p->timeCut += Abc_Clock() - clk;
+ assert( i == Vec_IntSize(p->vLutLevs) );
+ Vec_IntPush( p->vLutLevs, Delay );
+ //Vec_IntPush( p->vLevs, 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, Gia_ObjFaninId0(pObjI, i)), Vec_IntEntry(p->vLevs, Gia_ObjFaninId1(pObjI, i))) );
+ Vec_IntPush( p->vObj2Var, 0 );
+ Vec_IntFillExtra( p->vLutCuts, Vec_IntSize(p->vLutCuts) + p->pPars->nLutSize + 1, 0 );
+ Sbd_StoSaveBestDelayCut( p->pSto, i, Sbd_ObjCut(p, i) );
+ //Sbd_ManFindCut( p, i, p->vLits );
+ for ( k = 0; k < 4; k++ )
+ for ( w = 0; w < p->pPars->nWords; w++ )
+ Vec_WrdPush( p->vSims[k], 0 );
+ }
+ // make sure delay reduction is achieved
+ iNewLev = Vec_IntEntry( p->vLutLevs, Abc_Lit2Var(iLit) );
+ assert( !iNewLev || iNewLev < iCurLev );
+ // update delay of the initial node
+ //pObj = Gia_ManObj( p->pGia, Pivot );
+ assert( Vec_IntEntry(p->vLutLevs, Pivot) == iCurLev );
+ Vec_IntWriteEntry( p->vLutLevs, Pivot, iNewLev );
+ //Vec_IntWriteEntry( p->vLevs, Pivot, Pivot ? 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, Gia_ObjFaninId0(pObj, Pivot)), Vec_IntEntry(p->vLevs, Gia_ObjFaninId1(pObj, Pivot))) : 0 );
return 0;
}
@@ -1370,6 +1942,70 @@ int Sbd_ManImplement( Sbd_Man_t * p, int Pivot, word Truth )
SeeAlso []
***********************************************************************/
+void Sbd_ManDeriveMapping_rec( Sbd_Man_t * p, Gia_Man_t * pNew, int iObj )
+{
+ Gia_Obj_t * pObj; int k, * pCut;
+ if ( !iObj || Gia_ObjIsTravIdCurrentId(pNew, iObj) )
+ return;
+ Gia_ObjSetTravIdCurrentId(pNew, iObj);
+ pObj = Gia_ManObj( pNew, iObj );
+ if ( Gia_ObjIsCi(pObj) )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ pCut = Sbd_ObjCut2( p, iObj );
+ for ( k = 1; k <= pCut[0]; k++ )
+ Sbd_ManDeriveMapping_rec( p, pNew, pCut[k] );
+ // add mapping
+ Vec_IntWriteEntry( pNew->vMapping, iObj, Vec_IntSize(pNew->vMapping) );
+ for ( k = 0; k <= pCut[0]; k++ )
+ Vec_IntPush( pNew->vMapping, pCut[k] );
+ Vec_IntPush( pNew->vMapping, iObj );
+}
+void Sbd_ManDeriveMapping( Sbd_Man_t * p, Gia_Man_t * pNew )
+{
+ Gia_Obj_t * pObj, * pFan;
+ int i, k, iFan, iObjNew, iFanNew, * pCut, * pCutNew;
+ Vec_Int_t * vLeaves = Vec_IntAlloc( 100 );
+ // derive cuts for the new manager
+ p->vLutCuts2 = Vec_IntStart( Gia_ManObjNum(pNew) * (p->pPars->nLutSize + 1) );
+ Gia_ManForEachAnd( p->pGia, pObj, i )
+ {
+ if ( Vec_IntEntry(p->vMirrors, i) >= 0 )
+ continue;
+ if ( pObj->Value == ~0 )
+ continue;
+ iObjNew = Abc_Lit2Var( pObj->Value );
+ if ( !Gia_ObjIsAnd(Gia_ManObj(pNew, iObjNew)) )
+ continue;
+ pCutNew = Sbd_ObjCut2( p, iObjNew );
+ pCut = Sbd_ObjCut( p, i );
+ Vec_IntClear( vLeaves );
+ for ( k = 1; k <= pCut[0]; k++ )
+ {
+ iFan = Vec_IntEntry(p->vMirrors, pCut[k]) >= 0 ? Abc_Lit2Var(Vec_IntEntry(p->vMirrors, pCut[k])) : pCut[k];
+ pFan = Gia_ManObj( p->pGia, iFan );
+ if ( pFan->Value == ~0 )
+ continue;
+ iFanNew = Abc_Lit2Var( pFan->Value );
+ if ( iFanNew == 0 || iFanNew == iObjNew )
+ continue;
+ Vec_IntPushUniqueOrder( vLeaves, iFanNew );
+ }
+ assert( Vec_IntSize(vLeaves) <= p->pPars->nLutSize );
+ //assert( Vec_IntSize(vLeaves) > 1 );
+ pCutNew[0] = Vec_IntSize(vLeaves);
+ memcpy( pCutNew+1, Vec_IntArray(vLeaves), sizeof(int) * Vec_IntSize(vLeaves) );
+ }
+ Vec_IntFree( vLeaves );
+ // create new mapping
+ Vec_IntFreeP( &pNew->vMapping );
+ pNew->vMapping = Vec_IntAlloc( (p->pPars->nLutSize + 2) * Gia_ManObjNum(pNew) );
+ Vec_IntFill( pNew->vMapping, Gia_ManObjNum(pNew), 0 );
+ Gia_ManIncrementTravId( pNew );
+ Gia_ManForEachCo( pNew, pObj, i )
+ Sbd_ManDeriveMapping_rec( p, pNew, Gia_ObjFaninId0p(pNew, pObj) );
+ Vec_IntFreeP( &p->vLutCuts2 );
+}
void Sbd_ManDerive_rec( Gia_Man_t * pNew, Gia_Man_t * p, int Node, Vec_Int_t * vMirrors )
{
Gia_Obj_t * pObj;
@@ -1391,9 +2027,9 @@ void Sbd_ManDerive_rec( Gia_Man_t * pNew, Gia_Man_t * p, int Node, Vec_Int_t * v
if ( Obj != Node )
Gia_ManObj(p, Node)->Value = Abc_LitNotCond( pObj->Value, Abc_LitIsCompl(Vec_IntEntry(vMirrors, Node)) );
}
-Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors )
+Gia_Man_t * Sbd_ManDerive( Sbd_Man_t * pMan, Gia_Man_t * p, Vec_Int_t * vMirrors )
{
- Gia_Man_t * pNew;
+ Gia_Man_t * pNew, * pTemp;
Gia_Obj_t * pObj;
int i;
Gia_ManFillValue( p );
@@ -1413,6 +2049,13 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors )
Gia_ManHashStop( pNew );
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
Gia_ManTransferTiming( pNew, p );
+ if ( pMan->pPars->fMapping )
+ Sbd_ManDeriveMapping( pMan, pNew );
+ // remove dangling nodes
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManTransferTiming( pNew, pTemp );
+ Gia_ManTransferMapping( pNew, pTemp );
+ Gia_ManStop( pTemp );
return pNew;
}
@@ -1429,81 +2072,147 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors )
***********************************************************************/
void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot )
{
- int RetValue; word Truth = 0;
- if ( Sbd_ManMergeCuts( p, Pivot ) )
+ Sbd_Str_t Strs[SBD_DIV_MAX]; word Truth = 0;
+ int RetValue, nStrs = 0;
+ if ( !p->pSto && Sbd_ManMergeCuts( p, Pivot ) )
return;
- //if ( Pivot != 344 )
- // continue;
- if ( p->pPars->fVerbose )
- printf( "\nLooking at node %d\n", Pivot );
- if ( Sbd_ManWindow( p, Pivot ) )
+ if ( !Sbd_ManWindow( p, Pivot ) )
return;
+ //if ( Vec_IntSize(p->vWinObjs) > 100 )
+ // printf( "Obj %d : Win = %d TFO = %d. Roots = %d.\n", Pivot, Vec_IntSize(p->vWinObjs), Vec_IntSize(p->vTfo), Vec_IntSize(p->vRoots) );
+ p->nTried++;
+ p->nUsed++;
RetValue = Sbd_ManCheckConst( p, Pivot );
if ( RetValue >= 0 )
+ {
Vec_IntWriteEntry( p->vMirrors, Pivot, RetValue );
- else if ( Sbd_ManExplore( p, Pivot, &Truth ) )
- Sbd_ManImplement( p, Pivot, Truth );
+ //if ( p->pPars->fVerbose ) printf( "Node %5d: Detected constant %d.\n", Pivot, RetValue );
+ }
+ else if ( p->pPars->fFindDivs && p->pPars->nLutNum >= 1 && Sbd_ManExplore2( p, Pivot, &Truth ) )
+ {
+ int i;
+ Strs->fLut = 1;
+ Strs->nVarIns = Vec_IntSize( p->vDivSet );
+ for ( i = 0; i < Strs->nVarIns; i++ )
+ Strs->VarIns[i] = i;
+ Strs->Res = Truth;
+ Sbd_ManImplement2( p, Pivot, 1, Strs );
+ //if ( p->pPars->fVerbose ) printf( "Node %5d: Detected LUT%d\n", Pivot, p->pPars->nLutSize );
+ }
+ else if ( p->pPars->nLutNum >= 2 && Sbd_ManExplore3( p, Pivot, &nStrs, Strs ) )
+ {
+ Sbd_ManImplement2( p, Pivot, nStrs, Strs );
+ if ( !p->pPars->fVerbose )
+ return;
+ //if ( Vec_IntSize(p->vDivSet) <= 4 )
+ // printf( "Node %5d: Detected %d\n", Pivot, p->pPars->nLutSize );
+ //else if ( Vec_IntSize(p->vDivSet) <= 6 || (Vec_IntSize(p->vDivSet) == 7 && nStrs == 2) )
+ // printf( "Node %5d: Detected %d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize );
+ //else
+ // printf( "Node %5d: Detected %d%d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize, p->pPars->nLutSize );
+ }
+ else
+ p->nUsed--;
}
Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars )
{
Gia_Man_t * pNew;
Gia_Obj_t * pObj;
+ Vec_Bit_t * vPath;
Sbd_Man_t * p = Sbd_ManStart( pGia, pPars );
- int nNodesOld = Gia_ManObjNum(pGia);//, Count = 0;
+ int nNodesOld = Gia_ManObjNum(pGia);
int k, Pivot;
assert( pPars->nLutSize <= 6 );
- //Sbd_ManMergeTest( p );
+ // prepare references
+ Gia_ManForEachObj( p->pGia, pObj, Pivot )
+ Sbd_StoRefObj( p->pSto, Pivot, -1 );
//return NULL;
+ vPath = (pPars->fUsePath && Gia_ManHasMapping(pGia)) ? Sbc_ManCriticalPath(pGia) : NULL;
if ( pGia->pManTime != NULL && Tim_ManBoxNum((Tim_Man_t*)pGia->pManTime) )
{
Vec_Int_t * vNodes = Gia_ManOrderWithBoxes( pGia );
Tim_Man_t * pTimOld = (Tim_Man_t *)pGia->pManTime;
pGia->pManTime = Tim_ManDup( pTimOld, 1 );
+ //Tim_ManPrint( pGia->pManTime );
Tim_ManIncrementTravId( (Tim_Man_t *)pGia->pManTime );
Gia_ManForEachObjVec( vNodes, pGia, pObj, k )
{
Pivot = Gia_ObjId( pGia, pObj );
if ( Pivot >= nNodesOld )
- continue;
+ break;
if ( Gia_ObjIsAnd(pObj) )
- Sbd_NtkPerformOne( p, Pivot );
+ {
+ abctime clk = Abc_Clock();
+ int Delay = Sbd_StoComputeCutsNode( p->pSto, Pivot );
+ Sbd_StoSaveBestDelayCut( p->pSto, Pivot, Sbd_ObjCut(p, Pivot) );
+ p->timeCut += Abc_Clock() - clk;
+ Vec_IntWriteEntry( p->vLutLevs, Pivot, Delay );
+ if ( Delay > 1 && (!vPath || Vec_BitEntry(vPath, Pivot)) )
+ Sbd_NtkPerformOne( p, Pivot );
+ }
else if ( Gia_ObjIsCi(pObj) )
{
int arrTime = Tim_ManGetCiArrival( (Tim_Man_t*)pGia->pManTime, Gia_ObjCioId(pObj) );
Vec_IntWriteEntry( p->vLutLevs, Pivot, arrTime );
+ Sbd_StoComputeCutsCi( p->pSto, Pivot, arrTime, arrTime );
}
else if ( Gia_ObjIsCo(pObj) )
{
int arrTime = Vec_IntEntry( p->vLutLevs, Gia_ObjFaninId0(pObj, Pivot) );
Tim_ManSetCoArrival( (Tim_Man_t*)pGia->pManTime, Gia_ObjCioId(pObj), arrTime );
}
- else if ( !Gia_ObjIsConst0(pObj) )
- assert( 0 );
+ else if ( Gia_ObjIsConst0(pObj) )
+ Sbd_StoComputeCutsConst0( p->pSto, 0 );
+ else assert( 0 );
}
- //Tim_ManPrint( pGia->pManTime );
Tim_ManStop( (Tim_Man_t *)pGia->pManTime );
pGia->pManTime = pTimOld;
Vec_IntFree( vNodes );
}
else
{
- Gia_ManForEachAndId( pGia, Pivot )
- if ( Pivot < nNodesOld )
- Sbd_NtkPerformOne( p, Pivot );
+ Sbd_StoComputeCutsConst0( p->pSto, 0 );
+ Gia_ManForEachObj( pGia, pObj, Pivot )
+ {
+ if ( Pivot >= nNodesOld )
+ break;
+ if ( Gia_ObjIsCi(pObj) )
+ Sbd_StoComputeCutsCi( p->pSto, Pivot, 0, 0 );
+ else if ( Gia_ObjIsAnd(pObj) )
+ {
+ abctime clk = Abc_Clock();
+ int Delay = Sbd_StoComputeCutsNode( p->pSto, Pivot );
+ Sbd_StoSaveBestDelayCut( p->pSto, Pivot, Sbd_ObjCut(p, Pivot) );
+ p->timeCut += Abc_Clock() - clk;
+ Vec_IntWriteEntry( p->vLutLevs, Pivot, Delay );
+ if ( Delay > 1 && (!vPath || Vec_BitEntry(vPath, Pivot)) )
+ Sbd_NtkPerformOne( p, Pivot );
+ }
+ //if ( nNodesOld != Gia_ManObjNum(pGia) )
+ // break;
+ }
}
- printf( "Found %d constants and %d replacements with delay %d. ", p->nConsts, p->nChanges, Sbd_ManDelay(p) );
+ Vec_BitFreeP( &vPath );
p->timeTotal = Abc_Clock() - p->timeTotal;
- Abc_PrintTime( 1, "Time", p->timeTotal );
- pNew = Sbd_ManDerive( pGia, p->vMirrors );
+ if ( p->pPars->fVerbose )
+ {
+ printf( "K = %d. S = %d. N = %d. P = %d. ",
+ p->pPars->nLutSize, p->pPars->nLutNum, p->pPars->nCutSize, p->pPars->nCutNum );
+ printf( "Try = %d. Use = %d. C = %d. 1 = %d. 2 = %d. 3a = %d. 3b = %d. Lev = %d. ",
+ p->nTried, p->nUsed, p->nLuts[0], p->nLuts[1], p->nLuts[2], p->nLuts[3], p->nLuts[4], Sbd_ManDelay(p) );
+ Abc_PrintTime( 1, "Time", p->timeTotal );
+ }
+ pNew = Sbd_ManDerive( p, pGia, p->vMirrors );
// print runtime statistics
- p->timeOther = p->timeTotal - p->timeWin - p->timeCnf - p->timeSat - p->timeCov - p->timeEnu;
- if ( 0 )
+ p->timeOther = p->timeTotal - p->timeWin - p->timeCut - p->timeCov - p->timeCnf - p->timeSat - p->timeQbf;
+ if ( p->pPars->fVerbose )
{
ABC_PRTP( "Win", p->timeWin , p->timeTotal );
+ ABC_PRTP( "Cut", p->timeCut , p->timeTotal );
+ ABC_PRTP( "Cov", p->timeCov , p->timeTotal );
ABC_PRTP( "Cnf", p->timeCnf , p->timeTotal );
ABC_PRTP( "Sat", p->timeSat , p->timeTotal );
- ABC_PRTP( "Cov", p->timeCov , p->timeTotal );
- ABC_PRTP( "Enu", p->timeEnu , p->timeTotal );
+ ABC_PRTP( "Qbf", p->timeQbf , p->timeTotal );
ABC_PRTP( "Oth", p->timeOther, p->timeTotal );
ABC_PRTP( "ALL", p->timeTotal, p->timeTotal );
}
diff --git a/src/opt/sbd/sbdCut.c b/src/opt/sbd/sbdCut.c
new file mode 100644
index 00000000..59505c98
--- /dev/null
+++ b/src/opt/sbd/sbdCut.c
@@ -0,0 +1,872 @@
+/**CFile****************************************************************
+
+ FileName [sbdCut.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [SAT-based optimization using internal don't-cares.]
+
+ Synopsis [Cut computation.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: sbdCut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sbdInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define SBD_MAX_CUTSIZE 10
+#define SBD_MAX_CUTNUM 501
+#define SBD_MAX_TT_WORDS ((SBD_MAX_CUTSIZE > 6) ? 1 << (SBD_MAX_CUTSIZE-6) : 1)
+
+#define SBD_CUT_NO_LEAF 0xF
+
+typedef struct Sbd_Cut_t_ Sbd_Cut_t;
+struct Sbd_Cut_t_
+{
+ word Sign; // signature
+ int iFunc; // functionality
+ int Cost; // cut cost
+ int CostLev; // cut cost
+ unsigned nTreeLeaves : 9; // tree leaves
+ unsigned nSlowLeaves : 9; // slow leaves
+ unsigned nTopLeaves : 10; // top leaves
+ unsigned nLeaves : 4; // leaf count
+ int pLeaves[SBD_MAX_CUTSIZE]; // leaves
+};
+
+struct Sbd_Sto_t_
+{
+ int nLutSize;
+ int nCutSize;
+ int nCutNum;
+ int fCutMin;
+ int fVerbose;
+ Gia_Man_t * pGia; // user's AIG manager (will be modified by adding nodes)
+ Vec_Int_t * vMirrors; // mirrors for each node
+ Vec_Int_t * vDelays; // delays for each node
+ Vec_Int_t * vLevels; // levels for each node
+ Vec_Int_t * vRefs; // refs for each node
+ Vec_Wec_t * vCuts; // cuts for each node
+ Vec_Mem_t * vTtMem; // truth tables
+ Sbd_Cut_t pCuts[3][SBD_MAX_CUTNUM]; // temporary cuts
+ Sbd_Cut_t * ppCuts[SBD_MAX_CUTNUM]; // temporary cut pointers
+ int nCutsR; // the number of cuts
+ int Pivot; // current object
+ int iCutBest; // best-delay cut
+ int nCutsSpec; // special cuts
+ int nCutsOver; // overflow cuts
+ int DelayMin; // minimum delay
+ double CutCount[4]; // cut counters
+ abctime clkStart; // starting time
+};
+
+static inline word * Sbd_CutTruth( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) { return Vec_MemReadEntry(p->vTtMem, Abc_Lit2Var(pCut->iFunc)); }
+
+#define Sbd_ForEachCut( pList, pCut, i ) for ( i = 0, pCut = pList + 1; i < pList[0]; i++, pCut += pCut[0] + 2 )
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Check correctness of cuts.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline word Sbd_CutGetSign( Sbd_Cut_t * pCut )
+{
+ word Sign = 0; int i;
+ for ( i = 0; i < (int)pCut->nLeaves; i++ )
+ Sign |= ((word)1) << (pCut->pLeaves[i] & 0x3F);
+ return Sign;
+}
+static inline int Sbd_CutCheck( Sbd_Cut_t * pBase, Sbd_Cut_t * pCut ) // check if pCut is contained in pBase
+{
+ int nSizeB = pBase->nLeaves;
+ int nSizeC = pCut->nLeaves;
+ int i, * pB = pBase->pLeaves;
+ int k, * pC = pCut->pLeaves;
+ for ( i = 0; i < nSizeC; i++ )
+ {
+ for ( k = 0; k < nSizeB; k++ )
+ if ( pC[i] == pB[k] )
+ break;
+ if ( k == nSizeB )
+ return 0;
+ }
+ return 1;
+}
+static inline int Sbd_CutSetCheckArray( Sbd_Cut_t ** ppCuts, int nCuts )
+{
+ Sbd_Cut_t * pCut0, * pCut1;
+ int i, k, m, n, Value;
+ assert( nCuts > 0 );
+ for ( i = 0; i < nCuts; i++ )
+ {
+ pCut0 = ppCuts[i];
+ assert( pCut0->nLeaves <= SBD_MAX_CUTSIZE );
+ assert( pCut0->Sign == Sbd_CutGetSign(pCut0) );
+ // check duplicates
+ for ( m = 0; m < (int)pCut0->nLeaves; m++ )
+ for ( n = m + 1; n < (int)pCut0->nLeaves; n++ )
+ assert( pCut0->pLeaves[m] < pCut0->pLeaves[n] );
+ // check pairs
+ for ( k = 0; k < nCuts; k++ )
+ {
+ pCut1 = ppCuts[k];
+ if ( pCut0 == pCut1 )
+ continue;
+ // check containments
+ Value = Sbd_CutCheck( pCut0, pCut1 );
+ assert( Value == 0 );
+ }
+ }
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Sbd_CutMergeOrder( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_Cut_t * pCut, int nCutSize )
+{
+ int nSize0 = pCut0->nLeaves;
+ int nSize1 = pCut1->nLeaves;
+ int i, * pC0 = pCut0->pLeaves;
+ int k, * pC1 = pCut1->pLeaves;
+ int c, * pC = pCut->pLeaves;
+ // the case of the largest cut sizes
+ if ( nSize0 == nCutSize && nSize1 == nCutSize )
+ {
+ for ( i = 0; i < nSize0; i++ )
+ {
+ if ( pC0[i] != pC1[i] ) return 0;
+ pC[i] = pC0[i];
+ }
+ pCut->nLeaves = nCutSize;
+ pCut->iFunc = -1;
+ pCut->Sign = pCut0->Sign | pCut1->Sign;
+ return 1;
+ }
+ // compare two cuts with different numbers
+ i = k = c = 0;
+ if ( nSize0 == 0 ) goto FlushCut1;
+ if ( nSize1 == 0 ) goto FlushCut0;
+ while ( 1 )
+ {
+ if ( c == nCutSize ) return 0;
+ if ( pC0[i] < pC1[k] )
+ {
+ pC[c++] = pC0[i++];
+ if ( i >= nSize0 ) goto FlushCut1;
+ }
+ else if ( pC0[i] > pC1[k] )
+ {
+ pC[c++] = pC1[k++];
+ if ( k >= nSize1 ) goto FlushCut0;
+ }
+ else
+ {
+ pC[c++] = pC0[i++]; k++;
+ if ( i >= nSize0 ) goto FlushCut1;
+ if ( k >= nSize1 ) goto FlushCut0;
+ }
+ }
+
+FlushCut0:
+ if ( c + nSize0 > nCutSize + i ) return 0;
+ while ( i < nSize0 )
+ pC[c++] = pC0[i++];
+ pCut->nLeaves = c;
+ pCut->iFunc = -1;
+ pCut->Sign = pCut0->Sign | pCut1->Sign;
+ return 1;
+
+FlushCut1:
+ if ( c + nSize1 > nCutSize + k ) return 0;
+ while ( k < nSize1 )
+ pC[c++] = pC1[k++];
+ pCut->nLeaves = c;
+ pCut->iFunc = -1;
+ pCut->Sign = pCut0->Sign | pCut1->Sign;
+ return 1;
+}
+static inline int Sbd_CutMergeOrder2( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_Cut_t * pCut, int nCutSize )
+{
+ int x0, i0 = 0, nSize0 = pCut0->nLeaves, * pC0 = pCut0->pLeaves;
+ int x1, i1 = 0, nSize1 = pCut1->nLeaves, * pC1 = pCut1->pLeaves;
+ int xMin, c = 0, * pC = pCut->pLeaves;
+ while ( 1 )
+ {
+ x0 = (i0 == nSize0) ? ABC_INFINITY : pC0[i0];
+ x1 = (i1 == nSize1) ? ABC_INFINITY : pC1[i1];
+ xMin = Abc_MinInt(x0, x1);
+ if ( xMin == ABC_INFINITY ) break;
+ if ( c == nCutSize ) return 0;
+ pC[c++] = xMin;
+ if (x0 == xMin) i0++;
+ if (x1 == xMin) i1++;
+ }
+ pCut->nLeaves = c;
+ pCut->iFunc = -1;
+ pCut->Sign = pCut0->Sign | pCut1->Sign;
+ return 1;
+}
+static inline int Sbd_CutSetCutIsContainedOrder( Sbd_Cut_t * pBase, Sbd_Cut_t * pCut ) // check if pCut is contained in pBase
+{
+ int i, nSizeB = pBase->nLeaves;
+ int k, nSizeC = pCut->nLeaves;
+ if ( nSizeB == nSizeC )
+ {
+ for ( i = 0; i < nSizeB; i++ )
+ if ( pBase->pLeaves[i] != pCut->pLeaves[i] )
+ return 0;
+ return 1;
+ }
+ assert( nSizeB > nSizeC );
+ if ( nSizeC == 0 )
+ return 1;
+ for ( i = k = 0; i < nSizeB; i++ )
+ {
+ if ( pBase->pLeaves[i] > pCut->pLeaves[k] )
+ return 0;
+ if ( pBase->pLeaves[i] == pCut->pLeaves[k] )
+ {
+ if ( ++k == nSizeC )
+ return 1;
+ }
+ }
+ return 0;
+}
+static inline int Sbd_CutSetLastCutIsContained( Sbd_Cut_t ** pCuts, int nCuts )
+{
+ int i;
+ for ( i = 0; i < nCuts; i++ )
+ if ( pCuts[i]->nLeaves <= pCuts[nCuts]->nLeaves && (pCuts[i]->Sign & pCuts[nCuts]->Sign) == pCuts[i]->Sign && Sbd_CutSetCutIsContainedOrder(pCuts[nCuts], pCuts[i]) )
+ return 1;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Sbd_CutCompare( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1 )
+{
+ if ( pCut0->nLeaves <= 4 && pCut1->nLeaves <= 4 )
+ {
+ if ( pCut0->nLeaves < pCut1->nLeaves ) return -1;
+ if ( pCut0->nLeaves > pCut1->nLeaves ) return 1;
+ if ( pCut0->Cost < pCut1->Cost ) return -1;
+ if ( pCut0->Cost > pCut1->Cost ) return 1;
+ if ( pCut0->CostLev < pCut1->CostLev ) return -1;
+ if ( pCut0->CostLev > pCut1->CostLev ) return 1;
+ }
+ else if ( pCut0->nLeaves <= 4 )
+ return -1;
+ else if ( pCut1->nLeaves <= 4 )
+ return 1;
+ else
+ {
+ if ( pCut0->nTreeLeaves < pCut1->nTreeLeaves ) return -1;
+ if ( pCut0->nTreeLeaves > pCut1->nTreeLeaves ) return 1;
+ if ( pCut0->Cost < pCut1->Cost ) return -1;
+ if ( pCut0->Cost > pCut1->Cost ) return 1;
+ if ( pCut0->CostLev < pCut1->CostLev ) return -1;
+ if ( pCut0->CostLev > pCut1->CostLev ) return 1;
+ if ( pCut0->nLeaves < pCut1->nLeaves ) return -1;
+ if ( pCut0->nLeaves > pCut1->nLeaves ) return 1;
+ }
+ return 0;
+}
+static inline int Sbd_CutCompare2( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1 )
+{
+ assert( pCut0->nLeaves > 4 && pCut1->nLeaves > 4 );
+ if ( pCut0->nSlowLeaves < pCut1->nSlowLeaves ) return -1;
+ if ( pCut0->nSlowLeaves > pCut1->nSlowLeaves ) return 1;
+ if ( pCut0->nTreeLeaves < pCut1->nTreeLeaves ) return -1;
+ if ( pCut0->nTreeLeaves > pCut1->nTreeLeaves ) return 1;
+ if ( pCut0->Cost < pCut1->Cost ) return -1;
+ if ( pCut0->Cost > pCut1->Cost ) return 1;
+ if ( pCut0->CostLev < pCut1->CostLev ) return -1;
+ if ( pCut0->CostLev > pCut1->CostLev ) return 1;
+ if ( pCut0->nLeaves < pCut1->nLeaves ) return -1;
+ if ( pCut0->nLeaves > pCut1->nLeaves ) return 1;
+ return 0;
+}
+
+static inline int Sbd_CutSetLastCutContains( Sbd_Cut_t ** pCuts, int nCuts )
+{
+ int i, k, fChanges = 0;
+ for ( i = 0; i < nCuts; i++ )
+ if ( pCuts[nCuts]->nLeaves < pCuts[i]->nLeaves && (pCuts[nCuts]->Sign & pCuts[i]->Sign) == pCuts[nCuts]->Sign && Sbd_CutSetCutIsContainedOrder(pCuts[i], pCuts[nCuts]) )
+ pCuts[i]->nLeaves = SBD_CUT_NO_LEAF, fChanges = 1;
+ if ( !fChanges )
+ return nCuts;
+ for ( i = k = 0; i <= nCuts; i++ )
+ {
+ if ( pCuts[i]->nLeaves == SBD_CUT_NO_LEAF )
+ continue;
+ if ( k < i )
+ ABC_SWAP( Sbd_Cut_t *, pCuts[k], pCuts[i] );
+ k++;
+ }
+ return k - 1;
+}
+static inline void Sbd_CutSetSortByCost( Sbd_Cut_t ** pCuts, int nCuts )
+{
+ int i;
+ for ( i = nCuts; i > 0; i-- )
+ {
+ if ( Sbd_CutCompare(pCuts[i - 1], pCuts[i]) < 0 )//!= 1 )
+ return;
+ ABC_SWAP( Sbd_Cut_t *, pCuts[i - 1], pCuts[i] );
+ }
+}
+static inline int Sbd_CutSetAddCut( Sbd_Cut_t ** pCuts, int nCuts, int nCutNum )
+{
+ if ( nCuts == 0 )
+ return 1;
+ nCuts = Sbd_CutSetLastCutContains(pCuts, nCuts);
+ assert( nCuts >= 0 );
+ Sbd_CutSetSortByCost( pCuts, nCuts );
+ // add new cut if there is room
+ return Abc_MinInt( nCuts + 1, nCutNum - 1 );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Sbd_CutComputeTruth6( Sbd_Sto_t * p, Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, int fCompl0, int fCompl1, Sbd_Cut_t * pCutR, int fIsXor )
+{
+ int nOldSupp = pCutR->nLeaves, truthId, fCompl; word t;
+ word t0 = *Sbd_CutTruth(p, pCut0);
+ word t1 = *Sbd_CutTruth(p, pCut1);
+ if ( Abc_LitIsCompl(pCut0->iFunc) ^ fCompl0 ) t0 = ~t0;
+ if ( Abc_LitIsCompl(pCut1->iFunc) ^ fCompl1 ) t1 = ~t1;
+ t0 = Abc_Tt6Expand( t0, pCut0->pLeaves, pCut0->nLeaves, pCutR->pLeaves, pCutR->nLeaves );
+ t1 = Abc_Tt6Expand( t1, pCut1->pLeaves, pCut1->nLeaves, pCutR->pLeaves, pCutR->nLeaves );
+ t = fIsXor ? t0 ^ t1 : t0 & t1;
+ if ( (fCompl = (int)(t & 1)) ) t = ~t;
+ pCutR->nLeaves = Abc_Tt6MinBase( &t, pCutR->pLeaves, pCutR->nLeaves );
+ assert( (int)(t & 1) == 0 );
+ truthId = Vec_MemHashInsert(p->vTtMem, &t);
+ pCutR->iFunc = Abc_Var2Lit( truthId, fCompl );
+ assert( (int)pCutR->nLeaves <= nOldSupp );
+ return (int)pCutR->nLeaves < nOldSupp;
+}
+static inline int Sbd_CutComputeTruth( Sbd_Sto_t * p, Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, int fCompl0, int fCompl1, Sbd_Cut_t * pCutR, int fIsXor )
+{
+ if ( p->nCutSize <= 6 )
+ return Sbd_CutComputeTruth6( p, pCut0, pCut1, fCompl0, fCompl1, pCutR, fIsXor );
+ {
+ word uTruth[SBD_MAX_TT_WORDS], uTruth0[SBD_MAX_TT_WORDS], uTruth1[SBD_MAX_TT_WORDS];
+ int nOldSupp = pCutR->nLeaves, truthId;
+ int nCutSize = p->nCutSize, fCompl;
+ int nWords = Abc_Truth6WordNum(nCutSize);
+ word * pTruth0 = Sbd_CutTruth(p, pCut0);
+ word * pTruth1 = Sbd_CutTruth(p, pCut1);
+ Abc_TtCopy( uTruth0, pTruth0, nWords, Abc_LitIsCompl(pCut0->iFunc) ^ fCompl0 );
+ Abc_TtCopy( uTruth1, pTruth1, nWords, Abc_LitIsCompl(pCut1->iFunc) ^ fCompl1 );
+ Abc_TtExpand( uTruth0, nCutSize, pCut0->pLeaves, pCut0->nLeaves, pCutR->pLeaves, pCutR->nLeaves );
+ Abc_TtExpand( uTruth1, nCutSize, pCut1->pLeaves, pCut1->nLeaves, pCutR->pLeaves, pCutR->nLeaves );
+ if ( fIsXor )
+ Abc_TtXor( uTruth, uTruth0, uTruth1, nWords, (fCompl = (int)((uTruth0[0] ^ uTruth1[0]) & 1)) );
+ else
+ Abc_TtAnd( uTruth, uTruth0, uTruth1, nWords, (fCompl = (int)((uTruth0[0] & uTruth1[0]) & 1)) );
+ pCutR->nLeaves = Abc_TtMinBase( uTruth, pCutR->pLeaves, pCutR->nLeaves, nCutSize );
+ assert( (uTruth[0] & 1) == 0 );
+//Kit_DsdPrintFromTruth( uTruth, pCutR->nLeaves ), printf("\n" ), printf("\n" );
+ truthId = Vec_MemHashInsert(p->vTtMem, uTruth);
+ pCutR->iFunc = Abc_Var2Lit( truthId, fCompl );
+ assert( (int)pCutR->nLeaves <= nOldSupp );
+ return (int)pCutR->nLeaves < nOldSupp;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Sbd_CutCountBits( word i )
+{
+ i = i - ((i >> 1) & 0x5555555555555555);
+ i = (i & 0x3333333333333333) + ((i >> 2) & 0x3333333333333333);
+ i = ((i + (i >> 4)) & 0x0F0F0F0F0F0F0F0F);
+ return (i*(0x0101010101010101))>>56;
+}
+static inline int Sbd_CutCost( Sbd_Sto_t * p, Sbd_Cut_t * pCut )
+{
+ int i, Cost = 0;
+ for ( i = 0; i < (int)pCut->nLeaves; i++ )
+ Cost += Vec_IntEntry( p->vDelays, pCut->pLeaves[i] );
+ return Cost;
+}
+static inline int Sbd_CutCostLev( Sbd_Sto_t * p, Sbd_Cut_t * pCut )
+{
+ int i, Cost = 0;
+ for ( i = 0; i < (int)pCut->nLeaves; i++ )
+ Cost += Vec_IntEntry( p->vLevels, pCut->pLeaves[i] );
+ return Cost;
+}
+static inline int Sbd_CutTreeLeaves( Sbd_Sto_t * p, Sbd_Cut_t * pCut )
+{
+ int i, Cost = 0;
+ for ( i = 0; i < (int)pCut->nLeaves; i++ )
+ Cost += Vec_IntEntry( p->vRefs, pCut->pLeaves[i] ) == 1;
+ return Cost;
+}
+static inline int Sbd_CutSlowLeaves( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut )
+{
+ int i, Count = 0, Delay = Vec_IntEntry(p->vDelays, iObj);
+ for ( i = 0; i < (int)pCut->nLeaves; i++ )
+ Count += (Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay >= -1);
+ return Count;
+}
+static inline int Sbd_CutTopLeaves( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut )
+{
+ int i, Count = 0, Delay = Vec_IntEntry(p->vDelays, iObj);
+ for ( i = 0; i < (int)pCut->nLeaves; i++ )
+ Count += (Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay == -2);
+ return Count;
+}
+static inline void Sbd_CutAddUnit( Sbd_Sto_t * p, int iObj )
+{
+ Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj );
+ if ( Vec_IntSize(vThis) == 0 )
+ Vec_IntPush( vThis, 1 );
+ else
+ Vec_IntAddToEntry( vThis, 0, 1 );
+ Vec_IntPush( vThis, 1 );
+ Vec_IntPush( vThis, iObj );
+ Vec_IntPush( vThis, 2 );
+}
+static inline void Sbd_CutAddZero( Sbd_Sto_t * p, int iObj )
+{
+ Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj );
+ assert( Vec_IntSize(vThis) == 0 );
+ Vec_IntPush( vThis, 1 );
+ Vec_IntPush( vThis, 0 );
+ Vec_IntPush( vThis, 0 );
+}
+static inline int Sbd_StoPrepareSet( Sbd_Sto_t * p, int iObj, int Index )
+{
+ Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj );
+ int i, v, * pCut, * pList = Vec_IntArray( vThis );
+ Sbd_ForEachCut( pList, pCut, i )
+ {
+ Sbd_Cut_t * pCutTemp = &p->pCuts[Index][i];
+ pCutTemp->nLeaves = pCut[0];
+ for ( v = 1; v <= pCut[0]; v++ )
+ pCutTemp->pLeaves[v-1] = pCut[v];
+ pCutTemp->iFunc = pCut[pCut[0]+1];
+ pCutTemp->Sign = Sbd_CutGetSign( pCutTemp );
+ pCutTemp->Cost = Sbd_CutCost( p, pCutTemp );
+ pCutTemp->CostLev = Sbd_CutCostLev( p, pCutTemp );
+ pCutTemp->nTreeLeaves = Sbd_CutTreeLeaves( p, pCutTemp );
+ pCutTemp->nSlowLeaves = Sbd_CutSlowLeaves( p, iObj, pCutTemp );
+ pCutTemp->nTopLeaves = Sbd_CutTopLeaves( p, iObj, pCutTemp );
+ }
+ return pList[0];
+}
+static inline void Sbd_StoInitResult( Sbd_Sto_t * p )
+{
+ int i;
+ for ( i = 0; i < SBD_MAX_CUTNUM; i++ )
+ p->ppCuts[i] = &p->pCuts[2][i];
+}
+static inline void Sbd_StoStoreResult( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pCuts, int nCuts )
+{
+ int i, v;
+ Vec_Int_t * vList = Vec_WecEntry( p->vCuts, iObj );
+ Vec_IntPush( vList, nCuts );
+ for ( i = 0; i < nCuts; i++ )
+ {
+ Vec_IntPush( vList, pCuts[i]->nLeaves );
+ for ( v = 0; v < (int)pCuts[i]->nLeaves; v++ )
+ Vec_IntPush( vList, pCuts[i]->pLeaves[v] );
+ Vec_IntPush( vList, pCuts[i]->iFunc );
+ }
+}
+static inline void Sbd_StoComputeDelay( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pCuts, int nCuts )
+{
+ int i, v, Delay, DelayMin = ABC_INFINITY;
+ assert( nCuts > 0 );
+ p->iCutBest = -1;
+ for ( i = 0; i < nCuts; i++ )
+ {
+ if ( (int)pCuts[i]->nLeaves > p->nLutSize )
+ continue;
+ Delay = 0;
+ for ( v = 0; v < (int)pCuts[i]->nLeaves; v++ )
+ Delay = Abc_MaxInt( Delay, Vec_IntEntry(p->vDelays, pCuts[i]->pLeaves[v]) );
+ //DelayMin = Abc_MinInt( DelayMin, Delay );
+ if ( DelayMin > Delay )
+ {
+ DelayMin = Delay;
+ p->iCutBest = i;
+ }
+ else if ( DelayMin == Delay && p->iCutBest >= 0 && pCuts[p->iCutBest]->nLeaves > pCuts[i]->nLeaves )
+ p->iCutBest = i;
+ }
+ assert( p->iCutBest >= 0 );
+ assert( DelayMin < ABC_INFINITY );
+ DelayMin = (nCuts > 1 || pCuts[0]->nLeaves > 1) ? DelayMin + 1 : DelayMin;
+ Vec_IntWriteEntry( p->vDelays, iObj, DelayMin );
+ p->DelayMin = Abc_MaxInt( p->DelayMin, DelayMin );
+}
+static inline void Sbd_StoComputeSpec( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pCuts, int nCuts )
+{
+ int i;
+ for ( i = 0; i < nCuts; i++ )
+ {
+ pCuts[i]->nTopLeaves = Sbd_CutTopLeaves( p, iObj, pCuts[i] );
+ pCuts[i]->nSlowLeaves = Sbd_CutSlowLeaves( p, iObj, pCuts[i] );
+ p->nCutsSpec += (pCuts[i]->nSlowLeaves == 0);
+ }
+}
+static inline void Sbd_CutPrint( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut )
+{
+ int i, nDigits = Abc_Base10Log(Gia_ManObjNum(p->pGia));
+ int Delay = Vec_IntEntry(p->vDelays, iObj);
+ if ( pCut == NULL ) { printf( "No cut.\n" ); return; }
+ printf( "%d {", pCut->nLeaves );
+ for ( i = 0; i < (int)pCut->nLeaves; i++ )
+ printf( " %*d", nDigits, pCut->pLeaves[i] );
+ for ( ; i < (int)p->nCutSize; i++ )
+ printf( " %*s", nDigits, " " );
+ printf( " } Cost = %3d CostL = %3d Tree = %d Slow = %d Top = %d ",
+ pCut->Cost, pCut->CostLev, pCut->nTreeLeaves, pCut->nSlowLeaves, pCut->nTopLeaves );
+ printf( "%c ", pCut->nSlowLeaves == 0 ? '*' : ' ' );
+ for ( i = 0; i < (int)pCut->nLeaves; i++ )
+ printf( "%3d ", Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay );
+ printf( "\n" );
+}
+void Sbd_StoMergeCuts( Sbd_Sto_t * p, int iObj )
+{
+ Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj);
+ int fIsXor = Gia_ObjIsXor(pObj);
+ int nCutSize = p->nCutSize;
+ int nCutNum = p->nCutNum;
+ int Lit0m = p->vMirrors ? Vec_IntEntry( p->vMirrors, Gia_ObjFaninId0(pObj, iObj) ) : -1;
+ int Lit1m = p->vMirrors ? Vec_IntEntry( p->vMirrors, Gia_ObjFaninId1(pObj, iObj) ) : -1;
+ int fComp0 = Gia_ObjFaninC0(pObj) ^ (Lit0m >= 0 && Abc_LitIsCompl(Lit0m));
+ int fComp1 = Gia_ObjFaninC1(pObj) ^ (Lit1m >= 0 && Abc_LitIsCompl(Lit1m));
+ int Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, iObj);
+ int Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, iObj);
+ int nCuts0 = Sbd_StoPrepareSet( p, Fan0, 0 );
+ int nCuts1 = Sbd_StoPrepareSet( p, Fan1, 1 );
+ int i, k, nCutsR = 0;
+ Sbd_Cut_t * pCut0, * pCut1, ** pCutsR = p->ppCuts;
+ assert( !Gia_ObjIsBuf(pObj) );
+ assert( !Gia_ObjIsMux(p->pGia, pObj) );
+ Sbd_StoInitResult( p );
+ p->CutCount[0] += nCuts0 * nCuts1;
+ for ( i = 0, pCut0 = p->pCuts[0]; i < nCuts0; i++, pCut0++ )
+ for ( k = 0, pCut1 = p->pCuts[1]; k < nCuts1; k++, pCut1++ )
+ {
+ if ( (int)(pCut0->nLeaves + pCut1->nLeaves) > nCutSize && Sbd_CutCountBits(pCut0->Sign | pCut1->Sign) > nCutSize )
+ continue;
+ p->CutCount[1]++;
+ if ( !Sbd_CutMergeOrder(pCut0, pCut1, pCutsR[nCutsR], nCutSize) )
+ continue;
+ if ( Sbd_CutSetLastCutIsContained(pCutsR, nCutsR) )
+ continue;
+ p->CutCount[2]++;
+ if ( p->fCutMin && Sbd_CutComputeTruth(p, pCut0, pCut1, fComp0, fComp1, pCutsR[nCutsR], fIsXor) )
+ pCutsR[nCutsR]->Sign = Sbd_CutGetSign(pCutsR[nCutsR]);
+ pCutsR[nCutsR]->Cost = Sbd_CutCost( p, pCutsR[nCutsR] );
+ pCutsR[nCutsR]->CostLev = Sbd_CutCostLev( p, pCutsR[nCutsR] );
+ pCutsR[nCutsR]->nTreeLeaves = Sbd_CutTreeLeaves( p, pCutsR[nCutsR] );
+ nCutsR = Sbd_CutSetAddCut( pCutsR, nCutsR, nCutNum );
+ }
+ Sbd_StoComputeDelay( p, iObj, pCutsR, nCutsR );
+ Sbd_StoComputeSpec( p, iObj, pCutsR, nCutsR );
+ p->CutCount[3] += nCutsR;
+ p->nCutsOver += nCutsR == nCutNum-1;
+ p->nCutsR = nCutsR;
+ p->Pivot = iObj;
+ // debug printout
+ if ( 0 )
+ {
+ printf( "*** Obj = %4d Delay = %4d NumCuts = %4d\n", iObj, Vec_IntEntry(p->vDelays, iObj), nCutsR );
+ for ( i = 0; i < nCutsR; i++ )
+ if ( (int)pCutsR[i]->nLeaves <= p->nLutSize || pCutsR[i]->nSlowLeaves < 2 )
+ Sbd_CutPrint( p, iObj, pCutsR[i] );
+ printf( "\n" );
+ }
+ // verify
+ assert( nCutsR > 0 && nCutsR < nCutNum );
+ assert( Sbd_CutSetCheckArray(pCutsR, nCutsR) );
+ // store the cutset
+ Sbd_StoStoreResult( p, iObj, pCutsR, nCutsR );
+ if ( nCutsR > 1 || pCutsR[0]->nLeaves > 1 )
+ Sbd_CutAddUnit( p, iObj );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Incremental cut computation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, Vec_Int_t * vMirrors, int nLutSize, int nCutSize, int nCutNum, int fCutMin, int fVerbose )
+{
+ Sbd_Sto_t * p;
+ assert( nLutSize <= nCutSize );
+ assert( nCutSize < SBD_CUT_NO_LEAF );
+ assert( nCutSize > 1 && nCutSize <= SBD_MAX_CUTSIZE );
+ assert( nCutNum > 1 && nCutNum < SBD_MAX_CUTNUM );
+ p = ABC_CALLOC( Sbd_Sto_t, 1 );
+ p->clkStart = Abc_Clock();
+ p->nLutSize = nLutSize;
+ p->nCutSize = nCutSize;
+ p->nCutNum = nCutNum;
+ p->fCutMin = fCutMin;
+ p->fVerbose = fVerbose;
+ p->pGia = pGia;
+ p->vMirrors = vMirrors;
+ p->vDelays = Vec_IntStart( Gia_ManObjNum(pGia) );
+ p->vLevels = Vec_IntStart( Gia_ManObjNum(pGia) );
+ p->vRefs = Vec_IntAlloc( Gia_ManObjNum(pGia) );
+ p->vCuts = Vec_WecStart( Gia_ManObjNum(pGia) );
+ p->vTtMem = fCutMin ? Vec_MemAllocForTT( nCutSize, 0 ) : NULL;
+ return p;
+}
+void Sbd_StoFree( Sbd_Sto_t * p )
+{
+ Vec_IntFree( p->vDelays );
+ Vec_IntFree( p->vLevels );
+ Vec_IntFree( p->vRefs );
+ Vec_WecFree( p->vCuts );
+ if ( p->fCutMin )
+ Vec_MemHashFree( p->vTtMem );
+ if ( p->fCutMin )
+ Vec_MemFree( p->vTtMem );
+ ABC_FREE( p );
+}
+void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level )
+{
+ if ( iObj < Vec_IntSize(p->vDelays) )
+ {
+ Vec_IntWriteEntry( p->vDelays, iObj, Delay );
+ Vec_IntWriteEntry( p->vLevels, iObj, Level );
+ }
+ else
+ {
+ assert( iObj == Vec_IntSize(p->vDelays) );
+ assert( iObj == Vec_IntSize(p->vLevels) );
+ assert( iObj == Vec_WecSize(p->vCuts) );
+ Vec_IntPush( p->vDelays, Delay );
+ Vec_IntPush( p->vLevels, Level );
+ Vec_WecPushLevel( p->vCuts );
+ }
+}
+void Sbd_StoComputeCutsConst0( Sbd_Sto_t * p, int iObj )
+{
+ Sbd_StoComputeCutsObj( p, iObj, 0, 0 );
+ Sbd_CutAddZero( p, iObj );
+}
+void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level )
+{
+ Sbd_StoComputeCutsObj( p, iObj, Delay, Level );
+ Sbd_CutAddUnit( p, iObj );
+}
+int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj )
+{
+ Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj);
+ int Lev0 = Vec_IntEntry( p->vLevels, Gia_ObjFaninId0(pObj, iObj) );
+ int Lev1 = Vec_IntEntry( p->vLevels, Gia_ObjFaninId1(pObj, iObj) );
+ Sbd_StoComputeCutsObj( p, iObj, -1, 1 + Abc_MaxInt(Lev0, Lev1) );
+ Sbd_StoMergeCuts( p, iObj );
+ return Vec_IntEntry( p->vDelays, iObj );
+}
+void Sbd_StoSaveBestDelayCut( Sbd_Sto_t * p, int iObj, int * pCut )
+{
+ Sbd_Cut_t * pCutBest = p->ppCuts[p->iCutBest]; int i;
+ assert( iObj == p->Pivot );
+ pCut[0] = pCutBest->nLeaves;
+ for ( i = 0; i < (int)pCutBest->nLeaves; i++ )
+ pCut[i+1] = pCutBest->pLeaves[i];
+}
+int Sbd_StoObjRefs( Sbd_Sto_t * p, int iObj )
+{
+ return Vec_IntEntry(p->vRefs, iObj);
+}
+void Sbd_StoRefObj( Sbd_Sto_t * p, int iObj, int iMirror )
+{
+ Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj);
+ assert( iObj == Vec_IntSize(p->vRefs) );
+ assert( iMirror < iObj );
+ Vec_IntPush( p->vRefs, 0 );
+//printf( "Ref %d\n", iObj );
+ if ( iMirror > 0 )
+ {
+ Vec_IntWriteEntry( p->vRefs, iObj, Vec_IntEntry(p->vRefs, iMirror) );
+ Vec_IntWriteEntry( p->vRefs, iMirror, 1 );
+ }
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ int Lit0m = Vec_IntEntry( p->vMirrors, Gia_ObjFaninId0(pObj, iObj) );
+ int Lit1m = Vec_IntEntry( p->vMirrors, Gia_ObjFaninId1(pObj, iObj) );
+ int Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, iObj);
+ int Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, iObj);
+ Vec_IntAddToEntry( p->vRefs, Fan0, 1 );
+ Vec_IntAddToEntry( p->vRefs, Fan1, 1 );
+ }
+ else if ( Gia_ObjIsCo(pObj) )
+ {
+ int Lit0m = Vec_IntEntry( p->vMirrors, Gia_ObjFaninId0(pObj, iObj) );
+ assert( Lit0m == -1 );
+ Vec_IntAddToEntry( p->vRefs, Gia_ObjFaninId0(pObj, iObj), 1 );
+ }
+}
+void Sbd_StoDerefObj( Sbd_Sto_t * p, int iObj )
+{
+ Gia_Obj_t * pObj;
+ int Lit0m, Lit1m, Fan0, Fan1;
+ return;
+
+ pObj = Gia_ManObj(p->pGia, iObj);
+ if ( Vec_IntEntry(p->vRefs, iObj) == 0 )
+ printf( "Ref count mismatch at node %d\n", iObj );
+ assert( Vec_IntEntry(p->vRefs, iObj) > 0 );
+ Vec_IntAddToEntry( p->vRefs, iObj, -1 );
+ if ( Vec_IntEntry( p->vRefs, iObj ) > 0 )
+ return;
+ if ( Gia_ObjIsCi(pObj) )
+ return;
+//printf( "Deref %d\n", iObj );
+ assert( Gia_ObjIsAnd(pObj) );
+ Lit0m = Vec_IntEntry( p->vMirrors, Gia_ObjFaninId0(pObj, iObj) );
+ Lit1m = Vec_IntEntry( p->vMirrors, Gia_ObjFaninId1(pObj, iObj) );
+ Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, iObj);
+ Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, iObj);
+ if ( Fan0 ) Sbd_StoDerefObj( p, Fan0 );
+ if ( Fan1 ) Sbd_StoDerefObj( p, Fan1 );
+}
+int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int nSize, int * pLeaves )
+{
+ int fVerbose = 0;
+ Sbd_Cut_t * pCutBest = NULL; int i;
+ assert( p->Pivot == iObj );
+ if ( fVerbose && iObj % 1000 == 0 )
+ printf( "Node %6d : \n", iObj );
+ for ( i = 0; i < p->nCutsR; i++ )
+ {
+ if ( fVerbose && iObj % 1000 == 0 )
+ Sbd_CutPrint( p, iObj, p->ppCuts[i] );
+ if ( nSize && (int)p->ppCuts[i]->nLeaves != nSize )
+ continue;
+ if ( (int)p->ppCuts[i]->nLeaves > p->nLutSize &&
+ (int)p->ppCuts[i]->nSlowLeaves <= 1 &&
+ (int)p->ppCuts[i]->nTopLeaves <= p->nLutSize-1 &&
+ (pCutBest == NULL || Sbd_CutCompare2(pCutBest, p->ppCuts[i]) == 1) )
+ pCutBest = p->ppCuts[i];
+ }
+ if ( fVerbose && iObj % 1000 == 0 )
+ {
+ printf( "Best cut of size %d:\n", nSize );
+ Sbd_CutPrint( p, iObj, pCutBest );
+ }
+ if ( pCutBest == NULL )
+ return -1;
+ assert( pCutBest->nLeaves <= SBD_DIV_MAX );
+ for ( i = 0; i < (int)pCutBest->nLeaves; i++ )
+ pLeaves[i] = pCutBest->pLeaves[i];
+ return pCutBest->nLeaves;
+}
+void Sbd_StoComputeCutsTest( Gia_Man_t * pGia )
+{
+ Sbd_Sto_t * p = Sbd_StoAlloc( pGia, NULL, 4, 8, 100, 1, 1 );
+ Gia_Obj_t * pObj;
+ int i, iObj;
+ // prepare references
+ Gia_ManForEachObj( p->pGia, pObj, iObj )
+ Sbd_StoRefObj( p, iObj, -1 );
+ // compute cuts
+ Sbd_StoComputeCutsConst0( p, 0 );
+ Gia_ManForEachCiId( p->pGia, iObj, i )
+ Sbd_StoComputeCutsCi( p, iObj, 0, 0 );
+ Gia_ManForEachAnd( p->pGia, pObj, iObj )
+ Sbd_StoComputeCutsNode( p, iObj );
+ if ( p->fVerbose )
+ {
+ printf( "Running cut computation with LutSize = %d CutSize = %d CutNum = %d:\n", p->nLutSize, p->nCutSize, p->nCutNum );
+ 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( "Spec = %4d ", p->nCutsSpec );
+ printf( "Over = %4d ", p->nCutsOver );
+ printf( "Lev = %4d ", p->DelayMin );
+ Abc_PrintTime( 0, "Time", Abc_Clock() - p->clkStart );
+ }
+ Sbd_StoFree( p );
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/opt/sbd/sbdCut2.c b/src/opt/sbd/sbdCut2.c
new file mode 100644
index 00000000..b4a8be74
--- /dev/null
+++ b/src/opt/sbd/sbdCut2.c
@@ -0,0 +1,431 @@
+/**CFile****************************************************************
+
+ FileName [sbdCut2.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [SAT-based optimization using internal don't-cares.]
+
+ Synopsis [Cut computation.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: sbdCut2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sbdInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define SBD_MAX_CUTSIZE 10
+#define SBD_MAX_CUTNUM 501
+
+#define SBD_CUT_NO_LEAF 0xF
+
+typedef struct Sbd_Cut_t_ Sbd_Cut_t;
+struct Sbd_Cut_t_
+{
+ word Sign; // signature
+ int iFunc; // functionality
+ int Cost; // cut cost
+ int CostLev; // cut cost
+ unsigned nTreeLeaves : 9; // tree leaves
+ unsigned nSlowLeaves : 9; // slow leaves
+ unsigned nTopLeaves : 10; // top leaves
+ unsigned nLeaves : 4; // leaf count
+ int pLeaves[SBD_MAX_CUTSIZE]; // leaves
+};
+
+struct Sbd_Srv_t_
+{
+ int nLutSize;
+ int nCutSize;
+ int nCutNum;
+ int fVerbose;
+ Gia_Man_t * pGia; // user's AIG manager (will be modified by adding nodes)
+ Vec_Int_t * vMirrors; // mirrors for each node
+ Vec_Int_t * vLutLevs; // delays for each node
+ Vec_Int_t * vLevs; // levels for each node
+ Vec_Int_t * vRefs; // refs for each node
+ Sbd_Cut_t pCuts[SBD_MAX_CUTNUM]; // temporary cuts
+ Sbd_Cut_t * ppCuts[SBD_MAX_CUTNUM]; // temporary cut pointers
+ abctime clkStart; // starting time
+ Vec_Int_t * vCut0; // current cut
+ Vec_Int_t * vCut; // current cut
+ Vec_Int_t * vCutTop; // current cut
+ Vec_Int_t * vCutBot; // current cut
+};
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Sbd_Srv_t * Sbd_ManCutServerStart( Gia_Man_t * pGia, Vec_Int_t * vMirrors,
+ Vec_Int_t * vLutLevs, Vec_Int_t * vLevs, Vec_Int_t * vRefs,
+ int nLutSize, int nCutSize, int nCutNum, int fVerbose )
+{
+ Sbd_Srv_t * p;
+ assert( nLutSize <= nCutSize );
+ assert( nCutSize < SBD_CUT_NO_LEAF );
+ assert( nCutSize > 1 && nCutSize <= SBD_MAX_CUTSIZE );
+ assert( nCutNum > 1 && nCutNum < SBD_MAX_CUTNUM );
+ p = ABC_CALLOC( Sbd_Srv_t, 1 );
+ p->clkStart = Abc_Clock();
+ p->nLutSize = nLutSize;
+ p->nCutSize = nCutSize;
+ p->nCutNum = nCutNum;
+ p->fVerbose = fVerbose;
+ p->pGia = pGia;
+ p->vMirrors = vMirrors;
+ p->vLutLevs = vLutLevs;
+ p->vLevs = vLevs;
+ p->vRefs = vRefs;
+ p->vCut0 = Vec_IntAlloc( 100 );
+ p->vCut = Vec_IntAlloc( 100 );
+ p->vCutTop = Vec_IntAlloc( 100 );
+ p->vCutBot = Vec_IntAlloc( 100 );
+ return p;
+}
+void Sbd_ManCutServerStop( Sbd_Srv_t * p )
+{
+ Vec_IntFree( p->vCut0 );
+ Vec_IntFree( p->vCut );
+ Vec_IntFree( p->vCutTop );
+ Vec_IntFree( p->vCutBot );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Sbd_ManCutIsTopo_rec( Gia_Man_t * p, Vec_Int_t * vMirrors, int iObj )
+{
+ Gia_Obj_t * pObj;
+ int Ret0, Ret1;
+ if ( Vec_IntEntry(vMirrors, iObj) >= 0 )
+ iObj = Abc_Lit2Var(Vec_IntEntry(vMirrors, iObj));
+ if ( !iObj || Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return 1;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ pObj = Gia_ManObj( p, iObj );
+ if ( Gia_ObjIsCi(pObj) )
+ return 0;
+ assert( Gia_ObjIsAnd(pObj) );
+ Ret0 = Sbd_ManCutIsTopo_rec( p, vMirrors, Gia_ObjFaninId0(pObj, iObj) );
+ Ret1 = Sbd_ManCutIsTopo_rec( p, vMirrors, Gia_ObjFaninId1(pObj, iObj) );
+ return Ret0 && Ret1;
+}
+int Sbd_ManCutIsTopo( Gia_Man_t * p, Vec_Int_t * vMirrors, Vec_Int_t * vCut, int iObj )
+{
+ int i, Entry, RetValue;
+ Gia_ManIncrementTravId( p );
+ Vec_IntForEachEntry( vCut, Entry, i )
+ Gia_ObjSetTravIdCurrentId( p, Entry );
+ RetValue = Sbd_ManCutIsTopo_rec( p, vMirrors, iObj );
+ if ( RetValue == 0 )
+ printf( "Cut of node %d is not tological\n", iObj );
+ assert( RetValue );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Sbd_ManCutExpandOne( Gia_Man_t * p, Vec_Int_t * vMirrors, Vec_Int_t * vLutLevs, Vec_Int_t * vCut, int iThis, int iObj )
+{
+ int Lit0m, Lit1m, Fan0, Fan1, iPlace0, iPlace1;
+ int LutLev = Vec_IntEntry( vLutLevs, iObj );
+ Gia_Obj_t * pObj = Gia_ManObj(p, iObj);
+ if ( Gia_ObjIsCi(pObj) )
+ return 0;
+ assert( Gia_ObjIsAnd(pObj) );
+ Lit0m = Vec_IntEntry( vMirrors, Gia_ObjFaninId0(pObj, iObj) );
+ Lit1m = Vec_IntEntry( vMirrors, Gia_ObjFaninId1(pObj, iObj) );
+ Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, iObj);
+ Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, iObj);
+ iPlace0 = Vec_IntFind( vCut, Fan0 );
+ iPlace1 = Vec_IntFind( vCut, Fan1 );
+ if ( iPlace0 == -1 && iPlace1 == -1 )
+ return 0;
+ if ( Vec_IntEntry(vLutLevs, Fan0) > LutLev || Vec_IntEntry(vLutLevs, Fan1) > LutLev )
+ return 0;
+ Vec_IntDrop( vCut, iThis );
+ if ( iPlace0 == -1 && Fan0 )
+ Vec_IntPushOrder( vCut, Fan0 );
+ if ( iPlace1 == -1 && Fan1 )
+ Vec_IntPushOrder( vCut, Fan1 );
+ return 1;
+}
+void Vec_IntIsOrdered( Vec_Int_t * vCut )
+{
+ int i, Prev, Entry;
+ Prev = Vec_IntEntry( vCut, 0 );
+ Vec_IntForEachEntryStart( vCut, Entry, i, 1 )
+ {
+ assert( Prev < Entry );
+ Prev = Entry;
+ }
+}
+void Sbd_ManCutExpand( Gia_Man_t * p, Vec_Int_t * vMirrors, Vec_Int_t * vLutLevs, Vec_Int_t * vCut )
+{
+ int i, Entry;
+ do
+ {
+ Vec_IntForEachEntry( vCut, Entry, i )
+ if ( Sbd_ManCutExpandOne( p, vMirrors, vLutLevs, vCut, i, Entry ) )
+ break;
+ }
+ while ( i < Vec_IntSize(vCut) );
+}
+void Sbd_ManCutReload( Vec_Int_t * vMirrors, Vec_Int_t * vLutLevs, int LevStop, Vec_Int_t * vCut, Vec_Int_t * vCutTop, Vec_Int_t * vCutBot )
+{
+ int i, Entry;
+ Vec_IntClear( vCutTop );
+ Vec_IntClear( vCutBot );
+ Vec_IntForEachEntry( vCut, Entry, i )
+ {
+ assert( Entry );
+ assert( Vec_IntEntry(vMirrors, Entry) == -1 );
+ assert( Vec_IntEntry(vLutLevs, Entry) <= LevStop );
+ if ( Vec_IntEntry(vLutLevs, Entry) == LevStop )
+ Vec_IntPush( vCutTop, Entry );
+ else
+ Vec_IntPush( vCutBot, Entry );
+ }
+ Vec_IntIsOrdered( 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 )
+{
+ Gia_Obj_t * pObj;
+ int Ret0, Ret1;
+ if ( Vec_IntEntry(vMirrors, iObj) >= 0 )
+ iObj = Abc_Lit2Var(Vec_IntEntry(vMirrors, iObj));
+ if ( !iObj || Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return 1;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ pObj = Gia_ManObj( p, iObj );
+ if ( Gia_ObjIsCi(pObj) || Vec_IntEntry(vLutLevs, iObj) <= LevStop )
+ {
+ Vec_IntPush( vCut, iObj );
+ return Vec_IntEntry(vLutLevs, iObj) <= LevStop;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ Ret0 = Sbd_ManCutCollect_rec( p, vMirrors, Gia_ObjFaninId0(pObj, iObj), LevStop, vLutLevs, vCut );
+ Ret1 = Sbd_ManCutCollect_rec( p, vMirrors, Gia_ObjFaninId1(pObj, iObj), LevStop, vLutLevs, vCut );
+ return Ret0 && Ret1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Sbd_ManCutReduceTop( Gia_Man_t * p, Vec_Int_t * vMirrors, int iObj, Vec_Int_t * vLutLevs, Vec_Int_t * vCut, Vec_Int_t * vCutTop, int nCutSize )
+{
+ int i, Entry, Lit0m, Lit1m, Fan0, Fan1;
+ int LevStop = Vec_IntEntry(vLutLevs, iObj) - 2;
+ Vec_IntIsOrdered( vCut );
+ Vec_IntForEachEntryReverse( vCutTop, Entry, i )
+ {
+ Gia_Obj_t * pObj = Gia_ManObj( p, Entry );
+ if ( Gia_ObjIsCi(pObj) )
+ continue;
+ assert( Gia_ObjIsAnd(pObj) );
+ assert( Vec_IntEntry(vLutLevs, Entry) == LevStop );
+ Lit0m = Vec_IntEntry( vMirrors, Gia_ObjFaninId0(pObj, Entry) );
+ Lit1m = Vec_IntEntry( vMirrors, Gia_ObjFaninId1(pObj, Entry) );
+ Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, Entry);
+ Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, Entry);
+ if ( Vec_IntEntry(vLutLevs, Fan0) > LevStop || Vec_IntEntry(vLutLevs, Fan1) > LevStop )
+ continue;
+ assert( Vec_IntEntry(vLutLevs, Fan0) <= LevStop );
+ assert( Vec_IntEntry(vLutLevs, Fan1) <= LevStop );
+ if ( Vec_IntEntry(vLutLevs, Fan0) == LevStop && Vec_IntEntry(vLutLevs, Fan1) == LevStop )
+ continue;
+ Vec_IntRemove( vCut, Entry );
+ if ( Fan0 ) Vec_IntPushUniqueOrder( vCut, Fan0 );
+ if ( Fan1 ) Vec_IntPushUniqueOrder( vCut, Fan1 );
+ //Sbd_ManCutIsTopo( p, vMirrors, vCut, iObj );
+ return 1;
+ }
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Sbd_ManCutServerFirst( Sbd_Srv_t * p, int iObj, int * pLeaves )
+{
+ int RetValue, LevStop = Vec_IntEntry(p->vLutLevs, iObj) - 2;
+
+ Vec_IntClear( p->vCut );
+ Gia_ManIncrementTravId( p->pGia );
+ RetValue = Sbd_ManCutCollect_rec( p->pGia, p->vMirrors, iObj, LevStop, p->vLutLevs, p->vCut );
+ if ( RetValue == 0 ) // cannot build delay-improving cut
+ return -1;
+ // check if the current cut is good
+ Vec_IntSort( p->vCut, 0 );
+/*
+ Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot );
+ if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 )
+ {
+ //printf( "%d ", Vec_IntSize(p->vCut) );
+ memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) );
+ return Vec_IntSize(p->vCut);
+ }
+*/
+ // try to expand the cut
+ Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut );
+ Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot );
+ if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 )
+ {
+ //printf( "1=(%d,%d) ", Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) );
+ //printf( "%d ", Vec_IntSize(p->vCut) );
+ memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) );
+ return Vec_IntSize(p->vCut);
+ }
+
+ // try to reduce the topmost
+ Vec_IntClear( p->vCut0 );
+ Vec_IntAppend( p->vCut0, p->vCut );
+ if ( Vec_IntSize(p->vCut) < p->nCutSize && Sbd_ManCutReduceTop( p->pGia, p->vMirrors, iObj, p->vLutLevs, p->vCut, p->vCutTop, p->nCutSize ) )
+ {
+ Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut );
+ Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot );
+ assert( Vec_IntSize(p->vCut) <= p->nCutSize );
+ if ( Vec_IntSize(p->vCutTop) <= p->nLutSize-1 )
+ {
+ //printf( "%d -> %d (%d + %d)\n", Vec_IntSize(p->vCut0), Vec_IntSize(p->vCut), Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) );
+ memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) );
+ return Vec_IntSize(p->vCut);
+ }
+ // try again
+ if ( Vec_IntSize(p->vCut) < p->nCutSize && Sbd_ManCutReduceTop( p->pGia, p->vMirrors, iObj, p->vLutLevs, p->vCut, p->vCutTop, p->nCutSize ) )
+ {
+ Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut );
+ Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot );
+ assert( Vec_IntSize(p->vCut) <= p->nCutSize );
+ if ( Vec_IntSize(p->vCutTop) <= p->nLutSize-1 )
+ {
+ //printf( "* %d -> %d (%d + %d)\n", Vec_IntSize(p->vCut0), Vec_IntSize(p->vCut), Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) );
+ memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) );
+ return Vec_IntSize(p->vCut);
+ }
+ // try again
+ if ( Vec_IntSize(p->vCut) < p->nCutSize && Sbd_ManCutReduceTop( p->pGia, p->vMirrors, iObj, p->vLutLevs, p->vCut, p->vCutTop, p->nCutSize ) )
+ {
+ Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut );
+ Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot );
+ assert( Vec_IntSize(p->vCut) <= p->nCutSize );
+ if ( Vec_IntSize(p->vCutTop) <= p->nLutSize-1 )
+ {
+ //printf( "** %d -> %d (%d + %d)\n", Vec_IntSize(p->vCut0), Vec_IntSize(p->vCut), Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) );
+ memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) );
+ return Vec_IntSize(p->vCut);
+ }
+ // try again
+ if ( Vec_IntSize(p->vCut) < p->nCutSize && Sbd_ManCutReduceTop( p->pGia, p->vMirrors, iObj, p->vLutLevs, p->vCut, p->vCutTop, p->nCutSize ) )
+ {
+ Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut );
+ Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot );
+ assert( Vec_IntSize(p->vCut) <= p->nCutSize );
+ if ( Vec_IntSize(p->vCutTop) <= p->nLutSize-1 )
+ {
+ //printf( "*** %d -> %d (%d + %d)\n", Vec_IntSize(p->vCut0), Vec_IntSize(p->vCut), Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) );
+ memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) );
+ return Vec_IntSize(p->vCut);
+ }
+ }
+ }
+ }
+ }
+
+ // recompute the cut
+ Vec_IntClear( p->vCut );
+ Gia_ManIncrementTravId( p->pGia );
+ RetValue = Sbd_ManCutCollect_rec( p->pGia, p->vMirrors, iObj, LevStop-1, p->vLutLevs, p->vCut );
+ if ( RetValue == 0 ) // cannot build delay-improving cut
+ return -1;
+ // check if the current cut is good
+ Vec_IntSort( p->vCut, 0 );
+/*
+ Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot );
+ if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 )
+ {
+ //printf( "%d ", Vec_IntSize(p->vCut) );
+ memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) );
+ return Vec_IntSize(p->vCut);
+ }
+*/
+ // try to expand the cut
+ Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut );
+ Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot );
+ if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 )
+ {
+ //printf( "2=(%d,%d) ", Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) );
+ //printf( "%d ", Vec_IntSize(p->vCut) );
+ memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) );
+ return Vec_IntSize(p->vCut);
+ }
+
+ return -1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/opt/sbd/sbdInt.h b/src/opt/sbd/sbdInt.h
index 4c553fb4..eabe5355 100644
--- a/src/opt/sbd/sbdInt.h
+++ b/src/opt/sbd/sbdInt.h
@@ -52,10 +52,26 @@ ABC_NAMESPACE_HEADER_START
#define SBD_SAT_UNDEC 0x1234567812345678
#define SBD_SAT_SAT 0x8765432187654321
+#define SBD_LUTS_MAX 2
+#define SBD_SIZE_MAX 4
+#define SBD_DIV_MAX 10
+#define SBD_FVAR_MAX 100
+
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
+typedef struct Sbd_Sto_t_ Sbd_Sto_t;
+typedef struct Sbd_Srv_t_ Sbd_Srv_t;
+
+typedef struct Sbd_Str_t_ Sbd_Str_t;
+struct Sbd_Str_t_
+{
+ int fLut; // LUT or SEL
+ int nVarIns; // input count
+ int VarIns[SBD_DIV_MAX]; // input vars
+ word Res; // result of solving
+};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
@@ -66,7 +82,38 @@ ABC_NAMESPACE_HEADER_START
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-/*=== sbdCnf.c ==========================================================*/
+/*=== sbdCut.c ==========================================================*/
+extern Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, Vec_Int_t * vMirrors, int nLutSize, int nCutSize, int nCutNum, int fCutMin, int fVerbose );
+extern void Sbd_StoFree( Sbd_Sto_t * p );
+extern int Sbd_StoObjRefs( Sbd_Sto_t * p, int iObj );
+extern void Sbd_StoRefObj( Sbd_Sto_t * p, int iObj, int iMirror );
+extern void Sbd_StoDerefObj( Sbd_Sto_t * p, int iObj );
+extern void Sbd_StoComputeCutsConst0( Sbd_Sto_t * p, int iObj );
+extern void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level );
+extern void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level );
+extern int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj );
+extern void Sbd_StoSaveBestDelayCut( Sbd_Sto_t * p, int iObj, int * pCut );
+extern int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int nSize, int * pLeaves );
+/*=== sbdCut2.c ==========================================================*/
+extern Sbd_Srv_t * Sbd_ManCutServerStart( Gia_Man_t * pGia, Vec_Int_t * vMirrors,
+ Vec_Int_t * vLutLevs, Vec_Int_t * vLevs, Vec_Int_t * vRefs,
+ int nLutSize, int nCutSize, int nCutNum, int fVerbose );
+extern void Sbd_ManCutServerStop( Sbd_Srv_t * p );
+extern int Sbd_ManCutServerFirst( Sbd_Srv_t * p, int iObj, int * pLeaves );
+/*=== sbdWin.c ==========================================================*/
+extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivSet, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp );
+extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf );
+extern int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, word * pVarSims[], Vec_Int_t * vInds );
+extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset );
+/*=== sbdPath.c ==========================================================*/
+extern Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p );
+/*=== sbdQbf.c ==========================================================*/
+extern int Sbd_ProblemSolve(
+ Gia_Man_t * p, Vec_Int_t * vMirrors,
+ int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var,
+ Vec_Int_t * vTfo, Vec_Int_t * vRoots,
+ Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0
+ );
ABC_NAMESPACE_HEADER_END
diff --git a/src/opt/sbd/sbdLut.c b/src/opt/sbd/sbdLut.c
new file mode 100644
index 00000000..ffcb71f8
--- /dev/null
+++ b/src/opt/sbd/sbdLut.c
@@ -0,0 +1,311 @@
+/**CFile****************************************************************
+
+ FileName [sbdLut.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [SAT-based optimization using internal don't-cares.]
+
+ Synopsis [CNF computation.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: sbdLut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sbdInt.h"
+#include "misc/util/utilTruth.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+// count the number of parameter variables in the structure
+int Sbd_ProblemCountParams( int nStrs, Sbd_Str_t * pStr0 )
+{
+ Sbd_Str_t * pStr; int nPars = 0;
+ for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++ )
+ nPars += pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns;
+ return nPars;
+}
+// add clauses for the structure
+int Sbd_ProblemAddClauses( sat_solver * pSat, int nVars, int nStrs, int * pVars, Sbd_Str_t * pStr0 )
+{
+ // variable order: inputs, structure outputs, parameters
+ Sbd_Str_t * pStr;
+ int VarOut = nVars;
+ int VarPar = nVars + nStrs;
+ int m, k, n, status, pLits[SBD_SIZE_MAX+2];
+//printf( "Start par = %d. ", VarPar );
+ for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++, VarOut++ )
+ {
+ if ( pStr->fLut )
+ {
+ int nMints = 1 << pStr->nVarIns;
+ assert( pStr->nVarIns <= 6 );
+ for ( m = 0; m < nMints; m++, VarPar++ )
+ {
+ for ( k = 0; k < pStr->nVarIns; k++ )
+ pLits[k] = Abc_Var2Lit( pVars[pStr->VarIns[k]], (m >> k) & 1 );
+ for ( n = 0; n < 2; n++ )
+ {
+ pLits[pStr->nVarIns] = Abc_Var2Lit( pVars[VarPar], n );
+ pLits[pStr->nVarIns+1] = Abc_Var2Lit( pVars[VarOut], !n );
+ status = sat_solver_addclause( pSat, pLits, pLits + pStr->nVarIns + 2 );
+ if ( !status )
+ return 0;
+ }
+ }
+ }
+ else
+ {
+ assert( pStr->nVarIns <= SBD_DIV_MAX );
+ for ( k = 0; k < pStr->nVarIns; k++, VarPar++ )
+ {
+ for ( n = 0; n < 2; n++ )
+ {
+ pLits[0] = Abc_Var2Lit( pVars[VarPar], 1 );
+ pLits[1] = Abc_Var2Lit( pVars[VarOut], n );
+ pLits[2] = Abc_Var2Lit( pVars[pStr->VarIns[k]], !n );
+ status = sat_solver_addclause( pSat, pLits, pLits + 3 );
+ if ( !status )
+ return 0;
+ }
+ }
+ }
+ }
+ return 1;
+}
+void Sbd_ProblemAddClausesInit( sat_solver * pSat, int nVars, int nStrs, int * pVars, Sbd_Str_t * pStr0 )
+{
+ Sbd_Str_t * pStr;
+ int VarPar = nVars + nStrs;
+ int m, m2, status, pLits[SBD_DIV_MAX];
+ // make sure selector parameters are mutually exclusive
+ for ( pStr = pStr0; pStr < pStr0 + nStrs; VarPar += pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns, pStr++ )
+ {
+ if ( pStr->fLut )
+ continue;
+ // one variable should be selected
+ assert( pStr->nVarIns <= SBD_DIV_MAX );
+ for ( m = 0; m < pStr->nVarIns; m++ )
+ pLits[m] = Abc_Var2Lit( pVars[VarPar + m], 0 );
+ status = sat_solver_addclause( pSat, pLits, pLits + pStr->nVarIns );
+ assert( status );
+ // two variables cannot be selected
+ for ( m = 0; m < pStr->nVarIns; m++ )
+ for ( m2 = m+1; m2 < pStr->nVarIns; m2++ )
+ {
+ pLits[0] = Abc_Var2Lit( pVars[VarPar + m], 1 );
+ pLits[1] = Abc_Var2Lit( pVars[VarPar + m2], 1 );
+ status = sat_solver_addclause( pSat, pLits, pLits + 2 );
+ assert( status );
+ }
+ }
+}
+void Sbd_ProblemPrintSolution( int nStrs, Sbd_Str_t * pStr0, Vec_Int_t * vLits )
+{
+ Sbd_Str_t * pStr;
+ int m, nIters, iLit = 0;
+ printf( "Solution found:\n" );
+ for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++ )
+ {
+ nIters = pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns;
+ printf( "%s%d : ", pStr->fLut ? "LUT":"SEL", (int)(pStr-pStr0) );
+ for ( m = 0; m < nIters; m++, iLit++ )
+ printf( "%d", !Abc_LitIsCompl(Vec_IntEntry(vLits, iLit)) );
+ printf( " {" );
+ for ( m = 0; m < pStr->nVarIns; m++ )
+ printf( " %d", pStr->VarIns[m] );
+ printf( " }\n" );
+ }
+ assert( iLit == Vec_IntSize(vLits) );
+}
+void Sbd_ProblemCollectSolution( int nStrs, Sbd_Str_t * pStr0, Vec_Int_t * vLits )
+{
+ Sbd_Str_t * pStr;
+ int m, nIters, iLit = 0;
+ for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++ )
+ {
+ pStr->Res = 0;
+ if ( pStr->fLut )
+ {
+ nIters = 1 << pStr->nVarIns;
+ for ( m = 0; m < nIters; m++, iLit++ )
+ if ( !Abc_LitIsCompl(Vec_IntEntry(vLits, iLit)) )
+ Abc_TtSetBit( &pStr->Res, m );
+ pStr->Res = Abc_Tt6Stretch( pStr->Res, pStr->nVarIns );
+ }
+ else
+ {
+ nIters = 0;
+ for ( m = 0; m < pStr->nVarIns; m++, iLit++ )
+ if ( !Abc_LitIsCompl(Vec_IntEntry(vLits, iLit)) )
+ {
+ pStr->Res = pStr->VarIns[m];
+ nIters++;
+ }
+ assert( nIters == 1 );
+ }
+ }
+ assert( iLit == Vec_IntSize(vLits) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Solves QBF problem for the given window.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors,
+ int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var,
+ Vec_Int_t * vTfo, Vec_Int_t * vRoots,
+ Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0 ) // divisors, structures
+{
+ extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf );
+
+ int fVerbose = 0;
+ abctime clk = Abc_Clock();
+ Vec_Int_t * vLits = Vec_IntAlloc( 100 );
+ sat_solver * pSatCec = Sbd_ManSatSolver( NULL, p, vMirrors, Pivot, vWinObjs, vObj2Var, vTfo, vRoots, 1 );
+ sat_solver * pSatQbf = sat_solver_new();
+
+ int nVars = Vec_IntSize( vDivSet );
+ int nPars = Sbd_ProblemCountParams( nStrs, pStr0 );
+
+ int VarCecOut = Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots);
+ int VarCecPar = VarCecOut + nStrs;
+
+ int VarQbfPar = 0;
+ int VarQbfFree = nPars;
+
+ int pVarsCec[256];
+ int pVarsQbf[256];
+ int i, iVar, iLit, nIters;
+ int RetValue = 0;
+
+ assert( Vec_IntSize(vDivSet) <= SBD_DIV_MAX );
+ assert( nVars + nStrs + nPars <= 256 );
+
+ // collect CEC variables
+ Vec_IntForEachEntry( vDivSet, iVar, i )
+ pVarsCec[i] = iVar;
+ for ( i = 0; i < nStrs; i++ )
+ pVarsCec[nVars + i] = VarCecOut + i;
+ for ( i = 0; i < nPars; i++ )
+ pVarsCec[nVars + nStrs + i] = VarCecPar + i;
+
+ // collect QBF variables
+ for ( i = 0; i < nVars + nStrs; i++ )
+ pVarsQbf[i] = -1;
+ for ( i = 0; i < nPars; i++ )
+ pVarsQbf[nVars + nStrs + i] = VarQbfPar + i;
+
+ // add clauses to the CEC problem
+ Sbd_ProblemAddClauses( pSatCec, nVars, nStrs, pVarsCec, pStr0 );
+
+ // create QBF solver
+ sat_solver_setnvars( pSatQbf, 1000 );
+ Sbd_ProblemAddClausesInit( pSatQbf, nVars, nStrs, pVarsQbf, pStr0 );
+
+ // assume all parameter variables are 0
+ Vec_IntClear( vLits );
+ for ( i = 0; i < nPars; i++ )
+ Vec_IntPush( vLits, Abc_Var2Lit(VarCecPar + i, 1) );
+ for ( nIters = 0; nIters < (1 << nVars); nIters++ )
+ {
+ // check if these parameters solve the problem
+ int status = sat_solver_solve( pSatCec, Vec_IntArray(vLits), Vec_IntLimit(vLits), 0, 0, 0, 0 );
+ if ( status == l_False ) // solution found
+ break;
+ assert( status == l_True );
+
+ if ( fVerbose )
+ {
+ printf( "Iter %3d : ", nIters );
+ for ( i = 0; i < nPars; i++ )
+ printf( "%d", !Abc_LitIsCompl(Vec_IntEntry(vLits, i)) );
+ printf( " " );
+ }
+
+ Vec_IntClear( vLits );
+ // create new QBF variables
+ for ( i = 0; i < nVars + nStrs; i++ )
+ pVarsQbf[i] = VarQbfFree++;
+ // set their values
+ Vec_IntForEachEntry( vDivSet, iVar, i )
+ {
+ iLit = Abc_Var2Lit( pVarsQbf[i], !sat_solver_var_value(pSatCec, iVar) );
+ status = sat_solver_addclause( pSatQbf, &iLit, &iLit + 1 );
+ assert( status );
+ if ( fVerbose )
+ printf( "%d", sat_solver_var_value(pSatCec, iVar) );
+ }
+ iLit = Abc_Var2Lit( pVarsQbf[nVars], sat_solver_var_value(pSatCec, VarCecOut) );
+ status = sat_solver_addclause( pSatQbf, &iLit, &iLit + 1 );
+ assert( status );
+ if ( fVerbose )
+ printf( " %d\n", !sat_solver_var_value(pSatCec, VarCecOut) );
+ // add clauses to the QBF problem
+ if ( !Sbd_ProblemAddClauses( pSatQbf, nVars, nStrs, pVarsQbf, pStr0 ) )
+ break; // solution does not exist
+ // check if solution still exists
+ status = sat_solver_solve( pSatQbf, NULL, NULL, 0, 0, 0, 0 );
+ if ( status == l_False ) // solution does not exist
+ break;
+ assert( status == l_True );
+ // find the new values of parameters
+ assert( Vec_IntSize(vLits) == 0 );
+ for ( i = 0; i < nPars; i++ )
+ Vec_IntPush( vLits, Abc_Var2Lit(VarCecPar + i, !sat_solver_var_value(pSatQbf, VarQbfPar + i)) );
+ }
+ if ( Vec_IntSize(vLits) > 0 )
+ {
+ //Sbd_ProblemPrintSolution( nStrs, pStr0, vLits );
+ Sbd_ProblemCollectSolution( nStrs, pStr0, vLits );
+ RetValue = 1;
+ }
+ sat_solver_delete( pSatCec );
+ sat_solver_delete( pSatQbf );
+ Vec_IntFree( vLits );
+
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ return RetValue;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/opt/sbd/sbdPath.c b/src/opt/sbd/sbdPath.c
new file mode 100644
index 00000000..270c81c8
--- /dev/null
+++ b/src/opt/sbd/sbdPath.c
@@ -0,0 +1,197 @@
+/**CFile****************************************************************
+
+ FileName [sbdPath.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [SAT-based optimization using internal don't-cares.]
+
+ Synopsis [Critical path.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: sbdPath.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sbdInt.h"
+#include "misc/tim/tim.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Sbc_ManAddInternalToPath_rec( Gia_Man_t * p, int iObj, Vec_Bit_t * vPath )
+{
+ Gia_Obj_t * pObj;
+ int k, iFan, Value = 0;
+ if ( Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return Vec_BitEntry(vPath, iObj);
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ pObj = Gia_ManObj( p, iObj );
+ if ( Gia_ObjIsCi(pObj) )
+ return Vec_BitEntry(vPath, iObj);
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_LutForEachFanin( p, iObj, iFan, k )
+ Value |= Sbc_ManAddInternalToPath_rec( p, iFan, vPath );
+ if ( Value )
+ Vec_BitWriteEntry( vPath, iObj, 1 );
+ return Value;
+}
+void Sbc_ManAddInternalToPath( Gia_Man_t * p, Vec_Bit_t * vPath )
+{
+ int k, iFan, iObj;
+ Gia_ManForEachLut( p, iObj )
+ {
+ if ( !Vec_BitEntry(vPath, iObj) )
+ continue;
+ Gia_ManIncrementTravId( p );
+ Gia_LutForEachFanin( p, iObj, iFan, k )
+ Gia_ObjSetTravIdCurrentId(p, iFan);
+ Sbc_ManAddInternalToPath_rec( p, iObj, vPath );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Sbc_ManCriticalPath_rec( Gia_Man_t * p, int * pLevels, int iObj, int LevelFan, Vec_Bit_t * vPath, int Slack )
+{
+ Gia_Obj_t * pObj; int k, iFan;
+ if ( Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ pObj = Gia_ManObj( p, iObj );
+ Vec_BitWriteEntry( vPath, iObj, 1 );
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime;
+ int iBox = pManTime ? Tim_ManBoxForCi( pManTime, Gia_ObjCioId(pObj) ) : -1;
+ if ( iBox >= 0 )
+ {
+ int curCo = Tim_ManBoxInputFirst( pManTime, iBox );
+ int nBoxInputs = Tim_ManBoxInputNum( pManTime, iBox );
+ for ( k = 0; k < nBoxInputs; k++ )
+ {
+ Gia_Obj_t * pCo = Gia_ManCo( p, curCo + k );
+ int iDriver = Gia_ObjFaninId0p( p, pCo );
+ if ( (pLevels[iDriver]+Slack >= LevelFan-1) && iDriver )
+ Sbc_ManCriticalPath_rec( p, pLevels, iDriver, pLevels[iDriver], vPath, Abc_MaxInt(0, pLevels[iDriver]+Slack-(LevelFan-1)) );
+ }
+ }
+ return;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_LutForEachFanin( p, iObj, iFan, k )
+ if ( pLevels[iFan]+Slack >= LevelFan-1 )
+ Sbc_ManCriticalPath_rec( p, pLevels, iFan, pLevels[iFan], vPath, Abc_MaxInt(0, pLevels[iFan]+Slack-(LevelFan-1)) );
+}
+Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p )
+{
+ int * pLevels = NULL, k, iDriver, Slack = 1;
+ int nLevels = p->pManTime ? Gia_ManLutLevelWithBoxes(p) : Gia_ManLutLevel(p, &pLevels);
+ Vec_Bit_t * vPath = Vec_BitStart( Gia_ManObjNum(p) );
+ if ( p->pManTime )
+ pLevels = Vec_IntArray( p->vLevels );
+ Gia_ManIncrementTravId( p );
+ Gia_ManForEachCoDriverId( p, iDriver, k )
+ if ( (pLevels[iDriver] == nLevels) && iDriver )
+ Sbc_ManCriticalPath_rec( p, pLevels, iDriver, pLevels[iDriver], vPath, Slack );
+ if ( !p->pManTime )
+ ABC_FREE( pLevels );
+ Sbc_ManAddInternalToPath( p, vPath );
+ return vPath;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Sbc_ManDelayTrace( Gia_Man_t * p )
+{
+ Vec_Bit_t * vPath = Vec_BitStart( Gia_ManObjNum(p) );
+ int i, k, iFan, nLevels, * pLevels;
+ int nLuts = 0, nNodes = 0, nEdges = 0, nEdgesAll = 0;
+ if ( !Gia_ManHasMapping(p) )
+ {
+ printf( "No mapping is available.\n" );
+ return;
+ }
+ assert( Gia_ManHasMapping(p) );
+ // set critical CO drivers
+ nLevels = Gia_ManLutLevel( p, &pLevels );
+ Gia_ManForEachCoDriverId( p, iFan, i )
+ if ( pLevels[iFan] == nLevels )
+ Vec_BitWriteEntry( vPath, iFan, 1 );
+ // set critical internal nodes
+ Gia_ManForEachLutReverse( p, i )
+ {
+ nLuts++;
+ if ( !Vec_BitEntry(vPath, i) )
+ continue;
+ nNodes++;
+ Gia_LutForEachFanin( p, i, iFan, k )
+ {
+ if ( pLevels[iFan] +1 < pLevels[i] )
+ continue;
+ assert( pLevels[iFan] + 1 == pLevels[i] );
+ Vec_BitWriteEntry( vPath, iFan, 1 );
+ nEdges++;
+ //printf( "%d -> %d\n", i, iFan );
+ }
+ }
+ Gia_ManForEachLut( p, i )
+ Gia_LutForEachFanin( p, i, iFan, k )
+ nEdgesAll += (Vec_BitEntry(vPath, i) && Vec_BitEntry(vPath, iFan));
+
+ ABC_FREE( pLevels );
+ Vec_BitFree( vPath );
+ printf( "AIG = %d. LUT = %d. Lev = %d. Path nodes = %d. Path edges = %d. (%d.)\n",
+ Gia_ManAndNum(p), nLuts, nLevels, nNodes, nEdges, nEdgesAll );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/opt/sbd/sbdSat.c b/src/opt/sbd/sbdSat.c
index ae865627..f0de4dbf 100644
--- a/src/opt/sbd/sbdSat.c
+++ b/src/opt/sbd/sbdSat.c
@@ -37,10 +37,6 @@ ABC_NAMESPACE_IMPL_START
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
-#define SBD_LUTS_MAX 2
-#define SBD_SIZE_MAX 4
-#define SBD_DIV_MAX 16
-
// new AIG manager
typedef struct Sbd_Pro_t_ Sbd_Pro_t;
struct Sbd_Pro_t_
diff --git a/src/opt/sbd/sbdWin.c b/src/opt/sbd/sbdWin.c
index d722f456..069a4125 100644
--- a/src/opt/sbd/sbdWin.c
+++ b/src/opt/sbd/sbdWin.c
@@ -39,19 +39,25 @@ ABC_NAMESPACE_IMPL_START
a DFS ordered array of objects (vWinObjs) whose indexed in the array
(which will be used as SAT variables) are given in array vObj2Var.
The TFO nodes are listed as the last ones in vWinObjs. The root nodes
- are labeled with Abc_LitIsCompl() in vTfo and also given in vRoots.]
+ are labeled with Abc_LitIsCompl() in vTfo and also given in vRoots.
+ If fQbf is 1, returns the instance meant for QBF solving. It is using
+ the last variable (LastVar) as the placeholder for the second copy
+ of the pivot node.]
SideEffects []
SeeAlso []
***********************************************************************/
-sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots )
+sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors,
+ int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var,
+ Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf )
{
Gia_Obj_t * pObj;
int i, iLit = 1, iObj, Fan0, Fan1, Lit0m, Lit1m, Node, fCompl0, fCompl1, RetValue;
int TfoStart = Vec_IntSize(vWinObjs) - Vec_IntSize(vTfo);
int PivotVar = Vec_IntEntry(vObj2Var, Pivot);
+ int LastVar = Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots);
//Vec_IntPrint( vWinObjs );
//Vec_IntPrint( vTfo );
//Vec_IntPrint( vRoots );
@@ -60,7 +66,7 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi
pSat = sat_solver_new();
else
sat_solver_restart( pSat );
- sat_solver_setnvars( pSat, Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots) + 32 );
+ sat_solver_setnvars( pSat, Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots) + SBD_FVAR_MAX );
// create constant 0 clause
sat_solver_addclause( pSat, &iLit, &iLit + 1 );
// add clauses for all nodes
@@ -100,8 +106,13 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi
Fan1 = Vec_IntEntry( vObj2Var, Fan1 );
Fan0 = Fan0 < TfoStart ? Fan0 : Fan0 + Vec_IntSize(vTfo);
Fan1 = Fan1 < TfoStart ? Fan1 : Fan1 + Vec_IntSize(vTfo);
- fCompl0 = Gia_ObjFaninC0(pObj) ^ (Fan0 == PivotVar) ^ (Lit0m >= 0 && Abc_LitIsCompl(Lit0m));
- fCompl1 = Gia_ObjFaninC1(pObj) ^ (Fan1 == PivotVar) ^ (Lit1m >= 0 && Abc_LitIsCompl(Lit1m));
+ if ( fQbf )
+ {
+ Fan0 = Fan0 == PivotVar ? LastVar : Fan0;
+ Fan1 = Fan1 == PivotVar ? LastVar : Fan1;
+ }
+ fCompl0 = Gia_ObjFaninC0(pObj) ^ (!fQbf && Fan0 == PivotVar) ^ (Lit0m >= 0 && Abc_LitIsCompl(Lit0m));
+ fCompl1 = Gia_ObjFaninC1(pObj) ^ (!fQbf && Fan1 == PivotVar) ^ (Lit1m >= 0 && Abc_LitIsCompl(Lit1m));
if ( Gia_ObjIsXor(pObj) )
sat_solver_add_xor( pSat, Node, Fan0, Fan1, fCompl0 ^ fCompl1 );
else
@@ -127,7 +138,18 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi
sat_solver_delete( pSat );
return NULL;
}
- assert( sat_solver_nvars(pSat) == nVars + 32 );
+ assert( sat_solver_nvars(pSat) == nVars + SBD_FVAR_MAX );
+ }
+ else if ( fQbf )
+ {
+ int n, pLits[2];
+ for ( n = 0; n < 2; n++ )
+ {
+ pLits[0] = Abc_Var2Lit( PivotVar, n );
+ pLits[1] = Abc_Var2Lit( LastVar, n );
+ RetValue = sat_solver_addclause( pSat, pLits, pLits + 2 );
+ assert( RetValue );
+ }
}
// finalize
RetValue = sat_solver_simplify( pSat );
@@ -143,7 +165,7 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi
Synopsis [Solves one SAT problem.]
- Description [Computes node function for PivotVar with fanins in vDivVars
+ Description [Computes node function for PivotVar with fanins in vDivSet
using don't-care represented in the SAT solver. Uses array vValues to
return the values of the first Vec_IntSize(vValues) SAT variables in case
the implementation of the node with the given fanins does not exist.]
@@ -153,12 +175,13 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi
SeeAlso []
***********************************************************************/
-word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivVars, Vec_Int_t * vValues, Vec_Int_t * vTemp )
+word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivSet, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp )
{
int nBTLimit = 0;
word uCube, uTruth = 0;
int status, i, iVar, nFinal, * pFinal, pLits[2], nIter = 0;
assert( FreeVar < sat_solver_nvars(pSat) );
+ assert( Vec_IntSize(vDivVars) == Vec_IntSize(vDivValues) );
pLits[0] = Abc_Var2Lit( PivotVar, 0 ); // F = 1
pLits[1] = Abc_Var2Lit( FreeVar, 0 ); // iNewLit
while ( 1 )
@@ -171,12 +194,12 @@ word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDi
return uTruth;
assert( status == l_True );
// remember variable values
- for ( i = 0; i < Vec_IntSize(vValues); i++ )
- Vec_IntWriteEntry( vValues, i, 2*sat_solver_var_value(pSat, i) );
+ Vec_IntForEachEntry( vDivVars, iVar, i )
+ Vec_IntWriteEntry( vDivValues, i, 2*sat_solver_var_value(pSat, iVar) );
// collect divisor literals
Vec_IntClear( vTemp );
Vec_IntPush( vTemp, Abc_LitNot(pLits[0]) ); // F = 0
- Vec_IntForEachEntry( vDivVars, iVar, i )
+ Vec_IntForEachEntry( vDivSet, iVar, i )
Vec_IntPush( vTemp, sat_solver_var_literal(pSat, iVar) );
// check against offset
status = sat_solver_solve( pSat, Vec_IntArray(vTemp), Vec_IntArray(vTemp) + Vec_IntSize(vTemp), nBTLimit, 0, 0, 0 );
@@ -195,7 +218,7 @@ word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDi
if ( pFinal[i] == pLits[0] )
continue;
Vec_IntPush( vTemp, pFinal[i] );
- iVar = Vec_IntFind( vDivVars, Abc_Lit2Var(pFinal[i]) ); assert( iVar >= 0 );
+ iVar = Vec_IntFind( vDivSet, Abc_Lit2Var(pFinal[i]) ); assert( iVar >= 0 );
uCube &= Abc_LitIsCompl(pFinal[i]) ? s_Truths6[iVar] : ~s_Truths6[iVar];
}
uTruth |= uCube;
@@ -205,11 +228,11 @@ word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDi
}
assert( status == l_True );
// store the counter-example
- for ( i = 0; i < Vec_IntSize(vValues); i++ )
- Vec_IntAddToEntry( vValues, i, sat_solver_var_value(pSat, i) );
+ Vec_IntForEachEntry( vDivVars, iVar, i )
+ Vec_IntAddToEntry( vDivValues, i, sat_solver_var_value(pSat, iVar) );
- for ( i = 0; i < Vec_IntSize(vValues); i++ )
- Vec_IntAddToEntry( vValues, i, 0xC );
+ for ( i = 0; i < Vec_IntSize(vDivValues); i++ )
+ Vec_IntAddToEntry( vDivValues, i, 0xC );
/*
// reduce the counter example
for ( n = 0; n < 2; n++ )
@@ -232,6 +255,140 @@ word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDi
/**Function*************************************************************
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Sbd_ManSolve2( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp, Vec_Int_t * vSop )
+{
+ int nBTLimit = 0;
+ int status, i, iVar, nFinal, * pFinal, pLits[2], nIter = 0;
+ assert( FreeVar < sat_solver_nvars(pSat) );
+ assert( Vec_IntSize(vDivVars) == Vec_IntSize(vDivValues) );
+ pLits[0] = Abc_Var2Lit( PivotVar, 0 ); // F = 1
+ pLits[1] = Abc_Var2Lit( FreeVar, 0 ); // iNewLit
+ Vec_IntClear( vSop );
+ while ( 1 )
+ {
+ // find onset minterm
+ status = sat_solver_solve( pSat, pLits, pLits + 2, nBTLimit, 0, 0, 0 );
+ if ( status == l_Undef )
+ return 0;
+ if ( status == l_False )
+ return 1;
+ assert( status == l_True );
+ // remember variable values
+ //for ( i = 0; i < Vec_IntSize(vValues); i++ )
+ // Vec_IntWriteEntry( vValues, i, 2*sat_solver_var_value(pSat, i) );
+ // collect divisor literals
+ Vec_IntClear( vTemp );
+ Vec_IntPush( vTemp, Abc_LitNot(pLits[0]) ); // F = 0
+ //Vec_IntForEachEntry( vDivSet, iVar, i )
+ Vec_IntForEachEntry( vDivVars, iVar, i )
+ Vec_IntPush( vTemp, sat_solver_var_literal(pSat, iVar) );
+ // check against offset
+ status = sat_solver_solve( pSat, Vec_IntArray(vTemp), Vec_IntArray(vTemp) + Vec_IntSize(vTemp), nBTLimit, 0, 0, 0 );
+ if ( status == l_Undef )
+ return 0;
+ if ( status == l_True )
+ break;
+ assert( status == l_False );
+ // compute cube and add clause
+ nFinal = sat_solver_final( pSat, &pFinal );
+ Vec_IntClear( vTemp );
+ Vec_IntPush( vTemp, Abc_LitNot(pLits[1]) ); // NOT(iNewLit)
+ for ( i = 0; i < nFinal; i++ )
+ {
+ if ( pFinal[i] == pLits[0] )
+ continue;
+ Vec_IntPush( vTemp, pFinal[i] );
+ iVar = Vec_IntFind( vDivVars, Abc_Lit2Var(pFinal[i]) ); assert( iVar >= 0 );
+ //uCube &= Abc_LitIsCompl(pFinal[i]) ? s_Truths6[iVar] : ~s_Truths6[iVar];
+ Vec_IntPush( vSop, Abc_Var2Lit( iVar, !Abc_LitIsCompl(pFinal[i]) ) );
+ }
+ //uTruth |= uCube;
+ Vec_IntPush( vSop, -1 );
+ status = sat_solver_addclause( pSat, Vec_IntArray(vTemp), Vec_IntArray(vTemp) + Vec_IntSize(vTemp) );
+ assert( status );
+ nIter++;
+ }
+ assert( status == l_True );
+ // store the counter-example
+ //for ( i = 0; i < Vec_IntSize(vValues); i++ )
+ // Vec_IntAddToEntry( vValues, i, sat_solver_var_value(pSat, i) );
+ return 0;
+}
+
+word Sbd_ManSolverSupp( Vec_Int_t * vSop, int * pInds, int * pnVars )
+{
+ word Supp = 0;
+ int i, Entry, nVars = 0;
+ Vec_IntForEachEntry( vSop, Entry, i )
+ {
+ if ( Entry == -1 )
+ continue;
+ assert( Abc_Lit2Var(Entry) < 64 );
+ if ( (Supp >> Abc_Lit2Var(Entry)) & 1 )
+ continue;
+ pInds[Abc_Lit2Var(Entry)] = nVars++;
+ Supp |= (word)1 << Abc_Lit2Var(Entry);
+ }
+ *pnVars = nVars;
+ return Supp;
+}
+void Sbd_ManSolverPrint( Vec_Int_t * vSop )
+{
+ int v, i, Entry, nVars, pInds[64];
+ word Supp = Sbd_ManSolverSupp( vSop, pInds, &nVars );
+ char Cube[65] = {'\0'};
+ assert( Cube[nVars] == '\0' );
+ for ( v = 0; v < nVars; v++ )
+ Cube[v] = '-';
+ Vec_IntForEachEntry( vSop, Entry, i )
+ {
+ if ( Entry == -1 )
+ {
+ printf( "%s\n", Cube );
+ for ( v = 0; v < nVars; v++ )
+ Cube[v] = '-';
+ continue;
+ }
+ Cube[pInds[Abc_Lit2Var(Entry)]] = '1' - (char)Abc_LitIsCompl(Entry);
+ }
+ Supp = 0;
+}
+void Sbd_ManSolveSelect( Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots )
+{
+ Vec_Int_t * vSop = Vec_IntAlloc( 100 );
+ Vec_Int_t * vTemp = Vec_IntAlloc( 100 );
+ sat_solver * pSat = Sbd_ManSatSolver( NULL, p, vMirrors, Pivot, vWinObjs, vObj2Var, vTfo, vRoots, 0 );
+ int PivotVar = Vec_IntEntry(vObj2Var, Pivot);
+ int FreeVar = Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots);
+ int Status = Sbd_ManSolve2( pSat, PivotVar, FreeVar, vDivVars, vDivValues, vTemp, vSop );
+ printf( "Pivot = %4d. Divs = %4d. ", Pivot, Vec_IntSize(vDivVars) );
+ if ( Status == 0 )
+ printf( "UNSAT.\n" );
+ else
+ {
+ int nVars, pInds[64];
+ word Supp = Sbd_ManSolverSupp( vSop, pInds, &nVars );
+ //Sbd_ManSolverPrint( vSop );
+ printf( "SAT with %d vars and %d cubes.\n", nVars, Vec_IntCountEntry(vSop, -1) );
+ Supp = 0;
+ }
+ Vec_IntFree( vTemp );
+ Vec_IntFree( vSop );
+ sat_solver_delete( pSat );
+}
+
+
+/**Function*************************************************************
+
Synopsis [Returns a bunch of positive/negative random care minterms.]
Description [Returns 0/1 if the functions is const 0/1.]
@@ -273,6 +430,30 @@ int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar,
return -1;
}
+int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset )
+{
+ int nBTLimit = 0;
+ int n, i, k, status, iLit, iVar;
+ word * pPats[2] = {pOnset, pOffset};
+ assert( Vec_IntSize(vDivVars) < 64 );
+ for ( n = 0; n < 2; n++ )
+ for ( i = 0; i < nConsts; i++ )
+ {
+ sat_solver_random_polarity( pSat );
+ iLit = Abc_Var2Lit( PivotVar, n );
+ status = sat_solver_solve( pSat, &iLit, &iLit + 1, nBTLimit, 0, 0, 0 );
+ if ( status == l_Undef )
+ return -2;
+ if ( status == l_False )
+ return n;
+ pPats[n][i] = ((word)!n) << Vec_IntSize(vDivVars);
+ Vec_IntForEachEntry( vDivVars, iVar, k )
+ if ( sat_solver_var_value(pSat, iVar) )
+ Abc_TtXorBit(&pPats[n][i], k);
+ }
+ return -1;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/opt/sfm/sfmCnf.c b/src/opt/sfm/sfmCnf.c
index 0ab92258..b4dd11f8 100644
--- a/src/opt/sfm/sfmCnf.c
+++ b/src/opt/sfm/sfmCnf.c
@@ -45,7 +45,7 @@ ABC_NAMESPACE_IMPL_START
***********************************************************************/
void Sfm_PrintCnf( Vec_Str_t * vCnf )
{
- char Entry;
+ signed char Entry;
int i, Lit;
Vec_StrForEachEntry( vCnf, Entry, i )
{
@@ -153,7 +153,7 @@ Vec_Wec_t * Sfm_CreateCnf( Sfm_Ntk_t * p )
void Sfm_TranslateCnf( Vec_Wec_t * vRes, Vec_Str_t * vCnf, Vec_Int_t * vFaninMap, int iPivotVar )
{
Vec_Int_t * vClause;
- char Entry;
+ signed char Entry;
int i, Lit;
Vec_WecClear( vRes );
vClause = Vec_WecPushLevel( vRes );
diff --git a/src/proof/acec/acec.h b/src/proof/acec/acec.h
index c61b4485..fcbd32df 100644
--- a/src/proof/acec/acec.h
+++ b/src/proof/acec/acec.h
@@ -38,6 +38,22 @@ ABC_NAMESPACE_HEADER_START
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
+// combinational equivalence checking parameters
+typedef struct Acec_ParCec_t_ Acec_ParCec_t;
+struct Acec_ParCec_t_
+{
+ int nBTLimit; // conflict limit at a node
+ int TimeLimit; // the runtime limit in seconds
+ int fMiter; // input circuit is a miter
+ int fDualOutput; // dual-output miter
+ int fTwoOutput; // two-output miter
+ int fBooth; // expecting Booth multiplier
+ int fSilent; // print no messages
+ int fVeryVerbose; // verbose stats
+ int fVerbose; // verbose stats
+ int iOutFail; // the number of failed output
+};
+
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -50,8 +66,11 @@ ABC_NAMESPACE_HEADER_START
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+/*=== acecCl.c ========================================================*/
+extern Gia_Man_t * Acec_ManDecla( Gia_Man_t * pGia, int fBooth, int fVerbose );
/*=== acecCore.c ========================================================*/
-extern int Gia_PolynCec( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Cec_ParCec_t * pPars );
+extern void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p );
+extern int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars );
/*=== acecFadds.c ========================================================*/
extern Vec_Int_t * Gia_ManDetectFullAdders( Gia_Man_t * p, int fVerbose, Vec_Int_t ** vCutsXor2 );
extern Vec_Int_t * Gia_ManDetectHalfAdders( Gia_Man_t * p, int fVerbose );
@@ -60,6 +79,12 @@ extern Vec_Int_t * Gia_PolynReorder( Gia_Man_t * pGia, int fVerbose, int fVery
extern Vec_Int_t * Gia_PolynFindOrder( Gia_Man_t * pGia, Vec_Int_t * vFadds, Vec_Int_t * vHadds, int fVerbose, int fVeryVerbose );
/*=== acecPolyn.c ========================================================*/
extern void Gia_PolynBuild( Gia_Man_t * pGia, Vec_Int_t * vOrder, int fSigned, int fVerbose, int fVeryVerbose );
+/*=== acecRe.c ========================================================*/
+extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose );
+extern int Ree_ManCountFadds( Vec_Int_t * vAdds );
+extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose );
+/*=== acecTree.c ========================================================*/
+extern Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fBooth, int fVerbose );
ABC_NAMESPACE_HEADER_END
diff --git a/src/proof/acec/acecBo.c b/src/proof/acec/acecBo.c
new file mode 100644
index 00000000..9cddcd13
--- /dev/null
+++ b/src/proof/acec/acecBo.c
@@ -0,0 +1,216 @@
+/**CFile****************************************************************
+
+ FileName [acecBo.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [CEC for arithmetic circuits.]
+
+ Synopsis [Core procedures.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: acecBo.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "acecInt.h"
+#include "misc/vec/vecWec.h"
+#include "misc/extra/extra.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Acec_DetectBoothXorMux( Gia_Man_t * p, Gia_Obj_t * pMux, Gia_Obj_t * pXor, int pIns[3] )
+{
+ Gia_Obj_t * pFan0, * pFan1;
+ Gia_Obj_t * pDat0, * pDat1, * pCtrl;
+ if ( !Gia_ObjIsMuxType(pMux) || !Gia_ObjIsMuxType(pXor) )
+ return 0;
+ if ( !Gia_ObjRecognizeExor( pXor, &pFan0, &pFan1 ) )
+ return 0;
+ pFan0 = Gia_Regular(pFan0);
+ pFan1 = Gia_Regular(pFan1);
+ if ( Gia_ObjId(p, pFan0) > Gia_ObjId(p, pFan1) )
+ ABC_SWAP( Gia_Obj_t *, pFan0, pFan1 );
+ if ( !(pCtrl = Gia_ObjRecognizeMux( pMux, &pDat0, &pDat1 )) )
+ return 0;
+ pDat0 = Gia_Regular(pDat0);
+ pDat1 = Gia_Regular(pDat1);
+ pCtrl = Gia_Regular(pCtrl);
+ if ( !Gia_ObjIsAnd(pDat0) || !Gia_ObjIsAnd(pDat1) )
+ return 0;
+ if ( Gia_ObjFaninId0p(p, pDat0) != Gia_ObjFaninId0p(p, pDat1) ||
+ Gia_ObjFaninId1p(p, pDat0) != Gia_ObjFaninId1p(p, pDat1) )
+ return 0;
+ if ( Gia_ObjFaninId0p(p, pDat0) != Gia_ObjId(p, pFan0) ||
+ Gia_ObjFaninId1p(p, pDat0) != Gia_ObjId(p, pFan1) )
+ return 0;
+ pIns[0] = Gia_ObjId(p, pFan0);
+ pIns[1] = Gia_ObjId(p, pFan1);
+ pIns[2] = Gia_ObjId(p, pCtrl);
+ return 1;
+}
+int Acec_DetectBoothXorFanin( Gia_Man_t * p, Gia_Obj_t * pObj, int pIns[5] )
+{
+ Gia_Obj_t * pFan0, * pFan1;
+ //int Id = Gia_ObjId(p, pObj);
+ if ( !Gia_ObjIsAnd(pObj) )
+ return 0;
+ if ( !Gia_ObjFaninC0(pObj) || !Gia_ObjFaninC1(pObj) )
+ return 0;
+ pFan0 = Gia_ObjFanin0(pObj);
+ pFan1 = Gia_ObjFanin1(pObj);
+ if ( !Gia_ObjIsAnd(pFan0) || !Gia_ObjIsAnd(pFan1) )
+ return 0;
+ if ( Acec_DetectBoothXorMux(p, Gia_ObjFanin0(pFan0), Gia_ObjFanin0(pFan1), pIns) )
+ {
+ pIns[3] = Gia_ObjId(p, Gia_ObjFanin1(pFan0));
+ pIns[4] = Gia_ObjId(p, Gia_ObjFanin1(pFan1));
+ return 1;
+ }
+ if ( Acec_DetectBoothXorMux(p, Gia_ObjFanin0(pFan0), Gia_ObjFanin1(pFan1), pIns) )
+ {
+ pIns[3] = Gia_ObjId(p, Gia_ObjFanin1(pFan0));
+ pIns[4] = Gia_ObjId(p, Gia_ObjFanin0(pFan1));
+ return 1;
+ }
+ if ( Acec_DetectBoothXorMux(p, Gia_ObjFanin1(pFan0), Gia_ObjFanin0(pFan1), pIns) )
+ {
+ pIns[3] = Gia_ObjId(p, Gia_ObjFanin0(pFan0));
+ pIns[4] = Gia_ObjId(p, Gia_ObjFanin1(pFan1));
+ return 1;
+ }
+ if ( Acec_DetectBoothXorMux(p, Gia_ObjFanin1(pFan0), Gia_ObjFanin1(pFan1), pIns) )
+ {
+ pIns[3] = Gia_ObjId(p, Gia_ObjFanin0(pFan0));
+ pIns[4] = Gia_ObjId(p, Gia_ObjFanin0(pFan1));
+ return 1;
+ }
+ return 0;
+}
+int Acec_DetectBoothOne( Gia_Man_t * p, Gia_Obj_t * pObj, int pIns[5] )
+{
+ Gia_Obj_t * pFan0, * pFan1;
+ if ( !Gia_ObjRecognizeExor( pObj, &pFan0, &pFan1 ) )
+ return 0;
+ pFan0 = Gia_Regular(pFan0);
+ pFan1 = Gia_Regular(pFan1);
+ if ( Acec_DetectBoothXorFanin( p, pFan0, pIns ) && pIns[2] == Gia_ObjId(p, pFan1) )
+ return 1;
+ if ( Acec_DetectBoothXorFanin( p, pFan1, pIns ) && pIns[2] == Gia_ObjId(p, pFan0) )
+ return 1;
+ return 0;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Acec_DetectBoothTwoXor( Gia_Man_t * p, Gia_Obj_t * pObj, int pIns[5] )
+{
+ Gia_Obj_t * pFan0, * pFan1;
+ if ( !Gia_ObjIsAnd(pObj) )
+ return 0;
+ if ( Gia_ObjRecognizeExor( Gia_ObjFanin0(pObj), &pFan0, &pFan1 ) )
+ {
+ pIns[0] = Gia_ObjId(p, Gia_Regular(pFan0));
+ pIns[1] = Gia_ObjId(p, Gia_Regular(pFan1));
+ pIns[2] = -1;
+ pIns[3] = 0;
+ pIns[4] = Gia_ObjId(p, Gia_ObjFanin1(pObj));
+ return 1;
+ }
+ if ( Gia_ObjRecognizeExor( Gia_ObjFanin1(pObj), &pFan0, &pFan1 ) )
+ {
+ pIns[0] = Gia_ObjId(p, Gia_Regular(pFan0));
+ pIns[1] = Gia_ObjId(p, Gia_Regular(pFan1));
+ pIns[2] = -1;
+ pIns[3] = 0;
+ pIns[4] = Gia_ObjId(p, Gia_ObjFanin0(pObj));
+ return 1;
+ }
+ return 0;
+}
+int Acec_DetectBoothTwo( Gia_Man_t * p, Gia_Obj_t * pObj, int pIns[5] )
+{
+ Gia_Obj_t * pFan0, * pFan1;
+ if ( !Gia_ObjRecognizeExor( pObj, &pFan0, &pFan1 ) )
+ return 0;
+ pFan0 = Gia_Regular(pFan0);
+ pFan1 = Gia_Regular(pFan1);
+ if ( Acec_DetectBoothTwoXor( p, pFan0, pIns ) )
+ {
+ pIns[2] = Gia_ObjId(p, pFan1);
+ return 1;
+ }
+ if ( Acec_DetectBoothTwoXor( p, pFan1, pIns ) )
+ {
+ pIns[2] = Gia_ObjId(p, pFan0);
+ return 1;
+ }
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_DetectBoothTest( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i, pIns[5];
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( !Acec_DetectBoothOne(p, pObj, pIns) && !Acec_DetectBoothTwo(p, pObj, pIns) )
+ continue;
+ printf( "obj = %4d : b0 = %4d b1 = %4d b2 = %4d a0 = %4d a1 = %4d\n",
+ i, pIns[0], pIns[1], pIns[2], pIns[3], pIns[4] );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/acec/acecCl.c b/src/proof/acec/acecCl.c
index 32be3b30..6185677b 100644
--- a/src/proof/acec/acecCl.c
+++ b/src/proof/acec/acecCl.c
@@ -45,6 +45,396 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
+void Acec_ManDerive_rec( Gia_Man_t * pNew, Gia_Man_t * p, int Node, Vec_Int_t * vMirrors )
+{
+ Gia_Obj_t * pObj;
+ int Obj = Node;
+ if ( Vec_IntEntry(vMirrors, Node) >= 0 )
+ Obj = Abc_Lit2Var( Vec_IntEntry(vMirrors, Node) );
+ pObj = Gia_ManObj( p, Obj );
+ if ( !~pObj->Value )
+ {
+ assert( Gia_ObjIsAnd(pObj) );
+ Acec_ManDerive_rec( pNew, p, Gia_ObjFaninId0(pObj, Obj), vMirrors );
+ Acec_ManDerive_rec( pNew, p, Gia_ObjFaninId1(pObj, Obj), vMirrors );
+ if ( Gia_ObjIsXor(pObj) )
+ pObj->Value = Gia_ManAppendXorReal( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ else
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ }
+ // set the original node as well
+ if ( Obj != Node )
+ Gia_ManObj(p, Node)->Value = Abc_LitNotCond( pObj->Value, Abc_LitIsCompl(Vec_IntEntry(vMirrors, Node)) );
+}
+Gia_Man_t * Acec_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors )
+{
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj;
+ int i;
+ assert( p->pMuxes == NULL );
+ 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_ManHashAlloc( pNew );
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ManForEachCo( p, pObj, i )
+ Acec_ManDerive_rec( pNew, p, Gia_ObjFaninId0p(p, pObj), vMirrors );
+ Gia_ManForEachCo( p, pObj, i )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Gia_ManHashStop( pNew );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Acec_CollectXorTops( Gia_Man_t * p )
+{
+ Vec_Int_t * vRootXorSet = Vec_IntAlloc( Gia_ManCoNum(p) );
+ Gia_Obj_t * pObj, * pFan0, * pFan1, * pFan00, * pFan01, * pFan10, * pFan11;
+ int i, fXor0, fXor1, fFirstXor = 0;
+ Gia_ManForEachCoDriver( p, pObj, i )
+ {
+ if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) )
+ {
+ if ( fFirstXor )
+ {
+ printf( "XORs do not form a continuous sequence\n" );
+ Vec_IntFreeP( &vRootXorSet );
+ break;
+ }
+ continue;
+ }
+ fFirstXor = 1;
+ fXor0 = Gia_ObjRecognizeExor(Gia_Regular(pFan0), &pFan00, &pFan01);
+ fXor1 = Gia_ObjRecognizeExor(Gia_Regular(pFan1), &pFan10, &pFan11);
+ if ( fXor0 == fXor1 )
+ {
+ printf( "Both inputs of top level XOR have XOR/non-XOR\n" );
+ Vec_IntFreeP( &vRootXorSet );
+ break;
+ }
+ Vec_IntPush( vRootXorSet, Gia_ObjId(p, pObj) );
+ Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan0)) : Gia_ObjId(p, Gia_Regular(pFan1)) );
+ Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan10)) : Gia_ObjId(p, Gia_Regular(pFan00)) );
+ Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan11)) : Gia_ObjId(p, Gia_Regular(pFan01)) );
+ }
+ for ( i = 0; 4*i < Vec_IntSize(vRootXorSet); i++ )
+ {
+ printf( "%2d : ", i );
+ printf( "%4d <- ", Vec_IntEntry(vRootXorSet, 4*i) );
+ printf( "%4d ", Vec_IntEntry(vRootXorSet, 4*i+1) );
+ printf( "%4d ", Vec_IntEntry(vRootXorSet, 4*i+2) );
+ printf( "%4d ", Vec_IntEntry(vRootXorSet, 4*i+3) );
+ printf( "\n" );
+ }
+ return vRootXorSet;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Acec_DetectLitPolarity( Gia_Man_t * p, int Node, int Leaf )
+{
+ Gia_Obj_t * pNode;
+ int Lit0, Lit1;
+ if ( Node < Leaf )
+ return -1;
+ if ( Node == Leaf )
+ return Abc_Var2Lit(Node, 0);
+ pNode = Gia_ManObj( p, Node );
+ Lit0 = Acec_DetectLitPolarity( p, Gia_ObjFaninId0(pNode, Node), Leaf );
+ Lit1 = Acec_DetectLitPolarity( p, Gia_ObjFaninId1(pNode, Node), Leaf );
+ Lit0 = Lit0 == -1 ? Lit0 : Abc_LitNotCond( Lit0, Gia_ObjFaninC0(pNode) );
+ Lit1 = Lit1 == -1 ? Lit1 : Abc_LitNotCond( Lit1, Gia_ObjFaninC1(pNode) );
+ if ( Lit0 == -1 && Lit1 == -1 )
+ return -1;
+ assert( Lit0 != -1 || Lit1 != -1 );
+ if ( Lit0 != -1 && Lit1 != -1 )
+ {
+ assert( Lit0 == Lit1 );
+ printf( "Problem for leaf %d\n", Leaf );
+ return Lit0;
+ }
+ return Lit0 != -1 ? Lit0 : Lit1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_DetectComputeSuppOne_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp, Vec_Int_t * vNods )
+{
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ if ( pObj->fMark0 )
+ {
+ Vec_IntPush( vSupp, Gia_ObjId(p, pObj) );
+ return;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ Acec_DetectComputeSuppOne_rec( p, Gia_ObjFanin0(pObj), vSupp, vNods );
+ Acec_DetectComputeSuppOne_rec( p, Gia_ObjFanin1(pObj), vSupp, vNods );
+ Vec_IntPush( vNods, Gia_ObjId(p, pObj) );
+}
+void Acec_DetectComputeSupports( Gia_Man_t * p, Vec_Int_t * vRootXorSet )
+{
+ Vec_Int_t * vNods = Vec_IntAlloc( 100 );
+ Vec_Int_t * vPols = Vec_IntAlloc( 100 );
+ Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); int i, k, Node, Pol;
+ for ( i = 0; 4*i < Vec_IntSize(vRootXorSet); i++ )
+ {
+ Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) )->fMark0 = 1;
+ Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+2) )->fMark0 = 1;
+ Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+3) )->fMark0 = 1;
+ }
+ for ( i = 1; 4*i < Vec_IntSize(vRootXorSet); i++ )
+ {
+ Vec_IntClear( vSupp );
+ Gia_ManIncrementTravId( p );
+
+ Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) )->fMark0 = 0;
+ Acec_DetectComputeSuppOne_rec( p, Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) ), vSupp, vNods );
+ Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) )->fMark0 = 1;
+
+ Vec_IntSort( vSupp, 0 );
+
+ printf( "Out %4d : %4d \n", i, Vec_IntEntry(vRootXorSet, 4*i+1) );
+ Vec_IntPrint( vSupp );
+
+ printf( "Cone:\n" );
+ Vec_IntForEachEntry( vNods, Node, k )
+ Gia_ObjPrint( p, Gia_ManObj(p, Node) );
+
+
+ Vec_IntClear( vPols );
+ Vec_IntForEachEntry( vSupp, Node, k )
+ Vec_IntPush( vPols, Acec_DetectLitPolarity(p, Vec_IntEntry(vRootXorSet, 4*i+1), Node) );
+
+ Vec_IntForEachEntryTwo( vSupp, vPols, Node, Pol, k )
+ printf( "%d(%d) ", Node, Abc_LitIsCompl(Pol) );
+
+ printf( "\n" );
+
+ Vec_IntPrint( vSupp );
+ }
+ for ( i = 0; 4*i < Vec_IntSize(vRootXorSet); i++ )
+ {
+ Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) )->fMark0 = 0;
+ Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+2) )->fMark0 = 0;
+ Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+3) )->fMark0 = 0;
+ }
+ Vec_IntFree( vSupp );
+ Vec_IntFree( vPols );
+ Vec_IntFree( vNods );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Acec_DetectXorBuildNew( Gia_Man_t * p, Vec_Int_t * vRootXorSet )
+{
+ Gia_Man_t * pNew;
+ int i, k, iOr1, iAnd1, iAnd2, pLits[3]; // carry, in1, in2
+ Vec_Int_t * vMirrors = Vec_IntStart( Gia_ManObjNum(p) );
+ for ( i = 0; 4*i < Vec_IntSize(vRootXorSet); i++ )
+ {
+ pLits[0] = Acec_DetectLitPolarity( p, Vec_IntEntry(vRootXorSet, 4*i), Vec_IntEntry(vRootXorSet, 4*i+1) );
+ // get polarity of two new ones
+ for ( k = 1; k < 3; k++ )
+ pLits[k] = Acec_DetectLitPolarity( p, Vec_IntEntry(vRootXorSet, 4*i), Vec_IntEntry(vRootXorSet, 4*i+k+1) );
+ // create the gate
+ iOr1 = Gia_ManAppendOr( p, pLits[1], pLits[2] );
+ iAnd1 = Gia_ManAppendAnd( p, pLits[0], iOr1 );
+ iAnd2 = Gia_ManAppendAnd( p, pLits[1], pLits[2] );
+ pLits[0] = Gia_ManAppendOr( p, iAnd1, iAnd2 );
+ Vec_IntWriteEntry( vMirrors, Vec_IntEntry(vRootXorSet, 4*i+1), pLits[0] );
+ }
+ // remap the AIG using map
+ pNew = Acec_ManDerive( p, vMirrors );
+ Vec_IntFree( vMirrors );
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Acec_DetectAdditional( Gia_Man_t * p, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pNew;
+ Vec_Int_t * vRootXorSet;
+// Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( p, &vXors, 0 );
+
+ //Ree_ManPrintAdders( vAdds, 1 );
+// printf( "Detected %d full-adders and %d half-adders. Found %d XOR-cuts. ", Ree_ManCountFadds(vAdds), Vec_IntSize(vAdds)/6-Ree_ManCountFadds(vAdds), Vec_IntSize(vXors)/4 );
+// Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+
+ clk = Abc_Clock();
+ vRootXorSet = Acec_CollectXorTops( p );
+ if ( vRootXorSet )
+ {
+ Acec_DetectComputeSupports( p, vRootXorSet );
+
+ pNew = Acec_DetectXorBuildNew( p, vRootXorSet );
+ Vec_IntFree( vRootXorSet );
+ }
+ else
+ pNew = Gia_ManDup( p );
+
+ printf( "Detected %d top XORs. ", Vec_IntSize(vRootXorSet)/4 );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+
+// Vec_IntFree( vXors );
+// Vec_IntFree( vAdds );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Acec_RewriteTop( Gia_Man_t * p, Acec_Box_t * pBox )
+{
+ Vec_Int_t * vRes = Vec_IntAlloc( Gia_ManCoNum(p) + 1 );
+ Vec_Int_t * vLevel;
+ int i, k, iStart, iLit, Driver, Count = 0;
+ // determine how much to shift
+ Driver = Gia_ObjFaninId0p( p, Gia_ManCo(p, 0) );
+ Vec_WecForEachLevel( pBox->vRootLits, vLevel, iStart )
+ if ( Abc_Lit2Var(Vec_IntEntry(vLevel,0)) == Driver )
+ break;
+ assert( iStart < Gia_ManCoNum(p) );
+ //Vec_WecPrintLits( pBox->vRootLits );
+ Vec_WecForEachLevelStart( pBox->vRootLits, vLevel, i, iStart )
+ {
+ int In[3] = {0}, Out[2];
+ assert( Vec_IntSize(vLevel) > 0 );
+ assert( Vec_IntSize(vLevel) <= 3 );
+ if ( Vec_IntSize(vLevel) == 1 )
+ {
+ Vec_IntPush( vRes, Vec_IntEntry(vLevel, 0) );
+ continue;
+ }
+ Vec_IntForEachEntry( vLevel, iLit, k )
+ In[k] = iLit;
+ Acec_InsertFadd( p, In, Out );
+ Vec_IntPush( vRes, Out[0] );
+ if ( i+1 < Vec_WecSize(pBox->vRootLits) )
+ Vec_IntPush( Vec_WecEntry(pBox->vRootLits, i+1), Out[1] );
+ else
+ Vec_IntPush( Vec_WecPushLevel(pBox->vRootLits), Out[1] );
+ Count++;
+ }
+ assert( Vec_IntSize(vRes) >= Gia_ManCoNum(p) );
+ Vec_IntShrink( vRes, Gia_ManCoNum(p) );
+ printf( "Added %d adders for replace CLAs. ", Count );
+ return vRes;
+}
+Gia_Man_t * Acec_RewriteReplace( Gia_Man_t * p, Vec_Int_t * vRes )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj; int i;
+ assert( Gia_ManCoNum(p) == Vec_IntSize(vRes) );
+ // create new manager
+ 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) );
+ Gia_ManForEachCo( p, pObj, i )
+ {
+ int iLit = Vec_IntEntry( vRes, i );
+ Gia_Obj_t * pRepr = Gia_ManObj( p, Abc_Lit2Var(iLit) );
+ pObj->Value = Gia_ManAppendCo( pNew, pRepr->Value );
+ }
+ // set correct phase
+ Gia_ManSetPhase( p );
+ Gia_ManSetPhase( pNew );
+ Gia_ManForEachCo( pNew, pObj, i )
+ if ( Gia_ObjPhase(pObj) != Gia_ObjPhase(Gia_ManCo(p, i)) )
+ Gia_ObjFlipFaninC0( pObj );
+ // remove dangling nodes
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+Gia_Man_t * Acec_ManDecla( Gia_Man_t * pGia, int fBooth, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pNew = NULL;
+ Vec_Bit_t * vIgnore = fBooth ? Acec_BoothFindPPG(pGia) : NULL;
+ Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, 0, 0, fVerbose );
+ Vec_Int_t * vResult;
+ Vec_BitFreeP( &vIgnore );
+ if ( pBox == NULL ) // cannot match
+ {
+ printf( "Cannot find arithmetic boxes.\n" );
+ return Gia_ManDup( pGia );
+ }
+ vResult = Acec_RewriteTop( pGia, pBox );
+ Acec_BoxFreeP( &pBox );
+ pNew = Acec_RewriteReplace( pGia, vResult );
+ Vec_IntFree( vResult );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ return pNew;
+}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/proof/acec/acecCo.c b/src/proof/acec/acecCo.c
index 1e8ed7bb..a997eb03 100644
--- a/src/proof/acec/acecCo.c
+++ b/src/proof/acec/acecCo.c
@@ -109,7 +109,7 @@ Vec_Int_t * Gia_PolynCoreOrder_int( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Wec
{
Vec_Int_t * vOrder = Vec_IntAlloc( 1000 );
Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(pGia) );
- int i, k, Index, Driver, Entry1, Entry2 = -1;
+ int i, k, Index = -1, Driver, Entry1, Entry2 = -1;
// mark roots
Vec_IntForEachEntry( vRoots, Driver, i )
Vec_BitWriteEntry( vIsRoot, Driver, 1 );
diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c
index ac7ee67b..1a575fbe 100644
--- a/src/proof/acec/acecCore.c
+++ b/src/proof/acec/acecCore.c
@@ -19,6 +19,9 @@
***********************************************************************/
#include "acecInt.h"
+#include "proof/cec/cec.h"
+#include "misc/util/utilTruth.h"
+#include "misc/extra/extra.h"
ABC_NAMESPACE_IMPL_START
@@ -27,12 +30,452 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+#define TRUTH_UNUSED 0x1234567812345678
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
+ Synopsis [This procedure sets default parameters.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p )
+{
+ memset( p, 0, sizeof(Acec_ParCec_t) );
+ p->nBTLimit = 1000; // conflict limit at a node
+ p->TimeLimit = 0; // the runtime limit in seconds
+ p->fMiter = 0; // input circuit is a miter
+ p->fDualOutput = 0; // dual-output miter
+ p->fTwoOutput = 0; // two-output miter
+ p->fSilent = 0; // print no messages
+ p->fVeryVerbose = 0; // verbose stats
+ p->fVerbose = 0; // verbose stats
+ p->iOutFail = -1; // the number of failed output
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_VerifyClasses( Gia_Man_t * p, Vec_Wec_t * vLits, Vec_Wec_t * vReprs )
+{
+ Vec_Ptr_t * vFunc = Vec_PtrAlloc( Vec_WecSize(vLits) );
+ Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
+ Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vLevel;
+ int i, j, k, Entry, Entry2, nOvers = 0, nErrors = 0;
+ Vec_WecForEachLevel( vLits, vLevel, i )
+ {
+ Vec_Wrd_t * vTruths = Vec_WrdAlloc( Vec_IntSize(vLevel) );
+ Vec_IntForEachEntry( vLevel, Entry, k )
+ {
+ word Truth = Gia_ObjComputeTruth6Cis( p, Entry, vSupp, vTemp );
+ if ( Vec_IntSize(vSupp) > 6 )
+ {
+ nOvers++;
+ Vec_WrdPush( vTruths, TRUTH_UNUSED );
+ continue;
+ }
+ vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize );
+ if ( Vec_IntSize(vSupp) > 5 )
+ {
+ nOvers++;
+ Vec_WrdPush( vTruths, TRUTH_UNUSED );
+ continue;
+ }
+ Vec_WrdPush( vTruths, Truth );
+ }
+ Vec_PtrPush( vFunc, vTruths );
+ }
+ if ( nOvers )
+ printf( "Detected %d oversize support nodes.\n", nOvers );
+ Vec_IntFree( vSupp );
+ Vec_WrdFree( vTemp );
+ // verify the classes
+ Vec_WecForEachLevel( vReprs, vLevel, i )
+ {
+ Vec_Wrd_t * vTruths = (Vec_Wrd_t *)Vec_PtrEntry( vFunc, i );
+ Vec_IntForEachEntry( vLevel, Entry, k )
+ Vec_IntForEachEntryStart( vLevel, Entry2, j, k+1 )
+ {
+ word Truth = Vec_WrdEntry( vTruths, k );
+ word Truth2 = Vec_WrdEntry( vTruths, j );
+ if ( Entry == Entry2 )
+ {
+ nErrors++;
+ if ( Truth != Truth2 && Truth != TRUTH_UNUSED && Truth2 != TRUTH_UNUSED )
+ printf( "Rank %d: Lit %d and %d do not pass verification.\n", i, k, j );
+ }
+ if ( Entry == Abc_LitNot(Entry2) )
+ {
+ nErrors++;
+ if ( Truth != ~Truth2 && Truth != TRUTH_UNUSED && Truth2 != TRUTH_UNUSED )
+ printf( "Rank %d: Lit %d and %d do not pass verification.\n", i, k, j );
+ }
+ }
+ }
+ if ( nErrors )
+ printf( "Total errors in equivalence classes = %d.\n", nErrors );
+ Vec_VecFree( (Vec_Vec_t *)vFunc );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Acec_CommonStart( Gia_Man_t * pBase, Gia_Man_t * pAdd )
+{
+ Gia_Obj_t * pObj;
+ int i;
+ Gia_ManFillValue( pAdd );
+ Gia_ManConst0(pAdd)->Value = 0;
+ if ( pBase == NULL )
+ {
+ pBase = Gia_ManStart( Gia_ManObjNum(pAdd) );
+ pBase->pName = Abc_UtilStrsav( pAdd->pName );
+ pBase->pSpec = Abc_UtilStrsav( pAdd->pSpec );
+ Gia_ManForEachCi( pAdd, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pBase);
+ Gia_ManHashAlloc( pBase );
+ }
+ else
+ {
+ assert( Gia_ManCiNum(pBase) == Gia_ManCiNum(pAdd) );
+ Gia_ManForEachCi( pAdd, pObj, i )
+ pObj->Value = Gia_Obj2Lit( pBase, Gia_ManCi(pBase, i) );
+ }
+ Gia_ManForEachAnd( pAdd, pObj, i )
+ pObj->Value = Gia_ManHashAnd( pBase, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ return pBase;
+}
+void Acec_CommonFinish( Gia_Man_t * pBase )
+{
+ int Id;
+ Gia_ManCreateRefs( pBase );
+ Gia_ManForEachAndId( pBase, Id )
+ if ( Gia_ObjRefNumId(pBase, Id) == 0 )
+ Gia_ManAppendCo( pBase, Abc_Var2Lit(Id,0) );
+}
+Vec_Int_t * Acec_CountRemap( Gia_Man_t * pAdd, Gia_Man_t * pBase )
+{
+ Gia_Obj_t * pObj; int i;
+ Vec_Int_t * vMapNew = Vec_IntStartFull( Gia_ManObjNum(pAdd) );
+ Gia_ManSetPhase( pAdd );
+ Vec_IntWriteEntry( vMapNew, 0, 0 );
+ Gia_ManForEachCand( pAdd, pObj, i )
+ {
+ int iObjBase = Abc_Lit2Var(pObj->Value);
+ Gia_Obj_t * pObjBase = Gia_ManObj( pBase, iObjBase );
+ int iObjRepr = Abc_Lit2Var(pObjBase->Value);
+ Vec_IntWriteEntry( vMapNew, i, Abc_Var2Lit(iObjRepr, Gia_ObjPhase(pObj)) );
+ }
+ return vMapNew;
+}
+void Acec_ComputeEquivClasses( Gia_Man_t * pOne, Gia_Man_t * pTwo, Vec_Int_t ** pvMap1, Vec_Int_t ** pvMap2 )
+{
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pBase, * pRepr;
+ pBase = Acec_CommonStart( NULL, pOne );
+ pBase = Acec_CommonStart( pBase, pTwo );
+ Acec_CommonFinish( pBase );
+ //Gia_ManShow( pBase, NULL, 0, 0, 0 );
+ pRepr = Gia_ManComputeGiaEquivs( pBase, 100, 0 );
+ *pvMap1 = Acec_CountRemap( pOne, pBase );
+ *pvMap2 = Acec_CountRemap( pTwo, pBase );
+ Gia_ManStop( pBase );
+ Gia_ManStop( pRepr );
+ printf( "Finished computing equivalent nodes. " );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+}
+void Acec_MatchBoxesSort( int * pArray, int nSize, int * pCostLits )
+{
+ int i, j, best_i;
+ for ( i = 0; i < nSize-1; i++ )
+ {
+ best_i = i;
+ for ( j = i+1; j < nSize; j++ )
+ if ( Abc_Lit2LitL(pCostLits, pArray[j]) > Abc_Lit2LitL(pCostLits, pArray[best_i]) )
+ best_i = j;
+ ABC_SWAP( int, pArray[i], pArray[best_i] );
+ }
+}
+void Acec_MatchPrintEquivLits( Gia_Man_t * p, Vec_Wec_t * vLits, int * pCostLits, int fVerbose )
+{
+ Vec_Int_t * vSupp;
+ Vec_Wrd_t * vTemp;
+ Vec_Int_t * vLevel;
+ int i, k, Entry;
+ printf( "Leaf literals and their classes:\n" );
+ Vec_WecForEachLevel( vLits, vLevel, i )
+ {
+ if ( Vec_IntSize(vLevel) == 0 )
+ continue;
+ printf( "Rank %2d : %2d ", i, Vec_IntSize(vLevel) );
+ Vec_IntForEachEntry( vLevel, Entry, k )
+ printf( "%s%d(%d) ", Abc_LitIsCompl(Entry) ? "-":"+", Abc_Lit2Var(Entry), Abc_Lit2LitL(pCostLits, Entry) );
+ printf( "\n" );
+ }
+ if ( !fVerbose )
+ return;
+ vSupp = Vec_IntAlloc( 100 );
+ vTemp = Vec_WrdStart( Gia_ManObjNum(p) );
+ Vec_WecForEachLevel( vLits, vLevel, i )
+ {
+ //if ( i != 20 )
+ // continue;
+ if ( Vec_IntSize(vLevel) == 0 )
+ continue;
+ Vec_IntForEachEntry( vLevel, Entry, k )
+ {
+ word Truth = Gia_ObjComputeTruth6Cis( p, Entry, vSupp, vTemp );
+/*
+ {
+ int iObj = Abc_Lit2Var(Entry);
+ Gia_Man_t * pGia0 = Gia_ManDupAndCones( p, &iObj, 1, 1 );
+ Gia_ManShow( pGia0, NULL, 0, 0, 0 );
+ Gia_ManStop( pGia0 );
+ }
+*/
+ printf( "Rank = %4d : ", i );
+ printf( "Obj = %4d ", Abc_Lit2Var(Entry) );
+ if ( Vec_IntSize(vSupp) > 6 )
+ {
+ printf( "Supp = %d.\n", Vec_IntSize(vSupp) );
+ continue;
+ }
+ vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize );
+ if ( Vec_IntSize(vSupp) > 5 )
+ {
+ printf( "Supp = %d.\n", Vec_IntSize(vSupp) );
+ continue;
+ }
+ Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) );
+ if ( Vec_IntSize(vSupp) == 4 ) printf( " " );
+ if ( Vec_IntSize(vSupp) == 3 ) printf( " " );
+ if ( Vec_IntSize(vSupp) <= 2 ) printf( " " );
+ printf( " " );
+ Vec_IntPrint( vSupp );
+ }
+ printf( "\n" );
+ }
+ Vec_IntFree( vSupp );
+ Vec_WrdFree( vTemp );
+}
+Vec_Wec_t * Acec_MatchCopy( Vec_Wec_t * vLits, Vec_Int_t * vMap )
+{
+ Vec_Wec_t * vRes = Vec_WecStart( Vec_WecSize(vLits) );
+ Vec_Int_t * vLevel; int i, k, iLit;
+ Vec_WecForEachLevel( vLits, vLevel, i )
+ Vec_IntForEachEntry( vLevel, iLit, k )
+ Vec_WecPush( vRes, i, Abc_Lit2LitL(Vec_IntArray(vMap), iLit) );
+ return vRes;
+}
+int Acec_MatchCountCommon( Vec_Wec_t * vLits1, Vec_Wec_t * vLits2, int Shift )
+{
+ Vec_Int_t * vRes = Vec_IntAlloc( 100 );
+ Vec_Int_t * vLevel1, * vLevel2;
+ int i, nCommon = 0;
+ Vec_WecForEachLevel( vLits1, vLevel1, i )
+ {
+ if ( i+Shift < 0 || i+Shift >= Vec_WecSize(vLits2) )
+ continue;
+ vLevel2 = Vec_WecEntry( vLits2, i+Shift );
+ nCommon += Vec_IntTwoFindCommonReverse( vLevel1, vLevel2, vRes );
+ }
+ Vec_IntFree( vRes );
+ return nCommon;
+}
+void Vec_IntInsertOrder( Vec_Int_t * vLits, Vec_Int_t * vClasses, int Lit, int Class )
+{
+ int i;
+ for ( i = Vec_IntSize(vClasses)-1; i >= 0; i-- )
+ if ( Vec_IntEntry(vClasses,i) >= Class )
+ break;
+ Vec_IntInsert( vLits, i+1, Lit );
+ Vec_IntInsert( vClasses, i+1, Class );
+}
+void Acec_MoveDuplicates( Vec_Wec_t * vLits, Vec_Wec_t * vClasses )
+{
+ Vec_Int_t * vLevel1, * vLevel2;
+ int i, k, Prev, This, Entry, Counter = 0;
+ Vec_WecForEachLevel( vLits, vLevel1, i )
+ {
+ if ( i == Vec_WecSize(vLits) - 1 )
+ break;
+ vLevel2 = Vec_WecEntry(vClasses, i);
+ assert( Vec_IntSize(vLevel1) == Vec_IntSize(vLevel2) );
+ Prev = -1;
+ Vec_IntForEachEntry( vLevel2, This, k )
+ {
+ if ( Prev != This )
+ {
+ Prev = This;
+ continue;
+ }
+ Prev = -1;
+ Entry = Vec_IntEntry( vLevel1, k );
+
+ Vec_IntDrop( vLevel1, k );
+ Vec_IntDrop( vLevel2, k-- );
+
+ Vec_IntDrop( vLevel1, k );
+ Vec_IntDrop( vLevel2, k-- );
+
+ Vec_IntInsertOrder( Vec_WecEntry(vLits, i+1), Vec_WecEntry(vClasses, i+1), Entry, This );
+
+ assert( Vec_IntSize(vLevel1) == Vec_IntSize(vLevel2) );
+ assert( Vec_IntSize(Vec_WecEntry(vLits, i+1)) == Vec_IntSize(Vec_WecEntry(vClasses, i+1)) );
+ Counter++;
+ }
+ }
+ printf( "Moved %d pairs of PPs to normalize the matrix.\n", Counter );
+}
+
+void Acec_MatchCheckShift( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Vec_Wec_t * vLits0, Vec_Wec_t * vLits1, Vec_Int_t * vMap0, Vec_Int_t * vMap1, Vec_Wec_t * vRoots0, Vec_Wec_t * vRoots1 )
+{
+ Vec_Wec_t * vRes0 = Acec_MatchCopy( vLits0, vMap0 );
+ Vec_Wec_t * vRes1 = Acec_MatchCopy( vLits1, vMap1 );
+ int nCommon = Acec_MatchCountCommon( vRes0, vRes1, 0 );
+ int nCommonPlus = Acec_MatchCountCommon( vRes0, vRes1, 1 );
+ int nCommonMinus = Acec_MatchCountCommon( vRes0, vRes1, -1 );
+ if ( nCommonPlus >= nCommonMinus && nCommonPlus > nCommon )
+ {
+ Vec_WecInsertLevel( vLits0, 0 );
+ Vec_WecInsertLevel( vRoots0, 0 );
+ Vec_WecInsertLevel( vRes0, 0 );
+ printf( "Shifted one level up.\n" );
+ }
+ else if ( nCommonMinus > nCommonPlus && nCommonMinus > nCommon )
+ {
+ Vec_WecInsertLevel( vLits1, 0 );
+ Vec_WecInsertLevel( vRoots1, 0 );
+ Vec_WecInsertLevel( vRes1, 0 );
+ printf( "Shifted one level down.\n" );
+ }
+ Acec_MoveDuplicates( vLits0, vRes0 );
+ Acec_MoveDuplicates( vLits1, vRes1 );
+
+ //Vec_WecPrintLits( vLits1 );
+ //printf( "Input literals:\n" );
+ //Vec_WecPrintLits( vLits0 );
+ //printf( "Equiv classes:\n" );
+ //Vec_WecPrintLits( vRes0 );
+ //printf( "Input literals:\n" );
+ //Vec_WecPrintLits( vLits1 );
+ //printf( "Equiv classes:\n" );
+ //Vec_WecPrintLits( vRes1 );
+ //Acec_VerifyClasses( pGia0, vLits0, vRes0 );
+ //Acec_VerifyClasses( pGia1, vLits1, vRes1 );
+ Vec_WecFree( vRes0 );
+ Vec_WecFree( vRes1 );
+}
+int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 )
+{
+ Vec_Int_t * vMap0, * vMap1, * vLevel;
+ int i, nSize, nTotal;
+ Acec_ComputeEquivClasses( pBox0->pGia, pBox1->pGia, &vMap0, &vMap1 );
+ // sort nodes in the classes by their equivalences
+ Vec_WecForEachLevel( pBox0->vLeafLits, vLevel, i )
+ Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap0) );
+ Vec_WecForEachLevel( pBox1->vLeafLits, vLevel, i )
+ Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap1) );
+ Acec_MatchCheckShift( pBox0->pGia, pBox1->pGia, pBox0->vLeafLits, pBox1->vLeafLits, vMap0, vMap1, pBox0->vRootLits, pBox1->vRootLits );
+
+ //Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vLeafLits, Vec_IntArray(vMap0), 0 );
+ //Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vLeafLits, Vec_IntArray(vMap1), 0 );
+ //printf( "Outputs:\n" );
+ //Vec_WecPrintLits( pBox0->vRootLits );
+ //printf( "Outputs:\n" );
+ //Vec_WecPrintLits( pBox1->vRootLits );
+
+ // reorder nodes to have the same order
+ assert( pBox0->vShared == NULL );
+ assert( pBox1->vShared == NULL );
+ pBox0->vShared = Vec_WecStart( Vec_WecSize(pBox0->vLeafLits) );
+ pBox1->vShared = Vec_WecStart( Vec_WecSize(pBox1->vLeafLits) );
+ pBox0->vUnique = Vec_WecStart( Vec_WecSize(pBox0->vLeafLits) );
+ pBox1->vUnique = Vec_WecStart( Vec_WecSize(pBox1->vLeafLits) );
+ nSize = Abc_MinInt( Vec_WecSize(pBox0->vLeafLits), Vec_WecSize(pBox1->vLeafLits) );
+ Vec_WecForEachLevelStart( pBox0->vLeafLits, vLevel, i, nSize )
+ Vec_IntAppend( Vec_WecEntry(pBox0->vUnique, i), vLevel );
+ Vec_WecForEachLevelStart( pBox1->vLeafLits, vLevel, i, nSize )
+ Vec_IntAppend( Vec_WecEntry(pBox1->vUnique, i), vLevel );
+ for ( i = 0; i < nSize; i++ )
+ {
+ Vec_Int_t * vShared0 = Vec_WecEntry( pBox0->vShared, i );
+ Vec_Int_t * vShared1 = Vec_WecEntry( pBox1->vShared, i );
+ Vec_Int_t * vUnique0 = Vec_WecEntry( pBox0->vUnique, i );
+ Vec_Int_t * vUnique1 = Vec_WecEntry( pBox1->vUnique, i );
+
+ Vec_Int_t * vLevel0 = Vec_WecEntry( pBox0->vLeafLits, i );
+ Vec_Int_t * vLevel1 = Vec_WecEntry( pBox1->vLeafLits, i );
+ int * pBeg0 = Vec_IntArray(vLevel0);
+ int * pBeg1 = Vec_IntArray(vLevel1);
+ int * pEnd0 = Vec_IntLimit(vLevel0);
+ int * pEnd1 = Vec_IntLimit(vLevel1);
+ while ( pBeg0 < pEnd0 && pBeg1 < pEnd1 )
+ {
+ int Entry0 = Abc_Lit2LitL( Vec_IntArray(vMap0), *pBeg0 );
+ int Entry1 = Abc_Lit2LitL( Vec_IntArray(vMap1), *pBeg1 );
+ assert( *pBeg0 && *pBeg1 );
+ if ( Entry0 == Entry1 )
+ {
+ Vec_IntPush( vShared0, *pBeg0++ );
+ Vec_IntPush( vShared1, *pBeg1++ );
+ }
+ else if ( Entry0 > Entry1 )
+ Vec_IntPush( vUnique0, *pBeg0++ );
+ else
+ Vec_IntPush( vUnique1, *pBeg1++ );
+ }
+ while ( pBeg0 < pEnd0 )
+ Vec_IntPush( vUnique0, *pBeg0++ );
+ while ( pBeg1 < pEnd1 )
+ Vec_IntPush( vUnique1, *pBeg1++ );
+ assert( Vec_IntSize(vShared0) == Vec_IntSize(vShared1) );
+ assert( Vec_IntSize(vShared0) + Vec_IntSize(vUnique0) == Vec_IntSize(vLevel0) );
+ assert( Vec_IntSize(vShared1) + Vec_IntSize(vUnique1) == Vec_IntSize(vLevel1) );
+ }
+ nTotal = Vec_WecSizeSize(pBox0->vShared);
+ printf( "Box0: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox0->vLeafLits) );
+ printf( "Box1: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox1->vLeafLits) );
+
+ //Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vShared, Vec_IntArray(vMap0), 0 );
+ //Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vShared, Vec_IntArray(vMap1), 0 );
+ //printf( "\n" );
+
+ //Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vUnique, Vec_IntArray(vMap0), 0 );
+ //Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vUnique, Vec_IntArray(vMap1), 0 );
+
+ Vec_IntFree( vMap0 );
+ Vec_IntFree( vMap1 );
+ return nTotal;
+}
+
+/**Function*************************************************************
+
Synopsis []
Description []
@@ -42,15 +485,63 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
-int Gia_PolynCec( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Cec_ParCec_t * pPars )
-{
- Vec_Int_t * vOrder0 = Gia_PolynReorder( pGia0, pPars->fVerbose, pPars->fVeryVerbose );
- Vec_Int_t * vOrder1 = Gia_PolynReorder( pGia1, pPars->fVerbose, pPars->fVeryVerbose );
- Gia_PolynBuild( pGia0, vOrder0, 0, pPars->fVerbose, pPars->fVeryVerbose );
- Gia_PolynBuild( pGia1, vOrder1, 0, pPars->fVerbose, pPars->fVeryVerbose );
- Vec_IntFree( vOrder0 );
- Vec_IntFree( vOrder1 );
- return 1;
+int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars )
+{
+ int status = -1;
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pMiter;
+ Gia_Man_t * pGia0n = pGia0, * pGia1n = pGia1;
+ Cec_ParCec_t ParsCec, * pCecPars = &ParsCec;
+// Vec_Bit_t * vIgnore0 = pPars->fBooth ? Acec_BoothFindPPG(pGia0) : NULL;
+// Vec_Bit_t * vIgnore1 = pPars->fBooth ? Acec_BoothFindPPG(pGia1) : NULL;
+// Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0, vIgnore0, 0, 0, pPars->fVerbose );
+// Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1, vIgnore1, 0, 0, pPars->fVerbose );
+// Vec_BitFreeP( &vIgnore0 );
+// Vec_BitFreeP( &vIgnore1 );
+ Acec_Box_t * pBox0 = Acec_ProduceBox( pGia0, pPars->fVerbose );
+ Acec_Box_t * pBox1 = Acec_ProduceBox( pGia1, pPars->fVerbose );
+ if ( pBox0 == NULL || pBox1 == NULL ) // cannot match
+ printf( "Cannot find arithmetic boxes in both LHS and RHS. Trying regular CEC.\n" );
+ else if ( !Acec_MatchBoxes( pBox0, pBox1 ) ) // cannot find matching
+ printf( "Cannot match arithmetic boxes in LHS and RHS. Trying regular CEC.\n" );
+ else
+ {
+ pGia0n = Acec_InsertBox( pBox0, 0 );
+ pGia1n = Acec_InsertBox( pBox1, 0 );
+ printf( "Matching of adder trees in LHS and RHS succeeded. " );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ // remove the last output
+ Gia_ManPatchCoDriver( pGia0n, Gia_ManCoNum(pGia0n)-1, 0 );
+ Gia_ManPatchCoDriver( pGia1n, Gia_ManCoNum(pGia1n)-1, 0 );
+
+ Gia_ManPatchCoDriver( pGia0n, Gia_ManCoNum(pGia0n)-2, 0 );
+ Gia_ManPatchCoDriver( pGia1n, Gia_ManCoNum(pGia1n)-2, 0 );
+ }
+ // solve regular CEC problem
+ Cec_ManCecSetDefaultParams( pCecPars );
+ pCecPars->nBTLimit = pPars->nBTLimit;
+ pMiter = Gia_ManMiter( pGia0n, pGia1n, 0, 1, 0, 0, pPars->fVerbose );
+ if ( pMiter )
+ {
+ int fDumpMiter = 0;
+ if ( fDumpMiter )
+ {
+ Abc_Print( 0, "The verification miter is written into file \"%s\".\n", "acec_miter.aig" );
+ Gia_AigerWrite( pMiter, "acec_miter.aig", 0, 0 );
+ }
+ status = Cec_ManVerify( pMiter, pCecPars );
+ ABC_SWAP( Abc_Cex_t *, pGia0->pCexComb, pMiter->pCexComb );
+ Gia_ManStop( pMiter );
+ }
+ else
+ printf( "Miter computation has failed.\n" );
+ if ( pGia0n != pGia0 )
+ Gia_ManStop( pGia0n );
+ if ( pGia1n != pGia1 )
+ Gia_ManStop( pGia1n );
+ Acec_BoxFreeP( &pBox0 );
+ Acec_BoxFreeP( &pBox1 );
+ return status;
}
////////////////////////////////////////////////////////////////////////
diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h
index e761e56e..c4c8061e 100644
--- a/src/proof/acec/acecInt.h
+++ b/src/proof/acec/acecInt.h
@@ -27,7 +27,6 @@
////////////////////////////////////////////////////////////////////////
#include "aig/gia/gia.h"
-#include "proof/cec/cec.h"
#include "acec.h"
////////////////////////////////////////////////////////////////////////
@@ -38,6 +37,17 @@
ABC_NAMESPACE_HEADER_START
+typedef struct Acec_Box_t_ Acec_Box_t;
+struct Acec_Box_t_
+{
+ Gia_Man_t * pGia; // AIG manager
+ Vec_Wec_t * vAdds; // adders by rank
+ Vec_Wec_t * vLeafLits; // leaf literals by rank
+ Vec_Wec_t * vRootLits; // root literals by rank
+ Vec_Wec_t * vShared; // shared leaves
+ Vec_Wec_t * vUnique; // unique leaves
+};
+
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
@@ -46,6 +56,12 @@ ABC_NAMESPACE_HEADER_START
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
+static inline int Acec_SignBit( Vec_Int_t * vAdds, int iBox, int b ) { return (Vec_IntEntry(vAdds, 6*iBox+5) >> b) & 1; }
+static inline int Acec_SignBit2( Vec_Int_t * vAdds, int iBox, int b ) { return (Vec_IntEntry(vAdds, 6*iBox+5) >> (16+b)) & 1; }
+
+static inline void Acec_SignSetBit( Vec_Int_t * vAdds, int iBox, int b, int v ) { if ( v ) *Vec_IntEntryP(vAdds, 6*iBox+5) |= (1 << b); }
+static inline void Acec_SignSetBit2( Vec_Int_t * vAdds, int iBox, int b, int v ) { if ( v ) *Vec_IntEntryP(vAdds, 6*iBox+5) |= (1 << (16+b)); }
+
////////////////////////////////////////////////////////////////////////
/// ITERATORS ///
////////////////////////////////////////////////////////////////////////
@@ -54,9 +70,28 @@ ABC_NAMESPACE_HEADER_START
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+/*=== acecCo.c ========================================================*/
+extern Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vAddCos, Vec_Int_t ** pvIns, Vec_Int_t ** pvOuts );
+extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vRootBoxes );
+/*=== acecMult.c ========================================================*/
+extern Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits );
+extern Vec_Bit_t * Acec_BoothFindPPG( Gia_Man_t * p );
+extern Vec_Bit_t * Acec_MultMarkPPs( Gia_Man_t * p );
+/*=== acecNorm.c ========================================================*/
+extern void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] );
+extern Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll );
+/*=== acecTree.c ========================================================*/
+extern void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds );
+extern void Acec_TreePrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds );
+extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fFilterIn, int fFilterOut, int fVerbose );
+extern void Acec_BoxFreeP( Acec_Box_t ** ppBox );
/*=== acecUtil.c ========================================================*/
extern void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose );
extern Vec_Int_t * Gia_PolynCollectLastXor( Gia_Man_t * pGia, int fVerbose );
+/*=== acecUtil.c ========================================================*/
+extern Acec_Box_t * Acec_ProduceBox( Gia_Man_t * p, int fVerbose );
+
+
ABC_NAMESPACE_HEADER_END
diff --git a/src/proof/acec/acecMult.c b/src/proof/acec/acecMult.c
new file mode 100644
index 00000000..c63fdde2
--- /dev/null
+++ b/src/proof/acec/acecMult.c
@@ -0,0 +1,617 @@
+/**CFile****************************************************************
+
+ FileName [acecMult.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [CEC for arithmetic circuits.]
+
+ Synopsis [Multiplier.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: acecMult.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "acecInt.h"
+#include "misc/extra/extra.h"
+#include "misc/util/utilTruth.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+unsigned s_Classes4a[96] = {
+ 0xD728, 0xB748, 0x9F60, 0xD278, 0xB478, 0x96F0, 0xC66C, 0x96CC, 0x9C6C, 0x96AA, 0xA66A, 0x9A6A,
+ 0x28D7, 0x48B7, 0x609F, 0x2D87, 0x4B87, 0x690F, 0x3993, 0x6933, 0x6393, 0x6955, 0x5995, 0x6595,
+ 0xEB14, 0xED12, 0xF906, 0xE1B4, 0xE1D2, 0xF096, 0xC99C, 0xCC96, 0xC9C6, 0xAA96, 0xA99A, 0xA9A6,
+ 0x14EB, 0x12ED, 0x06F9, 0x1E4B, 0x1E2D, 0x0F69, 0x3663, 0x3369, 0x3639, 0x5569, 0x5665, 0x5659,
+ 0x7D82, 0x7B84, 0x6F90, 0x78D2, 0x78B4, 0x69F0, 0x6CC6, 0x69CC, 0x6C9C, 0x69AA, 0x6AA6, 0x6A9A,
+ 0x827D, 0x847B, 0x906F, 0x872D, 0x874B, 0x960F, 0x9339, 0x9633, 0x9363, 0x9655, 0x9559, 0x9565,
+ 0xBE41, 0xDE21, 0xF609, 0xB4E1, 0xD2E1, 0xF069, 0x9CC9, 0xCC69, 0xC6C9, 0xAA69, 0x9AA9, 0xA6A9,
+ 0x41BE, 0x21DE, 0x09F6, 0x4B1E, 0x2D1E, 0x0F96, 0x6336, 0x3396, 0x3936, 0x5596, 0x6556, 0x5956
+};
+
+unsigned s_Classes4b[384] = {
+ 0x35C0, 0x53A0, 0x1DC0, 0x4788, 0x2788, 0x1BA0, 0x3C50, 0x5A30, 0x1CD0, 0x4878, 0x2878, 0x1AB0,
+ 0x34C4, 0x606C, 0x3C44, 0x660C, 0x268C, 0x286C, 0x606A, 0x52A2, 0x486A, 0x468A, 0x660A, 0x5A22,
+ 0x3AC0, 0x5CA0, 0x2EC0, 0x7488, 0x7288, 0x4EA0, 0x3CA0, 0x5AC0, 0x2CE0, 0x7848, 0x7828, 0x4AE0,
+ 0x38C8, 0x6C60, 0x3C88, 0x66C0, 0x62C8, 0x6C28, 0x6A60, 0x58A8, 0x6A48, 0x64A8, 0x66A0, 0x5A88,
+ 0xC530, 0xA350, 0xD10C, 0x8B44, 0x8D22, 0xB10A, 0xC350, 0xA530, 0xD01C, 0x84B4, 0x82D2, 0xB01A,
+ 0xC434, 0x909C, 0xC344, 0x990C, 0x8C26, 0x82C6, 0x909A, 0xA252, 0x84A6, 0x8A46, 0x990A, 0xA522,
+ 0xCA30, 0xAC50, 0xE20C, 0xB844, 0xD822, 0xE40A, 0xC3A0, 0xA5C0, 0xE02C, 0xB484, 0xD282, 0xE04A,
+ 0xC838, 0x9C90, 0xC388, 0x99C0, 0xC862, 0xC682, 0x9A90, 0xA858, 0xA684, 0xA864, 0x99A0, 0xA588,
+ 0x530C, 0x350A, 0x4730, 0x1D22, 0x1B44, 0x2750, 0x503C, 0x305A, 0x4370, 0x12D2, 0x14B4, 0x2570,
+ 0x434C, 0x06C6, 0x443C, 0x0C66, 0x194C, 0x149C, 0x06A6, 0x252A, 0x129A, 0x192A, 0x0A66, 0x225A,
+ 0xA30C, 0xC50A, 0x8B30, 0xD122, 0xB144, 0x8D50, 0xA03C, 0xC05A, 0x83B0, 0xD212, 0xB414, 0x85D0,
+ 0x838C, 0xC606, 0x883C, 0xC066, 0x91C4, 0x9C14, 0xA606, 0x858A, 0x9A12, 0x91A2, 0xA066, 0x885A,
+ 0x5C03, 0x3A05, 0x7403, 0x2E11, 0x4E11, 0x7205, 0x50C3, 0x30A5, 0x7043, 0x21E1, 0x41E1, 0x7025,
+ 0x4C43, 0x09C9, 0x44C3, 0x0C99, 0x4C19, 0x41C9, 0x09A9, 0x2A25, 0x21A9, 0x2A19, 0x0A99, 0x22A5,
+ 0xAC03, 0xCA05, 0xB803, 0xE211, 0xE411, 0xD805, 0xA0C3, 0xC0A5, 0xB083, 0xE121, 0xE141, 0xD085,
+ 0x8C83, 0xC909, 0x88C3, 0xC099, 0xC491, 0xC941, 0xA909, 0x8A85, 0xA921, 0xA291, 0xA099, 0x88A5,
+ 0xC035, 0xA053, 0xC01D, 0x8847, 0x8827, 0xA01B, 0xC305, 0xA503, 0xC10D, 0x8487, 0x8287, 0xA10B,
+ 0xC131, 0x9093, 0xC311, 0x9903, 0x8923, 0x8293, 0x9095, 0xA151, 0x8495, 0x8945, 0x9905, 0xA511,
+ 0xC03A, 0xA05C, 0xC02E, 0x8874, 0x8872, 0xA04E, 0xC30A, 0xA50C, 0xC20E, 0x8784, 0x8782, 0xA40E,
+ 0xC232, 0x9390, 0xC322, 0x9930, 0x9832, 0x9382, 0x9590, 0xA454, 0x9584, 0x9854, 0x9950, 0xA544,
+ 0x30C5, 0x50A3, 0x0CD1, 0x448B, 0x228D, 0x0AB1, 0x3C05, 0x5A03, 0x0DC1, 0x484B, 0x282D, 0x0BA1,
+ 0x31C1, 0x6063, 0x3C11, 0x6603, 0x2389, 0x2839, 0x6065, 0x51A1, 0x4859, 0x4589, 0x6605, 0x5A11,
+ 0x30CA, 0x50AC, 0x0CE2, 0x44B8, 0x22D8, 0x0AE4, 0x3C0A, 0x5A0C, 0x0EC2, 0x4B48, 0x2D28, 0x0EA4,
+ 0x32C2, 0x6360, 0x3C22, 0x6630, 0x3298, 0x3928, 0x6560, 0x54A4, 0x5948, 0x5498, 0x6650, 0x5A44,
+ 0x0C53, 0x0A35, 0x3047, 0x221D, 0x441B, 0x5027, 0x05C3, 0x03A5, 0x3407, 0x212D, 0x414B, 0x5207,
+ 0x1C13, 0x0939, 0x11C3, 0x0399, 0x4613, 0x4163, 0x0959, 0x1A15, 0x2165, 0x2615, 0x0599, 0x11A5,
+ 0x0CA3, 0x0AC5, 0x308B, 0x22D1, 0x44B1, 0x508D, 0x0AC3, 0x0CA5, 0x380B, 0x2D21, 0x4B41, 0x580D,
+ 0x2C23, 0x3909, 0x22C3, 0x3099, 0x6431, 0x6341, 0x5909, 0x4A45, 0x6521, 0x6251, 0x5099, 0x44A5,
+ 0x035C, 0x053A, 0x0374, 0x112E, 0x114E, 0x0572, 0x053C, 0x035A, 0x0734, 0x121E, 0x141E, 0x0752,
+ 0x131C, 0x0636, 0x113C, 0x0366, 0x1346, 0x1436, 0x0656, 0x151A, 0x1256, 0x1526, 0x0566, 0x115A,
+ 0x03AC, 0x05CA, 0x03B8, 0x11E2, 0x11E4, 0x05D8, 0x0A3C, 0x0C5A, 0x0B38, 0x1E12, 0x1E14, 0x0D58,
+ 0x232C, 0x3606, 0x223C, 0x3066, 0x3164, 0x3614, 0x5606, 0x454A, 0x5612, 0x5162, 0x5066, 0x445A
+};
+
+unsigned s_Classes4c[768] = {
+ 0x35C0, 0x53A0, 0x1DC0, 0x4788, 0x2788, 0x1BA0, 0x3C50, 0x5A30, 0x1CD0, 0x4878, 0x2878, 0x1AB0,
+ 0x34C4, 0x606C, 0x3C44, 0x660C, 0x268C, 0x286C, 0x606A, 0x52A2, 0x486A, 0x468A, 0x660A, 0x5A22,
+ 0xCA3F, 0xAC5F, 0xE23F, 0xB877, 0xD877, 0xE45F, 0xC3AF, 0xA5CF, 0xE32F, 0xB787, 0xD787, 0xE54F,
+ 0xCB3B, 0x9F93, 0xC3BB, 0x99F3, 0xD973, 0xD793, 0x9F95, 0xAD5D, 0xB795, 0xB975, 0x99F5, 0xA5DD,
+ 0x3AC0, 0x5CA0, 0x2EC0, 0x7488, 0x7288, 0x4EA0, 0x3CA0, 0x5AC0, 0x2CE0, 0x7848, 0x7828, 0x4AE0,
+ 0x38C8, 0x6C60, 0x3C88, 0x66C0, 0x62C8, 0x6C28, 0x6A60, 0x58A8, 0x6A48, 0x64A8, 0x66A0, 0x5A88,
+ 0xC53F, 0xA35F, 0xD13F, 0x8B77, 0x8D77, 0xB15F, 0xC35F, 0xA53F, 0xD31F, 0x87B7, 0x87D7, 0xB51F,
+ 0xC737, 0x939F, 0xC377, 0x993F, 0x9D37, 0x93D7, 0x959F, 0xA757, 0x95B7, 0x9B57, 0x995F, 0xA577,
+ 0xC530, 0xA350, 0xD10C, 0x8B44, 0x8D22, 0xB10A, 0xC350, 0xA530, 0xD01C, 0x84B4, 0x82D2, 0xB01A,
+ 0xC434, 0x909C, 0xC344, 0x990C, 0x8C26, 0x82C6, 0x909A, 0xA252, 0x84A6, 0x8A46, 0x990A, 0xA522,
+ 0x3ACF, 0x5CAF, 0x2EF3, 0x74BB, 0x72DD, 0x4EF5, 0x3CAF, 0x5ACF, 0x2FE3, 0x7B4B, 0x7D2D, 0x4FE5,
+ 0x3BCB, 0x6F63, 0x3CBB, 0x66F3, 0x73D9, 0x7D39, 0x6F65, 0x5DAD, 0x7B59, 0x75B9, 0x66F5, 0x5ADD,
+ 0xCA30, 0xAC50, 0xE20C, 0xB844, 0xD822, 0xE40A, 0xC3A0, 0xA5C0, 0xE02C, 0xB484, 0xD282, 0xE04A,
+ 0xC838, 0x9C90, 0xC388, 0x99C0, 0xC862, 0xC682, 0x9A90, 0xA858, 0xA684, 0xA864, 0x99A0, 0xA588,
+ 0x35CF, 0x53AF, 0x1DF3, 0x47BB, 0x27DD, 0x1BF5, 0x3C5F, 0x5A3F, 0x1FD3, 0x4B7B, 0x2D7D, 0x1FB5,
+ 0x37C7, 0x636F, 0x3C77, 0x663F, 0x379D, 0x397D, 0x656F, 0x57A7, 0x597B, 0x579B, 0x665F, 0x5A77,
+ 0x530C, 0x350A, 0x4730, 0x1D22, 0x1B44, 0x2750, 0x503C, 0x305A, 0x4370, 0x12D2, 0x14B4, 0x2570,
+ 0x434C, 0x06C6, 0x443C, 0x0C66, 0x194C, 0x149C, 0x06A6, 0x252A, 0x129A, 0x192A, 0x0A66, 0x225A,
+ 0xACF3, 0xCAF5, 0xB8CF, 0xE2DD, 0xE4BB, 0xD8AF, 0xAFC3, 0xCFA5, 0xBC8F, 0xED2D, 0xEB4B, 0xDA8F,
+ 0xBCB3, 0xF939, 0xBBC3, 0xF399, 0xE6B3, 0xEB63, 0xF959, 0xDAD5, 0xED65, 0xE6D5, 0xF599, 0xDDA5,
+ 0xA30C, 0xC50A, 0x8B30, 0xD122, 0xB144, 0x8D50, 0xA03C, 0xC05A, 0x83B0, 0xD212, 0xB414, 0x85D0,
+ 0x838C, 0xC606, 0x883C, 0xC066, 0x91C4, 0x9C14, 0xA606, 0x858A, 0x9A12, 0x91A2, 0xA066, 0x885A,
+ 0x5CF3, 0x3AF5, 0x74CF, 0x2EDD, 0x4EBB, 0x72AF, 0x5FC3, 0x3FA5, 0x7C4F, 0x2DED, 0x4BEB, 0x7A2F,
+ 0x7C73, 0x39F9, 0x77C3, 0x3F99, 0x6E3B, 0x63EB, 0x59F9, 0x7A75, 0x65ED, 0x6E5D, 0x5F99, 0x77A5,
+ 0x5C03, 0x3A05, 0x7403, 0x2E11, 0x4E11, 0x7205, 0x50C3, 0x30A5, 0x7043, 0x21E1, 0x41E1, 0x7025,
+ 0x4C43, 0x09C9, 0x44C3, 0x0C99, 0x4C19, 0x41C9, 0x09A9, 0x2A25, 0x21A9, 0x2A19, 0x0A99, 0x22A5,
+ 0xA3FC, 0xC5FA, 0x8BFC, 0xD1EE, 0xB1EE, 0x8DFA, 0xAF3C, 0xCF5A, 0x8FBC, 0xDE1E, 0xBE1E, 0x8FDA,
+ 0xB3BC, 0xF636, 0xBB3C, 0xF366, 0xB3E6, 0xBE36, 0xF656, 0xD5DA, 0xDE56, 0xD5E6, 0xF566, 0xDD5A,
+ 0xAC03, 0xCA05, 0xB803, 0xE211, 0xE411, 0xD805, 0xA0C3, 0xC0A5, 0xB083, 0xE121, 0xE141, 0xD085,
+ 0x8C83, 0xC909, 0x88C3, 0xC099, 0xC491, 0xC941, 0xA909, 0x8A85, 0xA921, 0xA291, 0xA099, 0x88A5,
+ 0x53FC, 0x35FA, 0x47FC, 0x1DEE, 0x1BEE, 0x27FA, 0x5F3C, 0x3F5A, 0x4F7C, 0x1EDE, 0x1EBE, 0x2F7A,
+ 0x737C, 0x36F6, 0x773C, 0x3F66, 0x3B6E, 0x36BE, 0x56F6, 0x757A, 0x56DE, 0x5D6E, 0x5F66, 0x775A,
+ 0xC035, 0xA053, 0xC01D, 0x8847, 0x8827, 0xA01B, 0xC305, 0xA503, 0xC10D, 0x8487, 0x8287, 0xA10B,
+ 0xC131, 0x9093, 0xC311, 0x9903, 0x8923, 0x8293, 0x9095, 0xA151, 0x8495, 0x8945, 0x9905, 0xA511,
+ 0x3FCA, 0x5FAC, 0x3FE2, 0x77B8, 0x77D8, 0x5FE4, 0x3CFA, 0x5AFC, 0x3EF2, 0x7B78, 0x7D78, 0x5EF4,
+ 0x3ECE, 0x6F6C, 0x3CEE, 0x66FC, 0x76DC, 0x7D6C, 0x6F6A, 0x5EAE, 0x7B6A, 0x76BA, 0x66FA, 0x5AEE,
+ 0xC03A, 0xA05C, 0xC02E, 0x8874, 0x8872, 0xA04E, 0xC30A, 0xA50C, 0xC20E, 0x8784, 0x8782, 0xA40E,
+ 0xC232, 0x9390, 0xC322, 0x9930, 0x9832, 0x9382, 0x9590, 0xA454, 0x9584, 0x9854, 0x9950, 0xA544,
+ 0x3FC5, 0x5FA3, 0x3FD1, 0x778B, 0x778D, 0x5FB1, 0x3CF5, 0x5AF3, 0x3DF1, 0x787B, 0x787D, 0x5BF1,
+ 0x3DCD, 0x6C6F, 0x3CDD, 0x66CF, 0x67CD, 0x6C7D, 0x6A6F, 0x5BAB, 0x6A7B, 0x67AB, 0x66AF, 0x5ABB,
+ 0x30C5, 0x50A3, 0x0CD1, 0x448B, 0x228D, 0x0AB1, 0x3C05, 0x5A03, 0x0DC1, 0x484B, 0x282D, 0x0BA1,
+ 0x31C1, 0x6063, 0x3C11, 0x6603, 0x2389, 0x2839, 0x6065, 0x51A1, 0x4859, 0x4589, 0x6605, 0x5A11,
+ 0xCF3A, 0xAF5C, 0xF32E, 0xBB74, 0xDD72, 0xF54E, 0xC3FA, 0xA5FC, 0xF23E, 0xB7B4, 0xD7D2, 0xF45E,
+ 0xCE3E, 0x9F9C, 0xC3EE, 0x99FC, 0xDC76, 0xD7C6, 0x9F9A, 0xAE5E, 0xB7A6, 0xBA76, 0x99FA, 0xA5EE,
+ 0x30CA, 0x50AC, 0x0CE2, 0x44B8, 0x22D8, 0x0AE4, 0x3C0A, 0x5A0C, 0x0EC2, 0x4B48, 0x2D28, 0x0EA4,
+ 0x32C2, 0x6360, 0x3C22, 0x6630, 0x3298, 0x3928, 0x6560, 0x54A4, 0x5948, 0x5498, 0x6650, 0x5A44,
+ 0xCF35, 0xAF53, 0xF31D, 0xBB47, 0xDD27, 0xF51B, 0xC3F5, 0xA5F3, 0xF13D, 0xB4B7, 0xD2D7, 0xF15B,
+ 0xCD3D, 0x9C9F, 0xC3DD, 0x99CF, 0xCD67, 0xC6D7, 0x9A9F, 0xAB5B, 0xA6B7, 0xAB67, 0x99AF, 0xA5BB,
+ 0x0C53, 0x0A35, 0x3047, 0x221D, 0x441B, 0x5027, 0x05C3, 0x03A5, 0x3407, 0x212D, 0x414B, 0x5207,
+ 0x1C13, 0x0939, 0x11C3, 0x0399, 0x4613, 0x4163, 0x0959, 0x1A15, 0x2165, 0x2615, 0x0599, 0x11A5,
+ 0xF3AC, 0xF5CA, 0xCFB8, 0xDDE2, 0xBBE4, 0xAFD8, 0xFA3C, 0xFC5A, 0xCBF8, 0xDED2, 0xBEB4, 0xADF8,
+ 0xE3EC, 0xF6C6, 0xEE3C, 0xFC66, 0xB9EC, 0xBE9C, 0xF6A6, 0xE5EA, 0xDE9A, 0xD9EA, 0xFA66, 0xEE5A,
+ 0x0CA3, 0x0AC5, 0x308B, 0x22D1, 0x44B1, 0x508D, 0x0AC3, 0x0CA5, 0x380B, 0x2D21, 0x4B41, 0x580D,
+ 0x2C23, 0x3909, 0x22C3, 0x3099, 0x6431, 0x6341, 0x5909, 0x4A45, 0x6521, 0x6251, 0x5099, 0x44A5,
+ 0xF35C, 0xF53A, 0xCF74, 0xDD2E, 0xBB4E, 0xAF72, 0xF53C, 0xF35A, 0xC7F4, 0xD2DE, 0xB4BE, 0xA7F2,
+ 0xD3DC, 0xC6F6, 0xDD3C, 0xCF66, 0x9BCE, 0x9CBE, 0xA6F6, 0xB5BA, 0x9ADE, 0x9DAE, 0xAF66, 0xBB5A,
+ 0x035C, 0x053A, 0x0374, 0x112E, 0x114E, 0x0572, 0x053C, 0x035A, 0x0734, 0x121E, 0x141E, 0x0752,
+ 0x131C, 0x0636, 0x113C, 0x0366, 0x1346, 0x1436, 0x0656, 0x151A, 0x1256, 0x1526, 0x0566, 0x115A,
+ 0xFCA3, 0xFAC5, 0xFC8B, 0xEED1, 0xEEB1, 0xFA8D, 0xFAC3, 0xFCA5, 0xF8CB, 0xEDE1, 0xEBE1, 0xF8AD,
+ 0xECE3, 0xF9C9, 0xEEC3, 0xFC99, 0xECB9, 0xEBC9, 0xF9A9, 0xEAE5, 0xEDA9, 0xEAD9, 0xFA99, 0xEEA5,
+ 0x03AC, 0x05CA, 0x03B8, 0x11E2, 0x11E4, 0x05D8, 0x0A3C, 0x0C5A, 0x0B38, 0x1E12, 0x1E14, 0x0D58,
+ 0x232C, 0x3606, 0x223C, 0x3066, 0x3164, 0x3614, 0x5606, 0x454A, 0x5612, 0x5162, 0x5066, 0x445A,
+ 0xFC53, 0xFA35, 0xFC47, 0xEE1D, 0xEE1B, 0xFA27, 0xF5C3, 0xF3A5, 0xF4C7, 0xE1ED, 0xE1EB, 0xF2A7,
+ 0xDCD3, 0xC9F9, 0xDDC3, 0xCF99, 0xCE9B, 0xC9EB, 0xA9F9, 0xBAB5, 0xA9ED, 0xAE9D, 0xAF99, 0xBBA5
+};
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+
+/**Function*************************************************************
+
+ Synopsis [Computes NPN-canonical form using brute-force methods.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned Extra_TruthCanonNPN2( unsigned uTruth, int nVars, Vec_Int_t * vRes )
+{
+ static int nVarsOld, nPerms;
+ static char ** pPerms = NULL;
+
+ unsigned uTruthMin, uTruthC, uPhase, uPerm;
+ int nMints, k, i;
+
+ if ( pPerms == NULL )
+ {
+ nPerms = Extra_Factorial( nVars );
+ pPerms = Extra_Permutations( nVars );
+ nVarsOld = nVars;
+ }
+ else if ( nVarsOld != nVars )
+ {
+ ABC_FREE( pPerms );
+ nPerms = Extra_Factorial( nVars );
+ pPerms = Extra_Permutations( nVars );
+ nVarsOld = nVars;
+ }
+
+ nMints = (1 << nVars);
+ uTruthC = (unsigned)( (~uTruth) & ((~((unsigned)0)) >> (32-nMints)) );
+ uTruthMin = 0xFFFFFFFF;
+ for ( i = 0; i < nMints; i++ )
+ {
+ uPhase = Extra_TruthPolarize( uTruth, i, nVars );
+ for ( k = 0; k < nPerms; k++ )
+ {
+ uPerm = Extra_TruthPermute( uPhase, pPerms[k], nVars, 0 );
+ Vec_IntPushUnique( vRes, uPerm );
+ if ( uTruthMin > uPerm )
+ uTruthMin = uPerm;
+ }
+ uPhase = Extra_TruthPolarize( uTruthC, i, nVars );
+ for ( k = 0; k < nPerms; k++ )
+ {
+ uPerm = Extra_TruthPermute( uPhase, pPerms[k], nVars, 0 );
+ Vec_IntPushUnique( vRes, uPerm );
+ if ( uTruthMin > uPerm )
+ uTruthMin = uPerm;
+ }
+ }
+ return uTruthMin;
+}
+
+void Acec_MultFuncTest5()
+{
+ Vec_Int_t * vRes = Vec_IntAlloc( 1000 );
+ int i, Entry;
+
+ unsigned Truth = 0xF335ACC0;
+ unsigned Canon = Extra_TruthCanonNPN2( Truth, 5, vRes );
+
+ Extra_PrintHex( stdout, (unsigned*)&Truth, 5 ); printf( "\n" );
+ Extra_PrintHex( stdout, (unsigned*)&Canon, 5 ); printf( "\n" );
+
+ printf( "Members = %d.\n", Vec_IntSize(vRes) );
+ Vec_IntForEachEntry( vRes, Entry, i )
+ {
+ Extra_PrintHex( stdout, (unsigned*)&Entry, 5 );
+ printf( ", " );
+ if ( i % 8 == 7 )
+ printf( "\n" );
+ }
+
+ Vec_IntFree( vRes );
+}
+
+void Acec_MultFuncTest4()
+{
+ Vec_Int_t * vRes = Vec_IntAlloc( 1000 );
+ int i, Entry;
+
+ unsigned Truth = 0x35C0;
+ //unsigned Truth = 0xD728;
+ unsigned Canon = Extra_TruthCanonNPN2( Truth, 4, vRes );
+
+ Extra_PrintHex( stdout, (unsigned*)&Truth, 4 ); printf( "\n" );
+ Extra_PrintHex( stdout, (unsigned*)&Canon, 4 ); printf( "\n" );
+
+ printf( "Members = %d.\n", Vec_IntSize(vRes) );
+ Vec_IntForEachEntry( vRes, Entry, i )
+ {
+ Extra_PrintHex( stdout, (unsigned*)&Entry, 4 );
+ printf( ", " );
+ if ( i % 12 == 11 )
+ printf( "\n" );
+ }
+
+ Vec_IntFree( vRes );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Acec_MultCollectInputs( Vec_Int_t * vPairs, Vec_Int_t * vRanks, int iObj )
+{
+ Vec_Int_t * vItems = Vec_IntAlloc( 100 );
+ int k, iObj1, iObj2;
+ // collect all those appearing with this one
+ Vec_IntForEachEntryDouble( vPairs, iObj1, iObj2, k )
+ if ( iObj == iObj1 )
+ Vec_IntPushUnique( vItems, iObj2 );
+ else if ( iObj == iObj2 )
+ Vec_IntPushUnique( vItems, iObj1 );
+ // sort items by rank cost
+ Vec_IntSelectSortCost( Vec_IntArray(vItems), Vec_IntSize(vItems), vRanks );
+ return vItems;
+}
+Vec_Int_t * Acec_MultDetectInputs1( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits )
+{
+ Vec_Int_t * vInputs = Vec_IntAlloc( 100 );
+ Vec_Int_t * vCounts = Vec_IntStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vRanks = Vec_IntStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vPairs = Vec_IntAlloc( 100 );
+ Vec_Int_t * vItems = Vec_IntAlloc( 100 );
+ Vec_Int_t * vItems0;
+ Vec_Int_t * vItems1;
+ Vec_Int_t * vLevel;
+ int i, k, iLit, iObj, Count;
+ // count how many times each input appears
+ Vec_WecForEachLevel( vLeafLits, vLevel, i )
+ Vec_IntForEachEntry( vLevel, iLit, k )
+ {
+ iObj = Abc_Lit2Var(iLit);
+ Vec_IntAddToEntry( vCounts, Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj), 1 );
+ Vec_IntAddToEntry( vCounts, Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj), 1 );
+/*
+ printf( "Rank %2d : Leaf = %4d : (%2d, %2d)\n", i, iObj,
+ Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj), Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj) );
+ if ( k == Vec_IntSize(vLevel) - 1 )
+ printf( "\n" );
+*/
+ }
+ // count ranks for each one
+ Vec_WecForEachLevel( vLeafLits, vLevel, i )
+ Vec_IntForEachEntry( vLevel, iLit, k )
+ {
+ iObj = Abc_Lit2Var(iLit);
+ if ( Vec_IntEntry(vCounts, Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj)) < 2 )
+ {
+ printf( "Skipping %d.\n", iObj );
+ continue;
+ }
+ if ( Vec_IntEntry(vCounts, Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj)) < 2 )
+ {
+ printf( "Skipping %d.\n", iObj );
+ continue;
+ }
+ Vec_IntAddToEntry( vRanks, Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj), i );
+ Vec_IntAddToEntry( vRanks, Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj), i );
+
+ Vec_IntPushTwo( vPairs, Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj), Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj) );
+ }
+
+ // print statistics
+ Vec_IntForEachEntry( vCounts, Count, i )
+ {
+ if ( !Count )
+ continue;
+ if ( !Vec_IntEntry(vRanks, i) )
+ continue;
+ Vec_IntPush( vItems, i );
+ printf( "Obj = %3d Occurs = %3d Ranks = %3d\n", i, Count, Vec_IntEntry(vRanks, i) );
+ }
+ // sort items by rank cost
+ Vec_IntSelectSortCost( Vec_IntArray(vItems), Vec_IntSize(vItems), vRanks );
+ // collect all those appearing with the last one
+ vItems0 = Acec_MultCollectInputs( vPairs, vRanks, Vec_IntEntryLast(vItems) );
+ Vec_IntAppend( vInputs, vItems0 );
+ // collect all those appearing with the last one
+ vItems1 = Acec_MultCollectInputs( vPairs, vRanks, Vec_IntEntryLast(vItems0) );
+ Vec_IntAppend( vInputs, vItems1 );
+
+ Vec_IntPrint( vItems0 );
+ Vec_IntPrint( vItems1 );
+
+ Vec_IntFree( vCounts );
+ Vec_IntFree( vRanks );
+ Vec_IntFree( vPairs );
+ Vec_IntFree( vItems );
+ Vec_IntFree( vItems0 );
+ Vec_IntFree( vItems1 );
+ return vInputs;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits )
+{
+ Vec_Int_t * vInputs = Vec_IntAlloc( 100 );
+ Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
+ Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vRanks = Vec_IntStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vCounts = Vec_IntStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vLevel;
+ int i, k, iLit, iObj, j, Entry;
+
+ ABC_FREE( p->pRefs );
+ Gia_ManCreateRefs( p );
+ Gia_ManForEachCiId( p, iObj, i )
+ printf( "%d=%d ", iObj, Gia_ObjRefNumId(p, iObj) );
+ printf( "\n" );
+ Gia_ManForEachAndId( p, iObj )
+ if ( Gia_ObjRefNumId(p, iObj) >= 4 )
+ printf( "%d=%d ", iObj, Gia_ObjRefNumId(p, iObj) );
+ printf( "\n" );
+
+ Vec_WecForEachLevel( vLeafLits, vLevel, i )
+ Vec_IntForEachEntry( vLevel, iLit, k )
+ {
+ word Truth = Gia_ObjComputeTruth6Cis( p, iLit, vSupp, vTemp );
+ if ( Vec_IntSize(vSupp) >= 0 )
+ {
+ printf( "Leaf = %4d : ", Abc_Lit2Var(iLit) );
+ printf( "Rank = %2d ", i );
+ printf( "Supp = %2d ", Vec_IntSize(vSupp) );
+ Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) );
+ if ( Vec_IntSize(vSupp) == 4 ) printf( " " );
+ if ( Vec_IntSize(vSupp) == 3 ) printf( " " );
+ if ( Vec_IntSize(vSupp) <= 2 ) printf( " " );
+ printf( " " );
+ Vec_IntPrint( vSupp );
+ /*
+ if ( Truth == 0xF335ACC0F335ACC0 )
+ {
+ int iObj = Abc_Lit2Var(iLit);
+ Gia_Man_t * pGia0 = Gia_ManDupAndCones( p, &iObj, 1, 1 );
+ Gia_ManShow( pGia0, NULL, 0, 0, 0 );
+ Gia_ManStop( pGia0 );
+ }
+ */
+ }
+ // support rank counts
+ Vec_IntForEachEntry( vSupp, Entry, j )
+ {
+ Vec_IntAddToEntry( vRanks, Entry, i );
+ Vec_IntAddToEntry( vCounts, Entry, 1 );
+ }
+ if ( k == Vec_IntSize(vLevel)-1 )
+ printf( "\n" );
+ }
+
+ Vec_IntForEachEntry( vCounts, Entry, j )
+ if ( Entry )
+ printf( "%d=%d(%.2f) ", j, Entry, 1.0*Vec_IntEntry(vRanks, j)/Entry );
+ printf( "\n" );
+
+ Vec_IntFree( vSupp );
+ Vec_WrdFree( vTemp );
+ Vec_IntFree( vRanks );
+ Vec_IntFree( vCounts );
+ return vInputs;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Mark nodes whose function is exactly that of a Booth PP.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Bit_t * Acec_MultMarkPPs( Gia_Man_t * p )
+{
+ word Saved[32] = {
+ ABC_CONST(0xF335ACC0F335ACC0),
+ ABC_CONST(0x35C035C035C035C0),
+ ABC_CONST(0xD728D728D728D728),
+ ABC_CONST(0xFD80FD80FD80FD80),
+ ABC_CONST(0xACC0ACC0ACC0ACC0),
+ ABC_CONST(0x7878787878787878),
+ ABC_CONST(0x2828282828282828),
+ ABC_CONST(0xD0D0D0D0D0D0D0D0),
+ ABC_CONST(0x8080808080808080),
+ ABC_CONST(0x8888888888888888),
+ ABC_CONST(0xAAAAAAAAAAAAAAAA),
+ ABC_CONST(0x5555555555555555),
+
+ ABC_CONST(0xD5A8D5A8D5A8D5A8),
+ ABC_CONST(0x2A572A572A572A57),
+ ABC_CONST(0xF3C0F3C0F3C0F3C0),
+ ABC_CONST(0x5858585858585858),
+ ABC_CONST(0xA7A7A7A7A7A7A7A7),
+ ABC_CONST(0x2727272727272727),
+ ABC_CONST(0xD8D8D8D8D8D8D8D8)
+ };
+
+ Vec_Bit_t * vRes = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
+ int i, iObj, nProds = 0;
+ Gia_ManCleanMark0(p);
+ Gia_ManForEachAndId( p, iObj )
+ {
+ word Truth = Gia_ObjComputeTruth6Cis( p, Abc_Var2Lit(iObj, 0), vSupp, vTemp );
+ if ( Vec_IntSize(vSupp) > 6 )
+ continue;
+ vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize );
+ if ( Vec_IntSize(vSupp) > 5 )
+ continue;
+ for ( i = 0; i < 32 && Saved[i]; i++ )
+ {
+ if ( Truth == Saved[i] || Truth == ~Saved[i] )
+ {
+ Vec_BitWriteEntry( vRes, iObj, 1 );
+ nProds++;
+ break;
+ }
+ }
+ }
+ Gia_ManCleanMark0(p);
+ printf( "Collected %d pps.\n", nProds );
+ Vec_IntFree( vSupp );
+ Vec_WrdFree( vTemp );
+ return vRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_MultFindPPs_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vBold )
+{
+ Gia_Obj_t * pObj;
+ pObj = Gia_ManObj( p, iObj );
+ if ( pObj->fMark0 )
+ return;
+ pObj->fMark0 = 1;
+ if ( !Gia_ObjIsAnd(pObj) )
+ return;
+ Acec_MultFindPPs_rec( p, Gia_ObjFaninId0(pObj, iObj), vBold );
+ Acec_MultFindPPs_rec( p, Gia_ObjFaninId1(pObj, iObj), vBold );
+ Vec_IntPush( vBold, iObj );
+}
+Vec_Int_t * Acec_MultFindPPs( Gia_Man_t * p )
+{
+ word Saved[32] = {
+ ABC_CONST(0xF335ACC0F335ACC0),
+ ABC_CONST(0x35C035C035C035C0),
+ ABC_CONST(0xD728D728D728D728),
+ ABC_CONST(0xFD80FD80FD80FD80),
+ ABC_CONST(0xACC0ACC0ACC0ACC0),
+ ABC_CONST(0x7878787878787878),
+ ABC_CONST(0x2828282828282828),
+ ABC_CONST(0xD0D0D0D0D0D0D0D0),
+ ABC_CONST(0x8080808080808080),
+ ABC_CONST(0x8888888888888888),
+ ABC_CONST(0xAAAAAAAAAAAAAAAA),
+ ABC_CONST(0x5555555555555555),
+
+ ABC_CONST(0xD5A8D5A8D5A8D5A8),
+ ABC_CONST(0x2A572A572A572A57),
+ ABC_CONST(0xF3C0F3C0F3C0F3C0),
+ ABC_CONST(0x5858585858585858),
+ ABC_CONST(0xA7A7A7A7A7A7A7A7),
+ ABC_CONST(0x2727272727272727),
+ ABC_CONST(0xD8D8D8D8D8D8D8D8)
+ };
+
+ Vec_Int_t * vBold = Vec_IntAlloc( 100 );
+ Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
+ Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) );
+ int i, iObj, nProds = 0;
+ Gia_ManCleanMark0(p);
+ Gia_ManForEachAndId( p, iObj )
+ {
+ word Truth = Gia_ObjComputeTruth6Cis( p, Abc_Var2Lit(iObj, 0), vSupp, vTemp );
+ if ( Vec_IntSize(vSupp) > 6 )
+ continue;
+ vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize );
+ if ( Vec_IntSize(vSupp) > 5 )
+ continue;
+ for ( i = 0; i < 32 && Saved[i]; i++ )
+ {
+ if ( Truth == Saved[i] || Truth == ~Saved[i] )
+ {
+ //printf( "*** Node %d is PP with support %d.\n", iObj, Vec_IntSize(vSupp) );
+ Acec_MultFindPPs_rec( p, iObj, vBold );
+ nProds++;
+ break;
+ }
+ }
+ /*
+ if ( Saved[i] )
+ {
+ printf( "Obj = %4d ", iObj );
+ Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) );
+ if ( Vec_IntSize(vSupp) == 4 ) printf( " " );
+ if ( Vec_IntSize(vSupp) == 3 ) printf( " " );
+ if ( Vec_IntSize(vSupp) <= 2 ) printf( " " );
+ printf( " " );
+ Vec_IntPrint( vSupp );
+ }
+ */
+ }
+ Gia_ManCleanMark0(p);
+ printf( "Collected %d pps and %d nodes.\n", nProds, Vec_IntSize(vBold) );
+
+ Vec_IntFree( vSupp );
+ Vec_WrdFree( vTemp );
+ return vBold;
+}
+Vec_Bit_t * Acec_BoothFindPPG( Gia_Man_t * p )
+{
+ Vec_Bit_t * vIgnore = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vMap = Acec_MultFindPPs( p );
+ int i, Entry;
+ Vec_IntForEachEntry( vMap, Entry, i )
+ Vec_BitWriteEntry( vIgnore, Entry, 1 );
+ Vec_IntFree( vMap );
+ return vIgnore;
+}
+void Acec_MultFindPPsTest( Gia_Man_t * p )
+{
+ Vec_Int_t * vBold = Acec_MultFindPPs( p );
+ Gia_ManShow( p, vBold, 1, 0, 0 );
+ Vec_IntFree( vBold );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/acec/acecNorm.c b/src/proof/acec/acecNorm.c
new file mode 100644
index 00000000..f2acb37b
--- /dev/null
+++ b/src/proof/acec/acecNorm.c
@@ -0,0 +1,226 @@
+/**CFile****************************************************************
+
+ FileName [acecNorm.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [CEC for arithmetic circuits.]
+
+ Synopsis [Adder tree normalization.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: acecNorm.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "acecInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_InsertHadd( Gia_Man_t * pNew, int In[2], int Out[2] )
+{
+ int And, Or;
+ Out[1] = Gia_ManAppendAnd2( pNew, In[0], In[1] );
+ And = Gia_ManAppendAnd2( pNew, Abc_LitNot(In[0]), Abc_LitNot(In[1]) );
+ Or = Gia_ManAppendOr2( pNew, Out[1], And );
+ Out[0] = Abc_LitNot( Or );
+}
+void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] )
+{
+ int In2[2], Out1[2], Out2[2];
+ Acec_InsertHadd( pNew, In, Out1 );
+ In2[0] = Out1[0];
+ In2[1] = In[2];
+ Acec_InsertHadd( pNew, In2, Out2 );
+ Out[0] = Out2[0];
+ Out[1] = Gia_ManAppendOr2( pNew, Out1[1], Out2[1] );
+}
+Vec_Int_t * Acec_InsertTree( Gia_Man_t * pNew, Vec_Wec_t * vLeafMap )
+{
+ Vec_Int_t * vRootRanks = Vec_IntAlloc( Vec_WecSize(vLeafMap) + 5 );
+ Vec_Int_t * vLevel;
+ int i, In[3], Out[2];
+ Vec_WecForEachLevel( vLeafMap, vLevel, i )
+ {
+ if ( Vec_IntSize(vLevel) == 0 )
+ {
+ Vec_IntPush( vRootRanks, 0 );
+ continue;
+ }
+ while ( Vec_IntSize(vLevel) > 1 )
+ {
+ if ( Vec_IntSize(vLevel) == 2 )
+ Vec_IntPush( vLevel, 0 );
+ //In[2] = Vec_IntPop( vLevel );
+ //In[1] = Vec_IntPop( vLevel );
+ //In[0] = Vec_IntPop( vLevel );
+
+ In[0] = Vec_IntEntry( vLevel, 0 );
+ Vec_IntDrop( vLevel, 0 );
+
+ In[1] = Vec_IntEntry( vLevel, 0 );
+ Vec_IntDrop( vLevel, 0 );
+
+ In[2] = Vec_IntEntry( vLevel, 0 );
+ Vec_IntDrop( vLevel, 0 );
+
+ Acec_InsertFadd( pNew, In, Out );
+ Vec_IntPush( vLevel, Out[0] );
+ if ( i+1 < Vec_WecSize(vLeafMap) )
+ vLevel = Vec_WecEntry(vLeafMap, i+1);
+ else
+ vLevel = Vec_WecPushLevel(vLeafMap);
+ Vec_IntPush( vLevel, Out[1] );
+ vLevel = Vec_WecEntry(vLeafMap, i);
+ }
+ assert( Vec_IntSize(vLevel) == 1 );
+ Vec_IntPush( vRootRanks, Vec_IntEntry(vLevel, 0) );
+ }
+ return vRootRanks;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Acec_InsertBox_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( ~pObj->Value )
+ return pObj->Value;
+ assert( Gia_ObjIsAnd(pObj) );
+ Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Acec_InsertBox_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ return (pObj->Value = Gia_ManAppendAnd2( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ));
+}
+Vec_Int_t * Acec_BuildTree( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Int_t * vRootLits )
+{
+ Vec_Wec_t * vLeafMap = Vec_WecStart( Vec_WecSize(vLeafLits) );
+ Vec_Int_t * vLevel, * vRootRanks;
+ int i, k, iLit, iLitNew;
+ // add roo literals
+ if ( vRootLits )
+ Vec_IntForEachEntry( vRootLits, iLit, i )
+ {
+ if ( i < Vec_WecSize(vLeafMap) )
+ vLevel = Vec_WecEntry(vLeafMap, i);
+ else
+ vLevel = Vec_WecPushLevel(vLeafMap);
+ Vec_IntPush( vLevel, iLit );
+ }
+ // add other literals
+ Vec_WecForEachLevel( vLeafLits, vLevel, i )
+ Vec_IntForEachEntry( vLevel, iLit, k )
+ {
+ Gia_Obj_t * pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) );
+ iLitNew = Acec_InsertBox_rec( pNew, p, pObj );
+ iLitNew = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) );
+ Vec_WecPush( vLeafMap, i, iLitNew );
+ }
+ // construct map of root literals
+ vRootRanks = Acec_InsertTree( pNew, vLeafMap );
+ Vec_WecFree( vLeafMap );
+ return vRootRanks;
+}
+Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll )
+{
+ Gia_Man_t * p = pBox->pGia;
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj;
+ Vec_Int_t * vRootRanks, * vLevel, * vTemp;
+ int i, k, iLit, iLitNew;
+ 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 );
+ // implement tree
+ if ( fAll )
+ vRootRanks = Acec_BuildTree( pNew, p, pBox->vLeafLits, NULL );
+ else
+ {
+ assert( pBox->vShared != NULL );
+ assert( pBox->vUnique != NULL );
+ vRootRanks = Acec_BuildTree( pNew, p, pBox->vShared, NULL );
+ vRootRanks = Acec_BuildTree( pNew, p, pBox->vUnique, vTemp = vRootRanks );
+ Vec_IntFree( vTemp );
+ }
+ // update polarity of literals
+ Vec_WecForEachLevel( pBox->vRootLits, vLevel, i )
+ Vec_IntForEachEntry( vLevel, iLit, k )
+ {
+ pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) );
+ iLitNew = k ? 0 : Vec_IntEntry( vRootRanks, i );
+ pObj->Value = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) );
+ }
+ Vec_IntFree( vRootRanks );
+ // construct the outputs
+ Gia_ManForEachCo( p, pObj, i )
+ Acec_InsertBox_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) );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fBooth, int fVerbose )
+{
+ Vec_Bit_t * vIgnore = fBooth ? Acec_BoothFindPPG( pGia ) : NULL;
+ Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, 0, 0, fVerbose );
+ Gia_Man_t * pNew = Acec_InsertBox( pBox, 1 );
+ Acec_BoxFreeP( &pBox );
+ Vec_BitFreeP( &vIgnore );
+ return pNew;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/acec/acecPa.c b/src/proof/acec/acecPa.c
index ecaf2047..6b382d91 100644
--- a/src/proof/acec/acecPa.c
+++ b/src/proof/acec/acecPa.c
@@ -248,11 +248,6 @@ int Pas_ManComputeCuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vOrder, Ve
***********************************************************************/
void Pas_ManComputeCutsTest( Gia_Man_t * p )
{
- extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose );
- extern Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vAddCos, Vec_Int_t ** pvIns, Vec_Int_t ** pvOuts );
-
- extern int Ree_ManCountFadds( Vec_Int_t * vAdds );
- extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose );
abctime clk = Abc_Clock();
Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 );
Vec_Int_t * vIns, * vOuts;
diff --git a/src/proof/acec/acecPool.c b/src/proof/acec/acecPool.c
index 08ee37f2..0868545e 100644
--- a/src/proof/acec/acecPool.c
+++ b/src/proof/acec/acecPool.c
@@ -303,17 +303,9 @@ void Acec_ManPrintRanks( Vec_Int_t * vPairs )
***********************************************************************/
void Acec_ManProfile( Gia_Man_t * p, int fVerbose )
{
- extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose );
- extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds );
- extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds );
- extern int Ree_ManCountFadds( Vec_Int_t * vAdds );
- extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose );
-
abctime clk = Abc_Clock();
Vec_Wec_t * vBoxes; int i;
Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( p, &vXors, fVerbose );
- Ree_ManRemoveTrivial( p, vAdds );
- Ree_ManRemoveContained( p, vAdds );
//Ree_ManPrintAdders( vAdds, 1 );
printf( "Detected %d full-adders and %d half-adders. Found %d XOR-cuts. ", Ree_ManCountFadds(vAdds), Vec_IntSize(vAdds)/6-Ree_ManCountFadds(vAdds), Vec_IntSize(vXors)/4 );
@@ -396,13 +388,6 @@ Vec_Int_t * Acec_ManPoolTopMost( Gia_Man_t * p, Vec_Int_t * vAdds )
}
void Acec_ManPool( Gia_Man_t * p )
{
- extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose );
- extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vRootBoxes );
-
- extern int Ree_ManCountFadds( Vec_Int_t * vAdds );
- extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose );
- extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds );
- extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds );
Vec_Int_t * vTops, * vTree;
Vec_Wec_t * vTrees;
@@ -413,8 +398,6 @@ void Acec_ManPool( Gia_Man_t * p )
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
clk = Abc_Clock();
- Ree_ManRemoveTrivial( p, vAdds );
- Ree_ManRemoveContained( p, vAdds );
nFadds = Ree_ManCountFadds( vAdds );
printf( "Detected %d FAs and %d HAs. ", nFadds, Vec_IntSize(vAdds)/6-nFadds );
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
diff --git a/src/proof/acec/acecRe.c b/src/proof/acec/acecRe.c
index 26faad00..5e5ca688 100644
--- a/src/proof/acec/acecRe.c
+++ b/src/proof/acec/acecRe.c
@@ -147,6 +147,7 @@ static inline int Ree_ManCutFind( int iObj, int * pCut )
}
static inline int Ree_ManCutNotFind( int iObj1, int iObj2, int * pCut )
{
+ assert( pCut[0] == 3 );
if ( pCut[3] != iObj1 && pCut[3] != iObj2 ) return 0;
if ( pCut[2] != iObj1 && pCut[2] != iObj2 ) return 1;
if ( pCut[1] != iObj1 && pCut[1] != iObj2 ) return 2;
@@ -162,13 +163,19 @@ static inline int Ree_ManCutTruthOne( int * pCut0, int * pCut )
Truth0 = fComp0 ? ~Truth0 : Truth0;
if ( pCut0[0] == 2 )
{
- int Truths[3][8] = {
- { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, // {0,1,-}
- { 0x00, 0x05, 0x0A, 0x0F, 0x50, 0x55, 0x5A, 0x5F }, // {0,-,1}
- { 0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F } // {-,0,1}
- };
- int Truth = Truths[Ree_ManCutNotFind(pCut0[1], pCut0[2], pCut)][Truth0 & 0x7];
- return 0xFF & (fComp0 ? ~Truth : Truth);
+ if ( pCut[0] == 3 )
+ {
+ int Truths[3][8] = {
+ { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, // {0,1,-}
+ { 0x00, 0x05, 0x0A, 0x0F, 0x50, 0x55, 0x5A, 0x5F }, // {0,-,1}
+ { 0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F } // {-,0,1}
+ };
+ int Truth = Truths[Ree_ManCutNotFind(pCut0[1], pCut0[2], pCut)][Truth0 & 0x7];
+ return 0xFF & (fComp0 ? ~Truth : Truth);
+ }
+ assert( pCut[0] == 2 );
+ assert( pCut[1] == pCut0[1] && pCut[2] == pCut0[2] );
+ return pCut0[pCut0[0]+1];
}
if ( pCut0[0] == 1 )
{
@@ -236,10 +243,10 @@ int Ree_ObjComputeTruth( Gia_Man_t * p, int iObj, int * pCut )
SeeAlso []
***********************************************************************/
-void Ree_ManCutPrint( int * pCut, int Count, word Truth )
+void Ree_ManCutPrint( int * pCut, int Count, word Truth, int iObj )
{
int c;
- printf( "%d : ", Count );
+ printf( "%d : %d : ", Count, iObj );
for ( c = 1; c <= pCut[0]; c++ )
printf( "%3d ", pCut[c] );
for ( ; c <= 4; c++ )
@@ -290,7 +297,7 @@ void Ree_ManCutMerge( Gia_Man_t * p, int iObj, int * pList0, int * pList1, Vec_I
Vec_IntPushThree( vData, iObj, Value, TruthC );
}
if ( fVerbose )
- Ree_ManCutPrint( pCut, ++Count, TruthC );
+ Ree_ManCutPrint( pCut, ++Count, TruthC, iObj );
}
if ( !vXors )
return;
@@ -370,7 +377,7 @@ Vec_Int_t * Ree_ManDeriveAdds( Hash_IntMan_t * p, Vec_Int_t * vData, int fVerbos
Vec_IntForEachEntryDouble( vXorOne, iObj, Truth, j )
Vec_IntForEachEntryDouble( vMajOne, iObj2, Truth2, k )
{
- int SignAnd[8] = {0x88, 0x44, 0x22, 0x11, 0xEE, 0xDD, 0xBB, 0x77};
+ int SignAnd[8] = {0x88, 0x44, 0x22, 0x11, 0x77, 0xBB, 0xDD, 0xEE};
int SignMaj[8] = {0xE8, 0xD4, 0xB2, 0x71, 0x8E, 0x4D, 0x2B, 0x17};
int n, SignXor = (Truth == 0x99 || Truth == 0x69) << 3;
for ( n = 0; n < 8; n++ )
@@ -390,8 +397,18 @@ Vec_Int_t * Ree_ManDeriveAdds( Hash_IntMan_t * p, Vec_Int_t * vData, int fVerbos
Vec_WecFree( vMajMap );
return vAdds;
}
+int Ree_ManCompare( int * pCut0, int * pCut1 )
+{
+ if ( pCut0[3] < pCut1[3] ) return -1;
+ if ( pCut0[3] > pCut1[3] ) return 1;
+ if ( pCut0[4] < pCut1[4] ) return -1;
+ if ( pCut0[4] > pCut1[4] ) return 1;
+ return 0;
+}
Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose )
{
+ extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds );
+ extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds );
Gia_Obj_t * pObj;
int * pList0, * pList1, i, nCuts = 0;
Hash_IntMan_t * pHash = Hash_IntManStart( 1000 );
@@ -425,11 +442,15 @@ Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose
Vec_IntFree( vTemp );
Vec_IntFree( vCuts );
vAdds = Ree_ManDeriveAdds( pHash, vData, fVerbose );
+ qsort( Vec_IntArray(vAdds), Vec_IntSize(vAdds)/6, 24, (int (*)(const void *, const void *))Ree_ManCompare );
if ( fVerbose )
printf( "Adders = %d. Total cuts = %d. Hashed cuts = %d. Hashed/Adders = %.2f.\n",
Vec_IntSize(vAdds)/6, Vec_IntSize(vData)/3, Hash_IntManEntryNum(pHash), 6.0*Hash_IntManEntryNum(pHash)/Vec_IntSize(vAdds) );
Vec_IntFree( vData );
Hash_IntManStop( pHash );
+ Ree_ManRemoveTrivial( p, vAdds );
+ Ree_ManRemoveContained( p, vAdds );
+ //Ree_ManPrintAdders( vAdds, 1 );
return vAdds;
}
@@ -503,6 +524,10 @@ void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds )
{
pObjX = Gia_ManObj( p, Vec_IntEntry(vAdds, 6*i+3) );
pObjM = Gia_ManObj( p, Vec_IntEntry(vAdds, 6*i+4) );
+ // rule out if MAJ is a fanout of XOR
+ //if ( pObjX == Gia_ObjFanin0(pObjM) || pObjX == Gia_ObjFanin1(pObjM) )
+ // continue;
+ // rule out if MAJ is a fanin of XOR and has no other fanouts
if ( (pObjM == Gia_ObjFanin0(pObjX) || pObjM == Gia_ObjFanin1(pObjX)) && Gia_ObjRefNum(p, pObjM) == 1 )
continue;
}
diff --git a/src/proof/acec/acecSt.c b/src/proof/acec/acecSt.c
index 63aa8131..d97dadc9 100644
--- a/src/proof/acec/acecSt.c
+++ b/src/proof/acec/acecSt.c
@@ -21,6 +21,8 @@
#include "acecInt.h"
#include "misc/vec/vecWec.h"
#include "misc/extra/extra.h"
+#include "aig/aig/aig.h"
+#include "opt/dar/dar.h"
ABC_NAMESPACE_IMPL_START
diff --git a/src/proof/acec/acecStruct.c b/src/proof/acec/acecStruct.c
new file mode 100644
index 00000000..6702e13b
--- /dev/null
+++ b/src/proof/acec/acecStruct.c
@@ -0,0 +1,271 @@
+/**CFile****************************************************************
+
+ FileName [acecStruct.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [CEC for arithmetic circuits.]
+
+ Synopsis [Core procedures.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: acecStruct.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "acecInt.h"
+#include "misc/vec/vecWec.h"
+#include "misc/extra/extra.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Acec_StructDetectXorRoots( Gia_Man_t * p )
+{
+ Vec_Int_t * vXors = Vec_IntAlloc( 100 );
+ Vec_Bit_t * vXorIns = Vec_BitStart( Gia_ManObjNum(p) );
+ Gia_Obj_t * pFan0, * pFan1, * pObj;
+ int i, k = 0, Entry;
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) )
+ continue;
+ Vec_IntPush( vXors, i );
+ Vec_BitWriteEntry( vXorIns, Gia_ObjId(p, Gia_Regular(pFan0)), 1 );
+ Vec_BitWriteEntry( vXorIns, Gia_ObjId(p, Gia_Regular(pFan1)), 1 );
+ }
+ // collect XORs that not inputs of other XORs
+ Vec_IntForEachEntry( vXors, Entry, i )
+ if ( !Vec_BitEntry(vXorIns, Entry) )
+ Vec_IntWriteEntry( vXors, k++, Entry );
+ Vec_IntShrink( vXors, k );
+ Vec_BitFree( vXorIns );
+ return vXors;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Acec_StructAssignRanks( Gia_Man_t * p, Vec_Int_t * vXorRoots )
+{
+ Vec_Int_t * vDoubles = Vec_IntAlloc( 100 );
+ Gia_Obj_t * pFan0, * pFan1, * pObj;
+ int i, k, Fanins[2], Entry, Rank;
+ // map roots into their ranks
+ Vec_Int_t * vRanks = Vec_IntStartFull( Gia_ManObjNum(p) );
+ Vec_IntForEachEntry( vXorRoots, Entry, i )
+ Vec_IntWriteEntry( vRanks, Entry, i );
+ // map nodes into their ranks
+ Gia_ManForEachAndReverse( p, pObj, i )
+ {
+ if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) )
+ continue;
+ Rank = Vec_IntEntry( vRanks, i );
+ // skip XORs that are not part of any tree
+ if ( Rank == -1 )
+ continue;
+ // iterate through XOR inputs
+ Fanins[0] = Gia_ObjId(p, Gia_Regular(pFan0));
+ Fanins[1] = Gia_ObjId(p, Gia_Regular(pFan1));
+ for ( k = 0; k < 2; k++ )
+ {
+ Entry = Vec_IntEntry( vRanks, Fanins[k] );
+ if ( Entry == Rank ) // the same tree -- allow fanout in this tree
+ continue;
+ if ( Entry == -1 )
+ Vec_IntWriteEntry( vRanks, Fanins[k], Rank );
+ else
+ Vec_IntPush( vDoubles, Fanins[k] );
+ if ( Entry != -1 && Gia_ObjIsAnd(Gia_ManObj(p, Fanins[k])))
+ printf( "Xor node %d belongs to Tree %d and Tree %d.\n", Fanins[k], Entry, Rank );
+ }
+ }
+ // remove duplicated entries
+ Vec_IntForEachEntry( vDoubles, Entry, i )
+ Vec_IntWriteEntry( vRanks, Entry, -1 );
+ Vec_IntFree( vDoubles );
+ return vRanks;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Wec_t * Acec_FindTreeLeaves( Gia_Man_t * p, Vec_Int_t * vXorRoots, Vec_Int_t * vRanks )
+{
+ Vec_Bit_t * vMapXors = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Wec_t * vTreeLeaves = Vec_WecStart( Vec_IntSize(vXorRoots) );
+ Gia_Obj_t * pFan0, * pFan1, * pObj;
+ int i, k, Fanins[2], Rank;
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) )
+ continue;
+ Vec_BitWriteEntry( vMapXors, i, 1 );
+ Rank = Vec_IntEntry( vRanks, i );
+ // skip XORs that are not part of any tree
+ if ( Rank == -1 )
+ continue;
+ // iterate through XOR inputs
+ Fanins[0] = Gia_ObjId(p, Gia_Regular(pFan0));
+ Fanins[1] = Gia_ObjId(p, Gia_Regular(pFan1));
+ for ( k = 0; k < 2; k++ )
+ {
+ if ( Vec_BitEntry(vMapXors, Fanins[k]) )
+ {
+ assert( Rank == Vec_IntEntry(vRanks, Fanins[k]) );
+ continue;
+ }
+ Vec_WecPush( vTreeLeaves, Rank, Fanins[k] );
+ }
+ }
+ Vec_BitFree( vMapXors );
+ return vTreeLeaves;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Acec_FindShadows( Gia_Man_t * p, Vec_Int_t * vRanks )
+{
+ Vec_Int_t * vShadows = Vec_IntDup( vRanks );
+ Gia_Obj_t * pObj; int i, Shad0, Shad1;
+ Gia_ManForEachCi( p, pObj, i )
+ Vec_IntWriteEntry( vShadows, Gia_ObjId(p, pObj), -1 );
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( Vec_IntEntry(vShadows, i) >= 0 )
+ continue;
+ Shad0 = Vec_IntEntry(vShadows, Gia_ObjFaninId0(pObj, i));
+ Shad1 = Vec_IntEntry(vShadows, Gia_ObjFaninId1(pObj, i));
+ if ( Shad0 == Shad1 && Shad0 != -1 )
+ Vec_IntWriteEntry(vShadows, i, Shad0);
+ }
+ return vShadows;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Acec_CollectSupp_rec( Gia_Man_t * p, int iNode, int Rank, Vec_Int_t * vRanks )
+{
+ Gia_Obj_t * pObj;
+ int nSize;
+ if ( Gia_ObjIsTravIdCurrentId(p, iNode) )
+ return 0;
+ Gia_ObjSetTravIdCurrentId(p, iNode);
+ pObj = Gia_ManObj(p, iNode);
+ assert( Gia_ObjIsAnd(pObj) );
+ if ( Vec_IntEntry(vRanks, iNode) == Rank )
+ return 1;
+ nSize = Acec_CollectSupp_rec( p, Gia_ObjFaninId0(pObj, iNode), Rank, vRanks );
+ nSize += Acec_CollectSupp_rec( p, Gia_ObjFaninId1(pObj, iNode), Rank, vRanks );
+ return nSize;
+}
+Vec_Wec_t * Acec_FindNexts( Gia_Man_t * p, Vec_Int_t * vRanks, Vec_Int_t * vShadows, Vec_Wec_t * vTreeLeaves )
+{
+ Vec_Wec_t * vNexts = Vec_WecStart( Vec_WecSize(vTreeLeaves) );
+ Vec_Int_t * vTree;
+ int i, k, Node, Fanins[2], Shad0, Shad1, Rank, nSupp;
+ Vec_WecForEachLevel( vTreeLeaves, vTree, i )
+ Vec_IntForEachEntry( vTree, Node, k )
+ {
+ Gia_Obj_t * pObj = Gia_ManObj(p, Node);
+ if ( !Gia_ObjIsAnd(pObj) )
+ continue;
+ Fanins[0] = Gia_ObjFaninId0(pObj, Node);
+ Fanins[1] = Gia_ObjFaninId1(pObj, Node);
+ Shad0 = Vec_IntEntry(vShadows, Fanins[0]);
+ Shad1 = Vec_IntEntry(vShadows, Fanins[1]);
+ if ( Shad0 != Shad1 || Shad0 == -1 )
+ continue;
+ // check support size of Node in terms of the shadow of its fanins
+ Rank = Vec_IntEntry( vRanks, Node );
+ assert( Rank != Shad0 );
+ Gia_ManIncrementTravId( p );
+ nSupp = Acec_CollectSupp_rec( p, Node, Shad0, vRanks );
+ assert( nSupp > 1 );
+ if ( nSupp > 3 )
+ continue;
+ Vec_IntPushUniqueOrder( Vec_WecEntry(vNexts, Shad0), Rank );
+ }
+ return vNexts;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_StructTest( Gia_Man_t * p )
+{
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c
new file mode 100644
index 00000000..ab17d7b9
--- /dev/null
+++ b/src/proof/acec/acecTree.c
@@ -0,0 +1,783 @@
+/**CFile****************************************************************
+
+ FileName [acecTree.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [CEC for arithmetic circuits.]
+
+ Synopsis [Adder tree construction.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: acecTree.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "acecInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_BoxFree( Acec_Box_t * pBox )
+{
+ Vec_WecFreeP( &pBox->vAdds );
+ Vec_WecFreeP( &pBox->vLeafLits );
+ Vec_WecFreeP( &pBox->vRootLits );
+ Vec_WecFreeP( &pBox->vUnique );
+ Vec_WecFreeP( &pBox->vShared );
+ ABC_FREE( pBox );
+}
+void Acec_BoxFreeP( Acec_Box_t ** ppBox )
+{
+ if ( *ppBox )
+ Acec_BoxFree( *ppBox );
+ *ppBox = NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_VerifyBoxLeaves( Acec_Box_t * pBox, Vec_Bit_t * vIgnore )
+{
+ Vec_Int_t * vLevel;
+ int i, k, iLit, Count = 0;
+ if ( vIgnore == NULL )
+ return;
+ Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i )
+ Vec_IntForEachEntry( vLevel, iLit, k )
+ if ( Gia_ObjIsAnd(Gia_ManObj(pBox->pGia, Abc_Lit2Var(iLit))) && !Vec_BitEntry(vIgnore, Abc_Lit2Var(iLit)) )
+ printf( "Internal node %d of rank %d is not part of PPG.\n", Abc_Lit2Var(iLit), i ), Count++;
+ printf( "Detected %d suspicious leaves.\n", Count );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Filters trees by removing TFO of roots.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_TreeFilterOne( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree )
+{
+ Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Bit_t * vMarked = Vec_BitStart( Gia_ManObjNum(p) ) ;
+ Gia_Obj_t * pObj;
+ int i, k = 0, Box, Rank;
+ // mark roots
+ Vec_IntForEachEntryDouble( vTree, Box, Rank, i )
+ {
+ Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 );
+ Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 );
+ }
+ Vec_IntForEachEntryDouble( vTree, Box, Rank, i )
+ {
+ Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+0), 0 );
+ Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+1), 0 );
+ Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+2), 0 );
+ }
+ // iterate through nodes to detect TFO of roots
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( Vec_BitEntry(vIsRoot, Gia_ObjFaninId0(pObj,i)) || Vec_BitEntry(vIsRoot, Gia_ObjFaninId1(pObj,i)) ||
+ Vec_BitEntry(vMarked, Gia_ObjFaninId0(pObj,i)) || Vec_BitEntry(vMarked, Gia_ObjFaninId1(pObj,i)) )
+ Vec_BitWriteEntry( vMarked, i, 1 );
+ }
+ // remove those that overlap with roots
+ Vec_IntForEachEntryDouble( vTree, Box, Rank, i )
+ {
+ // special case of the first bit
+// if ( i == 0 )
+// continue;
+
+/*
+ if ( Vec_IntEntry(vAdds, 6*Box+3) == 24 && Vec_IntEntry(vAdds, 6*Box+4) == 22 )
+ {
+ printf( "**** removing special one \n" );
+ continue;
+ }
+ if ( Vec_IntEntry(vAdds, 6*Box+3) == 48 && Vec_IntEntry(vAdds, 6*Box+4) == 49 )
+ {
+ printf( "**** removing special one \n" );
+ continue;
+ }
+*/
+ if ( Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+3)) || Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+4)) )
+ {
+ printf( "Removing box %d=(%d,%d) of rank %d.\n", Box, Vec_IntEntry(vAdds, 6*Box+3), Vec_IntEntry(vAdds, 6*Box+4), Rank );
+ continue;
+ }
+ Vec_IntWriteEntry( vTree, k++, Box );
+ Vec_IntWriteEntry( vTree, k++, Rank );
+ }
+ Vec_IntShrink( vTree, k );
+ Vec_BitFree( vIsRoot );
+ Vec_BitFree( vMarked );
+}
+void Acec_TreeFilterTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vTrees )
+{
+ Vec_Int_t * vLevel;
+ int i;
+ Vec_WecForEachLevel( vTrees, vLevel, i )
+ Acec_TreeFilterOne( p, vAdds, vLevel );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Filters trees by removing TFO of roots.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_TreeMarkTFI_rec( Gia_Man_t * p, int Id, Vec_Bit_t * vMarked )
+{
+ Gia_Obj_t * pObj = Gia_ManObj(p, Id);
+ if ( Vec_BitEntry(vMarked, Id) )
+ return;
+ Vec_BitWriteEntry( vMarked, Id, 1 );
+ if ( !Gia_ObjIsAnd(pObj) )
+ return;
+ Acec_TreeMarkTFI_rec( p, Gia_ObjFaninId0(pObj, Id), vMarked );
+ Acec_TreeMarkTFI_rec( p, Gia_ObjFaninId1(pObj, Id), vMarked );
+}
+void Acec_TreeFilterOne2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree )
+{
+ Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Bit_t * vMarked = Vec_BitStart( Gia_ManObjNum(p) ) ;
+ Gia_Obj_t * pObj;
+ int i, k = 0, Box, Rank;
+ // mark leaves
+ Vec_IntForEachEntryDouble( vTree, Box, Rank, i )
+ {
+ Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 );
+ Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 );
+ Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 );
+ }
+ Vec_IntForEachEntryDouble( vTree, Box, Rank, i )
+ {
+ Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+3), 0 );
+ Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+4), 0 );
+ }
+ // mark TFI of leaves
+ Gia_ManForEachAnd( p, pObj, i )
+ if ( Vec_BitEntry(vIsLeaf, i) )
+ Acec_TreeMarkTFI_rec( p, i, vMarked );
+ // additional one
+//if ( 10942 < Gia_ManObjNum(p) )
+// Acec_TreeMarkTFI_rec( p, 10942, vMarked );
+ // remove those that overlap with the marked TFI
+ Vec_IntForEachEntryDouble( vTree, Box, Rank, i )
+ {
+ if ( Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+3)) || Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+4)) )
+ {
+ printf( "Removing box %d=(%d,%d) of rank %d.\n", Box, Vec_IntEntry(vAdds, 6*Box+3), Vec_IntEntry(vAdds, 6*Box+4), Rank );
+ continue;
+ }
+ Vec_IntWriteEntry( vTree, k++, Box );
+ Vec_IntWriteEntry( vTree, k++, Rank );
+ }
+ Vec_IntShrink( vTree, k );
+ Vec_BitFree( vIsLeaf );
+ Vec_BitFree( vMarked );
+}
+void Acec_TreeFilterTrees2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vTrees )
+{
+ Vec_Int_t * vLevel;
+ int i;
+ Vec_WecForEachLevel( vTrees, vLevel, i )
+ Acec_TreeFilterOne2( p, vAdds, vLevel );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Acec_TreeVerifyPhaseOne_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ int Truth0, Truth1;
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return pObj->Value;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ assert( Gia_ObjIsAnd(pObj) );
+ assert( !Gia_ObjIsXor(pObj) );
+ Truth0 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin0(pObj) );
+ Truth1 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin1(pObj) );
+ Truth0 = Gia_ObjFaninC0(pObj) ? 0xFF & ~Truth0 : Truth0;
+ Truth1 = Gia_ObjFaninC1(pObj) ? 0xFF & ~Truth1 : Truth1;
+ return (pObj->Value = Truth0 & Truth1);
+}
+void Acec_TreeVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox )
+{
+ Gia_Obj_t * pObj;
+ unsigned TruthXor, TruthMaj, Truths[3] = { 0xAA, 0xCC, 0xF0 };
+ int k, iObj, fFadd = Vec_IntEntry(vAdds, 6*iBox+2) > 0;
+ int fFlip = !fFadd && Acec_SignBit2(vAdds, iBox, 2);
+
+ Gia_ManIncrementTravId( p );
+ for ( k = 0; k < 3; k++ )
+ {
+ iObj = Vec_IntEntry( vAdds, 6*iBox+k );
+ if ( iObj == 0 )
+ continue;
+ pObj = Gia_ManObj( p, iObj );
+ pObj->Value = (Acec_SignBit2(vAdds, iBox, k) ^ fFlip) ? 0xFF & ~Truths[k] : Truths[k];
+ Gia_ObjSetTravIdCurrent( p, pObj );
+ }
+
+ iObj = Vec_IntEntry( vAdds, 6*iBox+3 );
+ TruthXor = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) );
+ TruthXor = (Acec_SignBit2(vAdds, iBox, 3) ^ fFlip) ? 0xFF & ~TruthXor : TruthXor;
+
+ iObj = Vec_IntEntry( vAdds, 6*iBox+4 );
+ TruthMaj = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) );
+ TruthMaj = (Acec_SignBit2(vAdds, iBox, 4) ^ fFlip) ? 0xFF & ~TruthMaj : TruthMaj;
+
+ if ( fFadd ) // FADD
+ {
+ if ( TruthXor != 0x96 )
+ printf( "Fadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) );
+ if ( TruthMaj != 0xE8 )
+ printf( "Fadd %d carry %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+4 ) );
+ }
+ else
+ {
+ //printf( "Sign1 = %d%d%d %d\n", Acec_SignBit(vAdds, iBox, 0), Acec_SignBit(vAdds, iBox, 1), Acec_SignBit(vAdds, iBox, 2), Acec_SignBit(vAdds, iBox, 3) );
+ //printf( "Sign2 = %d%d%d %d%d\n", Acec_SignBit2(vAdds, iBox, 0), Acec_SignBit2(vAdds, iBox, 1), Acec_SignBit2(vAdds, iBox, 2), Acec_SignBit2(vAdds, iBox, 3), Acec_SignBit2(vAdds, iBox, 4) );
+ if ( TruthXor != 0x66 )
+ printf( "Hadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) );
+ if ( TruthMaj != 0x88 )
+ printf( "Hadd %d carry %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+4 ) );
+ }
+}
+void Acec_TreeVerifyPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes )
+{
+ Vec_Int_t * vLevel;
+ int i, k, Box;
+ Vec_WecForEachLevel( vBoxes, vLevel, i )
+ Vec_IntForEachEntry( vLevel, Box, k )
+ Acec_TreeVerifyPhaseOne( p, vAdds, Box );
+}
+void Acec_TreeVerifyPhases2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes )
+{
+ Vec_Bit_t * vPhase = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Bit_t * vRoots = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vLevel;
+ int i, k, n, Box;
+ // mark all output points and their values
+ Vec_WecForEachLevel( vBoxes, vLevel, i )
+ Vec_IntForEachEntry( vLevel, Box, k )
+ {
+ Vec_BitWriteEntry( vRoots, Vec_IntEntry( vAdds, 6*Box+3 ), 1 );
+ Vec_BitWriteEntry( vRoots, Vec_IntEntry( vAdds, 6*Box+4 ), 1 );
+ Vec_BitWriteEntry( vPhase, Vec_IntEntry( vAdds, 6*Box+3 ), Acec_SignBit2(vAdds, Box, 3) );
+ Vec_BitWriteEntry( vPhase, Vec_IntEntry( vAdds, 6*Box+4 ), Acec_SignBit2(vAdds, Box, 4) );
+ }
+ // compare with input points
+ Vec_WecForEachLevel( vBoxes, vLevel, i )
+ Vec_IntForEachEntry( vLevel, Box, k )
+ for ( n = 0; n < 3; n++ )
+ {
+ if ( !Vec_BitEntry(vRoots, Vec_IntEntry(vAdds, 6*Box+n)) )
+ continue;
+ if ( Vec_BitEntry(vPhase, Vec_IntEntry(vAdds, 6*Box+n)) == Acec_SignBit2(vAdds, Box, n) )
+ continue;
+ printf( "Phase of input %d=%d is mismatched in box %d=(%d,%d).\n",
+ n, Vec_IntEntry(vAdds, 6*Box+n), Box, Vec_IntEntry(vAdds, 6*Box+3), Vec_IntEntry(vAdds, 6*Box+4) );
+ }
+ Vec_BitFree( vPhase );
+ Vec_BitFree( vRoots );
+}
+void Acec_TreeVerifyConnections( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes )
+{
+ Vec_Int_t * vCounts = Vec_IntStartFull( Gia_ManObjNum(p) );
+ Vec_Int_t * vLevel;
+ int i, k, n, Box;
+ // mark outputs
+ Vec_WecForEachLevel( vBoxes, vLevel, i )
+ Vec_IntForEachEntry( vLevel, Box, k )
+ {
+ Vec_IntWriteEntry( vCounts, Vec_IntEntry( vAdds, 6*Box+3 ), 0 );
+ Vec_IntWriteEntry( vCounts, Vec_IntEntry( vAdds, 6*Box+4 ), 0 );
+ }
+ // count fanouts
+ Vec_WecForEachLevel( vBoxes, vLevel, i )
+ Vec_IntForEachEntry( vLevel, Box, k )
+ for ( n = 0; n < 3; n++ )
+ if ( Vec_IntEntry( vCounts, Vec_IntEntry(vAdds, 6*Box+n) ) != -1 )
+ Vec_IntAddToEntry( vCounts, Vec_IntEntry(vAdds, 6*Box+n), 1 );
+ // print out
+ printf( "The adder tree has %d internal cut points. ", Vec_IntCountLarger(vCounts, -1) );
+ if ( Vec_IntCountLarger(vCounts, 1) == 0 )
+ printf( "There is no internal fanouts.\n" );
+ else
+ {
+ printf( "These %d points have more than one fanout:\n", Vec_IntCountLarger(vCounts, 1) );
+ Vec_IntForEachEntry( vCounts, Box, i )
+ if ( Box > 1 )
+ printf( "Node %d(lev %d) has fanout %d.\n", i, Gia_ObjLevelId(p, i), Box );
+ }
+ Vec_IntFree( vCounts );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates polarity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Acec_TreeCarryMap( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes )
+{
+ Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) );
+ Vec_Int_t * vLevel;
+ int i, k, Box;
+ Vec_WecForEachLevel( vBoxes, vLevel, i )
+ Vec_IntForEachEntry( vLevel, Box, k )
+ Vec_IntWriteEntry( vMap, Vec_IntEntry(vAdds, 6*Box+4), Box );
+ return vMap;
+}
+void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, int Node, int fPhase, Vec_Bit_t * vVisit )
+{
+ int k, iBox, iXor, fXorPhase, fPhaseThis;
+ assert( Node != 0 );
+ iBox = Vec_IntEntry( vMap, Node );
+ if ( iBox == -1 )
+ return;
+ assert( Node == Vec_IntEntry( vAdds, 6*iBox+4 ) );
+ if ( Vec_BitEntry(vVisit, iBox) )
+ return;
+ Vec_BitWriteEntry( vVisit, iBox, 1 );
+ iXor = Vec_IntEntry( vAdds, 6*iBox+3 );
+ fXorPhase = Acec_SignBit(vAdds, iBox, 3);
+ if ( Vec_IntEntry(vAdds, 6*iBox+2) == 0 )
+ {
+ //fPhaseThis = Acec_SignBit( vAdds, iBox, 2 ) ^ fPhase;
+ //fXorPhase ^= fPhaseThis;
+ //Acec_SignSetBit2( vAdds, iBox, 2, fPhaseThis ); // complemented HADD -- create const1 input
+ fPhase ^= Acec_SignBit( vAdds, iBox, 2 );
+ fXorPhase ^= fPhase;
+ Acec_SignSetBit2( vAdds, iBox, 2, fPhase ); // complemented HADD -- create const1 input
+ }
+ for ( k = 0; k < 3; k++ )
+ {
+ int iObj = Vec_IntEntry( vAdds, 6*iBox+k );
+ if ( iObj == 0 )
+ continue;
+ fPhaseThis = Acec_SignBit(vAdds, iBox, k) ^ fPhase;
+ fXorPhase ^= fPhaseThis;
+ Acec_TreePhases_rec( p, vAdds, vMap, iObj, fPhaseThis, vVisit );
+ Acec_SignSetBit2( vAdds, iBox, k, fPhaseThis );
+ }
+ Acec_SignSetBit2( vAdds, iBox, 3, fXorPhase );
+ Acec_SignSetBit2( vAdds, iBox, 4, fPhase );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find internal cut points with exactly one adder fanin/fanout.]
+
+ Description [Returns a map of point into its input/output adder.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_TreeAddInOutPoint( Vec_Int_t * vMap, int iObj, int iAdd, int fOut )
+{
+ int * pPlace = Vec_IntEntryP( vMap, Abc_Var2Lit(iObj, fOut) );
+ if ( *pPlace == -1 )
+ *pPlace = iAdd;
+ else if ( *pPlace >= 0 )
+ *pPlace = -2;
+}
+Vec_Int_t * Acec_TreeFindPoints( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vIgnore )
+{
+ Vec_Int_t * vMap = Vec_IntStartFull( 2*Gia_ManObjNum(p) );
+ int i;
+ for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ )
+ {
+ if ( vIgnore && (Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+3)) || Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+4))) )
+ continue;
+ Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+0), i, 0 );
+ Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+1), i, 0 );
+ Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+2), i, 0 );
+ Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+3), i, 1 );
+ Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+4), i, 1 );
+ }
+ return vMap;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find adder trees as groups of adders connected vis cut-points.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Acec_TreeWhichPoint( Vec_Int_t * vAdds, int iAdd, int iObj )
+{
+ int k;
+ for ( k = 0; k < 5; k++ )
+ if ( Vec_IntEntry(vAdds, 6*iAdd+k) == iObj )
+ return k;
+ assert( 0 );
+ return -1;
+}
+void Acec_TreeFindTrees2_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iAdd, int Rank, Vec_Int_t * vTree, Vec_Bit_t * vFound )
+{
+ extern void Acec_TreeFindTrees_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iObj, int Rank, Vec_Int_t * vTree, Vec_Bit_t * vFound );
+ int k;
+ if ( Vec_BitEntry(vFound, iAdd) )
+ return;
+ Vec_BitWriteEntry( vFound, iAdd, 1 );
+ Vec_IntPush( vTree, iAdd );
+ Vec_IntPush( vTree, Rank );
+ //printf( "Assigning rank %d to (%d:%d).\n", Rank, Vec_IntEntry(vAdds, 6*iAdd+3), Vec_IntEntry(vAdds, 6*iAdd+4) );
+ for ( k = 0; k < 5; k++ )
+ Acec_TreeFindTrees_rec( vAdds, vMap, Vec_IntEntry(vAdds, 6*iAdd+k), k == 4 ? Rank + 1 : Rank, vTree, vFound );
+}
+void Acec_TreeFindTrees_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iObj, int Rank, Vec_Int_t * vTree, Vec_Bit_t * vFound )
+{
+ int In = Vec_IntEntry( vMap, Abc_Var2Lit(iObj, 1) );
+ int Out = Vec_IntEntry( vMap, Abc_Var2Lit(iObj, 0) );
+ if ( In < 0 || Out < 0 )
+ return;
+ Acec_TreeFindTrees2_rec( vAdds, vMap, In, Acec_TreeWhichPoint(vAdds, In, iObj) == 4 ? Rank-1 : Rank, vTree, vFound );
+ Acec_TreeFindTrees2_rec( vAdds, vMap, Out, Rank, vTree, vFound );
+}
+Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vIgnore, int fFilterIn, int fFilterOut )
+{
+ Vec_Wec_t * vTrees = Vec_WecAlloc( 10 );
+ Vec_Int_t * vMap = Acec_TreeFindPoints( p, vAdds, vIgnore );
+ Vec_Bit_t * vFound = Vec_BitStart( Vec_IntSize(vAdds)/6 );
+ Vec_Int_t * vTree;
+ int i, k, In, Out, Box, Rank, MinRank;
+ // go through the cut-points
+ Vec_IntForEachEntryDouble( vMap, In, Out, i )
+ {
+ if ( In < 0 || Out < 0 )
+ continue;
+ assert( Vec_BitEntry(vFound, In) == Vec_BitEntry(vFound, Out) );
+ if ( Vec_BitEntry(vFound, In) )
+ continue;
+ vTree = Vec_WecPushLevel( vTrees );
+ Acec_TreeFindTrees_rec( vAdds, vMap, i/2, 0, vTree, vFound );
+ // normalize rank
+ MinRank = ABC_INFINITY;
+ Vec_IntForEachEntryDouble( vTree, Box, Rank, k )
+ MinRank = Abc_MinInt( MinRank, Rank );
+ Vec_IntForEachEntryDouble( vTree, Box, Rank, k )
+ Vec_IntWriteEntry( vTree, k+1, Rank - MinRank );
+ }
+ Vec_BitFree( vFound );
+ Vec_IntFree( vMap );
+ // filter trees
+ if ( fFilterIn )
+ Acec_TreeFilterTrees2( p, vAdds, vTrees );
+ else if ( fFilterOut )
+ Acec_TreeFilterTrees( p, vAdds, vTrees );
+ // sort by size
+ Vec_WecSort( vTrees, 1 );
+ return vTrees;
+}
+void Acec_TreeFindTreesTest( Gia_Man_t * p )
+{
+ Vec_Wec_t * vTrees;
+
+ abctime clk = Abc_Clock();
+ Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 );
+ int nFadds = Ree_ManCountFadds( vAdds );
+ printf( "Detected %d adders (%d FAs and %d HAs). ", Vec_IntSize(vAdds)/6, nFadds, Vec_IntSize(vAdds)/6-nFadds );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+
+ clk = Abc_Clock();
+ vTrees = Acec_TreeFindTrees( p, vAdds, NULL, 0, 0 );
+ printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ Vec_WecPrint( vTrees, 0 );
+
+ Vec_WecFree( vTrees );
+ Vec_IntFree( vAdds );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Derives one adder tree.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+`
+***********************************************************************/
+void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds )
+{
+ Vec_Int_t * vLevel;
+ int i, k, iBox;
+ Vec_WecForEachLevel( vBoxes, vLevel, i )
+ {
+ printf( " %4d : %2d {", i, Vec_IntSize(vLevel) );
+ Vec_IntForEachEntry( vLevel, iBox, k )
+ {
+ printf( " %s%d=(%d,%d)", Vec_IntEntry(vAdds, 6*iBox+2) == 0 ? "*":"", iBox,
+ Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) );
+ //printf( "(%d,%d,%d)", Vec_IntEntry(vAdds, 6*iBox+0), Vec_IntEntry(vAdds, 6*iBox+1), Vec_IntEntry(vAdds, 6*iBox+2) );
+ }
+ printf( " }\n" );
+ }
+}
+void Acec_TreePrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds )
+{
+ printf( "Adders:\n" );
+ Acec_PrintAdders( pBox->vAdds, vAdds );
+ printf( "Inputs:\n" );
+ Vec_WecPrintLits( pBox->vLeafLits );
+ printf( "Outputs:\n" );
+ Vec_WecPrintLits( pBox->vRootLits );
+// printf( "Node %d has level %d.\n", 3715, Gia_ObjLevelId(pBox->pGia, 3715) );
+// printf( "Node %d has level %d.\n", 167, Gia_ObjLevelId(pBox->pGia, 167) );
+// printf( "Node %d has level %d.\n", 278, Gia_ObjLevelId(pBox->pGia, 278) );
+// printf( "Node %d has level %d.\n", 597, Gia_ObjLevelId(pBox->pGia, 597) );
+}
+
+int Acec_CreateBoxMaxRank( Vec_Int_t * vTree )
+{
+ int k, Box, Rank, MaxRank = 0;
+ Vec_IntForEachEntryDouble( vTree, Box, Rank, k )
+ MaxRank = Abc_MaxInt( MaxRank, Rank );
+ return MaxRank;
+}
+Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree )
+{
+ int MaxRank = Acec_CreateBoxMaxRank(vTree);
+ Vec_Bit_t * vVisit = Vec_BitStart( Vec_IntSize(vAdds)/6 );
+ Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vLevel, * vMap;
+ int i, j, k, Box, Rank;//, Count = 0;
+
+ Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 );
+ pBox->pGia = p;
+ pBox->vAdds = Vec_WecStart( MaxRank + 1 );
+ pBox->vLeafLits = Vec_WecStart( MaxRank + 1 );
+ pBox->vRootLits = Vec_WecStart( MaxRank + 2 );
+
+ // collect boxes; mark inputs/outputs
+ Vec_IntForEachEntryDouble( vTree, Box, Rank, i )
+ {
+// if ( 37 == Box && 6 == Rank )
+// {
+// printf( "Skipping one adder...\n" );
+// continue;
+// }
+ Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 );
+ Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 );
+ Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 );
+ Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 );
+ Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 );
+ Vec_WecPush( pBox->vAdds, Rank, Box );
+ }
+ // sort each level
+ Vec_WecForEachLevel( pBox->vAdds, vLevel, i )
+ Vec_IntSort( vLevel, 0 );
+
+ // set phases starting from roots
+ vMap = Acec_TreeCarryMap( p, vAdds, pBox->vAdds );
+ Vec_WecForEachLevelReverse( pBox->vAdds, vLevel, i )
+ Vec_IntForEachEntry( vLevel, Box, k )
+ if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+4) ) )
+ {
+ //printf( "Pushing phase of output %d of box %d\n", Vec_IntEntry(vAdds, 6*Box+4), Box );
+ Acec_TreePhases_rec( p, vAdds, vMap, Vec_IntEntry(vAdds, 6*Box+4), Vec_IntEntry(vAdds, 6*Box+2) != 0, vVisit );
+ }
+ Acec_TreeVerifyPhases( p, vAdds, pBox->vAdds );
+ Acec_TreeVerifyPhases2( p, vAdds, pBox->vAdds );
+ Vec_BitFree( vVisit );
+ Vec_IntFree( vMap );
+
+ // collect inputs/outputs
+ Vec_BitWriteEntry( vIsRoot, 0, 1 );
+ Vec_WecForEachLevel( pBox->vAdds, vLevel, i )
+ Vec_IntForEachEntry( vLevel, Box, j )
+ {
+ for ( k = 0; k < 3; k++ )
+ if ( !Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) )
+ Vec_WecPush( pBox->vLeafLits, i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) );
+ for ( k = 3; k < 5; k++ )
+ if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) )
+ {
+ //if ( Vec_IntEntry(vAdds, 6*Box+k) == 10942 )
+ //{
+ // printf( "++++++++++++ Skipping special\n" );
+ // continue;
+ //}
+ Vec_WecPush( pBox->vRootLits, k == 4 ? i + 1 : i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) );
+ }
+ if ( Vec_IntEntry(vAdds, 6*Box+2) == 0 && Acec_SignBit2(vAdds, Box, 2) )
+ Vec_WecPush( pBox->vLeafLits, i, 1 );
+ }
+ Vec_BitFree( vIsLeaf );
+ Vec_BitFree( vIsRoot );
+ // sort each level
+ Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i )
+ Vec_IntSort( vLevel, 0 );
+ Vec_WecForEachLevel( pBox->vRootLits, vLevel, i )
+ Vec_IntSort( vLevel, 1 );
+ //return pBox;
+/*
+ // push literals forward
+ //Vec_WecPrint( pBox->vLeafLits, 0 );
+ Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i )
+ {
+ int This, Prev = Vec_IntEntry(vLevel, 0);
+ Vec_IntForEachEntryStart( vLevel, This, j, 1 )
+ {
+ if ( Prev != This )
+ {
+ Prev = This;
+ continue;
+ }
+ if ( i+1 >= Vec_WecSize(pBox->vLeafLits) )
+ continue;
+ Vec_IntPushOrder( Vec_WecEntry(pBox->vLeafLits, i+1), This );
+ Vec_IntDrop( vLevel, j-- );
+ Vec_IntDrop( vLevel, j-- );
+ Prev = -1;
+ Count++;
+ }
+ }
+ printf( "Pushed forward %d input literals.\n", Count );
+*/
+ //Vec_WecPrint( pBox->vLeafLits, 0 );
+ return pBox;
+}
+void Acec_CreateBoxTest( Gia_Man_t * p )
+{
+ Acec_Box_t * pBox;
+ Vec_Wec_t * vTrees;
+ Vec_Int_t * vTree;
+
+ abctime clk = Abc_Clock();
+ Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 );
+ int i, nFadds = Ree_ManCountFadds( vAdds );
+ printf( "Detected %d adders (%d FAs and %d HAs). ", Vec_IntSize(vAdds)/6, nFadds, Vec_IntSize(vAdds)/6-nFadds );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+
+ clk = Abc_Clock();
+ vTrees = Acec_TreeFindTrees( p, vAdds, NULL, 0, 0 );
+ printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ //Vec_WecPrint( vTrees, 0 );
+
+ Vec_WecForEachLevel( vTrees, vTree, i )
+ {
+ pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, i) );
+ printf( "Processing tree %d: Ranks = %d. Adders = %d. Leaves = %d. Roots = %d.\n",
+ i, Vec_WecSize(pBox->vAdds), Vec_WecSizeSize(pBox->vAdds),
+ Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) );
+ Acec_TreePrintBox( pBox, vAdds );
+ Acec_BoxFreeP( &pBox );
+ }
+
+ Vec_WecFree( vTrees );
+ Vec_IntFree( vAdds );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fFilterIn, int fFilterOut, int fVerbose )
+{
+ Acec_Box_t * pBox = NULL;
+ Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, fVerbose );
+ Vec_Wec_t * vTrees = Acec_TreeFindTrees( p, vAdds, vIgnore, fFilterIn, fFilterOut );
+ if ( vTrees && Vec_WecSize(vTrees) > 0 )
+ {
+ pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, 0) );
+ Acec_VerifyBoxLeaves( pBox, vIgnore );
+ }
+ if ( pBox )//&& fVerbose )
+ printf( "Processing tree %d: Ranks = %d. Adders = %d. Leaves = %d. Roots = %d.\n",
+ 0, Vec_WecSize(pBox->vAdds), Vec_WecSizeSize(pBox->vAdds),
+ Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) );
+ if ( pBox && fVerbose )
+ Acec_TreePrintBox( pBox, vAdds );
+ //Acec_PrintAdders( pBox0->vAdds, vAdds );
+ //Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits );
+ Vec_WecFreeP( &vTrees );
+ Vec_IntFree( vAdds );
+ return pBox;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/acec/acecUtil.c b/src/proof/acec/acecUtil.c
index 191856cf..be12afef 100644
--- a/src/proof/acec/acecUtil.c
+++ b/src/proof/acec/acecUtil.c
@@ -90,6 +90,29 @@ void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose )
Vec_IntFree( vXors );
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManDupTopMostRange( Gia_Man_t * p )
+{
+ Gia_Man_t * pNew;
+ Vec_Int_t * vTops = Vec_IntAlloc( 10 );
+ int i;
+ for ( i = 45; i < 52; i++ )
+ Vec_IntPush( vTops, Gia_ObjId( p, Gia_ObjFanin0(Gia_ManCo(p, i)) ) );
+ pNew = Gia_ManDupAndConesLimit( p, Vec_IntArray(vTops), Vec_IntSize(vTops), 100 );
+ Vec_IntFree( vTops );
+ return pNew;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/proof/acec/acecXor.c b/src/proof/acec/acecXor.c
new file mode 100644
index 00000000..71e0b7b3
--- /dev/null
+++ b/src/proof/acec/acecXor.c
@@ -0,0 +1,434 @@
+/**CFile****************************************************************
+
+ FileName [acecXor.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [CEC for arithmetic circuits.]
+
+ Synopsis [Detection of XOR trees.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: acecXor.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "acecInt.h"
+#include "misc/vec/vecWec.h"
+#include "misc/extra/extra.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_CheckXors( Gia_Man_t * p, Vec_Int_t * vXors )
+{
+ Gia_Obj_t * pFan0, * pFan1;
+ Vec_Int_t * vCount2 = Vec_IntAlloc( Gia_ManObjNum(p) );
+ int i, Entry, Count = 0;
+ for ( i = 0; 4*i < Vec_IntSize(vXors); i++ )
+ if ( Vec_IntEntry(vXors, 4*i+3) == 0 )
+ Vec_IntAddToEntry( vCount2, Vec_IntEntry(vXors, 4*i), 1 );
+ Vec_IntForEachEntry( vCount2, Entry, i )
+ if ( Entry > 1 )
+ printf( "*** Obj %d has %d two-input XOR cuts.\n", i, Entry ), Count++;
+ else if ( Entry == 1 && Gia_ObjRecognizeExor(Gia_ManObj(p, i), &pFan0, &pFan1) )
+ printf( "*** Obj %d cannot be recognized as XOR.\n", i );
+ if ( Count == 0 )
+ printf( "*** There no multiple two-input XOR cuts.\n" );
+ Vec_IntFree( vCount2 );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Acec_OrderTreeRoots( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vXorRoots, Vec_Int_t * vRanks )
+{
+ Vec_Int_t * vOrder = Vec_IntAlloc( Vec_IntSize(vXorRoots) );
+ Vec_Int_t * vMove = Vec_IntStartFull( Vec_IntSize(vXorRoots) );
+ int i, k, Entry, This;
+ // iterate through adders and for each try mark the next one
+ for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ )
+ {
+ int Node = Vec_IntEntry(vAdds, 6*i+4);
+ if ( Vec_IntEntry(vRanks, Node) == -1 )
+ continue;
+ for ( k = 0; k < 3; k++ )
+ {
+ int Fanin = Vec_IntEntry(vAdds, 6*i+k);
+ if ( Vec_IntEntry(vRanks, Fanin) == -1 )
+ continue;
+ //printf( "%4d: %2d -> %2d\n", Node, Vec_IntEntry(vRanks, Node), Vec_IntEntry(vRanks, Fanin) );
+ Vec_IntWriteEntry( vMove, Vec_IntEntry(vRanks, Node), Vec_IntEntry(vRanks, Fanin) );
+ }
+ }
+//Vec_IntPrint( vMove );
+ // find reodering
+ Vec_IntForEachEntry( vMove, Entry, i )
+ if ( Entry == -1 && Vec_IntFind(vMove, i) >= 0 )
+ break;
+ assert( i < Vec_IntSize(vMove) );
+ while ( 1 )
+ {
+ Vec_IntPush( vOrder, Vec_IntEntry(vXorRoots, i) );
+ Entry = i;
+ Vec_IntForEachEntry( vMove, This, i )
+ if ( This == Entry )
+ break;
+ if ( i == Vec_IntSize(vMove) )
+ break;
+ }
+ Vec_IntFree( vMove );
+//Vec_IntPrint( vOrder );
+ return vOrder;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+// marks XOR outputs
+Vec_Bit_t * Acec_MapXorOuts( Gia_Man_t * p, Vec_Int_t * vXors )
+{
+ Vec_Bit_t * vMap = Vec_BitStart( Gia_ManObjNum(p) ); int i;
+ for ( i = 0; 4*i < Vec_IntSize(vXors); i++ )
+ Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i), 1 );
+ return vMap;
+}
+// marks XOR outputs participating in trees
+Vec_Bit_t * Acec_MapXorOuts2( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vRanks )
+{
+ Vec_Bit_t * vMap = Vec_BitStart( Gia_ManObjNum(p) ); int i;
+ for ( i = 0; 4*i < Vec_IntSize(vXors); i++ )
+ if ( Vec_IntEntry(vRanks, Vec_IntEntry(vXors, 4*i)) != -1 )
+ Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i), 1 );
+ return vMap;
+}
+// marks MAJ outputs
+Vec_Bit_t * Acec_MapMajOuts( Gia_Man_t * p, Vec_Int_t * vAdds )
+{
+ Vec_Bit_t * vMap = Vec_BitStart( Gia_ManObjNum(p) ); int i;
+ for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ )
+ Vec_BitWriteEntry( vMap, Vec_IntEntry(vAdds, 6*i+4), 1 );
+ return vMap;
+}
+// marks MAJ outputs participating in trees
+Vec_Int_t * Acec_MapMajOuts2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vRanks )
+{
+ Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); int i;
+ for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ )
+ if ( Vec_IntEntry(vRanks, Vec_IntEntry(vAdds, 6*i+4)) != -1 )
+ Vec_IntWriteEntry( vMap, Vec_IntEntry(vAdds, 6*i+4), i );
+ return vMap;
+}
+// marks nodes appearing as fanins to XORs
+Vec_Bit_t * Acec_MapXorIns( Gia_Man_t * p, Vec_Int_t * vXors )
+{
+ Vec_Bit_t * vMap = Vec_BitStart( Gia_ManObjNum(p) ); int i;
+ for ( i = 0; 4*i < Vec_IntSize(vXors); i++ )
+ {
+ Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i+1), 1 );
+ Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i+2), 1 );
+ Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i+3), 1 );
+ }
+ return vMap;
+}
+// collects XOR roots (XOR nodes not appearing as fanins of other XORs)
+Vec_Int_t * Acec_FindXorRoots( Gia_Man_t * p, Vec_Int_t * vXors )
+{
+ Vec_Bit_t * vMapXorIns = Acec_MapXorIns( p, vXors );
+ Vec_Int_t * vXorRoots = Vec_IntAlloc( 100 ); int i;
+ for ( i = 0; 4*i < Vec_IntSize(vXors); i++ )
+ if ( !Vec_BitEntry(vMapXorIns, Vec_IntEntry(vXors, 4*i)) )
+ Vec_IntPushUniqueOrder( vXorRoots, Vec_IntEntry(vXors, 4*i) );
+ Vec_BitFree( vMapXorIns );
+ return vXorRoots;
+}
+// collects XOR trees belonging to each of XOR roots
+Vec_Int_t * Acec_RankTrees( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vXorRoots )
+{
+ Vec_Int_t * vDoubles = Vec_IntAlloc( 100 );
+ int i, k, Entry;
+ // map roots into their ranks
+ Vec_Int_t * vRanks = Vec_IntStartFull( Gia_ManObjNum(p) );
+ Vec_IntForEachEntry( vXorRoots, Entry, i )
+ Vec_IntWriteEntry( vRanks, Entry, i );
+ // map nodes into their ranks
+ for ( i = Vec_IntSize(vXors)/4 - 1; i >= 0; i-- )
+ {
+ int Root = Vec_IntEntry( vXors, 4*i );
+ int Rank = Vec_IntEntry( vRanks, Root );
+ // skip XORs that are not part of any tree
+ if ( Rank == -1 )
+ continue;
+ // iterate through XOR inputs
+ for ( k = 1; k < 4; k++ )
+ {
+ int Node = Vec_IntEntry( vXors, 4*i+k );
+ if ( Node == 0 ) // HA
+ continue;
+ Entry = Vec_IntEntry( vRanks, Node );
+ if ( Entry == Rank ) // the same tree
+ continue;
+ if ( Entry == -1 )
+ Vec_IntWriteEntry( vRanks, Node, Rank );
+ else
+ Vec_IntPush( vDoubles, Node );
+
+ if ( Entry != -1 && Gia_ObjIsAnd(Gia_ManObj(p, Node)))
+ printf( "Xor node %d belongs to Tree %d and Tree %d.\n", Node, Entry, Rank );
+ }
+ }
+ // remove duplicated entries
+ Vec_IntForEachEntry( vDoubles, Entry, i )
+ Vec_IntWriteEntry( vRanks, Entry, -1 );
+ Vec_IntFree( vDoubles );
+ return vRanks;
+}
+// collects leaves of each XOR tree
+Vec_Wec_t * Acec_FindXorLeaves( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vAdds, Vec_Int_t * vXorRoots, Vec_Int_t * vRanks, Vec_Wec_t ** pvAddBoxes )
+{
+ Vec_Bit_t * vMapXors = Acec_MapXorOuts2( p, vXors, vRanks );
+ Vec_Int_t * vMapMajs = Acec_MapMajOuts2( p, vAdds, vRanks );
+ Vec_Wec_t * vXorLeaves = Vec_WecStart( Vec_IntSize(vXorRoots) );
+ Vec_Wec_t * vAddBoxes = Vec_WecStart( Vec_IntSize(vXorRoots) );
+ int i, k;
+ for ( i = 0; 4*i < Vec_IntSize(vXors); i++ )
+ {
+ int Xor = Vec_IntEntry(vXors, 4*i);
+ int Rank = Vec_IntEntry(vRanks, Xor);
+ if ( Rank == -1 )
+ continue;
+ for ( k = 1; k < 4; k++ )
+ {
+ int Fanin = Vec_IntEntry(vXors, 4*i+k);
+ //int RankFanin = Vec_IntEntry(vRanks, Fanin);
+ if ( Fanin == 0 )
+ continue;
+ if ( Vec_BitEntry(vMapXors, Fanin) )
+ {
+ assert( Rank == Vec_IntEntry(vRanks, Fanin) );
+ continue;
+ }
+// if ( Vec_BitEntry(vMapXors, Fanin) && Rank == RankFanin )
+// continue;
+ if ( Vec_IntEntry(vMapMajs, Fanin) == -1 ) // no adder driving this input
+ Vec_WecPush( vXorLeaves, Rank, Fanin );
+ else if ( Vec_IntEntry(vRanks, Xor) > 0 ) // save adder box
+ Vec_WecPush( vAddBoxes, Rank-1, Vec_IntEntry(vMapMajs, Fanin) );
+ }
+ }
+ Vec_BitFree( vMapXors );
+ Vec_IntFree( vMapMajs );
+ if ( pvAddBoxes )
+ *pvAddBoxes = vAddBoxes;
+ return vXorLeaves;
+}
+void Acec_CheckBoothPPs( Gia_Man_t * p, Vec_Wec_t * vLitLeaves )
+{
+ Vec_Bit_t * vMarked = Acec_MultMarkPPs( p );
+ Vec_Int_t * vLevel;
+ int i, k, iLit;
+ Vec_WecForEachLevel( vLitLeaves, vLevel, i )
+ {
+ int CountPI = 0, CountB = 0, CountNB = 0;
+ Vec_IntForEachEntry( vLevel, iLit, k )
+ if ( !Gia_ObjIsAnd(Gia_ManObj(p, Abc_Lit2Var(iLit))) )
+ CountPI++;
+ else if ( Vec_BitEntry( vMarked, Abc_Lit2Var(iLit) ) )
+ CountB++;
+ else
+ CountNB++;
+
+ printf( "Rank %2d : Lits = %5d PI = %d Booth = %5d Non-Booth = %5d\n", i, Vec_IntSize(vLevel), CountPI, CountB, CountNB );
+ }
+ Vec_BitFree( vMarked );
+}
+Acec_Box_t * Acec_FindBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vAddBoxes, Vec_Wec_t * vXorLeaves, Vec_Int_t * vXorRoots )
+{
+ extern Vec_Int_t * Acec_TreeCarryMap( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes );
+ extern void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, int Node, int fPhase, Vec_Bit_t * vVisit );
+ extern void Acec_TreeVerifyPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes );
+ extern void Acec_TreeVerifyPhases2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes );
+
+ int MaxRank = Vec_WecSize( vAddBoxes );
+ Vec_Bit_t * vVisit = Vec_BitStart( Vec_IntSize(vAdds)/6 );
+ Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vLevel, * vLevel2, * vMap;
+ int i, j, k, Box, Node;
+
+ Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 );
+ pBox->pGia = p;
+ pBox->vAdds = vAddBoxes; // Vec_WecDup( vAddBoxes );
+ pBox->vLeafLits = Vec_WecStart( MaxRank + 0 );
+ pBox->vRootLits = Vec_WecStart( MaxRank + 0 );
+
+ assert( Vec_WecSize(vAddBoxes) == Vec_WecSize(vXorLeaves) );
+ assert( Vec_WecSize(vAddBoxes) == Vec_IntSize(vXorRoots) );
+
+ // collect boxes; mark inputs/outputs
+ Vec_WecForEachLevel( pBox->vAdds, vLevel, i )
+ Vec_IntForEachEntry( vLevel, Box, k )
+ {
+ Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 );
+ Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 );
+ Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 );
+ Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 );
+ Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 );
+ }
+ // sort each level
+ Vec_WecForEachLevel( pBox->vAdds, vLevel, i )
+ Vec_IntSort( vLevel, 0 );
+
+ // set phases starting from roots
+ vMap = Acec_TreeCarryMap( p, vAdds, pBox->vAdds );
+ Vec_WecForEachLevelReverse( pBox->vAdds, vLevel, i )
+ Vec_IntForEachEntry( vLevel, Box, k )
+ if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+4) ) )
+ {
+ //printf( "Pushing phase of output %d of box %d\n", Vec_IntEntry(vAdds, 6*Box+4), Box );
+ Acec_TreePhases_rec( p, vAdds, vMap, Vec_IntEntry(vAdds, 6*Box+4), Vec_IntEntry(vAdds, 6*Box+2) != 0, vVisit );
+ }
+ Acec_TreeVerifyPhases( p, vAdds, pBox->vAdds );
+ Acec_TreeVerifyPhases2( p, vAdds, pBox->vAdds );
+ Vec_BitFree( vVisit );
+ Vec_IntFree( vMap );
+
+ // collect inputs/outputs
+ Vec_BitWriteEntry( vIsRoot, 0, 1 );
+ Vec_WecForEachLevel( pBox->vAdds, vLevel, i )
+ Vec_IntForEachEntry( vLevel, Box, j )
+ {
+ for ( k = 0; k < 3; k++ )
+ if ( !Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) )
+ Vec_WecPush( pBox->vLeafLits, i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) );
+ for ( k = 3; k < 5; k++ )
+ if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) )
+ Vec_WecPush( pBox->vRootLits, k == 4 ? i + 1 : i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) );
+ if ( Vec_IntEntry(vAdds, 6*Box+2) == 0 && Acec_SignBit2(vAdds, Box, 2) )
+ Vec_WecPush( pBox->vLeafLits, i, 1 );
+ }
+ Vec_BitFree( vIsLeaf );
+ Vec_BitFree( vIsRoot );
+
+ // collect last bit
+ vLevel = Vec_WecEntry( pBox->vLeafLits, Vec_WecSize(pBox->vLeafLits)-1 );
+ vLevel2 = Vec_WecEntry( vXorLeaves, Vec_WecSize(vXorLeaves)-1 );
+ if ( Vec_IntSize(vLevel) == 0 && Vec_IntSize(vLevel2) > 0 )
+ {
+ Vec_IntForEachEntry( vLevel2, Node, k )
+ Vec_IntPush( vLevel, Abc_Var2Lit(Node, 0) );
+ }
+ vLevel = Vec_WecEntry( pBox->vRootLits, Vec_WecSize(pBox->vRootLits)-1 );
+ Vec_IntFill( vLevel, 1, Abc_Var2Lit(Vec_IntEntryLast(vXorRoots), 0) );
+
+ // sort each level
+ Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i )
+ Vec_IntSort( vLevel, 0 );
+ Vec_WecForEachLevel( pBox->vRootLits, vLevel, i )
+ Vec_IntSort( vLevel, 1 );
+
+ //Acec_CheckBoothPPs( p, pBox->vLeafLits );
+ return pBox;
+}
+
+Acec_Box_t * Acec_ProduceBox( Gia_Man_t * p, int fVerbose )
+{
+ extern void Acec_TreeVerifyConnections( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes );
+
+ abctime clk = Abc_Clock();
+ Acec_Box_t * pBox = NULL;
+ Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( p, &vXors, 0 );
+ Vec_Int_t * vTemp, * vXorRoots = Acec_FindXorRoots( p, vXors );
+ Vec_Int_t * vRanks = Acec_RankTrees( p, vXors, vXorRoots );
+ Vec_Wec_t * vXorLeaves, * vAddBoxes = NULL;
+
+ Gia_ManLevelNum(p);
+
+ //Acec_CheckXors( p, vXors );
+
+ //Ree_ManPrintAdders( vAdds, 1 );
+ if ( fVerbose )
+ printf( "Detected %d full-adders and %d half-adders. Found %d XOR-cuts. ", Ree_ManCountFadds(vAdds), Vec_IntSize(vAdds)/6-Ree_ManCountFadds(vAdds), Vec_IntSize(vXors)/4 );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+
+ vXorRoots = Acec_OrderTreeRoots( p, vAdds, vTemp = vXorRoots, vRanks );
+ Vec_IntFree( vTemp );
+ Vec_IntFree( vRanks );
+
+ vRanks = Acec_RankTrees( p, vXors, vXorRoots );
+ vXorLeaves = Acec_FindXorLeaves( p, vXors, vAdds, vXorRoots, vRanks, &vAddBoxes );
+ Vec_IntFree( vRanks );
+
+ //printf( "XOR roots after reordering: \n" );
+ //Vec_IntPrint( vXorRoots );
+ //printf( "XOR leaves: \n" );
+ //Vec_WecPrint( vXorLeaves, 0 );
+ //printf( "Adder boxes: \n" );
+ //Vec_WecPrint( vAddBoxes, 0 );
+
+ Acec_TreeVerifyConnections( p, vAdds, vAddBoxes );
+
+ pBox = Acec_FindBox( p, vAdds, vAddBoxes, vXorLeaves, vXorRoots );
+ //Vec_WecFree( vAddBoxes );
+
+ if ( fVerbose )
+ Acec_TreePrintBox( pBox, vAdds );
+
+ Vec_IntFree( vXorRoots );
+ Vec_WecFree( vXorLeaves );
+
+ Vec_IntFree( vXors );
+ Vec_IntFree( vAdds );
+
+ return pBox;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/acec/module.make b/src/proof/acec/module.make
index df6db695..f4c69892 100644
--- a/src/proof/acec/module.make
+++ b/src/proof/acec/module.make
@@ -1,13 +1,18 @@
SRC += src/proof/acec/acecCl.c \
src/proof/acec/acecCore.c \
src/proof/acec/acecCo.c \
+ src/proof/acec/acecBo.c \
src/proof/acec/acecRe.c \
src/proof/acec/acecPa.c \
src/proof/acec/acecPo.c \
src/proof/acec/acecPool.c \
src/proof/acec/acecCover.c \
src/proof/acec/acecFadds.c \
+ src/proof/acec/acecMult.c \
+ src/proof/acec/acecNorm.c \
src/proof/acec/acecOrder.c \
src/proof/acec/acecPolyn.c \
src/proof/acec/acecSt.c \
- src/proof/acec/acecUtil.c
+ src/proof/acec/acecTree.c \
+ src/proof/acec/acecUtil.c \
+ src/proof/acec/acecXor.c
diff --git a/src/proof/cec/cecCec.c b/src/proof/cec/cecCec.c
index 77a6ed4a..be6df65f 100644
--- a/src/proof/cec/cecCec.c
+++ b/src/proof/cec/cecCec.c
@@ -85,7 +85,7 @@ int Cec_ManVerifyOld( Gia_Man_t * pMiter, int fVerbose, int * piOutFail, abctime
{
if ( !fSilent )
{
- Abc_Print( 1, "Networks are equivalent. " );
+ Abc_Print( 1, "Networks are equivalent. " );
Abc_PrintTime( 1, "Time", Abc_Clock() - clkTotal );
}
}
@@ -93,7 +93,7 @@ int Cec_ManVerifyOld( Gia_Man_t * pMiter, int fVerbose, int * piOutFail, abctime
{
if ( !fSilent )
{
- Abc_Print( 1, "Networks are NOT EQUIVALENT. " );
+ Abc_Print( 1, "Networks are NOT EQUIVALENT. " );
Abc_PrintTime( 1, "Time", Abc_Clock() - clkTotal );
}
if ( pMiterCec->pData == NULL )
@@ -120,7 +120,7 @@ int Cec_ManVerifyOld( Gia_Man_t * pMiter, int fVerbose, int * piOutFail, abctime
}
else if ( !fSilent )
{
- Abc_Print( 1, "Networks are UNDECIDED. " );
+ Abc_Print( 1, "Networks are UNDECIDED. " );
Abc_PrintTime( 1, "Time", Abc_Clock() - clkTotal );
}
fflush( stdout );
@@ -225,8 +225,7 @@ int Cec_ManHandleSpecialCases( Gia_Man_t * p, Cec_ParCec_t * pPars )
***********************************************************************/
int Cec_ManVerifyNaive( Gia_Man_t * p, Cec_ParCec_t * pPars )
{
- extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
- Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
Gia_Obj_t * pObj0, * pObj1;
abctime clkStart = Abc_Clock();
diff --git a/src/proof/cec/cecSat.c b/src/proof/cec/cecSat.c
new file mode 100644
index 00000000..97bbb7d3
--- /dev/null
+++ b/src/proof/cec/cecSat.c
@@ -0,0 +1,1003 @@
+/**CFile****************************************************************
+
+ FileName [cecSat.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinational equivalence checking.]
+
+ Synopsis [Detection of structural isomorphism.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cecSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "aig/gia/gia.h"
+#include "misc/util/utilTruth.h"
+#include "sat/satoko/satoko.h"
+#include "sat/satoko/solver.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// sweeping manager
+typedef struct Cec2_Par_t_ Cec2_Par_t;
+struct Cec2_Par_t_
+{
+ int nSimWords; // simulation words
+ int nSimRounds; // simulation rounds
+ int nConfLimit; // SAT solver conflict limit
+ int fIsMiter; // this is a miter
+ int fUseCones; // use logic cones
+ int fVeryVerbose; // verbose stats
+ int fVerbose; // verbose stats
+};
+
+// SAT solving manager
+typedef struct Cec2_Man_t_ Cec2_Man_t;
+struct Cec2_Man_t_
+{
+ Cec2_Par_t * pPars; // parameters
+ Gia_Man_t * pAig; // user's AIG
+ Gia_Man_t * pNew; // internal AIG
+ // SAT solving
+ satoko_t * pSat; // SAT solver
+ Vec_Ptr_t * vFrontier; // CNF construction
+ Vec_Ptr_t * vFanins; // CNF construction
+ Vec_Wrd_t * vSims; // CI simulation info
+ Vec_Int_t * vNodesNew; // nodes
+ Vec_Int_t * vSatVars; // nodes
+ Vec_Int_t * vObjSatPairs; // nodes
+ Vec_Int_t * vCexTriples; // nodes
+ // statistics
+ int nSatSat;
+ int nSatUnsat;
+ int nSatUndec;
+ abctime timeSatSat;
+ abctime timeSatUnsat;
+ abctime timeSatUndec;
+ abctime timeSim;
+ abctime timeRefine;
+ abctime timeExtra;
+ abctime timeStart;
+};
+
+static inline int Cec2_ObjSatId( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjCopyArray(p, Gia_ObjId(p, pObj)); }
+static inline int Cec2_ObjSetSatId( Gia_Man_t * p, Gia_Obj_t * pObj, int Num ) { assert(Cec2_ObjSatId(p, pObj) == -1); Gia_ObjSetCopyArray(p, Gia_ObjId(p, pObj), Num); return Num; }
+static inline void Cec2_ObjCleanSatId( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert(Cec2_ObjSatId(p, pObj) != -1); Gia_ObjSetCopyArray(p, Gia_ObjId(p, pObj), -1); }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Sets parameter defaults.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec2_SetDefaultParams( Cec2_Par_t * p )
+{
+ memset( p, 0, sizeof(Cec2_Par_t) );
+ p->nSimWords = 8; // simulation words
+ p->nSimRounds = 4; // simulation rounds
+ p->nConfLimit = 1000; // conflict limit at a node
+ p->fIsMiter = 0; // this is a miter
+ p->fUseCones = 1; // use logic cones
+ p->fVeryVerbose = 0; // verbose stats
+ p->fVerbose = 1; // verbose stats
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds clauses to the solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec2_AddClausesMux( Gia_Man_t * p, Gia_Obj_t * pNode, satoko_t * pSat )
+{
+ int fPolarFlip = 0;
+ Gia_Obj_t * pNodeI, * pNodeT, * pNodeE;
+ int pLits[4], RetValue, VarF, VarI, VarT, VarE, fCompT, fCompE;
+
+ assert( !Gia_IsComplement( pNode ) );
+ assert( pNode->fMark0 );
+ // get nodes (I = if, T = then, E = else)
+ pNodeI = Gia_ObjRecognizeMux( pNode, &pNodeT, &pNodeE );
+ // get the variable numbers
+ VarF = Cec2_ObjSatId(p, pNode);
+ VarI = Cec2_ObjSatId(p, pNodeI);
+ VarT = Cec2_ObjSatId(p, Gia_Regular(pNodeT));
+ VarE = Cec2_ObjSatId(p, Gia_Regular(pNodeE));
+ // get the complementation flags
+ fCompT = Gia_IsComplement(pNodeT);
+ fCompE = Gia_IsComplement(pNodeE);
+
+ // f = ITE(i, t, e)
+
+ // i' + t' + f
+ // i' + t + f'
+ // i + e' + f
+ // i + e + f'
+
+ // create four clauses
+ pLits[0] = Abc_Var2Lit(VarI, 1);
+ pLits[1] = Abc_Var2Lit(VarT, 1^fCompT);
+ pLits[2] = Abc_Var2Lit(VarF, 0);
+ if ( fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( Gia_Regular(pNodeT)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] );
+ }
+ RetValue = satoko_add_clause( pSat, pLits, 3 );
+ assert( RetValue );
+ pLits[0] = Abc_Var2Lit(VarI, 1);
+ pLits[1] = Abc_Var2Lit(VarT, 0^fCompT);
+ pLits[2] = Abc_Var2Lit(VarF, 1);
+ if ( fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( Gia_Regular(pNodeT)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] );
+ }
+ RetValue = satoko_add_clause( pSat, pLits, 3 );
+ assert( RetValue );
+ pLits[0] = Abc_Var2Lit(VarI, 0);
+ pLits[1] = Abc_Var2Lit(VarE, 1^fCompE);
+ pLits[2] = Abc_Var2Lit(VarF, 0);
+ if ( fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] );
+ }
+ RetValue = satoko_add_clause( pSat, pLits, 3 );
+ assert( RetValue );
+ pLits[0] = Abc_Var2Lit(VarI, 0);
+ pLits[1] = Abc_Var2Lit(VarE, 0^fCompE);
+ pLits[2] = Abc_Var2Lit(VarF, 1);
+ if ( fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] );
+ }
+ RetValue = satoko_add_clause( pSat, pLits, 3 );
+ assert( RetValue );
+
+ // two additional clauses
+ // t' & e' -> f'
+ // t & e -> f
+
+ // t + e + f'
+ // t' + e' + f
+
+ if ( VarT == VarE )
+ {
+// assert( fCompT == !fCompE );
+ return;
+ }
+
+ pLits[0] = Abc_Var2Lit(VarT, 0^fCompT);
+ pLits[1] = Abc_Var2Lit(VarE, 0^fCompE);
+ pLits[2] = Abc_Var2Lit(VarF, 1);
+ if ( fPolarFlip )
+ {
+ if ( Gia_Regular(pNodeT)->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] );
+ }
+ RetValue = satoko_add_clause( pSat, pLits, 3 );
+ assert( RetValue );
+ pLits[0] = Abc_Var2Lit(VarT, 1^fCompT);
+ pLits[1] = Abc_Var2Lit(VarE, 1^fCompE);
+ pLits[2] = Abc_Var2Lit(VarF, 0);
+ if ( fPolarFlip )
+ {
+ if ( Gia_Regular(pNodeT)->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] );
+ }
+ RetValue = satoko_add_clause( pSat, pLits, 3 );
+ assert( RetValue );
+}
+void Cec2_AddClausesSuper( Gia_Man_t * p, Gia_Obj_t * pNode, Vec_Ptr_t * vSuper, satoko_t * pSat )
+{
+ int fPolarFlip = 0;
+ Gia_Obj_t * pFanin;
+ int * pLits, nLits, RetValue, i;
+ assert( !Gia_IsComplement(pNode) );
+ assert( Gia_ObjIsAnd( pNode ) );
+ // create storage for literals
+ nLits = Vec_PtrSize(vSuper) + 1;
+ pLits = ABC_ALLOC( int, nLits );
+ // suppose AND-gate is A & B = C
+ // add !A => !C or A + !C
+ Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i )
+ {
+ pLits[0] = Abc_Var2Lit(Cec2_ObjSatId(p, Gia_Regular(pFanin)), Gia_IsComplement(pFanin));
+ pLits[1] = Abc_Var2Lit(Cec2_ObjSatId(p, pNode), 1);
+ if ( fPolarFlip )
+ {
+ if ( Gia_Regular(pFanin)->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( pNode->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ }
+ RetValue = satoko_add_clause( pSat, pLits, 2 );
+ assert( RetValue );
+ }
+ // add A & B => C or !A + !B + C
+ Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i )
+ {
+ pLits[i] = Abc_Var2Lit(Cec2_ObjSatId(p, Gia_Regular(pFanin)), !Gia_IsComplement(pFanin));
+ if ( fPolarFlip )
+ {
+ if ( Gia_Regular(pFanin)->fPhase ) pLits[i] = Abc_LitNot( pLits[i] );
+ }
+ }
+ pLits[nLits-1] = Abc_Var2Lit(Cec2_ObjSatId(p, pNode), 0);
+ if ( fPolarFlip )
+ {
+ if ( pNode->fPhase ) pLits[nLits-1] = Abc_LitNot( pLits[nLits-1] );
+ }
+ RetValue = satoko_add_clause( pSat, pLits, nLits );
+ assert( RetValue );
+ ABC_FREE( pLits );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds clauses and returns CNF variable of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec2_CollectSuper_rec( Gia_Obj_t * pObj, Vec_Ptr_t * vSuper, int fFirst, int fUseMuxes )
+{
+ // if the new node is complemented or a PI, another gate begins
+ if ( Gia_IsComplement(pObj) || Gia_ObjIsCi(pObj) ||
+ (!fFirst && Gia_ObjValue(pObj) > 1) ||
+ (fUseMuxes && pObj->fMark0) )
+ {
+ Vec_PtrPushUnique( vSuper, pObj );
+ return;
+ }
+ // go through the branches
+ Cec2_CollectSuper_rec( Gia_ObjChild0(pObj), vSuper, 0, fUseMuxes );
+ Cec2_CollectSuper_rec( Gia_ObjChild1(pObj), vSuper, 0, fUseMuxes );
+}
+void Cec2_CollectSuper( Gia_Obj_t * pObj, int fUseMuxes, Vec_Ptr_t * vSuper )
+{
+ assert( !Gia_IsComplement(pObj) );
+ assert( !Gia_ObjIsCi(pObj) );
+ Vec_PtrClear( vSuper );
+ Cec2_CollectSuper_rec( pObj, vSuper, 1, fUseMuxes );
+}
+void Cec2_ObjAddToFrontier( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Ptr_t * vFrontier, satoko_t * pSat )
+{
+ assert( !Gia_IsComplement(pObj) );
+ assert( !Gia_ObjIsConst0(pObj) );
+ if ( Cec2_ObjSatId(p, pObj) >= 0 )
+ return;
+ assert( Cec2_ObjSatId(p, pObj) == -1 );
+ Cec2_ObjSetSatId( p, pObj, satoko_add_variable(pSat, 0) );
+ if ( Gia_ObjIsAnd(pObj) )
+ Vec_PtrPush( vFrontier, pObj );
+}
+int Cec2_ObjGetCnfVar( Cec2_Man_t * p, int iObj )
+{
+ Gia_Obj_t * pNode, * pFanin;
+ Gia_Obj_t * pObj = Gia_ManObj(p->pNew, iObj);
+ int i, k, fUseMuxes = 1;
+ // quit if CNF is ready
+ if ( Cec2_ObjSatId(p->pNew,pObj) >= 0 )
+ return Cec2_ObjSatId(p->pNew,pObj);
+ assert( iObj > 0 );
+ if ( Gia_ObjIsCi(pObj) )
+ return Cec2_ObjSetSatId( p->pNew, pObj, satoko_add_variable(p->pSat, 0) );
+ assert( Gia_ObjIsAnd(pObj) );
+ // start the frontier
+ Vec_PtrClear( p->vFrontier );
+ Cec2_ObjAddToFrontier( p->pNew, pObj, p->vFrontier, p->pSat );
+ // explore nodes in the frontier
+ Vec_PtrForEachEntry( Gia_Obj_t *, p->vFrontier, pNode, i )
+ {
+ // create the supergate
+ assert( Cec2_ObjSatId(p->pNew,pNode) >= 0 );
+ if ( fUseMuxes && pNode->fMark0 )
+ {
+ Vec_PtrClear( p->vFanins );
+ Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin0( Gia_ObjFanin0(pNode) ) );
+ Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin0( Gia_ObjFanin1(pNode) ) );
+ Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin1( Gia_ObjFanin0(pNode) ) );
+ Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin1( Gia_ObjFanin1(pNode) ) );
+ Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k )
+ Cec2_ObjAddToFrontier( p->pNew, Gia_Regular(pFanin), p->vFrontier, p->pSat );
+ Cec2_AddClausesMux( p->pNew, pNode, p->pSat );
+ }
+ else
+ {
+ Cec2_CollectSuper( pNode, fUseMuxes, p->vFanins );
+ Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k )
+ Cec2_ObjAddToFrontier( p->pNew, Gia_Regular(pFanin), p->vFrontier, p->pSat );
+ Cec2_AddClausesSuper( p->pNew, pNode, p->vFanins, p->pSat );
+ }
+ assert( Vec_PtrSize(p->vFanins) > 1 );
+ }
+ return Cec2_ObjSatId(p->pNew,pObj);
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Internal simulation APIs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline word * Cec2_ObjSim( Gia_Man_t * p, int iObj )
+{
+ return Vec_WrdEntryP( p->vSims, p->nSimWords * iObj );
+}
+static inline void Cec2_ObjSimSetInputBit( Gia_Man_t * p, int iObj, int Bit )
+{
+ word * pSim = Cec2_ObjSim( p, iObj );
+ if ( Abc_InfoHasBit( (unsigned*)pSim, p->iPatsPi ) != Bit )
+ Abc_InfoXorBit( (unsigned*)pSim, p->iPatsPi );
+}
+static inline void Cec2_ObjSimRo( Gia_Man_t * p, int iObj )
+{
+ int w;
+ word * pSimRo = Cec2_ObjSim( p, iObj );
+ word * pSimRi = Cec2_ObjSim( p, Gia_ObjRoToRiId(p, iObj) );
+ for ( w = 0; w < p->nSimWords; w++ )
+ pSimRo[w] = pSimRi[w];
+}
+static inline void Cec2_ObjSimCo( Gia_Man_t * p, int iObj )
+{
+ int w;
+ Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
+ word * pSimCo = Cec2_ObjSim( p, iObj );
+ word * pSimDri = Cec2_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) );
+ if ( Gia_ObjFaninC0(pObj) )
+ for ( w = 0; w < p->nSimWords; w++ )
+ pSimCo[w] = ~pSimDri[w];
+ else
+ for ( w = 0; w < p->nSimWords; w++ )
+ pSimCo[w] = pSimDri[w];
+}
+static inline void Cec2_ObjSimAnd( Gia_Man_t * p, int iObj )
+{
+ int w;
+ Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
+ word * pSim = Cec2_ObjSim( p, iObj );
+ word * pSim0 = Cec2_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) );
+ word * pSim1 = Cec2_ObjSim( p, Gia_ObjFaninId1(pObj, iObj) );
+ if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) )
+ for ( w = 0; w < p->nSimWords; w++ )
+ pSim[w] = ~pSim0[w] & ~pSim1[w];
+ else if ( Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) )
+ for ( w = 0; w < p->nSimWords; w++ )
+ pSim[w] = ~pSim0[w] & pSim1[w];
+ else if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) )
+ for ( w = 0; w < p->nSimWords; w++ )
+ pSim[w] = pSim0[w] & ~pSim1[w];
+ else
+ for ( w = 0; w < p->nSimWords; w++ )
+ pSim[w] = pSim0[w] & pSim1[w];
+}
+static inline int Cec2_ObjSimEqual( Gia_Man_t * p, int iObj0, int iObj1 )
+{
+ int w;
+ word * pSim0 = Cec2_ObjSim( p, iObj0 );
+ word * pSim1 = Cec2_ObjSim( p, iObj1 );
+ if ( (pSim0[0] & 1) == (pSim1[0] & 1) )
+ {
+ for ( w = 0; w < p->nSimWords; w++ )
+ if ( pSim0[w] != pSim1[w] )
+ return 0;
+ return 1;
+ }
+ else
+ {
+ for ( w = 0; w < p->nSimWords; w++ )
+ if ( pSim0[w] != ~pSim1[w] )
+ return 0;
+ return 1;
+ }
+}
+static inline void Cec2_ObjSimCi( Gia_Man_t * p, int iObj )
+{
+ int w;
+ word * pSim = Cec2_ObjSim( p, iObj );
+ for ( w = 0; w < p->nSimWords; w++ )
+ pSim[w] = Gia_ManRandomW( 0 );
+ pSim[0] <<= 1;
+}
+void Cec2_ManSimulateCis( Gia_Man_t * p )
+{
+ int i, Id;
+ Gia_ManForEachCiId( p, Id, i )
+ Cec2_ObjSimCi( p, Id );
+ p->iPatsPi = 1;
+}
+Abc_Cex_t * Cec2_ManDeriveCex( Gia_Man_t * p, int iOut, int iPat )
+{
+ Abc_Cex_t * pCex;
+ int i, Id;
+ pCex = Abc_CexAlloc( 0, Gia_ManCiNum(p), 1 );
+ pCex->iPo = iOut;
+ if ( iPat == -1 )
+ return pCex;
+ Gia_ManForEachCiId( p, Id, i )
+ if ( Abc_InfoHasBit((unsigned *)Cec2_ObjSim(p, Id), iPat) )
+ Abc_InfoSetBit( pCex->pData, i );
+ return pCex;
+}
+int Cec2_ManSimulateCos( Gia_Man_t * p )
+{
+ int i, Id;
+ // check outputs and generate CEX if they fail
+ Gia_ManForEachCoId( p, Id, i )
+ {
+ Cec2_ObjSimCo( p, Id );
+ if ( Cec2_ObjSimEqual(p, Id, 0) )
+ continue;
+ p->pCexSeq = Cec2_ManDeriveCex( p, i, Abc_TtFindFirstBit2(Cec2_ObjSim(p, Id), p->nSimWords) );
+ return 0;
+ }
+ return 1;
+}
+void Cec2_ManSaveCis( Gia_Man_t * p )
+{
+ int w, i, Id;
+ assert( p->vSimsPi != NULL );
+ for ( w = 0; w < p->nSimWords; w++ )
+ Gia_ManForEachCiId( p, Id, i )
+ Vec_WrdPush( p->vSimsPi, Cec2_ObjSim(p, Id)[w] );
+}
+void Cec2_ManSimulate( Gia_Man_t * p, Vec_Int_t * vTriples, Cec2_Man_t * pMan )
+{
+ extern void Cec2_ManSimClassRefineOne( Gia_Man_t * p, int iRepr );
+ abctime clk = Abc_Clock();
+ Gia_Obj_t * pObj;
+ int i, iRepr, iObj, Entry;
+ //Cec2_ManSaveCis( p );
+ Gia_ManForEachAnd( p, pObj, i )
+ Cec2_ObjSimAnd( p, i );
+ pMan->timeSim += Abc_Clock() - clk;
+ if ( p->pReprs == NULL )
+ return;
+ if ( vTriples )
+ {
+ Vec_IntForEachEntryTriple( vTriples, iRepr, iObj, Entry, i )
+ {
+ word * pSim0 = Cec2_ObjSim( p, iRepr );
+ word * pSim1 = Cec2_ObjSim( p, iObj );
+ int iPat = Abc_Lit2Var(Entry);
+ int fPhase = Abc_LitIsCompl(Entry);
+ if ( (fPhase ^ Abc_InfoHasBit((unsigned *)pSim0, iPat)) == Abc_InfoHasBit((unsigned *)pSim1, iPat) )
+ printf( "ERROR: Pattern %d did not disprove pair %d and %d.\n", iPat, iRepr, iObj );
+ }
+ }
+ clk = Abc_Clock();
+ Gia_ManForEachClass0( p, i )
+ Cec2_ManSimClassRefineOne( p, i );
+ pMan->timeRefine += Abc_Clock() - clk;
+}
+void Cec2_ManSimAlloc( Gia_Man_t * p, int nWords )
+{
+ Vec_WrdFreeP( &p->vSims );
+ Vec_WrdFreeP( &p->vSimsPi );
+ p->vSims = Vec_WrdStart( Gia_ManObjNum(p) * nWords );
+ p->vSimsPi = Vec_WrdAlloc( Gia_ManCiNum(p) * nWords * 4 ); // storage for CI patterns
+ p->nSimWords = nWords;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Computes hash key of the simulation info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec2_ManSimHashKey( word * pSim, int nSims, int nTableSize )
+{
+ static int s_Primes[16] = {
+ 1291, 1699, 1999, 2357, 2953, 3313, 3907, 4177,
+ 4831, 5147, 5647, 6343, 6899, 7103, 7873, 8147 };
+ unsigned uHash = 0, * pSimU = (unsigned *)pSim;
+ int i, nSimsU = 2 * nSims;
+ if ( pSimU[0] & 1 )
+ for ( i = 0; i < nSimsU; i++ )
+ uHash ^= ~pSimU[i] * s_Primes[i & 0xf];
+ else
+ for ( i = 0; i < nSimsU; i++ )
+ uHash ^= pSimU[i] * s_Primes[i & 0xf];
+ return (int)(uHash % nTableSize);
+
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creating initial equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec2_ManSimClassRefineOne( Gia_Man_t * p, int iRepr )
+{
+ int iObj, iPrev = iRepr, iPrev2, iRepr2;
+ Gia_ClassForEachObj1( p, iRepr, iRepr2 )
+ if ( Cec2_ObjSimEqual(p, iRepr, iRepr2) )
+ iPrev = iRepr2;
+ else
+ break;
+ if ( iRepr2 <= 0 ) // no refinement
+ return;
+ // relink remaining nodes of the class
+ // nodes that are equal to iRepr, remain in the class of iRepr
+ // nodes that are not equal to iRepr, move to the class of iRepr2
+ Gia_ObjSetRepr( p, iRepr2, GIA_VOID );
+ iPrev2 = iRepr2;
+ for ( iObj = Gia_ObjNext(p, iRepr2); iObj > 0; iObj = Gia_ObjNext(p, iObj) )
+ {
+ if ( Cec2_ObjSimEqual(p, iRepr, iObj) ) // remains with iRepr
+ {
+ Gia_ObjSetNext( p, iPrev, iObj );
+ iPrev = iObj;
+ }
+ else // moves to iRepr2
+ {
+ Gia_ObjSetRepr( p, iObj, iRepr2 );
+ Gia_ObjSetNext( p, iPrev2, iObj );
+ iPrev2 = iObj;
+ }
+ }
+ Gia_ObjSetNext( p, iPrev, -1 );
+ Gia_ObjSetNext( p, iPrev2, -1 );
+}
+void Cec2_ManCreateClasses( Gia_Man_t * p, Cec2_Man_t * pMan )
+{
+ abctime clk;
+ Gia_Obj_t * pObj;
+ int nWords = p->nSimWords;
+ int * pTable, nTableSize, i, Key;
+ // allocate representation
+ 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) );
+ // hash each node by its simulation info
+ nTableSize = Abc_PrimeCudd( Gia_ManObjNum(p) );
+ pTable = ABC_FALLOC( int, nTableSize );
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ p->pReprs[i].iRepr = GIA_VOID;
+ if ( Gia_ObjIsCo(pObj) )
+ continue;
+ Key = Cec2_ManSimHashKey( Cec2_ObjSim(p, i), nWords, nTableSize );
+ assert( Key >= 0 && Key < nTableSize );
+ if ( pTable[Key] == -1 )
+ pTable[Key] = i;
+ else
+ Gia_ObjSetRepr( p, i, pTable[Key] );
+ }
+ // create classes
+ for ( i = Gia_ManObjNum(p) - 1; i >= 0; i-- )
+ {
+ int iRepr = Gia_ObjRepr(p, i);
+ if ( iRepr == GIA_VOID )
+ continue;
+ Gia_ObjSetNext( p, i, Gia_ObjNext(p, iRepr) );
+ Gia_ObjSetNext( p, iRepr, i );
+ }
+ ABC_FREE( pTable );
+ clk = Abc_Clock();
+ Gia_ManForEachClass0( p, i )
+ Cec2_ManSimClassRefineOne( p, i );
+ pMan->timeRefine += Abc_Clock() - clk;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Cec2_Man_t * Cec2_ManCreate( Gia_Man_t * pAig, Cec2_Par_t * pPars )
+{
+ Cec2_Man_t * p;
+ Gia_Obj_t * pObj; int i;
+ //assert( Gia_ManRegNum(pAig) == 0 );
+ p = ABC_CALLOC( Cec2_Man_t, 1 );
+ memset( p, 0, sizeof(Cec2_Man_t) );
+ p->timeStart = Abc_Clock();
+ p->pPars = pPars;
+ p->pAig = pAig;
+ // create new manager
+ p->pNew = Gia_ManStart( Gia_ManObjNum(pAig) );
+ Gia_ManFillValue( pAig );
+ Gia_ManConst0(pAig)->Value = 0;
+ Gia_ManForEachCi( pAig, pObj, i )
+ pObj->Value = Gia_ManAppendCi( p->pNew );
+ Gia_ManHashAlloc( p->pNew );
+ Vec_IntFill( &p->pNew->vCopies, Gia_ManObjNum(p->pNew), -1 );
+ // SAT solving
+ p->pSat = satoko_create();
+ p->vFrontier = Vec_PtrAlloc( 1000 );
+ p->vFanins = Vec_PtrAlloc( 100 );
+ p->vNodesNew = Vec_IntAlloc( 100 );
+ p->vSatVars = Vec_IntAlloc( 100 );
+ p->vObjSatPairs = Vec_IntAlloc( 100 );
+ p->vCexTriples = Vec_IntAlloc( 100 );
+ // remember pointer to the solver in the AIG manager
+ pAig->pData = p->pSat;
+ return p;
+}
+void Cec2_ManDestroy( Cec2_Man_t * p )
+{
+ if ( p->pPars->fVerbose )
+ {
+ abctime timeTotal = Abc_Clock() - p->timeStart;
+ abctime timeSat = p->timeSatSat + p->timeSatUnsat + p->timeSatUndec;
+ abctime timeOther = timeTotal - timeSat - p->timeSim - p->timeRefine - p->timeExtra;
+// Abc_Print( 1, "%d\n", p->Num );
+ ABC_PRTP( "SAT solving", timeSat, timeTotal );
+ ABC_PRTP( " sat ", p->timeSatSat, timeTotal );
+ ABC_PRTP( " unsat ", p->timeSatUnsat, timeTotal );
+ ABC_PRTP( " fail ", p->timeSatUndec, timeTotal );
+ ABC_PRTP( "Simulation ", p->timeSim, timeTotal );
+ ABC_PRTP( "Refinement ", p->timeRefine, timeTotal );
+ ABC_PRTP( "Rollback ", p->timeExtra, timeTotal );
+ ABC_PRTP( "Other ", timeOther, timeTotal );
+ ABC_PRTP( "TOTAL ", timeTotal, timeTotal );
+ fflush( stdout );
+ }
+
+ Vec_WrdFreeP( &p->pAig->vSims );
+ //Vec_WrdFreeP( &p->pAig->vSimsPi );
+ Gia_ManCleanMark01( p->pAig );
+ satoko_destroy( p->pSat );
+ Gia_ManStopP( &p->pNew );
+ Vec_PtrFreeP( &p->vFrontier );
+ Vec_PtrFreeP( &p->vFanins );
+ Vec_IntFreeP( &p->vNodesNew );
+ Vec_IntFreeP( &p->vSatVars );
+ Vec_IntFreeP( &p->vObjSatPairs );
+ Vec_IntFreeP( &p->vCexTriples );
+ ABC_FREE( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Verify counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec2_ManVerify_rec( Gia_Man_t * p, int iObj, satoko_t * 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 = var_polarity(pSat, Cec2_ObjSatId(p, pObj)) == LIT_TRUE;
+ assert( Gia_ObjIsAnd(pObj) );
+ Value0 = Cec2_ManVerify_rec( p, Gia_ObjFaninId0(pObj, iObj), pSat ) ^ Gia_ObjFaninC0(pObj);
+ Value1 = Cec2_ManVerify_rec( p, Gia_ObjFaninId1(pObj, iObj), pSat ) ^ Gia_ObjFaninC1(pObj);
+ return pObj->fMark1 = Value0 & Value1;
+}
+void Cec2_ManVerify( Gia_Man_t * p, int iObj0, int iObj1, int fPhase, satoko_t * pSat )
+{
+// int val0 = var_polarity(pSat, Cec2_ObjSatId(p, Gia_ManObj(p, iObj0))) == LIT_TRUE;
+// int val1 = var_polarity(pSat, Cec2_ObjSatId(p, Gia_ManObj(p, iObj1))) == LIT_TRUE;
+ int Value0, Value1;
+ Gia_ManIncrementTravId( p );
+ Value0 = Cec2_ManVerify_rec( p, iObj0, pSat );
+ Value1 = Cec2_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 [Internal simulation APIs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec2_ManCollect_rec( Cec2_Man_t * p, int iObj )
+{
+ Gia_Obj_t * pObj;
+ if ( Gia_ObjIsTravIdCurrentId(p->pNew, iObj) )
+ return;
+ Gia_ObjSetTravIdCurrentId(p->pNew, iObj);
+ pObj = Gia_ManObj( p->pNew, iObj );
+ if ( Cec2_ObjSatId(p->pNew, pObj) >= 0 )
+ {
+ Vec_IntPush( p->vNodesNew, iObj );
+ Vec_IntPush( p->vSatVars, Cec2_ObjSatId(p->pNew, pObj) );
+ }
+ if ( !iObj )
+ return;
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ Cec2_ManCollect_rec( p, Gia_ObjFaninId0(pObj, iObj) );
+ Cec2_ManCollect_rec( p, Gia_ObjFaninId1(pObj, iObj) );
+ }
+ else
+ {
+ assert( Cec2_ObjSatId(p->pNew, pObj) >= 0 );
+ Vec_IntPushTwo( p->vObjSatPairs, Gia_ManCiIdToId(p->pAig, Gia_ObjCioId(pObj)), Cec2_ObjSatId(p->pNew, pObj) ); // SAT var
+ }
+}
+int Cec2_ManSolveTwo( Cec2_Man_t * p, int iObj0, int iObj1, int fPhase )
+{
+ Gia_Obj_t * pObj;
+ int status, i, iVar0, iVar1;
+ if (iObj1 < iObj0)
+ iObj1 ^= iObj0, iObj0 ^= iObj1, iObj1 ^= iObj0;
+ assert( iObj0 < iObj1 );
+ assert( p->pPars->fUseCones || solver_varnum(p->pSat) == 0 );
+ if ( !iObj0 && Cec2_ObjSatId(p->pNew, Gia_ManConst0(p->pNew)) == -1 )
+ Cec2_ObjSetSatId( p->pNew, Gia_ManConst0(p->pNew), satoko_add_variable(p->pSat, 0) );
+ iVar0 = Cec2_ObjGetCnfVar( p, iObj0 );
+ iVar1 = Cec2_ObjGetCnfVar( p, iObj1 );
+ // collect inputs and internal nodes
+ Vec_IntClear( p->vNodesNew );
+ Vec_IntClear( p->vSatVars );
+ Vec_IntClear( p->vObjSatPairs );
+ Gia_ManIncrementTravId( p->pNew );
+ Cec2_ManCollect_rec( p, iObj0 );
+ Cec2_ManCollect_rec( p, iObj1 );
+//printf( "%d ", Vec_IntSize(p->vNodesNew) );
+ // solve direct
+ if ( p->pPars->fUseCones ) satoko_mark_cone( p->pSat, Vec_IntArray(p->vSatVars), Vec_IntSize(p->vSatVars) );
+ satoko_assump_push( p->pSat, Abc_Var2Lit(iVar0, 1) );
+ satoko_assump_push( p->pSat, Abc_Var2Lit(iVar1, fPhase) );
+ status = satoko_solve( p->pSat );
+ satoko_assump_pop( p->pSat );
+ satoko_assump_pop( p->pSat );
+ if ( status == SATOKO_UNSAT && iObj0 > 0 )
+ {
+ // solve reverse
+ satoko_assump_push( p->pSat, Abc_Var2Lit(iVar0, 0) );
+ satoko_assump_push( p->pSat, Abc_Var2Lit(iVar1, !fPhase) );
+ status = satoko_solve( p->pSat );
+ satoko_assump_pop( p->pSat );
+ satoko_assump_pop( p->pSat );
+ }
+ if ( p->pPars->fUseCones ) satoko_unmark_cone( p->pSat, Vec_IntArray(p->vSatVars), Vec_IntSize(p->vSatVars) );
+ //if ( status == SATOKO_SAT )
+ // Cec2_ManVerify( p->pNew, iObj0, iObj1, fPhase, p->pSat );
+ if ( p->pPars->fUseCones )
+ return status;
+ Gia_ManForEachObjVec( p->vNodesNew, p->pNew, pObj, i )
+ Cec2_ObjCleanSatId( p->pNew, pObj );
+ return status;
+}
+
+int Cec2_ManSweepNode( Cec2_Man_t * p, int iObj )
+{
+ abctime clk = Abc_Clock();
+ int i, IdAig, IdSat, status, RetValue = 1;
+ Gia_Obj_t * pObj = Gia_ManObj( p->pAig, iObj );
+ Gia_Obj_t * pRepr = Gia_ObjReprObj( p->pAig, iObj );
+ int fCompl = Abc_LitIsCompl(pObj->Value) ^ Abc_LitIsCompl(pRepr->Value) ^ pObj->fPhase ^ pRepr->fPhase;
+ status = Cec2_ManSolveTwo( p, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl );
+ if ( status == SATOKO_SAT )
+ {
+ p->nSatSat++;
+ p->pAig->iPatsPi = (p->pAig->iPatsPi == 64 * p->pAig->nSimWords - 1) ? 1 : p->pAig->iPatsPi + 1;
+ assert( p->pAig->iPatsPi > 0 && p->pAig->iPatsPi < 64 * p->pAig->nSimWords );
+ Vec_IntForEachEntryDouble( p->vObjSatPairs, IdAig, IdSat, i )
+ Cec2_ObjSimSetInputBit( p->pAig, IdAig, var_polarity(p->pSat, IdSat) == LIT_TRUE );
+ RetValue = 0;
+ p->timeSatSat += Abc_Clock() - clk;
+ }
+ else if ( status == SATOKO_UNSAT )
+ {
+ p->nSatUnsat++;
+ pObj->Value = Abc_LitNotCond( pRepr->Value, fCompl );
+ Gia_ObjSetProved( p->pAig, iObj );
+ p->timeSatUnsat += Abc_Clock() - clk;
+ }
+ else
+ {
+ p->nSatUndec++;
+ assert( status == SATOKO_UNDEC );
+ Gia_ObjSetFailed( p->pAig, iObj );
+ assert( 0 );
+ p->timeSatUndec += Abc_Clock() - clk;
+ }
+ if ( p->pPars->fUseCones )
+ return RetValue;
+ clk = Abc_Clock();
+ satoko_rollback( p->pSat );
+ p->timeExtra += Abc_Clock() - clk;
+ p->pSat->stats.n_conflicts = 0;
+ return RetValue;
+}
+void Cec2_ManPrintStats( Gia_Man_t * p, Cec2_Par_t * pPars, Cec2_Man_t * pMan )
+{
+ if ( !pPars->fVerbose )
+ return;
+ printf( "S =%5d ", pMan ? pMan->nSatSat : 0 );
+ printf( "U =%5d ", pMan ? pMan->nSatUnsat : 0 );
+ printf( "F =%5d ", pMan ? pMan->nSatUndec : 0 );
+ Gia_ManEquivPrintClasses( p, pPars->fVeryVerbose, 0 );
+}
+int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars )
+{
+ Cec2_Man_t * pMan = Cec2_ManCreate( p, pPars );
+ Gia_Obj_t * pObj, * pRepr, * pObjNew;
+ int i, Iter, fDisproved = 1;
+
+ // check if any output trivially fails under all-0 pattern
+ Gia_ManSetPhase( p );
+ if ( pPars->fIsMiter )
+ {
+ Gia_ManForEachCo( p, pObj, i )
+ if ( pObj->fPhase )
+ {
+ p->pCexSeq = Cec2_ManDeriveCex( p, i, -1 );
+ return 0;
+ }
+ }
+
+ // simulate one round and create classes
+ Cec2_ManSimAlloc( p, pPars->nSimWords );
+ Cec2_ManSimulateCis( p );
+ Cec2_ManSimulate( p, NULL, pMan );
+ if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected
+ return 0;
+ Cec2_ManCreateClasses( p, pMan );
+ Cec2_ManPrintStats( p, pPars, pMan );
+
+ // perform additinal simulation
+ for ( i = 0; i < pPars->nSimRounds; i++ )
+ {
+ Cec2_ManSimulateCis( p );
+ Cec2_ManSimulate( p, NULL, pMan );
+ if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected
+ return 0;
+ Cec2_ManPrintStats( p, pPars, pMan );
+ }
+ // perform sweeping
+ //pMan = Cec2_ManCreate( p, pPars );
+ for ( Iter = 0; fDisproved; Iter++ )
+ {
+ fDisproved = 0;
+ Cec2_ManSimulateCis( p );
+ Vec_IntClear( pMan->vCexTriples );
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1 || Gia_ObjFanin1(pObj)->fMark1;
+ if ( pObj->fMark1 ) // skip nodes in the TFO of a disproved one
+ continue;
+ if ( ~pObj->Value ) // skip swept nodes
+ continue;
+ if ( !~Gia_ObjFanin0(pObj)->Value || !~Gia_ObjFanin1(pObj)->Value ) // skip fanouts of non-swept nodes
+ continue;
+ assert( !Gia_ObjProved(p, i) && !Gia_ObjFailed(p, i) );
+ // duplicate the node
+ pObj->Value = Gia_ManHashAnd( pMan->pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ if ( Vec_IntSize(&pMan->pNew->vCopies) == Abc_Lit2Var(pObj->Value) )
+ {
+ pObjNew = Gia_ManObj( pMan->pNew, Abc_Lit2Var(pObj->Value) );
+ pObjNew->fMark0 = Gia_ObjIsMuxType( pObjNew );
+ Gia_ObjSetPhase( pMan->pNew, pObjNew );
+ Vec_IntPush( &pMan->pNew->vCopies, -1 );
+ }
+ assert( Vec_IntSize(&pMan->pNew->vCopies) == Gia_ManObjNum(pMan->pNew) );
+ pRepr = Gia_ObjReprObj( p, i );
+ if ( pRepr == NULL || pRepr->fMark1 || !~pRepr->Value )
+ continue;
+ if ( Abc_Lit2Var(pObj->Value) == Abc_Lit2Var(pRepr->Value) )
+ {
+ assert( (pObj->Value ^ pRepr->Value) == (pObj->fPhase ^ pRepr->fPhase) );
+ Gia_ObjSetProved( p, i );
+ continue;
+ }
+ if ( Cec2_ManSweepNode(pMan, i) )
+ continue;
+ pObj->Value = ~0;
+ //Vec_IntPushThree( pMan->vCexTriples, Gia_ObjId(p, pRepr), i, Abc_Var2Lit(p->iPatsPi, pObj->fPhase ^ pRepr->fPhase) );
+ // mark nodes as disproved
+ fDisproved = 1;
+ //if ( Iter > 5 )
+ continue;
+ if ( Gia_ObjIsAnd(pRepr) )
+ pRepr->fMark1 = 1;
+ pObj->fMark1 = 1;
+ }
+ if ( fDisproved )
+ {
+ //printf( "The number of pattern = %d.\n", p->iPatsPi );
+ Cec2_ManSimulate( p, pMan->vCexTriples, pMan );
+ if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected
+ break;
+ }
+ Cec2_ManPrintStats( p, pPars, pMan );
+ }
+ Cec2_ManDestroy( pMan );
+ //Gia_ManEquivPrintClasses( p, 1, 0 );
+ return p->pCexSeq ? 0 : 1;
+}
+void Cec2_ManSimulateTest( Gia_Man_t * p )
+{
+ //abctime clk = Abc_Clock();
+ Cec2_Par_t Pars, * pPars = &Pars;
+ Cec2_SetDefaultParams( pPars );
+// Gia_ManComputeGiaEquivs( p, 100000, 0 );
+// Gia_ManEquivPrintClasses( p, 1, 0 );
+ Cec2_ManPerformSweeping( p, pPars );
+ //Abc_PrintTime( 1, "SAT sweeping time", Abc_Clock() - clk );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/cec/cecSimBack.c b/src/proof/cec/cecSimBack.c
new file mode 100644
index 00000000..c3d09ff5
--- /dev/null
+++ b/src/proof/cec/cecSimBack.c
@@ -0,0 +1,194 @@
+/**CFile****************************************************************
+
+ FileName [cecSimBack.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinational equivalence checking.]
+
+ Synopsis [Backward simulation.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cecSimBack.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cecInt.h"
+#include "aig/gia/giaAig.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ObjSatVerify( Gia_Man_t * p, Gia_Obj_t * pRoot, int Value )
+{
+ Gia_Obj_t * pObj;
+ int i, RetValue = 1;
+ printf( "Obj = %4d Value = %d ", Gia_ObjId(p, pRoot), Value );
+ Gia_ObjTerSimSet0( Gia_ManConst0(p) );
+ Gia_ManForEachCi( p, pObj, i )
+ if ( !Gia_ObjIsTravIdCurrent(p, pObj) )
+ Gia_ObjTerSimSetX( pObj ), printf( "x" );
+ else if ( pObj->fMark0 )
+ Gia_ObjTerSimSet1( pObj ), printf( "1" );
+ else
+ Gia_ObjTerSimSet0( pObj ), printf( "0" );
+ printf( " " );
+ Gia_ManForEachAnd( p, pObj, i )
+ Gia_ObjTerSimAnd( pObj );
+ if ( Value ? Gia_ObjTerSimGet1(pRoot) : Gia_ObjTerSimGet0(pRoot) )
+ printf( "Verification successful.\n" );
+ else
+ printf( "Verification failed.\n" ), RetValue = 0;
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Return 1 if pObj can have Value.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+word Cec_ManCheckSat2_rec( Gia_Man_t * p, Gia_Obj_t * pObj, word Value, Vec_Wrd_t * vValues )
+{
+ Gia_Obj_t * pFan0, * pFan1;
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return Value == (int)pObj->fMark0;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ pObj->fMark0 = Value;
+ if ( !Gia_ObjIsAnd(pObj) )
+ return 1;
+ pFan0 = Gia_ObjFanin0(pObj);
+ pFan1 = Gia_ObjFanin1(pObj);
+ if ( Value )
+ {
+ return Cec_ManCheckSat2_rec( p, pFan0, !Gia_ObjFaninC0(pObj), vValues ) &&
+ Cec_ManCheckSat2_rec( p, pFan1, !Gia_ObjFaninC1(pObj), vValues );
+ }
+ if ( Gia_ObjIsTravIdCurrent(p, pFan0) ) // already assigned
+ {
+ if ( Gia_ObjFaninC0(pObj) == (int)pFan0->fMark0 ) // justified
+ return 1;
+ return Cec_ManCheckSat2_rec( p, pFan1, Gia_ObjFaninC1(pObj), vValues );
+ }
+ if ( Gia_ObjIsTravIdCurrent(p, pFan1) ) // already assigned
+ {
+ if ( Gia_ObjFaninC1(pObj) == (int)pFan1->fMark0 ) // justified
+ return 1;
+ return Cec_ManCheckSat2_rec( p, pFan0, Gia_ObjFaninC0(pObj), vValues );
+ }
+ return Cec_ManCheckSat2_rec( p, pFan0, Gia_ObjFaninC0(pObj), vValues );
+}
+word Cec_ManCheckSat2( Gia_Man_t * p, Gia_Obj_t * pObj, int Value, Vec_Wrd_t * vValues )
+{
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Return 1 if pObj can have Value.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManCheckSat_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int Value )
+{
+ Gia_Obj_t * pFan0, * pFan1;
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return Value == (int)pObj->fMark0;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ pObj->fMark0 = Value;
+ if ( !Gia_ObjIsAnd(pObj) )
+ return 1;
+ pFan0 = Gia_ObjFanin0(pObj);
+ pFan1 = Gia_ObjFanin1(pObj);
+ if ( Value )
+ {
+ return Cec_ManCheckSat_rec( p, pFan0, !Gia_ObjFaninC0(pObj) ) &&
+ Cec_ManCheckSat_rec( p, pFan1, !Gia_ObjFaninC1(pObj) );
+ }
+ if ( Gia_ObjIsTravIdCurrent(p, pFan0) ) // already assigned
+ {
+ if ( Gia_ObjFaninC0(pObj) == (int)pFan0->fMark0 ) // justified
+ return 1;
+ return Cec_ManCheckSat_rec( p, pFan1, Gia_ObjFaninC1(pObj) );
+ }
+ if ( Gia_ObjIsTravIdCurrent(p, pFan1) ) // already assigned
+ {
+ if ( Gia_ObjFaninC1(pObj) == (int)pFan1->fMark0 ) // justified
+ return 1;
+ return Cec_ManCheckSat_rec( p, pFan0, Gia_ObjFaninC0(pObj) );
+ }
+ return Cec_ManCheckSat_rec( p, pFan0, Gia_ObjFaninC0(pObj) );
+}
+void Cec_ManSimBack( Gia_Man_t * p )
+{
+ abctime clk = Abc_Clock();
+ Vec_Wrd_t * vValues = Vec_WrdStart( Gia_ManObjNum(p) );
+ Gia_Obj_t * pObj;
+ int i, Count = 0;
+ word Res;
+ Gia_ManSetPhase( p );
+ //Gia_ManForEachAnd( p, pObj, i )
+ // printf( "%d", pObj->fPhase );
+ //printf( "\n" );
+ //return;
+
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ Gia_ManIncrementTravId(p);
+ //Gia_ManCleanMark0( p );
+ Res = Cec_ManCheckSat_rec( p, pObj, !pObj->fPhase );
+ //if ( Res )
+ // Cec_ObjSatVerify( p, pObj, !pObj->fPhase );
+
+ //Res = Cec_ManCheckSat2_rec( p, pObj, !pObj->fPhase ? ~(word)0 : 0, vValues );
+ //if ( Res )
+ // Cec_ObjSatVerify2( p, pObj, !pObj->fPhase, Res );
+
+ Count += (int)(Res > 0);
+ }
+ Vec_WrdFree( vValues );
+ printf( "Obj = %6d. SAT = %6d. ", Gia_ManAndNum(p), Count );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/cec/module.make b/src/proof/cec/module.make
index 82e0de74..38106e5e 100644
--- a/src/proof/cec/module.make
+++ b/src/proof/cec/module.make
@@ -6,6 +6,7 @@ SRC += src/proof/cec/cecCec.c \
src/proof/cec/cecIso.c \
src/proof/cec/cecMan.c \
src/proof/cec/cecPat.c \
+ src/proof/cec/cecSat.c \
src/proof/cec/cecSeq.c \
src/proof/cec/cecSolve.c \
src/proof/cec/cecSplit.c \
diff --git a/src/proof/fra/fraCec.c b/src/proof/fra/fraCec.c
index 130036a6..84f37930 100644
--- a/src/proof/fra/fraCec.c
+++ b/src/proof/fra/fraCec.c
@@ -547,17 +547,17 @@ int Fra_FraigCecTop( Aig_Man_t * pMan1, Aig_Man_t * pMan2, int nConfLimit, int n
// report the miter
if ( RetValue == 1 )
{
- printf( "Networks are equivalent. " );
+ printf( "Networks are equivalent. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
else if ( RetValue == 0 )
{
- printf( "Networks are NOT EQUIVALENT. " );
+ printf( "Networks are NOT EQUIVALENT. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
else
{
- printf( "Networks are UNDECIDED. " );
+ printf( "Networks are UNDECIDED. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
fflush( stdout );
diff --git a/src/proof/fra/fraSec.c b/src/proof/fra/fraSec.c
index 06011d2e..7e382fc8 100644
--- a/src/proof/fra/fraSec.c
+++ b/src/proof/fra/fraSec.c
@@ -606,7 +606,7 @@ finish:
{
if ( !pParSec->fSilent )
{
- printf( "Networks are equivalent. " );
+ printf( "Networks are equivalent. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
if ( pParSec->fReportSolution && !pParSec->fRecursive )
@@ -630,7 +630,7 @@ ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
if ( !pParSec->fSilent )
{
- printf( "Networks are NOT EQUIVALENT. " );
+ printf( "Networks are NOT EQUIVALENT. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
if ( pParSec->fReportSolution && !pParSec->fRecursive )
diff --git a/src/proof/pdr/module.make b/src/proof/pdr/module.make
index 5bee83f8..1dee93aa 100644
--- a/src/proof/pdr/module.make
+++ b/src/proof/pdr/module.make
@@ -1,7 +1,9 @@
SRC += src/proof/pdr/pdrCnf.c \
src/proof/pdr/pdrCore.c \
+ src/proof/pdr/pdrIncr.c \
src/proof/pdr/pdrInv.c \
src/proof/pdr/pdrMan.c \
src/proof/pdr/pdrSat.c \
src/proof/pdr/pdrTsim.c \
- src/proof/pdr/pdrUtil.c
+ src/proof/pdr/pdrTsim2.c \
+ src/proof/pdr/pdrUtil.c
diff --git a/src/proof/pdr/pdr.h b/src/proof/pdr/pdr.h
index 529a161f..51b04606 100644
--- a/src/proof/pdr/pdr.h
+++ b/src/proof/pdr/pdr.h
@@ -49,14 +49,23 @@ struct Pdr_Par_t_
int nTimeOut; // timeout in seconds
int nTimeOutGap; // approximate timeout in seconds since the last change
int nTimeOutOne; // approximate timeout in seconds per one output
+ int nRandomSeed; // value to seed the SAT solver with
int fTwoRounds; // use two rounds for generalization
int fMonoCnf; // monolythic CNF
+ int fNewXSim; // updated X-valued simulation
+ int fFlopPrio; // use structural flop priorities
+ int fFlopOrder; // order flops for 'analyze_final' during generalization
int fDumpInv; // dump inductive invariant
int fUseSupp; // use support in the invariant
int fShortest; // forces bug traces to be shortest
int fShiftStart; // allows clause pushing to start from an intermediate frame
int fReuseProofOblig; // reuses proof-obligationgs in the last timeframe
+ int fSimpleGeneral; // simplified generalization
int fSkipGeneral; // skips expensive generalization step
+ int fSkipDown; // skips the application of down
+ int fCtgs; // handle CTGs in down
+ int fUseAbs; // use abstraction
+ int fUseSimpleRef; // simplified CEX refinement
int fVerbose; // verbose output`
int fVeryVerbose; // very verbose output
int fNotVerbose; // not printing line by line progress
diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c
index c020c56a..501f9be6 100644
--- a/src/proof/pdr/pdrCore.c
+++ b/src/proof/pdr/pdrCore.c
@@ -20,6 +20,7 @@
#include "pdrInt.h"
#include "base/main/main.h"
+#include "misc/hash/hash.h"
ABC_NAMESPACE_IMPL_START
@@ -57,12 +58,20 @@ void Pdr_ManSetDefaultParams( Pdr_Par_t * pPars )
pPars->nConfLimit = 0; // limit on SAT solver conflicts
pPars->nConfGenLimit = 0; // limit on SAT solver conflicts during generalization
pPars->nRestLimit = 0; // limit on the number of proof-obligations
+ pPars->nRandomSeed = 91648253; // value to seed the SAT solver with
pPars->fTwoRounds = 0; // use two rounds for generalization
pPars->fMonoCnf = 0; // monolythic CNF
+ pPars->fNewXSim = 0; // updated X-valued simulation
+ pPars->fFlopPrio = 0; // use structural flop priorities
+ pPars->fFlopOrder = 0; // order flops for 'analyze_final' during generalization
pPars->fDumpInv = 0; // dump inductive invariant
pPars->fUseSupp = 1; // using support variables in the invariant
pPars->fShortest = 0; // forces bug traces to be shortest
pPars->fUsePropOut = 1; // use property output
+ pPars->fSkipDown = 1; // apply down in generalization
+ pPars->fCtgs = 0; // handle CTGs in down
+ pPars->fUseAbs = 0; // use abstraction
+ pPars->fUseSimpleRef = 0; // simplified CEX refinement
pPars->fVerbose = 0; // verbose output
pPars->fVeryVerbose = 0; // very verbose output
pPars->fNotVerbose = 0; // not printing line-by-line progress
@@ -118,7 +127,7 @@ Pdr_Set_t * Pdr_ManReduceClause( Pdr_Man_t * p, int k, Pdr_Set_t * pCube )
// make sure the cube works
{
int RetValue;
- RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, 0, 0 );
+ RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, 0, 0, 1 );
assert( RetValue );
}
*/
@@ -165,7 +174,7 @@ int Pdr_ManPushClauses( Pdr_Man_t * p )
}
// check if the clause can be moved to the next frame
- RetValue2 = Pdr_ManCheckCube( p, k, pCubeK, NULL, 0, 0 );
+ RetValue2 = Pdr_ManCheckCube( p, k, pCubeK, NULL, 0, 0, 1 );
if ( RetValue2 == -1 )
return -1;
if ( !RetValue2 )
@@ -296,6 +305,213 @@ int * Pdr_ManSortByPriority( Pdr_Man_t * p, Pdr_Set_t * pCube )
/**Function*************************************************************
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int ZPdr_ManSimpleMic( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube )
+{
+ int * pOrder;
+ int i, j, Lit, RetValue;
+ Pdr_Set_t * pCubeTmp;
+ // perform generalization
+ if ( p->pPars->fSkipGeneral )
+ return 0;
+
+ // sort literals by their occurences
+ pOrder = Pdr_ManSortByPriority( p, *ppCube );
+ // try removing literals
+ for ( j = 0; j < (*ppCube)->nLits; j++ )
+ {
+ // use ordering
+ // i = j;
+ i = pOrder[j];
+
+ assert( (*ppCube)->Lits[i] != -1 );
+ // check init state
+ if ( Pdr_SetIsInit(*ppCube, i) )
+ continue;
+ // try removing this literal
+ Lit = (*ppCube)->Lits[i]; (*ppCube)->Lits[i] = -1;
+ RetValue = Pdr_ManCheckCube( p, k, *ppCube, NULL, p->pPars->nConfLimit, 0, 1 );
+ if ( RetValue == -1 )
+ return -1;
+ (*ppCube)->Lits[i] = Lit;
+ if ( RetValue == 0 )
+ continue;
+
+ // success - update the cube
+ *ppCube = Pdr_SetCreateFrom( pCubeTmp = *ppCube, i );
+ Pdr_SetDeref( pCubeTmp );
+ assert( (*ppCube)->nLits > 0 );
+
+ // get the ordering by decreasing priority
+ pOrder = Pdr_ManSortByPriority( p, *ppCube );
+ j--;
+ }
+ return 0;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, Hash_Int_t * keep, Pdr_Set_t * pIndCube, int * added )
+{
+ int RetValue = 0, CtgRetValue, i, ctgAttempts, l, micResult;
+ int kMax = Vec_PtrSize(p->vSolvers)-1;
+ Pdr_Set_t * pCubeTmp, * pCubeMin, * pCtg;
+ while ( RetValue == 0 )
+ {
+ ctgAttempts = 0;
+ while ( p->pPars->fCtgs && RetValue == 0 && k > 1 && ctgAttempts < 3 )
+ {
+ pCtg = Pdr_SetDup( pPred );
+ //Check CTG for inductiveness
+ if ( Pdr_SetIsInit( pCtg, -1 ) )
+ {
+ Pdr_SetDeref( pCtg );
+ break;
+ }
+ if (*added == 0)
+ {
+ for ( i = 1; i <= k; i++ )
+ Pdr_ManSolverAddClause( p, i, pIndCube);
+ *added = 1;
+ }
+ ctgAttempts++;
+ CtgRetValue = Pdr_ManCheckCube( p, k-1, pCtg, NULL, p->pPars->nConfLimit, 0, 1 );
+ if ( CtgRetValue != 1 )
+ {
+ Pdr_SetDeref( pCtg );
+ break;
+ }
+ pCubeMin = Pdr_ManReduceClause( p, k-1, pCtg );
+ if ( pCubeMin == NULL )
+ pCubeMin = Pdr_SetDup ( pCtg );
+
+ for ( l = k; l < kMax; l++ )
+ if ( !Pdr_ManCheckCube( p, l, pCubeMin, NULL, 0, 0, 1 ) )
+ break;
+ micResult = ZPdr_ManSimpleMic( p, l-1, &pCubeMin );
+ assert ( micResult != -1 );
+
+ // add new clause
+ if ( p->pPars->fVeryVerbose )
+ {
+ Abc_Print( 1, "Adding cube " );
+ Pdr_SetPrint( stdout, pCubeMin, Aig_ManRegNum(p->pAig), NULL );
+ Abc_Print( 1, " to frame %d.\n", l );
+ }
+ // set priority flops
+ for ( i = 0; i < pCubeMin->nLits; i++ )
+ {
+ assert( pCubeMin->Lits[i] >= 0 );
+ assert( (pCubeMin->Lits[i] / 2) < Aig_ManRegNum(p->pAig) );
+ if ( (Vec_IntEntry(p->vPrio, pCubeMin->Lits[i] / 2) >> p->nPrioShift) == 0 )
+ p->nAbsFlops++;
+ Vec_IntAddToEntry( p->vPrio, pCubeMin->Lits[i] / 2, 1 << p->nPrioShift );
+ }
+
+ Vec_VecPush( p->vClauses, l, pCubeMin ); // consume ref
+ p->nCubes++;
+ // add clause
+ for ( i = 1; i <= l; i++ )
+ Pdr_ManSolverAddClause( p, i, pCubeMin );
+ Pdr_SetDeref( pPred );
+ RetValue = Pdr_ManCheckCube( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0, 1 );
+ assert( RetValue >= 0 );
+ Pdr_SetDeref( pCtg );
+ if ( RetValue == 1 )
+ {
+ //printf ("IT'S A ONE\n");
+ return 1;
+ }
+ }
+
+ //join
+ if ( p->pPars->fVeryVerbose )
+ {
+ printf("Cube:\n");
+ ZPdr_SetPrint( *ppCube );
+ printf("\nPred:\n");
+ ZPdr_SetPrint( pPred );
+ }
+ *ppCube = ZPdr_SetIntersection( pCubeTmp = *ppCube, pPred, keep );
+ Pdr_SetDeref( pCubeTmp );
+ Pdr_SetDeref( pPred );
+ if ( *ppCube == NULL )
+ return 0;
+ if ( p->pPars->fVeryVerbose )
+ {
+ printf("Intersection:\n");
+ ZPdr_SetPrint( *ppCube );
+ }
+ if ( Pdr_SetIsInit( *ppCube, -1 ) )
+ {
+ if ( p->pPars->fVeryVerbose )
+ printf ("Failed initiation\n");
+ return 0;
+ }
+ RetValue = Pdr_ManCheckCube( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0, 1 );
+ if ( RetValue == -1 )
+ return -1;
+ if ( RetValue == 1 )
+ {
+ //printf ("*********IT'S A ONE\n");
+ break;
+ }
+ if ( RetValue == 0 && (*ppCube)->nLits == 1)
+ {
+ Pdr_SetDeref( pPred ); // fixed memory leak
+ // A workaround for the incomplete assignment returned by the SAT
+ // solver
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Specialized sorting of flops based on cost.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntSelectSortCostReverseLit( int * pArray, int nSize, Vec_Int_t * vCosts )
+{
+ int i, j, best_i;
+ for ( i = 0; i < nSize-1; i++ )
+ {
+ best_i = i;
+ for ( j = i+1; j < nSize; j++ )
+ if ( Vec_IntEntry(vCosts, Abc_Lit2Var(pArray[j])) > Vec_IntEntry(vCosts, Abc_Lit2Var(pArray[best_i])) )
+ best_i = j;
+ ABC_SWAP( int, pArray[i], pArray[best_i] );
+ }
+}
+
+/**Function*************************************************************
+
Synopsis [Returns 1 if the state could be blocked.]
Description []
@@ -307,20 +523,28 @@ int * Pdr_ManSortByPriority( Pdr_Man_t * p, Pdr_Set_t * pCube )
***********************************************************************/
int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPred, Pdr_Set_t ** ppCubeMin )
{
- Pdr_Set_t * pCubeMin, * pCubeTmp = NULL;
- int i, j, n, Lit, RetValue;
+ Pdr_Set_t * pCubeMin, * pCubeTmp = NULL, * pPred = NULL, * pCubeCpy = NULL;
+ int i, j, Lit, RetValue;
abctime clk = Abc_Clock();
int * pOrder;
+ int added = 0;
+ Hash_Int_t * keep = NULL;
// if there is no induction, return
*ppCubeMin = NULL;
- RetValue = Pdr_ManCheckCube( p, k, pCube, ppPred, p->pPars->nConfLimit, 0 );
+ if ( p->pPars->fFlopOrder )
+ Vec_IntSelectSortCostReverseLit( pCube->Lits, pCube->nLits, p->vPrio );
+ RetValue = Pdr_ManCheckCube( p, k, pCube, ppPred, p->pPars->nConfLimit, 0, 1 );
+ if ( p->pPars->fFlopOrder )
+ Vec_IntSelectSort( pCube->Lits, pCube->nLits );
if ( RetValue == -1 )
return -1;
if ( RetValue == 0 )
{
- p->tGeneral += Abc_Clock() - clk;
+ p->tGeneral += clock() - clk;
return 0;
}
+
+ keep = p->pPars->fSkipDown ? NULL : Hash_IntAlloc( 1 );
// reduce clause using assumptions
// pCubeMin = Pdr_SetDup( pCube );
@@ -331,6 +555,16 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP
// perform generalization
if ( !p->pPars->fSkipGeneral )
{
+ // assume the unminimized cube
+ if ( p->pPars->fSimpleGeneral )
+ {
+ sat_solver * pSat = Pdr_ManFetchSolver( p, k );
+ Vec_Int_t * vLits1 = Pdr_ManCubeToLits( p, k, pCubeMin, 1, 0 );
+ int RetValue1 = sat_solver_addclause( pSat, Vec_IntArray(vLits1), Vec_IntArray(vLits1) + Vec_IntSize(vLits1) );
+ assert( RetValue1 == 1 );
+ sat_solver_compress( pSat );
+ }
+
// sort literals by their occurences
pOrder = Pdr_ManSortByPriority( p, pCubeMin );
// try removing literals
@@ -340,13 +574,23 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP
// i = j;
i = pOrder[j];
- // check init state
assert( pCubeMin->Lits[i] != -1 );
+ if ( keep && Hash_IntExists( keep, pCubeMin->Lits[i] ) )
+ {
+ //printf("Undroppable\n");
+ continue;
+ }
+
+ // check init state
if ( Pdr_SetIsInit(pCubeMin, i) )
continue;
+
// try removing this literal
- Lit = pCubeMin->Lits[i]; pCubeMin->Lits[i] = -1;
- RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 1 );
+ Lit = pCubeMin->Lits[i]; pCubeMin->Lits[i] = -1;
+ if ( p->pPars->fSkipDown )
+ RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 1, !p->pPars->fSimpleGeneral );
+ else
+ RetValue = Pdr_ManCheckCube( p, k, pCubeMin, &pPred, p->pPars->nConfLimit, 1, !p->pPars->fSimpleGeneral );
if ( RetValue == -1 )
{
Pdr_SetDeref( pCubeMin );
@@ -354,21 +598,58 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP
}
pCubeMin->Lits[i] = Lit;
if ( RetValue == 0 )
+ {
+ if ( p->pPars->fSkipDown )
+ continue;
+ pCubeCpy = Pdr_SetCreateFrom( pCubeMin, i );
+ RetValue = ZPdr_ManDown( p, k, &pCubeCpy, pPred, keep, pCubeMin, &added );
+ if ( p->pPars->fCtgs )
+ //CTG handling code messes up with the internal order array
+ pOrder = Pdr_ManSortByPriority( p, pCubeMin );
+ if ( RetValue == -1 )
+ {
+ Pdr_SetDeref( pCubeMin );
+ Pdr_SetDeref( pCubeCpy );
+ Pdr_SetDeref( pPred );
+ return -1;
+ }
+ if ( RetValue == 0 )
+ {
+ if ( keep )
+ Hash_IntWriteEntry( keep, pCubeMin->Lits[i], 0 );
+ if ( pCubeCpy )
+ Pdr_SetDeref( pCubeCpy );
+ continue;
+ }
+ //Inductive subclause
+ added = 0;
+ Pdr_SetDeref( pCubeMin );
+ pCubeMin = pCubeCpy;
+ assert( pCubeMin->nLits > 0 );
+ pOrder = Pdr_ManSortByPriority( p, pCubeMin );
+ j = -1;
continue;
-
- // remove j-th entry
- for ( n = j; n < pCubeMin->nLits-1; n++ )
- pOrder[n] = pOrder[n+1];
- j--;
+ }
+ added = 0;
// success - update the cube
pCubeMin = Pdr_SetCreateFrom( pCubeTmp = pCubeMin, i );
Pdr_SetDeref( pCubeTmp );
assert( pCubeMin->nLits > 0 );
- i--;
- // get the ordering by decreasing priorit
+ // assume the minimized cube
+ if ( p->pPars->fSimpleGeneral )
+ {
+ sat_solver * pSat = Pdr_ManFetchSolver( p, k );
+ Vec_Int_t * vLits1 = Pdr_ManCubeToLits( p, k, pCubeMin, 1, 0 );
+ int RetValue1 = sat_solver_addclause( pSat, Vec_IntArray(vLits1), Vec_IntArray(vLits1) + Vec_IntSize(vLits1) );
+ assert( RetValue1 == 1 );
+ sat_solver_compress( pSat );
+ }
+
+ // get the ordering by decreasing priority
pOrder = Pdr_ManSortByPriority( p, pCubeMin );
+ j--;
}
if ( p->pPars->fTwoRounds )
@@ -383,8 +664,8 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP
if ( Pdr_SetIsInit(pCubeMin, i) )
continue;
// try removing this literal
- Lit = pCubeMin->Lits[i]; pCubeMin->Lits[i] = -1;
- RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 0 );
+ Lit = pCubeMin->Lits[i]; pCubeMin->Lits[i] = -1;
+ RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 0, 1 );
if ( RetValue == -1 )
{
Pdr_SetDeref( pCubeMin );
@@ -394,25 +675,30 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP
if ( RetValue == 0 )
continue;
- // remove j-th entry
- for ( n = j; n < pCubeMin->nLits-1; n++ )
- pOrder[n] = pOrder[n+1];
- j--;
-
// success - update the cube
pCubeMin = Pdr_SetCreateFrom( pCubeTmp = pCubeMin, i );
Pdr_SetDeref( pCubeTmp );
assert( pCubeMin->nLits > 0 );
- i--;
- // get the ordering by decreasing priorit
+ // get the ordering by decreasing priority
pOrder = Pdr_ManSortByPriority( p, pCubeMin );
+ j--;
}
}
assert( ppCubeMin != NULL );
+ if ( p->pPars->fVeryVerbose )
+ {
+ printf("Cube:\n");
+ for ( i = 0; i < pCubeMin->nLits; i++)
+ {
+ printf ("%d ", pCubeMin->Lits[i]);
+ }
+ printf("\n");
+ }
*ppCubeMin = pCubeMin;
p->tGeneral += Abc_Clock() - clk;
+ if ( keep ) Hash_IntFree( keep );
return 1;
}
@@ -444,7 +730,7 @@ int Pdr_ManBlockCube( Pdr_Man_t * p, Pdr_Set_t * pCube )
{
Counter++;
pThis = Pdr_QueueHead( p );
- if ( pThis->iFrame == 0 )
+ if ( pThis->iFrame == 0 || (p->pPars->fUseAbs && Pdr_SetIsInit(pThis->pState, -1)) )
return 0; // SAT
if ( pThis->iFrame > kMax ) // finished this level
return 1;
@@ -497,7 +783,7 @@ int Pdr_ManBlockCube( Pdr_Man_t * p, Pdr_Set_t * pCube )
assert( pPred == NULL );
for ( k = pThis->iFrame; k < kMax; k++ )
{
- RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, 0, 0 );
+ RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, 0, 0, 1 );
if ( RetValue == -1 )
{
Pdr_OblDeref( pThis );
@@ -518,7 +804,9 @@ int Pdr_ManBlockCube( Pdr_Man_t * p, Pdr_Set_t * pCube )
{
assert( pCubeMin->Lits[i] >= 0 );
assert( (pCubeMin->Lits[i] / 2) < Aig_ManRegNum(p->pAig) );
- Vec_IntAddToEntry( p->vPrio, pCubeMin->Lits[i] / 2, 1 );
+ if ( (Vec_IntEntry(p->vPrio, pCubeMin->Lits[i] / 2) >> p->nPrioShift) == 0 )
+ p->nAbsFlops++;
+ Vec_IntAddToEntry( p->vPrio, pCubeMin->Lits[i] / 2, 1 << p->nPrioShift );
}
Vec_VecPush( p->vClauses, k, pCubeMin ); // consume ref
p->nCubes++;
@@ -577,29 +865,43 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
Pdr_Set_t * pCube = NULL;
Aig_Obj_t * pObj;
Abc_Cex_t * pCexNew;
- int k, RetValue = -1;
+ int iFrame, RetValue = -1;
int nOutDigits = Abc_Base10Log( Saig_ManPoNum(p->pAig) );
abctime clkStart = Abc_Clock(), clkOne = 0;
p->timeToStop = p->pPars->nTimeOut ? p->pPars->nTimeOut * CLOCKS_PER_SEC + Abc_Clock(): 0;
assert( Vec_PtrSize(p->vSolvers) == 0 );
// in the multi-output mode, mark trivial POs (those fed by const0) as solved
if ( p->pPars->fSolveAll )
- Saig_ManForEachPo( p->pAig, pObj, k )
+ Saig_ManForEachPo( p->pAig, pObj, iFrame )
if ( Aig_ObjChild0(pObj) == Aig_ManConst0(p->pAig) )
{
- Vec_IntWriteEntry( p->pPars->vOutMap, k, 1 ); // unsat
+ Vec_IntWriteEntry( p->pPars->vOutMap, iFrame, 1 ); // unsat
p->pPars->nProveOuts++;
if ( p->pPars->fUseBridge )
- Gia_ManToBridgeResult( stdout, 1, NULL, k );
+ Gia_ManToBridgeResult( stdout, 1, NULL, iFrame );
}
// create the first timeframe
p->pPars->timeLastSolved = Abc_Clock();
- Pdr_ManCreateSolver( p, (k = 0) );
+ Pdr_ManCreateSolver( p, (iFrame = 0) );
while ( 1 )
{
- p->nFrames = k;
- assert( k == Vec_PtrSize(p->vSolvers)-1 );
- p->iUseFrame = Abc_MaxInt(k, 1);
+ int fRefined = 0;
+ if ( p->pPars->fUseAbs && p->vAbsFlops == NULL && iFrame == 1 )
+ {
+// int i, Prio;
+ assert( p->vAbsFlops == NULL );
+ p->vAbsFlops = Vec_IntStart( Saig_ManRegNum(p->pAig) );
+ p->vMapFf2Ppi = Vec_IntStartFull( Saig_ManRegNum(p->pAig) );
+ p->vMapPpi2Ff = Vec_IntAlloc( 100 );
+// Vec_IntForEachEntry( p->vPrio, Prio, i )
+// if ( Prio >> p->nPrioShift )
+// Vec_IntWriteEntry( p->vAbsFlops, i, 1 );
+ }
+ //if ( p->pPars->fUseAbs && p->vAbsFlops )
+ // printf( "Starting frame %d with %d (%d) flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops), Vec_IntCountPositive(p->vPrio) );
+ p->nFrames = iFrame;
+ assert( iFrame == Vec_PtrSize(p->vSolvers)-1 );
+ p->iUseFrame = Abc_MaxInt(iFrame, 1);
Saig_ManForEachPo( p->pAig, pObj, p->iOutCur )
{
// skip disproved outputs
@@ -616,16 +918,16 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
{
if ( !p->pPars->fSolveAll )
{
- pCexNew = Abc_CexMakeTriv( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), k*Saig_ManPoNum(p->pAig)+p->iOutCur );
+ pCexNew = Abc_CexMakeTriv( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), iFrame*Saig_ManPoNum(p->pAig)+p->iOutCur );
p->pAig->pSeqModel = pCexNew;
return 0; // SAT
}
- pCexNew = (p->pPars->fUseBridge || p->pPars->fStoreCex) ? Abc_CexMakeTriv( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), k*Saig_ManPoNum(p->pAig)+p->iOutCur ) : (Abc_Cex_t *)(ABC_PTRINT_T)1;
+ pCexNew = (p->pPars->fUseBridge || p->pPars->fStoreCex) ? Abc_CexMakeTriv( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), iFrame*Saig_ManPoNum(p->pAig)+p->iOutCur ) : (Abc_Cex_t *)(ABC_PTRINT_T)1;
p->pPars->nFailOuts++;
if ( p->pPars->vOutMap ) Vec_IntWriteEntry( p->pPars->vOutMap, p->iOutCur, 0 );
if ( !p->pPars->fNotVerbose )
Abc_Print( 1, "Output %*d was trivially asserted in frame %2d (solved %*d out of %*d outputs).\n",
- nOutDigits, p->iOutCur, k, nOutDigits, p->pPars->nFailOuts, nOutDigits, Saig_ManPoNum(p->pAig) );
+ nOutDigits, p->iOutCur, iFrame, nOutDigits, p->pPars->nFailOuts, nOutDigits, Saig_ManPoNum(p->pAig) );
assert( Vec_PtrEntry(p->vCexes, p->iOutCur) == NULL );
if ( p->pPars->fUseBridge )
Gia_ManToBridgeResult( stdout, 0, pCexNew, pCexNew->iPo );
@@ -635,8 +937,8 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
if ( p->pPars->fVerbose )
Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
if ( !p->pPars->fSilent )
- Abc_Print( 1, "Quitting due to callback on fail.\n" );
- p->pPars->iFrame = k;
+ Abc_Print( 1, "Quitting due to callback on fail in frame %d.\n", iFrame );
+ p->pPars->iFrame = iFrame;
return -1;
}
if ( p->pPars->nFailOuts + p->pPars->nDropOuts == Saig_ManPoNum(p->pAig) )
@@ -658,11 +960,11 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
if ( p->pPars->fVerbose )
Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
if ( !p->pPars->fSilent )
- Abc_Print( 1, "Reached gap timeout (%d seconds).\n", p->pPars->nTimeOutGap );
- p->pPars->iFrame = k;
+ Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame );
+ p->pPars->iFrame = iFrame;
return -1;
}
- RetValue = Pdr_ManCheckCube( p, k, NULL, &pCube, p->pPars->nConfLimit, 0 );
+ RetValue = Pdr_ManCheckCube( p, iFrame, NULL, &pCube, p->pPars->nConfLimit, 0, 1 );
if ( RetValue == 1 )
break;
if ( RetValue == -1 )
@@ -670,9 +972,9 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
if ( p->pPars->fVerbose )
Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
if ( p->timeToStop && Abc_Clock() > p->timeToStop )
- Abc_Print( 1, "Reached timeout (%d seconds).\n", p->pPars->nTimeOut );
+ Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame );
else if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC )
- Abc_Print( 1, "Reached gap timeout (%d seconds).\n", p->pPars->nTimeOutGap );
+ Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame );
else if ( p->timeToStopOne && Abc_Clock() > p->timeToStopOne )
{
Pdr_QueueClean( p );
@@ -680,10 +982,10 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
break; // keep solving
}
else if ( p->pPars->nConfLimit )
- Abc_Print( 1, "Reached conflict limit (%d).\n", p->pPars->nConfLimit );
+ Abc_Print( 1, "Reached conflict limit (%d) in frame %d.\n", p->pPars->nConfLimit, iFrame );
else if ( p->pPars->fVerbose )
- Abc_Print( 1, "Computation cancelled by the callback.\n" );
- p->pPars->iFrame = k;
+ Abc_Print( 1, "Computation cancelled by the callback in frame %d.\n", iFrame );
+ p->pPars->iFrame = iFrame;
return -1;
}
if ( RetValue == 0 )
@@ -694,9 +996,9 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
if ( p->pPars->fVerbose )
Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
if ( p->timeToStop && Abc_Clock() > p->timeToStop )
- Abc_Print( 1, "Reached timeout (%d seconds).\n", p->pPars->nTimeOut );
+ Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame );
else if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC )
- Abc_Print( 1, "Reached gap timeout (%d seconds).\n", p->pPars->nTimeOutGap );
+ Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame );
else if ( p->timeToStopOne && Abc_Clock() > p->timeToStopOne )
{
Pdr_QueueClean( p );
@@ -704,25 +1006,36 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
break; // keep solving
}
else if ( p->pPars->nConfLimit )
- Abc_Print( 1, "Reached conflict limit (%d).\n", p->pPars->nConfLimit );
+ Abc_Print( 1, "Reached conflict limit (%d) in frame %d.\n", p->pPars->nConfLimit, iFrame );
else if ( p->pPars->fVerbose )
- Abc_Print( 1, "Computation cancelled by the callback.\n" );
- p->pPars->iFrame = k;
+ Abc_Print( 1, "Computation cancelled by the callback in frame %d.\n", iFrame );
+ p->pPars->iFrame = iFrame;
return -1;
}
if ( RetValue == 0 )
{
if ( fPrintClauses )
{
- Abc_Print( 1, "*** Clauses after frame %d:\n", k );
+ Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame );
Pdr_ManPrintClauses( p, 0 );
}
- if ( p->pPars->fVerbose )
+ if ( p->pPars->fVerbose && !p->pPars->fUseAbs )
Pdr_ManPrintProgress( p, !p->pPars->fSolveAll, Abc_Clock() - clkStart );
- p->pPars->iFrame = k;
+ p->pPars->iFrame = iFrame;
if ( !p->pPars->fSolveAll )
{
- p->pAig->pSeqModel = Pdr_ManDeriveCex(p);
+ abctime clk = Abc_Clock();
+ Abc_Cex_t * pCex = Pdr_ManDeriveCexAbs(p);
+ p->tAbs += Abc_Clock() - clk;
+ if ( pCex == NULL )
+ {
+ assert( p->pPars->fUseAbs );
+ Pdr_QueueClean( p );
+ pCube = NULL;
+ fRefined = 1;
+ break; // keep solving
+ }
+ p->pAig->pSeqModel = pCex;
return 0; // SAT
}
p->pPars->nFailOuts++;
@@ -737,13 +1050,13 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
if ( p->pPars->fVerbose )
Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
if ( !p->pPars->fSilent )
- Abc_Print( 1, "Quitting due to callback on fail.\n" );
- p->pPars->iFrame = k;
+ Abc_Print( 1, "Quitting due to callback on fail in frame %d.\n", iFrame );
+ p->pPars->iFrame = iFrame;
return -1;
}
if ( !p->pPars->fNotVerbose )
Abc_Print( 1, "Output %*d was asserted in frame %2d (%2d) (solved %*d out of %*d outputs).\n",
- nOutDigits, p->iOutCur, k, k, nOutDigits, p->pPars->nFailOuts, nOutDigits, Saig_ManPoNum(p->pAig) );
+ nOutDigits, p->iOutCur, iFrame, iFrame, nOutDigits, p->pPars->nFailOuts, nOutDigits, Saig_ManPoNum(p->pAig) );
if ( p->pPars->nFailOuts == Saig_ManPoNum(p->pAig) )
return 0; // all SAT
Pdr_QueueClean( p );
@@ -754,6 +1067,8 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
Pdr_ManPrintProgress( p, 0, Abc_Clock() - clkStart );
}
}
+ if ( fRefined )
+ break;
if ( p->pTime4Outs )
{
abctime timeSince = Abc_Clock() - clkOne;
@@ -765,22 +1080,32 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
if ( p->pPars->vOutMap )
Vec_IntWriteEntry( p->pPars->vOutMap, p->iOutCur, -1 );
if ( !p->pPars->fNotVerbose )
- Abc_Print( 1, "Timing out on output %*d.\n", nOutDigits, p->iOutCur );
+ Abc_Print( 1, "Timing out on output %*d in frame %d.\n", nOutDigits, p->iOutCur, iFrame );
}
p->timeToStopOne = 0;
}
}
-
+ if ( p->pPars->fUseAbs && p->vAbsFlops && !fRefined )
+ {
+ int i, Used;
+ Vec_IntForEachEntry( p->vAbsFlops, Used, i )
+ if ( Used && (Vec_IntEntry(p->vPrio, i) >> p->nPrioShift) == 0 )
+ Vec_IntWriteEntry( p->vAbsFlops, i, 0 );
+ }
if ( p->pPars->fVerbose )
- Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ Pdr_ManPrintProgress( p, !fRefined, Abc_Clock() - clkStart );
+ if ( fRefined )
+ continue;
+ //if ( p->pPars->fUseAbs && p->vAbsFlops )
+ // printf( "Finished frame %d with %d (%d) flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops), Vec_IntCountPositive(p->vPrio) );
// open a new timeframe
p->nQueLim = p->pPars->nRestLimit;
assert( pCube == NULL );
- Pdr_ManSetPropertyOutput( p, k );
- Pdr_ManCreateSolver( p, ++k );
+ Pdr_ManSetPropertyOutput( p, iFrame );
+ Pdr_ManCreateSolver( p, ++iFrame );
if ( fPrintClauses )
{
- Abc_Print( 1, "*** Clauses after frame %d:\n", k );
+ Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame );
Pdr_ManPrintClauses( p, 0 );
}
// push clauses into this timeframe
@@ -792,11 +1117,11 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
if ( !p->pPars->fSilent )
{
if ( p->timeToStop && Abc_Clock() > p->timeToStop )
- Abc_Print( 1, "Reached timeout (%d seconds).\n", p->pPars->nTimeOut );
+ Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame );
else
- Abc_Print( 1, "Reached conflict limit (%d).\n", p->pPars->nConfLimit );
+ Abc_Print( 1, "Reached conflict limit (%d) in frame.\n", p->pPars->nConfLimit, iFrame );
}
- p->pPars->iFrame = k;
+ p->pPars->iFrame = iFrame;
return -1;
}
if ( RetValue )
@@ -807,17 +1132,17 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
Pdr_ManReportInvariant( p );
if ( !p->pPars->fSilent )
Pdr_ManVerifyInvariant( p );
- p->pPars->iFrame = k;
+ p->pPars->iFrame = iFrame;
// count the number of UNSAT outputs
p->pPars->nProveOuts = Saig_ManPoNum(p->pAig) - p->pPars->nFailOuts - p->pPars->nDropOuts;
// convert previously 'unknown' into 'unsat'
if ( p->pPars->vOutMap )
- for ( k = 0; k < Saig_ManPoNum(p->pAig); k++ )
- if ( Vec_IntEntry(p->pPars->vOutMap, k) == -2 ) // unknown
+ for ( iFrame = 0; iFrame < Saig_ManPoNum(p->pAig); iFrame++ )
+ if ( Vec_IntEntry(p->pPars->vOutMap, iFrame) == -2 ) // unknown
{
- Vec_IntWriteEntry( p->pPars->vOutMap, k, 1 ); // unsat
+ Vec_IntWriteEntry( p->pPars->vOutMap, iFrame, 1 ); // unsat
if ( p->pPars->fUseBridge )
- Gia_ManToBridgeResult( stdout, 1, NULL, k );
+ Gia_ManToBridgeResult( stdout, 1, NULL, iFrame );
}
if ( p->pPars->nProveOuts == Saig_ManPoNum(p->pAig) )
return 1; // UNSAT
@@ -831,44 +1156,44 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
// check termination
if ( p->pPars->pFuncStop && p->pPars->pFuncStop(p->pPars->RunId) )
{
- p->pPars->iFrame = k;
+ p->pPars->iFrame = iFrame;
return -1;
}
if ( p->timeToStop && Abc_Clock() > p->timeToStop )
{
if ( fPrintClauses )
{
- Abc_Print( 1, "*** Clauses after frame %d:\n", k );
+ Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame );
Pdr_ManPrintClauses( p, 0 );
}
if ( p->pPars->fVerbose )
Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
if ( !p->pPars->fSilent )
- Abc_Print( 1, "Reached timeout (%d seconds).\n", p->pPars->nTimeOut );
- p->pPars->iFrame = k;
+ Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame );
+ p->pPars->iFrame = iFrame;
return -1;
}
if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC )
{
if ( fPrintClauses )
{
- Abc_Print( 1, "*** Clauses after frame %d:\n", k );
+ Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame );
Pdr_ManPrintClauses( p, 0 );
}
if ( p->pPars->fVerbose )
Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
if ( !p->pPars->fSilent )
- Abc_Print( 1, "Reached gap timeout (%d seconds).\n", p->pPars->nTimeOutGap );
- p->pPars->iFrame = k;
+ Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame );
+ p->pPars->iFrame = iFrame;
return -1;
}
- if ( p->pPars->nFrameMax && k >= p->pPars->nFrameMax )
+ if ( p->pPars->nFrameMax && iFrame >= p->pPars->nFrameMax )
{
if ( p->pPars->fVerbose )
Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
if ( !p->pPars->fSilent )
Abc_Print( 1, "Reached limit on the number of timeframes (%d).\n", p->pPars->nFrameMax );
- p->pPars->iFrame = k;
+ p->pPars->iFrame = iFrame;
return -1;
}
}
@@ -922,11 +1247,12 @@ int Pdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars )
}
if ( p->pPars->fDumpInv )
{
- Abc_FrameSetCnf( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) );
- Abc_FrameSetStr( Pdr_ManDumpString(p) );
- Abc_FrameSetInv( Pdr_ManCountFlopsInv(p) );
- Pdr_ManDumpClauses( p, (char *)"inv.pla", RetValue==1 );
+ char * pFileName = Extra_FileNameGenericAppend(p->pAig->pName, "_inv.pla");
+ Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) );
+ Pdr_ManDumpClauses( p, pFileName, RetValue==1 );
}
+ else if ( RetValue == 1 )
+ Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) );
p->tTotal += Abc_Clock() - clk;
Pdr_ManStop( p );
pPars->iFrame--;
diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c
new file mode 100644
index 00000000..3fcd3d31
--- /dev/null
+++ b/src/proof/pdr/pdrIncr.c
@@ -0,0 +1,760 @@
+/**CFile****************************************************************
+
+ FileName [pdrIncr.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Property driven reachability.]
+
+ Synopsis [PDR with incremental solving.]
+
+ Author [Yen-Sheng Ho, Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - Feb. 17, 2017.]
+
+ Revision [$Id: pdrIncr.c$]
+
+***********************************************************************/
+
+#include "pdrInt.h"
+#include "base/main/main.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters );
+extern int Pdr_ManBlockCube( Pdr_Man_t * p, Pdr_Set_t * pCube );
+extern int Pdr_ManPushClauses( Pdr_Man_t * p );
+extern int Gia_ManToBridgeAbort( FILE * pFile, int Size, unsigned char * pBuffer );
+extern int Gia_ManToBridgeResult( FILE * pFile, int Result, Abc_Cex_t * pCex, int iPoProved );
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void IPdr_ManPrintClauses( Vec_Vec_t * vClauses, int kStart, int nRegs )
+{
+ Vec_Ptr_t * vArrayK;
+ Pdr_Set_t * pCube;
+ int i, k, Counter = 0;
+ Vec_VecForEachLevelStart( vClauses, vArrayK, k, kStart )
+ {
+ Vec_PtrSort( vArrayK, (int (*)(void))Pdr_SetCompare );
+ Vec_PtrForEachEntry( Pdr_Set_t *, vArrayK, pCube, i )
+ {
+ Abc_Print( 1, "C=%4d. F=%4d ", Counter++, k );
+ Pdr_SetPrint( stdout, pCube, nRegs, NULL );
+ Abc_Print( 1, "\n" );
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [ Check if each cube c_k in frame k satisfies the query
+ R_{k-1} && T && !c_k && c_k' (must be UNSAT).
+ Return True if all cubes pass the check. ]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IPdr_ManCheckClauses( Pdr_Man_t * p )
+{
+ Pdr_Set_t * pCubeK;
+ Vec_Ptr_t * vArrayK;
+ int j, k, RetValue, kMax = Vec_PtrSize(p->vSolvers);
+ int iStartFrame = 1;
+ int counter = 0;
+
+ Vec_VecForEachLevelStartStop( p->vClauses, vArrayK, k, iStartFrame, kMax )
+ {
+ Vec_PtrForEachEntry( Pdr_Set_t *, vArrayK, pCubeK, j )
+ {
+ ++counter;
+ RetValue = Pdr_ManCheckCube( p, k - 1, pCubeK, NULL, 0, 0, 1 );
+
+ if ( !RetValue ) {
+ printf( "Cube[%d][%d] not inductive!\n", k, j );
+ }
+
+ assert( RetValue == 1 );
+ }
+ }
+
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Vec_t * IPdr_ManSaveClauses( Pdr_Man_t * p, int fDropLast )
+{
+ int i, k;
+ Vec_Vec_t * vClausesSaved;
+ Pdr_Set_t * pCla;
+
+ if ( Vec_VecSize( p->vClauses ) == 1 )
+ return NULL;
+ if ( Vec_VecSize( p->vClauses ) == 2 && fDropLast )
+ return NULL;
+
+ if ( fDropLast )
+ vClausesSaved = Vec_VecStart( Vec_VecSize(p->vClauses)-1 );
+ else
+ vClausesSaved = Vec_VecStart( Vec_VecSize(p->vClauses) );
+
+ Vec_VecForEachEntryStartStop( Pdr_Set_t *, p->vClauses, pCla, i, k, 0, Vec_VecSize(vClausesSaved) )
+ Vec_VecPush(vClausesSaved, i, Pdr_SetDup(pCla));
+
+ return vClausesSaved;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+sat_solver * IPdr_ManSetSolver( Pdr_Man_t * p, int k, int nTotal )
+{
+ sat_solver * pSat;
+ Vec_Ptr_t * vArrayK;
+ Pdr_Set_t * pCube;
+ int i, j;
+
+ assert( Vec_PtrSize(p->vSolvers) == k );
+ assert( Vec_IntSize(p->vActVars) == k );
+
+ pSat = zsat_solver_new_seed(p->pPars->nRandomSeed);
+ pSat = Pdr_ManNewSolver( pSat, p, k, (int)(k == 0) );
+ Vec_PtrPush( p->vSolvers, pSat );
+ Vec_IntPush( p->vActVars, 0 );
+
+ // set the property output
+ if ( k < nTotal - 1 )
+ Pdr_ManSetPropertyOutput( p, k );
+
+ if (k == 0)
+ return pSat;
+
+ // add the clauses
+ Vec_VecForEachLevelStart( p->vClauses, vArrayK, i, k )
+ Vec_PtrForEachEntry( Pdr_Set_t *, vArrayK, pCube, j )
+ Pdr_ManSolverAddClause( p, k, pCube );
+ return pSat;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses, Vec_Int_t * vMap )
+{
+ int i;
+
+ assert(vClauses);
+
+ Vec_VecFree(p->vClauses);
+ p->vClauses = vClauses;
+
+ // remap clause literals using mapping (old flop -> new flop) found in array vMap
+ if ( vMap )
+ {
+ Pdr_Set_t * pSet; int j, k;
+ Vec_VecForEachEntry( Pdr_Set_t *, vClauses, pSet, i, j )
+ for ( k = 0; k < pSet->nLits; k++ )
+ pSet->Lits[k] = Abc_Lit2LitV( Vec_IntArray(vMap), pSet->Lits[k] );
+ }
+
+ for ( i = 0; i < Vec_VecSize(p->vClauses); ++i )
+ IPdr_ManSetSolver( p, i, Vec_VecSize( p->vClauses ) );
+
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IPdr_ManSolveInt( Pdr_Man_t * p, int fCheckClauses, int fPushClauses )
+{
+ int fPrintClauses = 0;
+ Pdr_Set_t * pCube = NULL;
+ Aig_Obj_t * pObj;
+ Abc_Cex_t * pCexNew;
+ int iFrame, RetValue = -1;
+ int nOutDigits = Abc_Base10Log( Saig_ManPoNum(p->pAig) );
+ abctime clkStart = Abc_Clock(), clkOne = 0;
+ p->timeToStop = p->pPars->nTimeOut ? p->pPars->nTimeOut * CLOCKS_PER_SEC + Abc_Clock(): 0;
+ // assert( Vec_PtrSize(p->vSolvers) == 0 );
+ // in the multi-output mode, mark trivial POs (those fed by const0) as solved
+ if ( p->pPars->fSolveAll )
+ Saig_ManForEachPo( p->pAig, pObj, iFrame )
+ if ( Aig_ObjChild0(pObj) == Aig_ManConst0(p->pAig) )
+ {
+ Vec_IntWriteEntry( p->pPars->vOutMap, iFrame, 1 ); // unsat
+ p->pPars->nProveOuts++;
+ if ( p->pPars->fUseBridge )
+ Gia_ManToBridgeResult( stdout, 1, NULL, iFrame );
+ }
+ // create the first timeframe
+ p->pPars->timeLastSolved = Abc_Clock();
+
+ if ( Vec_VecSize(p->vClauses) == 0 )
+ Pdr_ManCreateSolver( p, (iFrame = 0) );
+ else {
+ iFrame = Vec_VecSize(p->vClauses) - 1;
+
+ if ( fCheckClauses )
+ {
+ if ( p->pPars->fVerbose )
+ Abc_Print( 1, "IPDR: Checking the reloaded length-%d trace...", iFrame + 1 ) ;
+ IPdr_ManCheckClauses( p );
+ if ( p->pPars->fVerbose )
+ Abc_Print( 1, " Passed!\n" ) ;
+ }
+
+ if ( fPushClauses )
+ {
+ p->iUseFrame = Abc_MaxInt(iFrame, 1);
+
+ if ( p->pPars->fVerbose )
+ {
+ Abc_Print( 1, "IPDR: Pushing the reloaded clauses. Before:\n" );
+ Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ }
+
+ RetValue = Pdr_ManPushClauses( p );
+
+ if ( p->pPars->fVerbose )
+ {
+ Abc_Print( 1, "IPDR: Finished pushing. After:\n" );
+ Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ }
+
+ if ( RetValue )
+ {
+ Pdr_ManReportInvariant( p );
+ Pdr_ManVerifyInvariant( p );
+ return 1;
+ }
+ }
+ }
+ while ( 1 )
+ {
+ int fRefined = 0;
+ if ( p->pPars->fUseAbs && p->vAbsFlops == NULL && iFrame == 1 )
+ {
+// int i, Prio;
+ assert( p->vAbsFlops == NULL );
+ p->vAbsFlops = Vec_IntStart( Saig_ManRegNum(p->pAig) );
+ p->vMapFf2Ppi = Vec_IntStartFull( Saig_ManRegNum(p->pAig) );
+ p->vMapPpi2Ff = Vec_IntAlloc( 100 );
+// Vec_IntForEachEntry( p->vPrio, Prio, i )
+// if ( Prio >> p->nPrioShift )
+// Vec_IntWriteEntry( p->vAbsFlops, i, 1 );
+ }
+ //if ( p->pPars->fUseAbs && p->vAbsFlops )
+ // printf( "Starting frame %d with %d (%d) flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops), Vec_IntCountPositive(p->vPrio) );
+ p->nFrames = iFrame;
+ assert( iFrame == Vec_PtrSize(p->vSolvers)-1 );
+ p->iUseFrame = Abc_MaxInt(iFrame, 1);
+ Saig_ManForEachPo( p->pAig, pObj, p->iOutCur )
+ {
+ // skip disproved outputs
+ if ( p->vCexes && Vec_PtrEntry(p->vCexes, p->iOutCur) )
+ continue;
+ // skip output whose time has run out
+ if ( p->pTime4Outs && p->pTime4Outs[p->iOutCur] == 0 )
+ continue;
+ // check if the output is trivially solved
+ if ( Aig_ObjChild0(pObj) == Aig_ManConst0(p->pAig) )
+ continue;
+ // check if the output is trivially solved
+ if ( Aig_ObjChild0(pObj) == Aig_ManConst1(p->pAig) )
+ {
+ if ( !p->pPars->fSolveAll )
+ {
+ pCexNew = Abc_CexMakeTriv( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), iFrame*Saig_ManPoNum(p->pAig)+p->iOutCur );
+ p->pAig->pSeqModel = pCexNew;
+ return 0; // SAT
+ }
+ pCexNew = (p->pPars->fUseBridge || p->pPars->fStoreCex) ? Abc_CexMakeTriv( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), iFrame*Saig_ManPoNum(p->pAig)+p->iOutCur ) : (Abc_Cex_t *)(ABC_PTRINT_T)1;
+ p->pPars->nFailOuts++;
+ if ( p->pPars->vOutMap ) Vec_IntWriteEntry( p->pPars->vOutMap, p->iOutCur, 0 );
+ if ( !p->pPars->fNotVerbose )
+ Abc_Print( 1, "Output %*d was trivially asserted in frame %2d (solved %*d out of %*d outputs).\n",
+ nOutDigits, p->iOutCur, iFrame, nOutDigits, p->pPars->nFailOuts, nOutDigits, Saig_ManPoNum(p->pAig) );
+ assert( Vec_PtrEntry(p->vCexes, p->iOutCur) == NULL );
+ if ( p->pPars->fUseBridge )
+ Gia_ManToBridgeResult( stdout, 0, pCexNew, pCexNew->iPo );
+ Vec_PtrWriteEntry( p->vCexes, p->iOutCur, pCexNew );
+ if ( p->pPars->pFuncOnFail && p->pPars->pFuncOnFail(p->iOutCur, p->pPars->fStoreCex ? (Abc_Cex_t *)Vec_PtrEntry(p->vCexes, p->iOutCur) : NULL) )
+ {
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ if ( !p->pPars->fSilent )
+ Abc_Print( 1, "Quitting due to callback on fail in frame %d.\n", iFrame );
+ p->pPars->iFrame = iFrame;
+ return -1;
+ }
+ if ( p->pPars->nFailOuts + p->pPars->nDropOuts == Saig_ManPoNum(p->pAig) )
+ return p->pPars->nFailOuts ? 0 : -1; // SAT or UNDEC
+ p->pPars->timeLastSolved = Abc_Clock();
+ continue;
+ }
+ // try to solve this output
+ if ( p->pTime4Outs )
+ {
+ assert( p->pTime4Outs[p->iOutCur] > 0 );
+ clkOne = Abc_Clock();
+ p->timeToStopOne = p->pTime4Outs[p->iOutCur] + Abc_Clock();
+ }
+ while ( 1 )
+ {
+ if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC )
+ {
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ if ( !p->pPars->fSilent )
+ Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame );
+ p->pPars->iFrame = iFrame;
+ return -1;
+ }
+ RetValue = Pdr_ManCheckCube( p, iFrame, NULL, &pCube, p->pPars->nConfLimit, 0, 1 );
+ if ( RetValue == 1 )
+ break;
+ if ( RetValue == -1 )
+ {
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ if ( p->timeToStop && Abc_Clock() > p->timeToStop )
+ Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame );
+ else if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC )
+ Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame );
+ else if ( p->timeToStopOne && Abc_Clock() > p->timeToStopOne )
+ {
+ Pdr_QueueClean( p );
+ pCube = NULL;
+ break; // keep solving
+ }
+ else if ( p->pPars->nConfLimit )
+ Abc_Print( 1, "Reached conflict limit (%d) in frame %d.\n", p->pPars->nConfLimit, iFrame );
+ else if ( p->pPars->fVerbose )
+ Abc_Print( 1, "Computation cancelled by the callback in frame %d.\n", iFrame );
+ p->pPars->iFrame = iFrame;
+ return -1;
+ }
+ if ( RetValue == 0 )
+ {
+ RetValue = Pdr_ManBlockCube( p, pCube );
+ if ( RetValue == -1 )
+ {
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ if ( p->timeToStop && Abc_Clock() > p->timeToStop )
+ Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame );
+ else if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC )
+ Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame );
+ else if ( p->timeToStopOne && Abc_Clock() > p->timeToStopOne )
+ {
+ Pdr_QueueClean( p );
+ pCube = NULL;
+ break; // keep solving
+ }
+ else if ( p->pPars->nConfLimit )
+ Abc_Print( 1, "Reached conflict limit (%d) in frame %d.\n", p->pPars->nConfLimit, iFrame );
+ else if ( p->pPars->fVerbose )
+ Abc_Print( 1, "Computation cancelled by the callback in frame %d.\n", iFrame );
+ p->pPars->iFrame = iFrame;
+ return -1;
+ }
+ if ( RetValue == 0 )
+ {
+ if ( fPrintClauses )
+ {
+ Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame );
+ Pdr_ManPrintClauses( p, 0 );
+ }
+ if ( p->pPars->fVerbose && !p->pPars->fUseAbs )
+ Pdr_ManPrintProgress( p, !p->pPars->fSolveAll, Abc_Clock() - clkStart );
+ p->pPars->iFrame = iFrame;
+ if ( !p->pPars->fSolveAll )
+ {
+ abctime clk = Abc_Clock();
+ Abc_Cex_t * pCex = Pdr_ManDeriveCexAbs(p);
+ p->tAbs += Abc_Clock() - clk;
+ if ( pCex == NULL )
+ {
+ assert( p->pPars->fUseAbs );
+ Pdr_QueueClean( p );
+ pCube = NULL;
+ fRefined = 1;
+ break; // keep solving
+ }
+ p->pAig->pSeqModel = pCex;
+ return 0; // SAT
+ }
+ p->pPars->nFailOuts++;
+ pCexNew = (p->pPars->fUseBridge || p->pPars->fStoreCex) ? Pdr_ManDeriveCex(p) : (Abc_Cex_t *)(ABC_PTRINT_T)1;
+ if ( p->pPars->vOutMap ) Vec_IntWriteEntry( p->pPars->vOutMap, p->iOutCur, 0 );
+ assert( Vec_PtrEntry(p->vCexes, p->iOutCur) == NULL );
+ if ( p->pPars->fUseBridge )
+ Gia_ManToBridgeResult( stdout, 0, pCexNew, pCexNew->iPo );
+ Vec_PtrWriteEntry( p->vCexes, p->iOutCur, pCexNew );
+ if ( p->pPars->pFuncOnFail && p->pPars->pFuncOnFail(p->iOutCur, p->pPars->fStoreCex ? (Abc_Cex_t *)Vec_PtrEntry(p->vCexes, p->iOutCur) : NULL) )
+ {
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ if ( !p->pPars->fSilent )
+ Abc_Print( 1, "Quitting due to callback on fail in frame %d.\n", iFrame );
+ p->pPars->iFrame = iFrame;
+ return -1;
+ }
+ if ( !p->pPars->fNotVerbose )
+ Abc_Print( 1, "Output %*d was asserted in frame %2d (%2d) (solved %*d out of %*d outputs).\n",
+ nOutDigits, p->iOutCur, iFrame, iFrame, nOutDigits, p->pPars->nFailOuts, nOutDigits, Saig_ManPoNum(p->pAig) );
+ if ( p->pPars->nFailOuts == Saig_ManPoNum(p->pAig) )
+ return 0; // all SAT
+ Pdr_QueueClean( p );
+ pCube = NULL;
+ break; // keep solving
+ }
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, 0, Abc_Clock() - clkStart );
+ }
+ }
+ if ( fRefined )
+ break;
+ if ( p->pTime4Outs )
+ {
+ abctime timeSince = Abc_Clock() - clkOne;
+ assert( p->pTime4Outs[p->iOutCur] > 0 );
+ p->pTime4Outs[p->iOutCur] = (p->pTime4Outs[p->iOutCur] > timeSince) ? p->pTime4Outs[p->iOutCur] - timeSince : 0;
+ if ( p->pTime4Outs[p->iOutCur] == 0 && Vec_PtrEntry(p->vCexes, p->iOutCur) == NULL ) // undecided
+ {
+ p->pPars->nDropOuts++;
+ if ( p->pPars->vOutMap )
+ Vec_IntWriteEntry( p->pPars->vOutMap, p->iOutCur, -1 );
+ if ( !p->pPars->fNotVerbose )
+ Abc_Print( 1, "Timing out on output %*d in frame %d.\n", nOutDigits, p->iOutCur, iFrame );
+ }
+ p->timeToStopOne = 0;
+ }
+ }
+ if ( p->pPars->fUseAbs && p->vAbsFlops && !fRefined )
+ {
+ int i, Used;
+ Vec_IntForEachEntry( p->vAbsFlops, Used, i )
+ if ( Used && (Vec_IntEntry(p->vPrio, i) >> p->nPrioShift) == 0 )
+ Vec_IntWriteEntry( p->vAbsFlops, i, 0 );
+ }
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, !fRefined, Abc_Clock() - clkStart );
+ if ( fRefined )
+ continue;
+ //if ( p->pPars->fUseAbs && p->vAbsFlops )
+ // printf( "Finished frame %d with %d (%d) flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops), Vec_IntCountPositive(p->vPrio) );
+ // open a new timeframe
+ p->nQueLim = p->pPars->nRestLimit;
+ assert( pCube == NULL );
+ Pdr_ManSetPropertyOutput( p, iFrame );
+ Pdr_ManCreateSolver( p, ++iFrame );
+ if ( fPrintClauses )
+ {
+ Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame );
+ Pdr_ManPrintClauses( p, 0 );
+ }
+ // push clauses into this timeframe
+ RetValue = Pdr_ManPushClauses( p );
+ if ( RetValue == -1 )
+ {
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ if ( !p->pPars->fSilent )
+ {
+ if ( p->timeToStop && Abc_Clock() > p->timeToStop )
+ Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame );
+ else
+ Abc_Print( 1, "Reached conflict limit (%d) in frame.\n", p->pPars->nConfLimit, iFrame );
+ }
+ p->pPars->iFrame = iFrame;
+ return -1;
+ }
+ if ( RetValue )
+ {
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ if ( !p->pPars->fSilent )
+ Pdr_ManReportInvariant( p );
+ if ( !p->pPars->fSilent )
+ Pdr_ManVerifyInvariant( p );
+ p->pPars->iFrame = iFrame;
+ // count the number of UNSAT outputs
+ p->pPars->nProveOuts = Saig_ManPoNum(p->pAig) - p->pPars->nFailOuts - p->pPars->nDropOuts;
+ // convert previously 'unknown' into 'unsat'
+ if ( p->pPars->vOutMap )
+ for ( iFrame = 0; iFrame < Saig_ManPoNum(p->pAig); iFrame++ )
+ if ( Vec_IntEntry(p->pPars->vOutMap, iFrame) == -2 ) // unknown
+ {
+ Vec_IntWriteEntry( p->pPars->vOutMap, iFrame, 1 ); // unsat
+ if ( p->pPars->fUseBridge )
+ Gia_ManToBridgeResult( stdout, 1, NULL, iFrame );
+ }
+ if ( p->pPars->nProveOuts == Saig_ManPoNum(p->pAig) )
+ return 1; // UNSAT
+ if ( p->pPars->nFailOuts > 0 )
+ return 0; // SAT
+ return -1;
+ }
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, 0, Abc_Clock() - clkStart );
+
+ // check termination
+ if ( p->pPars->pFuncStop && p->pPars->pFuncStop(p->pPars->RunId) )
+ {
+ p->pPars->iFrame = iFrame;
+ return -1;
+ }
+ if ( p->timeToStop && Abc_Clock() > p->timeToStop )
+ {
+ if ( fPrintClauses )
+ {
+ Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame );
+ Pdr_ManPrintClauses( p, 0 );
+ }
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ if ( !p->pPars->fSilent )
+ Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame );
+ p->pPars->iFrame = iFrame;
+ return -1;
+ }
+ if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC )
+ {
+ if ( fPrintClauses )
+ {
+ Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame );
+ Pdr_ManPrintClauses( p, 0 );
+ }
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ if ( !p->pPars->fSilent )
+ Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame );
+ p->pPars->iFrame = iFrame;
+ return -1;
+ }
+ if ( p->pPars->nFrameMax && iFrame >= p->pPars->nFrameMax )
+ {
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ if ( !p->pPars->fSilent )
+ Abc_Print( 1, "Reached limit on the number of timeframes (%d).\n", p->pPars->nFrameMax );
+ p->pPars->iFrame = iFrame;
+ return -1;
+ }
+ }
+ assert( 0 );
+ return -1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IPdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars )
+{
+ Pdr_Man_t * p;
+ int k, RetValue;
+ Vec_Vec_t * vClausesSaved;
+
+ abctime clk = Abc_Clock();
+ if ( pPars->nTimeOutOne && !pPars->fSolveAll )
+ pPars->nTimeOutOne = 0;
+ if ( pPars->nTimeOutOne && pPars->nTimeOut == 0 )
+ pPars->nTimeOut = pPars->nTimeOutOne * Saig_ManPoNum(pAig) / 1000 + (int)((pPars->nTimeOutOne * Saig_ManPoNum(pAig) % 1000) > 0);
+ if ( pPars->fVerbose )
+ {
+// Abc_Print( 1, "Running PDR by Niklas Een (aka IC3 by Aaron Bradley) with these parameters:\n" );
+ Abc_Print( 1, "VarMax = %d. FrameMax = %d. QueMax = %d. TimeMax = %d. ",
+ pPars->nRecycle,
+ pPars->nFrameMax,
+ pPars->nRestLimit,
+ pPars->nTimeOut );
+ Abc_Print( 1, "MonoCNF = %s. SkipGen = %s. SolveAll = %s.\n",
+ pPars->fMonoCnf ? "yes" : "no",
+ pPars->fSkipGeneral ? "yes" : "no",
+ pPars->fSolveAll ? "yes" : "no" );
+ }
+ ABC_FREE( pAig->pSeqModel );
+
+
+ p = Pdr_ManStart( pAig, pPars, NULL );
+ while ( 1 ) {
+ RetValue = IPdr_ManSolveInt( p, 1, 0 );
+
+ if ( RetValue == -1 && pPars->iFrame == pPars->nFrameMax) {
+ vClausesSaved = IPdr_ManSaveClauses( p, 1 );
+
+ Pdr_ManStop( p );
+
+ p = Pdr_ManStart( pAig, pPars, NULL );
+ IPdr_ManRestore( p, vClausesSaved, NULL );
+
+ pPars->nFrameMax = pPars->nFrameMax << 1;
+
+ continue;
+ }
+
+ if ( RetValue == 0 )
+ assert( pAig->pSeqModel != NULL || p->vCexes != NULL );
+ if ( p->vCexes )
+ {
+ assert( p->pAig->vSeqModelVec == NULL );
+ p->pAig->vSeqModelVec = p->vCexes;
+ p->vCexes = NULL;
+ }
+ if ( p->pPars->fDumpInv )
+ {
+ char * pFileName = Extra_FileNameGenericAppend(p->pAig->pName, "_inv.pla");
+ Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) );
+ Pdr_ManDumpClauses( p, pFileName, RetValue==1 );
+ }
+ else if ( RetValue == 1 )
+ Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) );
+
+ p->tTotal += Abc_Clock() - clk;
+ Pdr_ManStop( p );
+
+ break;
+ }
+
+
+ pPars->iFrame--;
+ // convert all -2 (unknown) entries into -1 (undec)
+ if ( pPars->vOutMap )
+ for ( k = 0; k < Saig_ManPoNum(pAig); k++ )
+ if ( Vec_IntEntry(pPars->vOutMap, k) == -2 ) // unknown
+ Vec_IntWriteEntry( pPars->vOutMap, k, -1 ); // undec
+ if ( pPars->fUseBridge )
+ Gia_ManToBridgeAbort( stdout, 7, (unsigned char *)"timeout" );
+ return RetValue;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkDarIPdr ( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars )
+{
+ int RetValue = -1;
+ abctime clk = Abc_Clock();
+ Aig_Man_t * pMan;
+ pMan = Abc_NtkToDar( pNtk, 0, 1 );
+
+ RetValue = IPdr_ManSolve( pMan, pPars );
+
+ if ( RetValue == 1 )
+ Abc_Print( 1, "Property proved. " );
+ else
+ {
+ if ( RetValue == 0 )
+ {
+ if ( pMan->pSeqModel == NULL )
+ Abc_Print( 1, "Counter-example is not available.\n" );
+ else
+ {
+ Abc_Print( 1, "Output %d of miter \"%s\" was asserted in frame %d. ", pMan->pSeqModel->iPo, pNtk->pName, pMan->pSeqModel->iFrame );
+ if ( !Saig_ManVerifyCex( pMan, pMan->pSeqModel ) )
+ Abc_Print( 1, "Counter-example verification has FAILED.\n" );
+ }
+ }
+ else if ( RetValue == -1 )
+ Abc_Print( 1, "Property UNDECIDED. " );
+ else
+ assert( 0 );
+ }
+ ABC_PRT( "Time", Abc_Clock() - clk );
+
+
+ ABC_FREE( pNtk->pSeqModel );
+ pNtk->pSeqModel = pMan->pSeqModel;
+ pMan->pSeqModel = NULL;
+ if ( pNtk->vSeqModelVec )
+ Vec_PtrFreeFree( pNtk->vSeqModelVec );
+ pNtk->vSeqModelVec = pMan->vSeqModelVec;
+ pMan->vSeqModelVec = NULL;
+ Aig_ManStop( pMan );
+ return RetValue;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
diff --git a/src/proof/pdr/pdrInt.h b/src/proof/pdr/pdrInt.h
index 6a08a150..e5b04339 100644
--- a/src/proof/pdr/pdrInt.h
+++ b/src/proof/pdr/pdrInt.h
@@ -30,6 +30,8 @@
#include "sat/cnf/cnf.h"
#include "sat/bsat/satSolver.h"
#include "pdr.h"
+#include "misc/hash/hashInt.h"
+#include "aig/gia/giaAig.h"
ABC_NAMESPACE_HEADER_START
@@ -41,6 +43,8 @@ ABC_NAMESPACE_HEADER_START
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
+typedef struct Txs_Man_t_ Txs_Man_t;
+
typedef struct Pdr_Set_t_ Pdr_Set_t;
struct Pdr_Set_t_
{
@@ -68,6 +72,7 @@ struct Pdr_Man_t_
// input problem
Pdr_Par_t * pPars; // parameters
Aig_Man_t * pAig; // user's AIG
+ Gia_Man_t * pGia; // user's AIG
// static CNF representation
Cnf_Man_t * pCnfMan; // CNF manager
Cnf_Dat_t * pCnf1; // CNF for this AIG
@@ -79,6 +84,7 @@ struct Pdr_Man_t_
Vec_Wec_t * vVLits; // CNF literals
// data representation
int iOutCur; // current output
+ int nPrioShift;// priority shift
Vec_Ptr_t * vCexes; // counter-examples for each output
Vec_Ptr_t * vSolvers; // SAT solvers
Vec_Vec_t * vClauses; // clauses by timeframe
@@ -86,6 +92,14 @@ struct Pdr_Man_t_
int * pOrder; // ordering of the lits
Vec_Int_t * vActVars; // the counter of activation variables
int iUseFrame; // the first used frame
+ int nAbsFlops; // the number of flops used
+ Vec_Int_t * vAbsFlops; // flops currently used
+ Vec_Int_t * vMapFf2Ppi;
+ Vec_Int_t * vMapPpi2Ff;
+ int nCexes;
+ int nCexesTotal;
+ // terminary simulation
+ Txs_Man_t * pTxs;
// internal use
Vec_Int_t * vPrio; // priority flops
Vec_Int_t * vLits; // array of literals
@@ -98,8 +112,6 @@ struct Pdr_Man_t_
Vec_Int_t * vVisits; // intermediate
Vec_Int_t * vCi2Rem; // CIs to be removed
Vec_Int_t * vRes; // final result
- Vec_Int_t * vSuppLits; // support literals
- Pdr_Set_t * pCubeJust; // justification
abctime * pTime4Outs;// timeout per output
Vec_Ptr_t * vInfCubes; // infinity clauses/cubes
// statistics
@@ -118,6 +130,8 @@ struct Pdr_Man_t_
int nQueCur;
int nQueMax;
int nQueLim;
+ int nXsimRuns;
+ int nXsimLits;
// runtime
abctime timeToStop;
abctime timeToStopOne;
@@ -130,6 +144,7 @@ struct Pdr_Man_t_
abctime tTsim;
abctime tContain;
abctime tCnf;
+ abctime tAbs;
abctime tTotal;
};
@@ -154,8 +169,6 @@ static inline abctime Pdr_ManTimeLimit( Pdr_Man_t * p )
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-/*=== pdrCex.c ==========================================================*/
-extern Abc_Cex_t * Pdr_ManDeriveCex( Pdr_Man_t * p );
/*=== pdrCnf.c ==========================================================*/
extern int Pdr_ObjSatVar( Pdr_Man_t * p, int k, int Pol, Aig_Obj_t * pObj );
extern int Pdr_ObjRegNum( Pdr_Man_t * p, int k, int iSatVar );
@@ -176,6 +189,7 @@ extern Vec_Int_t * Pdr_ManDeriveInfinityClauses( Pdr_Man_t * p, int fReduce
extern Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrioInit );
extern void Pdr_ManStop( Pdr_Man_t * p );
extern Abc_Cex_t * Pdr_ManDeriveCex( Pdr_Man_t * p );
+extern Abc_Cex_t * Pdr_ManDeriveCexAbs( Pdr_Man_t * p );
/*=== pdrSat.c ==========================================================*/
extern sat_solver * Pdr_ManCreateSolver( Pdr_Man_t * p, int k );
extern sat_solver * Pdr_ManFetchSolver( Pdr_Man_t * p, int k );
@@ -185,9 +199,13 @@ extern Vec_Int_t * Pdr_ManLitsToCube( Pdr_Man_t * p, int k, int * pArray, in
extern void Pdr_ManSolverAddClause( Pdr_Man_t * p, int k, Pdr_Set_t * pCube );
extern void Pdr_ManCollectValues( Pdr_Man_t * p, int k, Vec_Int_t * vObjIds, Vec_Int_t * vValues );
extern int Pdr_ManCheckCubeCs( Pdr_Man_t * p, int k, Pdr_Set_t * pCube );
-extern int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPred, int nConfLimit, int fTryConf );
+extern int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPred, int nConfLimit, int fTryConf, int fUseLit );
/*=== pdrTsim.c ==========================================================*/
extern Pdr_Set_t * Pdr_ManTernarySim( Pdr_Man_t * p, int k, Pdr_Set_t * pCube );
+/*=== pdrTsim2.c ==========================================================*/
+extern Txs_Man_t * Txs_ManStart( Pdr_Man_t * pMan, Aig_Man_t * pAig, Vec_Int_t * vPrio );
+extern void Txs_ManStop( Txs_Man_t * );
+extern Pdr_Set_t * Txs_ManTernarySim( Txs_Man_t * p, int k, Pdr_Set_t * pCube );
/*=== pdrUtil.c ==========================================================*/
extern Pdr_Set_t * Pdr_SetAlloc( int nSize );
extern Pdr_Set_t * Pdr_SetCreate( Vec_Int_t * vLits, Vec_Int_t * vPiLits );
@@ -196,10 +214,13 @@ extern Pdr_Set_t * Pdr_SetCreateSubset( Pdr_Set_t * pSet, int * pLits, int n
extern Pdr_Set_t * Pdr_SetDup( Pdr_Set_t * pSet );
extern Pdr_Set_t * Pdr_SetRef( Pdr_Set_t * p );
extern void Pdr_SetDeref( Pdr_Set_t * p );
+extern Pdr_Set_t * ZPdr_SetIntersection( Pdr_Set_t * p1, Pdr_Set_t * p2, Hash_Int_t * keep );
extern int Pdr_SetContains( Pdr_Set_t * pOld, Pdr_Set_t * pNew );
extern int Pdr_SetContainsSimple( Pdr_Set_t * pOld, Pdr_Set_t * pNew );
extern int Pdr_SetIsInit( Pdr_Set_t * p, int iRemove );
+extern int ZPdr_SetIsInit( Pdr_Set_t * p );
extern void Pdr_SetPrint( FILE * pFile, Pdr_Set_t * p, int nRegs, Vec_Int_t * vFlopCounts );
+extern void ZPdr_SetPrint( Pdr_Set_t * p );
extern void Pdr_SetPrintStr( Vec_Str_t * vStr, Pdr_Set_t * p, int nRegs, Vec_Int_t * vFlopCounts );
extern int Pdr_SetCompare( Pdr_Set_t ** pp1, Pdr_Set_t ** pp2 );
extern Pdr_Obl_t * Pdr_OblStart( int k, int prio, Pdr_Set_t * pState, Pdr_Obl_t * pNext );
@@ -212,7 +233,6 @@ extern void Pdr_QueueClean( Pdr_Man_t * p );
extern void Pdr_QueuePush( Pdr_Man_t * p, Pdr_Obl_t * pObl );
extern void Pdr_QueuePrint( Pdr_Man_t * p );
extern void Pdr_QueueStop( Pdr_Man_t * p );
-extern int Pdr_ManCubeJust( Pdr_Man_t * p, int k, Pdr_Set_t * pCube );
ABC_NAMESPACE_HEADER_END
diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c
index 02b90a36..baade033 100644
--- a/src/proof/pdr/pdrInv.c
+++ b/src/proof/pdr/pdrInv.c
@@ -50,7 +50,16 @@ void Pdr_ManPrintProgress( Pdr_Man_t * p, int fClose, abctime Time )
Vec_Ptr_t * vVec;
int i, ThisSize, Length, LengthStart;
if ( Vec_PtrSize(p->vSolvers) < 2 )
+ {
+ printf( "Frame " );
+ printf( "Clauses " );
+ printf( "Max Queue " );
+ printf( "Flops " );
+ printf( "Cex " );
+ printf( "Time" );
+ printf( "\n" );
return;
+ }
if ( Abc_FrameIsBatchMode() && !fClose )
return;
// count the total length of the printout
@@ -80,7 +89,10 @@ void Pdr_ManPrintProgress( Pdr_Man_t * p, int fClose, abctime Time )
}
for ( i = ThisSize; i < 70; i++ )
Abc_Print( 1, " " );
- Abc_Print( 1, "%6d", p->nQueMax );
+ Abc_Print( 1, "%5d", p->nQueMax );
+ Abc_Print( 1, "%6d", p->vAbsFlops ? Vec_IntCountPositive(p->vAbsFlops) : p->nAbsFlops );
+ if ( p->pPars->fUseAbs )
+ Abc_Print( 1, "%4d", p->nCexes );
Abc_Print( 1, "%10.2f sec", 1.0*Time/CLOCKS_PER_SEC );
if ( p->pPars->fSolveAll )
Abc_Print( 1, " CEX =%4d", p->pPars->nFailOuts );
@@ -88,7 +100,7 @@ void Pdr_ManPrintProgress( Pdr_Man_t * p, int fClose, abctime Time )
Abc_Print( 1, " T/O =%3d", p->pPars->nDropOuts );
Abc_Print( 1, "%s", fClose ? "\n":"\r" );
if ( fClose )
- p->nQueMax = 0;
+ p->nQueMax = 0, p->nCexes = 0;
fflush( stdout );
}
@@ -467,8 +479,10 @@ void Pdr_ManReportInvariant( Pdr_Man_t * p )
Vec_Ptr_t * vCubes;
int kStart = Pdr_ManFindInvariantStart( p );
vCubes = Pdr_ManCollectCubes( p, kStart );
- Abc_Print( 1, "Invariant F[%d] : %d clauses with %d flops (out of %d)\n",
- kStart, Vec_PtrSize(vCubes), Pdr_ManCountVariables(p, kStart), Aig_ManRegNum(p->pAig) );
+ Abc_Print( 1, "Invariant F[%d] : %d clauses with %d flops (out of %d) (cex = %d, ave = %.2f)\n",
+ kStart, Vec_PtrSize(vCubes), Pdr_ManCountVariables(p, kStart), Aig_ManRegNum(p->pAig), p->nCexesTotal, 1.0*p->nXsimLits/p->nXsimRuns );
+// Abc_Print( 1, "Invariant F[%d] : %d clauses with %d flops (out of %d)\n",
+// kStart, Vec_PtrSize(vCubes), Pdr_ManCountVariables(p, kStart), Aig_ManRegNum(p->pAig) );
Vec_PtrFree( vCubes );
}
@@ -605,9 +619,363 @@ Vec_Int_t * Pdr_ManDeriveInfinityClauses( Pdr_Man_t * p, int fReduce )
//Vec_PtrFree( vCubes );
Vec_PtrFreeP( &p->vInfCubes );
p->vInfCubes = vCubes;
+ Vec_IntPush( vResult, Aig_ManRegNum(p->pAig) );
return vResult;
}
+
+
+/**Function*************************************************************
+
+ Synopsis [Remove clauses while maintaining the invariant.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+#define Pdr_ForEachCube( pList, pCut, i ) for ( i = 0, pCut = pList + 1; i < pList[0]; i++, pCut += pCut[0] + 1 )
+
+Vec_Int_t * Pdr_InvMap( Vec_Int_t * vCounts )
+{
+ int i, k = 0, Count;
+ Vec_Int_t * vMap = Vec_IntStart( Vec_IntSize(vCounts) );
+ Vec_IntForEachEntry( vCounts, Count, i )
+ if ( Count )
+ Vec_IntWriteEntry( vMap, i, k++ );
+ return vMap;
+}
+Vec_Int_t * Pdr_InvCounts( Vec_Int_t * vInv )
+{
+ int i, k, * pCube, * pList = Vec_IntArray(vInv);
+ Vec_Int_t * vCounts = Vec_IntStart( Vec_IntEntryLast(vInv) );
+ Pdr_ForEachCube( pList, pCube, i )
+ for ( k = 0; k < pCube[0]; k++ )
+ Vec_IntAddToEntry( vCounts, Abc_Lit2Var(pCube[k+1]), 1 );
+ return vCounts;
+}
+int Pdr_InvUsedFlopNum( Vec_Int_t * vInv )
+{
+ Vec_Int_t * vCounts = Pdr_InvCounts( vInv );
+ int nZeros = Vec_IntCountZero( vCounts );
+ Vec_IntFree( vCounts );
+ return Vec_IntEntryLast(vInv) - nZeros;
+}
+
+Vec_Str_t * Pdr_InvPrintStr( Vec_Int_t * vInv, Vec_Int_t * vCounts )
+{
+ Vec_Str_t * vStr = Vec_StrAlloc( 1000 );
+ Vec_Int_t * vMap = Pdr_InvMap( vCounts );
+ int nVars = Vec_IntSize(vCounts) - Vec_IntCountZero(vCounts);
+ int i, k, * pCube, * pList = Vec_IntArray(vInv);
+ char * pBuffer = ABC_ALLOC( char, nVars );
+ for ( i = 0; i < nVars; i++ )
+ pBuffer[i] = '-';
+ Pdr_ForEachCube( pList, pCube, i )
+ {
+ for ( k = 0; k < pCube[0]; k++ )
+ pBuffer[Vec_IntEntry(vMap, Abc_Lit2Var(pCube[k+1]))] = '0' + !Abc_LitIsCompl(pCube[k+1]);
+ for ( k = 0; k < nVars; k++ )
+ Vec_StrPush( vStr, pBuffer[k] );
+ Vec_StrPush( vStr, ' ' );
+ Vec_StrPush( vStr, '1' );
+ Vec_StrPush( vStr, '\n' );
+ for ( k = 0; k < pCube[0]; k++ )
+ pBuffer[Vec_IntEntry(vMap, Abc_Lit2Var(pCube[k+1]))] = '-';
+ }
+ Vec_StrPush( vStr, '\0' );
+ ABC_FREE( pBuffer );
+ Vec_IntFree( vMap );
+ return vStr;
+}
+void Pdr_InvPrint( Vec_Int_t * vInv, int fVerbose )
+{
+ printf( "Invariant contains %d clauses with %d literals and %d flops (out of %d).\n", Vec_IntEntry(vInv, 0), Vec_IntSize(vInv)-Vec_IntEntry(vInv, 0)-2, Pdr_InvUsedFlopNum(vInv), Vec_IntEntryLast(vInv) );
+ if ( fVerbose )
+ {
+ Vec_Int_t * vCounts = Pdr_InvCounts( vInv );
+ Vec_Str_t * vStr = Pdr_InvPrintStr( vInv, vCounts );
+ printf( "%s", Vec_StrArray( vStr ) );
+ Vec_IntFree( vCounts );
+ Vec_StrFree( vStr );
+ }
+}
+
+int Pdr_InvCheck_int( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose, sat_solver * pSat, int fSkip )
+{
+ int nBTLimit = 0;
+ int fCheckProperty = 1;
+ int i, k, status, nFailed = 0, nFailedOuts = 0;
+ // collect cubes
+ int * pCube, * pList = Vec_IntArray(vInv);
+ // create variables
+ Vec_Int_t * vLits = Vec_IntAlloc(100);
+ int iFoVarBeg = sat_solver_nvars(pSat) - Gia_ManRegNum(p);
+ int iFiVarBeg = 1 + Gia_ManPoNum(p);
+ // add cubes
+ Pdr_ForEachCube( pList, pCube, i )
+ {
+ // collect literals
+ Vec_IntClear( vLits );
+ for ( k = 0; k < pCube[0]; k++ )
+ if ( pCube[k+1] != -1 )
+ Vec_IntPush( vLits, Abc_Var2Lit(iFoVarBeg + Abc_Lit2Var(pCube[k+1]), !Abc_LitIsCompl(pCube[k+1])) );
+ if ( Vec_IntSize(vLits) == 0 )
+ {
+ Vec_IntFree( vLits );
+ return 1;
+ }
+ // add it to the solver
+ status = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits) );
+ assert( status == 1 );
+ }
+ // verify property output
+ if ( fCheckProperty )
+ {
+ for ( i = 0; i < Gia_ManPoNum(p); i++ )
+ {
+ Vec_IntFill( vLits, 1, Abc_Var2Lit(1+i, 0) );
+ status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 );
+ if ( status == l_Undef ) // timeout
+ break;
+ if ( status == l_True ) // sat - property fails
+ {
+ if ( fVerbose )
+ printf( "Coverage check failed for output %d.\n", i );
+ nFailedOuts++;
+ if ( fSkip )
+ {
+ Vec_IntFree( vLits );
+ return 1;
+ }
+ continue;
+ }
+ assert( status == l_False ); // unsat - property holds
+ }
+ }
+ // iterate through cubes in the direct order
+ Pdr_ForEachCube( pList, pCube, i )
+ {
+ // collect cube
+ Vec_IntClear( vLits );
+ for ( k = 0; k < pCube[0]; k++ )
+ if ( pCube[k+1] != -1 )
+ Vec_IntPush( vLits, Abc_Var2Lit(iFiVarBeg + Abc_Lit2Var(pCube[k+1]), Abc_LitIsCompl(pCube[k+1])) );
+ // check if this cube intersects with the complement of other cubes in the solver
+ // if it does not intersect, then it is redundant and can be skipped
+ status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 );
+ if ( status != l_True && fVerbose )
+ printf( "Finished checking clause %d (out of %d)...\r", i, pList[0] );
+ if ( status == l_Undef ) // timeout
+ break;
+ if ( status == l_False ) // unsat -- correct
+ continue;
+ assert( status == l_True );
+ if ( fVerbose )
+ printf( "Inductiveness check failed for clause %d.\n", i );
+ nFailed++;
+ if ( fSkip )
+ {
+ Vec_IntFree( vLits );
+ return 1;
+ }
+ }
+ Vec_IntFree( vLits );
+ return nFailed + nFailedOuts;
+}
+
+int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose )
+{
+ int RetValue;
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
+ sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
+ assert( sat_solver_nvars(pSat) == pCnf->nVars );
+ Cnf_DataFree( pCnf );
+ RetValue = Pdr_InvCheck_int( p, vInv, fVerbose, pSat, 0 );
+ sat_solver_delete( pSat );
+ return RetValue;
+}
+
+Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose )
+{
+ int nBTLimit = 0;
+ int fCheckProperty = 1;
+ abctime clk = Abc_Clock();
+ int n, i, k, status, nLits, fFailed = 0, fCannot = 0, nRemoved = 0;
+ Vec_Int_t * vRes = NULL;
+ // create SAT solver
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
+ sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
+ int * pCube, * pList = Vec_IntArray(vInv), nCubes = pList[0];
+ // create variables
+ Vec_Int_t * vLits = Vec_IntAlloc(100);
+ Vec_Bit_t * vRemoved = Vec_BitStart( nCubes );
+ int iFoVarBeg = pCnf->nVars - Gia_ManRegNum(p);
+ int iFiVarBeg = 1 + Gia_ManPoNum(p);
+ int iAuxVarBeg = sat_solver_nvars(pSat);
+ // allocate auxiliary variables
+ assert( sat_solver_nvars(pSat) == pCnf->nVars );
+ sat_solver_setnvars( pSat, sat_solver_nvars(pSat) + nCubes );
+ // add clauses
+ Pdr_ForEachCube( pList, pCube, i )
+ {
+ // collect literals
+ Vec_IntFill( vLits, 1, Abc_Var2Lit(iAuxVarBeg + i, 1) ); // neg aux literal
+ for ( k = 0; k < pCube[0]; k++ )
+ Vec_IntPush( vLits, Abc_Var2Lit(iFoVarBeg + Abc_Lit2Var(pCube[k+1]), !Abc_LitIsCompl(pCube[k+1])) );
+ // add it to the solver
+ status = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits) );
+ assert( status == 1 );
+ }
+ // iterate through clauses
+ Pdr_ForEachCube( pList, pCube, i )
+ {
+ if ( Vec_BitEntry(vRemoved, i) )
+ continue;
+ // collect aux literals for remaining clauses
+ Vec_IntClear( vLits );
+ for ( k = 0; k < nCubes; k++ )
+ if ( k != i && !Vec_BitEntry(vRemoved, k) ) // skip this cube and already removed cubes
+ Vec_IntPush( vLits, Abc_Var2Lit(iAuxVarBeg + k, 0) ); // pos aux literal
+ nLits = Vec_IntSize( vLits );
+ // check if the property still holds
+ if ( fCheckProperty )
+ {
+ for ( k = 0; k < Gia_ManPoNum(p); k++ )
+ {
+ Vec_IntShrink( vLits, nLits );
+ Vec_IntPush( vLits, Abc_Var2Lit(1+k, 0) );
+ status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 );
+ if ( status == l_Undef ) // timeout
+ {
+ fFailed = 1;
+ break;
+ }
+ if ( status == l_True ) // sat - property fails
+ break;
+ assert( status == l_False ); // unsat - property holds
+ }
+ if ( fFailed )
+ break;
+ if ( k < Gia_ManPoNum(p) )
+ continue;
+ }
+ // check other clauses
+ fCannot = 0;
+ Pdr_ForEachCube( pList, pCube, n )
+ {
+ if ( Vec_BitEntry(vRemoved, n) || n == i )
+ continue;
+ // collect cube
+ Vec_IntShrink( vLits, nLits );
+ for ( k = 0; k < pCube[0]; k++ )
+ Vec_IntPush( vLits, Abc_Var2Lit(iFiVarBeg + Abc_Lit2Var(pCube[k+1]), Abc_LitIsCompl(pCube[k+1])) );
+ // check if this cube intersects with the complement of other cubes in the solver
+ // if it does not intersect, then it is redundant and can be skipped
+ status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 );
+ if ( status == l_Undef ) // timeout
+ {
+ fFailed = 1;
+ break;
+ }
+ if ( status == l_False ) // unsat -- correct
+ continue;
+ assert( status == l_True );
+ // cannot remove
+ fCannot = 1;
+ break;
+ }
+ if ( fFailed )
+ break;
+ if ( fCannot )
+ continue;
+ if ( fVerbose )
+ printf( "Removing clause %d.\n", i );
+ Vec_BitWriteEntry( vRemoved, i, 1 );
+ nRemoved++;
+ }
+ if ( nRemoved )
+ printf( "Invariant minimization reduced %d clauses (out of %d). ", nRemoved, nCubes );
+ else
+ printf( "Invariant minimization did not change the invariant. " );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ // cleanup cover
+ if ( !fFailed && nRemoved > 0 ) // finished without timeout and removed some cubes
+ {
+ vRes = Vec_IntAlloc( 1000 );
+ Vec_IntPush( vRes, nCubes-nRemoved );
+ Pdr_ForEachCube( pList, pCube, i )
+ if ( !Vec_BitEntry(vRemoved, i) )
+ for ( k = 0; k <= pCube[0]; k++ )
+ Vec_IntPush( vRes, pCube[k] );
+ Vec_IntPush( vRes, Vec_IntEntryLast(vInv) );
+ }
+ Cnf_DataFree( pCnf );
+ sat_solver_delete( pSat );
+ Vec_BitFree( vRemoved );
+ Vec_IntFree( vLits );
+ return vRes;
+}
+
+Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose )
+{
+ Vec_Int_t * vRes = NULL;
+ abctime clk = Abc_Clock();
+ int i, k, nLits = 0, * pCube, * pList = Vec_IntArray(vInv), nRemoved = 0;
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
+ sat_solver * pSat;
+// sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
+ Pdr_ForEachCube( pList, pCube, i )
+ {
+ nLits += pCube[0];
+ for ( k = 0; k < pCube[0]; k++ )
+ {
+ int Save = pCube[k+1];
+ pCube[k+1] = -1;
+ //sat_solver_bookmark( pSat );
+ pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
+ if ( Pdr_InvCheck_int(p, vInv, 0, pSat, 1) )
+ pCube[k+1] = Save;
+ else
+ {
+ if ( fVerbose )
+ printf( "Removing lit %d from clause %d.\n", k, i );
+ nRemoved++;
+ }
+ sat_solver_delete( pSat );
+ //sat_solver_rollback( pSat );
+ //sat_solver_bookmark( pSat );
+ }
+ }
+ Cnf_DataFree( pCnf );
+ //sat_solver_delete( pSat );
+ if ( nRemoved )
+ printf( "Invariant minimization reduced %d literals (out of %d). ", nRemoved, nLits );
+ else
+ printf( "Invariant minimization did not change the invariant. " );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ if ( nRemoved > 0 ) // finished without timeout and removed some lits
+ {
+ vRes = Vec_IntAlloc( 1000 );
+ Vec_IntPush( vRes, pList[0] );
+ Pdr_ForEachCube( pList, pCube, i )
+ {
+ int nLits = 0;
+ for ( k = 0; k < pCube[0]; k++ )
+ if ( pCube[k+1] != -1 )
+ nLits++;
+ Vec_IntPush( vRes, nLits );
+ for ( k = 0; k < pCube[0]; k++ )
+ if ( pCube[k+1] != -1 )
+ Vec_IntPush( vRes, pCube[k+1] );
+ }
+ Vec_IntPush( vRes, Vec_IntEntryLast(vInv) );
+ }
+ return vRes;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/proof/pdr/pdrMan.c b/src/proof/pdr/pdrMan.c
index b58c479b..a076223b 100644
--- a/src/proof/pdr/pdrMan.c
+++ b/src/proof/pdr/pdrMan.c
@@ -19,6 +19,7 @@
***********************************************************************/
#include "pdrInt.h"
+#include "sat/bmc/bmc.h"
ABC_NAMESPACE_IMPL_START
@@ -33,6 +34,208 @@ ABC_NAMESPACE_IMPL_START
/**Function*************************************************************
+ Synopsis [Structural analysis.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Pdr_ManDeriveFlopPriorities3( Gia_Man_t * p, int fMuxCtrls )
+{
+ int fDiscount = 0;
+ Vec_Wec_t * vLevels;
+ Vec_Int_t * vRes, * vLevel, * vCosts;
+ Gia_Obj_t * pObj, * pCtrl, * pData0, * pData1;
+ int i, k, Entry, MaxEntry = 0;
+ Gia_ManCreateRefs(p);
+ // discount references
+ if ( fDiscount )
+ {
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( !Gia_ObjIsMuxType(pObj) )
+ continue;
+ pCtrl = Gia_Regular(Gia_ObjRecognizeMux(pObj, &pData1, &pData0));
+ pData0 = Gia_Regular(pData0);
+ pData1 = Gia_Regular(pData1);
+ p->pRefs[Gia_ObjId(p, pCtrl)]--;
+ if ( pData0 == pData1 )
+ p->pRefs[Gia_ObjId(p, pData0)]--;
+ }
+ }
+ // create flop costs
+ vCosts = Vec_IntAlloc( Gia_ManRegNum(p) );
+ Gia_ManForEachRo( p, pObj, i )
+ {
+ Vec_IntPush( vCosts, Gia_ObjRefNum(p, pObj) );
+ MaxEntry = Abc_MaxInt( MaxEntry, Gia_ObjRefNum(p, pObj) );
+ //printf( "%d(%d) ", i, Gia_ObjRefNum(p, pObj) );
+ }
+ //printf( "\n" );
+ MaxEntry++;
+ // add costs due to MUX inputs
+ if ( fMuxCtrls )
+ {
+ int fVerbose = 0;
+ Vec_Bit_t * vCtrls = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Bit_t * vDatas = Vec_BitStart( Gia_ManObjNum(p) );
+ Gia_Obj_t * pCtrl, * pData1, * pData0;
+ int nCtrls = 0, nDatas = 0, nBoth = 0;
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( !Gia_ObjIsMuxType(pObj) )
+ continue;
+ pCtrl = Gia_ObjRecognizeMux( pObj, &pData1, &pData0 );
+ pCtrl = Gia_Regular(pCtrl);
+ pData1 = Gia_Regular(pData1);
+ pData0 = Gia_Regular(pData0);
+ Vec_BitWriteEntry( vCtrls, Gia_ObjId(p, pCtrl), 1 );
+ Vec_BitWriteEntry( vDatas, Gia_ObjId(p, pData1), 1 );
+ Vec_BitWriteEntry( vDatas, Gia_ObjId(p, pData0), 1 );
+ }
+ Gia_ManForEachRo( p, pObj, i )
+ if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) )
+ Vec_IntAddToEntry( vCosts, i, MaxEntry );
+ //else if ( Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) )
+ // Vec_IntAddToEntry( vCosts, i, MaxEntry );
+ MaxEntry = 2*MaxEntry + 1;
+ // print out
+ if ( fVerbose )
+ {
+ Gia_ManForEachRo( p, pObj, i )
+ {
+ if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) )
+ nCtrls++;
+ if ( Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) )
+ nDatas++;
+ if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) && Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) )
+ nBoth++;
+ }
+ printf( "%10s : Flops = %5d. Ctrls = %5d. Datas = %5d. Both = %5d.\n", Gia_ManName(p), Gia_ManRegNum(p), nCtrls, nDatas, nBoth );
+ }
+ Vec_BitFree( vCtrls );
+ Vec_BitFree( vDatas );
+ }
+ // create levelized structure
+ vLevels = Vec_WecStart( MaxEntry );
+ Vec_IntForEachEntry( vCosts, Entry, i )
+ Vec_WecPush( vLevels, Entry, i );
+ // collect in this order
+ MaxEntry = 0;
+ vRes = Vec_IntStart( Gia_ManRegNum(p) );
+ Vec_WecForEachLevel( vLevels, vLevel, i )
+ Vec_IntForEachEntry( vLevel, Entry, k )
+ Vec_IntWriteEntry( vRes, Entry, MaxEntry++ );
+ //printf( "%d ", Gia_ObjRefNum(p, Gia_ManCi(p, Gia_ManPiNum(p)+Entry)) );
+ //printf( "\n" );
+ assert( MaxEntry == Gia_ManRegNum(p) );
+ Vec_WecFree( vLevels );
+ Vec_IntFree( vCosts );
+ ABC_FREE( p->pRefs );
+//Vec_IntPrint( vRes );
+ return vRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Structural analysis.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Pdr_ManDeriveFlopPriorities2( Gia_Man_t * p, int fMuxCtrls )
+{
+ int fDiscount = 0;
+ Vec_Int_t * vRes = NULL;
+ Gia_Obj_t * pObj, * pCtrl, * pData0, * pData1;
+ int MaxEntry = 0;
+ int i, * pPerm;
+ // create flop costs
+ Vec_Int_t * vCosts = Vec_IntStart( Gia_ManRegNum(p) );
+ Gia_ManCreateRefs(p);
+ // discount references
+ if ( fDiscount )
+ {
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( !Gia_ObjIsMuxType(pObj) )
+ continue;
+ pCtrl = Gia_Regular(Gia_ObjRecognizeMux(pObj, &pData1, &pData0));
+ pData0 = Gia_Regular(pData0);
+ pData1 = Gia_Regular(pData1);
+ p->pRefs[Gia_ObjId(p, pCtrl)]--;
+ if ( pData0 == pData1 )
+ p->pRefs[Gia_ObjId(p, pData0)]--;
+ }
+ }
+ Gia_ManForEachRo( p, pObj, i )
+ {
+ Vec_IntWriteEntry( vCosts, i, Gia_ObjRefNum(p, pObj) );
+ MaxEntry = Abc_MaxInt( MaxEntry, Gia_ObjRefNum(p, pObj) );
+ }
+ MaxEntry++;
+ ABC_FREE( p->pRefs );
+ // add costs due to MUX inputs
+ if ( fMuxCtrls )
+ {
+ int fVerbose = 0;
+ Vec_Bit_t * vCtrls = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Bit_t * vDatas = Vec_BitStart( Gia_ManObjNum(p) );
+ Gia_Obj_t * pCtrl, * pData1, * pData0;
+ int nCtrls = 0, nDatas = 0, nBoth = 0;
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( !Gia_ObjIsMuxType(pObj) )
+ continue;
+ pCtrl = Gia_ObjRecognizeMux( pObj, &pData1, &pData0 );
+ pCtrl = Gia_Regular(pCtrl);
+ pData1 = Gia_Regular(pData1);
+ pData0 = Gia_Regular(pData0);
+ Vec_BitWriteEntry( vCtrls, Gia_ObjId(p, pCtrl), 1 );
+ Vec_BitWriteEntry( vDatas, Gia_ObjId(p, pData1), 1 );
+ Vec_BitWriteEntry( vDatas, Gia_ObjId(p, pData0), 1 );
+ }
+ Gia_ManForEachRo( p, pObj, i )
+ if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) )
+ Vec_IntAddToEntry( vCosts, i, MaxEntry );
+ //else if ( Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) )
+ // Vec_IntAddToEntry( vCosts, i, MaxEntry );
+ // print out
+ if ( fVerbose )
+ {
+ Gia_ManForEachRo( p, pObj, i )
+ {
+ if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) )
+ nCtrls++;
+ if ( Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) )
+ nDatas++;
+ if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) && Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) )
+ nBoth++;
+ }
+ printf( "%10s : Flops = %5d. Ctrls = %5d. Datas = %5d. Both = %5d.\n", Gia_ManName(p), Gia_ManRegNum(p), nCtrls, nDatas, nBoth );
+ }
+ Vec_BitFree( vCtrls );
+ Vec_BitFree( vDatas );
+ }
+ // create ordering based on costs
+ pPerm = Abc_MergeSortCost( Vec_IntArray(vCosts), Vec_IntSize(vCosts) );
+ vRes = Vec_IntAllocArray( pPerm, Vec_IntSize(vCosts) );
+ Vec_IntFree( vCosts );
+ vCosts = Vec_IntInvert( vRes, -1 );
+ Vec_IntFree( vRes );
+//Vec_IntPrint( vCosts );
+ return vCosts;
+}
+
+/**Function*************************************************************
+
Synopsis [Creates manager.]
Description []
@@ -48,6 +251,7 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio
p = ABC_CALLOC( Pdr_Man_t, 1 );
p->pPars = pPars;
p->pAig = pAig;
+ p->pGia = (pPars->fFlopPrio || p->pPars->fNewXSim || p->pPars->fUseAbs) ? Gia_ManFromAigSimple(pAig) : NULL;
p->vSolvers = Vec_PtrAlloc( 0 );
p->vClauses = Vec_VecAlloc( 0 );
p->pQueue = NULL;
@@ -56,7 +260,15 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio
if ( !p->pPars->fMonoCnf )
p->vVLits = Vec_WecStart( 1+Abc_MaxInt(1, Aig_ManLevels(pAig)) );
// internal use
- p->vPrio = vPrioInit ? vPrioInit : Vec_IntStart( Aig_ManRegNum(pAig) ); // priority flops
+ p->nPrioShift = Abc_Base2Log(Aig_ManRegNum(pAig));
+ if ( vPrioInit )
+ p->vPrio = vPrioInit;
+ else if ( pPars->fFlopPrio )
+ p->vPrio = Pdr_ManDeriveFlopPriorities2(p->pGia, 1);
+ else if ( p->pPars->fNewXSim )
+ p->vPrio = Vec_IntStartNatural( Aig_ManRegNum(pAig) );
+ else
+ p->vPrio = Vec_IntStart( Aig_ManRegNum(pAig) );
p->vLits = Vec_IntAlloc( 100 ); // array of literals
p->vCiObjs = Vec_IntAlloc( 100 ); // cone leaves
p->vCoObjs = Vec_IntAlloc( 100 ); // cone roots
@@ -67,9 +279,9 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio
p->vVisits = Vec_IntAlloc( 100 ); // intermediate
p->vCi2Rem = Vec_IntAlloc( 100 ); // CIs to be removed
p->vRes = Vec_IntAlloc( 100 ); // final result
- p->vSuppLits= Vec_IntAlloc( 100 ); // support literals
- p->pCubeJust= Pdr_SetAlloc( Saig_ManRegNum(pAig) );
p->pCnfMan = Cnf_ManStart();
+ // ternary simulation
+ p->pTxs = pPars->fNewXSim ? Txs_ManStart( p, pAig, p->vPrio ) : NULL;
// additional AIG data-members
if ( pAig->pFanData == NULL )
Aig_ManFanoutStart( pAig );
@@ -108,11 +320,12 @@ void Pdr_ManStop( Pdr_Man_t * p )
Pdr_Set_t * pCla;
sat_solver * pSat;
int i, k;
+ Gia_ManStopP( &p->pGia );
Aig_ManCleanMarkAB( p->pAig );
if ( p->pPars->fVerbose )
{
- Abc_Print( 1, "Block =%5d Oblig =%6d Clause =%6d Call =%6d (sat=%.1f%%) Start =%4d\n",
- p->nBlocks, p->nObligs, p->nCubes, p->nCalls, 100.0 * p->nCallsS / p->nCalls, p->nStarts );
+ Abc_Print( 1, "Block =%5d Oblig =%6d Clause =%6d Call =%6d (sat=%.1f%%) Cex =%4d Start =%4d\n",
+ p->nBlocks, p->nObligs, p->nCubes, p->nCalls, 100.0 * p->nCallsS / p->nCalls, p->nCexesTotal, p->nStarts );
ABC_PRTP( "SAT solving", p->tSat, p->tTotal );
ABC_PRTP( " unsat ", p->tSatUnsat, p->tTotal );
ABC_PRTP( " sat ", p->tSatSat, p->tTotal );
@@ -121,6 +334,7 @@ void Pdr_ManStop( Pdr_Man_t * p )
ABC_PRTP( "Ternary sim", p->tTsim, p->tTotal );
ABC_PRTP( "Containment", p->tContain, p->tTotal );
ABC_PRTP( "CNF compute", p->tCnf, p->tTotal );
+ ABC_PRTP( "Refinement ", p->tAbs, p->tTotal );
ABC_PRTP( "TOTAL ", p->tTotal, p->tTotal );
fflush( stdout );
}
@@ -150,6 +364,12 @@ void Pdr_ManStop( Pdr_Man_t * p )
Vec_WecFreeP( &p->vVLits );
// CNF manager
Cnf_ManStop( p->pCnfMan );
+ Vec_IntFreeP( &p->vAbsFlops );
+ Vec_IntFreeP( &p->vMapFf2Ppi );
+ Vec_IntFreeP( &p->vMapPpi2Ff );
+ // terminary simulation
+ if ( p->pPars->fNewXSim )
+ Txs_ManStop( p->pTxs );
// internal use
Vec_IntFreeP( &p->vPrio ); // priority flops
Vec_IntFree( p->vLits ); // array of literals
@@ -162,9 +382,7 @@ void Pdr_ManStop( Pdr_Man_t * p )
Vec_IntFree( p->vVisits ); // intermediate
Vec_IntFree( p->vCi2Rem ); // CIs to be removed
Vec_IntFree( p->vRes ); // final result
- Vec_IntFree( p->vSuppLits ); // support literals
Vec_PtrFreeP( &p->vInfCubes );
- ABC_FREE( p->pCubeJust );
ABC_FREE( p->pTime4Outs );
if ( p->vCexes )
Vec_PtrFreeFree( p->vCexes );
@@ -197,7 +415,6 @@ Abc_Cex_t * Pdr_ManDeriveCex( Pdr_Man_t * p )
nFrames++;
// create the counter-example
pCex = Abc_CexAlloc( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), nFrames );
-// pCex->iPo = (p->pPars->iOutput==-1)? 0 : p->pPars->iOutput;
pCex->iPo = p->iOutCur;
pCex->iFrame = nFrames-1;
for ( pObl = p->pQueue, f = 0; pObl; pObl = pObl->pNext, f++ )
@@ -206,6 +423,8 @@ Abc_Cex_t * Pdr_ManDeriveCex( Pdr_Man_t * p )
Lit = pObl->pState->Lits[i];
if ( lit_sign(Lit) )
continue;
+ if ( lit_var(Lit) >= pCex->nPis ) // allows PPI literals to be thrown away
+ continue;
assert( lit_var(Lit) < pCex->nPis );
Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + lit_var(Lit) );
}
@@ -215,6 +434,112 @@ Abc_Cex_t * Pdr_ManDeriveCex( Pdr_Man_t * p )
return pCex;
}
+/**Function*************************************************************
+
+ Synopsis [Derives counter-example when abstraction is used.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Cex_t * Pdr_ManDeriveCexAbs( Pdr_Man_t * p )
+{
+ extern Gia_Man_t * Gia_ManDupAbs( Gia_Man_t * p, Vec_Int_t * vMapPpi2Ff, Vec_Int_t * vMapFf2Ppi );
+
+ Gia_Man_t * pAbs;
+ Abc_Cex_t * pCex, * pCexCare;
+ Pdr_Obl_t * pObl;
+ int i, f, Lit, Flop, nFrames = 0;
+ int nPis = Saig_ManPiNum(p->pAig);
+ int nFfRefined = 0;
+ if ( !p->pPars->fUseAbs || !p->vMapPpi2Ff )
+ return Pdr_ManDeriveCex(p);
+ // restore previous map
+ Vec_IntForEachEntry( p->vMapPpi2Ff, Flop, i )
+ {
+ assert( Vec_IntEntry( p->vMapFf2Ppi, Flop ) == i );
+ Vec_IntWriteEntry( p->vMapFf2Ppi, Flop, -1 );
+ }
+ Vec_IntClear( p->vMapPpi2Ff );
+ // count the number of frames
+ for ( pObl = p->pQueue; pObl; pObl = pObl->pNext )
+ {
+ for ( i = pObl->pState->nLits; i < pObl->pState->nTotal; i++ )
+ {
+ Lit = pObl->pState->Lits[i];
+ if ( lit_var(Lit) < nPis ) // PI literal
+ continue;
+ Flop = lit_var(Lit) - nPis;
+ if ( Vec_IntEntry(p->vMapFf2Ppi, Flop) >= 0 ) // already used PPI literal
+ continue;
+ Vec_IntWriteEntry( p->vMapFf2Ppi, Flop, Vec_IntSize(p->vMapPpi2Ff) );
+ Vec_IntPush( p->vMapPpi2Ff, Flop );
+ }
+ nFrames++;
+ }
+ if ( Vec_IntSize(p->vMapPpi2Ff) == 0 ) // no PPIs -- this is a real CEX
+ return Pdr_ManDeriveCex(p);
+ if ( p->pPars->fUseSimpleRef )
+ {
+ // rely on ternary simulation to perform refinement
+ Vec_IntForEachEntry( p->vMapPpi2Ff, Flop, i )
+ {
+ assert( Vec_IntEntry(p->vAbsFlops, Flop) == 0 );
+ Vec_IntWriteEntry( p->vAbsFlops, Flop, 1 );
+ nFfRefined++;
+ }
+ }
+ else
+ {
+ // create the counter-example
+ pCex = Abc_CexAlloc( Aig_ManRegNum(p->pAig) - Vec_IntSize(p->vMapPpi2Ff), Saig_ManPiNum(p->pAig) + Vec_IntSize(p->vMapPpi2Ff), nFrames );
+ pCex->iPo = p->iOutCur;
+ pCex->iFrame = nFrames-1;
+ for ( pObl = p->pQueue, f = 0; pObl; pObl = pObl->pNext, f++ )
+ for ( i = pObl->pState->nLits; i < pObl->pState->nTotal; i++ )
+ {
+ Lit = pObl->pState->Lits[i];
+ if ( lit_sign(Lit) )
+ continue;
+ if ( lit_var(Lit) < nPis ) // PI literal
+ Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + lit_var(Lit) );
+ else
+ {
+ int iPPI = nPis + Vec_IntEntry(p->vMapFf2Ppi, lit_var(Lit) - nPis);
+ assert( iPPI < pCex->nPis );
+ Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + iPPI );
+ }
+ }
+ assert( f == nFrames );
+ // perform CEX minimization
+ pAbs = Gia_ManDupAbs( p->pGia, p->vMapPpi2Ff, p->vMapFf2Ppi );
+ pCexCare = Bmc_CexCareMinimizeAig( pAbs, nPis, pCex, 1, 0, 0 );
+ Gia_ManStop( pAbs );
+ assert( pCexCare->nPis == pCex->nPis );
+ Abc_CexFree( pCex );
+ // detect care PPIs
+ for ( f = 0; f < nFrames; f++ )
+ {
+ for ( i = nPis; i < pCexCare->nPis; i++ )
+ if ( Abc_InfoHasBit(pCexCare->pData, pCexCare->nRegs + pCexCare->nPis * f + i) )
+ {
+ if ( Vec_IntEntry(p->vAbsFlops, Vec_IntEntry(p->vMapPpi2Ff, i-nPis)) == 0 ) // currently abstracted
+ Vec_IntWriteEntry( p->vAbsFlops, Vec_IntEntry(p->vMapPpi2Ff, i-nPis), 1 ), nFfRefined++;
+ }
+ }
+ Abc_CexFree( pCexCare );
+ if ( nFfRefined == 0 ) // no refinement -- this is a real CEX
+ return Pdr_ManDeriveCex(p);
+ }
+ //printf( "CEX-based refinement refined %d flops.\n", nFfRefined );
+ p->nCexesTotal++;
+ p->nCexes++;
+ return NULL;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/proof/pdr/pdrSat.c b/src/proof/pdr/pdrSat.c
index 2e6130aa..ab582d9e 100644
--- a/src/proof/pdr/pdrSat.c
+++ b/src/proof/pdr/pdrSat.c
@@ -51,7 +51,8 @@ sat_solver * Pdr_ManCreateSolver( Pdr_Man_t * p, int k )
assert( Vec_VecSize(p->vClauses) == k );
assert( Vec_IntSize(p->vActVars) == k );
// create new solver
- pSat = sat_solver_new();
+// pSat = sat_solver_new();
+ pSat = zsat_solver_new_seed(p->pPars->nRandomSeed);
pSat = Pdr_ManNewSolver( pSat, p, k, (int)(k == 0) );
Vec_PtrPush( p->vSolvers, pSat );
Vec_VecExpand( p->vClauses, k );
@@ -86,7 +87,8 @@ sat_solver * Pdr_ManFetchSolver( Pdr_Man_t * p, int k )
p->nStarts++;
// sat_solver_delete( pSat );
// pSat = sat_solver_new();
- sat_solver_restart( pSat );
+// sat_solver_restart( pSat );
+ zsat_solver_restart_seed( pSat, p->pPars->nRandomSeed );
// create new SAT solver
pSat = Pdr_ManNewSolver( pSat, p, k, (int)(k == 0) );
// write new SAT solver
@@ -285,9 +287,9 @@ int Pdr_ManCheckCubeCs( Pdr_Man_t * p, int k, Pdr_Set_t * pCube )
SeeAlso []
***********************************************************************/
-int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPred, int nConfLimit, int fTryConf )
+int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPred, int nConfLimit, int fTryConf, int fUseLit )
{
- int fUseLit = 1;
+ //int fUseLit = 0;
int fLitUsed = 0;
sat_solver * pSat;
Vec_Int_t * vLits;
@@ -340,24 +342,6 @@ int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPr
else
return -1;
}
-/*
- if ( RetValue == l_True )
- {
- int RetValue2 = Pdr_ManCubeJust( p, k, pCube );
- if ( RetValue2 )
- p->nCasesSS++;
- else
- p->nCasesSU++;
- }
- else
- {
- int RetValue2 = Pdr_ManCubeJust( p, k, pCube );
- if ( RetValue2 )
- p->nCasesUS++;
- else
- p->nCasesUU++;
- }
-*/
}
clk = Abc_Clock() - clk;
p->tSat += clk;
@@ -375,7 +359,16 @@ int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPr
p->tSatSat += clk;
p->nCallsS++;
if ( ppPred )
- *ppPred = Pdr_ManTernarySim( p, k, pCube );
+ {
+ abctime clk = Abc_Clock();
+ if ( p->pPars->fNewXSim )
+ *ppPred = Txs_ManTernarySim( p->pTxs, k, pCube );
+ else
+ *ppPred = Pdr_ManTernarySim( p, k, pCube );
+ p->tTsim += Abc_Clock() - clk;
+ p->nXsimLits += (*ppPred)->nLits;
+ p->nXsimRuns++;
+ }
RetValue = 0;
}
diff --git a/src/proof/pdr/pdrTsim.c b/src/proof/pdr/pdrTsim.c
index 32d1c857..acbf70f5 100644
--- a/src/proof/pdr/pdrTsim.c
+++ b/src/proof/pdr/pdrTsim.c
@@ -364,7 +364,7 @@ Pdr_Set_t * Pdr_ManTernarySim( Pdr_Man_t * p, int k, Pdr_Set_t * pCube )
Vec_Int_t * vRes = p->vRes; // final result (flop literals)
Aig_Obj_t * pObj;
int i, Entry, RetValue;
- abctime clk = Abc_Clock();
+ //abctime clk = Abc_Clock();
// collect CO objects
Vec_IntClear( vCoObjs );
@@ -404,67 +404,65 @@ Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, NULL );
RetValue = Pdr_ManSimDataInit( p->pAig, vCiObjs, vCiVals, vNodes, vCoObjs, vCoVals, NULL );
assert( RetValue );
-#if 1
- // try removing high-priority flops
- Vec_IntClear( vCi2Rem );
- Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i )
+ // iteratively remove flops
+ if ( p->pPars->fFlopPrio )
{
- if ( !Saig_ObjIsLo( p->pAig, pObj ) )
- continue;
- Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig);
- if ( vPrio != NULL && Vec_IntEntry( vPrio, Entry ) != 0 )
- continue;
- Vec_IntClear( vUndo );
- if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) )
- Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) );
- else
- Pdr_ManExtendUndo( p->pAig, vUndo );
- }
- // try removing low-priority flops
- Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i )
- {
- if ( !Saig_ObjIsLo( p->pAig, pObj ) )
- continue;
- Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig);
- if ( vPrio == NULL || Vec_IntEntry( vPrio, Entry ) == 0 )
- continue;
- Vec_IntClear( vUndo );
- if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) )
- Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) );
- else
- Pdr_ManExtendUndo( p->pAig, vUndo );
- }
-#else
- // try removing low-priority flops
- Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i )
- {
- if ( !Saig_ObjIsLo( p->pAig, pObj ) )
- continue;
- Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig);
- if ( vPrio == NULL || Vec_IntEntry( vPrio, Entry ) == 0 )
- continue;
- Vec_IntClear( vUndo );
- if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) )
- Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) );
- else
- Pdr_ManExtendUndo( p->pAig, vUndo );
+ // collect flops and sort them by priority
+ Vec_IntClear( vRes );
+ Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i )
+ {
+ if ( !Saig_ObjIsLo( p->pAig, pObj ) )
+ continue;
+ Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig);
+ Vec_IntPush( vRes, Entry );
+ }
+ Vec_IntSelectSortCost( Vec_IntArray(vRes), Vec_IntSize(vRes), vPrio );
+
+ // try removing flops starting from low-priority to high-priority
+ Vec_IntClear( vCi2Rem );
+ Vec_IntForEachEntry( vRes, Entry, i )
+ {
+ pObj = Aig_ManCi( p->pAig, Saig_ManPiNum(p->pAig) + Entry );
+ assert( Saig_ObjIsLo( p->pAig, pObj ) );
+ Vec_IntClear( vUndo );
+ if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) )
+ Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) );
+ else
+ Pdr_ManExtendUndo( p->pAig, vUndo );
+ }
}
- // try removing high-priority flops
- Vec_IntClear( vCi2Rem );
- Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i )
+ else
{
- if ( !Saig_ObjIsLo( p->pAig, pObj ) )
- continue;
- Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig);
- if ( vPrio != NULL && Vec_IntEntry( vPrio, Entry ) != 0 )
- continue;
- Vec_IntClear( vUndo );
- if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) )
- Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) );
- else
- Pdr_ManExtendUndo( p->pAig, vUndo );
+ // try removing low-priority flops first
+ Vec_IntClear( vCi2Rem );
+ Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i )
+ {
+ if ( !Saig_ObjIsLo( p->pAig, pObj ) )
+ continue;
+ Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig);
+ if ( Vec_IntEntry(vPrio, Entry) )
+ continue;
+ Vec_IntClear( vUndo );
+ if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) )
+ Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) );
+ else
+ Pdr_ManExtendUndo( p->pAig, vUndo );
+ }
+ // try removing high-priority flops next
+ Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i )
+ {
+ if ( !Saig_ObjIsLo( p->pAig, pObj ) )
+ continue;
+ Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig);
+ if ( !Vec_IntEntry(vPrio, Entry) )
+ continue;
+ Vec_IntClear( vUndo );
+ if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) )
+ Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) );
+ else
+ Pdr_ManExtendUndo( p->pAig, vUndo );
+ }
}
-#endif
if ( p->pPars->fVeryVerbose )
Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, vCi2Rem );
@@ -474,9 +472,25 @@ Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, vCi2Rem );
// derive the set of resulting registers
Pdr_ManDeriveResult( p->pAig, vCiObjs, vCiVals, vCi2Rem, vRes, vPiLits );
assert( Vec_IntSize(vRes) > 0 );
- p->tTsim += Abc_Clock() - clk;
+ //p->tTsim += Abc_Clock() - clk;
+
+ // move abstracted literals from flops to inputs
+ if ( p->pPars->fUseAbs && p->vAbsFlops )
+ {
+ int i, iLit, k = 0;
+ Vec_IntForEachEntry( vRes, iLit, i )
+ {
+ if ( Vec_IntEntry(p->vAbsFlops, Abc_Lit2Var(iLit)) ) // used flop
+ Vec_IntWriteEntry( vRes, k++, iLit );
+ else
+ Vec_IntPush( vPiLits, 2*Saig_ManPiNum(p->pAig) + iLit );
+ }
+ Vec_IntShrink( vRes, k );
+ }
pRes = Pdr_SetCreate( vRes, vPiLits );
- assert( k == 0 || !Pdr_SetIsInit(pRes, -1) );
+ //ZH: Disabled assertion because this invariant doesn't hold with down
+ //because of the join operation which can bring in initial states
+ //assert( k == 0 || !Pdr_SetIsInit(pRes, -1) );
return pRes;
}
diff --git a/src/proof/pdr/pdrTsim2.c b/src/proof/pdr/pdrTsim2.c
new file mode 100644
index 00000000..8a86eecc
--- /dev/null
+++ b/src/proof/pdr/pdrTsim2.c
@@ -0,0 +1,550 @@
+/**CFile****************************************************************
+
+ FileName [pdrTsim.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Property driven reachability.]
+
+ Synopsis [Improved ternary simulation.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - November 20, 2010.]
+
+ Revision [$Id: pdrTsim.c,v 1.00 2010/11/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "pdrInt.h"
+#include "aig/gia/giaAig.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+struct Txs_Man_t_
+{
+ Gia_Man_t * pGia; // user's AIG
+ Vec_Int_t * vPrio; // priority of each flop
+ Vec_Int_t * vCiObjs; // cone leaves (CI obj IDs)
+ Vec_Int_t * vCoObjs; // cone roots (CO obj IDs)
+ Vec_Int_t * vCiVals; // cone leaf values (0/1 CI values)
+ Vec_Int_t * vCoVals; // cone root values (0/1 CO values)
+ Vec_Int_t * vNodes; // cone nodes (node obj IDs)
+ Vec_Int_t * vTemp; // cone nodes (node obj IDs)
+ Vec_Int_t * vPiLits; // resulting array of PI literals
+ Vec_Int_t * vFfLits; // resulting array of flop literals
+ Pdr_Man_t * pMan; // calling manager
+};
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Start and stop the ternary simulation engine.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Txs_Man_t * Txs_ManStart( Pdr_Man_t * pMan, Aig_Man_t * pAig, Vec_Int_t * vPrio )
+{
+ Txs_Man_t * p;
+// Aig_Obj_t * pObj;
+// int i;
+ assert( Vec_IntSize(vPrio) == Aig_ManRegNum(pAig) );
+ p = ABC_CALLOC( Txs_Man_t, 1 );
+ p->pGia = Gia_ManFromAigSimple(pAig); // user's AIG
+// Aig_ManForEachObj( pAig, pObj, i )
+// assert( i == 0 || pObj->iData == Abc_Var2Lit(i, 0) );
+ p->vPrio = vPrio; // priority of each flop
+ p->vCiObjs = Vec_IntAlloc( 100 ); // cone leaves (CI obj IDs)
+ p->vCoObjs = Vec_IntAlloc( 100 ); // cone roots (CO obj IDs)
+ p->vCiVals = Vec_IntAlloc( 100 ); // cone leaf values (0/1 CI values)
+ p->vCoVals = Vec_IntAlloc( 100 ); // cone root values (0/1 CO values)
+ p->vNodes = Vec_IntAlloc( 100 ); // cone nodes (node obj IDs)
+ p->vTemp = Vec_IntAlloc( 100 ); // cone nodes (node obj IDs)
+ p->vPiLits = Vec_IntAlloc( 100 ); // resulting array of PI literals
+ p->vFfLits = Vec_IntAlloc( 100 ); // resulting array of flop literals
+ p->pMan = pMan; // calling manager
+ return p;
+}
+void Txs_ManStop( Txs_Man_t * p )
+{
+ Gia_ManStop( p->pGia );
+ Vec_IntFree( p->vCiObjs );
+ Vec_IntFree( p->vCoObjs );
+ Vec_IntFree( p->vCiVals );
+ Vec_IntFree( p->vCoVals );
+ Vec_IntFree( p->vNodes );
+ Vec_IntFree( p->vTemp );
+ Vec_IntFree( p->vPiLits );
+ Vec_IntFree( p->vFfLits );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Marks the TFI cone and collects CIs and nodes.]
+
+ Description [For this procedure to work Value should not be ~0
+ at the beginning.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Txs_ManCollectCone_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vCiObjs, Vec_Int_t * vNodes )
+{
+ if ( !~pObj->Value )
+ return;
+ pObj->Value = ~0;
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ Vec_IntPush( vCiObjs, Gia_ObjId(p, pObj) );
+ return;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ Txs_ManCollectCone_rec( p, Gia_ObjFanin0(pObj), vCiObjs, vNodes );
+ Txs_ManCollectCone_rec( p, Gia_ObjFanin1(pObj), vCiObjs, vNodes );
+ Vec_IntPush( vNodes, Gia_ObjId(p, pObj) );
+}
+void Txs_ManCollectCone( Gia_Man_t * p, Vec_Int_t * vCoObjs, Vec_Int_t * vCiObjs, Vec_Int_t * vNodes )
+{
+ Gia_Obj_t * pObj; int i;
+// printf( "Collecting cones for clause with %d literals.\n", Vec_IntSize(vCoObjs) );
+ Vec_IntClear( vCiObjs );
+ Vec_IntClear( vNodes );
+ Gia_ManConst0(p)->Value = ~0;
+ Gia_ManForEachObjVec( vCoObjs, p, pObj, i )
+ Txs_ManCollectCone_rec( p, Gia_ObjFanin0(pObj), vCiObjs, vNodes );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Propagate values and assign priority.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Txs_ManForwardPass( Gia_Man_t * p,
+ Vec_Int_t * vPrio, Vec_Int_t * vCiObjs, Vec_Int_t * vCiVals,
+ Vec_Int_t * vNodes, Vec_Int_t * vCoObjs, Vec_Int_t * vCoVals )
+{
+ Gia_Obj_t * pObj, * pFan0, * pFan1;
+ int i, value0, value1;
+ pObj = Gia_ManConst0(p);
+ pObj->fMark0 = 0;
+ pObj->fMark1 = 0;
+ Gia_ManForEachObjVec( vCiObjs, p, pObj, i )
+ {
+ pObj->fMark0 = Vec_IntEntry(vCiVals, i);
+ pObj->fMark1 = 0;
+ pObj->Value = Gia_ObjIsPi(p, pObj) ? 0x7FFFFFFF : Vec_IntEntry(vPrio, Gia_ObjCioId(pObj)-Gia_ManPiNum(p));
+ assert( ~pObj->Value );
+ }
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ {
+ pFan0 = Gia_ObjFanin0(pObj);
+ pFan1 = Gia_ObjFanin1(pObj);
+ value0 = pFan0->fMark0 ^ Gia_ObjFaninC0(pObj);
+ value1 = pFan1->fMark0 ^ Gia_ObjFaninC1(pObj);
+ pObj->fMark0 = value0 && value1;
+ pObj->fMark1 = 0;
+ if ( pObj->fMark0 )
+ pObj->Value = Abc_MinInt( pFan0->Value, pFan1->Value );
+ else if ( value0 )
+ pObj->Value = pFan1->Value;
+ else if ( value1 )
+ pObj->Value = pFan0->Value;
+ else // if ( value0 == 0 && value1 == 0 )
+ pObj->Value = Abc_MaxInt( pFan0->Value, pFan1->Value );
+ assert( ~pObj->Value );
+ }
+ Gia_ManForEachObjVec( vCoObjs, p, pObj, i )
+ {
+ pFan0 = Gia_ObjFanin0(pObj);
+ pObj->fMark0 = (pFan0->fMark0 ^ Gia_ObjFaninC0(pObj));
+ pFan0->fMark1 = 1;
+ assert( (int)pObj->fMark0 == Vec_IntEntry(vCoVals, i) );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Propagate requirements and collect results.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Txs_ObjIsJust( Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ Gia_Obj_t * pFan0 = Gia_ObjFanin0(pObj);
+ Gia_Obj_t * pFan1 = Gia_ObjFanin1(pObj);
+ int value0 = pFan0->fMark0 ^ Gia_ObjFaninC0(pObj);
+ int value1 = pFan1->fMark0 ^ Gia_ObjFaninC1(pObj);
+ assert( Gia_ObjIsAnd(pObj) );
+ if ( pObj->fMark0 )
+ return pFan0->fMark1 && pFan1->fMark1;
+ assert( !pObj->fMark0 );
+ assert( !value0 || !value1 );
+ if ( value0 )
+ return pFan1->fMark1 || Gia_ObjIsPi(p, pFan1);
+ if ( value1 )
+ return pFan0->fMark1 || Gia_ObjIsPi(p, pFan0);
+ assert( !value0 && !value1 );
+ return pFan0->fMark1 || pFan1->fMark1 || Gia_ObjIsPi(p, pFan0) || Gia_ObjIsPi(p, pFan1);
+}
+void Txs_ManBackwardPass( Gia_Man_t * p, Vec_Int_t * vCiObjs, Vec_Int_t * vNodes, Vec_Int_t * vPiLits, Vec_Int_t * vFfLits )
+{
+ Gia_Obj_t * pObj, * pFan0, * pFan1; int i, value0, value1;
+ Gia_ManForEachObjVecReverse( vNodes, p, pObj, i )
+ {
+ if ( !pObj->fMark1 )
+ continue;
+ pObj->fMark1 = 0;
+ pFan0 = Gia_ObjFanin0(pObj);
+ pFan1 = Gia_ObjFanin1(pObj);
+ if ( pObj->fMark0 )
+ {
+ pFan0->fMark1 = 1;
+ pFan1->fMark1 = 1;
+ continue;
+ }
+ value0 = pFan0->fMark0 ^ Gia_ObjFaninC0(pObj);
+ value1 = pFan1->fMark0 ^ Gia_ObjFaninC1(pObj);
+ assert( !value0 || !value1 );
+ if ( value0 )
+ pFan1->fMark1 = 1;
+ else if ( value1 )
+ pFan0->fMark1 = 1;
+ else // if ( !value0 && !value1 )
+ {
+ if ( pFan0->fMark1 || pFan1->fMark1 )
+ continue;
+ if ( Gia_ObjIsPi(p, pFan0) )
+ pFan0->fMark1 = 1;
+ else if ( Gia_ObjIsPi(p, pFan1) )
+ pFan1->fMark1 = 1;
+ else if ( Gia_ObjIsAnd(pFan0) && Txs_ObjIsJust(p, pFan0) )
+ pFan0->fMark1 = 1;
+ else if ( Gia_ObjIsAnd(pFan1) && Txs_ObjIsJust(p, pFan1) )
+ pFan1->fMark1 = 1;
+ else
+ {
+ if ( pFan0->Value >= pFan1->Value )
+ pFan0->fMark1 = 1;
+ else
+ pFan1->fMark1 = 1;
+ }
+ }
+ }
+ Vec_IntClear( vPiLits );
+ Vec_IntClear( vFfLits );
+ Gia_ManForEachObjVec( vCiObjs, p, pObj, i )
+ {
+ if ( !pObj->fMark1 )
+ continue;
+ if ( Gia_ObjIsPi(p, pObj) )
+ Vec_IntPush( vPiLits, Abc_Var2Lit(Gia_ObjCioId(pObj), !pObj->fMark0) );
+ else
+ Vec_IntPush( vFfLits, Abc_Var2Lit(Gia_ObjCioId(pObj)-Gia_ManPiNum(p), !pObj->fMark0) );
+ }
+ assert( Vec_IntSize(vFfLits) > 0 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects justification path.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Txs_ManSelectJustPath( Gia_Man_t * p, Vec_Int_t * vNodes, Vec_Int_t * vCoObjs, Vec_Int_t * vRes )
+{
+ Gia_Obj_t * pObj, * pFan0, * pFan1;
+ int i, value0, value1;
+ // mark CO drivers
+ Gia_ManForEachObjVec( vCoObjs, p, pObj, i )
+ Gia_ObjFanin0(pObj)->fMark1 = 1;
+ // collect just paths
+ Vec_IntClear( vRes );
+ Gia_ManForEachObjVecReverse( vNodes, p, pObj, i )
+ {
+ if ( !pObj->fMark1 )
+ continue;
+ pObj->fMark1 = 0;
+ Vec_IntPush( vRes, Gia_ObjId(p, pObj) );
+ pFan0 = Gia_ObjFanin0(pObj);
+ pFan1 = Gia_ObjFanin1(pObj);
+ if ( pObj->fMark0 )
+ {
+ pFan0->fMark1 = 1;
+ pFan1->fMark1 = 1;
+ continue;
+ }
+ value0 = pFan0->fMark0 ^ Gia_ObjFaninC0(pObj);
+ value1 = pFan1->fMark0 ^ Gia_ObjFaninC1(pObj);
+ assert( !value0 || !value1 );
+ if ( value0 )
+ pFan1->fMark1 = 1;
+ else if ( value1 )
+ pFan0->fMark1 = 1;
+ else // if ( !value0 && !value1 )
+ {
+ pFan0->fMark1 = 1;
+ pFan1->fMark1 = 1;
+ }
+ }
+ Vec_IntReverseOrder( vRes );
+}
+void Txs_ManCollectJustPis( Gia_Man_t * p, Vec_Int_t * vCiObjs, Vec_Int_t * vPiLits )
+{
+ Gia_Obj_t * pObj; int i;
+ Vec_IntClear( vPiLits );
+ Gia_ManForEachObjVec( vCiObjs, p, pObj, i )
+ if ( pObj->fMark1 && Gia_ObjIsPi(p, pObj) )
+ Vec_IntPush( vPiLits, Abc_Var2Lit(Gia_ObjCioId(pObj), !pObj->fMark0) );
+}
+void Txs_ManInitPrio( Gia_Man_t * p, Vec_Int_t * vCiObjs )
+{
+ Gia_Obj_t * pObj; int i;
+ Gia_ManConst0(p)->Value = 0x7FFFFFFF;
+ Gia_ManForEachObjVec( vCiObjs, p, pObj, i )
+ pObj->Value = Gia_ObjIsPi(p, pObj) ? 0x7FFFFFFF : Gia_ObjCioId(pObj) - Gia_ManPiNum(p);
+}
+void Txs_ManPropagatePrio( Gia_Man_t * p, Vec_Int_t * vNodes, Vec_Int_t * vPrio )
+{
+ Gia_Obj_t * pObj, * pFan0, * pFan1;
+ int i, value0, value1;
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ {
+ pFan0 = Gia_ObjFanin0(pObj);
+ pFan1 = Gia_ObjFanin1(pObj);
+ if ( pObj->fMark0 )
+ {
+// pObj->Value = Abc_MinInt( pFan0->Value, pFan1->Value );
+ if ( pFan0->Value == 0x7FFFFFFF )
+ pObj->Value = pFan1->Value;
+ else if ( pFan1->Value == 0x7FFFFFFF )
+ pObj->Value = pFan0->Value;
+ else if ( Vec_IntEntry(vPrio, pFan0->Value) < Vec_IntEntry(vPrio, pFan1->Value) )
+ pObj->Value = pFan0->Value;
+ else
+ pObj->Value = pFan1->Value;
+ continue;
+ }
+ value0 = pFan0->fMark0 ^ Gia_ObjFaninC0(pObj);
+ value1 = pFan1->fMark0 ^ Gia_ObjFaninC1(pObj);
+ assert( !value0 || !value1 );
+ if ( value0 )
+ pObj->Value = pFan1->Value;
+ else if ( value1 )
+ pObj->Value = pFan0->Value;
+ else // if ( value0 == 0 && value1 == 0 )
+ {
+// pObj->Value = Abc_MaxInt( pFan0->Value, pFan1->Value );
+ if ( pFan0->Value == 0x7FFFFFFF || pFan1->Value == 0x7FFFFFFF )
+ pObj->Value = 0x7FFFFFFF;
+ else if ( Vec_IntEntry(vPrio, pFan0->Value) >= Vec_IntEntry(vPrio, pFan1->Value) )
+ pObj->Value = pFan0->Value;
+ else
+ pObj->Value = pFan1->Value;
+ }
+ assert( ~pObj->Value );
+ }
+}
+int Txs_ManFindMinId( Gia_Man_t * p, Vec_Int_t * vCoObjs, Vec_Int_t * vPrio )
+{
+ Gia_Obj_t * pObj; int i, iMinId = -1;
+ Gia_ManForEachObjVec( vCoObjs, p, pObj, i )
+ if ( Gia_ObjFanin0(pObj)->Value != 0x7FFFFFFF )
+ {
+ if ( iMinId == -1 || Vec_IntEntry(vPrio, iMinId) > Vec_IntEntry(vPrio, Gia_ObjFanin0(pObj)->Value) )
+ iMinId = Gia_ObjFanin0(pObj)->Value;
+ }
+ return iMinId;
+}
+void Txs_ManFindCiReduction( Gia_Man_t * p,
+ Vec_Int_t * vPrio, Vec_Int_t * vCiObjs,
+ Vec_Int_t * vNodes, Vec_Int_t * vCoObjs,
+ Vec_Int_t * vPiLits, Vec_Int_t * vFfLits, Vec_Int_t * vTemp )
+{
+ Gia_Obj_t * pObj;
+ int iPrioCi;
+ // propagate PI influence
+ Txs_ManSelectJustPath( p, vNodes, vCoObjs, vTemp );
+ Txs_ManCollectJustPis( p, vCiObjs, vPiLits );
+// printf( "%d -> %d ", Vec_IntSize(vNodes), Vec_IntSize(vTemp) );
+ // iteratively detect and remove smallest IDs
+ Vec_IntClear( vFfLits );
+ Txs_ManInitPrio( p, vCiObjs );
+ while ( 1 )
+ {
+ Txs_ManPropagatePrio( p, vTemp, vPrio );
+ iPrioCi = Txs_ManFindMinId( p, vCoObjs, vPrio );
+ if ( iPrioCi == -1 )
+ break;
+ pObj = Gia_ManCi( p, Gia_ManPiNum(p)+iPrioCi );
+ Vec_IntPush( vFfLits, Abc_Var2Lit(iPrioCi, !pObj->fMark0) );
+ pObj->Value = 0x7FFFFFFF;
+ }
+}
+void Txs_ManPrintFlopLits( Vec_Int_t * vFfLits, Vec_Int_t * vPrio )
+{
+ int i, Entry;
+ printf( "%3d : ", Vec_IntSize(vFfLits) );
+ Vec_IntForEachEntry( vFfLits, Entry, i )
+ printf( "%s%d(%d) ", Abc_LitIsCompl(Entry)? "+":"-", Abc_Lit2Var(Entry), Vec_IntEntry(vPrio, Abc_Lit2Var(Entry)) );
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Verify the result.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Txs_ManVerify( Gia_Man_t * p, Vec_Int_t * vCiObjs, Vec_Int_t * vNodes, Vec_Int_t * vPiLits, Vec_Int_t * vFfLits, Vec_Int_t * vCoObjs, Vec_Int_t * vCoVals )
+{
+ Gia_Obj_t * pObj;
+ int i, iLit;
+ Gia_ObjTerSimSet0( Gia_ManConst0(p) );
+ Gia_ManForEachObjVec( vCiObjs, p, pObj, i )
+ Gia_ObjTerSimSetX( pObj );
+ Vec_IntForEachEntry( vPiLits, iLit, i )
+ {
+ pObj = Gia_ManPi( p, Abc_Lit2Var(iLit) );
+ assert( Gia_ObjTerSimGetX(pObj) );
+ if ( Abc_LitIsCompl(iLit) )
+ Gia_ObjTerSimSet0( pObj );
+ else
+ Gia_ObjTerSimSet1( pObj );
+ }
+ Vec_IntForEachEntry( vFfLits, iLit, i )
+ {
+ pObj = Gia_ManCi( p, Gia_ManPiNum(p) + Abc_Lit2Var(iLit) );
+ assert( Gia_ObjTerSimGetX(pObj) );
+ if ( Abc_LitIsCompl(iLit) )
+ Gia_ObjTerSimSet0( pObj );
+ else
+ Gia_ObjTerSimSet1( pObj );
+ }
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ Gia_ObjTerSimAnd( pObj );
+ Gia_ManForEachObjVec( vCoObjs, p, pObj, i )
+ {
+ Gia_ObjTerSimCo( pObj );
+ if ( Vec_IntEntry(vCoVals, i) )
+ assert( Gia_ObjTerSimGet1(pObj) );
+ else
+ assert( Gia_ObjTerSimGet0(pObj) );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Shrinks values using ternary simulation.]
+
+ Description [The cube contains the set of flop index literals which,
+ when converted into a clause and applied to the combinational outputs,
+ led to a satisfiable SAT run in frame k (values stored in the SAT solver).
+ If the cube is NULL, it is assumed that the first property output was
+ asserted and failed.
+ The resulting array is a set of flop index literals that asserts the COs.
+ Priority contains 0 for i-th entry if the i-th FF is desirable to remove.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Pdr_Set_t * Txs_ManTernarySim( Txs_Man_t * p, int k, Pdr_Set_t * pCube )
+{
+ int fTryNew = 1;
+ Pdr_Set_t * pRes;
+ Gia_Obj_t * pObj;
+ // collect CO objects
+ Vec_IntClear( p->vCoObjs );
+ if ( pCube == NULL ) // the target is the property output
+ {
+ pObj = Gia_ManCo(p->pGia, p->pMan->iOutCur);
+ Vec_IntPush( p->vCoObjs, Gia_ObjId(p->pGia, pObj) );
+ }
+ else // the target is the cube
+ {
+ int i;
+ for ( i = 0; i < pCube->nLits; i++ )
+ {
+ if ( pCube->Lits[i] == -1 )
+ continue;
+ pObj = Gia_ManCo(p->pGia, Gia_ManPoNum(p->pGia) + Abc_Lit2Var(pCube->Lits[i]));
+ Vec_IntPush( p->vCoObjs, Gia_ObjId(p->pGia, pObj) );
+ }
+ }
+if ( 0 )
+{
+Abc_Print( 1, "Trying to justify cube " );
+if ( pCube )
+ Pdr_SetPrint( stdout, pCube, Gia_ManRegNum(p->pGia), NULL );
+else
+ Abc_Print( 1, "<prop=fail>" );
+Abc_Print( 1, " in frame %d.\n", k );
+}
+
+ // collect CI objects
+ Txs_ManCollectCone( p->pGia, p->vCoObjs, p->vCiObjs, p->vNodes );
+ // collect values
+ Pdr_ManCollectValues( p->pMan, k, p->vCiObjs, p->vCiVals );
+ Pdr_ManCollectValues( p->pMan, k, p->vCoObjs, p->vCoVals );
+
+ // perform two passes
+ Txs_ManForwardPass( p->pGia, p->vPrio, p->vCiObjs, p->vCiVals, p->vNodes, p->vCoObjs, p->vCoVals );
+ if ( fTryNew )
+ Txs_ManFindCiReduction( p->pGia, p->vPrio, p->vCiObjs, p->vNodes, p->vCoObjs, p->vPiLits, p->vFfLits, p->vTemp );
+ else
+ Txs_ManBackwardPass( p->pGia, p->vCiObjs, p->vNodes, p->vPiLits, p->vFfLits );
+ Txs_ManVerify( p->pGia, p->vCiObjs, p->vNodes, p->vPiLits, p->vFfLits, p->vCoObjs, p->vCoVals );
+
+ // derive the final set
+ pRes = Pdr_SetCreate( p->vFfLits, p->vPiLits );
+ //ZH: Disabled assertion because this invariant doesn't hold with down
+ //because of the join operation which can bring in initial states
+ //assert( k == 0 || !Pdr_SetIsInit(pRes, -1) );
+ return pRes;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
diff --git a/src/proof/pdr/pdrUtil.c b/src/proof/pdr/pdrUtil.c
index 53a8a54a..986697ac 100644
--- a/src/proof/pdr/pdrUtil.c
+++ b/src/proof/pdr/pdrUtil.c
@@ -260,6 +260,85 @@ void Pdr_SetPrint( FILE * pFile, Pdr_Set_t * p, int nRegs, Vec_Int_t * vFlopCoun
SeeAlso []
***********************************************************************/
+void ZPdr_SetPrint( Pdr_Set_t * p )
+{
+ int i;
+ for ( i = 0; i < p->nLits; i++)
+ printf ("%d ", p->Lits[i]);
+ printf ("\n");
+
+}
+
+/**Function*************************************************************
+
+ Synopsis [Return the intersection of p1 and p2.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Pdr_Set_t * ZPdr_SetIntersection( Pdr_Set_t * p1, Pdr_Set_t * p2, Hash_Int_t * keep )
+{
+ Pdr_Set_t * pIntersection;
+ Vec_Int_t * vCommonLits, * vPiLits;
+ int i, j, nLits;
+ nLits = p1->nLits;
+ if ( p2->nLits < nLits )
+ nLits = p2->nLits;
+ vCommonLits = Vec_IntAlloc( nLits );
+ vPiLits = Vec_IntAlloc( 1 );
+ for ( i = 0, j = 0; i < p1->nLits && j < p2->nLits; )
+ {
+ if ( p1->Lits[i] > p2->Lits[j] )
+ {
+ if ( Hash_IntExists( keep, p2->Lits[j] ) )
+ {
+ //about to drop a literal that should not be dropped
+ Vec_IntFree( vCommonLits );
+ Vec_IntFree( vPiLits );
+ return NULL;
+ }
+ j++;
+ }
+ else if ( p1->Lits[i] < p2->Lits[j] )
+ {
+ if ( Hash_IntExists( keep, p1->Lits[i] ) )
+ {
+ //about to drop a literal that should not be dropped
+ Vec_IntFree( vCommonLits );
+ Vec_IntFree( vPiLits );
+ return NULL;
+ }
+ i++;
+ }
+ else
+ {
+ Vec_IntPush( vCommonLits, p1->Lits[i] );
+ i++;
+ j++;
+ }
+ }
+ pIntersection = Pdr_SetCreate( vCommonLits, vPiLits );
+ Vec_IntFree( vCommonLits );
+ Vec_IntFree( vPiLits );
+ return pIntersection;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
void Pdr_SetPrintStr( Vec_Str_t * vStr, Pdr_Set_t * p, int nRegs, Vec_Int_t * vFlopCounts )
{
char * pBuff;
@@ -284,7 +363,7 @@ void Pdr_SetPrintStr( Vec_Str_t * vStr, Pdr_Set_t * p, int nRegs, Vec_Int_t * vF
}
Vec_StrPushBuffer( vStr, pBuff, k );
Vec_StrPush( vStr, ' ' );
- Vec_StrPush( vStr, '0' );
+ Vec_StrPush( vStr, '1' );
Vec_StrPush( vStr, '\n' );
ABC_FREE( pBuff );
}
@@ -674,8 +753,6 @@ int Pdr_NtkFindSatAssign_rec( Aig_Man_t * pAig, Aig_Obj_t * pNode, int Value, Pd
pNode->fMarkA = Value;
if ( Aig_ObjIsCi(pNode) )
{
-// if ( vSuppLits )
-// Vec_IntPush( vSuppLits, Abc_Var2Lit( Aig_ObjCioId(pNode), !Value ) );
if ( Saig_ObjIsLo(pAig, pNode) )
{
// pCube->Lits[pCube->nLits++] = Abc_Var2Lit( Aig_ObjCioId(pNode) - Saig_ManPiNum(pAig), !Value );
@@ -714,60 +791,6 @@ int Pdr_NtkFindSatAssign_rec( Aig_Man_t * pAig, Aig_Obj_t * pNode, int Value, Pd
return Pdr_NtkFindSatAssign_rec(pAig, Aig_ObjFanin0(pNode), Aig_ObjFaninC0(pNode), pCube, Heur);
}
-/**Function*************************************************************
-
- Synopsis [Returns 1 if SAT assignment is found; 0 otherwise.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Pdr_ManCubeJust( Pdr_Man_t * p, int k, Pdr_Set_t * pCube )
-{
- Aig_Obj_t * pNode;
- int i, v, fCompl;
-// return 0;
- for ( i = 0; i < 4; i++ )
- {
- // derive new assignment
- p->pCubeJust->nLits = 0;
- p->pCubeJust->Sign = 0;
- Aig_ManIncrementTravId( p->pAig );
- for ( v = 0; v < pCube->nLits; v++ )
- {
- if ( pCube->Lits[v] == -1 )
- continue;
- pNode = Saig_ManLi( p->pAig, lit_var(pCube->Lits[v]) );
- fCompl = lit_sign(pCube->Lits[v]) ^ Aig_ObjFaninC0(pNode);
- if ( !Pdr_NtkFindSatAssign_rec( p->pAig, Aig_ObjFanin0(pNode), !fCompl, p->pCubeJust, i ) )
- break;
- }
- if ( v < pCube->nLits )
- continue;
- // figure this out!!!
- if ( p->pCubeJust->nLits == 0 )
- continue;
- // successfully derived new assignment
- Vec_IntSelectSort( p->pCubeJust->Lits, p->pCubeJust->nLits );
- // check assignment against this cube
- if ( Pdr_SetContainsSimple( p->pCubeJust, pCube ) )
- continue;
-//printf( "\n" );
-//Pdr_SetPrint( stdout, pCube, Saig_ManRegNum(p->pAig), NULL ); printf( "\n" );
-//Pdr_SetPrint( stdout, p->pCubeJust, Saig_ManRegNum(p->pAig), NULL ); printf( "\n" );
- // check assignment against the clauses
- if ( Pdr_ManCheckContainment( p, k, p->pCubeJust ) )
- continue;
- // find good assignment
- return 1;
- }
- return 0;
-}
-
-
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/sat/bmc/bmc.h b/src/sat/bmc/bmc.h
index 30538253..a3f353c2 100644
--- a/src/sat/bmc/bmc.h
+++ b/src/sat/bmc/bmc.h
@@ -164,7 +164,8 @@ extern int Saig_ManBmcScalable( Aig_Man_t * pAig, Saig_ParBmc_t *
extern int Gia_ManBmcPerform( Gia_Man_t * p, Bmc_AndPar_t * pPars );
/*=== bmcCexCare.c ==========================================================*/
extern Abc_Cex_t * Bmc_CexCareExtendToObjects( Gia_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t * pCexCare );
-extern Abc_Cex_t * Bmc_CexCareMinimize( Aig_Man_t * p, Abc_Cex_t * pCex, int fCheck, int fVerbose );
+extern Abc_Cex_t * Bmc_CexCareMinimize( Aig_Man_t * p, int nRealPis, Abc_Cex_t * pCex, int nTryCexes, int fCheck, int fVerbose );
+extern Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nRealPis, Abc_Cex_t * pCex, int nTryCexes, int fCheck, int fVerbose );
extern void Bmc_CexCareVerify( Aig_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t * pCexMin, int fVerbose );
/*=== bmcCexCut.c ==========================================================*/
extern Gia_Man_t * Bmc_GiaTargetStates( Gia_Man_t * p, Abc_Cex_t * pCex, int iFrBeg, int iFrEnd, int fCombOnly, int fGenAll, int fAllFrames, int fVerbose );
@@ -172,7 +173,7 @@ extern Aig_Man_t * Bmc_AigTargetStates( Aig_Man_t * p, Abc_Cex_t * pCex, i
/*=== bmcCexMin.c ==========================================================*/
extern Abc_Cex_t * Saig_ManCexMinPerform( Aig_Man_t * pAig, Abc_Cex_t * pCex );
/*=== bmcCexTool.c ==========================================================*/
-extern void Bmc_CexPrint( Abc_Cex_t * pCex, int nInputs, int fVerbose );
+extern void Bmc_CexPrint( Abc_Cex_t * pCex, int nRealPis, int fVerbose );
extern int Bmc_CexVerify( Gia_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t * pCexCare );
/*=== bmcICheck.c ==========================================================*/
extern void Bmc_PerformICheck( Gia_Man_t * p, int nFramesMax, int nTimeOut, int fEmpty, int fVerbose );
diff --git a/src/sat/bmc/bmcBmcAnd.c b/src/sat/bmc/bmcBmcAnd.c
index 8087046a..3490d34f 100644
--- a/src/sat/bmc/bmcBmcAnd.c
+++ b/src/sat/bmc/bmcBmcAnd.c
@@ -986,8 +986,7 @@ int Gia_ManBmcPerformInt( Gia_Man_t * pGia, Bmc_AndPar_t * pPars )
{
// p->pFrames = Jf_ManDeriveCnf( pTemp = p->pFrames, 1 ); Gia_ManStop( pTemp );
// p->pCnf = (Cnf_Dat_t *)p->pFrames->pData; p->pFrames->pData = NULL;
- extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
- p->pCnf = Mf_ManGenerateCnf( p->pFrames, pPars->nLutSize, 1, 0, pPars->fVerbose );
+ p->pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p->pFrames, pPars->nLutSize, 1, 0, 0, pPars->fVerbose );
}
Vec_IntFillExtra( p->vId2Var, Gia_ManObjNum(p->pFrames), 0 );
// create clauses for constant node
diff --git a/src/sat/bmc/bmcCexCare.c b/src/sat/bmc/bmcCexCare.c
index 21fea429..cc3e85ea 100644
--- a/src/sat/bmc/bmcCexCare.c
+++ b/src/sat/bmc/bmcCexCare.c
@@ -88,7 +88,7 @@ Abc_Cex_t * Bmc_CexCareExtendToObjects( Gia_Man_t * p, Abc_Cex_t * pCex, Abc_Cex
/**Function*************************************************************
- Synopsis [Backward propagation.]
+ Synopsis [Forward propagation.]
Description []
@@ -97,21 +97,14 @@ Abc_Cex_t * Bmc_CexCareExtendToObjects( Gia_Man_t * p, Abc_Cex_t * pCex, Abc_Cex
SeeAlso []
***********************************************************************/
-void Bmc_CexCarePropagateFwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, int fGrow )
+void Bmc_CexCarePropagateFwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, Vec_Int_t * vPriosIn )
{
Gia_Obj_t * pObj;
int Prio, Prio0, Prio1;
int i, Phase0, Phase1;
- if ( (fGrow & 2) )
- {
- Gia_ManForEachPi( p, pObj, i )
- pObj->Value = Abc_Var2Lit( f * pCex->nPis + (pCex->nPis-1-i) + 1, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i) );
- }
- else
- {
- Gia_ManForEachPi( p, pObj, i )
- pObj->Value = Abc_Var2Lit( f * pCex->nPis + i + 1, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i) );
- }
+ assert( Vec_IntSize(vPriosIn) == pCex->nPis * (pCex->iFrame + 1) );
+ Gia_ManForEachPi( p, pObj, i )
+ pObj->Value = Vec_IntEntry( vPriosIn, f * pCex->nPis + i );
Gia_ManForEachAnd( p, pObj, i )
{
Prio0 = Abc_Lit2Var(Gia_ObjFanin0(pObj)->Value);
@@ -119,37 +112,38 @@ void Bmc_CexCarePropagateFwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, int fGr
Phase0 = Abc_LitIsCompl(Gia_ObjFanin0(pObj)->Value) ^ Gia_ObjFaninC0(pObj);
Phase1 = Abc_LitIsCompl(Gia_ObjFanin1(pObj)->Value) ^ Gia_ObjFaninC1(pObj);
if ( Phase0 && Phase1 )
- Prio = (fGrow & 1) ? Abc_MinInt(Prio0, Prio1) : Abc_MaxInt(Prio0, Prio1);
- else if ( Phase0 && !Phase1 )
+ Prio = Abc_MinInt(Prio0, Prio1);
+ else if ( Phase0 )
Prio = Prio1;
- else if ( !Phase0 && Phase1 )
+ else if ( Phase1 )
Prio = Prio0;
else // if ( !Phase0 && !Phase1 )
- Prio = (fGrow & 1) ? Abc_MaxInt(Prio0, Prio1) : Abc_MinInt(Prio0, Prio1);
- pObj->Value = Abc_Var2Lit( Prio, Phase0 & Phase1 );
+ Prio = Abc_MaxInt(Prio0, Prio1);
+ pObj->Value = Abc_Var2Lit( Prio, Phase0 && Phase1 );
+ pObj->fPhase = 0;
}
Gia_ManForEachCo( p, pObj, i )
pObj->Value = Abc_LitNotCond( Gia_ObjFanin0(pObj)->Value, Gia_ObjFaninC0(pObj) );
}
-void Bmc_CexCarePropagateFwd( Gia_Man_t * p, Abc_Cex_t * pCex, int fGrow, Vec_Int_t * vPrios )
+void Bmc_CexCarePropagateFwd( Gia_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vPriosIn, Vec_Int_t * vPriosFf )
{
- Gia_Obj_t * pObj, * pObjRo, * pObjRi;
- int f, i;
- Gia_ManConst0( p )->Value = 0;
- Gia_ManForEachRi( p, pObj, i )
- pObj->Value = 0;
- Vec_IntClear( vPrios );
+ Gia_Obj_t * pObjRo, * pObjRi;
+ int i, f, ValueMax = Abc_Var2Lit( pCex->nPis * (pCex->iFrame + 1), 0 );
+ Gia_ManConst0( p )->Value = ValueMax;
+ Gia_ManForEachRi( p, pObjRi, i )
+ pObjRi->Value = ValueMax;
+ Vec_IntClear( vPriosFf );
for ( f = 0; f <= pCex->iFrame; f++ )
{
Gia_ManForEachRiRo( p, pObjRi, pObjRo, i )
- Vec_IntPush( vPrios, (pObjRo->Value = pObjRi->Value) );
- Bmc_CexCarePropagateFwdOne( p, pCex, f, fGrow );
+ Vec_IntPush( vPriosFf, (pObjRo->Value = pObjRi->Value) );
+ Bmc_CexCarePropagateFwdOne( p, pCex, f, vPriosIn );
}
}
/**Function*************************************************************
- Synopsis [Forward propagation.]
+ Synopsis [Backward propagation.]
Description []
@@ -160,9 +154,9 @@ void Bmc_CexCarePropagateFwd( Gia_Man_t * p, Abc_Cex_t * pCex, int fGrow, Vec_In
***********************************************************************/
void Bmc_CexCarePropagateBwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, Abc_Cex_t * pCexMin )
{
- Gia_Obj_t * pObj;
+ Gia_Obj_t * pObj, * pFan0, * pFan1;
int i, Phase0, Phase1;
- Gia_ManForEachCand( p, pObj, i )
+ Gia_ManForEachCi( p, pObj, i )
pObj->fPhase = 0;
Gia_ManForEachCo( p, pObj, i )
if ( pObj->fPhase )
@@ -171,45 +165,60 @@ void Bmc_CexCarePropagateBwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, Abc_Cex
{
if ( !pObj->fPhase )
continue;
- Phase0 = Abc_LitIsCompl(Gia_ObjFanin0(pObj)->Value) ^ Gia_ObjFaninC0(pObj);
- Phase1 = Abc_LitIsCompl(Gia_ObjFanin1(pObj)->Value) ^ Gia_ObjFaninC1(pObj);
+ pFan0 = Gia_ObjFanin0(pObj);
+ pFan1 = Gia_ObjFanin1(pObj);
+ Phase0 = Abc_LitIsCompl(pFan0->Value) ^ Gia_ObjFaninC0(pObj);
+ Phase1 = Abc_LitIsCompl(pFan1->Value) ^ Gia_ObjFaninC1(pObj);
if ( Phase0 && Phase1 )
{
- Gia_ObjFanin0(pObj)->fPhase = 1;
- Gia_ObjFanin1(pObj)->fPhase = 1;
+ pFan0->fPhase = 1;
+ pFan1->fPhase = 1;
}
- else if ( Phase0 && !Phase1 )
- Gia_ObjFanin1(pObj)->fPhase = 1;
- else if ( !Phase0 && Phase1 )
- Gia_ObjFanin0(pObj)->fPhase = 1;
+ else if ( Phase0 )
+ pFan1->fPhase = 1;
+ else if ( Phase1 )
+ pFan0->fPhase = 1;
else // if ( !Phase0 && !Phase1 )
{
- if ( Abc_Lit2Var(Gia_ObjFanin0(pObj)->Value) <= Abc_Lit2Var(Gia_ObjFanin1(pObj)->Value) )
- Gia_ObjFanin0(pObj)->fPhase = 1;
+ if ( pFan0->fPhase || pFan1->fPhase )
+ continue;
+ if ( Gia_ObjIsPi(p, pFan0) )
+ pFan0->fPhase = 1;
+ else if ( Gia_ObjIsPi(p, pFan1) )
+ pFan1->fPhase = 1;
+// else if ( Gia_ObjIsAnd(pFan0) && Txs_ObjIsJust(p, pFan0) )
+// pFan0->fPhase = 1;
+// else if ( Gia_ObjIsAnd(pFan1) && Txs_ObjIsJust(p, pFan1) )
+// pFan1->fPhase = 1;
else
- Gia_ObjFanin1(pObj)->fPhase = 1;
+ {
+ if ( Abc_Lit2Var(pFan0->Value) > Abc_Lit2Var(pFan1->Value) )
+ pFan0->fPhase = 1;
+ else
+ pFan1->fPhase = 1;
+ }
}
}
Gia_ManForEachPi( p, pObj, i )
if ( pObj->fPhase )
Abc_InfoSetBit( pCexMin->pData, pCexMin->nRegs + pCexMin->nPis * f + i );
}
-Abc_Cex_t * Bmc_CexCarePropagateBwd( Gia_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vPrios, int fGrow )
+Abc_Cex_t * Bmc_CexCarePropagateBwd( Gia_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vPriosIn, Vec_Int_t * vPriosFf )
{
Abc_Cex_t * pCexMin;
- Gia_Obj_t * pObj, * pObjRo, * pObjRi;
+ Gia_Obj_t * pObjRo, * pObjRi;
int f, i;
pCexMin = Abc_CexAlloc( pCex->nRegs, pCex->nPis, pCex->iFrame + 1 );
pCexMin->iPo = pCex->iPo;
pCexMin->iFrame = pCex->iFrame;
- Gia_ManForEachCo( p, pObj, i )
- pObj->fPhase = 0;
+ Gia_ManForEachCo( p, pObjRi, i )
+ pObjRi->fPhase = 0;
for ( f = pCex->iFrame; f >= 0; f-- )
{
Gia_ManPo(p, pCex->iPo)->fPhase = (int)(f == pCex->iFrame);
- Gia_ManForEachRo( p, pObj, i )
- pObj->Value = Vec_IntEntry( vPrios, f * pCex->nRegs + i );
- Bmc_CexCarePropagateFwdOne( p, pCex, f, fGrow );
+ Gia_ManForEachRo( p, pObjRo, i )
+ pObjRo->Value = Vec_IntEntry( vPriosFf, f * pCex->nRegs + i );
+ Bmc_CexCarePropagateFwdOne( p, pCex, f, vPriosIn );
Bmc_CexCarePropagateBwdOne( p, pCex, f, pCexMin );
Gia_ManForEachRiRo( p, pObjRi, pObjRo, i )
pObjRi->fPhase = pObjRo->fPhase;
@@ -228,12 +237,26 @@ Abc_Cex_t * Bmc_CexCarePropagateBwd( Gia_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t
SeeAlso []
***********************************************************************/
-Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, Abc_Cex_t * pCex, int fCheck, int fVerbose )
+Abc_Cex_t * Bmc_CexCareTotal( Abc_Cex_t ** pCexes, int nCexes )
{
- int nTryCexes = 4; // belongs to range [1;4]
+ int i, k, nWords = Abc_BitWordNum( pCexes[0]->nBits );
+ Abc_Cex_t * pCexMin = Abc_CexAlloc( pCexes[0]->nRegs, pCexes[0]->nPis, pCexes[0]->iFrame + 1 );
+ pCexMin->iPo = pCexes[0]->iPo;
+ pCexMin->iFrame = pCexes[0]->iFrame;
+ for ( i = 0; i < nWords; i++ )
+ {
+ pCexMin->pData[i] = pCexes[0]->pData[i];
+ for ( k = 1; k < nCexes; k++ )
+ pCexMin->pData[i] &= pCexes[k]->pData[i];
+ }
+ return pCexMin;
+}
+Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nRealPis, Abc_Cex_t * pCex, int nTryCexes, int fCheck, int fVerbose )
+{
+ //int nTryCexes = 4; // belongs to range [1;4]
Abc_Cex_t * pCexBest, * pCexMin[4] = {NULL};
- int k, nOnesBest, nOnesCur;
- Vec_Int_t * vPrios;
+ int k, f, i, nOnesBest, nOnesCur, Counter = 0;
+ Vec_Int_t * vPriosIn, * vPriosFf;
if ( pCex->nPis != Gia_ManPiNum(p) )
{
printf( "Given CEX does to have same number of inputs as the AIG.\n" );
@@ -255,35 +278,125 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, Abc_Cex_t * pCex, int fCheck,
if ( fVerbose )
{
printf( "Original : " );
- Bmc_CexPrint( pCex, Gia_ManPiNum(p), 0 );
+ Bmc_CexPrint( pCex, nRealPis, 0 );
}
- vPrios = Vec_IntAlloc( pCex->nRegs * (pCex->iFrame + 1) );
+ vPriosIn = Vec_IntAlloc( pCex->nPis * (pCex->iFrame + 1) );
+ vPriosFf = Vec_IntAlloc( pCex->nRegs * (pCex->iFrame + 1) );
for ( k = 0; k < nTryCexes; k++ )
{
- Bmc_CexCarePropagateFwd(p, pCex, k, vPrios );
- assert( Vec_IntSize(vPrios) == pCex->nRegs * (pCex->iFrame + 1) );
+ Counter = 0;
+ Vec_IntFill( vPriosIn, pCex->nPis * (pCex->iFrame + 1), 0 );
+/*
+ if ( k == 0 )
+ {
+ for ( f = 0; f <= pCex->iFrame; f++ )
+ for ( i = nRealPis; i < Gia_ManPiNum(p); i++ )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ for ( f = 0; f <= pCex->iFrame; f++ )
+ for ( i = 0; i < nRealPis; i++ )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ }
+ else if ( k == 1 )
+ {
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ for ( i = nRealPis; i < Gia_ManPiNum(p); i++ )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ for ( i = 0; i < nRealPis; i++ )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ }
+ else if ( k == 2 )
+ {
+ for ( f = 0; f <= pCex->iFrame; f++ )
+ for ( i = Gia_ManPiNum(p) - 1; i >= nRealPis; i-- )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ for ( f = 0; f <= pCex->iFrame; f++ )
+ for ( i = nRealPis - 1; i >= 0; i-- )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ }
+ else if ( k == 3 )
+ {
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ for ( i = Gia_ManPiNum(p) - 1; i >= nRealPis; i-- )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ for ( i = nRealPis - 1; i >= 0; i-- )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ }
+ else assert( 0 );
+*/
+ if ( k == 0 )
+ {
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ for ( i = Gia_ManPiNum(p) - 1; i >= nRealPis; i-- )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ for ( i = nRealPis - 1; i >= 0; i-- )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ }
+ else if ( k == 1 )
+ {
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ for ( i = Gia_ManPiNum(p) - 1; i >= nRealPis; i-- )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ for ( i = 0; i < nRealPis; i++ )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ }
+ else if ( k == 2 )
+ {
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ for ( i = nRealPis; i < Gia_ManPiNum(p); i++ )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ for ( i = nRealPis - 1; i >= 0; i-- )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ }
+ else if ( k == 3 )
+ {
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ for ( i = nRealPis; i < Gia_ManPiNum(p); i++ )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ for ( i = 0; i < nRealPis; i++ )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ }
+ else assert( 0 );
+
+ assert( Counter == pCex->nPis * (pCex->iFrame + 1) );
+ Bmc_CexCarePropagateFwd( p, pCex, vPriosIn, vPriosFf );
+ assert( Vec_IntSize(vPriosFf) == pCex->nRegs * (pCex->iFrame + 1) );
if ( !Abc_LitIsCompl(Gia_ManPo(p, pCex->iPo)->Value) )
{
printf( "Counter-example is invalid.\n" );
- Vec_IntFree( vPrios );
+ Vec_IntFree( vPriosIn );
+ Vec_IntFree( vPriosFf );
return NULL;
}
- pCexMin[k] = Bmc_CexCarePropagateBwd( p, pCex, vPrios, k );
+ pCexMin[k] = Bmc_CexCarePropagateBwd( p, pCex, vPriosIn, vPriosFf );
if ( fVerbose )
{
- if ( (k & 1) )
- printf( "Decrease : " );
- else
- printf( "Increase : " );
- Bmc_CexPrint( pCexMin[k], Gia_ManPiNum(p), 0 );
+ if ( k == 0 )
+ printf( "PI- PPI-: " );
+ else if ( k == 1 )
+ printf( "PI+ PPI-: " );
+ else if ( k == 2 )
+ printf( "PI- PPI+: " );
+ else if ( k == 3 )
+ printf( "PI+ PPI+: " );
+ else assert( 0 );
+ Bmc_CexPrint( pCexMin[k], nRealPis, 0 );
}
}
- Vec_IntFree( vPrios );
+ Vec_IntFree( vPriosIn );
+ Vec_IntFree( vPriosFf );
// select the best one
pCexBest = pCexMin[0];
nOnesBest = Abc_CexCountOnes(pCexMin[0]);
for ( k = 1; k < nTryCexes; k++ )
{
+ if ( pCexMin[k] == NULL )
+ continue;
nOnesCur = Abc_CexCountOnes(pCexMin[k]);
if ( nOnesBest > nOnesCur )
{
@@ -291,25 +404,29 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, Abc_Cex_t * pCex, int fCheck,
pCexBest = pCexMin[k];
}
}
- for ( k = 0; k < nTryCexes; k++ )
- if ( pCexBest != pCexMin[k] )
- Abc_CexFreeP( &pCexMin[k] );
- // verify and return
if ( fVerbose )
{
+ //Abc_Cex_t * pTotal = Bmc_CexCareTotal( pCexMin, nTryCexes );
printf( "Final : " );
- Bmc_CexPrint( pCexBest, Gia_ManPiNum(p), 0 );
+ Bmc_CexPrint( pCexBest, nRealPis, 0 );
+ //printf( "Total : " );
+ //Bmc_CexPrint( pTotal, nRealPis, 0 );
+ //Abc_CexFreeP( &pTotal );
}
+ for ( k = 0; k < nTryCexes; k++ )
+ if ( pCexMin[k] && pCexBest != pCexMin[k] )
+ Abc_CexFreeP( &pCexMin[k] );
+ // verify and return
if ( !Bmc_CexVerify( p, pCex, pCexBest ) )
printf( "Counter-example verification has failed.\n" );
else if ( fCheck )
printf( "Counter-example verification succeeded.\n" );
return pCexBest;
}
-Abc_Cex_t * Bmc_CexCareMinimize( Aig_Man_t * p, Abc_Cex_t * pCex, int fCheck, int fVerbose )
+Abc_Cex_t * Bmc_CexCareMinimize( Aig_Man_t * p, int nRealPis, Abc_Cex_t * pCex, int nTryCexes, int fCheck, int fVerbose )
{
Gia_Man_t * pGia = Gia_ManFromAigSimple( p );
- Abc_Cex_t * pCexMin = Bmc_CexCareMinimizeAig( pGia, pCex, fCheck, fVerbose );
+ Abc_Cex_t * pCexMin = Bmc_CexCareMinimizeAig( pGia, nRealPis, pCex, nTryCexes, fCheck, fVerbose );
Gia_ManStop( pGia );
return pCexMin;
}
@@ -341,7 +458,14 @@ void Bmc_CexCareVerify( Aig_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t * pCexMin, in
printf( "Counter-example verification succeeded.\n" );
Gia_ManStop( pGia );
}
-
+/*
+ {
+ Aig_Man_t * pAig = Abc_NtkToDar( pNtk, 0, 1 );
+ Abc_Cex_t * pCex = Bmc_CexCareMinimize( pAig, 3*Saig_ManPiNum(pAig)/4, 4, pAbc->pCex, 1, 1 );
+ Aig_ManStop( pAig );
+ Abc_CexFree( pCex );
+ }
+*/
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/sat/bmc/bmcCexTools.c b/src/sat/bmc/bmcCexTools.c
index 1c0d798c..9c80b278 100644
--- a/src/sat/bmc/bmcCexTools.c
+++ b/src/sat/bmc/bmcCexTools.c
@@ -304,10 +304,10 @@ void Bmc_CexBuildNetworkTest( Gia_Man_t * p, Abc_Cex_t * pCex )
SeeAlso []
***********************************************************************/
-void Bmc_CexPrint( Abc_Cex_t * pCex, int nInputs, int fVerbose )
+void Bmc_CexPrint( Abc_Cex_t * pCex, int nRealPis, int fVerbose )
{
int i, k, Count, iBit = pCex->nRegs;
- Abc_CexPrintStatsInputs( pCex, nInputs );
+ Abc_CexPrintStatsInputs( pCex, nRealPis );
if ( !fVerbose )
return;
@@ -315,7 +315,7 @@ void Bmc_CexPrint( Abc_Cex_t * pCex, int nInputs, int fVerbose )
{
Count = 0;
printf( "%3d : ", i );
- for ( k = 0; k < nInputs; k++ )
+ for ( k = 0; k < nRealPis; k++ )
{
Count += Abc_InfoHasBit(pCex->pData, iBit);
printf( "%d", Abc_InfoHasBit(pCex->pData, iBit++) );
diff --git a/src/sat/bmc/bmcChain.c b/src/sat/bmc/bmcChain.c
index 324c7f6d..5af54306 100644
--- a/src/sat/bmc/bmcChain.c
+++ b/src/sat/bmc/bmcChain.c
@@ -185,10 +185,9 @@ Gia_Man_t * Gia_ManDupPosAndPropagateInit( Gia_Man_t * p )
}
sat_solver * Gia_ManDeriveSatSolver( Gia_Man_t * p, Vec_Int_t * vSatIds )
{
-// extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
sat_solver * pSat;
Aig_Man_t * pAig = Gia_ManToAigSimple( p );
-// Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 );
+// Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
Cnf_Dat_t * pCnf = Cnf_Derive( pAig, Aig_ManCoNum(pAig) );
// save SAT vars for the primary inputs
if ( vSatIds )
diff --git a/src/sat/bmc/bmcClp.c b/src/sat/bmc/bmcClp.c
index 8a69fe56..cfc608b1 100644
--- a/src/sat/bmc/bmcClp.c
+++ b/src/sat/bmc/bmcClp.c
@@ -30,8 +30,6 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
-
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -651,7 +649,7 @@ Vec_Str_t * Bmc_CollapseOneInt2( Gia_Man_t * p, int nCubeLim, int nBTLimit, int
int iOut = 0, iLit, iVar, status, n, Count, Start;
// create SAT solver
- Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
sat_solver * pSat[3] = {
(sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0),
(sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0),
@@ -841,7 +839,7 @@ Vec_Str_t * Bmc_CollapseOneOld( Gia_Man_t * p, int nCubeLim, int nBTLimit, int f
{
int fVeryVerbose = fVerbose;
int nVars = Gia_ManCiNum(p);
- Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
sat_solver * pSat[2] = { (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0), (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0) };
sat_solver * pSatClean[2] = { (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0), (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0) };
Vec_Str_t * vSop[2] = { Vec_StrAlloc(1000), Vec_StrAlloc(1000) }, * vRes = NULL;
@@ -1173,7 +1171,7 @@ cleanup:
}
Vec_Str_t * Bmc_CollapseOne3( Gia_Man_t * p, int nCubeLim, int nBTLimit, int fCanon, int fReverse, int fVerbose )
{
- Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
sat_solver * pSat0 = (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0);
sat_solver * pSat1 = (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0);
sat_solver * pSat2 = (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0);
@@ -1507,7 +1505,7 @@ cleanup:
}
Vec_Str_t * Bmc_CollapseOne( Gia_Man_t * p, int nCubeLim, int nBTLimit, int fCanon, int fReverse, int fVerbose )
{
- Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0);
Vec_Str_t * vSop = Bmc_CollapseOne_int( pSat, Gia_ManCiNum(p), nCubeLim, nBTLimit, fCanon, fReverse, fVerbose );
sat_solver_delete( pSat );
diff --git a/src/sat/bmc/bmcEnum.c b/src/sat/bmc/bmcEnum.c
new file mode 100644
index 00000000..45aeb2b3
--- /dev/null
+++ b/src/sat/bmc/bmcEnum.c
@@ -0,0 +1,223 @@
+/**CFile****************************************************************
+
+ FileName [bmcEnum.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [SAT-based bounded model checking.]
+
+ Synopsis [Enumeration.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: bmcEnum.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "bmc.h"
+#include "sat/cnf/cnf.h"
+#include "sat/bsat/satSolver.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManDeriveOne( Gia_Man_t * p, Vec_Int_t * vValues )
+{
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj; int i, fPhase0, fPhase1;
+ assert( Vec_IntSize(vValues) == Gia_ManCiNum(p) );
+ // propagate forward
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->fPhase = Vec_IntEntry(vValues, i);
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ fPhase0 = Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj);
+ fPhase1 = Gia_ObjPhase(Gia_ObjFanin1(pObj)) ^ Gia_ObjFaninC1(pObj);
+ pObj->fPhase = fPhase0 & fPhase1;
+ }
+ // propagate backward
+ Gia_ManCleanMark0(p);
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ObjFanin0(pObj)->fMark0 = 1;
+ Gia_ManForEachAndReverse( p, pObj, i )
+ {
+ if ( !pObj->fMark0 )
+ continue;
+ fPhase0 = Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj);
+ fPhase1 = Gia_ObjPhase(Gia_ObjFanin1(pObj)) ^ Gia_ObjFaninC1(pObj);
+ if ( fPhase0 == fPhase1 )
+ {
+ assert( (int)pObj->fPhase == fPhase0 );
+ Gia_ObjFanin0(pObj)->fMark0 = 1;
+ Gia_ObjFanin1(pObj)->fMark0 = 1;
+ }
+ else if ( fPhase0 )
+ {
+ assert( fPhase1 == 0 );
+ assert( pObj->fPhase == 0 );
+ Gia_ObjFanin1(pObj)->fMark0 = 1;
+ }
+ else if ( fPhase1 )
+ {
+ assert( fPhase0 == 0 );
+ assert( pObj->fPhase == 0 );
+ Gia_ObjFanin0(pObj)->fMark0 = 1;
+ }
+ }
+ // create new
+ 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 = Abc_LitNotCond( Gia_ManAppendCi(pNew), !Vec_IntEntry(vValues, i) );
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( !pObj->fMark0 )
+ continue;
+ fPhase0 = Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj);
+ fPhase1 = Gia_ObjPhase(Gia_ObjFanin1(pObj)) ^ Gia_ObjFaninC1(pObj);
+ if ( fPhase0 == fPhase1 )
+ {
+ assert( (int)pObj->fPhase == fPhase0 );
+ if ( pObj->fPhase )
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0(pObj)->Value, Gia_ObjFanin1(pObj)->Value );
+ else
+ pObj->Value = Gia_ManAppendOr( pNew, Gia_ObjFanin0(pObj)->Value, Gia_ObjFanin1(pObj)->Value );
+ }
+ else if ( fPhase0 )
+ {
+ assert( fPhase1 == 0 );
+ assert( pObj->fPhase == 0 );
+ pObj->Value = Gia_ObjFanin1(pObj)->Value;
+ }
+ else if ( fPhase1 )
+ {
+ assert( fPhase0 == 0 );
+ assert( pObj->fPhase == 0 );
+ pObj->Value = Gia_ObjFanin0(pObj)->Value;
+ }
+ }
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0(pObj)->Value );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ Gia_ManCleanMark0(p);
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManDeriveOneTest2( Gia_Man_t * p )
+{
+ Gia_Man_t * pNew;
+ Vec_Int_t * vValues = Vec_IntStart( Gia_ManCiNum(p) );
+ //Vec_IntFill( vValues, Gia_ManCiNum(p), 1 );
+ pNew = Gia_ManDeriveOne( p, vValues );
+ Vec_IntFree( vValues );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManDeriveOneTest( Gia_Man_t * p )
+{
+ int fVerbose = 1;
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj, * pRoot;
+ Vec_Int_t * vValues = Vec_IntStart( Gia_ManCiNum(p) );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
+ int i, iVar, nIter, iPoVarBeg = pCnf->nVars - Gia_ManCiNum(p);
+ sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
+ Vec_Int_t * vLits = Vec_IntAlloc( 100 );
+ Vec_IntPush( vLits, Abc_Var2Lit( 1, 1 ) );
+ for ( nIter = 0; nIter < 10000; nIter++ )
+ {
+ int status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), 0, 0, 0, 0 );
+ if ( status == l_False )
+ break;
+ // derive new set
+ assert( status == l_True );
+ for ( i = 0; i < Gia_ManCiNum(p); i++ )
+ {
+ Vec_IntWriteEntry( vValues, i, sat_solver_var_value(pSat, iPoVarBeg+i) );
+ printf( "%d", sat_solver_var_value(pSat, iPoVarBeg+i) );
+ }
+ printf( " : " );
+
+ pNew = Gia_ManDeriveOne( p, vValues );
+ // assign variables
+ Gia_ManForEachCi( pNew, pObj, i )
+ pObj->Value = iPoVarBeg+i;
+ iVar = sat_solver_nvars(pSat);
+ Gia_ManForEachAnd( pNew, pObj, i )
+ pObj->Value = iVar++;
+ sat_solver_setnvars( pSat, iVar );
+ // create new clauses
+ Gia_ManForEachAnd( pNew, pObj, i )
+ sat_solver_add_and( pSat, pObj->Value, Gia_ObjFanin0(pObj)->Value, Gia_ObjFanin1(pObj)->Value, Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj), 0 );
+ // add to the assumptions
+ pRoot = Gia_ManCo(pNew, 0);
+ Vec_IntPush( vLits, Abc_Var2Lit(Gia_ObjFanin0(pRoot)->Value, !Gia_ObjFaninC0(pRoot)) );
+ if ( fVerbose )
+ {
+ printf( "Iter = %5d : ", nIter );
+ printf( "And = %4d ", Gia_ManAndNum(pNew) );
+ printf( "\n" );
+ }
+ Gia_ManStop( pNew );
+ }
+ Vec_IntFree( vLits );
+ Vec_IntFree( vValues );
+ Cnf_DataFree( pCnf );
+ sat_solver_delete( pSat );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/sat/bmc/bmcExpand.c b/src/sat/bmc/bmcExpand.c
index f3ec999e..6c7a5988 100644
--- a/src/sat/bmc/bmcExpand.c
+++ b/src/sat/bmc/bmcExpand.c
@@ -33,8 +33,6 @@ ABC_NAMESPACE_IMPL_START
// iterator thought the cubes
#define Bmc_SopForEachCube( pSop, nVars, pCube ) for ( pCube = (pSop); *pCube; pCube += (nVars) + 3 )
-extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
-
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -93,7 +91,7 @@ int Abc_ObjExpandCubes( Vec_Str_t * vSop, Gia_Man_t * p, int nVars )
int fReverse = 0;
Vec_Int_t * vVars = Vec_IntAlloc( nVars );
- Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0);
int v, n, iLit, status, nCubesNew, iCiVarBeg = sat_solver_nvars(pSat) - nVars;
diff --git a/src/sat/bmc/bmcFault.c b/src/sat/bmc/bmcFault.c
index 8dc2a57f..71eef2c4 100644
--- a/src/sat/bmc/bmcFault.c
+++ b/src/sat/bmc/bmcFault.c
@@ -280,7 +280,7 @@ static inline Cnf_Dat_t * Cnf_DeriveGiaRemapped( Gia_Man_t * p )
pCnf = Cnf_Derive( pAig, Aig_ManCoNum(pAig) );
Aig_ManStop( pAig );
return pCnf;
-// return Mf_ManGenerateCnf( p, 8, 0, 0, 0 );
+// return (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
}
/**Function*************************************************************
diff --git a/src/sat/bmc/bmcFx.c b/src/sat/bmc/bmcFx.c
index 9cd37c88..15ea4f05 100644
--- a/src/sat/bmc/bmcFx.c
+++ b/src/sat/bmc/bmcFx.c
@@ -30,8 +30,6 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
-
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -598,7 +596,7 @@ int Bmc_FxCompute( Gia_Man_t * p )
extern Gia_Man_t * Gia_ManDupOnsetOffset( Gia_Man_t * p );
Gia_Man_t * p2 = Gia_ManDupOnsetOffset( p );
// create SAT solver
- Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p2, 8, 0, 0, 0 );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p2, 8, 0, 0, 0, 0 );
sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
// compute parameters
int nOuts = Gia_ManCoNum(p);
@@ -674,7 +672,7 @@ int Bmc_FxComputeOne( Gia_Man_t * p, int nIterMax, int nDiv2Add )
{
int Extra = 1000;
// create SAT solver
- Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
// compute parameters
int nCiVars = Gia_ManCiNum(p); // PI count
diff --git a/src/sat/bmc/bmcGen.c b/src/sat/bmc/bmcGen.c
index 74af1b78..460c9fec 100644
--- a/src/sat/bmc/bmcGen.c
+++ b/src/sat/bmc/bmcGen.c
@@ -29,8 +29,6 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
-
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -48,13 +46,13 @@ extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfOb
***********************************************************************/
static inline word * Gia_ManMoObj( Gia_Man_t * p, int iObj )
{
- return Vec_WrdEntryP( p->vSims, iObj * p->iPatsPi );
+ return Vec_WrdEntryP( p->vSims, iObj * p->nSimWords );
}
static inline void Gia_ManMoSetCi( Gia_Man_t * p, int iObj )
{
int w;
word * pSims = Gia_ManMoObj( p, iObj );
- for ( w = 0; w < p->iPatsPi; w++ )
+ for ( w = 0; w < p->nSimWords; w++ )
pSims[w] = Gia_ManRandomW( 0 );
}
static inline void Gia_ManMoSimAnd( Gia_Man_t * p, int iObj )
@@ -67,19 +65,19 @@ static inline void Gia_ManMoSimAnd( Gia_Man_t * p, int iObj )
if ( Gia_ObjFaninC0(pObj) )
{
if ( Gia_ObjFaninC1(pObj) )
- for ( w = 0; w < p->iPatsPi; w++ )
+ for ( w = 0; w < p->nSimWords; w++ )
pSims[w] = ~(pSims0[w] | pSims1[w]);
else
- for ( w = 0; w < p->iPatsPi; w++ )
+ for ( w = 0; w < p->nSimWords; w++ )
pSims[w] = ~pSims0[w] & pSims1[w];
}
else
{
if ( Gia_ObjFaninC1(pObj) )
- for ( w = 0; w < p->iPatsPi; w++ )
+ for ( w = 0; w < p->nSimWords; w++ )
pSims[w] = pSims0[w] & ~pSims1[w];
else
- for ( w = 0; w < p->iPatsPi; w++ )
+ for ( w = 0; w < p->nSimWords; w++ )
pSims[w] = pSims0[w] & pSims1[w];
}
}
@@ -91,12 +89,12 @@ static inline void Gia_ManMoSetCo( Gia_Man_t * p, int iObj )
word * pSims0 = Gia_ManMoObj( p, Gia_ObjFaninId0(pObj, iObj) );
if ( Gia_ObjFaninC0(pObj) )
{
- for ( w = 0; w < p->iPatsPi; w++ )
+ for ( w = 0; w < p->nSimWords; w++ )
pSims[w] = ~pSims0[w];
}
else
{
- for ( w = 0; w < p->iPatsPi; w++ )
+ for ( w = 0; w < p->nSimWords; w++ )
pSims[w] = pSims0[w];
}
}
@@ -104,7 +102,7 @@ void Gia_ManMoFindSimulate( Gia_Man_t * p, int nWords )
{
int i, iObj;
Gia_ManRandomW( 1 );
- p->iPatsPi = nWords;
+ p->nSimWords = nWords;
if ( p->vSims )
Vec_WrdFill( p->vSims, nWords * Gia_ManObjNum(p), 0 );
else
@@ -131,7 +129,7 @@ void Gia_ManMoFindSimulate( Gia_Man_t * p, int nWords )
int Gia_ManTestSatEnum( Gia_Man_t * p )
{
abctime clk = Abc_Clock(), clk2, clkTotal = 0;
- Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0);
int i, v, status, iLit, nWords = 1, iOutVar = 1, Count = 0;
Vec_Int_t * vVars = Vec_IntAlloc( 1000 );
diff --git a/src/sat/bmc/bmcICheck.c b/src/sat/bmc/bmcICheck.c
index a779b1ed..8d8c7c6b 100644
--- a/src/sat/bmc/bmcICheck.c
+++ b/src/sat/bmc/bmcICheck.c
@@ -392,11 +392,10 @@ int Bmc_PerformISearchOne( Gia_Man_t * p, int nFramesMax, int nTimeOut, int fRev
pCnf = Cnf_DeriveGiaRemapped( pMiter );
else
{
- extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
//pMiter = Jf_ManDeriveCnf( pTemp = pMiter, 0 );
//Gia_ManStop( pTemp );
//pCnf = (Cnf_Dat_t *)pMiter->pData; pMiter->pData = NULL;
- pCnf = Mf_ManGenerateCnf( pMiter, 8, 0, 0, 0 );
+ pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pMiter, 8, 0, 0, 0, 0 );
}
/*
// collect positive literals
diff --git a/src/sat/bsat/satSolver.c b/src/sat/bsat/satSolver.c
index 88a05093..df9ada8e 100644
--- a/src/sat/bsat/satSolver.c
+++ b/src/sat/bsat/satSolver.c
@@ -151,6 +151,7 @@ static inline void order_update(sat_solver* s, int v) // updateorder
i = parent;
parent = (i - 1) / 2;
}
+
heap[i] = x;
orderpos[x] = i;
}
@@ -192,11 +193,13 @@ static inline int order_select(sat_solver* s, float random_var_freq) // selectv
int i = 0;
int child = 1;
while (child < size){
+
if (child+1 < size && s->activity[heap[child]] < s->activity[heap[child+1]])
child++;
assert(child < size);
if (s->activity[x] >= s->activity[heap[child]])
break;
+
heap[i] = heap[child];
orderpos[heap[i]] = i;
i = child;
@@ -214,138 +217,234 @@ static inline int order_select(sat_solver* s, float random_var_freq) // selectv
void sat_solver_set_var_activity(sat_solver* s, int * pVars, int nVars)
{
int i;
+ assert( s->VarActType == 1 );
for (i = 0; i < s->size; i++)
s->activity[i] = 0;
- s->var_inc = 1;
+ s->var_inc = Abc_Dbl2Word(1);
for ( i = 0; i < nVars; i++ )
{
int iVar = pVars ? pVars[i] : i;
- s->activity[iVar] = nVars-i;
+ s->activity[iVar] = Abc_Dbl2Word(nVars-i);
order_update( s, iVar );
}
}
//=================================================================================================
-// Activity functions:
+// variable activities
-#ifdef USE_FLOAT_ACTIVITY
+static inline void solver_init_activities(sat_solver* s)
+{
+ // variable activities
+ s->VarActType = 0;
+ if ( s->VarActType == 0 )
+ {
+ s->var_inc = (1 << 5);
+ s->var_decay = -1;
+ }
+ else if ( s->VarActType == 1 )
+ {
+ s->var_inc = Abc_Dbl2Word(1.0);
+ s->var_decay = Abc_Dbl2Word(1.0 / 0.95);
+ }
+ else if ( s->VarActType == 2 )
+ {
+ s->var_inc = Xdbl_FromDouble(1.0);
+ s->var_decay = Xdbl_FromDouble(1.0 / 0.950);
+ }
+ else assert(0);
-static inline void act_var_rescale(sat_solver* s) {
- double* activity = s->activity;
- int i;
- for (i = 0; i < s->size; i++)
- activity[i] *= 1e-100;
- s->var_inc *= 1e-100;
-}
-static inline void act_clause_rescale(sat_solver* s) {
-// static abctime Total = 0;
- clause** cs = (clause**)veci_begin(&s->learnts);
- int i;//, clk = Abc_Clock();
- for (i = 0; i < veci_size(&s->learnts); i++){
- float a = clause_activity(cs[i]);
- clause_setactivity(cs[i], a * (float)1e-20);
- }
- s->cla_inc *= (float)1e-20;
-
- Total += Abc_Clock() - clk;
-// printf( "Rescaling... Cla inc = %10.3f Conf = %10d ", s->cla_inc, s->stats.conflicts );
-// Abc_PrintTime( 1, "Time", Total );
-}
-static inline void act_var_bump(sat_solver* s, int v) {
- s->activity[v] += s->var_inc;
- if (s->activity[v] > 1e100)
- act_var_rescale(s);
- if (s->orderpos[v] != -1)
- order_update(s,v);
-}
-static inline void act_var_bump_global(sat_solver* s, int v) {
- if ( !s->pGlobalVars )
- return;
- s->activity[v] += (s->var_inc * 3.0 * s->pGlobalVars[v]);
- if (s->activity[v] > 1e100)
- act_var_rescale(s);
- if (s->orderpos[v] != -1)
- order_update(s,v);
-}
-static inline void act_var_bump_factor(sat_solver* s, int v) {
- if ( !s->factors )
- return;
- s->activity[v] += (s->var_inc * s->factors[v]);
- if (s->activity[v] > 1e100)
- act_var_rescale(s);
- if (s->orderpos[v] != -1)
- order_update(s,v);
-}
-static inline void act_clause_bump(sat_solver* s, clause *c) {
- float a = clause_activity(c) + s->cla_inc;
- clause_setactivity(c,a);
- if (a > 1e20) act_clause_rescale(s);
+ // clause activities
+ s->ClaActType = 0;
+ if ( s->ClaActType == 0 )
+ {
+ s->cla_inc = (1 << 11);
+ s->cla_decay = -1;
+ }
+ else
+ {
+ s->cla_inc = 1;
+ s->cla_decay = (float)(1 / 0.999);
+ }
}
-static inline void act_var_decay(sat_solver* s) { s->var_inc *= s->var_decay; }
-static inline void act_clause_decay(sat_solver* s) { s->cla_inc *= s->cla_decay; }
-
-#else
-static inline void act_var_rescale(sat_solver* s) {
- unsigned* activity = s->activity;
- int i;
- for (i = 0; i < s->size; i++)
- activity[i] >>= 19;
- s->var_inc >>= 19;
- s->var_inc = Abc_MaxInt( s->var_inc, (1<<4) );
+static inline void act_var_rescale(sat_solver* s)
+{
+ if ( s->VarActType == 0 )
+ {
+ word* activity = s->activity;
+ int i;
+ for (i = 0; i < s->size; i++)
+ activity[i] >>= 19;
+ s->var_inc >>= 19;
+ s->var_inc = Abc_MaxInt( (unsigned)s->var_inc, (1<<4) );
+ }
+ else if ( s->VarActType == 1 )
+ {
+ double* activity = (double*)s->activity;
+ int i;
+ for (i = 0; i < s->size; i++)
+ activity[i] *= 1e-100;
+ s->var_inc = Abc_Dbl2Word( Abc_Word2Dbl(s->var_inc) * 1e-100 );
+ //printf( "Rescaling var activity...\n" );
+ }
+ else if ( s->VarActType == 2 )
+ {
+ xdbl * activity = s->activity;
+ int i;
+ for (i = 0; i < s->size; i++)
+ activity[i] = Xdbl_Div( activity[i], 200 ); // activity[i] / 2^200
+ s->var_inc = Xdbl_Div( s->var_inc, 200 );
+ }
+ else assert(0);
}
-
-static inline void act_clause_rescale(sat_solver* s) {
- static abctime Total = 0;
- abctime clk = Abc_Clock();
- unsigned* activity = (unsigned *)veci_begin(&s->act_clas);
- int i;
- for (i = 0; i < veci_size(&s->act_clas); i++)
- activity[i] >>= 14;
- s->cla_inc >>= 14;
- s->cla_inc = Abc_MaxInt( s->cla_inc, (1<<10) );
- Total += Abc_Clock() - clk;
-// printf( "Rescaling... Cla inc = %5d Conf = %10d ", s->cla_inc, s->stats.conflicts );
-// Abc_PrintTime( 1, "Time", Total );
-}
-
-static inline void act_var_bump(sat_solver* s, int v) {
- s->activity[v] += s->var_inc;
- if (s->activity[v] & 0x80000000)
- act_var_rescale(s);
- if (s->orderpos[v] != -1)
- order_update(s,v);
+static inline void act_var_bump(sat_solver* s, int v)
+{
+ if ( s->VarActType == 0 )
+ {
+ s->activity[v] += s->var_inc;
+ if ((unsigned)s->activity[v] & 0x80000000)
+ act_var_rescale(s);
+ if (s->orderpos[v] != -1)
+ order_update(s,v);
+ }
+ else if ( s->VarActType == 1 )
+ {
+ double act = Abc_Word2Dbl(s->activity[v]) + Abc_Word2Dbl(s->var_inc);
+ s->activity[v] = Abc_Dbl2Word(act);
+ if (act > 1e100)
+ act_var_rescale(s);
+ if (s->orderpos[v] != -1)
+ order_update(s,v);
+ }
+ else if ( s->VarActType == 2 )
+ {
+ s->activity[v] = Xdbl_Add( s->activity[v], s->var_inc );
+ if (s->activity[v] > ABC_CONST(0x014c924d692ca61b))
+ act_var_rescale(s);
+ if (s->orderpos[v] != -1)
+ order_update(s,v);
+ }
+ else assert(0);
}
-static inline void act_var_bump_global(sat_solver* s, int v) {
- if ( !s->pGlobalVars )
+static inline void act_var_bump_global(sat_solver* s, int v)
+{
+ if ( !s->pGlobalVars || !s->pGlobalVars[v] )
return;
- s->activity[v] += (int)(s->var_inc * 3 * s->pGlobalVars[v]);
- if (s->activity[v] & 0x80000000)
- act_var_rescale(s);
- if (s->orderpos[v] != -1)
- order_update(s,v);
+ if ( s->VarActType == 0 )
+ {
+ s->activity[v] += (int)((unsigned)s->var_inc * 3);
+ if (s->activity[v] & 0x80000000)
+ act_var_rescale(s);
+ if (s->orderpos[v] != -1)
+ order_update(s,v);
+ }
+ else if ( s->VarActType == 1 )
+ {
+ double act = Abc_Word2Dbl(s->activity[v]) + Abc_Word2Dbl(s->var_inc) * 3.0;
+ s->activity[v] = Abc_Dbl2Word(act);
+ if ( act > 1e100)
+ act_var_rescale(s);
+ if (s->orderpos[v] != -1)
+ order_update(s,v);
+ }
+ else if ( s->VarActType == 2 )
+ {
+ s->activity[v] = Xdbl_Add( s->activity[v], Xdbl_Mul(s->var_inc, Xdbl_FromDouble(3.0)) );
+ if (s->activity[v] > ABC_CONST(0x014c924d692ca61b))
+ act_var_rescale(s);
+ if (s->orderpos[v] != -1)
+ order_update(s,v);
+ }
+ else assert( 0 );
}
-static inline void act_var_bump_factor(sat_solver* s, int v) {
+static inline void act_var_bump_factor(sat_solver* s, int v)
+{
if ( !s->factors )
return;
- s->activity[v] += (int)(s->var_inc * s->factors[v]);
- if (s->activity[v] & 0x80000000)
- act_var_rescale(s);
- if (s->orderpos[v] != -1)
- order_update(s,v);
+ if ( s->VarActType == 0 )
+ {
+ s->activity[v] += (int)((unsigned)s->var_inc * (float)s->factors[v]);
+ if (s->activity[v] & 0x80000000)
+ act_var_rescale(s);
+ if (s->orderpos[v] != -1)
+ order_update(s,v);
+ }
+ else if ( s->VarActType == 1 )
+ {
+ double act = Abc_Word2Dbl(s->activity[v]) + Abc_Word2Dbl(s->var_inc) * s->factors[v];
+ s->activity[v] = Abc_Dbl2Word(act);
+ if ( act > 1e100)
+ act_var_rescale(s);
+ if (s->orderpos[v] != -1)
+ order_update(s,v);
+ }
+ else if ( s->VarActType == 2 )
+ {
+ s->activity[v] = Xdbl_Add( s->activity[v], Xdbl_Mul(s->var_inc, Xdbl_FromDouble(s->factors[v])) );
+ if (s->activity[v] > ABC_CONST(0x014c924d692ca61b))
+ act_var_rescale(s);
+ if (s->orderpos[v] != -1)
+ order_update(s,v);
+ }
+ else assert( 0 );
}
-static inline void act_clause_bump(sat_solver* s, clause*c) {
- unsigned* act = (unsigned *)veci_begin(&s->act_clas) + c->lits[c->size];
- *act += s->cla_inc;
- if ( *act & 0x80000000 )
- act_clause_rescale(s);
+static inline void act_var_decay(sat_solver* s)
+{
+ if ( s->VarActType == 0 )
+ s->var_inc += (s->var_inc >> 4);
+ else if ( s->VarActType == 1 )
+ s->var_inc = Abc_Dbl2Word( Abc_Word2Dbl(s->var_inc) * Abc_Word2Dbl(s->var_decay) );
+ else if ( s->VarActType == 2 )
+ s->var_inc = Xdbl_Mul(s->var_inc, s->var_decay);
+ else assert(0);
}
-static inline void act_var_decay(sat_solver* s) { s->var_inc += (s->var_inc >> 4); }
-static inline void act_clause_decay(sat_solver* s) { s->cla_inc += (s->cla_inc >> 10); }
-
-#endif
+// clause activities
+static inline void act_clause_rescale(sat_solver* s)
+{
+ if ( s->ClaActType == 0 )
+ {
+ unsigned* activity = (unsigned *)veci_begin(&s->act_clas);
+ int i;
+ for (i = 0; i < veci_size(&s->act_clas); i++)
+ activity[i] >>= 14;
+ s->cla_inc >>= 14;
+ s->cla_inc = Abc_MaxInt( s->cla_inc, (1<<10) );
+ }
+ else
+ {
+ float* activity = (float *)veci_begin(&s->act_clas);
+ int i;
+ for (i = 0; i < veci_size(&s->act_clas); i++)
+ activity[i] *= (float)1e-20;
+ s->cla_inc *= (float)1e-20;
+ }
+}
+static inline void act_clause_bump(sat_solver* s, clause *c)
+{
+ if ( s->ClaActType == 0 )
+ {
+ unsigned* act = (unsigned *)veci_begin(&s->act_clas) + c->lits[c->size];
+ *act += s->cla_inc;
+ if ( *act & 0x80000000 )
+ act_clause_rescale(s);
+ }
+ else
+ {
+ float* act = (float *)veci_begin(&s->act_clas) + c->lits[c->size];
+ *act += s->cla_inc;
+ if (*act > 1e20)
+ act_clause_rescale(s);
+ }
+}
+static inline void act_clause_decay(sat_solver* s)
+{
+ if ( s->ClaActType == 0 )
+ s->cla_inc += (s->cla_inc >> 10);
+ else
+ s->cla_inc *= s->cla_decay;
+}
//=================================================================================================
@@ -447,7 +546,10 @@ int sat_solver_clause_new(sat_solver* s, lit* begin, lit* end, int learnt)
assert( clause_id(c) == veci_size(&s->act_clas) );
// veci_push(&s->learned, h);
// act_clause_bump(s,clause_read(s, h));
- veci_push(&s->act_clas, (1<<10));
+ if ( s->ClaActType == 0 )
+ veci_push(&s->act_clas, (1<<10));
+ else
+ veci_push(&s->act_clas, s->cla_inc);
s->stats.learnts++;
s->stats.learnts_literals += size;
}
@@ -1037,7 +1139,6 @@ sat_solver* sat_solver_new(void)
veci_new(&s->act_clas);
veci_new(&s->stack);
// veci_new(&s->model);
- veci_new(&s->act_vars);
veci_new(&s->unit_lits);
veci_new(&s->temp_clause);
veci_new(&s->conf_final);
@@ -1054,15 +1155,10 @@ sat_solver* sat_solver_new(void)
s->cap = 0;
s->qhead = 0;
s->qtail = 0;
-#ifdef USE_FLOAT_ACTIVITY
- s->var_inc = 1;
- s->cla_inc = 1;
- s->var_decay = (float)(1 / 0.95 );
- s->cla_decay = (float)(1 / 0.999);
-#else
- s->var_inc = (1 << 5);
- s->cla_inc = (1 << 11);
-#endif
+
+ solver_init_activities(s);
+ veci_new(&s->act_vars);
+
s->root_level = 0;
// s->simpdb_assigns = 0;
// s->simpdb_props = 0;
@@ -1085,6 +1181,71 @@ sat_solver* sat_solver_new(void)
return s;
}
+sat_solver* zsat_solver_new_seed(double seed)
+{
+ sat_solver* s = (sat_solver*)ABC_CALLOC( char, sizeof(sat_solver));
+
+// Vec_SetAlloc_(&s->Mem, 15);
+ Sat_MemAlloc_(&s->Mem, 15);
+ s->hLearnts = -1;
+ s->hBinary = Sat_MemAppend( &s->Mem, NULL, 2, 0, 0 );
+ s->binary = clause_read( s, s->hBinary );
+
+ s->nLearntStart = LEARNT_MAX_START_DEFAULT; // starting learned clause limit
+ s->nLearntDelta = LEARNT_MAX_INCRE_DEFAULT; // delta of learned clause limit
+ s->nLearntRatio = LEARNT_MAX_RATIO_DEFAULT; // ratio of learned clause limit
+ s->nLearntMax = s->nLearntStart;
+
+ // initialize vectors
+ veci_new(&s->order);
+ veci_new(&s->trail_lim);
+ veci_new(&s->tagged);
+// veci_new(&s->learned);
+ veci_new(&s->act_clas);
+ veci_new(&s->stack);
+// veci_new(&s->model);
+ veci_new(&s->unit_lits);
+ veci_new(&s->temp_clause);
+ veci_new(&s->conf_final);
+
+ // initialize arrays
+ s->wlists = 0;
+ s->activity = 0;
+ s->orderpos = 0;
+ s->reasons = 0;
+ s->trail = 0;
+
+ // initialize other vars
+ s->size = 0;
+ s->cap = 0;
+ s->qhead = 0;
+ s->qtail = 0;
+
+ solver_init_activities(s);
+ veci_new(&s->act_vars);
+
+ s->root_level = 0;
+// s->simpdb_assigns = 0;
+// s->simpdb_props = 0;
+ s->random_seed = seed;
+ s->progress_estimate = 0;
+// s->binary = (clause*)ABC_ALLOC( char, sizeof(clause) + sizeof(lit)*2);
+// s->binary->size_learnt = (2 << 1);
+ s->verbosity = 0;
+
+ s->stats.starts = 0;
+ s->stats.decisions = 0;
+ s->stats.propagations = 0;
+ s->stats.inspects = 0;
+ s->stats.conflicts = 0;
+ s->stats.clauses = 0;
+ s->stats.clauses_literals = 0;
+ s->stats.learnts = 0;
+ s->stats.learnts_literals = 0;
+ s->stats.tot_literals = 0;
+ return s;
+}
+
void sat_solver_setnvars(sat_solver* s,int n)
{
int var;
@@ -1102,12 +1263,8 @@ void sat_solver_setnvars(sat_solver* s,int n)
s->polarity = ABC_REALLOC(char, s->polarity, s->cap);
s->tags = ABC_REALLOC(char, s->tags, s->cap);
s->loads = ABC_REALLOC(char, s->loads, s->cap);
-#ifdef USE_FLOAT_ACTIVITY
- s->activity = ABC_REALLOC(double, s->activity, s->cap);
-#else
- s->activity = ABC_REALLOC(unsigned, s->activity, s->cap);
- s->activity2 = ABC_REALLOC(unsigned, s->activity2,s->cap);
-#endif
+ s->activity = ABC_REALLOC(word, s->activity, s->cap);
+ s->activity2 = ABC_REALLOC(word, s->activity2,s->cap);
s->pFreqs = ABC_REALLOC(char, s->pFreqs, s->cap);
if ( s->factors )
@@ -1126,11 +1283,15 @@ void sat_solver_setnvars(sat_solver* s,int n)
veci_new(&s->wlists[2*var]);
if ( s->wlists[2*var+1].ptr == NULL )
veci_new(&s->wlists[2*var+1]);
-#ifdef USE_FLOAT_ACTIVITY
- s->activity[var] = 0;
-#else
- s->activity[var] = (1<<10);
-#endif
+
+ if ( s->VarActType == 0 )
+ s->activity[var] = (1<<10);
+ else if ( s->VarActType == 1 )
+ s->activity[var] = 0;
+ else if ( s->VarActType == 2 )
+ s->activity[var] = 0;
+ else assert(0);
+
s->pFreqs[var] = 0;
if ( s->factors )
s->factors [var] = 0;
@@ -1207,7 +1368,6 @@ void sat_solver_restart( sat_solver* s )
s->hBinary = Sat_MemAppend( &s->Mem, NULL, 2, 0, 0 );
s->binary = clause_read( s, s->hBinary );
- veci_resize(&s->act_clas, 0);
veci_resize(&s->trail_lim, 0);
veci_resize(&s->order, 0);
for ( i = 0; i < s->size*2; i++ )
@@ -1220,15 +1380,13 @@ void sat_solver_restart( sat_solver* s )
// s->cap = 0;
s->qhead = 0;
s->qtail = 0;
-#ifdef USE_FLOAT_ACTIVITY
- s->var_inc = 1;
- s->cla_inc = 1;
- s->var_decay = (float)(1 / 0.95 );
- s->cla_decay = (float)(1 / 0.999 );
-#else
- s->var_inc = (1 << 5);
- s->cla_inc = (1 << 11);
-#endif
+
+
+ // variable activities
+ solver_init_activities(s);
+ veci_resize(&s->act_clas, 0);
+
+
s->root_level = 0;
// s->simpdb_assigns = 0;
// s->simpdb_props = 0;
@@ -1248,6 +1406,49 @@ void sat_solver_restart( sat_solver* s )
s->stats.tot_literals = 0;
}
+void zsat_solver_restart_seed( sat_solver* s, double seed )
+{
+ int i;
+ Sat_MemRestart( &s->Mem );
+ s->hLearnts = -1;
+ s->hBinary = Sat_MemAppend( &s->Mem, NULL, 2, 0, 0 );
+ s->binary = clause_read( s, s->hBinary );
+
+ veci_resize(&s->trail_lim, 0);
+ veci_resize(&s->order, 0);
+ for ( i = 0; i < s->size*2; i++ )
+ s->wlists[i].size = 0;
+
+ s->nDBreduces = 0;
+
+ // initialize other vars
+ s->size = 0;
+// s->cap = 0;
+ s->qhead = 0;
+ s->qtail = 0;
+
+ solver_init_activities(s);
+ veci_resize(&s->act_clas, 0);
+
+ s->root_level = 0;
+// s->simpdb_assigns = 0;
+// s->simpdb_props = 0;
+ s->random_seed = seed;
+ s->progress_estimate = 0;
+ s->verbosity = 0;
+
+ s->stats.starts = 0;
+ s->stats.decisions = 0;
+ s->stats.propagations = 0;
+ s->stats.inspects = 0;
+ s->stats.conflicts = 0;
+ s->stats.clauses = 0;
+ s->stats.clauses_literals = 0;
+ s->stats.learnts = 0;
+ s->stats.learnts_literals = 0;
+ s->stats.tot_literals = 0;
+}
+
// returns memory in bytes used by the SAT solver
double sat_solver_memory( sat_solver* s )
{
@@ -1261,13 +1462,9 @@ double sat_solver_memory( sat_solver* s )
Mem += s->cap * sizeof(char); // ABC_FREE(s->polarity );
Mem += s->cap * sizeof(char); // ABC_FREE(s->tags );
Mem += s->cap * sizeof(char); // ABC_FREE(s->loads );
-#ifdef USE_FLOAT_ACTIVITY
- Mem += s->cap * sizeof(double); // ABC_FREE(s->activity );
-#else
- Mem += s->cap * sizeof(unsigned); // ABC_FREE(s->activity );
+ Mem += s->cap * sizeof(word); // ABC_FREE(s->activity );
if ( s->activity2 )
- Mem += s->cap * sizeof(unsigned); // ABC_FREE(s->activity2);
-#endif
+ Mem += s->cap * sizeof(word); // ABC_FREE(s->activity );
if ( s->factors )
Mem += s->cap * sizeof(double); // ABC_FREE(s->factors );
Mem += s->cap * sizeof(int); // ABC_FREE(s->orderpos );
@@ -1314,7 +1511,7 @@ void sat_solver_reducedb(sat_solver* s)
s->nDBreduces++;
-// printf( "Calling reduceDB with %d learned clause limit.\n", s->nLearntMax );
+ //printf( "Calling reduceDB with %d learned clause limit.\n", s->nLearntMax );
s->nLearntMax = s->nLearntStart + s->nLearntDelta * s->nDBreduces;
// return;
@@ -1323,8 +1520,11 @@ void sat_solver_reducedb(sat_solver* s)
Sat_MemForEachLearned( pMem, c, i, k )
{
Id = clause_id(c);
- pSortValues[Id] = (((7 - Abc_MinInt(c->lbd, 7)) << 28) | (act_clas[Id] >> 4));
// pSortValues[Id] = act[Id];
+ if ( s->ClaActType == 0 )
+ pSortValues[Id] = ((7 - Abc_MinInt(c->lbd, 7)) << 28) | (act_clas[Id] >> 4);
+ else
+ pSortValues[Id] = ((7 - Abc_MinInt(c->lbd, 7)) << 28);// | (act_clas[Id] >> 4);
assert( pSortValues[Id] >= 0 );
}
@@ -1430,7 +1630,7 @@ void sat_solver_rollback( sat_solver* s )
if ( s->activity2 )
{
s->var_inc = s->var_inc2;
- memcpy( s->activity, s->activity2, sizeof(unsigned) * s->iVarPivot );
+ memcpy( s->activity, s->activity2, sizeof(word) * s->iVarPivot );
}
veci_resize(&s->order, 0);
for ( i = 0; i < s->iVarPivot; i++ )
@@ -1479,15 +1679,9 @@ void sat_solver_rollback( sat_solver* s )
// s->cap = 0;
s->qhead = 0;
s->qtail = 0;
-#ifdef USE_FLOAT_ACTIVITY
- s->var_inc = 1;
- s->cla_inc = 1;
- s->var_decay = (float)(1 / 0.95 );
- s->cla_decay = (float)(1 / 0.999 );
-#else
- s->var_inc = (1 << 5);
- s->cla_inc = (1 << 11);
-#endif
+
+ solver_init_activities(s);
+
s->root_level = 0;
s->random_seed = 91648253;
s->progress_estimate = 0;
diff --git a/src/sat/bsat/satSolver.h b/src/sat/bsat/satSolver.h
index 7ef2c9e8..5a8483c1 100644
--- a/src/sat/bsat/satSolver.h
+++ b/src/sat/bsat/satSolver.h
@@ -30,11 +30,10 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
#include "satVec.h"
#include "satClause.h"
+#include "misc/util/utilDouble.h"
ABC_NAMESPACE_HEADER_START
-//#define USE_FLOAT_ACTIVITY
-
//=================================================================================================
// Public interface:
@@ -42,6 +41,7 @@ struct sat_solver_t;
typedef struct sat_solver_t sat_solver;
extern sat_solver* sat_solver_new(void);
+extern sat_solver* zsat_solver_new_seed(double seed);
extern void sat_solver_delete(sat_solver* s);
extern int sat_solver_addclause(sat_solver* s, lit* begin, lit* end);
@@ -54,6 +54,7 @@ extern int sat_solver_push(sat_solver* s, int p);
extern void sat_solver_pop(sat_solver* s);
extern void sat_solver_set_resource_limits(sat_solver* s, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, ABC_INT64_T nConfLimitGlobal, ABC_INT64_T nInsLimitGlobal);
extern void sat_solver_restart( sat_solver* s );
+extern void zsat_solver_restart_seed( sat_solver* s, double seed );
extern void sat_solver_rollback( sat_solver* s );
extern int sat_solver_nvars(sat_solver* s);
@@ -106,7 +107,6 @@ struct sat_solver_t
int hBinary; // the special binary clause
clause * binary;
veci* wlists; // watcher lists
- veci act_clas; // contain clause activities
// rollback
int iVarPivot; // the pivot for variables
@@ -114,19 +114,17 @@ struct sat_solver_t
int hProofPivot; // the pivot for proof records
// activities
-#ifdef USE_FLOAT_ACTIVITY
- double var_inc; // Amount to bump next variable with.
- double var_decay; // INVERSE decay factor for variable activity: stores 1/decay.
- float cla_inc; // Amount to bump next clause with.
- float cla_decay; // INVERSE decay factor for clause activity: stores 1/decay.
- double* activity; // A heuristic measurement of the activity of a variable.
-#else
- int var_inc; // Amount to bump next variable with.
- int var_inc2; // Amount to bump next variable with.
- int cla_inc; // Amount to bump next clause with.
- unsigned* activity; // A heuristic measurement of the activity of a variable.
- unsigned* activity2; // backup variable activity
-#endif
+ int VarActType;
+ int ClaActType;
+ word var_inc; // Amount to bump next variable with.
+ word var_inc2; // Amount to bump next variable with.
+ word var_decay; // INVERSE decay factor for variable activity: stores 1/decay.
+ word* activity; // A heuristic measurement of the activity of a variable.
+ word* activity2; // backup variable activity
+ unsigned cla_inc; // Amount to bump next clause with.
+ unsigned cla_decay; // INVERSE decay factor for clause activity: stores 1/decay.
+ veci act_clas; // contain clause activities
+
char * pFreqs; // how many times this variable was assigned a value
int nVarUsed;
@@ -216,9 +214,25 @@ static int sat_solver_var_literal( sat_solver* s, int v )
static void sat_solver_act_var_clear(sat_solver* s)
{
int i;
- for (i = 0; i < s->size; i++)
- s->activity[i] = 0;
- s->var_inc = 1;
+ if ( s->VarActType == 0 )
+ {
+ for (i = 0; i < s->size; i++)
+ s->activity[i] = (1 << 10);
+ s->var_inc = (1 << 5);
+ }
+ else if ( s->VarActType == 1 )
+ {
+ for (i = 0; i < s->size; i++)
+ s->activity[i] = 0;
+ s->var_inc = 1;
+ }
+ else if ( s->VarActType == 2 )
+ {
+ for (i = 0; i < s->size; i++)
+ s->activity[i] = Xdbl_Const1();
+ s->var_inc = Xdbl_Const1();
+ }
+ else assert(0);
}
static void sat_solver_compress(sat_solver* s)
{
@@ -229,7 +243,12 @@ static void sat_solver_compress(sat_solver* s)
(void) RetValue;
}
}
-
+static void sat_solver_delete_p( sat_solver ** ps )
+{
+ if ( *ps )
+ sat_solver_delete( *ps );
+ *ps = NULL;
+}
static void sat_solver_clean_polarity(sat_solver* s, int * pVars, int nVars )
{
int i;
@@ -280,7 +299,7 @@ static inline void sat_solver_bookmark(sat_solver* s)
if ( s->activity2 )
{
s->var_inc2 = s->var_inc;
- memcpy( s->activity2, s->activity, sizeof(unsigned) * s->iVarPivot );
+ memcpy( s->activity2, s->activity, sizeof(word) * s->iVarPivot );
}
}
static inline void sat_solver_set_pivot_variables( sat_solver* s, int * pPivots, int nPivots )
diff --git a/src/sat/cnf/cnfUtil.c b/src/sat/cnf/cnfUtil.c
index 96002df8..5ccbeb0d 100644
--- a/src/sat/cnf/cnfUtil.c
+++ b/src/sat/cnf/cnfUtil.c
@@ -374,7 +374,7 @@ Cnf_Dat_t * Cnf_DataReadFromFile( char * pFileName )
// create
pCnf = ABC_CALLOC( Cnf_Dat_t, 1 );
pCnf->nVars = nVars;
- pCnf->nClauses = nClas;
+ pCnf->nClauses = Vec_IntSize(vClas)-1;
pCnf->nLiterals = Vec_IntSize(vLits);
pCnf->pClauses = ABC_ALLOC( int *, Vec_IntSize(vClas) );
pCnf->pClauses[0] = Vec_IntReleaseArray(vLits);
diff --git a/src/sat/satoko/LICENSE b/src/sat/satoko/LICENSE
new file mode 100644
index 00000000..51938137
--- /dev/null
+++ b/src/sat/satoko/LICENSE
@@ -0,0 +1,22 @@
+Copyright 2017, Bruno Schmitt - UC Berkeley / UFRGS (bruno@oschmitt.com)
+
+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.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
diff --git a/src/sat/satoko/act_clause.h b/src/sat/satoko/act_clause.h
new file mode 100644
index 00000000..ade5e569
--- /dev/null
+++ b/src/sat/satoko/act_clause.h
@@ -0,0 +1,43 @@
+//===--- act_var.h ----------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__act_clause_h
+#define satoko__act_clause_h
+
+#include "solver.h"
+#include "types.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+static inline void clause_act_rescale(solver_t *s)
+{
+ unsigned i, cref;
+ struct clause *clause;
+
+ vec_uint_foreach(s->learnts, cref, i) {
+ clause = clause_read(s, cref);
+ clause->data[clause->size].act >>= 10;
+ }
+ s->clause_act_inc = stk_uint_max((s->clause_act_inc >> 10), (1 << 11));
+}
+
+static inline void clause_act_bump(solver_t *s, struct clause *clause)
+{
+ clause->data[clause->size].act += s->clause_act_inc;
+ if (clause->data[clause->size].act & 0x80000000)
+ clause_act_rescale(s);
+}
+
+static inline void clause_act_decay(solver_t *s)
+{
+ s->clause_act_inc += (s->clause_act_inc >> 10);
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__act_clause_h */
diff --git a/src/sat/satoko/act_var.h b/src/sat/satoko/act_var.h
new file mode 100644
index 00000000..6b0ff98a
--- /dev/null
+++ b/src/sat/satoko/act_var.h
@@ -0,0 +1,53 @@
+//===--- act_var.h ----------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__act_var_h
+#define satoko__act_var_h
+
+#include "solver.h"
+#include "types.h"
+#include "utils/heap.h"
+#include "utils/sdbl.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+/** Re-scale the activity value for all variables.
+ */
+static inline void var_act_rescale(solver_t *s)
+{
+ unsigned i;
+ act_t *activity = vec_act_data(s->activity);
+
+ for (i = 0; i < vec_sdbl_size(s->activity); i++)
+ activity[i] = sdbl_div(activity[i], s->opts.var_act_rescale);
+ s->var_act_inc = sdbl_div(s->var_act_inc, s->opts.var_act_rescale);
+}
+
+/** Increment the activity value of one variable ('var')
+ */
+static inline void var_act_bump(solver_t *s, unsigned var)
+{
+ act_t *activity = vec_act_data(s->activity);
+
+ activity[var] = sdbl_add(activity[var], s->var_act_inc);
+ if (activity[var] > s->opts.var_act_limit)
+ var_act_rescale(s);
+ if (heap_in_heap(s->var_order, var))
+ heap_decrease(s->var_order, var);
+}
+
+/** Increment the value by which variables activity values are incremented
+ */
+static inline void var_act_decay(solver_t *s)
+{
+ s->var_act_inc = sdbl_mult(s->var_act_inc, double2sdbl(1 /s->opts.var_decay));
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__act_var_h */
diff --git a/src/sat/satoko/cdb.h b/src/sat/satoko/cdb.h
new file mode 100644
index 00000000..32b0bf93
--- /dev/null
+++ b/src/sat/satoko/cdb.h
@@ -0,0 +1,106 @@
+//===--- cdb.h --------------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__cdb_h
+#define satoko__cdb_h
+
+#include "clause.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+/* Clauses DB data structure */
+struct cdb {
+ unsigned size;
+ unsigned cap;
+ unsigned wasted;
+ unsigned *data;
+};
+
+//===------------------------------------------------------------------------===
+// Clause DB API
+//===------------------------------------------------------------------------===
+static inline struct clause *cdb_handler(struct cdb *p, unsigned cref)
+{
+ return cref != 0xFFFFFFFF ? (struct clause *)(p->data + cref) : NULL;
+}
+
+static inline unsigned cdb_cref(struct cdb *p, unsigned *clause)
+{
+ return (unsigned)(clause - &(p->data[0]));
+}
+
+static inline void cdb_grow(struct cdb *p, unsigned cap)
+{
+ unsigned prev_cap = p->cap;
+
+ if (p->cap >= cap)
+ return;
+ while (p->cap < cap) {
+ unsigned delta = ((p->cap >> 1) + (p->cap >> 3) + 2) & (unsigned)(~1);
+ p->cap += delta;
+ assert(p->cap >= prev_cap);
+ }
+ assert(p->cap > 0);
+ p->data = satoko_realloc(unsigned, p->data, p->cap);
+}
+
+static inline struct cdb *cdb_alloc(unsigned cap)
+{
+ struct cdb *p = satoko_calloc(struct cdb, 1);
+ if (cap <= 0)
+ cap = 1024 * 1024;
+ cdb_grow(p, cap);
+ return p;
+}
+
+static inline void cdb_free(struct cdb *p)
+{
+ satoko_free(p->data);
+ satoko_free(p);
+}
+
+static inline unsigned cdb_append(struct cdb *p, unsigned size)
+{
+ unsigned prev_size;
+ assert(size > 0);
+ cdb_grow(p, p->size + size);
+ prev_size = p->size;
+ p->size += size;
+ assert(p->size > prev_size);
+ return prev_size;
+}
+
+static inline void cdb_remove(struct cdb *p, struct clause *clause)
+{
+ p->wasted += clause->size;
+}
+
+static inline void cdb_clear(struct cdb *p)
+{
+ p->wasted = 0;
+ p->size = 0;
+}
+
+static inline unsigned cdb_capacity(struct cdb *p)
+{
+ return p->cap;
+}
+
+static inline unsigned cdb_size(struct cdb *p)
+{
+ return p->size;
+}
+
+static inline unsigned cdb_wasted(struct cdb *p)
+{
+ return p->wasted;
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__cdb_h */
diff --git a/src/sat/satoko/clause.h b/src/sat/satoko/clause.h
new file mode 100644
index 00000000..2be18cd6
--- /dev/null
+++ b/src/sat/satoko/clause.h
@@ -0,0 +1,63 @@
+//===--- clause.h -----------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__clause_h
+#define satoko__clause_h
+
+#include "types.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+struct clause {
+ unsigned f_learnt : 1;
+ unsigned f_mark : 1;
+ unsigned f_reallocd : 1;
+ unsigned f_deletable : 1;
+ unsigned lbd : 28;
+ unsigned size;
+ union {
+ unsigned lit;
+ clause_act_t act;
+ } data[0];
+};
+
+//===------------------------------------------------------------------------===
+// Clause API
+//===------------------------------------------------------------------------===
+static inline int clause_compare(const void *p1, const void *p2)
+{
+ const struct clause *c1 = (const struct clause *)p1;
+ const struct clause *c2 = (const struct clause *)p2;
+
+ if (c1->size > 2 && c2->size == 2)
+ return 1;
+ if (c1->size == 2 && c2->size > 2)
+ return 0;
+ if (c1->size == 2 && c2->size == 2)
+ return 0;
+
+ if (c1->lbd > c2->lbd)
+ return 1;
+ if (c1->lbd < c2->lbd)
+ return 0;
+
+ return c1->data[c1->size].act < c2->data[c2->size].act;
+}
+
+static inline void clause_print(struct clause *clause)
+{
+ unsigned i;
+ printf("{ ");
+ for (i = 0; i < clause->size; i++)
+ printf("%u ", clause->data[i].lit);
+ printf("}\n");
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__clause_h */
diff --git a/src/sat/satoko/cnf_reader.c b/src/sat/satoko/cnf_reader.c
new file mode 100644
index 00000000..adb9a47b
--- /dev/null
+++ b/src/sat/satoko/cnf_reader.c
@@ -0,0 +1,156 @@
+//===--- cnf_reader.h -------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#include <assert.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "satoko.h"
+#include "solver.h"
+#include "utils/mem.h"
+#include "utils/vec/vec_uint.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_IMPL_START
+
+/** Read the file into an internal buffer.
+ *
+ * This function will receive a file name. The return data is a string ended
+ * with '\0'.
+ *
+ */
+static char * file_open(const char *fname)
+{
+ FILE *file = fopen(fname, "rb");
+ char *buffer;
+ int sz_file;
+ int ret;
+
+ if (file == NULL) {
+ printf("Couldn't open file: %s\n", fname);
+ return NULL;
+ }
+ fseek(file, 0, SEEK_END);
+ sz_file = ftell(file);
+ rewind(file);
+ buffer = satoko_alloc(char, sz_file + 3);
+ ret = fread(buffer, sz_file, 1, file);
+ buffer[sz_file + 0] = '\n';
+ buffer[sz_file + 1] = '\0';
+ return buffer;
+}
+
+static void skip_spaces(char **pos)
+{
+ assert(pos != NULL);
+ for (; isspace(**pos); (*pos)++);
+}
+
+static void skip_line(char **pos)
+{
+ assert(pos != NULL);
+ for(; **pos != '\n' && **pos != '\r' && **pos != EOF; (*pos)++);
+ if (**pos != EOF)
+ (*pos)++;
+ return;
+}
+
+static int read_int(char **token)
+{
+ int value = 0;
+ int neg = 0;
+
+ skip_spaces(token);
+ if (**token == '-') {
+ neg = 1;
+ (*token)++;
+ } else if (**token == '+')
+ (*token)++;
+
+ if (!isdigit(**token)) {
+ printf("Parsing error. Unexpected char: %c.\n", **token);
+ exit(EXIT_FAILURE);
+ }
+ while (isdigit(**token)) {
+ value = (value * 10) + (**token - '0');
+ (*token)++;
+ }
+ return neg ? -value : value;
+}
+
+static void read_clause(char **token, vec_uint_t *lits)
+{
+ int var;
+ unsigned sign;
+
+ vec_uint_clear(lits);
+ while (1) {
+ var = read_int(token);
+ if (var == 0)
+ break;
+ sign = (var > 0);
+ var = abs(var) - 1;
+ vec_uint_push_back(lits, var2lit((unsigned) var, (char)!sign));
+ }
+}
+
+/** Start the solver and reads the DIMAC file.
+ *
+ * Returns false upon immediate conflict.
+ */
+int satoko_parse_dimacs(char *fname, satoko_t **solver)
+{
+ satoko_t *p = NULL;
+ vec_uint_t *lits = NULL;
+ int n_var;
+ int n_clause;
+ char *buffer = file_open(fname);
+ char *token;
+
+ if (buffer == NULL)
+ return -1;
+
+ token = buffer;
+ while (1) {
+ skip_spaces(&token);
+ if (*token == 0)
+ break;
+ else if (*token == 'c')
+ skip_line(&token);
+ else if (*token == 'p') {
+ token++;
+ skip_spaces(&token);
+ for(; !isspace(*token); token++); /* skip 'cnf' */
+
+ n_var = read_int(&token);
+ n_clause = read_int(&token);
+ skip_line(&token);
+ lits = vec_uint_alloc((unsigned) n_var);
+ p = satoko_create();
+ } else {
+ if (lits == NULL) {
+ printf("There is no parameter line.\n");
+ satoko_free(buffer);
+ return -1;
+ }
+ read_clause(&token, lits);
+ if (!satoko_add_clause(p, (int*)vec_uint_data(lits), vec_uint_size(lits))) {
+ vec_uint_print(lits);
+ return 0;
+ }
+ }
+ }
+ vec_uint_free(lits);
+ satoko_free(buffer);
+ *solver = p;
+ return satoko_simplify(p);
+}
+
+ABC_NAMESPACE_IMPL_END
diff --git a/src/sat/satoko/module.make b/src/sat/satoko/module.make
new file mode 100644
index 00000000..512094ee
--- /dev/null
+++ b/src/sat/satoko/module.make
@@ -0,0 +1,3 @@
+SRC += src/sat/satoko/solver.c \
+ src/sat/satoko/solver_api.c \
+ src/sat/satoko/cnf_reader.c
diff --git a/src/sat/satoko/satoko.h b/src/sat/satoko/satoko.h
new file mode 100644
index 00000000..a0c4d216
--- /dev/null
+++ b/src/sat/satoko/satoko.h
@@ -0,0 +1,114 @@
+//===--- satoko.h -----------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__satoko_h
+#define satoko__satoko_h
+
+#include "types.h"
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+/** Return valeus */
+enum {
+ SATOKO_ERR = 0,
+ SATOKO_OK = 1
+};
+
+enum {
+ SATOKO_UNDEC = 0, /* Undecided */
+ SATOKO_SAT = 1,
+ SATOKO_UNSAT = -1
+};
+
+struct solver_t_;
+typedef struct solver_t_ satoko_t;
+
+typedef struct satoko_opts satoko_opts_t;
+struct satoko_opts {
+ /* Limits */
+ long conf_limit; /* Limit on the n.of conflicts */
+ long prop_limit; /* Limit on the n.of propagations */
+
+ /* Constants used for restart heuristic */
+ double f_rst; /* Used to force a restart */
+ double b_rst; /* Used to block a restart */
+ unsigned fst_block_rst; /* Lower bound n.of conflicts for start blocking restarts */
+ unsigned sz_lbd_bqueue; /* Size of the moving avarege queue for LBD (force restart) */
+ unsigned sz_trail_bqueue; /* Size of the moving avarege queue for Trail size (block restart) */
+
+ /* Constants used for clause database reduction heuristic */
+ unsigned n_conf_fst_reduce; /* N.of conflicts before first clause databese reduction */
+ unsigned inc_reduce; /* Increment to reduce */
+ unsigned inc_special_reduce; /* Special increment to reduce */
+ unsigned lbd_freeze_clause;
+ float learnt_ratio; /* Percentage of learned clauses to remove */
+
+ /* VSIDS heuristic */
+ double var_decay;
+ float clause_decay;
+ unsigned var_act_rescale;
+ act_t var_act_limit;
+
+
+ /* Binary resolution */
+ unsigned clause_max_sz_bin_resol;
+ unsigned clause_min_lbd_bin_resol;
+ float garbage_max_ratio;
+ char verbose;
+};
+
+typedef struct satoko_stats satoko_stats_t;
+struct satoko_stats {
+ unsigned n_starts;
+ unsigned n_reduce_db;
+
+ long n_decisions;
+ long n_propagations;
+ long n_inspects;
+ long n_conflicts;
+
+ long n_original_lits;
+ long n_learnt_lits;
+};
+
+
+//===------------------------------------------------------------------------===
+extern satoko_t *satoko_create(void);
+extern void satoko_destroy(satoko_t *);
+extern void satoko_reset(satoko_t *);
+
+extern void satoko_default_opts(satoko_opts_t *);
+extern void satoko_configure(satoko_t *, satoko_opts_t *);
+extern int satoko_parse_dimacs(char *, satoko_t **);
+extern int satoko_add_variable(satoko_t *, char);
+extern int satoko_add_clause(satoko_t *, int *, int);
+extern void satoko_assump_push(satoko_t *s, int);
+extern void satoko_assump_pop(satoko_t *s);
+extern int satoko_simplify(satoko_t *);
+extern int satoko_solve(satoko_t *);
+extern void satoko_mark_cone(satoko_t *, int *, int);
+extern void satoko_unmark_cone(satoko_t *, int *, int);
+
+extern void satoko_rollback(satoko_t *);
+extern void satoko_bookmark(satoko_t *);
+extern void satoko_unbookmark(satoko_t *);
+/* If problem is unsatisfiable under assumptions, this function is used to
+ * obtain the final conflict clause expressed in the assumptions.
+ *
+ * - It receives as inputs the solver and a pointer to a array where clause
+ * will be copied. The memory is allocated by the solver, but must be freed by
+ * the caller.
+ * - The return value is either the size of the array or -1 in case the final
+ * conflict cluase was not generated.
+ */
+extern int satoko_final_conflict(satoko_t *, unsigned *);
+
+extern satoko_stats_t satoko_stats(satoko_t *);
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__satoko_h */
diff --git a/src/sat/satoko/solver.c b/src/sat/satoko/solver.c
new file mode 100644
index 00000000..af3dcffb
--- /dev/null
+++ b/src/sat/satoko/solver.c
@@ -0,0 +1,718 @@
+//===--- solver.c -----------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <math.h>
+
+#include "act_clause.h"
+#include "act_var.h"
+#include "solver.h"
+#include "utils/heap.h"
+#include "utils/mem.h"
+#include "utils/sort.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_IMPL_START
+
+//===------------------------------------------------------------------------===
+// Lit funtions
+//===------------------------------------------------------------------------===
+/**
+ * A literal is said to be redundant in a given clause if and only if all
+ * variables in its reason are either present in that clause or (recursevely)
+ * redundant.
+ */
+static inline int lit_is_removable(solver_t* s, unsigned lit, unsigned min_level)
+{
+ unsigned top = vec_uint_size(s->tagged);
+
+ assert(lit_reason(s, lit) != UNDEF);
+ vec_uint_clear(s->stack);
+ vec_uint_push_back(s->stack, lit2var(lit));
+ while (vec_uint_size(s->stack)) {
+ unsigned i;
+ unsigned var = vec_uint_pop_back(s->stack);
+ struct clause *c = clause_read(s, var_reason(s, var));
+ unsigned *lits = &(c->data[0].lit);
+
+ assert(var_reason(s, var) != UNDEF);
+ if (c->size == 2 && lit_value(s, lits[0]) == LIT_FALSE) {
+ assert(lit_value(s, lits[1]) == LIT_TRUE);
+ stk_swap(unsigned, lits[0], lits[1]);
+ }
+
+ /* Check scan the literals of the reason clause.
+ * The first literal is skiped because is the literal itself. */
+ for (i = 1; i < c->size; i++) {
+ var = lit2var(lits[i]);
+
+ /* Check if the variable has already been seen or if it
+ * was assinged a value at the decision level 0. In a
+ * positive case, there is no need to look any further */
+ if (vec_char_at(s->seen, var) || var_dlevel(s, var) == 0)
+ continue;
+
+ /* If the variable has a reason clause and if it was
+ * assingned at a 'possible' level, then we need to
+ * check if it is recursively redundant, otherwise the
+ * literal being checked is not redundant */
+ if (var_reason(s, var) != UNDEF && ((1 << (var_dlevel(s, var) & 31)) & min_level)) {
+ vec_uint_push_back(s->stack, var);
+ vec_uint_push_back(s->tagged, var);
+ vec_char_assign(s->seen, var, 1);
+ } else {
+ vec_uint_foreach_start(s->tagged, var, i, top)
+ vec_char_assign(s->seen, var, 0);
+ vec_uint_shrink(s->tagged, top);
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+
+//===------------------------------------------------------------------------===
+// Clause functions
+//===------------------------------------------------------------------------===
+/* Calculate clause LBD (Literal Block Distance):
+ * - It's the number of variables in the final conflict clause that come from
+ * different decision levels
+ */
+static inline unsigned clause_clac_lbd(solver_t *s, unsigned *lits, unsigned size)
+{
+ unsigned i;
+ unsigned lbd = 0;
+
+ s->cur_stamp++;
+ for (i = 0; i < size; i++) {
+ unsigned level = lit_dlevel(s, lits[i]);
+ if (vec_uint_at(s->stamps, level) != s->cur_stamp) {
+ vec_uint_assign(s->stamps, level, s->cur_stamp);
+ lbd++;
+ }
+ }
+ return lbd;
+}
+
+static inline void clause_bin_resolution(solver_t *s, vec_uint_t *clause_lits)
+{
+ unsigned *lits = vec_uint_data(clause_lits);
+ unsigned counter, sz, i;
+ unsigned lit;
+ unsigned neg_lit = lit_neg(lits[0]);
+ struct watcher *w;
+
+ s->cur_stamp++;
+ vec_uint_foreach(clause_lits, lit, i)
+ vec_uint_assign(s->stamps, lit2var(lit), s->cur_stamp);
+
+ counter = 0;
+ watch_list_foreach_bin(s->watches, w, neg_lit) {
+ unsigned imp_lit = w->blocker;
+ if (vec_uint_at(s->stamps, lit2var(imp_lit)) == s->cur_stamp &&
+ lit_value(s, imp_lit) == LIT_TRUE) {
+ counter++;
+ vec_uint_assign(s->stamps, lit2var(imp_lit), (s->cur_stamp - 1));
+ }
+ }
+ if (counter > 0) {
+ sz = vec_uint_size(clause_lits) - 1;
+ for (i = 1; i < vec_uint_size(clause_lits) - counter; i++)
+ if (vec_uint_at(s->stamps, lit2var(lits[i])) != s->cur_stamp) {
+ stk_swap(unsigned, lits[i], lits[sz]);
+ i--;
+ sz--;
+ }
+ vec_uint_shrink(clause_lits, vec_uint_size(clause_lits) - counter);
+ }
+}
+
+static inline void clause_minimize(solver_t *s, vec_uint_t *clause_lits)
+{
+ unsigned i, j;
+ unsigned *lits = vec_uint_data(clause_lits);
+ unsigned min_level = 0;
+ unsigned clause_size;
+
+ for (i = 1; i < vec_uint_size(clause_lits); i++) {
+ unsigned level = lit_dlevel(s, lits[i]);
+ min_level |= 1 << (level & 31);
+ }
+
+ /* Remove reduntant literals */
+ vec_uint_foreach(clause_lits, i, j)
+ vec_uint_push_back(s->tagged, lit2var(i));
+ for (i = j = 1; i < vec_uint_size(clause_lits); i++)
+ if (lit_reason(s, lits[i]) == UNDEF || !lit_is_removable(s, lits[i], min_level))
+ lits[j++] = lits[i];
+ vec_uint_shrink(clause_lits, j);
+
+ /* Binary Resolution */
+ clause_size = vec_uint_size(clause_lits);
+ if (clause_size <= s->opts.clause_max_sz_bin_resol &&
+ clause_clac_lbd(s, lits, clause_size) <= s->opts.clause_min_lbd_bin_resol)
+ clause_bin_resolution(s, clause_lits);
+}
+
+static inline void clause_realloc(struct cdb *dest, struct cdb *src, unsigned *cref)
+{
+ unsigned new_cref;
+ struct clause *new_clause;
+ struct clause *old_clause = cdb_handler(src, *cref);
+
+ if (old_clause->f_reallocd) {
+ *cref = (unsigned) old_clause->size;
+ return;
+ }
+ new_cref = cdb_append(dest, 3 + old_clause->f_learnt + old_clause->size);
+ new_clause = cdb_handler(dest, new_cref);
+ memcpy(new_clause, old_clause, (3 + old_clause->f_learnt + old_clause->size) * 4);
+ old_clause->f_reallocd = 1;
+ old_clause->size = (unsigned) new_cref;
+ *cref = new_cref;
+}
+
+//===------------------------------------------------------------------------===
+// Solver internal functions
+//===------------------------------------------------------------------------===
+static inline unsigned solver_decide(solver_t *s)
+{
+ unsigned next_var = UNDEF;
+
+ while (next_var == UNDEF || var_value(s, next_var) != VAR_UNASSING) {
+ if (heap_size(s->var_order) == 0) {
+ next_var = UNDEF;
+ return UNDEF;
+ }
+ next_var = heap_remove_min(s->var_order);
+ if (solver_has_marks(s) && !var_mark(s, next_var))
+ next_var = UNDEF;
+ }
+ return var2lit(next_var, var_polarity(s, next_var));
+}
+
+static inline void solver_new_decision(solver_t *s, unsigned lit)
+{
+ if (solver_has_marks(s) && !var_mark(s, lit2var(lit)))
+ return;
+ assert(var_value(s, lit2var(lit)) == VAR_UNASSING);
+ vec_uint_push_back(s->trail_lim, vec_uint_size(s->trail));
+ solver_enqueue(s, lit, UNDEF);
+}
+
+/* Calculate Backtrack Level from the learnt clause */
+static inline unsigned solver_calc_bt_level(solver_t *s, vec_uint_t *learnt)
+{
+ unsigned i, tmp;
+ unsigned i_max = 1;
+ unsigned *lits = vec_uint_data(learnt);
+ unsigned max = lit_dlevel(s, lits[1]);
+
+ if (vec_uint_size(learnt) == 1)
+ return 0;
+ for (i = 2; i < vec_uint_size(learnt); i++) {
+ if (lit_dlevel(s, lits[i]) > max) {
+ max = lit_dlevel(s, lits[i]);
+ i_max = i;
+ }
+ }
+ tmp = lits[1];
+ lits[1] = lits[i_max];
+ lits[i_max] = tmp;
+ return lit_dlevel(s, lits[1]);
+}
+
+/**
+ * Most books and papers explain conflict analysis and the calculation of the
+ * 1UIP (first Unique Implication Point) using an implication graph. This
+ * function, however, do not explicity constructs the graph! It inspects the
+ * trail in reverse and figure out which literals should be added to the
+ * to-be-learnt clause using the reasons of each assignment.
+ *
+ * cur_lit: current literal being analyzed.
+ * n_paths: number of unprocessed paths from conlfict node to the current
+ * literal being analyzed (cur_lit).
+ *
+ * This functions performs a backward BFS (breadth-first search) for 1UIP node.
+ * The trail works as the BFS queue. The counter of unprocessed but seen
+ * variables (n_paths) allows us to identify when 'cur_lit' is the closest
+ * cause of conflict.
+ *
+ * When 'n_paths' reaches zero it means there are no unprocessed reverse paths
+ * back from the conflict node to 'cur_lit' - meaning it is the 1UIP decision
+ * variable.
+ *
+ */
+static inline void solver_analyze(solver_t *s, unsigned cref, vec_uint_t *learnt,
+ unsigned *bt_level, unsigned *lbd)
+{
+ unsigned i;
+ unsigned *trail = vec_uint_data(s->trail);
+ unsigned idx = vec_uint_size(s->trail) - 1;
+ unsigned n_paths = 0;
+ unsigned p = UNDEF;
+ unsigned var;
+
+ vec_uint_push_back(learnt, UNDEF);
+ do {
+ struct clause *clause;
+ unsigned *lits;
+ unsigned j;
+
+ assert(cref != UNDEF);
+ clause = clause_read(s, cref);
+ lits = &(clause->data[0].lit);
+
+ if (p != UNDEF && clause->size == 2 && lit_value(s, lits[0]) == LIT_FALSE) {
+ assert(lit_value(s, lits[1]) == LIT_TRUE);
+ stk_swap(unsigned, lits[0], lits[1] );
+ }
+
+ if (clause->f_learnt)
+ clause_act_bump(s, clause);
+
+ if (clause->f_learnt && clause->lbd > 2) {
+ unsigned n_levels = clause_clac_lbd(s, lits, clause->size);
+ if (n_levels + 1 < clause->lbd) {
+ if (clause->lbd <= s->opts.lbd_freeze_clause)
+ clause->f_deletable = 0;
+ clause->lbd = n_levels;
+ }
+ }
+
+ for (j = (p == UNDEF ? 0 : 1); j < clause->size; j++) {
+ var = lit2var(lits[j]);
+ if (vec_char_at(s->seen, var) || var_dlevel(s, var) == 0)
+ continue;
+ vec_char_assign(s->seen, var, 1);
+ var_act_bump(s, var);
+ if (var_dlevel(s, var) == solver_dlevel(s)) {
+ n_paths++;
+ if (var_reason(s, var) != UNDEF && clause_read(s, var_reason(s, var))->f_learnt)
+ vec_uint_push_back(s->last_dlevel, var);
+ } else
+ vec_uint_push_back(learnt, lits[j]);
+ }
+
+ while (!vec_char_at(s->seen, lit2var(trail[idx--])));
+
+ p = trail[idx + 1];
+ cref = lit_reason(s, p);
+ vec_char_assign(s->seen, lit2var(p), 0);
+ n_paths--;
+ } while (n_paths > 0);
+
+ vec_uint_data(learnt)[0] = lit_neg(p);
+ clause_minimize(s, learnt);
+ *bt_level = solver_calc_bt_level(s, learnt);
+ *lbd = clause_clac_lbd(s, vec_uint_data(learnt), vec_uint_size(learnt));
+
+ if (vec_uint_size(s->last_dlevel) > 0) {
+ vec_uint_foreach(s->last_dlevel, var, i) {
+ if (clause_read(s, var_reason(s, var))->lbd < *lbd)
+ var_act_bump(s, var);
+ }
+ vec_uint_clear(s->last_dlevel);
+ }
+ vec_uint_foreach(s->tagged, var, i)
+ vec_char_assign(s->seen, var, 0);
+ vec_uint_clear(s->tagged);
+}
+
+static inline int solver_rst(solver_t *s)
+{
+ return b_queue_is_valid(s->bq_lbd) &&
+ (((long)b_queue_avg(s->bq_lbd) * s->opts.f_rst) > (s->sum_lbd / s->stats.n_conflicts));
+}
+
+static inline int solver_block_rst(solver_t *s)
+{
+ return s->stats.n_conflicts > (int)s->opts.fst_block_rst &&
+ b_queue_is_valid(s->bq_lbd) &&
+ ((long)vec_uint_size(s->trail) > (s->opts.b_rst * (long)b_queue_avg(s->bq_trail)));
+}
+
+static inline void solver_handle_conflict(solver_t *s, unsigned confl_cref)
+{
+ unsigned bt_level;
+ unsigned lbd;
+ unsigned cref;
+
+ vec_uint_clear(s->temp_lits);
+ solver_analyze(s, confl_cref, s->temp_lits, &bt_level, &lbd);
+ s->sum_lbd += lbd;
+ b_queue_push(s->bq_lbd, lbd);
+ solver_cancel_until(s, bt_level);
+ cref = UNDEF;
+ if (vec_uint_size(s->temp_lits) > 1) {
+ cref = solver_clause_create(s, s->temp_lits, 1);
+ clause_watch(s, cref);
+ }
+ solver_enqueue(s, vec_uint_at(s->temp_lits, 0), cref);
+ var_act_decay(s);
+ clause_act_decay(s);
+}
+
+static inline void solver_analyze_final(solver_t *s, unsigned lit)
+{
+ int i;
+
+ vec_uint_clear(s->final_conflict);
+ vec_uint_push_back(s->final_conflict, lit);
+ if (solver_dlevel(s) == 0)
+ return;
+ vec_char_assign(s->seen, lit2var(lit), 1);
+ for (i = (int) vec_uint_size(s->trail) - 1; i >= (int) vec_uint_at(s->trail_lim, 0); i--) {
+ unsigned var = lit2var(vec_uint_at(s->trail, i));
+
+ if (vec_char_at(s->seen, var)) {
+ unsigned reason = var_reason(s, var);
+ if (reason == UNDEF) {
+ assert(var_dlevel(s, var) > 0);
+ vec_uint_push_back(s->final_conflict, lit_neg(vec_uint_at(s->trail, i)));
+ } else {
+ unsigned j;
+ struct clause *clause = clause_read(s, reason);
+ for (j = (clause->size == 2 ? 0 : 1); j < clause->size; j++) {
+ if (lit_dlevel(s, clause->data[j].lit) > 0)
+ vec_char_assign(s->seen, lit2var(clause->data[j].lit), 1);
+ }
+ }
+ vec_char_assign(s->seen, var, 0);
+ }
+ }
+ vec_char_assign(s->seen, lit2var(lit), 0);
+}
+
+static inline void solver_garbage_collect(solver_t *s)
+{
+ unsigned i;
+ unsigned *array;
+ struct cdb *new_cdb = cdb_alloc(cdb_capacity(s->all_clauses) - cdb_wasted(s->all_clauses));
+
+ if (s->book_cdb)
+ s->book_cdb = 0;
+
+ for (i = 0; i < 2 * vec_char_size(s->assigns); i++) {
+ struct watcher *w;
+ watch_list_foreach(s->watches, w, i)
+ clause_realloc(new_cdb, s->all_clauses, &(w->cref));
+ }
+
+ /* Update CREFS */
+ for (i = 0; i < vec_uint_size(s->trail); i++)
+ if (lit_reason(s, vec_uint_at(s->trail, i)) != UNDEF)
+ clause_realloc(new_cdb, s->all_clauses, &(vec_uint_data(s->reasons)[lit2var(vec_uint_at(s->trail, i))]));
+
+ array = vec_uint_data(s->learnts);
+ for (i = 0; i < vec_uint_size(s->learnts); i++)
+ clause_realloc(new_cdb, s->all_clauses, &(array[i]));
+
+ array = vec_uint_data(s->originals);
+ for (i = 0; i < vec_uint_size(s->originals); i++)
+ clause_realloc(new_cdb, s->all_clauses, &(array[i]));
+
+ cdb_free(s->all_clauses);
+ s->all_clauses = new_cdb;
+}
+
+static inline void solver_reduce_cdb(solver_t *s)
+{
+ unsigned i, limit;
+ unsigned n_learnts = vec_uint_size(s->learnts);
+ unsigned cref;
+ struct clause *clause;
+ struct clause **learnts_cls;
+
+ learnts_cls = satoko_alloc(struct clause *, n_learnts);
+ vec_uint_foreach_start(s->learnts, cref, i, s->book_cl_lrnt)
+ learnts_cls[i] = clause_read(s, cref);
+
+ limit = (unsigned)(n_learnts * s->opts.learnt_ratio);
+
+ satoko_sort((void *)learnts_cls, n_learnts,
+ (int (*)(const void *, const void *)) clause_compare);
+
+ if (learnts_cls[n_learnts / 2]->lbd <= 3)
+ s->RC2 += s->opts.inc_special_reduce;
+ if (learnts_cls[n_learnts - 1]->lbd <= 6)
+ s->RC2 += s->opts.inc_special_reduce;
+
+ vec_uint_clear(s->learnts);
+ for (i = 0; i < n_learnts; i++) {
+ clause = learnts_cls[i];
+ cref = cdb_cref(s->all_clauses, (unsigned *)clause);
+ assert(clause->f_mark == 0);
+ if (clause->f_deletable && clause->lbd > 2 && clause->size > 2 && lit_reason(s, clause->data[0].lit) != cref && (i < limit)) {
+ clause->f_mark = 1;
+ s->stats.n_learnt_lits -= clause->size;
+ clause_unwatch(s, cref);
+ cdb_remove(s->all_clauses, clause);
+ } else {
+ if (!clause->f_deletable)
+ limit++;
+ clause->f_deletable = 1;
+ vec_uint_push_back(s->learnts, cref);
+ }
+ }
+ satoko_free(learnts_cls);
+
+ if (s->opts.verbose) {
+ printf("reduceDB: Keeping %7d out of %7d clauses (%5.2f %%) \n",
+ vec_uint_size(s->learnts), n_learnts,
+ 100.0 * vec_uint_size(s->learnts) / n_learnts);
+ fflush(stdout);
+ }
+ if (cdb_wasted(s->all_clauses) > cdb_size(s->all_clauses) * s->opts.garbage_max_ratio)
+ solver_garbage_collect(s);
+}
+
+//===------------------------------------------------------------------------===
+// Solver external functions
+//===------------------------------------------------------------------------===
+unsigned solver_clause_create(solver_t *s, vec_uint_t *lits, unsigned f_learnt)
+{
+ struct clause *clause;
+ unsigned cref;
+ unsigned n_words;
+
+ assert(vec_uint_size(lits) > 1);
+ assert(f_learnt == 0 || f_learnt == 1);
+
+ n_words = 3 + f_learnt + vec_uint_size(lits);
+ cref = cdb_append(s->all_clauses, n_words);
+ clause = clause_read(s, cref);
+ clause->f_learnt = f_learnt;
+ clause->f_mark = 0;
+ clause->f_reallocd = 0;
+ clause->f_deletable = f_learnt;
+ clause->size = vec_uint_size(lits);
+ memcpy(&(clause->data[0].lit), vec_uint_data(lits), sizeof(unsigned) * vec_uint_size(lits));
+
+ if (f_learnt) {
+ vec_uint_push_back(s->learnts, cref);
+ clause->lbd = clause_clac_lbd(s, vec_uint_data(lits), vec_uint_size(lits));
+ clause->data[clause->size].act = 0;
+ s->stats.n_learnt_lits += vec_uint_size(lits);
+ clause_act_bump(s, clause);
+ } else {
+ vec_uint_push_back(s->originals, cref);
+ s->stats.n_original_lits += vec_uint_size(lits);
+ }
+ return cref;
+}
+
+void solver_cancel_until(solver_t *s, unsigned level)
+{
+ int i;
+
+ if (solver_dlevel(s) <= level)
+ return;
+ for (i = (int) vec_uint_size(s->trail) - 1; i >= (int) vec_uint_at(s->trail_lim, level); i--) {
+ unsigned var = lit2var(vec_uint_at(s->trail, (unsigned) i));
+
+ vec_char_assign(s->assigns, var, VAR_UNASSING);
+ vec_uint_assign(s->reasons, var, UNDEF);
+ vec_char_assign(s->polarity, var, lit_polarity(vec_uint_at(s->trail, (unsigned) i)));
+ if (!heap_in_heap(s->var_order, var))
+ heap_insert(s->var_order, var);
+ }
+ s->i_qhead = vec_uint_at(s->trail_lim, level);
+ vec_uint_shrink(s->trail, vec_uint_at(s->trail_lim, level));
+ vec_uint_shrink(s->trail_lim, level);
+}
+
+unsigned solver_propagate(solver_t *s)
+{
+ unsigned conf_cref = UNDEF;
+ unsigned *lits;
+ unsigned neg_lit;
+ unsigned n_propagations = 0;
+
+ while (s->i_qhead < vec_uint_size(s->trail)) {
+ unsigned p = vec_uint_at(s->trail, s->i_qhead++);
+ struct watch_list *ws;
+ struct watcher *begin;
+ struct watcher *end;
+ struct watcher *i, *j;
+
+ n_propagations++;
+ watch_list_foreach_bin(s->watches, i, p) {
+ if (solver_has_marks(s) && !var_mark(s, lit2var(i->blocker)))
+ continue;
+ if (var_value(s, lit2var(i->blocker)) == VAR_UNASSING)
+ solver_enqueue(s, i->blocker, i->cref);
+ else if (lit_value(s, i->blocker) == LIT_FALSE)
+ return i->cref;
+ }
+
+ ws = vec_wl_at(s->watches, p);
+ begin = watch_list_array(ws);
+ end = begin + watch_list_size(ws);
+ for (i = j = begin + ws->n_bin; i < end;) {
+ struct clause *clause;
+ struct watcher w;
+
+ if (solver_has_marks(s) && !var_mark(s, lit2var(i->blocker))) {
+ *j++ = *i++;
+ continue;
+ }
+ if (lit_value(s, i->blocker) == LIT_TRUE) {
+ *j++ = *i++;
+ continue;
+ }
+
+ clause = clause_read(s, i->cref);
+ lits = &(clause->data[0].lit);
+
+ // Make sure the false literal is data[1]:
+ neg_lit = lit_neg(p);
+ if (lits[0] == neg_lit)
+ stk_swap(unsigned, lits[0], lits[1]);
+ assert(lits[1] == neg_lit);
+
+ w.cref = i->cref;
+ w.blocker = lits[0];
+
+ /* If 0th watch is true, then clause is already satisfied. */
+ if (lits[0] != i->blocker && lit_value(s, lits[0]) == LIT_TRUE)
+ *j++ = w;
+ else {
+ /* Look for new watch */
+ unsigned k;
+ for (k = 2; k < clause->size; k++) {
+ if (lit_value(s, lits[k]) != LIT_FALSE) {
+ lits[1] = lits[k];
+ lits[k] = neg_lit;
+ watch_list_push(vec_wl_at(s->watches, lit_neg(lits[1])), w, 0);
+ goto next;
+ }
+ }
+
+ *j++ = w;
+
+ /* Clause becomes unit under this assignment */
+ if (lit_value(s, lits[0]) == LIT_FALSE) {
+ conf_cref = i->cref;
+ s->i_qhead = vec_uint_size(s->trail);
+ i++;
+ // Copy the remaining watches:
+ while (i < end)
+ *j++ = *i++;
+ } else
+ solver_enqueue(s, lits[0], i->cref);
+ }
+ next:
+ i++;
+ }
+
+ s->stats.n_inspects += j - watch_list_array(ws);
+ watch_list_shrink(ws, j - watch_list_array(ws));
+ }
+ s->stats.n_propagations += n_propagations;
+ s->n_props_simplify -= n_propagations;
+ return conf_cref;
+}
+
+char solver_search(solver_t *s)
+{
+ s->stats.n_starts++;
+ while (1) {
+ unsigned confl_cref = solver_propagate(s);
+ if (confl_cref != UNDEF) {
+ s->stats.n_conflicts++;
+ if (solver_dlevel(s) == 0)
+ return SATOKO_UNSAT;
+ /* Restart heuristic */
+ b_queue_push(s->bq_trail, vec_uint_size(s->trail));
+ if (solver_block_rst(s))
+ b_queue_clean(s->bq_lbd);
+ solver_handle_conflict(s, confl_cref);
+ } else {
+ /* No conflict */
+ unsigned next_lit;
+
+ if (solver_rst(s)) {
+ b_queue_clean(s->bq_lbd);
+ solver_cancel_until(s, 0);
+ return SATOKO_UNDEC;
+ }
+ if (solver_dlevel(s) == 0)
+ satoko_simplify(s);
+
+ /* Reduce the set of learnt clauses */
+ if (s->opts.learnt_ratio &&
+ s->stats.n_conflicts >= s->n_confl_bfr_reduce) {
+ s->RC1 = (s->stats.n_conflicts / s->RC2) + 1;
+ solver_reduce_cdb(s);
+ s->RC2 += s->opts.inc_reduce;
+ s->n_confl_bfr_reduce = s->RC1 * s->RC2;
+ }
+
+ /* Make decisions based on user assumptions */
+ next_lit = UNDEF;
+ while (solver_dlevel(s) < vec_uint_size(s->assumptions)) {
+ unsigned lit = vec_uint_at(s->assumptions, solver_dlevel(s));
+ if (lit_value(s, lit) == LIT_TRUE) {
+ vec_uint_push_back(s->trail_lim, vec_uint_size(s->trail));
+ } else if (lit_value(s, lit) == LIT_FALSE) {
+ solver_analyze_final(s, lit_neg(lit));
+ return SATOKO_UNSAT;
+ } else {
+ next_lit = lit;
+ break;
+ }
+
+ }
+ if (next_lit == UNDEF) {
+ s->stats.n_decisions++;
+ next_lit = solver_decide(s);
+ if (next_lit == UNDEF)
+ return SATOKO_SAT;
+ }
+ solver_new_decision(s, next_lit);
+ }
+ }
+}
+
+//===------------------------------------------------------------------------===
+// Debug procedure
+//===------------------------------------------------------------------------===
+void solver_debug_check(solver_t *s, int result)
+{
+ unsigned cref, i;
+ unsigned *array;
+
+ printf("Checking for trail(%u) inconsistencies...", vec_uint_size(s->trail));
+ array = vec_uint_data(s->trail);
+ for (i = 1; i < vec_uint_size(s->trail); i++)
+ if (array[i - 1] == lit_neg(array[i])) {
+ printf("Inconsistent trail: %u %u\n", array[i - 1], array[i]);
+ return;
+ }
+ printf(" TRAIL OK\n");
+
+ printf("Checking clauses... \n");
+ vec_uint_foreach(s->originals, cref, i) {
+ unsigned j;
+ struct clause *clause = clause_read(s, cref);
+ for (j = 0; j < clause->size; j++) {
+ if (vec_uint_find(s->trail, clause->data[j].lit)) {
+ break;
+ }
+ }
+ if (result == SATOKO_SAT && j == clause->size) {
+ printf("FOUND UNSAT CLAUSE!!!!\n");
+ clause_print(clause);
+ }
+ }
+}
+
+ABC_NAMESPACE_IMPL_END
diff --git a/src/sat/satoko/solver.h b/src/sat/satoko/solver.h
new file mode 100644
index 00000000..33f8ce88
--- /dev/null
+++ b/src/sat/satoko/solver.h
@@ -0,0 +1,254 @@
+//===--- solver.h -----------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__solver_h
+#define satoko__solver_h
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "clause.h"
+#include "cdb.h"
+#include "satoko.h"
+#include "types.h"
+#include "watch_list.h"
+#include "utils/b_queue.h"
+#include "utils/heap.h"
+#include "utils/mem.h"
+#include "utils/misc.h"
+#include "utils/vec/vec_char.h"
+#include "utils/vec/vec_sdbl.h"
+#include "utils/vec/vec_uint.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+enum {
+ LIT_FALSE = 1,
+ LIT_TRUE = 0,
+ VAR_UNASSING = 3
+};
+
+#define UNDEF 0xFFFFFFFF
+
+typedef struct solver_t_ solver_t;
+struct solver_t_ {
+ /* User data */
+ vec_uint_t *assumptions;
+ vec_uint_t *final_conflict;
+
+ /* Clauses Database */
+ struct cdb *all_clauses;
+ vec_uint_t *learnts;
+ vec_uint_t *originals;
+ vec_wl_t *watches;
+
+ /* Activity heuristic */
+ act_t var_act_inc; /* Amount to bump next variable with. */
+ clause_act_t clause_act_inc; /* Amount to bump next clause with. */
+
+ /* Variable Information */
+ vec_act_t *activity; /* A heuristic measurement of the activity of a variable. */
+ heap_t *var_order;
+ vec_uint_t *levels; /* Decision level of the current assignment */
+ vec_uint_t *reasons; /* Reason (clause) of the current assignment */
+ vec_char_t *assigns;
+ vec_char_t *polarity;
+
+ /* Assignments */
+ vec_uint_t *trail;
+ vec_uint_t *trail_lim; /* Separator indices for different decision levels in 'trail'. */
+ unsigned i_qhead; /* Head of propagation queue (as index into the trail). */
+ unsigned n_assigns_simplify; /* Number of top-level assignments since
+ last execution of 'simplify()'. */
+ long n_props_simplify; /* Remaining number of propagations that
+ must be made before next execution of
+ 'simplify()'. */
+
+ /* Temporary data used by Analyze */
+ vec_uint_t *temp_lits;
+ vec_char_t *seen;
+ vec_uint_t *tagged; /* Stack */
+ vec_uint_t *stack;
+ vec_uint_t *last_dlevel;
+
+ /* Temporary data used by Search method */
+ b_queue_t *bq_trail;
+ b_queue_t *bq_lbd;
+ long RC1;
+ long RC2;
+ long n_confl_bfr_reduce;
+ float sum_lbd;
+
+ /* Misc temporary */
+ unsigned cur_stamp; /* Used for marking literals and levels of interest */
+ vec_uint_t *stamps; /* Multipurpose stamp used to calculate LBD and
+ * clauses minimization with binary resolution */
+
+ /* Bookmark */
+ unsigned book_cl_orig; /* Bookmark for orignal problem clauses vector */
+ unsigned book_cl_lrnt; /* Bookmark for learnt clauses vector */
+ unsigned book_cdb; /* Bookmark clause database size */
+ unsigned book_vars; /* Bookmark number of variables */
+ unsigned book_trail; /* Bookmark trail size */
+
+ /* Temporary data used for solving cones */
+ vec_char_t *marks;
+
+ struct satoko_stats stats;
+ struct satoko_opts opts;
+};
+
+//===------------------------------------------------------------------------===
+extern unsigned solver_clause_create(solver_t *, vec_uint_t *, unsigned);
+extern char solver_search(solver_t *);
+extern void solver_cancel_until(solver_t *, unsigned);
+extern unsigned solver_propagate(solver_t *);
+extern void solver_debug_check(solver_t *, int);
+
+//===------------------------------------------------------------------------===
+// Inline var/lit functions
+//===------------------------------------------------------------------------===
+static inline unsigned var2lit(unsigned var, char polarity)
+{
+ return var + var + ((unsigned) polarity != 0);
+}
+
+static inline unsigned lit2var(unsigned lit)
+{
+ return lit >> 1;
+}
+//===------------------------------------------------------------------------===
+// Inline var functions
+//===------------------------------------------------------------------------===
+static inline char var_value(solver_t *s, unsigned var)
+{
+ return vec_char_at(s->assigns, var);
+}
+
+static inline char var_polarity(solver_t *s, unsigned var)
+{
+ return vec_char_at(s->polarity, var);
+}
+
+static inline unsigned var_dlevel(solver_t *s, unsigned var)
+{
+ return vec_uint_at(s->levels, var);
+}
+
+static inline unsigned var_reason(solver_t *s, unsigned var)
+{
+ return vec_uint_at(s->reasons, var);
+}
+static inline int var_mark(solver_t *s, unsigned var)
+{
+ return (int)vec_char_at(s->marks, var);
+}
+static inline void var_set_mark(solver_t *s, unsigned var)
+{
+ vec_char_assign(s->marks, var, 1);
+}
+static inline void var_clean_mark(solver_t *s, unsigned var)
+{
+ vec_char_assign(s->marks, var, 0);
+}
+//===------------------------------------------------------------------------===
+// Inline lit functions
+//===------------------------------------------------------------------------===
+static inline unsigned lit_neg(unsigned lit)
+{
+ return lit ^ 1;
+}
+
+static inline char lit_polarity(unsigned lit)
+{
+ return (char)(lit & 1);
+}
+
+static inline char lit_value(solver_t *s, unsigned lit)
+{
+ return lit_polarity(lit) ^ vec_char_at(s->assigns, lit2var(lit));
+}
+
+static inline unsigned lit_dlevel(solver_t *s, unsigned lit)
+{
+ return vec_uint_at(s->levels, lit2var(lit));
+}
+
+static inline unsigned lit_reason(solver_t *s, unsigned lit)
+{
+ return vec_uint_at(s->reasons, lit2var(lit));
+}
+//===------------------------------------------------------------------------===
+// Inline solver minor functions
+//===------------------------------------------------------------------------===
+static inline unsigned solver_check_limits(solver_t *s)
+{
+ return (s->opts.conf_limit == 0 || s->opts.conf_limit >= s->stats.n_conflicts) &&
+ (s->opts.prop_limit == 0 || s->opts.prop_limit >= s->stats.n_propagations);
+}
+
+/** Returns current decision level */
+static inline unsigned solver_dlevel(solver_t *s)
+{
+ return vec_uint_size(s->trail_lim);
+}
+
+static inline int solver_enqueue(solver_t *s, unsigned lit, unsigned reason)
+{
+ unsigned var = lit2var(lit);
+
+ vec_char_assign(s->assigns, var, lit_polarity(lit));
+ vec_uint_assign(s->levels, var, solver_dlevel(s));
+ vec_uint_assign(s->reasons, var, reason);
+ vec_uint_push_back(s->trail, lit);
+ return SATOKO_OK;
+}
+
+static inline int solver_varnum(solver_t *s)
+{
+ return vec_char_size(s->assigns);
+}
+static inline int solver_has_marks(solver_t *s)
+{
+ return (int)(s->marks != NULL);
+}
+
+//===------------------------------------------------------------------------===
+// Inline clause functions
+//===------------------------------------------------------------------------===
+static inline struct clause *clause_read(solver_t *s, unsigned cref)
+{
+ return cdb_handler(s->all_clauses, cref);
+}
+
+static inline void clause_watch(solver_t *s, unsigned cref)
+{
+ struct clause *clause = cdb_handler(s->all_clauses, cref);
+ struct watcher w1;
+ struct watcher w2;
+
+ w1.cref = cref;
+ w2.cref = cref;
+ w1.blocker = clause->data[1].lit;
+ w2.blocker = clause->data[0].lit;
+ watch_list_push(vec_wl_at(s->watches, lit_neg(clause->data[0].lit)), w1, (clause->size == 2));
+ watch_list_push(vec_wl_at(s->watches, lit_neg(clause->data[1].lit)), w2, (clause->size == 2));
+}
+
+static inline void clause_unwatch(solver_t *s, unsigned cref)
+{
+ struct clause *clause = cdb_handler(s->all_clauses, cref);
+ watch_list_remove(vec_wl_at(s->watches, lit_neg(clause->data[0].lit)), cref, (clause->size == 2));
+ watch_list_remove(vec_wl_at(s->watches, lit_neg(clause->data[1].lit)), cref, (clause->size == 2));
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__solver_h */
diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c
new file mode 100644
index 00000000..3cb9f3d3
--- /dev/null
+++ b/src/sat/satoko/solver_api.c
@@ -0,0 +1,445 @@
+//===--- solver_api.h -------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <math.h>
+
+#include "act_var.h"
+#include "solver.h"
+#include "utils/misc.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_IMPL_START
+
+//===------------------------------------------------------------------------===
+// Satoko internal functions
+//===------------------------------------------------------------------------===
+static inline void solver_rebuild_order(solver_t *s)
+{
+ unsigned var;
+ vec_uint_t *vars = vec_uint_alloc(vec_char_size(s->assigns));
+
+ for (var = 0; var < vec_char_size(s->assigns); var++)
+ if (var_value(s, var) == VAR_UNASSING)
+ vec_uint_push_back(vars, var);
+ heap_build(s->var_order, vars);
+ vec_uint_free(vars);
+}
+
+static inline int clause_is_satisfied(solver_t *s, struct clause *clause)
+{
+ unsigned i;
+ unsigned *lits = &(clause->data[0].lit);
+ for (i = 0; i < clause->size; i++)
+ if (lit_value(s, lits[i]) == LIT_TRUE)
+ return SATOKO_OK;
+ return SATOKO_ERR;
+}
+
+static inline void print_opts(solver_t *s)
+{
+ printf( "+-[ BLACK MAGIC - PARAMETERS ]-+\n");
+ printf( "| |\n");
+ printf( "|--> Restarts heuristic |\n");
+ printf( "| * LBD Queue = %6d |\n", s->opts.sz_lbd_bqueue);
+ printf( "| * Trail Queue = %6d |\n", s->opts.sz_trail_bqueue);
+ printf( "| * f_rst = %6.2f |\n", s->opts.f_rst);
+ printf( "| * b_rst = %6.2f |\n", s->opts.b_rst);
+ printf( "| |\n");
+ printf( "|--> Clause DB reduction: |\n");
+ printf( "| * First = %6d |\n", s->opts.n_conf_fst_reduce);
+ printf( "| * Inc = %6d |\n", s->opts.inc_reduce);
+ printf( "| * Special Inc = %6d |\n", s->opts.inc_special_reduce);
+ printf( "| * Protected (LBD) < %2d |\n", s->opts.lbd_freeze_clause);
+ printf( "| |\n");
+ printf( "|--> Binary resolution: |\n");
+ printf( "| * Clause size < %3d |\n", s->opts.clause_max_sz_bin_resol);
+ printf( "| * Clause lbd < %3d |\n", s->opts.clause_min_lbd_bin_resol);
+ printf( "+------------------------------+\n\n");
+}
+
+static inline void print_stats(solver_t *s)
+{
+ printf("starts : %10d\n", s->stats.n_starts);
+ printf("conflicts : %10ld\n", s->stats.n_conflicts);
+ printf("decisions : %10ld\n", s->stats.n_decisions);
+ printf("propagations : %10ld\n", s->stats.n_propagations);
+}
+
+//===------------------------------------------------------------------------===
+// Satoko external functions
+//===------------------------------------------------------------------------===
+solver_t * satoko_create()
+{
+ solver_t *s = satoko_calloc(solver_t, 1);
+
+ satoko_default_opts(&s->opts);
+ /* User data */
+ s->assumptions = vec_uint_alloc(0);
+ s->final_conflict = vec_uint_alloc(0);
+ /* Clauses Database */
+ s->all_clauses = cdb_alloc(0);
+ s->originals = vec_uint_alloc(0);
+ s->learnts = vec_uint_alloc(0);
+ s->watches = vec_wl_alloc(0);
+ /* Activity heuristic */
+ s->var_act_inc = VAR_ACT_INIT_INC;
+ s->clause_act_inc = CLAUSE_ACT_INIT_INC;
+ /* Variable Information */
+ s->activity = vec_act_alloc(0);
+ s->var_order = heap_alloc(s->activity);
+ s->levels = vec_uint_alloc(0);
+ s->reasons = vec_uint_alloc(0);
+ s->assigns = vec_char_alloc(0);
+ s->polarity = vec_char_alloc(0);
+ /* Assignments */
+ s->trail = vec_uint_alloc(0);
+ s->trail_lim = vec_uint_alloc(0);
+ /* Temporary data used by Search method */
+ s->bq_trail = b_queue_alloc(s->opts.sz_trail_bqueue);
+ s->bq_lbd = b_queue_alloc(s->opts.sz_lbd_bqueue);
+ s->n_confl_bfr_reduce = s->opts.n_conf_fst_reduce;
+ s->RC1 = 1;
+ s->RC2 = s->opts.n_conf_fst_reduce;
+ /* Temporary data used by Analyze */
+ s->temp_lits = vec_uint_alloc(0);
+ s->seen = vec_char_alloc(0);
+ s->tagged = vec_uint_alloc(0);
+ s->stack = vec_uint_alloc(0);
+ s->last_dlevel = vec_uint_alloc(0);
+ /* Misc temporary */
+ s->stamps = vec_uint_alloc(0);
+ return s;
+}
+
+void satoko_destroy(solver_t *s)
+{
+ vec_uint_free(s->assumptions);
+ vec_uint_free(s->final_conflict);
+ cdb_free(s->all_clauses);
+ vec_uint_free(s->originals);
+ vec_uint_free(s->learnts);
+ vec_wl_free(s->watches);
+ vec_act_free(s->activity);
+ heap_free(s->var_order);
+ vec_uint_free(s->levels);
+ vec_uint_free(s->reasons);
+ vec_char_free(s->assigns);
+ vec_char_free(s->polarity);
+ vec_uint_free(s->trail);
+ vec_uint_free(s->trail_lim);
+ b_queue_free(s->bq_lbd);
+ b_queue_free(s->bq_trail);
+ vec_uint_free(s->temp_lits);
+ vec_char_free(s->seen);
+ vec_uint_free(s->tagged);
+ vec_uint_free(s->stack);
+ vec_uint_free(s->last_dlevel);
+ vec_uint_free(s->stamps);
+ if (s->marks)
+ vec_char_free(s->marks);
+ satoko_free(s);
+}
+
+void satoko_default_opts(satoko_opts_t *opts)
+{
+ memset(opts, 0, sizeof(satoko_opts_t));
+ opts->verbose = 0;
+ /* Limits */
+ opts->conf_limit = 0;
+ opts->prop_limit = 0;
+ /* Constants used for restart heuristic */
+ opts->f_rst = 0.8;
+ opts->b_rst = 1.4;
+ opts->fst_block_rst = 10000;
+ opts->sz_lbd_bqueue = 50;
+ opts->sz_trail_bqueue = 5000;
+ /* Constants used for clause database reduction heuristic */
+ opts->n_conf_fst_reduce = 2000;
+ opts->inc_reduce = 300;
+ opts->inc_special_reduce = 1000;
+ opts->lbd_freeze_clause = 30;
+ opts->learnt_ratio = 0.5;
+ /* VSIDS heuristic */
+ opts->var_act_limit = VAR_ACT_LIMIT;
+ opts->var_act_rescale = VAR_ACT_RESCALE;
+ opts->var_decay = 0.95;
+ opts->clause_decay = (clause_act_t) 0.995;
+ /* Binary resolution */
+ opts->clause_max_sz_bin_resol = 30;
+ opts->clause_min_lbd_bin_resol = 6;
+
+ opts->garbage_max_ratio = (float) 0.3;
+}
+
+/**
+ * TODO: sanity check on configuration options
+ */
+void satoko_configure(satoko_t *s, satoko_opts_t *user_opts)
+{
+ assert(user_opts);
+ memcpy(&s->opts, user_opts, sizeof(satoko_opts_t));
+}
+
+int satoko_simplify(solver_t * s)
+{
+ unsigned i, j = 0;
+ unsigned cref;
+
+ assert(solver_dlevel(s) == 0);
+ if (solver_propagate(s) != UNDEF)
+ return SATOKO_ERR;
+ if (s->n_assigns_simplify == vec_uint_size(s->trail) || s->n_props_simplify > 0)
+ return SATOKO_OK;
+
+ vec_uint_foreach(s->originals, cref, i) {
+ struct clause *clause = clause_read(s, cref);
+
+ if (clause_is_satisfied(s, clause)) {
+ clause->f_mark = 1;
+ s->stats.n_original_lits -= clause->size;
+ clause_unwatch(s, cref);
+ } else
+ vec_uint_assign(s->originals, j++, cref);
+ }
+ vec_uint_shrink(s->originals, j);
+ solver_rebuild_order(s);
+ s->n_assigns_simplify = vec_uint_size(s->trail);
+ s->n_props_simplify = s->stats.n_original_lits + s->stats.n_learnt_lits;
+ return SATOKO_OK;
+}
+
+int satoko_add_variable(solver_t *s, char sign)
+{
+ unsigned var = vec_act_size(s->activity);
+ vec_wl_push(s->watches);
+ vec_wl_push(s->watches);
+ vec_act_push_back(s->activity, 0);
+ vec_uint_push_back(s->levels, 0);
+ vec_char_push_back(s->assigns, VAR_UNASSING);
+ vec_char_push_back(s->polarity, sign);
+ vec_uint_push_back(s->reasons, UNDEF);
+ vec_uint_push_back(s->stamps, 0);
+ vec_char_push_back(s->seen, 0);
+ heap_insert(s->var_order, var);
+ if (s->marks)
+ vec_char_push_back(s->marks, 0);
+ return var;
+}
+
+int satoko_add_clause(solver_t *s, int *lits, int size)
+{
+ unsigned i, j;
+ unsigned prev_lit;
+ unsigned max_var;
+ unsigned cref;
+
+ qsort((void *) lits, size, sizeof(unsigned), stk_uint_compare);
+ max_var = lit2var(lits[size - 1]);
+ while (max_var >= vec_act_size(s->activity))
+ satoko_add_variable(s, LIT_FALSE);
+
+ vec_uint_clear(s->temp_lits);
+ j = 0;
+ prev_lit = UNDEF;
+ for (i = 0; i < (unsigned)size; i++) {
+ if ((unsigned)lits[i] == lit_neg(prev_lit) || lit_value(s, lits[i]) == LIT_TRUE)
+ return SATOKO_OK;
+ else if ((unsigned)lits[i] != prev_lit && var_value(s, lit2var(lits[i])) == VAR_UNASSING) {
+ prev_lit = lits[i];
+ vec_uint_push_back(s->temp_lits, lits[i]);
+ }
+ }
+
+ if (vec_uint_size(s->temp_lits) == 0)
+ return SATOKO_ERR;
+ if (vec_uint_size(s->temp_lits) == 1) {
+ solver_enqueue(s, vec_uint_at(s->temp_lits, 0), UNDEF);
+ return (solver_propagate(s) == UNDEF);
+ }
+
+ cref = solver_clause_create(s, s->temp_lits, 0);
+ clause_watch(s, cref);
+ return SATOKO_OK;
+}
+
+void satoko_assump_push(solver_t *s, int lit)
+{
+ vec_uint_push_back(s->assumptions, lit);
+}
+
+void satoko_assump_pop(solver_t *s)
+{
+ assert(vec_uint_size(s->assumptions) > 0);
+ vec_uint_pop_back(s->assumptions);
+ solver_cancel_until(s, vec_uint_size(s->assumptions));
+}
+
+int satoko_solve(solver_t *s)
+{
+ char status = SATOKO_UNDEC;
+
+ assert(s);
+ //if (s->opts.verbose)
+ // print_opts(s);
+
+ while (status == SATOKO_UNDEC) {
+ status = solver_search(s);
+ if (solver_check_limits(s) == 0)
+ break;
+ }
+ if (s->opts.verbose)
+ print_stats(s);
+ solver_cancel_until(s, vec_uint_size(s->assumptions));
+ return status;
+}
+
+int satoko_final_conflict(solver_t *s, unsigned *out)
+{
+ if (vec_uint_size(s->final_conflict) == 0)
+ return -1;
+ out = satoko_alloc(unsigned, vec_uint_size(s->final_conflict));
+ memcpy(out, vec_uint_data(s->final_conflict),
+ sizeof(unsigned) * vec_uint_size(s->final_conflict));
+ return vec_uint_size(s->final_conflict);
+
+}
+
+satoko_stats_t satoko_stats(satoko_t *s)
+{
+ return s->stats;
+}
+
+void satoko_bookmark(satoko_t *s)
+{
+ assert(solver_dlevel(s) == 0);
+ s->book_cl_orig = vec_uint_size(s->originals);
+ s->book_cl_lrnt = vec_uint_size(s->learnts);
+ s->book_vars = vec_char_size(s->assigns);
+ s->book_trail = vec_uint_size(s->trail);
+}
+
+void satoko_unbookmark(satoko_t *s)
+{
+ s->book_cl_orig = 0;
+ s->book_cl_lrnt = 0;
+ s->book_cdb = 0;
+ s->book_vars = 0;
+ s->book_trail = 0;
+}
+
+void satoko_reset(satoko_t *s)
+{
+ vec_uint_clear(s->assumptions);
+ vec_uint_clear(s->final_conflict);
+ cdb_clear(s->all_clauses);
+ vec_uint_clear(s->originals);
+ vec_uint_clear(s->learnts);
+ vec_wl_clean(s->watches);
+ vec_act_clear(s->activity);
+ heap_clear(s->var_order);
+ vec_uint_clear(s->levels);
+ vec_uint_clear(s->reasons);
+ vec_char_clear(s->assigns);
+ vec_char_clear(s->polarity);
+ vec_uint_clear(s->trail);
+ vec_uint_clear(s->trail_lim);
+ b_queue_clean(s->bq_lbd);
+ b_queue_clean(s->bq_trail);
+ vec_uint_clear(s->temp_lits);
+ vec_char_clear(s->seen);
+ vec_uint_clear(s->tagged);
+ vec_uint_clear(s->stack);
+ vec_uint_clear(s->last_dlevel);
+ vec_uint_clear(s->stamps);
+ s->var_act_inc = VAR_ACT_INIT_INC;
+ s->clause_act_inc = CLAUSE_ACT_INIT_INC;
+ s->n_confl_bfr_reduce = s->opts.n_conf_fst_reduce;
+ s->RC1 = 1;
+ s->RC2 = s->opts.n_conf_fst_reduce;
+ s->book_cl_orig = 0;
+ s->book_cl_lrnt = 0;
+ s->book_cdb = 0;
+ s->book_vars = 0;
+ s->book_trail = 0;
+}
+
+void satoko_rollback(satoko_t *s)
+{
+ unsigned i, cref;
+ unsigned n_originals = vec_uint_size(s->originals) - s->book_cl_orig;
+ unsigned n_learnts = vec_uint_size(s->learnts) - s->book_cl_lrnt;
+ struct clause **cl_to_remove;
+
+ assert(solver_dlevel(s) == 0);
+ if (!s->book_vars) {
+ satoko_reset(s);
+ return;
+ }
+
+ cl_to_remove = satoko_alloc(struct clause *, n_originals + n_learnts);
+ /* Mark clauses */
+ vec_uint_foreach_start(s->originals, cref, i, s->book_cl_orig)
+ cl_to_remove[i] = clause_read(s, cref);
+ vec_uint_foreach_start(s->learnts, cref, i, s->book_cl_lrnt)
+ cl_to_remove[n_originals + i] = clause_read(s, cref);
+ for (i = 0; i < n_originals + n_learnts; i++) {
+ clause_unwatch(s, cdb_cref(s->all_clauses, (unsigned *)cl_to_remove[i]));
+ cl_to_remove[i]->f_mark = 1;
+ }
+ satoko_free(cl_to_remove);
+ vec_uint_shrink(s->originals, s->book_cl_orig);
+ vec_uint_shrink(s->learnts, s->book_cl_lrnt);
+ /* Shrink variable related vectors */
+ for (i = s->book_vars; i < 2 * vec_char_size(s->assigns); i++) {
+ vec_wl_at(s->watches, i)->size = 0;
+ vec_wl_at(s->watches, i)->n_bin = 0;
+ }
+ s->watches->size = s->book_vars;
+ vec_act_shrink(s->activity, s->book_vars);
+ vec_uint_shrink(s->levels, s->book_vars);
+ vec_uint_shrink(s->reasons, s->book_vars);
+ vec_uint_shrink(s->stamps, s->book_vars);
+ vec_char_shrink(s->assigns, s->book_vars);
+ vec_char_shrink(s->seen, s->book_vars);
+ vec_char_shrink(s->polarity, s->book_vars);
+ solver_rebuild_order(s);
+ /* Rewind solver and cancel level 0 assignments to the trail */
+ solver_cancel_until(s, 0);
+ vec_uint_shrink(s->trail, s->book_trail);
+ if (s->book_cdb)
+ s->all_clauses->size = s->book_cdb;
+ s->book_cl_orig = 0;
+ s->book_cl_lrnt = 0;
+ s->book_vars = 0;
+ s->book_trail = 0;
+}
+
+void satoko_mark_cone(satoko_t *s, int * pvars, int n_vars)
+{
+ int i;
+ if (!solver_has_marks(s))
+ s->marks = vec_char_init(solver_varnum(s), 0);
+ for (i = 0; i < n_vars; i++) {
+ var_set_mark(s, pvars[i]);
+ if (!heap_in_heap(s->var_order, pvars[i]))
+ heap_insert(s->var_order, pvars[i]);
+ }
+}
+
+void satoko_unmark_cone(satoko_t *s, int *pvars, int n_vars)
+{
+ int i;
+ assert(solver_has_marks(s));
+ for (i = 0; i < n_vars; i++)
+ var_clean_mark(s, pvars[i]);
+}
+
+ABC_NAMESPACE_IMPL_END
diff --git a/src/sat/satoko/types.h b/src/sat/satoko/types.h
new file mode 100644
index 00000000..06c190ab
--- /dev/null
+++ b/src/sat/satoko/types.h
@@ -0,0 +1,39 @@
+//===--- types.h ------------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__types_h
+#define satoko__types_h
+
+#include "utils/sdbl.h"
+#include "utils/vec/vec_sdbl.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+/* In Satoko ABC version this file is useless */
+
+#define VAR_ACT_INIT_INC SDBL_CONST1
+#define VAR_ACT_LIMIT ABC_CONST(0x014c924d692ca61b)
+#define VAR_ACT_RESCALE 200
+typedef sdbl_t act_t;
+typedef vec_sdbl_t vec_act_t ;
+#define vec_act_alloc(size) vec_sdbl_alloc(size)
+#define vec_act_free(vec) vec_sdbl_free(vec)
+#define vec_act_size(vec) vec_sdbl_size(vec)
+#define vec_act_data(vec) vec_sdbl_data(vec)
+#define vec_act_clear(vec) vec_sdbl_clear(vec)
+#define vec_act_shrink(vec, size) vec_sdbl_shrink(vec, size)
+#define vec_act_at(vec, idx) vec_sdbl_at(vec, idx)
+#define vec_act_push_back(vec, value) vec_sdbl_push_back(vec, value)
+
+
+#define CLAUSE_ACT_INIT_INC (1 << 11)
+typedef unsigned clause_act_t;
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__types_h */
diff --git a/src/sat/satoko/utils/b_queue.h b/src/sat/satoko/utils/b_queue.h
new file mode 100644
index 00000000..b9b62676
--- /dev/null
+++ b/src/sat/satoko/utils/b_queue.h
@@ -0,0 +1,81 @@
+//===--- b_queue.h ----------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__utils__b_queue_h
+#define satoko__utils__b_queue_h
+
+#include "mem.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+/* Bounded Queue */
+typedef struct b_queue_t_ b_queue_t;
+struct b_queue_t_ {
+ unsigned size;
+ unsigned cap;
+ unsigned i_first;
+ unsigned i_empty;
+ unsigned long sum;
+ unsigned *data;
+};
+
+//===------------------------------------------------------------------------===
+// Bounded Queue API
+//===------------------------------------------------------------------------===
+static inline b_queue_t *b_queue_alloc(unsigned cap)
+{
+ b_queue_t *p = satoko_calloc(b_queue_t, 1);
+ p->cap = cap;
+ p->data = satoko_calloc(unsigned, cap);
+ return p;
+}
+
+static inline void b_queue_free(b_queue_t *p)
+{
+ satoko_free(p->data);
+ satoko_free(p);
+}
+
+static inline void b_queue_push(b_queue_t *p, unsigned Value)
+{
+ if (p->size == p->cap) {
+ assert(p->i_first == p->i_empty);
+ p->sum -= p->data[p->i_first];
+ p->i_first = (p->i_first + 1) % p->cap;
+ } else
+ p->size++;
+
+ p->sum += Value;
+ p->data[p->i_empty] = Value;
+ if ((++p->i_empty) == p->cap) {
+ p->i_empty = 0;
+ p->i_first = 0;
+ }
+}
+
+static inline unsigned b_queue_avg(b_queue_t *p)
+{
+ return (unsigned)(p->sum / ((unsigned long) p->size));
+}
+
+static inline unsigned b_queue_is_valid(b_queue_t *p)
+{
+ return (p->cap == p->size);
+}
+
+static inline void b_queue_clean(b_queue_t *p)
+{
+ p->i_first = 0;
+ p->i_empty = 0;
+ p->size = 0;
+ p->sum = 0;
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__utils__b_queue_h */
diff --git a/src/sat/satoko/utils/heap.h b/src/sat/satoko/utils/heap.h
new file mode 100644
index 00000000..391b8a7e
--- /dev/null
+++ b/src/sat/satoko/utils/heap.h
@@ -0,0 +1,178 @@
+//===--- heap.h ----------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__utils__heap_h
+#define satoko__utils__heap_h
+
+#include "mem.h"
+#include "../types.h"
+#include "vec/vec_sdbl.h"
+#include "vec/vec_int.h"
+#include "vec/vec_uint.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+typedef struct heap_t_ heap_t;
+struct heap_t_ {
+ vec_int_t *indices;
+ vec_uint_t *data;
+ vec_act_t *weights;
+};
+//===------------------------------------------------------------------------===
+// Heap internal functions
+//===------------------------------------------------------------------------===
+static inline unsigned left(unsigned i) { return 2 * i + 1; }
+static inline unsigned right(unsigned i) { return (i + 1) * 2; }
+static inline unsigned parent(unsigned i) { return (i - 1) >> 1; }
+
+static inline int compare(heap_t *p, unsigned x, unsigned y)
+{
+ return vec_act_at(p->weights, x) > vec_act_at(p->weights, y);
+}
+
+static inline void heap_percolate_up(heap_t *h, unsigned i)
+{
+ unsigned x = vec_uint_at(h->data, i);
+ unsigned p = parent(i);
+
+ while (i != 0 && compare(h, x, vec_uint_at(h->data, p))) {
+ vec_uint_assign(h->data, i, vec_uint_at(h->data, p));
+ vec_int_assign(h->indices, vec_uint_at(h->data, p), (int) i);
+ i = p;
+ p = parent(p);
+ }
+ vec_uint_assign(h->data, i, x);
+ vec_int_assign(h->indices, x, (int) i);
+}
+
+static inline void heap_percolate_down(heap_t *h, unsigned i)
+{
+ unsigned x = vec_uint_at(h->data, i);
+
+ while (left(i) < vec_uint_size(h->data)) {
+ unsigned child = right(i) < vec_uint_size(h->data) &&
+ compare(h, vec_uint_at(h->data, right(i)), vec_uint_at(h->data, left(i)))
+ ? right(i)
+ : left(i);
+
+ if (!compare(h, vec_uint_at(h->data, child), x))
+ break;
+
+ vec_uint_assign(h->data, i, vec_uint_at(h->data, child));
+ vec_int_assign(h->indices, vec_uint_at(h->data, i), (int) i);
+ i = child;
+ }
+ vec_uint_assign(h->data, i, x);
+ vec_int_assign(h->indices, x, (int) i);
+}
+
+//===------------------------------------------------------------------------===
+// Heap API
+//===------------------------------------------------------------------------===
+static inline heap_t *heap_alloc(vec_act_t *weights)
+{
+ heap_t *p = satoko_alloc(heap_t, 1);
+ p->weights = weights;
+ p->indices = vec_int_alloc(0);
+ p->data = vec_uint_alloc(0);
+ return p;
+}
+
+static inline void heap_free(heap_t *p)
+{
+ vec_int_free(p->indices);
+ vec_uint_free(p->data);
+ satoko_free(p);
+}
+
+static inline unsigned heap_size(heap_t *p)
+{
+ return vec_uint_size(p->data);
+}
+
+static inline int heap_in_heap(heap_t *p, unsigned entry)
+{
+ return (entry < vec_int_size(p->indices)) &&
+ (vec_int_at(p->indices, entry) >= 0);
+}
+
+static inline void heap_increase(heap_t *p, unsigned entry)
+{
+ assert(heap_in_heap(p, entry));
+ heap_percolate_down(p, (unsigned) vec_int_at(p->indices, entry));
+}
+
+static inline void heap_decrease(heap_t *p, unsigned entry)
+{
+ assert(heap_in_heap(p, entry));
+ heap_percolate_up(p, (unsigned) vec_int_at(p->indices, entry));
+}
+
+static inline void heap_insert(heap_t *p, unsigned entry)
+{
+ if (vec_int_size(p->indices) < entry + 1) {
+ unsigned old_size = vec_int_size(p->indices);
+ unsigned i;
+ int e;
+ vec_int_resize(p->indices, entry + 1);
+ vec_int_foreach_start(p->indices, e, i, old_size)
+ vec_int_assign(p->indices, i, -1);
+ }
+ assert(!heap_in_heap(p, entry));
+ vec_int_assign(p->indices, entry, (int) vec_uint_size(p->data));
+ vec_uint_push_back(p->data, entry);
+ heap_percolate_up(p, (unsigned) vec_int_at(p->indices, entry));
+}
+
+static inline void heap_update(heap_t *p, unsigned i)
+{
+ if (!heap_in_heap(p, i))
+ heap_insert(p, i);
+ else {
+ heap_percolate_up(p, (unsigned) vec_int_at(p->indices, i));
+ heap_percolate_down(p, (unsigned) vec_int_at(p->indices, i));
+ }
+}
+
+static inline void heap_build(heap_t *p, vec_uint_t *entries)
+{
+ int i;
+ unsigned j, entry;
+
+ vec_uint_foreach(p->data, entry, j)
+ vec_int_assign(p->indices, entry, -1);
+ vec_uint_clear(p->data);
+ vec_uint_foreach(entries, entry, j) {
+ vec_int_assign(p->indices, entry, (int) j);
+ vec_uint_push_back(p->data, entry);
+ }
+ for ((i = vec_uint_size(p->data) / 2 - 1); i >= 0; i--)
+ heap_percolate_down(p, (unsigned) i);
+}
+
+static inline void heap_clear(heap_t *p)
+{
+ vec_int_clear(p->indices);
+ vec_uint_clear(p->data);
+}
+
+static inline unsigned heap_remove_min(heap_t *p)
+{
+ unsigned x = vec_uint_at(p->data, 0);
+ vec_uint_assign(p->data, 0, vec_uint_at(p->data, vec_uint_size(p->data) - 1));
+ vec_int_assign(p->indices, vec_uint_at(p->data, 0), 0);
+ vec_int_assign(p->indices, x, -1);
+ vec_uint_pop_back(p->data);
+ if (vec_uint_size(p->data) > 1)
+ heap_percolate_down(p, 0);
+ return x;
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__utils__heap_h */
diff --git a/src/sat/satoko/utils/mem.h b/src/sat/satoko/utils/mem.h
new file mode 100755
index 00000000..5ff9873d
--- /dev/null
+++ b/src/sat/satoko/utils/mem.h
@@ -0,0 +1,23 @@
+//===--- mem.h --------------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__utils__mem_h
+#define satoko__utils__mem_h
+
+#include <stdlib.h>
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+#define satoko_alloc(type, n_elements) ((type *) malloc((n_elements) * sizeof(type)))
+#define satoko_calloc(type, n_elements) ((type *) calloc((n_elements), sizeof(type)))
+#define satoko_realloc(type, ptr, n_elements) ((type *) realloc(ptr, (n_elements) * sizeof(type)))
+#define satoko_free(p) do { free(p); p = NULL; } while(0)
+
+ABC_NAMESPACE_HEADER_END
+#endif
diff --git a/src/sat/satoko/utils/misc.h b/src/sat/satoko/utils/misc.h
new file mode 100755
index 00000000..7205a096
--- /dev/null
+++ b/src/sat/satoko/utils/misc.h
@@ -0,0 +1,35 @@
+//===--- misc.h -------------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__utils__misc_h
+#define satoko__utils__misc_h
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+#define stk_swap(type, a, b) { type t = a; a = b; b = t; }
+
+static inline unsigned stk_uint_max(unsigned a, unsigned b)
+{
+ return a > b ? a : b;
+}
+
+static inline int stk_uint_compare(const void *p1, const void *p2)
+{
+ const unsigned pp1 = *(const unsigned *)p1;
+ const unsigned pp2 = *(const unsigned *)p2;
+
+ if (pp1 < pp2)
+ return -1;
+ if (pp1 > pp2)
+ return 1;
+ return 0;
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__utils__misc_h */
diff --git a/src/sat/satoko/utils/sdbl.h b/src/sat/satoko/utils/sdbl.h
new file mode 100644
index 00000000..9f90ba02
--- /dev/null
+++ b/src/sat/satoko/utils/sdbl.h
@@ -0,0 +1,133 @@
+//===--- sdbl.h -------------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+// by Alan Mishchenko
+#ifndef satoko__utils__sdbl_h
+#define satoko__utils__sdbl_h
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+/*
+ The sdbl_t floating-point number is represented as a 64-bit unsigned int.
+ The number is (2^expt)*mnt, where expt is a 16-bit exponent and mnt is a
+ 48-bit mantissa. The decimal point is located between the MSB of mnt,
+ which is always 1, and the remaining 15 digits of mnt.
+
+ Currently, only positive numbers are represented.
+
+ The range of possible values is [1.0; 2^(2^16-1)*1.111111111111111]
+ that is, the smallest possible number is 1.0 and the largest possible
+ number is 2^(---16 ones---).(1.---47 ones---)
+
+ Comparison of numbers can be done by comparing the underlying unsigned ints.
+
+ Only addition, multiplication, and division by 2^n are currently implemented.
+*/
+
+typedef word sdbl_t;
+
+static sdbl_t SDBL_CONST1 = ABC_CONST(0x0000800000000000);
+static sdbl_t SDBL_MAX = ~(sdbl_t)(0);
+
+union ui64_dbl { word ui64; double dbl; };
+
+static inline word sdbl_exp(sdbl_t a) { return a >> 48; }
+static inline word sdbl_mnt(sdbl_t a) { return (a << 16) >> 16; }
+
+static inline double sdbl2double(sdbl_t a) {
+ union ui64_dbl temp;
+ assert(sdbl_exp(a) < 1023);
+ temp.ui64 = ((sdbl_exp(a) + 1023) << 52) | (((a << 17) >> 17) << 5);
+ return temp.dbl;
+}
+
+static inline sdbl_t double2sdbl(double value)
+{
+ union ui64_dbl temp;
+ sdbl_t expt, mnt;
+ assert(value >= 1.0);
+ temp.dbl = value;
+ expt = (temp.ui64 >> 52) - 1023;
+ mnt = SDBL_CONST1 | ((temp.ui64 << 12) >> 17);
+ return (expt << 48) + mnt;
+}
+
+static inline sdbl_t sdbl_add(sdbl_t a, sdbl_t b)
+{
+ sdbl_t expt, mnt;
+ if (a < b) {
+ a ^= b;
+ b ^= a;
+ a ^= b;
+ }
+ assert(a >= b);
+ expt = sdbl_exp(a);
+ mnt = sdbl_mnt(a) + (sdbl_mnt(b) >> (sdbl_exp(a) - sdbl_exp(b)));
+ /* Check for carry */
+ if (mnt >> 48) {
+ expt++;
+ mnt >>= 1;
+ }
+ if (expt >> 16) /* overflow */
+ return SDBL_MAX;
+ return (expt << 48) + mnt;
+}
+
+static inline sdbl_t sdbl_mult(sdbl_t a, sdbl_t b)
+{
+ sdbl_t expt, mnt;
+ sdbl_t a_mnt, a_mnt_hi, a_mnt_lo;
+ sdbl_t b_mnt, b_mnt_hi, b_mnt_lo;
+ if (a < b) {
+ a ^= b;
+ b ^= a;
+ a ^= b;
+ }
+ assert( a >= b );
+ a_mnt = sdbl_mnt(a);
+ b_mnt = sdbl_mnt(b);
+ a_mnt_hi = a_mnt>>32;
+ b_mnt_hi = b_mnt>>32;
+ a_mnt_lo = (a_mnt<<32)>>32;
+ b_mnt_lo = (b_mnt<<32)>>32;
+ mnt = ((a_mnt_hi * b_mnt_hi) << 17) +
+ ((a_mnt_lo * b_mnt_lo) >> 47) +
+ ((a_mnt_lo * b_mnt_hi) >> 15) +
+ ((a_mnt_hi * b_mnt_lo) >> 15);
+ expt = sdbl_exp(a) + sdbl_exp(b);
+ /* Check for carry */
+ if (mnt >> 48) {
+ expt++;
+ mnt >>= 1;
+ }
+ if (expt >> 16) /* overflow */
+ return SDBL_MAX;
+ return (expt << 48) + mnt;
+}
+
+static inline sdbl_t sdbl_div(sdbl_t a, unsigned deg2)
+{
+ if (sdbl_exp(a) >= (word)deg2)
+ return ((sdbl_exp(a) - deg2) << 48) + sdbl_mnt(a);
+ return SDBL_CONST1;
+}
+
+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("%f\n", sdbl2double(SDBL_CONST1));
+ printf("%f\n", sdbl2double(ABC_CONST(0x000086BCA1AF286B)));
+
+}
+
+ABC_NAMESPACE_HEADER_END
+
+#endif /* satoko__utils__sdbl_h */
diff --git a/src/sat/satoko/utils/sort.h b/src/sat/satoko/utils/sort.h
new file mode 100644
index 00000000..285f4b91
--- /dev/null
+++ b/src/sat/satoko/utils/sort.h
@@ -0,0 +1,65 @@
+//===--- sort.h -------------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__utils__sort_h
+#define satoko__utils__sort_h
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+static inline void select_sort(void **data, unsigned size,
+ int (*comp_fn)(const void *, const void *))
+{
+ unsigned i, j, i_best;
+ void *temp;
+
+ for (i = 0; i < (size - 1); i++) {
+ i_best = i;
+ for (j = i + 1; j < size; j++) {
+ if (comp_fn(data[j], data[i_best]))
+ i_best = j;
+ }
+ temp = data[i];
+ data[i] = data[i_best];
+ data[i_best] = temp;
+ }
+}
+
+static void satoko_sort(void **data, unsigned size,
+ int (*comp_fn)(const void *, const void *))
+{
+ if (size <= 15)
+ select_sort(data, size, comp_fn);
+ else {
+ void *pivot = data[size / 2];
+ void *temp;
+ unsigned j = size;
+ int i = -1;
+
+ for (;;) {
+ do {
+ i++;
+ } while (comp_fn(data[i], pivot));
+ do {
+ j--;
+ } while (comp_fn(pivot, data[j]));
+
+ if ((unsigned) i >= j)
+ break;
+
+ temp = data[i];
+ data[i] = data[j];
+ data[j] = temp;
+ }
+ satoko_sort(data, (unsigned) i, comp_fn);
+ satoko_sort(data + i, (size - (unsigned) i), comp_fn);
+ }
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__utils__sort_h */
diff --git a/src/sat/satoko/utils/vec/vec_char.h b/src/sat/satoko/utils/vec/vec_char.h
new file mode 100644
index 00000000..7d5732ec
--- /dev/null
+++ b/src/sat/satoko/utils/vec/vec_char.h
@@ -0,0 +1,260 @@
+//===--- vec_char.h ---------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__utils__vec__vec_char_h
+#define satoko__utils__vec__vec_char_h
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "../mem.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+typedef struct vec_char_t_ vec_char_t;
+struct vec_char_t_ {
+ unsigned cap;
+ unsigned size;
+ char *data;
+};
+
+//===------------------------------------------------------------------------===
+// Vector Macros
+//===------------------------------------------------------------------------===
+#define vec_char_foreach(vec, entry, i) \
+ for (i = 0; (i < vec_char_size(vec)) && (((entry) = vec_char_at(vec, i)), 1); i++)
+
+#define vec_char_foreach_start(vec, entry, i, start) \
+ for (i = start; (i < vec_char_size(vec)) && (((entry) = vec_char_at(vec, i)), 1); i++)
+
+#define vec_char_foreach_stop(vec, entry, i, stop) \
+ for (i = 0; (i < stop) && (((entry) = vec_char_at(vec, i)), 1); i++)
+
+//===------------------------------------------------------------------------===
+// Vector API
+//===------------------------------------------------------------------------===
+static inline vec_char_t * vec_char_alloc(unsigned cap)
+{
+ vec_char_t *p = satoko_alloc(vec_char_t, 1);
+
+ if (cap > 0 && cap < 16)
+ cap = 16;
+ p->size = 0;
+ p->cap = cap;
+ p->data = p->cap ? satoko_alloc(char, p->cap) : NULL;
+ return p;
+}
+
+static inline vec_char_t * vec_char_alloc_exact(unsigned cap)
+{
+ vec_char_t *p = satoko_alloc(vec_char_t, 1);
+
+ cap = 0;
+ p->size = 0;
+ p->cap = cap;
+ p->data = p->cap ? satoko_alloc(char, p->cap ) : NULL;
+ return p;
+}
+
+static inline vec_char_t * vec_char_init(unsigned size, char value)
+{
+ vec_char_t *p = satoko_alloc(vec_char_t, 1);
+
+ p->cap = size;
+ p->size = size;
+ p->data = p->cap ? satoko_alloc(char, p->cap) : NULL;
+ memset(p->data, value, sizeof(char) * p->size);
+ return p;
+}
+
+static inline void vec_char_free(vec_char_t *p)
+{
+ if (p->data != NULL)
+ satoko_free(p->data);
+ satoko_free(p);
+}
+
+static inline unsigned vec_char_size(vec_char_t *p)
+{
+ return p->size;
+}
+
+static inline void vec_char_resize(vec_char_t *p, unsigned new_size)
+{
+ p->size = new_size;
+ if (p->cap >= new_size)
+ return;
+ p->data = satoko_realloc(char, p->data, new_size);
+ assert(p->data != NULL);
+ p->cap = new_size;
+}
+
+static inline void vec_char_shrink(vec_char_t *p, unsigned new_size)
+{
+ assert(p->cap > new_size);
+ p->size = new_size;
+}
+
+static inline void vec_char_reserve(vec_char_t *p, unsigned new_cap)
+{
+ if (p->cap >= new_cap)
+ return;
+ p->data = satoko_realloc(char, p->data, new_cap);
+ assert(p->data != NULL);
+ p->cap = new_cap;
+}
+
+static inline unsigned vec_char_capacity(vec_char_t *p)
+{
+ return p->cap;
+}
+
+static inline int vec_char_empty(vec_char_t *p)
+{
+ return p->size ? 0 : 1;
+}
+
+static inline void vec_char_erase(vec_char_t *p)
+{
+ satoko_free(p->data);
+ p->size = 0;
+ p->cap = 0;
+}
+
+static inline char vec_char_at(vec_char_t *p, unsigned idx)
+{
+ assert(idx >= 0 && idx < p->size);
+ return p->data[idx];
+}
+
+static inline char * vec_char_at_ptr(vec_char_t *p, unsigned idx)
+{
+ assert(idx >= 0 && idx < p->size);
+ return p->data + idx;
+}
+
+static inline char * vec_char_data(vec_char_t *p)
+{
+ assert(p);
+ return p->data;
+}
+
+static inline void vec_char_duplicate(vec_char_t *dest, const vec_char_t *src)
+{
+ assert(dest != NULL && src != NULL);
+ vec_char_resize(dest, src->cap);
+ memcpy(dest->data, src->data, sizeof(char) * src->cap);
+ dest->size = src->size;
+}
+
+static inline void vec_char_copy(vec_char_t *dest, const vec_char_t *src)
+{
+ assert(dest != NULL && src != NULL);
+ vec_char_resize(dest, src->size);
+ memcpy(dest->data, src->data, sizeof(char) * src->size);
+ dest->size = src->size;
+}
+
+static inline void vec_char_push_back(vec_char_t *p, char value)
+{
+ if (p->size == p->cap) {
+ if (p->cap < 16)
+ vec_char_reserve(p, 16);
+ else
+ vec_char_reserve(p, 2 * p->cap);
+ }
+ p->data[p->size] = value;
+ p->size++;
+}
+
+static inline char vec_char_pop_back(vec_char_t *p)
+{
+ assert(p && p->size);
+ return p->data[--p->size];
+}
+
+static inline void vec_char_assign(vec_char_t *p, unsigned idx, char value)
+{
+ assert((idx >= 0) && (idx < vec_char_size(p)));
+ p->data[idx] = value;
+}
+
+static inline void vec_char_insert(vec_char_t *p, unsigned idx, char value)
+{
+ assert((idx >= 0) && (idx < vec_char_size(p)));
+ vec_char_push_back(p, 0);
+ memmove(p->data + idx + 1, p->data + idx, (p->size - idx - 2) * sizeof(char));
+ p->data[idx] = value;
+}
+
+static inline void vec_char_drop(vec_char_t *p, unsigned idx)
+{
+ assert((idx >= 0) && (idx < vec_char_size(p)));
+ memmove(p->data + idx, p->data + idx + 1, (p->size - idx - 1) * sizeof(char));
+ p->size -= 1;
+}
+
+static inline void vec_char_clear(vec_char_t *p)
+{
+ p->size = 0;
+}
+
+static inline int vec_char_asc_compare(const void *p1, const void *p2)
+{
+ const char *pp1 = (const char *)p1;
+ const char *pp2 = (const char *)p2;
+
+ if (*pp1 < *pp2)
+ return -1;
+ if (*pp1 > *pp2)
+ return 1;
+ return 0;
+}
+
+static inline int vec_char_desc_compare(const void *p1, const void *p2)
+{
+ const char *pp1 = (const char *)p1;
+ const char *pp2 = (const char *)p2;
+
+ if (*pp1 > *pp2)
+ return -1;
+ if (*pp1 < *pp2)
+ return 1;
+ return 0;
+}
+
+static inline void vec_char_sort(vec_char_t *p, int ascending)
+{
+ if (ascending)
+ qsort((void *) p->data, p->size, sizeof(char),
+ (int (*)(const void *, const void *)) vec_char_asc_compare);
+ else
+ qsort((void*) p->data, p->size, sizeof(char),
+ (int (*)(const void *, const void *)) vec_char_desc_compare);
+}
+
+
+static inline long vec_char_memory(vec_char_t *p)
+{
+ return p == NULL ? 0 : sizeof(char) * p->cap + sizeof(vec_char_t);
+}
+
+static inline void vec_char_print(vec_char_t* p)
+{
+ unsigned i;
+ assert(p != NULL);
+ fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap);
+ for (i = 0; i < p->size; i++)
+ fprintf(stdout, " %d", p->data[i]);
+ fprintf(stdout, " }\n");
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__utils__vec__vec_char_h */
diff --git a/src/sat/satoko/utils/vec/vec_flt.h b/src/sat/satoko/utils/vec/vec_flt.h
new file mode 100644
index 00000000..d7c896d9
--- /dev/null
+++ b/src/sat/satoko/utils/vec/vec_flt.h
@@ -0,0 +1,246 @@
+//===--- vec_int.h ----------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__utils__vec__vec_flt_h
+#define satoko__utils__vec__vec_flt_h
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "../mem.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+typedef struct vec_flt_t_ vec_flt_t;
+struct vec_flt_t_ {
+ unsigned cap;
+ unsigned size;
+ float *data;
+};
+
+//===------------------------------------------------------------------------===
+// Vector Macros
+//===------------------------------------------------------------------------===
+#define vec_flt_foreach(vec, entry, i) \
+ for (i = 0; (i < vec->size) && (((entry) = vec_flt_at(vec, i)), 1); i++)
+
+#define vec_flt_foreach_start(vec, entry, i, start) \
+ for (i = start; (i < vec_flt_size(vec)) && (((entry) = vec_flt_at(vec, i)), 1); i++)
+
+#define vec_flt_foreach_stop(vec, entry, i, stop) \
+ for (i = 0; (i < stop) && (((entry) = vec_flt_at(vec, i)), 1); i++)
+
+//===------------------------------------------------------------------------===
+// Vector API
+//===------------------------------------------------------------------------===
+static inline vec_flt_t *vec_flt_alloc(unsigned cap)
+{
+ vec_flt_t* p = satoko_alloc(vec_flt_t, 1);
+
+ if (cap > 0 && cap < 16)
+ cap = 16;
+ p->size = 0;
+ p->cap = cap;
+ p->data = p->cap ? satoko_alloc(float, p->cap) : NULL;
+ return p;
+}
+
+static inline vec_flt_t *vec_flt_alloc_exact(unsigned cap)
+{
+ vec_flt_t* p = satoko_alloc(vec_flt_t, 1);
+
+ p->size = 0;
+ p->cap = cap;
+ p->data = p->cap ? satoko_alloc(float, p->cap) : NULL;
+ return p;
+}
+
+static inline vec_flt_t *vec_flt_init(unsigned size, float value)
+{
+ vec_flt_t* p = satoko_alloc(vec_flt_t, 1);
+
+ p->cap = size;
+ p->size = size;
+ p->data = p->cap ? satoko_alloc(float, p->cap) : NULL;
+ memset(p->data, value, sizeof(float) * p->size);
+ return p;
+}
+
+static inline void vec_flt_free(vec_flt_t *p)
+{
+ if (p->data != NULL)
+ satoko_free(p->data);
+ satoko_free(p);
+}
+
+static inline unsigned vec_flt_size(vec_flt_t *p)
+{
+ return p->size;
+}
+
+static inline void vec_flt_resize(vec_flt_t *p, unsigned new_size)
+{
+ p->size = new_size;
+ if (p->cap >= new_size)
+ return;
+ p->data = satoko_realloc(float, p->data, new_size);
+ assert(p->data != NULL);
+ p->cap = new_size;
+}
+
+static inline void vec_flt_reserve(vec_flt_t *p, unsigned new_cap)
+{
+ if (p->cap >= new_cap)
+ return;
+ p->data = satoko_realloc(float, p->data, new_cap);
+ assert(p->data != NULL);
+ p->cap = new_cap;
+}
+
+static inline unsigned vec_flt_capacity(vec_flt_t *p)
+{
+ return p->cap;
+}
+
+static inline int vec_flt_empty(vec_flt_t *p)
+{
+ return p->size ? 0 : 1;
+}
+
+static inline void vec_flt_erase(vec_flt_t *p)
+{
+ satoko_free(p->data);
+ p->size = 0;
+ p->cap = 0;
+}
+
+static inline float vec_flt_at(vec_flt_t *p, unsigned i)
+{
+ assert(i >= 0 && i < p->size);
+ return p->data[i];
+}
+
+static inline float *vec_flt_at_ptr(vec_flt_t *p, unsigned i)
+{
+ assert(i >= 0 && i < p->size);
+ return p->data + i;
+}
+
+static inline float *vec_flt_data(vec_flt_t *p)
+{
+ assert(p);
+ return p->data;
+}
+
+static inline void vec_flt_duplicate(vec_flt_t *dest, const vec_flt_t *src)
+{
+ assert(dest != NULL && src != NULL);
+ vec_flt_resize(dest, src->cap);
+ memcpy(dest->data, src->data, sizeof(float) * src->cap);
+ dest->size = src->size;
+}
+
+static inline void vec_flt_copy(vec_flt_t *dest, const vec_flt_t *src)
+{
+ assert(dest != NULL && src != NULL);
+ vec_flt_resize(dest, src->size);
+ memcpy(dest->data, src->data, sizeof(float) * src->size);
+ dest->size = src->size;
+}
+
+static inline void vec_flt_push_back(vec_flt_t *p, float value)
+{
+ if (p->size == p->cap) {
+ if (p->cap < 16)
+ vec_flt_reserve(p, 16);
+ else
+ vec_flt_reserve(p, 2 * p->cap);
+ }
+ p->data[p->size] = value;
+ p->size++;
+}
+
+static inline void vec_flt_assign(vec_flt_t *p, unsigned i, float value)
+{
+ assert((i >= 0) && (i < vec_flt_size(p)));
+ p->data[i] = value;
+}
+
+static inline void vec_flt_insert(vec_flt_t *p, unsigned i, float value)
+{
+ assert((i >= 0) && (i < vec_flt_size(p)));
+ vec_flt_push_back(p, 0);
+ memmove(p->data + i + 1, p->data + i, (p->size - i - 2) * sizeof(float));
+ p->data[i] = value;
+}
+
+static inline void vec_flt_drop(vec_flt_t *p, unsigned i)
+{
+ assert((i >= 0) && (i < vec_flt_size(p)));
+ memmove(p->data + i, p->data + i + 1, (p->size - i - 1) * sizeof(float));
+ p->size -= 1;
+}
+
+static inline void vec_flt_clear(vec_flt_t *p)
+{
+ p->size = 0;
+}
+
+static inline int vec_flt_asc_compare(const void *p1, const void *p2)
+{
+ const float *pp1 = (const float *) p1;
+ const float *pp2 = (const float *) p2;
+
+ if (*pp1 < *pp2)
+ return -1;
+ if (*pp1 > *pp2)
+ return 1;
+ return 0;
+}
+
+static inline int vec_flt_desc_compare(const void* p1, const void* p2)
+{
+ const float *pp1 = (const float *) p1;
+ const float *pp2 = (const float *) p2;
+
+ if (*pp1 > *pp2)
+ return -1;
+ if (*pp1 < *pp2)
+ return 1;
+ return 0;
+}
+
+static inline void vec_flt_sort(vec_flt_t* p, int ascending)
+{
+ if (ascending)
+ qsort((void *) p->data, p->size, sizeof(float),
+ (int (*)(const void*, const void*)) vec_flt_asc_compare);
+ else
+ qsort((void *) p->data, p->size, sizeof(float),
+ (int (*)(const void*, const void*)) vec_flt_desc_compare);
+}
+
+static inline long vec_flt_memory(vec_flt_t *p)
+{
+ return p == NULL ? 0 : sizeof(float) * p->cap + sizeof(vec_flt_t);
+}
+
+static inline void vec_flt_print(vec_flt_t *p)
+{
+ unsigned i;
+ assert(p != NULL);
+ fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap);
+ for (i = 0; i < p->size; i++)
+ fprintf(stdout, " %f", p->data[i]);
+ fprintf(stdout, " }\n");
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__utils__vec__vec_flt_h */
diff --git a/src/sat/satoko/utils/vec/vec_int.h b/src/sat/satoko/utils/vec/vec_int.h
new file mode 100755
index 00000000..75c5d134
--- /dev/null
+++ b/src/sat/satoko/utils/vec/vec_int.h
@@ -0,0 +1,240 @@
+//===--- vec_int.h ----------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__utils__vec__vec_int_h
+#define satoko__utils__vec__vec_int_h
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "../mem.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+typedef struct vec_int_t_ vec_int_t;
+struct vec_int_t_ {
+ unsigned cap;
+ unsigned size;
+ int *data;
+};
+
+//===------------------------------------------------------------------------===
+// Vector Macros
+//===------------------------------------------------------------------------===
+#define vec_int_foreach(vec, entry, i) \
+ for (i = 0; (i < vec->size) && (((entry) = vec_int_at(vec, i)), 1); i++)
+
+#define vec_int_foreach_start(vec, entry, i, start) \
+ for (i = start; (i < vec_int_size(vec)) && (((entry) = vec_int_at(vec, i)), 1); i++)
+
+#define vec_int_foreach_stop(vec, entry, i, stop) \
+ for (i = 0; (i < stop) && (((entry) = vec_int_at(vec, i)), 1); i++)
+
+//===------------------------------------------------------------------------===
+// Vector API
+//===------------------------------------------------------------------------===
+static inline vec_int_t *vec_int_alloc(unsigned cap)
+{
+ vec_int_t* p = satoko_alloc(vec_int_t, 1);
+
+ if (cap > 0 && cap < 16)
+ cap = 16;
+ p->size = 0;
+ p->cap = cap;
+ p->data = p->cap ? satoko_alloc(int, p->cap) : NULL;
+ return p;
+}
+
+static inline vec_int_t *vec_int_alloc_exact(unsigned cap)
+{
+ vec_int_t* p = satoko_alloc(vec_int_t, 1);
+
+ p->size = 0;
+ p->cap = cap;
+ p->data = p->cap ? satoko_alloc(int, p->cap) : NULL;
+ return p;
+}
+
+static inline vec_int_t *vec_int_init(unsigned size, int value)
+{
+ vec_int_t* p = satoko_alloc(vec_int_t, 1);
+
+ p->cap = size;
+ p->size = size;
+ p->data = p->cap ? satoko_alloc(int, p->cap) : NULL;
+ memset(p->data, value, sizeof(int) * p->size);
+ return p;
+}
+
+static inline void vec_int_free(vec_int_t *p)
+{
+ if (p->data != NULL)
+ satoko_free(p->data);
+ satoko_free(p);
+}
+
+static inline unsigned vec_int_size(vec_int_t *p)
+{
+ return p->size;
+}
+
+static inline void vec_int_resize(vec_int_t *p, unsigned new_size)
+{
+ p->size = new_size;
+ if (p->cap >= new_size)
+ return;
+ p->data = satoko_realloc(int, p->data, new_size);
+ assert(p->data != NULL);
+ p->cap = new_size;
+}
+
+static inline void vec_int_reserve(vec_int_t *p, unsigned new_cap)
+{
+ if (p->cap >= new_cap)
+ return;
+ p->data = satoko_realloc(int, p->data, new_cap);
+ assert(p->data != NULL);
+ p->cap = new_cap;
+}
+
+static inline unsigned vec_int_capacity(vec_int_t *p)
+{
+ return p->cap;
+}
+
+static inline int vec_int_empty(vec_int_t *p)
+{
+ return p->size ? 0 : 1;
+}
+
+static inline void vec_int_erase(vec_int_t *p)
+{
+ satoko_free(p->data);
+ p->size = 0;
+ p->cap = 0;
+}
+
+static inline int vec_int_at(vec_int_t *p, unsigned i)
+{
+ assert(i >= 0 && i < p->size);
+ return p->data[i];
+}
+
+static inline int *vec_int_at_ptr(vec_int_t *p, unsigned i)
+{
+ assert(i >= 0 && i < p->size);
+ return p->data + i;
+}
+
+static inline void vec_int_duplicate(vec_int_t *dest, const vec_int_t *src)
+{
+ assert(dest != NULL && src != NULL);
+ vec_int_resize(dest, src->cap);
+ memcpy(dest->data, src->data, sizeof(int) * src->cap);
+ dest->size = src->size;
+}
+
+static inline void vec_int_copy(vec_int_t *dest, const vec_int_t *src)
+{
+ assert(dest != NULL && src != NULL);
+ vec_int_resize(dest, src->size);
+ memcpy(dest->data, src->data, sizeof(int) * src->size);
+ dest->size = src->size;
+}
+
+static inline void vec_int_push_back(vec_int_t *p, int value)
+{
+ if (p->size == p->cap) {
+ if (p->cap < 16)
+ vec_int_reserve(p, 16);
+ else
+ vec_int_reserve(p, 2 * p->cap);
+ }
+ p->data[p->size] = value;
+ p->size++;
+}
+
+static inline void vec_int_assign(vec_int_t *p, unsigned i, int value)
+{
+ assert((i >= 0) && (i < vec_int_size(p)));
+ p->data[i] = value;
+}
+
+static inline void vec_int_insert(vec_int_t *p, unsigned i, int value)
+{
+ assert((i >= 0) && (i < vec_int_size(p)));
+ vec_int_push_back(p, 0);
+ memmove(p->data + i + 1, p->data + i, (p->size - i - 2) * sizeof(int));
+ p->data[i] = value;
+}
+
+static inline void vec_int_drop(vec_int_t *p, unsigned i)
+{
+ assert((i >= 0) && (i < vec_int_size(p)));
+ memmove(p->data + i, p->data + i + 1, (p->size - i - 1) * sizeof(int));
+ p->size -= 1;
+}
+
+static inline void vec_int_clear(vec_int_t *p)
+{
+ p->size = 0;
+}
+
+static inline int vec_int_asc_compare(const void *p1, const void *p2)
+{
+ const int *pp1 = (const int *) p1;
+ const int *pp2 = (const int *) p2;
+
+ if (*pp1 < *pp2)
+ return -1;
+ if (*pp1 > *pp2)
+ return 1;
+ return 0;
+}
+
+static inline int vec_int_desc_compare(const void* p1, const void* p2)
+{
+ const int *pp1 = (const int *) p1;
+ const int *pp2 = (const int *) p2;
+
+ if (*pp1 > *pp2)
+ return -1;
+ if (*pp1 < *pp2)
+ return 1;
+ return 0;
+}
+
+static inline void vec_int_sort(vec_int_t* p, int ascending)
+{
+ if (ascending)
+ qsort((void *) p->data, p->size, sizeof(int),
+ (int (*)(const void*, const void*)) vec_int_asc_compare);
+ else
+ qsort((void *) p->data, p->size, sizeof(int),
+ (int (*)(const void*, const void*)) vec_int_desc_compare);
+}
+
+static inline long vec_int_memory(vec_int_t *p)
+{
+ return p == NULL ? 0 : sizeof(int) * p->cap + sizeof(vec_int_t);
+}
+
+static inline void vec_int_print(vec_int_t *p)
+{
+ unsigned i;
+ assert(p != NULL);
+ fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap);
+ for (i = 0; i < p->size; i++)
+ fprintf(stdout, " %d", p->data[i]);
+ fprintf(stdout, " }\n");
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__utils__vec__vec_int_h */
diff --git a/src/sat/satoko/utils/vec/vec_sdbl.h b/src/sat/satoko/utils/vec/vec_sdbl.h
new file mode 100755
index 00000000..ec1c731c
--- /dev/null
+++ b/src/sat/satoko/utils/vec/vec_sdbl.h
@@ -0,0 +1,253 @@
+//===--- vec_int.h ----------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__utils__vec__vec_sdbl_h
+#define satoko__utils__vec__vec_sdbl_h
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "../mem.h"
+#include "../sdbl.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+typedef struct vec_sdbl_t_ vec_sdbl_t;
+struct vec_sdbl_t_ {
+ unsigned cap;
+ unsigned size;
+ sdbl_t *data;
+};
+
+//===------------------------------------------------------------------------===
+// Vector Macros
+//===------------------------------------------------------------------------===
+#define vec_sdbl_foreach(vec, entry, i) \
+ for (i = 0; (i < vec->size) && (((entry) = vec_sdbl_at(vec, i)), 1); i++)
+
+#define vec_sdbl_foreach_start(vec, entry, i, start) \
+ for (i = start; (i < vec_sdbl_size(vec)) && (((entry) = vec_sdbl_at(vec, i)), 1); i++)
+
+#define vec_sdbl_foreach_stop(vec, entry, i, stop) \
+ for (i = 0; (i < stop) && (((entry) = vec_sdbl_at(vec, i)), 1); i++)
+
+//===------------------------------------------------------------------------===
+// Vector API
+//===------------------------------------------------------------------------===
+static inline vec_sdbl_t *vec_sdbl_alloc(unsigned cap)
+{
+ vec_sdbl_t* p = satoko_alloc(vec_sdbl_t, 1);
+
+ if (cap > 0 && cap < 16)
+ cap = 16;
+ p->size = 0;
+ p->cap = cap;
+ p->data = p->cap ? satoko_alloc(sdbl_t, p->cap) : NULL;
+ return p;
+}
+
+static inline vec_sdbl_t *vec_sdbl_alloc_exact(unsigned cap)
+{
+ vec_sdbl_t* p = satoko_alloc(vec_sdbl_t, 1);
+
+ p->size = 0;
+ p->cap = cap;
+ p->data = p->cap ? satoko_alloc(sdbl_t, p->cap) : NULL;
+ return p;
+}
+
+static inline vec_sdbl_t *vec_sdbl_init(unsigned size, sdbl_t value)
+{
+ vec_sdbl_t* p = satoko_alloc(vec_sdbl_t, 1);
+
+ p->cap = size;
+ p->size = size;
+ p->data = p->cap ? satoko_alloc(sdbl_t, p->cap) : NULL;
+ memset(p->data, value, sizeof(sdbl_t) * p->size);
+ return p;
+}
+
+static inline void vec_sdbl_free(vec_sdbl_t *p)
+{
+ if (p->data != NULL)
+ satoko_free(p->data);
+ satoko_free(p);
+}
+
+static inline unsigned vec_sdbl_size(vec_sdbl_t *p)
+{
+ return p->size;
+}
+
+static inline void vec_sdbl_shrink(vec_sdbl_t *p, unsigned new_size)
+{
+ assert(new_size <= p->cap);
+ p->size = new_size;
+}
+
+static inline void vec_sdbl_resize(vec_sdbl_t *p, unsigned new_size)
+{
+ p->size = new_size;
+ if (p->cap >= new_size)
+ return;
+ p->data = satoko_realloc(sdbl_t, p->data, new_size);
+ assert(p->data != NULL);
+ p->cap = new_size;
+}
+
+static inline void vec_sdbl_reserve(vec_sdbl_t *p, unsigned new_cap)
+{
+ if (p->cap >= new_cap)
+ return;
+ p->data = satoko_realloc(sdbl_t, p->data, new_cap);
+ assert(p->data != NULL);
+ p->cap = new_cap;
+}
+
+static inline unsigned vec_sdbl_capacity(vec_sdbl_t *p)
+{
+ return p->cap;
+}
+
+static inline int vec_sdbl_empty(vec_sdbl_t *p)
+{
+ return p->size ? 0 : 1;
+}
+
+static inline void vec_sdbl_erase(vec_sdbl_t *p)
+{
+ satoko_free(p->data);
+ p->size = 0;
+ p->cap = 0;
+}
+
+static inline sdbl_t vec_sdbl_at(vec_sdbl_t *p, unsigned i)
+{
+ assert(i >= 0 && i < p->size);
+ return p->data[i];
+}
+
+static inline sdbl_t *vec_sdbl_at_ptr(vec_sdbl_t *p, unsigned i)
+{
+ assert(i >= 0 && i < p->size);
+ return p->data + i;
+}
+
+static inline sdbl_t *vec_sdbl_data(vec_sdbl_t *p)
+{
+ assert(p);
+ return p->data;
+}
+
+static inline void vec_sdbl_duplicate(vec_sdbl_t *dest, const vec_sdbl_t *src)
+{
+ assert(dest != NULL && src != NULL);
+ vec_sdbl_resize(dest, src->cap);
+ memcpy(dest->data, src->data, sizeof(sdbl_t) * src->cap);
+ dest->size = src->size;
+}
+
+static inline void vec_sdbl_copy(vec_sdbl_t *dest, const vec_sdbl_t *src)
+{
+ assert(dest != NULL && src != NULL);
+ vec_sdbl_resize(dest, src->size);
+ memcpy(dest->data, src->data, sizeof(sdbl_t) * src->size);
+ dest->size = src->size;
+}
+
+static inline void vec_sdbl_push_back(vec_sdbl_t *p, sdbl_t value)
+{
+ if (p->size == p->cap) {
+ if (p->cap < 16)
+ vec_sdbl_reserve(p, 16);
+ else
+ vec_sdbl_reserve(p, 2 * p->cap);
+ }
+ p->data[p->size] = value;
+ p->size++;
+}
+
+static inline void vec_sdbl_assign(vec_sdbl_t *p, unsigned i, sdbl_t value)
+{
+ assert((i >= 0) && (i < vec_sdbl_size(p)));
+ p->data[i] = value;
+}
+
+static inline void vec_sdbl_insert(vec_sdbl_t *p, unsigned i, sdbl_t value)
+{
+ assert((i >= 0) && (i < vec_sdbl_size(p)));
+ vec_sdbl_push_back(p, 0);
+ memmove(p->data + i + 1, p->data + i, (p->size - i - 2) * sizeof(sdbl_t));
+ p->data[i] = value;
+}
+
+static inline void vec_sdbl_drop(vec_sdbl_t *p, unsigned i)
+{
+ assert((i >= 0) && (i < vec_sdbl_size(p)));
+ memmove(p->data + i, p->data + i + 1, (p->size - i - 1) * sizeof(sdbl_t));
+ p->size -= 1;
+}
+
+static inline void vec_sdbl_clear(vec_sdbl_t *p)
+{
+ p->size = 0;
+}
+
+static inline int vec_sdbl_asc_compare(const void *p1, const void *p2)
+{
+ const sdbl_t *pp1 = (const sdbl_t *) p1;
+ const sdbl_t *pp2 = (const sdbl_t *) p2;
+
+ if (*pp1 < *pp2)
+ return -1;
+ if (*pp1 > *pp2)
+ return 1;
+ return 0;
+}
+
+static inline int vec_sdbl_desc_compare(const void* p1, const void* p2)
+{
+ const sdbl_t *pp1 = (const sdbl_t *) p1;
+ const sdbl_t *pp2 = (const sdbl_t *) p2;
+
+ if (*pp1 > *pp2)
+ return -1;
+ if (*pp1 < *pp2)
+ return 1;
+ return 0;
+}
+
+static inline void vec_sdbl_sort(vec_sdbl_t* p, int ascending)
+{
+ if (ascending)
+ qsort((void *) p->data, p->size, sizeof(sdbl_t),
+ (int (*)(const void*, const void*)) vec_sdbl_asc_compare);
+ else
+ qsort((void *) p->data, p->size, sizeof(sdbl_t),
+ (int (*)(const void*, const void*)) vec_sdbl_desc_compare);
+}
+
+static inline long vec_sdbl_memory(vec_sdbl_t *p)
+{
+ return p == NULL ? 0 : sizeof(sdbl_t) * p->cap + sizeof(vec_sdbl_t);
+}
+
+static inline void vec_sdbl_print(vec_sdbl_t *p)
+{
+ unsigned i;
+ assert(p != NULL);
+ fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap);
+ for (i = 0; i < p->size; i++)
+ fprintf(stdout, " %f", sdbl2double(p->data[i]));
+ fprintf(stdout, " }\n");
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__utils__vec__vec_sdbl_h */
diff --git a/src/sat/satoko/utils/vec/vec_uint.h b/src/sat/satoko/utils/vec/vec_uint.h
new file mode 100755
index 00000000..e6719ca3
--- /dev/null
+++ b/src/sat/satoko/utils/vec/vec_uint.h
@@ -0,0 +1,268 @@
+//===--- vec_uint.h ---------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__utils__vec__vec_uint_h
+#define satoko__utils__vec__vec_uint_h
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "../mem.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+typedef struct vec_uint_t_ vec_uint_t;
+struct vec_uint_t_ {
+ unsigned cap;
+ unsigned size;
+ unsigned* data;
+};
+
+//===------------------------------------------------------------------------===
+// Vector Macros
+//===------------------------------------------------------------------------===
+#define vec_uint_foreach(vec, entry, i) \
+ for (i = 0; (i < vec_uint_size(vec)) && (((entry) = vec_uint_at(vec, i)), 1); i++)
+
+#define vec_uint_foreach_start(vec, entry, i, start) \
+ for (i = start; (i < vec_uint_size(vec)) && (((entry) = vec_uint_at(vec, i)), 1); i++)
+
+#define vec_uint_foreach_stop(vec, entry, i, stop) \
+ for (i = 0; (i < stop) && (((entry) = vec_uint_at(vec, i)), 1); i++)
+
+//===------------------------------------------------------------------------===
+// Vector API
+//===------------------------------------------------------------------------===
+static inline vec_uint_t * vec_uint_alloc(unsigned cap)
+{
+ vec_uint_t *p = satoko_alloc(vec_uint_t, 1);
+
+ if (cap > 0 && cap < 16)
+ cap = 16;
+ p->size = 0;
+ p->cap = cap;
+ p->data = p->cap ? satoko_alloc(unsigned, p->cap) : NULL;
+ return p;
+}
+
+static inline vec_uint_t * vec_uint_alloc_exact(unsigned cap)
+{
+ vec_uint_t *p = satoko_alloc(vec_uint_t, 1);
+
+ cap = 0;
+ p->size = 0;
+ p->cap = cap;
+ p->data = p->cap ? satoko_alloc(unsigned, p->cap ) : NULL;
+ return p;
+}
+
+static inline vec_uint_t * vec_uint_init(unsigned size, unsigned value)
+{
+ vec_uint_t *p = satoko_alloc(vec_uint_t, 1);
+
+ p->cap = size;
+ p->size = size;
+ p->data = p->cap ? satoko_alloc(unsigned, p->cap ) : NULL;
+ memset(p->data, value, sizeof(unsigned) * p->size);
+ return p;
+}
+
+static inline void vec_uint_free(vec_uint_t *p)
+{
+ if (p->data != NULL)
+ satoko_free(p->data);
+ satoko_free(p);
+}
+
+static inline unsigned vec_uint_size(vec_uint_t *p)
+{
+ return p->size;
+}
+
+static inline void vec_uint_resize(vec_uint_t *p, unsigned new_size)
+{
+ p->size = new_size;
+ if (p->cap >= new_size)
+ return;
+ p->data = satoko_realloc(unsigned, p->data, new_size);
+ assert(p->data != NULL);
+ p->cap = new_size;
+}
+
+static inline void vec_uint_shrink(vec_uint_t *p, unsigned new_size)
+{
+ assert(p->cap >= new_size);
+ p->size = new_size;
+}
+
+static inline void vec_uint_reserve(vec_uint_t *p, unsigned new_cap)
+{
+ if (p->cap >= new_cap)
+ return;
+ p->data = satoko_realloc(unsigned, p->data, new_cap);
+ assert(p->data != NULL);
+ p->cap = new_cap;
+}
+
+static inline unsigned vec_uint_capacity(vec_uint_t *p)
+{
+ return p->cap;
+}
+
+static inline int vec_uint_empty(vec_uint_t *p)
+{
+ return p->size ? 0 : 1;
+}
+
+static inline void vec_uint_erase(vec_uint_t *p)
+{
+ satoko_free(p->data);
+ p->size = 0;
+ p->cap = 0;
+}
+
+static inline unsigned vec_uint_at(vec_uint_t *p, unsigned idx)
+{
+ assert(idx >= 0 && idx < p->size);
+ return p->data[idx];
+}
+
+static inline unsigned * vec_uint_at_ptr(vec_uint_t *p, unsigned idx)
+{
+ assert(idx >= 0 && idx < p->size);
+ return p->data + idx;
+}
+
+static inline unsigned vec_uint_find(vec_uint_t *p, unsigned entry)
+{
+ unsigned i;
+ for (i = 0; i < p->size; i++)
+ if (p->data[i] == entry)
+ return 1;
+ return 0;
+}
+
+static inline unsigned * vec_uint_data(vec_uint_t *p)
+{
+ assert(p);
+ return p->data;
+}
+
+static inline void vec_uint_duplicate(vec_uint_t *dest, const vec_uint_t *src)
+{
+ assert(dest != NULL && src != NULL);
+ vec_uint_resize(dest, src->cap);
+ memcpy(dest->data, src->data, sizeof(unsigned) * src->cap);
+ dest->size = src->size;
+}
+
+static inline void vec_uint_copy(vec_uint_t *dest, const vec_uint_t *src)
+{
+ assert(dest != NULL && src != NULL);
+ vec_uint_resize(dest, src->size);
+ memcpy(dest->data, src->data, sizeof(unsigned) * src->size);
+ dest->size = src->size;
+}
+
+static inline void vec_uint_push_back(vec_uint_t *p, unsigned value)
+{
+ if (p->size == p->cap) {
+ if (p->cap < 16)
+ vec_uint_reserve(p, 16);
+ else
+ vec_uint_reserve(p, 2 * p->cap);
+ }
+ p->data[p->size] = value;
+ p->size++;
+}
+
+static inline unsigned vec_uint_pop_back(vec_uint_t *p)
+{
+ assert(p && p->size);
+ return p->data[--p->size];
+}
+
+static inline void vec_uint_assign(vec_uint_t *p, unsigned idx, unsigned value)
+{
+ assert((idx >= 0) && (idx < vec_uint_size(p)));
+ p->data[idx] = value;
+}
+
+static inline void vec_uint_insert(vec_uint_t *p, unsigned idx, unsigned value)
+{
+ assert((idx >= 0) && (idx < vec_uint_size(p)));
+ vec_uint_push_back(p, 0);
+ memmove(p->data + idx + 1, p->data + idx, (p->size - idx - 2) * sizeof(unsigned));
+ p->data[idx] = value;
+}
+
+static inline void vec_uint_drop(vec_uint_t *p, unsigned idx)
+{
+ assert((idx >= 0) && (idx < vec_uint_size(p)));
+ memmove(p->data + idx, p->data + idx + 1, (p->size - idx - 1) * sizeof(unsigned));
+ p->size -= 1;
+}
+
+static inline void vec_uint_clear(vec_uint_t *p)
+{
+ p->size = 0;
+}
+
+static inline int vec_uint_asc_compare(const void *p1, const void *p2)
+{
+ const unsigned *pp1 = (const unsigned *) p1;
+ const unsigned *pp2 = (const unsigned *) p2;
+
+ if ( *pp1 < *pp2 )
+ return -1;
+ if ( *pp1 > *pp2 )
+ return 1;
+ return 0;
+}
+
+static inline int vec_uint_desc_compare(const void *p1, const void *p2)
+{
+ const unsigned *pp1 = (const unsigned *) p1;
+ const unsigned *pp2 = (const unsigned *) p2;
+
+ if ( *pp1 > *pp2 )
+ return -1;
+ if ( *pp1 < *pp2 )
+ return 1;
+ return 0;
+}
+
+static inline void vec_uint_sort(vec_uint_t *p, int ascending)
+{
+ if (ascending)
+ qsort((void *) p->data, p->size, sizeof(unsigned),
+ (int (*)(const void *, const void *)) vec_uint_asc_compare);
+ else
+ qsort((void*) p->data, p->size, sizeof(unsigned),
+ (int (*)(const void *, const void *)) vec_uint_desc_compare);
+}
+
+static inline long vec_uint_memory(vec_uint_t *p)
+{
+ return p == NULL ? 0 : sizeof(unsigned) * p->cap + sizeof(vec_uint_t);
+}
+
+static inline void vec_uint_print(vec_uint_t* p)
+{
+ unsigned i;
+ assert(p != NULL);
+ fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap);
+ for (i = 0; i < p->size; i++)
+ fprintf(stdout, " %u", p->data[i]);
+ fprintf(stdout, " }\n");
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__utils__vec__vec_uint_h */
diff --git a/src/sat/satoko/watch_list.h b/src/sat/satoko/watch_list.h
new file mode 100644
index 00000000..1bcbf3b4
--- /dev/null
+++ b/src/sat/satoko/watch_list.h
@@ -0,0 +1,203 @@
+//===--- watch_list.h -------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__watch_list_h
+#define satoko__watch_list_h
+
+#include "utils/mem.h"
+#include "utils/misc.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+struct watcher {
+ unsigned cref;
+ unsigned blocker;
+};
+
+struct watch_list {
+ unsigned cap;
+ unsigned size;
+ unsigned n_bin;
+ struct watcher *watchers;
+};
+
+typedef struct vec_wl_t_ vec_wl_t;
+struct vec_wl_t_ {
+ unsigned cap;
+ unsigned size;
+ struct watch_list *watch_lists;
+};
+
+//===------------------------------------------------------------------------===
+// Watch list Macros
+//===------------------------------------------------------------------------===
+#define watch_list_foreach(vec, watch, lit) \
+ for (watch = watch_list_array(vec_wl_at(vec, lit)); \
+ watch < watch_list_array(vec_wl_at(vec, lit)) + watch_list_size(vec_wl_at(vec, lit)); \
+ watch++)
+
+#define watch_list_foreach_bin(vec, watch, lit) \
+ for (watch = watch_list_array(vec_wl_at(vec, lit)); \
+ watch < watch_list_array(vec_wl_at(vec, lit)) + vec_wl_at(vec, lit)->n_bin; \
+ watch++)
+//===------------------------------------------------------------------------===
+// Watch list API
+//===------------------------------------------------------------------------===
+static inline void watch_list_free(struct watch_list *wl)
+{
+ if (wl->watchers)
+ satoko_free(wl->watchers);
+}
+
+static inline unsigned watch_list_size(struct watch_list *wl)
+{
+ return wl->size;
+}
+
+static inline void watch_list_shrink(struct watch_list *wl, unsigned size)
+{
+ assert(size <= wl->size);
+ wl->size = size;
+}
+
+static inline void watch_list_grow(struct watch_list *wl)
+{
+ unsigned new_size = (wl->cap < 4) ? 4 : (wl->cap / 2) * 3;
+ struct watcher *watchers =
+ satoko_realloc(struct watcher, wl->watchers, new_size);
+ if (watchers == NULL) {
+ printf("Failed to realloc memory from %.1f MB to %.1f "
+ "MB.\n",
+ 1.0 * wl->cap / (1 << 20),
+ 1.0 * new_size / (1 << 20));
+ fflush(stdout);
+ return;
+ }
+ wl->watchers = watchers;
+ wl->cap = new_size;
+}
+
+static inline void watch_list_push(struct watch_list *wl, struct watcher w, unsigned is_bin)
+{
+ assert(wl);
+ if (wl->size == wl->cap)
+ watch_list_grow(wl);
+ wl->watchers[wl->size++] = w;
+ if (is_bin && wl->size > wl->n_bin) {
+ stk_swap(struct watcher, wl->watchers[wl->n_bin], wl->watchers[wl->size - 1]);
+ wl->n_bin++;
+ }
+}
+
+static inline struct watcher *watch_list_array(struct watch_list *wl)
+{
+ return wl->watchers;
+}
+
+/* TODO: I still have mixed feelings if this change should be done, keeping the
+ * old code commented after it. */
+static inline void watch_list_remove(struct watch_list *wl, unsigned cref, unsigned is_bin)
+{
+ struct watcher *watchers = watch_list_array(wl);
+ unsigned i;
+ if (is_bin) {
+ for (i = 0; watchers[i].cref != cref; i++);
+ assert(i < watch_list_size(wl));
+ wl->n_bin--;
+ memmove((wl->watchers + i), (wl->watchers + i + 1),
+ (wl->size - i - 1) * sizeof(struct watcher));
+ } else {
+ for (i = wl->n_bin; watchers[i].cref != cref; i++);
+ assert(i < watch_list_size(wl));
+ stk_swap(struct watcher, wl->watchers[i], wl->watchers[wl->size - 1]);
+ }
+ wl->size -= 1;
+}
+
+/*
+static inline void watch_list_remove(struct watch_list *wl, unsigned cref, unsigned is_bin)
+{
+ struct watcher *watchers = watch_list_array(wl);
+ unsigned i;
+ if (is_bin) {
+ for (i = 0; watchers[i].cref != cref; i++);
+ wl->n_bin--;
+ } else
+ for (i = wl->n_bin; watchers[i].cref != cref; i++);
+ assert(i < watch_list_size(wl));
+ memmove((wl->watchers + i), (wl->watchers + i + 1),
+ (wl->size - i - 1) * sizeof(struct watcher));
+ wl->size -= 1;
+}
+*/
+
+static inline vec_wl_t *vec_wl_alloc(unsigned cap)
+{
+ vec_wl_t *vec_wl = satoko_alloc(vec_wl_t, 1);
+
+ if (cap == 0)
+ vec_wl->cap = 4;
+ else
+ vec_wl->cap = cap;
+ vec_wl->size = 0;
+ vec_wl->watch_lists = satoko_calloc(
+ struct watch_list, sizeof(struct watch_list) * vec_wl->cap);
+ return vec_wl;
+}
+
+static inline void vec_wl_free(vec_wl_t *vec_wl)
+{
+ unsigned i;
+ for (i = 0; i < vec_wl->cap; i++)
+ watch_list_free(vec_wl->watch_lists + i);
+ satoko_free(vec_wl->watch_lists);
+ satoko_free(vec_wl);
+}
+
+static inline void vec_wl_clean(vec_wl_t *vec_wl)
+{
+ unsigned i;
+ for (i = 0; i < vec_wl->size; i++) {
+ vec_wl->watch_lists[i].size = 0;
+ vec_wl->watch_lists[i].n_bin = 0;
+ }
+ vec_wl->size = 0;
+}
+
+static inline void vec_wl_push(vec_wl_t *vec_wl)
+{
+ if (vec_wl->size == vec_wl->cap) {
+ unsigned new_size =
+ (vec_wl->cap < 4) ? vec_wl->cap * 2 : (vec_wl->cap / 2) * 3;
+
+ vec_wl->watch_lists = satoko_realloc(
+ struct watch_list, vec_wl->watch_lists, new_size);
+ memset(vec_wl->watch_lists + vec_wl->cap, 0,
+ sizeof(struct watch_list) * (new_size - vec_wl->cap));
+ if (vec_wl->watch_lists == NULL) {
+ printf("failed to realloc memory from %.1f mb to %.1f "
+ "mb.\n",
+ 1.0 * vec_wl->cap / (1 << 20),
+ 1.0 * new_size / (1 << 20));
+ fflush(stdout);
+ }
+ vec_wl->cap = new_size;
+ }
+ vec_wl->size++;
+}
+
+static inline struct watch_list *vec_wl_at(vec_wl_t *vec_wl, unsigned idx)
+{
+ assert(idx < vec_wl->cap);
+ assert(idx < vec_wl->size);
+ return vec_wl->watch_lists + idx;
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__watch_list_h */
diff --git a/src/sat/xsat/license b/src/sat/xsat/license
new file mode 100644
index 00000000..a6389ab1
--- /dev/null
+++ b/src/sat/xsat/license
@@ -0,0 +1,39 @@
+xSAT - Copyright (c) 2016, Bruno Schmitt - UC Berkeley / UFRGS (boschmitt@inf.ufrgs.br)
+
+xSAT is based on Glucose v3(see Glucose copyrights below) and ABC C version of
+MiniSat (bsat) developed by Niklas Sorensson and modified by Alan Mishchenko.
+Permissions and copyrights of xSAT are exactly the same as Glucose v3/Minisat.
+(see below).
+
+---------------
+
+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.
+*******************************************************************************/
diff --git a/src/sat/xsat/module.make b/src/sat/xsat/module.make
new file mode 100644
index 00000000..1d7352e2
--- /dev/null
+++ b/src/sat/xsat/module.make
@@ -0,0 +1,3 @@
+SRC += src/sat/xsat/xsatSolver.c \
+ src/sat/xsat/xsatSolverAPI.c \
+ src/sat/xsat/xsatCnfReader.c
diff --git a/src/sat/xsat/xsat.h b/src/sat/xsat/xsat.h
new file mode 100644
index 00000000..b2962d91
--- /dev/null
+++ b/src/sat/xsat/xsat.h
@@ -0,0 +1,59 @@
+/**CFile****************************************************************
+
+ FileName [xsat.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [xSAT - A SAT solver written in C.
+ Read the license file for more info.]
+
+ Synopsis [External definitions of the solver.]
+
+ Author [Bruno Schmitt <boschmitt@inf.ufrgs.br>]
+
+ Affiliation [UC Berkeley / UFRGS]
+
+ Date [Ver. 1.0. Started - November 10, 2016.]
+
+ Revision []
+
+***********************************************************************/
+#ifndef ABC__sat__xSAT__xSAT_h
+#define ABC__sat__xSAT__xSAT_h
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+#include "misc/util/abc_global.h"
+#include "misc/vec/vecInt.h"
+
+ABC_NAMESPACE_HEADER_START
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+struct xSAT_Solver_t_;
+typedef struct xSAT_Solver_t_ xSAT_Solver_t;
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+/*=== xsatCnfReader.c ================================================*/
+extern int xSAT_SolverParseDimacs( FILE *, xSAT_Solver_t ** );
+
+/*=== xsatSolverAPI.c ================================================*/
+extern xSAT_Solver_t * xSAT_SolverCreate();
+extern void xSAT_SolverDestroy( xSAT_Solver_t * );
+
+extern int xSAT_SolverAddClause( xSAT_Solver_t *, Vec_Int_t * );
+extern int xSAT_SolverSimplify( xSAT_Solver_t * );
+extern int xSAT_SolverSolve( xSAT_Solver_t * );
+
+extern void xSAT_SolverPrintStats( xSAT_Solver_t * );
+
+ABC_NAMESPACE_HEADER_END
+
+#endif
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
diff --git a/src/sat/xsat/xsatBQueue.h b/src/sat/xsat/xsatBQueue.h
new file mode 100644
index 00000000..f75f3650
--- /dev/null
+++ b/src/sat/xsat/xsatBQueue.h
@@ -0,0 +1,190 @@
+/**CFile****************************************************************
+
+ FileName [xsatBQueue.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [xSAT - A SAT solver written in C.
+ Read the license file for more info.]
+
+ Synopsis [Bounded queue implementation.]
+
+ Author [Bruno Schmitt <boschmitt@inf.ufrgs.br>]
+
+ Affiliation [UC Berkeley / UFRGS]
+
+ Date [Ver. 1.0. Started - November 10, 2016.]
+
+ Revision []
+
+***********************************************************************/
+#ifndef ABC__sat__xSAT__xsatBQueue_h
+#define ABC__sat__xSAT__xsatBQueue_h
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+#include "misc/util/abc_global.h"
+
+ABC_NAMESPACE_HEADER_START
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+typedef struct xSAT_BQueue_t_ xSAT_BQueue_t;
+struct xSAT_BQueue_t_
+{
+ int nSize;
+ int nCap;
+ int iFirst;
+ int iEmpty;
+ word nSum;
+ unsigned * pData;
+};
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline xSAT_BQueue_t * xSAT_BQueueNew( int nCap )
+{
+ xSAT_BQueue_t * p = ABC_CALLOC( xSAT_BQueue_t, 1 );
+ p->nCap = nCap;
+ p->pData = ABC_CALLOC( unsigned, nCap );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_BQueueFree( xSAT_BQueue_t * p )
+{
+ ABC_FREE( p->pData );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_BQueuePush( xSAT_BQueue_t * p, unsigned Value )
+{
+ if ( p->nSize == p->nCap )
+ {
+ assert(p->iFirst == p->iEmpty);
+ p->nSum -= p->pData[p->iFirst];
+ p->iFirst = ( p->iFirst + 1 ) % p->nCap;
+ }
+ else
+ p->nSize++;
+
+ p->nSum += Value;
+ p->pData[p->iEmpty] = Value;
+ if ( ( ++p->iEmpty ) == p->nCap )
+ {
+ p->iEmpty = 0;
+ p->iFirst = 0;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int xSAT_BQueuePop( xSAT_BQueue_t * p )
+{
+ int RetValue;
+ assert( p->nSize >= 1 );
+ RetValue = p->pData[p->iFirst];
+ p->nSum -= RetValue;
+ p->iFirst = ( p->iFirst + 1 ) % p->nCap;
+ p->nSize--;
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline unsigned xSAT_BQueueAvg( xSAT_BQueue_t * p )
+{
+ return ( unsigned )( p->nSum / ( ( word ) p->nSize ) );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int xSAT_BQueueIsValid( xSAT_BQueue_t * p )
+{
+ return ( p->nCap == p->nSize );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_BQueueClean( xSAT_BQueue_t * p )
+{
+ p->iFirst = 0;
+ p->iEmpty = 0;
+ p->nSize = 0;
+ p->nSum = 0;
+}
+
+ABC_NAMESPACE_HEADER_END
+
+#endif
diff --git a/src/sat/xsat/xsatClause.h b/src/sat/xsat/xsatClause.h
new file mode 100644
index 00000000..ef353198
--- /dev/null
+++ b/src/sat/xsat/xsatClause.h
@@ -0,0 +1,109 @@
+/**CFile****************************************************************
+
+ FileName [xsatClause.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [xSAT - A SAT solver written in C.
+ Read the license file for more info.]
+
+ Synopsis [Clause data type definition.]
+
+ Author [Bruno Schmitt <boschmitt@inf.ufrgs.br>]
+
+ Affiliation [UC Berkeley / UFRGS]
+
+ Date [Ver. 1.0. Started - November 10, 2016.]
+
+ Revision []
+
+***********************************************************************/
+#ifndef ABC__sat__xSAT__xsatClause_h
+#define ABC__sat__xSAT__xsatClause_h
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+#include "misc/util/abc_global.h"
+
+ABC_NAMESPACE_HEADER_START
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+typedef struct xSAT_Clause_t_ xSAT_Clause_t;
+struct xSAT_Clause_t_
+{
+ unsigned fLearnt : 1;
+ unsigned fMark : 1;
+ unsigned fReallocd : 1;
+ unsigned fCanBeDel : 1;
+ unsigned nLBD : 28;
+ int nSize;
+ union {
+ int Lit;
+ unsigned Act;
+ } pData[0];
+};
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int xSAT_ClauseCompare( const void * p1, const void * p2 )
+{
+ xSAT_Clause_t * pC1 = ( xSAT_Clause_t * ) p1;
+ xSAT_Clause_t * pC2 = ( xSAT_Clause_t * ) p2;
+
+ if ( pC1->nSize > 2 && pC2->nSize == 2 )
+ return 1;
+ if ( pC1->nSize == 2 && pC2->nSize > 2 )
+ return 0;
+ if ( pC1->nSize == 2 && pC2->nSize == 2 )
+ return 0;
+
+ if ( pC1->nLBD > pC2->nLBD )
+ return 1;
+ if ( pC1->nLBD < pC2->nLBD )
+ return 0;
+
+ return pC1->pData[pC1->nSize].Act < pC2->pData[pC2->nSize].Act;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_ClausePrint( xSAT_Clause_t * pCla )
+{
+ int i;
+
+ printf("{ ");
+ for ( i = 0; i < pCla->nSize; i++ )
+ printf("%d ", pCla->pData[i].Lit );
+ printf("}\n");
+}
+
+ABC_NAMESPACE_HEADER_END
+
+#endif
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
diff --git a/src/sat/xsat/xsatCnfReader.c b/src/sat/xsat/xsatCnfReader.c
new file mode 100644
index 00000000..d23e8a0a
--- /dev/null
+++ b/src/sat/xsat/xsatCnfReader.c
@@ -0,0 +1,236 @@
+/**CFile****************************************************************
+
+ FileName [xsatCnfReader.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [xSAT - A SAT solver written in C.
+ Read the license file for more info.]
+
+ Synopsis [CNF DIMACS file format parser.]
+
+ Author [Bruno Schmitt <boschmitt@inf.ufrgs.br>]
+
+ Affiliation [UC Berkeley / UFRGS]
+
+ Date [Ver. 1.0. Started - November 10, 2016.]
+
+ Revision []
+
+***********************************************************************/
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+#include <ctype.h>
+
+#include "misc/util/abc_global.h"
+#include "misc/vec/vecInt.h"
+
+#include "xsatSolver.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Read the file into the internal buffer.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * xSAT_FileRead( FILE * pFile )
+{
+ int nFileSize;
+ char * pBuffer;
+ int RetValue;
+ // get the file size, in bytes
+ fseek( pFile, 0, SEEK_END );
+ nFileSize = ftell( pFile );
+ // move the file current reading position to the beginning
+ rewind( pFile );
+ // load the contents of the file into memory
+ pBuffer = ABC_ALLOC( char, nFileSize + 3 );
+ RetValue = fread( pBuffer, nFileSize, 1, pFile );
+ // terminate the string with '\0'
+ pBuffer[ nFileSize + 0] = '\n';
+ pBuffer[ nFileSize + 1] = '\0';
+ return pBuffer;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void skipLine( char ** pIn )
+{
+ while ( 1 )
+ {
+ if (**pIn == 0)
+ return;
+ if (**pIn == '\n')
+ {
+ (*pIn)++;
+ return;
+ }
+ (*pIn)++;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int xSAT_ReadInt( char ** pIn )
+{
+ int val = 0;
+ int neg = 0;
+
+ for(; isspace(**pIn); (*pIn)++);
+ if ( **pIn == '-' )
+ neg = 1,
+ (*pIn)++;
+ else if ( **pIn == '+' )
+ (*pIn)++;
+ if ( !isdigit(**pIn) )
+ fprintf(stderr, "PARSE ERROR! Unexpected char: %c\n", **pIn),
+ exit(1);
+ while ( isdigit(**pIn) )
+ val = val*10 + (**pIn - '0'),
+ (*pIn)++;
+ return neg ? -val : val;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void xSAT_ReadClause( char ** pIn, xSAT_Solver_t * p, Vec_Int_t * vLits )
+{
+ int token, var, sign;
+
+ Vec_IntClear( vLits );
+ while ( 1 )
+ {
+ token = xSAT_ReadInt( pIn );
+ if ( token == 0 )
+ break;
+ var = abs(token) - 1;
+ sign = (token > 0);
+ Vec_IntPush( vLits, xSAT_Var2Lit( var, !sign ) );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int xSAT_ParseDimacs( char * pText, xSAT_Solver_t ** pS )
+{
+ xSAT_Solver_t * p = NULL;
+ Vec_Int_t * vLits = NULL;
+ char * pIn = pText;
+ int nVars, nClas;
+ while ( 1 )
+ {
+ for(; isspace(*pIn); pIn++);
+ if ( *pIn == 0 )
+ break;
+ else if ( *pIn == 'c' )
+ skipLine( &pIn );
+ else if ( *pIn == 'p' )
+ {
+ pIn++;
+ for(; isspace(*pIn); pIn++);
+ for(; !isspace(*pIn); pIn++);
+
+ nVars = xSAT_ReadInt( &pIn );
+ nClas = xSAT_ReadInt( &pIn );
+ skipLine( &pIn );
+
+ /* start the solver */
+ p = xSAT_SolverCreate();
+ /* allocate the vector */
+ vLits = Vec_IntAlloc( nVars );
+ }
+ else
+ {
+ if ( p == NULL )
+ {
+ printf( "There is no parameter line.\n" );
+ exit(1);
+ }
+ xSAT_ReadClause( &pIn, p, vLits );
+ if ( !xSAT_SolverAddClause( p, vLits ) )
+ {
+ Vec_IntPrint(vLits);
+ return 0;
+ }
+ }
+ }
+ Vec_IntFree( vLits );
+ *pS = p;
+ return xSAT_SolverSimplify( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Starts the solver and reads the DIMAC file.]
+
+ Description [Returns FALSE upon immediate conflict.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int xSAT_SolverParseDimacs( FILE * pFile, xSAT_Solver_t ** p )
+{
+ char * pText;
+ int Value;
+ pText = xSAT_FileRead( pFile );
+ Value = xSAT_ParseDimacs( pText, p );
+ ABC_FREE( pText );
+ return Value;
+}
+
+ABC_NAMESPACE_IMPL_END
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
diff --git a/src/sat/xsat/xsatHeap.h b/src/sat/xsat/xsatHeap.h
new file mode 100644
index 00000000..409ce460
--- /dev/null
+++ b/src/sat/xsat/xsatHeap.h
@@ -0,0 +1,330 @@
+/**CFile****************************************************************
+
+ FileName [xsatHeap.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [xSAT - A SAT solver written in C.
+ Read the license file for more info.]
+
+ Synopsis [Heap implementation.]
+
+ Author [Bruno Schmitt <boschmitt@inf.ufrgs.br>]
+
+ Affiliation [UC Berkeley / UFRGS]
+
+ Date [Ver. 1.0. Started - November 10, 2016.]
+
+ Revision []
+
+***********************************************************************/
+#ifndef ABC__sat__xSAT__xsatHeap_h
+#define ABC__sat__xSAT__xsatHeap_h
+
+#include "misc/util/abc_global.h"
+#include "misc/vec/vecInt.h"
+
+ABC_NAMESPACE_HEADER_START
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+typedef struct xSAT_Heap_t_ xSAT_Heap_t;
+struct xSAT_Heap_t_
+{
+ Vec_Int_t * vActivity;
+ Vec_Int_t * vIndices;
+ Vec_Int_t * vHeap;
+};
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int xSAT_HeapSize( xSAT_Heap_t * h )
+{
+ return Vec_IntSize( h->vHeap );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int xSAT_HeapInHeap( xSAT_Heap_t * h, int Var )
+{
+ return ( Var < Vec_IntSize( h->vIndices ) ) && ( Vec_IntEntry( h->vIndices, Var ) >= 0 );
+}
+
+static inline int Left ( int i ) { return 2 * i + 1; }
+static inline int Right ( int i ) { return ( i + 1 ) * 2; }
+static inline int Parent( int i ) { return ( i - 1 ) >> 1; }
+static inline int Compare( xSAT_Heap_t * p, int x, int y )
+{
+ return ( unsigned )Vec_IntEntry( p->vActivity, x ) > ( unsigned )Vec_IntEntry( p->vActivity, y );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_HeapPercolateUp( xSAT_Heap_t * h, int i )
+{
+ int x = Vec_IntEntry( h->vHeap, i );
+ int p = Parent( i );
+
+ while ( i != 0 && Compare( h, x, Vec_IntEntry( h->vHeap, p ) ) )
+ {
+ Vec_IntWriteEntry( h->vHeap, i, Vec_IntEntry( h->vHeap, p ) );
+ Vec_IntWriteEntry( h->vIndices, Vec_IntEntry( h->vHeap, p ), i );
+ i = p;
+ p = Parent(p);
+ }
+ Vec_IntWriteEntry( h->vHeap, i, x );
+ Vec_IntWriteEntry( h->vIndices, x, i );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_HeapPercolateDown( xSAT_Heap_t * h, int i )
+{
+ int x = Vec_IntEntry( h->vHeap, i );
+
+ while ( Left( i ) < Vec_IntSize( h->vHeap ) )
+ {
+ int child = Right( i ) < Vec_IntSize( h->vHeap ) &&
+ Compare( h, Vec_IntEntry( h->vHeap, Right( i ) ), Vec_IntEntry( h->vHeap, Left( i ) ) ) ?
+ Right( i ) : Left( i );
+
+ if ( !Compare( h, Vec_IntEntry( h->vHeap, child ), x ) )
+ break;
+
+ Vec_IntWriteEntry( h->vHeap, i, Vec_IntEntry( h->vHeap, child ) );
+ Vec_IntWriteEntry( h->vIndices, Vec_IntEntry( h->vHeap, i ), i );
+ i = child;
+ }
+ Vec_IntWriteEntry( h->vHeap, i, x );
+ Vec_IntWriteEntry( h->vIndices, x, i );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline xSAT_Heap_t * xSAT_HeapAlloc( Vec_Int_t * vActivity )
+{
+ xSAT_Heap_t * p = ABC_ALLOC( xSAT_Heap_t, 1 );
+ p->vActivity = vActivity;
+ p->vIndices = Vec_IntAlloc( 0 );
+ p->vHeap = Vec_IntAlloc( 0 );
+
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_HeapFree( xSAT_Heap_t * p )
+{
+ Vec_IntFree( p->vIndices );
+ Vec_IntFree( p->vHeap );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_HeapIncrease( xSAT_Heap_t * h, int e )
+{
+ assert( xSAT_HeapInHeap( h, e ) );
+ xSAT_HeapPercolateDown( h, Vec_IntEntry( h->vIndices, e ) );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_HeapDecrease( xSAT_Heap_t * p, int e )
+{
+ assert( xSAT_HeapInHeap( p, e ) );
+ xSAT_HeapPercolateUp( p , Vec_IntEntry( p->vIndices, e ) );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_HeapInsert( xSAT_Heap_t * p, int n )
+{
+ Vec_IntFillExtra( p->vIndices, n + 1, -1);
+ assert( !xSAT_HeapInHeap( p, n ) );
+
+ Vec_IntWriteEntry( p->vIndices, n, Vec_IntSize( p->vHeap ) );
+ Vec_IntPush( p->vHeap, n );
+ xSAT_HeapPercolateUp( p, Vec_IntEntry( p->vIndices, n ) );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_HeapUpdate( xSAT_Heap_t * p, int i )
+{
+ if ( !xSAT_HeapInHeap( p, i ) )
+ xSAT_HeapInsert( p, i );
+ else
+ {
+ xSAT_HeapPercolateUp( p, Vec_IntEntry( p->vIndices, i ) );
+ xSAT_HeapPercolateDown( p, Vec_IntEntry( p->vIndices, i ) );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_HeapBuild( xSAT_Heap_t * p, Vec_Int_t * Vars )
+{
+ int i, Var;
+
+ Vec_IntForEachEntry( p->vHeap, Var, i )
+ Vec_IntWriteEntry( p->vIndices, Var, -1 );
+ Vec_IntClear( p->vHeap );
+
+ Vec_IntForEachEntry( Vars, Var, i )
+ {
+ Vec_IntWriteEntry( p->vIndices, Var, i );
+ Vec_IntPush( p->vHeap, Var );
+ }
+
+ for ( ( i = Vec_IntSize( p->vHeap ) / 2 - 1 ); i >= 0; i-- )
+ xSAT_HeapPercolateDown( p, i );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_HeapClear( xSAT_Heap_t * p )
+{
+ Vec_IntFill( p->vIndices, Vec_IntSize( p->vIndices ), -1 );
+ Vec_IntClear( p->vHeap );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int xSAT_HeapRemoveMin( xSAT_Heap_t * p )
+{
+ int x = Vec_IntEntry( p->vHeap, 0 );
+ Vec_IntWriteEntry( p->vHeap, 0, Vec_IntEntryLast( p->vHeap ) );
+ Vec_IntWriteEntry( p->vIndices, Vec_IntEntry( p->vHeap, 0), 0 );
+ Vec_IntWriteEntry( p->vIndices, x, -1 );
+ Vec_IntPop( p->vHeap );
+ if ( Vec_IntSize( p->vHeap ) > 1 )
+ xSAT_HeapPercolateDown( p, 0 );
+ return x;
+}
+
+ABC_NAMESPACE_HEADER_END
+
+#endif
diff --git a/src/sat/xsat/xsatMemory.h b/src/sat/xsat/xsatMemory.h
new file mode 100644
index 00000000..129c2f50
--- /dev/null
+++ b/src/sat/xsat/xsatMemory.h
@@ -0,0 +1,222 @@
+/**CFile****************************************************************
+
+ FileName [xsatMemory.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [xSAT - A SAT solver written in C.
+ Read the license file for more info.]
+
+ Synopsis [Memory management implementation.]
+
+ Author [Bruno Schmitt <boschmitt@inf.ufrgs.br>]
+
+ Affiliation [UC Berkeley / UFRGS]
+
+ Date [Ver. 1.0. Started - November 10, 2016.]
+
+ Revision []
+
+***********************************************************************/
+#ifndef ABC__sat__xSAT__xsatMemory_h
+#define ABC__sat__xSAT__xsatMemory_h
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+#include "misc/util/abc_global.h"
+
+#include "xsatClause.h"
+
+ABC_NAMESPACE_HEADER_START
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+typedef struct xSAT_Mem_t_ xSAT_Mem_t;
+struct xSAT_Mem_t_
+{
+ unsigned nSize;
+ unsigned nCap;
+ unsigned nWasted;
+ unsigned * pData;
+};
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline xSAT_Clause_t * xSAT_MemClauseHand( xSAT_Mem_t * p, int h )
+{
+ return h != 0xFFFFFFFF ? ( xSAT_Clause_t * )( p->pData + h ) : NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_MemGrow( xSAT_Mem_t * p, unsigned nCap )
+{
+ unsigned nPrevCap = p->nCap;
+ if ( p->nCap >= nCap )
+ return;
+ while (p->nCap < nCap)
+ {
+ unsigned delta = ( ( p->nCap >> 1 ) + ( p->nCap >> 3 ) + 2 ) & ~1;
+ p->nCap += delta;
+ assert(p->nCap >= nPrevCap);
+ }
+ assert(p->nCap > 0);
+ p->pData = ABC_REALLOC( unsigned, p->pData, p->nCap );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocating vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline xSAT_Mem_t * xSAT_MemAlloc( int nCap )
+{
+ xSAT_Mem_t * p;
+ p = ABC_CALLOC( xSAT_Mem_t, 1 );
+ if (nCap <= 0)
+ nCap = 1024*1024;
+
+ xSAT_MemGrow(p, nCap);
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resetting vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_MemRestart( xSAT_Mem_t * p )
+{
+ p->nSize = 0;
+ p->nWasted = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Freeing vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_MemFree( xSAT_Mem_t * p )
+{
+ ABC_FREE( p->pData );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates new clause.]
+
+ Description [The resulting clause is fully initialized.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline unsigned xSAT_MemAppend( xSAT_Mem_t * p, int nSize )
+{
+ unsigned nPrevSize;
+ assert(nSize > 0);
+ xSAT_MemGrow( p, p->nSize + nSize );
+ nPrevSize = p->nSize;
+ p->nSize += nSize;
+ assert(p->nSize > nPrevSize);
+ return nPrevSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline unsigned xSAT_MemCRef( xSAT_Mem_t * p, unsigned * pC )
+{
+ return ( unsigned )( pC - &(p->pData[0]) );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline unsigned xSAT_MemCap( xSAT_Mem_t * p )
+{
+ return p->nCap;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline unsigned xSAT_MemWastedCap( xSAT_Mem_t * p )
+{
+ return p->nWasted;
+}
+
+ABC_NAMESPACE_HEADER_END
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
diff --git a/src/sat/xsat/xsatSolver.c b/src/sat/xsat/xsatSolver.c
new file mode 100644
index 00000000..9807e1b7
--- /dev/null
+++ b/src/sat/xsat/xsatSolver.c
@@ -0,0 +1,1003 @@
+/**CFile****************************************************************
+
+ FileName [xsatSolver.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [xSAT - A SAT solver written in C.
+ Read the license file for more info.]
+
+ Synopsis [Solver internal functions implementation.]
+
+ Author [Bruno Schmitt <boschmitt@inf.ufrgs.br>]
+
+ Affiliation [UC Berkeley / UFRGS]
+
+ Date [Ver. 1.0. Started - November 10, 2016.]
+
+ Revision []
+
+***********************************************************************/
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <math.h>
+
+#include "xsatHeap.h"
+#include "xsatSolver.h"
+#include "xsatUtils.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int xSAT_SolverDecide( xSAT_Solver_t * s )
+{
+ int NextVar = VarUndef;
+
+ while ( NextVar == VarUndef || Vec_StrEntry( s->vAssigns, NextVar ) != VarX )
+ {
+ if ( xSAT_HeapSize( s->hOrder ) == 0 )
+ {
+ NextVar = VarUndef;
+ break;
+ }
+ else
+ NextVar = xSAT_HeapRemoveMin( s->hOrder );
+ }
+ return NextVar;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void xSAT_SolverRebuildOrderHeap( xSAT_Solver_t * s )
+{
+ Vec_Int_t * vTemp = Vec_IntAlloc( Vec_StrSize( s->vAssigns ) );
+ int Var;
+
+ for ( Var = 0; Var < Vec_StrSize( s->vAssigns ); Var++ )
+ if ( Vec_StrEntry( s->vAssigns, Var ) == VarX )
+ Vec_IntPush( vTemp, Var );
+
+ xSAT_HeapBuild( s->hOrder, vTemp );
+ Vec_IntFree( vTemp );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_SolverVarActRescale( xSAT_Solver_t * s )
+{
+ int i;
+ unsigned * pActivity = ( unsigned * ) Vec_IntArray( s->vActivity );
+
+ for ( i = 0; i < Vec_IntSize( s->vActivity ); i++ )
+ pActivity[i] >>= 19;
+
+ s->nVarActInc >>= 19;
+ s->nVarActInc = Abc_MaxInt( s->nVarActInc, ( 1 << 5 ) );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_SolverVarActBump( xSAT_Solver_t * s, int Var )
+{
+ unsigned * pActivity = ( unsigned * ) Vec_IntArray( s->vActivity );
+
+ pActivity[Var] += s->nVarActInc;
+ if ( pActivity[Var] & 0x80000000 )
+ xSAT_SolverVarActRescale( s );
+
+ if ( xSAT_HeapInHeap( s->hOrder, Var ) )
+ xSAT_HeapDecrease( s->hOrder, Var );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_SolverVarActDecay( xSAT_Solver_t * s )
+{
+ s->nVarActInc += ( s->nVarActInc >> 4 );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_SolverClaActRescale( xSAT_Solver_t * s )
+{
+ xSAT_Clause_t * pC;
+ int i, CRef;
+
+ Vec_IntForEachEntry( s->vLearnts, CRef, i )
+ {
+ pC = xSAT_SolverReadClause( s, ( unsigned ) CRef );
+ pC->pData[pC->nSize].Act >>= 14;
+ }
+ s->nClaActInc >>= 14;
+ s->nClaActInc = Abc_MaxInt( s->nClaActInc, ( 1 << 10 ) );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_SolverClaActBump( xSAT_Solver_t* s, xSAT_Clause_t * pCla )
+{
+ pCla->pData[pCla->nSize].Act += s->nClaActInc;
+ if ( pCla->pData[pCla->nSize].Act & 0x80000000 )
+ xSAT_SolverClaActRescale( s );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_SolverClaActDecay( xSAT_Solver_t * s )
+{
+ s->nClaActInc += ( s->nClaActInc >> 10 );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int xSAT_SolverClaCalcLBD( xSAT_Solver_t * s, xSAT_Clause_t * pCla )
+{
+ int i;
+ int nLBD = 0;
+
+ s->nStamp++;
+ for ( i = 0; i < pCla->nSize; i++ )
+ {
+ int Level = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( pCla->pData[i].Lit ) );
+ if ( ( unsigned ) Vec_IntEntry( s->vStamp, Level ) != s->nStamp )
+ {
+ Vec_IntWriteEntry( s->vStamp, Level, ( int ) s->nStamp );
+ nLBD++;
+ }
+ }
+ return nLBD;
+}
+
+static inline int xSAT_SolverClaCalcLBD2( xSAT_Solver_t * s, Vec_Int_t * vLits )
+{
+ int i;
+ int nLBD = 0;
+
+ s->nStamp++;
+ for ( i = 0; i < Vec_IntSize( vLits ); i++ )
+ {
+ int Level = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( Vec_IntEntry( vLits, i ) ) );
+ if ( ( unsigned ) Vec_IntEntry( s->vStamp, Level ) != s->nStamp )
+ {
+ Vec_IntWriteEntry( s->vStamp, Level, ( int ) s->nStamp );
+ nLBD++;
+ }
+ }
+ return nLBD;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned xSAT_SolverClaNew( xSAT_Solver_t * s, Vec_Int_t * vLits , int fLearnt )
+{
+ unsigned CRef;
+ xSAT_Clause_t * pCla;
+ xSAT_Watcher_t w1;
+ xSAT_Watcher_t w2;
+ unsigned nWords;
+
+ assert( Vec_IntSize( vLits ) > 1);
+ assert( fLearnt == 0 || fLearnt == 1 );
+
+ nWords = 3 + fLearnt + Vec_IntSize( vLits );
+ CRef = xSAT_MemAppend( s->pMemory, nWords );
+ pCla = xSAT_SolverReadClause( s, CRef );
+ pCla->fLearnt = fLearnt;
+ pCla->fMark = 0;
+ pCla->fReallocd = 0;
+ pCla->fCanBeDel = fLearnt;
+ pCla->nSize = Vec_IntSize( vLits );
+ memcpy( &( pCla->pData[0].Lit ), Vec_IntArray( vLits ), sizeof( int ) * Vec_IntSize( vLits ) );
+
+ if ( fLearnt )
+ {
+ Vec_IntPush( s->vLearnts, CRef );
+ pCla->nLBD = xSAT_SolverClaCalcLBD2( s, vLits );
+ pCla->pData[pCla->nSize].Act = 0;
+ s->Stats.nLearntLits += Vec_IntSize( vLits );
+ xSAT_SolverClaActBump(s, pCla);
+ }
+ else
+ {
+ Vec_IntPush( s->vClauses, CRef );
+ s->Stats.nClauseLits += Vec_IntSize( vLits );
+ }
+
+ w1.CRef = CRef;
+ w2.CRef = CRef;
+ w1.Blocker = pCla->pData[1].Lit;
+ w2.Blocker = pCla->pData[0].Lit;
+
+ if ( Vec_IntSize( vLits ) == 2 )
+ {
+ xSAT_WatchListPush( xSAT_VecWatchListEntry( s->vBinWatches, xSAT_NegLit( pCla->pData[0].Lit ) ), w1 );
+ xSAT_WatchListPush( xSAT_VecWatchListEntry( s->vBinWatches, xSAT_NegLit( pCla->pData[1].Lit ) ), w2 );
+ }
+ else
+ {
+ xSAT_WatchListPush( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( pCla->pData[0].Lit ) ), w1 );
+ xSAT_WatchListPush( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( pCla->pData[1].Lit ) ), w2 );
+ }
+ return CRef;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int xSAT_SolverEnqueue( xSAT_Solver_t * s, int Lit, unsigned Reason )
+{
+ int Var = xSAT_Lit2Var( Lit );
+
+ Vec_StrWriteEntry( s->vAssigns, Var, (char)xSAT_LitSign( Lit ) );
+ Vec_IntWriteEntry( s->vLevels, Var, xSAT_SolverDecisionLevel( s ) );
+ Vec_IntWriteEntry( s->vReasons, Var, ( int ) Reason );
+ Vec_IntPush( s->vTrail, Lit );
+
+ return true;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_SolverNewDecision( xSAT_Solver_t * s, int Lit )
+{
+ assert( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lit ) ) == VarX );
+ s->Stats.nDecisions++;
+ Vec_IntPush( s->vTrailLim, Vec_IntSize( s->vTrail ) );
+ xSAT_SolverEnqueue( s, Lit, CRefUndef );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void xSAT_SolverCancelUntil( xSAT_Solver_t * s, int Level )
+{
+ int c;
+
+ if ( xSAT_SolverDecisionLevel( s ) <= Level )
+ return;
+
+ for ( c = Vec_IntSize( s->vTrail ) - 1; c >= Vec_IntEntry( s->vTrailLim, Level ); c-- )
+ {
+ int Var = xSAT_Lit2Var( Vec_IntEntry( s->vTrail, c ) );
+
+ Vec_StrWriteEntry( s->vAssigns, Var, VarX );
+ Vec_IntWriteEntry( s->vReasons, Var, ( int ) CRefUndef );
+ Vec_StrWriteEntry( s->vPolarity, Var, ( char )xSAT_LitSign( Vec_IntEntry( s->vTrail, c ) ) );
+
+ if ( !xSAT_HeapInHeap( s->hOrder, Var ) )
+ xSAT_HeapInsert( s->hOrder, Var );
+ }
+
+ s->iQhead = Vec_IntEntry( s->vTrailLim, Level );
+ Vec_IntShrink( s->vTrail, Vec_IntEntry( s->vTrailLim, Level ) );
+ Vec_IntShrink( s->vTrailLim, Level );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int xSAT_SolverIsLitRemovable( xSAT_Solver_t* s, int Lit, int MinLevel )
+{
+ int top = Vec_IntSize( s->vTagged );
+
+ assert( ( unsigned ) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Lit ) ) != CRefUndef );
+ Vec_IntClear( s->vStack );
+ Vec_IntPush( s->vStack, xSAT_Lit2Var( Lit ) );
+
+ while ( Vec_IntSize( s->vStack ) )
+ {
+ int i;
+ int v = Vec_IntPop( s->vStack );
+ xSAT_Clause_t* c = xSAT_SolverReadClause(s, ( unsigned ) Vec_IntEntry( s->vReasons, v ) );
+ int * Lits = &( c->pData[0].Lit );
+
+ assert( (unsigned) Vec_IntEntry( s->vReasons, v ) != CRefUndef);
+ if( c->nSize == 2 && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[0] ) ) == xSAT_LitSign( xSAT_NegLit( Lits[0] ) ) )
+ {
+ assert( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[1] ) ) == xSAT_LitSign( ( Lits[1] ) ) );
+ ABC_SWAP( int, Lits[0], Lits[1] );
+ }
+
+ for ( i = 1; i < c->nSize; i++ )
+ {
+ int v = xSAT_Lit2Var( Lits[i] );
+ if ( !Vec_StrEntry( s->vSeen, v ) && Vec_IntEntry( s->vLevels, v ) )
+ {
+ if ( ( unsigned ) Vec_IntEntry( s->vReasons, v ) != CRefUndef && ( ( 1 << (Vec_IntEntry( s->vLevels, v ) & 31 ) ) & MinLevel ) )
+ {
+ Vec_IntPush( s->vStack, v );
+ Vec_IntPush( s->vTagged, Lits[i] );
+ Vec_StrWriteEntry( s->vSeen, v, 1 );
+ }
+ else
+ {
+ int Lit;
+ Vec_IntForEachEntryStart( s->vTagged, Lit, i, top )
+ Vec_StrWriteEntry( s->vSeen, xSAT_Lit2Var( Lit ), 0 );
+ Vec_IntShrink( s->vTagged, top );
+ return 0;
+ }
+ }
+ }
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void xSAT_SolverClaMinimisation( xSAT_Solver_t * s, Vec_Int_t * vLits )
+{
+ int * pLits = Vec_IntArray( vLits );
+ int MinLevel = 0;
+ int i, j;
+
+ for ( i = 1; i < Vec_IntSize( vLits ); i++ )
+ {
+ int Level = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( pLits[i] ) );
+ MinLevel |= 1 << ( Level & 31 );
+ }
+
+ /* Remove reduntant literals */
+ Vec_IntAppend( s->vTagged, vLits );
+ for ( i = j = 1; i < Vec_IntSize( vLits ); i++ )
+ if ( ( unsigned ) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( pLits[i] ) ) == CRefUndef || !xSAT_SolverIsLitRemovable( s, pLits[i], MinLevel ) )
+ pLits[j++] = pLits[i];
+ Vec_IntShrink( vLits, j );
+
+ /* Binary Resolution */
+ if( Vec_IntSize( vLits ) <= 30 && xSAT_SolverClaCalcLBD2( s, vLits ) <= 6 )
+ {
+ int nb, l;
+ int Lit;
+ int FlaseLit = xSAT_NegLit( pLits[0] );
+ xSAT_WatchList_t * ws = xSAT_VecWatchListEntry( s->vBinWatches, FlaseLit );
+ xSAT_Watcher_t * begin = xSAT_WatchListArray( ws );
+ xSAT_Watcher_t * end = begin + xSAT_WatchListSize( ws );
+ xSAT_Watcher_t * pWatcher;
+
+ s->nStamp++;
+ Vec_IntForEachEntry( vLits, Lit, i )
+ Vec_IntWriteEntry( s->vStamp, xSAT_Lit2Var( Lit ), ( int ) s->nStamp );
+
+ nb = 0;
+ for ( pWatcher = begin; pWatcher < end; pWatcher++ )
+ {
+ int ImpLit = pWatcher->Blocker;
+
+ if ( ( unsigned ) Vec_IntEntry( s->vStamp, xSAT_Lit2Var( ImpLit ) ) == s->nStamp && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( ImpLit ) ) == xSAT_LitSign( ImpLit ) )
+ {
+ nb++;
+ Vec_IntWriteEntry( s->vStamp, xSAT_Lit2Var( ImpLit ), ( int )( s->nStamp - 1 ) );
+ }
+ }
+
+ l = Vec_IntSize( vLits ) - 1;
+ if ( nb > 0 )
+ {
+ for ( i = 1; i < Vec_IntSize( vLits ) - nb; i++ )
+ if ( ( unsigned ) Vec_IntEntry( s->vStamp, xSAT_Lit2Var( pLits[i] ) ) != s->nStamp )
+ {
+ int TempLit = pLits[l];
+ pLits[l] = pLits[i];
+ pLits[i] = TempLit;
+ i--; l--;
+ }
+
+ Vec_IntShrink( vLits, Vec_IntSize( vLits ) - nb );
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void xSAT_SolverAnalyze( xSAT_Solver_t* s, unsigned ConfCRef, Vec_Int_t * vLearnt, int * OutBtLevel, unsigned * nLBD )
+{
+ int * trail = Vec_IntArray( s->vTrail );
+ int Count = 0;
+ int p = LitUndef;
+ int Idx = Vec_IntSize( s->vTrail ) - 1;
+ int * Lits;
+ int Lit;
+ int i, j;
+
+ Vec_IntPush( vLearnt, LitUndef );
+ do
+ {
+ xSAT_Clause_t * pCla;
+
+ assert( ConfCRef != CRefUndef );
+ pCla = xSAT_SolverReadClause(s, ConfCRef);
+ Lits = &( pCla->pData[0].Lit );
+
+ if( p != LitUndef && pCla->nSize == 2 && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[0] ) ) == xSAT_LitSign( xSAT_NegLit( Lits[0] ) ) )
+ {
+ assert( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[1] ) ) == xSAT_LitSign( ( Lits[1] ) ) );
+ ABC_SWAP( int, Lits[0], Lits[1] );
+ }
+
+ if ( pCla->fLearnt )
+ xSAT_SolverClaActBump( s, pCla );
+
+ if ( pCla->fLearnt && pCla->nLBD > 2 )
+ {
+ unsigned int nLevels = xSAT_SolverClaCalcLBD( s, pCla );
+ if ( nLevels + 1 < pCla->nLBD )
+ {
+ if ( pCla->nLBD <= s->Config.nLBDFrozenClause )
+ pCla->fCanBeDel = 0;
+ pCla->nLBD = nLevels;
+ }
+ }
+
+ for ( j = ( p == LitUndef ? 0 : 1 ); j < pCla->nSize; j++ )
+ {
+ int Var = xSAT_Lit2Var( Lits[j] );
+
+ if ( Vec_StrEntry( s->vSeen, Var ) == 0 && Vec_IntEntry( s->vLevels, Var ) > 0 )
+ {
+ Vec_StrWriteEntry( s->vSeen, Var, 1 );
+ xSAT_SolverVarActBump( s, Var );
+ if ( Vec_IntEntry( s->vLevels, Var ) >= xSAT_SolverDecisionLevel( s ) )
+ {
+ Count++;
+ if ( Vec_IntEntry( s->vReasons, Var ) != CRefUndef && xSAT_SolverReadClause( s, Vec_IntEntry( s->vReasons, Var ) )->fLearnt )
+ Vec_IntPush( s->vLastDLevel, Var );
+ }
+ else
+ Vec_IntPush( vLearnt, Lits[j] );
+ }
+ }
+
+ while ( !Vec_StrEntry( s->vSeen, xSAT_Lit2Var( trail[Idx--] ) ) );
+
+ // Next clause to look at
+ p = trail[Idx+1];
+ ConfCRef = ( unsigned ) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( p ) );
+ Vec_StrWriteEntry( s->vSeen, xSAT_Lit2Var( p ), 0 );
+ Count--;
+
+ } while ( Count > 0 );
+
+ Vec_IntArray( vLearnt )[0] = xSAT_NegLit( p );
+ xSAT_SolverClaMinimisation( s, vLearnt );
+
+ // Find the backtrack level
+ Lits = Vec_IntArray( vLearnt );
+ if ( Vec_IntSize( vLearnt ) == 1 )
+ *OutBtLevel = 0;
+ else
+ {
+ int iMax = 1;
+ int Max = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( Lits[1] ) );
+ int Tmp;
+
+ for (i = 2; i < Vec_IntSize( vLearnt ); i++)
+ if ( Vec_IntEntry( s->vLevels, xSAT_Lit2Var( Lits[i]) ) > Max)
+ {
+ Max = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( Lits[i]) );
+ iMax = i;
+ }
+
+ Tmp = Lits[1];
+ Lits[1] = Lits[iMax];
+ Lits[iMax] = Tmp;
+ *OutBtLevel = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( Lits[1] ) );
+ }
+
+ *nLBD = xSAT_SolverClaCalcLBD2( s, vLearnt );
+ if ( Vec_IntSize( s->vLastDLevel ) > 0 )
+ {
+ int Var;
+ Vec_IntForEachEntry( s->vLastDLevel, Var, i )
+ {
+ if ( xSAT_SolverReadClause( s, Vec_IntEntry( s->vReasons, Var ) )->nLBD < *nLBD )
+ xSAT_SolverVarActBump( s, Var );
+ }
+
+ Vec_IntClear( s->vLastDLevel );
+ }
+
+ Vec_IntForEachEntry( s->vTagged, Lit, i )
+ Vec_StrWriteEntry( s->vSeen, xSAT_Lit2Var( Lit ), 0 );
+ Vec_IntClear( s->vTagged );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned xSAT_SolverPropagate( xSAT_Solver_t* s )
+{
+ unsigned hConfl = CRefUndef;
+ int * Lits;
+ int NegLit;
+ int nProp = 0;
+
+ while ( s->iQhead < Vec_IntSize( s->vTrail ) )
+ {
+ int p = Vec_IntEntry( s->vTrail, s->iQhead++ );
+ xSAT_WatchList_t* ws = xSAT_VecWatchListEntry( s->vBinWatches, p );
+ xSAT_Watcher_t* begin = xSAT_WatchListArray( ws );
+ xSAT_Watcher_t* end = begin + xSAT_WatchListSize( ws );
+ xSAT_Watcher_t *i, *j;
+
+ nProp++;
+ for ( i = begin; i < end; i++ )
+ {
+ if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( i->Blocker ) ) == VarX )
+ xSAT_SolverEnqueue( s, i->Blocker, i->CRef );
+ else if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( i->Blocker ) ) == xSAT_LitSign( xSAT_NegLit( i->Blocker ) ) )
+ return i->CRef;
+ }
+
+ ws = xSAT_VecWatchListEntry( s->vWatches, p );
+ begin = xSAT_WatchListArray( ws );
+ end = begin + xSAT_WatchListSize( ws );
+
+ for ( i = j = begin; i < end; )
+ {
+ xSAT_Clause_t * pCla;
+ xSAT_Watcher_t w;
+ if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( i->Blocker ) ) == xSAT_LitSign( i->Blocker ) )
+ {
+ *j++ = *i++;
+ continue;
+ }
+
+ pCla = xSAT_SolverReadClause( s, i->CRef );
+ Lits = &( pCla->pData[0].Lit );
+
+ // Make sure the false literal is data[1]:
+ NegLit = xSAT_NegLit( p );
+ if ( Lits[0] == NegLit )
+ {
+ Lits[0] = Lits[1];
+ Lits[1] = NegLit;
+ }
+ assert( Lits[1] == NegLit );
+
+ w.CRef = i->CRef;
+ w.Blocker = Lits[0];
+
+ // If 0th watch is true, then clause is already satisfied.
+ if ( Lits[0] != i->Blocker && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[0] ) ) == xSAT_LitSign( Lits[0] ) )
+ *j++ = w;
+ else
+ {
+ // Look for new watch:
+ int * stop = Lits + pCla->nSize;
+ int * k;
+ for ( k = Lits + 2; k < stop; k++ )
+ {
+ if (Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( *k ) ) != !xSAT_LitSign( *k ) )
+ {
+ Lits[1] = *k;
+ *k = NegLit;
+ xSAT_WatchListPush( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( Lits[1] ) ), w );
+ goto next;
+ }
+ }
+
+ *j++ = w;
+
+ // Clause is unit under assignment:
+ if (Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[0] ) ) == xSAT_LitSign( xSAT_NegLit( Lits[0] ) ) )
+ {
+ hConfl = i->CRef;
+ i++;
+ s->iQhead = Vec_IntSize( s->vTrail );
+ // Copy the remaining watches:
+ while (i < end)
+ *j++ = *i++;
+ }
+ else
+ xSAT_SolverEnqueue( s, Lits[0], i->CRef );
+ }
+ next:
+ i++;
+ }
+
+ s->Stats.nInspects += j - xSAT_WatchListArray( ws );
+ xSAT_WatchListShrink( ws, j - xSAT_WatchListArray( ws ) );
+ }
+
+ s->Stats.nPropagations += nProp;
+ s->nPropSimplify -= nProp;
+
+ return hConfl;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void xSAT_SolverReduceDB( xSAT_Solver_t * s )
+{
+ static abctime TimeTotal = 0;
+ abctime clk = Abc_Clock();
+ int nLearnedOld = Vec_IntSize( s->vLearnts );
+ int i, limit;
+ unsigned CRef;
+ xSAT_Clause_t * pCla;
+ xSAT_Clause_t ** learnts_cls;
+
+ learnts_cls = ABC_ALLOC( xSAT_Clause_t *, nLearnedOld );
+ Vec_IntForEachEntry( s->vLearnts, CRef, i )
+ learnts_cls[i] = xSAT_SolverReadClause(s, CRef);
+
+ limit = nLearnedOld / 2;
+
+ xSAT_UtilSort((void *) learnts_cls, nLearnedOld,
+ (int (*)( const void *, const void * )) xSAT_ClauseCompare);
+
+ if ( learnts_cls[nLearnedOld / 2]->nLBD <= 3 )
+ s->nRC2 += s->Config.nSpecialIncReduce;
+ if ( learnts_cls[nLearnedOld - 1]->nLBD <= 5 )
+ s->nRC2 += s->Config.nSpecialIncReduce;
+
+ Vec_IntClear( s->vLearnts );
+ for ( i = 0; i < nLearnedOld; i++ )
+ {
+ unsigned CRef;
+
+ pCla = learnts_cls[i];
+ CRef = xSAT_MemCRef( s->pMemory, ( unsigned * ) pCla );
+ assert( pCla->fMark == 0 );
+ if ( pCla->fCanBeDel && pCla->nLBD > 2 && pCla->nSize > 2 && (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( pCla->pData[0].Lit ) ) != CRef && ( i < limit ) )
+ {
+ pCla->fMark = 1;
+ s->Stats.nLearntLits -= pCla->nSize;
+ xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( pCla->pData[0].Lit ) ), CRef );
+ xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( pCla->pData[1].Lit ) ), CRef );
+ }
+ else
+ {
+ if ( !pCla->fCanBeDel )
+ limit++;
+ pCla->fCanBeDel = 1;
+ Vec_IntPush( s->vLearnts, CRef );
+ }
+ }
+ ABC_FREE( learnts_cls );
+
+ TimeTotal += Abc_Clock() - clk;
+ if ( s->Config.fVerbose )
+ {
+ Abc_Print(1, "reduceDB: Keeping %7d out of %7d clauses (%5.2f %%) ",
+ Vec_IntSize( s->vLearnts ), nLearnedOld, 100.0 * Vec_IntSize( s->vLearnts ) / nLearnedOld );
+ Abc_PrintTime( 1, "Time", TimeTotal );
+ }
+ xSAT_SolverGarbageCollect(s);
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char xSAT_SolverSearch( xSAT_Solver_t * s )
+{
+ iword conflictC = 0;
+
+ s->Stats.nStarts++;
+ for (;;)
+ {
+ unsigned hConfl = xSAT_SolverPropagate( s );
+
+ if ( hConfl != CRefUndef )
+ {
+ /* Conflict */
+ int BacktrackLevel;
+ unsigned nLBD;
+ unsigned CRef;
+
+ s->Stats.nConflicts++;
+ conflictC++;
+
+ if ( xSAT_SolverDecisionLevel( s ) == 0 )
+ return LBoolFalse;
+
+ xSAT_BQueuePush( s->bqTrail, Vec_IntSize( s->vTrail ) );
+ if ( s->Stats.nConflicts > s->Config.nFirstBlockRestart && xSAT_BQueueIsValid( s->bqLBD ) && ( Vec_IntSize( s->vTrail ) > ( s->Config.R * ( iword ) xSAT_BQueueAvg( s->bqTrail ) ) ) )
+ xSAT_BQueueClean(s->bqLBD);
+
+ Vec_IntClear( s->vLearntClause );
+ xSAT_SolverAnalyze( s, hConfl, s->vLearntClause, &BacktrackLevel, &nLBD );
+
+ s->nSumLBD += nLBD;
+ xSAT_BQueuePush( s->bqLBD, nLBD );
+ xSAT_SolverCancelUntil( s, BacktrackLevel );
+
+ CRef = Vec_IntSize( s->vLearntClause ) == 1 ? CRefUndef : xSAT_SolverClaNew( s, s->vLearntClause , 1 );
+ xSAT_SolverEnqueue( s, Vec_IntEntry( s->vLearntClause , 0 ), CRef );
+
+ xSAT_SolverVarActDecay( s );
+ xSAT_SolverClaActDecay( s );
+ }
+ else
+ {
+ /* No conflict */
+ int NextVar;
+ if ( xSAT_BQueueIsValid( s->bqLBD ) && ( ( ( iword )xSAT_BQueueAvg( s->bqLBD ) * s->Config.K ) > ( s->nSumLBD / s->Stats.nConflicts ) ) )
+ {
+ xSAT_BQueueClean( s->bqLBD );
+ xSAT_SolverCancelUntil( s, 0 );
+ return LBoolUndef;
+ }
+
+ // Simplify the set of problem clauses:
+ if ( xSAT_SolverDecisionLevel( s ) == 0 )
+ xSAT_SolverSimplify( s );
+
+ // Reduce the set of learnt clauses:
+ if ( s->Stats.nConflicts >= s->nConfBeforeReduce )
+ {
+ s->nRC1 = ( s->Stats.nConflicts / s->nRC2 ) + 1;
+ xSAT_SolverReduceDB(s);
+ s->nRC2 += s->Config.nIncReduce;
+ s->nConfBeforeReduce = s->nRC1 * s->nRC2;
+ }
+
+ // New variable decision:
+ NextVar = xSAT_SolverDecide( s );
+
+ if ( NextVar == VarUndef )
+ return LBoolTrue;
+
+ xSAT_SolverNewDecision( s, xSAT_Var2Lit( NextVar, ( int ) Vec_StrEntry( s->vPolarity, NextVar ) ) );
+ }
+ }
+
+ return LBoolUndef; // cannot happen
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void xSAT_SolverClaRealloc( xSAT_Mem_t * pDest, xSAT_Mem_t * pSrc, unsigned * pCRef )
+{
+ unsigned nNewCRef;
+ xSAT_Clause_t * pNewCla;
+ xSAT_Clause_t * pOldCla = xSAT_MemClauseHand( pSrc, *pCRef );
+
+ if ( pOldCla->fReallocd )
+ {
+ *pCRef = ( unsigned ) pOldCla->nSize;
+ return;
+ }
+ nNewCRef = xSAT_MemAppend( pDest, 3 + pOldCla->fLearnt + pOldCla->nSize );
+ pNewCla = xSAT_MemClauseHand( pDest, nNewCRef );
+ memcpy( pNewCla, pOldCla, ( 3 + pOldCla->fLearnt + pOldCla->nSize ) * 4 );
+ pOldCla->fReallocd = 1;
+ pOldCla->nSize = ( unsigned ) nNewCRef;
+ *pCRef = nNewCRef;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void xSAT_SolverGarbageCollect( xSAT_Solver_t * s )
+{
+ int i;
+ unsigned * pArray;
+ xSAT_Mem_t * pNewMemMngr = xSAT_MemAlloc( xSAT_MemCap( s->pMemory ) - xSAT_MemWastedCap( s->pMemory ) );
+
+ for ( i = 0; i < 2 * Vec_StrSize( s->vAssigns ); i++ )
+ {
+ xSAT_WatchList_t* ws = xSAT_VecWatchListEntry( s->vWatches, i);
+ xSAT_Watcher_t* begin = xSAT_WatchListArray(ws);
+ xSAT_Watcher_t* end = begin + xSAT_WatchListSize(ws);
+ xSAT_Watcher_t *w;
+
+ for ( w = begin; w != end; w++ )
+ xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &(w->CRef) );
+
+ ws = xSAT_VecWatchListEntry( s->vBinWatches, i);
+ begin = xSAT_WatchListArray(ws);
+ end = begin + xSAT_WatchListSize(ws);
+ for ( w = begin; w != end; w++ )
+ xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &(w->CRef) );
+ }
+
+ for ( i = 0; i < Vec_IntSize( s->vTrail ); i++ )
+ if ( ( unsigned ) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) ) ) != CRefUndef )
+ xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, ( unsigned * ) &( Vec_IntArray( s->vReasons )[xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) )] ) );
+
+ pArray = ( unsigned * ) Vec_IntArray( s->vLearnts );
+ for ( i = 0; i < Vec_IntSize( s->vLearnts ); i++ )
+ xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &(pArray[i]) );
+
+ pArray = ( unsigned * ) Vec_IntArray( s->vClauses );
+ for ( i = 0; i < Vec_IntSize( s->vClauses ); i++ )
+ xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &(pArray[i]) );
+
+ xSAT_MemFree( s->pMemory );
+ s->pMemory = pNewMemMngr;
+}
+
+ABC_NAMESPACE_IMPL_END
diff --git a/src/sat/xsat/xsatSolver.h b/src/sat/xsat/xsatSolver.h
new file mode 100644
index 00000000..36432e03
--- /dev/null
+++ b/src/sat/xsat/xsatSolver.h
@@ -0,0 +1,248 @@
+/**CFile****************************************************************
+
+ FileName [xsatSolver.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [xSAT - A SAT solver written in C.
+ Read the license file for more info.]
+
+ Synopsis [Internal definitions of the solver.]
+
+ Author [Bruno Schmitt <boschmitt@inf.ufrgs.br>]
+
+ Affiliation [UC Berkeley / UFRGS]
+
+ Date [Ver. 1.0. Started - November 10, 2016.]
+
+ Revision []
+
+***********************************************************************/
+#ifndef ABC__sat__xSAT__xsatSolver_h
+#define ABC__sat__xSAT__xsatSolver_h
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "misc/util/abc_global.h"
+#include "misc/vec/vecStr.h"
+
+#include "xsat.h"
+#include "xsatBQueue.h"
+#include "xsatClause.h"
+#include "xsatHeap.h"
+#include "xsatMemory.h"
+#include "xsatWatchList.h"
+
+ABC_NAMESPACE_HEADER_START
+
+#ifndef __cplusplus
+#ifndef false
+# define false 0
+#endif
+#ifndef true
+# define true 1
+#endif
+#endif
+
+enum
+{
+ Var0 = 1,
+ Var1 = 0,
+ VarX = 3
+};
+
+enum
+{
+ LBoolUndef = 0,
+ LBoolTrue = 1,
+ LBoolFalse = -1
+};
+
+enum
+{
+ VarUndef = -1,
+ LitUndef = -2
+};
+
+#define CRefUndef 0xFFFFFFFF
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+typedef struct xSAT_SolverOptions_t_ xSAT_SolverOptions_t;
+struct xSAT_SolverOptions_t_
+{
+ char fVerbose;
+
+ // Limits
+ iword nConfLimit; // external limit on the number of conflicts
+ iword nInsLimit; // external limit on the number of implications
+ abctime nRuntimeLimit; // external limit on runtime
+
+ // Constants used for restart heuristic
+ double K; // Forces a restart
+ double R; // Block a restart
+ int nFirstBlockRestart; // Lower bound number of conflicts for start blocking restarts
+ int nSizeLBDQueue; // Size of the moving avarege queue for LBD (force restart)
+ int nSizeTrailQueue; // Size of the moving avarege queue for Trail size (block restart)
+
+ // Constants used for clause database reduction heuristic
+ int nConfFirstReduce; // Number of conflicts before first reduction
+ int nIncReduce; // Increment to reduce
+ int nSpecialIncReduce; // Special increment to reduce
+ unsigned nLBDFrozenClause;
+};
+
+typedef struct xSAT_Stats_t_ xSAT_Stats_t;
+struct xSAT_Stats_t_
+{
+ unsigned nStarts;
+ unsigned nReduceDB;
+
+ iword nDecisions;
+ iword nPropagations;
+ iword nInspects;
+ iword nConflicts;
+
+ iword nClauseLits;
+ iword nLearntLits;
+};
+
+struct xSAT_Solver_t_
+{
+ /* Clauses Database */
+ xSAT_Mem_t * pMemory;
+ Vec_Int_t * vLearnts;
+ Vec_Int_t * vClauses;
+ xSAT_VecWatchList_t * vWatches;
+ xSAT_VecWatchList_t * vBinWatches;
+
+ /* Activity heuristic */
+ int nVarActInc; /* Amount to bump next variable with. */
+ int nClaActInc; /* Amount to bump next clause with. */
+
+ /* Variable Information */
+ Vec_Int_t * vActivity; /* A heuristic measurement of the activity of a variable. */
+ xSAT_Heap_t * hOrder;
+ Vec_Int_t * vLevels; /* Decision level of the current assignment */
+ Vec_Int_t * vReasons; /* Reason (clause) of the current assignment */
+ Vec_Str_t * vAssigns; /* Current assignment. */
+ Vec_Str_t * vPolarity;
+ Vec_Str_t * vTags;
+
+ /* Assignments */
+ Vec_Int_t * vTrail;
+ Vec_Int_t * vTrailLim; // Separator indices for different decision levels in 'trail'.
+ int iQhead; // Head of propagation queue (as index into the trail).
+
+ int nAssignSimplify; /* Number of top-level assignments since last
+ * execution of 'simplify()'. */
+ iword nPropSimplify; /* Remaining number of propagations that must be
+ * made before next execution of 'simplify()'. */
+
+ /* Temporary data used by Search method */
+ xSAT_BQueue_t * bqTrail;
+ xSAT_BQueue_t * bqLBD;
+ float nSumLBD;
+ int nConfBeforeReduce;
+ long nRC1;
+ int nRC2;
+
+ /* Temporary data used by Analyze */
+ Vec_Int_t * vLearntClause;
+ Vec_Str_t * vSeen;
+ Vec_Int_t * vTagged;
+ Vec_Int_t * vStack;
+ Vec_Int_t * vLastDLevel;
+
+ /* Misc temporary */
+ unsigned nStamp;
+ Vec_Int_t * vStamp; /* Multipurpose stamp used to calculate LBD and
+ * clauses minimization with binary resolution */
+
+ xSAT_SolverOptions_t Config;
+ xSAT_Stats_t Stats;
+};
+
+static inline int xSAT_Var2Lit( int Var, int c )
+{
+ return Var + Var + ( c != 0 );
+}
+
+static inline int xSAT_NegLit( int Lit )
+{
+ return Lit ^ 1;
+}
+
+static inline int xSAT_Lit2Var( int Lit )
+{
+ return Lit >> 1;
+}
+
+static inline int xSAT_LitSign( int Lit )
+{
+ return Lit & 1;
+}
+
+static inline int xSAT_SolverDecisionLevel( xSAT_Solver_t * s )
+{
+ return Vec_IntSize( s->vTrailLim );
+}
+
+static inline xSAT_Clause_t * xSAT_SolverReadClause( xSAT_Solver_t * s, unsigned h )
+{
+ return xSAT_MemClauseHand( s->pMemory, h );
+}
+
+static inline int xSAT_SolverIsClauseSatisfied( xSAT_Solver_t * s, xSAT_Clause_t * pCla )
+{
+ int i;
+ int * Lits = &( pCla->pData[0].Lit );
+
+ for ( i = 0; i < pCla->nSize; i++ )
+ if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[i] ) ) == xSAT_LitSign( ( Lits[i] ) ) )
+ return true;
+
+ return false;
+}
+
+static inline void xSAT_SolverPrintClauses( xSAT_Solver_t * s )
+{
+ int i;
+ unsigned CRef;
+
+ Vec_IntForEachEntry( s->vClauses, CRef, i )
+ xSAT_ClausePrint( xSAT_SolverReadClause( s, CRef ) );
+}
+
+static inline void xSAT_SolverPrintState( xSAT_Solver_t * s )
+{
+ printf( "starts : %10d\n", s->Stats.nStarts );
+ printf( "conflicts : %10ld\n", s->Stats.nConflicts );
+ printf( "decisions : %10ld\n", s->Stats.nDecisions );
+ printf( "propagations : %10ld\n", s->Stats.nPropagations );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+extern unsigned xSAT_SolverClaNew( xSAT_Solver_t* s, Vec_Int_t * vLits, int fLearnt );
+extern char xSAT_SolverSearch( xSAT_Solver_t * s );
+
+extern void xSAT_SolverGarbageCollect( xSAT_Solver_t * s );
+
+extern int xSAT_SolverEnqueue( xSAT_Solver_t* s, int Lit, unsigned From );
+extern void xSAT_SolverCancelUntil( xSAT_Solver_t* s, int Level);
+extern unsigned xSAT_SolverPropagate( xSAT_Solver_t* s );
+extern void xSAT_SolverRebuildOrderHeap( xSAT_Solver_t* s );
+
+ABC_NAMESPACE_HEADER_END
+
+#endif
diff --git a/src/sat/xsat/xsatSolverAPI.c b/src/sat/xsat/xsatSolverAPI.c
new file mode 100644
index 00000000..7746dc0b
--- /dev/null
+++ b/src/sat/xsat/xsatSolverAPI.c
@@ -0,0 +1,346 @@
+/**CFile****************************************************************
+
+ FileName [xsatSolverAPI.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [xSAT - A SAT solver written in C.
+ Read the license file for more info.]
+
+ Synopsis [Solver external API functions implementation.]
+
+ Author [Bruno Schmitt <boschmitt@inf.ufrgs.br>]
+
+ Affiliation [UC Berkeley / UFRGS]
+
+ Date [Ver. 1.0. Started - November 10, 2016.]
+
+ Revision []
+
+***********************************************************************/
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <math.h>
+
+#include "xsatSolver.h"
+
+ABC_NAMESPACE_IMPL_START
+
+xSAT_SolverOptions_t DefaultConfig =
+{
+ 1, //.fVerbose = 1,
+
+ 0, //.nConfLimit = 0,
+ 0, //.nInsLimit = 0,
+ 0, //.nRuntimeLimit = 0,
+
+ 0.8, //.K = 0.8,
+ 1.4, //.R = 1.4,
+ 10000, //.nFirstBlockRestart = 10000,
+ 50, //.nSizeLBDQueue = 50,
+ 5000, //.nSizeTrailQueue = 5000,
+
+ 2000, //.nConfFirstReduce = 2000,
+ 300, //.nIncReduce = 300,
+ 1000, //.nSpecialIncReduce = 1000,
+
+ 30 //.nLBDFrozenClause = 30
+};
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+xSAT_Solver_t* xSAT_SolverCreate()
+{
+ xSAT_Solver_t * s = (xSAT_Solver_t *) ABC_CALLOC( char, sizeof( xSAT_Solver_t ) );
+ s->Config = DefaultConfig;
+
+ s->pMemory = xSAT_MemAlloc(0);
+ s->vClauses = Vec_IntAlloc(0);
+ s->vLearnts = Vec_IntAlloc(0);
+ s->vWatches = xSAT_VecWatchListAlloc( 0 );
+ s->vBinWatches = xSAT_VecWatchListAlloc( 0 );
+
+ s->vTrailLim = Vec_IntAlloc(0);
+ s->vTrail = Vec_IntAlloc( 0 );
+
+ s->vActivity = Vec_IntAlloc( 0 );
+ s->hOrder = xSAT_HeapAlloc( s->vActivity );
+
+ s->vPolarity = Vec_StrAlloc( 0 );
+ s->vTags = Vec_StrAlloc( 0 );
+ s->vAssigns = Vec_StrAlloc( 0 );
+ s->vLevels = Vec_IntAlloc( 0 );
+ s->vReasons = Vec_IntAlloc( 0 );
+ s->vStamp = Vec_IntAlloc( 0 );
+
+ s->vTagged = Vec_IntAlloc(0);
+ s->vStack = Vec_IntAlloc(0);
+
+ s->vSeen = Vec_StrAlloc( 0 );
+ s->vLearntClause = Vec_IntAlloc(0);
+ s->vLastDLevel = Vec_IntAlloc(0);
+
+
+ s->bqTrail = xSAT_BQueueNew( s->Config.nSizeTrailQueue );
+ s->bqLBD = xSAT_BQueueNew( s->Config.nSizeLBDQueue );
+
+ s->nVarActInc = (1 << 5);
+ s->nClaActInc = (1 << 11);
+
+ s->nConfBeforeReduce = s->Config.nConfFirstReduce;
+ s->nRC1 = 1;
+ s->nRC2 = s->Config.nConfFirstReduce;
+ return s;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void xSAT_SolverDestroy( xSAT_Solver_t * s )
+{
+ xSAT_MemFree( s->pMemory );
+ Vec_IntFree( s->vClauses );
+ Vec_IntFree( s->vLearnts );
+ xSAT_VecWatchListFree( s->vWatches );
+ xSAT_VecWatchListFree( s->vBinWatches );
+
+ xSAT_HeapFree(s->hOrder);
+ Vec_IntFree( s->vTrailLim );
+ Vec_IntFree( s->vTrail );
+ Vec_IntFree( s->vTagged );
+ Vec_IntFree( s->vStack );
+
+ Vec_StrFree( s->vSeen );
+ Vec_IntFree( s->vLearntClause );
+ Vec_IntFree( s->vLastDLevel );
+
+ Vec_IntFree( s->vActivity );
+ Vec_StrFree( s->vPolarity );
+ Vec_StrFree( s->vTags );
+ Vec_StrFree( s->vAssigns );
+ Vec_IntFree( s->vLevels );
+ Vec_IntFree( s->vReasons );
+ Vec_IntFree( s->vStamp );
+
+ xSAT_BQueueFree(s->bqLBD);
+ xSAT_BQueueFree(s->bqTrail);
+
+ ABC_FREE(s);
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int xSAT_SolverSimplify( xSAT_Solver_t * s )
+{
+ int i, j;
+ unsigned CRef;
+ assert( xSAT_SolverDecisionLevel(s) == 0 );
+
+ if ( xSAT_SolverPropagate(s) != CRefUndef )
+ return false;
+
+ if ( s->nAssignSimplify == Vec_IntSize( s->vTrail ) || s->nPropSimplify > 0 )
+ return true;
+
+ j = 0;
+ Vec_IntForEachEntry( s->vClauses, CRef, i )
+ {
+ xSAT_Clause_t * pCla = xSAT_SolverReadClause( s, CRef );
+ if ( xSAT_SolverIsClauseSatisfied( s, pCla ) )
+ {
+ pCla->fMark = 1;
+ s->Stats.nClauseLits -= pCla->nSize;
+
+ if ( pCla->nSize == 2 )
+ {
+ xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vBinWatches, xSAT_NegLit(pCla->pData[0].Lit) ), CRef );
+ xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vBinWatches, xSAT_NegLit(pCla->pData[1].Lit) ), CRef );
+ }
+ else
+ {
+ xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit(pCla->pData[0].Lit) ), CRef );
+ xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit(pCla->pData[1].Lit) ), CRef );
+ }
+ }
+ else
+ Vec_IntWriteEntry( s->vClauses, j++, CRef );
+ }
+ Vec_IntShrink( s->vClauses, j );
+ xSAT_SolverRebuildOrderHeap( s );
+
+ s->nAssignSimplify = Vec_IntSize( s->vTrail );
+ s->nPropSimplify = s->Stats.nClauseLits + s->Stats.nLearntLits;
+
+ return true;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void xSAT_SolverAddVariable( xSAT_Solver_t* s, int Sign )
+{
+ int Var = Vec_IntSize( s->vActivity );
+
+ xSAT_VecWatchListPush( s->vWatches );
+ xSAT_VecWatchListPush( s->vWatches );
+ xSAT_VecWatchListPush( s->vBinWatches );
+ xSAT_VecWatchListPush( s->vBinWatches );
+
+ Vec_IntPush( s->vActivity, 0 );
+ Vec_IntPush( s->vLevels, 0 );
+ Vec_StrPush( s->vAssigns, VarX );
+ Vec_StrPush( s->vPolarity, 1 );
+ Vec_StrPush( s->vTags, 0 );
+ Vec_IntPush( s->vReasons, ( int ) CRefUndef );
+ Vec_IntPush( s->vStamp, 0 );
+ Vec_StrPush( s->vSeen, 0 );
+
+ xSAT_HeapInsert( s->hOrder, Var );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int xSAT_SolverAddClause( xSAT_Solver_t * s, Vec_Int_t * vLits )
+{
+ int i, j;
+ int Lit, PrevLit;
+ int MaxVar;
+
+ Vec_IntSort( vLits, 0 );
+ MaxVar = xSAT_Lit2Var( Vec_IntEntryLast( vLits ) );
+ while ( MaxVar >= Vec_IntSize( s->vActivity ) )
+ xSAT_SolverAddVariable( s, 1 );
+
+ j = 0;
+ PrevLit = LitUndef;
+ Vec_IntForEachEntry( vLits, Lit, i )
+ {
+ if ( Lit == xSAT_NegLit( PrevLit ) || Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lit ) ) == xSAT_LitSign( Lit ) )
+ return true;
+ else if ( Lit != PrevLit && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lit ) ) == VarX )
+ {
+ PrevLit = Lit;
+ Vec_IntWriteEntry( vLits, j++, Lit );
+ }
+ }
+ Vec_IntShrink( vLits, j );
+
+ if ( Vec_IntSize( vLits ) == 0 )
+ return false;
+ if ( Vec_IntSize( vLits ) == 1 )
+ {
+ xSAT_SolverEnqueue( s, Vec_IntEntry( vLits, 0 ), CRefUndef );
+ return ( xSAT_SolverPropagate( s ) == CRefUndef );
+ }
+
+ xSAT_SolverClaNew( s, vLits, 0 );
+ return true;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int xSAT_SolverSolve( xSAT_Solver_t* s )
+{
+ char status = LBoolUndef;
+
+ assert(s);
+ if ( s->Config.fVerbose )
+ {
+ printf( "==========================================[ BLACK MAGIC ]================================================\n" );
+ printf( "| | | |\n" );
+ printf( "| - Restarts: | - Reduce Clause DB: | - Minimize Asserting: |\n" );
+ printf( "| * LBD Queue : %6d | * First : %6d | * size < %3d |\n", s->Config.nSizeLBDQueue, s->Config.nConfFirstReduce, 0 );
+ printf( "| * Trail Queue : %6d | * Inc : %6d | * lbd < %3d |\n", s->Config.nSizeTrailQueue, s->Config.nIncReduce, 0 );
+ printf( "| * K : %6.2f | * Special : %6d | |\n", s->Config.K, s->Config.nSpecialIncReduce );
+ printf( "| * R : %6.2f | * Protected : (lbd)< %2d | |\n", s->Config.R, s->Config.nLBDFrozenClause );
+ printf( "| | | |\n" );
+ printf( "=========================================================================================================\n" );
+ }
+
+ while ( status == LBoolUndef )
+ status = xSAT_SolverSearch( s );
+
+ if ( s->Config.fVerbose )
+ printf( "=========================================================================================================\n" );
+
+ xSAT_SolverCancelUntil( s, 0 );
+ return status;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void xSAT_SolverPrintStats( xSAT_Solver_t * s )
+{
+ printf( "starts : %10d\n", s->Stats.nStarts );
+ printf( "conflicts : %10ld\n", s->Stats.nConflicts );
+ printf( "decisions : %10ld\n", s->Stats.nDecisions );
+ printf( "propagations : %10ld\n", s->Stats.nPropagations );
+}
+
+ABC_NAMESPACE_IMPL_END
diff --git a/src/sat/xsat/xsatUtils.h b/src/sat/xsat/xsatUtils.h
new file mode 100644
index 00000000..7f774d85
--- /dev/null
+++ b/src/sat/xsat/xsatUtils.h
@@ -0,0 +1,106 @@
+/**CFile****************************************************************
+
+ FileName [xsatUtils.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [xSAT - A SAT solver written in C.
+ Read the license file for more info.]
+
+ Synopsis [Utility functions used in xSAT]
+
+ Author [Bruno Schmitt <boschmitt@inf.ufrgs.br>]
+
+ Affiliation [UC Berkeley / UFRGS]
+
+ Date [Ver. 1.0. Started - November 10, 2016.]
+
+ Revision []
+
+***********************************************************************/
+#ifndef ABC__sat__xSAT__xsatUtils_h
+#define ABC__sat__xSAT__xsatUtils_h
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+#include "misc/util/abc_global.h"
+
+ABC_NAMESPACE_HEADER_START
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_UtilSelectSort( void** pArray, int nSize, int(* CompFnct )( const void *, const void * ) )
+{
+ int i, j, iBest;
+ void* pTmp;
+
+ for ( i = 0; i < ( nSize - 1 ); i++ )
+ {
+ iBest = i;
+ for ( j = i + 1; j < nSize; j++ )
+ {
+ if ( CompFnct( pArray[j], pArray[iBest] ) )
+ iBest = j;
+ }
+ pTmp = pArray[i];
+ pArray[i] = pArray[iBest];
+ pArray[iBest] = pTmp;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void xSAT_UtilSort( void** pArray, int nSize, int(* CompFnct )( const void *, const void *) )
+{
+ if ( nSize <= 15 )
+ xSAT_UtilSelectSort( pArray, nSize, CompFnct );
+ else
+ {
+ void* pPivot = pArray[nSize / 2];
+ void* pTmp;
+ int i = -1;
+ int j = nSize;
+
+ for(;;)
+ {
+ do i++; while( CompFnct( pArray[i], pPivot ) );
+ do j--; while( CompFnct( pPivot, pArray[j] ) );
+
+ if ( i >= j )
+ break;
+
+ pTmp = pArray[i];
+ pArray[i] = pArray[j];
+ pArray[j] = pTmp;
+ }
+
+ xSAT_UtilSort( pArray, i, CompFnct );
+ xSAT_UtilSort( pArray + i, ( nSize - i ), CompFnct );
+ }
+}
+
+ABC_NAMESPACE_HEADER_END
+
+#endif
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
diff --git a/src/sat/xsat/xsatWatchList.h b/src/sat/xsat/xsatWatchList.h
new file mode 100644
index 00000000..284be100
--- /dev/null
+++ b/src/sat/xsat/xsatWatchList.h
@@ -0,0 +1,269 @@
+/**CFile****************************************************************
+
+ FileName [xsatWatchList.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [xSAT - A SAT solver written in C.
+ Read the license file for more info.]
+
+ Synopsis [Watch list and its related structures implementation]
+
+ Author [Bruno Schmitt <boschmitt@inf.ufrgs.br>]
+
+ Affiliation [UC Berkeley / UFRGS]
+
+ Date [Ver. 1.0. Started - November 10, 2016.]
+
+ Revision []
+
+***********************************************************************/
+#ifndef ABC__sat__xSAT__xsatWatchList_h
+#define ABC__sat__xSAT__xsatWatchList_h
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+#include "misc/util/abc_global.h"
+
+ABC_NAMESPACE_HEADER_START
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+typedef struct xSAT_Watcher_t_ xSAT_Watcher_t;
+struct xSAT_Watcher_t_
+{
+ unsigned CRef;
+ int Blocker;
+};
+
+typedef struct xSAT_WatchList_t_ xSAT_WatchList_t;
+struct xSAT_WatchList_t_
+{
+ int nCap;
+ int nSize;
+ xSAT_Watcher_t * pArray;
+};
+
+typedef struct xSAT_VecWatchList_t_ xSAT_VecWatchList_t;
+struct xSAT_VecWatchList_t_
+{
+ int nCap;
+ int nSize;
+ xSAT_WatchList_t * pArray;
+};
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_WatchListFree( xSAT_WatchList_t * v )
+{
+ if ( v->pArray )
+ ABC_FREE( v->pArray );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int xSAT_WatchListSize( xSAT_WatchList_t * v )
+{
+ return v->nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_WatchListShrink( xSAT_WatchList_t * v, int k )
+{
+ assert(k <= v->nSize);
+ v->nSize = k;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_WatchListPush( xSAT_WatchList_t * v, xSAT_Watcher_t e )
+{
+ assert( v );
+ if ( v->nSize == v->nCap )
+ {
+ int newsize = ( v->nCap < 4 ) ? 4 : ( v->nCap / 2 ) * 3;
+
+ v->pArray = ABC_REALLOC( xSAT_Watcher_t, v->pArray, newsize );
+ if ( v->pArray == NULL )
+ {
+ printf( "Failed to realloc memory from %.1f MB to %.1f MB.\n",
+ 1.0 * v->nCap / (1<<20), 1.0 * newsize / (1<<20) );
+ fflush( stdout );
+ }
+ v->nCap = newsize;
+ }
+
+ v->pArray[v->nSize++] = e;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline xSAT_Watcher_t* xSAT_WatchListArray( xSAT_WatchList_t * v )
+{
+ return v->pArray;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_WatchListRemove( xSAT_WatchList_t * v, unsigned CRef )
+{
+ xSAT_Watcher_t* ws = xSAT_WatchListArray(v);
+ int j = 0;
+
+ for ( ; ws[j].CRef != CRef; j++ );
+ assert( j < xSAT_WatchListSize( v ) );
+ memmove( v->pArray + j, v->pArray + j + 1, ( v->nSize - j - 1 ) * sizeof( xSAT_Watcher_t ) );
+ v->nSize -= 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline xSAT_VecWatchList_t * xSAT_VecWatchListAlloc( int nCap )
+{
+ xSAT_VecWatchList_t * v = ABC_ALLOC( xSAT_VecWatchList_t, 1 );
+
+ v->nCap = 4;
+ v->nSize = 0;
+ v->pArray = ( xSAT_WatchList_t * ) ABC_CALLOC(xSAT_WatchList_t, sizeof( xSAT_WatchList_t ) * v->nCap);
+ return v;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_VecWatchListFree( xSAT_VecWatchList_t* v )
+{
+ int i;
+ for( i = 0; i < v->nSize; i++ )
+ xSAT_WatchListFree( v->pArray + i );
+
+ ABC_FREE( v->pArray );
+ ABC_FREE( v );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_VecWatchListPush( xSAT_VecWatchList_t* v )
+{
+ if ( v->nSize == v->nCap )
+ {
+ int newsize = (v->nCap < 4) ? v->nCap * 2 : (v->nCap / 2) * 3;
+
+ v->pArray = ABC_REALLOC( xSAT_WatchList_t, v->pArray, newsize );
+ memset( v->pArray + v->nCap, 0, sizeof( xSAT_WatchList_t ) * ( newsize - v->nCap ) );
+ if ( v->pArray == NULL )
+ {
+ printf( "Failed to realloc memory from %.1f MB to %.1f MB.\n",
+ 1.0 * v->nCap / (1<<20), 1.0 * newsize / (1<<20) );
+ fflush( stdout );
+ }
+ v->nCap = newsize;
+ }
+
+ v->nSize++;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline xSAT_WatchList_t * xSAT_VecWatchListEntry( xSAT_VecWatchList_t* v, int iEntry )
+{
+ assert( iEntry < v->nCap );
+ assert( iEntry < v->nSize );
+ return v->pArray + iEntry;
+}
+
+ABC_NAMESPACE_HEADER_END
+
+#endif