Class: GV_FSM::FSM
Constant Summary
Constants included from Templates
Templates::CC, Templates::HEADER, Templates::HH
Instance Attribute Summary collapse
-
#cname ⇒ Object
Returns the value of attribute cname.
-
#description ⇒ Object
Returns the value of attribute description.
-
#dotfile ⇒ Object
readonly
Returns the value of attribute dotfile.
-
#error ⇒ Object
readonly
Returns the value of attribute error.
-
#ino ⇒ Object
Returns the value of attribute ino.
-
#prefix ⇒ Object
Returns the value of attribute prefix.
-
#project_name ⇒ Object
Returns the value of attribute project_name.
-
#sigint ⇒ Object
Returns the value of attribute sigint.
-
#states ⇒ Object
readonly
Returns the value of attribute states.
-
#syslog ⇒ Object
Returns the value of attribute syslog.
-
#transitions ⇒ Object
readonly
Returns the value of attribute transitions.
Instance Method Summary collapse
- #destinations ⇒ Object
- #generate_c(filename = @cname) ⇒ Object
- #generate_h(filename = @cname) ⇒ Object
-
#initialize(filename = nil) ⇒ FSM
constructor
A new instance of FSM.
- #parse(filename) ⇒ Object
- #state_functions_list ⇒ Object
- #states_list ⇒ Object
- #topology ⇒ Object
- #transition_functions_list ⇒ Object
- #transitions_map ⇒ Object
- #transitions_paths ⇒ Object
Constructor Details
#initialize(filename = nil) ⇒ FSM
Returns a new instance of FSM.
16 17 18 19 20 21 22 23 24 25 |
# File 'lib/gv_fsm.rb', line 16 def initialize(filename = nil) @prefix = "" @syslog = true @ino = false @error = nil @matrix = nil @nodemap = {} @sigint = nil parse(filename) if filename end |
Instance Attribute Details
#cname ⇒ Object
Returns the value of attribute cname.
13 14 15 |
# File 'lib/gv_fsm.rb', line 13 def cname @cname end |
#description ⇒ Object
Returns the value of attribute description.
13 14 15 |
# File 'lib/gv_fsm.rb', line 13 def description @description end |
#dotfile ⇒ Object (readonly)
Returns the value of attribute dotfile.
12 13 14 |
# File 'lib/gv_fsm.rb', line 12 def dotfile @dotfile end |
#error ⇒ Object (readonly)
Returns the value of attribute error.
12 13 14 |
# File 'lib/gv_fsm.rb', line 12 def error @error end |
#ino ⇒ Object
Returns the value of attribute ino.
13 14 15 |
# File 'lib/gv_fsm.rb', line 13 def ino @ino end |
#prefix ⇒ Object
Returns the value of attribute prefix.
12 13 14 |
# File 'lib/gv_fsm.rb', line 12 def prefix @prefix end |
#project_name ⇒ Object
Returns the value of attribute project_name.
13 14 15 |
# File 'lib/gv_fsm.rb', line 13 def project_name @project_name end |
#sigint ⇒ Object
Returns the value of attribute sigint.
13 14 15 |
# File 'lib/gv_fsm.rb', line 13 def sigint @sigint end |
#states ⇒ Object (readonly)
Returns the value of attribute states.
12 13 14 |
# File 'lib/gv_fsm.rb', line 12 def states @states end |
#syslog ⇒ Object
Returns the value of attribute syslog.
13 14 15 |
# File 'lib/gv_fsm.rb', line 13 def syslog @syslog end |
#transitions ⇒ Object (readonly)
Returns the value of attribute transitions.
12 13 14 |
# File 'lib/gv_fsm.rb', line 12 def transitions @transitions end |
Instance Method Details
#destinations ⇒ Object
125 126 127 128 129 130 131 132 |
# File 'lib/gv_fsm.rb', line 125 def destinations dest = Hash[states_list.map {|x| [x, []]}] @transitions.each do |t| dest[t[:from]] = [] unless dest[t[:from]] dest[t[:from]] << t[:to] end return dest end |
#generate_c(filename = @cname) ⇒ Object
143 144 145 146 147 148 149 150 151 |
# File 'lib/gv_fsm.rb', line 143 def generate_c(filename = @cname) ext = @ino ? "cpp" : "c" fname = "#{filename}.#{ext}" File.open(fname, "w") do |f| f.puts ERB.new(HEADER, 0, "<>").result(binding) f.puts ERB.new(CC, 0, "<>").result(binding) end return fname end |
#generate_h(filename = @cname) ⇒ Object
153 154 155 156 157 158 159 160 |
# File 'lib/gv_fsm.rb', line 153 def generate_h(filename = @cname) fname = "#{filename}.h" File.open(fname, "w") do |f| f.puts ERB.new(HEADER, 0, "<>").result(binding) f.puts ERB.new(HH, 0, "<>").result(binding) end return fname end |
#parse(filename) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/gv_fsm.rb', line 31 def parse(filename) raise ArgumentError, "File must be in .dot format" unless File.extname(filename) == ".dot" @cname = File.basename(filename, ".dot") unless (@cname and ! @cname.empty?) @dotfile = filename @states = [] @transitions = [] graph = GraphViz.parse(filename) do |g| if g.graph_count > 1 then @error = "Only one graph in the dot file is permitted" return nil end unless g.type == "digraph" then @error = "Graph is not directed" return nil end n = g.node_count if n == 0 then @error = "Graph is empty" return nil end @matrix = Matrix.zero(n, n) @description = g.name unless @description i = 0 g.each_node do |id| n = g.get_node(id) if n[:label].source.empty? or (n[:label].source == id and !n[:label].source.match(/^do_/)) then label = "do_#{id}" else label = n[:label].source end @nodemap[id] = i i += 1 @states << {id: id, function: @prefix+label} end g.each_edge do |e| @matrix[@nodemap[e.node_one], @nodemap[e.node_two]] += 1 from = e.node_one to = e.node_two unless e[:label] then @transitions << {from: from, to: to, function: nil} next end case e[:label].source when "" label = nil when /[#]/ label = "#{from}_to_#{to}" else label = e[:label].source end @transitions << {from: from, to: to, function: label ? @prefix+label : nil} end end unless graph then @error = "Parsing error" return nil end if (self.sigint && !states.find {|s| s[:id] == self.sigint}) then @error = "Missing SIGINT state #{self.sigint}" return nil end return graph end |
#state_functions_list ⇒ Object
96 97 98 |
# File 'lib/gv_fsm.rb', line 96 def state_functions_list @states.map {|s| s[:function]} end |
#states_list ⇒ Object
100 101 102 |
# File 'lib/gv_fsm.rb', line 100 def states_list @states.map {|s| s[:id]} end |
#topology ⇒ Object
162 163 164 165 166 167 168 169 170 |
# File 'lib/gv_fsm.rb', line 162 def topology res = {matrix: @matrix} # rows have the number of froms, columns the number of tos res[:froms] = @matrix.row_vectors.map {|v| v.sum } res[:tos] = @matrix.column_vectors.map {|v| v.sum } res[:sinks] = res[:froms].each_index.select {|i| res[:froms][i] == 0}.map {|i| @nodemap.keys[i]} res[:sources] = res[:tos].each_index.select {|i| res[:tos][i] == 0}.map {|i| @nodemap.keys[i]} return res end |
#transition_functions_list ⇒ Object
104 105 106 107 108 109 110 111 112 |
# File 'lib/gv_fsm.rb', line 104 def transition_functions_list lst = [] @transitions.each do |t| if t[:function] and !lst.include? t[:function] then lst << (t[:function] or "NULL") end end return lst end |
#transitions_map ⇒ Object
114 115 116 117 118 119 120 121 122 123 |
# File 'lib/gv_fsm.rb', line 114 def transitions_map idx = {} map = Array.new(@states.count) map.map! {|e| e = Array.new(@states.count, "NULL")} states_list.each_with_index {|s, i| idx[s] = i } @transitions.each do |t| map[idx[t[:from]]][idx[t[:to]]] = (t[:function] or "NULL") end map end |
#transitions_paths ⇒ Object
134 135 136 137 138 139 140 141 |
# File 'lib/gv_fsm.rb', line 134 def transitions_paths path = {} @transitions.each do |t| path[t[:function]] = [] unless path[t[:function]] path[t[:function]] << {from: t[:from], to: t[:to]} end return path end |