asmodis-rlsm 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/LICENCE +674 -0
- data/README +35 -0
- data/lib/dfa.rb +686 -0
- data/lib/mgen.rb +130 -0
- data/lib/monkey_patching.rb +109 -0
- data/lib/monoid.rb +533 -0
- data/lib/rlsm.rb +22 -0
- data/lib/rlsm_regexp.rb +584 -0
- data/spec/dfa_spec.rb +99 -0
- data/spec/monoid_spec.rb +270 -0
- data/spec/regexp_spec.rb +25 -0
- metadata +64 -0
data/spec/dfa_spec.rb
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'dfa')
|
2
|
+
|
3
|
+
describe RLSM::DFA do
|
4
|
+
before :each do
|
5
|
+
@dfa = RLSM::DFA.new ['a'],[0],0,[0],[['a',0,0]]
|
6
|
+
@dfa2 = RLSM::DFA.new( ['a', 'b'], [0,1,2], 0, [2],
|
7
|
+
[['a',0,0], ['a',1,2], ['a',2,2],
|
8
|
+
['b',0,1], ['b',1,1], ['b',2,2]])
|
9
|
+
@dfa3 = RLSM::DFA.new( ['a', 'b'], [0,1,2], 0, [2],
|
10
|
+
[['a',0,0], ['a',1,2], ['a',2,2],
|
11
|
+
['b',0,1], ['b',1,1]])
|
12
|
+
|
13
|
+
@dfa4 = RLSM::DFA.new( ['a', 'b'], [0,1,2,3,4], 0, [2,3],
|
14
|
+
[['a',0,0], ['a',1,2], ['a',2,2],
|
15
|
+
['b',0,1], ['b',1,1],
|
16
|
+
['a',3,4], ['a',4,3], ['b',3,2]])
|
17
|
+
|
18
|
+
@dfa5 = RLSM::DFA.new( ['a', 'b'], [0,1,2], 0, [1],
|
19
|
+
[['a',0,0], ['a',1,2], ['a',2,2],
|
20
|
+
['b',0,1], ['b',1,1]])
|
21
|
+
|
22
|
+
@dfa5b = RLSM::DFA.new( ['a', 'b'], [0,1,'c'], 0, [1],
|
23
|
+
[['a',0,0], ['a',1,'c'], ['a','c','c'],
|
24
|
+
['b',0,1], ['b',1,1]])
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should have an initial state" do
|
28
|
+
@dfa.initial_state.should_not be_nil
|
29
|
+
@dfa.initial_state.label.should == '0'
|
30
|
+
@dfa2.initial_state.should_not be_nil
|
31
|
+
@dfa2.initial_state.label.should == '0'
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should know the number of states" do
|
35
|
+
@dfa.num_states.should == 1
|
36
|
+
@dfa2.num_states.should == 3
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should know the number of final states" do
|
40
|
+
@dfa.num_finals.should == 1
|
41
|
+
@dfa2.num_finals.should == 1
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should know if it is complete" do
|
45
|
+
@dfa.complete?.should == true
|
46
|
+
@dfa2.complete?.should == true
|
47
|
+
@dfa3.complete?.should == false
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should complete a non complete DFA if requested" do
|
51
|
+
@dfa3.complete.should be_complete
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should find dead states" do
|
55
|
+
[@dfa,@dfa2,@dfa3].each { |d| d.dead_states?.should == false }
|
56
|
+
|
57
|
+
@dfa5.dead_states?.should == true
|
58
|
+
@dfa5.dead_states.map { |s| s.label }.should == ['2']
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should find unreachable states" do
|
62
|
+
[@dfa,@dfa2,@dfa3].each { |d| d.unreachable_states?.should == false }
|
63
|
+
|
64
|
+
@dfa4.unreachable_states?.should == true
|
65
|
+
@dfa4.unreachable_states.size.should == 2
|
66
|
+
@dfa4.unreachable_states.map { |s| s.label }.sort.should == ['3','4']
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should remove dead states" do
|
70
|
+
@dfa5.remove_dead_states.states.map { |s| s.label }.should == ['0','1']
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should remove unreachable states" do
|
74
|
+
d = @dfa4.remove_unreachable_states
|
75
|
+
d.states.map { |s| s.label }.sort.should == ['0','1','2']
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should minimize a DFA" do
|
79
|
+
d = RLSM::DFA.new(['a','b','c'], [0,1,2,3,4], 0, [4],
|
80
|
+
[['a',0,1], ['b',0,2], ['c',1,3], ['c',2,3], ['c',3,4]])
|
81
|
+
|
82
|
+
d.minimize!
|
83
|
+
d.states.map { |s| s.label }.sort.should == ['0','12', '3','4']
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should check for isomorphisms" do
|
87
|
+
@dfa2.should be_isomorph_to(@dfa2)
|
88
|
+
@dfa5.should be_isomorph_to(@dfa5b)
|
89
|
+
@dfa3.should_not be_isomorph_to(@dfa2)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should calculate the transition monoid" do
|
93
|
+
@dfa.transition_monoid.should == RLSM::Monoid.new('0')
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should caclulate a RegExp representation" do
|
97
|
+
@dfa.to_regexp.to_s.should == 'a*'
|
98
|
+
end
|
99
|
+
end
|
data/spec/monoid_spec.rb
ADDED
@@ -0,0 +1,270 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'monoid')
|
2
|
+
|
3
|
+
describe RLSM::Monoid, "basic stuff" do
|
4
|
+
before :each do
|
5
|
+
@m1 = RLSM::Monoid.new '0'
|
6
|
+
@m2 = RLSM::Monoid.new '00 01' #-> 01 11
|
7
|
+
@m3 = RLSM::Monoid.new '012 112 212'
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should have '0' as the neutral element" do
|
11
|
+
@m1[0,0].should == 0
|
12
|
+
|
13
|
+
[0,1].each { |x| @m2[0,x].should == x; @m2[x,0].should == x }
|
14
|
+
[0,1,2].each { |x| @m3[0,x].should == x; @m3[x,0].should == x }
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should decide if an other monoid is isomorphic" do
|
18
|
+
@m2.should == RLSM::Monoid.new('01 11')
|
19
|
+
@m3.should == RLSM::Monoid.new('002 012 022')
|
20
|
+
|
21
|
+
@m2.should_not == @m3
|
22
|
+
|
23
|
+
@m2.should_not == RLSM::Monoid.new('01 10')
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
describe RLSM::Monoid do
|
29
|
+
before :each do
|
30
|
+
@m0 = RLSM::Monoid.new '0'
|
31
|
+
@m1 = RLSM::Monoid.new '01 11'
|
32
|
+
@m2 = RLSM::Monoid.new '0123 1032 2323 3232'
|
33
|
+
end
|
34
|
+
|
35
|
+
[[],[0],[1], [2], [1,2], [1,3], [2,3], [1,2,3]].each do |set|
|
36
|
+
@m0 = RLSM::Monoid.new '0'
|
37
|
+
@m1 = RLSM::Monoid.new '01 11'
|
38
|
+
@m2 = RLSM::Monoid.new '0123 1032 2323 3232'
|
39
|
+
|
40
|
+
case set
|
41
|
+
when [], [0]
|
42
|
+
[@m0, @m1, @m2].each do |m|
|
43
|
+
it "should calculate the submonoid of #{m} generated by #{set}" do
|
44
|
+
sm = m.get_submonoid(set)
|
45
|
+
sm.should_not be_nil
|
46
|
+
sm.should == RLSM::Monoid.new('0')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
when [1]
|
50
|
+
it "should calculate the submonoid of #{@m1} generated by #{set}" do
|
51
|
+
@m1.get_submonoid(set).should == @m1
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should calculate the submonoid of #{@m2} generated by #{set}" do
|
55
|
+
@m2.get_submonoid(set).should == RLSM::Monoid.new('01 10')
|
56
|
+
end
|
57
|
+
when [2]
|
58
|
+
it "should calculate the submonoid of #{@m2} generated by #{set}" do
|
59
|
+
@m2.get_submonoid(set).should == @m1
|
60
|
+
end
|
61
|
+
when [1,2]
|
62
|
+
it "should calculate the submonoid of #{@m2} generated by #{set}" do
|
63
|
+
@m2.get_submonoid(set).should == @m2
|
64
|
+
end
|
65
|
+
when [1,3]
|
66
|
+
it "should calculate the submonoid of #{@m2} generated by #{set}" do
|
67
|
+
@m2.get_submonoid(set).should == @m2
|
68
|
+
end
|
69
|
+
when [2,3]
|
70
|
+
it "should calculate the submonoid of #{@m2} generated by #{set}" do
|
71
|
+
@m2.get_submonoid(set).should == RLSM::Monoid.new('012 112 221')
|
72
|
+
end
|
73
|
+
when [1,2,3]
|
74
|
+
it "should calculate the submonoid of #{@m2} generated by #{set}" do
|
75
|
+
@m2.get_submonoid(set).should == @m2
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should calculate the generator subset of #{RLSM::Monoid.new('0')}" do
|
81
|
+
RLSM::Monoid.new('0').generating_subset.should == []
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should calculate the generator subset of #{RLSM::Monoid.new('01 11')}" do
|
85
|
+
RLSM::Monoid.new('01 11').generating_subset.should == [1]
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should calculate the generator subset of #{RLSM::Monoid.new('0123 1032 2323 3232')}" do
|
89
|
+
RLSM::Monoid.new('0123 1032 2323 3232').generating_subset.should == [1,2]
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
describe RLSM::Monoid do
|
95
|
+
before :each do
|
96
|
+
@m1 = RLSM::Monoid.new '012345 113315 245255 315355 442245 555555'
|
97
|
+
@m2 = RLSM::Monoid.new '012345 103254 235454 324545 455454 544545'
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should calculate left ideals of elements" do
|
101
|
+
@m1.left_ideal_of(0).should == [0,1,2,3,4,5]
|
102
|
+
@m1.left_ideal_of(1).should == [1,4,5]
|
103
|
+
@m1.left_ideal_of(2).should == [2,3,5]
|
104
|
+
@m1.left_ideal_of(3).should == [2,3,5]
|
105
|
+
@m1.left_ideal_of(4).should == [1,4,5]
|
106
|
+
@m1.left_ideal_of(5).should == [5]
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should calculate right ideals of elements" do
|
110
|
+
@m1.right_ideal_of(0).should == [0,1,2,3,4,5]
|
111
|
+
@m1.right_ideal_of(1).should == [1,3,5]
|
112
|
+
@m1.right_ideal_of(2).should == [2,4,5]
|
113
|
+
@m1.right_ideal_of(3).should == [1,3,5]
|
114
|
+
@m1.right_ideal_of(4).should == [2,4,5]
|
115
|
+
@m1.right_ideal_of(5).should == [5]
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should calculate ideals of elements" do
|
119
|
+
@m1.ideal_of(0).should == [0,1,2,3,4,5]
|
120
|
+
@m1.ideal_of(1).should == [1,2,3,4,5]
|
121
|
+
@m1.ideal_of(2).should == [1,2,3,4,5]
|
122
|
+
@m1.ideal_of(3).should == [1,2,3,4,5]
|
123
|
+
@m1.ideal_of(4).should == [1,2,3,4,5]
|
124
|
+
@m1.ideal_of(5).should == [5]
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should calculate L-classes of elements" do
|
128
|
+
@m1.l_class_of(0).should == [0]
|
129
|
+
@m1.l_class_of(1).should == [1,4]
|
130
|
+
@m1.l_class_of(2).should == [2,3]
|
131
|
+
@m1.l_class_of(3).should == [2,3]
|
132
|
+
@m1.l_class_of(4).should == [1,4]
|
133
|
+
@m1.l_class_of(5).should == [5]
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should calculate R-classes of elements" do
|
137
|
+
@m1.r_class_of(0).should == [0]
|
138
|
+
@m1.r_class_of(1).should == [1,3]
|
139
|
+
@m1.r_class_of(2).should == [2,4]
|
140
|
+
@m1.r_class_of(3).should == [1,3]
|
141
|
+
@m1.r_class_of(4).should == [2,4]
|
142
|
+
@m1.r_class_of(5).should == [5]
|
143
|
+
end
|
144
|
+
|
145
|
+
# it "should calculate J-classes of elements" do
|
146
|
+
# @m1.j_class_of(0).should == [0]
|
147
|
+
# @m1.j_class_of(1).should == [1,2,3,4]
|
148
|
+
# @m1.j_class_of(2).should == [1,2,3,4]
|
149
|
+
# @m1.j_class_of(3).should == [1,2,3,4]
|
150
|
+
# @m1.j_class_of(4).should == [1,2,3,4]
|
151
|
+
# @m1.j_class_of(5).should == [5]
|
152
|
+
# end
|
153
|
+
|
154
|
+
it "should calculate H-classes of elements" do
|
155
|
+
@m1.h_class_of(0).should == [0]
|
156
|
+
@m1.h_class_of(1).should == [1]
|
157
|
+
@m1.h_class_of(2).should == [2]
|
158
|
+
@m1.h_class_of(3).should == [3]
|
159
|
+
@m1.h_class_of(4).should == [4]
|
160
|
+
@m1.h_class_of(5).should == [5]
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should calculate D-classes of elements" do
|
164
|
+
@m1.d_class_of(0).should == [0]
|
165
|
+
@m1.d_class_of(1).should == [1,2,3,4]
|
166
|
+
@m1.d_class_of(2).should == [1,2,3,4]
|
167
|
+
@m1.d_class_of(3).should == [1,2,3,4]
|
168
|
+
@m1.d_class_of(4).should == [1,2,3,4]
|
169
|
+
@m1.d_class_of(5).should == [5]
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should detect aperiodicity" do
|
173
|
+
@m1.aperiodic?.should == true
|
174
|
+
@m2.aperiodic?.should == false
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe RLSM::Monoid do
|
179
|
+
before :each do
|
180
|
+
@m1 = RLSM::Monoid.new '0'
|
181
|
+
@m2 = RLSM::Monoid.new '01 10'
|
182
|
+
@m3 = RLSM::Monoid.new '01 11'
|
183
|
+
@m4 = RLSM::Monoid.new '012 102 222'
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should detect a null element" do
|
187
|
+
@m1.null_element.should == false
|
188
|
+
@m2.null_element.should == false
|
189
|
+
@m3.null_element.should == 1
|
190
|
+
@m4.null_element.should == 2
|
191
|
+
end
|
192
|
+
|
193
|
+
it "should detect idempotent elements" do
|
194
|
+
[@m1, @m2, @m3].each { |m| m.idempotent?(0).should == true }
|
195
|
+
@m2.idempotent?(1).should == false
|
196
|
+
@m3.idempotent?(1).should == true
|
197
|
+
@m4.idempotent?(2).should == true
|
198
|
+
@m4.idempotent?(1).should == false
|
199
|
+
end
|
200
|
+
|
201
|
+
it "should find all idempotents" do
|
202
|
+
@m1.idempotents.should == [0]
|
203
|
+
@m2.idempotents.should == [0]
|
204
|
+
@m3.idempotents.should == [0,1]
|
205
|
+
@m4.idempotents.should == [0,2]
|
206
|
+
end
|
207
|
+
|
208
|
+
it "should decide if all elements are idempotent" do
|
209
|
+
@m1.idempotent?.should == true
|
210
|
+
@m2.idempotent?.should == false
|
211
|
+
@m3.idempotent?.should == true
|
212
|
+
@m4.idempotent?.should == false
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
describe RLSM::Monoid do
|
217
|
+
before :each do
|
218
|
+
@m1 = RLSM::Monoid.new('0123 1032 2323 3232')
|
219
|
+
end
|
220
|
+
|
221
|
+
it "should calculate all submonoids of a given order upto to isomorphie" do
|
222
|
+
@m1.submonoids_of_order(1).should == [RLSM::Monoid.new('0')]
|
223
|
+
@m1.submonoids_of_order(2).should == [RLSM::Monoid.new('01 10'), RLSM::Monoid.new('01 11')]
|
224
|
+
@m1.submonoids_of_order(3).should == [RLSM::Monoid.new('012 112 221')]
|
225
|
+
@m1.submonoids_of_order(4).should == [@m1]
|
226
|
+
end
|
227
|
+
|
228
|
+
it "should calculate all submonoids upto to isomorphie" do
|
229
|
+
@m1.submonoids.should == [RLSM::Monoid.new('0'), RLSM::Monoid.new('01 10'), RLSM::Monoid.new('01 11'),RLSM::Monoid.new('012 112 221'), @m1]
|
230
|
+
|
231
|
+
RLSM::Monoid.new('0').submonoids.should == [RLSM::Monoid.new('0')]
|
232
|
+
end
|
233
|
+
|
234
|
+
it "should calculate all proper submonoids upto to isomorphie" do
|
235
|
+
@m1.proper_submonoids.should == [RLSM::Monoid.new('01 10'), RLSM::Monoid.new('01 11'),RLSM::Monoid.new('012 112 221')]
|
236
|
+
|
237
|
+
RLSM::Monoid.new('0').proper_submonoids.should == []
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
describe RLSM::Monoid do
|
242
|
+
['0', '01 11', '012 112 212', '01234 11111 21212 31133 41234'].each do |tab|
|
243
|
+
it "should detect syntacticity of #{tab}" do
|
244
|
+
RLSM::Monoid.new(tab).syntactic?.should == true
|
245
|
+
end
|
246
|
+
|
247
|
+
it "should find a disjunctive subset of #{tab}" do
|
248
|
+
case tab
|
249
|
+
when '0'
|
250
|
+
RLSM::Monoid.new(tab).disjunctive_subset.should == []
|
251
|
+
when '01 11'
|
252
|
+
RLSM::Monoid.new(tab).disjunctive_subset.should == [0]
|
253
|
+
when '012 112 212'
|
254
|
+
RLSM::Monoid.new(tab).disjunctive_subset.should == [1]
|
255
|
+
when '01234 11111 21212 31133 41234'
|
256
|
+
RLSM::Monoid.new(tab).disjunctive_subset.should == [0,4]
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
['0123 1111 2222 3333', '01234 10234 22222 33222 44222'].each do |tab|
|
262
|
+
it "should detect nonsyntacticity of #{tab}" do
|
263
|
+
RLSM::Monoid.new(tab).syntactic?.should == false
|
264
|
+
end
|
265
|
+
|
266
|
+
it "should not find a disjunctive subset of #{tab}" do
|
267
|
+
RLSM::Monoid.new(tab).disjunctive_subset.should be_nil
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
data/spec/regexp_spec.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'dfa')
|
2
|
+
|
3
|
+
describe RLSM::RegExp do
|
4
|
+
['(ab', '(|ab)', '(ab|)', 'ab(*)', '(*a|b)', 'ab()cd'].each do |str|
|
5
|
+
it "should raise error for input #{str}" do
|
6
|
+
lambda { RLSM::RegExp.new str }.should raise_error(Exception)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
['', '&', 'a', 'a|b', 'ab', '(a|b)c', '(a*|bc&&&d)|abc|(a|b|c)*'].each do |s|
|
11
|
+
it "should accept the input #{s}" do
|
12
|
+
lambda { RLSM::RegExp.new s }.should_not raise_error(Exception)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should simplify a input" do
|
17
|
+
RLSM::RegExp.new('a&&**&&c***(bbbcccaa)**').to_s.should == 'ac*(bbbcccaa)*'
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should convert a regexp to an dfa" do
|
21
|
+
dfa1 = RLSM::RegExp.new('(a|b)aa*(&|b)a*').to_dfa
|
22
|
+
dfa1.states.size.should == 4
|
23
|
+
dfa1.final_states.map {|f| f.label}.sort.should == ['1', '2'].sort
|
24
|
+
end
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: asmodis-rlsm
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- asmodis
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-10-19 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: RLSM contains the three classes DFA, Monoid and REgExp for work with regular languages.
|
17
|
+
email: g.diemant@gmx.net
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README
|
24
|
+
- LICENCE
|
25
|
+
files:
|
26
|
+
- LICENCE
|
27
|
+
- README
|
28
|
+
- lib/monkey_patching.rb
|
29
|
+
- lib/monoid.rb
|
30
|
+
- lib/mgen.rb
|
31
|
+
- lib/rlsm_regexp.rb
|
32
|
+
- lib/dfa.rb
|
33
|
+
- lib/rlsm.rb
|
34
|
+
has_rdoc: true
|
35
|
+
homepage: http://github.org/asmodis/rlsm
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options:
|
38
|
+
- --main
|
39
|
+
- README
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
version:
|
48
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: "0"
|
53
|
+
version:
|
54
|
+
requirements: []
|
55
|
+
|
56
|
+
rubyforge_project:
|
57
|
+
rubygems_version: 1.2.0
|
58
|
+
signing_key:
|
59
|
+
specification_version: 2
|
60
|
+
summary: Classes for work with formal languages
|
61
|
+
test_files:
|
62
|
+
- spec/monoid_spec.rb
|
63
|
+
- spec/dfa_spec.rb
|
64
|
+
- spec/regexp_spec.rb
|