stamina 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +24 -0
- data/Gemfile.lock +5 -1
- data/bin/stamina +10 -0
- data/lib/stamina.rb +2 -1
- data/lib/stamina/abbadingo.rb +2 -0
- data/lib/stamina/abbadingo/random_dfa.rb +48 -0
- data/lib/stamina/abbadingo/random_sample.rb +146 -0
- data/lib/stamina/adl.rb +6 -6
- data/lib/stamina/automaton.rb +29 -4
- data/lib/stamina/automaton/complete.rb +36 -0
- data/lib/stamina/automaton/equivalence.rb +55 -0
- data/lib/stamina/automaton/metrics.rb +8 -1
- data/lib/stamina/automaton/minimize.rb +25 -0
- data/lib/stamina/automaton/minimize/hopcroft.rb +116 -0
- data/lib/stamina/automaton/minimize/pitchies.rb +64 -0
- data/lib/stamina/automaton/strip.rb +16 -0
- data/lib/stamina/automaton/walking.rb +46 -19
- data/lib/stamina/command.rb +45 -0
- data/lib/stamina/command/abbadingo_dfa.rb +81 -0
- data/lib/stamina/command/abbadingo_samples.rb +40 -0
- data/lib/stamina/command/adl2dot.rb +71 -0
- data/lib/stamina/command/classify.rb +48 -0
- data/lib/stamina/command/help.rb +27 -0
- data/lib/stamina/command/infer.rb +141 -0
- data/lib/stamina/command/metrics.rb +51 -0
- data/lib/stamina/command/robustness.rb +22 -0
- data/lib/stamina/command/score.rb +35 -0
- data/lib/stamina/errors.rb +4 -1
- data/lib/stamina/ext/math.rb +20 -0
- data/lib/stamina/induction/{redblue.rb → blue_fringe.rb} +29 -28
- data/lib/stamina/induction/commons.rb +32 -46
- data/lib/stamina/induction/rpni.rb +7 -9
- data/lib/stamina/induction/union_find.rb +3 -3
- data/lib/stamina/loader.rb +1 -0
- data/lib/stamina/sample.rb +79 -2
- data/lib/stamina/scoring.rb +37 -0
- data/lib/stamina/version.rb +2 -2
- data/stamina.gemspec +2 -1
- data/stamina.noespec +9 -12
- data/test/stamina/abbadingo/random_dfa_test.rb +16 -0
- data/test/stamina/abbadingo/random_sample_test.rb +78 -0
- data/test/stamina/adl_test.rb +27 -2
- data/test/stamina/automaton/complete_test.rb +58 -0
- data/test/stamina/automaton/equivalence_test.rb +120 -0
- data/test/stamina/automaton/minimize/hopcroft_test.rb +15 -0
- data/test/stamina/automaton/minimize/minimize_test.rb +55 -0
- data/test/stamina/automaton/minimize/pitchies_test.rb +15 -0
- data/test/stamina/automaton/minimize/rice_edu_10.adl +16 -0
- data/test/stamina/automaton/minimize/rice_edu_10.min.adl +13 -0
- data/test/stamina/automaton/minimize/rice_edu_13.adl +13 -0
- data/test/stamina/automaton/minimize/rice_edu_13.min.adl +7 -0
- data/test/stamina/automaton/minimize/should_strip_1.adl +8 -0
- data/test/stamina/automaton/minimize/should_strip_1.min.adl +6 -0
- data/test/stamina/automaton/minimize/unknown_1.adl +16 -0
- data/test/stamina/automaton/minimize/unknown_1.min.adl +12 -0
- data/test/stamina/automaton/strip_test.rb +36 -0
- data/test/stamina/automaton/walking/dfa_delta_test.rb +39 -0
- data/test/stamina/automaton_test.rb +13 -1
- data/test/stamina/induction/{redblue_test.rb → blue_fringe_test.rb} +22 -22
- data/test/stamina/sample_test.rb +75 -0
- data/test/stamina/stamina_test.rb +13 -2
- metadata +98 -23
- data/bin/adl2dot +0 -12
- data/bin/classify +0 -12
- data/bin/redblue +0 -12
- data/bin/rpni +0 -12
- data/lib/stamina/command/adl2dot_command.rb +0 -73
- data/lib/stamina/command/classify_command.rb +0 -57
- data/lib/stamina/command/redblue_command.rb +0 -58
- data/lib/stamina/command/rpni_command.rb +0 -58
- data/lib/stamina/command/stamina_command.rb +0 -79
data/lib/stamina/scoring.rb
CHANGED
@@ -171,6 +171,43 @@ module Stamina
|
|
171
171
|
end
|
172
172
|
alias :hbcr :harmonic_balanced_classification_rate
|
173
173
|
alias :harmonic_bcr :harmonic_balanced_classification_rate
|
174
|
+
|
175
|
+
MEASURES = [
|
176
|
+
:false_positive, :false_negative,
|
177
|
+
:true_positive, :true_negative,
|
178
|
+
:accuracy, :error_rate,
|
179
|
+
:precision, :recall, :f_measure,
|
180
|
+
:false_positive_rate, :false_negative_rate,
|
181
|
+
:true_positive_rate, :true_negative_rate,
|
182
|
+
:positive_predictive_value, :negative_predictive_value,
|
183
|
+
:sensitivity, :specificity,
|
184
|
+
:positive_likelihood, :negative_likelihood,
|
185
|
+
:balanced_classification_rate, :balanced_error_rate, :harmonic_bcr
|
186
|
+
]
|
187
|
+
|
188
|
+
def to_h
|
189
|
+
h = {}
|
190
|
+
MEASURES.each do |m|
|
191
|
+
h[m] = self.send(m.to_sym)
|
192
|
+
end
|
193
|
+
h
|
194
|
+
end
|
195
|
+
|
196
|
+
def to_s
|
197
|
+
s = ""
|
198
|
+
MEASURES.each do |m|
|
199
|
+
vals = case val = self.send(m.to_sym)
|
200
|
+
when Integer
|
201
|
+
"%s" % val
|
202
|
+
when Float
|
203
|
+
"%.5f" % val
|
204
|
+
else
|
205
|
+
"%s" % val
|
206
|
+
end
|
207
|
+
s += "%30s: %10s\n" % [m.to_s, vals]
|
208
|
+
end
|
209
|
+
s
|
210
|
+
end
|
174
211
|
|
175
212
|
end # module Scoring
|
176
213
|
end # module Stamina
|
data/lib/stamina/version.rb
CHANGED
data/stamina.gemspec
CHANGED
@@ -129,7 +129,8 @@ Gem::Specification.new do |s|
|
|
129
129
|
s.add_development_dependency("yard", "~> 0.6.4")
|
130
130
|
s.add_development_dependency("bluecloth", "~> 2.0.9")
|
131
131
|
s.add_development_dependency("wlang", "~> 0.10.1")
|
132
|
-
|
132
|
+
s.add_development_dependency("gnuplot", "~> 2.3.6")
|
133
|
+
s.add_dependency("quickl", "~> 0.2.0")
|
133
134
|
|
134
135
|
# The version of ruby required by this gem
|
135
136
|
#
|
data/stamina.noespec
CHANGED
@@ -9,7 +9,7 @@ variables:
|
|
9
9
|
upper:
|
10
10
|
Stamina
|
11
11
|
version:
|
12
|
-
0.
|
12
|
+
0.4.0
|
13
13
|
summary: |-
|
14
14
|
Automaton and Regular Inference Toolkit
|
15
15
|
description: |-
|
@@ -22,14 +22,11 @@ variables:
|
|
22
22
|
- http://stamina.chefbe.net/
|
23
23
|
- http://github.com/blambeau/stamina
|
24
24
|
dependencies:
|
25
|
-
|
26
|
-
- {name: rake, version: "~> 0.8.7",
|
27
|
-
|
28
|
-
- {name:
|
29
|
-
|
30
|
-
- {name:
|
31
|
-
|
32
|
-
- {name:
|
33
|
-
- {name: bluecloth, version: "~> 2.0.9", groups: [development]}
|
34
|
-
# wlang is required to run 'rake debug_mail'. See tasks/debug_mail.rake
|
35
|
-
- {name: wlang, version: "~> 0.10.1", groups: [development]}
|
25
|
+
- {name: quickl, version: "~> 0.2.0", groups: [runtime]}
|
26
|
+
- {name: rake, version: "~> 0.8.7", groups: [development]}
|
27
|
+
- {name: bundler, version: "~> 1.0", groups: [development]}
|
28
|
+
- {name: rspec, version: "~> 2.4.0", groups: [development]}
|
29
|
+
- {name: yard, version: "~> 0.6.4", groups: [development]}
|
30
|
+
- {name: bluecloth, version: "~> 2.0.9", groups: [development]}
|
31
|
+
- {name: wlang, version: "~> 0.10.1", groups: [development]}
|
32
|
+
- {name: gnuplot, version: "~> 2.3.6", groups: [development]}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'stamina/stamina_test'
|
2
|
+
require 'stamina/abbadingo'
|
3
|
+
module Stamina
|
4
|
+
module Abbadingo
|
5
|
+
class RandomDFATest < StaminaTest
|
6
|
+
|
7
|
+
def test_it_looks_ok_with_default_options
|
8
|
+
dfa = RandomDFA.new(32).execute
|
9
|
+
assert dfa.deterministic?
|
10
|
+
assert dfa.minimal?
|
11
|
+
assert dfa.complete?
|
12
|
+
end
|
13
|
+
|
14
|
+
end # class RandomDFATest
|
15
|
+
end # module Abbadingo
|
16
|
+
end # module Stamina
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'stamina/stamina_test'
|
2
|
+
require 'stamina/abbadingo'
|
3
|
+
module Stamina
|
4
|
+
module Abbadingo
|
5
|
+
class RandomSampleTest < StaminaTest
|
6
|
+
|
7
|
+
def test_length_for
|
8
|
+
rs = RandomSample::StringEnumerator.new
|
9
|
+
assert_equal 0, rs.length_for(1)
|
10
|
+
assert_equal 1, rs.length_for(2)
|
11
|
+
assert_equal 1, rs.length_for(3)
|
12
|
+
assert_equal 2, rs.length_for(4)
|
13
|
+
assert_equal 2, rs.length_for(5)
|
14
|
+
assert_equal 2, rs.length_for(6)
|
15
|
+
assert_equal 2, rs.length_for(7)
|
16
|
+
assert_equal 3, rs.length_for(8)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_string_for
|
20
|
+
rs = RandomSample::StringEnumerator.new
|
21
|
+
assert_equal [], rs.string_for(1)
|
22
|
+
assert_equal ["0"], rs.string_for(2)
|
23
|
+
assert_equal ["1"], rs.string_for(3)
|
24
|
+
assert_equal ["0", "0"], rs.string_for(4)
|
25
|
+
assert_equal ["1", "0"], rs.string_for(5)
|
26
|
+
assert_equal ["0", "1"], rs.string_for(6)
|
27
|
+
assert_equal ["1", "1"], rs.string_for(7)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_string_for_generates_all_diff
|
31
|
+
rs = RandomSample::StringEnumerator.new
|
32
|
+
h = {}
|
33
|
+
(1..100).each{|i| h[rs.string_for(i)] = true}
|
34
|
+
assert_equal 100, h.size
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_string_for_respects_distribution
|
38
|
+
rs = RandomSample::StringEnumerator.new
|
39
|
+
lengths = Hash.new{|h,k| h[k] = 0}
|
40
|
+
(1..127).each{|i| lengths[rs.string_for(i).size] += 1}
|
41
|
+
assert_equal [0, 1, 2, 3, 4, 5, 6], lengths.keys.sort
|
42
|
+
prop = (0..6).collect{|i| lengths[i].to_f/128}
|
43
|
+
assert_equal [0.0078125, 0.015625, 0.03125, 0.0625, 0.125, 0.25, 0.5], prop
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_enumerator
|
47
|
+
enum = RandomSample::StringEnumerator.new(10)
|
48
|
+
lengths = Hash.new{|h,k| h[k] = 0}
|
49
|
+
20000.times{lengths[enum.one.size] += 1}
|
50
|
+
assert (lengths.keys.sort - (0..10).to_a).empty?
|
51
|
+
prop = (0..10).collect{|i| lengths[i].to_f/20000}
|
52
|
+
assert((prop[-1] >= 0.45) && (prop[-1] <= 0.55))
|
53
|
+
assert((prop[-2] >= 0.2) && (prop[-2] <= 0.3))
|
54
|
+
assert((prop[-3] >= 0.1) && (prop[-3] <= 0.15))
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_it_can_be_used_on_small_dfas
|
58
|
+
dfa = RandomDFA.new(16).execute
|
59
|
+
training, test = RandomSample.execute(dfa)
|
60
|
+
|
61
|
+
assert test.size > 0
|
62
|
+
assert training.size > 0
|
63
|
+
|
64
|
+
# check training sample
|
65
|
+
assert training.positive_count > 0
|
66
|
+
assert training.negative_count > 0
|
67
|
+
assert dfa.correctly_classify?(training)
|
68
|
+
|
69
|
+
# check test sample
|
70
|
+
assert test.positive_count > 0
|
71
|
+
assert test.negative_count > 0
|
72
|
+
assert dfa.correctly_classify?(test)
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
end # class RandomDFATest
|
77
|
+
end # module Abbadingo
|
78
|
+
end # module Stamina
|
data/test/stamina/adl_test.rb
CHANGED
@@ -486,6 +486,31 @@ module Stamina
|
|
486
486
|
EOF
|
487
487
|
end
|
488
488
|
end
|
489
|
+
|
490
|
+
def test_allows_error_states
|
491
|
+
dfa = ADL::parse_automaton <<-EOF
|
492
|
+
5 0
|
493
|
+
0 true true true
|
494
|
+
1 false false true
|
495
|
+
2 false false false
|
496
|
+
3 false true false
|
497
|
+
4 false true
|
498
|
+
EOF
|
499
|
+
assert dfa.ith_state(0).accepting? && dfa.ith_state(0).error?
|
500
|
+
assert !dfa.ith_state(1).accepting? && dfa.ith_state(1).error?
|
501
|
+
assert !dfa.ith_state(2).accepting? && !dfa.ith_state(2).error?
|
502
|
+
assert dfa.ith_state(3).accepting? && !dfa.ith_state(3).error?
|
503
|
+
assert !dfa.ith_state(4).error?
|
504
|
+
end
|
505
|
+
|
506
|
+
def test_flushes_error_states
|
507
|
+
dfa = ADL::parse_automaton <<-EOF
|
508
|
+
2 0
|
509
|
+
0 true false
|
510
|
+
1 false false true
|
511
|
+
EOF
|
512
|
+
assert_equal "1 false false true", dfa.to_adl.split("\n")[2].strip
|
513
|
+
end
|
514
|
+
|
489
515
|
end # class ADLTest
|
490
|
-
|
491
|
-
end # module Stamina
|
516
|
+
end # module Stamina
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'stamina/stamina_test'
|
3
|
+
module Stamina
|
4
|
+
class Automaton
|
5
|
+
class CompleteTest < StaminaTest
|
6
|
+
|
7
|
+
def test_on_not_complete
|
8
|
+
x, y, z = nil, nil, nil
|
9
|
+
dfa = Automaton.new(true) do |fa|
|
10
|
+
fa.alphabet = ["a", "b"]
|
11
|
+
x = fa.add_state(:initial => true, :accepting => true)
|
12
|
+
y = fa.add_state(:initial => false, :accepting => false)
|
13
|
+
fa.connect(0,1,'a')
|
14
|
+
fa.connect(1,0,'b')
|
15
|
+
end
|
16
|
+
|
17
|
+
assert_equal false, dfa.complete?
|
18
|
+
dfa.complete!
|
19
|
+
assert_equal true, dfa.complete?
|
20
|
+
|
21
|
+
assert_equal 3, dfa.state_count
|
22
|
+
z = dfa.ith_state(2)
|
23
|
+
assert_equal z, dfa.dfa_delta(x, "b")
|
24
|
+
assert_equal y, dfa.dfa_delta(x, "a")
|
25
|
+
assert_equal z, dfa.dfa_delta(y, "a")
|
26
|
+
assert_equal x, dfa.dfa_delta(y, "b")
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_on_complete
|
30
|
+
dfa = Automaton.new(true) do |fa|
|
31
|
+
fa.alphabet = ["a"]
|
32
|
+
fa.add_state(:initial => true, :accepting => true)
|
33
|
+
fa.add_state(:initial => false, :accepting => false)
|
34
|
+
fa.connect(0,1,'a')
|
35
|
+
fa.connect(1,0,'a')
|
36
|
+
end
|
37
|
+
assert_equal true, dfa.complete?
|
38
|
+
dfa.complete!
|
39
|
+
assert_equal 2, dfa.state_count
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_it_has_a_non_touching_impl
|
43
|
+
dfa = Automaton.new(true) do |fa|
|
44
|
+
fa.alphabet = ["a", "b"]
|
45
|
+
fa.add_state(:initial => true, :accepting => true)
|
46
|
+
fa.add_state(:initial => false, :accepting => false)
|
47
|
+
fa.connect(0,1,'a')
|
48
|
+
fa.connect(1,0,'b')
|
49
|
+
end
|
50
|
+
c = dfa.complete
|
51
|
+
assert_equal 2, dfa.state_count
|
52
|
+
assert_equal 3, c.state_count
|
53
|
+
end
|
54
|
+
|
55
|
+
end # class CompleteTest
|
56
|
+
end # class Automaton
|
57
|
+
end # module Stamina
|
58
|
+
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'stamina/stamina_test'
|
3
|
+
module Stamina
|
4
|
+
class Automaton
|
5
|
+
class EquivalenceTest < StaminaTest
|
6
|
+
|
7
|
+
def test_equivalence_on_small_dfa
|
8
|
+
assert_equal true, @small_dfa <=> @small_dfa
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_equivalence_on_real_case
|
12
|
+
dfa1 = Stamina::ADL.parse_automaton <<-EOF
|
13
|
+
3 5
|
14
|
+
0 true false
|
15
|
+
1 false false
|
16
|
+
2 false true
|
17
|
+
0 1 a
|
18
|
+
1 1 a
|
19
|
+
1 2 b
|
20
|
+
2 2 b
|
21
|
+
0 2 b
|
22
|
+
EOF
|
23
|
+
dfa2 = Stamina::ADL.parse_automaton <<-EOF
|
24
|
+
3 5
|
25
|
+
0 false true
|
26
|
+
1 true false
|
27
|
+
2 false false
|
28
|
+
0 0 b
|
29
|
+
1 2 a
|
30
|
+
1 0 b
|
31
|
+
2 2 a
|
32
|
+
2 0 b
|
33
|
+
EOF
|
34
|
+
dfa3 = Stamina::ADL.parse_automaton <<-EOF
|
35
|
+
3 5
|
36
|
+
0 false false
|
37
|
+
1 false true
|
38
|
+
2 true false
|
39
|
+
0 0 a
|
40
|
+
0 1 b
|
41
|
+
1 1 b
|
42
|
+
2 0 a
|
43
|
+
2 1 b
|
44
|
+
EOF
|
45
|
+
assert_equal true, dfa1 <=> dfa2
|
46
|
+
assert_equal true, dfa2 <=> dfa1
|
47
|
+
assert_equal true, dfa1 <=> dfa3
|
48
|
+
assert_equal true, dfa3 <=> dfa1
|
49
|
+
assert_equal true, dfa2 <=> dfa3
|
50
|
+
assert_equal true, dfa3 <=> dfa2
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_equivalence_does_not_change_the_automata
|
54
|
+
dfa1 = Stamina::ADL.parse_automaton <<-EOF
|
55
|
+
1 1
|
56
|
+
0 true true
|
57
|
+
0 0 a
|
58
|
+
EOF
|
59
|
+
assert_not_nil dfa1.initial_state
|
60
|
+
assert_equal true, dfa1 <=> dfa1
|
61
|
+
assert_not_nil dfa1.initial_state
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_non_equivalent_dfa_are_recognized_1
|
65
|
+
dfa1 = Stamina::ADL.parse_automaton <<-EOF
|
66
|
+
3 5
|
67
|
+
0 true false
|
68
|
+
1 false false
|
69
|
+
2 false true
|
70
|
+
0 1 a
|
71
|
+
1 1 a
|
72
|
+
1 2 b
|
73
|
+
2 2 b
|
74
|
+
0 2 b
|
75
|
+
EOF
|
76
|
+
assert_equal false, @small_dfa <=> dfa1
|
77
|
+
assert_equal false, dfa1 <=> @small_dfa
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_non_equivalent_dfa_are_recognized_2
|
81
|
+
dfa1 = Stamina::ADL.parse_automaton <<-EOF
|
82
|
+
5 4
|
83
|
+
0 true false
|
84
|
+
1 false false
|
85
|
+
2 false false
|
86
|
+
3 false false
|
87
|
+
4 false false
|
88
|
+
0 1 a
|
89
|
+
1 2 a
|
90
|
+
2 3 a
|
91
|
+
3 4 a
|
92
|
+
EOF
|
93
|
+
dfa2 = Stamina::ADL.parse_automaton <<-EOF
|
94
|
+
1 1
|
95
|
+
0 true true
|
96
|
+
0 0 a
|
97
|
+
EOF
|
98
|
+
assert_equal false, dfa2 <=> dfa1
|
99
|
+
assert_not_nil dfa1.initial_state
|
100
|
+
assert_not_nil dfa2.initial_state
|
101
|
+
assert_equal false, dfa1 <=> dfa2
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_equivalence_takes_care_of_state_flags
|
105
|
+
dfa1 = Stamina::ADL.parse_automaton <<-EOF
|
106
|
+
1 0
|
107
|
+
0 true false
|
108
|
+
EOF
|
109
|
+
dfa2 = Stamina::ADL.parse_automaton <<-EOF
|
110
|
+
1 0
|
111
|
+
0 true true
|
112
|
+
EOF
|
113
|
+
assert_equal false, dfa1 <=> dfa2
|
114
|
+
assert_equal false, dfa2 <=> dfa1
|
115
|
+
end
|
116
|
+
|
117
|
+
end # class EquivalenceTest
|
118
|
+
end # class Automaton
|
119
|
+
end # module Stamina
|
120
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.expand_path("../minimize_test", __FILE__)
|
2
|
+
module Stamina
|
3
|
+
class Automaton
|
4
|
+
module Minimize
|
5
|
+
class HopcroftTest < MinimizeTest
|
6
|
+
|
7
|
+
def algo
|
8
|
+
Hopcroft
|
9
|
+
end
|
10
|
+
|
11
|
+
end # class HopcroftTest
|
12
|
+
end # module Minimize
|
13
|
+
end # class Automaton
|
14
|
+
end # module Stamina
|
15
|
+
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'stamina/stamina_test'
|
3
|
+
module Stamina
|
4
|
+
class Automaton
|
5
|
+
module Minimize
|
6
|
+
class MinimizeTest < StaminaTest
|
7
|
+
|
8
|
+
# To be overriden
|
9
|
+
def algo
|
10
|
+
nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_on_unknown_1
|
14
|
+
return unless algo
|
15
|
+
dfa = load_adl_automaton("unknown_1.adl", __FILE__)
|
16
|
+
min = load_adl_automaton("unknown_1.min.adl", __FILE__)
|
17
|
+
assert_equivalent(algo.execute(dfa), min)
|
18
|
+
end
|
19
|
+
|
20
|
+
# From slide 10 in http://www.clear.rice.edu/comp412/Lectures/L07DFAMin-1up.pdf
|
21
|
+
def test_on_rice_edu_10
|
22
|
+
return unless algo
|
23
|
+
dfa = load_adl_automaton("rice_edu_10.adl", __FILE__)
|
24
|
+
min = load_adl_automaton("rice_edu_10.min.adl", __FILE__)
|
25
|
+
assert_equivalent(algo.execute(dfa), min)
|
26
|
+
end
|
27
|
+
|
28
|
+
# From slide 13 in http://www.clear.rice.edu/comp412/Lectures/L07DFAMin-1up.pdf
|
29
|
+
def test_on_rice_edu_13
|
30
|
+
return unless algo
|
31
|
+
dfa = load_adl_automaton("rice_edu_13.adl", __FILE__)
|
32
|
+
min = load_adl_automaton("rice_edu_13.min.adl", __FILE__)
|
33
|
+
assert_equivalent(algo.execute(dfa), min)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_it_strips_when_needed
|
37
|
+
return unless algo
|
38
|
+
dfa = load_adl_automaton("should_strip_1.adl", __FILE__)
|
39
|
+
min = load_adl_automaton("should_strip_1.min.adl", __FILE__)
|
40
|
+
assert_equivalent(algo.execute(dfa), min)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_it_has_no_effect_on_already_minimal
|
44
|
+
return unless algo
|
45
|
+
dfa = load_adl_automaton("rice_edu_13.min.adl", __FILE__)
|
46
|
+
min = algo.execute(dfa)
|
47
|
+
assert_equal dfa.complete.state_count, min.complete.state_count
|
48
|
+
assert_equivalent(min, dfa)
|
49
|
+
end
|
50
|
+
|
51
|
+
end # class MinimizeTest
|
52
|
+
end # module Minimize
|
53
|
+
end # class Automaton
|
54
|
+
end # module Stamina
|
55
|
+
|