prolog_codewalk.pl -- Prolog code walker
This module walks over the loaded program, searching for callable predicates. It started as part of library(prolog_autoload) and has been turned into a separate module to facilitate operations that require the same reachability analysis, such as finding references to a predicate, finding unreachable code, etc.
For example, the following determins the call graph of the loaded
program. By using source(true)
, The exact location of the call in the
source file is passed into _Where.
:- dynamic calls/2. assert_call_graph :- retractall(calls(_, _)), prolog_walk_code([ trace_reference(_), on_trace(assert_edge), source(false) ]), predicate_property(calls(_,_), number_of_clauses(N)), format('Got ~D edges~n', [N]). assert_edge(Callee, Caller, _Where) :- calls(Caller, Callee), !. assert_edge(Callee, Caller, _Where) :- assertz(calls(Caller, Callee)).
- prolog_walk_code(+Options) is det
- Walk over all loaded (user) Prolog code. The following code is
processed:
- The bodies of all clauses in all user and library modules. This steps collects, but does not scan multifile predicates to avoid duplicate work.
- All multi-file predicates collected.
- All goals registered with initialization/1
Options processed:
- undefined(+Action)
- Action defines what happens if the analysis finds a
definitely undefined predicate. One of
ignore
orerror
(default isignore
). - autoload(+Boolean)
- Try to autoload code while walking. This is enabled by default to obtain as much as possible information about goals and find references from autoloaded libraries.
- clauses(+ListOfClauseReferences)
- Only process the given clauses. Can be used to find clauses
quickly using
source(false)
and then process only interesting clauses with source information. - module(+Module)
- Only process the given module
- module_class(+ModuleClassList)
- Limit processing to modules of the given classes. See
module_property/2 for details on module classes. Default
is to scan the classes
user
andlibrary
. - infer_meta_predicates(+BooleanOrAll)
- Use infer_meta_predicate/2 on predicates with clauses that
call known meta-predicates. The analysis is restarted until
a fixed point is reached. If
true
(default), analysis is only restarted if the inferred meta-predicate contains a callable argument. Ifall
, it will be restarted until no more new meta-predicates can be found. - walk_meta_predicates(Boolean)
- When
false
(defaulttrue
), do not analyse the arguments of meta predicates. Standard Prolog control structures are always analysed. - trace_reference(Callable)
- Print all calls to goals that subsume Callable. Goals are represented as Module:Callable (i.e., they are always qualified). See also subsumes_term/2.
- trace_condition(:Cond)
- Additional filter condition applied after
trace_reference
. Called ascall(Cond, Callee, Context)
, where Context is a dict containing the following keys:- caller:Context
- Qualified term representing the caller or the atom '<initialization>'.
- module:Context
- Module being processed
- clause:Context
- If we are processing a normal clause, the clause reference to this clause.
- initialization:Context
- If we are processing an initialization/1 directive, a term
File:Line
representing the location of the declaration.
- on_edge(:OnEdge)
- If a reference to
trace_reference
is found, callcall(OnEdge, Callee, Caller, Location)
, where Location is a dict containing a subset of the keysclause
,file
,character_count
,line_count
andline_position
. If full position information is available all keys are present. If the clause layout is unknown the only theclause
,file
andline_count
are available and the line is the start line of the clause. For a dynamic clause, only theclause
is present. If the position is associated to a directive, theclause
is missing. If nothing is known the Location is an empty dict. - on_trace(:OnTrace)
- As
on_edge
, but location is not translated and is one of these:clause_term_position(+ClauseRef, +TermPos)
clause(+ClauseRef)
file_term_position(+Path, +TermPos)
file(+File, +Line, -1, _)
- a variable (unknown)
Caller is the qualified head of the calling clause or the atom '<initialization>'.
- source(+Boolean)
- If
false
(defaulttrue
), to not try to obtain detailed source information for printed messages. - verbose(+Boolean)
- If
true
(defaultfalse
), report derived meta-predicates and iterations.@compat OnTrace was called using Caller-Location in older versions.
- subterm_pos(+SubTerm, +Term, :Cmp, +TermPosition, -SubTermPos) is nondet
- True when SubTerm is a sub term of Term, compared using Cmp,
TermPosition describes the term layout of Term and SubTermPos
describes the term layout of SubTerm. Cmp is typically one of
same_term
,==
,=@=
orsubsumes_term
- prolog_program_clause(-ClauseRef, +Options) is nondet
- True when ClauseRef is a reference for clause in the program.
Options is a subset of the options processed by
prolog_walk_code/1. The logic for deciding on which clauses to
enumerate is shared with prolog_walk_code/1.
- module(?Module)
module_class(+list(Classes))