|
VIS
|
#include "imgInt.h"
Include dependency graph for imgTfmFwd.c:Go to the source code of this file.
Functions | |
| static mdd_t * | ImageByInputSplit (ImgTfmInfo_t *info, array_t *vector, mdd_t *constraint, mdd_t *from, array_t *relationArray, mdd_t *cofactorCube, mdd_t *abstractCube, int splitMethod, int turnDepth, int depth) |
| static mdd_t * | ImageByStaticInputSplit (ImgTfmInfo_t *info, array_t *vector, mdd_t *from, array_t *relationArray, int turnDepth, int depth) |
| static mdd_t * | ImageByOutputSplit (ImgTfmInfo_t *info, array_t *vector, mdd_t *constraint, int depth) |
| static int | ImageDecomposeAndChooseSplitVar (ImgTfmInfo_t *info, array_t *vector, mdd_t *from, int splitMethod, int split, int piSplitFlag, array_t *vectorArray, array_t *varArray, mdd_t **singles, array_t *relationArray, array_t **newRelationArray, mdd_t **cofactorCube, mdd_t **abstractCube) |
| static mdd_t * | ImageFast2 (ImgTfmInfo_t *info, array_t *vector) |
| static int | FindDecomposableVariable (ImgTfmInfo_t *info, array_t *vector) |
| static int | TfmCheckImageValidity (ImgTfmInfo_t *info, mdd_t *image) |
| static void | FindIntermediateSupport (array_t *vector, ImgComponent_t *comp, int nVars, int nGroups, int *stack, char *stackFlag, int *funcGroup, int *size, char *intermediateVarFlag, int *intermediateVarFuncMap) |
| static void | PrintVectorDecomposition (ImgTfmInfo_t *info, array_t *vectorArray, array_t *varArray) |
| static int | CheckIfValidSplitOrGetNew (ImgTfmInfo_t *info, int split, array_t *vector, array_t *relationArray, mdd_t *from) |
| static int | ChooseInputSplittingVariable (ImgTfmInfo_t *info, array_t *vector, mdd_t *from, int splitMethod, int decompose, int piSplitFlag, int *varOccur) |
| static int | ChooseOutputSplittingVariable (ImgTfmInfo_t *info, array_t *vector, int splitMethod) |
| mdd_t * | ImgTfmImage (ImgTfmInfo_t *info, mdd_t *from) |
| mdd_t * | ImgChooseTrSplitVar (ImgTfmInfo_t *info, array_t *vector, array_t *relationArray, int trSplitMethod, int piSplitFlag) |
Variables | |
| static char rcsid[] | UNUSED = "$Id: imgTfmFwd.c,v 1.37 2005/04/22 19:45:46 jinh Exp $" |
| static int CheckIfValidSplitOrGetNew | ( | ImgTfmInfo_t * | info, |
| int | split, | ||
| array_t * | vector, | ||
| array_t * | relationArray, | ||
| mdd_t * | from | ||
| ) | [static] |
Function********************************************************************
Synopsis [Checks the splitting variable is valid and chooses new one if not valid.]
Description [Checks the splitting variable is already quantified from the transition relation. If yes, chooses new splitting variable. If there is no valid splitting variable, returns -1.]
SideEffects []
Definition at line 2983 of file imgTfmFwd.c.
{
int newSplit = split;
int i, j, nVars;
ImgComponent_t *comp;
char *support;
int *varOccur;
int decompose;
nVars = info->nVars;
support = ALLOC(char, sizeof(char) * nVars);
memset(support, 0, sizeof(char) * nVars);
comp = ImgComponentAlloc(info);
for (i = 0; i < array_n(relationArray); i++) {
comp->func = array_fetch(mdd_t *, relationArray, i);;
ImgSupportClear(info, comp->support);
ImgComponentGetSupport(comp);
for (j = 0; j < nVars; j++) {
if (comp->support[j]) {
if (j == split) {
comp->func = NIL(mdd_t);
ImgComponentFree(comp);
FREE(support);
return(split);
}
support[j] = 1;
}
}
}
comp->func = NIL(mdd_t);
ImgComponentFree(comp);
if (info->useConstraint && from)
decompose = 0;
else
decompose = 1;
varOccur = ALLOC(int, nVars);
memset(varOccur, 0, sizeof(int) * nVars);
if (from) {
comp = ImgComponentAlloc(info);
comp->func = from;
ImgComponentGetSupport(comp);
for (i = 0; i < nVars; i++) {
if (comp->support[i])
varOccur[i]++;
}
comp->func = NIL(mdd_t);
ImgComponentFree(comp);
}
FREE(support);
newSplit = ChooseInputSplittingVariable(info, vector, from,
info->option->inputSplit, decompose,
info->option->piSplitFlag, varOccur);
FREE(varOccur);
return(newSplit);
}
Here is the call graph for this function:
Here is the caller graph for this function:| static int ChooseInputSplittingVariable | ( | ImgTfmInfo_t * | info, |
| array_t * | vector, | ||
| mdd_t * | from, | ||
| int | splitMethod, | ||
| int | decompose, | ||
| int | piSplitFlag, | ||
| int * | varOccur | ||
| ) | [static] |
Function********************************************************************
Synopsis [Finds a splitting variable for input splitting.]
Description [Finds a splitting variable for input splitting.]
SideEffects []
Definition at line 3060 of file imgTfmFwd.c.
{
int nVars = info->nVars;
int bestVar = -1;
int secondBestVar = -1;
int bestCost, newCost;
int bestOccur, tieCount;
int secondBestOccur, secondTieCount;
int i, j;
ImgComponent_t *comp;
mdd_t *var, *varNot, *pcFunc, *ncFunc;
int *varCost;
int size = ImgVectorFunctionSize(vector);
if (info->option->inputSplit > 0) {
varCost = ALLOC(int, nVars);
memset(varCost, 0, sizeof(int) * nVars);
} else
varCost = NIL(int);
switch (splitMethod) {
case 0:
/* Find the most frequently occurred variable */
bestOccur = 0;
tieCount = 0;
secondBestOccur = 0;
secondTieCount = 0;
for (i = 0; i < nVars; i++) {
if (varOccur[i] == 0)
continue;
if (piSplitFlag == 0) {
if (st_lookup(info->quantifyVarsTable, (char *)(long)i,
NIL(char *))) {
if ((bestOccur == 0 && secondBestOccur == 0) ||
(varOccur[i] > bestOccur && varOccur[i] > secondBestOccur)) {
secondBestOccur = varOccur[i];
secondBestVar = i;
secondTieCount = 1;
} else if (secondBestOccur > bestOccur &&
varOccur[i] == secondBestOccur) {
secondTieCount++;
if (info->option->tieBreakMode == 0 &&
bdd_get_level_from_id(info->manager, i) <
bdd_get_level_from_id(info->manager, secondBestVar)) {
secondBestVar = i;
}
}
continue;
}
}
if (size < array_n(vector) &&
st_lookup(info->intermediateVarsTable, (char *)(long)i,
NIL(char *))) {
continue;
}
if (bestOccur == 0 || varOccur[i] > bestOccur) {
bestOccur = varOccur[i];
bestVar = i;
tieCount = 1;
} else if (varOccur[i] == bestOccur) {
tieCount++;
if (info->option->tieBreakMode == 0 &&
bdd_get_level_from_id(info->manager, i) <
bdd_get_level_from_id(info->manager, bestVar)) {
bestVar = i;
}
}
}
if (piSplitFlag == 0 && bestVar == -1) {
bestVar = secondBestVar;
bestOccur = secondBestOccur;
tieCount = secondTieCount;
}
if (info->option->tieBreakMode == 1 && tieCount > 1) {
bestCost = IMG_TF_MAX_INT;
for (i = bestVar; i < nVars; i++) {
if (varOccur[i] != bestOccur)
continue;
if (size < array_n(vector) &&
st_lookup(info->intermediateVarsTable, (char *)(long)i,
NIL(char *))) {
continue;
}
var = bdd_var_with_index(info->manager, i);
newCost = 0;
for (j = 0; j < array_n(vector); j++) {
comp = array_fetch(ImgComponent_t *, vector, j);
newCost += bdd_estimate_cofactor(comp->func, var, 1);
newCost += bdd_estimate_cofactor(comp->func, var, 0);
}
if (decompose == 0) {
newCost += bdd_estimate_cofactor(from, var, 1);
newCost += bdd_estimate_cofactor(from, var, 0);
}
mdd_free(var);
if (newCost < bestCost) {
bestVar = i;
bestCost = newCost;
} else if (newCost == bestCost) {
if (bdd_get_level_from_id(info->manager, i) <
bdd_get_level_from_id(info->manager, bestVar)) {
bestVar = i;
}
}
}
}
break;
case 1:
/* Find the variable which makes the smallest support after splitting */
bestCost = IMG_TF_MAX_INT;
for (i = 0; i < nVars; i++) {
if (varOccur[i] == 0)
continue;
if (size < array_n(vector) &&
st_lookup(info->intermediateVarsTable, (char *)(long)i,
NIL(char *))) {
continue;
}
var = bdd_var_with_index(info->manager, i);
varNot = mdd_not(var);
for (j = 0; j < array_n(vector); j++) {
comp = array_fetch(ImgComponent_t *, vector, j);
pcFunc = bdd_cofactor(comp->func, var);
varCost[i] += ImgCountBddSupports(pcFunc);
mdd_free(pcFunc);
ncFunc = bdd_cofactor(comp->func, varNot);
varCost[i] += ImgCountBddSupports(ncFunc);
mdd_free(ncFunc);
}
if (decompose == 0) {
pcFunc = bdd_cofactor(from, var);
varCost[i] += ImgCountBddSupports(pcFunc);
mdd_free(pcFunc);
ncFunc = bdd_cofactor(from, varNot);
varCost[i] += ImgCountBddSupports(ncFunc);
mdd_free(ncFunc);
}
mdd_free(var);
mdd_free(varNot);
if (varCost[i] < bestCost) {
bestCost = varCost[i];
bestVar = i;
} else if (varCost[i] == bestCost) {
if (varOccur[i] < varOccur[bestVar]) {
bestVar = i;
} else if (varOccur[i] == varOccur[bestVar]) {
if (bdd_get_level_from_id(info->manager, i) <
bdd_get_level_from_id(info->manager, bestVar)) {
bestVar = i;
}
}
}
}
break;
case 2:
/* Find the variable which makes the smallest BDDs of all functions
after splitting */
bestCost = IMG_TF_MAX_INT;
for (i = 0; i < nVars; i++) {
if (varOccur[i] == 0)
continue;
if (size < array_n(vector) &&
st_lookup(info->intermediateVarsTable, (char *)(long)i,
NIL(char *))) {
continue;
}
var = bdd_var_with_index(info->manager, i);
for (j = 0; j < array_n(vector); j++) {
comp = array_fetch(ImgComponent_t *, vector, j);
varCost[i] += bdd_estimate_cofactor(comp->func, var, 1);
varCost[i] += bdd_estimate_cofactor(comp->func, var, 0);
}
if (decompose == 0) {
varCost[i] += bdd_estimate_cofactor(from, var, 1);
varCost[i] += bdd_estimate_cofactor(from, var, 0);
}
mdd_free(var);
if (varCost[i] < bestCost) {
bestCost = varCost[i];
bestVar = i;
} else if (varCost[i] == bestCost) {
if (varOccur[i] < varOccur[bestVar]) {
bestVar = i;
} else if (varOccur[i] == varOccur[bestVar]) {
if (bdd_get_level_from_id(info->manager, i) <
bdd_get_level_from_id(info->manager, bestVar)) {
bestVar = i;
}
}
}
}
break;
case 3: /* top variable */
for (i = 0; i < nVars; i++) {
if (varOccur[i] == 0)
continue;
if (size < array_n(vector) &&
st_lookup(info->intermediateVarsTable, (char *)(long)i,
NIL(char *))) {
continue;
}
if (piSplitFlag == 0) {
if (st_lookup(info->quantifyVarsTable, (char *)(long)i,
NIL(char *))) {
if (bestVar == -1 && secondBestVar == -1)
secondBestVar = i;
else if (bdd_get_level_from_id(info->manager, i) <
bdd_get_level_from_id(info->manager, secondBestVar)) {
secondBestVar = i;
}
continue;
}
}
if (bestVar == -1 ||
bdd_get_level_from_id(info->manager, i) <
bdd_get_level_from_id(info->manager, bestVar)) {
bestVar = i;
}
}
if (piSplitFlag == 0 && bestVar == -1)
bestVar = secondBestVar;
break;
default:
break;
}
if (varCost)
FREE(varCost);
return(bestVar);
}
Here is the call graph for this function:
Here is the caller graph for this function:| static int ChooseOutputSplittingVariable | ( | ImgTfmInfo_t * | info, |
| array_t * | vector, | ||
| int | splitMethod | ||
| ) | [static] |
Function********************************************************************
Synopsis [Finds a splitting variable for output splitting.]
Description [Finds a splitting variable for output splitting.]
SideEffects []
Definition at line 3311 of file imgTfmFwd.c.
{
int bestVar = -1;
int bestCost, newCost;
int i;
ImgComponent_t *comp;
int size = ImgVectorFunctionSize(vector);
int index;
switch (splitMethod) {
case 0: /* smallest */
bestCost = IMG_TF_MAX_INT;
for (i = 0; i < array_n(vector); i++) {
comp = array_fetch(ImgComponent_t *, vector, i);
if (size < array_n(vector) &&
st_lookup(info->intermediateVarsTable,
(char *)(long)bdd_top_var_id(comp->var), NIL(char *))) {
continue;
}
newCost = bdd_size(comp->func);
if (newCost < bestCost) {
bestVar = i;
bestCost = newCost;
}
}
break;
case 1: /* largest */
bestCost = 0;
for (i = 0; i < array_n(vector); i++) {
comp = array_fetch(ImgComponent_t *, vector, i);
if (size < array_n(vector) &&
st_lookup(info->intermediateVarsTable,
(char *)(long)bdd_top_var_id(comp->var), NIL(char *))) {
continue;
}
newCost = bdd_size(comp->func);
if (newCost > bestCost) {
bestVar = i;
bestCost = newCost;
}
}
break;
case 2: /* top variable */
default:
comp = array_fetch(ImgComponent_t *, vector, 0);
bestVar = (int)bdd_top_var_id(comp->var);
for (i = 0; i < array_n(vector); i++) {
comp = array_fetch(ImgComponent_t *, vector, i);
index = (int)bdd_top_var_id(comp->var);
if (size < array_n(vector) &&
st_lookup(info->intermediateVarsTable, (char *)(long)index,
NIL(char *))) {
continue;
}
if (bestVar == -1 ||
bdd_get_level_from_id(info->manager, index) <
bdd_get_level_from_id(info->manager, bestVar)) {
bestVar = i;
}
}
break;
}
return(bestVar);
}
Here is the call graph for this function:
Here is the caller graph for this function:| static int FindDecomposableVariable | ( | ImgTfmInfo_t * | info, |
| array_t * | vector | ||
| ) | [static] |
Function********************************************************************
Synopsis [Finds a decomposable variable (articulation)]
Description [Finds a decomposable variable (articulation)]
SideEffects []
Definition at line 2716 of file imgTfmFwd.c.
{
int i, j, f, split;
int nChosen, index, varId;
int nVars, nFuncs;
char *varFlag;
int *funcGroup;
int *stack, size;
ImgComponent_t *comp;
char *stackFlag;
char *support;
int arraySize;
char *intermediateVarFlag;
int *intermediateVarFuncMap;
arraySize = array_n(vector);
if (info->nIntermediateVars)
nFuncs = ImgVectorFunctionSize(vector);
else
nFuncs = arraySize;
nVars = info->nVars;
funcGroup = ALLOC(int, arraySize);
varFlag = ALLOC(char, nVars);
stack = ALLOC(int, arraySize);
stackFlag = ALLOC(char, arraySize);
if (arraySize > nFuncs) {
intermediateVarFlag = ALLOC(char, nVars);
memset(intermediateVarFlag, 0, sizeof(char) * nVars);
intermediateVarFuncMap = ALLOC(int, nVars);
memset(intermediateVarFuncMap, 0, sizeof(int) * nVars);
for (i = 0; i < arraySize; i++) {
comp = array_fetch(ImgComponent_t *, vector, i);
if (comp->intermediate) {
index = (int)bdd_top_var_id(comp->var);
intermediateVarFlag[index] = 1;
intermediateVarFuncMap[index] = i;
}
}
} else {
intermediateVarFlag = NIL(char);
intermediateVarFuncMap = NIL(int);
}
varId = -1;
for (split = 0; split < nVars; split++) {
if (intermediateVarFlag[split])
continue;
memset(funcGroup, 0, sizeof(int) * arraySize);
memset(varFlag, 0, sizeof(char) * nVars);
memset(stackFlag, 0, sizeof(char) * arraySize);
varFlag[split] = 1;
nChosen = 0;
stack[0] = 0;
size = 1;
stackFlag[0] = 1;
while (size) {
size--;
f = stack[size];
funcGroup[f] = 1;
comp = array_fetch(ImgComponent_t *, vector, f);
nChosen++;
if (nChosen == arraySize)
break;
support = comp->support;
if (comp->intermediate) {
index = (int)bdd_top_var_id(comp->var);
support[index] = 1;
}
for (i = 0; i < nVars; i++) {
if (!support[i])
continue;
if (varFlag[i])
continue;
varFlag[i] = 1;
for (j = 0; j < nFuncs; j++) {
if (j == f || stackFlag[j])
continue;
comp = array_fetch(ImgComponent_t *, vector, j);
if (arraySize != nFuncs) {
if (intermediateVarFlag[i] && comp->intermediate) {
index = (int)bdd_top_var_id(comp->var);
if (index == i) {
if (funcGroup[j] == 0) {
stack[size] = j;
size++;
stackFlag[j] = 1;
}
FindIntermediateSupport(vector, comp, nVars, 0,
stack, stackFlag, funcGroup, &size,
intermediateVarFlag,
intermediateVarFuncMap);
continue;
}
}
}
if (funcGroup[j])
continue;
if (comp->support[i]) {
stack[size] = j;
size++;
stackFlag[j] = 1;
}
}
}
if (comp->intermediate) {
index = (int)bdd_top_var_id(comp->var);
support[index] = 0;
}
}
if (nChosen < nFuncs) {
varId = split;
break;
}
}
FREE(stackFlag);
FREE(stack);
FREE(funcGroup);
FREE(varFlag);
if (arraySize > nFuncs) {
FREE(intermediateVarFlag);
FREE(intermediateVarFuncMap);
}
return(varId);
}
Here is the call graph for this function:
Here is the caller graph for this function:| static void FindIntermediateSupport | ( | array_t * | vector, |
| ImgComponent_t * | comp, | ||
| int | nVars, | ||
| int | nGroups, | ||
| int * | stack, | ||
| char * | stackFlag, | ||
| int * | funcGroup, | ||
| int * | size, | ||
| char * | intermediateVarFlag, | ||
| int * | intermediateVarFuncMap | ||
| ) | [static] |
Function********************************************************************
Synopsis [Finds all other fanin intermediate functions of a given intermediate function.]
Description [Finds all other fanin intermediate functions of a given intermediate function. Adds the only intermediate functions are not in the stack. Updates the stack information.]
SideEffects []
Definition at line 2907 of file imgTfmFwd.c.
{
int i, f;
ImgComponent_t *intermediateComp;
for (i = 0; i < nVars; i++) {
if (comp->support[i]) {
if (intermediateVarFlag[i]) {
f = intermediateVarFuncMap[i];
if (stackFlag[f] || funcGroup[f] == nGroups + 1)
continue;
stack[*size] = f;
(*size)++;
stackFlag[f] = 1;
intermediateComp = array_fetch(ImgComponent_t *, vector, f);
FindIntermediateSupport(vector, intermediateComp, nVars, nGroups,
stack, stackFlag, funcGroup, size,
intermediateVarFlag, intermediateVarFuncMap);
}
}
}
}
Here is the caller graph for this function:| static mdd_t * ImageByInputSplit | ( | ImgTfmInfo_t * | info, |
| array_t * | vector, | ||
| mdd_t * | constraint, | ||
| mdd_t * | from, | ||
| array_t * | relationArray, | ||
| mdd_t * | cofactorCube, | ||
| mdd_t * | abstractCube, | ||
| int | splitMethod, | ||
| int | turnDepth, | ||
| int | depth | ||
| ) | [static] |
AutomaticStart
Function********************************************************************
Synopsis [Computes an image by input splitting.]
Description [Computes an image by input splitting.]
SideEffects []
Definition at line 638 of file imgTfmFwd.c.
{
array_t *newVector, *tmpVector;
mdd_t *new_, *resT, *resE, *res, *resPart, *resTmp;
mdd_t *var, *varNot, *cube, *tmp, *func;
int size, i, j, k, vectorSize;
array_t *vectorArray, *varArray;
int hit, turnFlag;
int split, nGroups, cubeSize;
mdd_t *refResult, *product;
mdd_t *newFrom, *fromT, *fromE;
ImgComponent_t *comp;
array_t *relationArrayT, *relationArrayE, *partRelationArray;
int constConstrain;
int nRecur;
array_t *newRelationArray, *tmpRelationArray, *abstractVars;
mdd_t *cofactor, *abstract;
mdd_t *newCofactorCube, *newAbstractCube;
mdd_t *partCofactorCube, *partAbstractCube;
mdd_t *cofactorCubeT, *cofactorCubeE;
mdd_t *abstractCubeT, *abstractCubeE;
mdd_t *essentialCube, *tmpRes;
int findEssential;
int foundEssentialDepth;
int foundEssentialDepthT, foundEssentialDepthE;
array_t *vectorT, *vectorE;
mdd_t *andT, *andE, *one;
float prevLambda;
int prevTotal, prevVectorBddSize, prevVectorSize;
int arraySize, nFuncs;
newRelationArray = NIL(array_t);
if (info->option->delayedSplit && relationArray) {
ImgVectorConstrain(info, vector, constraint, relationArray,
&newVector, &res, &newRelationArray,
&cofactor, &abstract, TRUE);
newCofactorCube = mdd_and(cofactorCube, cofactor, 1, 1);
mdd_free(cofactor);
newAbstractCube = mdd_and(abstractCube, abstract, 1, 1);
mdd_free(abstract);
if (info->option->debug) {
refResult = ImgImageByHybrid(info, newVector, from);
resPart = ImgImageByHybridWithStaticSplit(info, NIL(array_t), from,
newRelationArray,
newCofactorCube,
newAbstractCube);
assert(mdd_equal(refResult, resPart));
mdd_free(refResult);
mdd_free(resPart);
}
} else {
ImgVectorConstrain(info, vector, constraint, relationArray,
&newVector, &res, &newRelationArray,
NIL(mdd_t *), NIL(mdd_t *), TRUE);
newCofactorCube = NIL(mdd_t);
newAbstractCube = NIL(mdd_t);
if (info->option->debug) {
refResult = ImgImageByHybrid(info, newVector, from);
resPart = ImgImageByHybridWithStaticSplit(info, NIL(array_t), from,
newRelationArray,
NIL(mdd_t), NIL(mdd_t));
assert(mdd_equal(refResult, resPart));
mdd_free(refResult);
refResult = ImgImageByHybridWithStaticSplit(info, NIL(array_t), from,
relationArray,
NIL(mdd_t), NIL(mdd_t));
resTmp = mdd_and(resPart, res, 1, 1);
mdd_free(resPart);
assert(mdd_equal(refResult, resTmp));
mdd_free(refResult);
mdd_free(resTmp);
}
}
if (info->option->checkEquivalence &&
relationArray && !info->option->buildPartialTR) {
assert(ImgCheckEquivalence(info, newVector, newRelationArray,
newCofactorCube, newAbstractCube, 0));
}
if (from && info->option->findEssential) {
if (info->option->findEssential == 1)
findEssential = 1;
else {
if (depth >= info->lastFoundEssentialDepth)
findEssential = 1;
else
findEssential = 0;
}
} else
findEssential = 0;
if (findEssential) {
essentialCube = bdd_find_essential_cube(from);
if (!bdd_is_tautology(essentialCube, 1)) {
info->averageFoundEssential = (info->averageFoundEssential *
(float)info->nFoundEssentials + (float)(bdd_size(essentialCube) - 1)) /
(float)(info->nFoundEssentials + 1);
info->averageFoundEssentialDepth = (info->averageFoundEssentialDepth *
(float)info->nFoundEssentials + (float)depth) /
(float)(info->nFoundEssentials + 1);
if (info->nFoundEssentials == 0 || depth < info->topFoundEssentialDepth)
info->topFoundEssentialDepth = depth;
info->nFoundEssentials++;
if (info->option->printEssential && depth < IMG_TF_MAX_PRINT_DEPTH)
info->foundEssentials[depth]++;
tmpVector = newVector;
tmpRelationArray = newRelationArray;
if (info->option->delayedSplit && relationArray) {
ImgVectorMinimize(info, tmpVector, essentialCube, NIL(mdd_t),
tmpRelationArray, &newVector, &tmpRes,
&newRelationArray, &cofactor, &abstract);
tmp = newCofactorCube;
newCofactorCube = mdd_and(tmp, cofactor, 1, 1);
mdd_free(tmp);
mdd_free(cofactor);
tmp = newAbstractCube;
newAbstractCube = mdd_and(tmp, abstract, 1, 1);
mdd_free(tmp);
mdd_free(abstract);
} else {
ImgVectorMinimize(info, tmpVector, essentialCube, NIL(mdd_t),
tmpRelationArray, &newVector, &tmpRes,
&newRelationArray, NIL(mdd_t *), NIL(mdd_t *));
}
tmp = res;
res = mdd_and(tmp, tmpRes, 1, 1);
mdd_free(tmp);
ImgVectorFree(tmpVector);
if (tmpRelationArray && tmpRelationArray != relationArray &&
tmpRelationArray != newRelationArray)
mdd_array_free(tmpRelationArray);
foundEssentialDepth = depth;
} else
foundEssentialDepth = info->option->maxEssentialDepth;
mdd_free(essentialCube);
foundEssentialDepthT = info->option->maxEssentialDepth;
foundEssentialDepthE = info->option->maxEssentialDepth;
} else {
/* To remove compiler warnings */
foundEssentialDepth = -1;
foundEssentialDepthT = -1;
foundEssentialDepthE = -1;
}
if (info->option->debug) {
if (relationArray && from) {
refResult = ImgImageByHybrid(info, newVector, from);
resPart = ImgImageByHybridWithStaticSplit(info, NIL(array_t), from,
newRelationArray,
newCofactorCube,
newAbstractCube);
assert(mdd_equal(refResult, resPart));
mdd_free(refResult);
mdd_free(resPart);
}
}
info->nRecursion++;
arraySize = array_n(newVector);
if (info->nIntermediateVars)
nFuncs = ImgVectorFunctionSize(newVector);
else
nFuncs = arraySize;
if (nFuncs <= 1) {
if (info->useConstraint) {
if (nFuncs == 1) {
comp = array_fetch(ImgComponent_t *, newVector, 0);
if (arraySize > 1)
func = ImgGetComposedFunction(newVector);
else
func = comp->func;
if (mdd_lequal(from, func, 1, 1)) { /* func | from = 1 */
tmp = res;
res = mdd_and(tmp, comp->var, 1, 1);
mdd_free(tmp);
} else if (mdd_lequal(func, from, 1, 0)) { /* func | from = 0 */
tmp = res;
res = mdd_and(tmp, comp->var, 1, 0);
mdd_free(tmp);
}
if (arraySize > 1)
mdd_free(func);
}
}
if (relationArray && newRelationArray != relationArray)
mdd_array_free(newRelationArray);
if (newCofactorCube)
mdd_free(newCofactorCube);
if (newAbstractCube)
mdd_free(newAbstractCube);
ImgVectorFree(newVector);
info->averageDepth = (info->averageDepth * (float)info->nLeaves +
(float)depth) / (float)(info->nLeaves + 1);
if (depth > info->maxDepth)
info->maxDepth = depth;
info->nLeaves++;
if (findEssential)
info->foundEssentialDepth = foundEssentialDepth;
if (info->option->debug)
assert(TfmCheckImageValidity(info, res));
return(res);
}
turnFlag = 0;
if (splitMethod == 3 && turnDepth == -1) {
if (depth < info->option->splitMinDepth) {
info->nSplits++;
turnFlag = 0;
} else if (depth > info->option->splitMaxDepth) {
info->nConjoins++;
turnFlag = 1;
} else {
turnFlag = ImgDecideSplitOrConjoin(info, newVector, from, 0,
newRelationArray, newCofactorCube,
newAbstractCube, 0, depth);
}
} else {
if (splitMethod != 0) {
if (depth == turnDepth)
turnFlag = 1;
}
}
if (turnFlag || nFuncs == 2) {
hit = 1;
if (!info->imgCache ||
!(resPart = ImgCacheLookupTable(info, info->imgCache, newVector,
from))) {
hit = 0;
if (nFuncs == 2) {
if (info->useConstraint) {
ImgVectorConstrain(info, newVector, from, NIL(array_t),
&tmpVector, &resTmp, NIL(array_t *),
NIL(mdd_t *), NIL(mdd_t *), FALSE);
if (array_n(tmpVector) <= 1)
resPart = resTmp;
else {
mdd_free(resTmp);
resPart = ImageFast2(info, tmpVector);
}
ImgVectorFree(tmpVector);
} else
resPart = ImageFast2(info, newVector);
} else if (splitMethod == 2) {
if (info->useConstraint) {
ImgVectorConstrain(info, newVector, from, NIL(array_t),
&tmpVector, &resTmp, NIL(array_t *),
NIL(mdd_t *), NIL(mdd_t *), FALSE);
if (array_n(tmpVector) <= 1)
resPart = resTmp;
else if (array_n(tmpVector) == 2) {
mdd_free(resTmp);
resPart = ImageFast2(info, tmpVector);
} else {
tmp = mdd_one(info->manager);
resPart = ImageByOutputSplit(info, tmpVector, tmp, depth + 1);
mdd_free(tmp);
tmp = resPart;
resPart = mdd_and(tmp, resTmp, 1, 1);
mdd_free(tmp);
mdd_free(resTmp);
}
ImgVectorFree(tmpVector);
} else {
tmp = mdd_one(info->manager);
resPart = ImageByOutputSplit(info, newVector, tmp, depth + 1);
mdd_free(tmp);
}
} else {
if (relationArray) {
resPart = ImgImageByHybridWithStaticSplit(info, NIL(array_t), from,
newRelationArray,
newCofactorCube,
newAbstractCube);
} else
resPart = ImgImageByHybrid(info, newVector, from);
}
if (info->imgCache) {
if (from) {
ImgCacheInsertTable(info->imgCache, newVector, mdd_dup(from),
resPart);
} else
ImgCacheInsertTable(info->imgCache, newVector, NIL(mdd_t), resPart);
}
}
if (relationArray && newRelationArray != relationArray)
mdd_array_free(newRelationArray);
if (newCofactorCube)
mdd_free(newCofactorCube);
if (newAbstractCube)
mdd_free(newAbstractCube);
if (info->option->debug) {
refResult = ImgImageByHybrid(info, newVector, from);
assert(mdd_equal(refResult, resPart));
mdd_free(refResult);
}
new_ = mdd_and(res, resPart, 1, 1);
if (info->option->verbosity) {
size = bdd_size(new_);
if (size > info->maxIntermediateSize)
info->maxIntermediateSize = size;
if (info->option->printBddSize) {
fprintf(vis_stdout, "** tfm info: bdd_and(%d,%d) = %d\n",
bdd_size(res), bdd_size(resPart), size);
}
}
mdd_free(res);
res = new_;
if (!info->imgCache || hit) {
mdd_free(resPart);
ImgVectorFree(newVector);
}
info->averageDepth = (info->averageDepth * (float)info->nLeaves +
(float)depth) / (float)(info->nLeaves + 1);
if (depth > info->maxDepth)
info->maxDepth = depth;
info->nLeaves++;
if (turnFlag)
info->nTurns++;
if (findEssential)
info->foundEssentialDepth = foundEssentialDepth;
if (info->option->debug)
assert(TfmCheckImageValidity(info, res));
return(res);
}
if (info->imgCache) {
resPart = ImgCacheLookupTable(info, info->imgCache, newVector, from);
if (resPart) {
if (info->option->debug) {
refResult = ImgImageByHybrid(info, newVector, from);
assert(mdd_equal(refResult, resPart));
mdd_free(refResult);
}
new_ = mdd_and(res, resPart, 1, 1);
if (info->option->verbosity) {
size = bdd_size(new_);
if (size > info->maxIntermediateSize)
info->maxIntermediateSize = size;
if (info->option->printBddSize) {
fprintf(vis_stdout, "** tfm info: bdd_and(%d,%d) = %d\n",
bdd_size(res), bdd_size(resPart), size);
}
}
mdd_free(res);
mdd_free(resPart);
res = new_;
ImgVectorFree(newVector);
if (relationArray && newRelationArray != relationArray)
mdd_array_free(newRelationArray);
if (newCofactorCube)
mdd_free(newCofactorCube);
if (newAbstractCube)
mdd_free(newAbstractCube);
if (findEssential)
info->foundEssentialDepth = foundEssentialDepth;
if (info->option->debug)
assert(TfmCheckImageValidity(info, res));
return(res);
}
}
if (info->option->splitCubeFunc) {
split = -1;
cubeSize = 0;
for (i = 0; i < array_n(newVector); i++) {
comp = array_fetch(ImgComponent_t *, newVector, i);
if (bdd_is_cube(comp->func)) {
if (split == -1 || info->option->splitCubeFunc == 1 ||
bdd_size(comp->func) > cubeSize) {
split = i;
cubeSize = bdd_size(comp->func);
break;
}
}
}
if (split != -1) {
comp = array_fetch(ImgComponent_t *, newVector, split);
info->nCubeSplits++;
if (info->option->delayedSplit && relationArray) {
ImgVectorConstrain(info, newVector, comp->func, newRelationArray,
&vectorT, &andT, &relationArrayT,
&cofactor, &abstract, FALSE);
cofactorCubeT = mdd_and(newCofactorCube, cofactor, 1, 1);
mdd_free(cofactor);
abstractCubeT = mdd_and(newAbstractCube, abstract, 1, 1);
mdd_free(abstract);
} else {
ImgVectorConstrain(info, newVector, comp->func, newRelationArray,
&vectorT, &andT, &relationArrayT,
NIL(mdd_t *), NIL(mdd_t *), FALSE);
cofactorCubeT = NIL(mdd_t);
abstractCubeT = NIL(mdd_t);
}
if (from)
newFrom = bdd_cofactor(from, comp->func);
else
newFrom = from;
if (info->option->checkEquivalence &&
relationArray && !info->option->buildPartialTR) {
assert(ImgCheckEquivalence(info, vectorT, relationArrayT,
cofactorCubeT, abstractCubeT, 0));
}
one = mdd_one(info->manager);
if (newFrom && bdd_is_tautology(newFrom, 0))
resT = mdd_zero(info->manager);
else {
prevLambda = info->prevLambda;
prevTotal = info->prevTotal;
prevVectorBddSize = info->prevVectorBddSize;
prevVectorSize = info->prevVectorSize;
resT = ImageByInputSplit(info, vectorT, one, newFrom,
relationArrayT, cofactorCubeT, abstractCubeT,
splitMethod, turnDepth, depth + 1);
info->prevLambda = prevLambda;
info->prevTotal = prevTotal;
info->prevVectorBddSize = prevVectorBddSize;
info->prevVectorSize = prevVectorSize;
}
ImgVectorFree(vectorT);
if (newFrom)
mdd_free(newFrom);
if (!bdd_is_tautology(andT, 1)) {
tmp = resT;
resT = mdd_and(tmp, andT, 1, 1);
mdd_free(tmp);
}
if (findEssential)
foundEssentialDepthT = info->foundEssentialDepth;
if (relationArrayT && relationArrayT != newRelationArray)
mdd_array_free(relationArrayT);
if (cofactorCubeT && cofactorCubeT != newCofactorCube)
mdd_free(cofactorCubeT);
if (abstractCubeT && abstractCubeT != newAbstractCube)
mdd_free(abstractCubeT);
tmp = mdd_not(comp->func);
if (info->option->delayedSplit && relationArray) {
ImgVectorConstrain(info, newVector, tmp, newRelationArray,
&vectorE, &andE, &relationArrayE,
&cofactor, &abstract, FALSE);
cofactorCubeE = mdd_and(newCofactorCube, cofactor, 1, 1);
mdd_free(cofactor);
abstractCubeE = mdd_and(newAbstractCube, abstract, 1, 1);
mdd_free(abstract);
} else {
ImgVectorConstrain(info, newVector, tmp, newRelationArray,
&vectorE, &andE, &relationArrayE,
NIL(mdd_t *), NIL(mdd_t *), FALSE);
cofactorCubeE = NIL(mdd_t);
abstractCubeE = NIL(mdd_t);
}
if (from)
newFrom = bdd_cofactor(from, tmp);
else
newFrom = from;
mdd_free(tmp);
if (relationArray && newRelationArray != relationArray)
mdd_array_free(newRelationArray);
if (newCofactorCube)
mdd_free(newCofactorCube);
if (newAbstractCube)
mdd_free(newAbstractCube);
if (info->option->checkEquivalence &&
relationArray && !info->option->buildPartialTR) {
assert(ImgCheckEquivalence(info, vectorE, relationArrayE,
cofactorCubeE, abstractCubeE, 0));
}
if (newFrom && bdd_is_tautology(newFrom, 0))
resE = mdd_zero(info->manager);
else {
resE = ImageByInputSplit(info, vectorE, one, newFrom,
relationArrayE, cofactorCubeE, abstractCubeE,
splitMethod, turnDepth, depth + 1);
}
ImgVectorFree(vectorE);
if (newFrom)
mdd_free(newFrom);
if (!bdd_is_tautology(andE, 1)) {
tmp = resE;
resE = mdd_and(tmp, andE, 1, 1);
mdd_free(tmp);
}
if (findEssential)
foundEssentialDepthE = info->foundEssentialDepth;
if (relationArrayE && relationArrayE != newRelationArray)
mdd_array_free(relationArrayE);
if (cofactorCubeE && cofactorCubeE != newCofactorCube)
mdd_free(cofactorCubeE);
if (abstractCubeE && abstractCubeE != newAbstractCube)
mdd_free(abstractCubeE);
resPart = bdd_ite(comp->var, resT, resE, 1, 1, 1);
if (info->option->verbosity) {
size = bdd_size(resPart);
if (size > info->maxIntermediateSize)
info->maxIntermediateSize = size;
if (info->option->printBddSize) {
fprintf(vis_stdout, "** tfm info: bdd_ite(2,%d,%d) = %d\n",
bdd_size(resT), bdd_size(resE), size);
}
}
mdd_free(one);
if (info->imgCache)
ImgCacheInsertTable(info->imgCache, newVector, NIL(mdd_t), resPart);
if (info->option->debug) {
refResult = ImgImageByHybrid(info, newVector, from);
assert(mdd_equal(refResult, resPart));
mdd_free(refResult);
}
new_ = mdd_and(res, resPart, 1, 1);
if (info->option->verbosity) {
size = bdd_size(new_);
if (size > info->maxIntermediateSize)
info->maxIntermediateSize = size;
if (info->option->printBddSize) {
fprintf(vis_stdout, "** tfm info: bdd_and(%d,%d) = %d\n",
bdd_size(res), bdd_size(resPart), size);
}
}
mdd_free(res);
res = new_;
if (info->option->debug) {
refResult = ImgImageByHybrid(info, newVector, from);
assert(mdd_equal(refResult, resPart));
mdd_free(refResult);
}
if (!info->imgCache) {
mdd_free(resPart);
ImgVectorFree(newVector);
}
info->averageDepth = (info->averageDepth * (float)info->nLeaves +
(float)depth) / (float)(info->nLeaves + 1);
if (depth > info->maxDepth)
info->maxDepth = depth;
info->nLeaves++;
if (turnFlag)
info->nTurns++;
if (findEssential) {
if (foundEssentialDepth == info->option->maxEssentialDepth) {
if (foundEssentialDepthT < foundEssentialDepthE)
foundEssentialDepth = foundEssentialDepthT;
else
foundEssentialDepth = foundEssentialDepthE;
}
info->foundEssentialDepth = foundEssentialDepth;
}
if (info->option->debug)
assert(TfmCheckImageValidity(info, res));
return(res);
}
}
/* compute disconnected component and best variable selection */
vectorArray = array_alloc(array_t *, 0);
varArray = array_alloc(int, 0);
if (info->option->delayedSplit && relationArray) {
nGroups = ImageDecomposeAndChooseSplitVar(info, newVector, from, 0,
info->option->inputSplit,
info->option->piSplitFlag,
vectorArray, varArray, &product,
newRelationArray, &tmpRelationArray,
&cofactor, &abstract);
} else {
nGroups = ImageDecomposeAndChooseSplitVar(info, newVector, from, 0,
info->option->inputSplit,
info->option->piSplitFlag,
vectorArray, varArray, &product,
newRelationArray, &tmpRelationArray,
NIL(mdd_t *), NIL(mdd_t *));
cofactor = NIL(mdd_t);
abstract = NIL(mdd_t);
if (info->option->debug && nGroups >= 1) {
if (info->option->verbosity > 1) {
ImgPrintVectorDependency(info, newVector, info->option->verbosity);
PrintVectorDecomposition(info, vectorArray, varArray);
}
refResult = ImgImageByHybrid(info, newVector, from);
resPart = mdd_dup(product);
for (i = 0; i < array_n(vectorArray); i++) {
vector = array_fetch(array_t *, vectorArray, i);
resTmp = ImgImageByHybrid(info, vector, from);
tmp = resPart;
resPart = mdd_and(tmp, resTmp, 1, 1);
mdd_free(tmp);
mdd_free(resTmp);
if (arraySize > nFuncs) {
split = array_fetch(int, varArray, i);
assert(!st_is_member(info->intermediateVarsTable,
(char *)(long)split));
}
}
assert(mdd_equal(refResult, resPart));
mdd_free(refResult);
mdd_free(resPart);
}
}
vectorSize = array_n(newVector);
if ((!info->imgCache || nGroups <= 1) && !info->option->debug)
ImgVectorFree(newVector);
if (newRelationArray) {
if (newRelationArray != relationArray &&
tmpRelationArray != newRelationArray) {
mdd_array_free(newRelationArray);
}
newRelationArray = tmpRelationArray;
}
if (nGroups == 0) {
if (relationArray && newRelationArray != relationArray)
mdd_array_free(newRelationArray);
if (newCofactorCube)
mdd_free(newCofactorCube);
if (newAbstractCube)
mdd_free(newAbstractCube);
if (cofactor)
mdd_free(cofactor);
if (abstract)
mdd_free(abstract);
array_free(vectorArray);
array_free(varArray);
if (info->option->debug) {
refResult = ImgImageByHybrid(info, newVector, from);
assert(mdd_equal(refResult, product));
mdd_free(refResult);
ImgVectorFree(newVector);
}
new_ = mdd_and(res, product, 1, 1);
if (info->option->verbosity) {
size = bdd_size(new_);
if (size > info->maxIntermediateSize)
info->maxIntermediateSize = size;
if (info->option->printBddSize) {
fprintf(vis_stdout, "** tfm info: bdd_and(%d,%d) = %d\n",
bdd_size(res), bdd_size(product), size);
}
}
mdd_free(res);
mdd_free(product);
res = new_;
info->averageDepth = (info->averageDepth * (float)info->nLeaves +
(float)depth) / (float)(info->nLeaves + 1);
if (depth > info->maxDepth)
info->maxDepth = depth;
info->nLeaves++;
if (findEssential)
info->foundEssentialDepth = foundEssentialDepth;
if (info->option->debug)
assert(TfmCheckImageValidity(info, res));
return(res);
}
if (info->option->delayedSplit && relationArray) {
tmp = newCofactorCube;
newCofactorCube = mdd_and(tmp, cofactor, 1, 1);
mdd_free(tmp);
mdd_free(cofactor);
tmp = newAbstractCube;
newAbstractCube = mdd_and(tmp, abstract, 1, 1);
mdd_free(tmp);
mdd_free(abstract);
}
if (nGroups > 1) {
if (info->nDecomps == 0 || depth < info->topDecomp)
info->topDecomp = depth;
if (info->nDecomps == 0 || vectorSize > info->maxDecomp)
info->maxDecomp = vectorSize;
info->averageDecomp = (info->averageDecomp * (float)info->nDecomps +
(float)nGroups) / (float)(info->nDecomps + 1);
info->nDecomps++;
}
if (relationArray && nGroups > 1) {
abstractVars = array_alloc(mdd_t *, 0);
for (i = 0; i < array_n(vectorArray); i++) {
vector = array_fetch(array_t *, vectorArray, i);
cube = mdd_one(info->manager);
for (j = 0; j < nGroups; j++) {
if (j == i)
continue;
tmpVector = array_fetch(array_t *, vectorArray, j);
for (k = 0; k < array_n(tmpVector); k++) {
comp = array_fetch(ImgComponent_t *, tmpVector, k);
tmp = cube;
cube = mdd_and(cube, comp->var, 1, 1);
mdd_free(tmp);
}
}
tmp = ImgSubstitute(cube, info->functionData, Img_D2R_c);
mdd_free(cube);
array_insert_last(mdd_t *, abstractVars, tmp);
}
} else
abstractVars = NIL(array_t);
for (i = 0; i < array_n(vectorArray); i++) {
vector = array_fetch(array_t *, vectorArray, i);
if (from)
newFrom = mdd_dup(from);
else
newFrom = from;
if (relationArray) {
if (nGroups == 1) {
partRelationArray = newRelationArray;
if (info->option->delayedSplit) {
partCofactorCube = newCofactorCube;
partAbstractCube = newAbstractCube;
} else {
partCofactorCube = NIL(mdd_t);
partAbstractCube = NIL(mdd_t);
}
} else {
cube = array_fetch(mdd_t *, abstractVars, i);
if (info->option->delayedSplit) {
partRelationArray = newRelationArray;
partCofactorCube = mdd_dup(newCofactorCube);
partAbstractCube = mdd_and(newAbstractCube, cube, 1, 1);
} else {
partRelationArray = ImgGetAbstractedRelationArray(info->manager,
newRelationArray,
cube);
mdd_free(cube);
partCofactorCube = NIL(mdd_t);
partAbstractCube = NIL(mdd_t);
}
}
if (info->option->debug) {
refResult = ImgImageByHybrid(info, vector, from);
resPart = ImgImageByHybridWithStaticSplit(info, NIL(array_t), from,
partRelationArray,
partCofactorCube,
partAbstractCube);
assert(mdd_equal(refResult, resPart));
mdd_free(refResult);
mdd_free(resPart);
}
} else {
partRelationArray = newRelationArray;
partCofactorCube = NIL(mdd_t);
partAbstractCube = NIL(mdd_t);
}
hit = 1;
if (!info->imgCache || nGroups == 1 ||
!(resPart = ImgCacheLookupTable(info, info->imgCache, vector,
newFrom))) {
hit = 0;
if (arraySize > nFuncs)
size = ImgVectorFunctionSize(vector);
else
size = array_n(vector);
if (size == 1) {
comp = array_fetch(ImgComponent_t *, vector, 0);
if (array_n(vector) > 1)
func = ImgGetComposedFunction(vector);
else
func = comp->func;
if (info->useConstraint) {
constConstrain = ImgConstConstrain(func, newFrom);
if (constConstrain == 1)
resPart = mdd_dup(comp->var);
else if (constConstrain == 0)
resPart = mdd_not(comp->var);
else
resPart = mdd_one(info->manager);
} else {
if (bdd_is_tautology(func, 1))
resPart = mdd_dup(comp->var);
else if (bdd_is_tautology(func, 0))
resPart = mdd_not(comp->var);
else
resPart = mdd_one(info->manager);
}
if (array_n(vector) > 1)
mdd_free(func);
info->averageDepth = (info->averageDepth * (float)info->nLeaves +
(float)depth) / (float)(info->nLeaves + 1);
if (depth > info->maxDepth)
info->maxDepth = depth;
info->nLeaves++;
} else if (size == 2) {
if (info->useConstraint) {
ImgVectorConstrain(info, vector, newFrom, NIL(array_t),
&newVector, &resTmp, NIL(array_t *),
NIL(mdd_t *), NIL(mdd_t *), FALSE);
if (array_n(newVector) <= 1)
resPart = resTmp;
else {
mdd_free(resTmp);
resPart = ImageFast2(info, newVector);
}
ImgVectorFree(newVector);
} else
resPart = ImageFast2(info, vector);
info->averageDepth = (info->averageDepth * (float)info->nLeaves +
(float)depth) / (float)(info->nLeaves + 1);
if (depth > info->maxDepth)
info->maxDepth = depth;
info->nLeaves++;
} else {
nRecur = 0;
split = array_fetch(int, varArray, i);
if (partRelationArray && info->imgKeepPiInTr == FALSE) {
if (st_lookup(info->quantifyVarsTable, (char *)(long)split,
NIL(char *))) {
int newSplit;
/* checks the splitting is valid */
newSplit = CheckIfValidSplitOrGetNew(info, split, vector,
partRelationArray, from);
if (newSplit == -1) {
resPart = ImgImageByHybrid(info, vector, from);
info->averageDepth = (info->averageDepth * (float)info->nLeaves +
(float)depth) / (float)(info->nLeaves + 1);
if (depth > info->maxDepth)
info->maxDepth = depth;
info->nLeaves++;
info->nTurns++;
goto cache;
}
split = newSplit;
}
}
var = bdd_var_with_index(info->manager, split);
if (newFrom)
fromT = bdd_cofactor(newFrom, var);
else
fromT = NIL(mdd_t);
if (partRelationArray) {
if (info->option->delayedSplit) {
relationArrayT = partRelationArray;
cofactorCubeT = mdd_and(partCofactorCube, var, 1, 1);
} else {
relationArrayT = ImgGetCofactoredRelationArray(partRelationArray,
var);
cofactorCubeT = partCofactorCube;
}
} else {
relationArrayT = NIL(array_t);
cofactorCubeT = NIL(mdd_t);
}
if (!fromT || !bdd_is_tautology(fromT, 0)) {
prevLambda = info->prevLambda;
prevTotal = info->prevTotal;
prevVectorBddSize = info->prevVectorBddSize;
prevVectorSize = info->prevVectorSize;
resT = ImageByInputSplit(info, vector, var, fromT,
relationArrayT, cofactorCubeT, partAbstractCube,
splitMethod, turnDepth, depth + 1);
if (info->option->debug) {
refResult = ImgImageByHybridWithStaticSplit(info, NIL(array_t),
fromT, relationArrayT,
cofactorCubeT,
partAbstractCube);
assert(mdd_equal(refResult, resT));
mdd_free(refResult);
}
info->prevLambda = prevLambda;
info->prevTotal = prevTotal;
info->prevVectorBddSize = prevVectorBddSize;
info->prevVectorSize = prevVectorSize;
if (findEssential)
foundEssentialDepthT = info->foundEssentialDepth;
nRecur++;
} else
resT = mdd_zero(info->manager);
if (fromT)
mdd_free(fromT);
if (relationArrayT && relationArrayT != partRelationArray)
mdd_array_free(relationArrayT);
if (cofactorCubeT && cofactorCubeT != partCofactorCube)
mdd_free(cofactorCubeT);
if (bdd_is_tautology(resT, 1)) {
mdd_free(var);
resPart = resT;
info->nEmptySubImage++;
} else {
varNot = mdd_not(var);
mdd_free(var);
if (newFrom)
fromE = bdd_cofactor(newFrom, varNot);
else
fromE = NIL(mdd_t);
if (partRelationArray) {
if (info->option->delayedSplit) {
relationArrayE = partRelationArray;
cofactorCubeE = mdd_and(partCofactorCube, varNot, 1, 1);
} else {
relationArrayE = ImgGetCofactoredRelationArray(partRelationArray,
varNot);
cofactorCubeE = partCofactorCube;
}
} else {
relationArrayE = NIL(array_t);
cofactorCubeE = NIL(mdd_t);
}
if (!fromE || !bdd_is_tautology(fromE, 0)) {
resE = ImageByInputSplit(info, vector, varNot, fromE,
relationArrayE, cofactorCubeE, partAbstractCube,
splitMethod, turnDepth, depth + 1);
if (info->option->debug) {
refResult = ImgImageByHybridWithStaticSplit(info, NIL(array_t),
fromE, relationArrayE,
cofactorCubeE,
partAbstractCube);
assert(mdd_equal(refResult, resE));
mdd_free(refResult);
}
if (findEssential)
foundEssentialDepthE = info->foundEssentialDepth;
nRecur++;
} else
resE = mdd_zero(info->manager);
mdd_free(varNot);
if (fromE)
mdd_free(fromE);
if (relationArrayE && relationArrayE != partRelationArray)
mdd_array_free(relationArrayE);
if (cofactorCubeE && cofactorCubeE != partCofactorCube)
mdd_free(cofactorCubeE);
resPart = mdd_or(resT, resE, 1, 1);
if (info->option->debug) {
refResult = ImgImageByHybrid(info, vector, from);
assert(mdd_equal(refResult, resPart));
mdd_free(refResult);
}
if (info->option->verbosity) {
size = bdd_size(resPart);
if (size > info->maxIntermediateSize)
info->maxIntermediateSize = size;
if (info->option->printBddSize) {
fprintf(vis_stdout, "** tfm info: bdd_or(%d,%d) = %d\n",
bdd_size(resT), bdd_size(resE), size);
}
}
mdd_free(resT);
mdd_free(resE);
}
if (nRecur == 0) {
info->averageDepth = (info->averageDepth * (float)info->nLeaves +
(float)depth) / (float)(info->nLeaves + 1);
if (depth > info->maxDepth)
info->maxDepth = depth;
info->nLeaves++;
}
}
cache:
if (info->imgCache) {
ImgCacheInsertTable(info->imgCache, vector, newFrom, resPart);
if (info->option->debug) {
refResult = ImgImageByHybrid(info, vector, newFrom);
assert(mdd_equal(refResult, resPart));
mdd_free(refResult);
}
}
}
if (!info->imgCache || hit) {
ImgVectorFree(vector);
if (newFrom)
mdd_free(newFrom);
}
new_ = mdd_and(product, resPart, 1, 1);
if (info->option->verbosity) {
size = bdd_size(new_);
if (size > info->maxIntermediateSize)
info->maxIntermediateSize = size;
if (info->option->printBddSize) {
fprintf(vis_stdout, "** tfm info: bdd_and(%d,%d) = %d\n",
bdd_size(product), bdd_size(resPart), size);
}
}
mdd_free(product);
if (!info->imgCache || hit)
mdd_free(resPart);
product = new_;
if (nGroups > 1 && partRelationArray != newRelationArray)
mdd_array_free(partRelationArray);
if (partCofactorCube && partCofactorCube != newCofactorCube)
mdd_free(partCofactorCube);
if (partAbstractCube && partAbstractCube != newAbstractCube)
mdd_free(partAbstractCube);
}
if (abstractVars)
array_free(abstractVars);
if (relationArray && newRelationArray != relationArray)
mdd_array_free(newRelationArray);
if (newCofactorCube)
mdd_free(newCofactorCube);
if (newAbstractCube)
mdd_free(newAbstractCube);
array_free(vectorArray);
array_free(varArray);
if (info->imgCache && nGroups > 1) {
if (from) {
ImgCacheInsertTable(info->imgCache, newVector, mdd_dup(from),
mdd_dup(product));
} else {
ImgCacheInsertTable(info->imgCache, newVector, NIL(mdd_t),
mdd_dup(product));
}
}
if (info->option->debug) {
refResult = ImgImageByHybrid(info, newVector, from);
assert(mdd_equal(refResult, product));
mdd_free(refResult);
if (!info->imgCache || nGroups == 1)
ImgVectorFree(newVector);
}
new_ = mdd_and(res, product, 1, 1);
if (info->option->verbosity) {
size = bdd_size(new_);
if (size > info->maxIntermediateSize)
info->maxIntermediateSize = size;
if (info->option->printBddSize) {
fprintf(vis_stdout, "** tfm info: bdd_and(%d,%d) = %d\n",
bdd_size(res), bdd_size(product), size);
}
}
mdd_free(res);
mdd_free(product);
res = new_;
if (findEssential) {
if (foundEssentialDepth == info->option->maxEssentialDepth) {
if (foundEssentialDepthT < foundEssentialDepthE)
foundEssentialDepth = foundEssentialDepthT;
else
foundEssentialDepth = foundEssentialDepthE;
}
info->foundEssentialDepth = foundEssentialDepth;
}
if (info->option->debug)
assert(TfmCheckImageValidity(info, res));
return(res);
}
Here is the call graph for this function:
Here is the caller graph for this function:| static mdd_t * ImageByOutputSplit | ( | ImgTfmInfo_t * | info, |
| array_t * | vector, | ||
| mdd_t * | constraint, | ||
| int | depth | ||
| ) | [static] |
Function********************************************************************
Synopsis [Computes an image by output splitting.]
Description [Computes an image by output splitting.]
SideEffects []
Definition at line 1987 of file imgTfmFwd.c.
{
array_t *newVector;
mdd_t *new_, *resT, *resE, *res, *resPart;
mdd_t *constrain, *tmp, *func;
int size, i, vectorSize;
array_t *vectorArray, *varArray;
ImgComponent_t *comp;
int hit;
int split, nGroups;
mdd_t *product, *refResult;
ImgVectorConstrain(info, vector, constraint, NIL(array_t),
&newVector, &res, NIL(array_t *),
NIL(mdd_t *), NIL(mdd_t *), FALSE);
info->nRecursion++;
if (info->nIntermediateVars)
size = ImgVectorFunctionSize(newVector);
else
size = array_n(newVector);
if (size <= 1) {
ImgVectorFree(newVector);
info->averageDepth = (info->averageDepth * (float)info->nLeaves +
(float)depth) / (float)(info->nLeaves + 1);
if (depth > info->maxDepth)
info->maxDepth = depth;
info->nLeaves++;
return(res);
}
if (size == 2) {
hit = 1;
if (!info->imgCache ||
!(resPart = ImgCacheLookupTable(info, info->imgCache, newVector,
NIL(bdd_t)))) {
hit = 0;
resPart = ImageFast2(info, newVector);
if (info->imgCache)
ImgCacheInsertTable(info->imgCache, newVector, NIL(bdd_t), resPart);
}
if (info->option->debug) {
refResult = ImgImageByHybrid(info, newVector, NIL(mdd_t));
assert(mdd_equal(refResult, resPart));
mdd_free(refResult);
}
new_ = mdd_and(res, resPart, 1, 1);
if (info->option->verbosity) {
size = bdd_size(new_);
if (size > info->maxIntermediateSize)
info->maxIntermediateSize = size;
if (info->option->printBddSize) {
fprintf(vis_stdout, "** tfm info: bdd_and(%d,%d) = %d\n",
bdd_size(res), bdd_size(resPart), size);
}
}
mdd_free(res);
if (!info->imgCache || hit) {
mdd_free(resPart);
ImgVectorFree(newVector);
}
info->averageDepth = (info->averageDepth * (float)info->nLeaves +
(float)depth) / (float)(info->nLeaves + 1);
if (depth > info->maxDepth)
info->maxDepth = depth;
info->nLeaves++;
return(new_);
}
if (info->imgCache) {
resPart = ImgCacheLookupTable(info, info->imgCache, newVector, NIL(mdd_t));
if (resPart) {
if (info->option->debug) {
refResult = ImgImageByHybrid(info, newVector, NIL(mdd_t));
assert(mdd_equal(refResult, resPart));
mdd_free(refResult);
}
new_ = mdd_and(res, resPart, 1, 1);
if (info->option->verbosity) {
size = bdd_size(new_);
if (size > info->maxIntermediateSize)
info->maxIntermediateSize = size;
if (info->option->printBddSize) {
fprintf(vis_stdout, "** tfm info: bdd_and(%d,%d) = %d\n",
bdd_size(res), bdd_size(resPart), size);
}
}
mdd_free(res);
mdd_free(resPart);
res = new_;
ImgVectorFree(newVector);
return(res);
}
}
/* compute disconnected component and best variable selection */
vectorArray = array_alloc(array_t *, 0);
varArray = array_alloc(array_t *, 0);
nGroups = ImageDecomposeAndChooseSplitVar(info, newVector, NIL(mdd_t), 1,
info->option->outputSplit, 0,
vectorArray, varArray, &product,
NIL(array_t), NIL(array_t *),
NIL(mdd_t *), NIL(mdd_t *));
vectorSize = array_n(newVector);
if ((!info->imgCache || nGroups <= 1) && !info->option->debug)
ImgVectorFree(newVector);
if (nGroups == 0) {
array_free(vectorArray);
array_free(varArray);
if (info->option->debug) {
refResult = ImgImageByHybrid(info, newVector, NIL(mdd_t));
assert(mdd_equal(refResult, product));
mdd_free(refResult);
ImgVectorFree(newVector);
}
new_ = mdd_and(res, product, 1, 1);
if (info->option->verbosity) {
size = bdd_size(new_);
if (size > info->maxIntermediateSize)
info->maxIntermediateSize = size;
if (info->option->printBddSize) {
fprintf(vis_stdout, "** tfm info: bdd_and(%d,%d) = %d\n",
bdd_size(res), bdd_size(product), size);
}
}
mdd_free(res);
mdd_free(product);
res = new_;
info->averageDepth = (info->averageDepth * (float)info->nLeaves +
(float)depth) / (float)(info->nLeaves + 1);
if (depth > info->maxDepth)
info->maxDepth = depth;
info->nLeaves++;
return(res);
} else if (nGroups > 1) {
if (info->nDecomps == 0 || depth < info->topDecomp)
info->topDecomp = depth;
if (info->nDecomps == 0 || vectorSize > info->maxDecomp)
info->maxDecomp = vectorSize;
info->averageDecomp = (info->averageDecomp * (float)info->nDecomps +
(float)nGroups) / (float)(info->nDecomps + 1);
info->nDecomps++;
}
product = mdd_one(info->manager);
for (i = 0; i < array_n(vectorArray); i++) {
vector = array_fetch(array_t *, vectorArray, i);
hit = 1;
if (!info->imgCache || nGroups == 1 ||
!(resPart = ImgCacheLookupTable(info, info->imgCache, vector,
NIL(bdd_t)))) {
hit = 0;
if (info->nIntermediateVars)
size = ImgVectorFunctionSize(vector);
else
size = array_n(vector);
if (size == 1) {
comp = array_fetch(ImgComponent_t *, vector, 0);
if (array_n(vector) > 1)
func = ImgGetComposedFunction(vector);
else
func = comp->func;
if (bdd_is_tautology(func, 1))
resPart = mdd_dup(comp->var);
else if (bdd_is_tautology(func, 0))
resPart = mdd_not(comp->var);
else
resPart = mdd_one(info->manager);
if (array_n(vector) > 1)
mdd_free(func);
info->averageDepth = (info->averageDepth * (float)info->nLeaves +
(float)depth) / (float)(info->nLeaves + 1);
if (depth > info->maxDepth)
info->maxDepth = depth;
info->nLeaves++;
} else if (size == 2) {
resPart = ImageFast2(info, vector);
info->averageDepth = (info->averageDepth * (float)info->nLeaves +
(float)depth) / (float)(info->nLeaves + 1);
if (depth > info->maxDepth)
info->maxDepth = depth;
info->nLeaves++;
} else {
split = array_fetch(int, varArray, i);
comp = array_fetch(ImgComponent_t *, vector, split);
constrain = comp->func;
resT = ImageByOutputSplit(info, vector, constrain, depth + 1);
tmp = mdd_not(constrain);
resE = ImageByOutputSplit(info, vector, tmp, depth + 1);
mdd_free(tmp);
resPart = bdd_ite(comp->var, resT, resE, 1, 1, 1);
if (info->option->verbosity) {
size = bdd_size(resPart);
if (size > info->maxIntermediateSize)
info->maxIntermediateSize = size;
if (info->option->printBddSize) {
fprintf(vis_stdout, "** tfm info: bdd_ite(2,%d,%d) = %d\n",
bdd_size(resT), bdd_size(resE), size);
}
}
mdd_free(resT);
mdd_free(resE);
}
if (info->imgCache)
ImgCacheInsertTable(info->imgCache, vector, NIL(bdd_t), resPart);
}
if (!info->imgCache || hit)
ImgVectorFree(vector);
new_ = mdd_and(product, resPart, 1, 1);
if (info->option->verbosity) {
size = bdd_size(new_);
if (size > info->maxIntermediateSize)
info->maxIntermediateSize = size;
if (info->option->printBddSize) {
fprintf(vis_stdout, "** tfm info: bdd_and(%d,%d) = %d\n",
bdd_size(product), bdd_size(resPart), size);
}
}
mdd_free(product);
if (!info->imgCache || hit)
mdd_free(resPart);
product = new_;
}
array_free(vectorArray);
array_free(varArray);
if (info->imgCache && nGroups > 1) {
ImgCacheInsertTable(info->imgCache, newVector, NIL(mdd_t),
mdd_dup(product));
}
if (info->option->debug) {
refResult = ImgImageByHybrid(info, newVector, NIL(mdd_t));
assert(mdd_equal(refResult, product));
mdd_free(refResult);
if (!info->imgCache || nGroups == 1)
ImgVectorFree(newVector);
}
new_ = mdd_and(res, product, 1, 1);
if (info->option->verbosity) {
size = bdd_size(new_);
if (size > info->maxIntermediateSize)
info->maxIntermediateSize = size;
if (info->option->printBddSize) {
fprintf(vis_stdout, "** tfm info: bdd_and(%d,%d) = %d\n",
bdd_size(res), bdd_size(product), size);
}
}
mdd_free(res);
mdd_free(product);
res = new_;
return(res);
}
Here is the call graph for this function:
Here is the caller graph for this function:| static mdd_t * ImageByStaticInputSplit | ( | ImgTfmInfo_t * | info, |
| array_t * | vector, | ||
| mdd_t * | from, | ||
| array_t * | relationArray, | ||
| int | turnDepth, | ||
| int | depth | ||
| ) | [static] |
Function********************************************************************
Synopsis [Computes an image by static input splitting.]
Description [Computes an image by static input splitting.]
SideEffects []
Definition at line 1714 of file imgTfmFwd.c.
{
array_t *vectorT, *vectorE, *tmpVector;
mdd_t *resT, *resE, *res, *tmp, *cubeT, *cubeE;
mdd_t *fromT, *fromE;
mdd_t *var, *varNot;
array_t *relationArrayT, *relationArrayE;
array_t *newRelationArray, *tmpRelationArray;
int nRecur;
mdd_t *refResult, *and_;
mdd_t *essentialCube;
int findEssential;
int foundEssentialDepth, foundEssentialDepthT, foundEssentialDepthE;
int turnFlag, size;
info->nRecursion++;
turnFlag = 0;
if (turnDepth == -1) {
if (depth < info->option->splitMinDepth) {
info->nSplits++;
turnFlag = 0;
} else if (depth > info->option->splitMaxDepth) {
info->nConjoins++;
turnFlag = 1;
} else {
turnFlag = ImgDecideSplitOrConjoin(info, vector, from, 0,
relationArray, NIL(mdd_t),
NIL(mdd_t), 1, depth);
}
} else {
if (depth == turnDepth)
turnFlag = 1;
else
turnFlag = 0;
}
if (turnFlag) {
res = ImgImageByHybridWithStaticSplit(info, vector, from, relationArray,
NIL(mdd_t), NIL(mdd_t));
info->averageDepth = (info->averageDepth * (float)info->nLeaves +
(float)depth) / (float)(info->nLeaves + 1);
if (depth > info->maxDepth)
info->maxDepth = depth;
info->nLeaves++;
info->foundEssentialDepth = info->option->maxEssentialDepth;
return(res);
}
if (info->option->findEssential) {
if (info->option->findEssential == 1)
findEssential = 1;
else {
if (depth >= info->lastFoundEssentialDepth)
findEssential = 1;
else
findEssential = 0;
}
} else
findEssential = 0;
if (findEssential) {
essentialCube = bdd_find_essential_cube(from);
if (!bdd_is_tautology(essentialCube, 1)) {
info->averageFoundEssential = (info->averageFoundEssential *
(float)info->nFoundEssentials + (float)(bdd_size(essentialCube) - 1)) /
(float)(info->nFoundEssentials + 1);
info->averageFoundEssentialDepth = (info->averageFoundEssentialDepth *
(float)info->nFoundEssentials + (float)depth) /
(float)(info->nFoundEssentials + 1);
if (info->nFoundEssentials == 0 || depth < info->topFoundEssentialDepth)
info->topFoundEssentialDepth = depth;
if (info->option->printEssential && depth < IMG_TF_MAX_PRINT_DEPTH)
info->foundEssentials[depth]++;
info->nFoundEssentials++;
ImgVectorMinimize(info, vector, essentialCube, NIL(mdd_t), relationArray,
&tmpVector, &and_,
&tmpRelationArray, NIL(mdd_t *), NIL(mdd_t *));
foundEssentialDepth = depth;
} else {
tmpVector = vector;
tmpRelationArray = relationArray;
and_ = NIL(mdd_t);
foundEssentialDepth = info->option->maxEssentialDepth;
}
mdd_free(essentialCube);
foundEssentialDepthT = info->option->maxEssentialDepth;
foundEssentialDepthE = info->option->maxEssentialDepth;
} else {
tmpVector = vector;
tmpRelationArray = relationArray;
and_ = NIL(mdd_t);
/* To remove compiler warnings */
foundEssentialDepth = -1;
foundEssentialDepthT = -1;
foundEssentialDepthE = -1;
}
var = ImgChooseTrSplitVar(info, tmpVector, tmpRelationArray,
info->option->trSplitMethod,
info->option->piSplitFlag);
if (!var) {
res = ImgImageByHybridWithStaticSplit(info, vector, from, relationArray,
NIL(mdd_t), NIL(mdd_t));
info->averageDepth = (info->averageDepth * (float)info->nLeaves +
(float)depth) / (float)(info->nLeaves + 1);
if (depth > info->maxDepth)
info->maxDepth = depth;
info->nLeaves++;
info->foundEssentialDepth = info->option->maxEssentialDepth;
return(res);
}
nRecur = 0;
if (tmpVector) {
ImgVectorConstrain(info, tmpVector, var, tmpRelationArray,
&vectorT, &cubeT, &newRelationArray,
NIL(mdd_t *), NIL(mdd_t *), TRUE);
} else {
vectorT = NIL(array_t);
cubeT = NIL(mdd_t);
newRelationArray = tmpRelationArray;
}
fromT = bdd_cofactor(from, var);
relationArrayT = ImgGetCofactoredRelationArray(newRelationArray, var);
if (relationArray && newRelationArray != tmpRelationArray)
mdd_array_free(newRelationArray);
if (!bdd_is_tautology(fromT, 0)) {
resT = ImageByStaticInputSplit(info, vectorT, fromT,
relationArrayT, turnDepth, depth + 1);
if (findEssential)
foundEssentialDepthT = info->foundEssentialDepth;
if (vectorT) {
ImgVectorFree(vectorT);
if (!bdd_is_tautology(cubeT, 1)) {
tmp = resT;
resT = mdd_and(tmp, cubeT, 1, 1);
mdd_free(tmp);
}
mdd_free(cubeT);
}
nRecur++;
} else {
resT = mdd_zero(info->manager);
if (vectorT) {
ImgVectorFree(vectorT);
mdd_free(cubeT);
}
}
mdd_free(fromT);
mdd_array_free(relationArrayT);
if (bdd_is_tautology(resT, 1)) {
mdd_free(var);
if (vector && newRelationArray != relationArray)
mdd_array_free(newRelationArray);
res = resT;
info->nEmptySubImage++;
} else {
varNot = mdd_not(var);
mdd_free(var);
if (tmpVector) {
ImgVectorConstrain(info, tmpVector, varNot, tmpRelationArray,
&vectorE, &cubeE, &newRelationArray,
NIL(mdd_t *), NIL(mdd_t *), TRUE);
} else {
vectorE = NIL(array_t);
cubeE = NIL(mdd_t);
newRelationArray = tmpRelationArray;
}
fromE = bdd_cofactor(from, varNot);
relationArrayE = ImgGetCofactoredRelationArray(newRelationArray, varNot);
if (vector && newRelationArray != tmpRelationArray)
mdd_array_free(newRelationArray);
if (!bdd_is_tautology(fromE, 0)) {
resE = ImageByStaticInputSplit(info, vectorE, fromE,
relationArrayE, turnDepth, depth + 1);
if (findEssential)
foundEssentialDepthE = info->foundEssentialDepth;
if (vectorE) {
ImgVectorFree(vectorE);
if (!bdd_is_tautology(cubeE, 1)) {
tmp = resE;
resE = mdd_and(tmp, cubeE, 1, 1);
mdd_free(tmp);
}
mdd_free(cubeE);
}
nRecur++;
} else {
resE = mdd_zero(info->manager);
if (vectorE) {
ImgVectorFree(vectorE);
mdd_free(cubeE);
}
}
mdd_free(fromE);
mdd_array_free(relationArrayE);
res = mdd_or(resT, resE, 1, 1);
if (info->option->verbosity) {
size = bdd_size(res);
if (size > info->maxIntermediateSize)
info->maxIntermediateSize = size;
if (info->option->printBddSize) {
fprintf(vis_stdout, "** tfm info: bdd_or(%d,%d) = %d\n",
bdd_size(resT), bdd_size(resE), size);
}
}
mdd_free(resT);
mdd_free(resE);
mdd_free(varNot);
}
if (tmpVector && tmpVector != vector)
ImgVectorFree(tmpVector);
if (tmpRelationArray && tmpRelationArray != relationArray)
mdd_array_free(tmpRelationArray);
if (and_) {
tmp = res;
res = mdd_and(tmp, and_, 1, 1);
if (info->option->verbosity) {
size = bdd_size(res);
if (size > info->maxIntermediateSize)
info->maxIntermediateSize = size;
if (info->option->printBddSize) {
fprintf(vis_stdout, "** tfm info: bdd_and(%d,%d) = %d\n",
bdd_size(tmp), bdd_size(and_), size);
}
}
mdd_free(tmp);
}
if (info->option->debug) {
refResult = ImgImageByHybridWithStaticSplit(info, vector, from,
relationArray,
NIL(mdd_t), NIL(mdd_t));
assert(mdd_equal(refResult, res));
mdd_free(refResult);
}
if (nRecur == 0) {
info->averageDepth = (info->averageDepth * (float)info->nLeaves +
(float)depth) / (float)(info->nLeaves + 1);
if (depth > info->maxDepth)
info->maxDepth = depth;
info->nLeaves++;
}
if (findEssential) {
if (foundEssentialDepth == info->option->maxEssentialDepth) {
if (foundEssentialDepthT < foundEssentialDepthE)
foundEssentialDepth = foundEssentialDepthT;
else
foundEssentialDepth = foundEssentialDepthE;
}
info->foundEssentialDepth = foundEssentialDepth;
}
return(res);
}
Here is the call graph for this function:
Here is the caller graph for this function:| static int ImageDecomposeAndChooseSplitVar | ( | ImgTfmInfo_t * | info, |
| array_t * | vector, | ||
| mdd_t * | from, | ||
| int | splitMethod, | ||
| int | split, | ||
| int | piSplitFlag, | ||
| array_t * | vectorArray, | ||
| array_t * | varArray, | ||
| mdd_t ** | singles, | ||
| array_t * | relationArray, | ||
| array_t ** | newRelationArray, | ||
| mdd_t ** | cofactorCube, | ||
| mdd_t ** | abstractCube | ||
| ) | [static] |
Function********************************************************************
Synopsis [Try to decompose function vector and find a splitting variable for each decomposed block.]
Description [Try to decompose function vector and find a splitting variable for each decomposed block.]
SideEffects []
Definition at line 2264 of file imgTfmFwd.c.
{
int i, j, f, index;
int nGroups, nSingles, nChosen;
int nVars, nFuncs, arraySize;
char *varFlag;
int *funcGroup;
int *varOccur;
int bestVar;
int *stack, size;
ImgComponent_t *comp, *newComp;
array_t *partVector;
char *stackFlag;
char *support;
mdd_t *func;
int *varCost;
int decompose;
int res, constConstrain;
mdd_t *tmp, *cofactor, *abstract, *nsVar;
array_t *tmpRelationArray;
char *intermediateVarFlag;
int *intermediateVarFuncMap;
if (info->useConstraint && from && splitMethod == 0)
decompose = 0;
else
decompose = 1;
arraySize = array_n(vector);
if (info->nIntermediateVars)
nFuncs = ImgVectorFunctionSize(vector);
else
nFuncs = arraySize;
nVars = info->nVars;
*singles = mdd_one(info->manager);
if (relationArray) {
cofactor = mdd_one(info->manager);
abstract = mdd_one(info->manager);
} else {
cofactor = NIL(mdd_t);
abstract = NIL(mdd_t);
}
if (decompose) {
funcGroup = ALLOC(int, arraySize);
memset(funcGroup, 0, sizeof(int) * arraySize);
varFlag = ALLOC(char, nVars);
memset(varFlag, 0, sizeof(char) * nVars);
stack = ALLOC(int, arraySize);
stackFlag = ALLOC(char, arraySize);
memset(stackFlag, 0, sizeof(char) * arraySize);
if (arraySize > nFuncs) {
intermediateVarFlag = ALLOC(char, nVars);
memset(intermediateVarFlag, 0, sizeof(char) * nVars);
intermediateVarFuncMap = ALLOC(int, nVars);
memset(intermediateVarFuncMap, 0, sizeof(int) * nVars);
for (i = 0; i < arraySize; i++) {
comp = array_fetch(ImgComponent_t *, vector, i);
if (comp->intermediate) {
index = (int)bdd_top_var_id(comp->var);
intermediateVarFlag[index] = 1;
intermediateVarFuncMap[index] = i;
}
}
} else {
/* To remove compiler warnings */
intermediateVarFlag = NIL(char);
intermediateVarFuncMap = NIL(int);
}
} else {
/* To remove compiler warnings */
funcGroup = NIL(int);
varFlag = NIL(char);
stack = NIL(int);
stackFlag = NIL(char);
intermediateVarFlag = NIL(char);
intermediateVarFuncMap = NIL(int);
}
varOccur = ALLOC(int, nVars);
if (splitMethod == 0 && split > 0)
varCost = ALLOC(int, nVars);
else
varCost = NIL(int);
nGroups = 0;
nSingles = 0;
nChosen = 0;
while (nChosen < nFuncs) {
bestVar = -1;
memset(varOccur, 0, sizeof(int) * nVars);
if (varCost)
memset(varCost, 0, sizeof(int) * nVars);
if (decompose) {
size = 0;
for (i = 0; i < arraySize; i++) {
if (funcGroup[i] == 0) {
stack[0] = i;
size = 1;
stackFlag[i] = 1;
break;
}
}
assert(size == 1);
while (size) {
size--;
f = stack[size];
funcGroup[f] = nGroups + 1;
comp = array_fetch(ImgComponent_t *, vector, f);
nChosen++;
if (nChosen == arraySize)
break;
support = comp->support;
if (comp->intermediate) {
index = (int)bdd_top_var_id(comp->var);
support[index] = 1;
}
for (i = 0; i < nVars; i++) {
if (!support[i])
continue;
varOccur[i]++;
if (varFlag[i])
continue;
varFlag[i] = 1;
for (j = 0; j < arraySize; j++) {
if (j == f || stackFlag[j])
continue;
comp = array_fetch(ImgComponent_t *, vector, j);
if (arraySize != nFuncs) {
if (intermediateVarFlag[i] && comp->intermediate) {
index = (int)bdd_top_var_id(comp->var);
if (index == i) {
if (funcGroup[j] == 0) {
stack[size] = j;
size++;
stackFlag[j] = 1;
}
FindIntermediateSupport(vector, comp, nVars, nGroups,
stack, stackFlag, funcGroup, &size,
intermediateVarFlag,
intermediateVarFuncMap);
continue;
}
}
}
if (funcGroup[j])
continue;
if (comp->support[i]) {
stack[size] = j;
size++;
stackFlag[j] = 1;
}
}
}
if (comp->intermediate) {
index = (int)bdd_top_var_id(comp->var);
support[index] = 0;
}
}
} else {
for (i = 0; i < arraySize; i++) {
comp = array_fetch(ImgComponent_t *, vector, i);
support = comp->support;
for (j = 0; j < nVars; j++) {
if (support[j])
varOccur[j]++;
}
}
nChosen = nFuncs;
}
nGroups++;
/* Collect the functions which belong to the current group */
partVector = array_alloc(ImgComponent_t *, 0);
for (i = 0; i < arraySize; i++) {
if (decompose == 0 || funcGroup[i] == nGroups) {
comp = array_fetch(ImgComponent_t *, vector, i);
newComp = ImgComponentCopy(info, comp);
array_insert_last(ImgComponent_t *, partVector, newComp);
}
}
if (arraySize == nFuncs)
size = array_n(partVector);
else
size = ImgVectorFunctionSize(partVector);
if (size == 1) {
nSingles++;
if (size == array_n(partVector)) {
comp = array_fetch(ImgComponent_t *, partVector, 0);
func = comp->func;
} else {
comp = ImgGetLatchComponent(partVector);
func = ImgGetComposedFunction(partVector);
}
if (from) {
constConstrain = ImgConstConstrain(func, from);
if (constConstrain == 1)
res = 1;
else if (constConstrain == 0)
res = 0;
else
res = 2;
} else {
if (bdd_is_tautology(func, 1))
res = 1;
else if (bdd_is_tautology(func, 0))
res = 0;
else
res = 2;
}
if (size != array_n(partVector))
mdd_free(func);
if (res == 1) {
tmp = *singles;
*singles = mdd_and(tmp, comp->var, 1, 1);
mdd_free(tmp);
} else if (res == 0) {
tmp = *singles;
*singles = mdd_and(tmp, comp->var, 1, 0);
mdd_free(tmp);
}
if (abstract) {
nsVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c);
tmp = abstract;
abstract = mdd_and(tmp, nsVar, 1, 1);
mdd_free(tmp);
mdd_free(nsVar);
}
ImgVectorFree(partVector);
continue;
}
array_insert_last(array_t *, vectorArray, partVector);
if (splitMethod == 0) { /* input splitting */
if (decompose) {
if (info->option->findDecompVar) {
bestVar = FindDecomposableVariable(info, partVector);
if (bestVar != -1)
split = -1;
}
} else if (from) {
comp = ImgComponentAlloc(info);
comp->func = from;
ImgComponentGetSupport(comp);
for (i = 0; i < nVars; i++) {
if (comp->support[i])
varOccur[i]++;
}
comp->func = NIL(mdd_t);
ImgComponentFree(comp);
}
if (split != -1) {
bestVar = ChooseInputSplittingVariable(info, partVector, from,
info->option->inputSplit, decompose,
info->option->piSplitFlag, varOccur);
}
} else { /* output splitting */
bestVar = ChooseOutputSplittingVariable(info, partVector,
info->option->outputSplit);
}
assert(bestVar != -1);
array_insert_last(int, varArray, bestVar);
}
if (newRelationArray)
*newRelationArray = relationArray;
if (cofactorCube && abstractCube) {
if (cofactor)
*cofactorCube = cofactor;
if (abstract)
*abstractCube = abstract;
} else {
if (cofactor) {
if (bdd_is_tautology(cofactor, 1))
mdd_free(cofactor);
else {
*newRelationArray = ImgGetCofactoredRelationArray(relationArray,
cofactor);
mdd_free(cofactor);
}
}
if (abstract) {
if (bdd_is_tautology(abstract, 1))
mdd_free(abstract);
else {
tmpRelationArray = *newRelationArray;
*newRelationArray = ImgGetAbstractedRelationArray(info->manager,
tmpRelationArray,
abstract);
mdd_free(abstract);
if (tmpRelationArray != relationArray)
mdd_array_free(tmpRelationArray);
}
}
}
if (decompose) {
FREE(stackFlag);
FREE(stack);
FREE(funcGroup);
FREE(varFlag);
if (arraySize > nFuncs) {
FREE(intermediateVarFlag);
FREE(intermediateVarFuncMap);
}
}
FREE(varOccur);
if (varCost)
FREE(varCost);
nGroups -= nSingles;
return(nGroups);
}
Here is the call graph for this function:
Here is the caller graph for this function:| static mdd_t * ImageFast2 | ( | ImgTfmInfo_t * | info, |
| array_t * | vector | ||
| ) | [static] |
Function********************************************************************
Synopsis [Fast image computation when function vector contains only two functions.]
Description [Fast image computation when function vector contains only two functions.]
SideEffects []
Definition at line 2603 of file imgTfmFwd.c.
{
mdd_t *f1, *f2;
int f21n, f21p;
mdd_t *res, *resp, *resn;
mdd_t *i1, *i2;
ImgComponent_t *comp;
mdd_t *refResult;
int i, freeFlag, size;
array_t *varArray, *funcArray;
assert(ImgVectorFunctionSize(vector) == 2);
if (info->option->debug)
refResult = ImgImageByHybrid(info, vector, NIL(mdd_t));
else
refResult = NIL(mdd_t);
if (array_n(vector) == 2) {
comp = array_fetch(ImgComponent_t *, vector, 0);
f1 = comp->func;
i1 = comp->var;
comp = array_fetch(ImgComponent_t *, vector, 1);
f2 = comp->func;
i2 = comp->var;
freeFlag = 0;
} else {
varArray = array_alloc(mdd_t *, 0);
funcArray = array_alloc(mdd_t *, 0);
i1 = NIL(mdd_t);
i2 = NIL(mdd_t);
f1 = NIL(mdd_t);
f2 = NIL(mdd_t);
for (i = 0; i < array_n(vector); i++) {
comp = array_fetch(ImgComponent_t *, vector, i);
if (comp->intermediate) {
array_insert_last(mdd_t *, varArray, comp->var);
array_insert_last(mdd_t *, funcArray, comp->func);
continue;
}
if (f1) {
f2 = comp->func;
i2 = comp->var;
} else {
f1 = comp->func;
i1 = comp->var;
}
}
f1 = bdd_vector_compose(f1, varArray, funcArray);
f2 = bdd_vector_compose(f2, varArray, funcArray);
array_free(varArray);
array_free(funcArray);
freeFlag = 1;
}
ImgCheckConstConstrain(f1, f2, &f21p, &f21n);
if (f21p == 1)
resp = mdd_dup(i2);
else if (f21p == 0)
resp = mdd_not(i2);
else
resp = mdd_one(info->manager);
if (f21n == 1)
resn = mdd_dup(i2);
else if (f21n == 0)
resn = mdd_not(i2);
else
resn = mdd_one(info->manager);
/* merge final result */
res = bdd_ite(i1, resp, resn, 1, 1, 1);
if (info->option->verbosity) {
size = bdd_size(res);
if (size > info->maxIntermediateSize)
info->maxIntermediateSize = size;
if (info->option->printBddSize) {
fprintf(vis_stdout, "** tfm info: bdd_ite(2,%d,%d) = %d\n",
bdd_size(resp), bdd_size(resn), size);
}
}
mdd_free(resp);
mdd_free(resn);
if (freeFlag) {
mdd_free(f1);
mdd_free(f2);
}
if (info->option->debug) {
assert(mdd_equal(refResult, res));
mdd_free(refResult);
}
return(res);
}
Here is the call graph for this function:
Here is the caller graph for this function:| mdd_t* ImgChooseTrSplitVar | ( | ImgTfmInfo_t * | info, |
| array_t * | vector, | ||
| array_t * | relationArray, | ||
| int | trSplitMethod, | ||
| int | piSplitFlag | ||
| ) |
Function********************************************************************
Synopsis [Chooses splitting variables for static splitting.]
Description [Chooses splitting variables for static splitting.]
SideEffects []
Definition at line 536 of file imgTfmFwd.c.
{
int i, j, nVars;
ImgComponent_t *comp;
char *support;
int *varCost, bestCost = 0;
int id, split;
mdd_t *var, *relation;
nVars = info->nVars;
varCost = ALLOC(int, nVars);
memset(varCost, 0, sizeof(int) * nVars);
if (trSplitMethod == 0) {
if (vector) {
for (i = 0; i < array_n(vector); i++) {
comp = array_fetch(ImgComponent_t *, vector, i);
support = comp->support;
for (j = 0; j < nVars; j++) {
if (support[j])
varCost[j]++;
}
}
}
comp = ImgComponentAlloc(info);
support = comp->support;
for (i = 0; i < array_n(relationArray); i++) {
relation = array_fetch(mdd_t *, relationArray, i);
comp->func = relation;
ImgSupportClear(info, comp->support);
ImgComponentGetSupport(comp);
for (j = 0; j < nVars; j++) {
if (support[j])
varCost[j]++;
}
}
comp->func = NIL(mdd_t);
ImgComponentFree(comp);
} else {
for (i = 0; i < array_n(info->domainVarBddArray); i++) {
var = array_fetch(mdd_t *, info->domainVarBddArray, i);
id = (int)bdd_top_var_id(var);
if (vector) {
for (j = 0; j < array_n(vector); j++) {
comp = array_fetch(ImgComponent_t *, vector, j);
varCost[id] += bdd_estimate_cofactor(comp->func, var, 1);
varCost[id] += bdd_estimate_cofactor(comp->func, var, 0);
}
}
for (j = 0; j < array_n(relationArray); j++) {
relation = array_fetch(mdd_t *, relationArray, j);
varCost[id] += bdd_estimate_cofactor(relation, var, 1);
varCost[id] += bdd_estimate_cofactor(relation, var, 0);
}
varCost[id] = IMG_TF_MAX_INT - varCost[id];
}
}
split = -1;
for (i = 0; i < nVars; i++) {
if (varCost[i] == 0)
continue;
if (!piSplitFlag) {
if (st_lookup(info->quantifyVarsTable, (char *)(long)i, NIL(char *)))
continue;
}
if (st_lookup(info->rangeVarsTable, (char *)(long)i, NIL(char *)))
continue;
if (info->intermediateVarsTable &&
st_lookup(info->intermediateVarsTable, (char *)(long)i, NIL(char *))) {
continue;
}
if (split == -1 || varCost[i] > bestCost) {
bestCost = varCost[i];
split = i;
}
}
FREE(varCost);
if (split == -1)
return(NIL(mdd_t));
var = bdd_var_with_index(info->manager, split);
return(var);
}
Here is the call graph for this function:
Here is the caller graph for this function:| mdd_t* ImgTfmImage | ( | ImgTfmInfo_t * | info, |
| mdd_t * | from | ||
| ) |
AutomaticEnd Function********************************************************************
Synopsis [Computes an image with transition function method.]
Description [Computes an image with transition function method.]
SideEffects []
Definition at line 101 of file imgTfmFwd.c.
{
mdd_t *res, *r, *cube, *newFrom, *one;
array_t *newVector, *depVector;
int splitMethod, turnDepth;
mdd_t *refResult;
array_t *relationArray, *newRelationArray, *tmpRelationArray;
int eliminateDepend;
int partial, saveUseConstraint;
long size1, size2;
mdd_t *cofactorCube, *abstractCube;
int i, maxDepth, size, nDependVars;
info->maxIntermediateSize = 0;
if (info->eliminateDepend == 1 ||
(info->eliminateDepend == 2 && info->nPrevEliminatedFwd > 0)) {
eliminateDepend = 1;
} else
eliminateDepend = 0;
saveUseConstraint = info->useConstraint;
if (info->buildTR) {
if (eliminateDepend == 0 &&
info->option->splitMethod == 3 &&
info->option->splitMaxDepth < 0 &&
info->option->buildPartialTR == FALSE &&
info->option->rangeComp == 0 &&
info->option->findEssential == FALSE) {
r = ImgBddLinearAndSmooth(info->manager, from,
info->fwdClusteredRelationArray,
info->fwdArraySmoothVarBddArray,
info->fwdSmoothVarCubeArray,
info->option->verbosity);
res = ImgSubstitute(r, info->functionData, Img_R2D_c);
mdd_free(r);
return(res);
}
relationArray = mdd_array_duplicate(info->fwdClusteredRelationArray);
} else
relationArray = NIL(array_t);
if (info->useConstraint == 1 ||
(info->useConstraint == 2 &&
info->nImageComps == info->option->rangeTryThreshold)) {
if (info->buildTR == 2) {
newVector = NIL(array_t);
cube = mdd_one(info->manager);
if (eliminateDepend) {
newFrom = ImgTrmEliminateDependVars(info->functionData, relationArray,
from, NIL(mdd_t *), &nDependVars);
if (nDependVars) {
if (info->option->verbosity > 0)
(void)fprintf(vis_stdout, "Eliminated %d vars.\n", nDependVars);
info->averageFoundDependVars = (info->averageFoundDependVars *
(float)info->nFoundDependVars + (float)nDependVars) /
(float)(info->nFoundDependVars + 1);
info->nFoundDependVars++;
}
info->nPrevEliminatedFwd = nDependVars;
} else
newFrom = from;
cofactorCube = NIL(mdd_t);
abstractCube = NIL(mdd_t);
} else {
newVector = ImgVectorCopy(info, info->vector);
cube = mdd_one(info->manager);
if (eliminateDepend) {
newFrom = ImgTfmEliminateDependVars(info, newVector, relationArray,
from, NIL(array_t *), NIL(mdd_t *));
} else
newFrom = from;
if (info->option->delayedSplit && relationArray && info->buildTR != 2) {
cofactorCube = mdd_one(info->manager);
abstractCube = mdd_one(info->manager);
} else {
cofactorCube = NIL(mdd_t);
abstractCube = NIL(mdd_t);
}
}
} else {
if (eliminateDepend) {
depVector = ImgVectorCopy(info, info->vector);
newFrom = ImgTfmEliminateDependVars(info, depVector, relationArray, from,
NIL(array_t *), NIL(mdd_t *));
/* constrain delta w.r.t. from here */
if (info->option->delayedSplit && relationArray && info->buildTR != 2) {
ImgVectorConstrain(info, depVector, newFrom, relationArray,
&newVector, &cube, &newRelationArray, &cofactorCube,
&abstractCube, FALSE);
} else if (relationArray) {
ImgVectorConstrain(info, depVector, newFrom, relationArray,
&newVector, &cube, NIL(array_t *), &cofactorCube,
&abstractCube, FALSE);
newRelationArray = NIL(array_t);
} else {
ImgVectorConstrain(info, depVector, newFrom, NIL(array_t),
&newVector, &cube, NIL(array_t *), NIL(mdd_t *),
NIL(mdd_t *), FALSE);
newRelationArray = NIL(array_t);
cofactorCube = NIL(mdd_t);
abstractCube = NIL(mdd_t);
}
if (info->useConstraint == 2) {
size1 = ImgVectorBddSize(depVector);
size2 = ImgVectorBddSize(newVector);
if (info->option->rangeCheckReorder) {
bdd_reorder(info->manager);
size1 = ImgVectorBddSize(depVector);
size2 = ImgVectorBddSize(newVector);
}
if (size2 > size1 * info->option->rangeThreshold) { /* cancel */
if (info->option->verbosity)
fprintf(vis_stdout, "** tfm info: canceled range computation.\n");
info->useConstraint = 1;
ImgVectorFree(newVector);
newVector = depVector;
mdd_free(cube);
cube = mdd_one(info->manager);
if (newRelationArray && newRelationArray != relationArray)
mdd_array_free(newRelationArray);
if (cofactorCube) {
mdd_free(cofactorCube);
cofactorCube = mdd_one(info->manager);
}
if (abstractCube) {
mdd_free(abstractCube);
abstractCube = mdd_one(info->manager);
}
info->nImageComps++;
} else {
info->useConstraint = 0;
info->nImageComps = 0;
info->nRangeComps++;
}
}
if (info->useConstraint == 0)
ImgVectorFree(depVector);
} else {
newFrom = from;
/* constrain delta w.r.t. from here */
if (info->option->delayedSplit && relationArray && info->buildTR != 2) {
ImgVectorConstrain(info, info->vector, newFrom, relationArray,
&newVector, &cube, &newRelationArray, &cofactorCube,
&abstractCube, FALSE);
if (info->option->debug) {
refResult = ImgImageByHybrid(info, newVector, NIL(mdd_t));
res = ImgImageByHybridWithStaticSplit(info, NIL(array_t), NIL(mdd_t),
newRelationArray,
cofactorCube, abstractCube);
assert(mdd_equal(refResult, res));
mdd_free(refResult);
mdd_free(res);
}
} else if (relationArray) {
ImgVectorConstrain(info, info->vector, newFrom, relationArray,
&newVector, &cube, NIL(array_t *), &cofactorCube,
&abstractCube, FALSE);
newRelationArray = NIL(array_t);
} else {
ImgVectorConstrain(info, info->vector, newFrom, NIL(array_t),
&newVector, &cube, NIL(array_t *), NIL(mdd_t *),
NIL(mdd_t *), FALSE);
newRelationArray = NIL(array_t);
cofactorCube = NIL(mdd_t);
abstractCube = NIL(mdd_t);
}
if (info->useConstraint == 2) {
size1 = ImgVectorBddSize(info->vector);
size2 = ImgVectorBddSize(newVector);
if (info->option->rangeCheckReorder) {
bdd_reorder(info->manager);
size1 = ImgVectorBddSize(info->vector);
size2 = ImgVectorBddSize(newVector);
}
if (size2 > size1 * info->option->rangeThreshold) { /* cancel */
if (info->option->verbosity)
fprintf(vis_stdout, "** tfm info: canceled range computation.\n");
info->useConstraint = 1;
ImgVectorFree(newVector);
newVector = info->vector;
mdd_free(cube);
cube = mdd_one(info->manager);
if (newRelationArray && newRelationArray != relationArray)
mdd_array_free(newRelationArray);
if (cofactorCube) {
mdd_free(cofactorCube);
cofactorCube = mdd_one(info->manager);
}
if (abstractCube) {
mdd_free(abstractCube);
abstractCube = mdd_one(info->manager);
}
info->nImageComps++;
} else {
info->useConstraint = 0;
info->nImageComps = 0;
info->nRangeComps++;
}
}
}
if (info->useConstraint == 0 && relationArray) {
if (!newRelationArray) {
if (bdd_is_tautology(cofactorCube, 1) &&
bdd_is_tautology(abstractCube, 1)) {
newRelationArray = ImgGetConstrainedRelationArray(info, relationArray,
newFrom);
} else {
tmpRelationArray = ImgGetConstrainedRelationArray(info, relationArray,
newFrom);
newRelationArray = ImgGetCofactoredAbstractedRelationArray(
info->manager, tmpRelationArray,
cofactorCube, abstractCube);
if (info->option->debug) {
array_t *tmpVector;
tmpVector = ImgGetConstrainedVector(info, info->vector, newFrom);
if (info->option->checkEquivalence) {
assert(ImgCheckEquivalence(info, tmpVector, tmpRelationArray,
NIL(mdd_t), NIL(mdd_t), 0));
}
refResult = ImgImageByHybrid(info, tmpVector, NIL(mdd_t));
ImgVectorFree(tmpVector);
res = ImgImageByHybridWithStaticSplit(info, NIL(array_t),
NIL(mdd_t),
tmpRelationArray,
NIL(mdd_t), NIL(mdd_t));
assert(mdd_equal(refResult, res));
mdd_free(refResult);
mdd_free(res);
}
mdd_array_free(tmpRelationArray);
}
mdd_free(cofactorCube);
cofactorCube = NIL(mdd_t);
mdd_free(abstractCube);
abstractCube = NIL(mdd_t);
if (info->option->debug) {
refResult = ImgImageByHybrid(info, newVector, NIL(mdd_t));
res = ImgImageByHybridWithStaticSplit(info, NIL(array_t), NIL(mdd_t),
newRelationArray,
NIL(mdd_t), NIL(mdd_t));
assert(mdd_equal(refResult, res));
mdd_free(refResult);
mdd_free(res);
if (info->nIntermediateVars) {
mdd_t *tmp;
refResult = ImgImageByHybrid(info, info->vector, newFrom);
res = ImgImageByHybridWithStaticSplit(info, NIL(array_t), newFrom,
relationArray,
NIL(mdd_t), NIL(mdd_t));
assert(mdd_equal(refResult, res));
mdd_free(res);
tmp = ImgImageByHybrid(info, newVector, NIL(mdd_t));
res = mdd_and(tmp, cube, 1, 1);
if (info->option->verbosity) {
size = bdd_size(res);
if (size > info->maxIntermediateSize)
info->maxIntermediateSize = size;
if (info->option->printBddSize) {
fprintf(vis_stdout, "** tfm info: bdd_and(%d,%d) = %d\n",
bdd_size(tmp), bdd_size(cube), size);
}
}
mdd_free(tmp);
assert(mdd_equal(refResult, res));
mdd_free(refResult);
mdd_free(res);
}
}
}
if (relationArray != newRelationArray) {
mdd_array_free(relationArray);
relationArray = newRelationArray;
}
}
if (info->option->checkEquivalence) {
assert(ImgCheckEquivalence(info, newVector, newRelationArray,
NIL(mdd_t), NIL(mdd_t), 0));
}
}
partial = 0;
one = mdd_one(info->manager);
splitMethod = info->option->splitMethod;
if (splitMethod == 0) {
r = ImageByInputSplit(info, newVector, one, newFrom, NIL(array_t),
NIL(mdd_t), NIL(mdd_t), 0, 0, 0);
} else if (splitMethod == 1)
r = ImageByOutputSplit(info, newVector, one, 0);
else {
if (info->option->splitMethod == 0)
turnDepth = info->nVars + 1;
else
turnDepth = info->option->turnDepth;
if (turnDepth == 0) {
if (splitMethod == 2)
r = ImageByOutputSplit(info, newVector, one, 0);
else {
if (info->useConstraint && info->buildTR == 2) {
if (info->buildPartialTR) {
r = ImgImageByHybridWithStaticSplit(info, newVector, newFrom,
relationArray,
NIL(mdd_t), NIL(mdd_t));
} else {
r = ImgImageByHybridWithStaticSplit(info, NIL(array_t), newFrom,
relationArray,
NIL(mdd_t), NIL(mdd_t));
}
} else
r = ImgImageByHybrid(info, newVector, newFrom);
}
} else if (splitMethod == 2) {
r = ImageByInputSplit(info, newVector, one, newFrom, NIL(array_t),
NIL(mdd_t), NIL(mdd_t),
splitMethod, turnDepth, 0);
} else {
if (info->useConstraint) {
if (info->buildTR) {
if (info->buildTR == 2) {
if (info->buildPartialTR) {
r = ImageByStaticInputSplit(info, newVector, newFrom,
relationArray, turnDepth, 0);
partial = 1;
} else {
r = ImageByStaticInputSplit(info, NIL(array_t), newFrom,
relationArray, turnDepth, 0);
}
} else if (info->option->delayedSplit) {
r = ImageByInputSplit(info, newVector, one, newFrom, relationArray,
cofactorCube, abstractCube,
splitMethod, turnDepth, 0);
} else {
r = ImageByInputSplit(info, newVector, one, newFrom, relationArray,
NIL(mdd_t), NIL(mdd_t),
splitMethod, turnDepth, 0);
}
} else {
r = ImageByInputSplit(info, newVector, one, newFrom, NIL(array_t),
NIL(mdd_t), NIL(mdd_t),
splitMethod, turnDepth, 0);
}
} else if (info->buildTR == 1 && info->option->delayedSplit) {
r = ImageByInputSplit(info, newVector, one, NIL(mdd_t), relationArray,
cofactorCube, abstractCube,
splitMethod, turnDepth, 0);
} else {
r = ImageByInputSplit(info, newVector, one, NIL(mdd_t), relationArray,
NIL(mdd_t), NIL(mdd_t),
splitMethod, turnDepth, 0);
}
}
}
info->useConstraint = saveUseConstraint;
if (relationArray &&
!(info->option->debug && (partial || info->buildTR == 2))) {
mdd_array_free(relationArray);
}
if (info->imgCache && info->option->autoFlushCache == 1)
ImgFlushCache(info->imgCache);
mdd_free(one);
if (cofactorCube)
mdd_free(cofactorCube);
if (abstractCube)
mdd_free(abstractCube);
if (newFrom && newFrom != from)
mdd_free(newFrom);
res = bdd_and(r, cube, 1, 1);
if (info->option->verbosity) {
size = bdd_size(res);
if (size > info->maxIntermediateSize)
info->maxIntermediateSize = size;
if (info->option->printBddSize) {
fprintf(vis_stdout, "** tfm info: bdd_and(%d,%d) = %d\n",
bdd_size(r), bdd_size(cube), size);
}
}
mdd_free(r);
mdd_free(cube);
if (newVector != info->vector)
ImgVectorFree(newVector);
if (info->option->debug) {
if (info->buildTR == 2) {
refResult = ImgImageByHybridWithStaticSplit(info, NIL(array_t), from,
relationArray,
NIL(mdd_t), NIL(mdd_t));
mdd_array_free(relationArray);
} else {
if (partial) {
refResult = ImgImageByHybrid(info, info->fullVector, from);
assert(mdd_equal(refResult, res));
mdd_free(refResult);
refResult = ImgImageByHybridWithStaticSplit(info, info->vector, from,
relationArray,
NIL(mdd_t), NIL(mdd_t));
mdd_array_free(relationArray);
} else
refResult = ImgImageByHybrid(info, info->vector, from);
}
assert(mdd_equal(refResult, res));
mdd_free(refResult);
}
if (info->option->findEssential)
info->lastFoundEssentialDepth = info->foundEssentialDepth;
if (info->option->printEssential == 2) {
maxDepth = info->maxDepth < IMG_TF_MAX_PRINT_DEPTH ?
info->maxDepth : IMG_TF_MAX_PRINT_DEPTH;
fprintf(vis_stdout, "foundEssential:");
for (i = 0; i < maxDepth; i++)
fprintf(vis_stdout, " [%d]%d", i, info->foundEssentials[i]);
fprintf(vis_stdout, "\n");
}
if (info->option->verbosity) {
fprintf(vis_stdout, "** tfm info: max intermediate BDD size = %d\n",
info->maxIntermediateSize);
}
if (info->option->debug)
assert(TfmCheckImageValidity(info, res));
return(res);
}
Here is the call graph for this function:
Here is the caller graph for this function:| static void PrintVectorDecomposition | ( | ImgTfmInfo_t * | info, |
| array_t * | vectorArray, | ||
| array_t * | varArray | ||
| ) | [static] |
Function********************************************************************
Synopsis [Print the information of the decomposition.]
Description [Print the information of the decomposition.]
SideEffects []
Definition at line 2945 of file imgTfmFwd.c.
{
int i, j, n;
int var, index;
ImgComponent_t *comp;
array_t *vector;
fprintf(vis_stdout, "** tfm info: vector decomposition\n");
n = array_n(vectorArray);
for (i = 0; i < n; i++) {
vector = array_fetch(array_t *, vectorArray, i);
var = array_fetch(int, varArray, i);
fprintf(vis_stdout, "Group[%d] : num = %d, split = %d\n",
i, array_n(vector), var);
for (j = 0; j < array_n(vector); j++) {
comp = array_fetch(ImgComponent_t *, vector, j);
index = (int)bdd_top_var_id(comp->var);
fprintf(vis_stdout, " %d", index);
}
fprintf(vis_stdout, "\n");
}
}
Here is the caller graph for this function:| static int TfmCheckImageValidity | ( | ImgTfmInfo_t * | info, |
| mdd_t * | image | ||
| ) | [static] |
Function********************************************************************
Synopsis [Checks the support of image.]
Description [Checks the support of image.]
SideEffects []
Definition at line 2861 of file imgTfmFwd.c.
{
int i, id;
array_t *supportIds;
int status = 1;
supportIds = mdd_get_bdd_support_ids(info->manager, image);
for (i = 0; i < array_n(supportIds); i++) {
id = array_fetch(int, supportIds, i);
if (st_lookup(info->quantifyVarsTable, (char *)(long)id, NIL(char *))) {
fprintf(vis_stderr,
"** tfm error: image contains a primary input variable (%d)\n",
id);
status = 0;
}
if (st_lookup(info->rangeVarsTable, (char *)(long)id, NIL(char *))) {
fprintf(vis_stderr,
"** tfm error: image contains a range variable (%d)\n", id);
status = 0;
}
if (info->intermediateVarsTable &&
st_lookup(info->intermediateVarsTable, (char *)(long)id, NIL(char *))) {
fprintf(vis_stderr,
"** tfm error: image contains an intermediate variable (%d)\n",
id);
status = 0;
}
}
array_free(supportIds);
return(status);
}
Here is the caller graph for this function:char rcsid [] UNUSED = "$Id: imgTfmFwd.c,v 1.37 2005/04/22 19:45:46 jinh Exp $" [static] |
CFile***********************************************************************
FileName [imgTfmFwd.c]
PackageName [img]
Synopsis [Routines for image computation using transition function method.]
Description []
SeeAlso []
Author [In-Ho Moon]
Copyright [Copyright (c) 1994-1996 The Regents of the Univ. of Colorado. All rights reserved.
Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy, modify, and distribute this software and its documentation for any purpose, provided that the above copyright notice and the following two paragraphs appear in all copies of this software.
IN NO EVENT SHALL THE UNIVERSITY OF COLORADO BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF COLORADO HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
THE UNIVERSITY OF COLORADO SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF COLORADO HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.]
Definition at line 37 of file imgTfmFwd.c.