/* ---------------------------------------------------------------------- */ /* gem.c - original version of {gem_residues_enum} */ void gem_residues_enum(gem_ref_t root, int d, int rcol[], int r, int scol[], int s, int na, gem_ref_t nodes[], int *nnP) { demand((d >= 0) && (d <= gem_MAX_DIM), "invalid dimension"); int i; for(i = 0; i < r; i++) { demand((rcol[i] >= 0) && (rcol[i] <= d), "invalid R-color"); } for(i = 0; i < s; i++) { demand((scol[i] >= 0) && (scol[i] <= d), "invalid S-color"); } int nn = 0; /* Number of nodes seen so far. */ /* List of marked nodes: */ gem_ref_t *mark = notnull(malloc(na*sizeof(gem_ref_t)), "no mem"); int nnMark = 0; auto void mark_node(gem_ref_t p); auto int is_marked(gem_ref_t p); void mark_node(gem_ref_t p) { if ((p->label < 0) || (p->label >= (nnMark))||(mark[p->label]!=p)) { mark[nnMark] = p; mark[nnMark]->label = nnMark; (nnMark)++; } } int is_marked(gem_ref_t p) { return ((p->label >= 0) && (p->label < nnMark) && (mark[p->label] == p)); } /* The {r}-stack: */ gem_ref_t *rstack = notnull(malloc(na*sizeof(gem_ref_t)), "no mem"); int nnr = 0; /* The {s}-stack: */ gem_ref_t *sstack = notnull(malloc(na*sizeof(gem_ref_t)), "no mem"); sstack[0] = root; int nns = 1; while((nnr>0) || (nns>0)) { gem_ref_t p; if (nnr == 0) { p = sstack[--nns]; if (! is_marked(p)) { demand(nn < na, "too many nodes"); nodes[nn++] = p; } } else { p = rstack[--nnr]; } if (!is_marked(p)) { mark_node(p); for(i = 0; i < r; i++) { demand(nnr < na, "too many nodes"); rstack[nnr++] = p->adj[rcol[i]]; } for(i = 0; i < s; i++) { demand(nns < na, "too many nodes"); sstack[nns++] = p->adj[scol[i]]; } } } for(i = 0; i < nn; i++) { nodes[i]->label = i; } free(mark); free(rstack); free(sstack); (*nnP) = nn; } /* ---------------------------------------------------------------------- */ // used to collect data on a traversal typedef struct { gem_ref_t head; gem_ref_t tail; int color; } Edge; // a GEM node will have gem_MAX_DIM pointers //#define gem_MAX_NODES 10000000 // size of the stack used for traversing a gem. #define MAX_GEM_EDGES ((gem_MAX_NODES*gem_MAX_DIM+1)/2) // used to collect data on a traversal typedef struct { gem_ref_thead; gem_ref_ttail; int color; } Edge;