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,52 +0,0 @@
1
- module Stamina
2
- #
3
- # Provides a reusable module for binary classifiers. Classes including this
4
- # module are required to provide a label_of(string) method, returning '1' for
5
- # strings considered positive, and '0' fr strings considered negative.
6
- #
7
- # Note that an Automaton being a classifier it already includes this module.
8
- #
9
- module Classifier
10
-
11
- #
12
- # Computes a signature for a given sample (that is, an ordered set of strings).
13
- # The signature is a string containing 1 (considered positive, or accepted)
14
- # and 0 (considered negative, or rejected), one for each string.
15
- #
16
- def signature(sample)
17
- signature = ''
18
- sample.each do |str|
19
- signature << label_of(str)
20
- end
21
- signature
22
- end
23
- alias :classification_signature :signature
24
-
25
- #
26
- # Classifies a sample then compute the classification scoring that is obtained
27
- # by comparing the signature obtained by classification and the one of the sample
28
- # itself. Returns an object responding to methods defined in Scoring module.
29
- #
30
- # This method is actually a convenient shortcut for:
31
- #
32
- # Stamina::Scoring.scoring(signature(sample), sample.signature)
33
- #
34
- def scoring(sample)
35
- Stamina::Scoring.scoring(signature(sample), sample.signature)
36
- end
37
- alias :classification_scoring :scoring
38
-
39
- #
40
- # Checks if a labeled sample is correctly classified by the classifier.
41
- #
42
- def correctly_classify?(sample)
43
- sample.each do |str|
44
- label = label_of(str)
45
- expected = (str.positive? ? '1' : '0')
46
- return false unless expected==label
47
- end
48
- true
49
- end
50
-
51
- end # module Classifier
52
- end # module Stamina
@@ -1,45 +0,0 @@
1
- require 'stamina'
2
- module Stamina
3
- #
4
- # Stamina - A Ruby Automaton & Induction Toolkit
5
- #
6
- # SYNOPSIS
7
- # #{program_name} [--version] [--help] COMMAND [cmd opts] ARGS...
8
- #
9
- # OPTIONS
10
- # #{summarized_options}
11
- #
12
- # COMMANDS
13
- # #{summarized_subcommands}
14
- #
15
- # See '#{program_name} help COMMAND' for more information on a specific command.
16
- #
17
- class Command < ::Quickl::Delegator(__FILE__, __LINE__)
18
-
19
- # Install options
20
- options do |opt|
21
-
22
- # Show the help and exit
23
- opt.on_tail("--help", "Show help") do
24
- raise Quickl::Help
25
- end
26
-
27
- # Show version and exit
28
- opt.on_tail("--version", "Show version") do
29
- raise Quickl::Exit, "#{program_name} #{VERSION} (c) 2010-2011, Bernard Lambeau"
30
- end
31
-
32
- end
33
-
34
- end # class Command
35
- end # module Stamina
36
- require 'stamina/command/robustness'
37
- require 'stamina/command/help'
38
- require 'stamina/command/adl2dot'
39
- require 'stamina/command/metrics'
40
- require 'stamina/command/classify'
41
- require 'stamina/command/score'
42
- require 'stamina/command/abbadingo_dfa'
43
- require 'stamina/command/abbadingo_samples'
44
- require 'stamina/command/infer'
45
-
@@ -1,81 +0,0 @@
1
- module Stamina
2
- class Command
3
- #
4
- # Generates a DFA following Abbadingo's protocol
5
- #
6
- # SYNOPSIS
7
- # #{program_name} #{command_name}
8
- #
9
- # OPTIONS
10
- # #{summarized_options}
11
- #
12
- class AbbadingoDfa < Quickl::Command(__FILE__, __LINE__)
13
- include Robustness
14
-
15
- # Size of the target automaton
16
- attr_accessor :size
17
-
18
- # Tolerance on the size
19
- attr_accessor :size_tolerance
20
-
21
- # Tolerance on the automaton depth
22
- attr_accessor :depth_tolerance
23
-
24
- # Where to flush the dfa
25
- attr_accessor :output_file
26
-
27
- # Install options
28
- options do |opt|
29
-
30
- @size = 64
31
- opt.on("--size=X", Integer, "Sets the size of the automaton to generate") do |x|
32
- @size = x
33
- end
34
-
35
- @size_tolerance = nil
36
- opt.on("--size-tolerance[=X]", Integer, "Sets the tolerance on automaton size (in number of states)") do |x|
37
- @size_tolerance = x
38
- end
39
-
40
- @depth_tolerance = 0
41
- opt.on("--depth-tolerance[=X]", Integer, "Sets the tolerance on expected automaton depth (in length, 0 by default)") do |x|
42
- @depth_tolerance = x
43
- end
44
-
45
- @output_file = nil
46
- opt.on("-o", "--output=OUTPUT",
47
- "Flush DFA in output file") do |value|
48
- @output_file = assert_writable_file(value)
49
- end
50
-
51
- end # options
52
-
53
- def accept?(dfa)
54
- (size_tolerance.nil? || (size - dfa.state_count).abs <= size_tolerance) &&
55
- (depth_tolerance.nil? || ((2*Math.log2(size)-2) - dfa.depth).abs <= depth_tolerance)
56
- end
57
-
58
- # Command execution
59
- def execute(args)
60
- require 'stamina/abbadingo'
61
-
62
- # generate it
63
- randomizer = Stamina::Abbadingo::RandomDFA.new(size)
64
- begin
65
- dfa = randomizer.execute
66
- end until accept?(dfa)
67
-
68
- # flush it
69
- if output_file
70
- File.open(output_file, 'w') do |file|
71
- Stamina::ADL.print_automaton(dfa, file)
72
- end
73
- else
74
- Stamina::ADL.print_automaton(dfa, $stdout)
75
- end
76
- end
77
-
78
- end # class AbbadingoDFA
79
- end # class Command
80
- end # module Stamina
81
-
@@ -1,40 +0,0 @@
1
- module Stamina
2
- class Command
3
- #
4
- # Generates samples following Abbadingo's protocol
5
- #
6
- # SYNOPSIS
7
- # #{program_name} #{command_name} target.adl
8
- #
9
- # OPTIONS
10
- # #{summarized_options}
11
- #
12
- class AbbadingoSamples < Quickl::Command(__FILE__, __LINE__)
13
-
14
- # Install options
15
- options do |opt|
16
-
17
- end # options
18
-
19
- # Command execution
20
- def execute(args)
21
- raise Quickl::Help unless args.size == 1
22
-
23
- # Loads the target automaton
24
- target_file = args.first
25
- basename = File.basename(target_file, '.adl')
26
- dirname = File.dirname(target_file)
27
- target = Stamina::ADL::parse_automaton_file(target_file)
28
-
29
- require 'stamina/abbadingo'
30
- training, test = Stamina::Abbadingo::RandomSample.execute(target)
31
-
32
- # Flush results aside the target automaton file
33
- Stamina::ADL::print_sample_in_file(training, File.join(dirname, "#{basename}-training.adl"))
34
- Stamina::ADL::print_sample_in_file(test, File.join(dirname, "#{basename}-test.adl"))
35
- end
36
-
37
- end # class AbbadingoSamples
38
- end # class Command
39
- end # module Stamina
40
-
@@ -1,71 +0,0 @@
1
- module Stamina
2
- class Command
3
- #
4
- # Prints an automaton expressed in ADL in dot (or gif) format
5
- #
6
- # SYNOPSIS
7
- # #{program_name} #{command_name} automaton.adl
8
- #
9
- # OPTIONS
10
- # #{summarized_options}
11
- #
12
- class Adl2dot < Quickl::Command(__FILE__, __LINE__)
13
- include Robustness
14
-
15
- attr_reader :gif_output
16
-
17
- # Install options
18
- options do |opt|
19
-
20
- @output_file = nil
21
- opt.on("-o", "--output=OUTPUT",
22
- "Flush result output file") do |value|
23
- @output_file = assert_writable_file(value)
24
- end
25
-
26
- opt.on("-g", "--gif",
27
- "Generates a gif file instead of a dot one") do
28
- @gif_output = true
29
- end
30
-
31
- end # options
32
-
33
- def output_file(infile)
34
- @output_file || "#{File.basename(infile || 'stdin.adl', '.adl')}.#{gif_output ? 'gif' : 'dot'}"
35
- end
36
-
37
- # Command execution
38
- def execute(args)
39
- raise Quickl::Help unless args.size <= 1
40
-
41
- # Loads the target automaton
42
- input = if args.size == 1
43
- File.read assert_readable_file(args.first)
44
- else
45
- $stdin.readlines.join("\n")
46
- end
47
- automaton = Stamina::ADL::parse_automaton(input)
48
-
49
- # create a file for the dot output
50
- if gif_output
51
- require 'tempfile'
52
- dotfile = Tempfile.new("stamina").path
53
- else
54
- dotfile = output_file(args.first)
55
- end
56
-
57
- # Flush automaton inside it
58
- File.open(dotfile, 'w') do |f|
59
- f << automaton.to_dot
60
- end
61
-
62
- # if gif output, use dot to convert it
63
- if gif_output
64
- `dot -Tgif -o #{output_file(args.first)} #{dotfile}`
65
- end
66
- end
67
-
68
- end # class Adl2dot
69
- end # class Command
70
- end # module Stamina
71
-
@@ -1,48 +0,0 @@
1
- module Stamina
2
- class Command
3
- #
4
- # Classifies a sample thanks with an automaton
5
- #
6
- # SYNOPSIS
7
- # #{program_name} #{command_name} sample.adl automaton.adl
8
- #
9
- # OPTIONS
10
- # #{summarized_options}
11
- #
12
- class Classify < Quickl::Command(__FILE__, __LINE__)
13
- include Robustness
14
-
15
- # Where to flush the output
16
- attr_accessor :output_file
17
-
18
- # Install options
19
- options do |opt|
20
-
21
- @output_file = nil
22
- opt.on("-o", "--output=OUTPUT",
23
- "Flush classification signature in output file") do |value|
24
- assert_writable_file(value)
25
- @output_file = value
26
- end
27
-
28
- end # options
29
-
30
- # Command execution
31
- def execute(args)
32
- raise Quickl::Help unless args.size == 2
33
- sample = Stamina::ADL::parse_sample_file assert_readable_file(args.first)
34
- automaton = Stamina::ADL::parse_automaton_file assert_readable_file(args.last)
35
-
36
- if of = output_file
37
- File.open(of, 'w'){|io|
38
- io << automaton.signature(sample)
39
- }
40
- else
41
- $stdout << automaton.signature(sample)
42
- end
43
- end
44
-
45
- end # class Classify
46
- end # class Command
47
- end # module Stamina
48
-
@@ -1,27 +0,0 @@
1
- module Stamina
2
- class Command
3
- #
4
- # Show help about a specific command
5
- #
6
- # SYNOPSIS
7
- # #{program_name} #{command_name} COMMAND
8
- #
9
- class Help < Quickl::Command(__FILE__, __LINE__)
10
-
11
- # Let NoSuchCommandError be passed to higher stage
12
- no_react_to Quickl::NoSuchCommand
13
-
14
- # Command execution
15
- def execute(args)
16
- if args.size != 1
17
- puts super_command.help
18
- else
19
- cmd = has_command!(args.first, super_command)
20
- puts cmd.help
21
- end
22
- end
23
-
24
- end # class Help
25
- end # class Command
26
- end # module Stamina
27
-
@@ -1,141 +0,0 @@
1
- module Stamina
2
- class Command
3
- #
4
- # Grammar inference, induces a DFA from a training sample using an
5
- # chosen algorithm.
6
- #
7
- # SYNOPSIS
8
- # #{program_name} #{command_name} sample.adl
9
- #
10
- # OPTIONS
11
- # #{summarized_options}
12
- #
13
- class Infer < Quickl::Command(__FILE__, __LINE__)
14
- include Robustness
15
-
16
- attr_accessor :algorithm
17
- attr_accessor :take
18
- attr_accessor :score
19
- attr_accessor :verbose
20
- attr_accessor :drop
21
- attr_accessor :output_file
22
-
23
- # Install options
24
- options do |opt|
25
-
26
- @algorithm = :rpni
27
- opt.on("--algorithm=X", "Sets the induction algorithm to use (rpni, bluefringe)") do |x|
28
- @algorithm = x.to_sym
29
- end
30
-
31
- @take = 1.0
32
- opt.on("--take=X", Float, "Take only X% of available strings") do |x|
33
- @take = x.to_f
34
- unless @take > 0.0 and @take <= 1.0
35
- raise Quickl::InvalidOption, "Invalid --take option: #{@take}"
36
- end
37
- end
38
-
39
- @score = nil
40
- opt.on("--score=test.adl", "Add scoring information to metadata, using test.adl file") do |x|
41
- @score = assert_readable_file(x)
42
- end
43
-
44
- @verbose = true
45
- opt.on("-v", "--[no-]verbose", "Verbose mode") do |x|
46
- @verbose = x
47
- end
48
-
49
- @drop = false
50
- opt.on("-d", "--drop", "Drop result") do |x|
51
- @drop = x
52
- end
53
-
54
- @output_file = nil
55
- opt.on("-o", "--output=OUTPUT",
56
- "Flush induced DFA in output file") do |value|
57
- @output_file = assert_writable_file(value)
58
- end
59
-
60
- end # options
61
-
62
- def launch_induction(sample)
63
- require 'benchmark'
64
-
65
- algo_clazz = case algorithm
66
- when :rpni
67
- Stamina::Induction::RPNI
68
- when :bluefringe
69
- Stamina::Induction::BlueFringe
70
- else
71
- raise Quickl::InvalidOption, "Unknown induction algorithm: #{algo}"
72
- end
73
-
74
- dfa, tms = nil, nil
75
- tms = Benchmark.measure do
76
- dfa = algo_clazz.execute(sample, {:verbose => verbose})
77
- end
78
- [dfa, tms]
79
- end
80
-
81
- def load_sample(file)
82
- sample = Stamina::ADL.parse_sample_file(file)
83
- if @take != 1.0
84
- sampled = Stamina::Sample.new
85
- sample.each_positive{|s| sampled << s if Kernel.rand < @take}
86
- sample.each_negative{|s| sampled << s if Kernel.rand < @take}
87
- sample = sampled
88
- end
89
- sample
90
- end
91
-
92
- # Command execution
93
- def execute(args)
94
- raise Quickl::Help unless args.size == 1
95
-
96
- # Parses the sample
97
- $stderr << "Parsing sample...\n" if verbose
98
- sample = load_sample(assert_readable_file(args.first))
99
-
100
- # Induce the DFA
101
- dfa, tms = launch_induction(sample)
102
-
103
- # Flush result
104
- unless drop
105
- if output_file
106
- File.open(output_file, 'w') do |file|
107
- Stamina::ADL.print_automaton(dfa, file)
108
- end
109
- else
110
- Stamina::ADL.print_automaton(dfa, $stdout)
111
- end
112
- end
113
-
114
- # build meta information
115
- meta = {:algorithm => algorithm,
116
- :sample => File.basename(args.first),
117
- :take => take,
118
- :sample_size => sample.size,
119
- :positive_count => sample.positive_count,
120
- :negative_count => sample.negative_count,
121
- :real_time => tms.real,
122
- :total_time => tms.total,
123
- :user_time => tms.utime + tms.cutime,
124
- :system_time => tms.stime + tms.cstime}
125
-
126
- if score
127
- test = Stamina::ADL::parse_sample_file(score)
128
- classified_as = dfa.signature(test)
129
- reference = test.signature
130
- scoring = Scoring.scoring(classified_as, reference)
131
- meta.merge!(scoring.to_h)
132
- end
133
-
134
- # Display information
135
- puts meta.inspect
136
- end
137
-
138
- end # class Infer
139
- end # class Command
140
- end # module Stamina
141
-