summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2005-08-06 08:01:00 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2005-08-06 08:01:00 -0700
commitd0e834d1a615f8e0e9d04c2ac97811f63562bd0b (patch)
tree0973181bfb5ee7d556cc95bd640de16fee771e89
parent888e5bed5d7f56a5d86d91a6e8e88f3e5a3454dc (diff)
downloadabc-d0e834d1a615f8e0e9d04c2ac97811f63562bd0b.tar.gz
abc-d0e834d1a615f8e0e9d04c2ac97811f63562bd0b.tar.bz2
abc-d0e834d1a615f8e0e9d04c2ac97811f63562bd0b.zip
Version abc50806
-rw-r--r--abc.dsp68
-rw-r--r--abc.optbin52736 -> 52736 bytes
-rw-r--r--abc.plg1431
-rw-r--r--abc.rc2
-rw-r--r--src/base/abc/abc.c207
-rw-r--r--src/base/abc/abc.h1
-rw-r--r--src/base/abc/abcAttach.c9
-rw-r--r--src/base/abc/abcDfs.c7
-rw-r--r--src/base/abc/abcFxu.c262
-rw-r--r--src/base/abc/abcMap.c269
-rw-r--r--src/base/abc/abcNetlist.c7
-rw-r--r--src/base/abc/abcPrint.c2
-rw-r--r--src/base/abc/abcRenode.c2
-rw-r--r--src/base/abc/abcSop.c31
-rw-r--r--src/base/abc/abcStrash.c1
-rw-r--r--src/base/abc/abcUtil.c5
-rw-r--r--src/base/abc/abc_.c47
-rw-r--r--src/map/fpga/fpgaCore.c12
-rw-r--r--src/map/fpga/fpgaInt.h2
-rw-r--r--src/map/fpga/fpgaMatch.c106
-rw-r--r--src/map/fpga/fpgaTime.c28
-rw-r--r--src/map/fpga/fpgaUtils.c26
-rw-r--r--src/map/mapper/mapper.h3
-rw-r--r--src/map/mapper/mapperCore.c16
-rw-r--r--src/map/mapper/mapperCreate.c9
-rw-r--r--src/map/mapper/mapperCut.c28
-rw-r--r--src/map/mapper/mapperInt.h9
-rw-r--r--src/map/mapper/mapperTruth.c359
-rw-r--r--src/opt/fxu/fxu.c260
-rw-r--r--src/opt/fxu/fxu.h108
-rw-r--r--src/opt/fxu/fxuCreate.c425
-rw-r--r--src/opt/fxu/fxuHeapD.c445
-rw-r--r--src/opt/fxu/fxuHeapS.c444
-rw-r--r--src/opt/fxu/fxuInt.h541
-rw-r--r--src/opt/fxu/fxuList.c522
-rw-r--r--src/opt/fxu/fxuMatrix.c382
-rw-r--r--src/opt/fxu/fxuPair.c555
-rw-r--r--src/opt/fxu/fxuPrint.c195
-rw-r--r--src/opt/fxu/fxuReduce.c194
-rw-r--r--src/opt/fxu/fxuSelect.c603
-rw-r--r--src/opt/fxu/fxuSingle.c166
-rw-r--r--src/opt/fxu/fxuUpdate.c802
-rw-r--r--src/opt/fxu/module.make12
43 files changed, 7344 insertions, 1259 deletions
diff --git a/abc.dsp b/abc.dsp
index 7b906c53..d5555552 100644
--- a/abc.dsp
+++ b/abc.dsp
@@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /W3 /GX /O2 /I "src\base\abc" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\sop\mvc" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\fxa" /I "src\map\fpga" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\util" /I "src\misc\vec" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "HAVE_ASSERT_H" /FR /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "src\base\abc" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\bdd\dsd" /I "src\bdd\reo" /I "src\sop\mvc" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\fxa" /I "src\opt\fxu" /I "src\map\fpga" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\util" /I "src\misc\vec" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "HAVE_ASSERT_H" /FR /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
@@ -66,7 +66,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "src\base\abc" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\sop\mvc" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\fxa" /I "src\map\fpga" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\util" /I "src\misc\vec" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "HAVE_ASSERT_H" /FR /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "src\base\abc" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\bdd\dsd" /I "src\bdd\reo" /I "src\sop\mvc" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\fxa" /I "src\opt\fxu" /I "src\map\fpga" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\util" /I "src\misc\vec" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "HAVE_ASSERT_H" /FR /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
@@ -145,6 +145,10 @@ SOURCE=.\src\base\abc\abcFunc.c
# End Source File
# Begin Source File
+SOURCE=.\src\base\abc\abcFxu.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\base\abc\abcInt.h
# End Source File
# Begin Source File
@@ -964,6 +968,66 @@ SOURCE=.\src\sat\fraig\fraigVec.c
# PROP Default_Filter ""
# End Group
+# Begin Group "fxu"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\src\opt\fxu\fxu.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\opt\fxu\fxu.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\opt\fxu\fxuCreate.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\opt\fxu\fxuHeapD.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\opt\fxu\fxuHeapS.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\opt\fxu\fxuInt.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\opt\fxu\fxuList.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\opt\fxu\fxuMatrix.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\opt\fxu\fxuPair.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\opt\fxu\fxuPrint.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\opt\fxu\fxuReduce.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\opt\fxu\fxuSelect.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\opt\fxu\fxuSingle.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\opt\fxu\fxuUpdate.c
+# End Source File
+# End Group
# End Group
# Begin Group "map"
diff --git a/abc.opt b/abc.opt
index ca1164e8..06e5c5bd 100644
--- a/abc.opt
+++ b/abc.opt
Binary files differ
diff --git a/abc.plg b/abc.plg
index 18db3d30..1c54d293 100644
--- a/abc.plg
+++ b/abc.plg
@@ -3,960 +3,515 @@
<pre>
<h1>Build Log</h1>
<h3>
---------------------Configuration: abc - Win32 Release--------------------
+--------------------Configuration: abc - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
-Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP27C8.tmp" with contents
+Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP448.tmp" with contents
[
-/nologo /ML /W3 /GX /O2 /I "src\base\abc" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\sop\mvc" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\fxa" /I "src\map\fpga" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\util" /I "src\misc\vec" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "HAVE_ASSERT_H" /FR"Release/" /Fp"Release/abc.pch" /YX /Fo"Release/" /Fd"Release/" /FD /c
-"C:\_projects\abc\src\base\abc\abc.c"
-"C:\_projects\abc\src\base\abc\abcAig.c"
-"C:\_projects\abc\src\base\abc\abcAttach.c"
-"C:\_projects\abc\src\base\abc\abcCheck.c"
-"C:\_projects\abc\src\base\abc\abcCollapse.c"
-"C:\_projects\abc\src\base\abc\abcCreate.c"
-"C:\_projects\abc\src\base\abc\abcDfs.c"
-"C:\_projects\abc\src\base\abc\abcDsd.c"
-"C:\_projects\abc\src\base\abc\abcFanio.c"
-"C:\_projects\abc\src\base\abc\abcFpga.c"
-"C:\_projects\abc\src\base\abc\abcFraig.c"
-"C:\_projects\abc\src\base\abc\abcFunc.c"
-"C:\_projects\abc\src\base\abc\abcLatch.c"
-"C:\_projects\abc\src\base\abc\abcMap.c"
-"C:\_projects\abc\src\base\abc\abcMinBase.c"
-"C:\_projects\abc\src\base\abc\abcMiter.c"
-"C:\_projects\abc\src\base\abc\abcNames.c"
-"C:\_projects\abc\src\base\abc\abcNetlist.c"
-"C:\_projects\abc\src\base\abc\abcPrint.c"
-"C:\_projects\abc\src\base\abc\abcRefs.c"
-"C:\_projects\abc\src\base\abc\abcRenode.c"
-"C:\_projects\abc\src\base\abc\abcSat.c"
-"C:\_projects\abc\src\base\abc\abcSop.c"
-"C:\_projects\abc\src\base\abc\abcStrash.c"
-"C:\_projects\abc\src\base\abc\abcSweep.c"
-"C:\_projects\abc\src\base\abc\abcTiming.c"
-"C:\_projects\abc\src\base\abc\abcUtil.c"
-"C:\_projects\abc\src\base\abc\abcVerify.c"
-"C:\_projects\abc\src\base\cmd\cmd.c"
-"C:\_projects\abc\src\base\cmd\cmdAlias.c"
-"C:\_projects\abc\src\base\cmd\cmdApi.c"
-"C:\_projects\abc\src\base\cmd\cmdFlag.c"
-"C:\_projects\abc\src\base\cmd\cmdHist.c"
-"C:\_projects\abc\src\base\cmd\cmdUtils.c"
-"C:\_projects\abc\src\base\io\io.c"
-"C:\_projects\abc\src\base\io\ioRead.c"
-"C:\_projects\abc\src\base\io\ioReadBench.c"
-"C:\_projects\abc\src\base\io\ioReadBlif.c"
-"C:\_projects\abc\src\base\io\ioReadVerilog.c"
-"C:\_projects\abc\src\base\io\ioWriteBench.c"
-"C:\_projects\abc\src\base\io\ioWriteBlif.c"
-"C:\_projects\abc\src\base\io\ioWriteBlifLogic.c"
-"C:\_projects\abc\src\base\io\ioWriteCnf.c"
-"C:\_projects\abc\src\base\io\ioWriteGate.c"
-"C:\_projects\abc\src\base\main\main.c"
-"C:\_projects\abc\src\base\main\mainFrame.c"
-"C:\_projects\abc\src\base\main\mainInit.c"
-"C:\_projects\abc\src\base\main\mainUtils.c"
-"C:\_projects\abc\src\bdd\cudd\cuddAddAbs.c"
-"C:\_projects\abc\src\bdd\cudd\cuddAddApply.c"
-"C:\_projects\abc\src\bdd\cudd\cuddAddFind.c"
-"C:\_projects\abc\src\bdd\cudd\cuddAddInv.c"
-"C:\_projects\abc\src\bdd\cudd\cuddAddIte.c"
-"C:\_projects\abc\src\bdd\cudd\cuddAddNeg.c"
-"C:\_projects\abc\src\bdd\cudd\cuddAddWalsh.c"
-"C:\_projects\abc\src\bdd\cudd\cuddAndAbs.c"
-"C:\_projects\abc\src\bdd\cudd\cuddAnneal.c"
-"C:\_projects\abc\src\bdd\cudd\cuddApa.c"
-"C:\_projects\abc\src\bdd\cudd\cuddAPI.c"
-"C:\_projects\abc\src\bdd\cudd\cuddApprox.c"
-"C:\_projects\abc\src\bdd\cudd\cuddBddAbs.c"
-"C:\_projects\abc\src\bdd\cudd\cuddBddCorr.c"
-"C:\_projects\abc\src\bdd\cudd\cuddBddIte.c"
-"C:\_projects\abc\src\bdd\cudd\cuddBridge.c"
-"C:\_projects\abc\src\bdd\cudd\cuddCache.c"
-"C:\_projects\abc\src\bdd\cudd\cuddCheck.c"
-"C:\_projects\abc\src\bdd\cudd\cuddClip.c"
-"C:\_projects\abc\src\bdd\cudd\cuddCof.c"
-"C:\_projects\abc\src\bdd\cudd\cuddCompose.c"
-"C:\_projects\abc\src\bdd\cudd\cuddDecomp.c"
-"C:\_projects\abc\src\bdd\cudd\cuddEssent.c"
-"C:\_projects\abc\src\bdd\cudd\cuddExact.c"
-"C:\_projects\abc\src\bdd\cudd\cuddExport.c"
-"C:\_projects\abc\src\bdd\cudd\cuddGenCof.c"
-"C:\_projects\abc\src\bdd\cudd\cuddGenetic.c"
-"C:\_projects\abc\src\bdd\cudd\cuddGroup.c"
-"C:\_projects\abc\src\bdd\cudd\cuddHarwell.c"
-"C:\_projects\abc\src\bdd\cudd\cuddInit.c"
-"C:\_projects\abc\src\bdd\cudd\cuddInteract.c"
-"C:\_projects\abc\src\bdd\cudd\cuddLCache.c"
-"C:\_projects\abc\src\bdd\cudd\cuddLevelQ.c"
-"C:\_projects\abc\src\bdd\cudd\cuddLinear.c"
-"C:\_projects\abc\src\bdd\cudd\cuddLiteral.c"
-"C:\_projects\abc\src\bdd\cudd\cuddMatMult.c"
-"C:\_projects\abc\src\bdd\cudd\cuddPriority.c"
-"C:\_projects\abc\src\bdd\cudd\cuddRead.c"
-"C:\_projects\abc\src\bdd\cudd\cuddRef.c"
-"C:\_projects\abc\src\bdd\cudd\cuddReorder.c"
-"C:\_projects\abc\src\bdd\cudd\cuddSat.c"
-"C:\_projects\abc\src\bdd\cudd\cuddSign.c"
-"C:\_projects\abc\src\bdd\cudd\cuddSolve.c"
-"C:\_projects\abc\src\bdd\cudd\cuddSplit.c"
-"C:\_projects\abc\src\bdd\cudd\cuddSubsetHB.c"
-"C:\_projects\abc\src\bdd\cudd\cuddSubsetSP.c"
-"C:\_projects\abc\src\bdd\cudd\cuddSymmetry.c"
-"C:\_projects\abc\src\bdd\cudd\cuddTable.c"
-"C:\_projects\abc\src\bdd\cudd\cuddUtil.c"
-"C:\_projects\abc\src\bdd\cudd\cuddWindow.c"
-"C:\_projects\abc\src\bdd\cudd\cuddZddCount.c"
-"C:\_projects\abc\src\bdd\cudd\cuddZddFuncs.c"
-"C:\_projects\abc\src\bdd\cudd\cuddZddGroup.c"
-"C:\_projects\abc\src\bdd\cudd\cuddZddIsop.c"
-"C:\_projects\abc\src\bdd\cudd\cuddZddLin.c"
-"C:\_projects\abc\src\bdd\cudd\cuddZddMisc.c"
-"C:\_projects\abc\src\bdd\cudd\cuddZddPort.c"
-"C:\_projects\abc\src\bdd\cudd\cuddZddReord.c"
-"C:\_projects\abc\src\bdd\cudd\cuddZddSetop.c"
-"C:\_projects\abc\src\bdd\cudd\cuddZddSymm.c"
-"C:\_projects\abc\src\bdd\cudd\cuddZddUtil.c"
-"C:\_projects\abc\src\bdd\epd\epd.c"
-"C:\_projects\abc\src\bdd\mtr\mtrBasic.c"
-"C:\_projects\abc\src\bdd\mtr\mtrGroup.c"
-"C:\_projects\abc\src\bdd\parse\parseCore.c"
-"C:\_projects\abc\src\bdd\parse\parseStack.c"
-"C:\_projects\abc\src\bdd\dsd\dsdApi.c"
-"C:\_projects\abc\src\bdd\dsd\dsdCheck.c"
-"C:\_projects\abc\src\bdd\dsd\dsdLocal.c"
-"C:\_projects\abc\src\bdd\dsd\dsdMan.c"
-"C:\_projects\abc\src\bdd\dsd\dsdProc.c"
-"C:\_projects\abc\src\bdd\dsd\dsdTree.c"
-"C:\_projects\abc\src\bdd\reo\reoApi.c"
-"C:\_projects\abc\src\bdd\reo\reoCore.c"
-"C:\_projects\abc\src\bdd\reo\reoProfile.c"
-"C:\_projects\abc\src\bdd\reo\reoSift.c"
-"C:\_projects\abc\src\bdd\reo\reoSwap.c"
-"C:\_projects\abc\src\bdd\reo\reoTest.c"
-"C:\_projects\abc\src\bdd\reo\reoTransfer.c"
-"C:\_projects\abc\src\bdd\reo\reoUnits.c"
-"C:\_projects\abc\src\sop\mvc\mvc.c"
-"C:\_projects\abc\src\sop\mvc\mvcApi.c"
-"C:\_projects\abc\src\sop\mvc\mvcCompare.c"
-"C:\_projects\abc\src\sop\mvc\mvcContain.c"
-"C:\_projects\abc\src\sop\mvc\mvcCover.c"
-"C:\_projects\abc\src\sop\mvc\mvcCube.c"
-"C:\_projects\abc\src\sop\mvc\mvcDivide.c"
-"C:\_projects\abc\src\sop\mvc\mvcDivisor.c"
-"C:\_projects\abc\src\sop\mvc\mvcList.c"
-"C:\_projects\abc\src\sop\mvc\mvcLits.c"
-"C:\_projects\abc\src\sop\mvc\mvcMan.c"
-"C:\_projects\abc\src\sop\mvc\mvcOpAlg.c"
-"C:\_projects\abc\src\sop\mvc\mvcOpBool.c"
-"C:\_projects\abc\src\sop\mvc\mvcPrint.c"
-"C:\_projects\abc\src\sop\mvc\mvcSort.c"
-"C:\_projects\abc\src\sop\mvc\mvcUtils.c"
-"C:\_projects\abc\src\sop\ft\ftFactor.c"
-"C:\_projects\abc\src\sop\ft\ftPrint.c"
-"C:\_projects\abc\src\sat\asat\added.c"
-"C:\_projects\abc\src\sat\asat\solver.c"
-"C:\_projects\abc\src\sat\msat\msatActivity.c"
-"C:\_projects\abc\src\sat\msat\msatClause.c"
-"C:\_projects\abc\src\sat\msat\msatClauseVec.c"
-"C:\_projects\abc\src\sat\msat\msatMem.c"
-"C:\_projects\abc\src\sat\msat\msatOrderJ.c"
-"C:\_projects\abc\src\sat\msat\msatQueue.c"
-"C:\_projects\abc\src\sat\msat\msatRead.c"
-"C:\_projects\abc\src\sat\msat\msatSolverApi.c"
-"C:\_projects\abc\src\sat\msat\msatSolverCore.c"
-"C:\_projects\abc\src\sat\msat\msatSolverIo.c"
-"C:\_projects\abc\src\sat\msat\msatSolverSearch.c"
-"C:\_projects\abc\src\sat\msat\msatSort.c"
-"C:\_projects\abc\src\sat\msat\msatVec.c"
-"C:\_projects\abc\src\sat\fraig\fraigApi.c"
-"C:\_projects\abc\src\sat\fraig\fraigCanon.c"
-"C:\_projects\abc\src\sat\fraig\fraigFanout.c"
-"C:\_projects\abc\src\sat\fraig\fraigFeed.c"
-"C:\_projects\abc\src\sat\fraig\fraigMan.c"
-"C:\_projects\abc\src\sat\fraig\fraigMem.c"
-"C:\_projects\abc\src\sat\fraig\fraigNode.c"
-"C:\_projects\abc\src\sat\fraig\fraigPrime.c"
-"C:\_projects\abc\src\sat\fraig\fraigSat.c"
-"C:\_projects\abc\src\sat\fraig\fraigTable.c"
-"C:\_projects\abc\src\sat\fraig\fraigUtil.c"
-"C:\_projects\abc\src\sat\fraig\fraigVec.c"
-"C:\_projects\abc\src\map\fpga\fpga.c"
-"C:\_projects\abc\src\map\fpga\fpgaCore.c"
-"C:\_projects\abc\src\map\fpga\fpgaCreate.c"
-"C:\_projects\abc\src\map\fpga\fpgaCut.c"
-"C:\_projects\abc\src\map\fpga\fpgaCutUtils.c"
-"C:\_projects\abc\src\map\fpga\fpgaFanout.c"
-"C:\_projects\abc\src\map\fpga\fpgaLib.c"
-"C:\_projects\abc\src\map\fpga\fpgaMatch.c"
-"C:\_projects\abc\src\map\fpga\fpgaTime.c"
-"C:\_projects\abc\src\map\fpga\fpgaTruth.c"
-"C:\_projects\abc\src\map\fpga\fpgaUtils.c"
-"C:\_projects\abc\src\map\fpga\fpgaVec.c"
-"C:\_projects\abc\src\map\mapper\mapper.c"
-"C:\_projects\abc\src\map\mapper\mapperCanon.c"
-"C:\_projects\abc\src\map\mapper\mapperCore.c"
-"C:\_projects\abc\src\map\mapper\mapperCreate.c"
-"C:\_projects\abc\src\map\mapper\mapperCut.c"
-"C:\_projects\abc\src\map\mapper\mapperCutUtils.c"
-"C:\_projects\abc\src\map\mapper\mapperFanout.c"
-"C:\_projects\abc\src\map\mapper\mapperLib.c"
-"C:\_projects\abc\src\map\mapper\mapperMatch.c"
-"C:\_projects\abc\src\map\mapper\mapperRefs.c"
-"C:\_projects\abc\src\map\mapper\mapperSuper.c"
-"C:\_projects\abc\src\map\mapper\mapperTable.c"
-"C:\_projects\abc\src\map\mapper\mapperTime.c"
-"C:\_projects\abc\src\map\mapper\mapperTree.c"
-"C:\_projects\abc\src\map\mapper\mapperTruth.c"
-"C:\_projects\abc\src\map\mapper\mapperUtils.c"
-"C:\_projects\abc\src\map\mapper\mapperVec.c"
-"C:\_projects\abc\src\map\mio\mio.c"
-"C:\_projects\abc\src\map\mio\mioApi.c"
-"C:\_projects\abc\src\map\mio\mioFunc.c"
-"C:\_projects\abc\src\map\mio\mioRead.c"
-"C:\_projects\abc\src\map\mio\mioUtils.c"
-"C:\_projects\abc\src\map\super\super.c"
-"C:\_projects\abc\src\map\super\superAnd.c"
-"C:\_projects\abc\src\map\super\superGate.c"
-"C:\_projects\abc\src\map\super\superWrite.c"
-"C:\_projects\abc\src\misc\extra\extraUtilBdd.c"
-"C:\_projects\abc\src\misc\extra\extraUtilFile.c"
-"C:\_projects\abc\src\misc\extra\extraUtilMemory.c"
-"C:\_projects\abc\src\misc\extra\extraUtilMisc.c"
-"C:\_projects\abc\src\misc\extra\extraUtilProgress.c"
-"C:\_projects\abc\src\misc\extra\extraUtilReader.c"
-"C:\_projects\abc\src\misc\st\st.c"
-"C:\_projects\abc\src\misc\st\stmm.c"
-"C:\_projects\abc\src\misc\util\cpu_stats.c"
-"C:\_projects\abc\src\misc\util\cpu_time.c"
-"C:\_projects\abc\src\misc\util\datalimit.c"
-"C:\_projects\abc\src\misc\util\getopt.c"
-"C:\_projects\abc\src\misc\util\pathsearch.c"
-"C:\_projects\abc\src\misc\util\safe_mem.c"
-"C:\_projects\abc\src\misc\util\strsav.c"
-"C:\_projects\abc\src\misc\util\texpand.c"
+/nologo /MLd /W3 /Gm /GX /ZI /Od /I "src\base\abc" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\bdd\dsd" /I "src\bdd\reo" /I "src\sop\mvc" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\fxa" /I "src\opt\fxu" /I "src\map\fpga" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\util" /I "src\misc\vec" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "HAVE_ASSERT_H" /FR"Debug/" /Fp"Debug/abc.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c
+"C:\_projects\abc\src\opt\fxu\fxu.c"
]
-Creating command line "cl.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP27C8.tmp"
-Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP27C9.tmp" with contents
+Creating command line "cl.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP448.tmp"
+Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP449.tmp" with contents
[
-kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /pdb:"Release/abc.pdb" /machine:I386 /out:"_TEST/abc.exe"
-.\Release\abc.obj
-.\Release\abcAig.obj
-.\Release\abcAttach.obj
-.\Release\abcCheck.obj
-.\Release\abcCollapse.obj
-.\Release\abcCreate.obj
-.\Release\abcDfs.obj
-.\Release\abcDsd.obj
-.\Release\abcFanio.obj
-.\Release\abcFpga.obj
-.\Release\abcFraig.obj
-.\Release\abcFunc.obj
-.\Release\abcLatch.obj
-.\Release\abcMap.obj
-.\Release\abcMinBase.obj
-.\Release\abcMiter.obj
-.\Release\abcNames.obj
-.\Release\abcNetlist.obj
-.\Release\abcPrint.obj
-.\Release\abcRefs.obj
-.\Release\abcRenode.obj
-.\Release\abcSat.obj
-.\Release\abcSop.obj
-.\Release\abcStrash.obj
-.\Release\abcSweep.obj
-.\Release\abcTiming.obj
-.\Release\abcUtil.obj
-.\Release\abcVerify.obj
-.\Release\cmd.obj
-.\Release\cmdAlias.obj
-.\Release\cmdApi.obj
-.\Release\cmdFlag.obj
-.\Release\cmdHist.obj
-.\Release\cmdUtils.obj
-.\Release\io.obj
-.\Release\ioRead.obj
-.\Release\ioReadBench.obj
-.\Release\ioReadBlif.obj
-.\Release\ioReadVerilog.obj
-.\Release\ioWriteBench.obj
-.\Release\ioWriteBlif.obj
-.\Release\ioWriteBlifLogic.obj
-.\Release\ioWriteCnf.obj
-.\Release\ioWriteGate.obj
-.\Release\main.obj
-.\Release\mainFrame.obj
-.\Release\mainInit.obj
-.\Release\mainUtils.obj
-.\Release\cuddAddAbs.obj
-.\Release\cuddAddApply.obj
-.\Release\cuddAddFind.obj
-.\Release\cuddAddInv.obj
-.\Release\cuddAddIte.obj
-.\Release\cuddAddNeg.obj
-.\Release\cuddAddWalsh.obj
-.\Release\cuddAndAbs.obj
-.\Release\cuddAnneal.obj
-.\Release\cuddApa.obj
-.\Release\cuddAPI.obj
-.\Release\cuddApprox.obj
-.\Release\cuddBddAbs.obj
-.\Release\cuddBddCorr.obj
-.\Release\cuddBddIte.obj
-.\Release\cuddBridge.obj
-.\Release\cuddCache.obj
-.\Release\cuddCheck.obj
-.\Release\cuddClip.obj
-.\Release\cuddCof.obj
-.\Release\cuddCompose.obj
-.\Release\cuddDecomp.obj
-.\Release\cuddEssent.obj
-.\Release\cuddExact.obj
-.\Release\cuddExport.obj
-.\Release\cuddGenCof.obj
-.\Release\cuddGenetic.obj
-.\Release\cuddGroup.obj
-.\Release\cuddHarwell.obj
-.\Release\cuddInit.obj
-.\Release\cuddInteract.obj
-.\Release\cuddLCache.obj
-.\Release\cuddLevelQ.obj
-.\Release\cuddLinear.obj
-.\Release\cuddLiteral.obj
-.\Release\cuddMatMult.obj
-.\Release\cuddPriority.obj
-.\Release\cuddRead.obj
-.\Release\cuddRef.obj
-.\Release\cuddReorder.obj
-.\Release\cuddSat.obj
-.\Release\cuddSign.obj
-.\Release\cuddSolve.obj
-.\Release\cuddSplit.obj
-.\Release\cuddSubsetHB.obj
-.\Release\cuddSubsetSP.obj
-.\Release\cuddSymmetry.obj
-.\Release\cuddTable.obj
-.\Release\cuddUtil.obj
-.\Release\cuddWindow.obj
-.\Release\cuddZddCount.obj
-.\Release\cuddZddFuncs.obj
-.\Release\cuddZddGroup.obj
-.\Release\cuddZddIsop.obj
-.\Release\cuddZddLin.obj
-.\Release\cuddZddMisc.obj
-.\Release\cuddZddPort.obj
-.\Release\cuddZddReord.obj
-.\Release\cuddZddSetop.obj
-.\Release\cuddZddSymm.obj
-.\Release\cuddZddUtil.obj
-.\Release\epd.obj
-.\Release\mtrBasic.obj
-.\Release\mtrGroup.obj
-.\Release\parseCore.obj
-.\Release\parseStack.obj
-.\Release\dsdApi.obj
-.\Release\dsdCheck.obj
-.\Release\dsdLocal.obj
-.\Release\dsdMan.obj
-.\Release\dsdProc.obj
-.\Release\dsdTree.obj
-.\Release\reoApi.obj
-.\Release\reoCore.obj
-.\Release\reoProfile.obj
-.\Release\reoSift.obj
-.\Release\reoSwap.obj
-.\Release\reoTest.obj
-.\Release\reoTransfer.obj
-.\Release\reoUnits.obj
-.\Release\mvc.obj
-.\Release\mvcApi.obj
-.\Release\mvcCompare.obj
-.\Release\mvcContain.obj
-.\Release\mvcCover.obj
-.\Release\mvcCube.obj
-.\Release\mvcDivide.obj
-.\Release\mvcDivisor.obj
-.\Release\mvcList.obj
-.\Release\mvcLits.obj
-.\Release\mvcMan.obj
-.\Release\mvcOpAlg.obj
-.\Release\mvcOpBool.obj
-.\Release\mvcPrint.obj
-.\Release\mvcSort.obj
-.\Release\mvcUtils.obj
-.\Release\ftFactor.obj
-.\Release\ftPrint.obj
-.\Release\added.obj
-.\Release\solver.obj
-.\Release\msatActivity.obj
-.\Release\msatClause.obj
-.\Release\msatClauseVec.obj
-.\Release\msatMem.obj
-.\Release\msatOrderJ.obj
-.\Release\msatQueue.obj
-.\Release\msatRead.obj
-.\Release\msatSolverApi.obj
-.\Release\msatSolverCore.obj
-.\Release\msatSolverIo.obj
-.\Release\msatSolverSearch.obj
-.\Release\msatSort.obj
-.\Release\msatVec.obj
-.\Release\fraigApi.obj
-.\Release\fraigCanon.obj
-.\Release\fraigFanout.obj
-.\Release\fraigFeed.obj
-.\Release\fraigMan.obj
-.\Release\fraigMem.obj
-.\Release\fraigNode.obj
-.\Release\fraigPrime.obj
-.\Release\fraigSat.obj
-.\Release\fraigTable.obj
-.\Release\fraigUtil.obj
-.\Release\fraigVec.obj
-.\Release\fpga.obj
-.\Release\fpgaCore.obj
-.\Release\fpgaCreate.obj
-.\Release\fpgaCut.obj
-.\Release\fpgaCutUtils.obj
-.\Release\fpgaFanout.obj
-.\Release\fpgaLib.obj
-.\Release\fpgaMatch.obj
-.\Release\fpgaTime.obj
-.\Release\fpgaTruth.obj
-.\Release\fpgaUtils.obj
-.\Release\fpgaVec.obj
-.\Release\mapper.obj
-.\Release\mapperCanon.obj
-.\Release\mapperCore.obj
-.\Release\mapperCreate.obj
-.\Release\mapperCut.obj
-.\Release\mapperCutUtils.obj
-.\Release\mapperFanout.obj
-.\Release\mapperLib.obj
-.\Release\mapperMatch.obj
-.\Release\mapperRefs.obj
-.\Release\mapperSuper.obj
-.\Release\mapperTable.obj
-.\Release\mapperTime.obj
-.\Release\mapperTree.obj
-.\Release\mapperTruth.obj
-.\Release\mapperUtils.obj
-.\Release\mapperVec.obj
-.\Release\mio.obj
-.\Release\mioApi.obj
-.\Release\mioFunc.obj
-.\Release\mioRead.obj
-.\Release\mioUtils.obj
-.\Release\super.obj
-.\Release\superAnd.obj
-.\Release\superGate.obj
-.\Release\superWrite.obj
-.\Release\extraUtilBdd.obj
-.\Release\extraUtilFile.obj
-.\Release\extraUtilMemory.obj
-.\Release\extraUtilMisc.obj
-.\Release\extraUtilProgress.obj
-.\Release\extraUtilReader.obj
-.\Release\st.obj
-.\Release\stmm.obj
-.\Release\cpu_stats.obj
-.\Release\cpu_time.obj
-.\Release\datalimit.obj
-.\Release\getopt.obj
-.\Release\pathsearch.obj
-.\Release\safe_mem.obj
-.\Release\strsav.obj
-.\Release\texpand.obj
+kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:yes /pdb:"Debug/abc.pdb" /debug /machine:I386 /out:"_TEST/abc.exe" /pdbtype:sept
+.\Debug\abc.obj
+.\Debug\abcAig.obj
+.\Debug\abcAttach.obj
+.\Debug\abcCheck.obj
+.\Debug\abcCollapse.obj
+.\Debug\abcCreate.obj
+.\Debug\abcDfs.obj
+.\Debug\abcDsd.obj
+.\Debug\abcFanio.obj
+.\Debug\abcFpga.obj
+.\Debug\abcFraig.obj
+.\Debug\abcFunc.obj
+.\Debug\abcLatch.obj
+.\Debug\abcMap.obj
+.\Debug\abcMinBase.obj
+.\Debug\abcMiter.obj
+.\Debug\abcNames.obj
+.\Debug\abcNetlist.obj
+.\Debug\abcPrint.obj
+.\Debug\abcRefs.obj
+.\Debug\abcRenode.obj
+.\Debug\abcSat.obj
+.\Debug\abcSop.obj
+.\Debug\abcStrash.obj
+.\Debug\abcSweep.obj
+.\Debug\abcTiming.obj
+.\Debug\abcUtil.obj
+.\Debug\abcVerify.obj
+.\Debug\cmd.obj
+.\Debug\cmdAlias.obj
+.\Debug\cmdApi.obj
+.\Debug\cmdFlag.obj
+.\Debug\cmdHist.obj
+.\Debug\cmdUtils.obj
+.\Debug\io.obj
+.\Debug\ioRead.obj
+.\Debug\ioReadBench.obj
+.\Debug\ioReadBlif.obj
+.\Debug\ioReadVerilog.obj
+.\Debug\ioWriteBench.obj
+.\Debug\ioWriteBlif.obj
+.\Debug\ioWriteBlifLogic.obj
+.\Debug\ioWriteCnf.obj
+.\Debug\ioWriteGate.obj
+.\Debug\main.obj
+.\Debug\mainFrame.obj
+.\Debug\mainInit.obj
+.\Debug\mainUtils.obj
+.\Debug\cuddAddAbs.obj
+.\Debug\cuddAddApply.obj
+.\Debug\cuddAddFind.obj
+.\Debug\cuddAddInv.obj
+.\Debug\cuddAddIte.obj
+.\Debug\cuddAddNeg.obj
+.\Debug\cuddAddWalsh.obj
+.\Debug\cuddAndAbs.obj
+.\Debug\cuddAnneal.obj
+.\Debug\cuddApa.obj
+.\Debug\cuddAPI.obj
+.\Debug\cuddApprox.obj
+.\Debug\cuddBddAbs.obj
+.\Debug\cuddBddCorr.obj
+.\Debug\cuddBddIte.obj
+.\Debug\cuddBridge.obj
+.\Debug\cuddCache.obj
+.\Debug\cuddCheck.obj
+.\Debug\cuddClip.obj
+.\Debug\cuddCof.obj
+.\Debug\cuddCompose.obj
+.\Debug\cuddDecomp.obj
+.\Debug\cuddEssent.obj
+.\Debug\cuddExact.obj
+.\Debug\cuddExport.obj
+.\Debug\cuddGenCof.obj
+.\Debug\cuddGenetic.obj
+.\Debug\cuddGroup.obj
+.\Debug\cuddHarwell.obj
+.\Debug\cuddInit.obj
+.\Debug\cuddInteract.obj
+.\Debug\cuddLCache.obj
+.\Debug\cuddLevelQ.obj
+.\Debug\cuddLinear.obj
+.\Debug\cuddLiteral.obj
+.\Debug\cuddMatMult.obj
+.\Debug\cuddPriority.obj
+.\Debug\cuddRead.obj
+.\Debug\cuddRef.obj
+.\Debug\cuddReorder.obj
+.\Debug\cuddSat.obj
+.\Debug\cuddSign.obj
+.\Debug\cuddSolve.obj
+.\Debug\cuddSplit.obj
+.\Debug\cuddSubsetHB.obj
+.\Debug\cuddSubsetSP.obj
+.\Debug\cuddSymmetry.obj
+.\Debug\cuddTable.obj
+.\Debug\cuddUtil.obj
+.\Debug\cuddWindow.obj
+.\Debug\cuddZddCount.obj
+.\Debug\cuddZddFuncs.obj
+.\Debug\cuddZddGroup.obj
+.\Debug\cuddZddIsop.obj
+.\Debug\cuddZddLin.obj
+.\Debug\cuddZddMisc.obj
+.\Debug\cuddZddPort.obj
+.\Debug\cuddZddReord.obj
+.\Debug\cuddZddSetop.obj
+.\Debug\cuddZddSymm.obj
+.\Debug\cuddZddUtil.obj
+.\Debug\epd.obj
+.\Debug\mtrBasic.obj
+.\Debug\mtrGroup.obj
+.\Debug\parseCore.obj
+.\Debug\parseStack.obj
+.\Debug\dsdApi.obj
+.\Debug\dsdCheck.obj
+.\Debug\dsdLocal.obj
+.\Debug\dsdMan.obj
+.\Debug\dsdProc.obj
+.\Debug\dsdTree.obj
+.\Debug\reoApi.obj
+.\Debug\reoCore.obj
+.\Debug\reoProfile.obj
+.\Debug\reoSift.obj
+.\Debug\reoSwap.obj
+.\Debug\reoTest.obj
+.\Debug\reoTransfer.obj
+.\Debug\reoUnits.obj
+.\Debug\mvc.obj
+.\Debug\mvcApi.obj
+.\Debug\mvcCompare.obj
+.\Debug\mvcContain.obj
+.\Debug\mvcCover.obj
+.\Debug\mvcCube.obj
+.\Debug\mvcDivide.obj
+.\Debug\mvcDivisor.obj
+.\Debug\mvcList.obj
+.\Debug\mvcLits.obj
+.\Debug\mvcMan.obj
+.\Debug\mvcOpAlg.obj
+.\Debug\mvcOpBool.obj
+.\Debug\mvcPrint.obj
+.\Debug\mvcSort.obj
+.\Debug\mvcUtils.obj
+.\Debug\ftFactor.obj
+.\Debug\ftPrint.obj
+.\Debug\added.obj
+.\Debug\solver.obj
+.\Debug\msatActivity.obj
+.\Debug\msatClause.obj
+.\Debug\msatClauseVec.obj
+.\Debug\msatMem.obj
+.\Debug\msatOrderJ.obj
+.\Debug\msatQueue.obj
+.\Debug\msatRead.obj
+.\Debug\msatSolverApi.obj
+.\Debug\msatSolverCore.obj
+.\Debug\msatSolverIo.obj
+.\Debug\msatSolverSearch.obj
+.\Debug\msatSort.obj
+.\Debug\msatVec.obj
+.\Debug\fraigApi.obj
+.\Debug\fraigCanon.obj
+.\Debug\fraigFanout.obj
+.\Debug\fraigFeed.obj
+.\Debug\fraigMan.obj
+.\Debug\fraigMem.obj
+.\Debug\fraigNode.obj
+.\Debug\fraigPrime.obj
+.\Debug\fraigSat.obj
+.\Debug\fraigTable.obj
+.\Debug\fraigUtil.obj
+.\Debug\fraigVec.obj
+.\Debug\fpga.obj
+.\Debug\fpgaCore.obj
+.\Debug\fpgaCreate.obj
+.\Debug\fpgaCut.obj
+.\Debug\fpgaCutUtils.obj
+.\Debug\fpgaFanout.obj
+.\Debug\fpgaLib.obj
+.\Debug\fpgaMatch.obj
+.\Debug\fpgaTime.obj
+.\Debug\fpgaTruth.obj
+.\Debug\fpgaUtils.obj
+.\Debug\fpgaVec.obj
+.\Debug\mapper.obj
+.\Debug\mapperCanon.obj
+.\Debug\mapperCore.obj
+.\Debug\mapperCreate.obj
+.\Debug\mapperCut.obj
+.\Debug\mapperCutUtils.obj
+.\Debug\mapperFanout.obj
+.\Debug\mapperLib.obj
+.\Debug\mapperMatch.obj
+.\Debug\mapperRefs.obj
+.\Debug\mapperSuper.obj
+.\Debug\mapperTable.obj
+.\Debug\mapperTime.obj
+.\Debug\mapperTree.obj
+.\Debug\mapperTruth.obj
+.\Debug\mapperUtils.obj
+.\Debug\mapperVec.obj
+.\Debug\mio.obj
+.\Debug\mioApi.obj
+.\Debug\mioFunc.obj
+.\Debug\mioRead.obj
+.\Debug\mioUtils.obj
+.\Debug\super.obj
+.\Debug\superAnd.obj
+.\Debug\superGate.obj
+.\Debug\superWrite.obj
+.\Debug\extraUtilBdd.obj
+.\Debug\extraUtilFile.obj
+.\Debug\extraUtilMemory.obj
+.\Debug\extraUtilMisc.obj
+.\Debug\extraUtilProgress.obj
+.\Debug\extraUtilReader.obj
+.\Debug\st.obj
+.\Debug\stmm.obj
+.\Debug\cpu_stats.obj
+.\Debug\cpu_time.obj
+.\Debug\datalimit.obj
+.\Debug\getopt.obj
+.\Debug\pathsearch.obj
+.\Debug\safe_mem.obj
+.\Debug\strsav.obj
+.\Debug\texpand.obj
+.\Debug\fxuUpdate.obj
+.\Debug\fxu.obj
+.\Debug\fxuCreate.obj
+.\Debug\fxuHeapD.obj
+.\Debug\fxuHeapS.obj
+.\Debug\fxuList.obj
+.\Debug\fxuMatrix.obj
+.\Debug\fxuPair.obj
+.\Debug\fxuPrint.obj
+.\Debug\fxuReduce.obj
+.\Debug\fxuSelect.obj
+.\Debug\fxuSingle.obj
+.\Debug\abcFxu.obj
]
-Creating command line "link.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP27C9.tmp"
+Creating command line "link.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP449.tmp"
<h3>Output Window</h3>
Compiling...
-abc.c
-abcAig.c
-abcAttach.c
-abcCheck.c
-abcCollapse.c
-abcCreate.c
-abcDfs.c
-abcDsd.c
-abcFanio.c
-abcFpga.c
-abcFraig.c
-abcFunc.c
-abcLatch.c
-abcMap.c
-abcMinBase.c
-abcMiter.c
-abcNames.c
-abcNetlist.c
-abcPrint.c
-abcRefs.c
-abcRenode.c
-abcSat.c
-abcSop.c
-abcStrash.c
-abcSweep.c
-abcTiming.c
-abcUtil.c
-abcVerify.c
-cmd.c
-cmdAlias.c
-cmdApi.c
-cmdFlag.c
-cmdHist.c
-cmdUtils.c
-io.c
-ioRead.c
-ioReadBench.c
-ioReadBlif.c
-ioReadVerilog.c
-ioWriteBench.c
-ioWriteBlif.c
-ioWriteBlifLogic.c
-ioWriteCnf.c
-ioWriteGate.c
-main.c
-mainFrame.c
-mainInit.c
-mainUtils.c
-cuddAddAbs.c
-cuddAddApply.c
-cuddAddFind.c
-cuddAddInv.c
-cuddAddIte.c
-cuddAddNeg.c
-cuddAddWalsh.c
-cuddAndAbs.c
-cuddAnneal.c
-cuddApa.c
-C:\_projects\abc\src\bdd\cudd\cuddApa.c(181) : warning C4244: 'return' : conversion from 'unsigned long ' to 'unsigned short ', possible loss of data
-C:\_projects\abc\src\bdd\cudd\cuddApa.c(213) : warning C4244: 'return' : conversion from 'unsigned long ' to 'unsigned short ', possible loss of data
-C:\_projects\abc\src\bdd\cudd\cuddApa.c(530) : warning C4244: '=' : conversion from 'unsigned short ' to 'unsigned char ', possible loss of data
-C:\_projects\abc\src\bdd\cudd\cuddApa.c(588) : warning C4244: '=' : conversion from 'unsigned short ' to 'unsigned char ', possible loss of data
-cuddAPI.c
-cuddApprox.c
-cuddBddAbs.c
-cuddBddCorr.c
-cuddBddIte.c
-cuddBridge.c
-cuddCache.c
-C:\_projects\abc\src\bdd\cudd\cuddCache.c(902) : warning C4146: unary minus operator applied to unsigned type, result still unsigned
-cuddCheck.c
-cuddClip.c
-cuddCof.c
-cuddCompose.c
-cuddDecomp.c
-cuddEssent.c
-cuddExact.c
-cuddExport.c
-cuddGenCof.c
-cuddGenetic.c
-cuddGroup.c
-C:\_projects\abc\src\bdd\cudd\cuddGroup.c(2062) : warning C4018: '<=' : signed/unsigned mismatch
-cuddHarwell.c
-cuddInit.c
-cuddInteract.c
-cuddLCache.c
-C:\_projects\abc\src\bdd\cudd\cuddLCache.c(1387) : warning C4146: unary minus operator applied to unsigned type, result still unsigned
-cuddLevelQ.c
-cuddLinear.c
-cuddLiteral.c
-cuddMatMult.c
-cuddPriority.c
-cuddRead.c
-cuddRef.c
-cuddReorder.c
-C:\_projects\abc\src\bdd\cudd\cuddReorder.c(395) : warning C4146: unary minus operator applied to unsigned type, result still unsigned
-cuddSat.c
-C:\_projects\abc\src\bdd\cudd\cuddReorder.c(2016) : warning C4700: local variable 'minLevel' used without having been initialized
-C:\_projects\abc\src\bdd\cudd\cuddReorder.c(2020) : warning C4700: local variable 'maxLevel' used without having been initialized
-cuddSign.c
-cuddSolve.c
-cuddSplit.c
-cuddSubsetHB.c
-cuddSubsetSP.c
-cuddSymmetry.c
-cuddTable.c
-C:\_projects\abc\src\bdd\cudd\cuddTable.c(1822) : warning C4018: '<' : signed/unsigned mismatch
-C:\_projects\abc\src\bdd\cudd\cuddTable.c(1927) : warning C4018: '<' : signed/unsigned mismatch
-C:\_projects\abc\src\bdd\cudd\cuddTable.c(2235) : warning C4018: '<' : signed/unsigned mismatch
-C:\_projects\abc\src\bdd\cudd\cuddTable.c(2303) : warning C4018: '<' : signed/unsigned mismatch
-C:\_projects\abc\src\bdd\cudd\cuddTable.c(2358) : warning C4146: unary minus operator applied to unsigned type, result still unsigned
-cuddUtil.c
-cuddWindow.c
-cuddZddCount.c
-cuddZddFuncs.c
-cuddZddGroup.c
-cuddZddIsop.c
-cuddZddLin.c
-cuddZddMisc.c
-cuddZddPort.c
-cuddZddReord.c
-cuddZddSetop.c
-cuddZddSymm.c
-cuddZddUtil.c
-epd.c
-mtrBasic.c
-mtrGroup.c
-parseCore.c
-parseStack.c
-dsdApi.c
-dsdCheck.c
-dsdLocal.c
-dsdMan.c
-dsdProc.c
-dsdTree.c
-reoApi.c
-reoCore.c
-reoProfile.c
-reoSift.c
-reoSwap.c
-reoTest.c
-reoTransfer.c
-reoUnits.c
-mvc.c
-mvcApi.c
-mvcCompare.c
-mvcContain.c
-mvcCover.c
-mvcCube.c
-mvcDivide.c
-mvcDivisor.c
-mvcList.c
-mvcLits.c
-mvcMan.c
-mvcOpAlg.c
-mvcOpBool.c
-mvcPrint.c
-mvcSort.c
-mvcUtils.c
-ftFactor.c
-ftPrint.c
-added.c
-solver.c
-msatActivity.c
-msatClause.c
-msatClauseVec.c
-msatMem.c
-msatOrderJ.c
-msatQueue.c
-msatRead.c
-msatSolverApi.c
-msatSolverCore.c
-msatSolverIo.c
-msatSolverSearch.c
-msatSort.c
-msatVec.c
-fraigApi.c
-fraigCanon.c
-fraigFanout.c
-fraigFeed.c
-fraigMan.c
-fraigMem.c
-fraigNode.c
-fraigPrime.c
-fraigSat.c
-fraigTable.c
-fraigUtil.c
-fraigVec.c
-fpga.c
-fpgaCore.c
-fpgaCreate.c
-fpgaCut.c
-fpgaCutUtils.c
-fpgaFanout.c
-fpgaLib.c
-fpgaMatch.c
-fpgaTime.c
-fpgaTruth.c
-fpgaUtils.c
-fpgaVec.c
-mapper.c
-mapperCanon.c
-mapperCore.c
-mapperCreate.c
-mapperCut.c
-mapperCutUtils.c
-mapperFanout.c
-mapperLib.c
-mapperMatch.c
-mapperRefs.c
-mapperSuper.c
-mapperTable.c
-mapperTime.c
-mapperTree.c
-mapperTruth.c
-mapperUtils.c
-mapperVec.c
-mio.c
-mioApi.c
-mioFunc.c
-mioRead.c
-mioUtils.c
-super.c
-superAnd.c
-superGate.c
-superWrite.c
-extraUtilBdd.c
-extraUtilFile.c
-extraUtilMemory.c
-extraUtilMisc.c
-extraUtilProgress.c
-extraUtilReader.c
-st.c
-stmm.c
-cpu_stats.c
-cpu_time.c
-datalimit.c
-getopt.c
-C:\_projects\abc\src\misc\util\getopt.c(64) : warning C4013: 'index' undefined; assuming extern returning int
-C:\_projects\abc\src\misc\util\getopt.c(64) : warning C4047: '=' : 'char *' differs in levels of indirection from 'int '
-pathsearch.c
-C:\_projects\abc\src\misc\util\pathsearch.c(103) : warning C4013: 'index' undefined; assuming extern returning int
-C:\_projects\abc\src\misc\util\pathsearch.c(103) : warning C4047: '=' : 'char *' differs in levels of indirection from 'int '
-safe_mem.c
-strsav.c
-texpand.c
+fxu.c
Linking...
-Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP27CB.tmp" with contents
+Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP44A.tmp" with contents
[
-/nologo /o"Release/abc.bsc"
-.\Release\abc.sbr
-.\Release\abcAig.sbr
-.\Release\abcAttach.sbr
-.\Release\abcCheck.sbr
-.\Release\abcCollapse.sbr
-.\Release\abcCreate.sbr
-.\Release\abcDfs.sbr
-.\Release\abcDsd.sbr
-.\Release\abcFanio.sbr
-.\Release\abcFpga.sbr
-.\Release\abcFraig.sbr
-.\Release\abcFunc.sbr
-.\Release\abcLatch.sbr
-.\Release\abcMap.sbr
-.\Release\abcMinBase.sbr
-.\Release\abcMiter.sbr
-.\Release\abcNames.sbr
-.\Release\abcNetlist.sbr
-.\Release\abcPrint.sbr
-.\Release\abcRefs.sbr
-.\Release\abcRenode.sbr
-.\Release\abcSat.sbr
-.\Release\abcSop.sbr
-.\Release\abcStrash.sbr
-.\Release\abcSweep.sbr
-.\Release\abcTiming.sbr
-.\Release\abcUtil.sbr
-.\Release\abcVerify.sbr
-.\Release\cmd.sbr
-.\Release\cmdAlias.sbr
-.\Release\cmdApi.sbr
-.\Release\cmdFlag.sbr
-.\Release\cmdHist.sbr
-.\Release\cmdUtils.sbr
-.\Release\io.sbr
-.\Release\ioRead.sbr
-.\Release\ioReadBench.sbr
-.\Release\ioReadBlif.sbr
-.\Release\ioReadVerilog.sbr
-.\Release\ioWriteBench.sbr
-.\Release\ioWriteBlif.sbr
-.\Release\ioWriteBlifLogic.sbr
-.\Release\ioWriteCnf.sbr
-.\Release\ioWriteGate.sbr
-.\Release\main.sbr
-.\Release\mainFrame.sbr
-.\Release\mainInit.sbr
-.\Release\mainUtils.sbr
-.\Release\cuddAddAbs.sbr
-.\Release\cuddAddApply.sbr
-.\Release\cuddAddFind.sbr
-.\Release\cuddAddInv.sbr
-.\Release\cuddAddIte.sbr
-.\Release\cuddAddNeg.sbr
-.\Release\cuddAddWalsh.sbr
-.\Release\cuddAndAbs.sbr
-.\Release\cuddAnneal.sbr
-.\Release\cuddApa.sbr
-.\Release\cuddAPI.sbr
-.\Release\cuddApprox.sbr
-.\Release\cuddBddAbs.sbr
-.\Release\cuddBddCorr.sbr
-.\Release\cuddBddIte.sbr
-.\Release\cuddBridge.sbr
-.\Release\cuddCache.sbr
-.\Release\cuddCheck.sbr
-.\Release\cuddClip.sbr
-.\Release\cuddCof.sbr
-.\Release\cuddCompose.sbr
-.\Release\cuddDecomp.sbr
-.\Release\cuddEssent.sbr
-.\Release\cuddExact.sbr
-.\Release\cuddExport.sbr
-.\Release\cuddGenCof.sbr
-.\Release\cuddGenetic.sbr
-.\Release\cuddGroup.sbr
-.\Release\cuddHarwell.sbr
-.\Release\cuddInit.sbr
-.\Release\cuddInteract.sbr
-.\Release\cuddLCache.sbr
-.\Release\cuddLevelQ.sbr
-.\Release\cuddLinear.sbr
-.\Release\cuddLiteral.sbr
-.\Release\cuddMatMult.sbr
-.\Release\cuddPriority.sbr
-.\Release\cuddRead.sbr
-.\Release\cuddRef.sbr
-.\Release\cuddReorder.sbr
-.\Release\cuddSat.sbr
-.\Release\cuddSign.sbr
-.\Release\cuddSolve.sbr
-.\Release\cuddSplit.sbr
-.\Release\cuddSubsetHB.sbr
-.\Release\cuddSubsetSP.sbr
-.\Release\cuddSymmetry.sbr
-.\Release\cuddTable.sbr
-.\Release\cuddUtil.sbr
-.\Release\cuddWindow.sbr
-.\Release\cuddZddCount.sbr
-.\Release\cuddZddFuncs.sbr
-.\Release\cuddZddGroup.sbr
-.\Release\cuddZddIsop.sbr
-.\Release\cuddZddLin.sbr
-.\Release\cuddZddMisc.sbr
-.\Release\cuddZddPort.sbr
-.\Release\cuddZddReord.sbr
-.\Release\cuddZddSetop.sbr
-.\Release\cuddZddSymm.sbr
-.\Release\cuddZddUtil.sbr
-.\Release\epd.sbr
-.\Release\mtrBasic.sbr
-.\Release\mtrGroup.sbr
-.\Release\parseCore.sbr
-.\Release\parseStack.sbr
-.\Release\dsdApi.sbr
-.\Release\dsdCheck.sbr
-.\Release\dsdLocal.sbr
-.\Release\dsdMan.sbr
-.\Release\dsdProc.sbr
-.\Release\dsdTree.sbr
-.\Release\reoApi.sbr
-.\Release\reoCore.sbr
-.\Release\reoProfile.sbr
-.\Release\reoSift.sbr
-.\Release\reoSwap.sbr
-.\Release\reoTest.sbr
-.\Release\reoTransfer.sbr
-.\Release\reoUnits.sbr
-.\Release\mvc.sbr
-.\Release\mvcApi.sbr
-.\Release\mvcCompare.sbr
-.\Release\mvcContain.sbr
-.\Release\mvcCover.sbr
-.\Release\mvcCube.sbr
-.\Release\mvcDivide.sbr
-.\Release\mvcDivisor.sbr
-.\Release\mvcList.sbr
-.\Release\mvcLits.sbr
-.\Release\mvcMan.sbr
-.\Release\mvcOpAlg.sbr
-.\Release\mvcOpBool.sbr
-.\Release\mvcPrint.sbr
-.\Release\mvcSort.sbr
-.\Release\mvcUtils.sbr
-.\Release\ftFactor.sbr
-.\Release\ftPrint.sbr
-.\Release\added.sbr
-.\Release\solver.sbr
-.\Release\msatActivity.sbr
-.\Release\msatClause.sbr
-.\Release\msatClauseVec.sbr
-.\Release\msatMem.sbr
-.\Release\msatOrderJ.sbr
-.\Release\msatQueue.sbr
-.\Release\msatRead.sbr
-.\Release\msatSolverApi.sbr
-.\Release\msatSolverCore.sbr
-.\Release\msatSolverIo.sbr
-.\Release\msatSolverSearch.sbr
-.\Release\msatSort.sbr
-.\Release\msatVec.sbr
-.\Release\fraigApi.sbr
-.\Release\fraigCanon.sbr
-.\Release\fraigFanout.sbr
-.\Release\fraigFeed.sbr
-.\Release\fraigMan.sbr
-.\Release\fraigMem.sbr
-.\Release\fraigNode.sbr
-.\Release\fraigPrime.sbr
-.\Release\fraigSat.sbr
-.\Release\fraigTable.sbr
-.\Release\fraigUtil.sbr
-.\Release\fraigVec.sbr
-.\Release\fpga.sbr
-.\Release\fpgaCore.sbr
-.\Release\fpgaCreate.sbr
-.\Release\fpgaCut.sbr
-.\Release\fpgaCutUtils.sbr
-.\Release\fpgaFanout.sbr
-.\Release\fpgaLib.sbr
-.\Release\fpgaMatch.sbr
-.\Release\fpgaTime.sbr
-.\Release\fpgaTruth.sbr
-.\Release\fpgaUtils.sbr
-.\Release\fpgaVec.sbr
-.\Release\mapper.sbr
-.\Release\mapperCanon.sbr
-.\Release\mapperCore.sbr
-.\Release\mapperCreate.sbr
-.\Release\mapperCut.sbr
-.\Release\mapperCutUtils.sbr
-.\Release\mapperFanout.sbr
-.\Release\mapperLib.sbr
-.\Release\mapperMatch.sbr
-.\Release\mapperRefs.sbr
-.\Release\mapperSuper.sbr
-.\Release\mapperTable.sbr
-.\Release\mapperTime.sbr
-.\Release\mapperTree.sbr
-.\Release\mapperTruth.sbr
-.\Release\mapperUtils.sbr
-.\Release\mapperVec.sbr
-.\Release\mio.sbr
-.\Release\mioApi.sbr
-.\Release\mioFunc.sbr
-.\Release\mioRead.sbr
-.\Release\mioUtils.sbr
-.\Release\super.sbr
-.\Release\superAnd.sbr
-.\Release\superGate.sbr
-.\Release\superWrite.sbr
-.\Release\extraUtilBdd.sbr
-.\Release\extraUtilFile.sbr
-.\Release\extraUtilMemory.sbr
-.\Release\extraUtilMisc.sbr
-.\Release\extraUtilProgress.sbr
-.\Release\extraUtilReader.sbr
-.\Release\st.sbr
-.\Release\stmm.sbr
-.\Release\cpu_stats.sbr
-.\Release\cpu_time.sbr
-.\Release\datalimit.sbr
-.\Release\getopt.sbr
-.\Release\pathsearch.sbr
-.\Release\safe_mem.sbr
-.\Release\strsav.sbr
-.\Release\texpand.sbr]
-Creating command line "bscmake.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP27CB.tmp"
+/nologo /o"Debug/abc.bsc"
+.\Debug\abc.sbr
+.\Debug\abcAig.sbr
+.\Debug\abcAttach.sbr
+.\Debug\abcCheck.sbr
+.\Debug\abcCollapse.sbr
+.\Debug\abcCreate.sbr
+.\Debug\abcDfs.sbr
+.\Debug\abcDsd.sbr
+.\Debug\abcFanio.sbr
+.\Debug\abcFpga.sbr
+.\Debug\abcFraig.sbr
+.\Debug\abcFunc.sbr
+.\Debug\abcLatch.sbr
+.\Debug\abcMap.sbr
+.\Debug\abcMinBase.sbr
+.\Debug\abcMiter.sbr
+.\Debug\abcNames.sbr
+.\Debug\abcNetlist.sbr
+.\Debug\abcPrint.sbr
+.\Debug\abcRefs.sbr
+.\Debug\abcRenode.sbr
+.\Debug\abcSat.sbr
+.\Debug\abcSop.sbr
+.\Debug\abcStrash.sbr
+.\Debug\abcSweep.sbr
+.\Debug\abcTiming.sbr
+.\Debug\abcUtil.sbr
+.\Debug\abcVerify.sbr
+.\Debug\cmd.sbr
+.\Debug\cmdAlias.sbr
+.\Debug\cmdApi.sbr
+.\Debug\cmdFlag.sbr
+.\Debug\cmdHist.sbr
+.\Debug\cmdUtils.sbr
+.\Debug\io.sbr
+.\Debug\ioRead.sbr
+.\Debug\ioReadBench.sbr
+.\Debug\ioReadBlif.sbr
+.\Debug\ioReadVerilog.sbr
+.\Debug\ioWriteBench.sbr
+.\Debug\ioWriteBlif.sbr
+.\Debug\ioWriteBlifLogic.sbr
+.\Debug\ioWriteCnf.sbr
+.\Debug\ioWriteGate.sbr
+.\Debug\main.sbr
+.\Debug\mainFrame.sbr
+.\Debug\mainInit.sbr
+.\Debug\mainUtils.sbr
+.\Debug\cuddAddAbs.sbr
+.\Debug\cuddAddApply.sbr
+.\Debug\cuddAddFind.sbr
+.\Debug\cuddAddInv.sbr
+.\Debug\cuddAddIte.sbr
+.\Debug\cuddAddNeg.sbr
+.\Debug\cuddAddWalsh.sbr
+.\Debug\cuddAndAbs.sbr
+.\Debug\cuddAnneal.sbr
+.\Debug\cuddApa.sbr
+.\Debug\cuddAPI.sbr
+.\Debug\cuddApprox.sbr
+.\Debug\cuddBddAbs.sbr
+.\Debug\cuddBddCorr.sbr
+.\Debug\cuddBddIte.sbr
+.\Debug\cuddBridge.sbr
+.\Debug\cuddCache.sbr
+.\Debug\cuddCheck.sbr
+.\Debug\cuddClip.sbr
+.\Debug\cuddCof.sbr
+.\Debug\cuddCompose.sbr
+.\Debug\cuddDecomp.sbr
+.\Debug\cuddEssent.sbr
+.\Debug\cuddExact.sbr
+.\Debug\cuddExport.sbr
+.\Debug\cuddGenCof.sbr
+.\Debug\cuddGenetic.sbr
+.\Debug\cuddGroup.sbr
+.\Debug\cuddHarwell.sbr
+.\Debug\cuddInit.sbr
+.\Debug\cuddInteract.sbr
+.\Debug\cuddLCache.sbr
+.\Debug\cuddLevelQ.sbr
+.\Debug\cuddLinear.sbr
+.\Debug\cuddLiteral.sbr
+.\Debug\cuddMatMult.sbr
+.\Debug\cuddPriority.sbr
+.\Debug\cuddRead.sbr
+.\Debug\cuddRef.sbr
+.\Debug\cuddReorder.sbr
+.\Debug\cuddSat.sbr
+.\Debug\cuddSign.sbr
+.\Debug\cuddSolve.sbr
+.\Debug\cuddSplit.sbr
+.\Debug\cuddSubsetHB.sbr
+.\Debug\cuddSubsetSP.sbr
+.\Debug\cuddSymmetry.sbr
+.\Debug\cuddTable.sbr
+.\Debug\cuddUtil.sbr
+.\Debug\cuddWindow.sbr
+.\Debug\cuddZddCount.sbr
+.\Debug\cuddZddFuncs.sbr
+.\Debug\cuddZddGroup.sbr
+.\Debug\cuddZddIsop.sbr
+.\Debug\cuddZddLin.sbr
+.\Debug\cuddZddMisc.sbr
+.\Debug\cuddZddPort.sbr
+.\Debug\cuddZddReord.sbr
+.\Debug\cuddZddSetop.sbr
+.\Debug\cuddZddSymm.sbr
+.\Debug\cuddZddUtil.sbr
+.\Debug\epd.sbr
+.\Debug\mtrBasic.sbr
+.\Debug\mtrGroup.sbr
+.\Debug\parseCore.sbr
+.\Debug\parseStack.sbr
+.\Debug\dsdApi.sbr
+.\Debug\dsdCheck.sbr
+.\Debug\dsdLocal.sbr
+.\Debug\dsdMan.sbr
+.\Debug\dsdProc.sbr
+.\Debug\dsdTree.sbr
+.\Debug\reoApi.sbr
+.\Debug\reoCore.sbr
+.\Debug\reoProfile.sbr
+.\Debug\reoSift.sbr
+.\Debug\reoSwap.sbr
+.\Debug\reoTest.sbr
+.\Debug\reoTransfer.sbr
+.\Debug\reoUnits.sbr
+.\Debug\mvc.sbr
+.\Debug\mvcApi.sbr
+.\Debug\mvcCompare.sbr
+.\Debug\mvcContain.sbr
+.\Debug\mvcCover.sbr
+.\Debug\mvcCube.sbr
+.\Debug\mvcDivide.sbr
+.\Debug\mvcDivisor.sbr
+.\Debug\mvcList.sbr
+.\Debug\mvcLits.sbr
+.\Debug\mvcMan.sbr
+.\Debug\mvcOpAlg.sbr
+.\Debug\mvcOpBool.sbr
+.\Debug\mvcPrint.sbr
+.\Debug\mvcSort.sbr
+.\Debug\mvcUtils.sbr
+.\Debug\ftFactor.sbr
+.\Debug\ftPrint.sbr
+.\Debug\added.sbr
+.\Debug\solver.sbr
+.\Debug\msatActivity.sbr
+.\Debug\msatClause.sbr
+.\Debug\msatClauseVec.sbr
+.\Debug\msatMem.sbr
+.\Debug\msatOrderJ.sbr
+.\Debug\msatQueue.sbr
+.\Debug\msatRead.sbr
+.\Debug\msatSolverApi.sbr
+.\Debug\msatSolverCore.sbr
+.\Debug\msatSolverIo.sbr
+.\Debug\msatSolverSearch.sbr
+.\Debug\msatSort.sbr
+.\Debug\msatVec.sbr
+.\Debug\fraigApi.sbr
+.\Debug\fraigCanon.sbr
+.\Debug\fraigFanout.sbr
+.\Debug\fraigFeed.sbr
+.\Debug\fraigMan.sbr
+.\Debug\fraigMem.sbr
+.\Debug\fraigNode.sbr
+.\Debug\fraigPrime.sbr
+.\Debug\fraigSat.sbr
+.\Debug\fraigTable.sbr
+.\Debug\fraigUtil.sbr
+.\Debug\fraigVec.sbr
+.\Debug\fpga.sbr
+.\Debug\fpgaCore.sbr
+.\Debug\fpgaCreate.sbr
+.\Debug\fpgaCut.sbr
+.\Debug\fpgaCutUtils.sbr
+.\Debug\fpgaFanout.sbr
+.\Debug\fpgaLib.sbr
+.\Debug\fpgaMatch.sbr
+.\Debug\fpgaTime.sbr
+.\Debug\fpgaTruth.sbr
+.\Debug\fpgaUtils.sbr
+.\Debug\fpgaVec.sbr
+.\Debug\mapper.sbr
+.\Debug\mapperCanon.sbr
+.\Debug\mapperCore.sbr
+.\Debug\mapperCreate.sbr
+.\Debug\mapperCut.sbr
+.\Debug\mapperCutUtils.sbr
+.\Debug\mapperFanout.sbr
+.\Debug\mapperLib.sbr
+.\Debug\mapperMatch.sbr
+.\Debug\mapperRefs.sbr
+.\Debug\mapperSuper.sbr
+.\Debug\mapperTable.sbr
+.\Debug\mapperTime.sbr
+.\Debug\mapperTree.sbr
+.\Debug\mapperTruth.sbr
+.\Debug\mapperUtils.sbr
+.\Debug\mapperVec.sbr
+.\Debug\mio.sbr
+.\Debug\mioApi.sbr
+.\Debug\mioFunc.sbr
+.\Debug\mioRead.sbr
+.\Debug\mioUtils.sbr
+.\Debug\super.sbr
+.\Debug\superAnd.sbr
+.\Debug\superGate.sbr
+.\Debug\superWrite.sbr
+.\Debug\extraUtilBdd.sbr
+.\Debug\extraUtilFile.sbr
+.\Debug\extraUtilMemory.sbr
+.\Debug\extraUtilMisc.sbr
+.\Debug\extraUtilProgress.sbr
+.\Debug\extraUtilReader.sbr
+.\Debug\st.sbr
+.\Debug\stmm.sbr
+.\Debug\cpu_stats.sbr
+.\Debug\cpu_time.sbr
+.\Debug\datalimit.sbr
+.\Debug\getopt.sbr
+.\Debug\pathsearch.sbr
+.\Debug\safe_mem.sbr
+.\Debug\strsav.sbr
+.\Debug\texpand.sbr
+.\Debug\fxuUpdate.sbr
+.\Debug\fxu.sbr
+.\Debug\fxuCreate.sbr
+.\Debug\fxuHeapD.sbr
+.\Debug\fxuHeapS.sbr
+.\Debug\fxuList.sbr
+.\Debug\fxuMatrix.sbr
+.\Debug\fxuPair.sbr
+.\Debug\fxuPrint.sbr
+.\Debug\fxuReduce.sbr
+.\Debug\fxuSelect.sbr
+.\Debug\fxuSingle.sbr
+.\Debug\abcFxu.sbr]
+Creating command line "bscmake.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP44A.tmp"
Creating browse info file...
<h3>Output Window</h3>
<h3>Results</h3>
-abc.exe - 0 error(s), 19 warning(s)
+abc.exe - 0 error(s), 0 warning(s)
</pre>
</body>
</html>
diff --git a/abc.rc b/abc.rc
index 21a99e8d..ce064716 100644
--- a/abc.rc
+++ b/abc.rc
@@ -11,7 +11,7 @@ alias r read
alias rl read_blif
alias rb read_bench
alias rv read_verilog
-alias rsup read_super
+alias rsup read_super mcnc5_old.super
alias rlib read_library
alias sa set autoexec ps
alias so source -x
diff --git a/src/base/abc/abc.c b/src/base/abc/abc.c
index f9bcde33..1179e400 100644
--- a/src/base/abc/abc.c
+++ b/src/base/abc/abc.c
@@ -22,6 +22,7 @@
#include "mainInt.h"
#include "ft.h"
#include "fraig.h"
+#include "fxu.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
@@ -37,6 +38,7 @@ static int Ntk_CommandStrash ( Abc_Frame_t * pAbc, int argc, char ** argv
static int Ntk_CommandBalance ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Ntk_CommandRenode ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Ntk_CommandCleanup ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Ntk_CommandFx ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Ntk_CommandLogic ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Ntk_CommandMiter ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -55,6 +57,7 @@ static int Ntk_CommandFraigSweep ( Abc_Frame_t * pAbc, int argc, char ** argv
static int Ntk_CommandMap ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Ntk_CommandUnmap ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Ntk_CommandAttach ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Ntk_CommandSuperChoice ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Ntk_CommandFpga ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -88,6 +91,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Synthesis", "balance", Ntk_CommandBalance, 1 );
Cmd_CommandAdd( pAbc, "Synthesis", "renode", Ntk_CommandRenode, 1 );
Cmd_CommandAdd( pAbc, "Synthesis", "cleanup", Ntk_CommandCleanup, 1 );
+ Cmd_CommandAdd( pAbc, "Synthesis", "fx", Ntk_CommandFx, 1 );
Cmd_CommandAdd( pAbc, "Various", "logic", Ntk_CommandLogic, 1 );
Cmd_CommandAdd( pAbc, "Various", "miter", Ntk_CommandMiter, 1 );
@@ -106,6 +110,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "SC mapping", "map", Ntk_CommandMap, 1 );
Cmd_CommandAdd( pAbc, "SC mapping", "unmap", Ntk_CommandUnmap, 1 );
Cmd_CommandAdd( pAbc, "SC mapping", "attach", Ntk_CommandAttach, 1 );
+ Cmd_CommandAdd( pAbc, "SC mapping", "sc", Ntk_CommandSuperChoice, 1 );
Cmd_CommandAdd( pAbc, "FPGA mapping", "fpga", Ntk_CommandFpga, 1 );
@@ -750,6 +755,127 @@ usage:
return 1;
}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandFx( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Abc_Ntk_t * pNtk;
+ FILE * pOut, * pErr;
+ Fxu_Data_t * p = NULL;
+ int c;
+ extern bool Abc_NtkFastExtract( Abc_Ntk_t * pNtk, Fxu_Data_t * p );
+ extern void Abc_NtkFxuFreeInfo( Fxu_Data_t * p );
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // allocate the structure
+ p = ALLOC( Fxu_Data_t, 1 );
+ memset( p, 0, sizeof(Fxu_Data_t) );
+ // set the defaults
+ p->nPairsMax = 30000;
+ p->nNodesExt = 10000;
+ p->fOnlyS = 0;
+ p->fOnlyD = 0;
+ p->fUse0 = 0;
+ p->fUseCompl = 1;
+ p->fVerbose = 0;
+ util_getopt_reset();
+ while ( (c = util_getopt(argc, argv, "lnsdzcvh")) != EOF )
+ {
+ switch (c)
+ {
+ case 'l':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-l\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ p->nPairsMax = atoi(argv[util_optind]);
+ util_optind++;
+ if ( p->nPairsMax < 0 )
+ goto usage;
+ break;
+ case 'n':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-n\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ p->nNodesExt = atoi(argv[util_optind]);
+ util_optind++;
+ if ( p->nNodesExt < 0 )
+ goto usage;
+ break;
+ case 's':
+ p->fOnlyS ^= 1;
+ break;
+ case 'd':
+ p->fOnlyD ^= 1;
+ break;
+ case 'z':
+ p->fUse0 ^= 1;
+ break;
+ case 'c':
+ p->fUseCompl ^= 1;
+ break;
+ case 'v':
+ p->fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ Abc_NtkFxuFreeInfo( p );
+ return 1;
+ }
+
+ if ( Abc_NtkNodeNum(pNtk) == 0 )
+ {
+ fprintf( pErr, "The network does not have internal nodes.\n" );
+ Abc_NtkFxuFreeInfo( p );
+ return 1;
+ }
+
+ // the nodes to be merged are linked into the special linked list
+ Abc_NtkFastExtract( pNtk, p );
+ Abc_NtkFxuFreeInfo( p );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: fx [-n num] [-l num] [-sdzcvh]\n");
+ fprintf( pErr, "\t performs unate fast extract on the current network\n");
+ fprintf( pErr, "\t-n num : the maximum number of divisors to extract [default = %d]\n", p->nNodesExt );
+ fprintf( pErr, "\t-l num : the maximum number of cube pairs to consider [default = %d]\n", p->nPairsMax );
+ fprintf( pErr, "\t-s : use only single-cube divisors [default = %s]\n", p->fOnlyS? "yes": "no" );
+ fprintf( pErr, "\t-d : use only double-cube divisors [default = %s]\n", p->fOnlyD? "yes": "no" );
+ fprintf( pErr, "\t-z : use zero-weight divisors [default = %s]\n", p->fUse0? "yes": "no" );
+ fprintf( pErr, "\t-c : use complement in the binary case [default = %s]\n", p->fUseCompl? "yes": "no" );
+ fprintf( pErr, "\t-v : print verbose information [default = %s]\n", p->fVerbose? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ Abc_NtkFxuFreeInfo( p );
+ return 1;
+}
+
+
/**Function*************************************************************
Synopsis []
@@ -1189,6 +1315,7 @@ int Ntk_CommandFraig( Abc_Frame_t * pAbc, int argc, char ** argv )
Fraig_Params_t Params;
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk, * pNtkRes;
+ int fAllNodes;
int c;
pNtk = Abc_FrameReadNet(pAbc);
@@ -1196,6 +1323,7 @@ int Ntk_CommandFraig( Abc_Frame_t * pAbc, int argc, char ** argv )
pErr = Abc_FrameReadErr(pAbc);
// set defaults
+ fAllNodes = 0;
Params.nPatsRand = 2048; // the number of words of random simulation info
Params.nPatsDyna = 2048; // the number of words of dynamic simulation info
Params.nBTLimit = 99; // the max number of backtracks to perform
@@ -1208,7 +1336,7 @@ int Ntk_CommandFraig( Abc_Frame_t * pAbc, int argc, char ** argv )
Params.fVerbose = 0; // the verbosiness flag
Params.fVerboseP = 0; // the verbosiness flag
util_getopt_reset();
- while ( ( c = util_getopt( argc, argv, "RDBrscpvh" ) ) != EOF )
+ while ( ( c = util_getopt( argc, argv, "RDBrscpvah" ) ) != EOF )
{
switch ( c )
{
@@ -1262,7 +1390,9 @@ int Ntk_CommandFraig( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'v':
Params.fVerbose ^= 1;
break;
-
+ case 'a':
+ fAllNodes ^= 1;
+ break;
case 'h':
goto usage;
default:
@@ -1286,11 +1416,11 @@ int Ntk_CommandFraig( Abc_Frame_t * pAbc, int argc, char ** argv )
// get the new network
if ( Abc_NtkIsAig(pNtk) )
- pNtkRes = Abc_NtkFraig( pNtk, &Params, 0 );
+ pNtkRes = Abc_NtkFraig( pNtk, &Params, fAllNodes );
else
{
pNtk = Abc_NtkStrash( pNtk );
- pNtkRes = Abc_NtkFraig( pNtk, &Params, 0 );
+ pNtkRes = Abc_NtkFraig( pNtk, &Params, fAllNodes );
Abc_NtkDelete( pNtk );
}
if ( pNtkRes == NULL )
@@ -1308,7 +1438,7 @@ int Ntk_CommandFraig( Abc_Frame_t * pAbc, int argc, char ** argv )
usage:
sprintf( Buffer, "%d", Params.nBTLimit );
- fprintf( pErr, "usage: fraig [-R num] [-D num] [-B num] [-rscpvh]\n" );
+ fprintf( pErr, "usage: fraig [-R num] [-D num] [-B num] [-rscpvah]\n" );
fprintf( pErr, "\t transforms a logic network into a functionally reduced AIG\n" );
fprintf( pErr, "\t-R num : number of random patterns (127 < num < 32769) [default = %d]\n", Params.nPatsRand );
fprintf( pErr, "\t-D num : number of systematic patterns (127 < num < 32769) [default = %d]\n", Params.nPatsDyna );
@@ -1318,6 +1448,7 @@ usage:
fprintf( pErr, "\t-c : toggle accumulation of choices [default = %s]\n", Params.fChoicing? "yes": "no" );
fprintf( pErr, "\t-p : toggle proving the final miter [default = %s]\n", Params.fTryProve? "yes": "no" );
fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", Params.fVerbose? "yes": "no" );
+ fprintf( pErr, "\t-a : toggle between all nodes and DFS nodes [default = %s]\n", fAllNodes? "all": "dfs" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
@@ -1890,6 +2021,72 @@ usage:
return 1;
}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandSuperChoice( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ int c;
+ extern Abc_Ntk_t * Abc_NtkSuperChoice( Abc_Ntk_t * pNtk );
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ if ( !Abc_NtkIsAig(pNtk) )
+ {
+ fprintf( pErr, "Works only for the AIG representation.\n" );
+ return 1;
+ }
+
+ // get the new network
+ pNtkRes = Abc_NtkSuperChoice( pNtk );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Superchoicing has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: sc [-h]\n" );
+ fprintf( pErr, "\t performs superchoicing\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
/**Function*************************************************************
Synopsis []
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h
index d918cbc2..35fa85e9 100644
--- a/src/base/abc/abc.h
+++ b/src/base/abc/abc.h
@@ -480,6 +480,7 @@ extern bool Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int fVerbose );
extern solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk );
/*=== abcSop.c ==========================================================*/
extern char * Abc_SopRegister( Extra_MmFlex_t * pMan, char * pName );
+extern char * Abc_SopStart( Extra_MmFlex_t * pMan, int nCubes, int nVars );
extern int Abc_SopGetCubeNum( char * pSop );
extern int Abc_SopGetLitNum( char * pSop );
extern int Abc_SopGetVarNum( char * pSop );
diff --git a/src/base/abc/abcAttach.c b/src/base/abc/abcAttach.c
index 9d9c378f..950ecc1d 100644
--- a/src/base/abc/abcAttach.c
+++ b/src/base/abc/abcAttach.c
@@ -267,6 +267,8 @@ void Abc_AttachComputeTruth( char * pSop, unsigned uTruthsIn[][2], unsigned * uT
}
uTruthRes[0] |= uSignCube[0];
}
+ if ( Abc_SopGetPhase(pSop) == 0 )
+ uTruthRes[0] = ~uTruthRes[0];
if ( nInputs < 5 )
uTruthRes[0] &= ATTACH_MASK(1<<nInputs);
}
@@ -295,6 +297,13 @@ void Abc_AttachComputeTruth( char * pSop, unsigned uTruthsIn[][2], unsigned * uT
uTruthRes[0] |= uSignCube[0];
uTruthRes[1] |= uSignCube[1];
}
+
+ // complement if the SOP is complemented
+ if ( Abc_SopGetPhase(pSop) == 0 )
+ {
+ uTruthRes[0] = ~uTruthRes[0];
+ uTruthRes[1] = ~uTruthRes[1];
+ }
}
}
diff --git a/src/base/abc/abcDfs.c b/src/base/abc/abcDfs.c
index 7b330b95..5c75a94c 100644
--- a/src/base/abc/abcDfs.c
+++ b/src/base/abc/abcDfs.c
@@ -223,9 +223,12 @@ int Abc_NtkGetLevelNum( Abc_Ntk_t * pNtk )
}
else
{
- Abc_NtkForEachCo( pNtk, pNode, i )
+// Abc_NtkForEachCo( pNtk, pNode, i )
+ Abc_NtkForEachNode( pNtk, pNode, i )
{
- pDriver = Abc_ObjFanin0( pNode );
+// pDriver = Abc_ObjFanin0( pNode );
+ pDriver = pNode;
+
Abc_NtkGetLevelNum_rec( pDriver );
if ( LevelsMax < pDriver->Level )
LevelsMax = pDriver->Level;
diff --git a/src/base/abc/abcFxu.c b/src/base/abc/abcFxu.c
new file mode 100644
index 00000000..99f37dfc
--- /dev/null
+++ b/src/base/abc/abcFxu.c
@@ -0,0 +1,262 @@
+/**CFile****************************************************************
+
+ FileName [abcFxu.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Interface with the fast extract package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcFxu.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "fxu.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static bool Abc_NtkFxuCheck( Abc_Ntk_t * pNtk );
+static void Abc_NtkFxuCollectInfo( Abc_Ntk_t * pNtk, Fxu_Data_t * p );
+static void Abc_NtkFxuReconstruct( Abc_Ntk_t * pNtk, Fxu_Data_t * p );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs fast_extract on the current network.]
+
+ Description [Takes the network and the maximum number of nodes to extract.
+ Uses the concurrent double-cube and single cube divisor extraction procedure.
+ Modifies the network in the end, after extracting all nodes. Note that
+ Ntk_NetworkSweep() may increase the performance of this procedure because
+ the single-literal nodes will not be created in the sparse matrix. Returns 1
+ if the network has been changed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NtkFastExtract( Abc_Ntk_t * pNtk, Fxu_Data_t * p )
+{
+ assert( Abc_NtkIsLogicBdd(pNtk) || Abc_NtkIsLogicSop(pNtk) );
+ // convert nodes to SOPs
+ if ( Abc_NtkIsLogicBdd(pNtk) )
+ Abc_NtkBddToSop(pNtk);
+ else
+ { // to make sure the SOPs are SCC-free
+// Abc_NtkSopToBdd(pNtk);
+// Abc_NtkBddToSop(pNtk);
+ }
+ // check if the network meets the requirements
+ if ( !Abc_NtkFxuCheck(pNtk) )
+ {
+ printf( "Abc_NtkFastExtract: Nodes have duplicated or complemented fanins. FXU is not performed.\n" );
+ return 0;
+ }
+ // sweep removes useless nodes
+ Abc_NtkCleanup( pNtk, 0 );
+ // collect information about the covers
+ // make sure all covers are SCC free
+ // allocate literal array for each cover
+ Abc_NtkFxuCollectInfo( pNtk, p );
+ // call the fast extract procedure
+ // returns the number of divisor extracted
+ if ( Fxu_FastExtract(p) > 0 )
+ {
+ // update the network
+ Abc_NtkFxuReconstruct( pNtk, p );
+ // make sure everything is okay
+ if ( !Abc_NtkCheck( pNtk ) )
+ printf( "Abc_NtkFastExtract: The network check has failed.\n" );
+ return 1;
+ }
+ return 0;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Makes sure the nodes do not have complemented and duplicated fanins.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NtkFxuCheck( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode, * pFanin1, * pFanin2;
+ int n, i, k;
+ Abc_NtkForEachNode( pNtk, pNode, n )
+ {
+ Abc_ObjForEachFanin( pNode, pFanin1, i )
+ {
+ if ( Abc_ObjFaninC(pNode, i) )
+ return 0;
+ Abc_ObjForEachFanin( pNode, pFanin2, k )
+ {
+ if ( i == k )
+ continue;
+ if ( pFanin1 == pFanin2 )
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collect information about the network for fast_extract.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkFxuCollectInfo( Abc_Ntk_t * pNtk, Fxu_Data_t * p )
+{
+ Abc_Obj_t * pNode;
+ int i;
+ // add information to the manager
+ p->pManSop = pNtk->pManFunc;
+ p->vSops = Vec_PtrAlloc(0);
+ p->vFanins = Vec_PtrAlloc(0);
+ p->vSopsNew = Vec_PtrAlloc(0);
+ p->vFaninsNew = Vec_PtrAlloc(0);
+ Vec_PtrFill( p->vSops, pNtk->vObjs->nSize, NULL );
+ Vec_PtrFill( p->vFanins, pNtk->vObjs->nSize, NULL );
+ Vec_PtrFill( p->vSopsNew, pNtk->vObjs->nSize + p->nNodesExt, NULL );
+ Vec_PtrFill( p->vFaninsNew, pNtk->vObjs->nSize + p->nNodesExt, NULL );
+ // add SOPs and fanin array
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ if ( Abc_SopGetVarNum(pNode->pData) < 2 )
+ continue;
+ if ( Abc_SopGetCubeNum(pNode->pData) < 1 )
+ continue;
+ p->vSops->pArray[i] = pNode->pData;
+ p->vFanins->pArray[i] = &pNode->vFanins;
+ }
+ p->nNodesOld = pNtk->vObjs->nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkFxuFreeInfo( Fxu_Data_t * p )
+{
+ int i;
+ // free the arrays of new fanins
+ if ( p->vFaninsNew )
+ for ( i = 0; i < p->vFaninsNew->nSize; i++ )
+ if ( p->vFaninsNew->pArray[i] )
+ Vec_IntFree( p->vFaninsNew->pArray[i] );
+ // free the arrays
+ if ( p->vSops ) Vec_PtrFree( p->vSops );
+ if ( p->vSopsNew ) Vec_PtrFree( p->vSopsNew );
+ if ( p->vFanins ) Vec_PtrFree( p->vFanins );
+ if ( p->vFaninsNew ) Vec_PtrFree( p->vFaninsNew );
+ FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Recostructs the network after FX.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkFxuReconstruct( Abc_Ntk_t * pNtk, Fxu_Data_t * p )
+{
+ Vec_Fan_t * vFaninsOld;
+ Vec_Int_t * vFanins;
+ Abc_Obj_t * pNode, * pFanin;
+ int i, k;
+
+ assert( p->vFanins->nSize < p->vFaninsNew->nSize );
+ // create the new nodes
+ for ( i = p->vFanins->nSize; i < p->vFanins->nSize + p->nNodesNew; i++ )
+ {
+ // start the node
+ pNode = Abc_NtkCreateNode( pNtk );
+ assert( i == (int)pNode->Id );
+ }
+ // update the old nodes
+ for ( i = 0; i < p->vFanins->nSize; i++ )
+ {
+ // the new array of fanins
+ vFanins = p->vFaninsNew->pArray[i];
+ if ( vFanins == NULL )
+ continue;
+ // remove old fanins
+ pNode = Abc_NtkObj( pNtk, i );
+ vFaninsOld = &pNode->vFanins;
+ for ( k = vFaninsOld->nSize - 1; k >= 0; k-- )
+ {
+ pFanin = Abc_NtkObj( pNtk, vFaninsOld->pArray[k].iFan );
+ Abc_ObjDeleteFanin( pNode, pFanin );
+ }
+ // add new fanins
+ vFanins = p->vFaninsNew->pArray[i];
+ for ( k = 0; k < vFanins->nSize; k++ )
+ {
+ pFanin = Abc_NtkObj( pNtk, vFanins->pArray[k] );
+ Abc_ObjAddFanin( pNode, pFanin );
+ }
+ pNode->pData = p->vSopsNew->pArray[i];
+ assert( pNode->pData != NULL );
+ }
+ // set up the new nodes
+ for ( i = p->vFanins->nSize; i < p->vFanins->nSize + p->nNodesNew; i++ )
+ {
+ // get the new node
+ pNode = Abc_NtkObj( pNtk, i );
+ // add the fanins
+ vFanins = p->vFaninsNew->pArray[i];
+ for ( k = 0; k < vFanins->nSize; k++ )
+ {
+ pFanin = Abc_NtkObj( pNtk, vFanins->pArray[k] );
+ Abc_ObjAddFanin( pNode, pFanin );
+ }
+ pNode->pData = p->vSopsNew->pArray[i];
+ assert( pNode->pData != NULL );
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcMap.c b/src/base/abc/abcMap.c
index ca326ea1..7289b47b 100644
--- a/src/base/abc/abcMap.c
+++ b/src/base/abc/abcMap.c
@@ -33,6 +33,12 @@ static Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNode
static Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase );
static Abc_Obj_t * Abc_NodeFromMapSuper_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis );
static Abc_Obj_t * Abc_NtkFixCiDriver( Abc_Obj_t * pNode );
+
+static Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk );
+static void Abc_NodeSuperChoice( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode );
+static void Abc_NodeFromMapCutPhase( Abc_Ntk_t * pNtkNew, Map_Cut_t * pCut, int fPhase );
+static Abc_Obj_t * Abc_NodeFromMapSuperChoice_rec( Abc_Ntk_t * pNtkNew, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis );
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
@@ -53,8 +59,8 @@ Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int
{
int fCheck = 1;
Abc_Ntk_t * pNtkNew;
-
Map_Man_t * pMan;
+ int clk;
assert( Abc_NtkIsAig(pNtk) );
@@ -81,11 +87,13 @@ Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int
pMan = Abc_NtkToMap( pNtk, DelayTarget, fRecovery, fVerbose );
if ( pMan == NULL )
return NULL;
+clk = clock();
if ( !Map_Mapping( pMan ) )
{
Map_ManFree( pMan );
return NULL;
}
+ Map_ManPrintStatsToFile( pNtk->pSpec, Map_ManReadAreaFinal(pMan), Map_ManReadRequiredGlo(pMan), clock()-clk );
// reconstruct the network after mapping
pNtkNew = Abc_NtkFromMap( pMan, pNtk );
@@ -432,6 +440,265 @@ Abc_Obj_t * Abc_NtkFixCiDriver( Abc_Obj_t * pNode )
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Interface with the mapping package.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkSuperChoice( Abc_Ntk_t * pNtk )
+{
+ int fCheck = 1;
+ Abc_Ntk_t * pNtkNew;
+
+ Map_Man_t * pMan;
+
+ assert( Abc_NtkIsAig(pNtk) );
+
+ // check that the library is available
+ if ( Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) == NULL )
+ {
+ printf( "The current library is not available.\n" );
+ return 0;
+ }
+
+ // derive the supergate library
+ if ( Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()) == NULL && Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) )
+ {
+ printf( "A simple supergate library is derived from gate library \"%s\".\n",
+ Mio_LibraryReadName(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())) );
+ Map_SuperLibDeriveFromGenlib( Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) );
+ }
+
+ // print a warning about choice nodes
+ if ( Abc_NtkCountChoiceNodes( pNtk ) )
+ printf( "Performing mapping with choices.\n" );
+
+ // perform the mapping
+ pMan = Abc_NtkToMap( pNtk, -1, 1, 0 );
+ if ( pMan == NULL )
+ return NULL;
+ if ( !Map_Mapping( pMan ) )
+ {
+ Map_ManFree( pMan );
+ return NULL;
+ }
+
+ // reconstruct the network after mapping
+ pNtkNew = Abc_NtkFromMapSuperChoice( pMan, pNtk );
+ if ( pNtkNew == NULL )
+ return NULL;
+ Map_ManFree( pMan );
+
+ // make sure that everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkMap: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Creates the mapped network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
+{
+ ProgressBar * pProgress;
+ Abc_Ntk_t * pNtkNew, * pNtkNew2;
+ Abc_Obj_t * pNode;
+ int i;
+
+ // save the pointer to the mapped nodes
+ Abc_NtkForEachCi( pNtk, pNode, i )
+ pNode->pNext = pNode->pCopy;
+ Abc_NtkForEachPo( pNtk, pNode, i )
+ pNode->pNext = pNode->pCopy;
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ pNode->pNext = pNode->pCopy;
+
+ // duplicate the network
+ pNtkNew2 = Abc_NtkDup( pNtk );
+ pNtkNew = Abc_NtkRenode( pNtkNew2, 0, 20, 0, 0, 1 );
+ Abc_NtkBddToSop( pNtkNew );
+
+ // set the old network to point to the new network
+ Abc_NtkForEachCi( pNtk, pNode, i )
+ pNode->pCopy = pNode->pCopy->pCopy;
+ Abc_NtkForEachPo( pNtk, pNode, i )
+ pNode->pCopy = pNode->pCopy->pCopy;
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ pNode->pCopy = pNode->pCopy->pCopy;
+ Abc_NtkDelete( pNtkNew2 );
+
+ // set the pointers from the mapper to the new nodes
+ Abc_NtkForEachCi( pNtk, pNode, i )
+ {
+ Map_NodeSetData( Map_ManReadInputs(pMan)[i], 0, (char *)Abc_NodeCreateInv(pNtkNew,pNode->pCopy) );
+ Map_NodeSetData( Map_ManReadInputs(pMan)[i], 1, (char *)pNode->pCopy );
+ }
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ if ( Abc_NodeIsConst(pNode) )
+ continue;
+ Map_NodeSetData( (Map_Node_t *)pNode->pNext, 0, (char *)Abc_NodeCreateInv(pNtkNew,pNode->pCopy) );
+ Map_NodeSetData( (Map_Node_t *)pNode->pNext, 1, (char *)pNode->pCopy );
+ }
+
+ // assign the mapping of the required phase to the POs
+ pProgress = Extra_ProgressBarStart( stdout, Abc_NtkNodeNum(pNtk) );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ if ( Abc_NodeIsConst(pNode) )
+ continue;
+ Abc_NodeSuperChoice( pNtkNew, pNode );
+ }
+ Extra_ProgressBarStop( pProgress );
+ return pNtkNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Creates the mapped network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeSuperChoice( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode )
+{
+ Map_Node_t * pMapNode = (Map_Node_t *)pNode->pNext;
+ Map_Cut_t * pCuts, * pTemp;
+
+ pCuts = Map_NodeReadCuts(pMapNode);
+ for ( pTemp = Map_CutReadNext(pCuts); pTemp; pTemp = Map_CutReadNext(pTemp) )
+ {
+ Abc_NodeFromMapCutPhase( pNtkNew, pTemp, 0 );
+ Abc_NodeFromMapCutPhase( pNtkNew, pTemp, 1 );
+ }
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Constructs the nodes corrresponding to one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeFromMapCutPhase( Abc_Ntk_t * pNtkNew, Map_Cut_t * pCut, int fPhase )
+{
+ Abc_Obj_t * pNodePIs[10];
+ Map_Node_t ** ppLeaves;
+ Map_Super_t * pSuperBest;
+ unsigned uPhaseBest;
+ int i, fInvPin, nLeaves;
+
+ pSuperBest = Map_CutReadSuperBest( pCut, fPhase );
+ if ( pSuperBest == NULL )
+ return;
+
+ // get the information about the best cut
+ uPhaseBest = Map_CutReadPhaseBest( pCut, fPhase );
+ nLeaves = Map_CutReadLeavesNum( pCut );
+ ppLeaves = Map_CutReadLeaves( pCut );
+
+ // collect the PI nodes
+ for ( i = 0; i < nLeaves; i++ )
+ {
+ fInvPin = ((uPhaseBest & (1 << i)) > 0);
+ pNodePIs[i] = (Abc_Obj_t *)Map_NodeReadData( ppLeaves[i], !fInvPin );
+ assert( pNodePIs[i] != NULL );
+ }
+
+ // implement the supergate
+ Abc_NodeFromMapSuperChoice_rec( pNtkNew, pSuperBest, pNodePIs, nLeaves );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Constructs the nodes corrresponding to one supergate.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeFromMapSuperChoice_rec( Abc_Ntk_t * pNtkNew, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis )
+{
+ Mio_Gate_t * pRoot;
+ Map_Super_t ** ppFanins;
+ Abc_Obj_t * pNodeNew, * pNodeFanin;
+ int nFanins, Number, i;
+
+ // get the parameters of the supergate
+ pRoot = Map_SuperReadRoot(pSuper);
+ if ( pRoot == NULL )
+ {
+ Number = Map_SuperReadNum(pSuper);
+ if ( Number < nNodePis )
+ {
+ return pNodePis[Number];
+ }
+ else
+ {
+// assert( 0 );
+ /* It might happen that a super gate with 5 inputs is constructed that
+ * actually depends only on the first four variables; i.e the fifth is a
+ * don't care -- in that case we connect constant node for the fifth
+ * (since the cut only has 4 variables). An interesting question is what
+ * if the first variable (and not the fifth one is the redundant one;
+ * can that happen?) */
+ return Abc_NodeCreateConst0(pNtkNew);
+ }
+ }
+
+ // get information about the fanins of the supergate
+ nFanins = Map_SuperReadFaninNum( pSuper );
+ ppFanins = Map_SuperReadFanins( pSuper );
+ // create a new node with these fanins
+ pNodeNew = Abc_NtkCreateNode( pNtkNew );
+ for ( i = 0; i < nFanins; i++ )
+ {
+ pNodeFanin = Abc_NodeFromMapSuperChoice_rec( pNtkNew, ppFanins[i], pNodePis, nNodePis );
+ Abc_ObjAddFanin( pNodeNew, pNodeFanin );
+ }
+ pNodeNew->pData = Abc_SopRegister( pNtkNew->pManFunc, Mio_GateReadSop(pRoot) );
+ return pNodeNew;
+}
+
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/abc/abcNetlist.c b/src/base/abc/abcNetlist.c
index 671fa9bc..0b7b44a0 100644
--- a/src/base/abc/abcNetlist.c
+++ b/src/base/abc/abcNetlist.c
@@ -67,7 +67,12 @@ Abc_Ntk_t * Abc_NtkLogic( Abc_Ntk_t * pNtk )
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
// create and connect the POs
Abc_NtkForEachPo( pNtk, pObj, i )
- Abc_ObjAddFanin( Abc_NtkCreateTermPo(pNtkNew), Abc_ObjFanin0(pObj)->pCopy );
+ {
+ if ( Abc_ObjFaninNum(pObj) == 0 )
+ Abc_ObjAddFanin( Abc_NtkCreateTermPo(pNtkNew), pObj->pCopy );
+ else
+ Abc_ObjAddFanin( Abc_NtkCreateTermPo(pNtkNew), Abc_ObjFanin0(pObj)->pCopy );
+ }
// connect the latches
Abc_NtkForEachLatch( pNtk, pObj, i )
Abc_ObjAddFanin( pObj->pCopy, Abc_ObjFanin0(pObj)->pCopy );
diff --git a/src/base/abc/abcPrint.c b/src/base/abc/abcPrint.c
index 0c3a2b5e..49b6db72 100644
--- a/src/base/abc/abcPrint.c
+++ b/src/base/abc/abcPrint.c
@@ -59,7 +59,7 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk )
if ( Abc_NtkIsLogicSop(pNtk) )
{
fprintf( pFile, " cube = %5d", Abc_NtkGetCubeNum(pNtk) );
-// fprintf( pFile, " lit(sop) = %5d", Abc_NtkGetLitNum(pNtk) );
+ fprintf( pFile, " lit(sop) = %5d", Abc_NtkGetLitNum(pNtk) );
fprintf( pFile, " lit(fac) = %5d", Abc_NtkGetLitFactNum(pNtk) );
}
else if ( Abc_NtkIsLogicBdd(pNtk) )
diff --git a/src/base/abc/abcRenode.c b/src/base/abc/abcRenode.c
index 6a24ab80..ab1a09c3 100644
--- a/src/base/abc/abcRenode.c
+++ b/src/base/abc/abcRenode.c
@@ -130,6 +130,8 @@ void Abc_NtkRenodeInt( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
Abc_NtkForEachCo( pNtk, pNode, i )
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
+ if ( Abc_ObjIsTerm(Abc_ObjFanin0(pNode)) )
+ continue;
Abc_NtkRenode_rec( pNtkNew, Abc_ObjFanin0(pNode) );
}
Extra_ProgressBarStop( pProgress );
diff --git a/src/base/abc/abcSop.c b/src/base/abc/abcSop.c
index 9862ea8e..aabc2660 100644
--- a/src/base/abc/abcSop.c
+++ b/src/base/abc/abcSop.c
@@ -61,6 +61,37 @@ char * Abc_SopRegister( Extra_MmFlex_t * pMan, char * pName )
/**Function*************************************************************
+ Synopsis [Starts the constant 1 cover with the given number of variables and cubes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Abc_SopStart( Extra_MmFlex_t * pMan, int nCubes, int nVars )
+{
+ char * pSopCover;
+ char * pCube;
+ int i, v;
+ pSopCover = Extra_MmFlexEntryFetch( pMan, nCubes * (nVars + 3) + 1 );
+ for ( i = 0; i < nCubes; i++ )
+ {
+ pCube = pSopCover + i * (nVars + 3);
+ for ( v = 0; v < nVars; v++ )
+ pCube[v] = '-';
+ pCube[nVars + 0] = ' ';
+ pCube[nVars + 1] = '1';
+ pCube[nVars + 2] = '\n';
+ }
+ pSopCover[nCubes * (nVars + 3)] = 0;
+ return pSopCover;
+}
+
+
+/**Function*************************************************************
+
Synopsis [Reads the number of cubes in the cover.]
Description []
diff --git a/src/base/abc/abcStrash.c b/src/base/abc/abcStrash.c
index eb5b3df7..fcfeefda 100644
--- a/src/base/abc/abcStrash.c
+++ b/src/base/abc/abcStrash.c
@@ -107,6 +107,7 @@ void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
// perform strashing
vNodes = Abc_NtkDfs( pNtk );
+// vNodes = Abc_AigCollectAll( pNtk );
pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
for ( i = 0; i < vNodes->nSize; i++ )
{
diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c
index 1c826f95..e971ca18 100644
--- a/src/base/abc/abcUtil.c
+++ b/src/base/abc/abcUtil.c
@@ -768,6 +768,11 @@ Vec_Ptr_t * Abc_AigCollectAll( Abc_Ntk_t * pNtk )
vNodes = Vec_PtrAlloc( 100 );
Abc_NtkForEachNode( pNtk, pNode, i )
Vec_PtrPush( vNodes, pNode );
+
+ // works only if the levels are set!!!
+ if ( !Abc_NtkIsAig(pNtk) )
+ Abc_NtkGetLevelNum(pNtk);
+
Vec_PtrSort( vNodes, Abc_NodeCompareLevelsIncrease );
return vNodes;
}
diff --git a/src/base/abc/abc_.c b/src/base/abc/abc_.c
new file mode 100644
index 00000000..bef3836f
--- /dev/null
+++ b/src/base/abc/abc_.c
@@ -0,0 +1,47 @@
+/**CFile****************************************************************
+
+ FileName [abc_.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abc_.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/map/fpga/fpgaCore.c b/src/map/fpga/fpgaCore.c
index 37726542..457c2384 100644
--- a/src/map/fpga/fpgaCore.c
+++ b/src/map/fpga/fpgaCore.c
@@ -127,12 +127,19 @@ int Fpga_MappingPostProcess( Fpga_Man_t * p )
float aSwitchTotalPrev, aSwitchTotalCur;
int Iter, clk;
+
if ( p->fVerbose )
{
printf( "Iteration %dD : Area = %11.1f ", 0, Fpga_MappingArea( p ) );
PRT( "Time", p->timeMatch );
}
+
+// Fpga_MappingExplore( p );
+// p->fAreaGlo = Fpga_MappingArea( p );
+// return;
+
+
// aAreaTotalCur = FPGA_FLOAT_LARGE;
aAreaTotalCur = Fpga_MappingSetRefsAndArea( p );
@@ -159,6 +166,11 @@ PRT( "Time", clock() - clk );
} while ( aAreaTotalPrev > 1.02 * aAreaTotalCur );
+// Fpga_MappingExplore( p );
+// p->fAreaGlo = Fpga_MappingArea( p );
+// return;
+
+
/*
// compute the area of each cut
aAreaTotalCur = Fpga_MappingSetRefsAndArea( p );
diff --git a/src/map/fpga/fpgaInt.h b/src/map/fpga/fpgaInt.h
index 0fea9ec8..63308d53 100644
--- a/src/map/fpga/fpgaInt.h
+++ b/src/map/fpga/fpgaInt.h
@@ -334,6 +334,7 @@ extern float Fpga_TimeComputeArrivalMax( Fpga_Man_t * p );
extern void Fpga_TimeComputeRequiredGlobal( Fpga_Man_t * p );
extern void Fpga_TimeComputeRequired( Fpga_Man_t * p, float fRequired );
extern void Fpga_TimePropagateRequired( Fpga_Man_t * p, Fpga_NodeVec_t * vNodes );
+extern void Fpga_TimePropagateArrival( Fpga_Man_t * p );
/*=== fpgaTruth.c ===============================================================*/
extern void Fpga_MappingTruths( Fpga_Man_t * pMan );
/*=== fpgaVec.c =============================================================*/
@@ -368,6 +369,7 @@ extern float Fpga_MappingGetAreaFlow( Fpga_Man_t * p );
extern float Fpga_MappingArea( Fpga_Man_t * pMan );
extern float Fpga_MappingComputeCutAreas( Fpga_Man_t * pMan );
extern float Fpga_MappingSetRefsAndArea( Fpga_Man_t * pMan );
+extern Fpga_NodeVec_t * Fpga_MappingCollectRefed( Fpga_Man_t * pMan );
extern int Fpga_MappingCountLevels( Fpga_Man_t * pMan );
extern void Fpga_MappingUnmark( Fpga_Man_t * pMan );
extern void Fpga_MappingUnmark_rec( Fpga_Node_t * pNode );
diff --git a/src/map/fpga/fpgaMatch.c b/src/map/fpga/fpgaMatch.c
index 8668ce4b..599662f7 100644
--- a/src/map/fpga/fpgaMatch.c
+++ b/src/map/fpga/fpgaMatch.c
@@ -724,6 +724,112 @@ clk = clock();
}
#endif
+
+
+/**function*************************************************************
+
+ synopsis [Performs area minimization using a heuristic algorithm.]
+
+ description []
+
+ sideeffects []
+
+ seealso []
+
+***********************************************************************/
+float Fpga_FindBestNode( Fpga_Man_t * p, Fpga_NodeVec_t * vNodes, Fpga_Node_t ** ppNode, Fpga_Cut_t ** ppCutBest )
+{
+ Fpga_Node_t * pNode;
+ Fpga_Cut_t * pCut;
+ float Gain, CutArea1, CutArea2, CutArea3;
+ int i;
+
+ Gain = 0;
+ for ( i = 0; i < vNodes->nSize; i++ )
+ {
+ pNode = vNodes->pArray[i];
+ // deref the current cut
+ CutArea1 = Fpga_CutDeref( p, pNode, pNode->pCutBest, 0 );
+
+ // ref all the cuts
+ for ( pCut = pNode->pCuts->pNext; pCut; pCut = pCut->pNext )
+ {
+ if ( pCut == pNode->pCutBest )
+ continue;
+ if ( pCut->tArrival > pNode->tRequired )
+ continue;
+
+ CutArea2 = Fpga_CutGetAreaDerefed( p, pCut );
+ if ( Gain < CutArea1 - CutArea2 )
+ {
+ *ppNode = pNode;
+ *ppCutBest = pCut;
+ Gain = CutArea1 - CutArea2;
+ }
+ }
+ // ref the old cut
+ CutArea3 = Fpga_CutRef( p, pNode, pNode->pCutBest, 0 );
+ assert( CutArea1 == CutArea3 );
+ }
+ if ( Gain == 0 )
+ printf( "Returning no gain.\n" );
+
+ return Gain;
+}
+
+/**function*************************************************************
+
+ synopsis [Performs area minimization using a heuristic algorithm.]
+
+ description []
+
+ sideeffects []
+
+ seealso []
+
+***********************************************************************/
+void Fpga_MappingExplore( Fpga_Man_t * p )
+{
+ Fpga_Cut_t * pCutBest;
+ Fpga_Node_t * pNodeBest;
+ Fpga_NodeVec_t * vNodes;
+ float Area, Gain, CutArea1, CutArea2;
+ int i;
+
+ // compute the arrival times
+ Fpga_TimePropagateArrival( p );
+ p->fRequiredGlo = Fpga_TimeComputeArrivalMax( p );
+ Fpga_TimeComputeRequired( p, p->fRequiredGlo );
+
+ // assign the refs
+ Area = Fpga_MappingSetRefsAndArea( p );
+ // collect the nodes
+ vNodes = Fpga_MappingCollectRefed( p );
+ // find the best node to update
+ for ( i = 0; Gain = Fpga_FindBestNode(p, vNodes, &pNodeBest, &pCutBest); i++ )
+ {
+ // update the node
+ assert( pNodeBest->pCutBest != pCutBest );
+ // deref the current cut
+ CutArea1 = Fpga_CutDeref( p, pNodeBest, pNodeBest->pCutBest, 0 );
+ // ref the new cut
+ CutArea2 = Fpga_CutRef( p, pNodeBest, pCutBest, 0 );
+ assert( CutArea1 - CutArea2 == Gain );
+ printf( "Iteration %2d: Gain = %5.2f.\n", i, Gain );
+ // update the node
+ pNodeBest->pCutBest = pCutBest;
+ // collect new nodes
+ Fpga_NodeVecFree( vNodes );
+ vNodes = Fpga_MappingCollectRefed( p );
+ // compute the arrival and required times
+ Fpga_TimePropagateArrival( p );
+ Fpga_TimeComputeRequired( p, p->fRequiredGlo );
+ }
+
+
+}
+
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/map/fpga/fpgaTime.c b/src/map/fpga/fpgaTime.c
index df98faa1..066ae215 100644
--- a/src/map/fpga/fpgaTime.c
+++ b/src/map/fpga/fpgaTime.c
@@ -182,6 +182,34 @@ void Fpga_TimePropagateRequired( Fpga_Man_t * p, Fpga_NodeVec_t * vNodes )
}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the required times of all nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fpga_TimePropagateArrival( Fpga_Man_t * p )
+{
+ Fpga_Node_t * pNode;
+ Fpga_Cut_t * pCut;
+ int i;
+
+ // clean the required times and the fanout counts for all nodes
+ for ( i = 0; i < p->vAnds->nSize; i++ )
+ {
+ pNode = p->vAnds->pArray[i];
+ for ( pCut = pNode->pCuts->pNext; pCut; pCut = pCut->pNext )
+ pCut->tArrival = Fpga_TimeCutComputeArrival( p, pCut );
+ }
+}
+
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/map/fpga/fpgaUtils.c b/src/map/fpga/fpgaUtils.c
index a5b2cb32..fc67d52b 100644
--- a/src/map/fpga/fpgaUtils.c
+++ b/src/map/fpga/fpgaUtils.c
@@ -493,6 +493,32 @@ float Fpga_MappingSetRefsAndArea_rec( Fpga_Man_t * pMan, Fpga_Node_t * pNode )
/**Function*************************************************************
+ Synopsis [Collect the referenced nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Fpga_NodeVec_t * Fpga_MappingCollectRefed( Fpga_Man_t * pMan )
+{
+ Fpga_NodeVec_t * vNodes;
+ int i;
+ vNodes = Fpga_NodeVecAlloc( 100 );
+ for ( i = 0; i < pMan->vNodesAll->nSize; i++ )
+ {
+ if ( Fpga_NodeIsVar(pMan->vNodesAll->pArray[i]) )
+ continue;
+ if ( pMan->vNodesAll->pArray[i]->nRefs )
+ Fpga_NodeVecPush( vNodes, pMan->vNodesAll->pArray[i] );
+ }
+ return vNodes;
+}
+
+/**Function*************************************************************
+
Synopsis [Computes the number of logic levels not counting PIs/POs.]
Description []
diff --git a/src/map/mapper/mapper.h b/src/map/mapper/mapper.h
index a6bfccf8..9ef8ee17 100644
--- a/src/map/mapper/mapper.h
+++ b/src/map/mapper/mapper.h
@@ -82,6 +82,8 @@ extern Map_Node_t * Map_ManReadConst1 ( Map_Man_t * p );
extern Map_Time_t * Map_ManReadInputArrivals( Map_Man_t * p );
extern Mio_Library_t * Map_ManReadGenLib ( Map_Man_t * p );
extern bool Map_ManReadVerbose( Map_Man_t * p );
+extern float Map_ManReadAreaFinal( Map_Man_t * p );
+extern float Map_ManReadRequiredGlo( Map_Man_t * p );
extern void Map_ManSetTimeToMap( Map_Man_t * p, int Time );
extern void Map_ManSetTimeToNet( Map_Man_t * p, int Time );
extern void Map_ManSetTimeSweep( Map_Man_t * p, int Time );
@@ -125,6 +127,7 @@ extern Map_Node_t ** Map_CutReadLeaves( Map_Cut_t * p );
extern unsigned Map_CutReadPhaseBest( Map_Cut_t * p, int fPhase );
extern unsigned Map_CutReadPhase0( Map_Cut_t * p );
extern unsigned Map_CutReadPhase1( Map_Cut_t * p );
+extern Map_Cut_t * Map_CutReadNext( Map_Cut_t * p );
extern char * Map_SuperReadFormula( Map_Super_t * p );
extern Mio_Gate_t * Map_SuperReadRoot( Map_Super_t * p );
diff --git a/src/map/mapper/mapperCore.c b/src/map/mapper/mapperCore.c
index 415e4974..e72b9134 100644
--- a/src/map/mapper/mapperCore.c
+++ b/src/map/mapper/mapperCore.c
@@ -82,8 +82,8 @@ int Map_Mapping( Map_Man_t * p )
p->AreaBase = Map_MappingGetArea( p, p->vMapping );
if ( p->fVerbose )
{
-printf( "Delay : FanViols = %5d Flow = %11.1f Area = %11.1f %4.1f %% ",
- 0, Map_MappingGetAreaFlow(p), p->AreaBase, 0.0 );
+printf( "Delay : Delay = %5.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
+ p->fRequiredGlo, Map_MappingGetAreaFlow(p), p->AreaBase, 0.0 );
PRT( "Time", p->timeMatch );
}
//////////////////////////////////////////////////////////////////////
@@ -103,8 +103,8 @@ PRT( "Time", p->timeMatch );
p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
if ( p->fVerbose )
{
-printf( "AreaFlow : FanViols = %5d Flow = %11.1f Area = %11.1f %4.1f %% ",
- 0, Map_MappingGetAreaFlow(p), p->AreaFinal,
+printf( "AreaFlow : Delay = %5.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
+ p->fRequiredGlo, Map_MappingGetAreaFlow(p), p->AreaFinal,
100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
PRT( "Time", clock() - clk );
}
@@ -127,8 +127,8 @@ PRT( "Time", clock() - clk );
p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
if ( p->fVerbose )
{
-printf( "Area : FanViols = %5d Flow = %11.1f Area = %11.1f %4.1f %% ",
- 0, 0.0, p->AreaFinal,
+printf( "Area : Delay = %5.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
+ p->fRequiredGlo, 0.0, p->AreaFinal,
100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
PRT( "Time", clock() - clk );
}
@@ -151,8 +151,8 @@ PRT( "Time", clock() - clk );
p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
if ( p->fVerbose )
{
-printf( "Area : FanViols = %5d Flow = %11.1f Area = %11.1f %4.1f %% ",
- 0, 0.0, p->AreaFinal,
+printf( "Area : Delay = %5.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
+ p->fRequiredGlo, 0.0, p->AreaFinal,
100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
PRT( "Time", clock() - clk );
}
diff --git a/src/map/mapper/mapperCreate.c b/src/map/mapper/mapperCreate.c
index 61c90d1c..4d7ca7d0 100644
--- a/src/map/mapper/mapperCreate.c
+++ b/src/map/mapper/mapperCreate.c
@@ -52,6 +52,8 @@ Map_Node_t * Map_ManReadConst1 ( Map_Man_t * p ) { return
Map_Time_t * Map_ManReadInputArrivals( Map_Man_t * p ) { return p->pInputArrivals;}
Mio_Library_t * Map_ManReadGenLib ( Map_Man_t * p ) { return p->pSuperLib->pGenlib; }
bool Map_ManReadVerbose( Map_Man_t * p ) { return p->fVerbose; }
+float Map_ManReadAreaFinal( Map_Man_t * p ) { return p->AreaFinal; }
+float Map_ManReadRequiredGlo( Map_Man_t * p ) { return p->fRequiredGlo; }
void Map_ManSetTimeToMap( Map_Man_t * p, int Time ) { p->timeToMap = Time; }
void Map_ManSetTimeToNet( Map_Man_t * p, int Time ) { p->timeToNet = Time; }
void Map_ManSetTimeSweep( Map_Man_t * p, int Time ) { p->timeSweep = Time; }
@@ -126,6 +128,7 @@ Map_Node_t ** Map_CutReadLeaves( Map_Cut_t * p ) { return p->pp
unsigned Map_CutReadPhaseBest( Map_Cut_t * p, int fPhase ) { return p->M[fPhase].uPhaseBest;}
unsigned Map_CutReadPhase0( Map_Cut_t * p ) { return p->M[0].uPhaseBest;}
unsigned Map_CutReadPhase1( Map_Cut_t * p ) { return p->M[1].uPhaseBest;}
+Map_Cut_t * Map_CutReadNext( Map_Cut_t * p ) { return p->pNext; }
/**Function*************************************************************
@@ -190,7 +193,8 @@ Map_Man_t * Map_ManCreate( int nInputs, int nOutputs, int fVerbose )
p->pSuperLib = Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame());
p->nVarsMax = p->pSuperLib->nVarsMax;
p->fVerbose = fVerbose;
- p->fEpsilon = (float)0.00001;
+// p->fEpsilon = (float)0.00001;
+ p->fEpsilon = (float)0.001;
assert( p->nVarsMax > 0 );
// start various data structures
@@ -210,6 +214,7 @@ Map_Man_t * Map_ManCreate( int nInputs, int nOutputs, int fVerbose )
p->vMapping = Map_NodeVecAlloc( 100 );
p->vInside = Map_NodeVecAlloc( 100 );
p->vFanins = Map_NodeVecAlloc( 100 );
+ p->vVisited = Map_NodeVecAlloc( 100 );
// create the PI nodes
p->nInputs = nInputs;
@@ -253,6 +258,8 @@ void Map_ManFree( Map_Man_t * p )
Map_NodeVecFree( p->vNodesTemp );
if ( p->vMapping )
Map_NodeVecFree( p->vMapping );
+ if ( p->vVisited )
+ Map_NodeVecFree( p->vVisited );
Extra_MmFixedStop( p->mmNodes, 0 );
Extra_MmFixedStop( p->mmCuts, 0 );
FREE( p->pInputArrivals );
diff --git a/src/map/mapper/mapperCut.c b/src/map/mapper/mapperCut.c
index 87592365..8566c819 100644
--- a/src/map/mapper/mapperCut.c
+++ b/src/map/mapper/mapperCut.c
@@ -23,9 +23,9 @@
////////////////////////////////////////////////////////////////////////
// the largest number of cuts considered
-#define MAP_CUTS_MAX_COMPUTE 200
+#define MAP_CUTS_MAX_COMPUTE 1000
// the largest number of cuts used
-#define MAP_CUTS_MAX_USE 50
+#define MAP_CUTS_MAX_USE 250
// temporary hash table to store the cuts
typedef struct Map_CutTableStrutct_t Map_CutTable_t;
@@ -373,6 +373,14 @@ Map_Cut_t * Map_CutMergeLists( Map_Man_t * p, Map_CutTable_t * pTable,
pTemp1 = ppArray1[i];
pTemp2 = ppArray2[k];
+ if ( pTemp1->nLeaves == p->nVarsMax && pTemp2->nLeaves == p->nVarsMax )
+ {
+ if ( pTemp1->ppLeaves[0] != pTemp2->ppLeaves[0] )
+ continue;
+ if ( pTemp1->ppLeaves[1] != pTemp2->ppLeaves[1] )
+ continue;
+ }
+
// check if k-feasible cut exists
nNodes = Map_CutMergeTwo( pTemp1, pTemp2, ppNodes, p->nVarsMax );
if ( nNodes == 0 )
@@ -397,6 +405,14 @@ Map_Cut_t * Map_CutMergeLists( Map_Man_t * p, Map_CutTable_t * pTable,
pTemp1 = ppArray1[k];
pTemp2 = ppArray2[i];
+ if ( pTemp1->nLeaves == p->nVarsMax && pTemp2->nLeaves == p->nVarsMax )
+ {
+ if ( pTemp1->ppLeaves[0] != pTemp2->ppLeaves[0] )
+ continue;
+ if ( pTemp1->ppLeaves[1] != pTemp2->ppLeaves[1] )
+ continue;
+ }
+
// check if k-feasible cut exists
nNodes = Map_CutMergeTwo( pTemp1, pTemp2, ppNodes, p->nVarsMax );
if ( nNodes == 0 )
@@ -424,6 +440,14 @@ Map_Cut_t * Map_CutMergeLists( Map_Man_t * p, Map_CutTable_t * pTable,
pTemp1 = ppArray1[k];
pTemp2 = ppArray2[i];
+ if ( pTemp1->nLeaves == p->nVarsMax && pTemp2->nLeaves == p->nVarsMax )
+ {
+ if ( pTemp1->ppLeaves[0] != pTemp2->ppLeaves[0] )
+ continue;
+ if ( pTemp1->ppLeaves[1] != pTemp2->ppLeaves[1] )
+ continue;
+ }
+
// check if k-feasible cut exists
nNodes = Map_CutMergeTwo( pTemp1, pTemp2, ppNodes, p->nVarsMax );
if ( nNodes == 0 )
diff --git a/src/map/mapper/mapperInt.h b/src/map/mapper/mapperInt.h
index c5ecce73..d4262abb 100644
--- a/src/map/mapper/mapperInt.h
+++ b/src/map/mapper/mapperInt.h
@@ -121,6 +121,7 @@ struct Map_ManStruct_t_
unsigned uTruthsLarge[10][32]; // the elementary truth tables
int nCounts[32]; // the counter of minterms
int nCountsBest[32];// the counter of minterms
+ Map_NodeVec_t * vVisited; // the visited cuts during cut computation
// simulation info from the FRAIG manager
int nSimRounds; // the number of words in the simulation info
@@ -262,13 +263,7 @@ struct Map_CutStruct_t_
char nVolume; // the volume of this cut
char fMark; // the mark to denote visited cut
char Phase; // the mark to denote complemented cut
-// float fLevel; // the average level of the fanins
-
- unsigned uTruthTemp[2]; // the temporary truth table used to derive other cuts
- unsigned uTruthZero[2]; // the temporary truth table used to derive other cuts
- unsigned uTruthDc[2]; // the don't-cares (SDCs) computed for this cut
-
- Map_Match_t M[2]; // the matches for the positive/negative phase
+ Map_Match_t M[2]; // the matches for positive/negative phase
};
// the supergate internally represented
diff --git a/src/map/mapper/mapperTruth.c b/src/map/mapper/mapperTruth.c
index 9388b42f..67ef029b 100644
--- a/src/map/mapper/mapperTruth.c
+++ b/src/map/mapper/mapperTruth.c
@@ -22,20 +22,10 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-//static void Map_TruthsCutDcs( Map_Man_t * p, Map_Cut_t * pCut, unsigned uTruth[] );
-static void Map_TruthsCut( Map_Man_t * pMan, Map_Cut_t * pCut );
-static void Map_TruthsCut_rec( Map_Cut_t * pCut, unsigned uTruth[] );
-static void Map_TruthsUnmark_rec( Map_Cut_t * pCut );
-
-/*
-static int s_Same = 0;
-static int s_Diff = 0;
-static int s_Same2 = 0;
-static int s_Diff2 = 0;
-static int s_Truth = 0;
-static int s_Isop1 = 0;
-static int s_Isop2 = 0;
-*/
+static void Map_TruthsCut( Map_Man_t * pMan, Map_Cut_t * pCut );
+static void Map_TruthsCutOne( Map_Man_t * p, Map_Cut_t * pCut, unsigned uTruth[] );
+static void Map_CutsCollect_rec( Map_Cut_t * pCut, Map_NodeVec_t * vVisited );
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -85,10 +75,6 @@ void Map_MappingTruths( Map_Man_t * pMan )
Extra_ProgressBarUpdate( pProgress, i, "Tables ..." );
}
Extra_ProgressBarStop( pProgress );
-
-// printf( "Same = %6d. Diff = %6d.\n", s_Same, s_Diff );
-// printf( "Same2 = %6d. Diff2 = %6d.\n", s_Same2, s_Diff2 );
-// printf( "Truth = %6d. Isop1 = %6d. Isop2 = %6d.\n", s_Truth, s_Isop1, s_Isop2 );
}
/**Function*************************************************************
@@ -106,22 +92,11 @@ void Map_TruthsCut( Map_Man_t * p, Map_Cut_t * pCut )
{
unsigned uTruth[2], uCanon[2];
unsigned char uPhases[16];
- int i;
// generally speaking, 1-input cut can be matched into a wire!
if ( pCut->nLeaves == 1 )
return;
- // set the leaf truth tables
- for ( i = 0; i < pCut->nLeaves; i++ )
- {
- pCut->ppLeaves[i]->pCuts->uTruthTemp[0] = p->uTruths[i][0];
- pCut->ppLeaves[i]->pCuts->uTruthTemp[1] = p->uTruths[i][1];
- }
- // recursively compute the truth table
- pCut->nVolume = 0;
- Map_TruthsCut_rec( pCut, uTruth );
- // recursively unmark the visited cuts
- Map_TruthsUnmark_rec( pCut );
+ Map_TruthsCutOne( p, pCut, uTruth );
// compute the canonical form for the positive phase
Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
@@ -140,15 +115,11 @@ void Map_TruthsCut( Map_Man_t * p, Map_Cut_t * pCut )
// restore the truth table
uTruth[0] = ~uTruth[0];
uTruth[1] = ~uTruth[1];
- // enable don't-care computation
-// Map_TruthsCutDcs( p, pCut, uTruth );
}
-#if 0
-
/**Function*************************************************************
- Synopsis [Adds several other choices using SDCs.]
+ Synopsis [Computes the truth table of one cut.]
Description []
@@ -157,141 +128,79 @@ void Map_TruthsCut( Map_Man_t * p, Map_Cut_t * pCut )
SeeAlso []
***********************************************************************/
-void Map_TruthsCutDcs( Map_Man_t * p, Map_Cut_t * pCut, unsigned uTruth[] )
+void Map_TruthsCutOne( Map_Man_t * p, Map_Cut_t * pCut, unsigned uTruth[] )
{
- unsigned uIsop1[2], uIsop2[2], uCanon[2];
- unsigned char uPhases[16];
+ unsigned uTruth1[2], uTruth2[2];
+ Map_Cut_t * pTemp;
+ int i;
+ // mark the cut leaves
+ for ( i = 0; i < pCut->nLeaves; i++ )
+ {
+ pTemp = pCut->ppLeaves[i]->pCuts;
+ pTemp->fMark = 1;
+ pTemp->M[0].uPhaseBest = p->uTruths[i][0];
+ pTemp->M[1].uPhaseBest = p->uTruths[i][1];
+ }
+ assert( pCut->fMark == 0 );
- // add several other supergate classes derived using don't-cares
- if ( pCut->uTruthDc[0] )
+ // collect the cuts in the cut cone
+ p->vVisited->nSize = 0;
+ Map_CutsCollect_rec( pCut, p->vVisited );
+ assert( p->vVisited->nSize > 0 );
+ pCut->nVolume = p->vVisited->nSize;
+
+ // compute the tables and unmark
+ for ( i = 0; i < pCut->nLeaves; i++ )
+ {
+ pTemp = pCut->ppLeaves[i]->pCuts;
+ pTemp->fMark = 0;
+ }
+ for ( i = 0; i < p->vVisited->nSize; i++ )
{
- int nOnes;
- nOnes = Map_TruthCountOnes( pCut->uTruthDc, pCut->nLeaves );
- if ( nOnes == 1 )
+ // get the cut
+ pTemp = (Map_Cut_t *)p->vVisited->pArray[i];
+ pTemp->fMark = 0;
+ // get truth table of the first branch
+ if ( Map_CutIsComplement(pTemp->pOne) )
+ {
+ uTruth1[0] = ~Map_CutRegular(pTemp->pOne)->M[0].uPhaseBest;
+ uTruth1[1] = ~Map_CutRegular(pTemp->pOne)->M[1].uPhaseBest;
+ }
+ else
+ {
+ uTruth1[0] = Map_CutRegular(pTemp->pOne)->M[0].uPhaseBest;
+ uTruth1[1] = Map_CutRegular(pTemp->pOne)->M[1].uPhaseBest;
+ }
+ // get truth table of the second branch
+ if ( Map_CutIsComplement(pTemp->pTwo) )
+ {
+ uTruth2[0] = ~Map_CutRegular(pTemp->pTwo)->M[0].uPhaseBest;
+ uTruth2[1] = ~Map_CutRegular(pTemp->pTwo)->M[1].uPhaseBest;
+ }
+ else
{
- uTruth[0] ^= pCut->uTruthDc[0];
- uTruth[1] ^= pCut->uTruthDc[1];
-
- // compute the canonical form for the positive phase
- Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
- pCut->M[1].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
- pCut->M[1].uPhase = uPhases[0];
- p->nCanons++;
-
- // compute the canonical form for the negative phase
- uTruth[0] = ~uTruth[0];
- uTruth[1] = ~uTruth[1];
- Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
- pCut->M[0].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
- pCut->M[0].uPhase = uPhases[0];
- p->nCanons++;
+ uTruth2[0] = Map_CutRegular(pTemp->pTwo)->M[0].uPhaseBest;
+ uTruth2[1] = Map_CutRegular(pTemp->pTwo)->M[1].uPhaseBest;
}
- else if ( nOnes == 2 )
+ // get the truth table of the output
+ if ( !pTemp->Phase )
{
- int Num1, Num2, RetValue;
- RetValue = Map_TruthDetectTwoFirst( pCut->uTruthDc, pCut->nLeaves );
- Num1 = RetValue & 255;
- Num2 = (RetValue >> 8) & 255;
-
- // add the first bit
- Map_InfoFlipVar( uTruth, Num1 );
-
- // compute the canonical form for the positive phase
- Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
- pCut->M[1].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
- pCut->M[1].uPhase = uPhases[0];
- p->nCanons++;
-
- // compute the canonical form for the negative phase
- uTruth[0] = ~uTruth[0];
- uTruth[1] = ~uTruth[1];
- Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
- pCut->M[0].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
- pCut->M[0].uPhase = uPhases[0];
- p->nCanons++;
-
- // add the first bit
- Map_InfoFlipVar( uTruth, Num2 );
-
- // compute the canonical form for the positive phase
- Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
- pCut->M[1].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
- pCut->M[1].uPhase = uPhases[0];
- p->nCanons++;
-
- // compute the canonical form for the negative phase
- uTruth[0] = ~uTruth[0];
- uTruth[1] = ~uTruth[1];
- Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
- pCut->M[0].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
- pCut->M[0].uPhase = uPhases[0];
- p->nCanons++;
-
- // add the first bit
- Map_InfoFlipVar( uTruth, Num1 );
-
- // compute the canonical form for the positive phase
- Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
- pCut->M[1].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
- pCut->M[1].uPhase = uPhases[0];
- p->nCanons++;
-
- // compute the canonical form for the negative phase
- uTruth[0] = ~uTruth[0];
- uTruth[1] = ~uTruth[1];
- Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
- pCut->M[0].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
- pCut->M[0].uPhase = uPhases[0];
- p->nCanons++;
+ pTemp->M[0].uPhaseBest = uTruth1[0] & uTruth2[0];
+ pTemp->M[1].uPhaseBest = uTruth1[1] & uTruth2[1];
}
else
{
- // compute the ISOPs
- uIsop1[0] = Map_ComputeIsop_rec( p, uTruth[0] & ~pCut->uTruthDc[0], uTruth[0] | pCut->uTruthDc[0], 0, pCut->nLeaves, 0 );
- uIsop1[1] = uIsop1[0];
- if ( uIsop1[0] != uTruth[0] )
- {
- // compute the canonical form for the positive phase
- Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uIsop1, uPhases, uCanon );
- pCut->M[1].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
- pCut->M[1].uPhase = uPhases[0];
- p->nCanons++;
-
- // compute the canonical form for the negative phase
- uIsop1[0] = ~uIsop1[0];
- uIsop1[1] = ~uIsop1[1];
- Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uIsop1, uPhases, uCanon );
- pCut->M[0].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
- pCut->M[0].uPhase = uPhases[0];
- p->nCanons++;
- }
-
- uIsop2[0] = Map_ComputeIsop_rec( p, uTruth[0] & ~pCut->uTruthDc[0], uTruth[0] | pCut->uTruthDc[0], pCut->nLeaves-1, pCut->nLeaves, 1 );
- uIsop2[1] = uIsop2[0];
- if ( uIsop2[0] != uTruth[0] && uIsop2[0] != uIsop1[0] )
- {
- // compute the canonical form for the positive phase
- Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uIsop2, uPhases, uCanon );
- pCut->M[1].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
- p->nCanons++;
-
- // compute the canonical form for the negative phase
- uIsop2[0] = ~uIsop2[0];
- uIsop2[1] = ~uIsop2[1];
- Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uIsop2, uPhases, uCanon );
- pCut->M[0].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
- pCut->M[0].uPhase = uPhases[0];
- p->nCanons++;
- }
+ pTemp->M[0].uPhaseBest = ~(uTruth1[0] & uTruth2[0]);
+ pTemp->M[1].uPhaseBest = ~(uTruth1[1] & uTruth2[1]);
}
}
+ uTruth[0] = pTemp->M[0].uPhaseBest;
+ uTruth[1] = pTemp->M[1].uPhaseBest;
}
-#endif
-
/**Function*************************************************************
- Synopsis [Recursively derives the truth table for the cut.]
+ Synopsis [Recursively collect the cuts.]
Description []
@@ -300,147 +209,17 @@ void Map_TruthsCutDcs( Map_Man_t * p, Map_Cut_t * pCut, unsigned uTruth[] )
SeeAlso []
***********************************************************************/
-void Map_TruthsCut_rec( Map_Cut_t * pCut, unsigned uTruthRes[] )
+void Map_CutsCollect_rec( Map_Cut_t * pCut, Map_NodeVec_t * vVisited )
{
- unsigned uTruth1[2], uTruth2[2];
- // if this is the elementary cut, its truth table is already available
- if ( pCut->nLeaves == 1 )
- {
- uTruthRes[0] = pCut->uTruthTemp[0];
- uTruthRes[1] = pCut->uTruthTemp[1];
- return;
- }
- // if this node was already visited, return its computed truth table
if ( pCut->fMark )
- {
- uTruthRes[0] = pCut->uTruthTemp[0];
- uTruthRes[1] = pCut->uTruthTemp[1];
return;
- }
+ Map_CutsCollect_rec( Map_CutRegular(pCut->pOne), vVisited );
+ Map_CutsCollect_rec( Map_CutRegular(pCut->pTwo), vVisited );
+ assert( pCut->fMark == 0 );
pCut->fMark = 1;
- pCut->nVolume++;
-
- assert( !Map_IsComplement(pCut) );
- Map_TruthsCut_rec( Map_CutRegular(pCut->pOne), uTruth1 );
- if ( Map_CutIsComplement(pCut->pOne) )
- {
- uTruth1[0] = ~uTruth1[0];
- uTruth1[1] = ~uTruth1[1];
- }
- Map_TruthsCut_rec( Map_CutRegular(pCut->pTwo), uTruth2 );
- if ( Map_CutIsComplement(pCut->pTwo) )
- {
- uTruth2[0] = ~uTruth2[0];
- uTruth2[1] = ~uTruth2[1];
- }
- if ( !pCut->Phase )
- {
- uTruthRes[0] = pCut->uTruthTemp[0] = uTruth1[0] & uTruth2[0];
- uTruthRes[1] = pCut->uTruthTemp[1] = uTruth1[1] & uTruth2[1];
- }
- else
- {
- uTruthRes[0] = pCut->uTruthTemp[0] = ~(uTruth1[0] & uTruth2[0]);
- uTruthRes[1] = pCut->uTruthTemp[1] = ~(uTruth1[1] & uTruth2[1]);
- }
-}
-
-/**Function*************************************************************
-
- Synopsis [Recursively derives the truth table for the cut.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Map_TruthsUnmark_rec( Map_Cut_t * pCut )
-{
- if ( pCut->nLeaves == 1 )
- return;
- // if this node was already visited, return its computed truth table
- if ( pCut->fMark == 0 )
- return;
- pCut->fMark = 0;
- Map_TruthsUnmark_rec( Map_CutRegular(pCut->pOne) );
- Map_TruthsUnmark_rec( Map_CutRegular(pCut->pTwo) );
+ Map_NodeVecPush( vVisited, (Map_Node_t *)pCut );
}
-/**Function*************************************************************
-
- Synopsis [Returns the truth table of the don't-care set.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Map_TruthsCutDontCare( Map_Man_t * pMan, Map_Cut_t * pCut, unsigned * uTruthDc )
-{
- if ( pCut->pOne || (pCut->uTruthZero[0] == 0 && pCut->uTruthZero[1] == 0) )
- return 0;
- assert( (pCut->uTruthTemp[0] & pCut->uTruthZero[0]) == 0 );
- assert( (pCut->uTruthTemp[1] & pCut->uTruthZero[1]) == 0 );
- uTruthDc[0] = ((~0) & (~pCut->uTruthTemp[0]) & (~pCut->uTruthZero[0]));
- uTruthDc[1] = ((~0) & (~pCut->uTruthTemp[1]) & (~pCut->uTruthZero[1]));
- if ( uTruthDc[0] == 0 && uTruthDc[1] == 0 )
- return 0;
- return 1;
-}
-
-/**Function*************************************************************
-
- Synopsis [Expand the truth table]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Map_TruthCountOnes( unsigned * uTruth, int nLeaves )
-{
- int i, nMints, Counter;
- nMints = (1 << nLeaves);
- Counter = 0;
- for ( i = 0; i < nMints; i++ )
- Counter += Map_InfoReadVar( uTruth, i );
- return Counter;
-}
-
-/**Function*************************************************************
-
- Synopsis [Expand the truth table]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Map_TruthDetectTwoFirst( unsigned * uTruth, int nLeaves )
-{
- int i, nMints, Num1 = -1, Num2 = -1;
- nMints = (1 << nLeaves);
- for ( i = 0; i < nMints; i++ )
- if ( Map_InfoReadVar( uTruth, i ) )
- {
- if ( Num1 == -1 )
- Num1 = i;
- else if ( Num2 == -1 )
- Num2 = i;
- else
- break;
- }
- assert( Num1 != -1 && Num2 != -1 );
- return (Num1 << 8) | Num2;
-}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/opt/fxu/fxu.c b/src/opt/fxu/fxu.c
new file mode 100644
index 00000000..4b95b5a5
--- /dev/null
+++ b/src/opt/fxu/fxu.c
@@ -0,0 +1,260 @@
+/**CFile****************************************************************
+
+ FileName [fxu.c]
+
+ PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
+
+ Synopsis [The entrance into the fast extract module.]
+
+ Author [MVSIS Group]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - February 1, 2003.]
+
+ Revision [$Id: fxu.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "fxuInt.h"
+//#include "mvc.h"
+#include "fxu.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*===== fxuCreate.c ====================================================*/
+extern Fxu_Matrix * Fxu_CreateMatrix( Fxu_Data_t * pData );
+extern void Fxu_CreateCovers( Fxu_Matrix * p, Fxu_Data_t * pData );
+
+static int s_MemoryTotal;
+static int s_MemoryPeak;
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Performs fast_extract on a set of covers.]
+
+ Description [All the covers are given in the array p->ppCovers.
+ The resulting covers are returned in the array p->ppCoversNew.
+ The number of entries in both cover arrays is equal to the number
+ of all values in the current nodes plus the max expected number
+ of extracted nodes (p->nValuesCi + p->nValuesInt + p->nValuesExtMax).
+ The first p->nValuesCi entries, corresponding to the CI nodes, are NULL.
+ The next p->nValuesInt entries, corresponding to the int nodes, are covers
+ from which the divisors are extracted. The last p->nValuesExtMax entries
+ are reserved for the new covers to be extracted. The number of extracted
+ covers is returned. This number does not exceed the given number (p->nNodesExt).
+ Two other things are important for the correct operation of this procedure:
+ (1) The input covers should be SCC-free. (2) The literal array (pCover->pLits)
+ is allocated in each cover. The i-th entry in the literal array of a cover
+ is the number of the cover in the array p->ppCovers, which represents this
+ literal (variable value) in the given cover.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Fxu_FastExtract( Fxu_Data_t * pData )
+{
+ Fxu_Matrix * p;
+ Fxu_Single * pSingle;
+ Fxu_Double * pDouble;
+ int Weight1, Weight2, Weight3;
+
+ s_MemoryTotal = 0;
+ s_MemoryPeak = 0;
+
+ // create the matrix
+ p = Fxu_CreateMatrix( pData );
+ if ( p == NULL )
+ return -1;
+// if ( pData->fVerbose )
+// printf( "Memory usage after construction: Total = %d. Peak = %d.\n", s_MemoryTotal, s_MemoryPeak );
+//Fxu_MatrixPrint( NULL, p );
+
+ if ( pData->fOnlyS )
+ {
+ pData->nNodesNew = 0;
+ do
+ {
+ Weight1 = Fxu_HeapSingleReadMaxWeight( p->pHeapSingle );
+ if ( pData->fVerbose )
+ printf( "Best single = %3d.\n", Weight1 );
+ if ( Weight1 > 0 || Weight1 == 0 && pData->fUse0 )
+ Fxu_UpdateSingle( p );
+ else
+ break;
+ }
+ while ( ++pData->nNodesNew < pData->nNodesExt );
+ }
+ else if ( pData->fOnlyD )
+ {
+ pData->nNodesNew = 0;
+ do
+ {
+ Weight2 = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble );
+ if ( pData->fVerbose )
+ printf( "Best double = %3d.\n", Weight2 );
+ if ( Weight2 > 0 || Weight2 == 0 && pData->fUse0 )
+ Fxu_UpdateDouble( p );
+ else
+ break;
+ }
+ while ( ++pData->nNodesNew < pData->nNodesExt );
+ }
+ else if ( !pData->fUseCompl )
+ {
+ pData->nNodesNew = 0;
+ do
+ {
+ Weight1 = Fxu_HeapSingleReadMaxWeight( p->pHeapSingle );
+ Weight2 = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble );
+
+ if ( pData->fVerbose )
+ printf( "Best double = %3d. Best single = %3d.\n", Weight2, Weight1 );
+//Fxu_Select( p, &pSingle, &pDouble );
+
+ if ( Weight1 >= Weight2 )
+ {
+ if ( Weight1 > 0 || Weight1 == 0 && pData->fUse0 )
+ Fxu_UpdateSingle( p );
+ else
+ break;
+ }
+ else
+ {
+ if ( Weight2 > 0 || Weight2 == 0 && pData->fUse0 )
+ Fxu_UpdateDouble( p );
+ else
+ break;
+ }
+ }
+ while ( ++pData->nNodesNew < pData->nNodesExt );
+ }
+ else
+ { // use the complement
+ pData->nNodesNew = 0;
+ do
+ {
+ Weight1 = Fxu_HeapSingleReadMaxWeight( p->pHeapSingle );
+ Weight2 = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble );
+
+ // select the best single and double
+ Weight3 = Fxu_Select( p, &pSingle, &pDouble );
+ if ( pData->fVerbose )
+ printf( "Best double = %3d. Best single = %3d. Best complement = %3d.\n",
+ Weight2, Weight1, Weight3 );
+
+ if ( Weight3 > 0 || Weight3 == 0 && pData->fUse0 )
+ Fxu_Update( p, pSingle, pDouble );
+ else
+ break;
+ }
+ while ( ++pData->nNodesNew < pData->nNodesExt );
+ }
+
+ if ( pData->fVerbose )
+ printf( "Total single = %3d. Total double = %3d. Total compl = %3d.\n", p->nDivs1, p->nDivs2, p->nDivs3 );
+
+ // create the new covers
+ if ( pData->nNodesNew )
+ Fxu_CreateCovers( p, pData );
+ Fxu_MatrixDelete( p );
+// printf( "Memory usage after delocation: Total = %d. Peak = %d.\n", s_MemoryTotal, s_MemoryPeak );
+ if ( pData->nNodesNew == pData->nNodesExt )
+ printf( "Warning: The limit on the number of extracted divisors has been reached.\n" );
+ return pData->nNodesNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Unmarks the cubes in the ring.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_MatrixRingCubesUnmark( Fxu_Matrix * p )
+{
+ Fxu_Cube * pCube, * pCube2;
+ // unmark the cubes
+ Fxu_MatrixForEachCubeInRingSafe( p, pCube, pCube2 )
+ pCube->pOrder = NULL;
+ Fxu_MatrixRingCubesReset( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Unmarks the vars in the ring.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_MatrixRingVarsUnmark( Fxu_Matrix * p )
+{
+ Fxu_Var * pVar, * pVar2;
+ // unmark the vars
+ Fxu_MatrixForEachVarInRingSafe( p, pVar, pVar2 )
+ pVar->pOrder = NULL;
+ Fxu_MatrixRingVarsReset( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Fxu_MemFetch( Fxu_Matrix * p, int nBytes )
+{
+ s_MemoryTotal += nBytes;
+ if ( s_MemoryPeak < s_MemoryTotal )
+ s_MemoryPeak = s_MemoryTotal;
+// return malloc( nBytes );
+ return Extra_MmFixedEntryFetch( p->pMemMan );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_MemRecycle( Fxu_Matrix * p, char * pItem, int nBytes )
+{
+ s_MemoryTotal -= nBytes;
+// free( pItem );
+ Extra_MmFixedEntryRecycle( p->pMemMan, pItem );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/opt/fxu/fxu.h b/src/opt/fxu/fxu.h
new file mode 100644
index 00000000..5bc1e75f
--- /dev/null
+++ b/src/opt/fxu/fxu.h
@@ -0,0 +1,108 @@
+/**CFile****************************************************************
+
+ FileName [fxu.h]
+
+ PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
+
+ Synopsis [External declarations of fast extract for unate covers.]
+
+ Author [MVSIS Group]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - February 1, 2003.]
+
+ Revision [$Id: fxu.h,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __FXU_H__
+#define __FXU_H__
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include "vec.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#ifndef bool
+#define bool int
+#endif
+
+typedef struct FxuDataStruct Fxu_Data_t;
+
+// structure for the FX input/output data
+struct FxuDataStruct
+{
+ // user specified parameters
+ bool fOnlyS; // set to 1 to have only single-cube divs
+ bool fOnlyD; // set to 1 to have only double-cube divs
+ bool fUse0; // set to 1 to have 0-weight also extracted
+ bool fUseCompl; // set to 1 to have complement taken into account
+ bool fVerbose; // set to 1 to have verbose output
+ int nPairsMax; // the maximum number of cube pairs to consider
+/*
+ // parameters of the network
+ int fMvNetwork; // the network has some MV nodes
+ // the information about nodes
+ int nNodesCi; // the number of CI nodes of the network
+ int nNodesInt; // the number of internal nodes of the network
+ int nNodesOld; // the number of CI and int nodes
+ int nNodesNew; // the number of added nodes
+ int nNodesExt; // the max number of (binary) nodes to be added by FX
+ int nNodesAlloc; // the total number of all nodes
+ int * pNode2Value; // for each node, the number of its first value
+ // the information about values
+ int nValuesCi; // the total number of values of CI nodes
+ int nValuesInt; // the total number of values of int nodes
+ int nValuesOld; // the number of CI and int values
+ int nValuesNew; // the number of values added nodes
+ int nValuesExt; // the total number of values of the added nodes
+ int nValuesAlloc; // the total number of all values of all nodes
+ int * pValue2Node; // for each value, the number of its node
+ // the information about covers
+ Mvc_Cover_t ** ppCovers; // for each value, the corresponding cover
+ Mvc_Cover_t ** ppCoversNew; // for each value, the corresponding cover after FX
+ // the MVC manager
+ Mvc_Manager_t * pManMvc;
+*/
+ // statistics
+ int nNodesOld; // the old number of nodes
+ int nNodesExt; // the number of divisors to extract
+ int nNodesNew; // the number of divisors extracted
+
+ // the input information
+ Vec_Ptr_t * vSops; // the SOPs for each node in the network
+ Vec_Ptr_t * vFanins; // the fanins of each node in the network
+ // output information
+ Vec_Ptr_t * vSopsNew; // the SOPs for each node in the network after extraction
+ Vec_Ptr_t * vFaninsNew; // the fanins of each node in the network after extraction
+ // the SOP manager
+ Extra_MmFlex_t * pManSop;
+};
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*===== fxu.c ==========================================================*/
+extern int Fxu_FastExtract( Fxu_Data_t * pData );
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+#endif
+
diff --git a/src/opt/fxu/fxuCreate.c b/src/opt/fxu/fxuCreate.c
new file mode 100644
index 00000000..04b23fce
--- /dev/null
+++ b/src/opt/fxu/fxuCreate.c
@@ -0,0 +1,425 @@
+/**CFile****************************************************************
+
+ FileName [fxuCreate.c]
+
+ PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
+
+ Synopsis [Create matrix from covers and covers from matrix.]
+
+ Author [MVSIS Group]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - February 1, 2003.]
+
+ Revision [$Id: fxuCreate.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "fxuInt.h"
+#include "fxu.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+extern int Fxu_PreprocessCubePairs( Fxu_Matrix * p, Vec_Ptr_t * vCovers, int nPairsTotal, int nPairsMax );
+
+static void Fxu_CreateMatrixAddCube( Fxu_Matrix * p, Fxu_Cube * pCube, char * pSopCube, Vec_Fan_t * vFanins, int * pOrder );
+static int Fxu_CreateMatrixLitCompare( int * ptrX, int * ptrY );
+static void Fxu_CreateCoversNode( Fxu_Matrix * p, Fxu_Data_t * pData, int iNode, Fxu_Cube * pCubeFirst, Fxu_Cube * pCubeNext );
+static Fxu_Cube * Fxu_CreateCoversFirstCube( Fxu_Matrix * p, Fxu_Data_t * pData, int iNode );
+static Abc_Fan_t * s_pLits;
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Creates the sparse matrix from the array of Sop covers.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Fxu_Matrix * Fxu_CreateMatrix( Fxu_Data_t * pData )
+{
+ Fxu_Matrix * p;
+ Fxu_Var * pVar;
+ Fxu_Cube * pCubeFirst, * pCubeNew;
+ Fxu_Cube * pCube1, * pCube2;
+ char * pSopCover;
+ char * pSopCube;
+ int * pOrder, nBitsMax;
+ int i, v, c;
+ int nCubesTotal;
+ int nPairsTotal;
+ int nPairsStore;
+ int nCubes;
+ int iCube, iPair;
+ int nFanins;
+ Vec_Fan_t * vFanins;
+
+ // collect all sorts of statistics
+ nCubesTotal = 0;
+ nPairsTotal = 0;
+ nPairsStore = 0;
+ nBitsMax = -1;
+ for ( i = 0; i < pData->nNodesOld; i++ )
+ if ( pSopCover = pData->vSops->pArray[i] )
+ {
+ nCubes = Abc_SopGetCubeNum( pSopCover );
+ nFanins = Abc_SopGetVarNum( pSopCover );
+ assert( nFanins > 1 && nCubes > 0 );
+
+ nCubesTotal += nCubes;
+ nPairsTotal += nCubes * (nCubes - 1) / 2;
+ nPairsStore += nCubes * nCubes;
+ if ( nBitsMax < nFanins )
+ nBitsMax = nFanins;
+ }
+ if ( nBitsMax <= 0 )
+ {
+ printf( "The current network does not have SOPs to perform extraction.\n" );
+ return NULL;
+ }
+
+ if ( nPairsStore > 10000000 )
+ {
+ printf( "The problem is too large to be solved by \"fxu\" (%d cubes and %d cube pairs)\n", nCubesTotal, nPairsStore );
+ return NULL;
+ }
+
+ // start the matrix
+ p = Fxu_MatrixAllocate();
+ // create the column labels
+ p->ppVars = ALLOC( Fxu_Var *, 2 * (pData->nNodesOld + pData->nNodesExt) );
+ for ( i = 0; i < 2 * pData->nNodesOld; i++ )
+ p->ppVars[i] = Fxu_MatrixAddVar( p );
+
+ // allocate storage for all cube pairs at once
+ p->pppPairs = ALLOC( Fxu_Pair **, nCubesTotal + 100 );
+ p->ppPairs = ALLOC( Fxu_Pair *, nPairsStore + 100 );
+ memset( p->ppPairs, 0, sizeof(Fxu_Pair *) * nPairsStore );
+ iCube = 0;
+ iPair = 0;
+ for ( i = 0; i < pData->nNodesOld; i++ )
+ if ( pSopCover = pData->vSops->pArray[i] )
+ {
+ // get the number of cubes
+ nCubes = Abc_SopGetCubeNum( pSopCover );
+ // get the new var in the matrix
+ pVar = p->ppVars[2*i+1];
+ // assign the pair storage
+ pVar->nCubes = nCubes;
+ if ( nCubes > 0 )
+ {
+ pVar->ppPairs = p->pppPairs + iCube;
+ pVar->ppPairs[0] = p->ppPairs + iPair;
+ for ( v = 1; v < nCubes; v++ )
+ pVar->ppPairs[v] = pVar->ppPairs[v-1] + nCubes;
+ }
+ // update
+ iCube += nCubes;
+ iPair += nCubes * nCubes;
+ }
+ assert( iCube == nCubesTotal );
+ assert( iPair == nPairsStore );
+
+
+ // allocate room for the reordered literals
+ pOrder = ALLOC( int, nBitsMax );
+ // create the rows
+ for ( i = 0; i < pData->nNodesOld; i++ )
+ if ( pSopCover = pData->vSops->pArray[i] )
+ {
+ // get the new var in the matrix
+ pVar = p->ppVars[2*i+1];
+ // here we sort the literals of the cover
+ // in the increasing order of the numbers of the corresponding nodes
+ // because literals should be added to the matrix in this order
+ vFanins = pData->vFanins->pArray[i];
+ s_pLits = vFanins->pArray;
+ // start the variable order
+ nFanins = Abc_SopGetVarNum( pSopCover );
+ for ( v = 0; v < nFanins; v++ )
+ pOrder[v] = v;
+ // reorder the fanins
+ qsort( (void *)pOrder, nFanins, sizeof(int),(int (*)(const void *, const void *))Fxu_CreateMatrixLitCompare);
+ assert( s_pLits[ pOrder[0] ].iFan < s_pLits[ pOrder[nFanins-1] ].iFan );
+ // create the corresponding cubes in the matrix
+ pCubeFirst = NULL;
+ c = 0;
+ Abc_SopForEachCube( pSopCover, nFanins, pSopCube )
+ {
+ // create the cube
+ pCubeNew = Fxu_MatrixAddCube( p, pVar, c );
+ Fxu_CreateMatrixAddCube( p, pCubeNew, pSopCube, vFanins, pOrder );
+ if ( pCubeFirst == NULL )
+ pCubeFirst = pCubeNew;
+ pCubeNew->pFirst = pCubeFirst;
+ c++;
+ }
+ // set the first cube of this var
+ pVar->pFirst = pCubeFirst;
+ // create the divisors without preprocessing
+ if ( nPairsTotal <= pData->nPairsMax )
+ {
+ for ( pCube1 = pCubeFirst; pCube1; pCube1 = pCube1->pNext )
+ for ( pCube2 = pCube1? pCube1->pNext: NULL; pCube2; pCube2 = pCube2->pNext )
+ Fxu_MatrixAddDivisor( p, pCube1, pCube2 );
+ }
+ }
+ FREE( pOrder );
+
+ // consider the case when cube pairs should be preprocessed
+ // before adding them to the set of divisors
+ if ( nPairsTotal > pData->nPairsMax )
+ Fxu_PreprocessCubePairs( p, pData->vSops, nPairsTotal, pData->nPairsMax );
+
+ // add the var pairs to the heap
+ Fxu_MatrixComputeSingles( p );
+
+ // allocate temporary storage for pairs
+ if ( pData->nPairsMax < 1000 )
+ pData->nPairsMax = 1000;
+ p->pPairsTemp = ALLOC( Fxu_Pair *, pData->nPairsMax * 10 + 100 );
+ if ( pData->fVerbose )
+ {
+ double Density;
+ Density = ((double)p->nEntries) / p->lVars.nItems / p->lCubes.nItems;
+ fprintf( stdout, "Matrix: [vars x cubes] = [%d x %d] ",
+ p->lVars.nItems, p->lCubes.nItems );
+ fprintf( stdout, "Lits = %d Density = %.5f%%\n",
+ p->nEntries, Density );
+ fprintf( stdout, "1-cube divisors = %6d. ", p->lSingles.nItems );
+ fprintf( stdout, "2-cube divisors = %6d. ", p->nDivsTotal );
+ fprintf( stdout, "Cube pairs = %6d.", nPairsTotal );
+ fprintf( stdout, "\n" );
+ }
+// Fxu_MatrixPrint( stdout, p );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds one cube with literals to the matrix.]
+
+ Description [Create the cube and literals in the matrix corresponding
+ to the given cube in the SOP cover. Co-singleton transform is performed here.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_CreateMatrixAddCube( Fxu_Matrix * p, Fxu_Cube * pCube, char * pSopCube, Vec_Fan_t * vFanins, int * pOrder )
+{
+ Fxu_Var * pVar;
+ int Value, i;
+ // add literals to the matrix
+ Abc_CubeForEachVar( pSopCube, Value, i )
+ {
+ Value = pSopCube[pOrder[i]];
+ if ( Value == '0' )
+ {
+ pVar = p->ppVars[ 2 * vFanins->pArray[pOrder[i]].iFan + 1 ]; // CST
+ Fxu_MatrixAddLiteral( p, pCube, pVar );
+ }
+ else if ( Value == '1' )
+ {
+ pVar = p->ppVars[ 2 * vFanins->pArray[pOrder[i]].iFan ]; // CST
+ Fxu_MatrixAddLiteral( p, pCube, pVar );
+ }
+ }
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Creates the new array of Sop covers from the sparse matrix.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_CreateCovers( Fxu_Matrix * p, Fxu_Data_t * pData )
+{
+ Fxu_Cube * pCube, * pCubeFirst, * pCubeNext;
+ int iNode, n;
+ char * pSopCover;
+
+ // get the first cube of the first internal node
+ pCubeFirst = Fxu_CreateCoversFirstCube( p, pData, 0 );
+
+ // go through the internal nodes
+ for ( n = 0; n < pData->nNodesOld; n++ )
+ if ( pSopCover = pData->vSops->pArray[n] )
+ {
+ // get the number of this node
+ iNode = n;
+ // get the next first cube
+ pCubeNext = Fxu_CreateCoversFirstCube( p, pData, iNode + 1 );
+ // check if there any new variables in these cubes
+ for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext )
+ if ( pCube->lLits.pTail && pCube->lLits.pTail->iVar >= 2 * pData->nNodesOld )
+ break;
+ if ( pCube != pCubeNext )
+ Fxu_CreateCoversNode( p, pData, iNode, pCubeFirst, pCubeNext );
+ // update the first cube
+ pCubeFirst = pCubeNext;
+ }
+
+ // add the covers for the extracted nodes
+ for ( n = 0; n < pData->nNodesNew; n++ )
+ {
+ // get the number of this node
+ iNode = pData->nNodesOld + n;
+ // get the next first cube
+ pCubeNext = Fxu_CreateCoversFirstCube( p, pData, iNode + 1 );
+ // the node should be added
+ Fxu_CreateCoversNode( p, pData, iNode, pCubeFirst, pCubeNext );
+ // update the first cube
+ pCubeFirst = pCubeNext;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Create Sop covers for one node that has changed.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_CreateCoversNode( Fxu_Matrix * p, Fxu_Data_t * pData, int iNode, Fxu_Cube * pCubeFirst, Fxu_Cube * pCubeNext )
+{
+ Vec_Int_t * vInputsNew;
+ char * pSopCover;
+ char * pSopCube;
+ Fxu_Var * pVar;
+ Fxu_Cube * pCube;
+ Fxu_Lit * pLit;
+ int iNum, nCubes, v;
+ int fEmptyCube;
+
+ // collect positive polarity variable in the cubes between pCubeFirst and pCubeNext
+ Fxu_MatrixRingVarsStart( p );
+ for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext )
+ for ( pLit = pCube->lLits.pHead; pLit; pLit = pLit->pHNext )
+ {
+ pVar = p->ppVars[ 2 * (pLit->pVar->iVar/2) + 1 ];
+ if ( pVar->pOrder == NULL )
+ Fxu_MatrixRingVarsAdd( p, pVar );
+ }
+ Fxu_MatrixRingVarsStop( p );
+
+ // collect the variable numbers
+ vInputsNew = Vec_IntAlloc( 4 );
+ Fxu_MatrixForEachVarInRing( p, pVar )
+ Vec_IntPush( vInputsNew, pVar->iVar / 2 );
+ Fxu_MatrixRingVarsUnmark( p );
+
+ // sort the vars by their number
+ Vec_IntSort( vInputsNew, 0 );
+
+ // mark the vars with their numbers in the sorted array
+ for ( v = 0; v < vInputsNew->nSize; v++ )
+ {
+ p->ppVars[ 2 * vInputsNew->pArray[v] + 0 ]->lLits.nItems = v; // hack - reuse lLits.nItems
+ p->ppVars[ 2 * vInputsNew->pArray[v] + 1 ]->lLits.nItems = v; // hack - reuse lLits.nItems
+ }
+
+ // count the number of cubes
+ nCubes = 0;
+ for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext )
+ if ( pCube->lLits.nItems )
+ nCubes++;
+
+ // allocate room for the new cover
+ pSopCover = Abc_SopStart( pData->pManSop, nCubes, vInputsNew->nSize );
+ // set the correct polarity of the cover
+ if ( iNode < pData->nNodesOld && Abc_SopGetPhase( pData->vSops->pArray[iNode] ) == 0 )
+ Abc_SopComplement( pSopCover );
+
+ // add the cubes
+ nCubes = 0;
+ for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext )
+ {
+ if ( pCube->lLits.nItems == 0 )
+ continue;
+ // get hold of the SOP cube
+ pSopCube = pSopCover + nCubes * (vInputsNew->nSize + 3);
+ // insert literals
+ fEmptyCube = 1;
+ for ( pLit = pCube->lLits.pHead; pLit; pLit = pLit->pHNext )
+ {
+ iNum = pLit->pVar->lLits.nItems; // hack - reuse lLits.nItems
+ assert( iNum < vInputsNew->nSize );
+ if ( pLit->pVar->iVar / 2 < pData->nNodesOld )
+ pSopCube[iNum] = (pLit->pVar->iVar & 1)? '0' : '1'; // reverse CST
+ else
+ pSopCube[iNum] = (pLit->pVar->iVar & 1)? '1' : '0'; // no CST
+ fEmptyCube = 0;
+ }
+ assert( !fEmptyCube );
+ // count the cube
+ nCubes++;
+ }
+ assert( nCubes == Abc_SopGetCubeNum(pSopCover) );
+
+ pData->vSopsNew->pArray[iNode] = pSopCover;
+ pData->vFaninsNew->pArray[iNode] = vInputsNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Adds the var to storage.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Fxu_Cube * Fxu_CreateCoversFirstCube( Fxu_Matrix * p, Fxu_Data_t * pData, int iVar )
+{
+ int v;
+ for ( v = iVar; v < pData->nNodesOld + pData->nNodesNew; v++ )
+ if ( p->ppVars[ 2*v + 1 ]->pFirst )
+ return p->ppVars[ 2*v + 1 ]->pFirst;
+ return NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compares the vars by their number.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Fxu_CreateMatrixLitCompare( int * ptrX, int * ptrY )
+{
+ return s_pLits[*ptrX].iFan - s_pLits[*ptrY].iFan;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
diff --git a/src/opt/fxu/fxuHeapD.c b/src/opt/fxu/fxuHeapD.c
new file mode 100644
index 00000000..7c123249
--- /dev/null
+++ b/src/opt/fxu/fxuHeapD.c
@@ -0,0 +1,445 @@
+/**CFile****************************************************************
+
+ FileName [fxuHeapD.c]
+
+ PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
+
+ Synopsis [The priority queue for double cube divisors.]
+
+ Author [MVSIS Group]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - February 1, 2003.]
+
+ Revision [$Id: fxuHeapD.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "fxuInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define FXU_HEAP_DOUBLE_WEIGHT(pDiv) ((pDiv)->Weight)
+#define FXU_HEAP_DOUBLE_CURRENT(p, pDiv) ((p)->pTree[(pDiv)->HNum])
+#define FXU_HEAP_DOUBLE_PARENT_EXISTS(p, pDiv) ((pDiv)->HNum > 1)
+#define FXU_HEAP_DOUBLE_CHILD1_EXISTS(p, pDiv) (((pDiv)->HNum << 1) <= p->nItems)
+#define FXU_HEAP_DOUBLE_CHILD2_EXISTS(p, pDiv) ((((pDiv)->HNum << 1)+1) <= p->nItems)
+#define FXU_HEAP_DOUBLE_PARENT(p, pDiv) ((p)->pTree[(pDiv)->HNum >> 1])
+#define FXU_HEAP_DOUBLE_CHILD1(p, pDiv) ((p)->pTree[(pDiv)->HNum << 1])
+#define FXU_HEAP_DOUBLE_CHILD2(p, pDiv) ((p)->pTree[((pDiv)->HNum << 1)+1])
+#define FXU_HEAP_DOUBLE_ASSERT(p, pDiv) assert( (pDiv)->HNum >= 1 && (pDiv)->HNum <= p->nItemsAlloc )
+
+static void Fxu_HeapDoubleResize( Fxu_HeapDouble * p );
+static void Fxu_HeapDoubleSwap( Fxu_Double ** pDiv1, Fxu_Double ** pDiv2 );
+static void Fxu_HeapDoubleMoveUp( Fxu_HeapDouble * p, Fxu_Double * pDiv );
+static void Fxu_HeapDoubleMoveDn( Fxu_HeapDouble * p, Fxu_Double * pDiv );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Fxu_HeapDouble * Fxu_HeapDoubleStart()
+{
+ Fxu_HeapDouble * p;
+ p = ALLOC( Fxu_HeapDouble, 1 );
+ memset( p, 0, sizeof(Fxu_HeapDouble) );
+ p->nItems = 0;
+ p->nItemsAlloc = 10000;
+ p->pTree = ALLOC( Fxu_Double *, p->nItemsAlloc + 1 );
+ p->pTree[0] = NULL;
+ return p;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_HeapDoubleResize( Fxu_HeapDouble * p )
+{
+ p->nItemsAlloc *= 2;
+ p->pTree = REALLOC( Fxu_Double *, p->pTree, p->nItemsAlloc + 1 );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_HeapDoubleStop( Fxu_HeapDouble * p )
+{
+ free( p->pTree );
+ free( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_HeapDoublePrint( FILE * pFile, Fxu_HeapDouble * p )
+{
+ Fxu_Double * pDiv;
+ int Counter = 1;
+ int Degree = 1;
+
+ Fxu_HeapDoubleCheck( p );
+ fprintf( pFile, "The contents of the heap:\n" );
+ fprintf( pFile, "Level %d: ", Degree );
+ Fxu_HeapDoubleForEachItem( p, pDiv )
+ {
+ assert( Counter == p->pTree[Counter]->HNum );
+ fprintf( pFile, "%2d=%3d ", Counter, FXU_HEAP_DOUBLE_WEIGHT(p->pTree[Counter]) );
+ if ( ++Counter == (1 << Degree) )
+ {
+ fprintf( pFile, "\n" );
+ Degree++;
+ fprintf( pFile, "Level %d: ", Degree );
+ }
+ }
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "End of the heap printout.\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_HeapDoubleCheck( Fxu_HeapDouble * p )
+{
+ Fxu_Double * pDiv;
+ Fxu_HeapDoubleForEachItem( p, pDiv )
+ {
+ assert( pDiv->HNum == p->i );
+ Fxu_HeapDoubleCheckOne( p, pDiv );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_HeapDoubleCheckOne( Fxu_HeapDouble * p, Fxu_Double * pDiv )
+{
+ int Weight1, Weight2;
+ if ( FXU_HEAP_DOUBLE_CHILD1_EXISTS(p,pDiv) )
+ {
+ Weight1 = FXU_HEAP_DOUBLE_WEIGHT(pDiv);
+ Weight2 = FXU_HEAP_DOUBLE_WEIGHT( FXU_HEAP_DOUBLE_CHILD1(p,pDiv) );
+ assert( Weight1 >= Weight2 );
+ }
+ if ( FXU_HEAP_DOUBLE_CHILD2_EXISTS(p,pDiv) )
+ {
+ Weight1 = FXU_HEAP_DOUBLE_WEIGHT(pDiv);
+ Weight2 = FXU_HEAP_DOUBLE_WEIGHT( FXU_HEAP_DOUBLE_CHILD2(p,pDiv) );
+ assert( Weight1 >= Weight2 );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_HeapDoubleInsert( Fxu_HeapDouble * p, Fxu_Double * pDiv )
+{
+ if ( p->nItems == p->nItemsAlloc )
+ Fxu_HeapDoubleResize( p );
+ // put the last entry to the last place and move up
+ p->pTree[++p->nItems] = pDiv;
+ pDiv->HNum = p->nItems;
+ // move the last entry up if necessary
+ Fxu_HeapDoubleMoveUp( p, pDiv );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_HeapDoubleUpdate( Fxu_HeapDouble * p, Fxu_Double * pDiv )
+{
+//printf( "Updating divisor %d.\n", pDiv->Num );
+
+ FXU_HEAP_DOUBLE_ASSERT(p,pDiv);
+ if ( FXU_HEAP_DOUBLE_PARENT_EXISTS(p,pDiv) &&
+ FXU_HEAP_DOUBLE_WEIGHT(pDiv) > FXU_HEAP_DOUBLE_WEIGHT( FXU_HEAP_DOUBLE_PARENT(p,pDiv) ) )
+ Fxu_HeapDoubleMoveUp( p, pDiv );
+ else if ( FXU_HEAP_DOUBLE_CHILD1_EXISTS(p,pDiv) &&
+ FXU_HEAP_DOUBLE_WEIGHT(pDiv) < FXU_HEAP_DOUBLE_WEIGHT( FXU_HEAP_DOUBLE_CHILD1(p,pDiv) ) )
+ Fxu_HeapDoubleMoveDn( p, pDiv );
+ else if ( FXU_HEAP_DOUBLE_CHILD2_EXISTS(p,pDiv) &&
+ FXU_HEAP_DOUBLE_WEIGHT(pDiv) < FXU_HEAP_DOUBLE_WEIGHT( FXU_HEAP_DOUBLE_CHILD2(p,pDiv) ) )
+ Fxu_HeapDoubleMoveDn( p, pDiv );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_HeapDoubleDelete( Fxu_HeapDouble * p, Fxu_Double * pDiv )
+{
+ FXU_HEAP_DOUBLE_ASSERT(p,pDiv);
+ // put the last entry to the deleted place
+ // decrement the number of entries
+ p->pTree[pDiv->HNum] = p->pTree[p->nItems--];
+ p->pTree[pDiv->HNum]->HNum = pDiv->HNum;
+ // move the top entry down if necessary
+ Fxu_HeapDoubleUpdate( p, p->pTree[pDiv->HNum] );
+ pDiv->HNum = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Fxu_Double * Fxu_HeapDoubleReadMax( Fxu_HeapDouble * p )
+{
+ if ( p->nItems == 0 )
+ return NULL;
+ return p->pTree[1];
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Fxu_Double * Fxu_HeapDoubleGetMax( Fxu_HeapDouble * p )
+{
+ Fxu_Double * pDiv;
+ if ( p->nItems == 0 )
+ return NULL;
+ // prepare the return value
+ pDiv = p->pTree[1];
+ pDiv->HNum = 0;
+ // put the last entry on top
+ // decrement the number of entries
+ p->pTree[1] = p->pTree[p->nItems--];
+ p->pTree[1]->HNum = 1;
+ // move the top entry down if necessary
+ Fxu_HeapDoubleMoveDn( p, p->pTree[1] );
+ return pDiv;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Fxu_HeapDoubleReadMaxWeight( Fxu_HeapDouble * p )
+{
+ if ( p->nItems == 0 )
+ return -1;
+ else
+ return FXU_HEAP_DOUBLE_WEIGHT(p->pTree[1]);
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_HeapDoubleSwap( Fxu_Double ** pDiv1, Fxu_Double ** pDiv2 )
+{
+ Fxu_Double * pDiv;
+ int Temp;
+ pDiv = *pDiv1;
+ *pDiv1 = *pDiv2;
+ *pDiv2 = pDiv;
+ Temp = (*pDiv1)->HNum;
+ (*pDiv1)->HNum = (*pDiv2)->HNum;
+ (*pDiv2)->HNum = Temp;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_HeapDoubleMoveUp( Fxu_HeapDouble * p, Fxu_Double * pDiv )
+{
+ Fxu_Double ** ppDiv, ** ppPar;
+ ppDiv = &FXU_HEAP_DOUBLE_CURRENT(p, pDiv);
+ while ( FXU_HEAP_DOUBLE_PARENT_EXISTS(p,*ppDiv) )
+ {
+ ppPar = &FXU_HEAP_DOUBLE_PARENT(p,*ppDiv);
+ if ( FXU_HEAP_DOUBLE_WEIGHT(*ppDiv) > FXU_HEAP_DOUBLE_WEIGHT(*ppPar) )
+ {
+ Fxu_HeapDoubleSwap( ppDiv, ppPar );
+ ppDiv = ppPar;
+ }
+ else
+ break;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_HeapDoubleMoveDn( Fxu_HeapDouble * p, Fxu_Double * pDiv )
+{
+ Fxu_Double ** ppChild1, ** ppChild2, ** ppDiv;
+ ppDiv = &FXU_HEAP_DOUBLE_CURRENT(p, pDiv);
+ while ( FXU_HEAP_DOUBLE_CHILD1_EXISTS(p,*ppDiv) )
+ { // if Child1 does not exist, Child2 also does not exists
+
+ // get the children
+ ppChild1 = &FXU_HEAP_DOUBLE_CHILD1(p,*ppDiv);
+ if ( FXU_HEAP_DOUBLE_CHILD2_EXISTS(p,*ppDiv) )
+ {
+ ppChild2 = &FXU_HEAP_DOUBLE_CHILD2(p,*ppDiv);
+
+ // consider two cases
+ if ( FXU_HEAP_DOUBLE_WEIGHT(*ppDiv) >= FXU_HEAP_DOUBLE_WEIGHT(*ppChild1) &&
+ FXU_HEAP_DOUBLE_WEIGHT(*ppDiv) >= FXU_HEAP_DOUBLE_WEIGHT(*ppChild2) )
+ { // Div is larger than both, skip
+ break;
+ }
+ else
+ { // Div is smaller than one of them, then swap it with larger
+ if ( FXU_HEAP_DOUBLE_WEIGHT(*ppChild1) >= FXU_HEAP_DOUBLE_WEIGHT(*ppChild2) )
+ {
+ Fxu_HeapDoubleSwap( ppDiv, ppChild1 );
+ // update the pointer
+ ppDiv = ppChild1;
+ }
+ else
+ {
+ Fxu_HeapDoubleSwap( ppDiv, ppChild2 );
+ // update the pointer
+ ppDiv = ppChild2;
+ }
+ }
+ }
+ else // Child2 does not exist
+ {
+ // consider two cases
+ if ( FXU_HEAP_DOUBLE_WEIGHT(*ppDiv) >= FXU_HEAP_DOUBLE_WEIGHT(*ppChild1) )
+ { // Div is larger than Child1, skip
+ break;
+ }
+ else
+ { // Div is smaller than Child1, then swap them
+ Fxu_HeapDoubleSwap( ppDiv, ppChild1 );
+ // update the pointer
+ ppDiv = ppChild1;
+ }
+ }
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/opt/fxu/fxuHeapS.c b/src/opt/fxu/fxuHeapS.c
new file mode 100644
index 00000000..dbd66055
--- /dev/null
+++ b/src/opt/fxu/fxuHeapS.c
@@ -0,0 +1,444 @@
+/**CFile****************************************************************
+
+ FileName [fxuHeapS.c]
+
+ PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
+
+ Synopsis [The priority queue for variables.]
+
+ Author [MVSIS Group]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - February 1, 2003.]
+
+ Revision [$Id: fxuHeapS.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "fxuInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define FXU_HEAP_SINGLE_WEIGHT(pSingle) ((pSingle)->Weight)
+#define FXU_HEAP_SINGLE_CURRENT(p, pSingle) ((p)->pTree[(pSingle)->HNum])
+#define FXU_HEAP_SINGLE_PARENT_EXISTS(p, pSingle) ((pSingle)->HNum > 1)
+#define FXU_HEAP_SINGLE_CHILD1_EXISTS(p, pSingle) (((pSingle)->HNum << 1) <= p->nItems)
+#define FXU_HEAP_SINGLE_CHILD2_EXISTS(p, pSingle) ((((pSingle)->HNum << 1)+1) <= p->nItems)
+#define FXU_HEAP_SINGLE_PARENT(p, pSingle) ((p)->pTree[(pSingle)->HNum >> 1])
+#define FXU_HEAP_SINGLE_CHILD1(p, pSingle) ((p)->pTree[(pSingle)->HNum << 1])
+#define FXU_HEAP_SINGLE_CHILD2(p, pSingle) ((p)->pTree[((pSingle)->HNum << 1)+1])
+#define FXU_HEAP_SINGLE_ASSERT(p, pSingle) assert( (pSingle)->HNum >= 1 && (pSingle)->HNum <= p->nItemsAlloc )
+
+static void Fxu_HeapSingleResize( Fxu_HeapSingle * p );
+static void Fxu_HeapSingleSwap( Fxu_Single ** pSingle1, Fxu_Single ** pSingle2 );
+static void Fxu_HeapSingleMoveUp( Fxu_HeapSingle * p, Fxu_Single * pSingle );
+static void Fxu_HeapSingleMoveDn( Fxu_HeapSingle * p, Fxu_Single * pSingle );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Fxu_HeapSingle * Fxu_HeapSingleStart()
+{
+ Fxu_HeapSingle * p;
+ p = ALLOC( Fxu_HeapSingle, 1 );
+ memset( p, 0, sizeof(Fxu_HeapSingle) );
+ p->nItems = 0;
+ p->nItemsAlloc = 2000;
+ p->pTree = ALLOC( Fxu_Single *, p->nItemsAlloc + 10 );
+ p->pTree[0] = NULL;
+ return p;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_HeapSingleResize( Fxu_HeapSingle * p )
+{
+ p->nItemsAlloc *= 2;
+ p->pTree = REALLOC( Fxu_Single *, p->pTree, p->nItemsAlloc + 10 );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_HeapSingleStop( Fxu_HeapSingle * p )
+{
+ int i;
+ i = 0;
+ free( p->pTree );
+ i = 1;
+ free( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_HeapSinglePrint( FILE * pFile, Fxu_HeapSingle * p )
+{
+ Fxu_Single * pSingle;
+ int Counter = 1;
+ int Degree = 1;
+
+ Fxu_HeapSingleCheck( p );
+ fprintf( pFile, "The contents of the heap:\n" );
+ fprintf( pFile, "Level %d: ", Degree );
+ Fxu_HeapSingleForEachItem( p, pSingle )
+ {
+ assert( Counter == p->pTree[Counter]->HNum );
+ fprintf( pFile, "%2d=%3d ", Counter, FXU_HEAP_SINGLE_WEIGHT(p->pTree[Counter]) );
+ if ( ++Counter == (1 << Degree) )
+ {
+ fprintf( pFile, "\n" );
+ Degree++;
+ fprintf( pFile, "Level %d: ", Degree );
+ }
+ }
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "End of the heap printout.\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_HeapSingleCheck( Fxu_HeapSingle * p )
+{
+ Fxu_Single * pSingle;
+ Fxu_HeapSingleForEachItem( p, pSingle )
+ {
+ assert( pSingle->HNum == p->i );
+ Fxu_HeapSingleCheckOne( p, pSingle );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_HeapSingleCheckOne( Fxu_HeapSingle * p, Fxu_Single * pSingle )
+{
+ int Weight1, Weight2;
+ if ( FXU_HEAP_SINGLE_CHILD1_EXISTS(p,pSingle) )
+ {
+ Weight1 = FXU_HEAP_SINGLE_WEIGHT(pSingle);
+ Weight2 = FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD1(p,pSingle) );
+ assert( Weight1 >= Weight2 );
+ }
+ if ( FXU_HEAP_SINGLE_CHILD2_EXISTS(p,pSingle) )
+ {
+ Weight1 = FXU_HEAP_SINGLE_WEIGHT(pSingle);
+ Weight2 = FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD2(p,pSingle) );
+ assert( Weight1 >= Weight2 );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_HeapSingleInsert( Fxu_HeapSingle * p, Fxu_Single * pSingle )
+{
+ if ( p->nItems == p->nItemsAlloc )
+ Fxu_HeapSingleResize( p );
+ // put the last entry to the last place and move up
+ p->pTree[++p->nItems] = pSingle;
+ pSingle->HNum = p->nItems;
+ // move the last entry up if necessary
+ Fxu_HeapSingleMoveUp( p, pSingle );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_HeapSingleUpdate( Fxu_HeapSingle * p, Fxu_Single * pSingle )
+{
+ FXU_HEAP_SINGLE_ASSERT(p,pSingle);
+ if ( FXU_HEAP_SINGLE_PARENT_EXISTS(p,pSingle) &&
+ FXU_HEAP_SINGLE_WEIGHT(pSingle) > FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_PARENT(p,pSingle) ) )
+ Fxu_HeapSingleMoveUp( p, pSingle );
+ else if ( FXU_HEAP_SINGLE_CHILD1_EXISTS(p,pSingle) &&
+ FXU_HEAP_SINGLE_WEIGHT(pSingle) < FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD1(p,pSingle) ) )
+ Fxu_HeapSingleMoveDn( p, pSingle );
+ else if ( FXU_HEAP_SINGLE_CHILD2_EXISTS(p,pSingle) &&
+ FXU_HEAP_SINGLE_WEIGHT(pSingle) < FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD2(p,pSingle) ) )
+ Fxu_HeapSingleMoveDn( p, pSingle );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_HeapSingleDelete( Fxu_HeapSingle * p, Fxu_Single * pSingle )
+{
+ int Place = pSingle->HNum;
+ FXU_HEAP_SINGLE_ASSERT(p,pSingle);
+ // put the last entry to the deleted place
+ // decrement the number of entries
+ p->pTree[Place] = p->pTree[p->nItems--];
+ p->pTree[Place]->HNum = Place;
+ // move the top entry down if necessary
+ Fxu_HeapSingleUpdate( p, p->pTree[Place] );
+ pSingle->HNum = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Fxu_Single * Fxu_HeapSingleReadMax( Fxu_HeapSingle * p )
+{
+ if ( p->nItems == 0 )
+ return NULL;
+ return p->pTree[1];
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Fxu_Single * Fxu_HeapSingleGetMax( Fxu_HeapSingle * p )
+{
+ Fxu_Single * pSingle;
+ if ( p->nItems == 0 )
+ return NULL;
+ // prepare the return value
+ pSingle = p->pTree[1];
+ pSingle->HNum = 0;
+ // put the last entry on top
+ // decrement the number of entries
+ p->pTree[1] = p->pTree[p->nItems--];
+ p->pTree[1]->HNum = 1;
+ // move the top entry down if necessary
+ Fxu_HeapSingleMoveDn( p, p->pTree[1] );
+ return pSingle;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Fxu_HeapSingleReadMaxWeight( Fxu_HeapSingle * p )
+{
+ if ( p->nItems == 0 )
+ return -1;
+ return FXU_HEAP_SINGLE_WEIGHT(p->pTree[1]);
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_HeapSingleSwap( Fxu_Single ** pSingle1, Fxu_Single ** pSingle2 )
+{
+ Fxu_Single * pSingle;
+ int Temp;
+ pSingle = *pSingle1;
+ *pSingle1 = *pSingle2;
+ *pSingle2 = pSingle;
+ Temp = (*pSingle1)->HNum;
+ (*pSingle1)->HNum = (*pSingle2)->HNum;
+ (*pSingle2)->HNum = Temp;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_HeapSingleMoveUp( Fxu_HeapSingle * p, Fxu_Single * pSingle )
+{
+ Fxu_Single ** ppSingle, ** ppPar;
+ ppSingle = &FXU_HEAP_SINGLE_CURRENT(p, pSingle);
+ while ( FXU_HEAP_SINGLE_PARENT_EXISTS(p,*ppSingle) )
+ {
+ ppPar = &FXU_HEAP_SINGLE_PARENT(p,*ppSingle);
+ if ( FXU_HEAP_SINGLE_WEIGHT(*ppSingle) > FXU_HEAP_SINGLE_WEIGHT(*ppPar) )
+ {
+ Fxu_HeapSingleSwap( ppSingle, ppPar );
+ ppSingle = ppPar;
+ }
+ else
+ break;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_HeapSingleMoveDn( Fxu_HeapSingle * p, Fxu_Single * pSingle )
+{
+ Fxu_Single ** ppChild1, ** ppChild2, ** ppSingle;
+ ppSingle = &FXU_HEAP_SINGLE_CURRENT(p, pSingle);
+ while ( FXU_HEAP_SINGLE_CHILD1_EXISTS(p,*ppSingle) )
+ { // if Child1 does not exist, Child2 also does not exists
+
+ // get the children
+ ppChild1 = &FXU_HEAP_SINGLE_CHILD1(p,*ppSingle);
+ if ( FXU_HEAP_SINGLE_CHILD2_EXISTS(p,*ppSingle) )
+ {
+ ppChild2 = &FXU_HEAP_SINGLE_CHILD2(p,*ppSingle);
+
+ // consider two cases
+ if ( FXU_HEAP_SINGLE_WEIGHT(*ppSingle) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild1) &&
+ FXU_HEAP_SINGLE_WEIGHT(*ppSingle) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild2) )
+ { // Var is larger than both, skip
+ break;
+ }
+ else
+ { // Var is smaller than one of them, then swap it with larger
+ if ( FXU_HEAP_SINGLE_WEIGHT(*ppChild1) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild2) )
+ {
+ Fxu_HeapSingleSwap( ppSingle, ppChild1 );
+ // update the pointer
+ ppSingle = ppChild1;
+ }
+ else
+ {
+ Fxu_HeapSingleSwap( ppSingle, ppChild2 );
+ // update the pointer
+ ppSingle = ppChild2;
+ }
+ }
+ }
+ else // Child2 does not exist
+ {
+ // consider two cases
+ if ( FXU_HEAP_SINGLE_WEIGHT(*ppSingle) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild1) )
+ { // Var is larger than Child1, skip
+ break;
+ }
+ else
+ { // Var is smaller than Child1, then swap them
+ Fxu_HeapSingleSwap( ppSingle, ppChild1 );
+ // update the pointer
+ ppSingle = ppChild1;
+ }
+ }
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
diff --git a/src/opt/fxu/fxuInt.h b/src/opt/fxu/fxuInt.h
new file mode 100644
index 00000000..1f5a19b8
--- /dev/null
+++ b/src/opt/fxu/fxuInt.h
@@ -0,0 +1,541 @@
+/**CFile****************************************************************
+
+ FileName [fxuInt.h]
+
+ PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
+
+ Synopsis [Internal declarations of fast extract for unate covers.]
+
+ Author [MVSIS Group]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - February 1, 2003.]
+
+ Revision [$Id: fxuInt.h,v 1.3 2003/04/10 05:42:44 donald Exp $]
+
+***********************************************************************/
+
+#ifndef __FXU_INT_H__
+#define __FXU_INT_H__
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include "util.h"
+#include "extra.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+// uncomment this macro to switch to standard memory management
+//#define USE_SYSTEM_MEMORY_MANAGEMENT
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*
+ Here is an informal description of the FX data structure.
+ (1) The sparse matrix is filled with literals, associated with
+ cubes (row) and variables (columns). The matrix contains
+ all the cubes of all the nodes in the network.
+ (2) A cube is associated with
+ (a) its literals in the matrix,
+ (b) the output variable of the node, to which this cube belongs,
+ (3) A variable is associated with
+ (a) its literals in the matrix and
+ (b) the list of cube pairs in the cover, for which it is the output
+ (4) A cube pair is associated with two cubes and contains the counters
+ of literals in the base and in the cubes without the base
+ (5) A double-cube divisor is associated with list of all cube pairs
+ that produce it and its current weight (which is updated automatically
+ each time a new pair is added or an old pair is removed).
+ (6) A single-cube divisor is associated the pair of variables.
+*/
+
+// sparse matrix
+typedef struct FxuMatrix Fxu_Matrix; // the sparse matrix
+
+// sparse matrix contents: cubes (rows), vars (columns), literals (entries)
+typedef struct FxuCube Fxu_Cube; // one cube in the sparse matrix
+typedef struct FxuVar Fxu_Var; // one literal in the sparse matrix
+typedef struct FxuLit Fxu_Lit; // one entry in the sparse matrix
+
+// double cube divisors
+typedef struct FxuPair Fxu_Pair; // the pair of cubes
+typedef struct FxuDouble Fxu_Double; // the double-cube divisor
+typedef struct FxuSingle Fxu_Single; // the two-literal single-cube divisor
+
+// various lists
+typedef struct FxuListCube Fxu_ListCube; // the list of cubes
+typedef struct FxuListVar Fxu_ListVar; // the list of literals
+typedef struct FxuListLit Fxu_ListLit; // the list of entries
+typedef struct FxuListPair Fxu_ListPair; // the list of pairs
+typedef struct FxuListDouble Fxu_ListDouble; // the list of divisors
+typedef struct FxuListSingle Fxu_ListSingle; // the list of single-cube divisors
+
+// various heaps
+typedef struct FxuHeapDouble Fxu_HeapDouble; // the heap of divisors
+typedef struct FxuHeapSingle Fxu_HeapSingle; // the heap of variables
+
+
+// various lists
+
+// the list of cubes in the sparse matrix
+struct FxuListCube
+{
+ Fxu_Cube * pHead;
+ Fxu_Cube * pTail;
+ int nItems;
+};
+
+// the list of literals in the sparse matrix
+struct FxuListVar
+{
+ Fxu_Var * pHead;
+ Fxu_Var * pTail;
+ int nItems;
+};
+
+// the list of entries in the sparse matrix
+struct FxuListLit
+{
+ Fxu_Lit * pHead;
+ Fxu_Lit * pTail;
+ int nItems;
+};
+
+// the list of cube pair in the sparse matrix
+struct FxuListPair
+{
+ Fxu_Pair * pHead;
+ Fxu_Pair * pTail;
+ int nItems;
+};
+
+// the list of divisors in the sparse matrix
+struct FxuListDouble
+{
+ Fxu_Double * pHead;
+ Fxu_Double * pTail;
+ int nItems;
+};
+
+// the list of divisors in the sparse matrix
+struct FxuListSingle
+{
+ Fxu_Single * pHead;
+ Fxu_Single * pTail;
+ int nItems;
+};
+
+
+// various heaps
+
+// the heap of double cube divisors by weight
+struct FxuHeapDouble
+{
+ Fxu_Double ** pTree;
+ int nItems;
+ int nItemsAlloc;
+ int i;
+};
+
+// the heap of variable by their occurrence in the cubes
+struct FxuHeapSingle
+{
+ Fxu_Single ** pTree;
+ int nItems;
+ int nItemsAlloc;
+ int i;
+};
+
+
+
+// sparse matrix
+struct FxuMatrix // ~ 30 words
+{
+ // information about the network
+// int fMvNetwork; // set to 1 if the network has MV nodes
+// int * pValue2Node; // the mapping of values into nodes
+ // the cubes
+ Fxu_ListCube lCubes; // the double linked list of cubes
+ // the values (binary literals)
+ Fxu_ListVar lVars; // the double linked list of variables
+ Fxu_Var ** ppVars; // the array of variables
+ // the double cube divisors
+ Fxu_ListDouble * pTable; // the hash table of divisors
+ int nTableSize; // the hash table size
+ int nDivs; // the number of divisors in the table
+ int nDivsTotal; // the number of divisors in the table
+ Fxu_HeapDouble * pHeapDouble; // the heap of divisors by weight
+ // the single cube divisors
+ Fxu_ListSingle lSingles; // the linked list of single cube divisors
+ Fxu_HeapSingle * pHeapSingle; // the heap of variables by the number of literals in the matrix
+ // storage for cube pairs
+ Fxu_Pair *** pppPairs;
+ Fxu_Pair ** ppPairs;
+ // temporary storage for cubes
+ Fxu_Cube * pOrderCubes;
+ Fxu_Cube ** ppTailCubes;
+ // temporary storage for variables
+ Fxu_Var * pOrderVars;
+ Fxu_Var ** ppTailVars;
+ // temporary storage for pairs
+ Fxu_Pair ** pPairsTemp;
+ int nPairsTemp;
+// int nPairsMax;
+ // statistics
+ int nEntries; // the total number of entries in the sparse matrix
+ int nDivs1; // the single cube divisors taken
+ int nDivs2; // the double cube divisors taken
+ int nDivs3; // the double cube divisors with complement
+ // memory manager
+ Extra_MmFixed_t * pMemMan; // the memory manager for all small sized entries
+};
+
+// the cube in the sparse matrix
+struct FxuCube // 9 words
+{
+ int iCube; // the number of this cube in the cover
+ Fxu_Cube * pFirst; // the pointer to the first cube of this cover
+ Fxu_Var * pVar; // the variable representing the output of the cover
+ Fxu_ListLit lLits; // the row in the table
+ Fxu_Cube * pPrev; // the previous cube
+ Fxu_Cube * pNext; // the next cube
+ Fxu_Cube * pOrder; // the specialized linked list of cubes
+};
+
+// the variable in the sparse matrix
+struct FxuVar // 10 words
+{
+ int iVar; // the number of this variable
+ int nCubes; // the number of cubes assoc with this var
+ Fxu_Cube * pFirst; // the first cube assoc with this var
+ Fxu_Pair *** ppPairs; // the pairs of cubes assoc with this var
+ Fxu_ListLit lLits; // the column in the table
+ Fxu_Var * pPrev; // the previous variable
+ Fxu_Var * pNext; // the next variable
+ Fxu_Var * pOrder; // the specialized linked list of variables
+};
+
+// the literal entry in the sparse matrix
+struct FxuLit // 8 words
+{
+ int iVar; // the number of this variable
+ int iCube; // the number of this cube
+ Fxu_Cube * pCube; // the cube of this literal
+ Fxu_Var * pVar; // the variable of this literal
+ Fxu_Lit * pHPrev; // prev lit in the cube
+ Fxu_Lit * pHNext; // next lit in the cube
+ Fxu_Lit * pVPrev; // prev lit of the var
+ Fxu_Lit * pVNext; // next lit of the var
+};
+
+// the cube pair
+struct FxuPair // 10 words
+{
+ int nLits1; // the number of literals in the two cubes
+ int nLits2; // the number of literals in the two cubes
+ int nBase; // the number of literals in the base
+ Fxu_Double * pDiv; // the divisor of this pair
+ Fxu_Cube * pCube1; // the first cube of the pair
+ Fxu_Cube * pCube2; // the second cube of the pair
+ int iCube1; // the first cube of the pair
+ int iCube2; // the second cube of the pair
+ Fxu_Pair * pDPrev; // the previous pair in the divisor
+ Fxu_Pair * pDNext; // the next pair in the divisor
+};
+
+// the double cube divisor
+struct FxuDouble // 10 words
+{
+ int Num; // the unique number of this divisor
+ int HNum; // the heap number of this divisor
+ int Weight; // the weight of this divisor
+ unsigned Key; // the hash key of this divisor
+ Fxu_ListPair lPairs; // the pairs of cubes, which produce this divisor
+ Fxu_Double * pPrev; // the previous divisor in the table
+ Fxu_Double * pNext; // the next divisor in the table
+ Fxu_Double * pOrder; // the specialized linked list of divisors
+};
+
+// the single cube divisor
+struct FxuSingle // 7 words
+{
+ int Num; // the unique number of this divisor
+ int HNum; // the heap number of this divisor
+ int Weight; // the weight of this divisor
+ Fxu_Var * pVar1; // the first variable of the single-cube divisor
+ Fxu_Var * pVar2; // the second variable of the single-cube divisor
+ Fxu_Single * pPrev; // the previous divisor in the list
+ Fxu_Single * pNext; // the next divisor in the list
+};
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// minimum/maximum
+#define Fxu_Min( a, b ) ( ((a)<(b))? (a):(b) )
+#define Fxu_Max( a, b ) ( ((a)>(b))? (a):(b) )
+
+// selection of the minimum/maximum cube in the pair
+#define Fxu_PairMinCube( pPair ) (((pPair)->iCube1 < (pPair)->iCube2)? (pPair)->pCube1: (pPair)->pCube2)
+#define Fxu_PairMaxCube( pPair ) (((pPair)->iCube1 > (pPair)->iCube2)? (pPair)->pCube1: (pPair)->pCube2)
+#define Fxu_PairMinCubeInt( pPair ) (((pPair)->iCube1 < (pPair)->iCube2)? (pPair)->iCube1: (pPair)->iCube2)
+#define Fxu_PairMaxCubeInt( pPair ) (((pPair)->iCube1 > (pPair)->iCube2)? (pPair)->iCube1: (pPair)->iCube2)
+
+// iterators
+
+#define Fxu_MatrixForEachCube( Matrix, Cube )\
+ for ( Cube = (Matrix)->lCubes.pHead;\
+ Cube;\
+ Cube = Cube->pNext )
+#define Fxu_MatrixForEachCubeSafe( Matrix, Cube, Cube2 )\
+ for ( Cube = (Matrix)->lCubes.pHead, Cube2 = (Cube? Cube->pNext: NULL);\
+ Cube;\
+ Cube = Cube2, Cube2 = (Cube? Cube->pNext: NULL) )
+
+#define Fxu_MatrixForEachVariable( Matrix, Var )\
+ for ( Var = (Matrix)->lVars.pHead;\
+ Var;\
+ Var = Var->pNext )
+#define Fxu_MatrixForEachVariableSafe( Matrix, Var, Var2 )\
+ for ( Var = (Matrix)->lVars.pHead, Var2 = (Var? Var->pNext: NULL);\
+ Var;\
+ Var = Var2, Var2 = (Var? Var->pNext: NULL) )
+
+#define Fxu_MatrixForEachSingle( Matrix, Single )\
+ for ( Single = (Matrix)->lSingles.pHead;\
+ Single;\
+ Single = Single->pNext )
+#define Fxu_MatrixForEachSingleSafe( Matrix, Single, Single2 )\
+ for ( Single = (Matrix)->lSingles.pHead, Single2 = (Single? Single->pNext: NULL);\
+ Single;\
+ Single = Single2, Single2 = (Single? Single->pNext: NULL) )
+
+#define Fxu_TableForEachDouble( Matrix, Key, Div )\
+ for ( Div = (Matrix)->pTable[Key].pHead;\
+ Div;\
+ Div = Div->pNext )
+#define Fxu_TableForEachDoubleSafe( Matrix, Key, Div, Div2 )\
+ for ( Div = (Matrix)->pTable[Key].pHead, Div2 = (Div? Div->pNext: NULL);\
+ Div;\
+ Div = Div2, Div2 = (Div? Div->pNext: NULL) )
+
+#define Fxu_MatrixForEachDouble( Matrix, Div, Index )\
+ for ( Index = 0; Index < (Matrix)->nTableSize; Index++ )\
+ Fxu_TableForEachDouble( Matrix, Index, Div )
+#define Fxu_MatrixForEachDoubleSafe( Matrix, Div, Div2, Index )\
+ for ( Index = 0; Index < (Matrix)->nTableSize; Index++ )\
+ Fxu_TableForEachDoubleSafe( Matrix, Index, Div, Div2 )
+
+
+#define Fxu_CubeForEachLiteral( Cube, Lit )\
+ for ( Lit = (Cube)->lLits.pHead;\
+ Lit;\
+ Lit = Lit->pHNext )
+#define Fxu_CubeForEachLiteralSafe( Cube, Lit, Lit2 )\
+ for ( Lit = (Cube)->lLits.pHead, Lit2 = (Lit? Lit->pHNext: NULL);\
+ Lit;\
+ Lit = Lit2, Lit2 = (Lit? Lit->pHNext: NULL) )
+
+#define Fxu_VarForEachLiteral( Var, Lit )\
+ for ( Lit = (Var)->lLits.pHead;\
+ Lit;\
+ Lit = Lit->pVNext )
+
+#define Fxu_CubeForEachDivisor( Cube, Div )\
+ for ( Div = (Cube)->lDivs.pHead;\
+ Div;\
+ Div = Div->pCNext )
+
+#define Fxu_DoubleForEachPair( Div, Pair )\
+ for ( Pair = (Div)->lPairs.pHead;\
+ Pair;\
+ Pair = Pair->pDNext )
+#define Fxu_DoubleForEachPairSafe( Div, Pair, Pair2 )\
+ for ( Pair = (Div)->lPairs.pHead, Pair2 = (Pair? Pair->pDNext: NULL);\
+ Pair;\
+ Pair = Pair2, Pair2 = (Pair? Pair->pDNext: NULL) )
+
+
+// iterator through the cube pairs belonging to the given cube
+#define Fxu_CubeForEachPair( pCube, pPair, i )\
+ for ( i = 0;\
+ i < pCube->pVar->nCubes &&\
+ (((unsigned)(pPair = pCube->pVar->ppPairs[pCube->iCube][i])) >= 0);\
+ i++ )\
+ if ( pPair )
+
+// iterator through all the items in the heap
+#define Fxu_HeapDoubleForEachItem( Heap, Div )\
+ for ( Heap->i = 1;\
+ Heap->i <= Heap->nItems && (Div = Heap->pTree[Heap->i]);\
+ Heap->i++ )
+#define Fxu_HeapSingleForEachItem( Heap, Single )\
+ for ( Heap->i = 1;\
+ Heap->i <= Heap->nItems && (Single = Heap->pTree[Heap->i]);\
+ Heap->i++ )
+
+// starting the rings
+#define Fxu_MatrixRingCubesStart( Matrix ) (((Matrix)->ppTailCubes = &((Matrix)->pOrderCubes)), ((Matrix)->pOrderCubes = NULL))
+#define Fxu_MatrixRingVarsStart( Matrix ) (((Matrix)->ppTailVars = &((Matrix)->pOrderVars)), ((Matrix)->pOrderVars = NULL))
+// stopping the rings
+#define Fxu_MatrixRingCubesStop( Matrix )
+#define Fxu_MatrixRingVarsStop( Matrix )
+// resetting the rings
+#define Fxu_MatrixRingCubesReset( Matrix ) (((Matrix)->pOrderCubes = NULL), ((Matrix)->ppTailCubes = NULL))
+#define Fxu_MatrixRingVarsReset( Matrix ) (((Matrix)->pOrderVars = NULL), ((Matrix)->ppTailVars = NULL))
+// adding to the rings
+#define Fxu_MatrixRingCubesAdd( Matrix, Cube) ((*((Matrix)->ppTailCubes) = Cube), ((Matrix)->ppTailCubes = &(Cube)->pOrder), ((Cube)->pOrder = (Fxu_Cube *)1))
+#define Fxu_MatrixRingVarsAdd( Matrix, Var ) ((*((Matrix)->ppTailVars ) = Var ), ((Matrix)->ppTailVars = &(Var)->pOrder ), ((Var)->pOrder = (Fxu_Var *)1))
+// iterating through the rings
+#define Fxu_MatrixForEachCubeInRing( Matrix, Cube )\
+ if ( (Matrix)->pOrderCubes )\
+ for ( Cube = (Matrix)->pOrderCubes;\
+ Cube != (Fxu_Cube *)1;\
+ Cube = Cube->pOrder )
+#define Fxu_MatrixForEachCubeInRingSafe( Matrix, Cube, Cube2 )\
+ if ( (Matrix)->pOrderCubes )\
+ for ( Cube = (Matrix)->pOrderCubes, Cube2 = ((Cube != (Fxu_Cube *)1)? Cube->pOrder: (Fxu_Cube *)1);\
+ Cube != (Fxu_Cube *)1;\
+ Cube = Cube2, Cube2 = ((Cube != (Fxu_Cube *)1)? Cube->pOrder: (Fxu_Cube *)1) )
+#define Fxu_MatrixForEachVarInRing( Matrix, Var )\
+ if ( (Matrix)->pOrderVars )\
+ for ( Var = (Matrix)->pOrderVars;\
+ Var != (Fxu_Var *)1;\
+ Var = Var->pOrder )
+#define Fxu_MatrixForEachVarInRingSafe( Matrix, Var, Var2 )\
+ if ( (Matrix)->pOrderVars )\
+ for ( Var = (Matrix)->pOrderVars, Var2 = ((Var != (Fxu_Var *)1)? Var->pOrder: (Fxu_Var *)1);\
+ Var != (Fxu_Var *)1;\
+ Var = Var2, Var2 = ((Var != (Fxu_Var *)1)? Var->pOrder: (Fxu_Var *)1) )
+// the procedures are related to the above macros
+extern void Fxu_MatrixRingCubesUnmark( Fxu_Matrix * p );
+extern void Fxu_MatrixRingVarsUnmark( Fxu_Matrix * p );
+
+
+// macros working with memory
+// MEM_ALLOC: allocate the given number (Size) of items of type (Type)
+// MEM_FREE: deallocate the pointer (Pointer) to the given number (Size) of items of type (Type)
+#ifdef USE_SYSTEM_MEMORY_MANAGEMENT
+#define MEM_ALLOC_FXU( Manager, Type, Size ) ((Type *)malloc( (Size) * sizeof(Type) ))
+#define MEM_FREE_FXU( Manager, Type, Size, Pointer ) if ( Pointer ) { free(Pointer); Pointer = NULL; }
+#else
+#define MEM_ALLOC_FXU( Manager, Type, Size )\
+ ((Type *)Fxu_MemFetch( Manager, (Size) * sizeof(Type) ))
+#define MEM_FREE_FXU( Manager, Type, Size, Pointer )\
+ if ( Pointer ) { Fxu_MemRecycle( Manager, (char *)(Pointer), (Size) * sizeof(Type) ); Pointer = NULL; }
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*===== fxu.c ====================================================*/
+extern char * Fxu_MemFetch( Fxu_Matrix * p, int nBytes );
+extern void Fxu_MemRecycle( Fxu_Matrix * p, char * pItem, int nBytes );
+/*===== fxuCreate.c ====================================================*/
+/*===== fxuReduce.c ====================================================*/
+/*===== fxuPrint.c ====================================================*/
+extern void Fxu_MatrixPrint( FILE * pFile, Fxu_Matrix * p );
+extern void Fxu_MatrixPrintDivisorProfile( FILE * pFile, Fxu_Matrix * p );
+/*===== fxuSelect.c ====================================================*/
+extern int Fxu_Select( Fxu_Matrix * p, Fxu_Single ** ppSingle, Fxu_Double ** ppDouble );
+extern int Fxu_SelectSCD( Fxu_Matrix * p, int Weight, Fxu_Var ** ppVar1, Fxu_Var ** ppVar2 );
+/*===== fxuUpdate.c ====================================================*/
+extern void Fxu_Update( Fxu_Matrix * p, Fxu_Single * pSingle, Fxu_Double * pDouble );
+extern void Fxu_UpdateDouble( Fxu_Matrix * p );
+extern void Fxu_UpdateSingle( Fxu_Matrix * p );
+/*===== fxuPair.c ====================================================*/
+extern void Fxu_PairCanonicize( Fxu_Cube ** ppCube1, Fxu_Cube ** ppCube2 );
+extern unsigned Fxu_PairHashKeyArray( Fxu_Matrix * p, int piVarsC1[], int piVarsC2[], int nVarsC1, int nVarsC2 );
+extern unsigned Fxu_PairHashKey( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2, int * pnBase, int * pnLits1, int * pnLits2 );
+extern unsigned Fxu_PairHashKeyMv( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2, int * pnBase, int * pnLits1, int * pnLits2 );
+extern int Fxu_PairCompare( Fxu_Pair * pPair1, Fxu_Pair * pPair2 );
+extern void Fxu_PairAllocStorage( Fxu_Var * pVar, int nCubes );
+extern void Fxu_PairFreeStorage( Fxu_Var * pVar );
+extern void Fxu_PairClearStorage( Fxu_Cube * pCube );
+extern Fxu_Pair * Fxu_PairAlloc( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2 );
+extern void Fxu_PairAdd( Fxu_Pair * pPair );
+/*===== fxuSingle.c ====================================================*/
+extern void Fxu_MatrixComputeSingles( Fxu_Matrix * p );
+extern void Fxu_MatrixComputeSinglesOne( Fxu_Matrix * p, Fxu_Var * pVar );
+extern int Fxu_SingleCountCoincidence( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2 );
+/*===== fxuMatrix.c ====================================================*/
+// matrix
+extern Fxu_Matrix * Fxu_MatrixAllocate();
+extern void Fxu_MatrixDelete( Fxu_Matrix * p );
+// double-cube divisor
+extern void Fxu_MatrixAddDivisor( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2 );
+extern void Fxu_MatrixDelDivisor( Fxu_Matrix * p, Fxu_Double * pDiv );
+// single-cube divisor
+extern void Fxu_MatrixAddSingle( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2, int Weight );
+// variable
+extern Fxu_Var * Fxu_MatrixAddVar( Fxu_Matrix * p );
+// cube
+extern Fxu_Cube * Fxu_MatrixAddCube( Fxu_Matrix * p, Fxu_Var * pVar, int iCube );
+// literal
+extern void Fxu_MatrixAddLiteral( Fxu_Matrix * p, Fxu_Cube * pCube, Fxu_Var * pVar );
+extern void Fxu_MatrixDelLiteral( Fxu_Matrix * p, Fxu_Lit * pLit );
+/*===== fxuList.c ====================================================*/
+// matrix -> variable
+extern void Fxu_ListMatrixAddVariable( Fxu_Matrix * p, Fxu_Var * pVar );
+extern void Fxu_ListMatrixDelVariable( Fxu_Matrix * p, Fxu_Var * pVar );
+// matrix -> cube
+extern void Fxu_ListMatrixAddCube( Fxu_Matrix * p, Fxu_Cube * pCube );
+extern void Fxu_ListMatrixDelCube( Fxu_Matrix * p, Fxu_Cube * pCube );
+// matrix -> single
+extern void Fxu_ListMatrixAddSingle( Fxu_Matrix * p, Fxu_Single * pSingle );
+extern void Fxu_ListMatrixDelSingle( Fxu_Matrix * p, Fxu_Single * pSingle );
+// table -> divisor
+extern void Fxu_ListTableAddDivisor( Fxu_Matrix * p, Fxu_Double * pDiv );
+extern void Fxu_ListTableDelDivisor( Fxu_Matrix * p, Fxu_Double * pDiv );
+// cube -> literal
+extern void Fxu_ListCubeAddLiteral( Fxu_Cube * pCube, Fxu_Lit * pLit );
+extern void Fxu_ListCubeDelLiteral( Fxu_Cube * pCube, Fxu_Lit * pLit );
+// var -> literal
+extern void Fxu_ListVarAddLiteral( Fxu_Var * pVar, Fxu_Lit * pLit );
+extern void Fxu_ListVarDelLiteral( Fxu_Var * pVar, Fxu_Lit * pLit );
+// divisor -> pair
+extern void Fxu_ListDoubleAddPairLast( Fxu_Double * pDiv, Fxu_Pair * pLink );
+extern void Fxu_ListDoubleAddPairFirst( Fxu_Double * pDiv, Fxu_Pair * pLink );
+extern void Fxu_ListDoubleAddPairMiddle( Fxu_Double * pDiv, Fxu_Pair * pSpot, Fxu_Pair * pLink );
+extern void Fxu_ListDoubleDelPair( Fxu_Double * pDiv, Fxu_Pair * pPair );
+/*===== fxuHeapDouble.c ====================================================*/
+extern Fxu_HeapDouble * Fxu_HeapDoubleStart();
+extern void Fxu_HeapDoubleStop( Fxu_HeapDouble * p );
+extern void Fxu_HeapDoublePrint( FILE * pFile, Fxu_HeapDouble * p );
+extern void Fxu_HeapDoubleCheck( Fxu_HeapDouble * p );
+extern void Fxu_HeapDoubleCheckOne( Fxu_HeapDouble * p, Fxu_Double * pDiv );
+
+extern void Fxu_HeapDoubleInsert( Fxu_HeapDouble * p, Fxu_Double * pDiv );
+extern void Fxu_HeapDoubleUpdate( Fxu_HeapDouble * p, Fxu_Double * pDiv );
+extern void Fxu_HeapDoubleDelete( Fxu_HeapDouble * p, Fxu_Double * pDiv );
+extern int Fxu_HeapDoubleReadMaxWeight( Fxu_HeapDouble * p );
+extern Fxu_Double * Fxu_HeapDoubleReadMax( Fxu_HeapDouble * p );
+extern Fxu_Double * Fxu_HeapDoubleGetMax( Fxu_HeapDouble * p );
+/*===== fxuHeapSingle.c ====================================================*/
+extern Fxu_HeapSingle * Fxu_HeapSingleStart();
+extern void Fxu_HeapSingleStop( Fxu_HeapSingle * p );
+extern void Fxu_HeapSinglePrint( FILE * pFile, Fxu_HeapSingle * p );
+extern void Fxu_HeapSingleCheck( Fxu_HeapSingle * p );
+extern void Fxu_HeapSingleCheckOne( Fxu_HeapSingle * p, Fxu_Single * pSingle );
+
+extern void Fxu_HeapSingleInsert( Fxu_HeapSingle * p, Fxu_Single * pSingle );
+extern void Fxu_HeapSingleUpdate( Fxu_HeapSingle * p, Fxu_Single * pSingle );
+extern void Fxu_HeapSingleDelete( Fxu_HeapSingle * p, Fxu_Single * pSingle );
+extern int Fxu_HeapSingleReadMaxWeight( Fxu_HeapSingle * p );
+extern Fxu_Single * Fxu_HeapSingleReadMax( Fxu_HeapSingle * p );
+extern Fxu_Single * Fxu_HeapSingleGetMax( Fxu_HeapSingle * p );
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+#endif
+
diff --git a/src/opt/fxu/fxuList.c b/src/opt/fxu/fxuList.c
new file mode 100644
index 00000000..bb081d80
--- /dev/null
+++ b/src/opt/fxu/fxuList.c
@@ -0,0 +1,522 @@
+/**CFile****************************************************************
+
+ FileName [fxuList.c]
+
+ PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
+
+ Synopsis [Operations on lists.]
+
+ Author [MVSIS Group]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - February 1, 2003.]
+
+ Revision [$Id: fxuList.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "fxuInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// matrix -> var
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_ListMatrixAddVariable( Fxu_Matrix * p, Fxu_Var * pLink )
+{
+ Fxu_ListVar * pList = &p->lVars;
+ if ( pList->pHead == NULL )
+ {
+ pList->pHead = pLink;
+ pList->pTail = pLink;
+ pLink->pPrev = NULL;
+ pLink->pNext = NULL;
+ }
+ else
+ {
+ pLink->pNext = NULL;
+ pList->pTail->pNext = pLink;
+ pLink->pPrev = pList->pTail;
+ pList->pTail = pLink;
+ }
+ pList->nItems++;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_ListMatrixDelVariable( Fxu_Matrix * p, Fxu_Var * pLink )
+{
+ Fxu_ListVar * pList = &p->lVars;
+ if ( pList->pHead == pLink )
+ pList->pHead = pLink->pNext;
+ if ( pList->pTail == pLink )
+ pList->pTail = pLink->pPrev;
+ if ( pLink->pPrev )
+ pLink->pPrev->pNext = pLink->pNext;
+ if ( pLink->pNext )
+ pLink->pNext->pPrev = pLink->pPrev;
+ pList->nItems--;
+}
+
+
+// matrix -> cube
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_ListMatrixAddCube( Fxu_Matrix * p, Fxu_Cube * pLink )
+{
+ Fxu_ListCube * pList = &p->lCubes;
+ if ( pList->pHead == NULL )
+ {
+ pList->pHead = pLink;
+ pList->pTail = pLink;
+ pLink->pPrev = NULL;
+ pLink->pNext = NULL;
+ }
+ else
+ {
+ pLink->pNext = NULL;
+ pList->pTail->pNext = pLink;
+ pLink->pPrev = pList->pTail;
+ pList->pTail = pLink;
+ }
+ pList->nItems++;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_ListMatrixDelCube( Fxu_Matrix * p, Fxu_Cube * pLink )
+{
+ Fxu_ListCube * pList = &p->lCubes;
+ if ( pList->pHead == pLink )
+ pList->pHead = pLink->pNext;
+ if ( pList->pTail == pLink )
+ pList->pTail = pLink->pPrev;
+ if ( pLink->pPrev )
+ pLink->pPrev->pNext = pLink->pNext;
+ if ( pLink->pNext )
+ pLink->pNext->pPrev = pLink->pPrev;
+ pList->nItems--;
+}
+
+
+// matrix -> single
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_ListMatrixAddSingle( Fxu_Matrix * p, Fxu_Single * pLink )
+{
+ Fxu_ListSingle * pList = &p->lSingles;
+ if ( pList->pHead == NULL )
+ {
+ pList->pHead = pLink;
+ pList->pTail = pLink;
+ pLink->pPrev = NULL;
+ pLink->pNext = NULL;
+ }
+ else
+ {
+ pLink->pNext = NULL;
+ pList->pTail->pNext = pLink;
+ pLink->pPrev = pList->pTail;
+ pList->pTail = pLink;
+ }
+ pList->nItems++;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_ListMatrixDelSingle( Fxu_Matrix * p, Fxu_Single * pLink )
+{
+ Fxu_ListSingle * pList = &p->lSingles;
+ if ( pList->pHead == pLink )
+ pList->pHead = pLink->pNext;
+ if ( pList->pTail == pLink )
+ pList->pTail = pLink->pPrev;
+ if ( pLink->pPrev )
+ pLink->pPrev->pNext = pLink->pNext;
+ if ( pLink->pNext )
+ pLink->pNext->pPrev = pLink->pPrev;
+ pList->nItems--;
+}
+
+
+// table -> divisor
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_ListTableAddDivisor( Fxu_Matrix * p, Fxu_Double * pLink )
+{
+ Fxu_ListDouble * pList = &(p->pTable[pLink->Key]);
+ if ( pList->pHead == NULL )
+ {
+ pList->pHead = pLink;
+ pList->pTail = pLink;
+ pLink->pPrev = NULL;
+ pLink->pNext = NULL;
+ }
+ else
+ {
+ pLink->pNext = NULL;
+ pList->pTail->pNext = pLink;
+ pLink->pPrev = pList->pTail;
+ pList->pTail = pLink;
+ }
+ pList->nItems++;
+ p->nDivs++;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_ListTableDelDivisor( Fxu_Matrix * p, Fxu_Double * pLink )
+{
+ Fxu_ListDouble * pList = &(p->pTable[pLink->Key]);
+ if ( pList->pHead == pLink )
+ pList->pHead = pLink->pNext;
+ if ( pList->pTail == pLink )
+ pList->pTail = pLink->pPrev;
+ if ( pLink->pPrev )
+ pLink->pPrev->pNext = pLink->pNext;
+ if ( pLink->pNext )
+ pLink->pNext->pPrev = pLink->pPrev;
+ pList->nItems--;
+ p->nDivs--;
+}
+
+
+// cube -> literal
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_ListCubeAddLiteral( Fxu_Cube * pCube, Fxu_Lit * pLink )
+{
+ Fxu_ListLit * pList = &(pCube->lLits);
+ if ( pList->pHead == NULL )
+ {
+ pList->pHead = pLink;
+ pList->pTail = pLink;
+ pLink->pHPrev = NULL;
+ pLink->pHNext = NULL;
+ }
+ else
+ {
+ pLink->pHNext = NULL;
+ pList->pTail->pHNext = pLink;
+ pLink->pHPrev = pList->pTail;
+ pList->pTail = pLink;
+ }
+ pList->nItems++;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_ListCubeDelLiteral( Fxu_Cube * pCube, Fxu_Lit * pLink )
+{
+ Fxu_ListLit * pList = &(pCube->lLits);
+ if ( pList->pHead == pLink )
+ pList->pHead = pLink->pHNext;
+ if ( pList->pTail == pLink )
+ pList->pTail = pLink->pHPrev;
+ if ( pLink->pHPrev )
+ pLink->pHPrev->pHNext = pLink->pHNext;
+ if ( pLink->pHNext )
+ pLink->pHNext->pHPrev = pLink->pHPrev;
+ pList->nItems--;
+}
+
+
+// var -> literal
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_ListVarAddLiteral( Fxu_Var * pVar, Fxu_Lit * pLink )
+{
+ Fxu_ListLit * pList = &(pVar->lLits);
+ if ( pList->pHead == NULL )
+ {
+ pList->pHead = pLink;
+ pList->pTail = pLink;
+ pLink->pVPrev = NULL;
+ pLink->pVNext = NULL;
+ }
+ else
+ {
+ pLink->pVNext = NULL;
+ pList->pTail->pVNext = pLink;
+ pLink->pVPrev = pList->pTail;
+ pList->pTail = pLink;
+ }
+ pList->nItems++;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_ListVarDelLiteral( Fxu_Var * pVar, Fxu_Lit * pLink )
+{
+ Fxu_ListLit * pList = &(pVar->lLits);
+ if ( pList->pHead == pLink )
+ pList->pHead = pLink->pVNext;
+ if ( pList->pTail == pLink )
+ pList->pTail = pLink->pVPrev;
+ if ( pLink->pVPrev )
+ pLink->pVPrev->pVNext = pLink->pVNext;
+ if ( pLink->pVNext )
+ pLink->pVNext->pVPrev = pLink->pVPrev;
+ pList->nItems--;
+}
+
+
+
+// divisor -> pair
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_ListDoubleAddPairLast( Fxu_Double * pDiv, Fxu_Pair * pLink )
+{
+ Fxu_ListPair * pList = &pDiv->lPairs;
+ if ( pList->pHead == NULL )
+ {
+ pList->pHead = pLink;
+ pList->pTail = pLink;
+ pLink->pDPrev = NULL;
+ pLink->pDNext = NULL;
+ }
+ else
+ {
+ pLink->pDNext = NULL;
+ pList->pTail->pDNext = pLink;
+ pLink->pDPrev = pList->pTail;
+ pList->pTail = pLink;
+ }
+ pList->nItems++;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_ListDoubleAddPairFirst( Fxu_Double * pDiv, Fxu_Pair * pLink )
+{
+ Fxu_ListPair * pList = &pDiv->lPairs;
+ if ( pList->pHead == NULL )
+ {
+ pList->pHead = pLink;
+ pList->pTail = pLink;
+ pLink->pDPrev = NULL;
+ pLink->pDNext = NULL;
+ }
+ else
+ {
+ pLink->pDPrev = NULL;
+ pList->pHead->pDPrev = pLink;
+ pLink->pDNext = pList->pHead;
+ pList->pHead = pLink;
+ }
+ pList->nItems++;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds the entry in the middle of the list after the spot.]
+
+ Description [Assumes that spot points to the link, after which the given
+ link should be added. Spot cannot be NULL or the tail of the list.
+ Therefore, the head and the tail of the list are not changed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_ListDoubleAddPairMiddle( Fxu_Double * pDiv, Fxu_Pair * pSpot, Fxu_Pair * pLink )
+{
+ Fxu_ListPair * pList = &pDiv->lPairs;
+ assert( pSpot );
+ assert( pSpot != pList->pTail );
+ pLink->pDPrev = pSpot;
+ pLink->pDNext = pSpot->pDNext;
+ pLink->pDPrev->pDNext = pLink;
+ pLink->pDNext->pDPrev = pLink;
+ pList->nItems++;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_ListDoubleDelPair( Fxu_Double * pDiv, Fxu_Pair * pLink )
+{
+ Fxu_ListPair * pList = &pDiv->lPairs;
+ if ( pList->pHead == pLink )
+ pList->pHead = pLink->pDNext;
+ if ( pList->pTail == pLink )
+ pList->pTail = pLink->pDPrev;
+ if ( pLink->pDPrev )
+ pLink->pDPrev->pDNext = pLink->pDNext;
+ if ( pLink->pDNext )
+ pLink->pDNext->pDPrev = pLink->pDPrev;
+ pList->nItems--;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_ListDoubleAddPairPlace( Fxu_Double * pDiv, Fxu_Pair * pPair, Fxu_Pair * pPairSpot )
+{
+ printf( "Fxu_ListDoubleAddPairPlace() is called!\n" );
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/opt/fxu/fxuMatrix.c b/src/opt/fxu/fxuMatrix.c
new file mode 100644
index 00000000..0b732aef
--- /dev/null
+++ b/src/opt/fxu/fxuMatrix.c
@@ -0,0 +1,382 @@
+/**CFile****************************************************************
+
+ FileName [fxuMatrix.c]
+
+ PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
+
+ Synopsis [Procedures to manipulate the sparse matrix.]
+
+ Author [MVSIS Group]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - February 1, 2003.]
+
+ Revision [$Id: fxuMatrix.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "fxuInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+extern unsigned int Cudd_Prime( unsigned int p );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Fxu_Matrix * Fxu_MatrixAllocate()
+{
+ Fxu_Matrix * p;
+ p = ALLOC( Fxu_Matrix, 1 );
+ memset( p, 0, sizeof(Fxu_Matrix) );
+ p->nTableSize = Cudd_Prime(10000);
+ p->pTable = ALLOC( Fxu_ListDouble, p->nTableSize );
+ memset( p->pTable, 0, sizeof(Fxu_ListDouble) * p->nTableSize );
+#ifndef USE_SYSTEM_MEMORY_MANAGEMENT
+ {
+ // get the largest size in bytes for the following structures:
+ // Fxu_Cube, Fxu_Var, Fxu_Lit, Fxu_Pair, Fxu_Double, Fxu_Single
+ // (currently, Fxu_Var, Fxu_Pair, Fxu_Double take 10 machine words)
+ int nSizeMax, nSizeCur;
+ nSizeMax = -1;
+ nSizeCur = sizeof(Fxu_Cube);
+ if ( nSizeMax < nSizeCur )
+ nSizeMax = nSizeCur;
+ nSizeCur = sizeof(Fxu_Var);
+ if ( nSizeMax < nSizeCur )
+ nSizeMax = nSizeCur;
+ nSizeCur = sizeof(Fxu_Lit);
+ if ( nSizeMax < nSizeCur )
+ nSizeMax = nSizeCur;
+ nSizeCur = sizeof(Fxu_Pair);
+ if ( nSizeMax < nSizeCur )
+ nSizeMax = nSizeCur;
+ nSizeCur = sizeof(Fxu_Double);
+ if ( nSizeMax < nSizeCur )
+ nSizeMax = nSizeCur;
+ nSizeCur = sizeof(Fxu_Single);
+ if ( nSizeMax < nSizeCur )
+ nSizeMax = nSizeCur;
+ p->pMemMan = Extra_MmFixedStart( nSizeMax );
+ }
+#endif
+ p->pHeapDouble = Fxu_HeapDoubleStart();
+ p->pHeapSingle = Fxu_HeapSingleStart();
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_MatrixDelete( Fxu_Matrix * p )
+{
+ Fxu_HeapDoubleCheck( p->pHeapDouble );
+ Fxu_HeapDoubleStop( p->pHeapDouble );
+ Fxu_HeapSingleStop( p->pHeapSingle );
+
+ // delete other things
+#ifdef USE_SYSTEM_MEMORY_MANAGEMENT
+ // this code is not needed when the custom memory manager is used
+ {
+ Fxu_Cube * pCube, * pCube2;
+ Fxu_Var * pVar, * pVar2;
+ Fxu_Lit * pLit, * pLit2;
+ Fxu_Double * pDiv, * pDiv2;
+ Fxu_Single * pSingle, * pSingle2;
+ Fxu_Pair * pPair, * pPair2;
+ int i;
+ // delete the divisors
+ Fxu_MatrixForEachDoubleSafe( p, pDiv, pDiv2, i )
+ {
+ Fxu_DoubleForEachPairSafe( pDiv, pPair, pPair2 )
+ MEM_FREE_FXU( p, Fxu_Pair, 1, pPair );
+ MEM_FREE_FXU( p, Fxu_Double, 1, pDiv );
+ }
+ Fxu_MatrixForEachSingleSafe( p, pSingle, pSingle2 )
+ MEM_FREE_FXU( p, Fxu_Single, 1, pSingle );
+ // delete the entries
+ Fxu_MatrixForEachCube( p, pCube )
+ Fxu_CubeForEachLiteralSafe( pCube, pLit, pLit2 )
+ MEM_FREE_FXU( p, Fxu_Lit, 1, pLit );
+ // delete the cubes
+ Fxu_MatrixForEachCubeSafe( p, pCube, pCube2 )
+ MEM_FREE_FXU( p, Fxu_Cube, 1, pCube );
+ // delete the vars
+ Fxu_MatrixForEachVariableSafe( p, pVar, pVar2 )
+ MEM_FREE_FXU( p, Fxu_Var, 1, pVar );
+ }
+#else
+ Extra_MmFixedStop( p->pMemMan, 0 );
+#endif
+
+ FREE( p->pppPairs );
+ FREE( p->ppPairs );
+ FREE( p->pPairsTemp );
+ FREE( p->pTable );
+ FREE( p->ppVars );
+ FREE( p );
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Adds a variable to the matrix.]
+
+ Description [This procedure always adds variables at the end of the matrix.
+ It assigns the var's node and number. It adds the var to the linked list of
+ all variables and to the table of all nodes.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Fxu_Var * Fxu_MatrixAddVar( Fxu_Matrix * p )
+{
+ Fxu_Var * pVar;
+ pVar = MEM_ALLOC_FXU( p, Fxu_Var, 1 );
+ memset( pVar, 0, sizeof(Fxu_Var) );
+ pVar->iVar = p->lVars.nItems;
+ p->ppVars[pVar->iVar] = pVar;
+ Fxu_ListMatrixAddVariable( p, pVar );
+ return pVar;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds a literal to the matrix.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Fxu_Cube * Fxu_MatrixAddCube( Fxu_Matrix * p, Fxu_Var * pVar, int iCube )
+{
+ Fxu_Cube * pCube;
+ pCube = MEM_ALLOC_FXU( p, Fxu_Cube, 1 );
+ memset( pCube, 0, sizeof(Fxu_Cube) );
+ pCube->pVar = pVar;
+ pCube->iCube = iCube;
+ Fxu_ListMatrixAddCube( p, pCube );
+ return pCube;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds a literal to the matrix.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_MatrixAddLiteral( Fxu_Matrix * p, Fxu_Cube * pCube, Fxu_Var * pVar )
+{
+ Fxu_Lit * pLit;
+ pLit = MEM_ALLOC_FXU( p, Fxu_Lit, 1 );
+ memset( pLit, 0, sizeof(Fxu_Lit) );
+ // insert the literal into two linked lists
+ Fxu_ListCubeAddLiteral( pCube, pLit );
+ Fxu_ListVarAddLiteral( pVar, pLit );
+ // set the back pointers
+ pLit->pCube = pCube;
+ pLit->pVar = pVar;
+ pLit->iCube = pCube->iCube;
+ pLit->iVar = pVar->iVar;
+ // increment the literal counter
+ p->nEntries++;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Deletes the divisor from the matrix.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_MatrixDelDivisor( Fxu_Matrix * p, Fxu_Double * pDiv )
+{
+ // delete divisor from the table
+ Fxu_ListTableDelDivisor( p, pDiv );
+ // recycle the divisor
+ MEM_FREE_FXU( p, Fxu_Double, 1, pDiv );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Deletes the literal fromthe matrix.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_MatrixDelLiteral( Fxu_Matrix * p, Fxu_Lit * pLit )
+{
+ // delete the literal
+ Fxu_ListCubeDelLiteral( pLit->pCube, pLit );
+ Fxu_ListVarDelLiteral( pLit->pVar, pLit );
+ MEM_FREE_FXU( p, Fxu_Lit, 1, pLit );
+ // increment the literal counter
+ p->nEntries--;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Creates and adds a single cube divisor.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_MatrixAddSingle( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2, int Weight )
+{
+ Fxu_Single * pSingle;
+ assert( pVar1->iVar < pVar2->iVar );
+ pSingle = MEM_ALLOC_FXU( p, Fxu_Single, 1 );
+ memset( pSingle, 0, sizeof(Fxu_Single) );
+ pSingle->Num = p->lSingles.nItems;
+ pSingle->Weight = Weight;
+ pSingle->HNum = 0;
+ pSingle->pVar1 = pVar1;
+ pSingle->pVar2 = pVar2;
+ Fxu_ListMatrixAddSingle( p, pSingle );
+ // add to the heap
+ Fxu_HeapSingleInsert( p->pHeapSingle, pSingle );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_MatrixAddDivisor( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2 )
+{
+ Fxu_Pair * pPair;
+ Fxu_Double * pDiv;
+ int nBase, nLits1, nLits2;
+ int fFound;
+ unsigned Key;
+
+ // canonicize the pair
+ Fxu_PairCanonicize( &pCube1, &pCube2 );
+
+/*
+ // compute the hash key
+ if ( p->fMvNetwork )
+// if ( 0 )
+ { // in case of MV network, if all the values in the cube-free divisor
+ // belong to the same MV variable, this cube pair is not a divisor
+ Key = Fxu_PairHashKeyMv( p, pCube1, pCube2, &nBase, &nLits1, &nLits2 );
+ if ( Key == 0 )
+ return;
+ }
+ else
+*/
+ Key = Fxu_PairHashKey( p, pCube1, pCube2, &nBase, &nLits1, &nLits2 );
+
+ // create the cube pair
+ pPair = Fxu_PairAlloc( p, pCube1, pCube2 );
+ pPair->nBase = nBase;
+ pPair->nLits1 = nLits1;
+ pPair->nLits2 = nLits2;
+
+ // check if the divisor for this pair already exists
+ fFound = 0;
+ Key %= p->nTableSize;
+ Fxu_TableForEachDouble( p, Key, pDiv )
+ if ( Fxu_PairCompare( pPair, pDiv->lPairs.pTail ) ) // they are equal
+ {
+ fFound = 1;
+ break;
+ }
+
+ if ( !fFound )
+ { // create the new divisor
+ pDiv = MEM_ALLOC_FXU( p, Fxu_Double, 1 );
+ memset( pDiv, 0, sizeof(Fxu_Double) );
+ pDiv->Key = Key;
+ // set the number of this divisor
+ pDiv->Num = p->nDivsTotal++; // p->nDivs;
+ // insert the divisor in the table
+ Fxu_ListTableAddDivisor( p, pDiv );
+ // set the initial cost of the divisor
+ pDiv->Weight -= pPair->nLits1 + pPair->nLits2;
+ }
+
+ // link the pair to the cubes
+ Fxu_PairAdd( pPair );
+ // connect the pair and the divisor
+ pPair->pDiv = pDiv;
+ Fxu_ListDoubleAddPairLast( pDiv, pPair );
+ // update the max number of pairs in a divisor
+// if ( p->nPairsMax < pDiv->lPairs.nItems )
+// p->nPairsMax = pDiv->lPairs.nItems;
+ // update the divisor's weight
+ pDiv->Weight += pPair->nLits1 + pPair->nLits2 - 1 + pPair->nBase;
+ if ( fFound ) // update the divisor in the heap
+ Fxu_HeapDoubleUpdate( p->pHeapDouble, pDiv );
+ else // add the new divisor to the heap
+ Fxu_HeapDoubleInsert( p->pHeapDouble, pDiv );
+}
+
+/*
+ {
+ int piVarsC1[100], piVarsC2[100], nVarsC1, nVarsC2;
+ Fxu_Double * pDivCur;
+ Fxu_MatrixGetDoubleVars( p, pDiv, piVarsC1, piVarsC2, &nVarsC1, &nVarsC2 );
+ pDivCur = Fxu_MatrixFindDouble( p, piVarsC1, piVarsC2, nVarsC1, nVarsC2 );
+ assert( pDivCur == pDiv );
+ }
+*/
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/opt/fxu/fxuPair.c b/src/opt/fxu/fxuPair.c
new file mode 100644
index 00000000..be6be5e9
--- /dev/null
+++ b/src/opt/fxu/fxuPair.c
@@ -0,0 +1,555 @@
+/**CFile****************************************************************
+
+ FileName [fxuPair.c]
+
+ PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
+
+ Synopsis [Operations on cube pairs.]
+
+ Author [MVSIS Group]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - February 1, 2003.]
+
+ Revision [$Id: fxuPair.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "fxuInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define MAX_PRIMES 304
+
+static s_Primes[MAX_PRIMES] =
+{
+ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37,
+ 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89,
+ 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
+ 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223,
+ 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
+ 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359,
+ 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433,
+ 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
+ 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593,
+ 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
+ 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743,
+ 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827,
+ 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
+ 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997,
+ 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069,
+ 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163,
+ 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249,
+ 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321,
+ 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439,
+ 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511,
+ 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601,
+ 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693,
+ 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783,
+ 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877,
+ 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987,
+ 1993, 1997, 1999, 2003
+};
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Find the canonical permutation of two cubes in the pair.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_PairCanonicize( Fxu_Cube ** ppCube1, Fxu_Cube ** ppCube2 )
+{
+ Fxu_Lit * pLit1, * pLit2;
+ Fxu_Cube * pCubeTemp;
+
+ // walk through the cubes to determine
+ // the one that has higher first variable
+ pLit1 = (*ppCube1)->lLits.pHead;
+ pLit2 = (*ppCube2)->lLits.pHead;
+ while ( 1 )
+ {
+ if ( pLit1->iVar == pLit2->iVar )
+ {
+ pLit1 = pLit1->pHNext;
+ pLit2 = pLit2->pHNext;
+ continue;
+ }
+ assert( pLit1 && pLit2 ); // this is true if the covers are SCC-free
+ if ( pLit1->iVar > pLit2->iVar )
+ { // swap the cubes
+ pCubeTemp = *ppCube1;
+ *ppCube1 = *ppCube2;
+ *ppCube2 = pCubeTemp;
+ }
+ break;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find the canonical permutation of two cubes in the pair.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_PairCanonicize2( Fxu_Cube ** ppCube1, Fxu_Cube ** ppCube2 )
+{
+ Fxu_Cube * pCubeTemp;
+ // canonicize the pair by ordering the cubes
+ if ( (*ppCube1)->iCube > (*ppCube2)->iCube )
+ { // swap the cubes
+ pCubeTemp = *ppCube1;
+ *ppCube1 = *ppCube2;
+ *ppCube2 = pCubeTemp;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned Fxu_PairHashKeyArray( Fxu_Matrix * p, int piVarsC1[], int piVarsC2[], int nVarsC1, int nVarsC2 )
+{
+ int Offset1 = 100, Offset2 = 200, i;
+ unsigned Key;
+ // compute the hash key
+ Key = 0;
+ for ( i = 0; i < nVarsC1; i++ )
+ Key ^= s_Primes[Offset1+i] * piVarsC1[i];
+ for ( i = 0; i < nVarsC2; i++ )
+ Key ^= s_Primes[Offset2+i] * piVarsC2[i];
+ return Key;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the hash key of the divisor represented by the pair of cubes.]
+
+ Description [Goes through the variables in both cubes. Skips the identical
+ ones (this corresponds to making the cubes cube-free). Computes the hash
+ value of the cubes. Assigns the number of literals in the base and in the
+ cubes without base.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned Fxu_PairHashKey( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2,
+ int * pnBase, int * pnLits1, int * pnLits2 )
+{
+ int Offset1 = 100, Offset2 = 200;
+ int nBase, nLits1, nLits2;
+ Fxu_Lit * pLit1, * pLit2;
+ unsigned Key;
+
+ // compute the hash key
+ Key = 0;
+ nLits1 = 0;
+ nLits2 = 0;
+ nBase = 0;
+ pLit1 = pCube1->lLits.pHead;
+ pLit2 = pCube2->lLits.pHead;
+ while ( 1 )
+ {
+ if ( pLit1 && pLit2 )
+ {
+ if ( pLit1->iVar == pLit2->iVar )
+ { // ensure cube-free
+ pLit1 = pLit1->pHNext;
+ pLit2 = pLit2->pHNext;
+ // add this literal to the base
+ nBase++;
+ }
+ else if ( pLit1->iVar < pLit2->iVar )
+ {
+ Key ^= s_Primes[Offset1+nLits1] * pLit1->iVar;
+ pLit1 = pLit1->pHNext;
+ nLits1++;
+ }
+ else
+ {
+ Key ^= s_Primes[Offset2+nLits2] * pLit2->iVar;
+ pLit2 = pLit2->pHNext;
+ nLits2++;
+ }
+ }
+ else if ( pLit1 && !pLit2 )
+ {
+ Key ^= s_Primes[Offset1+nLits1] * pLit1->iVar;
+ pLit1 = pLit1->pHNext;
+ nLits1++;
+ }
+ else if ( !pLit1 && pLit2 )
+ {
+ Key ^= s_Primes[Offset2+nLits2] * pLit2->iVar;
+ pLit2 = pLit2->pHNext;
+ nLits2++;
+ }
+ else
+ break;
+ }
+ *pnBase = nBase;
+ *pnLits1 = nLits1;
+ *pnLits2 = nLits2;
+ return Key;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compares the two pairs.]
+
+ Description [Returns 1 if the divisors represented by these pairs
+ are equal.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Fxu_PairCompare( Fxu_Pair * pPair1, Fxu_Pair * pPair2 )
+{
+ Fxu_Lit * pD1C1, * pD1C2;
+ Fxu_Lit * pD2C1, * pD2C2;
+ int TopVar1, TopVar2;
+ int Code;
+
+ if ( pPair1->nLits1 != pPair2->nLits1 )
+ return 0;
+ if ( pPair1->nLits2 != pPair2->nLits2 )
+ return 0;
+
+ pD1C1 = pPair1->pCube1->lLits.pHead;
+ pD1C2 = pPair1->pCube2->lLits.pHead;
+
+ pD2C1 = pPair2->pCube1->lLits.pHead;
+ pD2C2 = pPair2->pCube2->lLits.pHead;
+
+ Code = pD1C1? 8: 0;
+ Code |= pD1C2? 4: 0;
+ Code |= pD2C1? 2: 0;
+ Code |= pD2C2? 1: 0;
+ assert( Code == 15 );
+
+ while ( 1 )
+ {
+ switch ( Code )
+ {
+ case 0: // -- -- NULL NULL NULL NULL
+ return 1;
+ case 1: // -- -1 NULL NULL NULL pD2C2
+ return 0;
+ case 2: // -- 1- NULL NULL pD2C1 NULL
+ return 0;
+ case 3: // -- 11 NULL NULL pD2C1 pD2C2
+ if ( pD2C1->iVar != pD2C2->iVar )
+ return 0;
+ pD2C1 = pD2C1->pHNext;
+ pD2C2 = pD2C2->pHNext;
+ break;
+ case 4: // -1 -- NULL pD1C2 NULL NULL
+ return 0;
+ case 5: // -1 -1 NULL pD1C2 NULL pD2C2
+ if ( pD1C2->iVar != pD2C2->iVar )
+ return 0;
+ pD1C2 = pD1C2->pHNext;
+ pD2C2 = pD2C2->pHNext;
+ break;
+ case 6: // -1 1- NULL pD1C2 pD2C1 NULL
+ return 0;
+ case 7: // -1 11 NULL pD1C2 pD2C1 pD2C2
+ TopVar2 = Fxu_Min( pD2C1->iVar, pD2C2->iVar );
+ if ( TopVar2 == pD1C2->iVar )
+ {
+ if ( pD2C1->iVar <= pD2C2->iVar )
+ return 0;
+ pD1C2 = pD1C2->pHNext;
+ pD2C2 = pD2C2->pHNext;
+ }
+ else if ( TopVar2 < pD1C2->iVar )
+ {
+ if ( pD2C1->iVar != pD2C2->iVar )
+ return 0;
+ pD2C1 = pD2C1->pHNext;
+ pD2C2 = pD2C2->pHNext;
+ }
+ else
+ return 0;
+ break;
+ case 8: // 1- -- pD1C1 NULL NULL NULL
+ return 0;
+ case 9: // 1- -1 pD1C1 NULL NULL pD2C2
+ return 0;
+ case 10: // 1- 1- pD1C1 NULL pD2C1 NULL
+ if ( pD1C1->iVar != pD2C1->iVar )
+ return 0;
+ pD1C1 = pD1C1->pHNext;
+ pD2C1 = pD2C1->pHNext;
+ break;
+ case 11: // 1- 11 pD1C1 NULL pD2C1 pD2C2
+ TopVar2 = Fxu_Min( pD2C1->iVar, pD2C2->iVar );
+ if ( TopVar2 == pD1C1->iVar )
+ {
+ if ( pD2C1->iVar >= pD2C2->iVar )
+ return 0;
+ pD1C1 = pD1C1->pHNext;
+ pD2C1 = pD2C1->pHNext;
+ }
+ else if ( TopVar2 < pD1C1->iVar )
+ {
+ if ( pD2C1->iVar != pD2C2->iVar )
+ return 0;
+ pD2C1 = pD2C1->pHNext;
+ pD2C2 = pD2C2->pHNext;
+ }
+ else
+ return 0;
+ break;
+ case 12: // 11 -- pD1C1 pD1C2 NULL NULL
+ if ( pD1C1->iVar != pD1C2->iVar )
+ return 0;
+ pD1C1 = pD1C1->pHNext;
+ pD1C2 = pD1C2->pHNext;
+ break;
+ case 13: // 11 -1 pD1C1 pD1C2 NULL pD2C2
+ TopVar1 = Fxu_Min( pD1C1->iVar, pD1C2->iVar );
+ if ( TopVar1 == pD2C2->iVar )
+ {
+ if ( pD1C1->iVar <= pD1C2->iVar )
+ return 0;
+ pD1C2 = pD1C2->pHNext;
+ pD2C2 = pD2C2->pHNext;
+ }
+ else if ( TopVar1 < pD2C2->iVar )
+ {
+ if ( pD1C1->iVar != pD1C2->iVar )
+ return 0;
+ pD1C1 = pD1C1->pHNext;
+ pD1C2 = pD1C2->pHNext;
+ }
+ else
+ return 0;
+ break;
+ case 14: // 11 1- pD1C1 pD1C2 pD2C1 NULL
+ TopVar1 = Fxu_Min( pD1C1->iVar, pD1C2->iVar );
+ if ( TopVar1 == pD2C1->iVar )
+ {
+ if ( pD1C1->iVar >= pD1C2->iVar )
+ return 0;
+ pD1C1 = pD1C1->pHNext;
+ pD2C1 = pD2C1->pHNext;
+ }
+ else if ( TopVar1 < pD2C1->iVar )
+ {
+ if ( pD1C1->iVar != pD1C2->iVar )
+ return 0;
+ pD1C1 = pD1C1->pHNext;
+ pD1C2 = pD1C2->pHNext;
+ }
+ else
+ return 0;
+ break;
+ case 15: // 11 11 pD1C1 pD1C2 pD2C1 pD2C2
+ TopVar1 = Fxu_Min( pD1C1->iVar, pD1C2->iVar );
+ TopVar2 = Fxu_Min( pD2C1->iVar, pD2C2->iVar );
+ if ( TopVar1 == TopVar2 )
+ {
+ if ( pD1C1->iVar == pD1C2->iVar )
+ {
+ if ( pD2C1->iVar != pD2C2->iVar )
+ return 0;
+ pD1C1 = pD1C1->pHNext;
+ pD1C2 = pD1C2->pHNext;
+ pD2C1 = pD2C1->pHNext;
+ pD2C2 = pD2C2->pHNext;
+ }
+ else
+ {
+ if ( pD2C1->iVar == pD2C2->iVar )
+ return 0;
+ if ( pD1C1->iVar < pD1C2->iVar )
+ {
+ if ( pD2C1->iVar > pD2C2->iVar )
+ return 0;
+ pD1C1 = pD1C1->pHNext;
+ pD2C1 = pD2C1->pHNext;
+ }
+ else
+ {
+ if ( pD2C1->iVar < pD2C2->iVar )
+ return 0;
+ pD1C2 = pD1C2->pHNext;
+ pD2C2 = pD2C2->pHNext;
+ }
+ }
+ }
+ else if ( TopVar1 < TopVar2 )
+ {
+ if ( pD1C1->iVar != pD1C2->iVar )
+ return 0;
+ pD1C1 = pD1C1->pHNext;
+ pD1C2 = pD1C2->pHNext;
+ }
+ else
+ {
+ if ( pD2C1->iVar != pD2C2->iVar )
+ return 0;
+ pD2C1 = pD2C1->pHNext;
+ pD2C2 = pD2C2->pHNext;
+ }
+ break;
+ default:
+ assert( 0 );
+ break;
+ }
+
+ Code = pD1C1? 8: 0;
+ Code |= pD1C2? 4: 0;
+ Code |= pD2C1? 2: 0;
+ Code |= pD2C2? 1: 0;
+ }
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Allocates the storage for cubes pairs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_PairAllocStorage( Fxu_Var * pVar, int nCubes )
+{
+ int k;
+// assert( pVar->nCubes == 0 );
+ pVar->nCubes = nCubes;
+ // allocate memory for all the pairs
+ pVar->ppPairs = ALLOC( Fxu_Pair **, nCubes );
+ pVar->ppPairs[0] = ALLOC( Fxu_Pair *, nCubes * nCubes );
+ memset( pVar->ppPairs[0], 0, sizeof(Fxu_Pair *) * nCubes * nCubes );
+ for ( k = 1; k < nCubes; k++ )
+ pVar->ppPairs[k] = pVar->ppPairs[k-1] + nCubes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Clears all pairs associated with this cube.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_PairClearStorage( Fxu_Cube * pCube )
+{
+ Fxu_Var * pVar;
+ int i;
+ pVar = pCube->pVar;
+ for ( i = 0; i < pVar->nCubes; i++ )
+ {
+ pVar->ppPairs[pCube->iCube][i] = NULL;
+ pVar->ppPairs[i][pCube->iCube] = NULL;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Clears all pairs associated with this cube.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_PairFreeStorage( Fxu_Var * pVar )
+{
+ if ( pVar->ppPairs )
+ {
+ FREE( pVar->ppPairs[0] );
+ FREE( pVar->ppPairs );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds the pair to storage.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Fxu_Pair * Fxu_PairAlloc( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2 )
+{
+ Fxu_Pair * pPair;
+ assert( pCube1->pVar == pCube2->pVar );
+ pPair = MEM_ALLOC_FXU( p, Fxu_Pair, 1 );
+ memset( pPair, 0, sizeof(Fxu_Pair) );
+ pPair->pCube1 = pCube1;
+ pPair->pCube2 = pCube2;
+ pPair->iCube1 = pCube1->iCube;
+ pPair->iCube2 = pCube2->iCube;
+ return pPair;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds the pair to storage.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_PairAdd( Fxu_Pair * pPair )
+{
+ Fxu_Var * pVar;
+
+ pVar = pPair->pCube1->pVar;
+ assert( pVar == pPair->pCube2->pVar );
+
+ pVar->ppPairs[pPair->iCube1][pPair->iCube2] = pPair;
+ pVar->ppPairs[pPair->iCube2][pPair->iCube1] = pPair;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/opt/fxu/fxuPrint.c b/src/opt/fxu/fxuPrint.c
new file mode 100644
index 00000000..2d25c0e9
--- /dev/null
+++ b/src/opt/fxu/fxuPrint.c
@@ -0,0 +1,195 @@
+/**CFile****************************************************************
+
+ FileName [fxuPrint.c]
+
+ PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
+
+ Synopsis [Various printing procedures.]
+
+ Author [MVSIS Group]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - February 1, 2003.]
+
+ Revision [$Id: fxuPrint.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "fxuInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_MatrixPrint( FILE * pFile, Fxu_Matrix * p )
+{
+ Fxu_Var * pVar;
+ Fxu_Cube * pCube;
+ Fxu_Double * pDiv;
+ Fxu_Single * pSingle;
+ Fxu_Lit * pLit;
+ Fxu_Pair * pPair;
+ int i, LastNum;
+ int fStdout;
+
+ fStdout = 1;
+ if ( pFile == NULL )
+ {
+ pFile = fopen( "matrix.txt", "w" );
+ fStdout = 0;
+ }
+
+ fprintf( pFile, "Matrix has %d vars, %d cubes, %d literals, %d divisors.\n",
+ p->lVars.nItems, p->lCubes.nItems, p->nEntries, p->nDivs );
+ fprintf( pFile, "Divisors selected so far: single = %d, double = %d.\n",
+ p->nDivs1, p->nDivs2 );
+ fprintf( pFile, "\n" );
+
+ // print the numbers on top of the matrix
+ for ( i = 0; i < 12; i++ )
+ fprintf( pFile, " " );
+ Fxu_MatrixForEachVariable( p, pVar )
+ fprintf( pFile, "%d", pVar->iVar % 10 );
+ fprintf( pFile, "\n" );
+
+ // print the rows
+ Fxu_MatrixForEachCube( p, pCube )
+ {
+ fprintf( pFile, "%4d", pCube->iCube );
+ fprintf( pFile, " " );
+ fprintf( pFile, "%4d", pCube->pVar->iVar );
+ fprintf( pFile, " " );
+
+ // print the literals
+ LastNum = -1;
+ Fxu_CubeForEachLiteral( pCube, pLit )
+ {
+ for ( i = LastNum + 1; i < pLit->pVar->iVar; i++ )
+ fprintf( pFile, "." );
+ fprintf( pFile, "1" );
+ LastNum = i;
+ }
+ for ( i = LastNum + 1; i < p->lVars.nItems; i++ )
+ fprintf( pFile, "." );
+ fprintf( pFile, "\n" );
+ }
+ fprintf( pFile, "\n" );
+
+ // print the double-cube divisors
+ fprintf( pFile, "The double divisors are:\n" );
+ Fxu_MatrixForEachDouble( p, pDiv, i )
+ {
+ fprintf( pFile, "Divisor #%3d (lit=%d,%d) (w=%2d): ",
+ pDiv->Num, pDiv->lPairs.pHead->nLits1,
+ pDiv->lPairs.pHead->nLits2, pDiv->Weight );
+ Fxu_DoubleForEachPair( pDiv, pPair )
+ fprintf( pFile, " <%d, %d> (b=%d)",
+ pPair->pCube1->iCube, pPair->pCube2->iCube, pPair->nBase );
+ fprintf( pFile, "\n" );
+ }
+ fprintf( pFile, "\n" );
+
+ // print the divisors associated with each cube
+ fprintf( pFile, "The cubes are:\n" );
+ Fxu_MatrixForEachCube( p, pCube )
+ {
+ fprintf( pFile, "Cube #%3d: ", pCube->iCube );
+ if ( pCube->pVar->ppPairs )
+ Fxu_CubeForEachPair( pCube, pPair, i )
+ fprintf( pFile, " <%d %d> (d=%d) (b=%d)",
+ pPair->iCube1, pPair->iCube2, pPair->pDiv->Num, pPair->nBase );
+ fprintf( pFile, "\n" );
+ }
+ fprintf( pFile, "\n" );
+
+ // print the single-cube divisors
+ fprintf( pFile, "The single divisors are:\n" );
+ Fxu_MatrixForEachSingle( p, pSingle )
+ {
+ fprintf( pFile, "Single-cube divisor #%5d: Var1 = %4d. Var2 = %4d. Weight = %2d\n",
+ pSingle->Num, pSingle->pVar1->iVar, pSingle->pVar2->iVar, pSingle->Weight );
+ }
+ fprintf( pFile, "\n" );
+
+/*
+ {
+ int Index;
+ fprintf( pFile, "Distribution of divisors in the hash table:\n" );
+ for ( Index = 0; Index < p->nTableSize; Index++ )
+ fprintf( pFile, " %d", p->pTable[Index].nItems );
+ fprintf( pFile, "\n" );
+ }
+*/
+ if ( !fStdout )
+ fclose( pFile );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_MatrixPrintDivisorProfile( FILE * pFile, Fxu_Matrix * p )
+{
+ Fxu_Double * pDiv;
+ int WeightMax;
+ int * pProfile;
+ int Counter1; // the number of -1 weight
+ int CounterL; // the number of less than -1 weight
+ int i;
+
+ WeightMax = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble );
+ pProfile = ALLOC( int, (WeightMax + 1) );
+ memset( pProfile, 0, sizeof(int) * (WeightMax + 1) );
+
+ Counter1 = 0;
+ CounterL = 0;
+ Fxu_MatrixForEachDouble( p, pDiv, i )
+ {
+ assert( pDiv->Weight <= WeightMax );
+ if ( pDiv->Weight == -1 )
+ Counter1++;
+ else if ( pDiv->Weight < 0 )
+ CounterL++;
+ else
+ pProfile[ pDiv->Weight ]++;
+ }
+
+ fprintf( pFile, "The double divisors profile:\n" );
+ fprintf( pFile, "Weight < -1 divisors = %6d\n", CounterL );
+ fprintf( pFile, "Weight -1 divisors = %6d\n", Counter1 );
+ for ( i = 0; i <= WeightMax; i++ )
+ if ( pProfile[i] )
+ fprintf( pFile, "Weight %3d divisors = %6d\n", i, pProfile[i] );
+ fprintf( pFile, "End of divisor profile printout\n" );
+ FREE( pProfile );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/opt/fxu/fxuReduce.c b/src/opt/fxu/fxuReduce.c
new file mode 100644
index 00000000..652d807b
--- /dev/null
+++ b/src/opt/fxu/fxuReduce.c
@@ -0,0 +1,194 @@
+/**CFile****************************************************************
+
+ FileName [fxuReduce.c]
+
+ PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
+
+ Synopsis [Procedures to reduce the number of considered cube pairs.]
+
+ Author [MVSIS Group]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - February 1, 2003.]
+
+ Revision [$Id: fxuReduce.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "fxuInt.h"
+#include "fxu.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static int Fxu_CountPairDiffs( char * pCover, unsigned char pDiffs[] );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Precomputes the pairs to use for creating two-cube divisors.]
+
+ Description [This procedure takes the matrix with variables and cubes
+ allocated (p), the original covers of the nodes (i-sets) and their number
+ (ppCovers,nCovers). The maximum number of pairs to compute and the total
+ number of pairs in existence. This procedure adds to the storage of
+ divisors exactly the given number of pairs (nPairsMax) while taking
+ first those pairs that have the smallest number of literals in their
+ cube-free form.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Fxu_PreprocessCubePairs( Fxu_Matrix * p, Vec_Ptr_t * vCovers, int nPairsTotal, int nPairsMax )
+{
+ unsigned char * pnLitsDiff; // storage for the counters of diff literals
+ int * pnPairCounters; // the counters of pairs for each number of diff literals
+ Fxu_Cube * pCubeFirst, * pCubeLast;
+ Fxu_Cube * pCube1, * pCube2;
+ Fxu_Var * pVar;
+ int nCubes, nBitsMax, nSum;
+ int CutOffNum, CutOffQuant;
+ int iPair, iQuant, k, c;
+ int clk = clock();
+ char * pSopCover;
+ int nFanins;
+
+ assert( nPairsMax < nPairsTotal );
+
+ // allocate storage for counter of diffs
+ pnLitsDiff = ALLOC( unsigned char, nPairsTotal );
+ // go through the covers and precompute the distances between the pairs
+ iPair = 0;
+ nBitsMax = -1;
+ for ( c = 0; c < vCovers->nSize; c++ )
+ if ( pSopCover = vCovers->pArray[c] )
+ {
+ nFanins = Abc_SopGetVarNum(pSopCover);
+ // precompute the differences
+ Fxu_CountPairDiffs( pSopCover, pnLitsDiff + iPair );
+ // update the counter
+ nCubes = Abc_SopGetCubeNum( pSopCover );
+ iPair += nCubes * (nCubes - 1) / 2;
+ if ( nBitsMax < nFanins )
+ nBitsMax = nFanins;
+ }
+ assert( iPair == nPairsTotal );
+
+ // allocate storage for counters of cube pairs by difference
+ pnPairCounters = ALLOC( int, 2 * nBitsMax );
+ memset( pnPairCounters, 0, sizeof(int) * 2 * nBitsMax );
+ // count the number of different pairs
+ for ( k = 0; k < nPairsTotal; k++ )
+ pnPairCounters[ pnLitsDiff[k] ]++;
+ // determine what pairs to take starting from the lower
+ // so that there would be exactly pPairsMax pairs
+ assert( pnPairCounters[0] == 0 ); // otherwise, covers are not dup-free
+ assert( pnPairCounters[1] == 0 ); // otherwise, covers are not SCC-free
+ nSum = 0;
+ for ( k = 0; k < 2 * nBitsMax; k++ )
+ {
+ nSum += pnPairCounters[k];
+ if ( nSum >= nPairsMax )
+ {
+ CutOffNum = k;
+ CutOffQuant = pnPairCounters[k] - (nSum - nPairsMax);
+ break;
+ }
+ }
+ FREE( pnPairCounters );
+
+ // set to 0 all the pairs above the cut-off number and quantity
+ iQuant = 0;
+ iPair = 0;
+ for ( k = 0; k < nPairsTotal; k++ )
+ if ( pnLitsDiff[k] > CutOffNum )
+ pnLitsDiff[k] = 0;
+ else if ( pnLitsDiff[k] == CutOffNum )
+ {
+ if ( iQuant++ >= CutOffQuant )
+ pnLitsDiff[k] = 0;
+ else
+ iPair++;
+ }
+ else
+ iPair++;
+ assert( iPair == nPairsMax );
+
+ // collect the corresponding pairs and add the divisors
+ iPair = 0;
+ for ( c = 0; c < vCovers->nSize; c++ )
+ if ( pSopCover = vCovers->pArray[c] )
+ {
+ // get the var
+ pVar = p->ppVars[2*c+1];
+ // get the first cube
+ pCubeFirst = pVar->pFirst;
+ // get the last cube
+ pCubeLast = pCubeFirst;
+ for ( k = 0; k < pVar->nCubes; k++ )
+ pCubeLast = pCubeLast->pNext;
+ assert( pCubeLast == NULL || pCubeLast->pVar != pVar );
+
+ // go through the cube pairs
+ for ( pCube1 = pCubeFirst; pCube1 != pCubeLast; pCube1 = pCube1->pNext )
+ for ( pCube2 = pCube1->pNext; pCube2 != pCubeLast; pCube2 = pCube2->pNext )
+ if ( pnLitsDiff[iPair++] )
+ { // create the divisors for this pair
+ Fxu_MatrixAddDivisor( p, pCube1, pCube2 );
+ }
+ }
+ assert( iPair == nPairsTotal );
+ FREE( pnLitsDiff );
+//PRT( "Preprocess", clock() - clk );
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Counts the differences in each cube pair in the cover.]
+
+ Description [Takes the cover (pCover) and the array where the
+ diff counters go (pDiffs). The array pDiffs should have as many
+ entries as there are different pairs of cubes in the cover: n(n-1)/2.
+ Fills out the array pDiffs with the following info: For each cube
+ pair, included in the array is the number of literals in both cubes
+ after they are made cube free.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Fxu_CountPairDiffs( char * pCover, unsigned char pDiffs[] )
+{
+ char * pCube1, * pCube2;
+ int nOnes, nCubePairs, nFanins, v;
+ nCubePairs = 0;
+ nFanins = Abc_SopGetVarNum(pCover);
+ Abc_SopForEachCube( pCover, nFanins, pCube1 )
+ Abc_SopForEachCube( pCube1, nFanins, pCube2 )
+ {
+ if ( pCube1 == pCube2 )
+ continue;
+ nOnes = 0;
+ for ( v = 0; v < nFanins; v++ )
+ nOnes += (pCube1[v] != pCube2[v]);
+ pDiffs[nCubePairs++] = nOnes;
+ }
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/opt/fxu/fxuSelect.c b/src/opt/fxu/fxuSelect.c
new file mode 100644
index 00000000..b56407a9
--- /dev/null
+++ b/src/opt/fxu/fxuSelect.c
@@ -0,0 +1,603 @@
+/**CFile****************************************************************
+
+ FileName [fxuSelect.c]
+
+ PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
+
+ Synopsis [Procedures to select the best divisor/complement pair.]
+
+ Author [MVSIS Group]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - February 1, 2003.]
+
+ Revision [$Id: fxuSelect.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "fxuInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define MAX_SIZE_LOOKAHEAD 20
+
+static int Fxu_MatrixFindComplement( Fxu_Matrix * p, int iVar );
+
+static Fxu_Double * Fxu_MatrixFindComplementSingle( Fxu_Matrix * p, Fxu_Single * pSingle );
+static Fxu_Single * Fxu_MatrixFindComplementDouble2( Fxu_Matrix * p, Fxu_Double * pDouble );
+static Fxu_Double * Fxu_MatrixFindComplementDouble4( Fxu_Matrix * p, Fxu_Double * pDouble );
+
+Fxu_Double * Fxu_MatrixFindDouble( Fxu_Matrix * p,
+ int piVarsC1[], int piVarsC2[], int nVarsC1, int nVarsC2 );
+void Fxu_MatrixGetDoubleVars( Fxu_Matrix * p, Fxu_Double * pDouble,
+ int piVarsC1[], int piVarsC2[], int * pnVarsC1, int * pnVarsC2 );
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Selects the best pair (Single,Double) and returns their weight.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Fxu_Select( Fxu_Matrix * p, Fxu_Single ** ppSingle, Fxu_Double ** ppDouble )
+{
+ // the top entries
+ Fxu_Single * pSingles[MAX_SIZE_LOOKAHEAD];
+ Fxu_Double * pDoubles[MAX_SIZE_LOOKAHEAD];
+ // the complements
+ Fxu_Double * pSCompl[MAX_SIZE_LOOKAHEAD];
+ Fxu_Single * pDComplS[MAX_SIZE_LOOKAHEAD];
+ Fxu_Double * pDComplD[MAX_SIZE_LOOKAHEAD];
+ Fxu_Pair * pPair;
+ int nSingles;
+ int nDoubles;
+ int i;
+ int WeightBest;
+ int WeightCur;
+ int iNum, fBestS;
+
+ // collect the top entries from the queues
+ for ( nSingles = 0; nSingles < MAX_SIZE_LOOKAHEAD; nSingles++ )
+ {
+ pSingles[nSingles] = Fxu_HeapSingleGetMax( p->pHeapSingle );
+ if ( pSingles[nSingles] == NULL )
+ break;
+ }
+ // put them back into the queue
+ for ( i = 0; i < nSingles; i++ )
+ if ( pSingles[i] )
+ Fxu_HeapSingleInsert( p->pHeapSingle, pSingles[i] );
+
+ // the same for doubles
+ // collect the top entries from the queues
+ for ( nDoubles = 0; nDoubles < MAX_SIZE_LOOKAHEAD; nDoubles++ )
+ {
+ pDoubles[nDoubles] = Fxu_HeapDoubleGetMax( p->pHeapDouble );
+ if ( pDoubles[nDoubles] == NULL )
+ break;
+ }
+ // put them back into the queue
+ for ( i = 0; i < nDoubles; i++ )
+ if ( pDoubles[i] )
+ Fxu_HeapDoubleInsert( p->pHeapDouble, pDoubles[i] );
+
+ // for each single, find the complement double (if any)
+ for ( i = 0; i < nSingles; i++ )
+ if ( pSingles[i] )
+ pSCompl[i] = Fxu_MatrixFindComplementSingle( p, pSingles[i] );
+
+ // for each double, find the complement single or double (if any)
+ for ( i = 0; i < nDoubles; i++ )
+ if ( pDoubles[i] )
+ {
+ pPair = pDoubles[i]->lPairs.pHead;
+ if ( pPair->nLits1 == 1 && pPair->nLits2 == 1 )
+ {
+ pDComplS[i] = Fxu_MatrixFindComplementDouble2( p, pDoubles[i] );
+ pDComplD[i] = NULL;
+ }
+// else if ( pPair->nLits1 == 2 && pPair->nLits2 == 2 )
+// {
+// pDComplS[i] = NULL;
+// pDComplD[i] = Fxu_MatrixFindComplementDouble4( p, pDoubles[i] );
+// }
+ else
+ {
+ pDComplS[i] = NULL;
+ pDComplD[i] = NULL;
+ }
+ }
+
+ // select the best pair
+ WeightBest = -1;
+ for ( i = 0; i < nSingles; i++ )
+ {
+ WeightCur = pSingles[i]->Weight;
+ if ( pSCompl[i] )
+ {
+ // add the weight of the double
+ WeightCur += pSCompl[i]->Weight;
+ // there is no need to implement this double, so...
+ pPair = pSCompl[i]->lPairs.pHead;
+ WeightCur += pPair->nLits1 + pPair->nLits2;
+ }
+ if ( WeightBest < WeightCur )
+ {
+ WeightBest = WeightCur;
+ *ppSingle = pSingles[i];
+ *ppDouble = pSCompl[i];
+ fBestS = 1;
+ iNum = i;
+ }
+ }
+ for ( i = 0; i < nDoubles; i++ )
+ {
+ WeightCur = pDoubles[i]->Weight;
+ if ( pDComplS[i] )
+ {
+ // add the weight of the single
+ WeightCur += pDComplS[i]->Weight;
+ // there is no need to implement this double, so...
+ pPair = pDoubles[i]->lPairs.pHead;
+ WeightCur += pPair->nLits1 + pPair->nLits2;
+ }
+ if ( WeightBest < WeightCur )
+ {
+ WeightBest = WeightCur;
+ *ppSingle = pDComplS[i];
+ *ppDouble = pDoubles[i];
+ fBestS = 0;
+ iNum = i;
+ }
+ }
+/*
+ // print the statistics
+ printf( "\n" );
+ for ( i = 0; i < nSingles; i++ )
+ {
+ printf( "Single #%d: Weight = %3d. ", i, pSingles[i]->Weight );
+ printf( "Compl: " );
+ if ( pSCompl[i] == NULL )
+ printf( "None." );
+ else
+ printf( "D Weight = %3d Sum = %3d",
+ pSCompl[i]->Weight, pSCompl[i]->Weight + pSingles[i]->Weight );
+ printf( "\n" );
+ }
+ printf( "\n" );
+ for ( i = 0; i < nDoubles; i++ )
+ {
+ printf( "Double #%d: Weight = %3d. ", i, pDoubles[i]->Weight );
+ printf( "Compl: " );
+ if ( pDComplS[i] == NULL && pDComplD[i] == NULL )
+ printf( "None." );
+ else if ( pDComplS[i] )
+ printf( "S Weight = %3d Sum = %3d",
+ pDComplS[i]->Weight, pDComplS[i]->Weight + pDoubles[i]->Weight );
+ else if ( pDComplD[i] )
+ printf( "D Weight = %3d Sum = %3d",
+ pDComplD[i]->Weight, pDComplD[i]->Weight + pDoubles[i]->Weight );
+ printf( "\n" );
+ }
+ if ( WeightBest == -1 )
+ printf( "Selected NONE\n" );
+ else
+ {
+ printf( "Selected = %s. ", fBestS? "S": "D" );
+ printf( "Number = %d. ", iNum );
+ printf( "Weight = %d.\n", WeightBest );
+ }
+ printf( "\n" );
+*/
+ return WeightBest;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Fxu_Double * Fxu_MatrixFindComplementSingle( Fxu_Matrix * p, Fxu_Single * pSingle )
+{
+// int * pValue2Node = p->pValue2Node;
+ int iVar1, iVar2;
+ int iVar1C, iVar2C;
+ // get the variables of this single div
+ iVar1 = pSingle->pVar1->iVar;
+ iVar2 = pSingle->pVar2->iVar;
+ iVar1C = Fxu_MatrixFindComplement( p, iVar1 );
+ iVar2C = Fxu_MatrixFindComplement( p, iVar2 );
+ if ( iVar1C == -1 || iVar2C == -1 )
+ return NULL;
+ assert( iVar1C < iVar2C );
+ return Fxu_MatrixFindDouble( p, &iVar1C, &iVar2C, 1, 1 );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Fxu_Single * Fxu_MatrixFindComplementDouble2( Fxu_Matrix * p, Fxu_Double * pDouble )
+{
+// int * pValue2Node = p->pValue2Node;
+ int piVarsC1[10], piVarsC2[10];
+ int nVarsC1, nVarsC2;
+ int iVar1, iVar2, iVarTemp;
+ int iVar1C, iVar2C;
+ Fxu_Single * pSingle;
+
+ // get the variables of this double div
+ Fxu_MatrixGetDoubleVars( p, pDouble, piVarsC1, piVarsC2, &nVarsC1, &nVarsC2 );
+ assert( nVarsC1 == 1 );
+ assert( nVarsC2 == 1 );
+ iVar1 = piVarsC1[0];
+ iVar2 = piVarsC2[0];
+ assert( iVar1 < iVar2 );
+
+ iVar1C = Fxu_MatrixFindComplement( p, iVar1 );
+ iVar2C = Fxu_MatrixFindComplement( p, iVar2 );
+ if ( iVar1C == -1 || iVar2C == -1 )
+ return NULL;
+
+ // go through the queque and find this one
+// assert( iVar1C < iVar2C );
+ if ( iVar1C > iVar2C )
+ {
+ iVarTemp = iVar1C;
+ iVar1C = iVar2C;
+ iVar2C = iVarTemp;
+ }
+
+ Fxu_MatrixForEachSingle( p, pSingle )
+ if ( pSingle->pVar1->iVar == iVar1C && pSingle->pVar2->iVar == iVar2C )
+ return pSingle;
+ return NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Fxu_Double * Fxu_MatrixFindComplementDouble4( Fxu_Matrix * p, Fxu_Double * pDouble )
+{
+// int * pValue2Node = p->pValue2Node;
+ int piVarsC1[10], piVarsC2[10];
+ int nVarsC1, nVarsC2;
+ int iVar11, iVar12, iVar21, iVar22;
+ int iVar11C, iVar12C, iVar21C, iVar22C;
+ int RetValue;
+
+ // get the variables of this double div
+ Fxu_MatrixGetDoubleVars( p, pDouble, piVarsC1, piVarsC2, &nVarsC1, &nVarsC2 );
+ assert( nVarsC1 == 2 && nVarsC2 == 2 );
+
+ iVar11 = piVarsC1[0];
+ iVar12 = piVarsC1[1];
+ iVar21 = piVarsC2[0];
+ iVar22 = piVarsC2[1];
+ assert( iVar11 < iVar21 );
+
+ iVar11C = Fxu_MatrixFindComplement( p, iVar11 );
+ iVar12C = Fxu_MatrixFindComplement( p, iVar12 );
+ iVar21C = Fxu_MatrixFindComplement( p, iVar21 );
+ iVar22C = Fxu_MatrixFindComplement( p, iVar22 );
+ if ( iVar11C == -1 || iVar12C == -1 || iVar21C == -1 || iVar22C == -1 )
+ return NULL;
+ if ( iVar11C != iVar21 || iVar12C != iVar22 ||
+ iVar21C != iVar11 || iVar22C != iVar12 )
+ return NULL;
+
+ // a'b' + ab => a'b + ab'
+ // a'b + ab' => a'b' + ab
+ // swap the second pair in each cube
+ RetValue = piVarsC1[1];
+ piVarsC1[1] = piVarsC2[1];
+ piVarsC2[1] = RetValue;
+
+ return Fxu_MatrixFindDouble( p, piVarsC1, piVarsC2, 2, 2 );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Fxu_MatrixFindComplement( Fxu_Matrix * p, int iVar )
+{
+ return iVar ^ 1;
+/*
+// int * pValue2Node = p->pValue2Node;
+ int iVarC;
+ int iNode;
+ int Beg, End;
+
+ // get the nodes
+ iNode = pValue2Node[iVar];
+ // get the first node with the same var
+ for ( Beg = iVar; Beg >= 0; Beg-- )
+ if ( pValue2Node[Beg] != iNode )
+ {
+ Beg++;
+ break;
+ }
+ // get the last node with the same var
+ for ( End = iVar; ; End++ )
+ if ( pValue2Node[End] != iNode )
+ {
+ End--;
+ break;
+ }
+
+ // if one of the vars is not binary, quit
+ if ( End - Beg > 1 )
+ return -1;
+
+ // get the complements
+ if ( iVar == Beg )
+ iVarC = End;
+ else if ( iVar == End )
+ iVarC = Beg;
+ else
+ {
+ assert( 0 );
+ }
+ return iVarC;
+*/
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_MatrixGetDoubleVars( Fxu_Matrix * p, Fxu_Double * pDouble,
+ int piVarsC1[], int piVarsC2[], int * pnVarsC1, int * pnVarsC2 )
+{
+ Fxu_Pair * pPair;
+ Fxu_Lit * pLit1, * pLit2;
+ int nLits1, nLits2;
+
+ // get the first pair
+ pPair = pDouble->lPairs.pHead;
+ // init the parameters
+ nLits1 = 0;
+ nLits2 = 0;
+ pLit1 = pPair->pCube1->lLits.pHead;
+ pLit2 = pPair->pCube2->lLits.pHead;
+ while ( 1 )
+ {
+ if ( pLit1 && pLit2 )
+ {
+ if ( pLit1->iVar == pLit2->iVar )
+ { // ensure cube-free
+ pLit1 = pLit1->pHNext;
+ pLit2 = pLit2->pHNext;
+ }
+ else if ( pLit1->iVar < pLit2->iVar )
+ {
+ piVarsC1[nLits1++] = pLit1->iVar;
+ pLit1 = pLit1->pHNext;
+ }
+ else
+ {
+ piVarsC2[nLits2++] = pLit2->iVar;
+ pLit2 = pLit2->pHNext;
+ }
+ }
+ else if ( pLit1 && !pLit2 )
+ {
+ piVarsC1[nLits1++] = pLit1->iVar;
+ pLit1 = pLit1->pHNext;
+ }
+ else if ( !pLit1 && pLit2 )
+ {
+ piVarsC2[nLits2++] = pLit2->iVar;
+ pLit2 = pLit2->pHNext;
+ }
+ else
+ break;
+ }
+ *pnVarsC1 = nLits1;
+ *pnVarsC2 = nLits2;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Fxu_Double * Fxu_MatrixFindDouble( Fxu_Matrix * p,
+ int piVarsC1[], int piVarsC2[], int nVarsC1, int nVarsC2 )
+{
+ int piVarsC1_[100], piVarsC2_[100];
+ int nVarsC1_, nVarsC2_, i;
+ Fxu_Double * pDouble;
+ Fxu_Pair * pPair;
+ unsigned Key;
+
+ assert( nVarsC1 > 0 );
+ assert( nVarsC2 > 0 );
+ assert( piVarsC1[0] < piVarsC2[0] );
+
+ // get the hash key
+ Key = Fxu_PairHashKeyArray( p, piVarsC1, piVarsC2, nVarsC1, nVarsC2 );
+
+ // check if the divisor for this pair already exists
+ Key %= p->nTableSize;
+ Fxu_TableForEachDouble( p, Key, pDouble )
+ {
+ pPair = pDouble->lPairs.pHead;
+ if ( pPair->nLits1 != nVarsC1 )
+ continue;
+ if ( pPair->nLits2 != nVarsC2 )
+ continue;
+ // get the cubes of this divisor
+ Fxu_MatrixGetDoubleVars( p, pDouble, piVarsC1_, piVarsC2_, &nVarsC1_, &nVarsC2_ );
+ // compare lits of the first cube
+ for ( i = 0; i < nVarsC1; i++ )
+ if ( piVarsC1[i] != piVarsC1_[i] )
+ break;
+ if ( i != nVarsC1 )
+ continue;
+ // compare lits of the second cube
+ for ( i = 0; i < nVarsC2; i++ )
+ if ( piVarsC2[i] != piVarsC2_[i] )
+ break;
+ if ( i != nVarsC2 )
+ continue;
+ return pDouble;
+ }
+ return NULL;
+}
+
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Fxu_SelectSCD( Fxu_Matrix * p, int WeightLimit, Fxu_Var ** ppVar1, Fxu_Var ** ppVar2 )
+{
+// int * pValue2Node = p->pValue2Node;
+ Fxu_Var * pVar1;
+ Fxu_Var * pVar2, * pVarTemp;
+ Fxu_Lit * pLitV, * pLitH;
+ int Coin;
+ int CounterAll;
+ int CounterTest;
+ int WeightCur;
+ int WeightBest;
+
+ CounterAll = 0;
+ CounterTest = 0;
+
+ WeightBest = -10;
+
+ // iterate through the columns in the matrix
+ Fxu_MatrixForEachVariable( p, pVar1 )
+ {
+ // start collecting the affected vars
+ Fxu_MatrixRingVarsStart( p );
+
+ // go through all the literals of this variable
+ for ( pLitV = pVar1->lLits.pHead; pLitV; pLitV = pLitV->pVNext )
+ {
+ // for this literal, go through all the horizontal literals
+ for ( pLitH = pLitV->pHNext; pLitH; pLitH = pLitH->pHNext )
+ {
+ // get another variable
+ pVar2 = pLitH->pVar;
+ CounterAll++;
+ // skip the var if it is already used
+ if ( pVar2->pOrder )
+ continue;
+ // skip the var if it belongs to the same node
+// if ( pValue2Node[pVar1->iVar] == pValue2Node[pVar2->iVar] )
+// continue;
+ // collect the var
+ Fxu_MatrixRingVarsAdd( p, pVar2 );
+ }
+ }
+ // stop collecting the selected vars
+ Fxu_MatrixRingVarsStop( p );
+
+ // iterate through the selected vars
+ Fxu_MatrixForEachVarInRing( p, pVar2 )
+ {
+ CounterTest++;
+
+ // count the coincidence
+ Coin = Fxu_SingleCountCoincidence( p, pVar1, pVar2 );
+ assert( Coin > 0 );
+
+ // get the new weight
+ WeightCur = Coin - 2;
+
+ // compare the weights
+ if ( WeightBest < WeightCur )
+ {
+ WeightBest = WeightCur;
+ *ppVar1 = pVar1;
+ *ppVar2 = pVar2;
+ }
+ }
+ // unmark the vars
+ Fxu_MatrixForEachVarInRingSafe( p, pVar2, pVarTemp )
+ pVar2->pOrder = NULL;
+ Fxu_MatrixRingVarsReset( p );
+ }
+
+// if ( WeightBest == WeightLimit )
+// return -1;
+ return WeightBest;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/opt/fxu/fxuSingle.c b/src/opt/fxu/fxuSingle.c
new file mode 100644
index 00000000..5af5c341
--- /dev/null
+++ b/src/opt/fxu/fxuSingle.c
@@ -0,0 +1,166 @@
+/**CFile****************************************************************
+
+ FileName [fxuSingle.c]
+
+ PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
+
+ Synopsis [Procedures to compute the set of single-cube divisors.]
+
+ Author [MVSIS Group]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - February 1, 2003.]
+
+ Revision [$Id: fxuSingle.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "fxuInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Computes and adds all single-cube divisors to storage.]
+
+ Description [This procedure should be called once when the matrix is
+ already contructed before the process of logic extraction begins..]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_MatrixComputeSingles( Fxu_Matrix * p )
+{
+ Fxu_Var * pVar;
+ // iterate through the columns in the matrix
+ Fxu_MatrixForEachVariable( p, pVar )
+ Fxu_MatrixComputeSinglesOne( p, pVar );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds the single-cube divisors associated with a new column.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_MatrixComputeSinglesOne( Fxu_Matrix * p, Fxu_Var * pVar )
+{
+// int * pValue2Node = p->pValue2Node;
+ Fxu_Lit * pLitV, * pLitH;
+ Fxu_Var * pVar2;
+ int Coin;
+// int CounterAll;
+// int CounterTest;
+ int WeightCur;
+
+ // start collecting the affected vars
+ Fxu_MatrixRingVarsStart( p );
+ // go through all the literals of this variable
+ for ( pLitV = pVar->lLits.pHead; pLitV; pLitV = pLitV->pVNext )
+ // for this literal, go through all the horizontal literals
+ for ( pLitH = pLitV->pHPrev; pLitH; pLitH = pLitH->pHPrev )
+ {
+ // get another variable
+ pVar2 = pLitH->pVar;
+// CounterAll++;
+ // skip the var if it is already used
+ if ( pVar2->pOrder )
+ continue;
+ // skip the var if it belongs to the same node
+// if ( pValue2Node[pVar->iVar] == pValue2Node[pVar2->iVar] )
+// continue;
+ // collect the var
+ Fxu_MatrixRingVarsAdd( p, pVar2 );
+ }
+ // stop collecting the selected vars
+ Fxu_MatrixRingVarsStop( p );
+
+ // iterate through the selected vars
+ Fxu_MatrixForEachVarInRing( p, pVar2 )
+ {
+// CounterTest++;
+ // count the coincidence
+ Coin = Fxu_SingleCountCoincidence( p, pVar2, pVar );
+ assert( Coin > 0 );
+ // get the new weight
+ WeightCur = Coin - 2;
+ if ( WeightCur >= 0 )
+ Fxu_MatrixAddSingle( p, pVar2, pVar, WeightCur );
+ }
+
+ // unmark the vars
+ Fxu_MatrixRingVarsUnmark( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the coincidence count of two columns.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Fxu_SingleCountCoincidence( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2 )
+{
+ Fxu_Lit * pLit1, * pLit2;
+ int Result;
+
+ // compute the coincidence count
+ Result = 0;
+ pLit1 = pVar1->lLits.pHead;
+ pLit2 = pVar2->lLits.pHead;
+ while ( 1 )
+ {
+ if ( pLit1 && pLit2 )
+ {
+ if ( pLit1->pCube->pVar->iVar == pLit2->pCube->pVar->iVar )
+ { // the variables are the same
+ if ( pLit1->iCube == pLit2->iCube )
+ { // the literals are the same
+ pLit1 = pLit1->pVNext;
+ pLit2 = pLit2->pVNext;
+ // add this literal to the coincidence
+ Result++;
+ }
+ else if ( pLit1->iCube < pLit2->iCube )
+ pLit1 = pLit1->pVNext;
+ else
+ pLit2 = pLit2->pVNext;
+ }
+ else if ( pLit1->pCube->pVar->iVar < pLit2->pCube->pVar->iVar )
+ pLit1 = pLit1->pVNext;
+ else
+ pLit2 = pLit2->pVNext;
+ }
+ else if ( pLit1 && !pLit2 )
+ pLit1 = pLit1->pVNext;
+ else if ( !pLit1 && pLit2 )
+ pLit2 = pLit2->pVNext;
+ else
+ break;
+ }
+ return Result;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/opt/fxu/fxuUpdate.c b/src/opt/fxu/fxuUpdate.c
new file mode 100644
index 00000000..b781e0b1
--- /dev/null
+++ b/src/opt/fxu/fxuUpdate.c
@@ -0,0 +1,802 @@
+/**CFile****************************************************************
+
+ FileName [fxuUpdate.c]
+
+ PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
+
+ Synopsis [Updating the sparse matrix when divisors are accepted.]
+
+ Author [MVSIS Group]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - February 1, 2003.]
+
+ Revision [$Id: fxuUpdate.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "fxuInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static void Fxu_UpdateDoublePairs( Fxu_Matrix * p, Fxu_Double * pDouble, Fxu_Var * pVar );
+static void Fxu_UpdateMatrixDoubleCreateCubes( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2, Fxu_Double * pDiv );
+static void Fxu_UpdateMatrixDoubleClean( Fxu_Matrix * p, Fxu_Cube * pCubeUse, Fxu_Cube * pCubeRem );
+static void Fxu_UpdateMatrixSingleClean( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2, Fxu_Var * pVarNew );
+
+static void Fxu_UpdateCreateNewVars( Fxu_Matrix * p, Fxu_Var ** ppVarC, Fxu_Var ** ppVarD, int nCubes );
+static int Fxu_UpdatePairCompare( Fxu_Pair ** ppP1, Fxu_Pair ** ppP2 );
+static void Fxu_UpdatePairsSort( Fxu_Matrix * p, Fxu_Double * pDouble );
+
+static void Fxu_UpdateCleanOldDoubles( Fxu_Matrix * p, Fxu_Double * pDiv, Fxu_Cube * pCube );
+static void Fxu_UpdateAddNewDoubles( Fxu_Matrix * p, Fxu_Cube * pCube );
+static void Fxu_UpdateCleanOldSingles( Fxu_Matrix * p );
+static void Fxu_UpdateAddNewSingles( Fxu_Matrix * p, Fxu_Var * pVar );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Updates the matrix after selecting two divisors.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_Update( Fxu_Matrix * p, Fxu_Single * pSingle, Fxu_Double * pDouble )
+{
+ Fxu_Cube * pCube, * pCubeNew;
+ Fxu_Var * pVarC, * pVarD;
+ Fxu_Var * pVar1, * pVar2;
+
+ // consider trivial cases
+ if ( pSingle == NULL )
+ {
+ assert( pDouble->Weight == Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble ) );
+ Fxu_UpdateDouble( p );
+ return;
+ }
+ if ( pDouble == NULL )
+ {
+ assert( pSingle->Weight == Fxu_HeapSingleReadMaxWeight( p->pHeapSingle ) );
+ Fxu_UpdateSingle( p );
+ return;
+ }
+
+ // get the variables of the single
+ pVar1 = pSingle->pVar1;
+ pVar2 = pSingle->pVar2;
+
+ // remove the best double from the heap
+ Fxu_HeapDoubleDelete( p->pHeapDouble, pDouble );
+ // remove the best divisor from the table
+ Fxu_ListTableDelDivisor( p, pDouble );
+
+ // create two new columns (vars)
+ Fxu_UpdateCreateNewVars( p, &pVarC, &pVarD, 1 );
+ // create one new row (cube)
+ pCubeNew = Fxu_MatrixAddCube( p, pVarD, 0 );
+ pCubeNew->pFirst = pCubeNew;
+ // set the first cube of the positive var
+ pVarD->pFirst = pCubeNew;
+
+ // start collecting the affected vars and cubes
+ Fxu_MatrixRingCubesStart( p );
+ Fxu_MatrixRingVarsStart( p );
+ // add the vars
+ Fxu_MatrixRingVarsAdd( p, pVar1 );
+ Fxu_MatrixRingVarsAdd( p, pVar2 );
+ // remove the literals and collect the affected cubes
+ // remove the divisors associated with this cube
+ // add to the affected cube the literal corresponding to the new column
+ Fxu_UpdateMatrixSingleClean( p, pVar1, pVar2, pVarD );
+ // replace each two cubes of the pair by one new cube
+ // the new cube contains the base and the new literal
+ Fxu_UpdateDoublePairs( p, pDouble, pVarC );
+ // stop collecting the affected vars and cubes
+ Fxu_MatrixRingCubesStop( p );
+ Fxu_MatrixRingVarsStop( p );
+
+ // add the literals to the new cube
+ assert( pVar1->iVar < pVar2->iVar );
+ assert( Fxu_SingleCountCoincidence( p, pVar1, pVar2 ) == 0 );
+ Fxu_MatrixAddLiteral( p, pCubeNew, pVar1 );
+ Fxu_MatrixAddLiteral( p, pCubeNew, pVar2 );
+
+ // create new doubles; we cannot add them in the same loop
+ // because we first have to create *all* new cubes for each node
+ Fxu_MatrixForEachCubeInRing( p, pCube )
+ Fxu_UpdateAddNewDoubles( p, pCube );
+ // update the singles after removing some literals
+ Fxu_UpdateCleanOldSingles( p );
+
+ // undo the temporary rings with cubes and vars
+ Fxu_MatrixRingCubesUnmark( p );
+ Fxu_MatrixRingVarsUnmark( p );
+ // we should undo the rings before creating new singles
+
+ // create new singles
+ Fxu_UpdateAddNewSingles( p, pVarC );
+ Fxu_UpdateAddNewSingles( p, pVarD );
+
+ // recycle the divisor
+ MEM_FREE_FXU( p, Fxu_Double, 1, pDouble );
+ p->nDivs3++;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Updates after accepting single cube divisor.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_UpdateSingle( Fxu_Matrix * p )
+{
+ Fxu_Single * pSingle;
+ Fxu_Cube * pCube, * pCubeNew;
+ Fxu_Var * pVarC, * pVarD;
+ Fxu_Var * pVar1, * pVar2;
+
+ // read the best divisor from the heap
+ pSingle = Fxu_HeapSingleReadMax( p->pHeapSingle );
+ // get the variables of this single-cube divisor
+ pVar1 = pSingle->pVar1;
+ pVar2 = pSingle->pVar2;
+
+ // create two new columns (vars)
+ Fxu_UpdateCreateNewVars( p, &pVarC, &pVarD, 1 );
+ // create one new row (cube)
+ pCubeNew = Fxu_MatrixAddCube( p, pVarD, 0 );
+ pCubeNew->pFirst = pCubeNew;
+ // set the first cube
+ pVarD->pFirst = pCubeNew;
+
+ // start collecting the affected vars and cubes
+ Fxu_MatrixRingCubesStart( p );
+ Fxu_MatrixRingVarsStart( p );
+ // add the vars
+ Fxu_MatrixRingVarsAdd( p, pVar1 );
+ Fxu_MatrixRingVarsAdd( p, pVar2 );
+ // remove the literals and collect the affected cubes
+ // remove the divisors associated with this cube
+ // add to the affected cube the literal corresponding to the new column
+ Fxu_UpdateMatrixSingleClean( p, pVar1, pVar2, pVarD );
+ // stop collecting the affected vars and cubes
+ Fxu_MatrixRingCubesStop( p );
+ Fxu_MatrixRingVarsStop( p );
+
+ // add the literals to the new cube
+ assert( pVar1->iVar < pVar2->iVar );
+ assert( Fxu_SingleCountCoincidence( p, pVar1, pVar2 ) == 0 );
+ Fxu_MatrixAddLiteral( p, pCubeNew, pVar1 );
+ Fxu_MatrixAddLiteral( p, pCubeNew, pVar2 );
+
+ // create new doubles; we cannot add them in the same loop
+ // because we first have to create *all* new cubes for each node
+ Fxu_MatrixForEachCubeInRing( p, pCube )
+ Fxu_UpdateAddNewDoubles( p, pCube );
+ // update the singles after removing some literals
+ Fxu_UpdateCleanOldSingles( p );
+ // we should undo the rings before creating new singles
+
+ // unmark the cubes
+ Fxu_MatrixRingCubesUnmark( p );
+ Fxu_MatrixRingVarsUnmark( p );
+
+ // create new singles
+ Fxu_UpdateAddNewSingles( p, pVarC );
+ Fxu_UpdateAddNewSingles( p, pVarD );
+ p->nDivs1++;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Updates the matrix after accepting a double cube divisor.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_UpdateDouble( Fxu_Matrix * p )
+{
+ Fxu_Double * pDiv;
+ Fxu_Cube * pCube, * pCubeNew1, * pCubeNew2;
+ Fxu_Var * pVarC, * pVarD;
+
+ // remove the best divisor from the heap
+ pDiv = Fxu_HeapDoubleGetMax( p->pHeapDouble );
+ // remove the best divisor from the table
+ Fxu_ListTableDelDivisor( p, pDiv );
+
+ // create two new columns (vars)
+ Fxu_UpdateCreateNewVars( p, &pVarC, &pVarD, 2 );
+ // create two new rows (cubes)
+ pCubeNew1 = Fxu_MatrixAddCube( p, pVarD, 0 );
+ pCubeNew1->pFirst = pCubeNew1;
+ pCubeNew2 = Fxu_MatrixAddCube( p, pVarD, 1 );
+ pCubeNew2->pFirst = pCubeNew1;
+ // set the first cube
+ pVarD->pFirst = pCubeNew1;
+
+ // add the literals to the new cubes
+ Fxu_UpdateMatrixDoubleCreateCubes( p, pCubeNew1, pCubeNew2, pDiv );
+
+ // start collecting the affected cubes and vars
+ Fxu_MatrixRingCubesStart( p );
+ Fxu_MatrixRingVarsStart( p );
+ // replace each two cubes of the pair by one new cube
+ // the new cube contains the base and the new literal
+ Fxu_UpdateDoublePairs( p, pDiv, pVarD );
+ // stop collecting the affected cubes and vars
+ Fxu_MatrixRingCubesStop( p );
+ Fxu_MatrixRingVarsStop( p );
+
+ // create new doubles; we cannot add them in the same loop
+ // because we first have to create *all* new cubes for each node
+ Fxu_MatrixForEachCubeInRing( p, pCube )
+ Fxu_UpdateAddNewDoubles( p, pCube );
+ // update the singles after removing some literals
+ Fxu_UpdateCleanOldSingles( p );
+
+ // undo the temporary rings with cubes and vars
+ Fxu_MatrixRingCubesUnmark( p );
+ Fxu_MatrixRingVarsUnmark( p );
+ // we should undo the rings before creating new singles
+
+ // create new singles
+ Fxu_UpdateAddNewSingles( p, pVarC );
+ Fxu_UpdateAddNewSingles( p, pVarD );
+
+ // recycle the divisor
+ MEM_FREE_FXU( p, Fxu_Double, 1, pDiv );
+ p->nDivs2++;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Update the pairs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_UpdateDoublePairs( Fxu_Matrix * p, Fxu_Double * pDouble, Fxu_Var * pVar )
+{
+ Fxu_Pair * pPair;
+ Fxu_Cube * pCubeUse, * pCubeRem;
+ int i;
+
+ // collect and sort the pairs
+ Fxu_UpdatePairsSort( p, pDouble );
+ for ( i = 0; i < p->nPairsTemp; i++ )
+ {
+ // get the pair
+ pPair = p->pPairsTemp[i];
+ // out of the two cubes, select the one which comes earlier
+ pCubeUse = Fxu_PairMinCube( pPair );
+ pCubeRem = Fxu_PairMaxCube( pPair );
+ // collect the affected cube
+ assert( pCubeUse->pOrder == NULL );
+ Fxu_MatrixRingCubesAdd( p, pCubeUse );
+
+ // remove some literals from pCubeUse and all literals from pCubeRem
+ Fxu_UpdateMatrixDoubleClean( p, pCubeUse, pCubeRem );
+ // add a literal that depends on the new variable
+ Fxu_MatrixAddLiteral( p, pCubeUse, pVar );
+ // check the literal count
+ assert( pCubeUse->lLits.nItems == pPair->nBase + 1 );
+ assert( pCubeRem->lLits.nItems == 0 );
+
+ // update the divisors by removing useless pairs
+ Fxu_UpdateCleanOldDoubles( p, pDouble, pCubeUse );
+ Fxu_UpdateCleanOldDoubles( p, pDouble, pCubeRem );
+ // remove the pair
+ MEM_FREE_FXU( p, Fxu_Pair, 1, pPair );
+ }
+ p->nPairsTemp = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Add two cubes corresponding to the given double-cube divisor.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_UpdateMatrixDoubleCreateCubes( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2, Fxu_Double * pDiv )
+{
+ Fxu_Lit * pLit1, * pLit2;
+ Fxu_Pair * pPair;
+ int nBase, nLits1, nLits2;
+
+ // fill in the SOP and copy the fanins
+ nBase = nLits1 = nLits2 = 0;
+ pPair = pDiv->lPairs.pHead;
+ pLit1 = pPair->pCube1->lLits.pHead;
+ pLit2 = pPair->pCube2->lLits.pHead;
+ while ( 1 )
+ {
+ if ( pLit1 && pLit2 )
+ {
+ if ( pLit1->iVar == pLit2->iVar )
+ { // skip the cube free part
+ pLit1 = pLit1->pHNext;
+ pLit2 = pLit2->pHNext;
+ nBase++;
+ }
+ else if ( pLit1->iVar < pLit2->iVar )
+ { // add literal to the first cube
+ Fxu_MatrixAddLiteral( p, pCube1, pLit1->pVar );
+ // move to the next literal in this cube
+ pLit1 = pLit1->pHNext;
+ nLits1++;
+ }
+ else
+ { // add literal to the second cube
+ Fxu_MatrixAddLiteral( p, pCube2, pLit2->pVar );
+ // move to the next literal in this cube
+ pLit2 = pLit2->pHNext;
+ nLits2++;
+ }
+ }
+ else if ( pLit1 && !pLit2 )
+ { // add literal to the first cube
+ Fxu_MatrixAddLiteral( p, pCube1, pLit1->pVar );
+ // move to the next literal in this cube
+ pLit1 = pLit1->pHNext;
+ nLits1++;
+ }
+ else if ( !pLit1 && pLit2 )
+ { // add literal to the second cube
+ Fxu_MatrixAddLiteral( p, pCube2, pLit2->pVar );
+ // move to the next literal in this cube
+ pLit2 = pLit2->pHNext;
+ nLits2++;
+ }
+ else
+ break;
+ }
+ assert( pPair->nLits1 == nLits1 );
+ assert( pPair->nLits2 == nLits2 );
+ assert( pPair->nBase == nBase );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Create the node equal to double-cube divisor.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_UpdateMatrixDoubleClean( Fxu_Matrix * p, Fxu_Cube * pCubeUse, Fxu_Cube * pCubeRem )
+{
+ Fxu_Lit * pLit1, * bLit1Next;
+ Fxu_Lit * pLit2, * bLit2Next;
+
+ // initialize the starting literals
+ pLit1 = pCubeUse->lLits.pHead;
+ pLit2 = pCubeRem->lLits.pHead;
+ bLit1Next = pLit1? pLit1->pHNext: NULL;
+ bLit2Next = pLit2? pLit2->pHNext: NULL;
+ // go through the pair and remove the literals in the base
+ // from the first cube and all literals from the second cube
+ while ( 1 )
+ {
+ if ( pLit1 && pLit2 )
+ {
+ if ( pLit1->iVar == pLit2->iVar )
+ { // this literal is present in both cubes - it belongs to the base
+ // mark the affected var
+ if ( pLit1->pVar->pOrder == NULL )
+ Fxu_MatrixRingVarsAdd( p, pLit1->pVar );
+ // leave the base in pCubeUse; delete it from pCubeRem
+ Fxu_MatrixDelLiteral( p, pLit2 );
+ // step to the next literals
+ pLit1 = bLit1Next;
+ pLit2 = bLit2Next;
+ bLit1Next = pLit1? pLit1->pHNext: NULL;
+ bLit2Next = pLit2? pLit2->pHNext: NULL;
+ }
+ else if ( pLit1->iVar < pLit2->iVar )
+ { // this literal is present in pCubeUse - remove it
+ // mark the affected var
+ if ( pLit1->pVar->pOrder == NULL )
+ Fxu_MatrixRingVarsAdd( p, pLit1->pVar );
+ // delete this literal
+ Fxu_MatrixDelLiteral( p, pLit1 );
+ // step to the next literals
+ pLit1 = bLit1Next;
+ bLit1Next = pLit1? pLit1->pHNext: NULL;
+ }
+ else
+ { // this literal is present in pCubeRem - remove it
+ // mark the affected var
+ if ( pLit2->pVar->pOrder == NULL )
+ Fxu_MatrixRingVarsAdd( p, pLit2->pVar );
+ // delete this literal
+ Fxu_MatrixDelLiteral( p, pLit2 );
+ // step to the next literals
+ pLit2 = bLit2Next;
+ bLit2Next = pLit2? pLit2->pHNext: NULL;
+ }
+ }
+ else if ( pLit1 && !pLit2 )
+ { // this literal is present in pCubeUse - leave it
+ // mark the affected var
+ if ( pLit1->pVar->pOrder == NULL )
+ Fxu_MatrixRingVarsAdd( p, pLit1->pVar );
+ // delete this literal
+ Fxu_MatrixDelLiteral( p, pLit1 );
+ // step to the next literals
+ pLit1 = bLit1Next;
+ bLit1Next = pLit1? pLit1->pHNext: NULL;
+ }
+ else if ( !pLit1 && pLit2 )
+ { // this literal is present in pCubeRem - remove it
+ // mark the affected var
+ if ( pLit2->pVar->pOrder == NULL )
+ Fxu_MatrixRingVarsAdd( p, pLit2->pVar );
+ // delete this literal
+ Fxu_MatrixDelLiteral( p, pLit2 );
+ // step to the next literals
+ pLit2 = bLit2Next;
+ bLit2Next = pLit2? pLit2->pHNext: NULL;
+ }
+ else
+ break;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Updates the matrix after selecting a single cube divisor.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_UpdateMatrixSingleClean( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2, Fxu_Var * pVarNew )
+{
+ Fxu_Lit * pLit1, * bLit1Next;
+ Fxu_Lit * pLit2, * bLit2Next;
+
+ // initialize the starting literals
+ pLit1 = pVar1->lLits.pHead;
+ pLit2 = pVar2->lLits.pHead;
+ bLit1Next = pLit1? pLit1->pVNext: NULL;
+ bLit2Next = pLit2? pLit2->pVNext: NULL;
+ while ( 1 )
+ {
+ if ( pLit1 && pLit2 )
+ {
+ if ( pLit1->pCube->pVar->iVar == pLit2->pCube->pVar->iVar )
+ { // these literals coincide
+ if ( pLit1->iCube == pLit2->iCube )
+ { // these literals coincide
+
+ // collect the affected cube
+ assert( pLit1->pCube->pOrder == NULL );
+ Fxu_MatrixRingCubesAdd( p, pLit1->pCube );
+
+ // add the literal to this cube corresponding to the new column
+ Fxu_MatrixAddLiteral( p, pLit1->pCube, pVarNew );
+ // clean the old cubes
+ Fxu_UpdateCleanOldDoubles( p, NULL, pLit1->pCube );
+
+ // remove the literals
+ Fxu_MatrixDelLiteral( p, pLit1 );
+ Fxu_MatrixDelLiteral( p, pLit2 );
+
+ // go to the next literals
+ pLit1 = bLit1Next;
+ pLit2 = bLit2Next;
+ bLit1Next = pLit1? pLit1->pVNext: NULL;
+ bLit2Next = pLit2? pLit2->pVNext: NULL;
+ }
+ else if ( pLit1->iCube < pLit2->iCube )
+ {
+ pLit1 = bLit1Next;
+ bLit1Next = pLit1? pLit1->pVNext: NULL;
+ }
+ else
+ {
+ pLit2 = bLit2Next;
+ bLit2Next = pLit2? pLit2->pVNext: NULL;
+ }
+ }
+ else if ( pLit1->pCube->pVar->iVar < pLit2->pCube->pVar->iVar )
+ {
+ pLit1 = bLit1Next;
+ bLit1Next = pLit1? pLit1->pVNext: NULL;
+ }
+ else
+ {
+ pLit2 = bLit2Next;
+ bLit2Next = pLit2? pLit2->pVNext: NULL;
+ }
+ }
+ else if ( pLit1 && !pLit2 )
+ {
+ pLit1 = bLit1Next;
+ bLit1Next = pLit1? pLit1->pVNext: NULL;
+ }
+ else if ( !pLit1 && pLit2 )
+ {
+ pLit2 = bLit2Next;
+ bLit2Next = pLit2? pLit2->pVNext: NULL;
+ }
+ else
+ break;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sort the pairs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_UpdatePairsSort( Fxu_Matrix * p, Fxu_Double * pDouble )
+{
+ Fxu_Pair * pPair;
+ // order the pairs by the first cube to ensure that
+ // new literals are added to the matrix from top to bottom
+ // collect pairs into the array
+ p->nPairsTemp = 0;
+ Fxu_DoubleForEachPair( pDouble, pPair )
+ p->pPairsTemp[ p->nPairsTemp++ ] = pPair;
+ if ( p->nPairsTemp > 1 )
+ { // sort
+ qsort( (void *)p->pPairsTemp, p->nPairsTemp, sizeof(Fxu_Pair *),
+ (int (*)(const void *, const void *)) Fxu_UpdatePairCompare );
+ assert( Fxu_UpdatePairCompare( p->pPairsTemp, p->pPairsTemp + p->nPairsTemp - 1 ) < 0 );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compares the vars by their number.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Fxu_UpdatePairCompare( Fxu_Pair ** ppP1, Fxu_Pair ** ppP2 )
+{
+ Fxu_Cube * pC1 = (*ppP1)->pCube1;
+ Fxu_Cube * pC2 = (*ppP2)->pCube1;
+ int iP1CubeMin, iP2CubeMin;
+ if ( pC1->pVar->iVar < pC2->pVar->iVar )
+ return -1;
+ if ( pC1->pVar->iVar > pC2->pVar->iVar )
+ return 1;
+ iP1CubeMin = Fxu_PairMinCubeInt( *ppP1 );
+ iP2CubeMin = Fxu_PairMinCubeInt( *ppP2 );
+ if ( iP1CubeMin < iP2CubeMin )
+ return -1;
+ if ( iP1CubeMin > iP2CubeMin )
+ return 1;
+ assert( 0 );
+ return 0;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Create new variables.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_UpdateCreateNewVars( Fxu_Matrix * p, Fxu_Var ** ppVarC, Fxu_Var ** ppVarD, int nCubes )
+{
+ Fxu_Var * pVarC, * pVarD;
+
+ // add a new column for the complement
+ pVarC = Fxu_MatrixAddVar( p );
+ pVarC->nCubes = 0;
+ // add a new column for the divisor
+ pVarD = Fxu_MatrixAddVar( p );
+ pVarD->nCubes = nCubes;
+
+ // mark this entry in the Value2Node array
+// assert( p->pValue2Node[pVarC->iVar] > 0 );
+// p->pValue2Node[pVarD->iVar ] = p->pValue2Node[pVarC->iVar];
+// p->pValue2Node[pVarD->iVar+1] = p->pValue2Node[pVarC->iVar]+1;
+
+ *ppVarC = pVarC;
+ *ppVarD = pVarD;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_UpdateCleanOldDoubles( Fxu_Matrix * p, Fxu_Double * pDiv, Fxu_Cube * pCube )
+{
+ Fxu_Double * pDivCur;
+ Fxu_Pair * pPair;
+ int i;
+
+ // if the cube is a recently introduced one
+ // it does not have pairs allocated
+ // in this case, there is nothing to update
+ if ( pCube->pVar->ppPairs == NULL )
+ return;
+
+ // go through all the pairs of this cube
+ Fxu_CubeForEachPair( pCube, pPair, i )
+ {
+ // get the divisor of this pair
+ pDivCur = pPair->pDiv;
+ // skip the current divisor
+ if ( pDivCur == pDiv )
+ continue;
+ // remove this pair
+ Fxu_ListDoubleDelPair( pDivCur, pPair );
+ // the divisor may have become useless by now
+ if ( pDivCur->lPairs.nItems == 0 )
+ {
+ assert( pDivCur->Weight == pPair->nBase - 1 );
+ Fxu_HeapDoubleDelete( p->pHeapDouble, pDivCur );
+ Fxu_MatrixDelDivisor( p, pDivCur );
+ }
+ else
+ {
+ // update the divisor's weight
+ pDivCur->Weight -= pPair->nLits1 + pPair->nLits2 - 1 + pPair->nBase;
+ Fxu_HeapDoubleUpdate( p->pHeapDouble, pDivCur );
+ }
+ MEM_FREE_FXU( p, Fxu_Pair, 1, pPair );
+ }
+ // finally erase all the pair info associated with this cube
+ Fxu_PairClearStorage( pCube );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds the new divisors that depend on the cube.]
+
+ Description [Go through all the non-empty cubes of this cover
+ (except the given cube) and, for each of them, add the new divisor
+ with the given cube.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_UpdateAddNewDoubles( Fxu_Matrix * p, Fxu_Cube * pCube )
+{
+ Fxu_Cube * pTemp;
+ assert( pCube->pOrder );
+
+ // if the cube is a recently introduced one
+ // it does not have pairs allocated
+ // in this case, there is nothing to update
+ if ( pCube->pVar->ppPairs == NULL )
+ return;
+
+ for ( pTemp = pCube->pFirst; pTemp->pVar == pCube->pVar; pTemp = pTemp->pNext )
+ {
+ // do not add pairs with the empty cubes
+ if ( pTemp->lLits.nItems == 0 )
+ continue;
+ // to prevent adding duplicated pairs of the new cubes
+ // do not add the pair, if the current cube is marked
+ if ( pTemp->pOrder && pTemp >= pCube )
+ continue;
+ Fxu_MatrixAddDivisor( p, pTemp, pCube );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Removes old single cube divisors.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_UpdateCleanOldSingles( Fxu_Matrix * p )
+{
+ Fxu_Single * pSingle, * pSingle2;
+ int WeightNew;
+
+ Fxu_MatrixForEachSingleSafe( p, pSingle, pSingle2 )
+ {
+ // if at least one of the variables is marked, recalculate
+ if ( pSingle->pVar1->pOrder || pSingle->pVar2->pOrder )
+ {
+ // get the new weight
+ WeightNew = -2 + Fxu_SingleCountCoincidence( p, pSingle->pVar1, pSingle->pVar2 );
+ if ( WeightNew >= 0 )
+ {
+ pSingle->Weight = WeightNew;
+ Fxu_HeapSingleUpdate( p->pHeapSingle, pSingle );
+ }
+ else
+ {
+ Fxu_HeapSingleDelete( p->pHeapSingle, pSingle );
+ Fxu_ListMatrixDelSingle( p, pSingle );
+ MEM_FREE_FXU( p, Fxu_Single, 1, pSingle );
+ }
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Updates the single cube divisors.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Fxu_UpdateAddNewSingles( Fxu_Matrix * p, Fxu_Var * pVar )
+{
+ Fxu_MatrixComputeSinglesOne( p, pVar );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/opt/fxu/module.make b/src/opt/fxu/module.make
new file mode 100644
index 00000000..331712d1
--- /dev/null
+++ b/src/opt/fxu/module.make
@@ -0,0 +1,12 @@
+SRC += fxu.c \
+ fxuCreate.c \
+ fxuHeapD.c \
+ fxuHeapS.c \
+ fxuList.c \
+ fxuMatrix.c \
+ fxuPair.c \
+ fxuPrint.c \
+ fxuReduce.c \
+ fxuSelect.c \
+ fxuSingle.c \
+ fxuUpdate.c