mirror of
https://github.com/YosysHQ/abc.git
synced 2026-09-02 02:37:25 +02:00
320 lines
5.9 KiB
C
320 lines
5.9 KiB
C
/*
|
|
* Revision Control Information
|
|
*
|
|
* $Source$
|
|
* $Author$
|
|
* $Revision$
|
|
* $Date$
|
|
*
|
|
*/
|
|
//#include "port.h"
|
|
#include "sparse_int.h"
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
|
|
/*
|
|
* allocate a new row vector
|
|
*/
|
|
sm_row *
|
|
sm_row_alloc()
|
|
{
|
|
register sm_row *prow;
|
|
|
|
#ifdef FAST_AND_LOOSE
|
|
if (sm_row_freelist == NIL(sm_row)) {
|
|
prow = ALLOC(sm_row, 1);
|
|
} else {
|
|
prow = sm_row_freelist;
|
|
sm_row_freelist = prow->next_row;
|
|
}
|
|
#else
|
|
prow = ALLOC(sm_row, 1);
|
|
#endif
|
|
|
|
prow->row_num = 0;
|
|
prow->length = 0;
|
|
prow->first_col = prow->last_col = NIL(sm_element);
|
|
prow->next_row = prow->prev_row = NIL(sm_row);
|
|
prow->flag = 0;
|
|
prow->user_word = NIL(char); /* for our user ... */
|
|
return prow;
|
|
}
|
|
|
|
|
|
/*
|
|
* free a row vector -- for FAST_AND_LOOSE, this is real cheap for rows;
|
|
* however, freeing a column must still walk down the column discarding
|
|
* the elements one-by-one; that is the only use for the extra '-DCOLS'
|
|
* compile flag ...
|
|
*/
|
|
void
|
|
sm_row_free(prow)
|
|
register sm_row *prow;
|
|
{
|
|
#if defined(FAST_AND_LOOSE) && ! defined(COLS)
|
|
if (prow->first_col != NIL(sm_element)) {
|
|
/* Add the linked list of row items to the free list */
|
|
prow->last_col->next_col = sm_element_freelist;
|
|
sm_element_freelist = prow->first_col;
|
|
}
|
|
|
|
/* Add the row to the free list of rows */
|
|
prow->next_row = sm_row_freelist;
|
|
sm_row_freelist = prow;
|
|
#else
|
|
register sm_element *p, *pnext;
|
|
|
|
for(p = prow->first_col; p != 0; p = pnext) {
|
|
pnext = p->next_col;
|
|
sm_element_free(p);
|
|
}
|
|
FREE(prow);
|
|
#endif
|
|
}
|
|
|
|
|
|
/*
|
|
* duplicate an existing row
|
|
*/
|
|
sm_row *
|
|
sm_row_dup(prow)
|
|
register sm_row *prow;
|
|
{
|
|
register sm_row *pnew;
|
|
register sm_element *p;
|
|
|
|
pnew = sm_row_alloc();
|
|
for(p = prow->first_col; p != 0; p = p->next_col) {
|
|
(void) sm_row_insert(pnew, p->col_num);
|
|
}
|
|
return pnew;
|
|
}
|
|
|
|
|
|
/*
|
|
* insert an element into a row vector
|
|
*/
|
|
sm_element *
|
|
sm_row_insert(prow, col)
|
|
register sm_row *prow;
|
|
register int col;
|
|
{
|
|
register sm_element *test, *element;
|
|
|
|
/* get a new item, save its address */
|
|
sm_element_alloc(element);
|
|
test = element;
|
|
sorted_insert(sm_element, prow->first_col, prow->last_col, prow->length,
|
|
next_col, prev_col, col_num, col, test);
|
|
|
|
/* if item was not used, free it */
|
|
if (element != test) {
|
|
sm_element_free(element);
|
|
}
|
|
|
|
/* either way, return the current new value */
|
|
return test;
|
|
}
|
|
|
|
|
|
/*
|
|
* remove an element from a row vector
|
|
*/
|
|
void
|
|
sm_row_remove(prow, col)
|
|
register sm_row *prow;
|
|
register int col;
|
|
{
|
|
register sm_element *p;
|
|
|
|
for(p = prow->first_col; p != 0 && p->col_num < col; p = p->next_col)
|
|
;
|
|
if (p != 0 && p->col_num == col) {
|
|
dll_unlink(p, prow->first_col, prow->last_col,
|
|
next_col, prev_col, prow->length);
|
|
sm_element_free(p);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* find an element (if it is in the row vector)
|
|
*/
|
|
sm_element *
|
|
sm_row_find(prow, col)
|
|
sm_row *prow;
|
|
int col;
|
|
{
|
|
register sm_element *p;
|
|
|
|
for(p = prow->first_col; p != 0 && p->col_num < col; p = p->next_col)
|
|
;
|
|
if (p != 0 && p->col_num == col) {
|
|
return p;
|
|
} else {
|
|
return NIL(sm_element);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* return 1 if row p2 contains row p1; 0 otherwise
|
|
*/
|
|
int
|
|
sm_row_contains(p1, p2)
|
|
sm_row *p1, *p2;
|
|
{
|
|
register sm_element *q1, *q2;
|
|
|
|
q1 = p1->first_col;
|
|
q2 = p2->first_col;
|
|
while (q1 != 0) {
|
|
if (q2 == 0 || q1->col_num < q2->col_num) {
|
|
return 0;
|
|
} else if (q1->col_num == q2->col_num) {
|
|
q1 = q1->next_col;
|
|
q2 = q2->next_col;
|
|
} else {
|
|
q2 = q2->next_col;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
|
|
/*
|
|
* return 1 if row p1 and row p2 share an element in common
|
|
*/
|
|
int
|
|
sm_row_intersects(p1, p2)
|
|
sm_row *p1, *p2;
|
|
{
|
|
register sm_element *q1, *q2;
|
|
|
|
q1 = p1->first_col;
|
|
q2 = p2->first_col;
|
|
if (q1 == 0 || q2 == 0) return 0;
|
|
for(;;) {
|
|
if (q1->col_num < q2->col_num) {
|
|
if ((q1 = q1->next_col) == 0) {
|
|
return 0;
|
|
}
|
|
} else if (q1->col_num > q2->col_num) {
|
|
if ((q2 = q2->next_col) == 0) {
|
|
return 0;
|
|
}
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* compare two rows, lexical ordering
|
|
*/
|
|
int
|
|
sm_row_compare(p1, p2)
|
|
sm_row *p1, *p2;
|
|
{
|
|
register sm_element *q1, *q2;
|
|
|
|
q1 = p1->first_col;
|
|
q2 = p2->first_col;
|
|
while(q1 != 0 && q2 != 0) {
|
|
if (q1->col_num != q2->col_num) {
|
|
return q1->col_num - q2->col_num;
|
|
}
|
|
q1 = q1->next_col;
|
|
q2 = q2->next_col;
|
|
}
|
|
|
|
if (q1 != 0) {
|
|
return 1;
|
|
} else if (q2 != 0) {
|
|
return -1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* return the intersection
|
|
*/
|
|
sm_row *
|
|
sm_row_and(p1, p2)
|
|
sm_row *p1, *p2;
|
|
{
|
|
register sm_element *q1, *q2;
|
|
register sm_row *result;
|
|
|
|
result = sm_row_alloc();
|
|
q1 = p1->first_col;
|
|
q2 = p2->first_col;
|
|
if (q1 == 0 || q2 == 0) return result;
|
|
for(;;) {
|
|
if (q1->col_num < q2->col_num) {
|
|
if ((q1 = q1->next_col) == 0) {
|
|
return result;
|
|
}
|
|
} else if (q1->col_num > q2->col_num) {
|
|
if ((q2 = q2->next_col) == 0) {
|
|
return result;
|
|
}
|
|
} else {
|
|
(void) sm_row_insert(result, q1->col_num);
|
|
if ((q1 = q1->next_col) == 0) {
|
|
return result;
|
|
}
|
|
if ((q2 = q2->next_col) == 0) {
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int
|
|
sm_row_hash(prow, modulus)
|
|
sm_row *prow;
|
|
int modulus;
|
|
{
|
|
register int sum;
|
|
register sm_element *p;
|
|
|
|
sum = 0;
|
|
for(p = prow->first_col; p != 0; p = p->next_col) {
|
|
sum = (sum*17 + p->col_num) % modulus;
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
/*
|
|
* remove an element from a row vector (given a pointer to the element)
|
|
*/
|
|
void
|
|
sm_row_remove_element(prow, p)
|
|
register sm_row *prow;
|
|
register sm_element *p;
|
|
{
|
|
dll_unlink(p, prow->first_col, prow->last_col,
|
|
next_col, prev_col, prow->length);
|
|
sm_element_free(p);
|
|
}
|
|
|
|
|
|
void
|
|
sm_row_print(fp, prow)
|
|
FILE *fp;
|
|
sm_row *prow;
|
|
{
|
|
sm_element *p;
|
|
|
|
for(p = prow->first_col; p != 0; p = p->next_col) {
|
|
(void) fprintf(fp, " %d", p->col_num);
|
|
}
|
|
}
|
|
ABC_NAMESPACE_IMPL_END
|
|
|