From ok@atlas.otago.ac.nz  Mon Mar 13 22:49:19 2000
Received: from atlas.otago.ac.nz (atlas.otago.ac.nz [139.80.32.250])
	by swi.psy.uva.nl (8.9.3/8.9.3) with ESMTP id WAA06349
	for <prolog@swi.psy.uva.nl>; Mon, 13 Mar 2000 22:49:15 +0100 (MET)
Received: (from ok@localhost)
	by atlas.otago.ac.nz (8.9.3/8.9.3) id KAA17425;
	Tue, 14 Mar 2000 10:49:04 +1300 (NZDT)
Date: Tue, 14 Mar 2000 10:49:04 +1300 (NZDT)
From: "Richard A. O'Keefe" <ok@atlas.otago.ac.nz>
Message-Id: <200003132149.KAA17425@atlas.otago.ac.nz>
To: ilya@isp.pitt.edu, prolog@swi.psy.uva.nl
Subject: Re:  Analyzing Prolog [Was: Printing to a file]

	are there any (preferably free) tools for analyzing Prolog
	sources? i.e. x-references, visualizers that show you what functions
	call what, etc?

The DEC-10 Prolog library includes a program called XREF.
This is/was a batch cross-references that took a list of files
and provided cross-reference information.

Quintus upgraded it to handle the :-meta_predicate declaration
(to be honest, I invented the :-meta_predicate declaration _for_ XREF
so that cross-referencing would work with the module system).
If I remember correctly (it has been a while) there was a total rewrite
at one point.

The DEC-10 Prolog library also includes a package IXREF.PL
for "interactive" cross-referencing; it never was upgraded to handle
the module system but should have been.

The Emacs interface for Quintus Prolog has a "find-definition" key
(Ctrl-X .); put the cursor on a call, hit find-definition, and you're
at the source code staring at the definition.  This requried support
from the underlying Prolog, of course.  There wasn't any find-callers
in the Emacs interface for the simple reason that there is in general
more than one.

Of course anything like this runs head first into the problem that a
Prolog program can do
    read(Clause),
    assert(Clause),
    ( Clause = :-(Head,_) -> true ; Head = Clause ),
    call(Head)
and now you don't even know what the set of definitions is, let alone
the set of callers.  Lisp has the same problem with
    (eval (read))

It is in fact _common_ for well-designed Prolog programs to generate
code at run-time, which makes precise cross-referencing tricky.

	Are there any metrics (and metric calculators) for quickly
	estimating the complexity of a Prolog program, a la the McCabe tools?
	
I don't know anything about the McCabe tools.  The McCabe _metric_ is
basically "count the IFs and add one" and in my view isn't much better
than SLOC.

You can of course count the number of predicates, the number of clauses,
the number of goals, the number of internal ifs, and so on.  You could
quite easily come up with a McCabe-ish metric (number of clauses plus
number of ';' and \+; a very close analogue that would be) except that
tables of facts are actually pretty simple, while this metric would make
them look complex.  And then hiding code as data would defeat this metric.

