Class: Tangle::BaseGraph

Inherits:
Object
  • Object
show all
Includes:
BaseGraphPrivate, BaseGraphProtected, Currify, Mixin::Initialize
Defined in:
lib/tangle/base_graph.rb

Overview

Abstract base class for (un)directed graphs

Direct Known Subclasses

Directed::Graph, Undirected::Graph

Instance Attribute Summary

Attributes included from Mixin::Initialize

#mixins

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Currify

included

Constructor Details

#initialize(currify: false, mixins: [], **kwargs) ⇒ BaseGraph

Initialize a new graph, optionally preloading it with vertices and edges

Graph.new() => Graph Graph.new(mixins: [MixinModule, …], …) => Graph

mixins is an array of modules that can be mixed into the various classes that makes up a graph. Initialization of a Graph, Vertex or Edge looks for submodules in each mixin, with the same name and extends any created object. Defaults to [Tangle::Mixin::Connectedness].

Any subclass of Graph should also subclass Edge to manage its unique constraints.



52
53
54
55
56
57
# File 'lib/tangle/base_graph.rb', line 52

def initialize(currify: false, mixins: [], **kwargs)
  @currify = currify
  initialize_vertices
  initialize_edges
  initialize_mixins(mixins: mixins, **kwargs)
end

Class Method Details

.[](vertices, edges = {}, **kwargs) ⇒ Object

Initialize a new graph, preloading it with vertices and edges

Graph[vertices] => Graph Graph[vertices, edges) => Graph

When vertices is a hash, it contains initialization kwargs as values and vertex names as keys. When vertices is an array of initialization kwargs, the vertices will be be anonymous.

edges can contain an array of exactly two, either names of vertices or vertices.

Any kwarg supported by Graph.new is also allowed.



32
33
34
35
36
37
# File 'lib/tangle/base_graph.rb', line 32

def self.[](vertices, edges = {}, **kwargs)
  graph = new(**kwargs)
  vertices.each { |vertex| graph.add_vertex(vertex) }
  edges.each { |from, to| graph.add_edge(from, to) }
  graph
end

Instance Method Details

#[](name) ⇒ Object

Return a named vertex



90
91
92
# File 'lib/tangle/base_graph.rb', line 90

def [](name)
  @vertices_by_name[name]
end

#add_edge(*vertices, **kvargs) ⇒ Object

Add a new edge to the graph

add_edge(vtx1, vtx2, …) => Edge



141
142
143
144
145
146
# File 'lib/tangle/base_graph.rb', line 141

def add_edge(*vertices, **kvargs)
  edge = new_edge(*vertices, mixins: @mixins, **kvargs)
  insert_edge(edge)
  vertices.each { |vertex| callback(vertex, :edge_added, edge) }
  edge
end

#add_vertex(vertex, name: nil) ⇒ Object Also known as: <<

Add a vertex into the graph

If a name: is given, or the vertex responds to :name, it will be registered by name in the graph



108
109
110
111
112
113
114
# File 'lib/tangle/base_graph.rb', line 108

def add_vertex(vertex, name: nil)
  name ||= callback(vertex, :name)
  insert_vertex(vertex, name)
  define_currified_methods(vertex, :vertex) if @currify
  callback(vertex, :added_to_graph, self)
  self
end

#cloneObject



73
74
75
76
77
# File 'lib/tangle/base_graph.rb', line 73

def clone
  result = super
  result.copy_vertices_and_edges(self)
  result
end

#edges(vertex = nil) ⇒ Object

Get all edges.

edges => Array



130
131
132
133
134
# File 'lib/tangle/base_graph.rb', line 130

def edges(vertex = nil)
  return @edges if vertex.nil?

  @vertices.fetch(vertex)
end

#fetch(name) ⇒ Object

Fetch a vertex by its name



85
86
87
# File 'lib/tangle/base_graph.rb', line 85

def fetch(name)
  @vertices_by_name.fetch(name)
end

#remove_edge(edge) ⇒ Object

Remove an edge from the graph



149
150
151
152
# File 'lib/tangle/base_graph.rb', line 149

def remove_edge(edge)
  delete_edge(edge)
  edge.each_vertex { |vertex| callback(vertex, :edge_removed, edge) }
end

#remove_vertex(vertex) ⇒ Object

Remove a vertex from the graph



118
119
120
121
122
123
124
# File 'lib/tangle/base_graph.rb', line 118

def remove_vertex(vertex)
  @vertices[vertex].each do |edge|
    remove_edge(edge) if edge.include?(vertex)
  end
  delete_vertex(vertex)
  callback(vertex, :removed_from_graph, self)
end

#select(&selector) ⇒ Object

Select vertices in the graph



100
101
102
# File 'lib/tangle/base_graph.rb', line 100

def select(&selector)
  @vertices.each_key.select(&selector)
end

#subgraph(included = nil, &selector) ⇒ Object

Return a subgraph, optionally filtered by a vertex selector block

subgraph => Graph subgraph { |vertex| … } => Graph

Unless a selector is provided, the subgraph contains the entire graph.



66
67
68
69
70
71
# File 'lib/tangle/base_graph.rb', line 66

def subgraph(included = nil, &selector)
  result = clone
  result.select_vertices!(included) unless included.nil?
  result.select_vertices!(&selector) if block_given?
  result
end

#to_sObject Also known as: inspect



79
80
81
# File 'lib/tangle/base_graph.rb', line 79

def to_s
  "#<#{self.class}: #{vertices.count} vertices, #{edges.count} edges>"
end

#verticesObject

Return all vertices in the graph



95
96
97
# File 'lib/tangle/base_graph.rb', line 95

def vertices
  @vertices.keys
end