• No results found

3.4 The PRISM Language

3.4.1 Fundamentals

The two basic elements of the PRISM language are modules and variables. A model is defined as the parallel composition of several interacting modules. Each module has a set of integer-valued, local variables with finite range. We will often refer to these as PRISM variables. The local state of a module at a particular time is given by a valuation of its local variables. A global state of the whole model is a valuation of the variables for all modules.

A module makes a transition from one local state to another by changing the value of its local variables. A transition of the whole model from one global state to another comprises transitions for one or more of its component modules. This can either be asyn- chronous, where a single module makes a transition independently, the others remaining in their current state, or synchronous, where two or more modules make a transition simultaneously.

The behaviour of each module, i.e. the transitions it can make in any given state, are defined by a set of commands. Each command consists of a guard, which identifies a subset of the global state space, and one or more updates, each of which corresponds to a possible transition of the module. Intuitively, if the model is in a state satisfying the guard of a command then the module can make the transitions defined by the updates of that command. The probability that each transition will be taken is also specified by the command. The precise nature of this information depends on the type of model being described. This will be clarified in the following sections through a number of small examples.

dtmc module M v : [0..3] init 0; [] (v = 0) → (v0 = 1); [] (v = 1) → 0.5 : (v0= 0) + 0.3 : (v0= 2) + 0.2 : (v0= 3); [] (v = 2) → (v0 = 2); [] (v = 3) → (v0 = 3); endmodule

Figure 3.9: The PRISM language: Example 1

3.4.2

Example 1

As a first example, we consider a description of the 4 state DTMC from Figure 3.3. This is shown in Figure 3.9. The first line identifies the model type, in this case a DTMC. The remaining lines define the modules which make up the model. For this simple example, only a single module M is required.

The first part of a module definition gives its set of local variables, identifying the name, range and initial value of each one. In this case, we have a single variable v with range [0..3] and initial value 0. Hence, the local state space of module M , and indeed the global state space of the whole DTMC, is {0, 1, 2, 3}.

The second part of a module definition gives its set of commands. Each one takes the form “ [] g → u ; ”, where g is the guard and u lists one or more updates. A guard is a predicate over all the variables of the model (in this case, just v). Since each state of the model is associated with a valuation of these variables, a guard defines a subset of the model’s state space. The updates specify transitions that the module can make. These are expressed in terms of how the values of the local variables would change if the

transition occurred. In our notation, v0 denotes the updated value of v, so “ v0 = 1 ”

implies simply that v’s value will change to 1.

Since the model is a DTMC, where more than one possible transition is listed, the likelihood of each being taken is given by a discrete probability distribution. The second command of M shows an example of this. There is a clear correspondence between this probability distribution and the one in state 1 of the DTMC in Figure 3.3. When there is only a single possible transition, we assume an implicit probability distribution which selects this transition with probability 1. This information can be omitted from the description, as is done in the first, third and fourth commands of M . Note that, in order to ensure that the model described is a DTMC, we require that the guards of the module are disjoint.

mdp module M1 v1: [0..10] init 0; [] (v1= 0) → (v10 = 1); [] (v1≥ 1) ∧ (v1≤ 9) → 0.5 : (v10 = v1− 1) + 0.5 : (v01= v1+ 1); [] (v1= 10) ∧ (v2≤ 5) → (v10 = 10); [] (v1= 10) ∧ (v2> 5) → (v10 = 9); endmodule module M2 v2: [0..10] init 0; [] (v2= 0) → (v20 = 1); [] (v2≥ 1) ∧ (v2≤ 9) → 0.5 : (v20 = v2− 1) + 0.5 : (v02= v2+ 1); [] (v2= 10) ∧ (v1≤ 5) → (v20 = 10); [] (v2= 10) ∧ (v1> 5) → (v20 = 9); endmodule

Figure 3.10: The PRISM language: Example 2

Since this DTMC is the one which we used for our PCTL model checking example in Section 3.3.1, we take this opportunity to illustrate how PCTL (and CSL) formulas are specified in PRISM. The only important issue to consider is how atomic propositions, the basic building blocks of the formulas, are expressed. The approach we take is to write them as predicates over PRISM variables. For example, in Section 3.3.1, we illustrated

model checking of the PCTL formula P≥0.5[¬ b U a]. Since a is satisfied only in state 2

and b only in state 3, the formula becomes P≥0.5[¬ (v = 3) U (v = 2)].

This small example is slightly misleading since it gives the impression that, to include an atomic proposition in a formula, we have to determine all the states satisfying it and then encode them as a predicate over PRISM variables. In more realistic examples, however, atomic propositions are used to label states with some property of interest. Since it is the PRISM variables themselves which determine the ‘meaning’ of a state, it is intuitive to describe atomic propositions in this way.

3.4.3

Example 2

Our second example, shown in Figure 3.10, describes an MDP. This is a slightly larger model than Example 1 and illustrates some additional features of the PRISM language, in particular demonstrating how several modules can be composed in parallel.

variable, v1 and v2, respectively. The basic layout of the definition for each module is as

described in Example 1. There are a few further points to note. Firstly, the commands here are more complex: we have used additional operators such as ≤, ≥ and ∧ in the guards; and the updates contain arithmetic expressions such as “ v10 = v1−1 ”. Essentially,

though, they both function exactly as before.

Secondly, the examples demonstrate that the guard of a command in one module can

reference variables from another module. Note, for example, the presence of variable v2,

belonging to module M2, in the third and fourth commands of module M1. This applies

only to guards, not updates: a module can only specify how its own local variables can change. Intuitively, this means that a module can read any variable in the model when deciding what transition to perform next, but can only update its own local variables when making the transition.

The complete model is constructed as the parallel composition of its component mod- ules. The state space of the model is the product of the modules’ state spaces. In this example, the state space of both M1 and M2 is {0, . . . , 10} so the global state space of the

model is {0, . . . , 10} × {0, . . . , 10}. By default, the parallel composition is asynchronous, meaning that each transition of the composed model corresponds to an independent tran- sition of a single module.

We assume that, in each global state of the model, some form of scheduling takes place to decide which module actually makes a transition. For MDPs, the scheduling is nondeterministic. The transitions which an individual module can make in each state of the model are defined by the description of that module. Note that, as in Example 1, there may be more than one possible transition available and, where this is the case, the module defines the probability that each is taken. Hence, each state of the resulting MDP comprises a nondeterministic choice between several probability distributions.

We clarify this using the example. Consider state (0, 1) of the model, i.e. the state

where v1 = 0 and v2 = 1. If module M1 were scheduled, v1 would change to 1 with

probability 1. If module M2 were scheduled, v2 would change to either 0 or 2 with equal

probability 0.5. Hence, in state (0, 1) of the MDP, we have a nondeterministic choice between a probability distribution which selects state (1, 1) with probability 1 or one which selects states (0, 0) and (0, 2) with equal probability 0.5.

In an MDP, scheduling due to parallel composition is not the only possible source of nondeterminism. We also allow local nondeterminism, where an individual module can choose between several transitions. Such behaviour is specified through multiple commands which have the overlapping guards. Returning to our example, let us assume

that module M1 had an additional command “[] (v1 = 0) → (v10 = 2);”. Then, the

ctmc module Mq vq: [0..50] init 0; [] (vq < 50) → 5 : (v0q = vq+ 1); [serve] (vq > 0) → 1 : (v0q = vq− 1); endmodule module Ms vs: [0..1] init 0; [serve] (vs= 0) → 20 : (vs0 = 1); [] (vs= 1) → 7 : (v0s= 0); endmodule

Figure 3.11: The PRISM language: Example 3

to the two probability distributions described in the previous paragraph, a probability distribution which selects state (2, 1) with probability 1.

Parallel composition of several PRISM modules is also applicable to DTMCs and CTMCs. We deal with the case for CTMCs in the next section. For DTMCs, we assume that the scheduling between modules is probabilistic and that each one is equally likely to be scheduled. This is not a particularly useful model of concurrency, but is included for completeness. In practice, DTMC models typically comprise either only a single module or several modules which are fully synchronised (i.e. move in lock-step).