Real-Time Behavioral Semantics of DSMLs
7.4 Formal Analysis of Real-Time Domain Specific Models with Maudewith Maude
7.4.1 Initial Considerations
Real-Time Maude (see Section 2.2.3) extends Maude’s rewriting, search, and model check-ing facilities to perform analysis and simulation over real-time systems. Real-Time Maude is designed to take maximum advantage of the high performance of the Maude engine. Most Real-Time Maude analysis commands are therefore executed by first transforming the current timed module into a Maude module, followed by the execution of a corresponding Maude com-mand [95]. In fact, a large majority of Real-Time Maude comcom-mands can be executed directly using the Maude engine. Only a few of them are only available for Real-Time Maude, such as thefind latestandfind earliestcommmands [93]. Since in this thesis we encode
e-Motions rules directly into (Core) Maude, we will make use of the (Core) Maude commands that represent the corresponding equivalent Real-Time Maude commands, following the direc-tions given in [95].
The execution of a specific Real-Time Maude command in (Core) Maude, as well as the tick mode selected by the user, will affect the rewrite rule that we define to model time elapse.
In Sections 7.3.1 and 7.3.7 we presented the default rule that models time elapse. This rule follows the maximal time sampling strategy (see Section 2.2.3), i.e., with this rule time will advance deterministically by the maximum time elapse of the system.
c r l [ tick ] :
{MODEL} in time T
=> {delta ( MODEL , TE ) } in time ( T plus TE ) i f TE : = mte ( MODEL )
/\ TE =/= zero .
However, other tick modes can also be considered. For instance, our e-Motions tool also supports the default tick mode. This tick mode is applied when the user specify a default time elapse for a specific simulation. If the user selects a default time value of, for instance,2time units, the rewrite rule that models time elapse will be defined as follows:
c r l [ tick ] :
{MODEL} in time T
=> {delta ( MODEL , TE ) } in time ( T plus TE ) i f TE : = minT ( mte ( MODEL ) , toRat ( 2 ) ) /\ TE =/= zero .
where theminToperation computes the minimum of two time values.
Note that in this case, time is advanced by the smallest value of the maximum time elapse of the system and the default time elapse value specified by the user.7 The user has to consider that all rewriting will be performed according to the chosen time sampling strategy, which of course impacts search and model checking [95].
Together with the tick mode selected by the user, the execution of a specific Real-Time Maude command in (Core) Maude usually places additional constraints to thetickrule. For instance, thetickrule should not tick the time beyond the time bound specified for any com-mand. These additional constrains will be usually encoded as further rule conditions. For instance, if we specify a time bound of 100 time units, the tick rule will be described as follows (this rule consider maximal tick mode):
c r l [ tick ] :
7ThetoRatoperation invocation is not needed in this case, but it is automatically included by our tool to cover the case on which the user considers dense time and specifies a float number as the default time elapse value.
{MODEL} in time T
=> {delta ( MODEL , TE ) } in time ( T plus TE ) i f TE : = mte ( MODEL )
/\ TE =/= zero
/\ ( T plus TE ) le toRat ( 1 0 0 ) .
where the le operation checks whether the first argument is less or equal than the second one.
In the next subsections, we will present several applications of (Core) Maude’s simulation and analysis commands. In most of these applications we will consider the maximal tick mode (otherwise it will be clearly stated), and we will refer explicitly to the additional constraints imposed on thetick rule by the corresponding Real Time Maude command. Note that these constraints, together with thetickrule, will be automatically generated by the e-Motions tool (see Section 7.5). For simulation purposes, we will use the MPN and RTTP examples. For analysis purposes, we will only use the RTTP example.8
Regarding the RTTP example, we will consider all the rules described in Section 7.2.4.
Regarding the MPN example, we will consider all the rules described in Section 7.2 but the RemoveOffPhonesrule and a) battery consumption will be modeled by the BatteryConsump-tion ongoing rule (see Figure 7.10), and b) the SwitchOn atomic rule (see Figure 7.5) will be turned into a normal (non-soft) rule—we will make phones to be switched on as soon as possible. These considerations have been taken into account to ease the interpretation of the simulation results. Finally, since both examples have a rule to generate the initial configura-tion of the system, the initial model that we will specify in the applicaconfigura-tion of simulaconfigura-tion and analysis commands will be in both cases empty.
op mpnModel : −> @Model . eq mpnModel = @MPNs@ { none } .
op rttpModel : −> @Model . eq rttpModel = @rttp@ { none } .
7.4.2 Simulation
Given a Maude specification as the one described in the previous sections, it can be executed by just successively applying equations and rewrite rules on an initial term. For this purpose, we can make use of Maude’s rewriteand frewriteas done with untimed specification.
8The MPN example is composed of a large number of rules. This issue, together with the high freedom that the system offers (calls do not have a specific duration, they can be performed to any phone at almost any moment of time, etc.), results in a high number of reachable states.
However, in real-time systems it is often more natural to measure and control the rewriting by the total duration of a computation than by the number of rewrites performed. In this section we will show how we can specify a time bound for a simulation.
For instance, let us explore a possible execution for the MPN system in six time units. To specify this time bound, we have to add the following condition to the tick rule: (T plus TE) le toRat(6). This condition will forbid time to elapse beyond six time units. Then, we use therewritecommand as follows:
Maude> r e w r i t e init( mpnModel ) .
The init operation adds to the model the clock and counter objects used by our infras-tructure (see Section 7.3), and the time stamp associated to each real-time state (see Sec-tion 2.2.3.1).
op init : @Model −> ClockedSystem . eq init( MM { OBJSET })
= { MM { < ’ids@ : Counter | value : 0 >
< ’rdm@ : Counter | value : 0 >
< ’clk@ : Clock | time : zero >
OBJSET } } in time zero .
As a result of the rewriting, Maude provides the following term:
{ @MPNs@ {
< ’0 : AtomicActionExec | participants : Set{ ’1 ; ’2 ; ’3 ; ’4 ; ’5 ; ’6 ; ’7} # variables : Set{mt} # startingTime : 0 # endingTime : 0 # action : "InitialModel" # maxTimer : 0 # minTimer : 0 # executionTime : 0 # status : realized >
< ’1 : ObjectRole | actualObject : ’8 # role : "p1">
< ’2 : ObjectRole | actualObject : ’9 # role : "p2">
< ’3 : ObjectRole | actualObject : ’10 # role : "p3">
< ’4 : ObjectRole | actualObject : ’11 # role : "p4">
< ’5 : ObjectRole | actualObject : ’12 # role : "a1">
< ’6 : ObjectRole | actualObject : ’13 # role : "a2">
< ’7 : ObjectRole | actualObject : ’14 # role : "mpn">
< ’8 : Phone | dialedCalls : OrderedSet{mt−ord} # receivedCalls : OrderedSet{mt−ord} # contacts : OrderedSet{ ’10 # ’11 # ’9} # number : 111 # on : true # battery : 94 # coverage : 1 # bps : 1 # vx : 1 # vy : 0 # xPos : 11 # yPos : 45 >
< ’9 : Phone | dialedCalls : OrderedSet{mt−ord} # receivedCalls : OrderedSet{mt−ord} # contacts : OrderedSet{ ’10 # ’11 # ’8} # number : 222 # on : true # battery : 44 # coverage : 1 # bps : 1 # vx : 0 # vy : −1 # xPos : 45 # yPos : 29 >
< ’ 1 0 : Phone | dialedCalls : OrderedSet{mt−ord} # receivedCalls : OrderedSet{mt−ord} # contacts : OrderedSet{ ’11 # ’8 # ’9 } # number : 333 # on : true # battery : 94 # coverage : 1 # bps : 1 # vx : 0 # vy : 1 # xPos : 15 # yPos : 21 >
< ’ 1 1 : Phone | dialedCalls : OrderedSet{mt−ord} # receivedCalls : OrderedSet{mt−ord} # contacts : OrderedSet{ ’10 # ’8 # ’9 } # number : 444 # on : true # battery : 44 # coverage : 2 # bps : 1 # vx : −1 # vy : 0 # xPos : 59 # yPos : 25 >
< ’ 1 2 : Antenna | xPos : 25 # yPos : 35 >
< ’ 1 3 : Antenna | xPos : 55 # yPos : 15 >
< ’ 1 4 : MPN | els : OrderedSet{ ’10 # ’11 # ’12 # ’13 # ’8 # ’9} # xSize : 80 #
ySize : 50 >
< ’ 1 5 : AtomicActionExec | participants : Set{ ’16} # variables : Set{mt} # startingTime : 0 # endingTime : 5 # action : "SwitchOn" # maxTimer : 0 # minTimer : 0 # status : realized >
< ’ 1 6 : ObjectRole | actualObject : ’10 # role : "p">
< ’ 1 7 : OngoingActionExec | participants : Set{ ’18 ; ’19} # variables : Set{mt} # startingTime : 0 # endingTime : 6 # action : "Moving" # maxTimer : null # upperBoundTimer : null >
< ’ 1 8 : ObjectRole | actualObject : ’10 # role : "p">
< ’ 1 9 : ObjectRole | actualObject : ’14 # role : "mpn">
< ’ 2 0 : AtomicActionExec | participants : Set{ ’21} # variables : Set{mt} # startingTime : 0 # endingTime : 5 # action : "SwitchOn" # maxTimer : 0 # minTimer : 0 # status : realized >
< ’ 2 1 : ObjectRole | actualObject : ’11 # role : "p">
< ’ 2 2 : OngoingActionExec | participants : Set{ ’23 ; ’24} # variables : Set{mt} # startingTime : 0 # endingTime : 6 # action : "Moving" # maxTimer : null # upperBoundTimer : null >
< ’ 2 3 : ObjectRole | actualObject : ’11 # role : "p">
< ’ 2 4 : ObjectRole | actualObject : ’14 # role : "mpn">
< ’ 2 5 : AtomicActionExec | participants : Set{ ’26} # variables : Set{mt} # startingTime : 0 # endingTime : 5 # action : "SwitchOn" # maxTimer : 0 # minTimer : 0 # status : realized >
< ’ 2 6 : ObjectRole | actualObject : ’8 # role : "p">
< ’ 2 7 : OngoingActionExec | participants : Set{ ’28 ; ’29} # variables : Set{mt} # startingTime : 0 # endingTime : 6 # action : "Moving" # maxTimer : null # upperBoundTimer : null >
< ’ 2 8 : ObjectRole | actualObject : ’8 # role : "p">
< ’ 2 9 : ObjectRole | actualObject : ’14 # role : "mpn">
< ’ 3 0 : AtomicActionExec | participants : Set{ ’31} # variables : Set{mt} # startingTime : 0 # endingTime : 5 # action : "SwitchOn" # maxTimer : 0 # minTimer : 0 # status : realized >
< ’ 3 1 : ObjectRole | actualObject : ’9 # role : "p">
< ’ 3 2 : OngoingActionExec | participants : Set{ ’33 ; ’34} # variables : Set{mt} # startingTime : 0 # endingTime : 6 # action : "Moving" # maxTimer : null # upperBoundTimer : null >
< ’ 3 3 : ObjectRole | actualObject : ’9 # role : "p">
< ’ 3 4 : ObjectRole | actualObject : ’14 # role : "mpn">
< ’ 3 5 : AtomicActionExec | participants : Set{ ’36 ; ’37} # variables : Set{mt} # startingTime : 5 # endingTime : 6 # action : "Coverage" # maxTimer : 0 # minTimer : 0 # status : realized >
< ’ 3 6 : ObjectRole | actualObject : ’10 # role : "p">
< ’ 3 7 : ObjectRole | actualObject : ’12 # role : "a">
< ’ 3 8 : OngoingActionExec | participants : Set{ ’39} # variables : Set{mt} #
startingTime : 5 # endingTime : 6 # action : "BatteryConsumption" # maxTimer : 95 # upperBoundTimer : null >
< ’ 3 9 : ObjectRole | actualObject : ’10 # role : "p">
< ’ 4 3 : AtomicActionExec | participants : Set{ ’44 ; ’45} # variables : Set{mt} # startingTime : 5 # endingTime : 6 # action : "Coverage" # maxTimer : 0 # minTimer : 0 # status : realized >
< ’ 4 4 : ObjectRole | actualObject : ’11 # role : "p">
< ’ 4 5 : ObjectRole | actualObject : ’13 # role : "a">
< ’ 4 6 : OngoingActionExec | participants : Set{ ’47} # variables : Set{mt} #
startingTime : 5 # endingTime : 6 # action : "BatteryConsumption" # maxTimer : 45 # upperBoundTimer : null >
< ’ 4 7 : ObjectRole | actualObject : ’11 # role : "p">
< ’ 5 1 : AtomicActionExec | participants : Set{ ’52 ; ’53} # variables : Set{mt} # startingTime : 5 # endingTime : 6 # action : "Coverage" # maxTimer : 0 # minTimer : 0 # status : realized >
< ’ 5 2 : ObjectRole | actualObject : ’8 # role : "p">
< ’ 5 3 : ObjectRole | actualObject : ’12 # role : "a">
< ’ 5 4 : OngoingActionExec | participants : Set{ ’55} # variables : Set{mt} #
startingTime : 5 # endingTime : 6 # action : "BatteryConsumption" # maxTimer : 95 # upperBoundTimer : null >
< ’ 5 5 : ObjectRole | actualObject : ’8 # role : "p">
< ’ 5 9 : AtomicActionExec | participants : Set{ ’60 ; ’61} # variables : Set{mt} # startingTime : 5 # endingTime : 6 # action : "Coverage" # maxTimer : 0 # minTimer : 0 # status : realized >
< ’ 6 0 : ObjectRole | actualObject : ’9 # role : "p">
< ’ 6 1 : ObjectRole | actualObject : ’12 # role : "a">
< ’ 6 2 : OngoingActionExec | participants : Set{ ’63} # variables : Set{mt} #
startingTime : 5 # endingTime : 6 # action : "BatteryConsumption" # maxTimer : 45 # upperBoundTimer : null >
< ’ 6 3 : ObjectRole | actualObject : ’9 # role : "p">
< ’ 6 7 : AtomicActionExec | participants : Set{ ’68 ; ’69} # variables : Set{mt} # startingTime : 5 # endingTime : 6 # action : "Coverage" # maxTimer : 0 # minTimer : 0 # status : realized >
< ’ 6 8 : ObjectRole | actualObject : ’9 # role : "p">
< ’ 6 9 : ObjectRole | actualObject : ’13 # role : "a">
< ’ 7 0 : OngoingActionExec | participants : Set{ ’71} # variables : Set{mt} # startingTime : 6 # endingTime : null # action : "BatteryConsumption" # maxTimer : freeze ( ’ 1 0 . battery / ’ 1 0 . bps ) # upperBoundTimer : null >
< ’ 7 1 : ObjectRole | actualObject : ’10 # role : "p">
< ’ 7 2 : OngoingActionExec | participants : Set{ ’73 ; ’74} # variables : Set{mt} # startingTime : 6 # endingTime : null # action : "Moving" # maxTimer : freeze ( null ) # upperBoundTimer : null >
< ’ 7 3 : ObjectRole | actualObject : ’10 # role : "p">
< ’ 7 4 : ObjectRole | actualObject : ’14 # role : "mpn">
< ’ 7 5 : OngoingActionExec | participants : Set{ ’76} # variables : Set{mt} # startingTime : 6 # endingTime : null # action : "BatteryConsumption" # maxTimer : freeze ( ’ 1 1 . battery / ’ 1 1 . bps ) # upperBoundTimer : null >
< ’ 7 6 : ObjectRole | actualObject : ’11 # role : "p">
< ’ 7 7 : OngoingActionExec | participants : Set{ ’78 ; ’79} # variables : Set{mt} # startingTime : 6 # endingTime : null # action : "Moving" # maxTimer : freeze ( null ) # upperBoundTimer : null >
< ’ 7 8 : ObjectRole | actualObject : ’11 # role : "p">
< ’ 7 9 : ObjectRole | actualObject : ’14 # role : "mpn">
< ’ 8 0 : AtomicActionExec | participants : Set{ ’81 ; ’82} # variables : Set{ ’83} #
startingTime : 6 # endingTime : null # action : "Call" # maxTimer : 30 # minTimer : 20 # executionTime : 0 # status : unfinished >
< ’ 8 1 : ObjectRole | actualObject : ’10 # role : "p1">
< ’ 8 2 : ObjectRole | actualObject : ’11 # role : "p2">
< ’ 8 3 : Variable | name : "initTime" # value : 6 >
< ’ 8 4 : OngoingActionExec | participants : Set{ ’85} # variables : Set{mt} # startingTime : 6 # endingTime : null # action : "BatteryConsumption" # maxTimer : freeze ( ’ 8 . battery / ’ 8 . bps ) # upperBoundTimer : null >
< ’ 8 5 : ObjectRole | actualObject : ’8 # role : "p">
< ’ 8 6 : OngoingActionExec | participants : Set{ ’87 ; ’88} # variables : Set{mt} # startingTime : 6 # endingTime : null # action : "Moving" # maxTimer : freeze ( null ) # upperBoundTimer : null >
< ’ 8 7 : ObjectRole | actualObject : ’8 # role : "p">
< ’ 8 8 : ObjectRole | actualObject : ’14 # role : "mpn">
< ’ 8 9 : OngoingActionExec | participants : Set{ ’90} # variables : Set{mt} # startingTime : 6 # endingTime : null # action : "BatteryConsumption" # maxTimer : freeze ( ’ 9 . battery / ’ 9 . bps ) # upperBoundTimer : null >
< ’ 9 0 : ObjectRole | actualObject : ’9 # role : "p">
< ’ 9 1 : OngoingActionExec | participants : Set{ ’92 ; ’93} # variables : Set{mt} # startingTime : 6 # endingTime : null # action : "Moving" # maxTimer : freeze ( null ) # upperBoundTimer : null >
< ’ 9 2 : ObjectRole | actualObject : ’9 # role : "p">
< ’ 9 3 : ObjectRole | actualObject : ’14 # role : "mpn">
< ’ 9 4 : AtomicActionExec | participants : Set{ ’95 ; ’96} # variables : Set{ ’97} # startingTime : 6 # endingTime : null # action : "Call" # maxTimer : 30 # minTimer : 20 # executionTime : 0 # status : unfinished >
< ’ 9 5 : ObjectRole | actualObject : ’8 # role : "p1">
The resulting term includes the model objects of our MPN example (see objects whose iden-tifiers go from’8to’14) as well as the objects included by our e-Motions infrastructure (see the remaining objects). All performed ongoing and atomic actions are captured by their corre-spondingAtomicActionExecandOngoingActionExecobjects, respectively. Actions that have been triggered but not finalized are also captured (see those atomic and ongoing action executions whose endingTime is set tonull). We can see by having a look at the’ids@
counter object that 98 objects have been created. However, not all of them will be found in the final result: ongoing action execution elements that represent consecutive executions of the same ongoing action with the same set of participants are combined (see Section 7.3.5.2). In six time units, all model objects have been created (by theInitialModelaction), the four phones have been switched on, and their coverage and position have been updated. Furthermore, two calls have started (see atomic action executions’80and’94) but not finished.
More interesting is the result given by simulating the system for 100 time units. This result can be obtained following the same procedure: firstly, we add a condition to thetickrule ((T plus TE) le toRat(100)), and secondly, we use therewritecommand as follows:
Maude> r e w r i t e init( mpnModel ) .
In this case, Maude provides the following result:
{ @MPNs@ {
< ’8 : Phone | coverage : 0 # bps : 1 # vx : −1 # vy : 0 # xPos : 55 # yPos : 45 # dialedCalls : OrderedSet{ ’309 # ’536} # receivedCalls : OrderedSet{mt−ord} # contacts : OrderedSet{ ’9 # ’11 # ’10} # number : 111 # on : false # battery : 0 >
< ’9 : Phone | coverage : 2 # bps : 1 # vx : 0 # vy : −1 # xPos : 45 # yPos : 35 # dialedCalls : OrderedSet{mt−ord} # receivedCalls : OrderedSet{ ’310 # ’537} # contacts : OrderedSet{ ’10 # ’8 # ’11} # number : 222 # on : false # battery : 0 >
< ’ 1 0 : Phone | coverage : 0 # bps : 1 # vx : 0 # vy : 1 # xPos : 15 # yPos : 15 # dialedCalls : OrderedSet{ ’296 # ’523 # ’561} # receivedCalls : OrderedSet{mt−ord} # contacts : OrderedSet{ ’8 # ’9 # ’11 } # number : 333 # on : false # battery : 0 >
< ’ 1 1 : Phone | coverage : 2 # bps : 1 # vx : 1 # vy : 0 # xPos : 35 # yPos : 25 # dialedCalls : OrderedSet{mt−ord} # receivedCalls : OrderedSet{ ’297 # ’524 # ’562} # contacts : OrderedSet{ ’9 # ’8 # ’10 } # number : 444 # on : false # battery : 0 >
We only show the model objects of our MPN example for readability reasons. In 100 time units, all phones are off (they all have run out from battery), phone’8has performed two calls to phone ’9, and phone ’10 has performed three calls to phone ’11. All calls have had a duration of twenty time units except the last one, which was performed from phone ’10 to phone ’11 after 46 time units of simulation, and had a duration of four time units. Since phone ’11 had only50 battery units when it was created, we can see that the call has been interrupted by theBatteryOffCalleerule, i.e., the callee ran out out battery after four time units participating in the call.
Let us now explore a possible execution for the RTTP system in 500 time units. Again, we add the corresponding tick rule condition (in this case(T plus TE) le toRat(500)), and we use therewritecommand as follows:
Maude> r e w r i t e init( rttpModel ) .
The result of the simulation is the following Maude term:
{ @rttp@ {
< ’6 : Node | receivedMessages : Sequence{ ’21 # ’45 # ’69 # ’93 # ’117} # localClock : ’ 8 # neighbors : Set{ ’7} >
< ’7 : Node | receivedMessages : Sequence{mt−ord} # localClock : ’9 # neighbors : Set{mt} >
As expected, we can see that five rounds of the protocol has been successfully realized. Node
’6has been the initiator, while node’7has been the responder (they correspond to then1and n2nodes depicted in Figure 7.24, respectively). In this case, all the RTT values are of40time units. Recall that classes, attributes and references are qualified with their containers’ names (although not shown here for readability reasons), and therefore clocks defined for the RTTP example (of classClock@rttp) will not be confused with the clock instance provided by our infrastructure (of classClock@MGBehavior).
Finally, we can also simulate a system with no time limit by simply not adding a time bound constraint to the the tickrule. In both of our examples, this will result in a non terminating execution. The reason is that we have a periodic action without a defined time upper bound:
theCoverage (in the MPN system) and theRequest(in the RTTP system) rules will be tried to be triggered every5and100time units, respectively. If we do not want to add a time bound for the simulation, we can define a time upper bound for these periodic rules, or we can specify an upper bound for the number of rule applications in therewriteorfrewritecommands as we have done for untimed specifications.
7.4.2.1 Querying the Result of a Simulation
As previously mentioned, the result of a simulation includes the model objects of the DSML, and the objects included by our e-Motions infrastructure, such as the objects that represent the performed actions. This result gives us a lot of useful information about the simulation, which can be further analyzed to reason about the behavior of the system. However, the way in which this information is presented (as a term of sort @Model) makes it hard for users to analyze
it. To mitigate this, our infrastructure provides then several operations to query the result of a simulation, and to present it in a more readable way. The complete list of these operations can be found in Appendix D.
For instance, the finalizedActions operation returns information on the actions that have been triggered and finalized (either realized, interrupted, or aborted); thecurrentActions operation returns information on the actions that have been triggered but not finalized. Assum-ing that we have stored the result of the simulation of the MPN system in six time units in a Maude constant namedresultMPNIn6, the result of the command:
Maude> r e d u c e currentActions( resultMPNIn6 ) .
is the following:
("BatteryConsumption" started at 6 with ’ 1 0 ) ("Moving" started at 6 with ( ’ 1 0 ; ’ 1 4 ) ) ("BatteryConsumption" started at 6 with ’ 1 1 ) ("Moving" started at 6 with ( ’ 1 1 ; ’ 1 4 ) ) ("Call" started at 6 with ( ’ 1 0 ; ’ 1 1 ) ) ("BatteryConsumption" started at 6 with ’ 8 ) ("Moving" started at 6 with ( ’ 1 4 ; ’ 8 ) ) ("BatteryConsumption" started at 6 with ’ 9 ) ("Moving" started at 6 with ( ’ 1 4 ; ’ 9 ) ) ("Call" started at 6 with ( ’ 8 ; ’ 9 ) )
The result is a list of elements composed of the name of the action, the time at which the action was triggered, and the set of the identifiers of the participant elements.
In a similar way, if we type:
Maude> r e d u c e finalizedActions( resultMPNIn6 ) .
we obtain a list with the finalized actions of the system:
("InitialModel" performed in[ 0 , 0 ] with ( ’ 1 0 ; ’ 1 1 ; ’ 1 2 ; ’ 1 3 ; ’ 1 4 ; ’ 8 ; ’ 9 ) ) ("BatteryConsumption" performed in[ 5 , 6 ] with ’ 1 1 ) ("Coverage" performed in[ 5 , 6 ] with ( ’ 1 2 ; ’ 8 ) ) ("BatteryConsumption" performed in[ 5 , 6 ] with ’ 8 ) ("Coverage" performed in[ 5 , 6 ] with ( ’ 1 2 ; ’ 9 ) ) ("BatteryConsumption" performed in[ 5 , 6 ] with ’ 9 )
("Coverage" performed in[ 5 , 6 ] with ( ’ 1 3 ; ’ 9 ) )
The elements of this list also include the time at which the action was finalized. By carefully observing this list, we realize that the Coverage rule has been applied for phone ’9(whose number is222) twice at the same moment of time5. The reason is that after five time units the phone is at the same Manhattan distance from both antennas, and therefore the rule is applied once per each antenna. Notice that this behavior is perfectly valid. However, if we would want to avoid this kind of situations, we could, e.g., include another NAC pattern in the Coverage rule that forbids (by means of an action execution element) the application of the rule it is already being applied to the same phonep.
7.4.3 Reachability Analysis
The Maude search command allows us to explore (following a breadth-first strategy) the reachable state space in different ways. In Section 6.2.2, we showed how this command may be parameterized by an upper bound on the number of solutions to look for. We also showed how it can be bounded by a maximum number of rule applications. In this section, we will show how thesearchcommand can be used to look for states which are reachable in a certain time interval (starting from the initial state).
As a first example, let us check that the local clocks of the RTTP example are always synchronized. Since we know that the Request periodic rule will be tried to be triggered every 100 time units (i.e., the number of states reachable from the initial state is infinite), we want to bound the search to 500 time units. Following the same procedure applied in the previous subsection, we will add the following condition to thetickrule: (T plus TE) le toRat(500). Then, we will look for a state that does not satisfy the invariant, i.e., we will look for a state on which two clocks have a different time value. If no solution is found, we are guaranteed that (starting from the initial model) clocks will always be synchronized. Given variables O1andO2 of sort Oid, CT1 and CT2 of sort Int, OBJSETof sort Set{@Object}, andTof sortTime, we can look for the undesired state by issuing the following command:
Maude> s e a r c h init( rttpModel ) =>∗
{ @rttp@ { < O1 : Clock | time : CT1 >
< O2 : Clock | time : CT2 >
OBJSET }} in time T such that CT1 = / = CT2 .
No solution.
No solution.