falluto 0.0.1 → 0.0.9

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/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