summaryrefslogtreecommitdiffstats
path: root/src/bdd/extrab/extraBddKmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bdd/extrab/extraBddKmap.c')
-rw-r--r--src/bdd/extrab/extraBddKmap.c876
1 files changed, 876 insertions, 0 deletions
diff --git a/src/bdd/extrab/extraBddKmap.c b/src/bdd/extrab/extraBddKmap.c
new file mode 100644
index 00000000..aa5efe75
--- /dev/null
+++ b/src/bdd/extrab/extraBddKmap.c
@@ -0,0 +1,876 @@
+/**CFile****************************************************************
+
+ FileName [extraBddKmap.c]
+
+ PackageName [extra]
+
+ Synopsis [Visualizing the K-map.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 2.0. Started - September 1, 2003.]
+
+ Revision [$Id: extraBddKmap.c,v 1.0 2003/05/21 18:03:50 alanmi Exp $]
+
+***********************************************************************/
+
+/// K-map visualization using pseudo graphics ///
+/// Version 1.0. Started - August 20, 2000 ///
+/// Version 2.0. Added to EXTRA - July 17, 2001 ///
+
+#include "extraBdd.h"
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+ABC_NAMESPACE_IMPL_START
+
+
+/*---------------------------------------------------------------------------*/
+/* Constant declarations */
+/*---------------------------------------------------------------------------*/
+
+// the maximum number of variables in the Karnaugh Map
+#define MAXVARS 20
+
+/*
+// single line
+#define SINGLE_VERTICAL (char)179
+#define SINGLE_HORIZONTAL (char)196
+#define SINGLE_TOP_LEFT (char)218
+#define SINGLE_TOP_RIGHT (char)191
+#define SINGLE_BOT_LEFT (char)192
+#define SINGLE_BOT_RIGHT (char)217
+
+// double line
+#define DOUBLE_VERTICAL (char)186
+#define DOUBLE_HORIZONTAL (char)205
+#define DOUBLE_TOP_LEFT (char)201
+#define DOUBLE_TOP_RIGHT (char)187
+#define DOUBLE_BOT_LEFT (char)200
+#define DOUBLE_BOT_RIGHT (char)188
+
+// line intersections
+#define SINGLES_CROSS (char)197
+#define DOUBLES_CROSS (char)206
+#define S_HOR_CROSS_D_VER (char)215
+#define S_VER_CROSS_D_HOR (char)216
+
+// single line joining
+#define S_JOINS_S_VER_LEFT (char)180
+#define S_JOINS_S_VER_RIGHT (char)195
+#define S_JOINS_S_HOR_TOP (char)193
+#define S_JOINS_S_HOR_BOT (char)194
+
+// double line joining
+#define D_JOINS_D_VER_LEFT (char)185
+#define D_JOINS_D_VER_RIGHT (char)204
+#define D_JOINS_D_HOR_TOP (char)202
+#define D_JOINS_D_HOR_BOT (char)203
+
+// single line joining double line
+#define S_JOINS_D_VER_LEFT (char)182
+#define S_JOINS_D_VER_RIGHT (char)199
+#define S_JOINS_D_HOR_TOP (char)207
+#define S_JOINS_D_HOR_BOT (char)209
+*/
+
+// single line
+#define SINGLE_VERTICAL (char)'|'
+#define SINGLE_HORIZONTAL (char)'-'
+#define SINGLE_TOP_LEFT (char)'+'
+#define SINGLE_TOP_RIGHT (char)'+'
+#define SINGLE_BOT_LEFT (char)'+'
+#define SINGLE_BOT_RIGHT (char)'+'
+
+// double line
+#define DOUBLE_VERTICAL (char)'|'
+#define DOUBLE_HORIZONTAL (char)'-'
+#define DOUBLE_TOP_LEFT (char)'+'
+#define DOUBLE_TOP_RIGHT (char)'+'
+#define DOUBLE_BOT_LEFT (char)'+'
+#define DOUBLE_BOT_RIGHT (char)'+'
+
+// line intersections
+#define SINGLES_CROSS (char)'+'
+#define DOUBLES_CROSS (char)'+'
+#define S_HOR_CROSS_D_VER (char)'+'
+#define S_VER_CROSS_D_HOR (char)'+'
+
+// single line joining
+#define S_JOINS_S_VER_LEFT (char)'+'
+#define S_JOINS_S_VER_RIGHT (char)'+'
+#define S_JOINS_S_HOR_TOP (char)'+'
+#define S_JOINS_S_HOR_BOT (char)'+'
+
+// double line joining
+#define D_JOINS_D_VER_LEFT (char)'+'
+#define D_JOINS_D_VER_RIGHT (char)'+'
+#define D_JOINS_D_HOR_TOP (char)'+'
+#define D_JOINS_D_HOR_BOT (char)'+'
+
+// single line joining double line
+#define S_JOINS_D_VER_LEFT (char)'+'
+#define S_JOINS_D_VER_RIGHT (char)'+'
+#define S_JOINS_D_HOR_TOP (char)'+'
+#define S_JOINS_D_HOR_BOT (char)'+'
+
+
+// other symbols
+#define UNDERSCORE (char)95
+//#define SYMBOL_ZERO (char)248 // degree sign
+//#define SYMBOL_ZERO (char)'o'
+#ifdef WIN32
+#define SYMBOL_ZERO (char)'0'
+#else
+#define SYMBOL_ZERO (char)' '
+#endif
+#define SYMBOL_ONE (char)'1'
+#define SYMBOL_DC (char)'-'
+#define SYMBOL_OVERLAP (char)'?'
+
+// full cells and half cells
+#define CELL_FREE (char)32
+#define CELL_FULL (char)219
+#define HALF_UPPER (char)223
+#define HALF_LOWER (char)220
+#define HALF_LEFT (char)221
+#define HALF_RIGHT (char)222
+
+
+/*---------------------------------------------------------------------------*/
+/* Structure declarations */
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/* Type declarations */
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/* Variable declarations */
+/*---------------------------------------------------------------------------*/
+
+// the array of BDD variables used internally
+static DdNode * s_XVars[MAXVARS];
+
+// flag which determines where the horizontal variable names are printed
+static int fHorizontalVarNamesPrintedAbove = 1;
+
+/*---------------------------------------------------------------------------*/
+/* Macro declarations */
+/*---------------------------------------------------------------------------*/
+
+
+/**AutomaticStart*************************************************************/
+
+/*---------------------------------------------------------------------------*/
+/* Static function prototypes */
+/*---------------------------------------------------------------------------*/
+
+// Oleg's way of generating the gray code
+static int GrayCode( int BinCode );
+static int BinCode ( int GrayCode );
+
+/**AutomaticEnd***************************************************************/
+
+
+/*---------------------------------------------------------------------------*/
+/* Definition of exported functions */
+/*---------------------------------------------------------------------------*/
+
+
+/**Function********************************************************************
+
+ Synopsis [Prints the K-map of the function.]
+
+ Description [If the pointer to the array of variables XVars is NULL,
+ fSuppType determines how the support will be determined.
+ fSuppType == 0 -- takes the first nVars of the manager
+ fSuppType == 1 -- takes the topmost nVars of the manager
+ fSuppType == 2 -- determines support from the on-set and the offset
+ ]
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+void Extra_PrintKMap(
+ FILE * Output, /* the output stream */
+ DdManager * dd,
+ DdNode * OnSet,
+ DdNode * OffSet,
+ int nVars,
+ DdNode ** XVars,
+ int fSuppType, /* the flag which determines how support is computed */
+ char ** pVarNames )
+{
+ int fPrintTruth = 1;
+ int d, p, n, s, v, h, w;
+ int nVarsVer;
+ int nVarsHor;
+ int nCellsVer;
+ int nCellsHor;
+ int nSkipSpaces;
+
+ // make sure that on-set and off-set do not overlap
+ if ( !Cudd_bddLeq( dd, OnSet, Cudd_Not(OffSet) ) )
+ {
+ fprintf( Output, "PrintKMap(): The on-set and the off-set overlap\n" );
+ return;
+ }
+ if ( nVars == 0 )
+ { printf( "Function is constant %d.\n", !Cudd_IsComplement(OnSet) ); return; }
+
+ // print truth table for debugging
+ if ( fPrintTruth )
+ {
+ DdNode * bCube, * bPart;
+ printf( "Truth table: " );
+ if ( nVars == 0 )
+ printf( "Constant" );
+ else if ( nVars == 1 )
+ printf( "1-var function" );
+ else
+ {
+// printf( "0x" );
+ for ( d = (1<<(nVars-2)) - 1; d >= 0; d-- )
+ {
+ int Value = 0;
+ for ( s = 0; s < 4; s++ )
+ {
+ bCube = Extra_bddBitsToCube( dd, 4*d+s, nVars, dd->vars, 0 ); Cudd_Ref( bCube );
+ bPart = Cudd_Cofactor( dd, OnSet, bCube ); Cudd_Ref( bPart );
+ Value |= ((int)(bPart == b1) << s);
+ Cudd_RecursiveDeref( dd, bPart );
+ Cudd_RecursiveDeref( dd, bCube );
+ }
+ if ( Value < 10 )
+ fprintf( stdout, "%d", Value );
+ else
+ fprintf( stdout, "%c", 'a' + Value-10 );
+ }
+ }
+ printf( "\n" );
+ }
+
+
+/*
+ if ( OnSet == b1 )
+ {
+ fprintf( Output, "PrintKMap(): Constant 1\n" );
+ return;
+ }
+ if ( OffSet == b1 )
+ {
+ fprintf( Output, "PrintKMap(): Constant 0\n" );
+ return;
+ }
+*/
+ if ( nVars < 0 || nVars > MAXVARS )
+ {
+ fprintf( Output, "PrintKMap(): The number of variables is less than zero or more than %d\n", MAXVARS );
+ return;
+ }
+
+ // determine the support if it is not given
+ if ( XVars == NULL )
+ {
+ if ( fSuppType == 0 )
+ { // assume that the support includes the first nVars of the manager
+ assert( nVars );
+ for ( v = 0; v < nVars; v++ )
+ s_XVars[v] = Cudd_bddIthVar( dd, v );
+ }
+ else if ( fSuppType == 1 )
+ { // assume that the support includes the topmost nVars of the manager
+ assert( nVars );
+ for ( v = 0; v < nVars; v++ )
+ s_XVars[v] = Cudd_bddIthVar( dd, dd->invperm[v] );
+ }
+ else // determine the support
+ {
+ DdNode * SuppOn, * SuppOff, * Supp;
+ int cVars = 0;
+ DdNode * TempSupp;
+
+ // determine support
+ SuppOn = Cudd_Support( dd, OnSet ); Cudd_Ref( SuppOn );
+ SuppOff = Cudd_Support( dd, OffSet ); Cudd_Ref( SuppOff );
+ Supp = Cudd_bddAnd( dd, SuppOn, SuppOff ); Cudd_Ref( Supp );
+ Cudd_RecursiveDeref( dd, SuppOn );
+ Cudd_RecursiveDeref( dd, SuppOff );
+
+ nVars = Cudd_SupportSize( dd, Supp );
+ if ( nVars > MAXVARS )
+ {
+ fprintf( Output, "PrintKMap(): The number of variables is more than %d\n", MAXVARS );
+ Cudd_RecursiveDeref( dd, Supp );
+ return;
+ }
+
+ // assign variables
+ for ( TempSupp = Supp; TempSupp != dd->one; TempSupp = Cudd_T(TempSupp), cVars++ )
+ s_XVars[cVars] = Cudd_bddIthVar( dd, TempSupp->index );
+
+ Cudd_RecursiveDeref( dd, TempSupp );
+ }
+ }
+ else
+ {
+ // copy variables
+ assert( XVars );
+ for ( v = 0; v < nVars; v++ )
+ s_XVars[v] = XVars[v];
+ }
+
+ ////////////////////////////////////////////////////////////////////
+ // determine the Karnaugh map parameters
+ nVarsVer = nVars/2;
+ nVarsHor = nVars - nVarsVer;
+
+ nCellsVer = (1<<nVarsVer);
+ nCellsHor = (1<<nVarsHor);
+ nSkipSpaces = nVarsVer + 1;
+
+ ////////////////////////////////////////////////////////////////////
+ // print variable names
+ fprintf( Output, "\n" );
+ for ( w = 0; w < nVarsVer; w++ )
+ if ( pVarNames == NULL )
+ fprintf( Output, "%c", 'a'+nVarsHor+w );
+ else
+ fprintf( Output, " %s", pVarNames[nVarsHor+w] );
+
+ if ( fHorizontalVarNamesPrintedAbove )
+ {
+ fprintf( Output, " \\ " );
+ for ( w = 0; w < nVarsHor; w++ )
+ if ( pVarNames == NULL )
+ fprintf( Output, "%c", 'a'+w );
+ else
+ fprintf( Output, "%s ", pVarNames[w] );
+ }
+ fprintf( Output, "\n" );
+
+ if ( fHorizontalVarNamesPrintedAbove )
+ {
+ ////////////////////////////////////////////////////////////////////
+ // print horizontal digits
+ for ( d = 0; d < nVarsHor; d++ )
+ {
+ for ( p = 0; p < nSkipSpaces + 2; p++, fprintf( Output, " " ) );
+ for ( n = 0; n < nCellsHor; n++ )
+ if ( GrayCode(n) & (1<<(nVarsHor-1-d)) )
+ fprintf( Output, "1 " );
+ else
+ fprintf( Output, "0 " );
+ fprintf( Output, "\n" );
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////
+ // print the upper line
+ for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
+ fprintf( Output, "%c", DOUBLE_TOP_LEFT );
+ for ( s = 0; s < nCellsHor; s++ )
+ {
+ fprintf( Output, "%c", DOUBLE_HORIZONTAL );
+ fprintf( Output, "%c", DOUBLE_HORIZONTAL );
+ fprintf( Output, "%c", DOUBLE_HORIZONTAL );
+ if ( s != nCellsHor-1 )
+ {
+ if ( s&1 )
+ fprintf( Output, "%c", D_JOINS_D_HOR_BOT );
+ else
+ fprintf( Output, "%c", S_JOINS_D_HOR_BOT );
+ }
+ }
+ fprintf( Output, "%c", DOUBLE_TOP_RIGHT );
+ fprintf( Output, "\n" );
+
+ ////////////////////////////////////////////////////////////////////
+ // print the map
+ for ( v = 0; v < nCellsVer; v++ )
+ {
+ DdNode * CubeVerBDD;
+
+ // print horizontal digits
+// for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
+ for ( n = 0; n < nVarsVer; n++ )
+ if ( GrayCode(v) & (1<<(nVarsVer-1-n)) )
+ fprintf( Output, "1" );
+ else
+ fprintf( Output, "0" );
+ fprintf( Output, " " );
+
+ // find vertical cube
+ CubeVerBDD = Extra_bddBitsToCube( dd, GrayCode(v), nVarsVer, s_XVars+nVarsHor, 1 ); Cudd_Ref( CubeVerBDD );
+
+ // print text line
+ fprintf( Output, "%c", DOUBLE_VERTICAL );
+ for ( h = 0; h < nCellsHor; h++ )
+ {
+ DdNode * CubeHorBDD, * Prod, * ValueOnSet, * ValueOffSet;
+
+ fprintf( Output, " " );
+// fprintf( Output, "x" );
+ ///////////////////////////////////////////////////////////////
+ // determine what should be printed
+ CubeHorBDD = Extra_bddBitsToCube( dd, GrayCode(h), nVarsHor, s_XVars, 1 ); Cudd_Ref( CubeHorBDD );
+ Prod = Cudd_bddAnd( dd, CubeHorBDD, CubeVerBDD ); Cudd_Ref( Prod );
+ Cudd_RecursiveDeref( dd, CubeHorBDD );
+
+ ValueOnSet = Cudd_Cofactor( dd, OnSet, Prod ); Cudd_Ref( ValueOnSet );
+ ValueOffSet = Cudd_Cofactor( dd, OffSet, Prod ); Cudd_Ref( ValueOffSet );
+ Cudd_RecursiveDeref( dd, Prod );
+
+#ifdef WIN32
+ {
+ HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
+ char Symb = 0, Color = 0;
+ if ( ValueOnSet == b1 && ValueOffSet == b0 )
+ Symb = SYMBOL_ONE, Color = 14; // yellow
+ else if ( ValueOnSet == b0 && ValueOffSet == b1 )
+ Symb = SYMBOL_ZERO, Color = 11; // blue
+ else if ( ValueOnSet == b0 && ValueOffSet == b0 )
+ Symb = SYMBOL_DC, Color = 10; // green
+ else if ( ValueOnSet == b1 && ValueOffSet == b1 )
+ Symb = SYMBOL_OVERLAP, Color = 12; // red
+ else
+ assert(0);
+ SetConsoleTextAttribute( hConsole, Color );
+ fprintf( Output, "%c", Symb );
+ SetConsoleTextAttribute( hConsole, 7 );
+ }
+#else
+ {
+ if ( ValueOnSet == b1 && ValueOffSet == b0 )
+ fprintf( Output, "%c", SYMBOL_ONE );
+ else if ( ValueOnSet == b0 && ValueOffSet == b1 )
+ fprintf( Output, "%c", SYMBOL_ZERO );
+ else if ( ValueOnSet == b0 && ValueOffSet == b0 )
+ fprintf( Output, "%c", SYMBOL_DC );
+ else if ( ValueOnSet == b1 && ValueOffSet == b1 )
+ fprintf( Output, "%c", SYMBOL_OVERLAP );
+ else
+ assert(0);
+ }
+#endif
+
+ Cudd_RecursiveDeref( dd, ValueOnSet );
+ Cudd_RecursiveDeref( dd, ValueOffSet );
+ ///////////////////////////////////////////////////////////////
+ fprintf( Output, " " );
+
+ if ( h != nCellsHor-1 )
+ {
+ if ( h&1 )
+ fprintf( Output, "%c", DOUBLE_VERTICAL );
+ else
+ fprintf( Output, "%c", SINGLE_VERTICAL );
+ }
+ }
+ fprintf( Output, "%c", DOUBLE_VERTICAL );
+ fprintf( Output, "\n" );
+
+ Cudd_RecursiveDeref( dd, CubeVerBDD );
+
+ if ( v != nCellsVer-1 )
+ // print separator line
+ {
+ for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
+ if ( v&1 )
+ {
+ fprintf( Output, "%c", D_JOINS_D_VER_RIGHT );
+ for ( s = 0; s < nCellsHor; s++ )
+ {
+ fprintf( Output, "%c", DOUBLE_HORIZONTAL );
+ fprintf( Output, "%c", DOUBLE_HORIZONTAL );
+ fprintf( Output, "%c", DOUBLE_HORIZONTAL );
+ if ( s != nCellsHor-1 )
+ {
+ if ( s&1 )
+ fprintf( Output, "%c", DOUBLES_CROSS );
+ else
+ fprintf( Output, "%c", S_VER_CROSS_D_HOR );
+ }
+ }
+ fprintf( Output, "%c", D_JOINS_D_VER_LEFT );
+ }
+ else
+ {
+ fprintf( Output, "%c", S_JOINS_D_VER_RIGHT );
+ for ( s = 0; s < nCellsHor; s++ )
+ {
+ fprintf( Output, "%c", SINGLE_HORIZONTAL );
+ fprintf( Output, "%c", SINGLE_HORIZONTAL );
+ fprintf( Output, "%c", SINGLE_HORIZONTAL );
+ if ( s != nCellsHor-1 )
+ {
+ if ( s&1 )
+ fprintf( Output, "%c", S_HOR_CROSS_D_VER );
+ else
+ fprintf( Output, "%c", SINGLES_CROSS );
+ }
+ }
+ fprintf( Output, "%c", S_JOINS_D_VER_LEFT );
+ }
+ fprintf( Output, "\n" );
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////
+ // print the lower line
+ for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
+ fprintf( Output, "%c", DOUBLE_BOT_LEFT );
+ for ( s = 0; s < nCellsHor; s++ )
+ {
+ fprintf( Output, "%c", DOUBLE_HORIZONTAL );
+ fprintf( Output, "%c", DOUBLE_HORIZONTAL );
+ fprintf( Output, "%c", DOUBLE_HORIZONTAL );
+ if ( s != nCellsHor-1 )
+ {
+ if ( s&1 )
+ fprintf( Output, "%c", D_JOINS_D_HOR_TOP );
+ else
+ fprintf( Output, "%c", S_JOINS_D_HOR_TOP );
+ }
+ }
+ fprintf( Output, "%c", DOUBLE_BOT_RIGHT );
+ fprintf( Output, "\n" );
+
+ if ( !fHorizontalVarNamesPrintedAbove )
+ {
+ ////////////////////////////////////////////////////////////////////
+ // print horizontal digits
+ for ( d = 0; d < nVarsHor; d++ )
+ {
+ for ( p = 0; p < nSkipSpaces + 2; p++, fprintf( Output, " " ) );
+ for ( n = 0; n < nCellsHor; n++ )
+ if ( GrayCode(n) & (1<<(nVarsHor-1-d)) )
+ fprintf( Output, "1 " );
+ else
+ fprintf( Output, "0 " );
+
+ /////////////////////////////////
+ fprintf( Output, "%c", (char)('a'+d) );
+ /////////////////////////////////
+ fprintf( Output, "\n" );
+ }
+ }
+}
+
+
+
+/**Function********************************************************************
+
+ Synopsis [Prints the K-map of the relation.]
+
+ Description [Assumes that the relation depends the first nXVars of XVars and
+ the first nYVars of YVars. Draws X and Y vars and vertical and horizontal vars.]
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+void Extra_PrintKMapRelation(
+ FILE * Output, /* the output stream */
+ DdManager * dd,
+ DdNode * OnSet,
+ DdNode * OffSet,
+ int nXVars,
+ int nYVars,
+ DdNode ** XVars,
+ DdNode ** YVars ) /* the flag which determines how support is computed */
+{
+ int d, p, n, s, v, h, w;
+ int nVars;
+ int nVarsVer;
+ int nVarsHor;
+ int nCellsVer;
+ int nCellsHor;
+ int nSkipSpaces;
+
+ // make sure that on-set and off-set do not overlap
+ if ( !Cudd_bddLeq( dd, OnSet, Cudd_Not(OffSet) ) )
+ {
+ fprintf( Output, "PrintKMap(): The on-set and the off-set overlap\n" );
+ return;
+ }
+
+ if ( OnSet == b1 )
+ {
+ fprintf( Output, "PrintKMap(): Constant 1\n" );
+ return;
+ }
+ if ( OffSet == b1 )
+ {
+ fprintf( Output, "PrintKMap(): Constant 0\n" );
+ return;
+ }
+
+ nVars = nXVars + nYVars;
+ if ( nVars < 0 || nVars > MAXVARS )
+ {
+ fprintf( Output, "PrintKMap(): The number of variables is less than zero or more than %d\n", MAXVARS );
+ return;
+ }
+
+
+ ////////////////////////////////////////////////////////////////////
+ // determine the Karnaugh map parameters
+ nVarsVer = nXVars;
+ nVarsHor = nYVars;
+ nCellsVer = (1<<nVarsVer);
+ nCellsHor = (1<<nVarsHor);
+ nSkipSpaces = nVarsVer + 1;
+
+ ////////////////////////////////////////////////////////////////////
+ // print variable names
+ fprintf( Output, "\n" );
+ for ( w = 0; w < nVarsVer; w++ )
+ fprintf( Output, "%c", 'a'+nVarsHor+w );
+ if ( fHorizontalVarNamesPrintedAbove )
+ {
+ fprintf( Output, " \\ " );
+ for ( w = 0; w < nVarsHor; w++ )
+ fprintf( Output, "%c", 'a'+w );
+ }
+ fprintf( Output, "\n" );
+
+ if ( fHorizontalVarNamesPrintedAbove )
+ {
+ ////////////////////////////////////////////////////////////////////
+ // print horizontal digits
+ for ( d = 0; d < nVarsHor; d++ )
+ {
+ for ( p = 0; p < nSkipSpaces + 2; p++, fprintf( Output, " " ) );
+ for ( n = 0; n < nCellsHor; n++ )
+ if ( GrayCode(n) & (1<<(nVarsHor-1-d)) )
+ fprintf( Output, "1 " );
+ else
+ fprintf( Output, "0 " );
+ fprintf( Output, "\n" );
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////
+ // print the upper line
+ for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
+ fprintf( Output, "%c", DOUBLE_TOP_LEFT );
+ for ( s = 0; s < nCellsHor; s++ )
+ {
+ fprintf( Output, "%c", DOUBLE_HORIZONTAL );
+ fprintf( Output, "%c", DOUBLE_HORIZONTAL );
+ fprintf( Output, "%c", DOUBLE_HORIZONTAL );
+ if ( s != nCellsHor-1 )
+ {
+ if ( s&1 )
+ fprintf( Output, "%c", D_JOINS_D_HOR_BOT );
+ else
+ fprintf( Output, "%c", S_JOINS_D_HOR_BOT );
+ }
+ }
+ fprintf( Output, "%c", DOUBLE_TOP_RIGHT );
+ fprintf( Output, "\n" );
+
+ ////////////////////////////////////////////////////////////////////
+ // print the map
+ for ( v = 0; v < nCellsVer; v++ )
+ {
+ DdNode * CubeVerBDD;
+
+ // print horizontal digits
+// for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
+ for ( n = 0; n < nVarsVer; n++ )
+ if ( GrayCode(v) & (1<<(nVarsVer-1-n)) )
+ fprintf( Output, "1" );
+ else
+ fprintf( Output, "0" );
+ fprintf( Output, " " );
+
+ // find vertical cube
+// CubeVerBDD = Extra_bddBitsToCube( dd, GrayCode(v), nVarsVer, s_XVars+nVarsHor ); Cudd_Ref( CubeVerBDD );
+ CubeVerBDD = Extra_bddBitsToCube( dd, GrayCode(v), nXVars, XVars, 1 ); Cudd_Ref( CubeVerBDD );
+
+ // print text line
+ fprintf( Output, "%c", DOUBLE_VERTICAL );
+ for ( h = 0; h < nCellsHor; h++ )
+ {
+ DdNode * CubeHorBDD, * Prod, * ValueOnSet, * ValueOffSet;
+
+ fprintf( Output, " " );
+// fprintf( Output, "x" );
+ ///////////////////////////////////////////////////////////////
+ // determine what should be printed
+// CubeHorBDD = Extra_bddBitsToCube( dd, GrayCode(h), nVarsHor, s_XVars ); Cudd_Ref( CubeHorBDD );
+ CubeHorBDD = Extra_bddBitsToCube( dd, GrayCode(h), nYVars, YVars, 1 ); Cudd_Ref( CubeHorBDD );
+ Prod = Cudd_bddAnd( dd, CubeHorBDD, CubeVerBDD ); Cudd_Ref( Prod );
+ Cudd_RecursiveDeref( dd, CubeHorBDD );
+
+ ValueOnSet = Cudd_Cofactor( dd, OnSet, Prod ); Cudd_Ref( ValueOnSet );
+ ValueOffSet = Cudd_Cofactor( dd, OffSet, Prod ); Cudd_Ref( ValueOffSet );
+ Cudd_RecursiveDeref( dd, Prod );
+
+ if ( ValueOnSet == b1 && ValueOffSet == b0 )
+ fprintf( Output, "%c", SYMBOL_ONE );
+ else if ( ValueOnSet == b0 && ValueOffSet == b1 )
+ fprintf( Output, "%c", SYMBOL_ZERO );
+ else if ( ValueOnSet == b0 && ValueOffSet == b0 )
+ fprintf( Output, "%c", SYMBOL_DC );
+ else if ( ValueOnSet == b1 && ValueOffSet == b1 )
+ fprintf( Output, "%c", SYMBOL_OVERLAP );
+ else
+ assert(0);
+
+ Cudd_RecursiveDeref( dd, ValueOnSet );
+ Cudd_RecursiveDeref( dd, ValueOffSet );
+ ///////////////////////////////////////////////////////////////
+ fprintf( Output, " " );
+
+ if ( h != nCellsHor-1 )
+ {
+ if ( h&1 )
+ fprintf( Output, "%c", DOUBLE_VERTICAL );
+ else
+ fprintf( Output, "%c", SINGLE_VERTICAL );
+ }
+ }
+ fprintf( Output, "%c", DOUBLE_VERTICAL );
+ fprintf( Output, "\n" );
+
+ Cudd_RecursiveDeref( dd, CubeVerBDD );
+
+ if ( v != nCellsVer-1 )
+ // print separator line
+ {
+ for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
+ if ( v&1 )
+ {
+ fprintf( Output, "%c", D_JOINS_D_VER_RIGHT );
+ for ( s = 0; s < nCellsHor; s++ )
+ {
+ fprintf( Output, "%c", DOUBLE_HORIZONTAL );
+ fprintf( Output, "%c", DOUBLE_HORIZONTAL );
+ fprintf( Output, "%c", DOUBLE_HORIZONTAL );
+ if ( s != nCellsHor-1 )
+ {
+ if ( s&1 )
+ fprintf( Output, "%c", DOUBLES_CROSS );
+ else
+ fprintf( Output, "%c", S_VER_CROSS_D_HOR );
+ }
+ }
+ fprintf( Output, "%c", D_JOINS_D_VER_LEFT );
+ }
+ else
+ {
+ fprintf( Output, "%c", S_JOINS_D_VER_RIGHT );
+ for ( s = 0; s < nCellsHor; s++ )
+ {
+ fprintf( Output, "%c", SINGLE_HORIZONTAL );
+ fprintf( Output, "%c", SINGLE_HORIZONTAL );
+ fprintf( Output, "%c", SINGLE_HORIZONTAL );
+ if ( s != nCellsHor-1 )
+ {
+ if ( s&1 )
+ fprintf( Output, "%c", S_HOR_CROSS_D_VER );
+ else
+ fprintf( Output, "%c", SINGLES_CROSS );
+ }
+ }
+ fprintf( Output, "%c", S_JOINS_D_VER_LEFT );
+ }
+ fprintf( Output, "\n" );
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////
+ // print the lower line
+ for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
+ fprintf( Output, "%c", DOUBLE_BOT_LEFT );
+ for ( s = 0; s < nCellsHor; s++ )
+ {
+ fprintf( Output, "%c", DOUBLE_HORIZONTAL );
+ fprintf( Output, "%c", DOUBLE_HORIZONTAL );
+ fprintf( Output, "%c", DOUBLE_HORIZONTAL );
+ if ( s != nCellsHor-1 )
+ {
+ if ( s&1 )
+ fprintf( Output, "%c", D_JOINS_D_HOR_TOP );
+ else
+ fprintf( Output, "%c", S_JOINS_D_HOR_TOP );
+ }
+ }
+ fprintf( Output, "%c", DOUBLE_BOT_RIGHT );
+ fprintf( Output, "\n" );
+
+ if ( !fHorizontalVarNamesPrintedAbove )
+ {
+ ////////////////////////////////////////////////////////////////////
+ // print horizontal digits
+ for ( d = 0; d < nVarsHor; d++ )
+ {
+ for ( p = 0; p < nSkipSpaces + 2; p++, fprintf( Output, " " ) );
+ for ( n = 0; n < nCellsHor; n++ )
+ if ( GrayCode(n) & (1<<(nVarsHor-1-d)) )
+ fprintf( Output, "1 " );
+ else
+ fprintf( Output, "0 " );
+
+ /////////////////////////////////
+ fprintf( Output, "%c", (char)('a'+d) );
+ /////////////////////////////////
+ fprintf( Output, "\n" );
+ }
+ }
+}
+
+
+
+/*---------------------------------------------------------------------------*/
+/* Definition of static functions */
+/*---------------------------------------------------------------------------*/
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int GrayCode ( int BinCode )
+{
+ return BinCode ^ ( BinCode >> 1 );
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int BinCode ( int GrayCode )
+{
+ int bc = GrayCode;
+ while( GrayCode >>= 1 ) bc ^= GrayCode;
+ return bc;
+}
+
+
+ABC_NAMESPACE_IMPL_END
+