Keywords

figure a
figure b

1 Introduction

Programmable logic controllers (PLCs) are industrial computer systems designed to manage tasks in diverse applications, from assembly lines to robotic devices. The IEC 61131-3 international standard [9] defines the programming languages tailored for developing PLC programs, such as Structured Text (ST), a high-level imperative language. The critical role of PLCs lies in their ability to improve the flexibility, efficiency, and reliability of complex industrial control systems.

Ensuring the correctness of PLC programs is of paramount importance due to their safety-critical nature in industrial applications. Over the years, formal analysis of PLC programs has received significant attention from both academia and industry. In response to this demand, many techniques and tools have been developed for formally analyzing PLC programs, including [2, 4, 10, 13, 19, 25, 34], written in various PLC programming languages. In particular, ST is the most expressive of all PLC languages and is widely used for formal analysis [11].

Recent advances introduce a complete executable semantics of PLC ST [18, 38]. Traditional “translation-based” methods (e.g., [4, 10, 13]) convert PLC ST programs into the input language of another analysis tool. They are inherently limited to a particular syntactic subset of the language, determined by the capabilities of the target input language. In contrast, the complete semantics [18, 38] can directly deal with the full syntactic subset of the language.

While the existing complete semantics [18, 24, 38] detail the language constructs of PLC ST, they overlook complex multitasking aspects. PLC programs run in iterative rounds, called scan cycles, interacting with their controlled entities at each iteration. They manage multiple tasks with different periods, deadlines, and priorities, allowing high-priority tasks to preempt low-priority tasks. Capturing this complex nondeterministic behavior remains an unresolved problem.

Our goal is to extend the PLC ST semantics [24, 38] for preemptive multitask programs. There are two central challenges to achieve this goal:

  • Although PLC ST programs operate within fixed time intervals, they can be executed or preempted at any moment within a dense time domain. It is essential to completely capture all possible behaviors.

  • Task execution and preemption, despite their arbitrariness, often lead to indistinguishable outcomes. It is crucial to identify and focus on the minimal interactions without compromising completeness.

To address these issues, we first define a “time-complete” semantics that naturally captures all possible behaviors over time points. We then introduce an abstraction to identify equivalent behaviors over time intervals.

Our time-complete semantics of PLC ST, based on the K framework [35], explicitly considers each time point within a dense time domain, and faithfully models task execution and preemption at arbitrary times. In particular, a state in our semantics contains a global time, and the tick rule can advance the global time by any amount before the deadline caused by intervals of tasks. Since this semantics involves an infinite number of behaviors within a finite time period, it is not executable and is unsuitable for automated analysis.

To deal with the non-executability problem, we define an abstraction of the time-complete semantics, resulting in a time-abstract semantics of PLC ST. In contrast to the time-complete semantics, it restricts the focus to a finite number of interleaving scenarios within a finite time period. Each global time in a state is abstracted into the time interval spanning from the earliest start time to the earliest deadline of the tasks involved. Importantly, our semantics is equivalent to the time-complete semantics in terms of bisimulation.

The nondeterministic nature of preemptive multitasking can still lead to the state explosion problem. To illustrate, consider two tasks \(T_1\) and \(T_2\), where \(T_2\) has a higher priority. If \(T_1\) runs a sequence of code \(s_1 ; s_2 ; \cdots ; s_{n}\), then \(T_2\) can preempt \(T_1\) after executing any of \(s_i\), resulting in n potential preemption scenarios. However, only statements that interact with global variables can produce different results. To avoid such redundant behavior, we propose state space reduction methods for our semantics, based on partial order reduction [33].

This paper is organized as follows. Section 2 gives some background on the basic K semantics of PLC ST and partial order reduction. Section 3 explains details of multitask PLC with preemption and introduces a running example. Section 4 presents the time-complete semantics of PLC ST, and Sect. 5 presents the time-abstract semantics. Section 6 presents the state space reduction methods for our semantics, and Sect. 7 shows the experimental results. Section 8 discusses related work. Finally, Sect. 9 presents some concluding remarks.

2 Preliminaries

K Framework. K [35] is a semantic framework for programming languages, based on rewriting logic [27]. It has been widely used to formalize a variety of languages, including C [12], Java [3], JavaScript [31], PLC ST [38], AADL [21, 22], and so on. There are several tools that can be used to execute and analyze programming languages using K, including the K tool [20] and Maude [8, 37].

In K, program states are represented as multisets of nested cells, called configurations. Each cell represents a component of a program state, such as computations and stores. Transitions between configurations are specified as (labeled) K rules, written in a notation that specifies only the relevant parts.

A computation in K is defined as a \(\curvearrowright \)-separated sequence of computational tasks. For example, \(t_1 \curvearrowright t_2 \curvearrowright \ldots \curvearrowright t_n\) represents the computation consisting of \(t_1\) followed by \(t_2\) followed by \(t_3\), and so on. A task can be decomposed into simpler tasks, and the result of a task is forwarded to the subsequent tasks. E.g., \((5 + x) * 2\) is decomposed into \(x \curvearrowright 5 + \square \curvearrowright \square * 2\), where \(\square \) is a placeholder for the result of a previous task. If x evaluates to some value, say 4, then \(4 \curvearrowright 5 + \square \curvearrowright \square * 2\) becomes \(5 + 4 \curvearrowright \square * 2\), which eventually becomes 18.

The following shows a typical example of K rules for variable lookup, where \(\texttt{lookup}\) is a label, the k cell contains a computation, \(\textit{env}\) contains a map from variables to locations, and \(\textit{store}\) contains a map from locations to values:

figure c

A horizontal line represents a state change, and “\(\mathop {...}\)” indicates irrelevant parts. A cell without horizontal lines is not changed by the rule. By the lookup rule, if the first item in k is x, then x is replaced by the value v of x in its location l.

PLC ST and its K Semantics. Structured text (ST) is a textual programming language defined in the IEC 61131-3 standard [9]. ST supports common features of imperative programming language, such as (local and global) variable assignments, conditionals, loops, and functions. ST also has unique constructs, such as function blocks, which are callable “objects” with state variables. Functions, function blocks, and programs are called program organization units (POUs).

We briefly summarize the syntax of PLC ST. A program is declared with the syntax PROGRAM \(\textit{Name}\) ... END_PROGRAM. A program consists of variable declarations and code. A variable declaration section is declared with the syntax VAR \(\textit{SectionType}\) ... END_VAR, where \(\textit{SectionType}\) is one of GLOBAL, INPUT, and OUTPUT, or omitted (local in this case). A global variable section can be written outside of a program. A body of code begins after variable sections.

We give an overview of the K semantics of PLC ST [18, 24, 38]. Figure 1 shows part of the structure of K configurations. The k, \(\textit{env}\), and \(\textit{store}\) cells are explained above. The \(\textit{stack}\) cell contains a call stack, which stores the caller’s environment and computation when a function block is called. The \(\textit{pouDef}\) cell is a map from POU identifiers to POU declarations, each of which contains variable declarations and code. The \(\textit{pList}\) cell contains a list of programs to run.

Fig. 1.
figure 1

Examples of K cells for PLC ST.

Figure 2 shows some of the K rules in the PLC ST semantics. Thanks to the modularity of the K technique [35, 36], the K rules for common imperative language constructs, such as assign for variable assignment, and if-true and if-false for conditional statements, are (almost) identical to those for other imperative languages, except for slight syntactic differences.

When a function block is called (fbCall), the POU instance \( [\textit{fb}, \eta ]\) is obtained, where \(\eta \) is a local environment, and tasks of binding the arguments and executing the code S are loaded in k. When the code S is executed (fbExec), the current environment \(\rho \) and the remaining computation \(\kappa \) are pushed to \(\textit{stack}\), and \(\eta \) becomes a new environment in \(\textit{env}\). When there are no more tasks in k (fbQuit), the previous environment \(\rho \) and the computation \(\kappa \) are restored from \(\textit{stack}\).

Fig. 2.
figure 2

Examples of K rules for PLC ST.

Transition Systems. A transition system \(\mathcal {S}\) is a tuple \((S, s_0, T, \textit{AP}, L)\) [1, 33], where S is a set of states, \(s_0 \in S\) is an initial state, T is a set of transitions such that \(\alpha \in T\) is a partial function \(\alpha : S \rightarrow S\), \(\textit{AP}\) is a set of atomic propositions, and \(L : S \rightarrow 2^{\textit{AP}}\) is a state labeling function. A transition \(\alpha \in T\) is enabled in a state \(s \in S\) if \(\alpha (s)\) is defined. We denote by \(\textit{enabled}(s)\) the set of transitions enabled in s. We often write \(s \xrightarrow {\alpha } s'\) to denote \(\alpha (s) = s'\) for \(s, s' \in S\).

For two transition systems \(\mathcal {S}_i = (S_i, s_0^i, T_i, \textit{AP}, L_i)\), \(i = 1, 2\), a binary relation \(R \in S_1 \times S_2\) is a simulation [7] from \(\mathcal {S}_1\) to \(\mathcal {S}_2\) iff: (i) \((s_0^1, s_0^2) \in R\);  and  (ii) for any \((s_1, s_2) \in R\), \(L(s_1) = L(s_2)\) holds,  and if \(s_1 \xrightarrow {\alpha } s_1'\), there exists \(s_2' \in S\) such that \(s_2 \xrightarrow {\alpha } s_2'\) and \((s_1', s_2') \in R\). A simulation R from \(\mathcal {S}_1\) to \(\mathcal {S}_2\) is called a bisimulation iff \(R^{-1}\) is also a simulation from \(\mathcal {S}_2\) to \(\mathcal {S}_1\).

The K semantics of PLC ST naturally defines a transition system, provided that \(\textit{AP}\) and L are given. States are given by K configurations. Each transition \(\alpha _l\) is identified by a rule label l such that \(s \xrightarrow {\alpha _l} s'\) iff s is reduced to \(s'\) by a K rule with label l. For the “single-task” case, \(\alpha _l\) is well defined as a partial function because single-task PLC programs are deterministic. For the “multitask” case, we also need task identifiers as well as rule labels (see Sect. 4.2).

Partial Order Reduction. Consider a transition system \(\mathcal {S} = (S, s_0, T, \textit{AP}, L)\). A transition \(\alpha \in T\) is invisible iff \(s \xrightarrow {\alpha } s'\) implies \(L(s) = L(s')\). An independence relation \(I \subseteq T \times T\) is a symmetric and anti-reflexive relation such that for any pair of transitions \((\alpha , \beta ) \in I\) and state \(s \in S\), where \(\alpha , \beta \in \textit{enabled}(s)\), (i) \(\alpha \in \textit{enabled}(\beta (s))\) and \(\beta \in \textit{enabled}(\alpha (s))\),  and (ii) \(\alpha (\beta (s)) = \beta (\alpha (s))\). Its complement \(D = (T \times T) \setminus I\) is called a dependency relation.

We consider partial order reduction using ample sets [33]. An ample set of a state \(s \in S\) is a subset of the enabled transitions \(\textit{ample}(s) \subseteq \textit{enabled}(s)\). A state \(s \in S\) is called fully expanded when \(\textit{ample}(s) = \textit{enabled}(s)\). When exploring the state space, only the transitions in \(\textit{ample}(s)\) are explored instead of all the transitions in \(\textit{enabled}(s)\). This results in a reduced transition system \(\hat{\mathcal {S}}\) that is behaviorally equivalent when ample sets are chosen appropriately.

The following conditions guarantee that a transition system \(\mathcal {S}\) and its reduced version \(\hat{\mathcal {S}}\) are behaviorally equivalent [33]: (i) \(\textit{ample}(s) \ne \emptyset \) iff \(\textit{enabled}(s) \ne \emptyset \); (ii) a transition that is dependent on a transition in \(\textit{ample}(s)\) cannot occur before a transition in \(\textit{ample}(s)\) occurs first.Footnote 1; (iii) if s is not fully expanded, all transitions in \(\textit{ample}(s)\) are invisible; and (iv) any cycle in the reduced state space \(\hat{\mathcal {S}}\) contains at least one fully expanded state.

3 Multitask PLC and a Running Example

In multitask PLC, each program is assigned an interval and a priority. A program is scheduled to run periodically, where the interval determines the duration of each period. Priorities are given as natural numbers, where a lower number indicates a higher priority. A program with a higher priority can preempt the execution of a program with a lower priority. The execution of each program must be completed before the beginning of its next round.

Multitask PLC programs are difficult to analyze because of their complex interleaving possibilities. Due to the nondeterministic nature of preemption, the number of different interleavings can grow exponentially with the number of programs. E.g., if a program with k statements is preempted, preemption can occur after the i-th statement for any \(1 \le i \le k\), Therefore, for n programs with different priorities, there are \(O(k^{n-1})\) interleaving possibilities by preemption.

Our running example is inspired by the two-wheeled self-balancing robot [6]. The robot moves on flat ground while maintaining its balance. It is equipped with a sonar sensor that detects nearby obstacles. The current state information is displayed on the attached panel. It takes control input from a remote controller to move forward, backward, and turn.

The system consists of three programs: balanceControl, sonar, and display, with intervals of \(3\,\textrm{ms}\), \(4\,\textrm{ms}\), and \(12\,\textrm{ms}\), and priorities of 1, 2, and 3, respectively. Figure 3 shows a code snippet of balanceControl and sonar, where the intervals and priorities are declared in CONFIGURATION. The global variables mode and obstacle_flag are used for communication between different programs.

The balanceControl program takes control inputs (such as cmd_forward and cmd_turn) and balancing inputs (such as gyro_sensor). The robot has two modes CAL and CONTROL, where the global variable mode indicates the current mode. When balanceControl is executed for the first time, it calibrates and sets the appropriate initial settings for the robot and sets mode to CONTROL. The program starts controlling the robot from the second round.

The sonar program takes sonar sensor inputs (such as sonar). When mode is CONTROL, the program measures the distances to nearby objects to detect an imminent collision hazard. If so, it sets the global variable obstacle_flag to TRUE. At this point, balanceControl ignores its control input and attempts to stop the robot by setting cmd_forward to \(-100\).

Fig. 3.
figure 3

Two-wheeled self-balancing robot code.

Figure 4 shows two interleaving scenarios that reach different outcomes. Each rectangle denotes the range from the earliest possible start time to the deadline for a task. The heads and tails of horizontal arrows denote the start and end of program execution. The curved vertical arrows denote preemption and its return. In Scenario 1, there is no preemption.

Fig. 4.
figure 4

Two interleaving scenarios of the robot example.

4 Formal Semantics of Multitask PLC

This section presents an executable semantics of PLC ST with preemptive multitasking, which extends the existing K semantics of PLC ST [18, 24, 38]. Our semantics specifies all possible interleavings by nondeterministic preemption over a dense time domain. We take into account a global time that can be advanced by any amount up to the deadline, determined by the intervals of tasks.

Fig. 5.
figure 5

K configurations for multitask PLC.

4.1 K Configuration for Multitask PLC

Figure 5 depicts the K cells for specifying preemptive multitasking behaviors, in addition to the existing cells in the original semantics [18, 24, 38]: (1) \(\textit{time}\) denotes the current time; (2) \(\textit{active}\) denotes the identifier of the currently running program; (3) \(\textit{interval}\) has a map from program identifiers to their intervals; (4) \(\textit{pQueue}\) contains a priority queue of tasks that are ready to run according to \(\textit{time}\) and \(\textit{interval}\); and (5) \(\textit{futureTS}\) contains tasks that are not ready.

Tasks are represented as a tuple \((\textit{id}, \textit{pr}, \textit{es}, \textit{dl})\), where \(\textit{id}\) is the identifier of the program, \(\textit{pr}\) is the program’s priority, \(\textit{es}\) is the earliest start time, and \(\textit{dl}\) is the deadline. Each program can start after its earliest start time and must end before its deadline. When the current time is 0, \(\textit{es}\) is 0 and \(\textit{dl}\) is the interval.

The \(\textit{Program}\) cell encompasses the program’s identifier, a computation, and an environment and a call stack. Unlike the single-task semantics in Sect. 2, in our multi-task semantics, each program maintains its own computation, environment, and stack. That is, a full K configuration has the nested structure of the form (where other K cells not used in this paper are omitted):

figure d

4.2 K Rules for Multitask PLC

Fig. 6.
figure 6

K rules for preemptive multitasking.

Figure 6 shows the K rules to specify preemptive multitasking behaviors. The tick rule (nondeterministically) increments the current time up to the minimum deadline of the tasks, where \( \textit{minDL}(\textit{pq}, \textit{ft}) = \min (\textit{deadlines}(\textit{pq}) \cup \textit{deadlines}(\textit{ft})) \), with \(\textit{deadlines}(A)\) denoting the set of deadlines in A. The side condition of tick maintains the following validity constraint: the value of the \(\textit{time}\) cell should not exceed any of the deadlines of the tasks in \(\textit{pQueue}\) and \(\textit{futureTS}\).

Lemma 1

For a K configuration that satisfies the validity constraint, any next configuration obtained by applying a rule also satisfies the constraint.

The execute rule executes the top task in \(\textit{pQueue}\) if no task is currently running. Before the rule is applied, the \(\textit{active}\) cell is empty,  and the execution of each program is “blocked” by \(\blacksquare \) at the top of its \(\textit{k}\) cell. Suppose P is the program for the top task in \(\textit{pQueue}\). When execute is applied, the \(\textit{active}\) cell is updated with the program’s identifier P, and \(\blacksquare \) is removed from the top of P’s k cell.

The placeT rule moves a task in \(\textit{futureTS}\) into \(\textit{pQueue}\), when the task is ready to run according to \(\textit{time}\) and \(\textit{interval}\). The function \(\textit{insert}(\textit{pq}, T)\) inserts task T into the priority queue \(\textit{pq}\). The side condition states that the current time is between its earliest start time and the deadline. It also sets the third item of the task to the current time t to record when this happens.

The endProgram rule is applied when the execution of the active program is finished. Suppose P is the active program and the k cell of P is empty. When endProgram is applied, the \(\textit{active}\) cell becomes empty and the corresponding task is removed from \(\textit{pQueue}\). The subsequent task for P is added to \(\textit{futureTS}\), where the earliest start time and deadline are increased by P’s interval \(\iota \). Finally, the code of P, where the execution is blocked by \(\blacksquare \), is loaded into the k cell of P. The side condition asserts that the execution of P takes non-zero time.

The preempt rule preempts a lower-priority task, and executes a higher-priority task in \(\textit{pQueue}\). In the rule, P has a higher priority than \(P'\) because it is the top element in \(\textit{pQueue}\). The \(\textit{active}\) becomes P, and \(\blacksquare \) moves to \(P'\) from P.

It is worth noting that the rules in Fig. 6 are all nondeterministic. The time can be increased by any value up to the deadline, and different tasks can have the same priority and interval. For this reason, transitions with tick are identified by time differences (e.g., \(\texttt {tick}(1)\) increases the time by 1), and transitions with the other four rules are identified by rule labels and program identifiers (e.g., placeT(P) moves a task \((P, \ldots )\) from \(\textit{futureTS}\) to \(\textit{pQueue}\)).

4.3 Example of K Rule Applications

Fig. 7.
figure 7

An example of execution sequences, where \(P_b = \textit{balanceControl}\) and \(P_s = \textit{sonar}\).

Figure 7 shows a sequence of states simulating an execution path for Scenario 2 in Fig. 4. Applying execute to state \(s_1\) to execute balanceControl gives \(s_2\). After 1 s, balanceControl executes its code (using other K rules) and then endProgram is applied, resulting in \(s_3\). The following shows the transitions:

figure e

Likewise, Scenario 1 can be simulated by the following sequence of transitions. It is the same as the above up to \(s_3\), and has different states after that.

figure f

5 Time Abstraction

A single program execution can produce an infinite number of cases, due to nondeterministic time advances. In Scenario 2 of Fig. 4, the first execution of balanceControl can end in \(1\,\textit{ms}\), \(0.5\,\textit{ms}\), \(0.25\,\textit{ms}\), and so on. However, there are only a finite number of critical times that may change the possible behaviors.

This section presents a time abstraction for our multitask PLC ST semantics. The main idea is to express time abstractly with a time interval that represents an infinite number of time points. We define an abstract function that maps a concrete K configuration to its abstract version and apply it globally to the K rules defined in Sect. 4.2. We show that the resulting abstract semantics is equivalent to the concrete PLC semantics in terms of bisimulation.

5.1 Abstraction Function

The abstraction function takes a K configuration with a time value and returns the K configuration with a time interval that (i) contains the original time, and (ii) encompasses all other times that have equivalent behaviors. Now the \(\textit{time}\) cell contains a pair of times \(\mid t_1, t_2 \mid \), and represents the set of all the times that are contained in the left-closed right-open interval \([t_1, t_2)\).

Definition 1

Given a K configuration \(s = \langle t \rangle _\textit{time}\ \langle \textit{pq} \rangle _\textit{pQueue}\ \langle \textit{ft} \rangle _\textit{futureTS}\ \cdots \), its time abstraction is defined as follows, where \( \textit{maxES}(\textit{pq}) = \min (\textit{startTimes}(\textit{pq})) \), with \(\textit{startTimes}(\textit{pq})\) denoting the set of earliest start times in \(\textit{pq}\):

$$ \lambda (s) = \langle \mid \textit{max}(\textit{maxES}(\textit{pq}), t), \textit{minDL}(\textit{pq},\ \textit{ft}) \mid \rangle _\textit{time}\ \langle \textit{pq} \rangle _\textit{pQueue}\ \langle \textit{ft} \rangle _\textit{futureTS}\ \cdots $$

Figure 8 shows the interleaving rules with the abstract time. Except tick, endProgram, and placeT, all other K rules, including execute and preempt, are the same before and after the abstraction. The tick rule is now identity. The endProgram and placeT rules move the possible time range of the system. It moves the minimum time value (left) to maximum earliest start times of the tasks in \(\textit{pQueue}\) or remains unchanged if the priority queue is empty. The maximum time value (right) is moved to the minimum deadlines of the tasks in \(\textit{pQueue}\) and \(\textit{futureTS}\) altogether.

Fig. 8.
figure 8

K rules for multitask interleaving with abstract time

5.2 Equivalence Before and After Abstraction

The concrete semantics and the abstract semantics are equivalent in terms of bisimulation. Let R be a binary relation between concrete configurations and abstract configurations such that \((s, \lambda (s)) \in R\) for each configuration s. Then, R is a bisimulation with respect to atomic propositions not depending on \(\textit{time}\).

By construction, for a concrete transition \(s \xrightarrow {\alpha } s'\), there exists an abstract transition \(\lambda (s) \xrightarrow {\alpha } \lambda (s')\). For an abstract transition \(\hat{s} \xrightarrow {\alpha } \hat{s'}\), there also exists a corresponding concrete transition \(s \xrightarrow {\alpha } s'\), where the \(\textit{time}\) values t and \(t'\) of s and \(s'\), respectively, can be any values in the corresponding intervals such that: (i) \(t \le t'\) if \(\alpha = \texttt{tick}\), and (ii) \(t = t'\) if \(\alpha \ne \texttt{tick}\). The complete proof of the following theorem can be found in [23].

Theorem 1

Given an initial K configuration \(s_0\) satisfying the validity constraint, R is a bisimulation between the concrete transition system \(\mathcal {S}\) from \(s_0\) and the abstract transition system \(\hat{\mathcal {S}}\) from \(\lambda (s_0)\).

6 State Space Reduction

In this section, we introduce two state space reduction methods that reduce the state space. Since the K rules we introduced involve many nondeterministic choices, it results in a large state space that makes it hard to analyze.

The first technique is the application of the ample set approach. Based on the observation that interleaving of placeT with other rules spawns many different but essentially the same execution paths, we include placeT in the ample set, if not fully expanded. It is not simple because not all enabled placeT can be prioritized without consequences. The second technique is to put rules that do not change the local memory first. This is possible because the atomic properties of interest in this paper only depend on the local memory.

6.1 Our Ample Set Approach

Consider state \(\langle \cdot \rangle _\textit{active}\ \langle (P_1, 1, 0, 20) \rangle _\textit{pQueue}\ \langle (P_2, 2, 5, 25) \rangle _\textit{futureTS}\ \mathop {...}\). From this state, both execute and placeT are applicable. In either order, it converges to \(\langle P \rangle _\textit{active}\ \langle (P_1, 1, 0, 20)\, \langle (P_2, 2, 5, 25) \rangle _\textit{pQueue}\ \langle \cdot \rangle _\textit{futureTS}\ \mathop {...}\), and all states in this procedure including the intermediate states share the same set of atomic properties held. Thus, we only need to explore one of these paths. This phenomenon stems from the independence of these two rules. Just like this case, when placeT does not change the top element of \(\textit{pQueue}\), it is only dependent on tick.

Definition 2

For a state s, if \(\texttt{placeT}(P) \in \textit{enabled}(s)\) and \(\texttt{placeT}(P)\) does not change the top element of \(\textit{pQueue}\), \(\textit{ample}(s) = \{\texttt{placeT}(P), \texttt{tick}(\tau ) \}\); otherwise, \(\textit{ample}(s) = \textit{enabled}(s)\).

To prove that Definition 2 satisfies the ample set conditions, we first show the following lemma for Condition (ii). Lemma 2 shows that placeT is independent of any other rule except tick if it does not change the top element of \(\textit{pQueue}\), since only the top element of \(\textit{pQueue}\) decides what to execute or preempt. Lemma 2 also shows that tick is independent of any other rule except placeT, since the other rules do not restrain the side condition of tick.

Lemma 2

(1) \(\texttt{placeT}(P)\) is independent of all other transitions except \(\texttt{tick}(\tau )\), if it does not change the top element of the \(\textit{pQueue}\) cell. (2) \(\texttt{tick}(\tau )\) is independent of all other transitions except \(\texttt{placeT}(\cdot )\).

The following theorem states that \(\textit{ample}\) in Definition 2 satisfies the ample set conditions regarding atomic propositions that do not modify \(\textit{time}, \textit{pQueue}\), and \(\textit{futureTS}\). (See [23] for the full proof.)

Theorem 2

For any execution path without continuous infinite application of \(\texttt{tick}\), \(\textit{ample}\) satisfies the four conditions for partial order reduction.

Proof

(Sketch). (i) It immediately follows from Definition 2. (ii) It holds since transitions in \(\textit{ample}(s)\) are only dependent on other transitions in \(\textit{ample}\) and no other enabled transitions. When \(\texttt {placeT}(P)\) does not change the top element of \(\textit{pQueue}\), Lemma 2 shows the independence of \(\texttt {placeT}(P)\) and of \(\texttt {tick}\) with all other rules. (iii) When it is not fully expanded, \(\textit{ample}(s)\) contains tick and placeT. These two rules are invisible since they only look and modify \(\textit{time}, \textit{pQueue}\), and \(\textit{futureTS}\) cells, which are irrelevant to any atomic propositions of interest. (iv) By Definition 2, when \(\textit{ample}(s) \ne \textit{enabled}(s), \textit{ample}(s) = \{ \texttt {placeT}(P), \texttt {tick}(\tau ) \}\). The number placeT is bounded by the number of tasks in \(\textit{futureTS}\). With the assumption that there is no cycle only consisting of tick, if there is a cycle in the reduced system, it must contain at least one fully expanded state.    \(\square \)

6.2 Internal Transitions Without Memory Update

Certain scenarios may be equivalent even if they are not addressed by our ample set approach. Consider the following state: \(s = \langle P \rangle _ active \ \langle \langle x \curvearrowright \mathop {...}\rangle _k\ \langle P \rangle _ id \rangle _ program \ \langle (P', 1, 0, 30)\ (P, 2, 0, 20)\rangle _ pQueue \ \mathop {...}\). Both lookup and preempt are enabled in s. Applying preempt results in \(\langle P' \rangle _ active \ \langle \langle \blacksquare \curvearrowright x \curvearrowright \mathop {...}\rangle _k\ \langle P \rangle _ id \rangle _ program \ \langle (P', 1, 0, 30)\ (P, 2, 0, 20)\rangle _ pQueue \ \mathop {...}\), where lookup is not enabled anymore. This makes lookup dependent on preempt and cannot satisfy Condition (ii) of ample set. All rules such as if-T, if-F, and fbCall, which operate internally in a k cell of a program without modifying the memory state show the same phenomena. We call these rules internal rules.

Figure 9 shows a state space diagram when an internal transition \(\tau \) and preempt is possible. Each circle represents a state and the active task is shown below each circle. We start from the bottom-left state. Whether we choose \(\tau \) or preempt, it converges to the same state in the top-right state. States within the same dashed oval are indistinguishable from outside because \(\tau \) does not modify any part of the memory in the system. Therefore, we only need to explore the top path by prioritizing internal rules over preempt.

Suppose a state labeling function satisfies the following condition: for any two states s and \(s'\) with the same \(\textit{store}\) cell, \(L(s) = L(s')\). Based on the above observation, we have the following theorem (the proof is in [23]).

Theorem 3

Consider a state s such that \(\texttt{preempt}(Q), \tau \in \textit{enabled}(s)\), where \(\tau \) is internal. For any \(s \xrightarrow {\texttt{preempt}(Q)} s_1 \xrightarrow {\alpha _1} \cdots \xrightarrow {\alpha _{n-1}} s_{n} \xrightarrow {\tau } t\), there exists \(s \xrightarrow {\tau } s' \xrightarrow {\texttt{preempt}(Q)} s_1' \xrightarrow {\alpha _1} \cdots \xrightarrow {\alpha _{n-1}} t\), such that \(L(s_i) = L(s_i')\) for \(1 \le i \le n\).

Fig. 9.
figure 9

State diagram when an internal transition and preempt are available

7 Experimental Evaluation

To evaluate the effectiveness of our methods, we have implemented our semantics and state space reduction methods in Maude [8].Footnote 2 We have conducted experiments to measure the performance of state space exploration up to a given model time bound. We first compare time and the number of states before and after the abstraction. To emphasize the strength of the abstracted semantics, we also compare it with the sampling-based approach, which is very fast but skips a significant part of the full state space. Then, we compare the time and state space with and without each of the reduction methods in the abstract setting. We refer to the longer report [23] for more details.

We consider seven models, each with 2 priority settings and 3 model time bounds. The first model is the self-balancing robot in Sect. 3. We manually adapted and translated the original source’s C program into PLC ST programs. The second model is the traffic light example from [24] adapted to a multitask setting. There are four light controllers, two for cars and two for pedestrians. There is one task for a timer, thus there are up to 5 programs in total. The LOC of the robot model is 75 and the LOC of the traffic light model is 259. The third to the sixth model is a variant of the second model with different numbers of traffic lights. The seventh model is from the PLCOpen library [4]; it is a single-task model but adapted to a multitask model (the LOC is 2154).

In the case of concrete semantics, since the nondeterministic tick rule is not executable per se, we symbolically execute this semantics using the approach in [24]. In the sampling-based semantics, we increase the time by the greatest common divisor of the intervals of the programs. The sampling method samples the time of the greatest common divisor of the intervals of all the programs. All experiments were conducted on Intel Xeon 2.8 GHz with 256 GB memory. Timeout is set to 1 h in all settings.

Fig. 10.
figure 10

Analysis time comparison between concrete, sampling, and abstract semantics

Figure 10 shows the analysis time comparison in scale between concrete and abstract (left) and sampling and abstract (right). The timed-out data is marked at the edge of the graph. In all cases, state space exploration with time abstraction takes less state space and time than the concrete semantics. In cases where the execution with concrete semantics is not timed out, the abstract semantics takes at most a hundredth of time. Except for only one case, abstract semantics outperforms the sampling-based semantics.

Fig. 11.
figure 11

Analysis time comparison with and without reduction techniques

Figure 11 shows the state space exploration time comparison of abstract semantics with and without each reduction technique. ‘noReduction’ is the result without any reduction methods, ‘ample’ with our ample set approach, ‘internal’ with the reduction using internal memory, and ‘both’ with both reduction methods. The x-axis shows the benchmark models with their settings. ‘r’ means our robot models and ‘t1’–‘t5’ are the traffic light models with varying numbers of traffic lights. ‘cb2’ is the one from PLCOpen safety library. ‘s’ and ‘c’ respectively note the priority setting with fewer possible preemptions (simple) and with greater preemption points (complex). ‘b1’–‘b3’ shows the model’s time bound. ‘bn’ maps to the bound of the greatest common divisor of intervals \(\times n\). The y-axis shows the analysis time in seconds. Both methods proved their effectiveness. The internal rule reduction is effective throughout all the settings. The ample set approach is more effective in settings with more equal-priority programs. Applying both reductions proved to be the most efficient.

8 Related Work

Numerous methods exist for formally analyzing PLC programs written in various languages, including Function Block Diagram [25, 32], Sequential Function Chart [2, 15, 19], Ladder Diagram [26, 34], Instruction List [5], and Structured Text [4, 10, 13]. Most of these approaches utilize a model checking methodology. As mentioned in Sect. 1, they typically involve translating PLC programs into models that are compatible with existing model checking tools.

The K framework, along with its methodology for semantic definition [35], has been successfully applied to a variety of programming languages, including C [12, 16], Java [3], JavaScript [31], Ethereum Virtual Machine [17], etc. In particular, several studies [18, 24, 38] propose a K semantics for PLC ST. However, preemptive multitasking features and their state-space reduction methods are not considered in these previous K semantics for PLC ST.

A relatively small number of studies deal with multitask PLC. In [14], a technique for symbolic execution of multitask PLC with preemption is presented. However, it is aimed at generating test inputs rather than formal analysis. Another paper [28] focuses on the verification of multitask PLCs with preemption. It is used to verify a specific class of timed multitask PLC program with input delay using the Uppaal tool. However, [28] focuses on Sequential Function Chart (SFC) and Ladder Diagram (LD), whereas our work focuses on ST.

Real-Time Maude [30] provides several formal analysis methods for real-time systems, along with time-complete abstraction [29]. It is based on the maximal time elapse strategy, where time elapses until the earliest time at which any event is enabled. However, the maximal time elapse strategy is not complete for multitask PLC ST, because events may happen in arbitrary time. In contrast, our time-optimal semantics is equivalent to the time-complete semantics.

9 Concluding Remarks

We have presented an executable semantics of multitask PLC ST with preemption, based on the K framework. Our semantics efficiently and faithfully covers all possible interleaving scenarios by nondeterministic preemption. We have defined a time-complete semantics that explicitly considers a dense time domain. We have then defined a time abstraction to identify equivalent behaviors across time intervals, resulting in behaviorally equivalent time-abstract semantics.

To cope with the state explosion problem by nondeterministic preemptive multitasking, we have proposed state space reduction techniques based on partial order reduction. We have evaluated the effectiveness of our techniques using several multitask PLC ST benchmarks. The experimental results have shown a significant improvement in the performance of state space exploration using our time-abstract semantics and state space reduction techniques.

There are several limitations to be addressed in the future work. We should develop more case studies on model checking multitask PLC ST programs, including industrial case studies. Our current implementation lacks tool support and we plan to integrate our framework with existing analysis tools, such as STbmc [24]. Since our framework does not yet support multi-PLC configurations, we should expand our semantics to support multi-PLC.