blob: aa5efe75f1da204ffc2074add5c8148268ec93f9 [file] [log] [blame]
/**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