falluto 0.0.1 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
data/bin/cleantrace.rb ADDED
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+
5
+ require 'falluto/ruby_extensions'
6
+ require 'falluto/version'
7
+
8
+ class TraceCleaner
9
+ def clean tracefile, auxfile, output
10
+ load_auxdata auxfile
11
+ do_clean tracefile, output
12
+ end
13
+
14
+ private
15
+
16
+ def load_auxdata filename
17
+ @auxvars, @specs = [], []
18
+
19
+ IO.foreach(filename) do |line|
20
+ if line =~ /^VAR: (.*)$/
21
+ @auxvars << $1.chomp
22
+ elsif line =~ /^SPEC: (.*)$/
23
+ @specs << $1.chomp
24
+ end
25
+ end
26
+ end
27
+
28
+ def do_clean filename, output
29
+ varsregexp = @auxvars.join('|')
30
+ i = 0
31
+
32
+ IO.foreach(filename) do |line|
33
+ if line =~ /^-- specification (.*) is (true|false)/
34
+ output.puts "Spec: #{@specs[i]} is #{$2}"
35
+ output.puts "Counterexample:" if $2 == "false"
36
+ i += 1
37
+ elsif ((!varsregexp.empty?) && (line =~ /#{varsregexp}/))
38
+ # skip it
39
+ elsif (line =~ /-- Loop/) or (line !~ /^(\*\*\*|WARNING|--|Trace|$)/)
40
+ output.print line
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ def parse_cmdline_args
47
+ options = {:file => nil, :auxfile => nil, :output => nil}
48
+ optparser = OptionParser.new do |opts|
49
+ opts.on('-f', '--file <trace_file>', 'Indicate the <trace_file> to be cleaned.') do |file|
50
+ options[:file] = file
51
+ end
52
+
53
+ opts.on('-a', '--auxfile <aux_file>', 'Indicate the <aux_file> which contains compiler objects.') do |file|
54
+ options[:auxfile] = file
55
+ end
56
+
57
+ opts.on('-o', '--output <clean_trace>', 'Indicate the output file which will have the clean trace.') do |file|
58
+ options[:output] = file
59
+ end
60
+
61
+ opts.on('-v', '--version', "Print the version number of #{Falluto::NAME} and exit.") do |x|
62
+ puts Falluto::Version::STRING
63
+ exit 0
64
+ end
65
+ end
66
+ optparser.parse!
67
+ options
68
+ end
69
+
70
+
71
+ def main
72
+ begin
73
+ options = parse_cmdline_args
74
+
75
+ tracefile = options[:file]
76
+ auxfile = options[:auxfile]
77
+ cleantrace = options[:output]
78
+
79
+ puts "Reading NuSMV trace from: #{tracefile}"
80
+ puts "Reading support objects from: #{auxfile}"
81
+ puts "Writing clean trace to: #{cleantrace}"
82
+
83
+ cleaner = TraceCleaner.new
84
+ File.open(cleantrace, "w+") do |output|
85
+ cleaner.clean tracefile, auxfile, output
86
+ end
87
+
88
+ puts "Done."
89
+
90
+ rescue => e
91
+ puts ""
92
+ puts "ERROR: #{Falluto::NAME}: #{e} "
93
+ exit 1
94
+ end
95
+ end
96
+
97
+ main
data/bin/falluto.rb CHANGED
@@ -1,3 +1,93 @@
1
- gem 'falluto'
1
+ #!/usr/bin/ruby
2
+
3
+ require 'optparse'
4
+
5
+ require 'falluto/ruby_extensions'
6
+ require 'falluto/version'
7
+
8
+ def parse_cmdline_args
9
+ options = {:file => nil}
10
+ optparser = OptionParser.new do |opts|
11
+ opts.on('-f', '--file <input_file>', 'Verify the model and specs given in <input_file>.') do |file|
12
+ options[:file] = file
13
+ end
14
+
15
+ opts.on('-n', '--nusmv <options>', 'Additional options for NuSMV (between quotes).') do |nusmvopts|
16
+ options[:nusmvopts] = nusmvopts
17
+ end
18
+
19
+ opts.on('-g', '--graph', 'Generate graph of the counterexample automata.') do |x|
20
+ options[:graph] = true
21
+ end
22
+
23
+ opts.on('-v', '--version', "Print the version number of #{Falluto::NAME} and exit.") do |x|
24
+ puts Falluto::Version::STRING
25
+ exit 0
26
+ end
27
+ end
28
+ optparser.parse!
29
+ options
30
+ end
31
+
32
+ def execute_command cmd
33
+ puts cmd
34
+ out = %x{#{cmd}}
35
+ puts out if out !~ /^$/
36
+ end
37
+
38
+ def compile inputfile, modelfile, auxfile
39
+ puts "# Compiling..."
40
+ cmd = "ftnusmv.rb -f #{inputfile} -o #{modelfile} -a #{auxfile}"
41
+ execute_command cmd
42
+ end
43
+
44
+ def check_model modelfile, tracefile, opts = nil
45
+ puts "# Model checking..."
46
+ cmd = "NuSMV #{opts} #{modelfile} > #{tracefile}"
47
+ execute_command cmd
48
+ end
49
+
50
+ def clean_trace tracefile, auxfile, cleantracefile
51
+ puts "# Cleaning trace..."
52
+ cmd = "cleantrace.rb -f #{tracefile} -a #{auxfile} -o #{cleantracefile}"
53
+ execute_command cmd
54
+ end
55
+
56
+ def generate_automata tracefile, dotfile, pdffile
57
+ puts "# Graphing automata..."
58
+ cmd = "viewtrace.rb -f #{tracefile} -d #{dotfile} -o #{pdffile}"
59
+ execute_command cmd
60
+ end
61
+
62
+ def main
63
+ begin
64
+ options = parse_cmdline_args
65
+
66
+ inputfile = File.expand_path options[:file]
67
+ modelfile = File.replace_extension inputfile, 'out'
68
+ auxfile = File.replace_extension inputfile, 'aux'
69
+ tracefile = File.replace_extension inputfile, 'trace'
70
+ cleantracefile = File.replace_extension inputfile, "clean"
71
+ dotfile = File.replace_extension inputfile, "dot"
72
+ pdffile = File.replace_extension inputfile, "pdf"
73
+
74
+ puts Falluto::Version::STRING
75
+ puts ""
76
+
77
+ compile inputfile, modelfile, auxfile
78
+ check_model modelfile, tracefile, options[:nusmvopts]
79
+ clean_trace tracefile, auxfile, cleantracefile
80
+
81
+ if options[:graph]
82
+ generate_automata cleantracefile, dotfile, pdffile
83
+ end
84
+
85
+ rescue OptionParser::InvalidOption => e
86
+ puts "Falluto: " + e
87
+ exit 1
88
+ end
89
+ end
90
+
91
+ main
92
+
2
93
 
3
- puts "hello world"
data/bin/ftnusmv.rb ADDED
@@ -0,0 +1,96 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # FT-NuSMV compiler front end
4
+
5
+ require 'optparse' # to build a nicer CLI
6
+
7
+ require 'falluto/compiler'
8
+ require 'falluto/version'
9
+
10
+ def parse_cmdline_args
11
+ options = {:method => :compile, :rule => 'program', :file => nil, :output => nil, :auxfile => nil }
12
+ op = OptionParser.new do |opts|
13
+ opts.on('-f', '--file FILE', 'Specify input file') do |f|
14
+ options[:file] = f
15
+ end
16
+
17
+ opts.on('-o', '--output FILE', 'Specify output file (compiled model)') do |f|
18
+ options[:output] = f
19
+ end
20
+
21
+ opts.on('-a', '--auxfile FILE', 'Specify auxiliar file (auxiliar variables, etc)') do |f|
22
+ options[:auxfile] = f
23
+ end
24
+
25
+ opts.on('-v', '--version', "Print the version number of #{Falluto::NAME} and exit.") do |x|
26
+ puts Falluto::Version::STRING
27
+ exit 0
28
+ end
29
+ end
30
+ op.parse!
31
+ options
32
+ end
33
+
34
+ def save_auxiliar_data compiler, filename
35
+ File.open(filename, "w+") do |f|
36
+ compiler.auxiliar_variables.each do |v|
37
+ f.puts "VAR: #{v}"
38
+ end
39
+ compiler.specs.each do |s|
40
+ f.puts "SPEC: #{s}"
41
+ end
42
+ end
43
+ end
44
+
45
+ def save_compiled_code compiler, filename
46
+ File.open(filename, "w+") do |f|
47
+ f.puts compiler.compiled_string
48
+ end
49
+ end
50
+
51
+ def main
52
+ begin
53
+ options = parse_cmdline_args
54
+
55
+ infile = options[:file]
56
+ outfile = options[:output]
57
+ auxfile = options[:auxfile]
58
+
59
+
60
+ puts "Reading input model from: #{infile}"
61
+ puts "Writing compiled model to: #{outfile}"
62
+ puts "Writing support objects to: #{auxfile}"
63
+
64
+ string = File.read infile
65
+ compiler = Compiler.new
66
+ compiler.run string
67
+
68
+ # save compiled string into output file
69
+ save_compiled_code compiler, outfile
70
+
71
+ # save auxiliar data into separate file
72
+ save_auxiliar_data compiler, auxfile
73
+
74
+ puts "Done."
75
+
76
+ rescue UndeclaredFault => e
77
+ puts ""
78
+ puts "ERROR: Fault #{e} undeclared in module "
79
+ exit 1
80
+ rescue RedefinedFault => e
81
+ puts ""
82
+ puts "ERROR: Fault #{e} already declared in module "
83
+ exit 1
84
+ rescue OptionParser::InvalidOption => e
85
+ puts ""
86
+ puts "ERROR: #{e}"
87
+ exit 1
88
+ rescue => e
89
+ puts ""
90
+ puts "ERROR: #{Falluto::NAME}: #{e}"
91
+ exit 1
92
+ end
93
+ end
94
+
95
+ main
96
+
data/bin/viewtrace.rb ADDED
@@ -0,0 +1,162 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+
5
+ require 'falluto/ruby_extensions'
6
+ require 'falluto/version'
7
+
8
+ class Edge
9
+ def initialize source, dest
10
+ @source = source
11
+ @dest = dest
12
+ @label = ''
13
+ end
14
+ def << str
15
+ @label << str.chomp.strip + '\\n'
16
+ end
17
+ def to_dot
18
+ "#{@source.quote} -> #{@dest.quote} [label=#{@label.quote}];"
19
+ end
20
+ end
21
+
22
+ class LoopEdge < Edge
23
+ def to_dot
24
+ "#{@source.quote} -> #{@dest.quote} [style=dotted,bold label=#{'LOOP'.quote}];"
25
+ end
26
+ end
27
+
28
+ class Node
29
+ attr_reader :name, :has_loop
30
+ def initialize name, has_loop
31
+ @name = name
32
+ @label = 'State: ' + name + '\\n'
33
+ @has_loop = has_loop
34
+ end
35
+ def << str
36
+ @label << str.chomp.strip + '\\n'
37
+ end
38
+ def to_dot
39
+ "#{@name.quote} [label=#{@label.quote}];"
40
+ end
41
+ end
42
+
43
+ class TraceParser
44
+ def initialize file
45
+ @nodes = []
46
+ @edges = []
47
+ parse file
48
+ end
49
+
50
+ def to_dot
51
+ "digraph G {\n" +
52
+ @nodes.collect{|n| n.to_dot + "\n" }.join +
53
+ @edges.collect{|e| e.to_dot + "\n" }.join +
54
+ "}\n"
55
+ end
56
+
57
+ private
58
+ def parse file
59
+ @elems = []
60
+ node = nil
61
+ edge = nil
62
+ has_loop = false
63
+ IO.foreach(file) do |line|
64
+ case line
65
+ when /\*\*\*/
66
+ # do nothing
67
+ when /^Trace Description: (.*)/
68
+ # do nothing
69
+ when /^Trace Type: (.*)/
70
+ # do nothing
71
+ when /-- Loop/
72
+ has_loop = true
73
+ when /-> State: (\S+)/
74
+ node = Node.new $1, has_loop
75
+ has_loop = false
76
+ @nodes << node
77
+ edge = nil
78
+ when /-> Input: (\S+) /
79
+ edge = Edge.new node.name, $1
80
+ @edges << edge
81
+ node = nil
82
+ else
83
+ node <<(line) if node
84
+ edge <<(line) if edge
85
+ end
86
+ end
87
+ build_loops
88
+ nil
89
+ end
90
+
91
+ def build_loops
92
+ source = @nodes.last
93
+ loop_nodes = @nodes.select {|n| n.has_loop}
94
+ loop_nodes.each { |dest| @edges << LoopEdge.new(source.name, dest.name) }
95
+ end
96
+ end
97
+
98
+
99
+ def parse_cmdline_args
100
+ options = {:file => nil}
101
+ op = OptionParser.new do |opts|
102
+ opts.on('-f', '--file <trace_file>', 'Generate the automata for the trace in <trace_file>.') do |file|
103
+ options[:file] = file
104
+ end
105
+
106
+ opts.on('-d', '--dotfile <dot_file>', 'Save the output dot file to <dot_file>.') do |file|
107
+ options[:dotfile] = file
108
+ end
109
+
110
+ opts.on('-o', '--output <pdf_file>', 'Save the output PDF to file <pdf_file>.') do |output|
111
+ options[:pdffile] = output
112
+ end
113
+
114
+ opts.on('-v', '--version', "Print the version number of #{Falluto::NAME} and exit.") do |x|
115
+ puts Falluto::Version::STRING
116
+ exit 0
117
+ end
118
+ end
119
+ op.parse!
120
+ options
121
+ end
122
+
123
+
124
+ def dump_dot tracefile, dotfile
125
+ tp = TraceParser.new tracefile
126
+
127
+ File.open(dotfile, "w+") do |f|
128
+ f.puts tp.to_dot
129
+ end
130
+ end
131
+
132
+ def generate_pdf dotfile, pdffile
133
+ %x{dot -Tpdf #{dotfile} -o #{pdffile}}
134
+ end
135
+
136
+
137
+ def main
138
+ begin
139
+ options = parse_cmdline_args
140
+
141
+ tracefile = options[:file]
142
+ dotfile = options[:dotfile]
143
+ pdffile = options[:pdffile]
144
+
145
+ puts "Reading clean trace from: #{tracefile}"
146
+ puts "Writing dot file to: #{dotfile}"
147
+ puts "Writing automata to: #{pdffile}"
148
+
149
+ dump_dot tracefile, dotfile
150
+ generate_pdf dotfile, pdffile
151
+
152
+ puts "Done."
153
+
154
+ rescue => e
155
+ puts ""
156
+ puts "ERROR: #{Falluto::NAME}: #{e} "
157
+ puts e.backtrace.join("\n")
158
+ exit 1
159
+ end
160
+ end
161
+
162
+ main