Class: ArtDecomp::FSM
- Inherits:
-
Object
- Object
- ArtDecomp::FSM
- Defined in:
- lib/art-decomp/fsm.rb
Class Method Summary collapse
Instance Method Summary collapse
- #==(other) ⇒ Object (also: #eql?)
- #beta_f ⇒ Object
- #beta_q ⇒ Object
- #beta_qp ⇒ Object
- #beta_x(ins) ⇒ Object
- #beta_y(ins) ⇒ Object
- #expand_x(ins) ⇒ Object
- #fsm_cells(archs) ⇒ Object
- #general_relevance ⇒ Object
- #hash ⇒ Object
- #implementable_in?(archs) ⇒ Boolean
-
#initialize(inputs, outputs, state, next_state) ⇒ FSM
constructor
A new instance of FSM.
- #input_count ⇒ Object
- #output_count ⇒ Object
- #q_encoding(rows) ⇒ Object
- #state_rows_of_next_state_of(rows) ⇒ Object
- #stats ⇒ Object
- #to_kiss ⇒ Object
- #truth_table? ⇒ Boolean
- #unique_relevance ⇒ Object
- #x_encoding(ins, rows) ⇒ Object
- #y_encoding(rows) ⇒ Object
Constructor Details
#initialize(inputs, outputs, state, next_state) ⇒ FSM
Returns a new instance of FSM.
28 29 30 |
# File 'lib/art-decomp/fsm.rb', line 28 def initialize inputs, outputs, state, next_state @inputs, @outputs, @state, @next_state = inputs.freeze, outputs.freeze, state.freeze, next_state.freeze end |
Class Method Details
.from_kiss(kiss) ⇒ Object
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/art-decomp/fsm.rb', line 3 def self.from_kiss kiss kiss = File.read kiss unless kiss.index "\n" inputs, outputs, state, next_state = [], [], [], [] kiss.lines do |line| case line when /^\s*[01-]+\s+\S+\s+\S+\s+[01-]+\s*$/ then ins, st, nxt, outs = *line.split when /^\s*[01-]+\s+[01-]+\s*$/ then st, nxt, ins, outs = DontCare, DontCare, *line.split else next end inputs << ins.split(//).map(&:to_sym) outputs << outs.split(//).map(&:to_sym) state << (st == '*' ? DontCare : st.to_sym) next_state << (nxt == '*' ? DontCare : nxt.to_sym) end # FIXME: the below hack makes state have all possible values by expanding a don’t-care a bit (if present) (next_state - state - [DontCare]).each do |missing_state| i = state.index DontCare state << missing_state next_state << next_state[i] inputs << inputs[i] outputs << outputs[i] end if state.index DontCare new inputs.transpose, outputs.transpose, state, next_state end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
32 33 34 |
# File 'lib/art-decomp/fsm.rb', line 32 def == other [@inputs, @outputs, @state, @next_state] == [other.inputs, other.outputs, other.state, other.next_state] end |
#beta_f ⇒ Object
36 37 38 |
# File 'lib/art-decomp/fsm.rb', line 36 def beta_f @outputs.map { |o| Blanket.from_array o }.inject(:*) * Blanket.from_array(@next_state) end |
#beta_q ⇒ Object
40 41 42 |
# File 'lib/art-decomp/fsm.rb', line 40 def beta_q Blanket.from_array @state end |
#beta_qp ⇒ Object
44 45 46 |
# File 'lib/art-decomp/fsm.rb', line 44 def beta_qp Blanket.from_array @next_state end |
#beta_x(ins) ⇒ Object
48 49 50 |
# File 'lib/art-decomp/fsm.rb', line 48 def beta_x ins beta @inputs, ins end |
#beta_y(ins) ⇒ Object
52 53 54 |
# File 'lib/art-decomp/fsm.rb', line 52 def beta_y ins beta @outputs, ins end |
#expand_x(ins) ⇒ Object
58 59 60 61 |
# File 'lib/art-decomp/fsm.rb', line 58 def ins return self unless ins.any? { |i| @inputs[i].include? DontCare } FSM.from_kiss to_kiss.lines.map { |line| line.(ins) }.flatten.sort.join end |
#fsm_cells(archs) ⇒ Object
63 64 65 66 |
# File 'lib/art-decomp/fsm.rb', line 63 def fsm_cells archs return 0 if @outputs.map { |output| Blanket.from_array output }.inject(:*).size < 2 Arch[input_count + beta_q.pins, output_count + beta_q.pins].cells archs end |
#general_relevance ⇒ Object
68 69 70 |
# File 'lib/art-decomp/fsm.rb', line 68 def general_relevance relevance false end |
#hash ⇒ Object
72 73 74 |
# File 'lib/art-decomp/fsm.rb', line 72 def hash @inputs.hash ^ @outputs.hash ^ @state.hash ^ @next_state.hash end |
#implementable_in?(archs) ⇒ Boolean
76 77 78 |
# File 'lib/art-decomp/fsm.rb', line 76 def implementable_in? archs not fsm_cells(archs).nil? end |
#input_count ⇒ Object
80 81 82 |
# File 'lib/art-decomp/fsm.rb', line 80 def input_count @inputs.size end |
#output_count ⇒ Object
89 90 91 |
# File 'lib/art-decomp/fsm.rb', line 89 def output_count @outputs.size end |
#q_encoding(rows) ⇒ Object
84 85 86 87 |
# File 'lib/art-decomp/fsm.rb', line 84 def q_encoding rows # FIXME: consider tr DontCare, '*' encoding @state, rows end |
#state_rows_of_next_state_of(rows) ⇒ Object
93 94 95 96 |
# File 'lib/art-decomp/fsm.rb', line 93 def state_rows_of_next_state_of rows state = @next_state[rows.bits.first] B[*(0...@state.size).select { |i| @state[i] == state or @state[i] == DontCare }] end |
#stats ⇒ Object
98 99 100 |
# File 'lib/art-decomp/fsm.rb', line 98 def stats "#{@inputs.size}/#{@outputs.size}+#{(@state.uniq - [DontCare]).size}s" end |
#to_kiss ⇒ Object
102 103 104 105 106 107 108 109 |
# File 'lib/art-decomp/fsm.rb', line 102 def to_kiss st = @state.map { |e| e == DontCare ? '*' : e } nxt = @next_state.map { |e| e == DontCare ? '*' : e } div = Array.new @state.size, ' ' mid = truth_table? ? [div] : [div, st, div, nxt, div] cols = @inputs + mid + @outputs KISS.new(cols.transpose.map(&:join)).formatted end |
#truth_table? ⇒ Boolean
111 112 113 |
# File 'lib/art-decomp/fsm.rb', line 111 def truth_table? @state.all? { |s| s == DontCare } and @next_state.all? { |ns| ns == DontCare } end |
#unique_relevance ⇒ Object
115 116 117 |
# File 'lib/art-decomp/fsm.rb', line 115 def unique_relevance relevance true end |
#x_encoding(ins, rows) ⇒ Object
119 120 121 |
# File 'lib/art-decomp/fsm.rb', line 119 def x_encoding ins, rows ins.map { |i| encoding @inputs[i], rows }.join end |
#y_encoding(rows) ⇒ Object
123 124 125 |
# File 'lib/art-decomp/fsm.rb', line 123 def y_encoding rows @outputs.map { |output| encoding output, rows }.join end |