yargi 0.1.2 → 0.2.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/CHANGELOG.md +54 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +23 -0
- data/LICENCE.md +22 -0
- data/Manifest.txt +15 -0
- data/README.md +128 -0
- data/Rakefile +23 -0
- data/examples/fs2dot.rb +1 -1
- data/examples/random.rb +20 -0
- data/lib/yargi.rb +8 -10
- data/lib/yargi/decorate.rb +55 -0
- data/lib/yargi/digraph.rb +71 -46
- data/lib/yargi/digraph_edge.rb +23 -23
- data/lib/yargi/digraph_vertex.rb +27 -27
- data/lib/yargi/edge_set.rb +12 -12
- data/lib/yargi/element_set.rb +54 -54
- data/lib/yargi/loader.rb +1 -0
- data/lib/yargi/markable.rb +12 -12
- data/lib/yargi/predicate.rb +62 -43
- data/lib/yargi/random.rb +98 -0
- data/lib/yargi/version.rb +14 -0
- data/lib/yargi/vertex_set.rb +12 -12
- data/spec/spec_helper.rb +2 -0
- data/spec/test_decorate.rb +28 -0
- data/spec/test_digraph.rb +42 -0
- data/spec/test_random.rb +45 -0
- data/spec/test_yargi.rb +8 -0
- data/tasks/debug_mail.rake +75 -0
- data/tasks/debug_mail.txt +13 -0
- data/tasks/gem.rake +68 -0
- data/tasks/spec_test.rake +71 -0
- data/tasks/unit_test.rake +76 -0
- data/tasks/yard.rake +51 -0
- data/test/test_all.rb +1 -1
- data/test/yargi/README-example.gif +0 -0
- data/test/yargi/digraph_set_features_test.rb +14 -16
- data/test/yargi/digraph_test.rb +33 -33
- data/test/yargi/digraph_vertex_test.rb +9 -9
- data/test/yargi/documentation_test.rb +7 -7
- data/test/yargi/edge_set_test.rb +3 -3
- data/test/yargi/element_set_test.rb +2 -2
- data/test/yargi/hypotheses_test.rb +4 -4
- data/test/yargi/markable_test.rb +11 -11
- data/test/yargi/predicate_test.rb +14 -14
- data/test/yargi/source-sink.gif +0 -0
- data/test/yargi/vertex_set_test.rb +7 -7
- data/yargi.gemspec +187 -0
- data/yargi.noespec +23 -0
- metadata +110 -38
- data/CONTRIBUTE +0 -11
- data/LICENCE +0 -25
- data/README +0 -79
- data/examples/fs2dot.dot +0 -78
- data/examples/fs2dot.gif +0 -0
data/lib/yargi/digraph_edge.rb
CHANGED
@@ -1,81 +1,81 @@
|
|
1
1
|
module Yargi
|
2
2
|
class Digraph
|
3
|
-
|
3
|
+
|
4
4
|
#
|
5
5
|
# Edge inside a digraph
|
6
6
|
#
|
7
|
-
# Methods reconnect, index= are provided for Digraph itself and are not
|
8
|
-
# intended to be used directly. Probably unexpectedly, source and target
|
7
|
+
# Methods reconnect, index= are provided for Digraph itself and are not
|
8
|
+
# intended to be used directly. Probably unexpectedly, source and target
|
9
9
|
# writers are provided as reconnection shortcuts and can be used by users.
|
10
10
|
#
|
11
11
|
class Edge
|
12
12
|
include Yargi::Markable
|
13
|
-
|
13
|
+
|
14
14
|
# Owning graph
|
15
15
|
attr_reader :graph
|
16
16
|
alias :digraph :graph
|
17
|
-
|
17
|
+
|
18
18
|
# Index in the vertices list of the owner
|
19
19
|
attr_accessor :index
|
20
|
-
|
20
|
+
|
21
21
|
# Source vertex
|
22
22
|
attr_reader :source
|
23
|
-
|
23
|
+
|
24
24
|
# Target vertex
|
25
25
|
attr_reader :target
|
26
|
-
|
26
|
+
|
27
27
|
# Creates an edge instance
|
28
28
|
def initialize(graph, index, source, target)
|
29
29
|
@graph, @index = graph, index
|
30
30
|
@source, @target = source, target
|
31
31
|
end
|
32
32
|
|
33
|
-
|
33
|
+
|
34
34
|
### Pseudo-protected section ##########################################
|
35
|
-
|
35
|
+
|
36
36
|
# Reconnects source and target
|
37
37
|
def reconnect(source, target)
|
38
38
|
@source = source if source
|
39
39
|
@target = target if target
|
40
40
|
end
|
41
41
|
|
42
|
-
|
42
|
+
|
43
43
|
### Query section #######################################################
|
44
|
-
|
44
|
+
|
45
45
|
# Returns edge extremities
|
46
46
|
def extremities
|
47
47
|
VertexSet[source, target]
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
# Shortcut for digraph.reconnect(edge, source, nil)
|
51
51
|
def source=(source)
|
52
52
|
@graph.reconnect(self, source, nil)
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
# Shortcut for digraph.reconnect(edge, nil, target)
|
56
56
|
def target=(target)
|
57
57
|
@graph.reconnect(self, nil, target)
|
58
58
|
end
|
59
|
-
|
60
|
-
|
59
|
+
|
60
|
+
|
61
61
|
### Sort, Hash, etc. section ############################################
|
62
|
-
|
62
|
+
|
63
63
|
# Compares indexes
|
64
64
|
def <=>(other)
|
65
65
|
return nil unless Edge===other and self.graph==other.graph
|
66
66
|
self.index <=> other.index
|
67
67
|
end
|
68
|
-
|
69
|
-
|
68
|
+
|
69
|
+
|
70
70
|
### Export section ######################################################
|
71
|
-
|
71
|
+
|
72
72
|
# Returns a string representation
|
73
73
|
def to_s; "e#{index}:#{source.to_s}->#{target.to_s}" end
|
74
|
-
|
74
|
+
|
75
75
|
# Inspects the vertex
|
76
76
|
def inspect; "e#{index}:#{source.inspect}->#{target.inspect}" end
|
77
|
-
|
77
|
+
|
78
78
|
end # class Edge
|
79
|
-
|
79
|
+
|
80
80
|
end
|
81
81
|
end
|
data/lib/yargi/digraph_vertex.rb
CHANGED
@@ -1,98 +1,98 @@
|
|
1
1
|
module Yargi
|
2
2
|
class Digraph
|
3
|
-
|
3
|
+
|
4
4
|
#
|
5
5
|
# Vertex inside a digraph.
|
6
6
|
#
|
7
|
-
# Methods add_in_edge, remove_in_edge, add_out_edge, remove_out_edge and index=
|
7
|
+
# Methods add_in_edge, remove_in_edge, add_out_edge, remove_out_edge and index=
|
8
8
|
# are provided for Digraph itself and are not intended to be used directly.
|
9
9
|
#
|
10
10
|
class Vertex
|
11
11
|
include Yargi::Markable
|
12
|
-
|
12
|
+
|
13
13
|
# Owning graph
|
14
14
|
attr_reader :graph
|
15
15
|
alias :digraph :graph
|
16
|
-
|
16
|
+
|
17
17
|
# Index in the vertices list of the owner
|
18
18
|
attr_accessor :index
|
19
|
-
|
19
|
+
|
20
20
|
# Creates a vertex instance
|
21
21
|
def initialize(graph, index)
|
22
22
|
@graph, @index = graph, index
|
23
23
|
@in_edges, @out_edges = EdgeSet[], EdgeSet[]
|
24
24
|
end
|
25
25
|
|
26
|
-
|
26
|
+
|
27
27
|
### Query section #######################################################
|
28
|
-
|
28
|
+
|
29
29
|
# Returns a copy of the incoming edges list.
|
30
30
|
def in_edges(filter=nil, &block)
|
31
31
|
@in_edges.filter(filter, &block)
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
# Returns a copy of the outgoing edges list.
|
35
35
|
def out_edges(filter=nil, &block)
|
36
36
|
@out_edges.filter(filter, &block)
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
# Returns all adjacent vertices
|
40
40
|
def adjacent(filter=nil, &block)
|
41
41
|
(in_adjacent(filter, &block) + out_adjacent(filter, &block)).uniq
|
42
42
|
end
|
43
|
-
|
44
|
-
# Returns back-adjacent vertices
|
43
|
+
|
44
|
+
# Returns back-adjacent vertices
|
45
45
|
def in_adjacent(filter=nil, &block)
|
46
46
|
@in_edges.source.filter(filter, &block)
|
47
47
|
end
|
48
|
-
|
49
|
-
# Returns forward-adjacent vertices
|
48
|
+
|
49
|
+
# Returns forward-adjacent vertices
|
50
50
|
def out_adjacent(filter=nil, &block)
|
51
51
|
@out_edges.target.filter(filter, &block)
|
52
52
|
end
|
53
53
|
|
54
|
-
|
54
|
+
|
55
55
|
### Pseudo-protected section ##########################################
|
56
|
-
|
56
|
+
|
57
57
|
# Adds an incoming edge
|
58
58
|
def add_in_edge(edge)
|
59
59
|
@in_edges << edge
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
# Removes an incoming edge
|
63
63
|
def remove_in_edge(edge)
|
64
64
|
@in_edges.delete(edge)
|
65
65
|
end
|
66
|
-
|
66
|
+
|
67
67
|
# Adds an outgoing edge
|
68
68
|
def add_out_edge(edge)
|
69
69
|
@out_edges << edge
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
# Removes an outgoing edge
|
73
73
|
def remove_out_edge(edge)
|
74
74
|
@out_edges.delete(edge)
|
75
75
|
end
|
76
|
-
|
77
|
-
|
76
|
+
|
77
|
+
|
78
78
|
### Sort, Hash, etc. section ############################################
|
79
|
-
|
79
|
+
|
80
80
|
# Compares indexes
|
81
81
|
def <=>(other)
|
82
82
|
return nil unless Vertex===other and self.graph==other.graph
|
83
83
|
self.index <=> other.index
|
84
84
|
end
|
85
|
-
|
86
|
-
|
85
|
+
|
86
|
+
|
87
87
|
### Export section ######################################################
|
88
|
-
|
88
|
+
|
89
89
|
# Returns a string representation
|
90
90
|
def to_s; "V#{index}" end
|
91
|
-
|
91
|
+
|
92
92
|
# Inspects the vertex
|
93
93
|
def inspect; "V#{index}" end
|
94
|
-
|
94
|
+
|
95
95
|
end # class Vertex
|
96
|
-
|
96
|
+
|
97
97
|
end
|
98
98
|
end
|
data/lib/yargi/edge_set.rb
CHANGED
@@ -1,45 +1,45 @@
|
|
1
1
|
module Yargi
|
2
|
-
|
2
|
+
|
3
3
|
# A set of edges
|
4
4
|
class EdgeSet < ElementSet
|
5
|
-
|
5
|
+
|
6
6
|
### Factory section #######################################################
|
7
|
-
|
7
|
+
|
8
8
|
# Creates a VertexSet instance using _elements_ varargs.
|
9
9
|
def self.[](*elements)
|
10
10
|
EdgeSet.new(elements)
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
### Walking section #######################################################
|
14
|
-
|
14
|
+
|
15
15
|
# Returns a VertexSet with reachable vertices using the edges of this set.
|
16
16
|
def target
|
17
17
|
VertexSet.new(self.collect {|e| e.target}).uniq
|
18
18
|
end
|
19
19
|
alias :targets :target
|
20
|
-
|
21
|
-
# Returns a VertexSet with back-reachable vertices using the edges of this
|
20
|
+
|
21
|
+
# Returns a VertexSet with back-reachable vertices using the edges of this
|
22
22
|
# set.
|
23
23
|
def source
|
24
24
|
VertexSet.new(self.collect {|e| e.source}).uniq
|
25
25
|
end
|
26
26
|
alias :sources :source
|
27
|
-
|
27
|
+
|
28
28
|
### Writing section #######################################################
|
29
|
-
|
29
|
+
|
30
30
|
# Fired to each edge in the set
|
31
31
|
def source=(source)
|
32
32
|
self.each{|e| e.source=source}
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
# Fired to each edge in the set
|
36
36
|
def target=(target)
|
37
37
|
self.each{|e| e.target=target}
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
### Protected section #####################################################
|
41
41
|
protected
|
42
|
-
|
42
|
+
|
43
43
|
# Extends with EdgeSet instead of ElementSet
|
44
44
|
def extend_result(result)
|
45
45
|
EdgeSet.new(result)
|
data/lib/yargi/element_set.rb
CHANGED
@@ -1,139 +1,139 @@
|
|
1
1
|
require 'delegate'
|
2
2
|
|
3
3
|
module Yargi
|
4
|
-
|
4
|
+
|
5
5
|
# Main module of VertexSet and EdgeSet
|
6
6
|
class ElementSet < Array
|
7
|
-
|
7
|
+
|
8
8
|
### Factory section #######################################################
|
9
|
-
|
9
|
+
|
10
10
|
# Creates a ElementSet instance using _elements_ varargs.
|
11
11
|
def self.[](*elements)
|
12
12
|
ElementSet.new(elements)
|
13
13
|
end
|
14
|
-
|
15
|
-
|
14
|
+
|
15
|
+
|
16
16
|
### Array handling ########################################################
|
17
17
|
|
18
18
|
# Same as Array.dup
|
19
19
|
def dup() # :nodoc: #
|
20
|
-
extend_result(super)
|
20
|
+
extend_result(super)
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
# See Array.compact
|
24
24
|
def compact() # :nodoc: #
|
25
|
-
extend_result(super)
|
25
|
+
extend_result(super)
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
# See Array.flatten
|
29
29
|
def flatten() # :nodoc: #
|
30
|
-
extend_result(super)
|
30
|
+
extend_result(super)
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
# See Array.reverse
|
34
34
|
def reverse() # :nodoc: #
|
35
|
-
extend_result(super)
|
35
|
+
extend_result(super)
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
# See Array.uniq
|
39
39
|
def uniq() # :nodoc: #
|
40
|
-
extend_result(super)
|
40
|
+
extend_result(super)
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
# See Array.sort
|
44
44
|
def sort(&block) # :nodoc: #
|
45
|
-
extend_result(super(&block))
|
45
|
+
extend_result(super(&block))
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
# See Array.concat
|
49
49
|
def concat(other) # :nodoc: #
|
50
50
|
extend_result(super(other))
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
# See Array.[]
|
54
54
|
def [](*args) # :nodoc: #
|
55
55
|
result = super(*args)
|
56
|
-
Array===result ? extend_result(result) : result
|
56
|
+
Array===result ? extend_result(result) : result
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
# See Array.+
|
60
60
|
def +(right) # :nodoc: #
|
61
|
-
extend_result(super(right))
|
61
|
+
extend_result(super(right))
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
# See Array.-
|
65
65
|
def -(right) # :nodoc: #
|
66
|
-
extend_result(super(right))
|
66
|
+
extend_result(super(right))
|
67
67
|
end
|
68
|
-
|
69
|
-
|
68
|
+
|
69
|
+
|
70
70
|
### Enumerable handling ###################################################
|
71
|
-
|
71
|
+
|
72
72
|
# See Enumerable.each_cons
|
73
73
|
def each_cons(n) # :nodoc: #
|
74
|
-
super(n) {|c| yield extend_result(c)}
|
74
|
+
super(n) {|c| yield extend_result(c)}
|
75
75
|
end
|
76
|
-
|
76
|
+
|
77
77
|
# See Enumerable.each_slice
|
78
78
|
def each_slice(n) # :nodoc: #
|
79
|
-
super(n) {|c| yield extend_result(c)}
|
79
|
+
super(n) {|c| yield extend_result(c)}
|
80
80
|
end
|
81
|
-
|
81
|
+
|
82
82
|
# See Enumerable.select
|
83
83
|
def select(&block) # :nodoc: #
|
84
|
-
extend_result(super(&block))
|
84
|
+
extend_result(super(&block))
|
85
85
|
end
|
86
|
-
|
86
|
+
|
87
87
|
# See Enumerable.find_all
|
88
88
|
def find_all(&block) # :nodoc: #
|
89
|
-
extend_result(super(&block))
|
89
|
+
extend_result(super(&block))
|
90
90
|
end
|
91
|
-
|
91
|
+
|
92
92
|
# See Enumerable.grep
|
93
93
|
def grep(pattern, &block) # :nodoc: #
|
94
94
|
greped = super(pattern, &block)
|
95
95
|
block_given? ? greped : extend_result(greped)
|
96
96
|
end
|
97
|
-
|
97
|
+
|
98
98
|
# See Enumerable.reject
|
99
99
|
def partition(&block) # :nodoc: #
|
100
100
|
p = super(&block)
|
101
101
|
[extend_result(p[0]), extend_result(p[1])]
|
102
102
|
end
|
103
|
-
|
103
|
+
|
104
104
|
# See Enumerable.reject
|
105
105
|
def reject(&block) # :nodoc: #
|
106
|
-
extend_result(super(&block))
|
106
|
+
extend_result(super(&block))
|
107
107
|
end
|
108
|
-
|
109
|
-
|
108
|
+
|
109
|
+
|
110
110
|
### Markable handling #####################################################
|
111
|
-
|
112
|
-
# Fired to each element of the group.
|
111
|
+
|
112
|
+
# Fired to each element of the group.
|
113
113
|
def tag(*modules)
|
114
114
|
self.each {|elm| elm.tag(*modules)}
|
115
115
|
end
|
116
|
-
|
117
|
-
# Collects result of get_mark invocation on each element of the
|
116
|
+
|
117
|
+
# Collects result of get_mark invocation on each element of the
|
118
118
|
# group and returns it as an array.
|
119
119
|
def get_mark(key)
|
120
120
|
self.collect {|elm| elm.get_mark(key)}
|
121
121
|
end
|
122
122
|
|
123
|
-
# Fired to each element of the group. Values are duplicated by default.
|
123
|
+
# Fired to each element of the group. Values are duplicated by default.
|
124
124
|
# Put dup to false to avoid this behavior.
|
125
125
|
def set_mark(key, value, dup=true)
|
126
126
|
self.each {|elm| elm.set_mark(key, (dup and not(Symbol===value)) ? value.dup : value)}
|
127
127
|
end
|
128
|
-
|
128
|
+
|
129
129
|
# When _marks_ is provided, the invocation is fired to all group
|
130
130
|
# elements. When a block is given, it is called on each element,
|
131
131
|
# passing it as argument. If the block returns a hash, that hash
|
132
|
-
# is installed as marks on the iterated element.
|
132
|
+
# is installed as marks on the iterated element.
|
133
133
|
# The two usages (_marks_ and block) can be used conjointly.
|
134
134
|
def add_marks(marks=nil)
|
135
135
|
self.each {|elm| elm.add_marks(marks)} if marks
|
136
|
-
if block_given?
|
136
|
+
if block_given?
|
137
137
|
self.each do |elm|
|
138
138
|
hash = yield elm
|
139
139
|
elm.add_marks(hash) if Hash===hash
|
@@ -141,20 +141,20 @@ module Yargi
|
|
141
141
|
end
|
142
142
|
end
|
143
143
|
alias :merge_marks :add_marks
|
144
|
-
|
145
|
-
|
144
|
+
|
145
|
+
|
146
146
|
### Query handling ########################################################
|
147
|
-
|
148
|
-
# Filters this set with a 'predicate and block' predicate
|
147
|
+
|
148
|
+
# Filters this set with a 'predicate and block' predicate
|
149
149
|
# (see Yargi::Predicate)
|
150
150
|
def filter(predicate=nil, &block)
|
151
151
|
pred = Yargi::Predicate.to_predicate(predicate, &block)
|
152
152
|
extend_result(self.select{|e| pred===e})
|
153
153
|
end
|
154
|
-
|
154
|
+
|
155
155
|
### Protected section #####################################################
|
156
156
|
protected
|
157
|
-
|
157
|
+
|
158
158
|
# Extends a resulting array with the module. This method is intended
|
159
159
|
# to be overrided by specialization of this module.
|
160
160
|
def extend_result(result)
|
@@ -162,5 +162,5 @@ module Yargi
|
|
162
162
|
end
|
163
163
|
|
164
164
|
end # class ElementSet
|
165
|
-
|
165
|
+
|
166
166
|
end
|