Formally Verified Animation for RoboChart using Interaction Trees

RoboChart is a core notation in the RoboStar framework. It is a timed and probabilistic domain-specific and state machine-based language for robotics. RoboChart supports shared variables and communication across entities in its component model. It has formal denotational semantics given in CSP. The semantic technique of Interaction Trees (ITrees) represents behaviours of reactive and concurrent programs interacting with their environments. Recent mechanisation of ITrees, along with ITree-based CSP semantics and a Z mathematical toolkit in Isabelle/HOL, bring new applications of verification and animation for state-rich process languages, such as RoboChart. In this paper, we use ITrees to give RoboChart novel operational semantics, implement it in Isabelle, and use Isabelle's code generator to generate verified and executable animations. We illustrate our approach using an autonomous chemical detector model and a patrol robot model additionally exhibiting nondeterminism and using shared variables. With animation, we show two concrete scenarios for the chemical detector when the robot encounters different environmental inputs and three concrete scenarios for the patrol robot when its calibrated position is in different sections of a corridor. We also verify that the animated scenarios are truly trace refinements of the CSP denotational semantics of the RoboChart models using FDR, a refinement model checker for CSP. This ensures that our approach to resolving nondeterminism using CSP operators with priority is sound and correct.


Introduction
The RoboStar 1 framework [1] brings modern modelling and verification technologies into software engineering for robotics. In this framework, models of the platform, environment, design, and simulations are given formal semantics in a unified semantic framework [2]. Correctness of simulation is guaranteed with respect to particular models using a variety of analytical technologies including model checking, theorem proving, and testing. Additionally, modelling, semantics generation, verification, simulation, and testing are automated and integrated into an Eclipse-based tool, RoboTool. 2 The core of RoboStar is RoboChart [3,4], a timed and probabilistic domain-specific language for robotics, which provides UML-like architectural and state machine modelling notations. RoboChart is distinctive in its formal semantics [3,5,4], which enables automated verification using model checking and theorem proving [6].

RoboChart
RoboChart is a state machine-based notation for the modelling of robotic applications. RoboChart also has a component model with notions of controller and module, in addition to state machines, to foster reuse. In a RoboChart model, physical robots are abstracted into robotic platforms through variables, events, and operations. We describe features of RoboChart for modelling controllers of robots using as two examples: an autonomous chemical detector [17,3,18] in Sect. 2.1 and a patrol robot in Sect. 2.2. We refer to the RoboChart reference manual [18] for a complete account of the notation and its semantics.

Autonomous chemical detector
The robot is equipped with sensors to (1) analyse the air to detect dangerous gases; (2) detect obstacles; and (3) estimate change in position (using an odometer). The controller of the robot performs a random walk with obstacle avoidance. Upon detecting a chemical with its intensity above a threshold, the robot drops a flag and stops there. This model 3 [3] has been studied and analysed in RoboTool, using FDR4, 4 a CSP refinement checker.
The top-level structure of a RoboChart model, a module, is shown in Fig. 1. The module ChemicalDetector contains a robotic platform Vehicle and two controller references MainController and MicroController. The physical robot is abstracted into the robotic platform through variables, events, and operations. The platform provides the controllers with services (1) to read its sensor data through three events: gas, obstacle, and odometer; (2) for movement through three operations: move, randomWalk, and shortRandomWalk as grouped in an interface Operations; and (3) to drop a flag through receiving a flag event. These services represent observable behaviour or external interaction of the controllers with the physical robot. The controllers MainController is responsible for gas analysis and MicroController accounts for the robot movement with obstacle avoidance.  A platform and controllers communicate using directional connections. For example, the platform is linked to MainController through an asynchronous connection on event gas of type seq(GasSensor), sequences of type GasSensor. Furthermore, the MainController and MicroController interact using the events turn, stop, and resume to allow MainController to instruct MicroController to turn towards the location where the gas is detected, stop the robot if the gas is dangerous, or resume its movement behaviour (by ignoring the current movement operation) if no gas is detected. These interactions are the internal behaviour of controllers and are not observable.
The types used in the module are defined in the two imported packages: Chemical and Location shown in Figures 2 and 3. The Chemical package declares primitive types Chem and Intensity, enumerations Status and Angle, a record GasSensor containing two fields (c of type Chem and i of type Intensity), and five functions specified using preconditions and postconditions (in the original model, two are specified and three are unspecified). The Location package declares an enumeration Loc and defines an operation changeDireciton using a state machine. The operation has a parameter l of type Loc and a constant lv. Basically, this operation aims to move the robot in the opposite direction of the currently detected gas location l using a constant linear velocity lv.
MainController, defined in the left diagram of Fig. 4, is implemented using a state machine GasAnalysis (by a contained reference to the machine), presented in the right diagram of Fig. 4.
The machine GasAnalysis declares one constant thr of type Intensity for the intensity threshold, and four variables (gas of Seq(GasSensor), st of Status, i of Intensity, and a of Angle) for a sequence of gas sensor readings (from the platform), and the gas analysis results including its status (either no gas NoGas or a gas gasD detected), intensity and angle. The machine also contains a variety of nodes: one initial junction ( ), seven normal states such as NoGas and Analysis, and a final state ( ). A state may have an entry action such as an assignment of st from an application of function analysis to gs in the state Analysis, an exit action, or a during action.
In state machines, transitions connect states and junctions. Transitions have a label with optional features: a trigger event, a clock reset, a guard condition, and an action. For example, the transition of GasAnalysis from NoGas to Analysis has an input trigger gas?gs enabling the machine to receive sensor readings from the channel gs and store the value in the variable gs, and the transition from GasDetected to Reading has a guard (not goreq(i, thr)) and an action (a=location(gs); turn!a) which is a sequential composition of an assignment and an output communication (turn!a) enabling the machine to send the angle a of the detected gas over the channel turn.
This machine gives the behaviour of the robot's gas analysis: (1) enter the state NoGas after the transition from the initial junction is taken; (2) wait for the gas sensor to be ready on channel gs, then receive readings, recorded in gs, on the channel from the platform (via connections from MainController), and at the same time the transition to state Analysis is taken; (3) upon entering the state Analysis whose entry action is executed first to analyse the sensor readings by the function analysis and to record the result in variable st; (4) signal the event resume if no gas is detected (guard [st == noGas]) and return to state NoGas; (5) go to state GasDetected otherwise (guard [st == gasD]); (6) upon entering the state GasDetected whose entry action is executed to determine the intensity by the function intensity and to record the result in variable i; (7) signal stop if the intensity i is larger than or equal to (implemented in function goreq) the intensity threshold thr, and terminate by going to the final state; (8) take the transition to state Reading otherwise with the action of the transition being executed to determine the angle a of the detected gas and signal turn towards the angle; (9) try to read the gas sensor again at state Reading with its only outgoing transition, and if the transitions is taken, the machine is back to state Analysis.
MicroController, defined in Fig. 5, is implemented using a state machine Movement (by a contained reference), presented in Fig. 6, and a reference to the operation changeDireciton. The machine Movement declares various constants such as lv for linear velocity, four variables (a, d0, d1, and l) for the preservation of values (angle, odometer readings, and location) carried on communication, and a clock T. The machine also contains one initial junction, seven normal states such as Waiting and Going, and a final state. Notably, the state Waiting has a during action, an operation call randomWalk(), which provides parallelism in a machine and means the robot is doing a random walk at the state. This operation can be interrupted at any time as long as a transition from the state is taken. The transitions of this machine have labels with various features. The transition from Going to Avoiding has an input trigger obstable?l and a clock reset #T, and the transition from TryingAgain to AvoidingAgain has an input trigger and an action odometer?d1 (an input communication). The transition from AvoidingAgain to Avoiding has a clock reset #T and a disjunctive guard in which since(T) counts the elapsed time since the last reset of T.
This machine gives the behaviour of the robot's response to outcomes of the chemical analysis: (1) resume to state Waiting if no gas is detected (implemented in GasAnalysis); (2) stop to state Found and then terminate , if a gas above the threshold is detected; (3) turn to the direction, where a gas is detected but not above the threshold, with obstacle avoidance in state Going; (4) upon the first detection of an obstacle, reset T and start Avoiding with an initial odometer reading and the movement direction changed (software waits for evadeTime for the effect of that change); (5) if a gas is still detected after the changed direction, TryingAgain to turn and move to the gas direction; (6) if another obstacle is detected during avoidance, AvoidingAgain by reading the odometer to check the distance of two obstacles; (7) if the robot has moved far enough between the two obstacles or not got stuck long enough, go back to continue Avoiding; (8) otherwise, the robot has got stuck in a corner, use a shortRandomWalk for GettingOut of the area, then resume normal activities.

One-dimensional patrol robot
In addition to the features introduced in the chemical detector example, RoboChart also supports abstraction via nondeterministic choice and interaction via shared variables, which is exemplified in the model for a one-dimensional patrol robot on a corridor. The corridor, as shown in Fig. 7, is split into three sections by four boundaries, denoted by their coordinates: -MAX INT, -MAX, MAX, and MAX INT. The left and right boundaries are hard and represent the walls, and the other two are soft and represent controlled limits. Section S2, soft boundaries exclusive, is the central working area. The sections S1 and S3, soft boundaries inclusive, are limited sections and the robot will tend to move to S2 if it is in these sections.
Basically, the control software of this patrol robot behaves as follows: (1) it maintains a belief state (x ) of the robot, default at 0 (denoting the centre of the corridor) and able to reset to 0 by an event reset; (2) when x is 0, it can be calibrated to the actual position of the robot from its sensor by a cal event; (3) when x is within S2, it can be either increased or decreased by 1, denoting the robot moves either to the left or to the right nondeterministically; (4) when x is within S1, it can only be increased by 1, denoting the robot moves to the right; and (5) when x is within S3, it can only be decreased by 1, denoting the robot moves to the left.  We illustrate in Fig. 8 the RoboChart model for this patrol robot. The module PatrolMod contains a robotic platform RP and a controller Ctrl composed of two state machines CalSTM and MoveSTM. RP declares two output events cal of type int and reset, and two inputs events left and right (to indicate the direction of moving and its new position) of type int through the interface eventsInf, and provides a variable x of type int through the interface dataInf. This variable is shared in Ctrl and also to the two machines by requesting dataInf.
The machine CalSTM sets x to 0 in the action (x=0) of its default transition t0 to state cal, and then it is ready for calibration from the input trigger cal?l of the transition t1 if [x==0], or to update x (the action update!x of the transition t2 ) to MoveSTM through a connection on event update of type int otherwise [x!=0]. We note that it is not mandatory to use this communication mechanism to update x to MoveSTM because x is shared in MoveSTM too. We use this way here to illustrate how nondeterminism is introduced in MoveSTM and how it interleaves with the shared variable.
The machine MoveSTM is responsible for resetting x (x=0) by the self-transition t2 of state move with trigger reset, and the robot movement around the corridor based on the value (of variable x) which passes on update and stored in a local variable l by the other two self-transitions (t1 and t3) from state move. If l is larger than -MAX (guard [l>-MAX] of t3 where MAX is a constant variable), denoting sections S2 and S3, x is updated to l-1, followed by a left!x event. If l is less than MAX (guard [l<MAX] of t1), denoting sections S2 and S1, x is updated to l+1, followed by a right!x event. Consequently, if l is in section S2, the choice between the two transitions is nondeterministic. We note that MAX INT is not explicitly declared in the model and will be given in verification or animation where int is bounded.
Next, we describe the extra ITree-based CSP operators in order for the RoboChart semantics and return to the two models in Sect. 4.

Interaction trees
In this section, we briefly introduce interaction trees and extend our existing CSP semantics with additional operators to support the RoboChart semantics. These include three operators (interrupt, exception, and renaming) that are introduced in the previous work [16], one generalised choice operator and two prioritised variants of hiding and renaming operators introduced in this extension paper.
Interaction trees (ITrees) [9] are a data structure for modelling reactive systems that interact with their environment through events. They are potentially infinite and defined as coinductive trees [19] in Isabelle/HOL. codatatype ( e, r) itree = Ret r | Sil "( e, r) itree" | Vis " e → ( e, r) itree" ITrees are parameterised over two types: e for events (E ), and r for return values or states (R) . Three possible interactions are provided: (1) Ret x : termination ( x ) with a value x of type R returned; (2) Sil P : an internal silent event (τ P , for a successor ITree P ); or (3) Vis F : a choice among several visible events represented by a partial function F of type E → (E , R)itree. Partial functions are part of the Z toolkit 5 [20] which is also mechanised in Isabelle/HOL. Deterministic CSP processes can be given executable semantics using ITrees. The determinism is inherent, since we use a partial function to model events and their continuations. Specifically, each unique event must map to at most one continuation. The benefit of this approach is that ITrees are easy to implement and animate, since the behaviour depends solely on provided input events. Therefore, our CSP operators cannot introduce nondeterminism, which must be statically resolved.
Our animator takes a model with an ITree-based semantics in Isabelle/HOL, and generates Haskell code for the underlying ITree. Though this often an infinite structure, Haskell's intrinsic use of lazy evaluation allows to model and partially evaluate infinite objects. We can therefore step through an ITree's behaviour by unfolding the various constructors of the underlying algebraic (co)datatype. When a Vis constructor is encountered, the user is presented with a choice for one of the enabled events. When a Sil is encountered, it is simply removed and the successor ITree animated. This allows us to compress long sequences of τ events, and so simplified animation. Finally, Ret leads to termination of the animation.
Previously, the following CSP processes and operators have been defined: (1) basic processes: skip, stop, and div ; (2) input prefixing: inp c V (communicate any value from A over the channel c);(3) output prefixing c!v ; (4) guard b; (5) external choice P 2 Q; (6) parallel composition P A Q; (7) hiding P \ A; (8) sequential composition P Q; (9) loop and iterate. Though operators like external choice and parallelism can introduce nondeterminism, we restrict this by construction. Nevertheless, different strategies can be employed for statically resolving nondeterminsim, which we explore further in this section.
Here, we give an ITree semantics to extra CSP operators to allow us to give an ITree-based semantics to RoboChart. We (1) generalise external choice; (2) introduce three new operators-interrupt, exception, and renaming operators-used in the RoboChart's semantics to allow interruption of a during-action, termination of a state machine, a controller, or a module, and alphabet transformation of processes; and (3) add prioritised variants of renaming and hiding to statically resolve nondeterminism based on an order. We restrict ourselves to deterministic operators as it makes the animation of large models more efficient.

Generalised choice and external choice
Previously [10], we have given a semantics to CSP's external choice operator as a corecursive definition. Our mechanisation of ITrees intrinsically supports external choice through the use of partial functions to model visible events. However, our definition of choice can be generalised to support more flexible choice schemes. For example, priority can be given to one branch of the choice, in order to statically resolve any nondeterminism. We achieve this through a novel generalised choice operator, P M Q. For this, we use a merge function M, which merges two choice functions of type E → (E , R)itree. The operator is defined as a corecursive function using the equations listed below.
When making a choice between two visible event functions, Vis F and Vis G, the merge function is applied to combine the two. When combining two return value ITrees, Ret x and Ret y, we require that the two possible values are identical, and otherwise deadlock, to avoid nondeterminism. For silent events (τ ) and returns, we also prioritise their occurrence before any visible activity can occur. In particular, any τ events are greedily consumed before any visible event or return can occur.
With generalised choice, we can define external choice using a merge function F G = (dom(G) − F ) ⊕ (dom(F ) − G), and defining P 2 Q = P Q. This function combines all event maplets from F and G, whilst ignoring any maplets whose events occur in the intersection dom(F ) ∩ dom(G). For example {e 1 → P 1 , e 2 → P 2 } {e 3 → P 3 , e 2 → P 4 } = {e 1 → P 1 , e 3 → P 3 }, since e 2 is ignored. This again avoids nondeterminism, and when the two domains are disjoint the operator can be considered as a union. Another benefit of the generalised choice operator is that, as with Hoare and He's parallel-by-merge operator [2], properties of the choice operator reduce to properties of the merge function itself. This simplifies proofs of algebraic properties for choice functions. The most basic property of a merge function is wellformedness: Generalised choice has stop as a unit, since it can add no further behaviour. Moreover, div is a zero since τ events always take priority, and so a diverge process prevents choices being made. We can commute a choice by taking the converse of the merge function, where M ∼ = (λ F G. M G F ). As a result of the final law, if M is symmetric, that is M = M ∼ , then choice is commutative: P M Q = Q M P . From these properties, we can conclude that external choice is commutative and has stop as a unit. The former follows because f ⊕ g = g ⊕ f whenever dom f ∩ dom g = ∅, a property that is ensured by the construction of .
We now consider how we can derive alternative choice schemes. In some circumstances, it may be undesirable that possible events are lost by the external choice. For example, a → P 2 a → Q actually ends up as stop, since the two processes both have a as an initial event. We can instead resolve any nondeterminism by choosing to prioritise the addition of events from either the left, or the right branch. We introduce a biased choice operator, P 2 Q = Q ⊕ P , which chooses events from P whenever initial events are present in both P and Q. For example, a → P 2 a → Q = a → P , since the event from the left branch is prioritised.

Interrupt
The second operator we introduce is interrupt [7,8], P Q, which behaves like P except that if at any time Q performs one of its initial events then it takes over. We present partial functions as sets below. This operator, along with the other two, is defined corecursively, which allows them to operate on the infinite structure of an ITree. In corecursive definitions, every corecursive call on the right-hand side of each equation must be guarded by an ITree constructor.

Definition 3.3 (Interrupt).
In the definition, − is called the domain anti-restriction, and A − R denotes the domain restriction of relation R to the complement of set A. The Sil cases allow τ events to happen independently with priority and without resolving . The Ret cases terminate with the value x returned from either the left or right side of .
For the Vis cases, it is also Vis constructed from an overriding ⊕ of the further two sets, representing two partial functions. In the partial function, (dom(G) − F ) restricts the domain of F to the complement of the domain of G. The first partial function denotes that an initial event e of P , that is not the initial event of Q, can occur independently (without resolving the interrupt) and its continuation is a corecursive call P Q. The second function is just G, which denotes that the initial events of Q can happen no matter whether they are in F or not. This means if P and Q share events, Q has priority. This prevents nondeterminism.

Exception
Next, we present the exception operator, P [[A Q, which behaves like P initially, but if P ever performs an event from the set A, then Q takes over.

Definition 3.4 (Exception).
( The Ret case terminates immediately with the value x returned, and Q will not be performed. The Sil case allows the τ event to be consumed. Similar to Definition 3.3, the Vis case is also represented by the overriding of two partial functions. The first partial function represents that an initial event e of P , that is not in A (that is, e ∈ dom(A − F )), can occur independently and its continuation is a corecursive call P [[A Q. Following the execution of an initial event e of P that is in A (that is, e ∈ (A ∩ dom(F )), the exception behaves like Q, which is expressed by the second partial function.

Renaming
The other new operator we define for this work is renaming, P [[ρ]], which renames events of P according to the renaming relation ρ : E 1 ↔ E 2 . We note this relation is possibly heterogeneous, and so E 1 and E 2 are different types of events. First, we define an auxiliary function for making a relation functional by removing any pairs that have duplicate distinct values. This is the case when the renaming relation, restricted to the initial events of P , is functional.
This produces the minimal functional relation that is consistent with R. For example, This function is used to avoid nondeterminism introduced by renaming multiple events to the same event. We use this function to define the renaming operator.
The Ret case behaves like P and the renaming has no effect on it. The Sil case allows τ events to be consumed since they are not subject to renaming. In the Vis case, G is a partial function (E 2 → (E 1 , R)itree) that is the backward partial function composition • of F and a partial function made using mk functional from the inverse ∼ of the relation (dom(F ) ρ) which is the domain restriction of ρ to the domain dom(F ) of F . Basically, the multiple events of E 1 that are mapped to the same event of E 2 in ρ and also are the initial events of P , or in dom(F ), are removed in G. The renaming result is a partial function in which each event e 2 in the domain of G is mapped to a renamed process by a corecursive call P [[ρ]] where (e 2 → P ) ∈ G.
Because many-to-one mappings in ρ are removed by mk functional in G, the potential nondeterminism is excluded. For example, (renaming excludes nondeterminism) Here, the only available initial event after renaming is ea because the relation (dom(F ) ρ) ∼ is equal to {e →e 1 , e →e 2 , ea →e 3 } and mk functional removes the first two pairs (because of duplicate distinct values), and so results in {ea → e 3 }.
Remark 3.1. Roscoe [8] defines three ways for renaming in CSP. Injective functional renaming will not change the behaviour of a CSP process and is an alternative to parametrised CSP processes on channels.
Non-injective functional renaming may change the behaviour of a process by ignoring some level of detail or introducing nondeterminism. Relational renaming, a more general and powerful operator than the other two functional renamings, allows many-to-one (may introduce nondeterminism), or one-to-many (to offer more choice) mappings. What machine-readable CSP (CSPM) supports and FDR implements is relational renaming. We investigated all these approaches and chose to implement here the relational renaming with many-to-one and one-to-many mappings. This is mainly because RoboChart's semantics is defined using CSPM and verified using FDR. For many-to-one mappings, our definition here, however, blocks these many events and the definition of renaming with priority in Sect. 3.6, as follows, chooses one of these many events according to their priority.

Hiding with priority
The current semantics [10] of hiding P \ A is deadlock if more than one initial events of P are in A. This is to avoid nondeterminism caused by hiding of two possible events. This restriction can be relaxed by placing events to be hidden in an order. For example, Hiding events in a different order, therefore, resolves the external choice differently without deadlock. This difference is due to the maximal progress assumption of hiding: (a → P 2 b → Q) \ {a} is actually equal to τ (P \ {a}).
We define hiding with priority, P \ p el ( ), to put these events to be hidden in an order based on their order in a list el .
The foldl builds a return value by applying the function (λ Q e. Q \ {e}) (say f ) to the combined result (initially P ) and elements in el based on their orders. For example, The above examples now can be expressed as

Renaming with priority
Because the relation ρ of type E 1 ↔ E 2 in the renaming definition 3.5 is possibly heterogeneous (so E 1 and E 2 are different types), renaming cannot be like hiding with priority to place the events to be renamed in an order to rename events one by one. This is because renaming a process changes its event type from E 1 to E 2 , and so we cannot rename other events of type E 1 anymore. For this reason, we define renaming with priority, P [[ ]] p , which renames events of P according to a finite sequence of type seq (E 1 × E 2 ). We use the finite sequence type here to describe the mathematical definition of this operator and its representation in Isabelle is actually lists. A finite sequence of type seq X is a finite partial function N → X from natural numbers N to X . With , a priority is given based on the indices of pairs in the sequence in order to resolve potential nondeterminism in a particular way. For those pairs that have the same second element (in other words, many-to-one mappings), the pair with the smallest index has the highest priority. This renaming with a priority operator will only rename the event with the highest priority and block other events with lower priority.
Prior to the definition of P [[ ]] p , we need to define another two functions. The first function is the domain restriction l of to a set A.
This produces a new sequence, compacted from a function, or a set of ordered pairs, in which each member s is in and the first element (s.2).1 (of type E 1 ) of the second element s.2 (of type E 1 × E 2 ) of s is in A, by the squash function [20]. When a type is obvious, we use a short form This could be used in set comprehension, quantification, etc.
We give an example below to illustrate how l works. For the second function drop dup( ), we need to drop the pairs with lower priority (and so bigger indices).
We define an auxiliary least function first.
) has the least index number p.1 in the members q of that have the same target event (q.2).2 (of type E 2 ) as that (p.2).2 of p. In other words, p has the least index number in a set of renaming pairs that have multiple events renamed to the same event as in p. Now drop dup( ) is defined below.
The first predicate (maximal) in the conjunction states that every element in the resultant drop dup( ) is least in , and the second predicate (minimal) states that every least element in must be in the resultant drop dup( ). Here, the pair (e 2 , e) is dropped because it does not have the highest priority in terms of the target event e (due to the fact that e appears early in (e 1 , e)). With the two functions given above, we can define P [[ ]] p corecursively.

Definition 3.6 (Renaming with priority).
( This definition is similar to Definition 3.5 except that here is a sequence of renaming pairs and the relation in the inverse now has all its domain elements mapped to distinct values by drop dup. Because drop dup defines a sequence of type N → (E 1 × E 2 ), we get the range of the sequence by the ran function, which is a relation.
The difference between renaming and renaming with priority is exemplified below.   Compared to (renaming excludes nondeterminism), the potential nondeterminism introduced by renaming both e 1 and e 2 to e is resolved by giving priority to the renaming map (e 1 , e). If (e 1 , e) and (e 2 , e) are swapped, then the renaming will give priority to e 2 and its continuation is Q (instead of P ).

RoboChart semantics in interaction trees
In this section, we describe how we give semantics to RoboChart in terms of ITrees in Isabelle/HOL. These include types, instantiations, functions, state machines, controllers, and modules. In the implementation of RoboChart's semantics, we also take into account the practical details of the CSP semantics generation in RoboTool, such as naming and bounded primitive types.
In particular, nondeterministic choice between transitions, for example in Fig. 8, is resolved by the use of the prioritised renaming operator defined earlier through ordered transition event mappings. This is not covered in the previous work [16] and is the new contribution of this paper.

Overview of RoboChart semantics
The RoboChart CSP semantics is sketched in Fig. 9. The semantics for modules, controllers, state machines, and (either composite or basic) states are CSP processes. The semantics for a robotic platform, however, is different from controllers and state machines in that it does not have a particular behaviour and so its semantics is not a CSP process because the platform is an abstraction of a physical robot through variables, events, and operations.
Semantically, RoboChart has a hierarchical memory model with a memory for the robotic platform at the top, memories for controllers in the middle, and memories for state machines inside their container controllers. A memory process records the reads and writes of variables for components (the platform, controllers, and state machines) in scope. The memory for a state machine caches the (both local and shared) variables it requires, and so the semantics of the machine is independent of the location where these variables are declared. The memory for a controller or the platform, however, is different from that of a state machine in that it not only accepts updates to the variables in the memory but also propagates the updates down the hierarchy to the memories of state machines that require the updated variables.
The RoboChart semantics of the autonomous chemical detector model in Sect. 2.1 is shown in Fig. 10. The semantics of the module is a parallel composition of the two controllers with the robotic platform memory

Renamed GasAnalysis
Ctrl memory

Renamed MicroController
Waiting Going ... (RP memory) and a buffer process (Buffer). The buffer process models the asynchronous connection from MainController to MicroController on event turn in Fig. 1. This semantics for asynchronous connections is omitted in Fig. 9 for simplicity. The platform memory and the controller memories for this chemical detector model are simply the CSP process skip because the platform and the controllers do not provide any variables for sharing. The platform memory and the controller memory for the one-dimensional patrol robot in Sect. 2.2, nevertheless, record the access and update of the shared variable x and propagate its update to the controller, and finally to the state machines in the controller.

Renamed Movement
The semantics of MainController (or MicroController) is the composition of the CSP process for the semantics of its contained state machine GasAnalysis (or Movement) with the controller memory. We note the CSP processes for the controllers are renamed, such as Renamed MainController. This is because RoboChart uses directed connections for communication, but CSP's parallel composition requires composites to have the same channel names for communication. We, therefore, need to rename the exported channels of the controller CSP processes to ensure the channel names for the two controllers in a connection are the same, and so they can communicate with each other.
Similarly, the CSP processes for the semantics of the state machines (GasAnalysis and Movement) are also renamed for the same reason to ensure the state machines in a controller can communicate on directed connections. The renaming is not compulsory for the chemical detector model because each controller contains only one state machine, but it is mandatory for the patrol robot because the controller contains two state machines connected on event update. So in general, we always rename them.
The semantics of the state machine GasAnalysis is a parallel composition of the node (including the junction i0 and the states NoGas, etc.) processes with the machine memory recording the access and update of the local variables of the machine. The semantics of the machine Movement has a similar structure. The memories of the state machines CalSTM and MoveSTM in Fig. 8, nonetheless, record not only their local variables l but also the shared variable x.
Practical consideration. Our ITree-based semantics for RoboChart in this paper aims for consistency with the restricted CSP semantics generated in RoboTool. Here the restriction particularly refers to bounded types for basic RoboChart types and corresponding closed arithmetic operators. In the future, we could use unbounded basic types with usual operators, then enforce enumerations just in the animator, not in the semantics like this work. One advantage of using this restricted semantics is the possibility to reuse the current CSP semantics generator in RoboTool to generate corresponding ITrees-based theories for Isabelle to automatically generate Haskell code.
RoboTool automatically generates multiple versions of CSP semantics for a RoboChart model, including a standard version (S), an optimised version (D) that reduces internal interaction to some extent, an optimised and visible version (VS) that further exposes internal interaction, and an optimised and compressed version (O) with compressions using strong bisimulation and diamond elimination [8]. All these versions use some compressions. Our ITree-based semantics for RoboChart in this paper is based on the D version because RoboTool uses this version for verification. Our semantics here does not support compressions in the D version. Instead, we implement a form of compression for internal events in the animator.

Types
RoboChart has its type system based on that of the Z notation [21]. It supports basic types: Primi-tiveType, Enumeration, records (or schema types), and other additional types from the mathematical toolkits of Z.
The core package of RoboTool provides five primitive types: boolean, naturals, integers, real numbers, and string. We map integers, naturals, and strings onto the corresponding types in Isabelle/HOL, but with support for code generation to target language types. This improves the efficiency of evaluation and thus animation. RoboChart models can also have abstract primitive types with no explicit constructors, such as Chem and Intensity in the chemical detector model presented in Sect. 2. We map primitive types to finite enumerations for the purpose of code generation. We define a finite type PrimType parametrised over two types: t for specialisation and a numeral type a for the number of elements.
datatype ( t, a::finite) PrimType = PrimTypeC a For example, Chem is implemented as a generic type a Chem = (ChemT, a) PrimType ( ). An example of a finite type a is the numeral type in Isabelle, such as type 2 which contains two elements: zero (0::2) and one (1::2). In order to construct an element of type Chem, we define a dedicated constructor ChemC which is simply a type cast of PrimTypeC. Finally, we use (ChemC 0::2) and (ChemC 1::2) to construct such two elements of type (2 Chem).
For enumerations and records, we use datatype and record in Isabelle. The Status and GasSensor below are such examples for the corresponding types in the Chemical package shown in Fig.2 datatype Status = Status_noGas | Status_gasD record a GasSensor = gs c :: " a Chem" gs i :: " a Intensity" An instantiation type (2 GasSensor) is a record containing two fields of finite types (2 Chem) and (2 Intensity), both of which have two elements. We now can construct an element (|gs c = Chem (1::2), gs i = IntensityC (0::2)| ) of this type: the chemical is q and the intensity is 0.
For finite sequences such as Seq(GasSensor), we also bound the length of each sequence in this type. We define bounded lists or sequences ( a, n::finite) blist over two parametrised types: a for the type of elements and a finite type n for the maximum length of each list.
typedef ( a, n::finite) blist = {xs:: a list. length xs ≤ CARD( n)} CARD here retrieves the cardinality of n. We introduce a notation a blist[ n] for this type and also define several functions: (a) blength to get the length of a bounded sequence; (b) bnth to get the nth element of a bounded sequence; (c) bappend (@ s ) to concatenate two bounded sequence; and (d) bmake to construct a bounded sequence from a finite list.
For other types, we have their counterparts in the Z toolkit.

Instantiations
The instantiation.csp file of the CSP semantics contains common definitions used by all models for verification using FDR. These include the definitions of bounded core types (named types in CSP) and arithmetic operators under which these bounded types are closed. We show below one example for type core int and three for the arithmetic operators, closed under a bounded type T. In the definition of Plus, if e1+e2 is within T then this is the result, otherwise, it is e1. Other definitions Minus and Neg are similar. We use locale [22] in Isabelle to define these for reuse in all models. Locales allow us to characterise abstract parameters (such as min int and max int, to define bounded core type core int) and assumptions in a local theory context. locale robochart_confs = fixes min_int::"integer" and max_int::"integer" and max_nat::"natural" and min_real::"integer" and max_real::"integer" We define bounded core types as sets by ranges given by a lower limit and an upper limit, such as parameters min int and max int. Additionally, in code generation, we use lists to implement sets, and so we define a list of ranges first in core int list and then convert it into a set core int set.
We note a named type in CSP can be used as a type as well as a set expression, and so a bounded core type is a type and also an expression. Isabelle, however, has different concepts for types and expressions, and they cannot be used interchangeably. For this reason, we have core types in Sect. 4.2 and bounded sets for these types here. The definition Plus illustrated above corresponds to that in the instantiation.csp file and is an example to define a closure operator.
In the theory of Isabelle for a RoboChart model, we instantiate this locale using interpretation ( ), which allows us to assign concrete values for the parameters. An example is shown below which instantiates the parameters (limits) of the locale to -2, 2, ... etc.
Then we can use rc.core int set and rc.Plus to access the instantiated definitions.

Functions
Functions in RoboChart benefit from the rich expressions in Isabelle and the Z toolkit in Isabelle. The expressions that are not supported in CSP-M such as logical quantifications are naturally present in Isabelle. Using the code generator, the preconditions and postconditions of a function definition can be solved effectively, while this is not possible in CSP-M and FDR.
As mentioned in Sect. 2.1, three (goreq, angle, and analysis) among the five functions defined in the Chemical package of the autonomous chemical detector model in Fig. 2 are unspecified, and two (analysis and intensity) among them are specified in the original model. Our model presented in Fig. 2 specify all five functions. With the capability of solving preconditions and postconditions of functions introduced in our work, we detect two problems in the definitions of the two specified functions in the original model, which are corrected in our model. Next, we present the semantics of the two functions (intensity and location) in our implementation.
The intensity function defined in Fig. 2 has a precondition ( ) that the length (size) of the parameter gs is larger than 0, and two postconditions ( ) involving universal and existential quantifications where @ separates constraint and predicate parts, and goreq is a ≥ relation on intensities. The result of the function is the largest intensity in gs. For verification with FDR in RoboTool, an explicit implementation of this function must be supplied. Our definition of this function in Isabelle, however, is directly from its specification and is shown below.
definition "pre Chemical intensity gs = (blength gs > 0)" definition "Chemical intensity gs = (THE result. (∀x::nat < blength gs. Chemical goreq(result, gs i (bnth gs x)))∧ (∃x::nat < blength gs. result = gs i (bnth gs x)))" In the definitions, blength gs gives the length of a bounded sequence gs, bnth gs n gives the nth element in gs, and gs i returns the field value in a record of type GasSensor. The two definitions are straightforward except that a definite description (THE result, denoting the unique result such that the predicate holds) is used to return the result. We have two definitions here corresponding to the definition of intensity: one for its precondition and one for its postconditions. This is due to the semantics of such a function f in RoboChart: a boolean guard (pre(f) & P) where pre(f) is the preconditions of f and f is called in process P , and so if the preconditions are not satisfied, the semantics deadlocks. We note that there is an error in the definition of intensity in the original model where ≤ (instead of <) is used for comparison between x (and y) and size(gs). This is because sequences are zero-indexed. Our animation detects this error and so we have fixed it.
The location function defined in Fig. 2 has one precondition and one postcondition and their corresponding definitions in Isabelle are shown below. The result of this function is the location (on the right or in the front of the robot, according to the definition of the angle function) where the largest intensity in gs is detected.
definition "pre Chemical location gs = (blength gs > 0)" definition "Chemical location gs = (THE result. (∃x::nat<blength gs. (Chemical intensity(gs) = gs i (bnth gs x)) ∧ (¬ (∃y::nat < x. (Chemical intensity(gs) = gs i (bnth gs y)))) ∧ (∀x::nat < blength gs. Chemical goreq(result, gs i (bnth gs x))) (result = Chemical angle(x))))" Inside the definite description is an existential quantification over an index x of gs such that (a conjunction of three conjuncts) (1) the intensity gs i (bnth gs x) of the sensor reading at index x is the largest intensity (Chemical intensity(gs)) in gs; (2) there does not exist an index y such that y is less than x and the intensity at y is also the largest intensity in gs (in other word, x is the smallest index whose intensity is the largest); and (3) the result of the function is just the angle Chemical angle(x) of x.
We also found another error in the postcondition of location in the original model: the postcondition is not strong enough to identify a unique result of the function for the same input (and so the result is a relation and not a function). Our definition of the function fixes this problem by specifying that x is the smallest index.
While there are problems with the definitions of intensity and location in the original model, their implementations in CSP for verification with FDR previously, however, are correct. This leads to an inconsistency between models and their semantic implementation for verification. Our approach presented here translates the specification of functions from models to their semantic implementation in Isabelle directly, and so the consistency is preserved. This is one benefit of our approach.

Channels and alphabet transformation
A CSP process in our semantics is an interaction tree of type (E , R)itree, parametrised over a type E of events representing the event alphabet (Σ) of the CSP process and a type R of return values. E is declared through the chantype command and expressed as a finite set of channels declared in the command. Each channel c is modelled by a prism [23]: V =⇒ ∆ E where V is the value type of c. Each prism contains two functions [10, Definition 5]: a destructor match: E → V and a constructor build: V ⇒ E . We show an example to illustrate the creation of such an event alphabet chan. chantype chan = Input::integer Output::integer State::"integer list" This chan declares three channels: Input and Output of type integer, and State of type integer list. Each channel is modelled by a prism. For example, the channel Input, carrying a value of integer, has a type integer =⇒ ∆ chan. We use build Input 1 (a notation Input C 1 introduced for it) to construct an event (Input 1) of type chan. External choice P 2 Q requires that P and Q have the same type (E , R)itree and so the same event type E . Parallel composition P A Q additionally requires that the type R of return values is empty (() or unit in Isabelle) because CSP processes in parallel usually do not return data, and so both P and Q should be the type of (E , ())itree. A here is a set of events and of type P E .
For the CSP processes that have different types, they need to be transformed into the same type prior to composition. The alphabet transformation of a process P of type (E 1 , R)itree is through renaming (or renaming with priority) according to a renaming relation ρ of type E 1 ↔ E 2 (or a finite sequence of type seq (E 1 × E 2 )), and the resultant process P We also note that the renaming relation or the finite sequence for the renaming operators is "total"only events of type E 1 in the relation or the sequence are renamed and others are blocked -no matter whether this is a homogeneous (E 1 and E 2 are the same) or heterogeneous (E 1 and E 2 are different) renaming. This is different from the relational renaming operator in CSPM where the relation is partial and so the events that are not in the renaming relation are not affected by the renaming. This difference is due to the fact that ITrees or Isabelle's terms are strongly typed.
In our ITree-based semantics for RoboChart, illustrated in Fig. 10 for the autonomous chemical detector model, each state machine, controller, or module has a different event alphabet by declaring an individual channel type. For example, the state machine GasAnalysis, the controller MainController, and the module ChemicalDetector declare channel types Chan GasAnalysis, Chan MainController, and Chan -ChemicalDetector. The renamed GasAnalysis transforms the event alphabet of GasAnalysis from Chan -GasAnalysis to Chan MainController, and so it can be composed in parallel with the controller memory (whose event type is Chan MainController). Similarly, the two controllers are renamed to the event alphabet Chan ChemicalDetector of the module, and so they are able to be composed in parallel with the robotic platform memory and buffer processes.

State machines
The RoboChart semantics of a state machine is a parallel composition of memory processes for its variables (MemoryVar) and transitions (MemoryTrans), and a process (STM) for its behaviour with internal events hidden and also catering for its termination using the exception operator.
STM is a parallel composition of the behaviour (STM I) for its initial junction and the restricted behaviour (S R) for each state S synchronising on state entering and exiting events. A state's behaviour S involves the entering of this state, the execution of its during-action, and the execution of one of its transitions. The execution of a transition exits the state, executes the action of the transition, and enters the target state of the transition. Not all transitions are available for S, such as the transitions from sibling states of S and substates of S. These transitions are excluded in the restricted behaviour S R.
The channel type of Movement includes four kinds of channels. Firstly, flow control channels include (a) internal 6 for transitions without a trigger; (b) enter, entered, exit, and exited for the entering and exiting of a state; and (c) terminate for the termination of the machine. Secondly, variable channels contain a set and a get channel for each variable with an additional set EXT for each shared variable to accept an external update. Thirdly, event channels include two channels for each event of the machine, one such as obstacle for the event obstacle used in actions of RoboChart and another such as obstacle (with an additional TIDS for its type) for the event obstacle used as triggers of transitions. The distinction of two event channels (obstacle and obstacle ) for each event (obstacle) is necessary because the guard of a transition is evaluated in MemoryTrans, and so only the trigger event (not action event) of the transition is subject to the guard evaluation, and, therefore, has a new channel (obstacle ) with a transition id. We note, however, that events obstacle .tid of this new channel are eventually renamed to the event channel obstacle in the process for the machine. Fourthly, operation call channels include a channel such as moveCall for each call to the operation move provided by the platform.

Memory for variables and transitions
The memory process Memory x for a shared variable x, such as x in the state machine CalSTM in Fig. 8, is shown below.
The process is an infinite loop. It provides three choices: output the value v on get x without updating the variable and accept a local (or external) update of the variable through set x (or set EXT x). For a local variable of the state machine, its memory process does not provide an external update.
The memory process for transitions of the state machine Movement in Fig. 6 is partially (3 in 24 transitions) illustrated below.
The state of this loop process is a constant id (used to identify a RoboChart module). Each choice corresponds to a transition: (1) the first choice for the default transition t1 from the initial junction to state Waiting which has no trigger (hence internal); (2) the second for the self transition of state Waiting whose trigger is an output resume (din because the resume event acts as an input in the state machine according to the connection in Fig. 5); and (3) the third for the transition from Waiting to state Going which has an input trigger turn?a where we use a notation turn ?(TID t3, din, a∈Chemical Angle) to denote inp turn {(TID t3, din, a) | a∈Chemical Angle} (input values from a set of triples by set comprehension over a channel turn ); and (4) the fourth for the transition from AvoidingAgain to Avoiding whose guard is (d1-d0>stuckDist) (time semantics is ignored,becomes a closed operator rc.Minus under core int) and evaluated in this memory transition process. We note that these choices will not lead to nondeterminism because their initial input or output events are parametrised over a distinct TID (for each choice).
For the transition with an input trigger and a guard together, such as the self transition of the state move in Fig. 8 with a trigger update?l and a guard [l>=-MAX], its semantics in CSP is a constrained input prefix: update?l:(l≥-MAX) where (l≥-MAX) is a constraint on l. So the memory process for transitions of the state machine MoveSTM in Fig. 8 has choices illustrated below.

Nodes
The semantics of each node in a state machine is a CSP process. In this paper, we consider three kinds of nodes: initial junctions, basic states, and final states, which are used in the two RoboChart models. Semantics for other nodes including normal junctions and composite states are part of our future work.
Initial junctions. We show the semantics for the initial junction i0 in the state machine CalSTM in Fig. 8, which has an outgoing transition t0 with an action x=0 to set the variable x to 0.
The process outputs (1) a pair (TID t0, din) on the channel internal, denoting the empty trigger of t0 from i0 to state cal; (2) 0 on the channel set x, denoting the initialisation of x to 0 (by parallel composition with the memory for x presented later), which corresponds to the action of t0; (3) a pair (SID CalSTM, SID CalSTM cal) on the channel enter, denoting the start of entering the state cal; and (4) a pair (SID CalSTM, SID CalSTM cal) on the channel entered, denoting the completion of entering cal.
States. The process S for the behaviour of a state S is sketched below.
S (id ) = enter ?sd : OSIDS → S exec(id , fst sd ) S exec(id , s) = S entry entered !(s, SID S )  S and S exec are defined by mutual recursion. Initially, S accepts enter ing from other nodes of the state machine containing S where OSIDS denotes a set of pairs (oSID, SID S ) (oSID is SID for one of the other nodes and SID S is SID for S). Afterwards, the behaviour of S is given by S exec with its second argument being the other node (the first element of sd ).
S exec, with a parameter s denoting the node entering S, executes the entry action of S first, if any, denoted by S entry. Then S is entered . After that, the behaviour is given by an interrupt. The duringaction of S (S during) can be executed if none of the initial events of the right side (external choices) of the interrupt is performed, that is, none of the self transitions sTrans of S or other transitions oTrans from S is taken, or none of the trigger events EvtChs of the state machine containing S is signalled. If, however, any of these transitions is taken or any of these trigger events is signalled, then the during-action is interrupted. A stop process after S during prevents the interrupt from being terminated and so interruption is always possible.
For each t of sTrans, it behaves as follows: (1) the corresponding event channel e t for its trigger event, such as obstacle , synchronises on t (identified by TID t) only; (2) S starts to exit by itself where pSID S denotes (SID S , SID S ); (3) the exit action of S, denoted by S exit, is executed; (4) S is exited ; (5) t starts to enter S again because it is a self transition; and (6) finally S exec is recursively called with the source state s being SID S .
For each t of oTrans, the early behaviour is the same as above and so it is omitted (...). After S is exited , t starts to enter its target from S, identified by SID td , and then the target is entered . Finally, S returns to its initial state (S (id ) is called) and accepts a further enter request.
For each trigger event e of the state machine containing S, there is a corresponding additional event channel e declared in the channel type of the machine. The set of these channels is denoted by EvtChs. If this event e of a transition t is signalled (e?(TID t, )), the during-action is interrupted and S accepts an exit from one of the other nodes. Then its exit action, denoted by S exit, is executed. Afterwards, S is exited from the node (fst sd ). Finally, S returns to its initial state (S (id ) is called) and accepts a further enter request.
S and S exec are implemented in ITrees through nested iterations: the outer iteration, corresponding to S , is an infinite loop and the inner, corresponding to S exec, is a conditional iteration by the iterate constructor. The condition is true for self-transitions and false otherwise.
An example of the process for state Waiting in Movement in Fig. 6 is shown below. Ret (True, fst (snd r), SID_Waiting)) 2 10 (turn_?(TID_t2, din, a∈Chemical_Angle) → set_a!a → 11 exit!(SID_Waiting, SID_Waiting) → exited!(SID_Waiting, SID_Waiting) → 12 enter!(SID_Waiting, SID_Going) → entered!(SID_Waiting, SID_Going) ; 13 Ret (False, fst (snd r), SID_Waiting)) 2 14 ... 15 ))) (ret)); Ret (id)) Basically, State Waiting is an infinite loop, an ITree, whose state (a state of an ITree is its carried data or its return value) is an integer id (corresponding to the parameter id), with a nested conditional iteration by iterate (corresponding to S exec). The state of the iteration is a triple such as (True, id, fst sd), whose first element is a boolean value to indicate if this iteration terminates or not, whose second element is id, and whose third element is the RoboChart state (for example fst sd, see lines 2 and 3) that initiates entering of the state Waiting of S exec. Initially, the state of the iteration is passed from its preceding Ret construct and recorded in a variable ret (also the third argument of iterate, see line 15).
In the iteration body, snd (snd r) on line 5 is the third element of the tuple r and is a RoboChart state. CALL randomWalk(id) on line 6 corresponds to the call to an operation randomWalk (provided by the robotic platform) in the during-action of Waiting. Lines 7 to 9 correspond to the self transition t0 of Waiting, whose trigger is resume, and lines 10 to 13 correspond to the transition t2 (from Waiting to Going) whose trigger is turn?a. We note that there is no entered event for t0 and the first element in the return value Ret(True, fst (snd r), SID Waiting) is True. This is because t0 is a self transition and it does not need to wait for entering shown on line 2. The first element True makes iterate continue its inner iteration, and the third element SID Waiting means this is entering from the state Waiting itself. The transition t2 is different from t0 in that it (1) has an input trigger to get the angle and record it in the local variable a, as shown on line 10; and (2) will exit Waiting (on line 11) and enter Going (on line 12). The execution of this transition will leave the inner iteration by setting the first element of the return value to False (on line 13).
The restricted behaviour of Waiting is shown below.

State_Waiting_R = λid. State_Waiting(id) internal events -trigger events skip
State Waiting R is a parallel composition of State Waiting and a skip process over a set of events for synchronisation which is the set difference of all internal events internal event (including e events and internal events) and all trigger events trigger events of the machine Movement. The parallel composition with skip blocks all events in the synchronisation set and leaves all events in trigger events to proceed independently. We note that for a basic state such as Waiting, its restricted process will not change its behaviour State Waiting. The reason why restricted behaviour is needed is because of composite states. We will deal with it in the future.

Composition of STM and memory processes
As sketched in Figs 9 and 10, the semantics of a state machine is the parallel composition of the composed processes for its nodes and its memory. We show below the composed processes for the nodes of the state machine CalSTM in Fig. 8.

STM_CalSTM = λid. I_i0(id) |[ flow_events_from_other_states ]| State_cal_R
The composed process STM CalSTM (called the node process) is a parallel composition of the process I i0 for the initial junction and the restricted process State cal R for the state cal over all the flow events flow events from other states that enter cal from other states.
Then the node process of a state machine is composed in parallel with the memory of the machine with proper event hiding. The definitions of such composition (called the node memory process) are omitted here for simplicity and can be found online (MemorySTM Movement for the machine Movement and MemorySTM CalSTM for the machine CalSTM). We note that in such a process, the internal events used for synchronisation between the node process and the memory, the get events of all variables, and the set events of all local variables are hidden because these events are used to synchronise between the node process and the memory and are internal. The set events of shared variables are not hidden because the update to shared variables by the set events needs to be propagated to other state machines.
As discussed previously, each event e of a state machine has two corresponding event channels e (for triggers) and e (for actions) in the semantics of the machines, such as obstacle and obstacle for the event obstacle of the machine Movement. Trigger event channels e in the composition of the nodes and the memory of a machine are renamed to e by forgetting the first element (a transition identifier) of the value carried on e . For example, MemorySTM Movement is renamed according to a renaming relation event map.

Renamed_MemorySTM_Movement = MemorySTM Movement [[event map]]
The event map contains the mappings not only for the trigger events like (obstacle .(TID t6, din, Loc left), obstacle.(din, Loc left)) but also for other event channels (events for actions, terminate, shared variable channels set and set EXT, and operation call) that will not be renamed like (obstacle.(din, Loc left), obstacle.(din, Loc left)) and (terminate.(), terminate.()) because the renaming relation is total.
Renaming, however, may result in nondeterminism in the RoboChart semantics, which is excluded in our renaming operator. For example, the renaming of MemorySTM MoveSTM for the state machine MoveSTM in Fig. 8 blocks both self transitions of the state move that have an input trigger update?l.

Renamed_MemorySTM_MoveSTM = MemorySTM MoveSTM [[event map]]
The event map contains the mappings like (update . (TID t1, din, v), update.(din, v)) and (update . (TID t3, din, v), update.(din, v)) where v is a literal integer number in core int. For v that is between -MAX and MAX, the two events update . (TID t1, din, v) and update .(TID t3, din, v) are both enabled for communication (see the definition of MoveSTM MemoryTrans where both predicates in the two set comprehensions are satisfied) and they are mapped to a same event update.(din, v) in this relation. According to the definition of renaming in Sect. 3.4, both events are blocked and so the state move is not able to take the two self transitions. This problem can be solved by using the renaming with priority defined in Sect. 3.6.

Renamedp_MemorySTM_MoveSTM = MemorySTM MoveSTM [[event map list]] p
The event map list has the same mappings as event map, but it is a list (and so the mappings are ordered) instead of a relation. This renaming gives priority to the event at the front of the list. If (update .(TID t3, din, v), update.(din, v)) is after (update . (TID t1, din, v), update.(din, v)), then t1 has a priority and so the nondeterminism is resolved. This corresponds to moving towards only one direction (to the left) when the robot is in Section S2 in Fig. 7, instead of the nondeterministic choice of two directions. If we change the order of the two mappings, then t3 will have a priority and the direction of the movement to the right will be chosen.
The semantics of a state machine also needs to take its termination (for example the final state is reached) into consideration. This is shown in the process for MoveSTM below.

D MoveSTM = (Renamedp MemorySTM MoveSTM [[{terminate.()} skip) \ internal_events
Based on the definition of the exception operator, if Renamedp MemorySTM MoveSTM ever performs a terminate event, then skip will take over and so the process terminates. The process also hides all internal events and flow control events, defined in internal events.

Operations
Operations in RoboChart can be provided by robotic platforms such as move and randomWalk in Fig. 1, or defined by state machines such as changeDirection in Fig. 3.
The semantics of a call (an action) to an operation that is provided by a robotic platform is an event to record the call with appropriate parameters. For example, the semantics of move(lv,a), the entry action of the state Going in Fig. 6, is get a?a → moveCall!(const lv, a) → where the message on the channel moveCall contains the value const lv of the constant variable lv and the value of the local variable a, retrieved from the memory through get a.
The semantics of a state machine-defined operation is different from that of a state machine because an operation is not an independent execution element like a state machine. Its behaviour is within the scope of the state machine that calls the operation. For this reason, the semantics of the operation does not include a separate channel type (or an event alphabet) and does not have a separate memory. Instead, all channels required for the operation are declared along with the channels for the caller state machine in a channel-type declaration. For example, the channel type Chan Movement of Movement has the following additional channels for the operation changeDirection.
chantype Chan_Movement = ... internal_changeDirection :: TIDS_changeDirection enter_changeDirection :: "SIDS_changeDirection×SIDS_changeDirection" entered_changeDirection :: "SIDS_changeDirection×SIDS_changeDirection" exit_changeDirection :: "SIDS_changeDirection×SIDS_changeDirection" exited_changeDirection :: "SIDS_changeDirection×SIDS_changeDirection" terminate_changeDirection:: unit get_l_changeDirection :: "Location_Loc" set_l_changeDirection :: "Location_Loc" The get l and set l channels are for the parameter l of the operation and not for a local variable l (indeed, there is no such local variable). Different from local variables, l is only set once (set l) by the caller of the operation for passing its value, not inside the operation like local variables. The call changeDirection(l) to the operation in the entry action of the state Avoiding has its semantics in CSP as follows.
CALL__changeDirection_Movement = get l Movement?l → set l changeDirection!l → ; D changeDirection The first input event gets the value of the local variable l of Movement and the value is recorded in l. The second event updates the value of the parameter l (in the memory) of changeDirection to l. Finally, the process for this call behaves like the process D changeDirection for changeDirection. We note that the process D changeDirection is not similar to the process D MoveSTM to have a composition of the node process and the memory process of the machine. D changeDirection basically is a node process with appropriate event hiding and termination. The memory of changeDirection is part of the memory of Movement and so it is composed in parallel with the node process of Movement like the memory of Movement.

Controllers
The event alphabet of the process for a controller contains a termination channel, shared variable channels, event channels, and operation call channels. The event channels include not only the events of the controller but also those in connections between its state machines. The channel type of the controller Ctrl in Fig. 8 is such one example.
chantype Chan_Ctrl = terminate_Ctrl :: unit set_x_Ctrl :: core_int get_x_Ctrl :: core_int set_EXT_x_Ctrl :: core_int set_EXT_x_Ctrl_CalSTM :: core_int set_EXT_x_Ctrl_MoveSTM :: core_int rec_Ctrl :: "InOut×core_int" reset_Ctrl :: "InOut" update_Ctrl :: "InOut×core_int" This channel type includes a terminate channel, two get and set channels for the required shared variable x, three set EXT channels for accepting the update of x (through set EXT x Ctrl) and then propagating the update to the state machines of the controller that require x: CalSTM and MoveSTM (through set EXT x Ctrl CalSTM and set EXT x Ctrl MoveSTM), and three event channels. The event channels are not only for the events rec and reset of Ctrl but also for the event update that is used for communication between the two state machines. The memory of a controller deals with the update of shared variables. The memory of Ctrl is such an example.
This process accepts an update to x through an input event and propagates it to CalSTM and MoveSTM through two output events. Parallel composition of the heterogeneous state machine processes (D CalSTM and D MoveSTM, for example, have different event alphabets) for a controller requires they all share a common event type E , and so we rename them. The events of the state machines are renamed to the corresponding events in the controller alphabet, according to the connections between the controller and its state machines.  Ctrl.(dout, v), which allows the two state machines to communicate on the channel update through parallel composition according to the directions (CalSTM uses it for output and MoveSTM uses it for input) of the event update in the connection between the state machines.
The semantics of a controller is a parallel composition of the composed state machine processes and its memory with appropriate event hiding and termination. The process for Ctrl is given as follows.

Modules
Similar to the event alphabet of the process for a controller, that of the process for a module also contains a termination channel, shared variable channels, event channels, and operation call channels. The event channels include not only the events of its platform but also the events in connections between its controllers for the same reason.
The process for a module is a parallel composition of the renamed processes for its controllers, memory processes, and buffer processes for asynchronous connections between its controllers such as the connection on event turn from MainController to MicroController in Fig. 1. The semantics for this connection is a one-place buffer. buffer = loop (λla. (((length la ≥ 0)∧(length la ≤ 1)) &turn?(dout, a∈Chemical_Angle) → [a] ) 2 ((length la > 0) &turn!(din, hd la) The state of a buffer process is of type V list where V is the value type (Chemical Angle) of the event channel (turn) corresponding to the event (turn) of the connection (c) which this buffer process is for. The buffer process is an infinite loop whose body is an external choice of two processes: (1) if the length of its state (a list) is either 0 or 1, it accepts an input (a) on the channel turn whose event direction is dout (and so the output from MainController) and then terminates with the updated state (a new list [a] with the only element a); and (2) if its state is not an empty list, it outputs the head element (hd la) of the list on the channel turn whose event direction is din (and so the input to MicroController) and then terminates with the update state (an empty list []).
We also note that when renaming the processes for controllers, it is not necessary to swap the direction of the event channels for the events of the controllers that are connected asynchronous. This is because of the usage of a buffer having connected the output of the event on one controller and the input of the event § ¤ 1 Starting ITree animation... on another controller through shared buffer elements. This is different from renaming the processes for state machines where one side uses an opposite direction. The memory of a module deals with the update of shared variables and also the propagation of the update to its controllers, which is similar to that of a controller. The definition of the process for a module is omitted for simplicity and can be found online (D ChemicalDetector for the autonomous chemical detector and D PatrolMod for the patrol robot).

Code generation, animation, and case studies
As discussed previously in [10,Sect. 5], the animation of ITrees is achieved through code generation [13] in Isabelle. Infinite corecursive definitions over ITrees are implemented using lazy evaluation in Haskell. Associative lists are used as an implementation for partial functions in ITrees and a simple animator in Haskell is presented. Using the same approach for animation, we are able to animate the two RoboChart models shown in Sect. 2.

Autonomous chemical detector
We illustrate two scenarios of the animation of the autonomous chemical detector in Figs. 11 and 12. Here, we instantiate Chem and Intensity to be a numeral type 2 and the sequence of GasSensor is bounded to 2, which is the same as the instantiations for the verification with FDR4. An animation scenario represents the interaction of the model with its environment: the lines starting with Events are produced by the model and represent all enabled events; and the lines starting with [Choose: 1-n] represents a user's choice of enabled events from number 1 to n. In Fig. 12, we omit the lines for enabled events and append the chosen event to the chosen number for simplicity. Figure 11 illustrates the behaviour of the model when detecting a dangerous chemical: (1) initially the controller calls the platform to perform a random walk: the number 1 event is chosen on line #3, which corresponds to the call of the during action randomWalk() of state Waiting in Fig. 6; (2) then a sequence of gas sensor readings is received through the gas event, and we choose number 9 (among 21 enabled gas events shown on lines #4-6 where the first element Din of each event is omitted) on line #7: Gas [(0,0),(1,1)], representing a chemical being detected and its intensity is high in the second pair of the sequence; (3) the controllers call the move operation with speed 0 (on line #9), provided by the platform, to stop the robot; (4) the controllers indicate the platform to drop a flag (on line #11); and finally (5) the controllers terminate (on line #12).
In Fig. 12, we illustrate another scenario: a chemical is detected but its intensity is low for the two readings on lines #2 and #7. The model behaves as follows: (1) the initial behaviour is the same: calling the platform to request a random walk; (2) a sequence of gas sensor readings is received (online #2); (3) the controllers call the move operation (the entry action of the state Going in Fig. 6) to request the robot to move forward at speed 1 (on line #3); (4) an obstacle on its right is encountered (on line #4); (5) the odometer § reading is 0 (on line #5); (6) the controllers call move (the action of a transition in the defined operation changeDirection) to request the robot to move towards its opposite direction (left here) to the obstacle at speed 1 (online #6); (7) another reading of the gas sensor shows there is still a chemical detected with low intensity (on line #7); (8) the controllers call move (the entry action of state TryingAgain in machine Movement) to request the robot to move towards its front at speed 1 (on line #8); (9) an obstacle on its left is encountered (on line #9); (10) the odometer reading (the action of the transition from state TryingAgain to state AvoidingAgain) is 1 (on line #10); (11) there is another odometer reading (0) on line #11, which corresponds to the entry action of state Avoiding (the entering of this state is resulted from the taken transition from state AvoidingAgain to state Avoiding due to its guard d1-d0>stuckDist is true where the values of d0 and d1 are the previous two odometer readings 0 and 1, and the value of stuckDist is set 0 in this animation); (12) we omit further interactions. Based on the animation, we also observe that if no chemical is detected, the model returns to its initial state. If the low-intensity chemical is detected, even without progress of MicroController, the model can continuously read through the gas event without blocking. This is due to the connection between the controllers on event turn being asynchronous, and so MainController can continuously send a turn event without waiting for the synchronisation of MicroController. In our implementation in ITrees, the buffer process defined previously for the connection reflects this behaviour: overwriting the buffer is always allowed.

The patrol robot
In this example, we instantiate MAX INT to 3 and MAX to 2 and illustrate three scenarios of the animation of the patrol robot corresponding to the three sections (S1, S2, and S3) of the corridor in Fig. 7.
We show the first scenario in Fig. 13, which is related to the calibrated position in S1. The model behaves as follows: (1) initially the controller provides eight events on lines #2-4 for users to choose: one to reset the position and another seven to set the calibrated position to an integer value between -3 and 3; (2) the second event (2) is chosen on line #5, denoting the calibrated position is -3 and so the robot is in S1; (3) the only available event on lines #6-10 is Right_PatrolMod 7 which corresponds to the right event in the RoboChart model, denoting the movement of the robot towards the right side of the corridor at the new positions (-2, -1, and 0 respectively); (4) since the new position on line #10 is 0 now, the controller could accept a right event and calibration events on lines #11-13; (5) the right event is chosen on line 14, and after that (6) the controller returns to its initial state: having the same available events on lines #15-17 as initially available events on lines 2-4. When x is equal to -3 and -2 (in section S1), the robot moves towards the right side and x is increased by 1, as illustrated on line #6-9. This behaviour is consistent with the semantics of the model. After x becomes -1 (in section S2), the model nondeterministically chooses to move towards the left side or the right side. Our animation on lines #6-10, and #14, however, shows only the right side is chosen. This § ¤ 1 Starting ITree Simulation... is because of the use of renaming with priority in Renamedp MemorySTM MoveSTM and the higher priority of the update event on t1 than t3 to resolve the nondeterminism (and so the priority is given to the movement towards the right side). In the RoboChart model, we expect each left or right event corresponds to decrease or increase x by 1. The animation, however, shows that the new positions (-2, -1, and 0) on the right event on lines #7, #9, and #14 stay the same as their previous positions on lines #5, #8, and #10. This is actually due to the semantics of shared variables in RoboChart, specifically the mechanism used to update shared variables and propagate the updates, which is subtle. We illustrate the implemented mechanism in our semantics in Fig. 14 where the exchange of the value of x in the module, the controller, and the two machines is through communication (labelled with an identifier, a channel, and a message over the channel).
The communications 1 to 4 show that the change of x to -2 in CalSTM is updated to the module PatrolMod, and then this update is propagated down the memory hierarchy to the controller Ctrl, subsequently to the state machines CalSTM and MoveSTM. The update and propagation, however, are not atomic. Between these communications, the memories can be accessed and evaluated using the outdated value. This is further demonstrated by communications 5 to 11. Consider a new update of x to -1 (by communication 5) in the memory of MoveSTM, the update and propagation are similar to the previous update (to -2). We here, however, consider the value of x in CalSTM is accessed (by the event get x on communication 8) and evaluated in the guard [x!=0] of the transition in the machine before the new value -1 is propagated to the machine (on communication 9). This means the action of the transition still outputs -2 on the event update!-2, not the -1 because the new value has not been seen in this machine. As a consequence, the input trigger update?l in the machine MoveSTM will receive a value -2 and so x is set to -1 (x=l+1) again, as indicated on communication 11. The updates of x to -1 on communications 5 and 11 correspond to the action x=l+1 (rc.Plus l 1 rc.core int set in our semantics) in the self transition of MoveSTM, which is followed by an output event right!x. The animation, therefore, shows two Right_PatrolMod events on lines #8 and #9.
It is worth mentioning that the RoboChart semantics in this model with the shared variable x has a high degree of nondeterminism because of the interleaving of events between the module, the controller, and the state machines, and eventually nondeterminism due to the hiding of these interleaving events. Our implementation of the semantics reduces nondeterminism in a particular way: the maximal progress assumption (internal events τ have a higher priority) [10]. We also note that the animated behaviour of two Right PatrolMod events for a position is one behaviour of the RoboChart's standard semantics. This has been verified using FDR that this scenario is a trace refinement of the standard semantics (generated in RoboTool). In order for the verification, we encode the scenario in Fig. 13 in a CSP process Scenario1 below and then use FDR to check the assertion satisfied. ¦ ¥ In the assertion, PatrolMod is the CSP process for the module PatrolMod in the generated CSP semantics in RoboTool.
Though semantically allowed, the model does not reflect the optimal way to use shared variables. We could, for example, design models to allow only one state machine to update a shared variable and other state machines to access its value or add additional events (such as start update and end update) to enforce a synchronisation of updates to shared variables. Our patrol robot model here is presented to reveal the subtle semantics of using shared variables.
In Fig. 15, we consider the second scenario where the calibrated position is 1 (in S2). The model behaves as follows: (1) the sixth event (6) is chosen on line #5, denoting the calibrated position is 1 and so the robot is in S2; (2) then the robot moves towards the right side at position 2 (lines #6 and #7); (3) subsequently the robot moves towards the left direction to position 1 (lines #8 and #9); and (4) finally, the robot repeats steps (2) and (3) to patrol between position 1 and position 2. We also verified this scenario is a trace refinement of the standard semantics, shown below.
Starting ITree Simulation...   ¦ ¥ The third scenario, we consider, is shown in Fig. 16 where initially the calibrated position is 3 (in S3) on line #5. The robot starts to move towards the left side to position 2 (on lines #6 and #7) and position 1 (on lines #8 and #9), and then towards the right side back to position 2 (on lines #10 and #11). After that, the behaviour is the same as that in the second scenario in Fig. 15. Similarly, we verified this scenario is a trace refinement of the standard semantics. ¦ ¥ In this example, reset is enabled when x is -1 (on line #2) and 1 (on line #3). This difference is due to the maximal progress assumption in the definition of external choice and hiding in our approach: internal events have priority over external events. In this patrol robot model, the event update is internal and reset is external, so update has priority over reset. When x is not 0, the guard [x!=0] in the self transition of Cal in the machine CalSTM is true, which enables CalSTM to communicate with the machine MoveSTM on update, and then the transition with the trigger reset cannot be taken due to its lower priority than update. The reset, therefore, is only enabled when x is 0.

Related work
Animation is a lightweight formal method. Kazmierczak et al. [24] describe the advantages of using animation to verify models. It is highly automated and cheap to perform. It provides an insight into the specification and its implicit assumptions and is very suitable for demonstrating the system. It is a form of interactive testing of the model and its properties. It requires little expertise: less than model checking and much less than theorem proving. But its biggest drawback is that it cannot prove consistency, correctness, or completeness.
Animation can be tailored to specific application domains. For example, Boichut et al. [25] report on using animation to improve the formal specifications of security protocols. They animate these specifications to draw diagrams of typical executions of the protocols. They use this to visualise protocol termination and understand interleaved execution. They experiment with the animation to detect unwanted side effects. Finally, they use visualisation to simulate intruders to find attacks not detected by other protocol analysis tools.
We use ITrees to implement a framework for the animation of formal specifications. The ProB animator and model checker provides a different framework [15]. ProB contains a model checker and a constraint-based checker, both of which can be used to detect various errors in B specifications. It implements a back-end in a framework for a variety of different specification languages, including the B language, Event-B, CSP-M, TLA+, and Z.
De Souza [26] provides another framework: Joker. This is a tool for producing animators for formal languages. The application is based on general labelled transition systems and provides graphical animation, supporting B, CSP, and Z.
Rosu et al. [27] develop K, 8 a rewriting-based executable semantic framework. The operational semantics of programming languages such as C [28] and Java [29] are proposed based on K. Our ITree-based approach is also an executable semantic framework enabling the definition of operational semantics, but for both abstract specification languages and concrete refinements. And so program development by refinement is supported in our framework. Higher-order logic and nondeterminism are some features of interaction trees, but not for K.
Stateflow is a graphical language integrated in the Simulink of Matlab to model and simulate decision logic using state machines and flow charts. During simulation, transitions in state machines are evaluated, by default, based on the order in which they are created [30]. This is the same as our approach to resolve nondeterministic choice between transitions using the prioritised renaming operator.

Conclusions
This work gives RoboChart an ITree-based operational semantics and enables the animation of Robo-Chart using code generation in Isabelle/HOL. To provide animation support, we extend ITree-based CSP with extra operators and present their definitions. We describe how the semantics of RoboChart is implemented in ITree-based CSP, and illustrate it with an autonomous chemical detector model and a patrol robot model. With the semantics of a RoboChart model in Isabelle, we generate Haskell code and animate it using a simple simulator. We show two concrete scenarios of the chemical detector example and three concrete scenarios of the patrol robot model using animation. The analysis using FDR shows these scenarios are trace refinements of the standard RoboChart CSP semantics, and so our approach gives and animates a refinement of the original models.
This work targets deterministic RoboChart models and also nondeterministic RoboChart models (but nondeterminism is resolved in a priority way in the semantics and so deterministic semantics eventually). Our work covers a large part of RoboChart features (but not all). Our immediate future work is to investigate the support of nondeterminism in the semantics and give semantics to more features such as hierarchical state machines and timed semantics.
In this paper, we manually translate the RoboChart semantics to Isabelle. Particularly, we take Robo-Chart's CSP semantics generated in RoboTool into account to define consistent and also restricted semantics based on an optimised version of the CSP semantics. This practical consideration could entitle us to largely reuse the current CSP semantics generator in RoboTool to automatically generate ITree-based CSP semantics. Then the whole workflow from RoboChart models to Haskell code can be fully automated and our work here brings insights into it. This is part of our future work.
With the RoboChart semantics in ITrees, we can also conduct verification in Isabelle/HOL, in addition to animation in this paper. We will investigate the use of temporal logic as a property language for the verification of ITrees. We note that verification can also capitalise on the contributions of this work.
ITrees can also be extended to other semantic domains. Further work would be of great help in extending ITrees with probability and linking them to discrete-time Markov chains (DTMCs) [31,32], which will allow us to give an ITree-based probabilistic semantics to RoboChart.
Our work has many potential applications in robotics. Further research could investigate the development of verified ROS nodes using code generation here for a concrete implementation of RoboChart controllers. We also could use this approach to automatically generate a sound runtime monitor from RoboChart models to observe the behaviour of systems that are derived from the models.
We use a basic textual animation in this work. This will be improved to directly allow the visualisation of RoboChart models in RoboTool for animation. Eventually, users of RoboTool are able to animate a state machine, or a controller, or a whole model by clicking transitions or events.