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/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
@@ -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
@@ -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