GVPR question - Select nodes, then filter a graph for all related nodes

I am trying to create a gvpr script to get a collection of node names as parameter and returns a graph with all nodes that are directly or remotely connected to these tables.

Is there a good example for it. Tried to ask chat gpt and got a non running code :slightly_smiling_face:

Here is a similar program - only lightly tested.

  • allow multiple node names
  • mark all for deletion
  • unmark connected nodes & edges
  • do not delete until the final END_G
/*
  given the name of a node (via the command line -a argument)
    color that node yellow
    color all descendents and connecting edges green
    color all other nodes grey
*/
BEGIN{
  node_t   aNode,  Start;
  graph_t  aGraph, Root;
  int      seenE[], seenN[];
  int      Ecnt=0;
  string   start;

  /////////////////////////////////////////////////////////////////////
  // the anEdge argument is a local argument, never part of calling the function
  //   each call creates a new instance
  //   so the nxtedge call does not over-write
  void nodeTraverse(node_t thisNode,   edge_t   anEdge){
    print("// NODE: ", thisNode.name, "  seen: ", seenN[thisNode]);
    if (seenN[thisNode]!=1){
      seenN[thisNode]=1;
      thisNode.fillcolor="green";
      thisNode.style="filled";      
      for (anEdge = fstedge(thisNode); anEdge; anEdge = nxtedge(anEdge,thisNode)){
        print("// edge: ", anEdge.name, "  ", anEdge.tail, "  ", anEdge.head, "  seen: ", seenE[anEdge]);
        if (seenE[anEdge]==0){
	  anEdge.color="green";
          seenE[anEdge]=1;
          print("// recurse: ", anEdge.head);
          nodeTraverse(anEdge.head, anEdge);
          nodeTraverse(anEdge.tail, anEdge);	  
        }
      }
    }
    print ("//  DONE: ", thisNode.name);
  }  // end of nodeTraverse
  //////////////////////////////////////////////
}
BEG_G{
  Root=$G;
  start=ARGV[0];
  print ("//   start: ", start);
  Start=isNode($G, start);
  if (Start==NULL){
    printf(2, "Error: unknown node >%s<\n", start);
    exit(9);
  }
}
//
// grey out all nodes & edges
// we will color the ones we want later
//
N{
  $.style="filled";
  $.fillcolor="lightgrey";
}
E{
  $.color="lightgrey";
}
// now find all the children & color them & their edges
END_G{
  nodeTraverse(Start);  // no edge parameter on this call
  print("//  Start: ", Start.name,Start.color);
  Start.fillcolor="yellow";
}

Here is a different method of achieving the goal.
I have not tested either solution on graphs w/ clusters and expect problems there.

BEGIN{
  int      i, maxN, maxSG,  Node[], Delete[];
  graph_t  aG, subG[] ;
}
BEG_G{
  i=0;
  maxN=0;
  while (i<ARGC) {
    Node[ARGV[i]]=1;
    print("//   node: ", ARGV[i]);
    if (isNode($G, ARGV[i])==NULL)
      printf(2, "Node \"%s\" not found\n", ARGV[i]);
    i++;
  }
}
N{
  int skip;
  Delete[$]=1;  // mark all for deletion, we will fix later
  if (Node[$.name]) {
    print("//  BINGO: ", $.name);
    skip=0;
    for (subG[i]) {
      if (isNode(subG[i], $.name)) {
        skip=1;  // already have this subgraph
      }
    }
    if (skip==0) {
      aG=compOf($G,$);
      subG[++maxSG]=aG;
      induce(aG);
    }
  }
}
END_G{
  node_t aNode;
  for (subG[i]) {
    for (aNode=fstnode(subG[i]); aNode; aNode = nxtnode_sg(subG[i], aNode)) {
      unset(Delete, aNode);
    }
  }
  for (Delete[aNode])
    delete($G, aNode);
}