diff --git a/source/finite-state-machines/ch-finite-state-machines.ptx b/source/finite-state-machines/ch-finite-state-machines.ptx index 93b115d1..31c3afee 100644 --- a/source/finite-state-machines/ch-finite-state-machines.ptx +++ b/source/finite-state-machines/ch-finite-state-machines.ptx @@ -3,15 +3,18 @@ Finite State Machines -

- In this chapter, we explore a powerful abstract model: finite-state machine (finite - automata). Beyond its theory, we'll see how to use SageMath to define, model, then build, - visualize and run an example of a state machine to solve a real-world problem.

+

In this chapter, we explore a powerful abstract model: finite-state machines. + Beyond the theory, we'll see how to use Sage to define, model and build, then + visualize and run a few examples of state machines to solve real-world problems.

diff --git a/source/finite-state-machines/sec-extended-example.ptx b/source/finite-state-machines/sec-extended-example.ptx index ab6153c4..b3818a54 100644 --- a/source/finite-state-machines/sec-extended-example.ptx +++ b/source/finite-state-machines/sec-extended-example.ptx @@ -1,6 +1,7 @@
FSM in Action + Controlling Traffic Lights and Pedestrian Crossing Signals

diff --git a/source/finite-state-machines/sec-modeling-finite-state-machines.ptx b/source/finite-state-machines/sec-modeling-finite-state-machines.ptx index f227ab31..c2a348d1 100644 --- a/source/finite-state-machines/sec-modeling-finite-state-machines.ptx +++ b/source/finite-state-machines/sec-modeling-finite-state-machines.ptx @@ -1,29 +1,125 @@

- State Machine in SageMath + State Machine in Sage state machines model

- Although SageMath does have a dedicated built-in module to handle state + Although Sage does have a dedicated built-in module to handle state machines, we can still model, construct, display, and run relatively simple state machines, leveraging the general-purpose tools, such as graphs and transition matrices, to represent and work with state machines.

In this section, we'll explore how to define states, create a state transition graph, - visualize the state machine, and simulate its execution in SageMath.

+ visualize the state machine, and simulate its execution in Sage.

+ + + Example of Application of FSMs + + State Machine Transitions and Outputs +

Assume there is a 3-levels elevator (floors 1 thru 3). this elevator moves in the + same direction (up or down) until it reaches the last floor while moving up, or + the first floor while moving down. It makes stop at every floor on its way up or + down. Each floor has 3 buttons to press while selecting the destination floor. +

+

Next, we'll see how to model and simulate this system using an FSM. In this example, + we have the various states S={fl_1, fl_2, fl_3} representing each of the + floors, the different user inputs X={push-1, push-2, push-3}, and the + possible outputs for the elevator Z={go_up, go_down, no_action} The different + components of this FSM can be transcribed in the following table.

+ + + + + | + + + next state + + + | + + + output + + + + from + | + + push-1 + push-2 + push-3 + + | + + push-1 + push-2 + push-3 + + + + fl_1 + + | + + fl_1 + fl_2 + fl_3 + + | + + no_change + go_up + go_up + + + + fl_2 + + | + + fl_1 + fl_2 + fl_3 + + | + + go_down + no_change + go_up + + + + fl_3 + + | + + fl_1 + fl_2 + fl_3 + + | + + go_down + go_down + no_change + + + +
+
+ Define States, Transitions and Outputs

The first step is to define the states and transitions in the state machine. We can @@ -31,56 +127,57 @@

- # Define states - states = ['S0', 'S1', 'S2', 'S3', 'S4'] + # Define state, input and output sets + states = ['fl_1', 'fl_2', 'fl_3'] + inputs = ['push-1', 'push-2', 'push-3'] + outputs = ['go_up', 'go_down', 'no_change'] - # Assume there are 2 possible input events (actions) {A0, A1}, we then - # define transitions as a dictionary {current_state: {input: next_state}} + # transitions are defined as a dictionary {(current_state, input): next_state} transitions = { - 'S0': { - 'A0': 'S1' - }, - 'S1': { - 'A0': 'S2', - 'A1': 'S3' - }, - 'S2': { - 'A0': 'S0', - 'A1': 'S4' - }, - 'S3': { - 'A0': 'S4' - }, - 'S4': { - 'A0': 'S0' - } + ('fl_1', 'push-1'): 'fl_1', + ('fl_1', 'push-2'): 'fl_2', + ('fl_1', 'push-3'): 'fl_3', + + ('fl_2', 'push-1'): 'fl_1', + ('fl_2', 'push-2'): 'fl_2', + ('fl_2', 'push-3'): 'fl_3', + + ('fl_3', 'push-1'): 'fl_1', + ('fl_3', 'push-2'): 'fl_2', + ('fl_3', 'push-3'): 'fl_3', } - # The machine output controls a locking mechanism that can be either LOCKED, or UNLOCKED + # The machine output controls how the elevator would move outputs = { - 'S0': 'LOCKED', - 'S1': 'LOCKED', - 'S2': 'LOCKED', - 'S3': 'UNLOCKED', - 'S4': 'UNLOCKED' + ('fl_1', 'push-1'): 'no_change', + ('fl_1', 'push-2'): 'go_up', + ('fl_1', 'push-3'): 'go_up', + + ('fl_2', 'push-1'): 'go_down', + ('fl_2', 'push-2'): 'no_change', + ('fl_2', 'push-3'): 'go_up', + + ('fl_3', 'push-1'): 'go_down', + ('fl_3', 'push-2'): 'go_down', + ('fl_3', 'push-3'): 'no_change', } # Display the machine configuration - import json print('States: ', states, '\n') - print('Transitions: ', json.dumps(transitions, indent=2), '\n') - print('Outputs: ', json.dumps(outputs, indent=2), '\n') + print('Transitions: ', transitions, '\n') + print('Outputs: ', outputs, '\n')

- The states are defined as vertices in the graph, the transitions (along with the outputs) are defined as directed + The states are defined as vertices in the graph, the transitions (along with the + outputs) are defined as directed edges between these vertices.

- Create Graph Model of State Machine -

In SageMath, we can use the DiGraph class to represent the states, transitions - and outputs of the state machine as a directed graph, and use the graph structure to + Create and Display the Graph Model of State Machine +

In Sage, we can use the DiGraph class to represent the states, transitions and + outputs of the state machine as a directed graph, and use the graph structure to visualize the state machine representation.

@@ -88,43 +185,27 @@ # from sage.graphs.digraph import DiGraph # Initialize a directed graph - SM = DiGraph() + SM = DiGraph(loops=True) # Add states as vertices SM.add_vertices(states) # Add transitions and outputs as edges - for state, transition in transitions.items(): - if outputs[state] == 'LOCKED': - output = 'L' - elif outputs[state] == 'UNLOCKED': - output = 'U' - else: - output = '?' - - for action, next_state in transition.items(): - edge_label = f"{action},{output}" - SM.add_edge(state, next_state, label=edge_label) - - SM.__repr__() - - - -
- - Display the State Machine -

- The SM.show() command renders a graphical representation of the state machine. - Each vertex in the graph represents a state, and each directed edge represents a - transition, labeled with the input.

- - + for (_state, _input), next_state in transitions.items(): + _output = outputs[(_state, _input)] + edge_label = f"{_input}, {_output}" + SM.add_edge(_state, next_state, label=edge_label) + # Display the graph (state machine) SM.show(edge_labels=True) +

The SM.show() command renders a graphical representation of the state machine. + Each vertex in the graph represents a state, and each directed edge represents a + transition, labeled with the input.

+ Run the State Machine

@@ -135,30 +216,28 @@ # Function to run the state machine def run_state_machine(start_state, inputs): current_state = start_state - for action in inputs: - print(f"Current State: {current_state}, Action: {action}") + for _input in inputs: + print(f"Current State: {current_state}, Input: {_input}") - if action in transitions[current_state]: - current_state = transitions[current_state][action] - print(f"Transitioned to: {current_state}") + if (current_state, _input) in transitions: + current_state = transitions[(current_state, _input)] + print(f"Transitioned to: {current_state}\n") else: - print(f"No transition available for action {action} in state {current_state}") + print(f"No transition available for input {_input} in state {current_state}") break - print(f"Final State: {current_state}") - + print(f"New State: {current_state}") # Example of running the state machine - start_state = 'S0' - inputs = ['A0', 'A0', 'A1', 'A0'] + start_state = 'fl_2' + inputs = ['push-1', 'push-1', 'push-3', 'push-2'] run_state_machine(start_state, inputs) -

- The run_state_machine function simulates the state machine by processing - a list of inputs starting from an initial state.

+

The run_state_machine function simulates the state machine by processing a list + of inputs starting from an initial state.

@@ -174,10 +253,10 @@

- FSMState() helps define state for the given label, the is_initial - flag can be set to true to indicate the current state will be the initial state - of the finite state machine. add_state() method is then used to append the state - to the state machine

+ FSMState() helps define state for the given label, the is_initial flag can + be set to true to indicate the current state will be the initial state of the + finite state machine. add_state() method is then used to append the state to the + state machine

go = FSMState('GO', is_initial=True) @@ -192,8 +271,7 @@ -

- To check whether or not a finite state machine has a state defined, has_state() +

To check whether or not a finite state machine has a state defined, has_state() method can be used by passing in the state label (case-sensitive).

@@ -202,8 +280,8 @@

- states() method is used to enumerate the list of all defined states - of the state machine.

+ states() method is used to enumerate the list of all defined states of the state + machine.

fsm.states() @@ -211,8 +289,7 @@

- initial_states() method lists the defined initial state(s) - of the state machine.

+ initial_states() method lists the defined initial state(s) of the state machine.

fsm.initial_states() @@ -220,11 +297,10 @@

- FSMTransition() defines a new transition between two states, - as well as the input (the transition trigger) and output associated - with the new state after teh transition.add_transition() method - attach the defined transition to the state machine. transitions() - method is used to enumerate the list of all defined transitions of the + FSMTransition() defines a new transition between two states, as well as the input + (the transition trigger) and output associated with the new state after teh transition. + add_transition() method attach the defined transition to the state machine. + transitions() method is used to enumerate the list of all defined transitions of the state machine.

@@ -239,16 +315,14 @@ -

- Once the states and transitions as defined, the state machine can berun - using process() method. -

+

Once the states and transitions as defined, the state machine can berun using + process() method.

# pass in the initial state and the list of inputs _, final_state, outputs_history = fsm.process( - initial_state=go, - input_tape=[1, 2, 0], + initial_state=go, + input_tape=[1, 2, 0], ) # display final/current state @@ -257,8 +331,8 @@

- process() method also returned the list of intermediary outputs during - the state machine run.

+ process() method also returned the list of intermediary outputs during the state + machine run.

# print out the outputs of the state machine run @@ -274,32 +348,34 @@ -

- The FiniteStateMachine class also offers LATEX representation of the state +

The FiniteStateMachine class also offers LATEX representation of the state machine using the latex_options() method.

- - - # define LATEX printout options - fsm.latex_options( - coordinates={ - 'day': (0, 0), - 'night': (6, 0)}, - initial_where={'day': 'below'}, - format_letter=fsm.format_letter_negative, - format_state_label=lambda x: x.label(), - ) - - # display LATEX commands - print(latex(fsm)) - - - -
+ + + # define LATEX printout options + fsm.latex_options( + coordinates={ + 'day': (0, 0), + 'night': (6, 0)}, + initial_where={'day': 'below'}, + format_letter=fsm.format_letter_negative, + format_state_label=lambda x: x.label(), + ) + + # display LATEX commands + print(latex(fsm)) + + + +

- The above are basic commands with a typical workflow of defining and running of simple finite - state machines. The general structure of the state machine can be adapted to fit different use - cases. The examples shown can be customized and fine-tuned to reflect more complex scenarios - (more states, different input sequences, ...etc).

+ The above are basic commands with a typical workflow of defining and running of simple + finite + state machines. The general structure of the state machine can be adapted to fit + different use + cases. The examples shown can be customized and fine-tuned to reflect more complex + scenarios + (more states, different input sequences, etc.)

diff --git a/source/finite-state-machines/sec-state-machine-definition.ptx b/source/finite-state-machines/sec-state-machine-definition.ptx index 73bb30a1..8a5179da 100644 --- a/source/finite-state-machines/sec-state-machine-definition.ptx +++ b/source/finite-state-machines/sec-state-machine-definition.ptx @@ -1,53 +1,221 @@
- Finite-State Machines - -

The defining feature of any abstract machine is its memory structure, ranging from a + Definitions and Components + +

The defining feature of any abstract machine is its memory structure, ranging from a finite set of states in the case of finite-state machines to more complex memory - systems (Turing machines).

-

A Finite-State Machine (FSM) has an input device (that physically could represent - a tape, data stream, memory space ...etc), divided into segments, each holding an - instruction symbol or a blank. This abstract machine also has a read head that scans the - current symbol from the input alphabet X. After each read, the head always moves - to the next segment. The machine may also have an output device, with symbols drawn from - an output alphabet Z, which may differ from the input alphabet.

+ systems (ex.Turing machines, and Petri net).

+ +

A Finite-State Machine (FSM) is a a computational model that has a finite + set of possible states S, a finite set of possible input symbols (the input + alphabet) X, a finite set of possible output symbols (the output alphabet) + Z. The machine can exist in one of the states at any time, and based on the + machine input and its current state, it can transition to any other state. The default + state of an FSM is referred to as the initial state.

+ +

An infinite sequence of input (respectively, output) symbols is called an input + (respectively, output) stream. Although the input and output alphabets of a + finite-state machine are finite sets, the input and output streams can be of + infinite size.

+ +

For every input the machine receives, it transition to a new state (or remains at the + current state), and it produces an output. The functions that take in the machine + current state and its input and map them to the machine's future state and its output + are referred to as the state transition function and the output + function respectively.

+ +

In a finite state machine, a final state (also known as the accepted state) is a + special predefined state that indicates whether an input sequence is valid or + accepted by the machine. The set F of all final states is a subset of the states + set S.

+ +

When the state machine processes a finite input sequence, it transition through various + states based on each input in the sequence and the current state of the machine. If, + after processing the entire sequence, the machine ends up in any of the final state, + then the input is considered valid (or recognized according to the machine's rules). + Otherwise, the input is rejected as invalid. The final states subset is only meaningful + for finite state machines that process the inputs sequence in chunks or segments.

+ Definition state machines definition -

A finite-state machine is defined by a sextuple (S, X, Z, w, t, s_1) where: +

A finite-state machine is defined by the tuple (S, X, Z, w, t, s_0, F) where:

  • - S=\{s_1, s_2,\ldots , s_r\} is the state set, a finite set that - corresponds to the set of memory configurations that the machine can have at - any time, where s_1 is the initial state.

    + S=\{s_0, s_1, s_2,\ldots , s_n\} is the state set, a finite set that + corresponds to the set of all memory configurations that the machine can have at any + time s_0 is the initial state + optionally F \subset S is + the subset of all final states (when omitted, it is assumed that F=S).

  • - X=\{x_1, x_2, \ldots ,x_m\} is the input alphabet.

    + X=\{x_0, x_1, x_2, \ldots ,x_m\} is the input alphabet.

  • - Z=\{z_1,z_2, \ldots ,z_n\} is the output alphabet.

    + Z=\{z_0, z_1,z_2, \ldots ,z_k\} is the output alphabet.

  • - w: X\times S \to Z is the output function, which specifies which - output symbol w(x, s) \in Z is written onto the output device when - the machine is in state s and the input symbol x is read.

    + w: S\times X \to Z is the output function, which specifies which + output symbol w(s, x) \in Z is written onto the output device when the machine is + in state s and the input symbol x is read.

  • - t:X\times S\to S is the next-state (or transition) function, which - specifies which state t(x, s) \in S the machine should enter when - it is in state s and it reads the symbol x.

    + t:S\times X \to S is the next-state (or transition) function, which + specifies which state t(s, x) \in S the machine should move to when it is + currently in state s and it reads the input symbol x.

+ + + Types of Finite State Machines + + + Mealy Machine + +

The output in a Mealy Machine, is a function of both the current + state and the input, which means the output can change immediately when inputs + change, without needing to wait for the state transition.

+ +

A Mealy machine is represented by the 6-tuple (S, X, Z, w, t, s_0) where: +

    +
  • +

    + S=\{s_0, s_1, s_2,\ldots , s_n\} is the state set, and s_0 + is the initial state.

    +
  • +
  • +

    + X=\{x_0, x_1, x_2, \ldots ,x_m\} is the input alphabet.

    +
  • +
  • +

    + Z=\{z_0, z_1,z_2, \ldots ,z_k\} is the output alphabet.

    +
  • +
  • +

    + w: S\times X \to Z is the output function, which specifies which + output symbol w(s, x) \in Z maps to the machine state s and the input + x.

    +
  • +
  • +

    + t:S\times X \to S is the transition function, which + specifies which next state t(s, x) \in S the machine should move to when its + current state is s and it has the input symbol x.

    +
  • +
+

+

Example: A vending machine that produces output based on the current state and + inserted coins.

+
+
+ + + Moore Machine +

In a Moore Machine, the output depends solely on the current state. + Unlike Mealy state machine, this machine must enter a new state for the output to change.

+ +

A Moore machine is also represented by the 6-tuple (S, X, Z, w, t, s_0) where: +

    +
  • +

    + S=\{s_0, s_1, s_2,\ldots , s_n\} is the state set, and s_0 + is the initial state.

    +
  • +
  • +

    + X=\{x_0, x_1, x_2, \ldots ,x_m\} is the input alphabet.

    +
  • +
  • +

    + Z=\{z_0, z_1,z_2, \ldots ,z_k\} is the output alphabet.

    +
  • +
  • +

    + w: S \to Z is the output function, which specifies which + output symbol w(s) \in Z maps to the machine current state s.

    +
  • +
  • +

    + t:S\times X \to S is the transition function, which + specifies which next state t(s, x) \in S the machine should move to when + its current state is s and it has the input symbol x.

    +
  • +
+

+

Example: A traffic light system where the light color is based on the current + state of the system.

+
+
+ + + Other Variants of FSMs + + Finite-State Automaton +

A Finite-State Automaton is a finite state machine with no output, + and it is represented by the 5-tuple (S, X, t, s_0, F) where: +

    +
  • +

    + S=\{s_0, s_1, s_2,\ldots , s_n\} is the state set, and s_0 + is the initial state, and F is the set of finite states.

    +
  • +
  • +

    + X=\{x_0, x_1, x_2, \ldots ,x_m\} is the input alphabet.

    +
  • +
  • +

    + t:S\times X \to S is the transition function, which + specifies which next state t(s, x) \in S the machine should move to when + its current state is s and it has the input symbol x.

    +
  • +
+

+
+ + + Deterministic Finite Automaton (DFA) +

A Deterministic Finite Automaton (DFA) is a simplified FSM where each + state has exactly one transition for each input.

+

DFAs are typically used for lexical analysis, language recognition, and pattern matching. + Example: A string-matching system to recognize specific languages or regular expressions.

+
+ + + Nondeterministic Finite Automaton (NFA) +

Unlike DFA, an NFA allows multiple transitions for the same input or even + transitions without consuming input (\epsilon-transitions).

+

Example: Regular expression (RegEx) engines that explore multiple paths to find a pattern match.

+
+ + + Turing Machine +

A Turing Machine is an FSM with infinite tape memory representing both the input and + output streams (shared stream). Unlike all other FSMs, a Turing machine can alter the input/output + stream, and as such it is capable of simulating any algorithm. Turing machines are the theoretical + foundation for modern computation.

+

Example: Any general-purpose computer executing any algorithm can be modeled as a Turing Machine.

+
+
+ + +

+ Finite state machines are a foundational concept in computer science, which offer a structured way to + model systems with discrete states and transitions. Different variants like Mealy machine and + Moore machine have distinct characteristics, and as such can adapt to various applications. +

+