Perpetual Testing Logo

Manipulating Graphs with GenSet

A Simple Example: Removing Transitive Edges

Here is an example to illustrate how the GenSet language and processor can be used to perform simple graph manipulations. Suppose we have a rather cluttered graph (e.g., of method or procedure calls in a software system), and wish to clean it up by removing edges that can be inferred from transitivity. We'll use a very simple graph to illustrate.

 

In this example, there is an edge from a to b, an edge from b to e, and an edge from a to e. We wish to remove the edge from a to e because a path from a to e through b already exists. The edge from a to j should likewise be removed. We write the following GenSet program for this purpose:

	/* Convert the "Calls" edges to a set-valued attribute */
	edges->attrib Calls; 

	/* Calculate the transitive closure, excluding direct calls */
	attribute { n| Calls[n->this] }  TransitiveCalls = 
		/union { m| Calls[this->m] } . 
			Calls(m) union TransitiveCalls(m); 

	/* Remove the transitive calls */
	attribute { n | Calls[n->this] } NonTransitive = 
		Calls(this) exclude TransitiveCalls(this);

	/* Convert the resulting attribute back into graph edges */
	attrib->edges NonTransitive;

The result* is:

*The result actually contains both the original "Calls" edges and the newly computed "NonTransitive" edges; we used a separate utility to remove the former.

[Up to "Exchanging Attributed Graphs] [Up to "Perpetual Testing at U. Oregon"]


Contact: Michal Young