VIS
|
#include "synthInt.h"
Go to the source code of this file.
Data Structures | |
struct | bfs_item |
struct | bfs_list |
Defines | |
#define | MAX_COUNT 100000000 |
Typedefs | |
typedef struct bfs_item | BfsItem |
typedef struct bfs_list | BfsList |
Functions | |
static int | FindQuickDivisor (bdd_node *f, bdd_node *one, int *v) |
bdd_node * | Synth_ZddQuickDivisor (bdd_manager *dd, bdd_node *f) |
bdd_node * | Synth_ZddLeastDivisor (bdd_manager *dd, bdd_node *f) |
bdd_node * | Synth_ZddMostDivisor (bdd_manager *dd, bdd_node *f) |
bdd_node * | Synth_ZddLevelZeroDivisor (bdd_manager *dd, bdd_node *f) |
bdd_node * | Synth_ZddCommonDivisor (bdd_manager *dd, bdd_node *f) |
bdd_node * | Synth_ZddLpDivisor (bdd_manager *dd, bdd_node *f) |
bdd_node * | SynthZddQuickDivisor (bdd_manager *dd, bdd_node *f) |
bdd_node * | SynthZddLeastDivisor (bdd_manager *dd, bdd_node *f) |
bdd_node * | SynthZddMostDivisor (bdd_manager *dd, bdd_node *f) |
bdd_node * | SynthZddLevelZeroDivisor (bdd_manager *dd, bdd_node *f) |
bdd_node * | SynthZddCommonDivisor (bdd_manager *dd, bdd_node *f) |
bdd_node * | SynthZddLpDivisor (bdd_manager *dd, bdd_node *f) |
void | SynthCountLiteralOccurrence (bdd_manager *dd, bdd_node *f, int *count) |
Variables | |
static char rcsid[] | UNUSED = "$Id: synthDiv.c,v 1.25 2002/09/10 05:50:52 fabio Exp $" |
#define MAX_COUNT 100000000 |
Definition at line 25 of file synthDiv.c.
Struct**********************************************************************
Synopsis [Structure of one BFS item to count variable occurrences.]
Description [Structure of one BFS item to count variable occurrences.]
SeeAlso []
Struct**********************************************************************
Synopsis [Structure for BFS operation to count variable occurrences.]
Description [Structure for BFS operation to count variable occurrences.]
SeeAlso []
static int FindQuickDivisor | ( | bdd_node * | f, |
bdd_node * | one, | ||
int * | v | ||
) | [static] |
AutomaticStart
Function********************************************************************
Synopsis [Finds a ZDD node that is referred by more than one parent node in a function.]
Description [Finds a ZDD node that is referred by more than one parent node in a function. Performs a DFS from f. Whenever a node is visited, the node is marked. When a node is visited, if the node is already marked, it returns the index of the node. Uses the LSB of the next pointer as visited flag. This function returns the number of path to constant 1 from the node, and return value -1 means already found.]
SideEffects [Once this function is called, SynthZddClearFlag() should be called right after.];
SeeAlso [SynthZddClearFlag]
Definition at line 1055 of file synthDiv.c.
{ int c, ct, ce; bdd_node *temp = bdd_read_next(f); if (bdd_is_constant(f)) { if (f == one) return(1); else return(0); } if (bdd_is_complement(temp)) { /* already visited */ *v = bdd_node_read_index(f); return(-1); } /* mark as visited */ bdd_set_next(f, bdd_not_bdd_node(temp)); ct = FindQuickDivisor(bdd_bdd_T(f), one, v); if (ct == -1) /* already found */ return(-1); else if (ct > 1) { *v = bdd_node_read_index(f); return(-1); } ce = FindQuickDivisor(bdd_bdd_E(f), one, v); if (ce == -1) /* already found */ return(-1); /* Add the number of path to constant 1 from two children nodes. */ c = ct + ce; return(c); }
bdd_node* Synth_ZddCommonDivisor | ( | bdd_manager * | dd, |
bdd_node * | f | ||
) |
Function********************************************************************
Synopsis [Find a divisor whose literals occur in all cubes.]
Description [Find a divisor whose literals occur in all cubes. It returns a ZDD node.]
SideEffects []
SeeAlso [Synth_ZddQuickDivisor Synth_ZddMostDivisor Synth_ZddLeastDivisor Synth_ZddLevelZeroDivisor Synth_ZddLpDivisor]
Definition at line 242 of file synthDiv.c.
{ bdd_node *res; if (bdd_get_package_name() != CUDD) { (void)fprintf(vis_stderr, "** synth error: Synthesis package can be used only with CUDD package\n"); (void)fprintf(vis_stderr,"** synth error: Please link with CUDD package\n"); return NIL(bdd_node); } do { bdd_set_reordered_field(dd, 0); res = SynthZddCommonDivisor(dd, f); } while (bdd_read_reordered_field(dd) == 1); return(res); }
bdd_node* Synth_ZddLeastDivisor | ( | bdd_manager * | dd, |
bdd_node * | f | ||
) |
Function********************************************************************
Synopsis [Finds a divisor that occurs the least frequently (but more than once) in the cubes of a cover.]
Description [Finds a divisor that occurs the least frequently (but more than once) in the cubes of a cover. It returns a ZDD node.]
SideEffects []
SeeAlso [Synth_ZddQuickDivisor Synth_ZddMostDivisor Synth_ZddLevelZeroDivisor Synth_ZddCommonDivisor Synth_ZddLpDivisor]
Definition at line 139 of file synthDiv.c.
{ bdd_node *res; if (bdd_get_package_name() != CUDD) { (void)fprintf(vis_stderr, "** synth error: Synthesis package can be used only with CUDD package\n"); (void)fprintf(vis_stderr,"** synth error: Please link with CUDD package\n"); return NIL(bdd_node); } do { bdd_set_reordered_field(dd, 0); res = SynthZddLeastDivisor(dd, f); } while (bdd_read_reordered_field(dd) == 1); return(res); }
bdd_node* Synth_ZddLevelZeroDivisor | ( | bdd_manager * | dd, |
bdd_node * | f | ||
) |
Function********************************************************************
Synopsis [Finds a divisor that is a level-0 cokernel.]
Description [Finds a divisor that is a level-0 cokernel. It returns a ZDD node.]
SideEffects []
SeeAlso [Synth_ZddQuickDivisor Synth_ZddLeastDivisor Synth_ZddMostDivisor Synth_ZddCommonDivisor Synth_ZddLpDivisor]
Definition at line 208 of file synthDiv.c.
{ bdd_node *res; if (bdd_get_package_name() != CUDD) { (void)fprintf(vis_stderr, "** synth error: Synthesis package can be used only with CUDD package\n"); (void)fprintf(vis_stderr,"** synth error: Please link with CUDD package\n"); return NIL(bdd_node); } do { bdd_set_reordered_field(dd, 0); res = SynthZddLevelZeroDivisor(dd, f); } while (bdd_read_reordered_field(dd) == 1); return(res); }
bdd_node* Synth_ZddLpDivisor | ( | bdd_manager * | dd, |
bdd_node * | f | ||
) |
Function********************************************************************
Synopsis [Find a good divisor for low power.]
Description [Find a good divisor for low power. It returns a ZDD node.]
SideEffects []
SeeAlso [Synth_ZddQuickDivisor Synth_ZddMostDivisor Synth_ZddLeastDivisor Synth_ZddLevelZeroDivisor Synth_ZddCommonDivisor]
Definition at line 275 of file synthDiv.c.
{ bdd_node *res; if (bdd_get_package_name() != CUDD) { (void)fprintf(vis_stderr, "** synth error: Synthesis package can be used only with CUDD package\n"); (void)fprintf(vis_stderr,"** synth error: Please link with CUDD package\n"); return NIL(bdd_node); } do { bdd_set_reordered_field(dd, 0); res = SynthZddLpDivisor(dd, f); } while (bdd_read_reordered_field(dd) == 1); return(res); }
bdd_node* Synth_ZddMostDivisor | ( | bdd_manager * | dd, |
bdd_node * | f | ||
) |
Function********************************************************************
Synopsis [Finds a divisor that occurs the most frequently in the cubes of a cover.]
Description [Finds a divisor that occurs the most frequently in the cubes of a cover. It returns a ZDD node.]
SideEffects []
SeeAlso [Synth_ZddQuickDivisor Synth_ZddLeastDivisor Synth_ZddLevelZeroDivisor Synth_ZddCommonDivisor Synth_ZddLpDivisor]
Definition at line 174 of file synthDiv.c.
{ bdd_node *res; if (bdd_get_package_name() != CUDD) { (void)fprintf(vis_stderr, "** synth error: Synthesis package can be used only with CUDD package\n"); (void)fprintf(vis_stderr,"** synth error: Please link with CUDD package\n"); return NIL(bdd_node); } do { bdd_set_reordered_field(dd, 0); res = SynthZddMostDivisor(dd, f); } while (bdd_read_reordered_field(dd) == 1); return(res); }
bdd_node* Synth_ZddQuickDivisor | ( | bdd_manager * | dd, |
bdd_node * | f | ||
) |
AutomaticEnd Function********************************************************************
Synopsis [Finds a divisor that occurs in more than one cube of the ZDD graph.]
Description [Finds a divisor that occurs in more than one cube of the ZDD graph. This is done in a greedy manner. It returns a ZDD node.]
SideEffects []
SeeAlso [Synth_ZddLeastDivisor Synth_ZddMostDivisor Synth_ZddLevelZeroDivisor Synth_ZddCommonDivisor Synth_ZddLpDivisor]
Definition at line 104 of file synthDiv.c.
{ bdd_node *res; if (bdd_get_package_name() != CUDD) { (void)fprintf(vis_stderr, "** synth error: Synthesis package can be used only with CUDD package\n"); (void)fprintf(vis_stderr,"** synth error: Please link with CUDD package\n"); return NIL(bdd_node); } do { bdd_set_reordered_field(dd, 0); res = SynthZddQuickDivisor(dd, f); } while (bdd_read_reordered_field(dd) == 1); return(res); }
void SynthCountLiteralOccurrence | ( | bdd_manager * | dd, |
bdd_node * | f, | ||
int * | count | ||
) |
Function********************************************************************
Synopsis [Counts the number of occurrences of each variable.]
Description [Counts the number of occurrences of each variable. First, we count the number of paths to the top node for each node from top to bottom. Let this number be C_t. Initially, C_t of the top node is 1, and C_t of a node is the sum of C_t's of all predecessors of the node. Second, we count the number of paths to the constant one node from bottom to top. Let this number be C_1. Initially, C_1 of the constant one node is 1 and C_1 of the constant zero node is 0, and C_1 of a node is the sum of C_1's of two successors of the node. Third, we count the number of occurrences of variables using the C_t's and C_1's of each node. Here, let C_m of a node be C_t of the node times C_1 of then child of the node. The number of occurrences of a variable is determined by summing C_m of all nodes that belongs to the variable in the ZDD. The argument count is passed by caller, and it is an array of integer to store the number of occurrence for each variable, and the size of the array is the number of ZDD variables.]
SideEffects []
SeeAlso []
Definition at line 812 of file synthDiv.c.
{ BfsItem **level, *item, *cur_item, *next_item, *last_item; BfsList *list, *pre_list, *cur_list, *next_list, *last_list; BfsList *new_list, *save_last_list; int cur_level, next_level, start_level, last_level; int exist; bdd_node *zero = bdd_read_zero(dd); bdd_node *one = bdd_read_one(dd); int i, ct, ce; bdd_node *node; int lv, *index, id; int sizeZ = bdd_num_zdd_vars(dd); if (bdd_is_constant(f)) return; level = ALLOC(BfsItem *, sizeZ); (void)memset((void *)level, 0, sizeof(BfsItem *) * sizeZ); index = ALLOC(int, sizeZ); (void)memset((void *)index, 0, sizeof(int) * sizeZ); /* Initialize BFS by entering f in the queue. */ item = ALLOC(BfsItem, 1); (void)memset((void *)item, 0, sizeof(BfsItem)); item->node = f; item->reach = 1; lv = bdd_read_zdd_level(dd,bdd_node_read_index(f)); level[lv] = item; index[lv] = bdd_node_read_index(f); start_level = last_level = lv; if (!bdd_is_constant(bdd_bdd_T(f))) { list = ALLOC(BfsList, 1); (void)memset((void *)list, 0, sizeof(BfsList)); list->item = item; list->child = 1; last_list = list; } else list = last_list = (BfsList *)NULL; if (!bdd_is_constant(bdd_bdd_E(f))) { last_list = ALLOC(BfsList, 1); (void)memset((void *)last_list, 0, sizeof(BfsList)); last_list->item = item; last_list->child = 0; if (list) list->next = last_list; else list = last_list; } /* Perform the BFS. */ while (list) { cur_level = sizeZ; cur_list = list; while (cur_list) { if (cur_list->child) id = bdd_node_read_index(bdd_bdd_T(cur_list->item->node)); else id = bdd_node_read_index(bdd_bdd_E(cur_list->item->node)); next_level = bdd_read_zdd_level(dd,id); cur_level = (cur_level < next_level) ? cur_level : next_level; cur_list = cur_list->next; } last_level = cur_level; save_last_list = last_list; pre_list = (BfsList *)NULL; cur_list = list; while (cur_list) { if (cur_list->child) id = bdd_node_read_index(bdd_bdd_T(cur_list->item->node)); else id = bdd_node_read_index(bdd_bdd_E(cur_list->item->node)); next_level = bdd_read_zdd_level(dd,id); if (next_level != cur_level) { pre_list = cur_list; cur_list = cur_list->next; continue; } if (cur_list->child) node = bdd_bdd_T(cur_list->item->node); else node = bdd_bdd_E(cur_list->item->node); exist = 0; last_item = level[cur_level]; while (last_item) { if (node == last_item->node) { last_item->reach += cur_list->item->reach; exist = 1; break; } if (last_item->next) last_item = last_item->next; else break; } if (exist == 0) { item = ALLOC(BfsItem, 1); (void)memset((void *)item, 0, sizeof(BfsItem)); item->node = node; item->reach = cur_list->item->reach; if (last_item) last_item->next = item; else { level[cur_level] = item; index[cur_level] = id; } if (!bdd_is_constant(bdd_bdd_T(node))) { new_list = ALLOC(BfsList, 1); (void)memset((void *)new_list, 0, sizeof(BfsList)); new_list->item = item; new_list->child = 1; last_list->next = new_list; last_list = new_list; } if (!bdd_is_constant(bdd_bdd_E(node))) { new_list = ALLOC(BfsList, 1); (void)memset((void *)new_list, 0, sizeof(BfsList)); new_list->item = item; new_list->child = 0; last_list->next = new_list; last_list = new_list; } } next_list = cur_list->next; if (cur_list == list && cur_list == last_list) { FREE(cur_list); list = next_list; } else if (cur_list == list) { FREE(cur_list); pre_list = (BfsList *)NULL; if (list == save_last_list) { list = next_list; next_list = (BfsList *)NULL; } else list = next_list; } else if (cur_list == last_list) { if (pre_list) pre_list->next = cur_list->next; FREE(cur_list); last_list = pre_list; } else { if (pre_list) pre_list->next = cur_list->next; if (cur_list == save_last_list) { FREE(cur_list); next_list = (BfsList *)NULL; } else FREE(cur_list); } cur_list = next_list; } } /* Compute the number of paths to the constant 1 for each node in * bottom up fashion. Update the occurrence count of the variables. */ for (i = last_level; i >= start_level; i--) { item = level[i]; while (item) { ct = ce = 0; if (bdd_bdd_T(item->node) == one) ct = 1; else { node = bdd_bdd_T(item->node); next_level = bdd_read_zdd_level(dd, bdd_node_read_index(node)); cur_item = level[next_level]; while (cur_item) { if (cur_item->node == node) { ct = cur_item->count; break; } cur_item = cur_item->next; } } if (bdd_bdd_E(item->node) != zero) { node = bdd_bdd_E(item->node); next_level = bdd_read_zdd_level(dd, bdd_node_read_index(node)); cur_item = level[next_level]; while (cur_item) { if (cur_item->node == node) { ce = cur_item->count; break; } cur_item = cur_item->next; } } item->count = ct + ce; count[index[i]] += ct * item->reach; item = item->next; } } /* Clean up. */ for (i = last_level; i >= start_level; i--) { item = level[i]; while (item) { next_item = item->next; FREE(item); item = next_item; } } FREE(level); FREE(index); }
bdd_node* SynthZddCommonDivisor | ( | bdd_manager * | dd, |
bdd_node * | f | ||
) |
Function********************************************************************
Synopsis [The internal function of Synth_ZddCommonDivisor.]
Description [The internal function of Synth_ZddCommonDivisor.]
SideEffects []
SeeAlso [SynthZddQuickDivisor SynthZddLeastDivisor SynthZddMostDivisor SynthZddLevelZeroDivisor SynthZddLpDivisor]
Definition at line 640 of file synthDiv.c.
{ int i; int nvars; int *count; bdd_node *one = bdd_read_one(dd); bdd_node *zero = bdd_read_zero(dd); bdd_node *divisor, *node, *tmp; int nCubes; divisor = (bdd_node *)NULL; /* NULL means no such divisor exists */ if (f == one || f == zero) return(divisor); nCubes = bdd_zdd_count(dd, f); if (nCubes == 1) return(divisor); /* Find the literals that appear exactly as many times as there * are cubes. These literals appear in all cubes, hence in the * common divisor. Their product is accumulated in divisor. */ nvars = bdd_num_zdd_vars(dd); count = ALLOC(int, nvars); (void)memset((void *)count, 0, sizeof(int) * nvars); SynthCountLiteralOccurrence(dd, f, count); for (i = 0; i < nvars; i++) { if (count[i] == nCubes) { node = bdd_zdd_get_node(dd, i, one, zero); if (!node) { FREE(count); return(NULL); } bdd_ref(node); if (!divisor) { divisor = node; continue; } tmp = divisor; divisor = (* SynthGetZddProductRecurFunc())(dd, divisor, node); if (!divisor) { bdd_recursive_deref_zdd(dd, tmp); bdd_recursive_deref_zdd(dd, node); FREE(count); return(NULL); } bdd_ref(divisor); bdd_recursive_deref_zdd(dd, tmp); bdd_recursive_deref_zdd(dd, node); } } FREE(count); if (divisor) bdd_deref(divisor); return(divisor); }
bdd_node* SynthZddLeastDivisor | ( | bdd_manager * | dd, |
bdd_node * | f | ||
) |
Function********************************************************************
Synopsis [Performs the recursive steps of Synth_ZddLeastDivisor.]
Description [Performs the recursive steps of Synth_ZddLeastDivisor.]
SideEffects []
SeeAlso [SynthZddQuickDivisor SynthZddMostDivisor SynthZddLevelZeroDivisor SynthZddCommonDivisor SynthZddLpDivisor]
Definition at line 402 of file synthDiv.c.
{ int i, v; int nvars, min_count; int *count; bdd_node *one = bdd_read_one(dd); bdd_node *zero = bdd_read_zero(dd); bdd_node *divisor, *node; bdd_node *tmp1; if (f == one || f == zero) return(f); /* Find the literal that occurs the least among those occuring at * least twice. */ v = -1; min_count = MAX_COUNT; nvars = bdd_num_zdd_vars(dd); count = ALLOC(int, nvars); (void)memset((void *)count, 0, sizeof(int) * nvars); SynthCountLiteralOccurrence(dd, f, count); for (i = 0; i < nvars; i++) { if (count[i] > 1 && count[i] < min_count) { v = i; min_count = count[i]; } } FREE(count); if (v == -1) { /* All literal appear exactly once. We are done. */ return(f); } /* Obtain the literal divisor from its index and divide f. */ node = bdd_zdd_get_node(dd, v, one, zero); if (!node) { return(NULL); } bdd_ref(node); tmp1 = (* SynthGetZddDivideRecurFunc())(dd, f, node); if (!tmp1) { bdd_recursive_deref_zdd(dd, node); return(NULL); } bdd_ref(tmp1); bdd_recursive_deref_zdd(dd, node); /* Recur on the quotient to make sure that all literals appear once. */ divisor = SynthZddLeastDivisor(dd, tmp1); if (!divisor) { bdd_recursive_deref_zdd(dd, tmp1); return(NULL); } bdd_ref(divisor); bdd_recursive_deref_zdd(dd, tmp1); bdd_deref(divisor); return(divisor); }
bdd_node* SynthZddLevelZeroDivisor | ( | bdd_manager * | dd, |
bdd_node * | f | ||
) |
Function********************************************************************
Synopsis [Performs the recursive steps of Synth_ZddLevelZeroDivisor.]
Description [Performs the recursive steps of Synth_ZddLevelZeroDivisor.]
SideEffects []
SeeAlso [SynthZddQuickDivisor SynthZddLeastDivisor SynthZddMostDivisor SynthZddCommonDivisor SynthZddLpDivisor]
Definition at line 556 of file synthDiv.c.
{ int i, v; int nvars, max_count; int *count; bdd_node *one = bdd_read_one(dd); bdd_node *zero = bdd_read_zero(dd); bdd_node *divisor, *node; bdd_node *tmp1, *tmp2; if (f == one || f == zero) return(f); /* Find the literal that occurs the most. */ v = -1; max_count = 1; nvars = bdd_num_zdd_vars(dd); count = ALLOC(int, nvars); (void)memset((void *)count, 0, sizeof(int) * nvars); SynthCountLiteralOccurrence(dd, f, count); for (i = 0; i < nvars; i++) { if (count[i] > max_count) { v = i; max_count = count[i]; } } FREE(count); if (v == -1) { /* All literal appear exactly once. We are done. */ return(f); } /* Obtain the literal divisor from its index and divide f. */ node = bdd_zdd_get_node(dd, v, one, zero); if (!node) return(NULL); bdd_ref(node); tmp1 = (* SynthGetZddDivideRecurFunc())(dd, f, node); if (!tmp1) { bdd_recursive_deref_zdd(dd, node); return(NULL); } bdd_ref(tmp1); bdd_recursive_deref_zdd(dd, node); /* Factor out all literals appearing in all cubes. */ tmp2 = SynthMakeCubeFree(dd, tmp1); if (!tmp2) { bdd_recursive_deref_zdd(dd, tmp1); return(NULL); } bdd_ref(tmp2); bdd_recursive_deref_zdd(dd, tmp1); /* Recur on the quotient to make sure that all literals appear once. */ divisor = SynthZddLevelZeroDivisor(dd, tmp2); if (!divisor) { bdd_recursive_deref_zdd(dd, tmp2); return(NULL); } bdd_ref(divisor); bdd_recursive_deref_zdd(dd, tmp2); bdd_deref(divisor); return(divisor); }
bdd_node* SynthZddLpDivisor | ( | bdd_manager * | dd, |
bdd_node * | f | ||
) |
Function********************************************************************
Synopsis [Performs the recursive steps of Synth_ZddLpDivisor.]
Description [Performs the recursive steps of Synth_ZddLpDivisor.]
SideEffects []
SeeAlso [SynthZddQuickDivisor SynthZddLeastDivisor SynthZddMostDivisor SynthZddLevelZeroDivisor SynthZddCommonDivisor]
Definition at line 712 of file synthDiv.c.
{ int i, v; int nvars, min_count, min_pos = 0; int *count; bdd_node *one = bdd_read_one(dd); bdd_node *zero = bdd_read_zero(dd); bdd_node *divisor, *node; bdd_node *tmp1; if (f == one || f == zero) return(f); /* Find the literal that occurs the least among those occuring at * least twice. */ v = -1; min_count = MAX_COUNT; nvars = bdd_num_zdd_vars(dd); count = ALLOC(int, nvars); (void)memset((void *)count, 0, sizeof(int) * nvars); SynthCountLiteralOccurrence(dd, f, count); for (i = 0; i < nvars; i++) { if (count[i] > 1 && count[i] < min_count) { v = i; min_count = count[i]; min_pos = i; } } if (v == -1) { /* All literal appear exactly once. We are done. */ FREE(count); return(f); } /* Among the literals with minimum count, find a good one. */ v = SynthFindDivisorForLowPower(count, nvars, min_count, min_pos); FREE(count); if (v == -1) { return(f); } /* Obtain the literal divisor from its index and divide f. */ node = bdd_zdd_get_node(dd, v, one, zero); if (!node) return(NULL); bdd_ref(node); tmp1 = (* SynthGetZddDivideRecurFunc())(dd, f, node); if (!tmp1) { bdd_recursive_deref_zdd(dd, node); return(NULL); } bdd_ref(tmp1); bdd_recursive_deref_zdd(dd, node); /* Recur on the quotient to make sure that all literals appear once. */ divisor = SynthZddLpDivisor(dd, tmp1); if (!divisor) { bdd_recursive_deref_zdd(dd, tmp1); return(NULL); } bdd_ref(divisor); bdd_recursive_deref_zdd(dd, tmp1); bdd_deref(divisor); return(divisor); }
bdd_node* SynthZddMostDivisor | ( | bdd_manager * | dd, |
bdd_node * | f | ||
) |
Function********************************************************************
Synopsis [Performs the recursive steps of Synth_ZddMostDivisor.]
Description [Performs the recursive steps of Synth_ZddMostDivisor.]
SideEffects []
SeeAlso [SynthZddQuickDivisor SynthZddLeastDivisor SynthZddLevelZeroDivisor SynthZddCommonDivisor SynthZddLpDivisor]
Definition at line 480 of file synthDiv.c.
{ int i, v; int nvars, max_count; int *count; bdd_node *one = bdd_read_one(dd); bdd_node *zero = bdd_read_zero(dd); bdd_node *divisor, *node; bdd_node *tmp1; if (f == one || f == zero) return(f); /* Find the literal that occurs the most. */ v = -1; max_count = 1; nvars = bdd_num_zdd_vars(dd); count = ALLOC(int, nvars); (void)memset((void *)count, 0, sizeof(int) * nvars); SynthCountLiteralOccurrence(dd, f, count); for (i = 0; i < nvars; i++) { if (count[i] > max_count) { v = i; max_count = count[i]; } } FREE(count); if (v == -1) { /* All literal appear exactly once. We are done. */ return(f); } /* Obtain the literal divisor from its index and divide f. */ node = bdd_zdd_get_node(dd, v, one, zero); if (!node) return(NULL); bdd_ref(node); tmp1 = (* SynthGetZddDivideRecurFunc())(dd, f, node); if (!tmp1) { bdd_recursive_deref_zdd(dd, node); return(NULL); } bdd_ref(tmp1); bdd_recursive_deref_zdd(dd, node); /* Recur on the quotient to make sure that all literals appear once. */ divisor = SynthZddMostDivisor(dd, tmp1); if (!divisor) { bdd_recursive_deref_zdd(dd, tmp1); return(NULL); } bdd_ref(divisor); bdd_recursive_deref_zdd(dd, tmp1); bdd_deref(divisor); return(divisor); }
bdd_node* SynthZddQuickDivisor | ( | bdd_manager * | dd, |
bdd_node * | f | ||
) |
Function********************************************************************
Synopsis [Performs the recursive steps of Synth_ZddQuickDivisor.]
Description [Performs the recursive steps of Synth_ZddQuickDivisor. When FindQuickDivisor fails to find a literal, the function uses as backup strategy finding the literal that occurs the least. The reason is the following. If a node has more than one parent, then it is guaranteed to appear in more than one cube. However, the converse is not true.]
SideEffects []
SeeAlso [SynthZddLeastDivisor SynthZddMostDivisor SynthZddLevelZeroDivisor SynthZddCommonDivisor SynthZddLpDivisor]
Definition at line 318 of file synthDiv.c.
{ int i, v; int nvars; int *count; bdd_node *one = bdd_read_one(dd); bdd_node *zero = bdd_read_zero(dd); bdd_node *divisor, *node; bdd_node *tmp; int min_count; if (f == one || f == zero) return(f); /* Search for a literal appearing in at least two cubes. */ v = -1; FindQuickDivisor(f, one, &v); SynthZddClearFlag(f); if (v == -1) { /* Quick divisor not found by looking at the ZDD graph. * Find the literal that occurs the least among those occuring * at least twice. */ min_count = MAX_COUNT; nvars = bdd_num_zdd_vars(dd); count = ALLOC(int, nvars); (void)memset((void *)count, 0, sizeof(int) * nvars); SynthCountLiteralOccurrence(dd, f, count); for (i = 0; i < nvars; i++) { if (count[i] > 1 && count[i] < min_count) { v = i; min_count = count[i]; } } FREE(count); if (v == -1) { /* All literal appear exactly once. We are done. */ return(f); } } /* Obtain the literal divisor from its index and divide f. */ node = bdd_zdd_get_node(dd, v, one, zero); if (!node) return(NULL); bdd_ref(node); tmp = (* SynthGetZddDivideRecurFunc())(dd, f, node); if (!tmp) { bdd_recursive_deref_zdd(dd,node); return(NULL); } bdd_ref(tmp); bdd_recursive_deref_zdd(dd, node); /* Recur on the quotient to make sure that all literals appear once. */ divisor = SynthZddQuickDivisor(dd, tmp); if (!divisor) { bdd_recursive_deref_zdd(dd,tmp); return(NULL); } bdd_ref(divisor); bdd_recursive_deref_zdd(dd, tmp); bdd_deref(divisor); return(divisor); }
char rcsid [] UNUSED = "$Id: synthDiv.c,v 1.25 2002/09/10 05:50:52 fabio Exp $" [static] |
CFile***********************************************************************
FileName [synthDiv.c]
PackageName [synth]
Synopsis [Divisor functions.]
Author [In-Ho Moon, Balakrishna Kumthekar]
Copyright [This file was created at the University of Colorado at Boulder. The University of Colorado at Boulder makes no warranty about the suitability of this software for any purpose. It is presented on an AS IS basis.]
Definition at line 19 of file synthDiv.c.