You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
235 lines
5.4 KiB
235 lines
5.4 KiB
//==============================================================================
|
|
//
|
|
// File: dd_info.cc
|
|
// Date: 16/9/99
|
|
// Author: Dave Parker
|
|
// Desc: DD analysis/information functions
|
|
//
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
// Copyright (c) 2002-2004, Dave Parker
|
|
//
|
|
// This file is part of PRISM.
|
|
//
|
|
// PRISM is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation; either version 2 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// PRISM is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with PRISM; if not, write to the Free Software Foundation,
|
|
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
//
|
|
//==============================================================================
|
|
|
|
#include <math.h>
|
|
#include <util.h>
|
|
#include <cudd.h>
|
|
#include "dd_basics.h"
|
|
#include "dd_term.h"
|
|
#include "dd_info.h"
|
|
|
|
extern FILE *dd_out;
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
int DD_GetNumNodes
|
|
(
|
|
DdManager *ddman,
|
|
DdNode *dd
|
|
)
|
|
{
|
|
return Cudd_DagSize(dd);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
int DD_GetNumTerminals
|
|
(
|
|
DdManager *ddman,
|
|
DdNode *dd
|
|
)
|
|
{
|
|
return Cudd_CountLeaves(dd);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
double DD_GetNumMinterms
|
|
(
|
|
DdManager *ddman,
|
|
DdNode *dd,
|
|
int num_vars
|
|
)
|
|
{
|
|
return Cudd_CountMinterm(ddman, dd, num_vars);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
double DD_GetNumPaths
|
|
(
|
|
DdManager *ddman,
|
|
DdNode *dd
|
|
)
|
|
{
|
|
return Cudd_CountPath(dd);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void DD_PrintInfo
|
|
(
|
|
DdManager *ddman,
|
|
DdNode *dd,
|
|
int num_vars)
|
|
{
|
|
int nodes, terminals;
|
|
double minterms;
|
|
|
|
nodes = Cudd_DagSize(dd);
|
|
terminals = Cudd_CountLeaves(dd);
|
|
minterms = Cudd_CountMinterm(ddman, dd, num_vars);
|
|
fprintf(dd_out, "%d nodes (%d terminal), %.0f minterms\n", nodes, terminals, minterms);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void DD_PrintInfoBrief
|
|
(
|
|
DdManager *ddman,
|
|
DdNode *dd,
|
|
int num_vars)
|
|
{
|
|
int nodes, terminals;
|
|
double minterms;
|
|
|
|
nodes = Cudd_DagSize(dd);
|
|
terminals = Cudd_CountLeaves(dd);
|
|
minterms = Cudd_CountMinterm(ddman, dd, num_vars);
|
|
fprintf(dd_out, "[%d,%d,%.0f]\n", nodes, terminals, minterms);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void DD_PrintSupport
|
|
(
|
|
DdManager *ddman,
|
|
DdNode *dd
|
|
)
|
|
{
|
|
DdNode *supp, *tmp;
|
|
|
|
fprintf(dd_out, "(");
|
|
supp = Cudd_Support(ddman, dd);
|
|
Cudd_Ref(supp);
|
|
tmp = supp;
|
|
while (!Cudd_IsConstant(tmp)) {
|
|
fprintf(dd_out, " %d", Cudd_NodeReadIndex(tmp));
|
|
tmp = Cudd_T(tmp);
|
|
}
|
|
fprintf(dd_out, " )\n");
|
|
Cudd_RecursiveDeref(ddman, supp);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
DdNode *DD_GetSupport
|
|
(
|
|
DdManager *ddman,
|
|
DdNode *dd
|
|
)
|
|
{
|
|
DdNode *supp, *supp2;
|
|
|
|
supp = Cudd_Support(ddman, dd);
|
|
Cudd_Ref(supp);
|
|
supp2 = Cudd_BddToAdd(ddman, supp);
|
|
Cudd_Ref(supp2);
|
|
Cudd_RecursiveDeref(ddman, supp);
|
|
|
|
return supp2;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void DD_PrintTerminals
|
|
(
|
|
DdManager *ddman,
|
|
DdNode *dd
|
|
)
|
|
{
|
|
DdNode *tmp;
|
|
double max;
|
|
int count = 0;
|
|
|
|
Cudd_Ref(dd);
|
|
tmp = dd;
|
|
|
|
// remove any negative terminals (if any)
|
|
// and warn the user
|
|
if (Cudd_V(Cudd_addFindMin(ddman, tmp)) < 0) {
|
|
fprintf(dd_out, "Warning: DD_PrintTerminals is ignoring negative terminals.\n");
|
|
Cudd_Ref(tmp);
|
|
tmp = DD_Apply(ddman, APPLY_TIMES, DD_GreaterThan(ddman, tmp, 0), tmp);
|
|
}
|
|
|
|
while (tmp != Cudd_addConst(ddman, 0)) {
|
|
max = Cudd_V(Cudd_addFindMax(ddman, tmp));
|
|
fprintf(dd_out, "%f ", max);
|
|
count++;
|
|
Cudd_Ref(tmp);
|
|
tmp = DD_ITE(ddman, DD_Equals(ddman, tmp, max), DD_Constant(ddman, 0), tmp);
|
|
}
|
|
Cudd_RecursiveDeref(ddman, tmp);
|
|
if (count < Cudd_CountLeaves(dd)) {
|
|
fprintf(dd_out, "%f", 0.0);
|
|
}
|
|
fprintf(dd_out, "\n");
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void DD_PrintTerminalsAndNumbers
|
|
(
|
|
DdManager *ddman,
|
|
DdNode *dd,
|
|
int num_vars)
|
|
{
|
|
DdNode *tmp, *tmp2;
|
|
double max, num, count = 0.0;
|
|
|
|
Cudd_Ref(dd);
|
|
tmp = dd;
|
|
|
|
// remove any negative terminals (if any)
|
|
// and warn the user
|
|
if (Cudd_V(Cudd_addFindMin(ddman, tmp)) < 0) {
|
|
fprintf(dd_out, "Warning: DD_PrintTerminals is ignoring negative terminals.\n");
|
|
Cudd_Ref(tmp);
|
|
tmp = DD_Apply(ddman, APPLY_TIMES, DD_GreaterThan(ddman, tmp, 0), tmp);
|
|
}
|
|
|
|
while (tmp != Cudd_addConst(ddman, 0)) {
|
|
max = Cudd_V(Cudd_addFindMax(ddman, tmp));
|
|
fprintf(dd_out, "%f ", max);
|
|
Cudd_Ref(tmp);
|
|
tmp2 = DD_Equals(ddman, tmp, max);
|
|
num = Cudd_CountMinterm(ddman, tmp2, num_vars);
|
|
count += num;
|
|
fprintf(dd_out, "(%.0f) ", num);
|
|
tmp = DD_ITE(ddman, tmp2, DD_Constant(ddman, 0), tmp);
|
|
}
|
|
Cudd_RecursiveDeref(ddman, tmp);
|
|
if (count < pow(2, num_vars)) {
|
|
fprintf(dd_out, "%f (%.0f)", 0.0, pow(2, num_vars) - count);
|
|
}
|
|
fprintf(dd_out, "\n");
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|