static cluster_data* cluster_map(graph_t *mastergraph, graph_t *g) { /* search meta-graph to find clusters */ graph_t *mg, *subg; node_t *mm, *mn; node_t *n; edge_t *me; /* array of arrays of node indices in each cluster */ int **cs,*cn; int i,j,nclusters=0; bool* assigned = N_NEW(agnnodes(g), bool); cluster_data *cdata = GNEW(cluster_data); cdata->ntoplevel = agnnodes(g); mm = mastergraph->meta_node; mg = mm->graph; for (me = agfstout(mg, mm); me; me = agnxtout(mg, me)) { mn = me->head; subg = agusergraph(mn); if (!strncmp(subg->name, "cluster", 7)) { nclusters++; } } cdata->nvars=0; cdata->nclusters = nclusters; cs = cdata->clusters = N_GNEW(nclusters,int*); cn = cdata->clustersizes = N_GNEW(nclusters,int); /* fprintf(stderr,"search %d clusters...\n",nclusters); */ for (me = agfstout(mg, mm); me; me = agnxtout(mg, me)) { mn = me->head; subg = agusergraph(mn); /* clusters are processed by separate calls to ordered_edges */ if (!strncmp(subg->name, "cluster", 7)) { int *c; *cn = agnnodes(subg); cdata->nvars += *cn; c = *cs++ = N_GNEW(*cn++,int); /* fprintf(stderr,"Cluster with %d nodes...\n",agnnodes(subg)); */ for (n = agfstnode(subg); n; n = agnxtnode(subg, n)) { node_t *gn; int ind = 0; for (gn = agfstnode(g); gn; gn = agnxtnode(g, gn)) { if(gn->id==n->id) break; ind++; } /* fprintf(stderr," node=%s, id=%d, ind=%d\n",n->name,n->id,ind); */ *c++=ind; assigned[ind]=true; cdata->ntoplevel--; } } }
/** Determine the current active state. * Note that there might be multiple active states if there are sub-fsms. It will * only consider the active state of the bottom-fsm. * @return the current active state */ std::string SkillGuiGraphDrawingArea::get_active_state(graph_t *graph) { if (! graph) { return ""; } // Loop through the nodes in the graph/subgraph and find the active node for (node_t *n = agfstnode(graph); n; n = agnxtnode(graph, n)) { const char *actattr = agget(n, (char *)"active"); if (actattr && (strcmp(actattr, "true") == 0) ) { node_t *mn = agmetanode(graph); graph_t *mg = mn->graph; // Check to see if the node has an edge going into a subgraph for (edge_t *me = agfstout(mg, mn); me; me = agnxtout(mg, me)) { graph_t *subgraph = agusergraph(me->head); for (edge_t *e = agfstout(graph, n); e; e = agnxtout(graph, e)) { for (node_t *subnode = agfstnode(subgraph); subnode; subnode = agnxtnode(subgraph, subnode)) { if (agnameof(subnode) == agnameof(e->head)) { // The node goes into a subgraph, recursively find and return the active subnode name return get_active_state(subgraph); } } } } // The node has no subgraph, return the name of the active node return agnameof(n); } } return ""; }
static int eval (Agraph_t* g, int root) { Agraph_t* mg; Agedge_t* me; Agnode_t* mn; Agraph_t* subg; if (root && !(GTYPE(g) & gtype)) return 1; if ((flags & CL) && root) cl_count (g); emit (g, root); if (recurse) { n_indent++; mg = g->meta_node->graph; for (me = agfstout(mg,g->meta_node); me; me = agnxtout(mg,me)) { mn = me->head; subg = agusergraph(mn); eval (subg, 0); } n_indent--; } return 0; }
Agraph_t *agnxtsubg(Agraph_t *g, Agedge_t **lastedge) { Agedge_t *e; Agraph_t *meta = g->meta_node->graph; e = agnxtout(meta, *lastedge); *lastedge = e; if (!e) return NULL; return agusergraph(e->head); }
static void add_graph_attr(Agraph_t * g, Agsym_t * attr) { Agnode_t *n; if (g->meta_node) { for (n = agfstnode(g->meta_node->graph); n; n = agnxtnode(g->meta_node->graph, n)) obj_init_attr(agusergraph(n), attr); } else obj_init_attr(g, attr); }
static void add_node_attr(Agraph_t * g, Agsym_t * attr) { Agnode_t *n; Agproto_t *proto; for (n = agfstnode(g); n; n = agnxtnode(g, n)) obj_init_attr(n, attr); if (g->meta_node) { for (n = agfstnode(g->meta_node->graph); n; n = agnxtnode(g->meta_node->graph, n)) for (proto = agusergraph(n)->proto; proto; proto = proto->prev) obj_init_attr(proto->n, attr); } else for (proto = g->proto; proto; proto = proto->prev) obj_init_attr(proto->n, attr); }
void rm(Agraph_t *g) { Agedge_t *e; if (g->meta_node) { for (e = agfstout(g->meta_node->graph, g->meta_node); e; e = agnxtout(g->meta_node->graph, e)) { rm(agusergraph(e->head)); } if (g == g->root) { agclose(g); } else { agdelete(g->meta_node->graph, g->meta_node); } } else { fprintf(stderr, "subgraph has no meta_node\n"); } }
Agraph_t *firstsupg(Agraph_t *g) { Agraph_t *mg; Agnode_t *n; Agedge_t *e; if (!g) return NULL; n = g->meta_node; if (!n) return NULL; mg = n->graph; if (!mg) return NULL; e = agfstin(mg, n); if (!e) return NULL; return agusergraph(e->tail); }
static void cleanup_subgs(graph_t * g) { graph_t *mg; edge_t *me; node_t *mn; graph_t *subg; mg = g->meta_node->graph; for (me = agfstout(mg, g->meta_node); me; me = agnxtout(mg, me)) { mn = me->head; subg = agusergraph(mn); free_label(GD_label(subg)); if (GD_alg(subg)) { free(PORTS(subg)); free(GD_alg(subg)); } cleanup_subgs(subg); } }
static void cl_count (Agraph_t* g) { Agraph_t* mg; Agedge_t* me; Agnode_t* mn; Agraph_t* subg; int sum = 0; mg = g->meta_node->graph; for (me = agfstout(mg,g->meta_node); me; me = agnxtout(mg,me)) { mn = me->head; subg = agusergraph(mn); cl_count(subg); sum += GD_cl_cnt(subg); if (strncmp(subg->name,"cluster",7) == 0) sum++; } GD_cl_cnt(g) = sum; }
Agraph_t *nextsupg(Agraph_t *g, Agraph_t *sg) { Agraph_t *mg; Agnode_t *ng, *nsg; Agedge_t *e; if (!g || !sg) return NULL; ng = g->meta_node; nsg = sg->meta_node; if (!ng || !nsg) return NULL; mg = ng->graph; if (!mg) return NULL; e = agfindedge(mg, nsg, ng); if (!e) return NULL; e = agnxtin(mg, e); if (!e) return NULL; return agusergraph(e->tail); }
int rank_set_class(graph_t* g) { static char *name[] = {"same","min","source","max","sink",NULL}; static int class[] = {SAMERANK,MINRANK,SOURCERANK,MAXRANK,SINKRANK,0}; int val; if (is_cluster(g)) return CLUSTER; val = maptoken(agget(g,"rank"),name,class); GD_set_type(g) = val; return val; } /* Execute union commands for "same rank" subgraphs and clusters. */ void collapse_sets(graph_t* g) { int c; graph_t *mg,*subg; node_t *mn,*n; edge_t *me; mg = g->meta_node->graph; for (me = agfstout(mg,g->meta_node); me; me = agnxtout(mg,me)) { mn = me->head; subg = agusergraph(mn); c = rank_set_class(subg); if (c) { if ((c == CLUSTER) && CL_type == LOCAL) collapse_cluster(g,subg); else collapse_rankset(g,subg,c); } /* mark nodes with ordered edges so their leaves are not collapsed */ if (agget(subg,"ordering")) for (n = agfstnode(subg); n; n = agnxtnode(subg,n)) ND_order(n) = 1; } }
static void write_subg(Agraph_t * g, FILE * fp, Agraph_t * par, int indent, printdict_t * state) { Agraph_t *subg, *meta; Agnode_t *n, *pn; Agedge_t *e, *pe; Dict_t *save_e, *save_n; if (indent) { tabover(fp, indent++); if (dtsearch(state->subgleft, g->meta_node)) { if (strncmp(g->name, "_anonymous", 10)) fprintf(fp, "subgraph %s {\n", agcanonical(g->name)); else fprintf(fp, "{\n"); /* no name printed for anonymous subg */ write_diffattr(fp, indent, g, par, g->univ->globattr); /* The root node and edge environment use the dictionaries, * not the proto node or edge, so the next level down must * record differences with the dictionaries. */ if (par == g->root) { pn = NULL; pe = NULL; } else { pn = par->proto->n; pe = par->proto->e; } write_diffattr(fp, indent, g->proto->n, pn, g->univ->nodeattr); write_diffattr(fp, indent, g->proto->e, pe, g->univ->edgeattr); dtdelete(state->subgleft, g->meta_node); } else { fprintf(fp, "subgraph %s;\n", agcanonical(g->name)); return; } } else write_diffattr(fp, ++indent, g, NULL, g->univ->globattr); save_n = state->n_insubg; save_e = state->e_insubg; meta = g->meta_node->graph; state->n_insubg = dtopen(&agNamedisc, Dttree); state->e_insubg = dtopen(&agOutdisc, Dttree); for (e = agfstout(meta, g->meta_node); e; e = agnxtout(meta, e)) { subg = agusergraph(e->head); write_subg(subg, fp, g, indent, state); } for (n = agfstnode(g); n; n = agnxtnode(g, n)) { if (dtsearch(state->nodesleft, n)) { agwrnode(g, fp, n, TRUE, indent); dtdelete(state->nodesleft, n); } else { if (dtsearch(state->n_insubg, n) == NULL) { agwrnode(g, fp, n, FALSE, indent); } } dtinsert(save_n, n); } dtdisc(g->outedges, &agEdgedisc, 0); /* sort by id */ for (e = (Agedge_t *) dtfirst(g->outedges); e; e = (Agedge_t *) dtnext(g->outedges, e)) { if (dtsearch(state->edgesleft, e)) { tabover(fp, indent); agwredge(g, fp, e, TRUE); dtdelete(state->edgesleft, e); } else { if (dtsearch(state->e_insubg, e) == NULL) { tabover(fp, indent); agwredge(g, fp, e, FALSE); } } dtinsert(save_e, e); } dtdisc(g->outedges, &agOutdisc, 0); /* sort by name */ dtclose(state->n_insubg); state->n_insubg = save_n; dtclose(state->e_insubg); state->e_insubg = save_e; if (indent > 1) { tabover(fp, indent - 1); fprintf(fp, "}\n"); } }
/* find_blocks: */ static void find_blocks(Agraph_t * g, circ_state * state) { Agnode_t *n; Agnode_t *root = NULL; block_t *rootBlock = NULL; blocklist_t ublks; #ifdef USER_BLOCKS graph_t *clust_subg; graph_t *mg; edge_t *me; node_t *mm; int isRoot; #endif initBlocklist(&ublks); /* check to see if there is a node which is set to be the root */ if (state->rootname) { root = agfindnode(g, state->rootname); } if (!root && state->N_root) { for (n = agfstnode(g); n; n = agnxtnode(g, n)) { if (late_bool(ORIGN(n), state->N_root, 0)) { root = n; break; } } } #ifdef USER_BLOCKS /* process clusters first */ /* by construction, all subgraphs are blocks and are non-empty */ mm = g->meta_node; mg = mm->graph; for (me = agfstout(mg, mm); me; me = agnxtout(mg, me)) { block_t *block; clust_subg = agusergraph(me->head); isRoot = 0; block = mkBlock(clust_subg); /* block = makeBlock(g, state); */ for (n = agfstnode(clust_subg); n; n = agnxtnode(clust_subg, n)) { if (!BCDONE(n)) { /* test not necessary if blocks disjoint */ SET_BCDONE(n); BLOCK(n) = block; if (n == root) isRoot = 1; } } if (isRoot) { /* Assume blocks are disjoint, so don't check if rootBlock is * already assigned. */ rootBlock = block; insertBlock(&state->bl, block); } else { appendBlock(&state->bl, block); } } ublks.first = state->bl.first; ublks.last = state->bl.last; #endif if (!root) root = agfstnode(g); dfs(g, root, state, !rootBlock); #ifdef USER_BLOCKS /* If g has user-supplied blocks, it may be disconnected. * We then fall into the following ugly loop. * We are guaranteed !VISITED(n) and PARENT(n) has been * set to a visited node. */ if (ublks.first) { while (n = findUnvisited(&ublks)) { dfs(g, n, state, 0); } } #endif }
/* could happen with an undirected edge */ char *temp; temp = tp; tp = hp; hp = temp; } if (tp && tp[0]) { agxset(e,TAILX,tp); agstrfree(tp); } if (hp && hp[0]) { agxset(e,HEADX,hp); agstrfree(hp); } } } } } tailptr = SP->list; while (tailptr) { freeptr = tailptr; tailptr = tailptr->link; if (TAG_OF(freeptr->data.obj) == TAG_NODE) free(freeptr); } if (G != SP->subg) abort(); agpopproto(G); In_edge_stmt = SP->in_edge_stmt; old_SP = SP; SP = SP->link; In_decl = FALSE; free(old_SP); Current_class = TAG_GRAPH; } #if 0 /* NOT USED */ static Agraph_t *parent_of(Agraph_t *g) { Agraph_t *rv; rv = agusergraph(agfstin(g->meta_node->graph,g->meta_node)->tail); return rv; }
/* Execute union commands for "same rank" subgraphs and clusters. */ static void collapse_sets(graph_t *rg, graph_t *g) { int c; graph_t *subg; #ifdef OBSOLETE node_t *n; #endif #ifndef WITH_CGRAPH graph_t *mg; node_t *mn; edge_t *me; mg = g->meta_node->graph; for (me = agfstout(mg, g->meta_node); me; me = agnxtout(mg, me)) { mn = aghead(me); subg = agusergraph(mn); #else /* WITH_CGRAPH */ for (subg = agfstsubg(g); subg; subg = agnxtsubg(subg)) { #endif /* WITH_CGRAPH */ c = rank_set_class(subg); if (c) { if ((c == CLUSTER) && CL_type == LOCAL) collapse_cluster(rg, subg); else collapse_rankset(rg, subg, c); } else collapse_sets(rg, subg); #ifdef OBSOLETE Collapsing leaves is currently obsolete /* mark nodes with ordered edges so their leaves are not collapsed */ if (agget(subg, "ordering")) for (n = agfstnode(subg); n; n = agnxtnode(subg, n)) ND_order(n) = 1; #endif } } static void find_clusters(graph_t * g) { graph_t *subg; #ifndef WITH_CGRAPH graph_t *mg; node_t *mn; edge_t *me; mg = g->meta_node->graph; for (me = agfstout(mg, g->meta_node); me; me = agnxtout(mg, me)) { mn = me->head; subg = agusergraph(mn); #else /* WITH_CGRAPH */ for (subg = agfstsubg(agroot(g)); subg; subg = agnxtsubg(subg)) { #endif /* WITH_CGRAPH */ if (GD_set_type(subg) == CLUSTER) collapse_cluster(g, subg); } } static void set_minmax(graph_t * g) { int c; GD_minrank(g) += ND_rank(GD_leader(g)); GD_maxrank(g) += ND_rank(GD_leader(g)); for (c = 1; c <= GD_n_cluster(g); c++) set_minmax(GD_clust(g)[c]); }