Introduction
Modern computer systems are used to complete increasingly complex tasks such as finance transactions, communications, and industrial control. Therefore, it is increasingly important that we are confident that a system will function correctly. Traditional testing methods can be used to find faults in software. This involves running test cases using selected inputs, observing the output and identifying any issues. However, this can not always provide full coverage of all possible situations, especially when there are multiple processes, concurrency and complex situations. Model checking enables us to use mathematical models and logical reasoning to determine if a system meets certain requirements. This helps us to explore the possible behaviours within the system to find conditions that may lead to failures. Model checking is particularly useful for building reliable software and safety critical systems.
Model checking is a verification method that can be used to determine if a mathematical model of a computer system meets the desired properties. It uses ideas from computer science, maths, logic and software engineering to analyse the behaviour. It enables verification tools to look at the system and find issues such as deadlocks, incorrect communication, vulnerabilities and unexpected behaviours. The model checking can find errors that may not be found during traditional testing. This can be done by understanding key concepts such as state transition systems, state spaces, temporal logic, verification properties and counterexamples.

What is Model Checking in Computer Science?
Model checking is a formal verification method that can be used to determine if the computer system behaves as expected. This is achieved by creating a mathematical model to represent the system. The developer identifies the desired behaviour of the system and the properties that the system must meet. This is then converted into mathematical logic. The model checker looks at the model to see if the properties are satisfied. If the properties are found not to be met, details can be provided to show why the issue occurred.
Unlike traditional testing, model checking can be used to explore all possible execution paths. For example, if a banking application is being created to allow money transfers between customer accounts. This must ensure that transactions have been completed correctly, and the account balance has not been affected. However, during traditional testing, multiple scenarios may be tested but it may not cover all possible concurrency. Model checking can look at all possible execution paths to ensure the conditions are met. Model checking is an important technique to ensure complex errors can be found in software.
Key Concepts of Model Checking
1. State Transition Systems
A state transition system is a mathematical model that represents the computer system. This shows the different states the system can be in. A state is a specific situation that can occur during the execution. A transition is an action that causes the system to move from one state to another. For example, a simple login application may have states such as logged out, logging in, authenticated and denied. If the user enters the correct login details, the system will change to the authenticated state. On the other hand, if the login details are incorrect, the system will change to the denied state.
State transition systems are very useful as they can simplify complex software. A system may have thousands of internal states, however, the developer can create a simplified model. This can be shown using a directed graph, with circles/nodes representing states. Arrows can be used to represent transitions. Initial states can also be identified to show where the execution will begin. Terminal states can be identified to show a state that can not transition. Model checking can be performed to ensure the system can not get into an invalid state, or become permanently locked.

2. State Spaces
A state space is a complete list of all the states that can be entered in a model. This is one of the most important concepts within model checking, as we want to look at all possible system states to determine if the properties are met. The size of the state space depends on the complexity of the system, the number of variables and the number of different actions that can occur. For example, if there are multiple devices within a communication system, there may be multiple different states depending on if the devices are connected, disconnected, transmitting or waiting.
As the complexity increases, this can cause the state space to become extremely large. This is known as state space explosion. When multiple processes are running simultaneously, this can cause a huge number of possible execution paths. Even a simple piece of software can have many states due to the number of variables and concurrency. Developers and researchers use techniques such as abstraction, symbolic representation, partial order reduction and bounded verification to reduce the amount of information that needs to be checked.
3. Temporal Logic
Temporal logic is a mathematical language that can be used to describe properties. Unlike traditional logic, temporal logic can describe required properties such as sequences, future possibilities and statements that must be true throughout the execution. This makes it very useful for model checking as computer systems are constantly changing state. Temporal logic can be used to describe properties such as ensuring all requests receive a response, ensuring two processes do not access a restricted resource at the same time and ensuring a particular safety condition is always true.
There are two common types of temporal logic, Linear Temporal Logic (LTL) and Computation Tree Logic (CTL). LTL is used to describe properties of a single execution path. CTL is used to describe the properties of multiple execution paths. Both use temporal logic operators. For example, the G operator in LTL means that a condition must always be true. The F operator means a condition must eventually be true. The X operator represents the next state. The U operator means a condition must always be true until another condition becomes true. This can be used to describe complex conditions.
4. Verification Properties
Verification properties are conditions that must be met for the system to behave correctly. These are the requirements that the mathematical model will be checked against. Within model checking, verification properties are often split into safety properties and liveness properties. Safety properties are conditions that must never occur. For example, two processes accessing the same protected resource, and unauthorised users accessing confidential information. On the other hand, liveness properties are conditions that must occur. For example, ensuring processes receive a response to their request, and ensuring that waiting operations are completed.
An online payments platform may have properties such as a safety property that ensures a customer will not be charged twice for a single transaction. They may also have a liveness property that ensures all valid payments will eventually receive a confirmation or rejection. The model checker can look at the system model to ensure these conditions are met. If two payment processes are able to interfere with each other, this may mean that the safety property is not met. If a process can be stuck waiting forever, this may mean the liveness property is not met. Clearly defining these properties will help the developers create measurable conditions to ensure the system is correct.
5. Counterexamples
A counterexample is a list of states and transitions that show why a system does not meet the verification property. If the model checker identifies that a requirement is not met, a counterexample can be provided to show what execution path caused the issue. This is one of the most useful aspects of model checking. It provides structured information to help show why an issue has occurred. Engineers can look at the relevant operations.
For example, if the application allows two processes to update the same record in the database. Only one process should be allowed to update the record at any one time. If the model checker identifies that there is an execution path where both processes have read the original value, this may indicate there is an issue with concurrency. The counterexample will show the order of operations that caused this to happen. The developer can look at the synchronisation mechanism and tweak the relevant code/design. This can then be verified again.
How Model Checking Works
Model checking works by converting the system requirements into a mathematical form. Whilst the method varies per tool, the general steps involve creating a model, defining properties, exploring the state space, analysing the results and fixing any issues.
It is important that the model accurately reflects the important behaviours in the actual system. The properties must be defined using logical statements. If the model is not complete or incorrect it may give misleading results.
Step 1 – Create a Mathematical Model
The first step is to create a mathematical model. This is normally done using a state transition system. The developer will identify the important components, variables, conditions and operations that will impact the behaviour of the system. They will then describe how these interact within the system.
For example, a traffic light controller may have states such as red, red and amber, green, amber. The model will show what transitions are allowed between the states. This can help the developer understand how the controller will behave without having to test all possibilities on the actual traffic lights.
Step 2 – Define Logical Specifications
The developer will define the properties that the system must meet. This will be defined using formal logic. This may include temporal logic. For example, if the developer is creating a communication protocol, they may define a property that says that after sending a valid request, the device will eventually receive a response. They may also define a property that says that two processes must not access the same exclusive resource.
This will convert the general expectations into specific conditions that can be analysed by the model checker. This is a particularly important step as poor specifications will mean the verification is not effective. The developer must understand what the system should do and define the essential conditions for it to be correct.
Step 3 – Explore the State Space
The model checker will look at the states and transitions of the mathematical model. This may involve explicit state exploration, symbolic techniques or other algorithms. The model checker will look at the conditions and determine if the properties are met.
It may identify states that can not be reached, transitions that lead to invalid states or execution paths that stop the system from progressing. It is important that this is done efficiently as complex models can have extremely large state spaces.
Step 4 – Analyse the Results
Once the state space has been explored, the model checker will provide feedback. If the properties are met, this shows that within the model, the system will meet the requirements. If a property is not met, the model checker may provide a counterexample to show the execution path.
The developer can look at this to understand why the issue occurred. They will determine if it was due to the system design, assumptions made in the implementation or the logical specifications. The results must be analysed carefully as just because the verification was successful does not mean all aspects of the real system will be correct.

Step 5 – Fix and Verify Again
If an error is identified during verification, the developer will change the system design, implementation or model. They can then verify again to determine if this has fixed the issue. This will help to improve the reliability of the system. The developer will also have the chance to look at different design options.
For example, if there is an issue with two processes entering a conflicting state, the developer may decide to add a rule around resources. Once the model has been updated, the model checker can look at the new behaviour to ensure the relevant safety and liveness properties are met. This is an important part of creating reliable software.
Issues That Can Be Identified Using Model Checking
1. Deadlock
Deadlock occurs when two or more processes become permanently stuck. This can occur when processes are waiting for a resource or condition to be released or met by another process. Deadlock is a common issue when there are shared resources, concurrency and complex resource management.
For example, one process may be waiting for another resource whilst holding a record in the database. Whilst this process is waiting, another process may be holding this resource and waiting for the first record. This means neither process can progress. Model checking can help identify if the system can enter a state where none of the relevant processes can progress.
2. Security Vulnerabilities
Model checking can help identify security vulnerabilities. The developer can define properties to ensure that unauthorized users can not enter protected states, access restricted resources or perform actions that they are not authorised to. The model checker will look at the transitions to ensure these conditions are met. For example, a system may require that only authenticated users can access confidential account information.
If there is a way for an unauthenticated user to enter a protected state using an unexpected execution path, this can be identified using verification. Whilst model checking can’t fully replace thorough security testing, it can provide an extra method of analysing security related behaviour.
3. Concurrency Issues
Concurrency issues can occur when multiple processes/threads are running. This can cause unexpected results. This can be difficult to identify as the outcome may depend on the order of the operations. Common issues include race conditions, incorrect data updates and incorrect synchronisation.
Model checking can be useful as it can look at different execution paths to identify if any of them do not meet the requirements. For example, if a database application allows two users to update the same information. If the system does not manage these updates correctly, one may override the other or provide inconsistent information. This can be identified using verification.

4. Unexpected Behaviours
Sometimes computer systems do not behave as expected. This can be due to incorrect assumptions, incomplete requirements or interactions between components. A feature may work correctly under normal circumstances but fail when unexpected events occur or multiple operations are happening.
Model checking can help identify these issues. For example, an automated device may be expected to stop an operation when a condition becomes true. If the model allows another event to occur that stops the transition from happening, this may be identified during verification. This can help the developer improve the predictability of the system.
Applications Of Model Checking In Computer Science
Model checking can be used in a variety of areas within computing. It is particularly useful when there are concurrent processes, complex communication and strict requirements.
Whilst it may not be suitable for all software development projects, it can provide many benefits when failures could impact data integrity, service availability, security and physical equipment. Below are examples of where model checking can be used.
1. Operating Systems
An operating system manages important processes within the computer such as process scheduling, memory management, file access and application/hardware communication. This involves many processes that may be running concurrently. Therefore it is important to manage the synchronisation carefully to avoid deadlocks, resource conflicts and unexpected behaviours.
Model checking can help the developers to look at scheduling algorithms, process management and synchronisation to ensure they meet important requirements. For example, it can be used to determine if processes can become permanently stuck whilst waiting for a resource. Or if two processes can enter a protected section. This can help to improve the reliability of the operating system and resource management.
2. Communication Protocols
Communication Protocols refer to the process by which devices and software applications communicate with one another. They define how messages will be sent, received, acknowledged and processed. If the protocol does not function as intended then issues can occur such as duplicate messages, lost information and security issues. Model checking can be very useful for protocol designers, to see how different message sequences can be handled and ensure the protocols meet their intended requirements.
For example, a model could be created to simulate two devices communicating. This could show how any delays, duplicated messages or unexpected message order will affect the system. The model can also show whether the messages will eventually be sent and that both devices have a shared understanding of the current state of their connection. This makes model checking an invaluable tool for developing reliable systems.
3. Embedded Devices
Embedded devices are specialised computing devices designed to carry out a specific function. Many embedded devices are present in vehicles, medical monitoring equipment, home devices, telecommunication devices and industrial devices. Many of these devices will have limited computing resources and will need to react to specific conditions in their environment.
Model checking can be used to verify that the control logic, timing and hardware-software interactions meet the requirements. For example, a temperature control device may have a requirement to turn on the cooling system if the temperature goes above a certain point. This can be verified using a model to see if there are any issues with the model entering an incorrect state or not reacting.
4. Industrial Automation
Industrial automation uses computer controlled devices to manage processes. Often, there will be multiple devices involved in the automation process that need to work together in a specific order. If there are issues with the communication or control logic then this can cause disruption to the production process, damage to the devices and unsafe conditions.
Model checking can be used to verify the interactions of the automated components. For example, a manufacturing system may require the conveyor belt to stop before the robotic component carries out a specific action. This can be checked using a mathematical model to ensure that the system does not enter an invalid state where both actions are carried out incorrectly.
5. Safety Critical Software
Safety critical software refers to software that controls or supports a system that could result in serious consequences if it behaves incorrectly. This could be seen in aircraft control systems, medical equipment, train signalling and certain industrial control systems.
The software needs to be carefully verified to ensure there are no issues. Model checking can be used to check that the essential properties are always true. For example, an aircraft control system may have requirements to prevent conflicting controls or ensure that specific safety conditions are met. Using formal verification provides further evidence that the requirements are satisfied.

Popular Model Checking Tools
There are various tools available to aid model checking and formal verification. Each has different features such as modelling languages, logic types and verification processes. Some are ideal for checking communication protocols and concurrent systems whilst others are for software models, hardware designs and mathematics. Choosing the right tool will depend on the system being checked, what properties need to be checked and how complex the model is.
| Model Checking Tool | Primary Use | Features |
| SPIN | Verifying Concurrent Software Systems & Communication Protocols | Supports Promela modelling language and temporal logic. |
| NuSMV | Symbolic Model Checking | Supports CTL & LTL specifications. |
| UPPAAL | Verifying Real Time Systems | Supports Timed Automata. |
| PRISM | Probabilistic Model Checking | Analyses systems with probabilities. |
| TLA+ | Specifying and Verifying Concurrent & Distributed Systems | Uses mathematics to specify the system. |
SPIN
SPIN is a model checking tool that can be used to analyse Concurrent Software Systems and Communication Protocols. It uses a modelling language known as Promela, to define processes, channels and interactions between concurrent components.
The tool can be used to check different sequences of execution and identify issues such as deadlock, incorrect synchronisation and logical issues. It can also be used to define Linear Temporal Logic specifications. It is a great tool for checking concurrent processes.
NuSMV
NuSMV is a Symbolic Model Checker that can be used to verify Finite State Systems. The tool can be used to define properties using Computation Tree Logic and Linear Temporal Logic. Rather than defining each state individually, symbolic techniques can be used to create large groups of states.
This can make the verification process more efficient for complex models. This tool can be used in research and engineering to ensure that the system meets specific logical requirements. It can be particularly useful for verifying hardware and software designs.
UPPAAL
UPPAAL is a verification tool that can be used for Real Time Systems. The system can be defined using a network of timed automata. These mathematically defined models use clocks to ensure that events are occurring within acceptable timescales. For example, an automated control system may require a response to happen within a specific timeframe after the signal is received.
This can be verified using UPPAAL to ensure that the system meets the timing requirements. This can be particularly useful for embedded systems, communications and other time sensitive applications.
PRISM
PRISM is a Probabilistic Model Checker that can be used for systems with uncertainty. Whilst traditional model checking tools are used to determine whether a property will always be true or if it can occur, probabilistic model checking can be used to see how likely it is to happen.
This can be particularly useful for systems that have components that may fail with a certain probability. For example, probabilistic models can be used to analyse the reliability of a communication network. It can also be used to analyse how likely it is that the system will successfully complete an operation. PRISM supports analysing quantitative properties.
TLA+
TLA+ is a formal specification language that can be used to describe concurrent & distributed systems. The tool uses mathematical expressions to define states, actions and relationships between actions. The tool comes with a model checker (TLC) that can be used to check the specification and look for any requirements that have not been met.
This is particularly useful for distributed systems as multiple computers will need to interact with one another. This allows developers to think about algorithms and the system architecture before implementing in a programming language. This can help to expose design issues at an early stage which could be cheaper and less complicated to correct.
Advantages
Using model checking can provide many benefits to software developers, system designers and engineers. Firstly, it provides a way of verifying a wide range of behaviours that would not be possible to cover using manually selected test cases. This can help to identify any issues that may only occur under specific circumstances or sequences. The tool can also provide counterexamples. This means developers will know why the requirement has not been met. This can make debugging and improving the system more systematic. Secondly, it can help to find errors at an early stage. Developers can create mathematical models and analyse the behaviours before creating the full software/hardware.
This can help to identify design issues early on which can save time and resources. It can also help to make the requirements more specific as developers will need to think about how they expect the system to behave using formal logical specifications. This can reduce ambiguity. Finally, it can increase confidence in systems that need to be reliable. This can be particularly useful for systems with concurrent processes, communication protocols and safety requirements. It can help to provide a more robust quality assurance process when paired with testing and other verification techniques.
Limitations
Model checking can have some limitations. One of the biggest issues is the state space explosion. Complex applications may have many variables, processes and interactions meaning there are a massive amount of possible states. This can require a lot of processing power, memory and time to analyse all of the possibilities. Developers will use abstraction techniques, state reduction and symbolic techniques to help reduce this issue. However, care must be taken when reducing the model as it may lose important information and prevent the verification tool from finding certain issues.
Another limitation is that the accuracy of the mathematical model will greatly affect the results. If the model is not accurate then the results may not be complete. If an important requirement is missed then the verification will not be able to determine if this requirement has been met. Finally, it does not automatically prove that the final implementation will behave exactly as the model. There may be differences between the model and the actual software/hardware, operating environment or external components which can cause further issues. Therefore, model checking should be used alongside other engineering processes such as software testing, code reviews, security analysis and validation.
Model Checking vs Traditional Testing
Model checking and traditional testing can both be used to help developers find issues in their software. Traditional testing involves running the program with specific inputs and determining if the outputs are correct. Developers will create test cases to test normal operations, unusual situations and failure scenarios. Whereas, model checking analyses the mathematical model of the system. This determines if the properties will be met for the relevant possible behaviours. The two techniques are complementary.
Traditional testing is essential as it helps analyse the actual software, user interface, performance and any issues that may arise with the real hardware or operating environment. However, model checking can be particularly useful for logical correctness, concurrency, protocol and complex interactions. However, it can’t guarantee that the implementation is completely defect free. By using both techniques, developers can analyse the system from a different perspective and provide stronger evidence that the system is correct. This can improve the quality of the software.
The Future of Model Checking in Software Engineering
With increasing complexity of computer systems, there is an ever growing need for reliable verification methods. With new technologies such as artificial intelligence, autonomous devices, cloud computing, distributed applications and advanced industrial automation, there are new complexities that can cause unpredictable behaviours in software. Model checking is expected to be an important tool going forward as it provides a mathematical approach to analysing the system behaviour. Improvements in symbolic verification, automated abstraction and state reduction are helping researchers and engineers to overcome some of these issues.
It is also relevant for systems that combine software and physical processes (cyber-physical systems). These systems will involve connecting computing components with sensors, machines, communications and the real world. The behaviour may depend on the timing, physical conditions and multiple independent components. Formal verification techniques can help developers verify that the system meets their operational and safety requirements. With an increased focus on reliability, security and accountability in software engineering, model checking will continue to be an important tool for identifying design issues.
Conclusion
Model checking is an important formal verification technique. It uses mathematical models and logical specifications to determine if a computer system meets defined requirements. State transition systems can be created to represent the software. The state space can then be analysed using temporal logic to identify any potential execution paths. This can be particularly useful as counterexamples can be generated. This helps engineers to understand how issues are occurring. It can also help identify several key issues such as deadlock, concurrency issues, security issues and unexpected behaviours.
It can be applied to many different areas such as operating systems, communication protocols, embedded devices, industrial automation and safety critical software. There are many tools available such as SPIN, NuSMV, UPPAAL, PRISM and TLA+.Whilst there are some challenges such as state space explosion, accuracy of the model and resource requirements, using model checking alongside traditional testing and other software verification techniques can provide many benefits. Overall, it can help developers identify design issues early on, determine clear requirements for correctness and create more predictable, reliable and secure computer systems.



