tangle 0.8.2 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.travis.yml DELETED
@@ -1,5 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- rvm:
4
- - 2.5.0
5
- before_install: gem install bundler -v 1.16.0
data/lib/tangle/graph.rb DELETED
@@ -1,81 +0,0 @@
1
- require 'tangle/mixin'
2
- require 'tangle/mixin/connectedness'
3
- require 'tangle/edge'
4
- require 'tangle/graph_vertices'
5
- require 'tangle/graph_edges'
6
-
7
- module Tangle
8
- #
9
- # Base class for all kinds of graphs
10
- #
11
- class Graph
12
- include Tangle::GraphVertices
13
- include Tangle::GraphEdges
14
- include Tangle::Mixin::Initialize
15
- Edge = Tangle::Edge
16
- DEFAULT_MIXINS = Tangle::Mixin::Connectedness::MIXINS
17
-
18
- # Initialize a new graph, preloading it with vertices and edges
19
- #
20
- # Graph[+vertices+] => Graph
21
- # Graph[+vertices+, +edges+) => Graph
22
- #
23
- # When +vertices+ is a hash, it contains initialization kwargs as
24
- # values and vertex names as keys. When +vertices+ is an array of
25
- # initialization kwargs, the vertices will be be anonymous.
26
- #
27
- # +edges+ can contain an array of exactly two, either names of vertices
28
- # or vertices.
29
- #
30
- # Any kwarg supported by Graph.new is also allowed.
31
- #
32
- def self.[](vertices, edges = {}, **kwargs)
33
- graph = new(**kwargs)
34
- vertices.each { |vertex| graph.add_vertex(vertex) }
35
- edges.each { |from, to| graph.add_edge(from, to) }
36
- graph
37
- end
38
-
39
- # Initialize a new graph, optionally preloading it with vertices and edges
40
- #
41
- # Graph.new() => Graph
42
- # Graph.new(mixins: [MixinModule, ...], ...) => Graph
43
- #
44
- # +mixins+ is an array of modules that can be mixed into the various
45
- # classes that makes up a graph. Initialization of a Graph, Vertex or Edge
46
- # looks for submodules in each mixin, with the same name and extends
47
- # any created object. Defaults to [Tangle::Mixin::Connectedness].
48
- #
49
- # Any subclass of Graph should also subclass Edge to manage its unique
50
- # constraints.
51
- #
52
- def initialize(mixins: self.class::DEFAULT_MIXINS, **kwargs)
53
- initialize_vertices
54
- initialize_edges
55
- initialize_mixins(mixins: mixins, **kwargs)
56
- end
57
-
58
- # Return a subgraph, optionally filtered by a vertex selector block
59
- #
60
- # subgraph => Graph
61
- # subgraph { |vertex| ... } => Graph
62
- #
63
- # Unless a selector is provided, the subgraph contains the entire graph.
64
- #
65
- def subgraph(included = nil)
66
- included ||= vertices
67
- result = clone
68
- vertices.each do |vertex|
69
- result.remove_vertex(vertex) unless included.include?(vertex)
70
- next unless block_given?
71
- result.remove_vertex(vertex) unless yield(vertex)
72
- end
73
- result
74
- end
75
-
76
- def to_s
77
- "#<#{self.class}: #{vertices.count} vertices, #{edges.count} edges>"
78
- end
79
- alias inspect to_s
80
- end
81
- end
@@ -1,49 +0,0 @@
1
- require 'set'
2
-
3
- module Tangle
4
- # Edge related methods in a graph
5
- module GraphEdges
6
- # Get all edges.
7
- #
8
- # edges => Array
9
- #
10
- def edges(vertex = nil)
11
- return @edges if vertex.nil?
12
- @vertices.fetch(vertex)
13
- end
14
-
15
- # Add a new edge to the graph
16
- #
17
- # add_edge(vtx1, vtx2, ...) => Edge
18
- #
19
- def add_edge(*vertices, **kvargs)
20
- insert_edge(self.class::Edge.new(*vertices, mixins: @mixins, **kvargs))
21
- end
22
-
23
- # Remove an edge from the graph
24
- def remove_edge(edge)
25
- edge.each_vertex do |vertex|
26
- @vertices.fetch(vertex).delete(edge)
27
- end
28
- @edges.delete(edge)
29
- end
30
-
31
- protected
32
-
33
- # Insert a prepared edge into the graph
34
- #
35
- def insert_edge(edge)
36
- @edges << edge
37
- edge.each_vertex do |vertex|
38
- @vertices.fetch(vertex) << edge
39
- end
40
- edge
41
- end
42
-
43
- private
44
-
45
- def initialize_edges
46
- @edges = Set[]
47
- end
48
- end
49
- end
@@ -1,68 +0,0 @@
1
- module Tangle
2
- module Mixin
3
- #
4
- # Mixins for adding connectedness features
5
- #
6
- module Connectedness
7
- MIXINS = [Tangle::Mixin::Connectedness].freeze
8
- #
9
- # Mixin for adding connectedness to a graph
10
- #
11
- module Graph
12
- # Two vertices are adjacent if there is an edge between them
13
- def adjacent?(vertex, other)
14
- edges(vertex).any? { |edge| edge[vertex] == other }
15
- end
16
-
17
- # Return the set of adjacent vertices
18
- def adjacent(vertex)
19
- Set.new(edges(vertex).map { |edge| edge.walk(vertex) })
20
- end
21
-
22
- # Get the largest connected subgraph for a vertex.
23
- # Also aliased as :component and :connected_component
24
- #
25
- # connected_subgraph(vertex) => Graph
26
- #
27
- def connected_subgraph(vertex)
28
- subgraph { |other| connected_vertices?(vertex, other) }
29
- end
30
- alias component connected_subgraph
31
- alias connected_component connected_subgraph
32
-
33
- # Get the largest subgraph that is not connected to a vertex, or what's
34
- # left after removing the connected subgraph.
35
- #
36
- def disconnected_subgraph(vertex)
37
- subgraph { |other| !connected_vertices?(vertex, other) }
38
- end
39
-
40
- # A graph is connected if all vertices are connected to all vertices
41
- # An empty graph is disconnected.
42
- #
43
- def connected?(*tested_vertices)
44
- tested_vertices = vertices if tested_vertices.empty?
45
- return false if tested_vertices.empty?
46
-
47
- tested_vertices.combination(2).all? do |pair|
48
- this, that = pair.to_a
49
- reachable(this).any? { |other| other == that }
50
- end
51
- end
52
-
53
- # A graph is disconnected if any vertex is not connected to all other.
54
- # An empty graph is disconnected.
55
- #
56
- def disconnected?(*tested_vertices)
57
- !connected?(*tested_vertices)
58
- end
59
-
60
- # Return a breadth-first Enumerator for all reachable vertices,
61
- # by transitive adjacency.
62
- def reachable(start_vertex)
63
- vertex_enumerator(start_vertex, :adjacent)
64
- end
65
- end
66
- end
67
- end
68
- end
@@ -1,17 +0,0 @@
1
- require 'tangle/graph'
2
-
3
- module Tangle
4
- module Simple
5
- #
6
- # A simple graph, without loops and multiple edges
7
- class Graph < Tangle::Graph
8
- protected
9
-
10
- def insert_edge(edge)
11
- raise LoopError if edge.loop?
12
- raise MultiEdgeError if adjacent?(*edge.each_vertex)
13
- super
14
- end
15
- end
16
- end
17
- end