stamina 0.4.0 → 0.5.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.
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