Parametric Regular Path Queries
Kaveri now includes an implementation of the parametric regular path query engine. Regular path queries are regular expression based
queries that are matched against graph paths. The result of the query is a graph path that satisfies the properties specified by the query.
Parametric regular path queries extend the regular expression pattern with variables called parameters. These parameters are bound
to special values in the path as the property is satisfied. They are useful in finding paths with interesting properties or for
verifying properties along all paths between two nodes in the graph. For details about the parametric regular queries please
refer to [PEQ].
There are two kinds of queries that are supported:
- Existential Queries: These determine if there exist paths in the graph that
satisfy a given property. The query is run from a starting node and the result of the query is all the paths leading out from that
node that satisfy the given property.
- Universal Queries: These determine if all the paths from a given node
satisfy the given property. They are used for verifying properties along paths in the graph.
In Kaveri, the queries are run on the program dependency graph as calculated by Indus. The graph is constructed
as follows:
- Node: Nodes are linked to Jimple program points.
- Edges: Edges connect program points with each edge having a label. The label indicates the dependency relation between the two
program points.
The query is thus a program dependency based parametric regular expression. The BNF for the input query language is as follows:
Query := ("Equery" | "Uquery") Name { union };
Name := ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*
union := repterm repterm*
repterm := term repetition?
repetition := ? | * | +
term := group | atom
group := '(' union ')'
atom := < constructor >
constructor := constructor-name '(' var-name ')'
var-name := ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*
The constructors are defined as follows: (x is the variable name).
- cdepd(x) : Follow the control dependence edge from the current node and reach the
point that the current node is control dependent on. x binds to current node.
- cdept(x) : Follow the control dependence edge from the current node and reach the
point that control dependent on the current node. x binds to current node.
- idef(x) : Follow the identifier data dependence edge from the current node and reach the
point where the variable used in the current node is defined. x binds to local variable.
- iuse(x) : Follow the identifier data dependence edge from the current node and reach the
point where the variable defined in the current node is used. x binds to local variable.
- idepd(x) : Follow the interference dependence edge from the current node and reach the
point that the current node is interference depedent on. x binds to soot field that causes the interference.
- idept(x) : Follow the interference dependence edge from the current node and reach the
point that the node that is interference dependent on the current node. x binds to soot field that causes the interference.
- rdepd(x) : Follow the ready dependence edge from the current node and reach the
point that the current node is ready dependent on. x binds to current node.
- rdept(x) : Follow the ready dependence edge from the current node and reach the
point that ready dependent on the current node. x binds to current node.
- sdepd(x) : Follow the synchronization dependence edge from the current node and reach the
point that the current node is synchronization dependent on. x binds to current node.
- sdept(x) : Follow the synchronization dependence edge from the current node and reach the
point that synchronization dependent on the current node. x binds to current node.
- ddepd(x) : Follow the divergence dependence edge from the current node and reach the
point that the current node is divergence dependent on. x binds to current node.
- ddept(x) : Follow the divergence dependence edge from the current node and reach the
point that divergence dependent on the current node. x binds to current node.
- rdef(x) : Follow the reference data dependence edge from the current node and reach the
point where the variable used in the current node is defined. x binds to reference variable.
- ruse(x) : Follow the reference data dependence edge from the current node and reach the
point where the variable defined in the current node is used. x binds to reference variable.
Examples of valid queries are:
To run the parametric queries, the peq view has to be activated. This can be done from Window -> Show View -> Others
-> Kaveri -> Peq View. Before using the peq view, a slice must already have been performed. Also a point to be noted is that the
dependence information available from peq depends on the configuration used by the slice. If the particular configuration disables a dependence
and the query uses it, the result will be empty even though edges might exist in reality. So before using the peq engine, please use a slice configuration with all the
dependencies turned on. The following toolbar buttons are present in the view:
- Tracking: Switches the view on/off like the Jimple view.
- Add a query: Opens a text box where the query can be entered. A default template is provided.
- Run the query :Runs the query and populates the result tab..
- Update the statement: Updates the location from which to run the query. To use it, navigate to a different
program point in the Java editor and press Update to change the starting location of the query..
- Remove the query: Deletes the currently selected query from the combo box.
Steps to use the query engine:
- Switch the view to on state by toggling the tracking toolbar button.
- Naviate to the desired program point in the Java editor.
- Press update to refresh the view.
- Press add to add a new query or pick a query from the combo box.
- Press run to run the query. The result pane is populated with the results of the query. The result nodes can be expaned to view the
graph edge that was matched. Double clicking on the edge source and destination nodes highlights the corressponding Java statement in the editor.
The substitutions that were made till that point are displayed on the right pane. Click on the result node to get the complete substitution map.
Using PEQ requires that the ANTLR eclipse plugin is installed. It can be obtained from http://antlreclipse.sourceforge.net/ . Also the peq eclipse plugin has
to be installed separately. Install procedure for the peq plugin is similar to that of Kaveri.