Class: YATM::Machine

Inherits:
Object
  • Object
show all
Defined in:
lib/yatm/machine/machine.rb

Overview

This is the class used to set up and use the turing machine.

Use #event to create the various transitions. The states are automatically inferred to be all the states added through this method.

Use #initial_state once to select the initial state, and #final_state however many times to mark states as final.

The content of the tape can be given upon initializing the machine, through the parameter content, or with the method #reset.

Examples:

A turing machine which prints an “OX” and halts at position 0.

m = YATM::Machine.new
m.event nil,
  start:   [:running, "O", :r],
  running: [:halt, "X", :l]
m.initial_state :start
m.final_state :halt
m.run!

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(position: 0, content: [nil]) ⇒ Machine

Returns a new instance of Machine.

Parameters:

  • position (Integer) (defaults to: 0)

    The initial position of the machine’s head.

  • content (Array) (defaults to: [nil])

    The initial content of the tape, starting from position 0.



32
33
34
35
36
# File 'lib/yatm/machine/machine.rb', line 32

def initialize(position: 0, content: [nil])
  @tape = YATM::Tape.new(content, position: position)
  @state_machine = YATM::StateMachine.new
  @history = []
end

Instance Attribute Details

#historyArray<Hash> (readonly)

Returns A record of the transitions undergone by the machine.

Returns:

  • (Array<Hash>)

    A record of the transitions undergone by the machine.



28
29
30
# File 'lib/yatm/machine/machine.rb', line 28

def history
  @history
end

#state_machineObject (readonly)

The state machine associated with this turing machine.



26
27
28
# File 'lib/yatm/machine/machine.rb', line 26

def state_machine
  @state_machine
end

#tapeObject (readonly)

The tape over which values can be written and read by the machine.



24
25
26
# File 'lib/yatm/machine/machine.rb', line 24

def tape
  @tape
end

Instance Method Details

#eventObject



50
# File 'lib/yatm/machine/machine.rb', line 50

def event(...); @state_machine.event(...); end

#eventsObject



48
# File 'lib/yatm/machine/machine.rb', line 48

def events(...); @state_machine.events(...); end

#final_stateArray

Returns The complete list of final states.

Parameters:

  • states (#to_s && #to_sym)

    The state or array of states to be marked as final states

Returns:

  • (Array)

    The complete list of final states



43
# File 'lib/yatm/machine/machine.rb', line 43

def final_state(...); @state_machine.final_state(...); end

#initial_stateString, ...

Returns The initial state.

Parameters:

  • state (String, Symbol, Number)

    The state to be set as the starting state.

Returns:

  • (String, Symbol, Number)

    The initial state.



40
# File 'lib/yatm/machine/machine.rb', line 40

def initial_state(...); @state_machine.initial_state(...); end

#resetObject



52
53
54
55
56
# File 'lib/yatm/machine/machine.rb', line 52

def reset(...)
  @history = []
  @tape.reset(...)
  @state_machine.reset
end

#runObject



107
108
109
# File 'lib/yatm/machine/machine.rb', line 107

def run(...)
  run!(...) rescue YATM::Error
end

#run!(max = Float::INFINITY) ⇒ Object



100
101
102
103
104
105
# File 'lib/yatm/machine/machine.rb', line 100

def run!(max = Float::INFINITY)
  (1..max).each do
    latest = step!
    break to_h if latest[:final]
  end
end

#statesArray

Returns The list of all states of the state machine.

Returns:

  • (Array)

    The list of all states of the state machine



46
# File 'lib/yatm/machine/machine.rb', line 46

def states(...); @state_machine.states(...); end

#stepObject



96
97
98
# File 'lib/yatm/machine/machine.rb', line 96

def step(...)
  step!(...) rescue YATM::Error
end

#step!(n = 1) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/yatm/machine/machine.rb', line 81

def step!(n = 1)
  return if n < 1

  (1..n).each do
    result = @state_machine.process!(@tape.read)
    @history << result
    break if result[:final]

    @tape.write result[:write]
    @tape.move result[:move]
  end

  @history.last
end

#to_hObject



58
59
60
61
62
63
64
# File 'lib/yatm/machine/machine.rb', line 58

def to_h
  {
    state: @state_machine.current_state,
    final: @state_machine.final_states.include?(@state_machine.current_state),
    position: @tape.pos
  }
end

#to_sObject



66
# File 'lib/yatm/machine/machine.rb', line 66

def to_s; to_h.to_s; end

#to_txtObject



68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/yatm/machine/machine.rb', line 68

def to_txt
  <<~TO_S
    ,_______________
    | State Machine
    `---------------
    #{@state_machine}
    ,______
    | Tape
    `------
    #{@tape}
  TO_S
end