stamina 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. data/CHANGELOG.md +22 -5
  2. data/LICENCE.md +2 -2
  3. data/bin/stamina +1 -7
  4. data/lib/stamina.rb +10 -19
  5. metadata +54 -333
  6. data/.gemtest +0 -0
  7. data/Gemfile +0 -2
  8. data/Gemfile.lock +0 -37
  9. data/Manifest.txt +0 -16
  10. data/README.md +0 -78
  11. data/Rakefile +0 -23
  12. data/example/adl/automaton.adl +0 -49
  13. data/example/adl/sample.adl +0 -53
  14. data/example/basic/characteristic_sample.adl +0 -32
  15. data/example/basic/target.adl +0 -9
  16. data/example/competition/31_test.adl +0 -1500
  17. data/example/competition/31_training.adl +0 -1759
  18. data/lib/stamina/abbadingo.rb +0 -2
  19. data/lib/stamina/abbadingo/random_dfa.rb +0 -48
  20. data/lib/stamina/abbadingo/random_sample.rb +0 -146
  21. data/lib/stamina/adl.rb +0 -298
  22. data/lib/stamina/automaton.rb +0 -1263
  23. data/lib/stamina/automaton/complete.rb +0 -36
  24. data/lib/stamina/automaton/equivalence.rb +0 -55
  25. data/lib/stamina/automaton/metrics.rb +0 -78
  26. data/lib/stamina/automaton/minimize.rb +0 -25
  27. data/lib/stamina/automaton/minimize/hopcroft.rb +0 -116
  28. data/lib/stamina/automaton/minimize/pitchies.rb +0 -64
  29. data/lib/stamina/automaton/strip.rb +0 -16
  30. data/lib/stamina/automaton/walking.rb +0 -363
  31. data/lib/stamina/classifier.rb +0 -52
  32. data/lib/stamina/command.rb +0 -45
  33. data/lib/stamina/command/abbadingo_dfa.rb +0 -81
  34. data/lib/stamina/command/abbadingo_samples.rb +0 -40
  35. data/lib/stamina/command/adl2dot.rb +0 -71
  36. data/lib/stamina/command/classify.rb +0 -48
  37. data/lib/stamina/command/help.rb +0 -27
  38. data/lib/stamina/command/infer.rb +0 -141
  39. data/lib/stamina/command/metrics.rb +0 -51
  40. data/lib/stamina/command/robustness.rb +0 -22
  41. data/lib/stamina/command/score.rb +0 -35
  42. data/lib/stamina/errors.rb +0 -23
  43. data/lib/stamina/ext/math.rb +0 -20
  44. data/lib/stamina/induction/blue_fringe.rb +0 -265
  45. data/lib/stamina/induction/commons.rb +0 -156
  46. data/lib/stamina/induction/rpni.rb +0 -186
  47. data/lib/stamina/induction/union_find.rb +0 -377
  48. data/lib/stamina/input_string.rb +0 -123
  49. data/lib/stamina/loader.rb +0 -1
  50. data/lib/stamina/markable.rb +0 -42
  51. data/lib/stamina/sample.rb +0 -267
  52. data/lib/stamina/scoring.rb +0 -213
  53. data/lib/stamina/utils.rb +0 -1
  54. data/lib/stamina/utils/decorate.rb +0 -81
  55. data/lib/stamina/version.rb +0 -14
  56. data/stamina.gemspec +0 -191
  57. data/stamina.noespec +0 -32
  58. data/tasks/debug_mail.rake +0 -78
  59. data/tasks/debug_mail.txt +0 -13
  60. data/tasks/gem.rake +0 -68
  61. data/tasks/spec_test.rake +0 -79
  62. data/tasks/unit_test.rake +0 -77
  63. data/tasks/yard.rake +0 -51
  64. data/test/stamina/abbadingo/random_dfa_test.rb +0 -16
  65. data/test/stamina/abbadingo/random_sample_test.rb +0 -78
  66. data/test/stamina/adl_test.rb +0 -516
  67. data/test/stamina/automaton/classifier_test.rb +0 -259
  68. data/test/stamina/automaton/complete_test.rb +0 -58
  69. data/test/stamina/automaton/equivalence_test.rb +0 -120
  70. data/test/stamina/automaton/metrics_test.rb +0 -36
  71. data/test/stamina/automaton/minimize/hopcroft_test.rb +0 -15
  72. data/test/stamina/automaton/minimize/minimize_test.rb +0 -55
  73. data/test/stamina/automaton/minimize/pitchies_test.rb +0 -15
  74. data/test/stamina/automaton/minimize/rice_edu_10.adl +0 -16
  75. data/test/stamina/automaton/minimize/rice_edu_10.min.adl +0 -13
  76. data/test/stamina/automaton/minimize/rice_edu_13.adl +0 -13
  77. data/test/stamina/automaton/minimize/rice_edu_13.min.adl +0 -7
  78. data/test/stamina/automaton/minimize/should_strip_1.adl +0 -8
  79. data/test/stamina/automaton/minimize/should_strip_1.min.adl +0 -6
  80. data/test/stamina/automaton/minimize/unknown_1.adl +0 -16
  81. data/test/stamina/automaton/minimize/unknown_1.min.adl +0 -12
  82. data/test/stamina/automaton/strip_test.rb +0 -36
  83. data/test/stamina/automaton/to_dot_test.rb +0 -64
  84. data/test/stamina/automaton/walking/dfa_delta_test.rb +0 -39
  85. data/test/stamina/automaton/walking_test.rb +0 -206
  86. data/test/stamina/automaton_additional_test.rb +0 -190
  87. data/test/stamina/automaton_test.rb +0 -1104
  88. data/test/stamina/exit.rb +0 -3
  89. data/test/stamina/induction/blue_fringe_test.rb +0 -83
  90. data/test/stamina/induction/induction_test.rb +0 -70
  91. data/test/stamina/induction/redblue_mergesamestatebug_expected.adl +0 -19
  92. data/test/stamina/induction/redblue_mergesamestatebug_pta.dot +0 -64
  93. data/test/stamina/induction/redblue_mergesamestatebug_sample.adl +0 -9
  94. data/test/stamina/induction/redblue_universal_expected.adl +0 -4
  95. data/test/stamina/induction/redblue_universal_sample.adl +0 -5
  96. data/test/stamina/induction/rpni_inria_expected.adl +0 -7
  97. data/test/stamina/induction/rpni_inria_sample.adl +0 -9
  98. data/test/stamina/induction/rpni_test.rb +0 -129
  99. data/test/stamina/induction/rpni_test_pta.dot +0 -22
  100. data/test/stamina/induction/rpni_universal_expected.adl +0 -4
  101. data/test/stamina/induction/rpni_universal_sample.adl +0 -4
  102. data/test/stamina/induction/union_find_test.rb +0 -124
  103. data/test/stamina/input_string_test.rb +0 -323
  104. data/test/stamina/markable_test.rb +0 -70
  105. data/test/stamina/randdfa.adl +0 -66
  106. data/test/stamina/sample.adl +0 -4
  107. data/test/stamina/sample_classify_test.rb +0 -149
  108. data/test/stamina/sample_test.rb +0 -290
  109. data/test/stamina/scoring_test.rb +0 -63
  110. data/test/stamina/small_dfa.dot +0 -16
  111. data/test/stamina/small_dfa.gif +0 -0
  112. data/test/stamina/small_nfa.dot +0 -18
  113. data/test/stamina/small_nfa.gif +0 -0
  114. data/test/stamina/stamina_test.rb +0 -80
  115. data/test/stamina/utils/decorate_test.rb +0 -65
  116. data/test/test_all.rb +0 -7
@@ -1,190 +0,0 @@
1
- require 'stamina'
2
- require 'test/unit'
3
-
4
- module Stamina
5
- class AutomataOperationsTest < Test::Unit::TestCase
6
-
7
- def setup
8
- @dfa = ADL::parse_automaton <<-AUTOMATON
9
- 3 4
10
- A true false
11
- B false false
12
- C false true
13
- A B a
14
- B C b
15
- C C a
16
- C B b
17
- AUTOMATON
18
-
19
- @another = ADL::parse_automaton <<-AUTOMATON
20
- 3 3
21
- A true true
22
- B false false
23
- C false true
24
- A B a
25
- B C a
26
- C C a
27
- AUTOMATON
28
-
29
- @small = ADL::parse_automaton <<-AUTOMATON
30
- 1 1
31
- S true true
32
- S S a
33
- AUTOMATON
34
- end
35
-
36
- # With names of new states thrown away
37
- def test_add_states1a
38
- assert_equal(false, @dfa.accepts?('?'))
39
- small_init = @dfa.add_automaton(@small)
40
- @dfa.connect(@dfa.initial_state,small_init,'c')
41
-
42
- assert_equal(4, @dfa.state_count)
43
- assert_equal(6, @dfa.edge_count)
44
-
45
- check_dfa_unchanged(@dfa)
46
- assert_equal(true, @dfa.accepts?('? c'))
47
- assert_equal(true, @dfa.accepts?('? c a a a'))
48
- assert_equal(false, @dfa.accepts?('? c a a b a'))
49
-
50
- assert_raise ArgumentError do
51
- @dfa.get_state('S') # non-existing state
52
- end
53
-
54
- end
55
-
56
- # Checks that the supplied automaton matches @dfa
57
- def check_dfa_unchanged(automaton)
58
- assert_equal(false, automaton.accepts?('?'))
59
- assert_equal(false, automaton.accepts?('? a'))
60
- assert_equal(false, automaton.accepts?('? a c'))
61
- assert_equal(true, automaton.accepts?('? a b'))
62
- assert_equal(true, automaton.accepts?('? a b a'))
63
- assert_equal(false, automaton.accepts?('? a b a b'))
64
- assert_equal(true, automaton.accepts?('? a b a b b'))
65
- end
66
-
67
- def test_add_states1b
68
- another_init = @dfa.add_automaton(@another)
69
-
70
- @dfa.connect(@dfa.initial_state,another_init,'c')
71
-
72
- assert_equal(6, @dfa.state_count)
73
- assert_equal(8, @dfa.edge_count)
74
-
75
- check_dfa_unchanged(@dfa)
76
- assert_equal(true, @dfa.accepts?('? c'))
77
- assert_equal(false, @dfa.accepts?('? c a'))
78
- assert_equal(true, @dfa.accepts?('? c a a a'))
79
- assert_equal(false, @dfa.accepts?('? c a a b a'))
80
- end
81
-
82
- # Without throwing away names of new states
83
- def test_add_states2
84
- small_init = @dfa.add_automaton(@small,false)
85
- @dfa.connect(@dfa.initial_state,small_init,'c')
86
-
87
- assert_equal(4, @dfa.state_count)
88
- assert_equal(6, @dfa.edge_count)
89
-
90
- @dfa.get_state('S') # this one should exist
91
- end
92
-
93
- # Testing with an empty automaton
94
-
95
- def create_empty_automaton
96
- empty = ADL::parse_automaton <<-AUTOMATON
97
- 1 0
98
- B true true
99
- AUTOMATON
100
- empty.drop_state(empty.get_state("B"))
101
- empty
102
- end
103
-
104
- def test_add_states4a
105
- empty = create_empty_automaton
106
- empty.add_automaton(empty,false)
107
-
108
- assert_equal(0, empty.state_count)
109
- assert_equal(0, empty.edge_count)
110
- end
111
-
112
- def test_add_states4b
113
- empty = create_empty_automaton
114
- empty.add_automaton(empty,true)
115
-
116
- assert_equal(0, empty.state_count)
117
- assert_equal(0, empty.edge_count)
118
- end
119
-
120
- def test_add_states5
121
- @dfa.add_automaton(create_empty_automaton,false)
122
- assert_equal(3, @dfa.state_count);assert_equal(4, @dfa.edge_count);check_dfa_unchanged(@dfa)
123
- end
124
-
125
- def test_add_states6
126
- empty = create_empty_automaton
127
- initial=empty.add_automaton(@dfa, true)
128
- initial.initial!
129
- assert_equal(3, empty.state_count);assert_equal(4, empty.edge_count);check_dfa_unchanged(empty)
130
- end
131
-
132
- def test_dup_1
133
- empty = create_empty_automaton
134
- anotherEmpty = empty.dup
135
-
136
- anotherEmpty.add_state(:accepting => true)
137
- end
138
-
139
- # Tests that adding states/transitions actually copies them
140
- def test_add_states_really_copies
141
- outAOrig_edge1 = @dfa.initial_state.out_edges.select { |e| e.symbol == 'a'}[0]
142
- outAOrig_edge2 = outAOrig_edge1.to.out_edges.select { |e| e.symbol == 'a'}[0]
143
- outAN_edge1 = @another.initial_state.out_edges.select { |e| e.symbol == 'a'}[0]
144
- outAN_edge2 = outAN_edge1.to.out_edges.select { |e| e.symbol == 'a'}[0]
145
-
146
- stateAO_O = @dfa.initial_state
147
- stateAO_1 = @dfa.step(nil,'a')[0]
148
-
149
- stateAN_O = @another.initial_state
150
- stateAN_1 = @another.step(nil,'a')[0]
151
-
152
- another_init = @dfa.add_automaton(@another)
153
-
154
- @dfa.connect(@dfa.initial_state,another_init,'c')
155
-
156
- assert_equal(6, @dfa.state_count)
157
- assert_equal(8, @dfa.edge_count)
158
-
159
- check_dfa_unchanged(@dfa)
160
- assert_equal(true, @dfa.accepts?('? c'))
161
-
162
-
163
- outA_edge1 = @dfa.initial_state.out_edges.select { |e| e.symbol == 'a'}[0]
164
- outA_edge2 = outA_edge1.to.out_edges.select { |e| e.symbol == 'a'}[0]
165
-
166
- stateA_O = @dfa.initial_state
167
- stateA_1 = @dfa.step(nil,'a')[0]
168
-
169
- outB_edge1 = another_init.out_edges.select { |e| e.symbol == 'a'}[0]
170
- outB_edge2 = outB_edge1.to.out_edges.select { |e| e.symbol == 'a'}[0]
171
-
172
- stateB_O = another_init
173
- stateB_1 = another_init.step('a')[0]
174
-
175
- assert_same stateAO_O,stateA_O
176
- assert_same stateAO_1,stateA_1
177
- assert_not_same stateAN_O,stateB_O
178
- assert_not_same stateAN_1,stateB_1
179
-
180
- assert_same outAOrig_edge1, outA_edge1
181
- assert_same outAOrig_edge2, outA_edge2
182
- assert_not_same outB_edge1, outAN_edge1
183
- assert_not_same outB_edge2, outAN_edge2
184
- end
185
-
186
-
187
-
188
- end # class AutomataOperationsTest
189
- end # module Stamina
190
-
@@ -1,1104 +0,0 @@
1
- require 'stamina/stamina_test'
2
- require 'stamina/automaton'
3
- module Stamina
4
-
5
- class AutomatonTest < StaminaTest
6
-
7
- def test_state_sink_q
8
- x, y = nil, nil
9
- Automaton.new(true) do |fa|
10
- x = fa.add_state(:initial => true, :accepting => true)
11
- y = fa.add_state(:initial => false, :accepting => false)
12
- fa.connect(0,1,'a')
13
- fa.connect(1,1,'b')
14
- end
15
- assert_equal false, x.sink?
16
- assert_equal true, y.sink?
17
- end
18
-
19
- # Tests that an automaton can be created with onself=true
20
- def test_new_on_self
21
- Automaton.new(true) do |fa|
22
- fa.add_state(:initial => true)
23
- add_state(:accepting => true)
24
- connect(0,1,'a')
25
- fa.connect(1,0,'b')
26
- end
27
- end
28
-
29
- # Tests that an automaton can be created with onself=true
30
- def test_new_not_on_self
31
- Automaton.new(false) do |fa|
32
- fa.add_state(:initial => true)
33
- fa.add_state(:accepting => true)
34
- fa.connect(0,1,'a')
35
- fa.connect(1,0,'b')
36
- end
37
- end
38
-
39
- # Tests Automaton documentation example.
40
- def test_documentation_example
41
- # Building an automaton for the regular language a(ba)*
42
- # It's a deterministic one, so we enforce it!
43
- fa = Automaton.new do
44
- add_state(:initial => true)
45
- add_state(:accepting => true)
46
- connect(0,1,'a')
47
- connect(1,0,'b')
48
- end
49
-
50
- # And we now it accepts 'a b a b a', and rejects 'a b' as well as ''
51
- assert_equal(true, fa.accepts?('? a b a b a'))
52
- assert_equal(false,fa.accepts?('? a b'))
53
- assert_equal(true, fa.rejects?('?'))
54
- end
55
-
56
- ### tests on small dfa #######################################################
57
-
58
- # Tests Automaton#states on examples
59
- def test_states_on_examples
60
- assert_equal(4,@small_dfa.states.size)
61
- assert_equal(4,@small_nfa.states.size)
62
- end
63
-
64
- # Tests Automaton#edges on examples
65
- def test_edges_on_examples
66
- assert_equal(6,@small_dfa.edges.size)
67
- assert_equal(7,@small_nfa.edges.size)
68
- end
69
-
70
- # Tests Automaton#state_count on examples
71
- def test_state_count_on_examples
72
- assert_equal(4, @small_dfa.state_count)
73
- assert_equal(4, @small_nfa.state_count)
74
- end
75
-
76
- # Tests Automaton#edge_count on examples
77
- def test_edge_count_on_examples
78
- assert_equal(6, @small_dfa.edge_count)
79
- assert_equal(7, @small_nfa.edge_count)
80
- end
81
-
82
- # Tests Automaton#ith_state on examples
83
- def test_ith_state_on_examples
84
- @examples.each do |fa|
85
- states = []
86
- 0.upto(fa.state_count-1) do |i|
87
- states << fa.ith_state(i)
88
- end
89
- assert_equal(fa.states, states)
90
- end
91
- end
92
-
93
- # Tests Automaton#ith_states on examples
94
- def test_ith_states_on_examples
95
- assert_equal(@small_dfa.states, @small_dfa.ith_states(0,1,2,3))
96
- assert_equal([@small_dfa.ith_state(1)], @small_dfa.ith_states(1))
97
- assert_equal(@small_nfa.states, @small_nfa.ith_states(0,1,2,3))
98
- assert_equal([@small_nfa.ith_state(1)], @small_nfa.ith_states(1))
99
- end
100
-
101
- # Tests Automaton#ith_edge on examples
102
- def test_ith_edge_on_examples
103
- @examples.each do |fa|
104
- edges = []
105
- 0.upto(fa.edge_count-1) do |i|
106
- edges << fa.ith_edge(i)
107
- end
108
- assert_equal(fa.edges, edges)
109
- end
110
- end
111
-
112
- # Tests Automaton#ith_edges on examples
113
- def test_ith_edges_on_examples
114
- assert_equal(@small_dfa.edges, @small_dfa.ith_edges(0,1,2,3,4,5))
115
- assert_equal([@small_dfa.ith_edge(1)], @small_dfa.ith_edges(1))
116
- assert_equal([@small_dfa.ith_edge(1), @small_dfa.ith_edge(4)], @small_dfa.ith_edges(1,4))
117
- assert_equal(@small_nfa.edges, @small_nfa.ith_edges(0,1,2,3,4,5,6))
118
- assert_equal([@small_nfa.ith_edge(1)], @small_nfa.ith_edges(1))
119
- assert_equal([@small_nfa.ith_edge(1), @small_nfa.ith_edge(4)], @small_nfa.ith_edges(1,4))
120
- end
121
-
122
- # Tests Automaton#each_state on examples
123
- def test_each_state_on_examples
124
- @examples.each do |fa|
125
- states = []
126
- fa.each_state {|s| states << s}
127
- assert_equal(fa.states, states)
128
- end
129
- end
130
-
131
- # Tests Automaton#each_edge on examples
132
- def test_each_state_on_examples
133
- @examples.each do |fa|
134
- edges = []
135
- fa.each_edge {|e| edges << e}
136
- assert_equal(fa.edges, edges)
137
- end
138
- end
139
-
140
- # Tests Automaton#in_edges on examples
141
- def test_in_edges_on_examples
142
- assert_equal(@small_dfa.ith_edges(4), @small_dfa.in_edges(0,true))
143
- assert_equal(@small_dfa.ith_edges(0,5), @small_dfa.in_edges(1,true))
144
- assert_equal(@small_dfa.ith_edges(1,3), @small_dfa.in_edges(2,true))
145
- assert_equal(@small_dfa.ith_edges(2), @small_dfa.in_edges(3,true))
146
-
147
- assert_equal(@small_nfa.ith_edges(5), @small_nfa.in_edges(0,true))
148
- assert_equal(@small_nfa.ith_edges(0,1,6), @small_nfa.in_edges(1,true))
149
- assert_equal(@small_nfa.ith_edges(2), @small_nfa.in_edges(2,true))
150
- assert_equal(@small_nfa.ith_edges(3,4), @small_nfa.in_edges(3,true))
151
- end
152
-
153
- # Tests Automaton#in_edges on examples
154
- def test_in_edges_and_out_edges_by_state_name
155
- dfa = ADL.parse_automaton <<-DFA
156
- 2 2
157
- First true false
158
- Second false true
159
- First Second a
160
- Second First b
161
- DFA
162
- assert_equal dfa.ith_edges(0), dfa.in_edges('Second')
163
- assert_equal dfa.ith_edges(0), dfa.out_edges('First')
164
- end
165
-
166
- # Tests Automaton#out_edges on examples
167
- def test_out_edges_on_examples
168
- assert_equal(@small_dfa.ith_edges(0), @small_dfa.out_edges(0,true))
169
- assert_equal(@small_dfa.ith_edges(1,2,5), @small_dfa.out_edges(1,true))
170
- assert_equal(@small_dfa.ith_edges(4), @small_dfa.out_edges(2,true))
171
- assert_equal(@small_dfa.ith_edges(3), @small_dfa.out_edges(3,true))
172
-
173
- assert_equal(@small_nfa.ith_edges(0), @small_nfa.out_edges(0,true))
174
- assert_equal(@small_nfa.ith_edges(1,2,3), @small_nfa.out_edges(1,true))
175
- assert_equal(@small_nfa.ith_edges(4,6), @small_nfa.out_edges(2,true))
176
- assert_equal(@small_nfa.ith_edges(5), @small_nfa.out_edges(3,true))
177
- end
178
-
179
- # Tests Automaton#in_symbols on examples
180
- def test_in_symbols_on_examples
181
- assert_equal(['c'], @small_dfa.in_symbols(0,true))
182
- assert_equal(['a','c'], @small_dfa.in_symbols(1,true))
183
- assert_equal(['b'], @small_dfa.in_symbols(2,true))
184
- assert_equal(['a'], @small_dfa.in_symbols(3,true))
185
-
186
- assert_equal(['a'], @small_nfa.in_symbols(0,true))
187
- assert_equal([nil,'a'], @small_nfa.in_symbols(1,true))
188
- assert_equal(['b'], @small_nfa.in_symbols(2,true))
189
- assert_equal(['b','c'], @small_nfa.in_symbols(3,true))
190
- end
191
-
192
- # Tests Automaton#out_edges on examples
193
- def test_out_symbols_on_examples
194
- assert_equal(['a'], @small_dfa.out_symbols(0,true))
195
- assert_equal(['a', 'b', 'c'], @small_dfa.out_symbols(1,true))
196
- assert_equal(['c'], @small_dfa.out_symbols(2,true))
197
- assert_equal(['b'], @small_dfa.out_symbols(3,true))
198
-
199
- assert_equal(['a'], @small_nfa.out_symbols(0,true))
200
- assert_equal([nil, 'b'], @small_nfa.out_symbols(1,true))
201
- assert_equal([nil, 'c'], @small_nfa.out_symbols(2,true))
202
- assert_equal(['a'], @small_nfa.out_symbols(3,true))
203
- end
204
-
205
- # Tests Automaton#adjacent_states on examples
206
- def test_adjacent_states_on_examples
207
- assert_equal(@small_dfa.ith_states(1,2), @small_dfa.adjacent_states(0).sort)
208
- assert_equal(@small_dfa.ith_states(0,1,2,3), @small_dfa.adjacent_states(1).sort)
209
- assert_equal(@small_dfa.ith_states(0,1,3), @small_dfa.adjacent_states(2).sort)
210
- assert_equal(@small_dfa.ith_states(1,2), @small_dfa.adjacent_states(3).sort)
211
-
212
- assert_equal(@small_nfa.ith_states(1,3), @small_nfa.adjacent_states(0).sort)
213
- assert_equal(@small_nfa.ith_states(0,1,2,3), @small_nfa.adjacent_states(1).sort)
214
- assert_equal(@small_nfa.ith_states(1,3), @small_nfa.adjacent_states(2).sort)
215
- assert_equal(@small_nfa.ith_states(0,1,2), @small_nfa.adjacent_states(3).sort)
216
- end
217
-
218
- # Tests Automaton#in_adjacent_states on examples
219
- def test_in_adjacent_states_on_examples
220
- assert_equal(@small_dfa.ith_states(2), @small_dfa.in_adjacent_states(0).sort)
221
- assert_equal(@small_dfa.ith_states(0,1), @small_dfa.in_adjacent_states(1).sort)
222
- assert_equal(@small_dfa.ith_states(1,3), @small_dfa.in_adjacent_states(2).sort)
223
- assert_equal(@small_dfa.ith_states(1), @small_dfa.in_adjacent_states(3).sort)
224
-
225
- assert_equal(@small_nfa.ith_states(3), @small_nfa.in_adjacent_states(0).sort)
226
- assert_equal(@small_nfa.ith_states(0,1,2), @small_nfa.in_adjacent_states(1).sort)
227
- assert_equal(@small_nfa.ith_states(1), @small_nfa.in_adjacent_states(2).sort)
228
- assert_equal(@small_nfa.ith_states(1,2), @small_nfa.in_adjacent_states(3).sort)
229
- end
230
-
231
- # Tests Automaton#out_adjacent_states on examples
232
- def test_out_adjacent_states_on_examples
233
- assert_equal(@small_dfa.ith_states(1), @small_dfa.out_adjacent_states(0).sort)
234
- assert_equal(@small_dfa.ith_states(1,2,3), @small_dfa.out_adjacent_states(1).sort)
235
- assert_equal(@small_dfa.ith_states(0), @small_dfa.out_adjacent_states(2).sort)
236
- assert_equal(@small_dfa.ith_states(2), @small_dfa.out_adjacent_states(3).sort)
237
-
238
- assert_equal(@small_nfa.ith_states(1), @small_nfa.out_adjacent_states(0).sort)
239
- assert_equal(@small_nfa.ith_states(1,2,3), @small_nfa.out_adjacent_states(1).sort)
240
- assert_equal(@small_nfa.ith_states(1,3), @small_nfa.out_adjacent_states(2).sort)
241
- assert_equal(@small_nfa.ith_states(0), @small_nfa.out_adjacent_states(3).sort)
242
- end
243
-
244
- # Tests Automaton#initial_states on examples
245
- def test_initial_states_on_examples
246
- assert_equal([@small_dfa.ith_state(3)], @small_dfa.initial_states())
247
- assert_equal(@small_nfa.ith_states(0,3), @small_nfa.initial_states().sort)
248
- end
249
-
250
- # Tests Automaton#initial_state on examples
251
- def test_initial_state_on_examples
252
- assert_equal(@small_dfa.ith_state(3), @small_dfa.initial_state())
253
- end
254
-
255
- # Tests Automaton#step on examples
256
- def test_step_on_examples
257
- assert_equal([], @small_dfa.step(0,'b'))
258
- @small_dfa.each_state do |s|
259
- s.out_edges.each do |e|
260
- assert_equal([e.target], @small_dfa.step(s,e.symbol))
261
- end
262
- end
263
-
264
- assert_equal([], @small_nfa.step(0, 'b'))
265
- assert_equal(@small_nfa.ith_states(1), @small_nfa.step(0, 'a'))
266
- assert_equal(@small_nfa.ith_states(2,3), @small_nfa.step(1, 'b'))
267
- assert_equal(@small_nfa.ith_states(1), @small_nfa.step(1, nil))
268
- end
269
-
270
- # Tests Automaton#dfa_step on examples
271
- def test_dfa_step_on_examples
272
- assert_equal(nil, @small_dfa.dfa_step(0,'b'))
273
- @small_dfa.each_state do |s|
274
- s.out_edges.each do |e|
275
- assert_equal(e.target, @small_dfa.dfa_step(s,e.symbol))
276
- end
277
- end
278
- end
279
-
280
- # Tests Automaton#delta on examples
281
- def test_delta_on_examples
282
- assert_equal([], @small_dfa.delta(0,'b'))
283
- @small_dfa.each_state do |s|
284
- s.out_edges.each do |e|
285
- assert_equal([e.target], @small_dfa.delta(s,e.symbol))
286
- end
287
- end
288
-
289
- assert_equal([], @small_nfa.delta(0,'b'))
290
- assert_equal(@small_nfa.ith_states(1,2,3), @small_nfa.delta(1, 'b').sort)
291
- assert_equal(@small_nfa.ith_states(), @small_nfa.delta(1, 'a').sort)
292
- assert_equal(@small_nfa.ith_states(1), @small_nfa.delta(0, 'a').sort)
293
- assert_equal(@small_nfa.ith_states(1,2,3), @small_nfa.delta(2, 'b').sort)
294
- end
295
-
296
- # Tests Automaton#dfa_delta on examples
297
- def test_dfa_delta_on_examples
298
- assert_equal(nil, @small_dfa.dfa_delta(0,'b'))
299
- @small_dfa.each_state do |s|
300
- s.out_edges.each do |e|
301
- assert_equal(e.target, @small_dfa.dfa_delta(s,e.symbol))
302
- end
303
- end
304
- end
305
-
306
- ### tests by methods #########################################################
307
-
308
- # Tests Automaton#add_state
309
- def test_add_state
310
- Automaton.new(false) do |fa|
311
- s0 = fa.add_state
312
- assert_equal(1, fa.state_count)
313
- assert_equal(false, s0.initial?)
314
- assert_equal(false, s0.accepting?)
315
-
316
- s1 = fa.add_state(:initial => true)
317
- assert_equal(2, fa.state_count)
318
- assert_equal(true, s1.initial?)
319
- assert_equal(false, s1.accepting?)
320
-
321
- s2 = fa.add_state(:initial => true, :accepting => true)
322
- assert_equal(3, fa.state_count)
323
- assert_equal(true, s2.initial?)
324
- assert_equal(true, s2.accepting?)
325
-
326
- s3 = fa.add_state(:myownkey => "blambeau")
327
- assert_equal(4, fa.state_count)
328
- assert_equal(false, s3.initial?)
329
- assert_equal(false, s3.accepting?)
330
- assert_equal("blambeau", s3[:myownkey])
331
-
332
- assert_equal(0, fa.edge_count)
333
- end
334
- end
335
-
336
- # Simply tests that aliases of add_state work.
337
- def test_add_state_aliases
338
- Automaton.new(false) do |fa|
339
- assert_not_nil(s0 = fa.add_state(:initial => true))
340
- assert_not_nil(s1 = fa.create_state)
341
- assert_not_nil fa.add_edge(s0,s1, 'a')
342
- end
343
- end
344
-
345
- # Tests Automaton#add_edge
346
- def test_add_edge
347
- Automaton.new(false) do |fa|
348
- s0 = fa.add_state(:initial => true)
349
- s1 = fa.add_state(:initial => false, :accepting => true)
350
- edge = fa.add_edge(s0, s1, {:symbol => 'a'})
351
-
352
- # check automaton
353
- assert_equal(2, fa.state_count)
354
- assert_equal(1, fa.edge_count)
355
-
356
- # check edge
357
- assert_equal('a', edge.symbol)
358
- assert_equal(s0, edge.source)
359
- assert_equal(s0, edge.from)
360
- assert_equal(s1, edge.target)
361
- assert_equal(s1, edge.to)
362
-
363
- # check states
364
- assert_equal([edge], s0.out_edges)
365
- assert_equal([edge], s1.in_edges)
366
- assert_equal(true, s0.deterministic?)
367
- assert_equal(true, s1.deterministic?)
368
- end
369
- end
370
-
371
- # Simply tests that aliases of add_edge work.
372
- def test_add_edge_aliases
373
- Automaton.new(false) do |fa|
374
- s0 = fa.add_state(:initial => true)
375
- s1 = fa.create_state
376
- assert_not_nil fa.add_edge(s0,s1, 'a')
377
- assert_not_nil fa.create_edge(s0,s1,'b')
378
- assert_not_nil fa.connect(s0,s1,'c')
379
- end
380
- end
381
-
382
- # Tests queries of states by names
383
- def test_state_names_1
384
- s0,s1,s2 = nil,nil,nil
385
- simple_dfa = Automaton.new(false) do |fa|
386
- s0 = fa.add_state(:initial => true, :name => 'A')
387
- s1 = fa.add_state(:accepting => true, :name => 'B')
388
- s2 = fa.add_state(:name => 'C')
389
- fa.connect(s0, s1, 'a')
390
- fa.connect(s1, s1, 'b')
391
- fa.connect(s1, s2, 'c')
392
- end
393
- assert_raise ArgumentError do
394
- simple_dfa.get_state(56) # wrong type
395
- end
396
- assert_raise ArgumentError do
397
- simple_dfa.get_state('T') # non-existing name
398
- end
399
-
400
- assert_raise ArgumentError do
401
- simple_dfa.get_state('') # non-existing state
402
- end
403
-
404
- assert_raise ArgumentError do
405
- simple_dfa.get_state(nil) # nil name
406
- end
407
- assert_equal s0,simple_dfa.get_state('A')
408
- assert_equal s1,simple_dfa.get_state('B')
409
- assert_equal s2,simple_dfa.get_state('C')
410
- end
411
-
412
- # tests queries of states by names
413
- def test_state_names_2
414
- simple_dfa = Automaton.new(false) do |fa|
415
- fa.add_state(:initial => true)
416
- end
417
- assert_raise ArgumentError do
418
- simple_dfa.get_state('') # non-existing state
419
- end
420
- end
421
-
422
- # Tests Automaton#drop_state
423
- def test_drop_state
424
- s0, s1, e00, e01, e10, e11 = nil
425
- fa = Automaton.new do |fa|
426
- s0 = fa.add_state(:initial => true)
427
- s1 = fa.add_state
428
- e01 = fa.connect(s0, s1, 'a')
429
- e00 = fa.connect(s0, s0, 'b')
430
- e10 = fa.connect(s1, s0, 'b')
431
- e11 = fa.connect(s1, s1, 'a')
432
- end
433
-
434
- fa.drop_state(s1)
435
- assert_equal(false, fa.states.include?(s1))
436
- assert_equal(1, fa.state_count)
437
- assert_equal(1, fa.edge_count)
438
- assert_equal(-1, s1.index)
439
- assert_equal(-1, e01.index)
440
- assert_equal(-1, e10.index)
441
- assert_equal(-1, e11.index)
442
- assert_equal(0, s0.index)
443
- assert_equal(0, e00.index)
444
- end
445
-
446
- def test_drop_state_respects_indexing
447
- fa = Stamina::ADL.parse_automaton <<-EOF
448
- 5 5
449
- 0 true false
450
- 1 false false
451
- 2 false false
452
- 3 false false
453
- 4 false false
454
- 0 1 a
455
- 0 2 b
456
- 1 2 b
457
- 2 3 a
458
- 3 4 b
459
- EOF
460
- fa.drop_state(1)
461
- assert_equal 4, fa.state_count
462
- end
463
-
464
- # Tests Automaton#drop_state
465
- def test_drop_state_aliases
466
- s0, s1, e00, e01, e10, e11 = nil
467
- fa = Automaton.new do |fa|
468
- s0 = fa.add_state(:initial => true)
469
- s1 = fa.add_state
470
- e01 = fa.connect(s0, s1, 'a')
471
- e00 = fa.connect(s0, s0, 'b')
472
- e10 = fa.connect(s1, s0, 'b')
473
- e11 = fa.connect(s1, s1, 'a')
474
- end
475
-
476
- fa.delete_state(s1)
477
- assert_equal(1, fa.state_count)
478
- assert_equal(1, fa.edge_count)
479
- end
480
-
481
- def test_same_state_cannot_be_dropped_twice
482
- s0, s1, e00, e01, e10, e11 = nil
483
- fa = Automaton.new do |fa|
484
- s0 = fa.add_state(:initial => true)
485
- s1 = fa.add_state
486
- e01 = fa.connect(s0, s1, 'a')
487
- e00 = fa.connect(s0, s0, 'b')
488
- e10 = fa.connect(s1, s0, 'b')
489
- e11 = fa.connect(s1, s1, 'a')
490
- end
491
-
492
- fa.drop_state(s1)
493
- assert_equal(false, fa.states.include?(s1))
494
- assert_raise ArgumentError do
495
- fa.drop_state(s1)
496
- end
497
- end
498
-
499
- # Tests Automaton#drop_states
500
- def test_drop_states
501
- s0, s1, s2, e00, e01, e10, e11, e02, e21 = nil
502
- fa = Automaton.new do |fa|
503
- s0 = fa.add_state(:initial => true)
504
- s1, s2 = fa.add_n_states(2)
505
- e01 = fa.connect(s0, s1, 'a')
506
- e00 = fa.connect(s0, s0, 'b')
507
- e10 = fa.connect(s1, s0, 'b')
508
- e11 = fa.connect(s1, s1, 'a')
509
- e02 = fa.connect(s0, s2, 'c')
510
- e21 = fa.connect(s2, s1, 'a')
511
- end
512
-
513
- fa.drop_states(s1,s2)
514
- assert_equal(1, fa.state_count)
515
- assert_equal(1, fa.edge_count)
516
- assert_equal(-1, s1.index)
517
- assert_equal(-1, s2.index)
518
- assert_equal(false, fa.states.include?(s1))
519
- assert_equal(false, fa.states.include?(s2))
520
- end
521
-
522
- # Tests Automaton#drop_edge
523
- def test_drop_edge
524
- s0, s1, e01, e10 = nil
525
- fa = Automaton.new do |fa|
526
- s0 = fa.add_state(:initial => true)
527
- s1 = fa.add_state
528
- e01 = fa.connect(s0, s1, 'a')
529
- e10 = fa.connect(s1, s0, 'b')
530
- end
531
-
532
- # we drop second edge
533
- fa.drop_edge(e10)
534
- assert_equal(2, fa.state_count)
535
- assert_equal(1, fa.edge_count)
536
- assert_equal(0, e01.index, 'First edge index has not changed')
537
-
538
- # connect it again
539
- e10 = fa.connect(s1, s0, 'b')
540
-
541
- # we drop the first one this time
542
- fa.drop_edge(e01)
543
- assert_equal(2, fa.state_count)
544
- assert_equal(1, fa.edge_count)
545
- assert_equal(0, e10.index, 'Second edge became first')
546
- end
547
-
548
- # Tests Automaton#drop_edge
549
- def test_drop_edge_by_index
550
- s0, s1, e01, e10 = nil
551
- fa = Automaton.new do |fa|
552
- s0 = fa.add_state(:initial => true)
553
- s1 = fa.add_state
554
- e01 = fa.connect(s0, s1, 'a')
555
- e10 = fa.connect(s1, s0, 'b')
556
- end
557
-
558
- # we drop second edge
559
- fa.drop_edge(1)
560
- assert_equal(2, fa.state_count)
561
- assert_equal(1, fa.edge_count)
562
- assert_equal(0, e01.index, 'First edge index has not changed')
563
- end
564
-
565
- # Tests aliases of Automaton#drop_edge
566
- def test_drop_edge_aliases
567
- s0, s1, e01, e10 = nil
568
- fa = Automaton.new do |fa|
569
- s0 = fa.add_state(:initial => true)
570
- s1 = fa.add_state
571
- e01 = fa.connect(s0, s1, 'a')
572
- e10 = fa.connect(s1, s0, 'b')
573
- end
574
-
575
- # we drop second edge
576
- fa.delete_edge(e10)
577
- assert_equal(2, fa.state_count)
578
- assert_equal(1, fa.edge_count)
579
- assert_equal(0, e01.index, 'First edge index has not changed')
580
- end
581
-
582
- # Tests that an edge cannot be dropped twice
583
- def test_same_edge_cannot_be_dropped_twice
584
- s0, s1, e01, e10 = nil
585
- fa = Automaton.new do |fa|
586
- s0 = fa.add_state(:initial => true)
587
- s1 = fa.add_state
588
- e01 = fa.connect(s0, s1, 'a')
589
- e10 = fa.connect(s1, s0, 'b')
590
- end
591
-
592
- # we drop first edge
593
- fa.drop_edge(e01)
594
-
595
- # cannot drop it again
596
- assert_raise ArgumentError do
597
- fa.drop_edge(e01)
598
- end
599
- end
600
-
601
- # Tests Automaton#drop_edges
602
- def test_drop_edges
603
- s0, s1, e01, e10, e11 = nil
604
- fa = Automaton.new do |fa|
605
- s0 = fa.add_state(:initial => true)
606
- s1 = fa.add_state
607
- e10 = fa.connect(s1, s0, 'b')
608
- e01 = fa.connect(s0, s1, 'a')
609
- e11 = fa.connect(s1, s1, 'a')
610
- end
611
-
612
- fa.drop_edges(e10,e11)
613
- assert_equal(2, fa.state_count)
614
- assert_equal(1, fa.edge_count)
615
- assert_equal(0, e01.index)
616
- end
617
-
618
- # Tests that Automaton#drop_edges allows removing all edges
619
- def test_drop_edges_recognizes_sub_transaction
620
- s0, ea, eb, ec = nil
621
- fa = Automaton.new do |fa|
622
- s0 = fa.add_state(:initial => true)
623
- ea = fa.connect(s0, s0, 'a')
624
- eb = fa.connect(s0, s0, 'b')
625
- ec = fa.connect(s0, s0, 'c')
626
- end
627
- fa.drop_edges(ea, eb, ec)
628
- assert_equal(0, fa.edge_count)
629
- assert_equal(0, s0.in_edges.size)
630
- assert_equal(0, s0.out_edges.size)
631
- end
632
-
633
- # Tests Automaton#drop_edges
634
- def test_drop_edges_allow_any_order_of_arguments
635
- s0, s1, e01, e10, e11 = nil
636
- fa = Automaton.new do |fa|
637
- s0 = fa.add_state(:initial => true)
638
- s1 = fa.add_state
639
- e10 = fa.connect(s1, s0, 'b')
640
- e01 = fa.connect(s0, s1, 'a')
641
- e11 = fa.connect(s1, s1, 'a')
642
- end
643
-
644
- fa.drop_edges(e11,e10)
645
- assert_equal(2, fa.state_count)
646
- assert_equal(1, fa.edge_count)
647
- assert_equal(0, e01.index)
648
- end
649
-
650
- # Tests aliases of Automaton#drop_edges
651
- def test_drop_edges_aliases
652
- s0, s1, e01, e10, e11 = nil
653
- fa = Automaton.new do |fa|
654
- s0 = fa.add_state(:initial => true)
655
- s1 = fa.add_state
656
- e10 = fa.connect(s1, s0, 'b')
657
- e01 = fa.connect(s0, s1, 'a')
658
- e11 = fa.connect(s1, s1, 'a')
659
- end
660
-
661
- fa.delete_edges(e10,e11)
662
- assert_equal(2, fa.state_count)
663
- assert_equal(1, fa.edge_count)
664
- assert_equal(0, e01.index)
665
- end
666
-
667
- # Tests Automaton#edges on invalid edge arguments
668
- def test_drop_edges_detects_invalid_edges
669
- s0, s1, e01, e10, e11 = nil
670
- fa = Automaton.new do |fa|
671
- s0 = fa.add_state(:initial => true)
672
- s1 = fa.add_state
673
- e10 = fa.connect(s1, s0, 'b')
674
- e01 = fa.connect(s0, s1, 'a')
675
- e11 = fa.connect(s1, s1, 'a')
676
- end
677
-
678
- fa.drop_edge(e10)
679
- assert_raise ArgumentError do
680
- fa.drop_edges(e11,e10)
681
- end
682
- assert_equal(2, fa.state_count)
683
- assert_equal(2, fa.edge_count)
684
- end
685
-
686
- ### tests by scenarios #######################################################
687
-
688
- # Tests creating an automaton for the empty regular language
689
- def test_automaton_of_empty_language
690
- fa, s0 = nil
691
- assert_nothing_raised do
692
- fa = Automaton.new do |fa|
693
- s0 = fa.add_state(:initial => true, :accepting => false)
694
- end
695
- end
696
- assert_equal(1, fa.state_count)
697
- assert_equal(0, fa.edge_count)
698
- assert_equal(true, fa.deterministic?)
699
- assert_equal([s0], fa.initial_states)
700
- assert_equal(s0, fa.initial_state)
701
- assert_equal([s0], fa.states)
702
- assert_equal([], fa.edges)
703
- assert_equal([], fa.in_edges(s0))
704
- assert_equal([], fa.out_edges(s0))
705
- assert_equal([], fa.in_symbols(s0))
706
- assert_equal([], fa.out_symbols(s0))
707
- assert_equal([], fa.adjacent_states(s0))
708
- assert_equal([], fa.in_adjacent_states(s0))
709
- assert_equal([], fa.out_adjacent_states(s0))
710
- end
711
-
712
- # Tests creating an automaton for the regular language that only accepts the
713
- # empty string.
714
- def test_automaton_of_lambda_language
715
- fa, s0 = nil
716
- assert_nothing_raised do
717
- fa = Automaton.new do |fa|
718
- s0 = fa.add_state(:initial => true, :accepting => true)
719
- end
720
- end
721
- assert_equal(1, fa.state_count)
722
- assert_equal(0, fa.edge_count)
723
- assert_equal([s0], fa.states)
724
- assert_equal(true, fa.deterministic?)
725
- assert_equal([s0], fa.initial_states)
726
- assert_equal(s0, fa.initial_state)
727
- assert_equal([], fa.edges)
728
- assert_equal([], fa.in_edges(s0))
729
- assert_equal([], fa.out_edges(s0))
730
- assert_equal([], fa.in_symbols(s0))
731
- assert_equal([], fa.out_symbols(s0))
732
- assert_equal([], fa.adjacent_states(s0))
733
- assert_equal([], fa.in_adjacent_states(s0))
734
- assert_equal([], fa.out_adjacent_states(s0))
735
- end
736
-
737
- # Tests that automaton can be created with nil symbols on edges
738
- def test_automaton_with_epsilon
739
- fa, s0, s1, edge = nil
740
- assert_nothing_raised do
741
- fa = Automaton.new(false) do |fa|
742
- s0 = fa.add_state(:initial => true, :accepting => true)
743
- s1 = fa.add_state
744
- edge = fa.connect(s0, s1, {:symbol => nil})
745
- assert_equal(nil, edge.symbol)
746
- end
747
- end
748
- assert_equal(false, fa.deterministic?)
749
- assert_equal([s0,s1], fa.initial_states.sort)
750
- assert_equal(true, fa.initial_states.include?(fa.initial_state))
751
- end
752
-
753
- # Tests creation an automaton with one accepting state with looping 'a'
754
- # symbol.
755
- def test_automaton_of_whole_langage_on_a
756
- fa, s0, e0 = nil
757
- assert_nothing_raised do
758
- fa = Automaton.new do |fa|
759
- s0 = fa.add_state(:initial => true, :accepting => true)
760
- e0 = fa.add_edge(s0, s0, {:symbol => 'a'})
761
- end
762
- end
763
-
764
- # check the whole automaton
765
- assert_equal(1, fa.state_count)
766
- assert_equal(1, fa.edge_count)
767
- assert_equal([s0], fa.states)
768
- assert_equal([e0], fa.edges)
769
- assert_equal(true, fa.deterministic?)
770
- assert_equal([s0], fa.initial_states)
771
- assert_equal(s0, fa.initial_state)
772
- assert_equal([e0], fa.in_edges(s0))
773
- assert_equal([e0], fa.out_edges(s0))
774
- assert_equal(['a'], fa.in_symbols(s0))
775
- assert_equal(['a'], fa.out_symbols(s0))
776
- assert_equal([s0], fa.adjacent_states(s0))
777
- assert_equal([s0], fa.in_adjacent_states(s0))
778
- assert_equal([s0], fa.out_adjacent_states(s0))
779
- end
780
-
781
- # Tests creating a simple deterministic automaton
782
- def test_deterministic_fa_with_two_states
783
- s0, s1, e01, e10, fa = nil
784
-
785
- # automaton construction, should not raise anything
786
- fa = Automaton.new do |a|
787
- s0 = a.add_state(:initial => true)
788
- s1 = a.add_state(:accepting => true)
789
- e01 = a.add_edge(s0, s1, 'a')
790
- e10 = a.add_edge(s1, s0, 'b')
791
- end
792
-
793
- # check automaton
794
- assert_equal(2, fa.state_count)
795
- assert_equal(2, fa.edge_count)
796
- assert_equal(true, fa.deterministic?)
797
- assert_equal([s0], fa.initial_states)
798
- assert_equal(s0, fa.initial_state)
799
- assert_equal([s0,s1], fa.states)
800
- assert_equal([e01,e10], fa.edges)
801
-
802
- # check state s0
803
- assert_equal(true, s0.initial?)
804
- assert_equal(false, s0.accepting?)
805
- assert_equal(true, s0.deterministic?)
806
- assert_equal([e01], s0.out_edges)
807
- assert_equal([e10], s0.in_edges)
808
-
809
- # check state s1
810
- assert_equal(false, s1.initial?)
811
- assert_equal(true, s1.accepting?)
812
- assert_equal(true, s1.deterministic?)
813
- assert_equal([e10], s1.out_edges)
814
- assert_equal([e01], s1.in_edges)
815
-
816
- # check edge 01
817
- assert_equal('a', e01.symbol)
818
- assert_equal(s0, e01.source)
819
- assert_equal(s1, e01.target)
820
-
821
- # check edge 10
822
- assert_equal('b', e10.symbol)
823
- assert_equal(s1, e10.source)
824
- assert_equal(s0, e10.target)
825
-
826
- # check the whole automaton
827
- assert_equal(2, fa.state_count)
828
- assert_equal(2, fa.edge_count)
829
- assert_equal([s0, s1], fa.states)
830
- assert_equal([e01, e10], fa.edges)
831
- assert_equal([e10], fa.in_edges(s0))
832
- assert_equal([e01], fa.out_edges(s0))
833
- assert_equal(['b'], fa.in_symbols(s0))
834
- assert_equal(['a'], fa.out_symbols(s0))
835
- assert_equal([e01], fa.in_edges(s1))
836
- assert_equal([e10], fa.out_edges(s1))
837
- assert_equal(['a'], fa.in_symbols(s1))
838
- assert_equal(['b'], fa.out_symbols(s1))
839
- assert_equal([s1], fa.adjacent_states(s0))
840
- assert_equal([s1], fa.in_adjacent_states(s0))
841
- assert_equal([s1], fa.out_adjacent_states(s0))
842
- assert_equal([s0], fa.adjacent_states(s1))
843
- assert_equal([s0], fa.in_adjacent_states(s1))
844
- assert_equal([s0], fa.out_adjacent_states(s1))
845
-
846
- # check that it is recognized as a deterministic automaton
847
- assert_equal true, fa.deterministic?
848
- end
849
-
850
- # Tests nfa.deterministic? on documentation example
851
- def test_documentation_example2
852
- # create some automaton (here a non deterministic automaton)
853
- nfa = Automaton.new do |fa|
854
- s0 = fa.add_state(:initial => true, :accepting => false)
855
- s1 = fa.add_state(:initial => false, :accepting => true)
856
- s2 = fa.add_state(:initial => false, :accepting => true)
857
- fa.add_edge(s0, s1, 'a')
858
- fa.add_edge(s0, s2, 'a')
859
- end
860
-
861
- # check that it is recognized as a non deterministic one
862
- assert_equal false,nfa.deterministic?
863
- end
864
-
865
- # Tests Node#delta on a deterministic automaton
866
- def test_state_delta_on_deterministic
867
- nfa, s0, s1, s2 = nil
868
- nfa = Automaton.new do |fa|
869
- s0 = fa.add_state(:initial => true)
870
- s1, s2 = fa.add_state, fa.add_state
871
- fa.connect(s0, s1, 'a')
872
- fa.connect(s0, s2, 'b')
873
- fa.connect(s1, s0, 'b')
874
- fa.connect(s1, s2, 'c')
875
- end
876
- assert_equal(true, nfa.deterministic?)
877
-
878
- # letting state choose its data-structure
879
- assert_equal([s1], s0.delta('a'))
880
- assert_equal([s2], s0.delta('b'))
881
- assert_equal([], s0.delta('c'))
882
- assert_equal([s0], s1.delta('b'))
883
- assert_equal([s2], s1.delta('c'))
884
- end
885
-
886
- # Tests Node#delta on a non deterministic automaton
887
- def test_state_delta_on_non_deterministic
888
- fa, s0, s1, s2 = nil
889
- fa = Automaton.new do |fa|
890
- s0 = fa.add_state(:initial => true)
891
- s1, s2 = fa.add_state, fa.add_state
892
- fa.connect(s0, s1, 'a')
893
- fa.connect(s0, s2, 'a')
894
- fa.connect(s1, s1, 'b')
895
- fa.connect(s1, s2, 'b')
896
- end
897
- assert_equal(false, fa.deterministic?)
898
- assert_equal([s1,s2], s0.delta('a').sort)
899
- assert_equal([], s0.delta('c').sort)
900
- assert_equal([s1,s2], s1.delta('b').sort)
901
- assert_equal([], s2.delta('a').sort)
902
- assert_equal([], s2.delta('b').sort)
903
- end
904
-
905
- # Tests Node#delta on a non deterministic automaton with epsilon letters
906
- def test_state_delta_on_non_deterministic_with_epsilon
907
- #
908
- # tests on s0 -a-> s1 -a-> s2
909
- # with a looping nil on s1
910
- #
911
- fa, s0, s1, s2, s3, s4 = nil
912
- fa = Automaton.new do |fa|
913
- s0 = fa.add_state(:initial => true)
914
- s1, s2 = fa.add_state, fa.add_state
915
- fa.connect(s0,s1,'a')
916
- fa.connect(s1,s1,nil)
917
- fa.connect(s1,s2,'a')
918
- end
919
- assert_equal(false, fa.deterministic?)
920
- assert_equal([], s0.delta('b'))
921
- assert_equal([s1], s0.delta('a'))
922
- assert_equal([s2], s1.delta('a'))
923
- assert_equal([s1], s1.delta(nil))
924
-
925
- #
926
- # tests on s0 -a-> s1 -nil-> s2
927
- #
928
- fa = Automaton.new do |fa|
929
- s0 = fa.add_state(:initial => true)
930
- s1, s2 = fa.add_state, fa.add_state
931
- fa.connect(s0,s1,'a')
932
- fa.connect(s1,s2,nil)
933
- end
934
- assert_equal(false, fa.deterministic?)
935
- assert_equal([], s0.delta(nil))
936
- assert_equal([s1,s2], s0.delta('a').sort)
937
- assert_equal([], s1.delta('a'))
938
- assert_equal([s2], s1.delta(nil))
939
-
940
- #
941
- # tests on s0 -a-> s1 -nil-> s2 -a-> s3
942
- #
943
- fa = Automaton.new do |fa|
944
- s0 = fa.add_state(:initial => true)
945
- s1, s2, s3 = fa.add_state, fa.add_state, fa.add_state
946
- fa.connect(s0,s1,'a')
947
- fa.connect(s1,s2,nil)
948
- fa.connect(s2,s3,'a')
949
- end
950
- assert_equal(false, fa.deterministic?)
951
- assert_equal([], s0.delta(nil))
952
- assert_equal([s1,s2], s0.delta('a').sort)
953
- assert_equal([s3], s1.delta('a'))
954
- assert_equal([s3], s2.delta('a'))
955
- assert_equal([s2], s1.delta(nil))
956
-
957
- # s0 -a-> s1 -nil-> s2
958
- # s1 <-a- s1
959
- # s1<->a
960
- fa = Automaton.new do |fa|
961
- s0 = fa.add_state(:initial => true)
962
- s1, s2 = fa.add_state, fa.add_state
963
- fa.connect(s0,s1,'a')
964
- fa.connect(s1,s1,'a')
965
- fa.connect(s1,s2,nil)
966
- fa.connect(s2,s1,'a')
967
- end
968
- assert_equal(false, fa.deterministic?)
969
- assert_equal([s1,s2], s0.delta('a').sort)
970
- assert_equal([s1,s2], s1.delta('a').sort)
971
- assert_equal([s1,s2], s2.delta('a').sort)
972
-
973
- # s0 -nil-> s1 -a-> s2 -nil-> s3
974
- # s1 -a-> s4
975
- fa = Automaton.new do |fa|
976
- s0 = fa.add_state(:initial => true)
977
- s1, s2, s3, s4 = fa.add_n_states(4)
978
- fa.connect(s0,s1,nil)
979
- fa.connect(s1,s2,'a')
980
- fa.connect(s2,s3,nil)
981
- fa.connect(s1,s4,'a')
982
- end
983
- assert_equal(false, fa.deterministic?)
984
- assert_equal([s1], s0.delta(nil))
985
- assert_equal([s2,s3,s4], s0.delta('a').sort)
986
- assert_equal([s2,s3,s4], s1.delta('a').sort)
987
- end
988
-
989
- # Tests State#dfa_delta on a deterministic automaton
990
- def test_state_dfa_delta_on_deterministic
991
- fa, s0, s1, s2 = nil
992
- fa = Automaton.new do |fa|
993
- s0 = fa.add_state(:initial => true)
994
- s1, s2 = fa.add_state, fa.add_state
995
- fa.connect(s0, s1, 'a')
996
- fa.connect(s0, s2, 'b')
997
- fa.connect(s1, s0, 'b')
998
- fa.connect(s1, s2, 'c')
999
- end
1000
- assert_equal(true, fa.deterministic?)
1001
-
1002
- # letting state choose its data-structure
1003
- assert_equal(s1, s0.dfa_delta('a'))
1004
- assert_equal(s2, s0.dfa_delta('b'))
1005
- assert_equal(nil, s0.dfa_delta('c'))
1006
- assert_equal(s0, s1.dfa_delta('b'))
1007
- assert_equal(s2, s1.dfa_delta('c'))
1008
- end
1009
-
1010
- # Tests State#epsilon_closure
1011
- def test_epsilon_closure_on_non_deterministic_automaton
1012
- s0, s1, s2, s3, s4 = nil
1013
- fa = Automaton.new do |fa|
1014
- s0 = fa.add_state(:initial => true) #
1015
- s1, s2, s3, s4 = fa.add_n_states(4) # s1 -b-> s3
1016
- fa.connect(s0, s1, 'a') # a
1017
- fa.connect(s0, s2, 'a') # s0
1018
- fa.connect(s1, s3, 'b') # a
1019
- fa.connect(s2, s4, 'c') # s2 -c-> s4
1020
- end #
1021
- fa.states.each do |s|
1022
- assert_equal([s], s.epsilon_closure)
1023
- end
1024
-
1025
- fa.connect(s2, s2, 'b')
1026
- assert_equal([s2], s2.delta('b'))
1027
-
1028
- fa.connect(s2, s1, nil)
1029
- assert_equal([s1], s2.step(nil))
1030
- assert_equal([s1,s2], s2.epsilon_closure.sort)
1031
- assert_equal([s1,s2,s3], s2.delta('b').sort)
1032
- end
1033
-
1034
- # Tests Walking#walk on a non-deterministic automaton.
1035
- def test_state_delta_on_non_deterministic_automaton_from_walkbug
1036
- s0, s1, s2, s3, s4 = nil
1037
- fa = Automaton.new do |fa|
1038
- s0 = fa.add_state(:initial => true)
1039
- s1, s2, s3, s4 = fa.add_n_states(4)
1040
- fa.connect(s0, s1, 'a')
1041
- fa.connect(s0, s2, 'a')
1042
- fa.connect(s1, s3, 'b')
1043
- fa.connect(s2, s4, 'c')
1044
- fa.connect(s2, s2, 'b')
1045
- fa.connect(s2, s1, nil)
1046
- end
1047
- assert_equal([s1,s2,s3], s2.delta('b').sort)
1048
- end
1049
-
1050
- ### Dup test section ###########################################################
1051
-
1052
- def test_automaton_can_be_duplicated
1053
- dup = @small_dfa.dup
1054
- assert_equal @small_dfa.state_count, dup.state_count
1055
- assert_equal @small_dfa.edge_count, dup.edge_count
1056
- end
1057
-
1058
- ### Alphabet test section ######################################################
1059
-
1060
- def test_alphabet_on_examples
1061
- assert_equal ['a', 'b', 'c'], @small_dfa.alphabet
1062
- assert_equal ['a', 'b', 'c'], @small_nfa.alphabet
1063
- end
1064
-
1065
- def test_valid_alphabet_may_be_set
1066
- dfa = @small_dfa.dup
1067
- dfa.alphabet = ['c', 'a', 'b', 'z']
1068
- assert_equal ['a','b','c','z'], dfa.alphabet
1069
- end
1070
-
1071
- def test_invalid_alphabet_cannot_be_set
1072
- dfa = @small_dfa.dup
1073
- assert_raise ArgumentError do
1074
- dfa.alphabet = ['a', 'b']
1075
- end
1076
- assert_raise ArgumentError do
1077
- dfa.alphabet = ['a', 'a', 'b']
1078
- end
1079
- assert_raise ArgumentError do
1080
- dfa.alphabet = ['a', 'b', nil]
1081
- end
1082
- end
1083
-
1084
- ### tests initial state cache ##################################################
1085
- def test_initial_state_cache_works_correctly
1086
- dfa = Stamina::ADL.parse_automaton <<-EOF
1087
- 2 2
1088
- 0 true false
1089
- 1 false true
1090
- 0 1 a
1091
- 1 0 b
1092
- EOF
1093
- initial, other = dfa.ith_state(0), dfa.ith_state(1)
1094
- assert_equal initial, dfa.initial_state
1095
- initial[:hello] = "world"
1096
- assert_equal initial, dfa.initial_state
1097
- dfa.ith_state(0)[:initial] = false
1098
- dfa.ith_state(1)[:initial] = true
1099
- assert_equal other, dfa.initial_state
1100
- end
1101
-
1102
- end
1103
-
1104
- end # module Stamina