Fixpoint computation implemented using the work list algorithm. This module makes writing data-flow analysis easy.
One of the simplest fixpoint analysis is that of reachability.
Given a directed graph module G
, its analysis can be implemented
as follows:
module Reachability = Graph.Fixpoint.Make(G)
(struct
type vertex = G.E.vertex
type edge = G.E.t
type g = G.t
type data = bool
let direction = Graph.Fixpoint.Forward
let equal = (=)
let join = (||)
let analyze _ = (fun x -> x)
end)
The types for vertex
, edge
and g
are those of the graph to be
analyzed. The data
type is bool
: It will tell if the
vertex is reachable from the start vertex. The equal
operation
for bool
is simply structural equality; the join
operation is
logical or. The analyze
function is very simple, too: If the
predecessor vertex is reachable, so is the successor vertex of the
edge.
To use the analysis, an instance of a graph g
is required. For
this analysis a predicate is_root_vertex : G.E.vertex -> bool
is
required to initialize the reachability of the root vertex to
true
and of all other vertices to false
.
let g = ...
let result = Reachability.analyze is_root_vertex g
The result
is a map of type G.E.vertex -> bool
that can be
queried for every vertex to tell if the vertex is reachable from
the root vertex.
analyze f g
computes the fixpoint on the given graph using the
work list algorithm. Beware that a misconstructed Analysis will
not terminate! f
is used to create the initial analysis
data. The function returned is a map to see what data was computed
for which node.
Beware of applying function analyze
partially, to arguments
f
and g
only. The result is a function that is to be used to query
the result of the analysis.