falluto 0.0.1 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,87 @@
1
+ module Falluto
2
+ module NuSMV
3
+ class AuxiliarVariable
4
+ attr_reader :name, :condition
5
+ def initialize name, condition
6
+ @name, @condition = name, condition
7
+ end
8
+ end
9
+
10
+ class Fault
11
+ GUARD_VARIABLE_FORMAT = '%s_g%d'
12
+
13
+ attr_reader :name, :process_name
14
+ attr_reader :precondition, :restore
15
+ attr_reader :precondition_variable, :restore_variable, :active_variable,
16
+ :fairness_variable
17
+
18
+ def initialize modul, name, precondition, restore, effect
19
+ @name = name
20
+ @process_name = "#{modul}_#{name}"
21
+ @precondition = precondition
22
+ @restore = restore
23
+ @system_effect = effect
24
+
25
+ @fairness_variable = "#{@name}_vfair"
26
+ @precondition_variable = "#{@name}_pre"
27
+ @restore_variable = "#{@name}_restore"
28
+ @active_variable = "active"
29
+
30
+ @auxiliar_variables = []
31
+
32
+ end
33
+
34
+ def add_auxiliar_variable guard
35
+ vname = next_auxiliar_variable
36
+ @auxiliar_variables << AuxiliarVariable.new(vname, guard)
37
+ end
38
+
39
+ def next_auxiliar_variable
40
+ i = @auxiliar_variables.length + 1
41
+ GUARD_VARIABLE_FORMAT % [@name, i]
42
+ end
43
+
44
+ def strong_fairness inst
45
+ "((G F (#{fairness_condition(inst)})) -> (G F (#{inst}.#{fairness_variable})))"
46
+ end
47
+
48
+ ##### Variables affected by system effect
49
+ def each_affected_variable &block
50
+ @system_effect.variables.each{ |v| yield v }
51
+ end
52
+
53
+ def each_affected_variable_with_effect &block
54
+ @system_effect.each_pair{ |v, effect| yield v, effect }
55
+ end
56
+
57
+ def instance_signature
58
+ parameters = "#{precondition_variable}, #{restore_variable}"
59
+ each_affected_variable{|v| parameters << ", #{v}"}
60
+ %Q|#{process_name}(#{parameters})|
61
+ end
62
+
63
+ def each_auxiliar_variable &block
64
+ @auxiliar_variables.each {|v| yield v}
65
+ end
66
+
67
+ def fairness_condition inst = nil
68
+ if inst.nil?
69
+ not_effect = "! #{@name}.#{active_variable}"
70
+ # not_effect = "! #{active_variable}"
71
+ else
72
+ not_effect = "! #{inst}.#{@name}.#{active_variable}"
73
+ end
74
+
75
+ if @auxiliar_variables.empty?
76
+ not_effect
77
+ else
78
+ vars = @auxiliar_variables.collect do |v|
79
+ (inst.nil? ? '' : "#{inst}.") + v.name
80
+ end
81
+ '( ' + vars.join(' | ') + " ) & #{not_effect}"
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+
@@ -0,0 +1,45 @@
1
+ require 'falluto/symboltable'
2
+
3
+ module Falluto
4
+ module NuSMV
5
+ class Module
6
+ attr_reader :name
7
+
8
+ def initialize name
9
+ @name = name
10
+ @faults = SymbolTable.new
11
+ @variables = SymbolTable.new
12
+ end
13
+
14
+ def add_fault fault
15
+ @faults.insert fault
16
+ end
17
+
18
+ def get_faults *fault_names
19
+ fault_names.collect{ |fname| @faults.get fname }
20
+ # @faults.get f
21
+ end
22
+
23
+ def is_defined? fault
24
+ @faults.has? fault
25
+ end
26
+
27
+ def has_faults?
28
+ not @faults.empty?
29
+ end
30
+
31
+ def each_fault &block
32
+ @faults.each &block
33
+ end
34
+
35
+ def add_variable var
36
+ @variables.insert var
37
+ end
38
+
39
+ def each_variable &block
40
+ @variables.each &block
41
+ end
42
+
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,13 @@
1
+ module Falluto
2
+ module NuSMV
3
+ class Variable
4
+ attr_reader :name, :type
5
+ def initialize(name, type)
6
+ raise 'name cannot be empty' if (name.nil? or name.empty?)
7
+ raise 'type cannot be empty' if (type.nil? or type.empty?)
8
+ @name, @type = name, type
9
+ end
10
+ end
11
+ end
12
+ end
13
+
@@ -0,0 +1,4 @@
1
+ require 'falluto/nusmv/codegen'
2
+ require 'falluto/nusmv/variable'
3
+ require 'falluto/nusmv/module'
4
+ require 'falluto/nusmv/fault'
@@ -0,0 +1,10 @@
1
+ class Class
2
+ def human_name
3
+ name.to_s.gsub(/::/, '_').
4
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
5
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
6
+ tr("-", "_").
7
+ downcase
8
+ end
9
+ end
10
+
@@ -0,0 +1,5 @@
1
+ class File
2
+ def self.replace_extension filename, newext
3
+ File.basename(filename, '.*') + ".#{newext}"
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ class Hash
2
+ alias variables keys
3
+ end
@@ -0,0 +1,5 @@
1
+ class String
2
+ def quote
3
+ '"' + self + '"'
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ require 'falluto/ruby_extensions/class'
2
+ require 'falluto/ruby_extensions/file'
3
+ require 'falluto/ruby_extensions/hash'
4
+ require 'falluto/ruby_extensions/string'
@@ -0,0 +1,34 @@
1
+ class SymbolTable
2
+ include Enumerable
3
+
4
+ def initialize attribute = :name
5
+ @table = Hash.new
6
+ @attribute = attribute
7
+ end
8
+
9
+ def has? object
10
+ key = object.send(@attribute)
11
+ @table.include? key
12
+ end
13
+
14
+ def insert(object)
15
+ key = object.send(@attribute)
16
+ @table[key] = object
17
+ end
18
+ alias << insert
19
+
20
+ def get key
21
+ @table[key]
22
+ end
23
+ alias [] get
24
+
25
+ def empty?
26
+ @table.empty?
27
+ end
28
+
29
+ def each &block
30
+ @table.values.each &block
31
+ end
32
+ end
33
+
34
+
@@ -0,0 +1,10 @@
1
+ module Falluto
2
+ module Version
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ PATCH = 9
6
+
7
+ STRING = "#{MAJOR}.#{MINOR}.#{PATCH}"
8
+ end
9
+ NAME = "Falluto"
10
+ end
@@ -0,0 +1,121 @@
1
+ require 'spec_helper'
2
+ require 'falluto/grammar'
3
+
4
+ describe 'a Falluto Parser' do
5
+ before do
6
+ @parser = Falluto::GrammarParser.new
7
+ end
8
+
9
+ it 'should parse a simple module' do
10
+ tree = @parser.parse %q{
11
+ MODULE main
12
+ }
13
+ tree.should.not.be.nil
14
+ end
15
+
16
+ it 'should parse a module with a variable' do
17
+ tree = @parser.parse %q{
18
+ MODULE main
19
+ VAR
20
+ x : boolean;
21
+ }
22
+ tree.should.not.be.nil
23
+ end
24
+
25
+ it 'should parse a fault declaration' do
26
+ @parser.root = :fault
27
+ declaration = @parser.parse %q{FAULT f
28
+ pre(true);
29
+ effect(x = 0, y = 1);
30
+ restores(false);
31
+ }
32
+ declaration.should.not.be.nil
33
+ declaration.name.should.equal 'f'
34
+ declaration.precondition.should.equal 'true'
35
+ declaration.restores.should.equal 'false'
36
+ declaration.effect.should.equal 'x' => '0', 'y' => '1'
37
+ end
38
+
39
+ it 'should parse a module with a fault' do
40
+ tree = @parser.parse %q{
41
+ MODULE main
42
+ FAULT f
43
+ pre(cond1 & cond2 | cond3);
44
+ effect(x = x + 1);
45
+ restores(!reset);
46
+ VAR
47
+ x : boolean;
48
+ }
49
+ tree.should.not.be.nil
50
+ end
51
+
52
+ it 'should parse a module with two faults' do
53
+ tree = @parser.parse %q{
54
+ MODULE main
55
+ FAULT f
56
+ pre(cond1 & cond2 | cond3);
57
+ effect(x = x + 1);
58
+ restores(!reset);
59
+ FAULT g
60
+ pre(cond1 & cond2 | cond3);
61
+ effect(x = x + 1);
62
+ restores(!reset);
63
+ VAR
64
+ x : boolean;
65
+ }
66
+ tree.should.not.be.nil
67
+ end
68
+
69
+ it 'should parse a module with a fault in next assignment' do
70
+ tree = @parser.parse %q{
71
+ MODULE main
72
+ FAULT f
73
+ pre(cond1 & cond2 | cond3);
74
+ effect(x = x + 1);
75
+ restores(!reset);
76
+ VAR
77
+ x : boolean;
78
+ ASSIGN
79
+ next(x) := x + 1 disabled_by {f};
80
+ }
81
+ tree.should.not.be.nil
82
+ end
83
+
84
+ it 'should parse a module with a fault in case assignment' do
85
+ tree = @parser.parse %q{
86
+ MODULE main
87
+ FAULT f
88
+ pre(cond1 & cond2 | cond3);
89
+ effect(x = x + 1);
90
+ restores(!reset);
91
+ VAR
92
+ x : boolean;
93
+ ASSIGN
94
+ next(x) :=
95
+ case
96
+ c1 : x + 1;
97
+ 1 : x;
98
+ esac disabled_by {f};
99
+ }
100
+ tree.should.not.be.nil
101
+ end
102
+
103
+ it 'should parse a module with a fault in case element' do
104
+ tree = @parser.parse %q{
105
+ MODULE main
106
+ FAULT f
107
+ pre(cond1 & cond2 | cond3);
108
+ effect(x = x + 1);
109
+ restores(!reset);
110
+ VAR
111
+ x : boolean;
112
+ ASSIGN
113
+ next(x) :=
114
+ case
115
+ c1 : x + 1 disabled_by {f};
116
+ 1 : x;
117
+ esac;
118
+ }
119
+ tree.should.not.be.nil
120
+ end
121
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+ require 'falluto/nusmv'
3
+
4
+ describe 'a Falluto Fault' do
5
+ before do
6
+ pre = 'x > 0'
7
+ restore = 'x >= 0'
8
+ effect = nil
9
+ @fault = Falluto::NuSMV::Fault.new 'Foo', 'Bar', pre, restore, effect
10
+ end
11
+
12
+ it 'should have a name' do
13
+ @fault.name.should.be.equal 'Bar'
14
+ @fault.process_name.should.be.equal 'Foo_Bar'
15
+ end
16
+
17
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+ require 'falluto/nusmv'
3
+
4
+ describe 'a NuSMV Code Generator' do
5
+ before do
6
+ @generator = Falluto::NuSMV::CodeGenerator.new
7
+ end
8
+
9
+ it 'should generate a module' do
10
+ @generator.module('main(a, b)').should.equal 'MODULE main(a, b)'
11
+ end
12
+
13
+ it 'should generate a variable' do
14
+ @generator.variable_declaration('v', 'boolean').should.equal 'VAR v : boolean;'
15
+ end
16
+
17
+ it 'should instance a process' do
18
+ @generator.instance_process('no_params').should.equal 'process no_params();'
19
+ @generator.instance_process('sometype', 'arg1', 'arg2').should.equal 'process sometype(arg1, arg2);'
20
+ end
21
+
22
+ it 'should generate a process' do
23
+ @generator.process('sometype()').should.equal 'process sometype()'
24
+ end
25
+
26
+ it 'should generate a fairness constraint' do
27
+ @generator.fairness('running').should.equal 'FAIRNESS running'
28
+ end
29
+
30
+ it 'should generate macros' do
31
+ @generator.define('v', 'expr').should.equal 'DEFINE v := (expr);'
32
+ end
33
+
34
+ it 'should generate an LTL spec' do
35
+ @generator.ltlspec('G F p').should.equal 'LTLSPEC G F p'
36
+ end
37
+
38
+ it 'should generate implication' do
39
+ @generator.implies('p', 'q').should.equal '((p) -> (q))'
40
+ end
41
+ end
42
+
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+ require 'falluto/nusmv'
3
+
4
+ describe 'a NuSMV Module' do
5
+ before do
6
+ @module = Falluto::NuSMV::Module.new 'SomeModule'
7
+ end
8
+
9
+ it 'should have a name' do
10
+ @module.name.should.equal 'SomeModule'
11
+ end
12
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+ require 'falluto/nusmv'
3
+
4
+ describe 'a NuSMV Variable' do
5
+ before do
6
+ end
7
+
8
+ it 'should have a name and type' do
9
+ var = Falluto::NuSMV::Variable.new 'procvar', 'SomeProcType'
10
+ var.name.should.equal 'procvar'
11
+ var.type.should.equal 'SomeProcType'
12
+ end
13
+
14
+ it 'should raise an error if name is nil or empty' do
15
+ lambda { Falluto::NuSMV::Variable.new nil, 'sometype' }.
16
+ should.raise(Exception).
17
+ message.should.match(/name cannot be empty/)
18
+ lambda { Falluto::NuSMV::Variable.new '', 'sometype' }.
19
+ should.raise(Exception).
20
+ message.should.match(/name cannot be empty/)
21
+ end
22
+
23
+ it 'should raise an error if type is nil or empty' do
24
+ lambda { Falluto::NuSMV::Variable.new 'somename', nil }.
25
+ should.raise(Exception).
26
+ message.should.match(/type cannot be empty/)
27
+ lambda { Falluto::NuSMV::Variable.new 'somename', '' }.
28
+ should.raise(Exception).
29
+ message.should.match(/type cannot be empty/)
30
+ end
31
+ end
32
+
@@ -0,0 +1,4 @@
1
+ require 'rubygems'
2
+ require 'bacon'
3
+
4
+ Bacon.summary_on_exit
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: falluto
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Edgardo Hames
@@ -9,18 +9,18 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-17 00:00:00 -08:00
13
- default_executable: falluto.rb
12
+ date: 2010-01-06 00:00:00 -08:00
13
+ default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
- name: thoughtbot-shoulda
16
+ name: bacon
17
17
  type: :development
18
18
  version_requirement:
19
19
  version_requirements: !ruby/object:Gem::Requirement
20
20
  requirements:
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: "0"
23
+ version: 1.1.0
24
24
  version:
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: treetop
@@ -35,22 +35,39 @@ dependencies:
35
35
  description: A model checker for verifying fault tolerant systems
36
36
  email: ehames@gmail.com
37
37
  executables:
38
+ - cleantrace.rb
38
39
  - falluto.rb
40
+ - ftnusmv.rb
41
+ - viewtrace.rb
39
42
  extensions: []
40
43
 
41
44
  extra_rdoc_files:
42
45
  - LICENSE
43
46
  - README.rdoc
44
47
  files:
45
- - .document
46
- - .gitignore
48
+ - bin/cleantrace.rb
49
+ - bin/falluto.rb
50
+ - bin/ftnusmv.rb
51
+ - bin/viewtrace.rb
52
+ - lib/falluto/compiler.rb
53
+ - lib/falluto/grammar.rb
54
+ - lib/falluto/grammar/nodes.rb
55
+ - lib/falluto/grammar/rules.treetop
56
+ - lib/falluto/grammar/tokens.treetop
57
+ - lib/falluto/nusmv.rb
58
+ - lib/falluto/nusmv/codegen.rb
59
+ - lib/falluto/nusmv/fault.rb
60
+ - lib/falluto/nusmv/module.rb
61
+ - lib/falluto/nusmv/variable.rb
62
+ - lib/falluto/ruby_extensions.rb
63
+ - lib/falluto/ruby_extensions/class.rb
64
+ - lib/falluto/ruby_extensions/file.rb
65
+ - lib/falluto/ruby_extensions/hash.rb
66
+ - lib/falluto/ruby_extensions/string.rb
67
+ - lib/falluto/symboltable.rb
68
+ - lib/falluto/version.rb
47
69
  - LICENSE
48
70
  - README.rdoc
49
- - Rakefile
50
- - VERSION
51
- - bin/falluto.rb
52
- - test/helper.rb
53
- - test/test_falluto.rb
54
71
  has_rdoc: true
55
72
  homepage: http://github.com/ehames/falluto
56
73
  licenses: []
@@ -80,5 +97,9 @@ signing_key:
80
97
  specification_version: 3
81
98
  summary: A model checker for verifying fault tolerant systems
82
99
  test_files:
83
- - test/helper.rb
84
- - test/test_falluto.rb
100
+ - spec/grammar/parser_spec.rb
101
+ - spec/spec_helper.rb
102
+ - spec/nusmv/fault_spec.rb
103
+ - spec/nusmv/variable_spec.rb
104
+ - spec/nusmv/generator_spec.rb
105
+ - spec/nusmv/module_spec.rb
data/.document DELETED
@@ -1,5 +0,0 @@
1
- README.rdoc
2
- lib/**/*.rb
3
- bin/*
4
- features/**/*.feature
5
- LICENSE
data/.gitignore DELETED
@@ -1,21 +0,0 @@
1
- ## MAC OS
2
- .DS_Store
3
-
4
- ## TEXTMATE
5
- *.tmproj
6
- tmtags
7
-
8
- ## EMACS
9
- *~
10
- \#*
11
- .\#*
12
-
13
- ## VIM
14
- *.swp
15
-
16
- ## PROJECT::GENERAL
17
- coverage
18
- rdoc
19
- pkg
20
-
21
- ## PROJECT::SPECIFIC
data/Rakefile DELETED
@@ -1,56 +0,0 @@
1
- require 'rubygems'
2
- require 'rake'
3
-
4
- begin
5
- require 'jeweler'
6
- Jeweler::Tasks.new do |gem|
7
- gem.name = "falluto"
8
- gem.summary = %Q{A model checker for verifying fault tolerant systems}
9
- gem.description = %Q{A model checker for verifying fault tolerant systems}
10
- gem.email = "ehames@gmail.com"
11
- gem.homepage = "http://github.com/ehames/falluto"
12
- gem.authors = ["Edgardo Hames"]
13
- gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
14
-
15
- gem.add_dependency "treetop", ">= 1.2.3"
16
-
17
- # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
- end
19
- Jeweler::GemcutterTasks.new
20
- rescue LoadError
21
- puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
22
- end
23
-
24
- require 'rake/testtask'
25
- Rake::TestTask.new(:test) do |test|
26
- test.libs << 'lib' << 'test'
27
- test.pattern = 'test/**/test_*.rb'
28
- test.verbose = true
29
- end
30
-
31
- begin
32
- require 'rcov/rcovtask'
33
- Rcov::RcovTask.new do |test|
34
- test.libs << 'test'
35
- test.pattern = 'test/**/test_*.rb'
36
- test.verbose = true
37
- end
38
- rescue LoadError
39
- task :rcov do
40
- abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
41
- end
42
- end
43
-
44
- task :test => :check_dependencies
45
-
46
- task :default => :test
47
-
48
- require 'rake/rdoctask'
49
- Rake::RDocTask.new do |rdoc|
50
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
51
-
52
- rdoc.rdoc_dir = 'rdoc'
53
- rdoc.title = "falluto #{version}"
54
- rdoc.rdoc_files.include('README*')
55
- rdoc.rdoc_files.include('lib/**/*.rb')
56
- end
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.0.1
data/test/helper.rb DELETED
@@ -1,10 +0,0 @@
1
- require 'rubygems'
2
- require 'test/unit'
3
- require 'shoulda'
4
-
5
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
- $LOAD_PATH.unshift(File.dirname(__FILE__))
7
- require 'falluto'
8
-
9
- class Test::Unit::TestCase
10
- end
data/test/test_falluto.rb DELETED
@@ -1,7 +0,0 @@
1
- require 'helper'
2
-
3
- class TestFalluto < Test::Unit::TestCase
4
- should "probably rename this file and start testing for real" do
5
- flunk "hey buddy, you should probably rename this file and start testing for real"
6
- end
7
- end