stamina 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/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
|
+
|