Grok is a tool that can help you manipulate facts, such as those generated using cfx and fbgen, i.e., tuples of the form:
relation source target
For example, this tuple means that procedure P calls procedure Q:
call P Q
This form of tuple is called RSF (for Rigi Standard Form).
Grok can be used to do these three things for you:
getset procs procs.setreads a set from file procs.set and creates an in-memory set called procs.
The following example shows a common use of the relational composition command. We assume that the file contain.rsf lists information about which file contain which procedure and call.rsf contains info on which procedure calls which procedure. Here is a grok script that induces the call relation at the file level.
getdb contain.rsf % Read the containment information
adddb call.rsf % Read the call information
invcontain = inv contain % Create a new relation called invcontain
% which is the inverse of the contain relation
tmp = contain * call % Create a temporary relation called tmp
% which will be the composition of the
% relations contain and call
% Only composition of two relations is
% supported at this point, that's why we
% need the temporary relation
filecall = tmp * invcontain % The relation filecall is now the composition
% of tmp and invcontain, so effectively it is
% the composiiton of contain, call and invcontain.
putrel filecall filecall.rsf % The file filecall.rsf will now contain the
% facts for relation filecall.