PreviousUpNext

15.4.789  src/lib/graph/start-stop.pkg

# Start-stop adaptor.  Add a new start/stop node to a graph view.
#
# -- Allen Leung

# Compiled by:
#     src/lib/graph/graphs.lib

stipulate
    package odg =  oop_digraph;                                         # oop_digraph   is from   src/lib/graph/oop-digraph.pkg
herein

    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.pkg
herein

    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;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext