Class: StateMachineChecker::FiniteStateMachine

Inherits:
Object
  • Object
show all
Defined in:
lib/state_machine_checker/finite_state_machine.rb

Overview

Represents a finite state machine: a set of states, an initial state, and transitions among them.

This class is used to limit the dependency on any particular state machine library.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(initial_state, transitions) ⇒ FiniteStateMachine

Returns a new instance of FiniteStateMachine.

Parameters:

  • initial_state (Symbol)

    the name of the initial state.

  • transitions (Array<Transition>)

    the transitions of the FSM.


12
13
14
15
# File 'lib/state_machine_checker/finite_state_machine.rb', line 12

def initialize(initial_state, transitions)
  @initial_state = initial_state
  @transitions = transitions
end

Instance Attribute Details

#initial_stateObject (readonly)

Returns the value of attribute initial_state


8
9
10
# File 'lib/state_machine_checker/finite_state_machine.rb', line 8

def initial_state
  @initial_state
end

#transitionsObject (readonly)

Returns the value of attribute transitions


8
9
10
# File 'lib/state_machine_checker/finite_state_machine.rb', line 8

def transitions
  @transitions
end

Instance Method Details

#state_pathsEnumerator<Array(Symbol, Array<Transition>)>

Enumerate the states and for each provide a path to it.

Returns:

  • (Enumerator<Array(Symbol, Array<Transition>)>)

    an enumerator where each element is a pair of a state and an array of transitions to reach the state.


22
23
24
25
26
# File 'lib/state_machine_checker/finite_state_machine.rb', line 22

def state_paths
  Enumerator.new do |yielder|
    depth_first_search(Set.new, initial_state, [], yielder)
  end
end

#statesEnumerator<Symbol>

Enumerate the states.

Returns:

  • (Enumerator<Symbol>)

    an enumerator over the names of the states.


31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/state_machine_checker/finite_state_machine.rb', line 31

def states
  seen = Set.new

  Enumerator.new do |yielder|
    seen << initial_state
    yielder << initial_state

    transitions.each do |transition|
      unless seen.include?(transition.from)
        seen << transition.from
        yielder << transition.from
      end

      unless seen.include?(transition.to)
        seen << transition.to
        yielder << transition.to
      end
    end
  end
end

#transitions_from(state) ⇒ Object


64
65
66
# File 'lib/state_machine_checker/finite_state_machine.rb', line 64

def transitions_from(state)
  transitions.select { |t| t.from == state }
end

#transitions_to(state) ⇒ Object


68
69
70
# File 'lib/state_machine_checker/finite_state_machine.rb', line 68

def transitions_to(state)
  transitions.select { |t| t.to == state }
end

#traverse(from_state, reverse: false) {|Symbol, Array<Symbol>| ... } ⇒ Object

Traverse the graph from the given state. Yield each state and the transitions from it to the from_state. If the result of the block is falsey for any state then the search will not continue to the children of that state.

Parameters:

  • from_state (Symbol)
  • reverse (true, false) (defaults to: false)

    traverse in reverse?

Yields:

  • (Symbol, Array<Symbol>)

60
61
62
# File 'lib/state_machine_checker/finite_state_machine.rb', line 60

def traverse(from_state, reverse: false, &block)
  rec_traverse(from_state, [], Set[from_state], reverse, &block)
end