PreviousUpNext

15.3.361  src/lib/src/digraph.api

## digraph.api
#
# API for simple, general-purpose fully-persistent graphs.
#
# Digraph differs from Digraphxy mainly by supporting subgraphs
# at the cost of not supporting type variables on Node and Tag
# -- instead we use "the Exception hack" to store arbitrary
# values on nodes and edges.
#
# Each Node and Tag is issued a unique Int id when created.
# Two Nodes are equal iff they have the same 'id'.
# Two Tags  are equal iff they have the same 'id'.
# Two Edges are equal iff their Nodes and Tags are equal.
#
# NB: We could avoid the Exception hack by making digraph.pkg
# a generic, but then every graph algorithm would need to be
# a generic too, and in general we'd need to re-instantiate
# them all for each new instantiation of digraph-g.pkg.
#     That sounds like a continuing pain in the ass which
# would discourage use of graphs.
#     I'd much rather have a couple of generic digraph types
# (digraph.pkg + digraphxy.pkg) so that all the relevant graph
# algorithms can be precompiled and ready to go.

# Compiled by:
#     src/lib/std/standard.lib

# Compare to:
#     src/lib/src/digraphxy.api
#     src/lib/src/tuplebase.api
#     src/lib/graph/oop-digraph.api

# This api is implemented in:
#
#     src/lib/src/digraph.pkg
#
api Digraph {
    #
    Other = Exception;                                                  # We support the usual hack of using Exception as an extensible datatype to associate arbitrary values with Edges and Tags.

    Graph;
    Node;
    Tag;

    Datum = NONE
          | INT    Int
          | ID     Id
          | FLOAT  Float
          | STRING String
          | OTHER  Other
          | TBASE  Exception                                            # Making Datum and Graph mutually recursive would be messy, so we use the exception hack instead.
          ;

    Tagless_Edge  = (Node,      Node);
    Edge          = (Node, Tag, Node);

    package ts: Set;                                                    # Sets of Tagless_Edges.        Set is from   src/lib/src/set.api
    package es: Set;                                                    # Sets of Edges.                Set is from   src/lib/src/set.api

    make_node:          Void    -> Node;                                # Create an Node.
    make_int_node:      Int     -> Node;                                # Create an Node with an associated Int    value, retrievable via node_int.
    make_id_node:       Id      -> Node;                                # Create an Node with an associated Id     value, retrievable via node_id.
    make_string_node:   String  -> Node;                                # Create an Node with an associated String value, retrievable via node_string.
    make_float_node:    Float   -> Node;                                # Create an Node with an associated Float  value, retrievable via node_float.
    make_graph_node:    Graph   -> Node;                                # Create an Node with an associated Graph  value, retrievable via node_graph.
    make_other_node:    Other   -> Node;                                # Create an Node with an associated Other  value, retrievable via node_other. This allows arbitrary values to be associated with the Node.

    node_datum:         Node    -> Datum;                               # Return Datum  associated with given Node.
    node_int:           Node    -> Null_Or(Int);                        # Return Int    associated with given Node, if any, else NULL.
    node_id:            Node    -> Null_Or(Id);                         # Return Id     associated with given Node, if any, else NULL.
    node_string:        Node    -> Null_Or(String);                     # Return String associated with given Node, if any, else NULL.
    node_float:         Node    -> Null_Or(Float);                      # Return Float  associated with given Node, if any, else NULL.
    node_graph:         Node    -> Null_Or(Graph);                      # Return Graph  associated with given Node, if any, else NULL.
    node_other:         Node    -> Null_Or(Other);                      # Return Other  associated with given Node, if any, else NULL.

    make_tag:           Void    -> Tag;                                 # Create an Tag.
    make_int_tag:       Int     -> Tag;                                 # Create an Tag with an associated Int    value, retrievable via tag_int.
    make_id_tag:        Id      -> Tag;                                 # Create an Tag with an associated Id     value, retrievable via tag_id.
    make_string_tag:    String  -> Tag;                                 # Create an Tag with an associated String value, retrievable via tag_string.
    make_float_tag:     Float   -> Tag;                                 # Create an Tag with an associated Float  value, retrievable via tag_float.
    make_graph_tag:     Graph   -> Tag;                                 # Create an Tag with an associated Other  value, retrievable via tag_graph.
    make_other_tag:     Other   -> Tag;                                 # Create an Tag with an associated Other  value, retrievable via tag_other. This allows arbitrary values to be associated with the Tag.

    tag_datum:          Tag   -> Datum;                                 # Return Datum  associated with given Tag.
    tag_int:            Tag   -> Null_Or(Int);                          # Return Int    associated with given Tag, if any, else NULL.
    tag_id:             Tag   -> Null_Or(Id);                           # Return Id     associated with given Tag, if any, else NULL.
    tag_string:         Tag   -> Null_Or(String);                       # Return String associated with given Tag, if any, else NULL.
    tag_float:          Tag   -> Null_Or(Float);                        # Return Float  associated with given Tag, if any, else NULL.
    tag_graph:          Tag   -> Null_Or(Graph);                        # Return Graph  associated with given Tag, if any, else NULL.
    tag_other:          Tag   -> Null_Or(Other);                        # Return Other  associated with given Tag, if any, else NULL.

    empty_graph:        Graph;

    put_tagless_edge:   (Graph, Tagless_Edge) -> Graph;                 # Store  a Tagless_Edge  into the Graph, returning the updated Graph. The input Graph is unchanged.
    put_edge:           (Graph, Edge        ) -> Graph;                 # Store  a         Edge  into the Graph, returning the updated Graph. The input Graph is unchanged.

    drop_tagless_edge:  (Graph, Tagless_Edge ) -> Graph;                # Remove a Tagless_Edge  from the Graph, returning the updated Graph. The input Graph is unchanged.
    drop_edge:          (Graph, Edge) -> Graph;                         # Remove an        Edge  from the Graph, returning the updated Graph. The input Graph is unchanged.


    get_tagless_edges:   Graph        ->         ts::Set ;              # Get all Tagless_Edges  in Graph.  User can iterate via ts::apply etc or do set operations via ts::union etc -- see src/lib/src/set.api
    #
    get_tagless_edges1: (Graph, Node) -> Null_Or(ts::Set);              # Get all Tagless_Edges  in Graph with given Node in first  slot.
    get_tagless_edges2: (Graph, Node) -> Null_Or(ts::Set);              # Get all Tagless_Edges  in Graph with given Node in second slot.
    #
    has_tagless_edge:   (Graph, Tagless_Edge) -> Bool;                  # See if given Tagless_Edge is in Graph.
    has_edge:           (Graph, Edge) -> Bool;                          # See if given         Edge is in Graph.

    get_edges:           Graph        ->         es::Set ;              # Get all Edges  in Graph.    User can iterate via es::apply etc or do set operations via es::union etc -- see src/lib/src/set.api.
    #
    get_edges1:         (Graph, Node) -> Null_Or(es::Set);              # Get all Edges in Graph with given Node in first  slot.
    get_edges2:         (Graph, Tag ) -> Null_Or(es::Set);              # Get all Edges in Graph with given Node in second slot.
    get_edges3:         (Graph, Node) -> Null_Or(es::Set);              # Get all Edges in Graph with given Node in third  slot.
    #
    get_edges12:        (Graph, Node, Tag ) -> Null_Or(es::Set);        # Get all Edges in Graph with given Node, Tag in first  and second slots.
    get_edges13:        (Graph, Node, Node) -> Null_Or(es::Set);        # Get all Edges in Graph with given Node,Node in first  and third  slots.
    get_edges23:        (Graph, Tag,  Node) -> Null_Or(es::Set);        # Get all Edges in Graph with given  Tag,Node in second and third  slots.
    #

    nodes_apply:         Graph -> (Node -> Void) -> Void;               # Apply given fn once per Node for all Nodes in Graph.  This iterates over all Edges in the Graph.
    tags_apply:          Graph -> (Tag  -> Void) -> Void;               # Apply given fn once per Tag  for all Tags  in Graph.  This iterates over all Edges in the Graph.

};                                                                      # api Graph


## Original code by Jeff Prothero Copyright (c) 2014-2015,
## released per terms of SMLNJ-COPYRIGHT.


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext