Keywords

1 Introduction and Related Work

Collective Adaptive Systems (CAS) consist of a large number of entities with decentralised control and varying degrees of complex autonomous behaviour. CAS are at the core of the envisioned smart cities of the future and encompass systems like smart urban transport and smart grids. The pervasive nature of CAS and thus their impact on society requires the development of reliable rigorous design models as well as a priori analysis techniques of such models—covering all relevant aspects of their behaviour, including quantitative and emergent ones—before they are put into operationFootnote 1.

Model-checking has been widely recognised as a powerful approach to the automatic verification of concurrent and distributed systems. It consists of an efficient procedure that, given an abstract model of the system, decides whether the model satisfies a logical formula, typically drawn from a temporal logic. Unfortunately, traditional model-checking suffers from the so called state-space explosion problem which hampers scalability of the approach. In particular, its application to very large models, like those typical of CAS, is infeasible. In [15, 17] Latella et al. presented a scalable mean-field model-checking procedure for verifying bounded PCTL (Probabilistic Computation Tree Logic) [11] properties of selected individuals in the context of systems consisting of a large number of similar, but independent, interacting objects; a limited form of global system properties can be treated as well. The procedure can be used with huge population sizes, as typical of analysis techniques based on mean-field approximation; the average behaviour of the population is approximated using a population Discrete Time Markov Chain (DTMC) convergence result [21] and is used for representing the context in which the selected individuals operate (see [15, 17, 21] for details). The model-checking procedure is implemented in the tool FlyFast as an instantiation of a probabilistic on-the-fly model-checker; the latter is parametric on (the semantic model of) the modelling language [15, 16].

FlyFast comes with simple modelling language. An agentFootnote 2 is a finite state process, a generic state C of which is specified by a state defining equation like \( C\ {:}\!\!= a_1.C_1+ \ldots + a_r.C_r. \) Intuitively, the above notation defines state C of the agent and postulates that there are r outgoing transitions from C, with action \(a_j\) labelling a transition going from C to \(C_j\). A probability value is assigned to each action a by means of a probability function definition \(a\ {:}{:}\ E\), where the actual probability is given by the value of expression E in the current occupancy measure vector \({\mathbf m}\). Assume a system is composed of N instances of the agent and that the states of the agent are \(C_1, \ldots C_S\). The occupancy measure vector at the current time is the vector \((m_1,\ldots ,m_S)\) s.t. \(m_j\) yields the fraction of agents currently in state \(C_j\) over the total number N of agents. A system specification is a triple composed by an agent specification—given as a set of state defining equations—a set of probability function definitions, and an initial global state. Finally, FlyFast provides the user with formula declarations which allow for the interpretation of bounded PCTL atomic propositions in the model at hand. The computational model is clock-synchronous; at each step each agent must perform an independent step (which may be an idle self-loop) so that the global state probabilities are given as the product of agent step probabilities, and a new occupancy measure vector can be computed. The global system behaviour is thus a DTMC as well as the stochastic process given by the occupancy measure vector. Notably, for N sufficiently large, the latter can be approximated deterministically, i.e. by a function of time. This brings to a dramatic decrease in size of the global state space: at each step, the total number of potential next states drops from \(S^N\) to S, which makes bounded PCTL model-checking of very large population systems possible (the interested reader is referred to [15, 17, 21] for details).

Recently, modelling and programming languages have been proposed specifically for autonomic computing systems and CAS [3, 9, 12]. Typically, in such frameworks, a system is composed of a set of independent components where a component is a process equipped with a set of attributes describing features of the component. A classical example of attribute is the component location. An additional environment is often used for the specification of common or global features. The attributes of a component can be updated during its execution so that the association between attribute names and attribute values is mantained in the dynamic store of the component. Attributes can be used in predicates appearing in language constructs for component interaction. For instance a component may broadcast a message to all those components satisfying a given predicate; similarly a component may wait for a message from any of those components satisfying a given predicate.

In the present paper, we propose an extension of the FlyFast front-end modelling language for dealing with components and predicate-based interaction. The extension has been inspired by Carma [3]. Components are expressed as pairs process-store; actions are predicate based multi-cast output and input primitivesFootnote 3. Associated to each action there is also an (atomic) probabilistic store-update. For instance, assume components have an attribute named \(\mathsf {loc}\) which takes values in the set of points of a space type. The following action models a multi-cast via channel \(\alpha \) to all components in the same location as the sender, making it change location randomly: \(\alpha ^*[\mathsf {loc}=\mathbf {my}.\mathsf {loc}]{\langle \rangle }\{\mathsf {loc}\leftarrow \mathsf {randomLoc}(\mathsf {loc})\}\). Here \(\mathsf {randomLoc}\) is assumed to be a random generator of points in the spaceFootnote 4. The computational model is clock-synchronous as well, but at the component level. In addition, each component is equipped with a local outbox. The effect of an output action \(\alpha ^*[\pi _r]{\langle \rangle }\sigma \) is to deliver output label \(\alpha {\langle \rangle }\) to the local outbox, together with the predicate \(\pi _r\), which receiver components will be required to satisfy, as well as the current store \(\gamma \) of the component executing the action; the current store is updated according to update \(\sigma \). Note that output actions are non-blocking and that successive output actions of the same component rewrite its outbox. An input action \(\alpha ^*[\pi _s]()\sigma \) by a component will be executed with a probability which is proportional to the fraction of all those components whose outboxes currently contain the label \(\alpha {\langle \rangle }\), a predicate \(\pi _r\) which is satisfied by the component, and a store \(\gamma \) which satisfies in turn predicate \(\pi _s\). If such a fraction is zero, then the input action will not take place (input is blocking), otherwise the action takes place, the store of the component is updated via \(\sigma \), and its outbox cleared. Thus, as in the original FlyFast language, component interaction is probabilistic, but now the fraction of the components satisfying the relevant predicates plays a role in the computation of transition probabilities. We provide the formal probabilistic semantics of the extended language and a translation to the original FlyFast language which makes the model-checker support the extended language. The translation is proved correct.

Related Work. As we mentioned before, this work has been inspired by Carma [3], which in turn shares features with SCEL [9]. There are several aspects of either languages that are not present in our proposal. The main reason for the absence of most of them is the fact that this work is intended as a proof of concept rather than the realisation of a ready-to-use tool for reasoning about CAS. So we aim at keeping the language minimal and focussing only on attribute-based interaction in the context of stochastic and mean-field semantics and model-checking. A feature of Carma not considered here is the notion of global environment, since it represents a singularity point that does not fit well with limit approximation techniques. Finally, we point out that the stochastic semantics of Carma are based on time inhomogeneous CTMCs, due to the fact that action parameters may be time dependent, while we use DTMCs as semantic basis. The notion of the outbox is reminiscent of the notion of the ether in PALOMA [10] in the sense that the collection of all outboxes together can be though of as a kind of ether; but such a collection is intrinsically distributed among the components so that it cannot represent a bottleneck in the execution of the system neither a singularity point in the deterministic approximation. Fluid model-checking for continuous time systems is addressed in [4] where a global model-checking procedure for the Continuous Stochastic Logic (CSL, [2]) is given, which is based on continuous limit approximated semantics. Fluid semantics have proved very useful for reasoning about large coordination systems (see e.g. [6, 18, 23]). Predicate-/attribute-based inter-process communication has been originally proposed in [19] where several variants of predicate-/attribute-based communication primitives—including blocking / non-blocking, bounded / unbounded—are discussed in the context of a study on high-level language constructs for distributed systems with decentralised control (see for instance [22]). The notion of predicate-/attribute-based interaction is central in the definition of SCEL [9] where its synchronous-communication variant has been given formal semantics. Asynchronous-communication variants have been defined for stochastic versions of SCEL [20]. An attribute-interaction based calculus is proposed in [1] where broadcast communication links among components are dynamically established on the basis of the interdependences determined by predicates over attributes. A reduction semantics approach is adopted where each transition involves the group composed of both sender and receivers. Attribute \(\pi \)-Calculus has been proposed in [14] and extended to Imperative \(\pi \)-Calculus in [13]; in both calculi, which inherit the classical point-to-point communication paradigm of the \(\pi \)-Calculus, as opposed to multi-cast, attributes are related to messages rather than to processes. None of the above mentioned works on predicate-/attribute-based languages addresses mean-field approximated model-checking so, to the best of our knowledge, the present paper is the first proposal on the subject.

2 Attribute-Based Coordination Language and Logic

In this section we define an attribute-based population description language and related logic. A system is defined as a population of N identical interacting componentsFootnote 5 in a clock-synchronous fashion. Each component is equipped with a finite set of attributes; the current store \(\gamma \in \varGamma \) of the component maps each attribute name to an attribute value.

2.1 Syntax

A component specification is a pair \((\varDelta ,F)\) where \(\varDelta \) is a finite set of state-defining equations, one for each state of the component and F is a set of auxiliary function definitionsFootnote 6. We let \(\mathcal{{S}}_{}\), ranged over by \(C,C', C_1, \ldots \) denote the (denumerable, non-empty) set of all states which can be used in equations. Each equation defines the transitions from the state to other states of the component; each transition is labelled by the action the component performs when the transition takes place. The general format of a state defining equation is: \(C\ {:}\!\!= [g_1]P_1 + \ldots + [g_r]P_r\) where each guard [g] is a predicate \(\pi \) defined according to the following grammar: \( \pi \ {:}{:}\!\!= \top \; |\; \bot \; |\; e_1 \, \underline{\bowtie } \, e_2 \; |\; \lnot \pi \; |\; \pi _1 \;\;\wedge \;\;\pi _2 \).

\(\top \) (\(\bot \), resp.) stands for the truth value true (false resp.), while \(\underline{\bowtie }\, \in \{\ge ,>,\le ,<\}\); we let \(\bowtie \, \in \{>,<\}\). An expression e can be an attribute name a, or \(\mathbf {my}.a\) referring to the value of a in the component where it occurs, or a value v in given set \(\mathcal{{V}}\). In defining equations as above, we abbreviate \([\top ]P_j\) with \(P_j\) and we omit summands of the form \([\bot ]P_j\). Each \(P_j\) in a state defining equation as above is of the form \(p_j\ {:}{:}\ act_j.C_j\), where \(p_j\) is a probability expression, i.e. an expression with value in [0, 1], built from constants \(v \in [0,1]\) and the special operator \(\textsf {frc}\,C\), combined using standard arithmetic operators; for state C, \(\textsf {frc}\,C\) returns the fraction of the components that are currently in state C, over the total of N components. Clearly, the use of the \(\textsf {frc}\,\) operator allows action (and, ultimately, transition) probability to depend on the global state of the system. Actions \(act_j\) can be output actions \(\alpha ^*[\pi ]{\langle \rangle }\sigma \) or input actions \(\alpha ^*[\pi ]()\sigma \). We assume a countable set of action types \({\mathcal{{A}}}_{}\), with \(\alpha \in {\mathcal{{A}}}_{}\). The effect of an output action \(\alpha ^*[\pi ]{\langle \rangle }\sigma \) is a broadcast to all those components satisfying predicate \(\pi \) and which are willing to accept the interaction. This is achieved by means of delivering \(\alpha {\langle \rangle }\), together with some additional information, to the outbox of the component executing the action, as we will discuss in detail in Sect. 2.2. In addition, the store of the component executing the action is updated according to the update \(\sigma \), which is a function from \(\varGamma \) to the class of probability distributions over \(\varGamma \)—i.e., in the general case, the update may be probabilistic. Similarly, an input action \(\alpha ^*[\pi ]()\sigma \) is used to receive an \(\alpha \)-message sent by a component satisfying predicate \(\pi \). More specifically, the probability of executing the input action will be proportional to the fraction of components which have sent the \(\alpha \)-message while satisfying predicate \(\pi \) and requiring a predicate which is satisfied by the component executing the input action. Also input actions are provided with a store update \(\sigma \) whereas the component outbox is cleared as (a side) effect of their execution. In the sequel, we shall call address predicates the predicates \([\pi ]\) used for identifying the partners in input/output actions. For updates, we use the following notation: \( \{a_1 \leftarrow e_1^{\gamma }, \ldots , a_t \leftarrow e_t^{\gamma }\} \) where \(e_j^{\gamma }\) is an expression which may also include functions—the definition of which are to be provided in F—which may depend on the component store \(\gamma \) and produce random results, as we shall see below. Attributes different from \(a_1, \ldots , a_t\) are left unchanged by the update. We require that any attribute name a occurring in a guard [g], or in the expressions \(e_1^{\gamma }, \ldots , e_t^{\gamma }\), must appear in the form \(\mathbf {my}.a\) (thus referring to the value of the attribute in the local store of the component). An attribute name a may appear both with and without the \(\mathbf {my}.\) prefix in the address predicate \(\pi \). Intuitively, equation \(C\ {:}\!\!= [g_1]P_1 + \ldots + [g_r]P_r\) defines state C of the component at hand and postulates that there are r potential outgoing transitions from C, with action \(act_j\) labelling a transition going from C to \(C_j\). The actual transitions will be determined by the value of the guards and the action probabilities. Note that it may happen that the current cumulative probability value of the enabled transitions is less than 1; for this reason, the language provides the construct \(\mathbf {rest}\ {:}{:}\ \alpha [\pi ]{\langle \rangle }\sigma .C\), where \(\mathbf {rest}\) is defined as the residual probability; it is required that there is at most one \(\mathbf {rest}\)-branch (typically the last one) in every state defining equation. Only output actions are allowed in \(\mathbf {rest}\)-branches; this ensures that the residual probability is not affected by the fraction of those components in the system satisfying the address predicate. Obviously, in a given component specification there is exactly one defining equation for each state of the component. We let \(\mathcal{{S}}_{\varDelta }\) denote the finite set of states defined by \(\varDelta \). Similarly, \(\varGamma _{\varDelta }\), \({\mathcal{{A}}}_{\varDelta }\) and \(\varPi _{\varDelta }\) denote the set of all stores associated to \(\varDelta \), the action types and the predicates occurring in (the equations of) \(\varDelta \). Finally, we let \(\mathcal{{V}}_{\varDelta }\) denote the set of values which can be taken by the attributes of a component specified by \(\varDelta \). Note that we assume \(\mathcal{{V}}_{\varDelta }\) is a finite set—thus also \(\varGamma _{\varDelta }\) is finite; model finiteness is a common assumption for modelling languages supported by automatic analysis and verification tools.

Example 1

(A spatially distributed Computer Epidemic Model). We enrich the Computer Epidemic Model of [5], SEIR, with infection communication and a bi-dimen-sional Regular GRID [7] model for space, where for each point \(\ell \) the following specific operators are defined, with the usual North, South, East, West meaning: \(\mathsf {N}(\ell ), \mathsf {S}(\ell )\), \(\mathsf {E}(\ell ), \mathsf {W}(\ell )\). Each component is equipped with a position attribute, named \(\mathsf {loc}\), which is always yielding the current position (i.e. point) in space of the component and is the only attribute of the component. Note that, given the abstract nature of the bi-dimensional Regular GRID, such a “point” could be a physical point is space, but also a specific region (or patch) in a patched representation of space. We will implicitly refer to the second interpretation in the sequel. In the model, given in Fig. 1, the purpose of auxiliary function \(\texttt {Jump}\) is twofold: (i) it defines a function from positions to discrete probability distributions which, given position \(\ell \), characterizes a probability distribution which assignes probability \(p_{\mathsf {N}}(\ell )\) to \(\mathsf {N}(\ell )\), probability \(p_{\mathsf {S}}(\ell )\) to \(\mathsf {S}(\ell )\), and so on and (ii) defines a random position generator which, given position \(\ell \), randomly returns a new position according to the specified probabilities. Note that the probabilities are themselves functions of the position and they are assumed being declared as additional auxiliary functions. In the equation for \(\texttt {S}\) in Fig. 1, probability constants \(h, m_N,\ldots ,m_W\) are factors in [0, 1] with cumulative value at most 1, each to be multiplied by the actual probability of the associated (input) action. The latter will be computed as the fraction of the local states which satisfy the required predicate. The resulting values, when taken all together, will characterize a probability sub-distribution; the residual probability will be associated to a \(\mathbf {rest}\)-self-loop. Similar considerations apply to the probability constants in the definition of other states (e.g. i in the figure). We assume \(h > m_N \approx m_S \approx m_E \approx m_W\). In other words, an agent has higher probability to get the infection from agents in the same place than from agents in adjacent places; the probability drops to zero in all other cases. \(\bullet \)

Fig. 1.
figure 1

A four state model: susceptible (S), exposed (E), infected (I), and recover (R).

A system is modelled as a population of N instances of a component, so a system specification \(\Upsilon \) is a triple \((\varDelta , F, \varvec{\varSigma _0})^{(N)}\) where \((\varDelta ,F)\) is a component specification and \(\varvec{\varSigma _0}\) is the initial (system) global state, which will be discussed below. In the sequel we will often write \(\varDelta \) instead of \((\varDelta ,F)\).

2.2 Probabilistic Semantics

In order to model component interactions within a system, each component is equipped with a local outbox. The idea is that, whenever a component executes an output action, the related output will be available in the component’s outbox only during the next clock tick; in the next state, (other) components will be able to get the message by means of corresponding input actions. After such a tick, the outbox will be empty or filled with the information generated by a subsequent output action of the component. Formally, let \(\varLambda _{\varDelta }^{O}\) be the set \( \varLambda _{\varDelta }^{O} = \{\alpha {\langle \rangle } | \alpha \in {\mathcal{{A}}}_{\varDelta }\} \). An outbox-state \(O \in \mathcal{{O}}_{\varDelta } = \{{\langle \rangle }\} \cup (\varGamma _{\varDelta } \times \varPi _{\varDelta } \times \varLambda _{\varDelta }^{O})\) is either empty or a triple \((\gamma , \pi , \alpha {\langle \rangle })\). A component-state \(\varSigma \) is a triple \(\varSigma =(C,\gamma , O) \in \mathcal{{S}}_{\varDelta } \times \varGamma _{\varDelta } \times \mathcal{{O}}_{\varDelta }=\varOmega _{\varDelta }\), where \(C,\gamma ,O\) are the current state, store and outbox-state of the component, respectively. If the component-state is the target of a transition modelling the execution of an output action, then \(O=(\gamma ', \pi , \alpha {\langle \rangle })\), where \(\gamma '\) is the store of the (component-state) source of the transition, \(\pi \) is the predicate used in the action—actualized with \(\gamma '\)—and \(\alpha {\langle \rangle }\) the actual message sent by the action. If, instead, the component-state is the target of a transition for an input action, then \(O={\langle \rangle }\), i.e. the empty outbox. A global state is a tuple \(\varvec{\varSigma }=((C_{1}, \gamma _{1},O_{1}),\ldots ,(C_{N}, \gamma _{N},O_{N})) \in \varOmega _{\varDelta }^N\) where \(\varvec{\varSigma }_{[j]}= (C_{j}, \gamma _{j},O_{j})\) is the component-state of the j-th instance in the population for \(j=1\ldots N\). We say that N is the population size of the system. In the sequel, we will omit the explicit indication of the size N in \(( \varDelta , F, \varvec{\varSigma _0} )^{(N)}\), and elements thereof or related functions, writing simply \(( \varDelta , F, \varvec{\varSigma _0} )\), when this cannot cause confusion. In summary, a system specification can be thought of as process algebraic clock-synchronous parallel composition of N processes. The probabilistic behaviour of a system can be derived from its specification \(( \varDelta , F, \varvec{\varSigma _0} )^{(N)}\). We remind that \(\varOmega _{\varDelta }\) is finite, since so are sets \(\mathcal{{S}}_{\varDelta }, \varGamma _{\varDelta }\) and \(\mathcal{{O}}_{\varDelta }\). Assume \(\varOmega _{\varDelta }= \{\varSigma _1,\ldots ,\varSigma _S\}\) and let \(\mathcal{{U}}^S\) be the set \(\{{\mathbf m}\in [0,1]^S |\sum _{i=1}^{S} {\mathbf m}_{[i]} \!=\!1\}\); we can assume, w.l.o.g. that there is a total ordering on \(\varOmega _{\varDelta }\) so that we can unambiguously associate each component \(m_j\) of a vector \({\mathbf m} = ( m_1, \ldots , m_S ) \in \mathcal{{U}}^S\) with a distinct element \(\varSigma _j\) of \(\{\varSigma _1,\ldots ,\varSigma _S\}\). With each global state \(\varvec{\varSigma }^{(N)}\) an occupancy measure vector \({\mathbf M}^{(N)}(\varvec{\varSigma }^{(N)}) \in \mathcal{{U}}^S\) is associated where \({\mathbf M}^{(N)}(\varvec{\varSigma }^{(N)}) = ( M^{(N)}_1,\ldots ,M^{(N)}_S )\) with \(M^{(N)}_i = \frac{1}{N}\sum _{n=1}^{N} \mathbf {1}_{\{\varvec{\varSigma }^{(N)}_{[n]} = \varSigma _i\}}\) for \(i=1,\ldots ,S\) and the value of \(\mathbf {1}_{\{\alpha = \beta \}}\) is 1, if \(\alpha = \beta \), and 0 otherwise. So, for \(\varSigma _i=(C_i,\gamma _i,O_i)\), \(M^{(N)}_i\) is the fraction, in the current global state \(\varvec{\varSigma }^{(N)}\), of the component instances which are in state \(C_i\), have store \(\gamma _i\) and outbox \(O_i\), over the total number N. We assume semantic interpretation functions \(\mathbf {E_L}[\![\cdot ]\!]\) and \(\mathbf {E_R}[\![\cdot ]\!]\) for the local, remote respectively, interpretation of expressions and predicates and a function \(\mathbf {E_P}[\![\cdot ]\!]\) for the interpretation of probability expressions. \(\mathbf {E_L}[\![e]\!]\) (\(\mathbf {E_R}[\![e]\!]\), respectively) takes a local (remote, respectively) store \(\gamma \) as an argument, whereas \(\mathbf {E_P}[\![p]\!]\) takes an occupancy measure vector \({\mathbf m}\) as an argument. We note that \(\mathbf {E_L}[\![a]\!]_{\gamma } =a, \mathbf {E_L}[\![\mathbf {my}.a]\!]_{\gamma } = \gamma (a)\), \(\mathbf {E_R}[\![a]\!]_{\gamma } = \gamma (a)\), and \(\mathbf {E_P}[\![\textsf {frc}\,C]\!]_{{\mathbf m}} = \sum _{i=1}^S\{{\mathbf m}_{[i]} | \varSigma _i= (C,\gamma _i,O_i)\}\); moreover, \(\mathbf {E_R}[\![\mathbf {my}.a]\!]_{\gamma }\), \(\mathbf {E_P}[\![\mathrm {tt}]\!]_{{\mathbf m}}\), \(\mathbf {E_P}[\![\mathrm {ff}]\!]_{{\mathbf m}}\), \(\mathbf {E_L}[\![\textsf {frc}\,C]\!]_{\gamma }\), and \(\mathbf {E_R}[\![\textsf {frc}\,C]\!]_{\gamma }\) are undefined as are, for the sake of simplicity, \(\mathbf {E_P}[\![a]\!]_{{\mathbf m}}\), \(\mathbf {E_P}[\![\mathbf {my}.a]\!]_{{\mathbf m}}\). The definition of the above semantic interpretation functions on composition terms can be given recursively on the structure of the terms and is left out here. In particular, we assume them extended to tuples. Similarly, we assume standard techniques and machinery for auxiliary functions in store updates; the semantics of update \(\sigma \) in the current store \(\gamma \) will be denoted by \(\mathbf {E_U}[\![\sigma ]\!]_{\gamma }\), that is a probability distribution over storesFootnote 7.

Let \(\varLambda _{\varDelta }\) be defined as \(\varLambda _{\varDelta }=\varLambda _{\varDelta }^{O} \cup \varLambda _{\varDelta }^{I}\), with \(\varLambda _{\varDelta }^{O}\) as above, and \( \varLambda _{\varDelta }^{I} = \{\alpha () | \alpha \in {\mathcal{{A}}}_{\varDelta }\} \). A component specification \((\varDelta ,F)\) characterises the (component) transition probability matrix as a function of occupancy measure vectors \({\mathbf m}\), \(\mathbf {K}^{(N)}{:}\ \mathcal{{U}}^S \times \varOmega _{\varDelta } \times \varOmega _{\varDelta } \rightarrow [0,1]\) such that is the probability of a one step jump from component-state \(\varSigma \) to component-state \(\varSigma '\), given (that the global system state induces) occupancy measure vector \({\mathbf m}\). \(\mathbf {K}^{(N)}({\mathbf m})_{\varSigma ,\varSigma '}\) is computed by making use of a transition relation over the space of component-states \(\varOmega _{\varDelta }\), with transition labels drawn from \(\varTheta _{\varDelta } \subset \varLambda _{\varDelta } \times [0,1]\). More specifically, the transition relation is the relation such that iff is the defining equation for C and , where is the least relation induced by the rules in Fig. 2. The component transition matrix function \(\mathbf {K}^{(N)}({\mathbf m})_{\varSigma ,\varSigma '} \) is defined as follows: . Note that all the above summations are finite under our assumption that so is \(\mathcal{{V}}_{\varDelta }\). The behaviour of the system is the result of the parallel-synchronous execution of the N instances of the component. Thus, the probabilistic behaviour of the system is characterised by the DTMC \({\mathbf X}^{(N)}(t)\) with initial probability distribution \(\varvec{\delta }_{\varvec{\varSigma _0}}\) and one step probability matrix \(\mathbf {P}^{(N)}\) defined by the following product: \( \mathbf {P}^{(N)}_{\varvec{\varSigma },\varvec{\varSigma '}} = \varPi _{n=1}^{N} \mathbf {K}^{(N)}({\mathbf M}^{(N)}(\varvec{\varSigma }))_{\varvec{\varSigma }_{[n]},\varvec{\varSigma '}_{[n]}}. \) Of course, the ‘occupancy measure’ view of the evolution in time of stochastic process \({\mathbf X}^{(N)}(t)\) is again a DTMC, namely the occupancy measure DTMC, which is defined as expected: \({\mathbf M}^{(N)}(t) = {\mathbf M}^{(N)}({\mathbf X}^{(N)}(t))\).

Fig. 2.
figure 2

Probabilistic Semantics Rules

2.3 Bounded PCTL

We recall that, given a set \(\mathscr {P}\) of atomic propositions, the syntax of PCTL state formulas \(\varPhi \) and path formulas \(\varphi \) is defined as follows, where \({\texttt {ap}}\in \mathscr {P}\) and \(k\ge 0\) :\( \varPhi \ {:}{:}\!\!= {\texttt {ap}} \mid \lnot \, \varPhi \mid \varPhi \, \wedge \, \varPhi \mid {\mathcal{{P}}}_{\bowtie p}(\varphi )\) where \(\varphi \ {:}{:}\!\!= \mathcal{{X}}\,\varPhi \mid \varPhi \, \mathcal{{U}}^{\le k} \, \varPhi \). PCTL formulas are interpreted over state labelled DTMCs, which are pairs \((\mathcal{{M}}, L)\) where \(\mathcal{{M}}\) is a DTMC and L is a mapping from the set of states of \(\mathcal{{M}}\) to \(2^\mathscr {P}\); for each state s, L(s) is the set of atomic propositions true in s Footnote 8. For the purposes of FlyFast bounded PCTL model-checking, our system specifications are enriched with the declaration of three different kinds of atomic propositions. A declaration of the form \({\texttt {ap\,at}}\,C\) associates atomic proposition \({\texttt {ap}}\) to state \(C \in \mathcal {S}_{\varDelta }\). Thus \(\mathtt {ap}\) must be included in the set \(L(\varvec{\varSigma })\) for each global state \(\varvec{\varSigma }=((C_{1}, \gamma _{1},O_{1}),\ldots ,(C_{N}, \gamma _{N},O_{N}))\) such that \(C_{1} = C\) (recall here that FlyFast performs model-checking of the first object in the context of the global system). A declaration of the form \({\texttt {ap}} \, \mathsf {def}\, (\mathbf {my}.a \, \underline{\bowtie }\, v)\) associates atomic proposition \(\mathtt {ap}\) to all component-states \((C, \gamma ,O)\) s.t. attribute a is \(\, \underline{\bowtie }\, v\). So, \(\mathtt {ap}\) must be included in the set \(L(\varvec{\varSigma })\) for each global state \(\varvec{\varSigma }=((C_{1}, \gamma _{1},O_{1}),\ldots ,(C_{N}, \gamma _{N},O_{N}))\) such that \(\mathbf {E_L}[\![\mathbf {my}.a \, \underline{\bowtie }\, v]\!]_{\gamma _{1}} = \mathrm{{tt}}\). Finally, a limited form of global atomic predicate is provided by means of a declaration of the form \(\mathtt {ap} \, \mathsf {def}\, (\textsf {frc}\,C \, \bowtie \, v)\); in this case, \(\mathtt {ap}\) must be included in the set \(L({\varvec{\varSigma }})\) for each global state \(\varvec{\varSigma }\) s.t. the fraction in \(\varvec{\varSigma }\) of the component states \((C, \gamma ,O)\), for any \(\gamma \) and O, is \(\bowtie \) than \(v\in [0,1]\).

3 A Translation to FlyFast

In this section we define a translation \(\mathcal{{I}}\) such that, given system specification \(\Upsilon = ( \varDelta _{\Upsilon }, F_{\Upsilon }, \varvec{\varSigma _0})^{(N)}\), \(\mathcal{{I}}(\Upsilon ) = {\langle \varDelta ,A,{\mathbf C_0} \rangle }^{(N)}\) is a FlyFast [15, 17] system specification preserving probabilistic semantics. The attribute-based FlyFast front-end is then completed with a simple translation at the PCTL level, also provided in this section. We map every component state of \(\Upsilon \) to a distinct state of \(\mathcal{{I}}(\Upsilon )\) by means of a total injection \(\mathcal{{I}}_{\mathcal{{S}}_{}}{:} \varOmega _{\varDelta _{\Upsilon }} \rightarrow \mathcal{{S}}_{}\). The mapping of actions is a bit more delicate because we have to respect FlyFast static constraints and, in particular, we have to avoid multiple probability function definitions for the same action. To that purpose, we could distinguish different occurrences of the same action in different transitions, characterized by their source and target states in \(\varOmega _{\varDelta _{\Upsilon }}\). In practice, since an action of a component cannot be influenced by the current outbox of the component, it is sufficient to use a total injection \(\mathcal{{I}}_{{\mathcal{{A}}}_{}}\) of the following type \((\mathcal{{S}}_{\varDelta _{\Upsilon }} \times \varGamma _{\varDelta _{\Upsilon }}) \times \varLambda _{\varDelta _{\Upsilon }} \times \varOmega _{\varDelta _{\Upsilon }} \rightarrow {\mathcal{{A}}}_{}\) for the mapping of actions. In the sequel we show how to build \(\mathcal{{I}}(\Upsilon ) = {\langle \varDelta ,A,{\mathbf C_0} \rangle }^{(N)}\) from \(\Upsilon = ( \varDelta _{\Upsilon }, F_{\Upsilon }, \varvec{\varSigma _0})^{(N)}\). The translation algorithm is given in Fig. 3, where for action \(act\in \{\alpha ^*[\pi ]{\langle \rangle }\sigma ,\alpha ^*[\pi ]()\sigma \}\) we let \(T(act)=\alpha \), \(P(act)=\pi \), and \(U(act)=\sigma \). \(\mathsf {SUM}\{t | \mathsf {cond}(t)\}\) denotes the syntactical term representing the sum of terms \(t\in \{t|\mathsf {cond}(t) = \mathrm {tt}\}\), i.e. \(t_1 + \ldots + t_n\), if \(\{t|\mathsf {cond}(t) = \mathrm {tt}\}=\{t_1, \ldots , t_n\}\not =\emptyset \) and 0 if \(\{t|\mathsf {cond}(t) = \mathrm {tt}\}\) is the empty set. Finally, by \(t*t'\) we mean the syntactical term representing the product of terms t and \(t'\). Output actions are dealt with in step 1. Consider for example action \(\texttt {ext}^*[\bot ]{\langle \rangle } \{\mathbf {my}.\mathsf {loc}\leftarrow \texttt {Jump}(\mathbf {my}.\mathsf {loc})\}\) in the definition of state S in Fig. 1. Suppose the possible values for locations are ABCD, so that stores are functions in \(\{\mathsf {loc}\} \rightarrow \{A,B,C,D\}\). The algorithm generates 12 actions (diagonal jumps are not contemplated in the example). Let us focus on the action \(\xi \) associated to local position A (i.e. \(\gamma = [\mathsf {loc}\mapsto A]\)) and possible next position B (i.e. \(\gamma '= [\mathsf {loc}\mapsto B]\)); the algorithm will generate probability function definition \(\xi \ {:}{:}\ \texttt {p}_{\mathsf {W}}(A)*{ext}\) as well as a transition leading to (a state which is the encoding, via \(\mathcal{{I}}_{\mathcal{{S}}_{}}\), of) the component state with E as (proper) state, store \(\gamma '\), and outbox \((\gamma , \bot , \texttt {ext}{\langle \rangle })\). Since the action is not depending on the current outbox, in practice a copy of such a transition is generated for each component state sharing the same proper state S and the same store \(\gamma \). In the general case, in a defining equation for a state C there might be multiple occurrences of the same action, bringing to the same next state \(C'\); the algorithm takes care of this and collects them in order to generate a single transition; the appropriate probability is expressed by means of the \(\mathsf {SUM}\{\ldots \}\) term. The translation scheme for input actions is defined in case 2 and is similar, except that for each term \(p_j\) in the \(\mathsf {SUM}\{\ldots \}\) expression one has also to consider the sum \(\varPhi _j\) of the fractions of the possible partners. The translation of the \(\mathbf {rest}\) case is straighforward.

Fig. 3.
figure 3

The translation algorithm

Let \(\mathbf {K}^{(N)}_{\mathcal{{I}}(\Upsilon )}\ {:}\ \mathcal{{U}}^S \times \mathcal{{I}}_{\mathcal{{S}}_{}}(\varOmega _{\varDelta }) \times \mathcal{{I}}_{\mathcal{{S}}_{}}(\varOmega _{\varDelta }) \rightarrow [0,1]\) be the step probability function associated to \(\mathcal{{I}}(\Upsilon )\) by the FlyFast language probabilistic semantics definition (see [15, 17] for details) and \(\mathbf {K}^{(N)}_{\Upsilon }\ {:}\ \mathcal{{U}}^S \times \varOmega _{\varDelta } \times \varOmega _{\varDelta } \rightarrow [0,1]\) be the step probability function for \(\Upsilon \) as defined in Sect. 2.2. It is easy to see that:

Theorem 1

For all \(N >0\), occupancy measure vector \({\mathbf m} \in \mathcal{{U}}^S\) and \(\varSigma ,\varSigma ' \in \varOmega _{\varDelta }\) the following holds: \( \mathbf {K}^{(N)}_{\Upsilon }({\mathbf m})_{\varSigma ,\varSigma '} = \mathbf {K}^{(N)}_{\mathcal{{I}}(\Upsilon )}({\mathbf m})_{\mathcal{{I}}_{\mathcal{{S}}_{}}(\varSigma ),\mathcal{{I}}_{\mathcal{{S}}_{}}(\varSigma ')}. \)

Proof (scketch). We first observe that, by definition, which, by definition of , is equal to

Consider the outer summation and suppose \((\alpha {\langle \rangle },p)\) be the index of a summand. Without loss of generality, assume there is only one instance of such a summand and there is only one \(k \in J\) such that the following transition is derived using the rules of Fig. 2: . So, we have \(\mathbf {K}^{(N)}_{\Upsilon }({\mathbf m})_{(C,\gamma ,O),(C',\gamma ',O')} = \bar{p}_k\) such that , where \(C :=\sum _{j \in J} [g_j] p_j\ {:}{:}\ act_j.C_j\) is the defining equation for C. Suppose \([g_k] p_k\not =\mathbf {rest}\), so that Rule (1) of Fig. 2 has been used for generating the transition. This implies that \(\mathbf {E_L}[\![g_k]\!]_{\gamma }= \mathrm{{tt}}\), \(\bar{p}_k = \mathbf {E_U}[\![\sigma ]\!]_{\gamma }(\gamma ') \cdot \mathbf {E_P}[\![p_k]\!]_{{\mathbf m}}\), \(C' = C_k\), and \(O'=(\gamma ,\mathbf {E_L}[\![\pi ]\!]_{\gamma },\alpha {\langle \rangle })\). Under the above conditions, by definition of the translation algorithm, the action \( \xi = \mathcal{{I}}_{{\mathcal{{A}}}_{}}((C,\gamma ), \alpha {\langle \rangle }, (C',\gamma ',O')) \) and related action probability function definition \(\xi \ {:}{:}\ \mathbf {E_U}[\![\sigma ]\!]_{\gamma }(\gamma ')* \mathsf {SUM}\{p_k\}\) are included in the FlyFast model. Moreover, the summand \(\xi . \, \mathcal{{I}}_{\mathcal{{S}}_{}}(C',\gamma ',O')\) is added in the equation for state \(\mathcal{{I}}_{\mathcal{{S}}_{}}(C,\gamma ,O)\) in the FlyFast model. Using the semantics definition of the FlyFast language [15, 17], we get that the probability assigned to \(\xi \) is \( \mathbf {E_U}[\![\sigma ]\!]_{\gamma }(\gamma ') \cdot \mathbf {E_P}[\![p_k]\!]_{{\mathbf m}} \), that is, exactly \(\bar{p}_k\). Thus \( \mathbf {K}^{(N)}_{\Upsilon }({\mathbf m})_{\varSigma ,\varSigma '} = \mathbf {K}^{(N)}_{\mathcal{{I}}(\Upsilon )}({\mathbf m})_{\mathcal{{I}}_{\mathcal{{S}}_{}}(\varSigma ),\mathcal{{I}}_{\mathcal{{S}}_{}}(\varSigma ')}. \) The proof for all the other cases is similar. \(\bullet \)

The translation of atomic proposition declarations into FlyFast formula declarations is the obvious one and is shown in Fig. 4 where \(\mathsf {OR}\{e | \mathsf {cond}(e)\}\) denotes the syntactical term representing the disjunction of expressions \(e\in \{e|\mathsf {cond}(e) = \mathrm{{tt}}\}\), i.e. \(e_1 | \ldots | e_n\), if \(\{e|\mathsf {cond}(e) = \mathrm {tt}\}=\{e_1, \ldots , e_n\}\not =\emptyset \) and \(\mathrm{{ff}}\), if \(\{e|\mathsf {cond}(e) = \mathrm {tt}\}\) is the empty set.

Fig. 4.
figure 4

Translation of atomic proposition declarations. The translation is not defined whenever \(\mathsf {OR}\{t | \mathsf {cond}(t)\}=\mathrm {ff}\) or \(\mathsf {SUM}\{t | \mathsf {cond}(t)\}=0\).

4 Epidemic Example Revisited

We return to the distributed Epidemic example of Fig. 1 where, for the sake of simplicity, we consider a simple patched space, consisting of the usual four quadrants ABCD in the Cartesian Plane, as in Fig. 5 (left). We model a ‘flow’ from quadrant C to quadrant A by defining the jump probabilities as in the table in Fig. 5 (right)Footnote 9, where \(l=0.6\) and \(s=1-l\), so that \(l>s\).

Fig. 5.
figure 5

The Cartesian quadrants (left) and the jump probabilities (right).

We consider a model in which initially there are 10.000 components in state S in quadrant C and 100 in state S in quadrant A. The non-zero values of the parameters are the same for each quadrant, defined as follows: \(h=0.2, ext=0.1, ei=0.4, ii=0.8, ir=0.2, rs=0.1,m_N=m_S=m_E=m_W=0.05\).

Fig. 6.
figure 6

Fast simulation for each of the four quadrants.

Figure 6 shows the fast-simulation resultsFootnote 10 for the model for each of the four quadrants. This functionality is built-in in the FlyFast tool. In the figure, the fractions of numbers of the components in each of the four states at each of the four locations are shown. Note that these fractions correspond to appropriate predicates on standard atomic propositions; for instance the fraction of components in state S at quandrant A is captured by \(\mathtt {s}\, \wedge \,\mathtt {a}\), assuming the following declarations: s at S and a def (my .loc = A). The simulation of single elements, taken as the average over 10 runs shows a very good correspondence with the fast-simulation results. The results also show good correspondence to the original SEIR model [5] when the probability to move between quadrants is set to zero and in the initial state the total population is in state S and in one specific quadrant in the former model. Besides fast simulation, that gives an idea of the average global behaviour of the system, we can also analyse the behaviour of a single component in the context of the overall behaviour. We consider two example properties as illustration. Let us first consider a component initially in state S and located in A and let atomic propositions i and c be declared as follows: \({\texttt {i\,at\,I}}\) and . The following formula (P1) states that the probability is greater than p that the component ends up infected in quadrant C by time t: \({\mathcal{{P}}}_{> p}(\mathrm {tt}\, \mathcal{{U}}^{\le t} \, (i \wedge c))\). FlyFast allows one to study the dynamics of the actual probability as a function of t, by means of the notation \({\mathcal{{P}}}_{= ?}(\mathrm {tt}\, \mathcal{{U}}^{\le t} \, (i \wedge c))\) and the resulting graph, for the above initial conditions and for the first 70 time units is shown in Fig. 7 (left). For comparison, the formula for an agent starting in C and ending up in A and being infected is shown as well in the same figure. The results for a more complicated, nested, formula (P2) are shown in Fig. 7 (right). P2 expresses the probability, over time, of a component reaching a situation in which it is neither infected nor exposed, and from which it can reach a state in which it has a probability higher than 0.15 to be infected and located in C within the next 10 time units; formula P2 is given below, where \(\mathtt {i}\) is assumed defined by \({\texttt {i\,at\,I}}\): \({\mathcal{{P}}}_{= ?}(\mathrm{{tt}} \, \, \mathcal{{U}}^{\le t} \, (\lnot (i \vee e) \wedge {\mathcal{{P}}}_{> 0.15}(\mathrm{{tt}} \, \, \mathcal{{U}}^{\le 10} \, (i \wedge c))))\). The formula has been considered for a component which is initially in A and in state S; the figure shows also a similar formula, where the role of A and C is exchanged and a probability higher than 0.45 instead of 0.15 is considered.

Fig. 7.
figure 7

Model checking results for properties P1 (left) and P2 (right).

For both types of properties a considerable difference in the probabilities can be observed for an agent that is initially located in A or in C, due to the flow of movement that has been introduced. This illustrates a clear dependence of the results on the dynamically changing spatial distribution of components. The total number of states, actions and transitions for the resulting FlyFast object specification is 52, 114 and 468 respectively, while the number of states of the global approximated model which have been generated for the analysis of formula P2 is 2.323 (2.185 when A and C are swapped). The model checking time for the more complicated nested formula P2 and for all values of t (70) is 10.343 (9.921 when A and C are swapped) ms, \(\approx 148\, (141)\, ms\) per checking session, for a model with a total population of 10.100 objects. A well-known feature of mean-field model checking is that the model checking time is independent of the size of the population, however, further experimentation with more extended spatial models and more attributes, that do effect this time, is planned as future work.

5 Conclusions

The attribute-based interaction paradigm is deemed fundamental for agent interaction in the context of Autonomic or Collective Adaptive Systems [1, 3, 9, 12, 20]. In this paper we have presented a attribute-based coordination modelling language as a front-end for FlyFast, an on-the-fly mean-field model-checker for bounded PCTL. The language extends the original FlyFast modelling language by replacing its actions with input (output, respectively) actions where senders (receivers, respectively) are specified by means of predicates on dynamic attributes on system components, where a component is a process/attribute-store pair. A translation to the standard FlyFast language has been presented, its correctness has been showed as well as an example of its application to a simple case study. It should be noted that the introduction of attributes in a process model is an intrinsic source of complexity in terms of component state-space size. Such an increase, in the worst case, goes with \(|\mathcal{{V}}_{\varDelta }|^{|Att_{\varDelta }|}\cdot (|{\mathcal{{A}}}_{\varDelta }^{O}| +1)\), where \(Att_{\varDelta }\) is the set of attributes of the component, \(\mathcal{{V}}_{\varDelta }\) is the set of values they can take, and \({\mathcal{{A}}}_{\varDelta }^{O}\) is the set of output actions occurring in the component specification (which may appear in its outbox). The obvious consequence of this is that one has to carefully ponder the importance and necessity of each and every new attribute used in a model, although, it must be kept in mind that the real source of state-space explosion is the size of the system, and this issue is addressed by Mean-Field approximation. A first optimisation consists in considering only reachable component states as well as eliminating actions with constant zero probability and simplifying boolean combinations of FlyFast atomic propositions in the translation. A possible additional line of investigation is the study of techniques for DTMC minimization to Mean-field analysis, so that the number of difference equations can decrease as a consequence, in a similar way as for CTMCs and the number of differential equations in fluid flow analysis [24].