sequitur 0.1.15 → 0.1.16

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ODUxYjgzNjcxM2M5ZWQxZDgxNmE0NjJiM2E5Njc5MzBlY2Q1NDc2Mg==
5
- data.tar.gz: !binary |-
6
- MjRjY2Q2MmRmOWEyZGE2NDI1NWQ2ZDJhZjdlMjE5YzdiMDhkOWI4YQ==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- NDI0YzNmOWI4ZTBlZGNjNDkxNmNmNTRhNDJjZDMzMDY4OWE4YmU5YmRjZmJl
10
- NzI5MjViMjhhNGYyODkyNGQzNGMyMGFhMjRkNjMyMDBlOTFlN2ZhNzgzYzk1
11
- MTgxNjYzYTA4YmFkZWE1ZDlmOTc0MDdkMzJmOGQzMTFiYmEzYWQ=
12
- data.tar.gz: !binary |-
13
- OGI1NWI4NDBlMjhhYzQ3NWUyNDI1MmFkZmI0ZTgzYWRlZWQ1OTZlZWM4Yzg1
14
- OTIxMDc4Zjc2NmY1MDExNzQ5OWYyZTkwY2EyZjgwMTczZGFkOGE2YzJkMjAx
15
- NGQxMWY2NDBkOTBlNTM1M2I2YWNiNDA1M2U1MjZlMWFjY2RjZTI=
2
+ SHA1:
3
+ metadata.gz: b1af553fad3ecc43dc57cc44e040b01d855caf01
4
+ data.tar.gz: 541cc47ff348f3886a95bde5eba649c1f1a91913
5
+ SHA512:
6
+ metadata.gz: db612a6216a109a99a216e2cfaca23feaf20243c121fd404956bc76109f5926e67af4cb26c29f747040f93348768ab2f40e1db3070d096fd96dc687d290a3bf9
7
+ data.tar.gz: 21ae7581e271eb66e7f8a4578ae451e994670cc138afe341f18722cfbf7cd8625a559748281f2986ce121ba10da2a58438c12f1c04b8db0dd6f3e084e0e2d186
@@ -1 +1 @@
1
- 1.9.3
1
+ 2.2.3
@@ -1,3 +1,7 @@
1
+ ### 0.1.16 / 2015-09-05
2
+ * [CHANGE] Minor. Code re-formatted to please Rubocop 0.34.0
3
+ * [FIX] File `sequitur.gemspec`: updated gem version in development dependencies
4
+
1
5
  ### 0.1.15 / 2015-06-16
2
6
  * [CHANGE] Code re-formatted to please Rubocop 0.32.0
3
7
  * [FIX] File `.rubocop.yml`: change some cop settings.
data/Gemfile CHANGED
@@ -3,8 +3,9 @@ source 'https://rubygems.org'
3
3
 
4
4
 
5
5
  group :development do
6
- gem 'rake', '>= 0.8.0'
7
- gem 'rspec', '>= 3.0.0'
8
- gem 'simplecov', '>= 0.5.0'
6
+ gem 'rake', '>= 10.0.0'
7
+ gem 'rspec', '>= 2.1.0'
8
+ gem 'simplecov', '>= 0.8.0'
9
9
  gem 'coveralls', '>= 0.7.0'
10
10
  end
11
+
@@ -3,7 +3,7 @@
3
3
 
4
4
  module Sequitur # Module used as a namespace
5
5
  # The version number of the gem.
6
- Version = '0.1.15'
6
+ Version = '0.1.16'
7
7
 
8
8
  # Brief description of the gem.
9
9
  Description = 'Ruby implementation of the Sequitur algorithm'
@@ -121,7 +121,7 @@ class SequiturGrammar < DynamicGrammar
121
121
  # And delete P
122
122
  def restore_utility(prod_index)
123
123
  # Retrieve useless prod from its index
124
- useless_prod = productions[prod_index]
124
+ useless_prod = productions[prod_index]
125
125
 
126
126
  # Retrieve production referencing useless one
127
127
  referencing = nil
@@ -71,7 +71,7 @@ describe DynamicGrammar do
71
71
  expect(p_b.refcount).to eq(1)
72
72
  expect(p_c.refcount).to eq(1)
73
73
 
74
- subject.remove_production(1) # 1 => p_a
74
+ subject.remove_production(1) # 1 => p_a
75
75
  expect(subject.productions.size).to eq(4)
76
76
  expect(p_b.refcount).to eq(1)
77
77
  expect(p_c.refcount).to eq(1)
@@ -60,7 +60,7 @@ SNIPPET
60
60
 
61
61
  it 'should support visit events with an explicit visitor' do
62
62
  instance = BaseText.new(destination)
63
- a_visitor = sample_grammar.visitor # Use visitor explicitly
63
+ a_visitor = sample_grammar.visitor # Use visitor explicitly
64
64
  instance.render(a_visitor)
65
65
  expectations = <<-SNIPPET
66
66
  start :.
@@ -72,8 +72,8 @@ describe ProductionRef do
72
72
 
73
73
  it 'should compare to other production (reference)' do
74
74
  same = ProductionRef.new(target)
75
- expect(subject).to eq(subject) # Strict identity
76
- expect(subject).to eq(same) # 2 references pointing to same production
75
+ expect(subject).to eq(subject) # Strict identity
76
+ expect(subject).to eq(same) # 2 references pointing to same production
77
77
  expect(subject).to eq(target)
78
78
  end
79
79
 
@@ -129,7 +129,7 @@ describe Production do
129
129
  # Side-effect: refcount of production to append is incremented
130
130
  expect(p_a.refcount).to be(0)
131
131
 
132
- input = [p_a, :b, :c, :d, p_a, :e, :f] # p_a appears twice
132
+ input = [p_a, :b, :c, :d, p_a, :e, :f] # p_a appears twice
133
133
  input.each { |symb| subject.append_symbol(symb) }
134
134
  expect(p_a.refcount).to be(2)
135
135
  end
@@ -139,7 +139,7 @@ describe Production do
139
139
  ref_a = ProductionRef.new(p_a)
140
140
  expect(p_a.refcount).to be(1)
141
141
 
142
- input = [ref_a, :b, :c, :d, ref_a] # ref_a appears twice
142
+ input = [ref_a, :b, :c, :d, ref_a] # ref_a appears twice
143
143
  input.each { |symb| subject.append_symbol(symb) }
144
144
 
145
145
  # References in rhs should point to p_a...
@@ -1,304 +1,304 @@
1
- require_relative '../spec_helper'
2
-
3
- # Load the class under test
4
- require_relative '../../lib/sequitur/sequitur_grammar'
5
-
6
- module Sequitur # Re-open the module to get rid of qualified names
7
- describe SequiturGrammar do
8
- # Factory method. Returns an empty enumerator (
9
- # i.e. without elements to iterate)
10
- def empty_enum()
11
- return [].to_enum
12
- end
13
-
14
- context 'Creation from an enumeration of tokens:' do
15
- it 'could be created with an empty enumerator' do
16
- expect { SequiturGrammar.new(empty_enum) }.not_to raise_error
17
-
18
- # Creation
19
- instance = SequiturGrammar.new(empty_enum)
20
-
21
- # Initialization
22
- expect(instance.productions.size).to eq(1)
23
- expect(instance.start).to eq(instance.productions.first)
24
- expect(instance.start).to be_empty
25
- end
26
-
27
- it 'could be created with single token' do
28
- # Creation
29
- instance = SequiturGrammar.new([:a].to_enum)
30
-
31
- # Initialization
32
- expect(instance.productions.size).to eq(1)
33
- expect(instance.start).to eq(instance.productions.first)
34
- expect(instance.start.rhs).to eq([:a])
35
- end
36
-
37
- it 'could be created with multiple unique tokens' do
38
- # Creation
39
- instance = SequiturGrammar.new([:a, :b, :c, :d].to_enum)
40
-
41
- # Initialization
42
- expect(instance.productions.size).to eq(1)
43
- expect(instance.start).to eq(instance.productions.first)
44
- expect(instance.start.rhs).to eq([:a, :b, :c, :d])
45
- end
46
-
47
- it 'could be created with a repeating digram' do
48
- instance = SequiturGrammar.new([:a, :b, :a, :b].to_enum)
49
-
50
- # Expectations:
51
- # S : A A.
52
- # A : a b.
53
- expect(instance.productions.size).to eq(2)
54
- p_a = instance.productions[1]
55
- expect(p_a.rhs).to eq([:a, :b])
56
- expect(instance.start.rhs).to eq([p_a, p_a])
57
- end
58
-
59
- it 'should enforce the utility rule' do
60
- instance = SequiturGrammar.new([:a, :b, :c, :a, :b, :c].to_enum)
61
-
62
- # Expectations without utility rule:
63
- # S : B B.
64
- # A : a b.
65
- # B : A c.
66
-
67
- # Expectations with utility rule:
68
- # S : A A.
69
- # A : a b c.
70
- expect(instance.productions.size).to eq(2)
71
- p_a = instance.productions.last
72
- expect(p_a.rhs).to eq([:a, :b, :c])
73
- expect(instance.start.rhs).to eq([p_a, p_a])
74
- end
75
-
76
- it 'should cope with a pattern that caused an exception' do
77
- input = 'aaac' # This sequence raised an exception
78
-
79
- # Creation
80
- expect { SequiturGrammar.new(input.chars) }.not_to raise_error
81
- end
82
-
83
-
84
- it 'should cope with the example from presentation' do
85
- input = 'bbebeebebebbebee'
86
-
87
- # Creation
88
- instance = SequiturGrammar.new(input.chars)
89
-
90
- # Expectations:
91
- # S: P3 P2 P3
92
- # P1: b e
93
- # P2: P1 P1
94
- # P3: b P2 e
95
- expect(instance.productions.size).to eq(4)
96
- (p1, p2, p3) = instance.productions[1..3]
97
- expect(instance.start.rhs).to eq([p3, p2, p3])
98
- expect(p1.rhs).to eq(%w(b e))
99
- expect(p2.rhs).to eq([p1, p1])
100
- expect(p3.rhs).to eq(['b', p2, 'e'])
101
- end
102
-
103
- it 'should work with strings instead of single char input tokens' do
104
- # Raw input is sequence of chars
105
- raw_input = 'bbebeebebebbebee'
106
-
107
- # Convert them into multichar strings
108
- input = raw_input.chars.map do |ch|
109
- 'letter_' + ch
110
- end
111
-
112
- # Creation
113
- instance = SequiturGrammar.new(input.to_enum)
114
-
115
- # Expectations:
116
- # S: P3 P2 P3
117
- # P1: b e
118
- # P2: P1 P1
119
- # P3: b P2 e
120
- expect(instance.productions.size).to eq(4)
121
- (p1, p2, p3) = instance.productions[1..3]
122
- expect(instance.start.rhs).to eq([p3, p2, p3])
123
- expect(p1.rhs).to eq(%w(letter_b letter_e))
124
- expect(p2.rhs).to eq([p1, p1])
125
- expect(p3.rhs).to eq(['letter_b', p2, 'letter_e'])
126
- end
127
-
128
- it 'should work with Symbol instead of single char input tokens' do
129
- # Raw input is sequence of single characters
130
- raw_input = 'bbebeebebebbebee'
131
-
132
- # Convert them into symbols
133
- input = raw_input.chars.map(&:to_sym)
134
-
135
- # Creation
136
- instance = SequiturGrammar.new(input.to_enum)
137
-
138
- # Expectations:
139
- # S: P3 P2 P3
140
- # P1: b e
141
- # P2: P1 P1
142
- # P3: b P2 e
143
- expect(instance.productions.size).to eq(4)
144
- (p1, p2, p3) = instance.productions[1..3]
145
- expect(instance.start.rhs).to eq([p3, p2, p3])
146
- expect(p1.rhs).to eq([:b, :e])
147
- expect(p2.rhs).to eq([p1, p1])
148
- expect(p3.rhs).to eq([:b, p2, :e])
149
- end
150
-
151
-
152
- it 'should work with integer values as input tokens' do
153
- # Raw input is sequence of hex digits
154
- raw_input = 'bbebeebebebbebee'
155
-
156
- # Convert them into Fixnums
157
- input = raw_input.chars.map { |ch| ch.to_i(16) }
158
-
159
- # Creation
160
- instance = SequiturGrammar.new(input.to_enum)
161
-
162
- # Expectations:
163
- # S: P3 P2 P3
164
- # P1: b e
165
- # P2: P1 P1
166
- # P3: b P2 e
167
- expect(instance.productions.size).to eq(4)
168
- (p1, p2, p3) = instance.productions[1..3]
169
- expect(instance.start.rhs).to eq([p3, p2, p3])
170
- expect(p1.rhs).to eq([0xb, 0xe])
171
- expect(p2.rhs).to eq([p1, p1])
172
- expect(p3.rhs).to eq([0xb, p2, 0xe])
173
- end
174
-
175
- it 'should cope with the example from sequitur.info website' do
176
- input = 'abcabdabcabd'
177
- instance = SequiturGrammar.new(input.chars)
178
-
179
- # Expectations:
180
- # 0 → 2 2
181
- # 1 → a b
182
- # 2 → 1 c 1 d
183
-
184
- expect(instance.productions.size).to eq(3)
185
- (p1, p2) = instance.productions[1..2]
186
- expect(instance.start.rhs).to eq([p2, p2])
187
- expect(p1.rhs).to eq(%w(a b))
188
- expect(p2.rhs).to eq([p1, 'c', p1, 'd'])
189
- end
190
-
191
- it "should cope with the example from Salomon's book" do
192
- input = 'abcdbcabcdbc'
193
- instance = SequiturGrammar.new(input.chars)
194
-
195
- # Expectations:
196
- # S → CC
197
- # A → bc
198
- # C → aAdA
199
-
200
- expect(instance.productions.size).to eq(3)
201
- (p_a, p_c) = instance.productions[1..2]
202
- expect(instance.start.rhs).to eq([p_c, p_c])
203
- expect(p_a.rhs).to eq(%w(b c))
204
- expect(p_c.rhs).to eq(['a', p_a, 'd', p_a])
205
- end
206
-
207
- it 'should cope with the "porridge" example from sequitur.info' do
208
- # Another example from sequitur.info website
209
- input = <<-SNIPPET
210
- pease porridge hot,
211
- pease porridge cold,
212
- pease porridge in the pot,
213
- nine days old.
214
-
215
- some like it hot,
216
- some like it cold,
217
- some like it in the pot,
218
- nine days old.
219
- SNIPPET
220
- # Expectations (sequitur.org)
221
- # 0 → 1 2 3 4 3 5 ↵ 6 2 7 4 7 5
222
- # 1 → p e a s 8 r r i d g 9 pease_porridge_
223
- # 2 → h o t hot
224
- # 3 → 10 1 ,↵pease_porridge_
225
- # 4 → c 11 cold
226
- # 5 → 12 _ t h 8 t 10 n 12 9 d a y s _ 11 . ↵
227
- # in_the_pot,↵nine_days_old.↵
228
- # 6 → s o m 9 l i k 9 i t _ some_like_it_
229
- # 7 → 10 6 ,↵some_like_it_
230
- # 8 → 9 p o e_po
231
- # 9 → e _ e_
232
- # 10 → , ↵ ,↵
233
- # 11 → o l d old
234
- # 12 → i n in
235
-
236
- instance = SequiturGrammar.new(input.chars)
237
- expect(instance.productions.size).to eq(13)
238
- p0 = instance.start
239
- expect(p0.rhs.size).to eq(13)
240
-
241
- (p1, p2, p3, p4, p5, p6, p7, p8, p9) = instance.productions[1..9]
242
- (p10, p11, p12) = instance.productions[10..12]
243
-
244
- # Note: the productions aren't sorted the same way as
245
- # the sequitur.info implementation.
246
- p0_expectation = [
247
- p2, p8, p3, p10, p3, p12, "\n",
248
- p9, p8, p11, p10, p11, p12
249
- ]
250
- expect(p0.rhs).to eq(p0_expectation) # Rule 0 above
251
- expect(p1.rhs).to eq(['e', ' ']) # Rule 9 above
252
- expect(p2.rhs).to eq([%w(p e a s), p4, %w(r r i d g), p1].flatten) # R1
253
- expect(p3.rhs).to eq([p5, p2]) # Rule 3 above
254
- expect(p4.rhs).to eq([p1, 'p', 'o']) # Rule 8 above
255
- expect(p5.rhs).to eq([',', "\n"]) # Rule 10 above
256
- expect(p6.rhs).to eq(%w(i n)) # Rule 12 above
257
- expect(p7.rhs).to eq(%w(o l d)) # Rule 11 above
258
- expect(p8.rhs).to eq(%w(h o t)) # Rule 2 above
259
- p9_expectation = [%w(s o m), p1, %w(l i k), p1, 'i', 't', ' '].flatten
260
- expect(p9.rhs).to eq(p9_expectation) # Rule 6 above
261
- expect(p10.rhs).to eq(['c', p7]) # Rule 4 above
262
- expect(p11.rhs).to eq([p5, p9]) # Rule 7 above
263
- p12_expectation = [
264
- p6, ' ', 't', 'h', p4, 't', p5, 'n', p6, p1,
265
- %w(d a y s), ' ', p7, '.', "\n"
266
- ].flatten
267
- expect(p12.rhs).to eq(p12_expectation) # Rule 5 above
268
- end
269
-
270
- it 'should work with a sequence of Ruby Symbols' do
271
- input = 'abcabdabcabd'.chars.map(&:to_sym)
272
- instance = SequiturGrammar.new(input.to_enum)
273
-
274
- # Expectations:
275
- # start : P2 P2.
276
- # P1 : :a :b
277
- # P2 : P1 :c P1 :d.
278
-
279
- expect(instance.productions.size).to eq(3)
280
- (p1, p2) = instance.productions[1..2]
281
- expect(instance.start.rhs).to eq([p2, p2])
282
- expect(p1.rhs).to eq([:a, :b])
283
- expect(p2.rhs).to eq([p1, :c, p1, :d])
284
- end
285
- end # context
286
-
287
- context 'Generating a text representation of itself:' do
288
- it 'should generate a text representation when empty' do
289
- instance = SequiturGrammar.new(empty_enum)
290
- expectation = "#{instance.start.object_id} : ."
291
-
292
- expect(instance.to_string).to eq(expectation)
293
- end
294
-
295
- it 'should generate a text representation of a simple production' do
296
- instance = SequiturGrammar.new([:a].to_enum)
297
- expectation = "#{instance.start.object_id} : a."
298
- expect(instance.to_string).to eq(expectation)
299
- end
300
- end # context
301
- end # describe
302
- end # module
303
-
304
- # End of file
1
+ require_relative '../spec_helper'
2
+
3
+ # Load the class under test
4
+ require_relative '../../lib/sequitur/sequitur_grammar'
5
+
6
+ module Sequitur # Re-open the module to get rid of qualified names
7
+ describe SequiturGrammar do
8
+ # Factory method. Returns an empty enumerator (
9
+ # i.e. without elements to iterate)
10
+ def empty_enum()
11
+ return [].to_enum
12
+ end
13
+
14
+ context 'Creation from an enumeration of tokens:' do
15
+ it 'could be created with an empty enumerator' do
16
+ expect { SequiturGrammar.new(empty_enum) }.not_to raise_error
17
+
18
+ # Creation
19
+ instance = SequiturGrammar.new(empty_enum)
20
+
21
+ # Initialization
22
+ expect(instance.productions.size).to eq(1)
23
+ expect(instance.start).to eq(instance.productions.first)
24
+ expect(instance.start).to be_empty
25
+ end
26
+
27
+ it 'could be created with single token' do
28
+ # Creation
29
+ instance = SequiturGrammar.new([:a].to_enum)
30
+
31
+ # Initialization
32
+ expect(instance.productions.size).to eq(1)
33
+ expect(instance.start).to eq(instance.productions.first)
34
+ expect(instance.start.rhs).to eq([:a])
35
+ end
36
+
37
+ it 'could be created with multiple unique tokens' do
38
+ # Creation
39
+ instance = SequiturGrammar.new([:a, :b, :c, :d].to_enum)
40
+
41
+ # Initialization
42
+ expect(instance.productions.size).to eq(1)
43
+ expect(instance.start).to eq(instance.productions.first)
44
+ expect(instance.start.rhs).to eq([:a, :b, :c, :d])
45
+ end
46
+
47
+ it 'could be created with a repeating digram' do
48
+ instance = SequiturGrammar.new([:a, :b, :a, :b].to_enum)
49
+
50
+ # Expectations:
51
+ # S : A A.
52
+ # A : a b.
53
+ expect(instance.productions.size).to eq(2)
54
+ p_a = instance.productions[1]
55
+ expect(p_a.rhs).to eq([:a, :b])
56
+ expect(instance.start.rhs).to eq([p_a, p_a])
57
+ end
58
+
59
+ it 'should enforce the utility rule' do
60
+ instance = SequiturGrammar.new([:a, :b, :c, :a, :b, :c].to_enum)
61
+
62
+ # Expectations without utility rule:
63
+ # S : B B.
64
+ # A : a b.
65
+ # B : A c.
66
+
67
+ # Expectations with utility rule:
68
+ # S : A A.
69
+ # A : a b c.
70
+ expect(instance.productions.size).to eq(2)
71
+ p_a = instance.productions.last
72
+ expect(p_a.rhs).to eq([:a, :b, :c])
73
+ expect(instance.start.rhs).to eq([p_a, p_a])
74
+ end
75
+
76
+ it 'should cope with a pattern that caused an exception' do
77
+ input = 'aaac' # This sequence raised an exception
78
+
79
+ # Creation
80
+ expect { SequiturGrammar.new(input.chars) }.not_to raise_error
81
+ end
82
+
83
+
84
+ it 'should cope with the example from presentation' do
85
+ input = 'bbebeebebebbebee'
86
+
87
+ # Creation
88
+ instance = SequiturGrammar.new(input.chars)
89
+
90
+ # Expectations:
91
+ # S: P3 P2 P3
92
+ # P1: b e
93
+ # P2: P1 P1
94
+ # P3: b P2 e
95
+ expect(instance.productions.size).to eq(4)
96
+ (p1, p2, p3) = instance.productions[1..3]
97
+ expect(instance.start.rhs).to eq([p3, p2, p3])
98
+ expect(p1.rhs).to eq(%w(b e))
99
+ expect(p2.rhs).to eq([p1, p1])
100
+ expect(p3.rhs).to eq(['b', p2, 'e'])
101
+ end
102
+
103
+ it 'should work with strings instead of single char input tokens' do
104
+ # Raw input is sequence of chars
105
+ raw_input = 'bbebeebebebbebee'
106
+
107
+ # Convert them into multichar strings
108
+ input = raw_input.chars.map do |ch|
109
+ 'letter_' + ch
110
+ end
111
+
112
+ # Creation
113
+ instance = SequiturGrammar.new(input.to_enum)
114
+
115
+ # Expectations:
116
+ # S: P3 P2 P3
117
+ # P1: b e
118
+ # P2: P1 P1
119
+ # P3: b P2 e
120
+ expect(instance.productions.size).to eq(4)
121
+ (p1, p2, p3) = instance.productions[1..3]
122
+ expect(instance.start.rhs).to eq([p3, p2, p3])
123
+ expect(p1.rhs).to eq(%w(letter_b letter_e))
124
+ expect(p2.rhs).to eq([p1, p1])
125
+ expect(p3.rhs).to eq(['letter_b', p2, 'letter_e'])
126
+ end
127
+
128
+ it 'should work with Symbol instead of single char input tokens' do
129
+ # Raw input is sequence of single characters
130
+ raw_input = 'bbebeebebebbebee'
131
+
132
+ # Convert them into symbols
133
+ input = raw_input.chars.map(&:to_sym)
134
+
135
+ # Creation
136
+ instance = SequiturGrammar.new(input.to_enum)
137
+
138
+ # Expectations:
139
+ # S: P3 P2 P3
140
+ # P1: b e
141
+ # P2: P1 P1
142
+ # P3: b P2 e
143
+ expect(instance.productions.size).to eq(4)
144
+ (p1, p2, p3) = instance.productions[1..3]
145
+ expect(instance.start.rhs).to eq([p3, p2, p3])
146
+ expect(p1.rhs).to eq([:b, :e])
147
+ expect(p2.rhs).to eq([p1, p1])
148
+ expect(p3.rhs).to eq([:b, p2, :e])
149
+ end
150
+
151
+
152
+ it 'should work with integer values as input tokens' do
153
+ # Raw input is sequence of hex digits
154
+ raw_input = 'bbebeebebebbebee'
155
+
156
+ # Convert them into Fixnums
157
+ input = raw_input.chars.map { |ch| ch.to_i(16) }
158
+
159
+ # Creation
160
+ instance = SequiturGrammar.new(input.to_enum)
161
+
162
+ # Expectations:
163
+ # S: P3 P2 P3
164
+ # P1: b e
165
+ # P2: P1 P1
166
+ # P3: b P2 e
167
+ expect(instance.productions.size).to eq(4)
168
+ (p1, p2, p3) = instance.productions[1..3]
169
+ expect(instance.start.rhs).to eq([p3, p2, p3])
170
+ expect(p1.rhs).to eq([0xb, 0xe])
171
+ expect(p2.rhs).to eq([p1, p1])
172
+ expect(p3.rhs).to eq([0xb, p2, 0xe])
173
+ end
174
+
175
+ it 'should cope with the example from sequitur.info website' do
176
+ input = 'abcabdabcabd'
177
+ instance = SequiturGrammar.new(input.chars)
178
+
179
+ # Expectations:
180
+ # 0 → 2 2
181
+ # 1 → a b
182
+ # 2 → 1 c 1 d
183
+
184
+ expect(instance.productions.size).to eq(3)
185
+ (p1, p2) = instance.productions[1..2]
186
+ expect(instance.start.rhs).to eq([p2, p2])
187
+ expect(p1.rhs).to eq(%w(a b))
188
+ expect(p2.rhs).to eq([p1, 'c', p1, 'd'])
189
+ end
190
+
191
+ it "should cope with the example from Salomon's book" do
192
+ input = 'abcdbcabcdbc'
193
+ instance = SequiturGrammar.new(input.chars)
194
+
195
+ # Expectations:
196
+ # S → CC
197
+ # A → bc
198
+ # C → aAdA
199
+
200
+ expect(instance.productions.size).to eq(3)
201
+ (p_a, p_c) = instance.productions[1..2]
202
+ expect(instance.start.rhs).to eq([p_c, p_c])
203
+ expect(p_a.rhs).to eq(%w(b c))
204
+ expect(p_c.rhs).to eq(['a', p_a, 'd', p_a])
205
+ end
206
+
207
+ it 'should cope with the "porridge" example from sequitur.info' do
208
+ # Another example from sequitur.info website
209
+ input = <<-SNIPPET
210
+ pease porridge hot,
211
+ pease porridge cold,
212
+ pease porridge in the pot,
213
+ nine days old.
214
+
215
+ some like it hot,
216
+ some like it cold,
217
+ some like it in the pot,
218
+ nine days old.
219
+ SNIPPET
220
+ # Expectations (sequitur.org)
221
+ # 0 → 1 2 3 4 3 5 ↵ 6 2 7 4 7 5
222
+ # 1 → p e a s 8 r r i d g 9 pease_porridge_
223
+ # 2 → h o t hot
224
+ # 3 → 10 1 ,↵pease_porridge_
225
+ # 4 → c 11 cold
226
+ # 5 → 12 _ t h 8 t 10 n 12 9 d a y s _ 11 . ↵
227
+ # in_the_pot,↵nine_days_old.↵
228
+ # 6 → s o m 9 l i k 9 i t _ some_like_it_
229
+ # 7 → 10 6 ,↵some_like_it_
230
+ # 8 → 9 p o e_po
231
+ # 9 → e _ e_
232
+ # 10 → , ↵ ,↵
233
+ # 11 → o l d old
234
+ # 12 → i n in
235
+
236
+ instance = SequiturGrammar.new(input.chars)
237
+ expect(instance.productions.size).to eq(13)
238
+ p0 = instance.start
239
+ expect(p0.rhs.size).to eq(13)
240
+
241
+ (p1, p2, p3, p4, p5, p6, p7, p8, p9) = instance.productions[1..9]
242
+ (p10, p11, p12) = instance.productions[10..12]
243
+
244
+ # Note: the productions aren't sorted the same way as
245
+ # the sequitur.info implementation.
246
+ p0_expectation = [
247
+ p2, p8, p3, p10, p3, p12, "\n",
248
+ p9, p8, p11, p10, p11, p12
249
+ ]
250
+ expect(p0.rhs).to eq(p0_expectation) # Rule 0 above
251
+ expect(p1.rhs).to eq(['e', ' ']) # Rule 9 above
252
+ expect(p2.rhs).to eq([%w(p e a s), p4, %w(r r i d g), p1].flatten) # R1
253
+ expect(p3.rhs).to eq([p5, p2]) # Rule 3 above
254
+ expect(p4.rhs).to eq([p1, 'p', 'o']) # Rule 8 above
255
+ expect(p5.rhs).to eq([',', "\n"]) # Rule 10 above
256
+ expect(p6.rhs).to eq(%w(i n)) # Rule 12 above
257
+ expect(p7.rhs).to eq(%w(o l d)) # Rule 11 above
258
+ expect(p8.rhs).to eq(%w(h o t)) # Rule 2 above
259
+ p9_expectation = [%w(s o m), p1, %w(l i k), p1, 'i', 't', ' '].flatten
260
+ expect(p9.rhs).to eq(p9_expectation) # Rule 6 above
261
+ expect(p10.rhs).to eq(['c', p7]) # Rule 4 above
262
+ expect(p11.rhs).to eq([p5, p9]) # Rule 7 above
263
+ p12_expectation = [
264
+ p6, ' ', 't', 'h', p4, 't', p5, 'n', p6, p1,
265
+ %w(d a y s), ' ', p7, '.', "\n"
266
+ ].flatten
267
+ expect(p12.rhs).to eq(p12_expectation) # Rule 5 above
268
+ end
269
+
270
+ it 'should work with a sequence of Ruby Symbols' do
271
+ input = 'abcabdabcabd'.chars.map(&:to_sym)
272
+ instance = SequiturGrammar.new(input.to_enum)
273
+
274
+ # Expectations:
275
+ # start : P2 P2.
276
+ # P1 : :a :b
277
+ # P2 : P1 :c P1 :d.
278
+
279
+ expect(instance.productions.size).to eq(3)
280
+ (p1, p2) = instance.productions[1..2]
281
+ expect(instance.start.rhs).to eq([p2, p2])
282
+ expect(p1.rhs).to eq([:a, :b])
283
+ expect(p2.rhs).to eq([p1, :c, p1, :d])
284
+ end
285
+ end # context
286
+
287
+ context 'Generating a text representation of itself:' do
288
+ it 'should generate a text representation when empty' do
289
+ instance = SequiturGrammar.new(empty_enum)
290
+ expectation = "#{instance.start.object_id} : ."
291
+
292
+ expect(instance.to_string).to eq(expectation)
293
+ end
294
+
295
+ it 'should generate a text representation of a simple production' do
296
+ instance = SequiturGrammar.new([:a].to_enum)
297
+ expectation = "#{instance.start.object_id} : a."
298
+ expect(instance.to_string).to eq(expectation)
299
+ end
300
+ end # context
301
+ end # describe
302
+ end # module
303
+
304
+ # End of file
metadata CHANGED
@@ -1,86 +1,104 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequitur
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.15
4
+ version: 0.1.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitri Geshef
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-16 00:00:00.000000000 Z
11
+ date: 2015-09-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ! '>='
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.8.0
19
+ version: 10.0.0
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 10.0.0
20
23
  type: :development
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - ! '>='
27
+ - - "~>"
25
28
  - !ruby/object:Gem::Version
26
- version: 0.8.0
29
+ version: 10.0.0
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 10.0.0
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: rspec
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
- - - ! '>='
37
+ - - "~>"
32
38
  - !ruby/object:Gem::Version
33
- version: 3.0.0
39
+ version: 2.1.0
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 2.1.0
34
43
  type: :development
35
44
  prerelease: false
36
45
  version_requirements: !ruby/object:Gem::Requirement
37
46
  requirements:
38
- - - ! '>='
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: 2.1.0
50
+ - - ">="
39
51
  - !ruby/object:Gem::Version
40
- version: 3.0.0
52
+ version: 2.1.0
41
53
  - !ruby/object:Gem::Dependency
42
54
  name: simplecov
43
55
  requirement: !ruby/object:Gem::Requirement
44
56
  requirements:
45
- - - ! '>='
57
+ - - ">="
46
58
  - !ruby/object:Gem::Version
47
- version: 0.5.0
59
+ version: 0.8.0
48
60
  type: :development
49
61
  prerelease: false
50
62
  version_requirements: !ruby/object:Gem::Requirement
51
63
  requirements:
52
- - - ! '>='
64
+ - - ">="
53
65
  - !ruby/object:Gem::Version
54
- version: 0.5.0
66
+ version: 0.8.0
55
67
  - !ruby/object:Gem::Dependency
56
68
  name: coveralls
57
69
  requirement: !ruby/object:Gem::Requirement
58
70
  requirements:
59
- - - ! '>='
71
+ - - ">="
60
72
  - !ruby/object:Gem::Version
61
73
  version: 0.7.0
62
74
  type: :development
63
75
  prerelease: false
64
76
  version_requirements: !ruby/object:Gem::Requirement
65
77
  requirements:
66
- - - ! '>='
78
+ - - ">="
67
79
  - !ruby/object:Gem::Version
68
80
  version: 0.7.0
69
81
  - !ruby/object:Gem::Dependency
70
82
  name: rubygems
71
83
  requirement: !ruby/object:Gem::Requirement
72
84
  requirements:
73
- - - ! '>='
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: '2.0'
88
+ - - ">="
74
89
  - !ruby/object:Gem::Version
75
90
  version: 2.0.0
76
91
  type: :development
77
92
  prerelease: false
78
93
  version_requirements: !ruby/object:Gem::Requirement
79
94
  requirements:
80
- - - ! '>='
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '2.0'
98
+ - - ">="
81
99
  - !ruby/object:Gem::Version
82
100
  version: 2.0.0
83
- description: ! "Ruby implementation of the Sequitur algorithm. This algorithm automatically
101
+ description: "Ruby implementation of the Sequitur algorithm. This algorithm automatically
84
102
  \nfinds repetitions and hierarchical structures in a given sequence of input \ntokens.
85
103
  It encodes the input into a context-free grammar. \nThe Sequitur algorithm can be
86
104
  used to \na) compress a sequence of items,\nb) discover patterns in an sequence,
@@ -91,18 +109,23 @@ extensions: []
91
109
  extra_rdoc_files:
92
110
  - README.md
93
111
  files:
94
- - .rubocop.yml
95
- - .rspec
96
- - .ruby-gemset
97
- - .ruby-version
98
- - .simplecov
99
- - .travis.yml
100
- - .yardopts
101
- - Gemfile
102
- - Rakefile
112
+ - ".rspec"
113
+ - ".rubocop.yml"
114
+ - ".ruby-gemset"
115
+ - ".ruby-version"
116
+ - ".simplecov"
117
+ - ".travis.yml"
118
+ - ".yardopts"
103
119
  - CHANGELOG.md
120
+ - Gemfile
104
121
  - LICENSE.txt
105
122
  - README.md
123
+ - Rakefile
124
+ - examples/integer_sample.rb
125
+ - examples/porridge.rb
126
+ - examples/simple_case.rb
127
+ - examples/symbol_sample.rb
128
+ - examples/word_sample.rb
106
129
  - lib/sequitur.rb
107
130
  - lib/sequitur/constants.rb
108
131
  - lib/sequitur/digram.rb
@@ -125,39 +148,31 @@ files:
125
148
  - spec/sequitur/sequitur_grammar_spec.rb
126
149
  - spec/sequitur/symbol_sequence_spec.rb
127
150
  - spec/spec_helper.rb
128
- - examples/integer_sample.rb
129
- - examples/porridge.rb
130
- - examples/simple_case.rb
131
- - examples/symbol_sample.rb
132
- - examples/word_sample.rb
133
151
  homepage: https://github.com/famished-tiger/Sequitur
134
152
  licenses:
135
153
  - MIT
136
154
  metadata: {}
137
- post_install_message: ! '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
138
-
155
+ post_install_message: |
156
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
139
157
  Thank you for installing Sequitur...
140
-
141
158
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
142
-
143
- '
144
159
  rdoc_options:
145
160
  - --charset=UTF-8 --exclude="examples|features|spec"
146
161
  require_paths:
147
162
  - lib
148
163
  required_ruby_version: !ruby/object:Gem::Requirement
149
164
  requirements:
150
- - - ! '>='
165
+ - - ">="
151
166
  - !ruby/object:Gem::Version
152
167
  version: 1.9.1
153
168
  required_rubygems_version: !ruby/object:Gem::Requirement
154
169
  requirements:
155
- - - ! '>='
170
+ - - ">="
156
171
  - !ruby/object:Gem::Version
157
172
  version: '0'
158
173
  requirements: []
159
174
  rubyforge_project:
160
- rubygems_version: 2.0.3
175
+ rubygems_version: 2.4.5.1
161
176
  signing_key:
162
177
  specification_version: 4
163
178
  summary: Ruby implementation of the Sequitur algorithm