# Start-stop adaptor. Add a new start/stop node to a graph view.
#
# -- Allen Leung
# Compiled by:
#
src/lib/graph/graphs.libstipulate
package odg = oop_digraph; # oop_digraph is from
src/lib/graph/oop-digraph.pkgherein
api Start_Stop_View {
#
start_stop_view
: { start: odg::Node(N),
stop: odg::Node(N),
edges: List( odg::Edge(E) )
}
->
odg::Digraph(N,E,G) # Here N,E,G stand stead for the types of client-package-supplied records associated with (respectively) nodes, edges and graphs.
->
odg::Digraph(N,E,G);
};
end;
stipulate
package odg = oop_digraph; # oop_digraph is from
src/lib/graph/oop-digraph.pkgherein
package start_stop_view
: (weak) Start_Stop_View # Start_Stop_View is from
src/lib/graph/start-stop.pkg {
fun start_stop_view { start as (start'', x),
stop as (stop'', y), edges } (odg::DIGRAPH graph)
=
{ fun readonly _ = raise exception odg::READ_ONLY;
fun get_nodes () = start ! stop ! graph.nodes ();
fun order () = graph.order () + 2;
fun size () = graph.size () + 1;
fun capacity ()
=
int::max (start''+1, int::max (stop''+1, graph.capacity ()));
fun exit_to_stop n
=
map
(\\ (i, _, e)
=
(i, stop'', e))
(graph.exit_edges n);
fun entry_to_start n
=
map
(\\ (_, j, e) = (start'', j, e))
(graph.entry_edges n);
fun out_edges n
=
(if (n == start'' ) edges; else [];fi)
@
(exit_to_stop n)
@
graph.out_edges n;
fun in_edges n
=
(if (n == stop'' ) edges; else []; fi)
@
(entry_to_start n)
@
graph.in_edges n;
fun get_edges ()
=
list::cat (map (\\ (n, _) = out_edges n)
(get_nodes ()));
fun get_succ n = map #2 (out_edges n);
fun get_pred n = map #1 (in_edges n);
fun has_edge (i, j)
=
list::exists
(\\ (_, k, _) = j == k)
(out_edges i);
fun has_node n
=
n == start'' or
n == stop'' or
graph.has_node n;
fun node_info n
=
if (n == start'' ) x;
else if (n == stop'' ) y;
else graph.node_info n; fi; fi;
fun entries () = [start''];
fun exits () = [stop'' ];
fun entry_edges n = [];
fun exit_edges n = [];
fun forall_nodes f = apply f (get_nodes());
fun forall_edges f = apply f (get_edges());
odg::DIGRAPH
{ name => graph.name,
graph_info => graph.graph_info,
allot_node_id => readonly,
add_node => readonly,
add_edge => readonly,
remove_node => readonly,
set_in_edges => readonly,
set_out_edges => readonly,
set_entries => readonly,
set_exits => readonly,
garbage_collect => graph.garbage_collect,
nodes => get_nodes,
edges => get_edges,
order,
size,
capacity,
out_edges,
in_edges,
next => get_succ,
prior => get_pred,
has_edge,
has_node,
node_info,
entries,
exits,
entry_edges,
exit_edges,
forall_nodes,
forall_edges
};
};
};
end;