Yes, both library(prolog_xref) and library(prolog_codewalk) can create the data. Generate a .dot file and call graphviz and you are done. Knowing your program, I doubt it will be possible to make sense of the enormous graph. I recently wrote a similar thing for a moderate size s(CASP) program. That was barely manageable after tweaking the rules to omit a lot of stuff we considered irrelevant.
IMO a general call graph is not so useful. A dependency graph at the file/module level can work (gxref/0 can make that). Specific partial graphs may also be (the connections between a (small) set of predicates, mutual recursive loops, etc.).
edit, might be that the PDT plugin for the Eclipse IDE can do graphs?
It is not so much the tool I’m worried about, but the human trying to read and understand such enormous graphs Technically, both Graphviz and Cytoscape can probably render the graph. You need to zoom in very deep to get the labels readable though, loosing all overview. In the mentioned project we used Cytoscape.js. It is less good at compact placements of nodes with varying size labels and routing edges around nodes than Graphviz. It is a lot easier to add some interactivity to the graph. So, we added search to highlight and enlarge matching nodes and their (direct) dependencies and hovering the graph with similar effects. Hopefully that will at some point become available.
When I used it (but this was a more than 10 years ago) Cytoscape was able to show only parts of the network, among many other things. My memory is not what it used to be though, I might be wrong. The filtering was based on node/edge properties so this might not be immediately available with a call graph. Maybe best ignore me on the topic I most definitely used Cytoscape for different kinds of networks.
variant_sha1/2 looks like a good candidate. Another way would be to use numbervars/4 with the option singleton(true) and write to an atom with the option numbervars(true). That is more complex, but provides a readable identifier.
An program easily consists of thousands of predicates … A hundred labeled predicate nodes with edges between them is already getting hard to grasp.
I guess that depends on the size, structure and what you want to know about the program. Typically being able to navigate to callers and callees satisfies for me. Very infrequently I have harder questions where my solution was to write Prolog queries over the dependency graph.
Wouldn’t modules help in limiting the interconnections, allowing “zooming” in or out to get different levels of granularity? Also, one would want to remove links to “utility” predicates, such as maplist/3 or select/3.
(For myself, I haven’t found much use for graphic tools … if the program is well-structured, the graph doesn’t add much; if it’s not well-structured, the graph is a mess)
My case is probably very unusual. The application is a reverse engineering system that applies many interconnected rules. The rules are dictated by the system being reverse engineered and so are not “well structured”.
I’ve been trying to identify cycles of negations, ala well-founded semantics, to better understand where the system is not well defined.
Here is the graph I produced, in case anyone is curious. It’s already quite simplified.
Each edge indicates a negative dependence, i.e., an edge from A to B might be caused by A :- not(B).
Can you point to a paper(s) or blog(s) that explain those terms i.e. well-founded semantics in more detail, in particular when I read well defined I am thinking the code is expected to halt, there are no competing locks, the results are of a specific type, etc.
While I have not used sCASP I have to wonder if that might not be of use to your problem.