sequitur 0.1.15 → 0.1.16

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.
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