stamina 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/CHANGELOG.md +24 -0
  2. data/Gemfile.lock +5 -1
  3. data/bin/stamina +10 -0
  4. data/lib/stamina.rb +2 -1
  5. data/lib/stamina/abbadingo.rb +2 -0
  6. data/lib/stamina/abbadingo/random_dfa.rb +48 -0
  7. data/lib/stamina/abbadingo/random_sample.rb +146 -0
  8. data/lib/stamina/adl.rb +6 -6
  9. data/lib/stamina/automaton.rb +29 -4
  10. data/lib/stamina/automaton/complete.rb +36 -0
  11. data/lib/stamina/automaton/equivalence.rb +55 -0
  12. data/lib/stamina/automaton/metrics.rb +8 -1
  13. data/lib/stamina/automaton/minimize.rb +25 -0
  14. data/lib/stamina/automaton/minimize/hopcroft.rb +116 -0
  15. data/lib/stamina/automaton/minimize/pitchies.rb +64 -0
  16. data/lib/stamina/automaton/strip.rb +16 -0
  17. data/lib/stamina/automaton/walking.rb +46 -19
  18. data/lib/stamina/command.rb +45 -0
  19. data/lib/stamina/command/abbadingo_dfa.rb +81 -0
  20. data/lib/stamina/command/abbadingo_samples.rb +40 -0
  21. data/lib/stamina/command/adl2dot.rb +71 -0
  22. data/lib/stamina/command/classify.rb +48 -0
  23. data/lib/stamina/command/help.rb +27 -0
  24. data/lib/stamina/command/infer.rb +141 -0
  25. data/lib/stamina/command/metrics.rb +51 -0
  26. data/lib/stamina/command/robustness.rb +22 -0
  27. data/lib/stamina/command/score.rb +35 -0
  28. data/lib/stamina/errors.rb +4 -1
  29. data/lib/stamina/ext/math.rb +20 -0
  30. data/lib/stamina/induction/{redblue.rb → blue_fringe.rb} +29 -28
  31. data/lib/stamina/induction/commons.rb +32 -46
  32. data/lib/stamina/induction/rpni.rb +7 -9
  33. data/lib/stamina/induction/union_find.rb +3 -3
  34. data/lib/stamina/loader.rb +1 -0
  35. data/lib/stamina/sample.rb +79 -2
  36. data/lib/stamina/scoring.rb +37 -0
  37. data/lib/stamina/version.rb +2 -2
  38. data/stamina.gemspec +2 -1
  39. data/stamina.noespec +9 -12
  40. data/test/stamina/abbadingo/random_dfa_test.rb +16 -0
  41. data/test/stamina/abbadingo/random_sample_test.rb +78 -0
  42. data/test/stamina/adl_test.rb +27 -2
  43. data/test/stamina/automaton/complete_test.rb +58 -0
  44. data/test/stamina/automaton/equivalence_test.rb +120 -0
  45. data/test/stamina/automaton/minimize/hopcroft_test.rb +15 -0
  46. data/test/stamina/automaton/minimize/minimize_test.rb +55 -0
  47. data/test/stamina/automaton/minimize/pitchies_test.rb +15 -0
  48. data/test/stamina/automaton/minimize/rice_edu_10.adl +16 -0
  49. data/test/stamina/automaton/minimize/rice_edu_10.min.adl +13 -0
  50. data/test/stamina/automaton/minimize/rice_edu_13.adl +13 -0
  51. data/test/stamina/automaton/minimize/rice_edu_13.min.adl +7 -0
  52. data/test/stamina/automaton/minimize/should_strip_1.adl +8 -0
  53. data/test/stamina/automaton/minimize/should_strip_1.min.adl +6 -0
  54. data/test/stamina/automaton/minimize/unknown_1.adl +16 -0
  55. data/test/stamina/automaton/minimize/unknown_1.min.adl +12 -0
  56. data/test/stamina/automaton/strip_test.rb +36 -0
  57. data/test/stamina/automaton/walking/dfa_delta_test.rb +39 -0
  58. data/test/stamina/automaton_test.rb +13 -1
  59. data/test/stamina/induction/{redblue_test.rb → blue_fringe_test.rb} +22 -22
  60. data/test/stamina/sample_test.rb +75 -0
  61. data/test/stamina/stamina_test.rb +13 -2
  62. metadata +98 -23
  63. data/bin/adl2dot +0 -12
  64. data/bin/classify +0 -12
  65. data/bin/redblue +0 -12
  66. data/bin/rpni +0 -12
  67. data/lib/stamina/command/adl2dot_command.rb +0 -73
  68. data/lib/stamina/command/classify_command.rb +0 -57
  69. data/lib/stamina/command/redblue_command.rb +0 -58
  70. data/lib/stamina/command/rpni_command.rb +0 -58
  71. data/lib/stamina/command/stamina_command.rb +0 -79
data/bin/adl2dot DELETED
@@ -1,12 +0,0 @@
1
- #!/usr/bin/env ruby
2
- $LOAD_PATH << File.join(File.dirname(__FILE__),'..','lib')
3
- require "stamina"
4
- require "stamina/command/adl2dot_command"
5
- begin
6
- Stamina::Command::Adl2DotCommand.new.main(ARGV)
7
- rescue => ex
8
- puts "Internal error occured, sorry for the inconvenience."
9
- puts "If the problem persists, please contact Stamina developpers with the \
10
- following backtrace:"
11
- raise ex
12
- end
data/bin/classify DELETED
@@ -1,12 +0,0 @@
1
- #!/usr/bin/env ruby
2
- $LOAD_PATH << File.join(File.dirname(__FILE__),'..','lib')
3
- require "stamina"
4
- require "stamina/command/classify_command"
5
- begin
6
- Stamina::Command::ClassifyCommand.new.main(ARGV)
7
- rescue => ex
8
- puts "Internal error occured, sorry for the inconvenience."
9
- puts "If the problem persists, please contact Stamina developpers with the \
10
- following backtrace:"
11
- raise ex
12
- end
data/bin/redblue DELETED
@@ -1,12 +0,0 @@
1
- #!/usr/bin/env ruby
2
- $LOAD_PATH << File.join(File.dirname(__FILE__),'..','lib')
3
- require "stamina"
4
- require "stamina/command/redblue_command"
5
- begin
6
- Stamina::Command::RedBlueCommand.new.main(ARGV)
7
- rescue => ex
8
- puts "Internal error occured, sorry for the inconvenience."
9
- puts "If the problem persists, please contact Stamina developpers with the \
10
- following backtrace:"
11
- raise ex
12
- end
data/bin/rpni DELETED
@@ -1,12 +0,0 @@
1
- #!/usr/bin/env ruby
2
- $LOAD_PATH << File.join(File.dirname(__FILE__),'..','lib')
3
- require "stamina"
4
- require "stamina/command/rpni_command"
5
- begin
6
- Stamina::Command::RPNICommand.new.main(ARGV)
7
- rescue => ex
8
- puts "Internal error occured, sorry for the inconvenience."
9
- puts "If the problem persists, please contact Stamina developpers with the \
10
- following backtrace:"
11
- raise ex
12
- end
@@ -1,73 +0,0 @@
1
- require 'stamina/command/stamina_command'
2
- module Stamina
3
- module Command
4
-
5
- # Implementation of the adl2dot command line tool
6
- class Adl2DotCommand < StaminaCommand
7
-
8
- # Gif output instead of dot?
9
- attr_reader :gif_output
10
-
11
- # Creates a score command instance
12
- def initialize
13
- super("adl2dot", "[options] automaton.adl",
14
- "Prints an automaton expressed in ADL in dot (or gif) format")
15
- @gif_output = false
16
- end
17
-
18
- # Installs additional options
19
- def options
20
- super do |opt|
21
- opt.on("-o", "--output=OUTPUT",
22
- "Flush result output file") do |value|
23
- assert_writable_file(value)
24
- @output_file = value
25
- end
26
- opt.on("-g", "--gif",
27
- "Generates a gif file instead of a dot one") do
28
- @gif_output = true
29
- end
30
- end
31
- end
32
-
33
- # Sets the automaton file
34
- def automaton_file=(file)
35
- assert_readable_file(file)
36
- @automaton_file = file
37
- @automaton = Stamina::ADL.parse_automaton_file(file)
38
- rescue Stamina::ADL::ParseError
39
- raise ArgumentError, "#{file} is not a valid ADL automaton file"
40
- end
41
-
42
- # Returns the output file to use
43
- def output_file
44
- @output_file || "#{File.basename(@automaton_file, '.adl')}.#{gif_output ? 'gif' : 'dot'}"
45
- end
46
-
47
- # Executes the command
48
- def main(argv)
49
- parse(argv, :automaton_file)
50
-
51
- # create a file for the dot output
52
- if gif_output
53
- require 'tempfile'
54
- dotfile = Tempfile.new("stamina").path
55
- else
56
- dotfile = output_file
57
- end
58
-
59
- # Flush automaton inside it
60
- File.open(dotfile, 'w') do |f|
61
- f << Stamina::ADL.parse_automaton_file(@automaton_file).to_dot
62
- end
63
-
64
- # if gif output, use dot to convert it
65
- if gif_output
66
- `dot -Tgif -o #{output_file} #{dotfile}`
67
- end
68
- end
69
-
70
- end # class ScoreCommand
71
-
72
- end # module Command
73
- end # module Stamina
@@ -1,57 +0,0 @@
1
- require 'stamina/command/stamina_command'
2
- require 'stamina/induction/rpni'
3
- module Stamina
4
- module Command
5
-
6
- # Implementation of the classify command line tool
7
- class ClassifyCommand < StaminaCommand
8
-
9
- # Creates a score command instance
10
- def initialize
11
- super("classify", "[options] sample.adl automaton.adl",
12
- "Classify a sample using an automaton, both expressed in ADL")
13
- end
14
-
15
- # Installs additional options
16
- def options
17
- super do |opt|
18
- opt.on("-o", "--output=OUTPUT",
19
- "Flush classification signature in output file") do |value|
20
- assert_writable_file(value)
21
- @output_file = value
22
- end
23
- end
24
- end
25
-
26
- # Sets the sample file
27
- def sample_file=(file)
28
- assert_readable_file(file)
29
- @sample = Stamina::ADL.parse_sample_file(file)
30
- rescue Stamina::ADL::ParseError
31
- raise ArgumentError, "#{file} is not a valid ADL sample file"
32
- end
33
-
34
- # Sets the automaton file
35
- def automaton_file=(file)
36
- assert_readable_file(file)
37
- @automaton = Stamina::ADL.parse_automaton_file(file)
38
- rescue Stamina::ADL::ParseError
39
- raise ArgumentError, "#{file} is not a valid ADL automaton file"
40
- end
41
-
42
- # Executes the command
43
- def main(argv)
44
- parse(argv, :sample_file, :automaton_file)
45
- if @output_file
46
- File.open(@output_file, 'w') do |file|
47
- file << @automaton.signature(@sample) << "\n"
48
- end
49
- else
50
- STDOUT << @automaton.signature(@sample) << "\n"
51
- end
52
- end
53
-
54
- end # class ClassifyCommand
55
-
56
- end # module Command
57
- end # module Stamina
@@ -1,58 +0,0 @@
1
- require 'stamina/command/stamina_command'
2
- require 'stamina/induction/redblue'
3
- module Stamina
4
- module Command
5
-
6
- # Implementation of the redblue command line tool
7
- class RedBlueCommand < StaminaCommand
8
-
9
- # Creates a score command instance
10
- def initialize
11
- super("redblue", "[options] sample.adl",
12
- "Executes RedBlue (Regular Positive and Negative Inference) on a ADL sample and\n"\
13
- "flushes the induced DFA on the standard output in ADL format as well")
14
- end
15
-
16
- # Installs additional options
17
- def options
18
- super do |opt|
19
- opt.on("-v", "--verbose", "Verbose mode") do
20
- @verbose = true
21
- end
22
- opt.on("-o", "--output=OUTPUT",
23
- "Flush induced DFA in output file") do |value|
24
- assert_writable_file(value)
25
- @output_file = value
26
- end
27
- end
28
- end
29
-
30
- # Sets the sample file
31
- def sample_file=(file)
32
- assert_readable_file(file)
33
- puts "Parsing sample and building PTA" if @verbose
34
- @sample = Stamina::ADL.parse_sample_file(file)
35
- rescue Stamina::ADL::ParseError
36
- raise ArgumentError, "#{file} is not a valid ADL sample file"
37
- end
38
-
39
- # Executes the command
40
- def main(argv)
41
- parse(argv, :sample_file)
42
- t1 = Time.now
43
- dfa = Stamina::Induction::RedBlue.execute(@sample, {:verbose => @verbose})
44
- t2 = Time.now
45
- if @output_file
46
- File.open(@output_file, 'w') do |file|
47
- Stamina::ADL.print_automaton(dfa, file)
48
- end
49
- else
50
- Stamina::ADL.print_automaton(dfa, STDOUT)
51
- end
52
- puts "Executed in #{t2-t1} sec" if @verbose
53
- end
54
-
55
- end # class ScoreCommand
56
-
57
- end # module Command
58
- end # module Stamina
@@ -1,58 +0,0 @@
1
- require 'stamina/command/stamina_command'
2
- require 'stamina/induction/rpni'
3
- module Stamina
4
- module Command
5
-
6
- # Implementation of the rpni command line tool
7
- class RPNICommand < StaminaCommand
8
-
9
- # Creates a score command instance
10
- def initialize
11
- super("rpni", "[options] sample.adl",
12
- "Executes RPNI (Regular Positive and Negative Inference) on a ADL sample and\n"\
13
- "flushes the induced DFA on the standard output in ADL format as well")
14
- end
15
-
16
- # Installs additional options
17
- def options
18
- super do |opt|
19
- opt.on("-v", "--verbose", "Verbose mode") do
20
- @verbose = true
21
- end
22
- opt.on("-o", "--output=OUTPUT",
23
- "Flush induced DFA in output file") do |value|
24
- assert_writable_file(value)
25
- @output_file = value
26
- end
27
- end
28
- end
29
-
30
- # Sets the sample file
31
- def sample_file=(file)
32
- assert_readable_file(file)
33
- puts "Parsing sample and building PTA" if @verbose
34
- @sample = Stamina::ADL.parse_sample_file(file)
35
- rescue Stamina::ADL::ParseError
36
- raise ArgumentError, "#{file} is not a valid ADL sample file"
37
- end
38
-
39
- # Executes the command
40
- def main(argv)
41
- parse(argv, :sample_file)
42
- t1 = Time.now
43
- dfa = Stamina::Induction::RPNI.execute(@sample, {:verbose => @verbose})
44
- t2 = Time.now
45
- if @output_file
46
- File.open(@output_file, 'w') do |file|
47
- Stamina::ADL.print_automaton(dfa, file)
48
- end
49
- else
50
- Stamina::ADL.print_automaton(dfa, STDOUT)
51
- end
52
- puts "Executed in #{t2-t1} sec" if @verbose
53
- end
54
-
55
- end # class ScoreCommand
56
-
57
- end # module Command
58
- end # module Stamina
@@ -1,79 +0,0 @@
1
- require 'stamina'
2
- require 'optparse'
3
- module Stamina
4
- module Command
5
-
6
- # Helper to create stamina commands
7
- class StaminaCommand
8
-
9
- # Command name
10
- attr_reader :name
11
-
12
- # Command description
13
- attr_reader :description
14
-
15
- # Command usage
16
- attr_reader :usage
17
-
18
- # Creates a command with a name, usage and description
19
- def initialize(name, usage, description)
20
- @name = name
21
- @usage = usage
22
- @description = description
23
- end
24
-
25
- # Creates options
26
- def options(&block)
27
- OptionParser.new do |opt|
28
- opt.program_name = name
29
- opt.version = Stamina::VERSION
30
- opt.release = nil
31
- opt.summary_indent = ' ' * 4
32
- banner = <<-EOF
33
- # usage: #{opt.program_name} #{usage}
34
- # #{description}
35
- EOF
36
- opt.banner = banner.gsub(/[ \t]+# /, "")
37
- block.call(opt) if block
38
- opt.on_tail("-h", "--help", "Show this message") do
39
- puts opt
40
- exit
41
- end
42
- end
43
- end
44
-
45
- # Prints usage (and optionnaly exits)
46
- def show_usage(and_exit=true)
47
- puts options
48
- Kernel.exit if and_exit
49
- end
50
-
51
- # Checks that a given file is readable or raises an ArgumentError
52
- def assert_readable_file(file)
53
- raise ArgumentError, "File #{file} does not exists" unless File.exists?(file)
54
- raise ArgumentError, "File #{file} cannot be read" unless File.readable?(file)
55
- end
56
-
57
- # Checks that a given file is writable or raises an ArgumentError
58
- def assert_writable_file(file)
59
- raise ArgumentError, "File #{file} cannot be written" \
60
- unless not(File.exists?(file)) or File.writable?(file)
61
- end
62
-
63
- # Parses arguments and install last argument as instance variables
64
- def parse(argv, *variables)
65
- rest = options.parse(argv)
66
- show_usage(true) unless rest.size==variables.size
67
- variables.each_with_index do |var,i|
68
- self.send("#{var}=".to_sym, rest[i])
69
- end
70
- rescue ArgumentError => ex
71
- puts ex.message
72
- puts
73
- show_usage(true)
74
- end
75
-
76
- end # class StaminaCommand
77
-
78
- end # module Command
79
- end # module Stamina