stamina 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +22 -5
- data/LICENCE.md +2 -2
- data/bin/stamina +1 -7
- data/lib/stamina.rb +10 -19
- metadata +54 -333
- data/.gemtest +0 -0
- data/Gemfile +0 -2
- data/Gemfile.lock +0 -37
- data/Manifest.txt +0 -16
- data/README.md +0 -78
- data/Rakefile +0 -23
- data/example/adl/automaton.adl +0 -49
- data/example/adl/sample.adl +0 -53
- data/example/basic/characteristic_sample.adl +0 -32
- data/example/basic/target.adl +0 -9
- data/example/competition/31_test.adl +0 -1500
- data/example/competition/31_training.adl +0 -1759
- data/lib/stamina/abbadingo.rb +0 -2
- data/lib/stamina/abbadingo/random_dfa.rb +0 -48
- data/lib/stamina/abbadingo/random_sample.rb +0 -146
- data/lib/stamina/adl.rb +0 -298
- data/lib/stamina/automaton.rb +0 -1263
- data/lib/stamina/automaton/complete.rb +0 -36
- data/lib/stamina/automaton/equivalence.rb +0 -55
- data/lib/stamina/automaton/metrics.rb +0 -78
- data/lib/stamina/automaton/minimize.rb +0 -25
- data/lib/stamina/automaton/minimize/hopcroft.rb +0 -116
- data/lib/stamina/automaton/minimize/pitchies.rb +0 -64
- data/lib/stamina/automaton/strip.rb +0 -16
- data/lib/stamina/automaton/walking.rb +0 -363
- data/lib/stamina/classifier.rb +0 -52
- data/lib/stamina/command.rb +0 -45
- data/lib/stamina/command/abbadingo_dfa.rb +0 -81
- data/lib/stamina/command/abbadingo_samples.rb +0 -40
- data/lib/stamina/command/adl2dot.rb +0 -71
- data/lib/stamina/command/classify.rb +0 -48
- data/lib/stamina/command/help.rb +0 -27
- data/lib/stamina/command/infer.rb +0 -141
- data/lib/stamina/command/metrics.rb +0 -51
- data/lib/stamina/command/robustness.rb +0 -22
- data/lib/stamina/command/score.rb +0 -35
- data/lib/stamina/errors.rb +0 -23
- data/lib/stamina/ext/math.rb +0 -20
- data/lib/stamina/induction/blue_fringe.rb +0 -265
- data/lib/stamina/induction/commons.rb +0 -156
- data/lib/stamina/induction/rpni.rb +0 -186
- data/lib/stamina/induction/union_find.rb +0 -377
- data/lib/stamina/input_string.rb +0 -123
- data/lib/stamina/loader.rb +0 -1
- data/lib/stamina/markable.rb +0 -42
- data/lib/stamina/sample.rb +0 -267
- data/lib/stamina/scoring.rb +0 -213
- data/lib/stamina/utils.rb +0 -1
- data/lib/stamina/utils/decorate.rb +0 -81
- data/lib/stamina/version.rb +0 -14
- data/stamina.gemspec +0 -191
- data/stamina.noespec +0 -32
- data/tasks/debug_mail.rake +0 -78
- data/tasks/debug_mail.txt +0 -13
- data/tasks/gem.rake +0 -68
- data/tasks/spec_test.rake +0 -79
- data/tasks/unit_test.rake +0 -77
- data/tasks/yard.rake +0 -51
- data/test/stamina/abbadingo/random_dfa_test.rb +0 -16
- data/test/stamina/abbadingo/random_sample_test.rb +0 -78
- data/test/stamina/adl_test.rb +0 -516
- data/test/stamina/automaton/classifier_test.rb +0 -259
- data/test/stamina/automaton/complete_test.rb +0 -58
- data/test/stamina/automaton/equivalence_test.rb +0 -120
- data/test/stamina/automaton/metrics_test.rb +0 -36
- data/test/stamina/automaton/minimize/hopcroft_test.rb +0 -15
- data/test/stamina/automaton/minimize/minimize_test.rb +0 -55
- data/test/stamina/automaton/minimize/pitchies_test.rb +0 -15
- data/test/stamina/automaton/minimize/rice_edu_10.adl +0 -16
- data/test/stamina/automaton/minimize/rice_edu_10.min.adl +0 -13
- data/test/stamina/automaton/minimize/rice_edu_13.adl +0 -13
- data/test/stamina/automaton/minimize/rice_edu_13.min.adl +0 -7
- data/test/stamina/automaton/minimize/should_strip_1.adl +0 -8
- data/test/stamina/automaton/minimize/should_strip_1.min.adl +0 -6
- data/test/stamina/automaton/minimize/unknown_1.adl +0 -16
- data/test/stamina/automaton/minimize/unknown_1.min.adl +0 -12
- data/test/stamina/automaton/strip_test.rb +0 -36
- data/test/stamina/automaton/to_dot_test.rb +0 -64
- data/test/stamina/automaton/walking/dfa_delta_test.rb +0 -39
- data/test/stamina/automaton/walking_test.rb +0 -206
- data/test/stamina/automaton_additional_test.rb +0 -190
- data/test/stamina/automaton_test.rb +0 -1104
- data/test/stamina/exit.rb +0 -3
- data/test/stamina/induction/blue_fringe_test.rb +0 -83
- data/test/stamina/induction/induction_test.rb +0 -70
- data/test/stamina/induction/redblue_mergesamestatebug_expected.adl +0 -19
- data/test/stamina/induction/redblue_mergesamestatebug_pta.dot +0 -64
- data/test/stamina/induction/redblue_mergesamestatebug_sample.adl +0 -9
- data/test/stamina/induction/redblue_universal_expected.adl +0 -4
- data/test/stamina/induction/redblue_universal_sample.adl +0 -5
- data/test/stamina/induction/rpni_inria_expected.adl +0 -7
- data/test/stamina/induction/rpni_inria_sample.adl +0 -9
- data/test/stamina/induction/rpni_test.rb +0 -129
- data/test/stamina/induction/rpni_test_pta.dot +0 -22
- data/test/stamina/induction/rpni_universal_expected.adl +0 -4
- data/test/stamina/induction/rpni_universal_sample.adl +0 -4
- data/test/stamina/induction/union_find_test.rb +0 -124
- data/test/stamina/input_string_test.rb +0 -323
- data/test/stamina/markable_test.rb +0 -70
- data/test/stamina/randdfa.adl +0 -66
- data/test/stamina/sample.adl +0 -4
- data/test/stamina/sample_classify_test.rb +0 -149
- data/test/stamina/sample_test.rb +0 -290
- data/test/stamina/scoring_test.rb +0 -63
- data/test/stamina/small_dfa.dot +0 -16
- data/test/stamina/small_dfa.gif +0 -0
- data/test/stamina/small_nfa.dot +0 -18
- data/test/stamina/small_nfa.gif +0 -0
- data/test/stamina/stamina_test.rb +0 -80
- data/test/stamina/utils/decorate_test.rb +0 -65
- data/test/test_all.rb +0 -7
data/lib/stamina/classifier.rb
DELETED
@@ -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
|
data/lib/stamina/command.rb
DELETED
@@ -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
|
-
|
data/lib/stamina/command/help.rb
DELETED
@@ -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
|
-
|