Types

At the top of the type hierachy we have AbstractEdges and AbstractNodes. These are pretty abstract in the sense that they capture anything that might somehow be interpreted as an edge or node. More concrete (but still not concrete concrete) are Edge and Node.

Edge/Node

Edge and Node are still not concrete but have fields of reliable types to interface with.

StenoGraphs implements DirectedEdge and UndirectedEdge as concrete subtypes of Edge as well as SimpleNode as concrete subtype of Node.

SimpleNode/UndirectedEdge/DirectedEdge

These are the concrete Node and Edge types implemented by StenoGraphs.

StenoGraphs.UndirectedEdgeType
UndirectedEdge(src, dst)

Subtype of Edge. Undirected edge from src to dst. What is what does not matter.

Example

julia> e1 = UndirectedEdge(Node(:a), Node(:b))
a ↔ b

julia> e2 = UndirectedEdge(Node(:b), Node(:a))
b ↔ a

julia> isequal(e1, e2)
true

julia> unique([e1, e2])
a ↔ b
source

MetaEdge/MetaNode

These types store a node/edge alongside metadata.

Modified Nodes and Edges

These concrete types store a node/edge alongside modifiers (either NodeModifiers or EdgeModifiers) as metadata.

StenoGraphs.ModifiedNodeType
ModifiedNode

Subtype of MetaNode that contains two fields (node and modifiers). modifiers is a Dict{Symbol, NodeModifier} where the keys are nameof(typeof(NodeModifier)). Modifiying a node with several modifiers of the same type will therefore overwrite old modifiers.

Example

julia> struct Observed <: NodeModifier end

julia> struct Label{N <: String} <: NodeModifier s::N end

julia> Node(:b) ^ Label("some label") ^ Observed()
b^[Observed(), Label{String}("some label")]

julia> Node(:b) ^ Label("some label") ^ Observed() ^ Label("some other label")
b^[Observed(), Label{String}("some other label")]
source
StenoGraphs.ModifyingNodeType
ModifyingNode

Subtype of MetaNode that contains two fields (node and modifiers). modifiers is a Dict{Symbol, EdgeModifier} where the keys are nameof(typeof(EdgeModifier)). Modifiying an node with several modifiers of the same type will therefore overwrite old modifiers. A ModifyingNode is created by multiplying it (*) with an EdgeModifier since it will modify edges build upon it. If you want to modify the node use ^ and see ModifiedNode.

Example

julia> struct Weight{N <: Number} <: EdgeModifier w::N end

julia> struct Start{N <: Number} <: EdgeModifier s::N end

julia> @StenoGraph a → b * Weight(3) * Start(2)
a → b * [Start{Int64}(2), Weight{Int64}(3)]

julia> @StenoGraph a → b * Weight(3) * Start(2) * Weight(2)
a → b * [Start{Int64}(2), Weight{Int64}(2)]
source
StenoGraphs.ModifiedEdgeType
ModifiedEdge

Subtype of MetaEdge that contains two fields (edge and modifiers). modifiers is a Dict{Symbol, EdgeModifier} where the keys are nameof(typeof(EdgeModifier)). Modifiying an edge with several modifiers of the same type will therefore overwrite old modifiers. A ModifiedEdge is created by modifying an edge directly (with *) or via ModifyingNodes where a node is modified that than modifies the edge.

Example

julia> struct Weight{N <: Number} <: EdgeModifier w::N end

julia> struct Start{N <: Number} <: EdgeModifier s::N end

julia> ModifiedEdge(Edge(Node(:a), Node(:b)), Weight(3))
a → b * Weight{Int64}(3)

julia> ModifiedEdge(Edge(Node(:a), Node(:b)), Weight(3)) == Edge(Node(:a), Node(:b)) * Weight(3)
true

julia> ModifiedEdge(Edge(Node(:a), Node(:b)), [Weight(3), Start(2)])
a → b * [Start{Int64}(2), Weight{Int64}(3)]

julia> @StenoGraph a → b * Weight(3) * Start(2)
a → b * [Start{Int64}(2), Weight{Int64}(3)]

julia> @StenoGraph a → b * Weight(3) * Start(2) * Weight(2)
a → b * [Start{Int64}(2), Weight{Int64}(2)]
source

Modifiers

StenoGraphs.ModifierType
Modifier

The abstract type that powers EdgeModifier and NodeModifier. StenoGraphs does not implement any concrete modifiers.

source
StenoGraphs.NodeModifierType
NodeModifier

Subtype of Modifier. ModifiedNodes require NodeModifiers. NodeModifiers usually make use of ^ for creating ModifiedNodes. Since StenoGraphs does not implement any NodeModifier users must implement them. If these may contain any mutable fields (i.e. strings, vectors, arrays, etc.) users must take care to implement comparison methods.

Example

# `StenoGraphs` does not implement any `NodeModifier`s
julia> struct Label <: NodeModifier l end

julia> import Base.==

julia> ==(x::Label, y::Label) = x.l == y.l;

julia> ModifiedNode(Node(:a), Label("hi")) == Node(:a)^Label("hi")
true
source
StenoGraphs.EdgeModifierType
EdgeModifier

Subtype of Modifier. ModifiedEdges require EdgeModifiers. EdgeModifiers usually make use of * for creating ModifiedEdges/ModifyingNodes. One special application for EdgeModifiers is the creation of ModifyingNodes. Since StenoGraphs does not implement any EdgeModifier users must implement them. If these are not atomic they must take care to implement comparison methods (see examples in NodeModifier)

Example

# `StenoGraphs` does not implement any `EdgeModifier`s
julia> struct Weight{N <: Number} <: EdgeModifier w::N end

julia> ModifiedEdge(Edge(Node(:a), Node(:b)), Weight(.5)) == # directly create ModifiedEdge
        Edge(Node(:a), Node(:b)) * Weight(.5) == # modify an edge
        Edge(Node(:a), Node(:b) * Weight(.5)) # modify Edge through a ModifyingNode
true
source