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



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

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

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

Add a new edge to the graph

add_edge(vtx1, vtx2, …) => Edge



134
135
136
137
138
139
# File 'lib/tangle/base_graph.rb', line 134

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



102
103
104
105
106
107
108
# File 'lib/tangle/base_graph.rb', line 102

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

#edges(vertex = nil) ⇒ Object

Get all edges.

edges => Array



124
125
126
127
# File 'lib/tangle/base_graph.rb', line 124

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

#fetch(name) ⇒ Object

Fetch a vertex by its name



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

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

#remove_edge(edge) ⇒ Object

Remove an edge from the graph



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

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



112
113
114
115
116
117
118
# File 'lib/tangle/base_graph.rb', line 112

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



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

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



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

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

#verticesObject

Return all vertices in the graph



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

def vertices
  @vertices.keys
end