Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

210
Dipartimento di Informatica Universit` a di L’Aquila Via Vetoio, I-67100 L’Aquila, Italy http://www.di.univaq.it Dissertation Explicit Algorithms for Probabilistic Model Checking Igor Melatti June 2005 Advisor PhD Program Supervisor Prof. B. Intrigila Prof. M. Flammini c Igor Melatti, 2005. All rights reserved

Transcript of Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

Page 1: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

Dipartimento di InformaticaUniversita di L’Aquila

Via Vetoio, I-67100 L’Aquila, Italy

http://www.di.univaq.it

Dissertation

Explicit Algorithms for Probabilistic Model Checking

Igor Melatti

June 2005

Advisor PhD Program Supervisor

Prof. B. Intrigila Prof. M. Flammini

c© Igor Melatti, 2005. All rights reserved

Page 2: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor
Page 3: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

ABSTRACT

In this Thesis we present two explicit algorithms for the verification of finite horizon properties of Proba-bilistic Systems modeled by Discrete Time Markov Chains.

The first algorithm deals with finite horizon safety properties only. Thus, given a Markov Chain M and aninteger k (horizon), this algorithm is able to check whether the probability of reaching an error state of Min at most k steps is below a given threshold.

On the other hand, the second algorithm is able to handle generic BPCTL (Bounded PCTL) formulas, i.e.PCTL formulas in which all Until operators are bounded, possibly with different bounds. This entails thatwe consider only system runs (paths) of bounded length. Thus, given a Markov Chain M and a BPCTLformula Φ, our algorithm checks if Φ is satisfied in M. This allows to verify important properties, whichis not possible to check with the first algorithm, such as e.g. robustness in Discrete Time Stochastic HybridSystems.

We present an implementation of our algorithms within a suitable extension of the Murϕ verifier. We callFHP-Murϕ (Finite Horizon Probabilistic Murϕ) such extension of the Murϕ verifier.

Finally, we give experimental results comparing FHP-Murϕwith PRISM, a state-of-the-art symbolic modelchecker for Markov Chains. Our experimental results show that FHP-Murϕ can effectively handle verifi-cations for systems that are out of reach for PRISM, namely those involving arithmetic operations on thestate variables. However, PRISM is a more general verifier than Murϕ, since it handles also other MarkovChain based models, and is able to verify also unbounded PCTL formulas.

Page 4: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor
Page 5: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

ACKNOWLEDGMENTS

This Thesis has been realized thanks to the support of many people. First of all, I need to thank my advisor,Prof. Benedetto Intrigila, together with Prof. Enrico Tronci, for their ideas and advices. But I cannot forgetProf. Giuseppe Della Penna, for his help in the coding. Moreover, I have to thank my family, for theirpatience, and my PhD Program companions, for the beautiful three years I’ve spent together with them.

Finally, I have to thank my thesis reviewers, namely Prof. Andrea Maggiolo Schettini, Prof. GaneshGopalakrishnan and Xiaofang Chen for their suggestion on how to improve a previous version of thisThesis.

Page 6: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

TABLE OF CONTENTS

Abstract i

Acknowledgments iii

Table of Contents iii

List of Figures vii

List of Tables ix

1 Introduction 11.1 Related Works . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

1.1.1 Probabilistic Model Checkers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.2 Thesis Content Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2 Theoretical Basis 52.1 Markov Chains . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2.1.1 “Real World” Markov Chains . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82.2 The BPCTL Language . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.2.1 BPCTL Bounded Semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112.3 Finite State/Discrete Time Stochastic Processes . . . . . . . . . . . . . . . . . . . . . . . 152.4 The Murϕ Verifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

2.4.1 Murϕ Input Language . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202.4.2 A Toy Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

3 Verification of Safety Properties 253.1 Finite Horizon Safety Verification of Markov Chains . . . . . . . . . . . . . . . . . . . . 253.2 Explicit Finite Horizon Safety Verification of Markov Chains . . . . . . . . . . . . . . . . 31

3.2.1 Algorithm Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313.2.2 Algorithm Correctness . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323.2.3 Algorithm Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

3.3 Experimental Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353.3.1 Probabilistic Dining Philosophers . . . . . . . . . . . . . . . . . . . . . . . . . . 353.3.2 A “Real world” Probabilistic Hybrid System . . . . . . . . . . . . . . . . . . . . 40

4 Verification of BPCTL Properties 434.1 Explicit BPCTL Model Checking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

4.1.1 Algorithm Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444.1.2 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 494.1.3 Algorithm Correctness . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 514.1.4 Algorithm Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

4.2 Experimental Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 594.2.1 Probabilistic Dining Philosophers . . . . . . . . . . . . . . . . . . . . . . . . . . 594.2.2 A “Real World” Probabilistic Hybrid System . . . . . . . . . . . . . . . . . . . . 61

5 FHP-Murϕ Language Expressiveness 635.1 Markov Chains and PFSSs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

Page 7: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

TABLE OF CONTENTS v

5.2 Probabilistic Rule Based Transition Systems . . . . . . . . . . . . . . . . . . . . . . . . . 645.3 From Communicating Stochastic Processes to PRBTS . . . . . . . . . . . . . . . . . . . . 655.4 Two protocols in FHP-Murϕ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

5.4.1 A Length-Based Queue System . . . . . . . . . . . . . . . . . . . . . . . . . . . 675.4.2 A Time-Based Server-Queue System . . . . . . . . . . . . . . . . . . . . . . . . 69

6 Conclusions 756.1 Future Works . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

A FHP-Murϕ: the Input Language 77A.1 An Overall Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77A.2 C++, Lex and Yacc Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

A.2.1 Modifications to mu.y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79A.2.2 Modifications to mu.l . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83A.2.3 Modifications to lextable.C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84A.2.4 Modifications to mu.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84A.2.5 Modifications to mu.C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86A.2.6 Modifications to rule.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88A.2.7 Modifications to rule.C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89A.2.8 Modifications to decl.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90A.2.9 Modifications to decl.C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92A.2.10 Modifications to expr.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93A.2.11 Modifications to expr.C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94A.2.12 Modifications to cpp code.C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94

B FHP-Murϕ: the Verifier 113B.1 C++ Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113

B.1.1 Modifications to mu prolog.inc . . . . . . . . . . . . . . . . . . . . . . . . . . . 113B.1.2 Modifications to mu epilog.ing . . . . . . . . . . . . . . . . . . . . . . . . . . . 115B.1.3 Modifications to mu real.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117B.1.4 Modifications to mu real.C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125B.1.5 Modifications to mu io.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125B.1.6 Modifications to mu io.C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127B.1.7 Modifications to mu util dep.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138B.1.8 Modifications to mu util.C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140B.1.9 Modifications to mu verifier.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140B.1.10 Modifications to mu verifier.C . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140B.1.11 Modifications to mu state.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141B.1.12 Modifications to mu state.C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142B.1.13 Added file splitFile.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145B.1.14 Added file splitFile.C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146B.1.15 Added file mu probstack.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151B.1.16 Added file mu probstack.C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154B.1.17 Modifications to mu system.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161B.1.18 Modifications to mu system.C . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164

C PRISM code for LQS with 10 entries 183

References 195

Page 8: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor
Page 9: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

LIST OF FIGURES

2.1 Graphical representation of the Markov Chain M of Example 2.2 . . . . . . . . . . . . . 72.2 A simple FHP-Murϕ code defining the PFSS of Example 2.3 . . . . . . . . . . . . . . . . 92.3 Graphical representation of the PFSS S of Example 2.3 . . . . . . . . . . . . . . . . . . . 102.4 Explicit Breadth–First Search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192.5 Murϕ execution model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212.6 A Nondeterministic Finite State System . . . . . . . . . . . . . . . . . . . . . . . . . . . 212.7 Murϕ code for the NFSS in Figure 2.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222.8 Murϕ error trace for Murϕ model in Figure 2.7 . . . . . . . . . . . . . . . . . . . . . . . 23

3.1 Graphical representation of the Markov Chain M of Example 3.1 . . . . . . . . . . . . . 283.2 Computation of P [tt U≤k φ]. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303.3 Function Safety . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333.4 Functions Insert and Checktable . . . . . . . . . . . . . . . . . . . . . . . . . . . 343.5 Enqueue and Dequeue operations in the queue disk storage mechanism . . . . . . . . . 363.6 Pnueli-Zuck algorithm fragment to be modified in PRISM . . . . . . . . . . . . . . . . . 383.7 Pnueli-Zuck algorithm modified fragment in PRISM . . . . . . . . . . . . . . . . . . . . 383.8 BPCTL formula in PRISM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383.9 Pnueli-Zuck algorithm in FHP-Murϕ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393.10 Ruleset for TCS with probabilistic user demand . . . . . . . . . . . . . . . . . . . . . . . 41

4.1 Functions BPCTL, BPCTL rec and evalX . . . . . . . . . . . . . . . . . . . . . . . . . 454.2 Functions evalU and DF Search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 464.3 Function try to evaluate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474.4 Function insert cache . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484.5 The PFSS of Example 4.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504.6 The PFSS of Example 4.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504.7 The PFSS of Example 4.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 514.8 Cache evolution for Example 4.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 514.9 Functions evalU nC and DF Search nC . . . . . . . . . . . . . . . . . . . . . . . . . 524.10 Push and pop operations in the stack cycling mechanism . . . . . . . . . . . . . . . . . . 58

5.1 FHP-Murϕ implementation sketch for LQS . . . . . . . . . . . . . . . . . . . . . . . . . 685.2 FHP-Murϕ implementation sketch for TSQS (1) . . . . . . . . . . . . . . . . . . . . . . . 705.3 FHP-Murϕ implementation sketch for TSQS (2) . . . . . . . . . . . . . . . . . . . . . . . 715.4 PRISM implementation for LQS with 4 queue entries . . . . . . . . . . . . . . . . . . . . 73

Page 10: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor
Page 11: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

LIST OF TABLES

3.1 Experimental results for the verification of a finite horizon safety property on the Pnueli-Zuck protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

3.2 Experimental results for the verification of a finite horizon safety property on the Lehmann-Rabin protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

3.3 Experimental results for the verification of a finite horizon safety property on the TurbogasControl System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

4.1 Experimental results for the verification of a BPCTL property on the Pnueli-Zuck protocolas it is found in the PRISM distribution . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

4.2 Experimental results for the verification of a BPCTL property on the Lehmann-Rabin pro-tocol as it is found in the PRISM distribution . . . . . . . . . . . . . . . . . . . . . . . . 60

4.3 Experimental results for the verification of a BPCTL property on the Pnueli-Zuck protocolas it was modified in Section 3.3.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

4.4 Experimental results for the verification of a BPCTL property on the Lehmann-Rabin pro-tocol as it was modified in Section 3.3.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

4.5 Experimental results for the verification of a BPCTL property on the Turbogas Control System 62

Page 12: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor
Page 13: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

CHAPTER 1

INTRODUCTION

Model checking techniques [6, 22, 33, 34, 47, 57] are widely used to verify correctness of digital hardware,embedded software and protocols by modeling such systems as Nondeterministic Finite State Systems (inthe sequel, we refer to these kind of mathematical objects as NFSSs). In practice, NFSSs can be seen asdirected graphs where the edges indicate the allowed transitions between states.

However, there are many reactive systems that exhibit uncertainty in their behavior, i.e. which are stochastic(of probabilistic) systems. This happens in fault tolerant systems, as well as in some kind of protocols, suchas randomized distributed protocols and communication protocols. Typically, stochastic systems cannot beconveniently modeled using NFSSs. Thus, other mathematical objects have to be used, in order to takeinto account the probabilistic aspect of these systems. Moreover, a model for stochastic systems has to besuch that the automatic analysis can be carried out in an efficient way. The simplest mathematical objectmatching these requirements is the Discrete Time Markov Chain [3, 25] (in the sequel, just Markov Chain).In fact, a Markov Chain can be seen as a directed graph labeled with outgoing probabilities on its edges, soit is not too different from a NFSS. Obviously, not all stochastic systems can be modeled as Markov Chains,since they may need to keep memory of their past, while Markov Chains are memoryless. Moreover, thereare mathematical objects which are derived from Markov Chains and are often used to model stochasticsystems:

Markov Decision Processes (MDP) allow to introduce nondeterminism in the definition of a MarkovChain;

Continuous Time Markov Chains (CTMC) define an exponential probability distribution by allowing atransition to delay by a given rate.

In this Thesis we restrict ourselves to systems which can be directly modeled as Markov Chain (Chapters 3and 4), or have models that are translatable in a Markov Chain (Chapter 5).

Once the system has been modeled, standard model checking approach is to show that the NFSS S underanalysis satisfies a given property Φ, typically expressed in CTL (Computation Tree Logic [10]) or LTL(Linear Time Logic, [11]), or their variants (such as ACTL or CTL∗). Moreover, if S does not satisfy Φ,then a counterexample showing how S violates Φ is reported.

On the other hand, a property to be proved on a stochastic system has to deal with probabilities, whichare not expressible with CTL or LTL. To this end, Probabilistic Logics have been proposed, such as PCTL(Probabilistic CTL [26]), used when the model is a Markov Chain or an MDP, or CSL (Continuous Stochas-tic Logic [1]) which is used when the model is a CTMC. The collection of techniques whose goal is to stateif a given PCTL formula is satisfied in a given Markov Chain or MDP (or a CSL formula in a CTMC) iscalled Probabilistic Model Checking. In practice, probabilistic model checking typically performs a quan-titative verification, i.e. is typically used to prove that the executions leading to errors have an acceptableprobability to occur. For example, a probabilistic model checker may automatically verify a system propertylike “the probability that a message is not delivered after 0.1 seconds is less than 0.20”. Thus, typically,

1

Page 14: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

2 Chapter 1. Introduction

no counterexample is required if the given stochastic systems does not satisfy the given property. In fact, inthe above example, we already know that a message may be not delivered after 0.1 seconds, and we wantsimply to know if this occurs with an acceptable probability (20%).

Note that, following [39, 40], we are using the expression “probabilistic model checking” to mean modelchecking of probabilistic systems, while in [58] “probabilistic verification” has been used to indicate aparticular technique for model checking of NFSSs. Namely, in [58] the hash compaction technique isdescribed, which may cause a system state not to be explored with an unknown, but low, probability, thusmaking probabilistic the final response itself.

Many methods have been proposed for probabilistic model checking, e.g. [4, 13, 16, 25–27, 44, 53, 62];moreover, starting from the second half of the 90s, efficient Probabilistic Model Checkers [23, 28, 52] havebeen developed. However, to the best of our knowledge, the currently state-of-the-art probabilistic modelchecker is PRISM [2, 40, 52]. PRISM is a symbolic model checker, since it bases most of its computationson MTBDDs (Multi Terminal Binary Decision Diagrams, [12]), which are a generalization of OBDDs(Ordered Binary Decision Diagrams, [5]). Namely, OBDDs represents sets of states via their characteristicfunction, while MTBDDs can represent the probability of a state to be in a set, by allowing real numbersin the interval [0, 1] (instead of boolean values) on terminal nodes. More in detail, as it is shown in [40],PRISM verification algorithm is based on an hybrid approach, which uses a MTBDD to represent thesystem transition matrix and sparse matrix algorithms to carry out the (quantitative) probabilistic analysis.This allows PRISM to be faster than probabilistic model checkers based only on MTBDDs (e.g., ProbVerus[28]) and avoids the state explosion problem of probabilistic model checkers based only on sparse matrices(e.g., ETMCC [31] or the algorithms in [25, 26]). A more detailed list of already available probabilisticmodel checkers may be found in Section 1.1.1.

However, the general problem of probabilistic model checking has been proved to be P-SPACE complete[42], so PRISM, as well as the other model checkers, is not able to solve all instances within a reasonabletime and/or memory. More specifically, as it happens in standard model checking of NFSSs, the mainobstruction is the state explosion problem, which arises, for PRISM, especially for systems requiring manyarithmetical operations on the state variables. In fact, it is known [5] that in this case OBDDs (and soMTBDDs) reach their worst behavior, i.e. they require an exponential amount of memory w.r.t. the numberof variables describing the system. Examples of such systems are the so called Discrete Time StochasticHybrid Systems, in which discrete and real variable coexist; for such systems, PRISM requires too muchmemory to store the MTBDDs needed for the computation.

In standard model checking of NFSSs, this OBDD limitation can be sometimes overcome by using, in-stead of a symbolic (i.e. OBDD-based) algorithm, an explicit one, i.e. based on an explicit enumerationof the system states. This works especially for software like (asynchronous) systems [35], whereas sym-bolic model checkers typically perform better on hardware like (synchronous) systems. Among the modelcheckers based on symbolic algorithms, we have to cite SMV [56], NuSMV [48] and UPPAAL [43, 61],while among the model checkers based on explicit algorithms we have to mention SPIN [57] and Murϕ[47]. Thus, it is natural to think that an explicit algorithm may work also in probabilistic model check-ing. However, to the best of our knowledge, the explicit approach has not been tried in probabilistic modelchecking.

This motivated the development, the implementation and the experimentation of two explicit algorithms forprobabilistic model checking, which will be described in this Thesis:

• The first algorithm, while accepting a generic (Discrete Time) Markov Chain, only allows the verifi-cation of finite horizon safety properties. Typically, this algorithm is able to determine if the proba-bility that a system reaches, in a given number of steps, an error state, is less than a given probabilitythreshold. Thus, notwithstanding its limitation, this algorithm covers important properties.

The algorithm is described in Chapter 3, where we also give a proof of its correctness, together withsome experimental results comparing its performance with PRISM. These experiments show that the

Page 15: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

1.1 Related Works 3

explicit approach to probabilistic model checking is indeed affordable, since our algorithm, as it wasexpected, succeeds in verifying stochastic systems in which PRISM run out of a 2GB memory; thesesystems indeed involve many arithmetic operations in the computing of the transition function. Apreliminary version of these results has already been published in [18].

• The second algorithm still takes as input a generic Markov Chain, but allows to verify general PCTLformulas, provided that they only deal with system executions of finite length. Since this is equivalentto have integer bounds on all the until operators of the PCTL formula (of course, different untils mayhave different bounds), we call the resulting logic BPCTL (Bounded PCTL). In particular, this allowsto verify, besides the finite horizon safety properties of the first algorithm, also BPCTL formulas withnested untils, e.g. the ones expressing reliability or robustness properties on system runs of finitelength. An example of such properties may be the sequent: “the probability of reaching within k1

steps an undesired state, which will not be left with high probability within k2 steps, is low”, wherek2 is low. By an undesired state we mean a state in which the system should not be, e.g. a state inwhich the system cannot stay for a too long time, otherwise a damage occurs.

This algorithm, that is quite different from the first one, is described in Chapter 4, where we prove itscorrectness and conduct some experiments, in order to compare its performances with PRISM. Again,we have that, in the class of Markov Chains having a complex transition function, we outperformPRISM. A preliminary version of these results has already been published in [20].

From the performance point of view, both algorithms are inspired by the results obtained in [21]. In fact,they are both able to use magnetic disk storage in a clever way, i.e. limiting disk seeks. Because of thelarge size of modern hard disks, we have that state explosion is hardly a problem for our algorithms, whilethe computation time is our real bottleneck. Moreover, our algorithms use a cache in RAM (although indifferent ways), allowing them to speed up computation by storing intermediate results. Thus, they cantrade RAM memory with computation time, i.e. the more RAM available the faster the verification.

Finally, both algorithms have been implemented within the Murϕ model checker; we call the resultingprobabilistic model checker FHP-Murϕ (Finite Horizon Probabilistic Murϕ, available at [24]).

As a concluding note, in Chapter 5 we analyze the properties of the new input language used by FHP-Murϕto define Markov Chains, by comparing it with the PRISM one. In this way, we will show that our languageis more natural than the PRISM one in order to specify many stochastic systems. A related idea has beenpublished in [19].

1.1 RELATED WORKS

Probabilistic model checking is a relatively young research field, the first works in this direction havingbeen published in the second half of the 90s. We can fix the starting point for probabilistic model checkingin [26], in which PCTL is introduced, together with an algorithm for PCTL model checking.

However, the algorithm in [26] was not feasible for large systems, since it was based on a state labeling. Inthe following years, more effective algorithms have been proposed, extending the approach also to MDPsand CTMCs, and basing the computation on MTBDDs; the more representative works in this directionare [1, 2, 7, 37, 40]. Actually, the hybrid approach presented in [40] and implemented in PRISM may beconsidered the best algorithm for probabilistic model checking at present.

1.1.1 PROBABILISTIC MODEL CHECKERS

We complete our brief survey of probabilistic model checking by giving a description of the probabilisticmodel checkers which have been effectively developed.

Page 16: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

4 Chapter 1. Introduction

PRISM (PRobabilistIc Symbolic Model checker[52] is, to the best of our knowledge, the currently state-of-the-art probabilistic model checker, and it has been successfully used to verify some importantstochastic systems (e.g. [15, 41, 54]). PRISM can use three approaches to Markov Chain analysis:

• a sparse matrix based approach (option -s);

• a symbolic approach totally based on MTBDDs and OBDDs (option -m);

• a hybrid approach (default).

The meaning for these options is the following. As it is described in [40], the symbolic approachperforms well for memory occupation, but it is too slow in MTBDDs computations. However, itturned out that numerical computations directly based on sparse matrices were orders of magnitudefaster. Thus, the hybrid approach was implemented, and is now the best verification modality. Inpractice, the PRISM hybrid approach to probabilistic model checking uses extensions of the MTBDDdata structure and borrows ideas from the sparse matrix techniques in order to overcome performanceproblems. By way of comparison, PRISM also allows to use directly the numerical sparse matrixcomputational routines equivalent to the MTBDDs ones (this is the -s option). However, the hybridapproach is the one giving the best results.

ProbVerus [28] is completely based on MTBDDs, so its computation engine is substantially equivalentto PRISM with option -m. It works only with Discrete Time Markov Chains, but handles the fullPCTL. It is important for historical reasons, having been one of the first (succeeded) attempts toapply symbolic algorithms to PCTL model checking. However, it is now covered by PRISM.

E `MC2 (ETMCC) [23] is a prototype model checker for CTMCs, where requirements are expressed inCSL. Its verification engine is based on a sparse matrix representation, so it is substantially equivalentto PRISM with option -s.

TwoTowers [60] is a software tool for the functional verification, security analysis, and performance eval-uation of computer, communication and software systems. For the performance evaluation, TwoTow-ers uses a Markov Chain solver which is based on numerical resolution [59], so it is equivalent tosparse matrix techniques (PRISM option -s).

Finally, we have to mention APMC (Approximate Probabilistic Model Checker, [30]), which is not a prob-abilistic model checker in the sense we use in this Thesis. In fact, APMC takes in input a Markov Chain Mand a positive LTL property φ (so, it does not accept probabilistic properties to be verified). Then, a ran-domized distributed algorithm is used to approximate the probability that φ is satisfied with high confidenceby M.

1.2 THESIS CONTENT SUMMARY

Summing up, these are the Thesis contents:

Chapter 2 gives the basic definitions and properties which are necessary to understand the rest of theThesis.

Chapter 3 describes an explicit algorithm for the verification of finite horizon safety properties of MarkovChains. The algorithm performances are then compared with PRISM ones.

Chapter 4 describes an explicit algorithm for the verification of BPCTL properties of Markov Chains.Also this algorithm is then compared to PRISM.

Chapter 5 illustrates some interesting properties of the FHP-Murϕ input language.

Page 17: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

CHAPTER 2

THEORETICAL BASIS

In this chapter, we give some mathematical definitions and properties on Markov Chains and related con-cepts, which will be useful in this Thesis. Moreover, in Section 2.4 we give a brief introduction to the modelchecker Murϕ, since all our implementations are done within it.

Before going into the details of the mathematical statements we are interested in, we have to point out thenotation we use. To this end, let S be a finite set, the elements of which we call states. By assuming thatthere is a predefined order on states, and by abuse of notation, we will indifferently speak of states andnatural number indices, so considering n+ 1 as denoting the state s if n is the number of states precedings in the given order.

This allows us to use states as row vectors (and matrices) indices. Thus, if S = {s1, . . . , sn} and x ∈ Rn,

then for all 1 ≤ i ≤ n we pose xsi= xi, and analogously, for P ∈ R

n×n, we pose Psi,sj= Pi,j for all

1 ≤ i, j ≤ n. Note that this also allows to regard a function f from S to [0, 1] as a |S|-dimensional rowvector x: it is sufficient to pose xi = f(si). Analogously, a function f from S × S to [0, 1] is regarded as a|S| × |S|-dimensional matrix P, by posing Pi,j = f(si, sj).

Example 2.1. If S = {0, 5, 7} (the order is the straightforward one), and f : S → [0, 1] is such that

f(i) = i+110 , then f is represented by the vector x = 1

10

(

1 6 8)

.

Analogously, if f : S × S → [0, 1] is such that f(i, j) = i+j20 , then f is represented by the matrix

P =1

20

0 5 7

5 10 12

7 12 14

.

This allows us to give our first definition.

Definition 2.1. A probability distribution (simply distribution in the following) on S is a function x : S →

[0, 1], or equivalently a |S|-dimensional row vector x, such that∑

i∈S

x(i) = 1. A distribution x represents

state j ∈ S iff x(j) = xj = 1 (thus x(i) = xi = 0 when i 6= j).

If distribution x represents s ∈ S, by abuse of language we also write x ∈ S to mean that distributionx represents a state and we use x in place of s, i.e. of the element of S represented by x. In the follow-ing we often represent states using distributions, since this allows us to use matrix notation to define ourcomputations.

For exposition completeness we recall the standard matrix operations: xP is the row vector y such that, forall s ∈ S, ys =

j∈S xjPj,s and AB is the matrix C such that, for all s, t ∈ S, Cs,t =∑

j∈S As,jBj,t.

5

Page 18: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

6 Chapter 2. Theoretical Basis

Moreover, An, being n ∈ N, is defined in the usual way, i.e.: A0 = I, An+1 = AnA, where I is theidentity matrix such that, for all s ∈ S, I(s, s) = 1 and I(s, t) = 0 for s 6= t.

We also recall some notations and definitions from other mathematical fields. We denote with B the set{0, 1} of boolean values; as usual 0 stands for false and 1 stands for true. Moreover, we denote with S∗ theset of all finite sequences of symbols in S, while S∞ is the set of all infinite sequences of symbols in S.

Finally, the following Definition, taken from [55], will be useful in the following.

Definition 2.2. Let X be a set. Then a σ-algebra F is a nonempty collection of subsets of X such that thefollowing holds:

1. The empty set is in F .

2. If A is in F , then so is the complement of A.

3. If An is a sequence of elements of F , then the union of the Ans is in F .

If S is any collection of subsets of X , then we can always find a σ-algebra containing S, namely the powerset of X . By taking the intersection of all σ-algebras containing S, we obtain the smallest such σ-algebra.We call the smallest σ-algebra containing S the σ-algebra generated by S.

2.1 MARKOV CHAINS

In this section, we give some basic definitions on Markov Chains; for further details see, e.g., [3].

Definition 2.3. Let S be a finite set of states. A Discrete Time Markov Chain (just Markov Chain in thefollowing) is a triple M = (S,P, q) where q ∈ S is the initial state and P : S × S → [0, 1] is a stochastic

matrix, i.e. for all s ∈ S,∑

t∈S

P(s, t) = 1.

Definition 2.4. An execution sequence (or path) in the Markov Chain M = (S,P, q) is a nonempty finiteor infinite sequence π = s0s1s2 . . . where, for all i ≥ 0, si ∈ S is a state and P(si, si+1) > 0. If π isa path, we write π(k) for the state sk, and we write π|k for the sequence s0s1s2 . . . sk−1. The length of afinite path π = s0s1s2 . . . sk is k, i.e. the number of transitions, whereas the length of an infinite path is∞; we denote with |π| the length of π. In M we also define the following sets of paths:

• Path(M, s) = {π ∈ S∞ | π is a path in M and π(0) = s} is the set of infinite paths π in Mstarting from s;

• Pathk(M, s) = {π ∈ S∗ | π is a path in M and π(0) = s and |π| = k} is set of paths π in Mstarting from s and of length exactly k;

• Path≤k(M, s) = {π ∈ S∗ | π is a path in M and π(0) = s and |π| ≤ k} is set of paths π in Mstarting from s and of length at most k;

• Path(M) = Path(M, q);

• Pathk(M) = Pathk(M, q);

• PathM = {π ∈ Path(M, s) | s ∈ S} is the set of all infinite paths in M.

Finally, we say that a state s ∈ S is reachable in k steps if it exists a path π ∈ Pathk(M) such thatπ(k) = s.

Page 19: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

2.1 Markov Chains 7

Definition 2.5. Let M = (S,P, q) be a Markov Chain. For s ∈ S we denote with∑

(s) the smallest

σ-algebra on Path(M, s) which, for any finite path ρ starting at s, contains the basic cylinders {π ∈Path(M, s) | ρ is a prefix of π}. Then, the probability measure Prob on

(s) is the unique measuresuch that, for any finite path ρ starting at s, Prob{π ∈ Path(M, s) | ρ is a prefix of π} = P(ρ) =k−1∏

i=0

P(ρ(i), ρ(i+ 1)) = P(ρ(0), ρ(1)) P(ρ(1), ρ(2)) · · ·P(ρ(k − 1), ρ(k)), where k = |ρ|.

A Markov Chain M = (S,P, q) can be seen as a method to define what is the probability p to go to a statet ∈ S, when the current state is s ∈ S and it is not required that p depends on the preceding path leadingfrom q to s; in this case, we will have p = P(s, t).

Example 2.2. Let S = {s0, s1} and M = (S,P, s0), with

P =

(

0 113

23

)

.

Then, if the current state is s0, the next state will be s1. On the contrary, if the current state is s1, then thereis probability 1

3 to go to state s0 and probability 23 to stay in state s1. Moreover, being P(s0, s0) = 0, we

have that Path(M) = {π ∈ S∞ | π(0) = s0 and π(k) = s0 ⇒ π(k + 1) = s1}.

A graphical representation of M is shown in Figure 2.1.

0 s1s0

1

13

23

Figure 2.1: Graphical representation of the Markov Chain M of Example 2.2

Definition 2.4 shows that a Markov Chain M = (S,P, q) can be viewed as a method to generate sequencesof states. More generally, M can generate a sequence of distributions. In fact, let M be the Markov Chain

defined in Example 2.2, and let x =(

1 0)

be the distribution representing s0. Then, we have that

xP =(

0 1)

= s1, and in fact, starting from s0, the only possibility is to go to state s1. On the

contrary, if x =(

0 1)

= s1, then we have that xP =(

13

23

)

, which is the right probability

distribution starting from s1.

Thus, given a distribution x, the distribution y obtained by one execution step of Markov Chain M =(S,P, q) is computed as: y = xP. In particular if y = xP and x represents state s we have that, for allt ∈ S, y(t) = Ps,t, so the distribution obtained by making one step from s coincides with the s-th row ofP.

Page 20: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

8 Chapter 2. Theoretical Basis

2.1.1 “REAL WORLD” MARKOV CHAINS

The Markov Chain definition given in Definition 2.3 is appropriate to study mathematical properties ofMarkov Chains. However, Markov Chains arising from probabilistic concurrent systems are usually definedusing a suitable programming language rather than a stochastic matrix. As a matter of fact the (huge) sizeof the stochastic matrix of concurrent systems is one of the main obstructions to overcome in probabilisticmodel checking.

Thus, a Markov Chain is presented to a probabilistic model checker by defining, using a suitable program-ming language, a next state function that returns the immediate successors of a given state, together withthe probability of the corresponding transition. The following definition formalizes this notion.

Definition 2.6. A Probabilistic Finite State System (shortened PFSS in the following) S is a 4-tuple(S, q,A,next), where S is a finite set of states, q ∈ S is the initial state, A is a finite set of labelsand next : S → 2S×A×[0,1] is a function taking a state s as argument and returning a set next(s) of

triplets (t, a, p) ∈ S ×A× [0, 1] such that∑

(t,a,p)∈next(s)

p = 1.

Note that, in Definition 2.6, we are forced to introduce the set A of labels in order to manage the case inwhich the next function returns more than one probabilistic transition from a state s to the same state twith the same probability p. The following example should clarify this point.

Example 2.3. Consider the simple FHP-Murϕ code (see Section 2.4.1 and Appendix A.1) in Figure 2.2;the corresponding PFSS is S = ({s0, s1}, s0, {r1, r2, r3, r4}, next), where function next is defined as:next(s0) = {(s0, r1, 1)} and next(s1) = {(s0, r2,

16 ), (s0, r3,

16 ), (s1, r4,

23 )}. In S, we denoted with si

the state in which x has value i, and we used the rule names as labels. Note that, since there are two rulesleading from s1 to s0 with probability 1

6 , they have to be distinguished by different labels (r2 and r3) inthe definition of next.

A graphical representation of S is shown in Figure 2.3.

Between PFSS and Markov Chains there is a strict connection. Namely, with each PFSS can be associatedexactly one Markov Chain (see Definition 2.7). On the other hand, there are many PFSSs describing a givenMarkov Chain (see Section 5.1).

Definition 2.7. Let S = (S, q,A,next) be a PFSS. The Markov Chain associated with S is Smc =

(S,P, q), where, for all s, t ∈ S, P(s, t) =∑

(t,a,p)∈next(s)

p.

Moreover, a state sequence π = s0s1s2 . . . is a path in S iff it is a path in Smc; this allows to define alsoPath(S, s) = Path(Smc, s) for all s ∈ S, and Path(S) = Path(S, q).

Example 2.4. If S is the PFSS given in Example 2.3, then Smc equals the M of Example 2.2.

2.2 THE BPCTL LANGUAGE

In this section we give syntax (Definition 2.8) and semantics (Definition 2.9) for the language we use todefine the formulas. Namely, we define syntax and semantics for the BPCTL (Bounded PCTL) language.The BPCTL language is a proper subset of the PCTL language (Probabilistic Computational Tree Logic[26]) in which all Until operators are bounded, possibly with different bounds. This entails that we consideronly paths (system runs) of bounded length.

Page 21: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

2.2 The BPCTL Language 9

var x : 0..1; /* x can assume values 0 and 1 */

/* Auxiliary function returning the real value 1.0 if theargument x is true, and 0.0 otherwise */

f u n c t i o n FromBoolToReal(x : boolean) : r e a l;begin

re turn x ? 1.0 : 0.0;end;

/* Definition of the initial state */s t a r t s t a t e "init"

beginx := 0;

end;

/* If we are in 0, we surely move to 1 */r u l e "r1"FromBoolToReal(x = 0) ==>beginx := 1;

end;

/* If we are in 1, we move to 0 with probability 16 */

r u l e "r2"(1.0/6.0)*FromBoolToReal(x = 1) ==>beginx := 0;

end;

/* Again, if we are in 1, we move to 0 with probability 16 */

r u l e "r3"(1.0/6.0)*FromBoolToReal(x = 1) ==>beginx := 0;

end;

/* If we are in 1, we stay in 1 with probability 23 */

r u l e "r4"(2.0/3.0)*FromBoolToReal(x = 1) ==>beginx := 1;

end;

Figure 2.2: A simple FHP-Murϕ code defining the PFSS of Example 2.3

Page 22: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

10 Chapter 2. Theoretical Basis

r2, 16

s1s0 r4, 23

r1, 1

r3, 16

Figure 2.3: Graphical representation of the PFSS S of Example 2.3

Definition 2.8. Let AP be a finite set of atomic propositions on a finite set of states S, i.e. of booleanfunctions p : S → B. The BPCTL language LBPCTL is the language generated by the following grammar:

Φ ::= tt | p | Φ1 ∧ Φ2 | ¬Φ | [XΦ]wα| [Φ1 U≤k Φ2]wα

where α ∈ [0, 1], p ∈ AP , k ∈ N and the symbol w is one of the symbols >,≥.

Definition 2.9. Let M = (S,P, q) be a Markov Chain. Then, the satisfaction relation |= ⊆ S ×LBPCTL

is defined, for all s ∈ S, as follows (to shorten our notation, we write s |= Φ to mean that (s,Φ) ∈|=):

• s |= tt (tt stands for true, so each state satisfies it);

• s |= p iff p(s) = 1;

• s |= Φ1 ∧ Φ2 iff s |= Φ1 and s |= Φ2;

• s |= ¬Φ iff s 6|= Φ (i.e., iff s |= Φ does not hold);

• s |= [XΦ]wα iff Prob{π ∈ Path(M, s) | π |= XΦ} w α, where

– π |= XΦ iff π(1) |= Φ;

• s |= [Φ1 U≤k Φ2]wα iff Prob{π ∈ Path(M, s) | π |= Φ1 U≤k Φ2} w α, where

– π |= Φ1 U≤k Φ2 iff ∃h ≤ k : (π(h) |= Φ2 and ∀i < h π(i) |= Φ1).

Moreover, let F be a BPCTL formula. Then, M |= F iff q |= F .

Finally, let S be a PFSS. Then, S |= F iff Smc |= F .

The two following definitions will be useful in the following.

Definition 2.10. A BPCTL formula Φ is said to be a U-formula iff there are two BPCTL formulas Φ1,Φ2 ∈LBPCTL, k ∈ N and α ∈ [0, 1] such that Φ ≡ [Φ1 U≤k Φ2]wα. Analogously, Φ is said to be a X-formulaiff there are a BPCTL formula Φ1 ∈ LBPCTL and α ∈ [0, 1] such that Φ ≡ [X Φ1]wα.

Definition 2.11. Let M = (S,P, q) be a Markov Chain, Φ,Ψ ∈ LBPCTL be BPCTL formulas, k ∈ N

and s ∈ S. Then we write Ps[Φ U≤k Ψ] for Prob{π ∈ Path(M, s) | π |= Φ U≤k Ψ}, and Ps[X Φ] forProb{π ∈ Path(M, s) | π |= X Φ}.

With overload of notation, if F ≡ [Φ U≤k Ψ]wα is a U-formula, we write Ps[F ] for Prob{π ∈Path(M, s) | π |= Φ U≤k Ψ}. Analogously, if F ≡ [X Φ]wα is a X-formula, we write Ps[F ] forProb{π ∈ Path(M, s) | π |= X Φ}.

Page 23: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

2.2 The BPCTL Language 11

2.2.1 BPCTL BOUNDED SEMANTICS

From Definition 2.9, we can intuitively see that the truth value for s |= Φ can be evaluated by takinginto account only paths of finite length k, provided that k is large enough and computing, when needed,Prob{π ∈ Pathk(M, s) | P(π)} (for some path property P) as

π | P(π)

P(π).

This is formally stated in Theorem 2.4: for all BPCTL formulas Φ, there exists a k ∈ N such that, for allstates s ∈ S and for all h ≥ k, s |=h Φ iff s |= Φ. This Section is dedicated to the proof of Theorem 2.4.

First of all, we have to give the semantics of |=k (Definition 2.12), which will be the same as |=, but will beundefined when it is necessary to take into consideration paths of length greater than k. Recall that 0 standsfor false and 1 stands for true.

Definition 2.12. Let M = (S,P, q) be a Markov Chain. Then, the satisfaction function |=: S × N ×LBPCTL → {⊥, 0, 1} is defined, for all s ∈ S, k ∈ N and Φ,Φ1,Φ2 ∈ LBPCTL, as follows (to shortenour notation, we write s |=k Φ for |= (s, k,Φ)):

• s |=k tt = 1

• s |=k p = p(s)

• s |=k ¬Φ =

{

⊥ if s |=k Φ =⊥

not s |=k Φ otherwise

• s |=k Φ1 ∧ Φ2 =

{

⊥ if s |=k Φ1 =⊥ or s |=k Φ2 =⊥

s |=k Φ1 and s |=k Φ2 otherwise

• s |=k [XΦ]wα =

{

⊥ if A

Prob{π ∈ Path(M, s) | π |=k XΦ = 1} w α otherwise

• s |=k [Φ1 U≤h Φ2]wα =

{

⊥ if B

Prob{π ∈ Path(M, s) | π |=k Φ1 U≤h Φ2 = 1} w α otherwise

where we pose, to make the last two formulas more readable,A ≡ ∃π ∈ Path(M, s) : π |=k XΦ =⊥ andB ≡ ∃π ∈ Path(M, s) : π |=k Φ1 U≤h Φ2 =⊥.

By simultaneous induction hypothesis the satisfaction function |=: PathM ×N×LBPCTL → {1, 0,⊥}, isgiven in the following (again, π |=k Φ =def |= (π, k,Φ)). Let π ∈ PathM and k ∈ N, then:

• π |=k XΦ =

{

⊥ if k < 1

π(1) |=k−1 Φ otherwise

• π |=k Φ1 U≤h Φ2 =

⊥ if C

∃j ∈ N : 0 ≤ j ≤ h and π(j) |=k−j Φ2

and (∀0 ≤ i ≤ j − 1 π(i) |=k−i Φ1) otherwise

where we pose, to make the last formula more readable, C ≡ (k < h) or (∃j ∈ N : 0 ≤ j ≤h and π(j) |=k−j Φ2 =⊥) or (∃j ∈ N : 0 ≤ j ≤ h− 1 and π(j) |=k−j Φ1 =⊥).

Finally, let Φ ∈ LBPCTL be a BPCTL formula. Then we put M |=k Φ =def q |=k Φ.

Page 24: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

12 Chapter 2. Theoretical Basis

Note that |=k is defined in a strict way, since π |=k Φ is sometimes set to ⊥ even when it could be evaluated.For instance, suppose that we have to evaluate π |=1 Φ, with Φ ≡ [[φ1 U≤2 φ2]≥0.5 U≤1φ3]≥0.6, being φ1,φ2 and φ3 atomic propositions; then, by Definition 2.12, π |=1 Φ =⊥. However, if π(0) and all the stateswhich are reachable from π(0) do not satisfy φ1, then π |=1 Φ could be evaluated. In fact, since s 6|= φ1

implies Ps[φ1 U≤2 φ2] = 0 6≥ 0.5, it is not necessary to examine, for all states s which are reachable in 1step from π(0), the paths of length 2 starting from s. We make this choice in Definition 2.12 because in thissection we are interested in the theoretical fact that exists a k such that s |=k Φ iff s |= Φ, and not in findingthe minimum of such k; moreover, we want this k to depend only on Φ, and not on the PFSS or MarkovChain under analysis. Of course, in the algorithm of Chapter 4 we consider also the performance aspect.

Definition 2.12 directly implies the following Lemma.

Lemma 2.1. Let M = (S,P, q) be a Markov Chain and Φ ∈ LBPCTL be a BPCTL formula. Then, for allk ∈ N, we have that (∀s ∈ S s |=k Φ 6=⊥) or (∀s ∈ S s |=k Φ =⊥).

Proof. The proof is by structural induction on Φ: supposing that ∀k ∈ N ((∀s ∈ S s |=k Φi 6=⊥) or (∀s ∈S s |=k Φi =⊥)) holds for all subformulas Φi of Φ, we show that ∀k ∈ N ((∀s ∈ S s |=k Φ 6=⊥) or(∀s ∈ S s |=k Φ =⊥).

As induction basis note that, if Φ is tt or an atomic proposition (i.e., it does not contain any subformula),then s |=k Φ 6=⊥ for all k ∈ N and s ∈ S, so the induction basis is proved. For the other cases, we have:

1. if Φ ≡ ¬Φ1, then, by Definition 2.12, we have that, for all k ∈ N and s ∈ S, s |=k Φ1 =⊥ iffs |=k Φ =⊥, so the induction step is proved;

2. if Φ ≡ Φ1 ∧ Φ2, then fix a k ∈ N. By induction hypothesis, we have the following cases:

(a) ∀s ∈ S s |=k Φ1 =⊥ and ∀s ∈ S s |=k Φ2 =⊥, so ∀s ∈ S s |=k Φ =⊥ and the induction stepis proved;

(b) ∀s ∈ S s |=k Φ1 6=⊥ and ∀s ∈ S s |=k Φ2 =⊥, so ∀s ∈ S s |=k Φ =⊥ and the induction stepis proved;

(c) ∀s ∈ S s |=k Φ1 =⊥ and ∀s ∈ S s |=k Φ2 6=⊥: as the previous case;

(d) ∀s ∈ S s |=k Φ1 6=⊥ and ∀s ∈ S s |=k Φ2 6=⊥, so ∀s ∈ S s |=k Φ 6=⊥ and the induction stepis proved;

3. if Φ ≡ [XΦ1]wα, then fix a k ∈ N. By induction hypothesis, we have the following cases:

(a) ∀s ∈ S s |=k Φ1 =⊥, so ∀s ∈ S s |=k Φ =⊥ and the induction step is proved;

(b) ∀s ∈ S s |=k Φ1 6=⊥, then, again by induction hypothesis, there are the following cases:

i. k < 1, so ∀s ∈ S s |=k Φ =⊥ and the induction step is proved;

ii. ∀s ∈ S s |=k−1 Φ1 6=⊥, so ∀s ∈ S s |=k Φ 6=⊥ and the induction step is proved;

iii. ∀s ∈ S s |=k−1 Φ1 =⊥, so ∀s ∈ S s |=k Φ =⊥ and the induction step is proved;

4. if Φ ≡ [Φ1 U≤h Φ2]wα, then fix a k ∈ N. By induction hypothesis, we have the following cases:

(a) ∀s ∈ S s |=k Φ1 =⊥ and ∀s ∈ S s |=k Φ2 =⊥, so ∀s ∈ S s |=k Φ =⊥ and the induction stepis proved;

(b) ∀s ∈ S s |=k Φ1 6=⊥ and ∀s ∈ S s |=k Φ2 =⊥, so ∀s ∈ S s |=k Φ =⊥ and the induction stepis proved;

(c) ∀s ∈ S s |=k Φ1 =⊥ and ∀s ∈ S s |=k Φ2 6=⊥: as the previous case;

(d) ∀s ∈ S s |=k Φ1 6=⊥ and ∀s ∈ S s |=k Φ2 6=⊥, then, again by induction hypothesis, there arethe following cases:

Page 25: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

2.2 The BPCTL Language 13

i. k < h, so ∀s ∈ S s |=k Φ =⊥ and the induction step is proved;ii. ∃0 ≤ j ≤ h : ∀s ∈ S s |=k−j Φ2 =⊥, so ∀s ∈ S s |=k Φ =⊥ and the induction step is

proved;

iii. ∃0 ≤ j ≤ h− 1 : ∀s ∈ S s |=k−j Φ1 =⊥, so ∀s ∈ S s |=k Φ =⊥ and the induction stepis proved;

iv. all the above three cases are false, so ∀s ∈ S s |=k Φ 6=⊥ and the induction step is proved.

Now, we want to compute a horizon k ∈ N such that, for all Φ ∈ LBPCTL, h ≥ k and s ∈ S, s |=h Φ iffs |= Φ. This k is given as a function of the BPCTL formula in Definition 2.13.

Definition 2.13. The function µ : LBPCTL → N is inductively defined as follows:

• µ(tt) = 0

• µ(p) = 0 for all atomic propositions p ∈ AP

• µ(¬Φ) = µ(Φ)

• µ(Φ1 ∧ Φ2) = max{µ(Φ1), µ(Φ2)}

• µ([XΦ]wα) = µ(Φ) + 1

• µ([Φ1 U≤h Φ2]wα) =

{

max{µ(Φ1) + h− 1, µ(Φ2) + h} if h ≥ 1

µ(Φ2) otherwise

We now demonstrate (Theorem 2.4) that the value returned by µ has the required properties. To do this, westart with two lemmas.

Lemma 2.2. Let M = (S,P, q) be a Markov Chain and Φ ∈ LBPCTL be a BPCTL formula. Then, ifthere exists a k ∈ N such that, for all states s ∈ S, s |=k Φ 6=⊥, then we have that, for all n ≥ k and forall states s ∈ S, s |=n Φ 6=⊥.

Proof. As for Lemma 2.1, the proof is by structural induction on Φ: supposing that ∀k ∈ N ((∀s ∈ S s |=k

Φi 6=⊥) ⇒ (∀n ≥ k ∀s ∈ S s |=n Φi 6=⊥)) holds for all subformulas Φi of Φ, we show that∀k ∈ N ((∀s ∈ S s |=k Φ 6=⊥) ⇒ (∀n ≥ k ∀s ∈ S s |=n Φ 6=⊥)).

As induction basis note that, if Φ is tt or an atomic proposition (i.e., it does not contain any subformula),then s |=k Φ 6=⊥ for all k ∈ N and s ∈ S, so the induction basis is proved. For the other cases, we have:

1. if Φ ≡ ¬Φ1, then, by Definition 2.12, we have that, for all k ∈ N and s ∈ S, s |=k Φ1 =⊥ iffs |=k Φ =⊥, so the induction step is proved;

2. if Φ ≡ Φ1 ∧ Φ2, then we have the following cases:

(a) ∀k ∈ N ∃s ∈ S : s |=k Φ =⊥, and the induction step is proved (however note that, by Lemma2.1, this implies that ∀k ∈ N ∀s ∈ S s |=k Φ =⊥; by Lemma 2.3, this is impossible);

(b) otherwise, let k ∈ N be such that ∀s ∈ S s |=k Φ 6=⊥. Then, by Definition 2.12, we have that∀s ∈ S s |=k Φ1 6=⊥ and ∀s ∈ S s |=k Φ2 6=⊥. By induction hypothesis, we have that ∀n ≥k ∀s ∈ S s |=n Φ1 6=⊥ and ∀n ≥ k ∀s ∈ S s |=n Φ2 6=⊥, so ∀n ≥ k ∀s ∈ S s |=n Φ 6=⊥and the induction step is proved;

Page 26: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

14 Chapter 2. Theoretical Basis

3. if Φ ≡ [XΦ1]wα, then we have the following cases:

(a) ∀k ∈ N ∃s ∈ S : s |=k Φ =⊥ and the induction step is proved (however, it holds the samereasoning of item 2a);

(b) otherwise, let k ∈ N be such that ∀s ∈ S s |=k Φ 6=⊥. Then, by Definition 2.12, we have thatk ≥ 1 and ∀π ∈ Path(M, s) π(1) |=k−1 Φ1 6=⊥; so, by Lemma 2.1, ∀s ∈ S s |=k−1 Φ1 6=⊥.By induction hypothesis, we have that ∀n ≥ k−1 ∀s ∈ S s |=n Φ1 6=⊥, so, again by Definition2.12, ∀n ≥ k ∀s ∈ S s |=n Φ 6=⊥ and the induction step is proved;

4. if Φ ≡ [Φ1 U≤h Φ2]wα, then we have the following cases:

(a) ∀k ∈ N ∃s ∈ S : s |=k Φ =⊥, and the induction step is proved (however, it holds the samereasoning of item 2a);

(b) otherwise, let k ∈ N be such that ∀s ∈ S s |=k Φ 6=⊥. Then, by Definition 2.12, we have thatk ≥ h and ∀j = 0, . . . , h ∀s ∈ S s |=k−j Φ2 6=⊥ and ∀j = 0, . . . , h − 1 ∀s ∈ S s |=k−j

Φ1 6=⊥. By induction hypothesis, we have that ∀n ≥ k − h ∀s ∈ S s |=n Φ2 6=⊥ and∀n ≥ k − h+ 1 ∀s ∈ S s |=n Φ1 6=⊥. Hence, ∀n ≥ k ∀s ∈ S s |=n Φ 6=⊥ and the inductionstep is proved.

Lemma 2.3. Let M = (S,P, q) be a Markov Chain and Φ ∈ LBPCTL be a BPCTL formula. Then, for allk ≥ µ(Φ), we have that, for all s ∈ S, s |=k Φ 6=⊥.

Proof. By Lemma 2.2, it is sufficient to prove that ∀s ∈ S s |=µ(Φ) Φ 6=⊥.

As for Lemmas 2.1 and 2.2, the proof is by structural induction on Φ: supposing that ∀s ∈ S s |=µ(Φi)

Φi 6=⊥ holds for all subformulas Φi of Φ, we show that ∀s ∈ S s |=µ(Φ) Φ 6=⊥.

As induction basis, we have that if Φ is tt or an atomic proposition (i.e., it does not contain any subformula),then it is never evaluated to ⊥. For the other cases, we have:

1. if Φ ≡ ¬Φ1, then by structural induction we know that, ∀s ∈ S s |=µ(Φ1) Φ1 6=⊥. Since µ(Φ) =µ(Φ1), and by Definition 2.12, for all k ∈ N and s ∈ S, s |=k Φ1 6=⊥ iff s |=k Φ 6=⊥, then we havethat for all s ∈ S, s |=µ(Φ) Φ 6=⊥, and the induction step is proved;

2. if Φ ≡ Φ1 ∧ Φ2, then by induction hypothesis we know that, ∀s ∈ S s |=µ(Φ1) Φ1 6=⊥6= s |=µ(Φ2)

Φ2. Since µ(Φ) = max{µ(Φ1), µ(Φ2)}, we have that µ(Φ) ≥ µ(Φ1) and µ(Φ) ≥ µ(Φ2), so byLemma 2.2 ∀s ∈ S s |=µ(Φ) Φ1 6=⊥6= s |=µ(Φ) Φ2. By Definition 2.12, we have that ∀s ∈S s |=µ(Φ) Φ 6=⊥;

3. if Φ ≡ [XΦ1]wα, then by induction hypothesis we know that, ∀s ∈ S s |=µ(Φ1) Φ1 6=⊥. ByDefinition 2.12, this statement, together with the fact that µ(Φ1) + 1 ≥ 1 (this holds since, for allΨ ∈ LBPCTL, µ(Φ) ≥ 0), implies that ∀s ∈ S s |=µ(Φ1)+1 Φ 6=⊥. Since µ(Φ) = µ(Φ1) + 1, wehave again that s |=µ(Φ) Φ 6=⊥;

4. if Φ = [Φ1 U≤h Φ2]wα, then by induction hypothesis we know that, ∀s ∈ S s |=µ(Φ1) Φ1 6=⊥6=s |=µ(Φ2) Φ2. Now, if h = 0, by Definition 2.12 we have that ∀k ∈ N ∀s ∈ S s |=k Φ 6=⊥ iffs |=k Φ2 6=⊥, so, being µ(Φ) = µ(Φ2), the induction step is proved. Otherwise, if h ≥ 1 thenµ(Φ) = max{µ(Φ1)+h−1, µ(Φ2)+h}. Suppose, by contradiction, that ∃s ∈ S : s |=µ(Φ) Φ =⊥.By Definition 2.12, at least one of these three conditions has to hold:

(a) µ(Φ) < h: this is impossible since, being µ(Ψ) ≥ 0 for all Ψ ∈ LBPCTL, we have thatµ(Φ) = max{µ(Φ1) + h− 1, µ(Φ2) + h} ≥ max{h− 1, h} = h;

Page 27: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

2.3 Finite State/Discrete Time Stochastic Processes 15

(b) there exists a π ∈ Path(M, s) such that ∃j ∈ N : 0 ≤ j ≤ h and π(j) |=µ(Φ)−j Φ2 =⊥.However, by induction basis we know that π(j) |=µ(Φ2)Φ2

6=⊥; moreover, µ(Φ) ≥ µ(Φ2) + h,so, for all j ≤ h, µ(Φ) − j ≥ µ(Φ2). These two facts imply, by Lemma 2.2 and inductionhypothesis, that π(j) |=µ(Φ)−j Φ2 6=⊥;

(c) there exists a π ∈ Path(M, s) such that ∃j ∈ N : 0 ≤ j ≤ h− 1 and π(j) |=µ(Φ)−j Φ1 =⊥.However, by induction basis we know that π(j) |=µ(Φ1)Φ1

6=⊥; moreover, µ(Φ) ≥ µ(Φ1)+h−1, so, for all j ≤ h−1, µ(Φ)−j ≥ µ(Φ1). These two facts imply, by Lemma 2.2 and inductionhypothesis, that π(j) |=µ(Φ)−j Φ1 6=⊥.

Now, we can give our main Theorem.

Theorem 2.4. Let M = (S,P, q) be a Markov Chain and Φ ∈ LBPCTL be a BPCTL formula. Then, forall k ≥ µ(Φ) and s ∈ S, we have that s |=k Φ iff s |= Φ.

Proof. The proof descends immediately from Lemma 2.3 and from the fact that, for all Φ ∈ LBPCTL,k ∈ N and s ∈ S, s |=k Φ 6=⊥ implies s |=k Φ = s |= Φ; the latter statement holds because Definitions2.9 and 2.12 are equal every time that the latter does not evaluate to ⊥.

Finally, we give a simple corollary of Theorem 2.4.

Corollary 2.5. Let M = (S,P, q) be a Markov Chain and Φ ∈ LBPCTL be a BPCTL formula. ThenM |=µ(Φ) Φ iff M |= Φ.

2.3 FINITE STATE/DISCRETE TIME STOCHASTIC PROCESSES

In this section, we give some basic definitions on Finite State/Discrete Time General Stochastic Processes;for more details on stochastic processes see, e.g., [49].

Definition 2.14. Let S be a finite set of states. A Finite State/Discrete Time Stochastic Process (shortenedSP in the following) is a triple X = (S,P, q) where q ∈ S is the initial state and the transition function

P : S × S∗ × S → [0, 1] is such that for all s ∈ S and π ∈ S∗,∑

t∈S

P(s, π, t) = 1.

Definition 2.15. An execution sequence (or path) in the SP X = (S,P, q) is a nonempty (finite or infinite)sequence π = s0s1s2 . . . where si are states and

P(si, s0 . . . si−1, si+1) > 0

for i ≥ 0. If π = s0s1s2 . . . we write π(k) for sk, and we write π|k for the sequence s0s1s2 . . . sk−1. Thelength of a finite path π = s0s1s2 . . . sk is k, i.e. the number of transitions, whereas the length of an infinitepath is ∞; we denote with |π| the length of π. We denote with Path(X , s) the set of infinite paths π in Xsuch that π(0) = s; finally, we write also Path(X ) for Path(X , q).

Page 28: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

16 Chapter 2. Theoretical Basis

Definition 2.16. Let X = (S,P, q) be a SP. For s ∈ S we denote with∑

(s) the smallest σ-algebra on Path(X , s) which, for any finite path ρ starting at s, contains the basic cylinders {π ∈Path(X , s) | ρ is a prefix of π}. The probability measure Prob on

(s) is the unique mea-

sure with Prob{π ∈ Path(X , s) | ρ is a prefix of π} = P(ρ) =k−1∏

i=0

P(ρ(i), ρ|i, ρ(i + 1)) =

P(ρ(0), ε, ρ(1))P(ρ(1), ρ|1, ρ(2)) · · ·P(ρ(k − 1), ρ|(k − 1), ρ(k)), where k = |ρ| and ε is the empty se-quence.

By Definition 2.3, it is clear that a Markov Chain is a particular SP, such that the transition functionP(s, π, t) actually does not depend on π (“lack of memory”) and therefore reduces to a stochastic matrix.

Example 2.5. Let S = {s0, s1} and X = (S,P, s0), with (remember that ε is the empty sequence ofstates):

P(s, π, t) =

12 if s = s0 and t = s0 and π = ε12 if s = s0 and t = s1 and π = ε

1 if s = s0 and t = s0 and π 6= ε and ∀0 ≤ k < |π| π(k) = s0

1 if s = s0 and t = s1 and π 6= ε and ∃0 ≤ k < |π| : π(k) = s1

1 if s = s1 and t = s1

0 otherwise

Here we have that Path(X ) = {π ∈ S∞ | π(0) = s0 and (∀k ≥ 1 π(k) = s0 or ∀k ≥ 1 π(k) = s1)} ={s∞0 , s0s

∞1 }.

Now, we want to verify BPCTL properties not only on Markov Chains, but also on SPs. However, thisobjective can be very difficult to reach, both from a computational and from an analytical point of view,also on very simple properties such as the safety ones [4, 13, 14]. So, the first task is to single out a largeenough class of tractable SP. So, we restrict our analysis to SP such that their transition probabilities dependonly on some fixed characteristics of the process history. We formalize this as follows.

Definition 2.17. Let X = (S,P, q) be an SP. We say that X has finite character n iff there exists anequivalence relation R on S∗ of finite index n (that is with n equivalence classes) such that for every π1,π2 ∈ S∗

if R(π1, π2) then ∀s, t ∈ S P(s, π1, t) = P(s, π2, t)

We will show (Chapter 5) that finite character SPs are expressible in a rather easy way in FHP-Murϕ. Thus,we can use the algorithms developed for Markov Chains analysis to analyze finite character SPs too. Thisis possible since each finite character SP X can be reduced to a Markov Chain Xmc; this is formalized inthe following.

Definition 2.18. Let X = (S,P, q) be a SP of finite character n w.r.t. a relation R, and let Q0, . . . , Qn−1

be an enumeration of the equivalence classes of R. Then, the Markov Chain Xmc = (S′,P′, q′) is definedas follows:

1. S′ = S × {0, . . . , n− 1};

2. q′ = (q, i0), where i0 is such that ε ∈ Qi0 ;

Page 29: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

2.3 Finite State/Discrete Time Stochastic Processes 17

3. let (s, i), (t, j) ∈ S′, then

P′((s, i), (t, j)) =

{

P(s, π, t) if ∃π ∈ S∗ : π ∈ Qi and πs ∈ Qj

0 otherwise

where we denote with πs the path obtained by appending the state s at the end of the path π. Notethat P′ is well defined: in fact, even if there is more than one path with the required property, all thesepaths, belonging to the same equivalence class (Qi in the formula above), define the same probability.

To see that Xmc is indeed a Markov Chain, we have to show that, for all (s, i) ∈ S ′,∑

(t,j)∈S′ P′((s, i), (t, j)) = 1; this holds since

(t,j)∈S′ P′((s, i), (t, j)) =

t∈S P(s, π, t) = 1, be-ing π ∈ S∗ such that π ∈ Qi and πs ∈ Qj .

Example 2.6. Let X = (S,P, s0) be the SP in Example 2.5. We have that X is an SP of finite character 3,with Q0 = {ε}, Q1 = {π ∈ S∗ | π 6= ε and ∀0 ≤ k < |π| π(k) = s0} and Q2 = (S∗\Q1)\Q0. So, wehave that Xmc = ({(s0, 0), (s0, 1), (s0, 2), (s1, 0), (s1, 1), (s1, 2)},P′, (s0, 0)), with

P′ =

0 12 0 0 1

2 0

0 1 0 0 0 0

0 0 0 0 0 1

0 0 0 0 0 1

0 0 0 0 0 1

0 0 0 0 0 1

We now show that there is a 1-1 relation between paths in finite character SPs and corresponding MarkovChains.

Definition 2.19. Let X = (S,P, q) be a SP of finite character n w.r.t. a relation R, and let Q0, . . . , Qn−1

be an enumeration of the equivalence classes of R. Let π ∈ Path(X , s) be a path in X . Then, the statesequence πmc is built in a way such that, for all h ≥ 0, πmc(h) = (π(h), ih), where ih is the index of theequivalence class such that π|h ∈ Qih

.

Proposition 2.6. Let X = (S,P, q) be a SP of finite character n w.r.t. a relation R, let Q0, . . . , Qn−1 bean enumeration of the equivalence classes of R and let Xmc = (S′,P′, q′). If π ∈ Path(X , s) is a path inX , then πmc is a path on Xmc (so, πmc ∈ Path(Xmc, q′)).

Proof. Since πmc is indeed made of states in S ′, so we only have to prove that, for all h ≥ 0,P′(πmc(h), πmc(h+ 1)) > 0.

To do this, fix an h; we have that P′(πmc(h), πmc(h+1)) = P′((π(h), ih), (π(h+1), ih+1)), where π|h ∈Qih

and π|(h+1) = (π|h)·π(h) ∈ Qih+1. By Definition 2.18, we have that P′((π(h), ih), (π(h+1), ih+1))

= P(π(h), π|h, π(h + 1)) > 0, where the last relation holds since π ∈ Path(X , s) by hypothesis.

Proposition 2.7. Let X = (S,P, q) be a SP of finite character n w.r.t. a relation R, let Q0, . . . , Qn−1 bean enumeration of the equivalence classes of R and let Xmc = (S′,P′, q′). If π ∈ Path(Xmc, q′) is a pathin Xmc, then it exists exactly one path ρ ∈ Path(X , s) such that ρmc = π.

Proof. Suppose that π = (π(0), i0)(π(1), i1) . . . (π(h), ih) . . .. ρ is also the path π(0)π(1) . . . π(h) . . .. Itis obvious to see that ρ is the unique path with the desired property, since a different path σ should have atleast a different state, so σmc 6= π.

Page 30: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

18 Chapter 2. Theoretical Basis

Finally, we show that the probability measure Prob on a PRBTS X (Definition 2.16) is equivalent to theone on the corresponding Markov Chain Xmc (Definition 2.5). This motivates the dissertation of Chapter5, in which we use our Markov Chain analysis algorithms to analyze also finite character SPs.

Proposition 2.8. Let X = (S,P, q) be a finite character SP, and let n,R,Q0, . . . , Qn−1, i0 be, respectively,the finite character of X , the relation w.r.t. which X is of finite character, the n equivalence classes of Rand the index of the equivalence class containing ε (i.e. i0 is such that ε ∈ Qi0 ). Then, for all finite paths ρof X ,

Prob{π ∈ Path(X , s) | ρ is a prefix of π} = Prob{π ∈ Path(Xmc, (s, i0)) | ρmc is a prefix of π}

Proof. By Definitions 2.16, 2.19 and 2.5 we have that Prob{π ∈ Path(X , s) | ρ is a prefix of π} =

P(ρ) =

k−1∏

h=0

P(ρ(h), ρ|h, ρ(h + 1)) =

k−1∏

h=0

P′((ρ(h), ih), (ρ(h + 1), ih+1)) = P′(ρmc) = Prob{π ∈

Path(Xmc, (s, i0)) | ρmc is a prefix of π}.

2.4 THE MURϕ VERIFIER

In this section we give a short overview of the Murϕ verifier. For further details we refer the reader to[22, 47].

We begin by giving the definition of the model underlying the Murϕ verifier.

Definition 2.20. A Nondeterministic Finite State System (shortened NFSS in the following) S is a 4-tuple(S, I,A,next), where S is a finite set of states, I ⊆ S is the set of the initial states, A is a finite set oflabels and next : S → 2S×A is a function taking a state s as argument and returning a set next(s) ofpairs (t, a) ∈ S ×A.

Note that the definition of NFSS is a simpler version of Definition 2.6 of PFSS, since it does not considerprobabilities. Thus, NFSSs function next returns, given a state s, the states in which s may go, togetherwith a label to manage the case of multiple transitions between the same states.

From a conceptual point of view Murϕ takes as input a NFSS S and checks whether a given invariantproperty φ for S is satisfied.

An invariant property can be seen as a map from (the states of) S to the set B of boolean values; usingthe speech of Section 2.2, it is an atomic proposition. Thus, the verification goal is to check if the giveninvariant φ holds in each state s reachable from an initial state q ∈ I (i.e., φ(s) = 1). Of course, in general,this check entails visiting all reachable system states.

Figure 2.4 shows the standard BF (Breadth-First) state space exploration algorithm. Essentially this is thealgorithm used by Murϕ to visit the state space of a given system S. The algorithm makes use of two mainmemory data structures. A Queue, where states are stored and retrieved (in FIFO order) during the search,and a Hash Table used to store all visited states.

Since S is a finite state system, the algorithm in Figure 2.4 always terminates since we never visit the samestate more than once.

Page 31: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

2.4 The Murϕ Verifier 19

FIFO Queue Q;HashTable T;

/* Returns true iff φ holds in all the reachable states */bool BFS(NFSS S, AP φ){let S = (S, I,A, next);

/* is there an initial state which is an error state? */foreach s in I{

i f (!φ(s))/* error found, S does not satisfy φ */re turn f a l s e;

}

/* load Q with initial states */foreach s in I Enqueue(Q, s);

/* mark the initial states as visited */foreach s in I H a s h I n s e r t(T, s);

/* visit */whi le (Q 6= ∅){/* take from Q the state to be expanded */s = Dequeue(Q);/* s expansion */foreach (s_next, a) in n e x t(s){

i f (!φ(s_next))/* error found, S does not satisfy φ */re turn f a l s e;

i f (s_next i s not in T){/* s next must be eventually expanded */Enqueue(Q, s_next);/* mark s next as visited */H a s h I n s e r t(T, s_next);

} /* if */} /* foreach */

} /* while *//* here, Q is empty and T contains all the reachable states *//* error not found, S satisfies φ */re turn true;

} /* BFS() */

Figure 2.4: Explicit Breadth–First Search

Page 32: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

20 Chapter 2. Theoretical Basis

2.4.1 MURϕ INPUT LANGUAGE

Murϕ input consists of a definition of the system S to be verified and a definition of the property φ to bechecked. Both definitions are stored in a file that we call here Murϕ description.

The Murϕ description language for system S is a high-level programming language for finite state asyn-chronous concurrent systems (i.e. software like systems). Murϕ description language is high-level in thesense that many features found in common high-level programming languages such as Pascal or C are partof Murϕ. For example, Murϕ has user-defined data types, procedures, and parameterization of descriptions.

More in detail, a Murϕ description consists of:

• a set of declarations of constants, (finite) types, global variables;

• a collection of declarations of functions and procedures;

• a description of the initial states;

• a collection of transition rules;

• a set of invariants.

Note that the declaration of the global variables defines the Murϕ state. In fact, a Murϕ state is an assign-ment of values to all of the global variables of the description. Hence, if the types of the global variables arethe finite sets D1, . . . , Dn, and the NFSS to be described is S = (S, I,A,next), then S = D1× . . .×Dn.

Thus, global variables defines the (static) structure of the model. On the other hand, the behavioral part (i.e.,function next) of Murϕ is the collection of transition rules. Each transition rule is a guarded commandwhich consists of a condition (a boolean expression on the global variables) and an action (a statement thatcan modify the values of the variables).

The condition and the action are both written in a Pascal-like language. The action can be an arbitrarilycomplex statement containing loops and conditionals. No matter how complex it is, the action is executedatomically, i.e. no other rule can change the variables or otherwise interfere with it while it is being exe-cuted. More formally, if a rule r causes state s to become t, then next(s) ⊇ {(t, r)}.

Thus, an execution of the description is generated by executing the endless loop in Figure 2.5.

Note that nondeterministic aspect of Murϕ descriptions is exploited in the two random choices in Figure2.5. The user has no control over how these choices are made, so a correct Murϕ program must do the rightthing no matter which rules are chosen. However, once a rule has been chosen, the action is deterministic(there is a unique next state).

2.4.2 A TOY EXAMPLE

A small toy example should help to clarify the matter. Let us consider the finite state system S in Figure2.6. The initial state of S is shown, as usual, with an ingoing arrow; moreover, nodes are labeled with statevalues and edges are labeled with disturbance values.

Murϕ code for the NFSS S of Figure 2.6 is given in Figure 2.7 where we have examples of constants, types,global variables, functions, initial states, transition rules and invariants.

Page 33: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

2.4 The Murϕ Verifier 21

/* Make a random walk in the NFSS described by MD */void Make_a_run(MurϕDescription MD){pick at random an initial state s among the ones in MD;s_current = s;whi le (1) { /* loop forever */RulesEnabled = ∅;foreach rule r in MD{

i f (the r guard i s satisfied by s_current)RulesEnabled = RulesEnabled ∪ r;

} /* foreach */pick at random a rule r in RulesEnabled;execute the r body on s_current, so obtaining s_next;s_current = s_next;

} /* while */} /* Make_a_run() */

Figure 2.5: Murϕ execution model

Figure 2.8 summarizes the output of the Murϕ verifier when given the input in Figure 2.7. Namely, theMurϕ verifier returns an error trace, i.e. a (loopless) path in the graph in Figure 2.6 from an initial state toa state violating the invariant property. If we replace the < sign in the invariant in Figure 2.7 with ≤ thenthe invariant property is always satisfied since all reachable states of S have a value less than or equal to 5(see Figure 2.6).

Remark 2.1. In the BF algorithm in Figure 2.4 only reachable states are visited and thus stored in the hashtable T. Hence the set of reachable states depends only on the system dynamics. For example, the set ofreachable states for the NFSS defined in Figure 2.6 is the integer interval [0, 5]. This set does not depend onstate type (the type of variable x in Figure 2.7) as long as state type contains the integer interval[0, 5]. For example if in Figure 2.7 we change state type declaration to state type : 0..100the set of reachable states is still the integer interval [0, 5].

0

1

2

3

4

50

1

2

1

2

1

2

1

2

2

1

20 0

0 0

01

Figure 2.6: A Nondeterministic Finite State System

Page 34: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

22 Chapter 2. Theoretical Basis

/* constant declarations */c o n s tMAX_STATE_VALUE : 5;MAX_DISTURB : 2;

/* type declarations */type/* integers from 0 to 10 */state_type : 0 .. 10;/* integers from 0 to 2 */disturbance_type : 0 .. MAX_DISTURB;

/* (global) variable declarations */var/* x is a variable of type state_type */x : state_type;

/* define next state function */f u n c t i o n next(x: state_type; d : disturbance_type): state_type;begin

i f (x <= MAX_STATE_VALUE - MAX_DISTURB) thenre turn (x + d);

e l s ere turn (x - d);

e n d i fend;

/* define initial state */s t a r t s t a t e "startstate"

beginx := 0;

end;

/* nondeterministic disturbances trigger system transitions */r u l e s e t d : disturbance_type do/* define parametric transition rule *//* here, d varies in disturbance type, thus there are MAX DISTURB

+ 1 variants of rule "time step" */r u l e "time step" t rue ==>beginx := next(x, d);

end;end;

/* define property to be verified */i n v a r i a n t "x is not too big"(x < MAX_STATE_VALUE);

Figure 2.7: Murϕ code for the NFSS in Figure 2.6

Page 35: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

2.4 The Murϕ Verifier 23

Startstate startstate fired.x:0----------Rule time step, d:1 fired.x:1----------Rule time step, d:2 fired.x:3----------Rule time step, d:2 fired.The last state of the trace(in full) is:x:5----------

Figure 2.8: Murϕ error trace for Murϕ model in Figure 2.7

Page 36: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor
Page 37: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

CHAPTER 3

VERIFICATION OF SAFETY PROPERTIES

In this chapter, we will illustrate an algorithm for the verification of Discrete Time Markov Chains. Thisalgorithm is only able to verify finite horizon safety properties, e.g. it is able to state if the system underanalysis has an acceptable error probability. In Chapter 4 we will introduce a more general algorithm.

The chapter is organized as follows. In Section 3.1, we give the idea on which our algorithm lies. Then,in Section 3.2 we will describe our algorithm in a more detailed way; here, we also give a proof of thealgorithm correctness and sketch its implementation within the Murϕ verifier. Section 3.3 close the chapterby showing some meaningful experimental results and making a comparison with PRISM performances.

3.1 FINITE HORIZON SAFETY VERIFICATION OF MARKOV CHAINS

We suppose we are given the following objects:

• a Markov Chain M = (S,P, q);

• an atomic proposition φ ∈ AP ;

• an integer k ∈ N;

• a probability threshold α ∈ [0, 1].

We want to design an algorithm able to check if p ≤ α, where p is the probability that a path of length kstarting from q reaches a state s satisfying φ (i.e. φ(s) = 1).

By using the notation of Section 2.2, this is equivalent to verify the following BPCTL formula:

q |= ¬[tt U≤k φ]>α. (3.1)

Note that, if φ models an error condition, this computation allows us to compute the probability that thesystem modeled by M reaches an erroneous configuration in k execution steps. Thus, there are few prop-erties that are verifiable via this algorithm, but they are important properties. In the rest of this chapter, wewill refer to states s such that φ(s) = 1 as error states.

We now give some definitions and propositions which will be useful to understand how the algorithmworks. Here, our main goal is to compute P [tt U≤k φ] (see Definition 2.11), since once this value has beenobtained, the truth value of (3.1) is straightforward.

We begin with a definition of a Markov Chain derived from M by means of φ.

25

Page 38: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

26 Chapter 3. Verification of Safety Properties

Definition 3.1. Let M = (S,P, q) be a Markov Chain and let φ : S → B be an atomic proposition. Wedefine Markov Chain Mφ as follows: Mφ = (S,Pφ, q), where for all s, t ∈ S,

Pφ(s, t) =

P(s, t) if ¬φ(s)

1 if φ(s) and (s = t)

0 if φ(s) and (s 6= t)

To see that Mφ is indeed a Markov Chain, it is sufficient to show that, for all s ∈ S,∑

t∈S Pφ(s, t) =1; this is true since, if φ(s) = 1, then

t∈S Pφ(s, t) = Pφ(s, s) = 1; otherwise, if φ(s) = 0, then∑

t∈S Pφ(s, t) =∑

t∈S P(s, t) = 1 (M is a Markov Chain by hypothesis).

In other words, Markov Chain Mφ is obtained from M by replacing all outgoing edges from any errorstate s with just one edge leading back to s. Thus, once an error state is entered, Mφ is forced to cycle onit. This is equivalent to say that, if a path leads to an error state s, then it necessarily goes on repeating s;more formally, if in a path π ∈ Path(Mφ) there exists a n ∈ N such that φ(π(n)) = 1, then, for all h > n,π(h) = π(n). This, in turn, entails that for Mφ the probability of reaching a state s satisfying φ in exactlyk steps equals the probability of reaching s in at most k steps.

Definition 3.1 is useful in Proposition 3.2, which our algorithm is based on. In order to prove Proposition3.2, we have to enunciate Lemma 3.1.

Lemma 3.1. Let M = (S,P, q) be a Markov Chain, let k ∈ N be an integer, and let φ : S → B be anatomic proposition. Then,

Prob{π ∈ Path(M) | ∃i ≤ k : φ(π(i))} = Prob{π ∈ Path(Mφ) | φ(π(k))}

Proof. Note that, for all k ∈ N, we can limit to finite paths, so Prob{π ∈ Path(M) | ∃i ≤ k : φ(π(i))} =Prob{π ∈ Pathk(M) | ∃i ≤ k : φ(π(i))} and Prob{π ∈ Path(Mφ) | φ(π(k))} = Prob{π ∈Pathk(Mφ) | φ(π(k))}. Thus, it is sufficient to prove that

Prob{π ∈ Pathk(M) | ∃i ≤ k : φ(π(i))} = Prob{π ∈ Pathk(Mφ) | φ(π(k))}

To this end, we will use the sequent objects:

• φk(Pathk(M)) = {π ∈ Pathk(M) | ∃i ≤ k : φ(π(i))}; this is the set Pathk without the paths onwhich φ never holds;

• mk(φ, π) = min{0 ≤ i ≤ k | φ(π(i))}, where π ∈ φk(Pathk(M)); this is a function which, givenφ and a path π on which φ holds, returns the index of the first state of π on which φ holds;

• Pathφ(M) = {ρ = s0 . . . si | ∃π ∈ φk(Pathk(M)) : (ρ is a prefix of π ∧ i = mk(φ, π)))}; foreach path π in φk(Pathk(M)), this set contains the prefix of π that ends in the first state satisfyingφ.

To shorten formulas, we define A = φk(Pathk(M)), B = Pathφ(M), D = φk(Pathk(Mφ)), m =mk(φ, π) and C = Pathk−mk(φ,π)((S,P, π(mk(φ, π)))). Hence we have that

Prob{π ∈ Pathk(M) | ∃i ≤ k : φ(π(i))} =

Page 39: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

3.1 Finite Horizon Safety Verification of Markov Chains 27

Prob{π ∈ Pathk(M) | π ∈ A} =∑

π∈A

k−1∏

j=0

P(π(j), π(j + 1)) = (3.2)

π∈B

m−1∏

j=0

P(π(j), π(j + 1))

ρ∈C

k−m−1∏

h=0

P(ρ(h), ρ(h+ 1))

= (3.3)

π∈B

m−1∏

j=0

P(π(j), π(j + 1)) =∑

π∈B

m−1∏

j=0

P(π(j), π(j + 1))

(

k−1∏

h=m

1

)

= (3.4)

π∈D

k−1∏

j=0

Pφ(π(j), π(j + 1)) = Prob{π ∈ Pathk(Mφ) | ∃i ≤ k : φ(π(i))} =

Prob{π ∈ Pathk(Mφ) | φ(π(k))}

In the passage (3.2) we have used the Definition 2.5, while in transforming (3.3) to (3.4) we have usedthe fact that, if M′ = (S′,P′, q′) is a Markov Chain, then for all s ∈ S ′, n ∈ N and 1 ≤ k ≤ n,∑

π∈Pathn(M′,s)

∏k−1j=0 P′(π(j), π(j + 1)) = 11. Moreover, the final equivalence is due to Definition 3.1:

in fact, a π ∈ Pathk(Mφ), when reaches a state s in which φ holds, is forced to infinitely cycle on s withprobability 1 (every other transition from s has probability 0, so it is not activated).

Proposition 3.2. Let M = (S,P, q) be a Markov Chain, φ : S → B be an atomic proposition and q bethe distribution representing q. Then,

P [tt U≤k φ] = Prob{π ∈ Path(M) | ∃i ≤ k : φ(π(i))} =∑

s | φ(s)

(qPφk)s

Proof. By Lemma 3.1, it is sufficient to prove that

Prob{π ∈ Path(Mφ) | φ(π(k))} =∑

s | φ(s)

(qPφk)s

From Markov Chain theory [3], we have that, for all s ∈ S,

Prob{π ∈ Path(Mφ) | π(k) = s} = (qPφk)s

So, we have that

Prob{π ∈ Path(Mφ) | φ(π(k))} =

1This is an obvious property of Markov Chains, and it is a direct consequence of the Markov Chain property that, for all s ∈ S ′,P

t∈SP

′(s, t) = 1. Intuitively, both these two properties states that, if we are in a state s, then we surely go somewhere (includingcycling in s). The only difference is that the latter property only holds for 1 step, while the above one holds for any number of steps.

Page 40: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

28 Chapter 3. Verification of Safety Properties

Prob{π ∈ Path(Mφ) | ∨s | φ(s) π(k) = s} =∑

s | φ(s)

Prob{π ∈ Path(Mφ) | π(k) = s} =

s | φ(s)

(qPφk)s

Example 3.1. Let S = {s0, s1} and M = (S,P, s0), with

P =

(

45

15

710

310

)

A graphical representation of M is shown in Figure 3.1.

Now, let φ be defined as follows: φ(s) = (s = s1), i.e. only state s1 satisfies φ. Then, we have that

P0φ = I =

(

1 0

0 1

)

P1φ = Pφ =

(

45

15

0 1

)

P2φ =

(

1625

925

0 1

)

P3φ =

(

64125

61125

0 1

)

So, by Proposition 3.2, we haveP [tt U≤0 φ] =((

1 0)

P0φ

)

s1

= 0; P [tt U≤1 φ] =((

1 0)

P1φ

)

s1

= 15 ; P [tt U≤2 φ] =

((

1 0)

P2φ

)

s1

= 925 ; P [tt U≤3 φ] =

((

1 0)

P3φ

)

s1

= 61125 .

45 s1s0

15

710

310

Figure 3.1: Graphical representation of the Markov Chain M of Example 3.1

Proposition 3.2 suggests the idea that P [tt U≤k φ] may be computed by generating qPφk; after having

done this, it is not difficult to make the summation on the error states. So, we design an algorithm which,by making a Breadth First (BF) visit of M, computes, for each BF level 0 ≤ i ≤ k − 1, the distributionqPφ

i as the content of the next level BF queue.

In Figure 3.2 we show function compute P, which realizes this computation. From a formal point of view,compute P does not take as input a Markov Chain, since in Section 2.1.1 we have defined PFSSs as theway which is used to define a Markov Chain. Thus, compute P input is a PFSS S, an integer k ∈ N

and an atomic proposition φ ∈ AP , while the output is P [tt U≤k φ] on the Markov Chain Smc. To thisend, w.r.t function BFS of Figure 2.4, we have that in compute P no check on already visited states isdone, and only non-error states are enqueued (as suggested by Proposition 3.2). Moreover, P [tt U≤k φ] iscomputed via variable prob err, which is incremented every time that an error state is encountered.

Page 41: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

3.1 Finite Horizon Safety Verification of Markov Chains 29

Note that our algorithm is designed in order to avoid the generation of the transition matrix for MarkovChain Smc, which is usually huge because of the known state explosion problem. The correctness offunction compute P of Figure 3.2 is proved in Proposition 3.4, by means of Lemma 3.3.

Lemma 3.3. Let S = (S, q,A,next) be a PFSS, k ∈ N be a nonnegative integer and φ : S → B bean atomic proposition such that φ(q) = 0. Then, for all 0 ≤ i ≤ k holds the following. At the beginningof level i in function compute P(S, k, φ), Q curr contains n pairs (s1, p1), . . . , (sn, pn), where n is thenumber of the paths π1, . . . , πn such that, for all 1 ≤ m ≤ n, πm satisfies the following properties:

1. |π| = i;

2. π(0) = q;

3. π(i) = sm;

4. P(π) = p;

5. for all 0 ≤ j ≤ i, φ(π(j)) = 0.

Proof. The proof is done by induction on i.

As induction basis, we have that, at the beginning of BF level 0, Q curr contains only the pair (q, 1), andin fact the only path of length 0 starting from q is q itself; finally, φ(q) = 0 and P(q) = 1 (i.e. the pathconsisting only of q has probability 1).

As induction step, we suppose our statement valid for i, and we prove it for i+1. To this end, let π1, . . . , πn

be the paths of length i+ 1 starting from q such that, for all 1 ≤ m ≤ n and 0 ≤ j ≤ i+ 1, φ(πm(j)) = 0.Moreover, let Q curri be the queue Q curr at the beginning of level i. By induction hypothesis we havethat, for all 1 ≤ m ≤ n, the pairs (πm(i),P(πm|(i + 1))) (i.e., these pairs contains the last but onestate of the path, together with the probability of the path πm without the last state) were stored in thequeue Q curri. During the level i computation, these pairs are dequeued and expanded to create the queueQ curri+1 (via the queue Q nexti+1).

Now, suppose by contradiction that exists a 1 ≤ m ≤ n such that (πm(i + 1),P(πm)) is not enqueued inQ curri+1 during the level i computation. Since, by induction hypothesis, (πm(i),P(πm|(i + 1))) is onQ curri, we have that (πm(i + 1),P(πm)) will be eventually enqueued in Q curri+1. In fact, P(πm) =P(πm|(i+1))P(πm(i), πm(i+1)) and compute P makes exactly this computation, with p= P(πm|(i+1)) (it is taken from Q curri) and p next= P(πm(i), πm(i+1)). Moreover, no error states are enqueuedat this level, so by induction hypothesis for all 1 ≤ m ≤ n and 0 ≤ j ≤ i+ 1, φ(πm(j)) = 0.

On the other hand, suppose by contradiction that a pair (s, p) is enqueued in Q curri+1, but for all 1 ≤m ≤ n (s, p) 6= (sm, pm) . By induction hypothesis, Q curri contains only pairs (πm(i),P(πm|(i+ 1)))satisfying conditions 1-5; thus, since only the states in Q curri are expanded, we have that there exists1 ≤ m1, . . . ,mh ≤ n such that s = πml

(i + 1) = smlfor all 1 ≤ l ≤ h. Hence, p 6= pml

= P(πml)

has to hold for all 1 ≤ l ≤ h. However, take a 1 ≤ l ≤ h; then, p is computed as p ∗ p next =P(πml

(i+ 1))P(πml(i), πml

(i+ 1)) = P(πml) = pml

(where the last equivalence holds for the proof ofthe first part of this lemma). This contradiction ends the proof.

Proposition 3.4. Let S = (S, q,A,next) be a PFSS, k ∈ N be a nonnegative integer and φ : S → Bbe an atomic proposition. Then, function compute P(S, k, φ) of Figure 3.2 returns P [tt U≤k φ] (on theMarkov Chain Smc).

Page 42: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

30 Chapter 3. Verification of Safety Properties

/* Compute P [tt U≤k φ] on the Markov Chain Smc */compute_P(PFSS S, i n t k, AP φ){Let S = (S, q,A, next);/* if the initial state is itself an error state, the error

is reached with probability 1, since the initial stateis reachable with probability 1 */

i f (φ(q))re turn 1;

/* prob err accumulates P [tt U≤k φ] */prob_err = 0;/* Q curr and Q next are queues of state-probability pairs */Q_curr = ∅;Q_next = ∅;/* initially, the only state to be expanded is the initial

one */Enqueue(Q_curr, (q, 1));/* BF levels from 0 to k - 1 */foreach i s. t. 0 ≤ i ≤ k - 1{/* BF level i begins */whi le(Q_curr 6= ∅){/* dequeue from the current level... */(s, p) = Dequeue(Q_curr);/* s expansion */foreach (s_next, a, p_next) in n e x t(s){

i f (φ(s_next))/* s next is an error state */prob_err = prob_err + p*p_next;

e l s e/* ...enqueue in the next level */Enqueue(Q_next, (s_next, p*p_next));

} /* foreach */} /* while *//* BF level i finished, we now have to expand the states in

Q next */Q_curr = Q_next;Q_next = ∅;

} /* foreach *//* exploration ended, now prob err contains the searched

value, i.e. P [tt U≤k φ] */re turn prob_err;

} /* compute_P() */

Figure 3.2: Computation of P [tt U≤k φ].

Page 43: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

3.2 Explicit Finite Horizon Safety Verification of Markov Chains 31

Proof. Let M = Smc. By Proposition 3.2, we have to show only that the final value of prob err is∑

s | φ(s)

(qPφk)s. To this end, let Π(s, k, r) = {π ∈ Pathk(Mφ, s) | π(k) = r} and Π(s, φ, k, r) = {π ∈

Path≤k(M, s) | ∃ρ ∈ Pathk(Mφ, s)∃0 ≤ i ≤ k : ρ(i) = r and ∀j < i ρ(j) 6= r and π = ρ|(i + 1) =ρ0 . . . ρi} (i.e. Π(s, φ, k, r) contains all the paths of length at most k leading from s to r without goingthrough error states). Then, we have that

s | φ(s)

(qPφk)s = (3.5)

s | φ(s)

π∈Π(q,k,s)

Pφ(π) =∑

s | φ(s)

π∈Π(q,φ,k,s)

Pφ(π) = (3.6)

s | φ(s)

π∈Π(q,φ,k,s)

P(π) (3.7)

Here, the passage from (3.5) and (3.6) is a known property of Markov Chains [3]; the other passages aredue to the definition of Pφ (Definition 3.1).

To complete the proof, we only have to observe that, by Lemma 3.3 and its proof, (3.7) is exactly thecomputation carried out for variable prob err in function compute P. In fact, the queue contains, for alllevel i, the paths in {π ∈ Π(q, φ, i, s) | |π| = i and φ(s) = 0}, while the ones in {π ∈ Π(s, φ, i, r) | ∃1 ≤j ≤ i : φ(π(j)) = 1} are used to increment prob err.

3.2 EXPLICIT FINITE HORIZON SAFETY VERIFICATION OF MARKOV

CHAINS

In this section, taking as starting point the function compute P of Figure 3.2, we will present an efficientdisk based explicit algorithm which, given a PFSS S and a BPCTL formula F of the form (3.1), checks ifS |= F , i.e. if it holds that P [tt U≤k φ] ≤ α.

3.2.1 ALGORITHM DESCRIPTION

Our algorithm makes use of the following data structures:

M is a cache table storing, for each slot, a pair (state, probability); the two fields of each slot are identified bythe names state and prob, respectively. It has a fixed size, set at the beginning of the verificationas a parameter.

Q curr, Q next are, respectively, the queues for the current and the next level front of the BF visit.Since M does not grow, these are the only data structures which may fill the memory. However,our implementation is designed in order to efficiently use the disk when the available RAM is notsufficient to store both M and the queues (see Section 3.2.3).

Page 44: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

32 Chapter 3. Verification of Safety Properties

From the behavioral point of view, instead, our algorithm is composed of three main functions:

Safety (Figure 3.3) efficiently implements the computation described in Figure 3.2, by making use ofthe other (auxiliary) functions.

Insert (Figure 3.4) uses a cache table M in RAM to reduce the queue length, thus saving computationtime. In fact, every time it is necessary to enqueue a new pair (state s, probability p), Insert(s,p) is called. If a pair (s, p′) is already stored in cache M, we simply update the stored probabilityp′ in M, adding p to it; otherwise, we store (s, p) in M. If this causes a collision (i.e., if the slot of Min which we have to put (s, p) is already occupied), we call function Checktable to empty M andthus free the needed cache slot.

Checktable (Figure 3.4) simply flushes M into Q next. It is actually the only function that enqueuesvalues in Q new and is used by function Insert to free M when a collision occurs. Checktableis also called at the end of the while in function Safety (Figure 3.3), so that all states reached inthe current level will be expanded in the next one.

Remark 3.1. The algorithm described in Figures 3.3 and 3.4 extends the compute P function of Figure3.2 by means of a cache table M. Indeed, M is used as a temporary buffer before inserting a state and itsprobability in the queue, thus avoiding the insertion of some duplicates. Moreover, if no collision occurs, allduplicates are avoided. In fact, if we were not using M, for each state s at level i we would have n copies ofs in the queue, where n is the number of paths of length i leading to state s from initial state q without goingthrough an error state (this is exactly what happens in Figure 3.2, see Lemma 3.3). On the other hand, byusing M and assuming that there are no collisions, these n copies collapses in one cache slot. Thus, ourqueue will contain, after the call to Checktable at the end of the level, one copy of s. On the other hand,if some collisions occur in M, we will have h copies of s in the queue, with h << n. More formal details onwhat happens to the cache and the queue may be found in Section 3.2.2.

Obviously, this mechanism saves queue space as well as computation time. In fact, if the RAM available forM grows, there will be less collisions, hence less duplicated states in the queue, so the number of states tobe explored decreases and, finally, the computation time is reduced. In this way we are creating a trade-offbetween space and time; for this reason, M should be as large as possible.

3.2.2 ALGORITHM CORRECTNESS

To prove the correctness of the algorithm shown in Figures 3.3 and 3.4, we only have to show that thecaching mechanism does not affect the validity of Proposition 3.4. To show this, consider again the algo-rithm without the cache (Figure 3.2); as we showed in Lemma 3.3, if there are n paths π1, . . . , πn leadingfrom q to s in i steps without going through an error state, then at the end of level i there will be n copies ofs in the queue. Suppose now thatm of these copies, namely (s, pi1), . . . , (s, pim

) (withm ≤ n), collapse inonly one queue entry, together with the sum of the corresponding probabilities, i.e. the queue now contains(s, p), being

∑mj=1 pij

, instead of the m entries (s, pi1), . . . , (s, pim). It is easy to see that the computation

of prob err still remains correct. In fact, if φ(s) = 0 prob err will not be updated, otherwise it will beincremented directly by p in the algorithm with the cache, and by

∑mj=1 pij

(withm different incrementingstatements) with the other one.

Thus, to prove the correctness of function Safety, it is sufficient to show that the caching mechanismjust collapses states in the queue as described above. To this end, suppose that a state s is reached n timesin BF level j, from the queue pairs (s1, p1), . . . , (sn, pn) (note that could happen that si = sj for some1 ≤ i, j ≤ n). If no cache collision occurs at level j, then there will be a cache slot h such that M[h] = (s, p),with p =

∑ni=1 piP(si, s). Thus, instead of n pairs (s, p1), . . . , (s, pn), being pi = piP(si, s), only one

pair (s, p) will be enqueued (when level j finishes). Since p =∑n

i=1 piP(si, s), the computation is correctby the above reasoning.

Page 45: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

3.2 Explicit Finite Horizon Safety Verification of Markov Chains 33

/* Main function, returns true iff S |= F */bool Safety(PFSS S, formula F){Let S = (S, q,A, next);Let F ≡ ¬[tt U≤k φ]>α;/* this function works only if F is of the above type */i f (φ(q))

re turn true;prob_err = 0;Enqueue(Q_curr, (q, 1));

foreach i s. t. 0 ≤ i ≤ k - 1{/* M is a cache table for the current BF level, so it has

to be cleared at the beginning of the level itself */clear all slots in M;

whi le (Q_curr 6= ∅){(s, p) = Dequeue(Q_curr);/* s expansion */foreach (s_next, a, p_next) in n e x t(s){

i f (φ(s_next)){prob_err = prob_err + p*p_next;i f (prob_err > α)/* property does not hold */re turn f a l s e ;

} /* if */e l s e/* Instead of enqueuing in Qnext, M is used */Insert(s_next, p*p_next);

} /* foreach */} /* while */

/* here, Q curr is empty but Q next does not contain all thestates to be expanded */

Checktable();/* now Q_next contains all the states to be expanded */Q_curr = Q_next;Q_next = ∅;

} /* foreach */

/* property holds */re turn true;

} /* Safety() */

Figure 3.3: Function Safety

Page 46: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

34 Chapter 3. Verification of Safety Properties

/* Manage the accesses to M */Insert(state s, double p){h = hash(s);

i f (M[h] i s free){/* insert the pair (s, p) in M */M[h].state = s;M[h].prob = p;

} /* if */e l s e i f (M[h].state == s)/* the probability to reach s is the preceding one plus the

new probability p, thus update M[h].prob */M[h].prob = M[h].prob + p;

e l s e{/* s could not be inserted, since its slot is occupied by

another state */Checktable();/* there is space to insert now */

/* now, the pair (s, p) can be inserted in M */M[h].state = s;M[h].prob = p;

} /* else */} /* Insert() */

/* Empty M by filling Q next */Checktable(){move M in Q_next and clear M;

} /* Checktable() */

Figure 3.4: Functions Insert and Checktable

Page 47: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

3.3 Experimental Results 35

In the most general case, suppose that m collisions c1, . . . , cm occurs between the n visits of s, and letl1, . . . , lm be the indexes of the states causing a collision. Then, at the end of level j the queue Q next willcontain m+ 1 copies of s, with probabilities

∑lii=1 piP(si, s). We have so proved the following theorem.

Theorem 3.5. Let F ∈ LBPCTL be a BPCTL formula such that F ≡ ¬[tt U≤k φ]>α, and let S =(S, q,A,next) be a PFSS. Then, Safety(S, F ) returns true iff S |= F .

3.2.3 ALGORITHM IMPLEMENTATION

We implemented the algorithm shown in Section 3.2.1 within an already existent model checker: this allowsus not to deal with the definition from scratch of an input language and with the creation of the basicverification structures. To this end, we choose the Murϕ model checker [47] since its input language iseasily modifiable in order to specify Markov Chains; we call the resulting tool FHP-Murϕ (Finite HorizonProbabilistic Murϕ).

Thus, we modified the Murϕ original input language (see Section 2.4.1) in order to make it able to definea PFSS S. To this end, we replace boolean conditions on rule guards with probabilities, and use BPCTLformulas instead of invariants; moreover, the BPCTL formulas accepted by FHP-Murϕ are slightly moregeneral than those of Definition 2.8, since they accept all the possible orderings: >,≥, <,≤. The technicaldetails for the FHP-Murϕ input language may be found in Appendix A, together with the Lex, Yacc andC++ code for the FHP-Murϕ compiler.

For what concerns the implementation of the verification algorithm, it is built on the pseudocode of Figures3.3 and 3.4, by properly modifying the existent Murϕ code. In fact, having now probability instead ofbooleans on rule guards, we are indeed able to define a function implementing the next structure used inFigures 3.2 and 3.3, as well as the Murϕ definition of the starting state allows to know which is q.

Finally, we have pointed out in Section 3.2.1 that the queues are only partially stored on RAM, being theremaining part maintained on disk storage. This is efficiently done by means of the mechanism describedin [21]; for exposition completeness, we show in Figure 3.5 the pseudocode of enqueue and dequeue oper-ations, and of the related functions.

The complete FHP-Murϕ code for the verification may be found in Appendix B.

3.3 EXPERIMENTAL RESULTS

To show effectiveness of our approach we run two kind of experiments.

First, in Section 3.3.1, we compare verifications of finite horizon safety formulas done by FHP-Murϕ withverifications of the same models and formulas done by the probabilistic model checker PRISM [52].

Second, in Section 3.3.2, we run FHP-Murϕ to verify a finite horizon safety property on a quite largeprobabilistic hybrid systems.

3.3.1 PROBABILISTIC DINING PHILOSOPHERS

In this section we give our experimental results on using FHP-Murϕ on the probabilistic protocols includedin PRISM distribution [52]. We do not consider the protocols that lead to Markov Decision Processes or to

Page 48: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

36 Chapter 3. Verification of Safety Properties

void Enqueue(state s, double p){

i f (tail_queue i s full) swap_out();/* now, tail queue is not full */insert (s, p) into tail_queue;tail_queue_elements++;

} /* Enqueue() */

/* hyp: Dequeue is always called on a nonempty queue */(state, double) Dequeue(){

i f (head_queue == ∅) swap_in();/* head queue is not empty now */head_queue_elements--;re turn top of head_queue;

} /* Dequeue() */

/* Moves part of the queue from RAM to disk */void swap_out(){append tail_queue to swapout_file;tail_queue_elements = 0;

} /* swap_out() */

/* Moves part of the queue from disk to RAM */void swap_in(){

i f (swapin_file 6= ∅)load head_queue with at most ram_queue_size states fromswapin_file;

e l s e{/* swapin file is empty, we use swapout file */swap the swapin_file and swapout_file;i f (swapin_file 6= ∅)load head_queue with at most ram_queue_size states fromswapin_file;

e l s e{/* also swapout file is empty, we use tail queue */swap the head_queue and tail_queue;i f (head_queue == ∅)/* underflow error */error("queue is empty");

} /* else */} /* else */head_queue_elements = number of states in head_queue;

} /* swap_in() */

Figure 3.5: Enqueue and Dequeue operations in the queue disk storage mechanism

Page 49: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

3.3 Experimental Results 37

Continuous Time Markov Chains, since FHP-Murϕ cannot directly deal with them. Hence we only considerPnueli-Zuck [51] and Lehmann-Rabin [45, 46] probabilistic dining philosophers protocols. Moreover, wemodify PRISM definitions for such protocols in order to be able to define a significant finite horizon safetyproperty on them. In fact, the PCTL formulas for these protocols included in the PRISM distribution arenot finite horizon safety properties.

The probabilistic dining philosophers protocol can be described as follows. The situation is the same as thestandard dining philosophers problem: there are n philosophers sitting at a round table with n plates and nforks. Each philosopher behaves as follows. Initially, he thinks for an unpredictable time, then he becomeshungry and repeatedly tries to get both forks at his left and his right side; he succeeds in this try if and onlyif no one of his two neighbors has already taken the adjacent fork. When a philosopher has gotten both theforks, he eats for some time, then he releases both forks and returns in the thinking state.

The probabilistic extension proposed by Pnueli-Zuck consists in having a random choice in two points:

• a philosopher who is thinking may continue to think with a 20% probability, and may try to get theforks with a 80% probability;

• a philosopher who is trying to get his forks, will try the left one first with probability 50%, and theright one first with the same probability.

On the other hand, Lehmann-Rabin proposed a fairness extension to the Pnueli-Zuck protocol. In fact,at any time tick, only one philosopher may perform an action. Thus, in the Lehmann-Rabin protocol, aphilosopher may make any action if and only if it will not cause another philosopher to have waited morethan a given threshold without having done any action.

Our modifications to PRISM protocols consist in adding variables to count the number of times that aphilosopher fails in getting both forks. E.g., in the Pnueli-Zuck protocol, we replaced the code fragmentin Figure 3.6 with the one in Figure 3.7. This modification obviously does not change the protocols be-havior, but allows us to write a BPCTL formula which requires that the probability of these counters to betoo high, i.e. equal to a given maximum value (MAX CONT in the following), is low. More formally, ifP (MAX CONT, k) is the probability that a philosopher counter reaches MAX CONT in at most k steps, thenP (MAX CONT, k) has not to overtake a given probability threshold α. This corresponds to verify quality ofservice properties, which are very frequent in practice. Figure 3.8 shows the PRISM code for the BPCTLproperty to be verified, stating that the probability that a counter reaches MAX CONT has to be at most 10−3.

On the other hand, we translate into FHP-Murϕ the modified PRISM definitions, so that for each protocol,FHP-Murϕ and PRISM definitions specify exactly the same Markov Chain; e.g., in Figure 3.9 we have theFHP-Murϕ code corresponding to the PRISM code fragment of Figure 3.7.

To assess FHP-Murϕ effectiveness, in Tables 3.1 and 3.2 we compare the results obtained with FHP-Murϕ and with PRISM on, respectively, Pnueli-Zuck and Lehmann-Rabin protocols (modified as describedabove). In these experiments, we always set k = 20 (see Figures 3.8 and 3.9), and we use a machine with2 processors (both INTEL Pentium III 500MHz) and 2GB of RAM. As in Figure 3.9, NPHIL indicates thenumber of philosophers, while MAX CONT, as already said, is maximum number of times that a philosophercan fail in getting both forks before dying. For what concerns the verification options, the FHP-Murϕ RAMmemory occupations are a priori fixed by the option -mM . On the other hand, PRISM options are thedefault ones in the first rows of Tables 3.1 and 3.2, while the “N/A” value means that PRISM was unableto complete the verification. In this latter case, also the -m and -s options (totally MTBDD and algebraicverification algorithm respectively) have been used, with the same failing result.

This is due to the fact that these protocols requires some non-trivial mathematical operations, that is exactlythe case in which OBDDs, and thus MTBDDs, reach their worst memory occupation. On the contrary,

Page 50: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

38 Chapter 3. Verification of Safety Properties

module phil1p1: [0..10] i n i t 0;

. . . . .// if the philosopher has failed to get both the forks,// he has to try to get them from the beginning[] p1=6 -> (p1’=1);// the same as above, but the philosopher tried the two// forks in the inverse order[] p1=7 -> (p1’=1);

. . . . .// the philosopher has eaten and released the forks, he// can return to thinking[] p1=10 -> (p1’=0)

endmodule

Figure 3.6: Pnueli-Zuck algorithm fragment to be modified in PRISM

module phil1p1: [0..10] i n i t 0;cont1: [0..3] i n i t 0;

. . . . .// w.r.t. Figure 3.6, we also increment cont1 till the// saturation value MAX_CONT[] p1=6 & cont1!=MAX_CONT -> (p1’=1) & (cont1’=cont1+1);[] p1=6 & cont1=MAX_CONT -> (p1’=1);[] p1=7 & cont1!=MAX_CONT -> (p1’=1) & (cont1’=cont1+1);[] p1=7 & cont1=MAX_CONT -> (p1’=1);

. . . . .// when returning at the thinking state, we have to reset// cont1[] p1=10 -> (p1’=0) & (cont1’=0);

endmodule

Figure 3.7: Pnueli-Zuck algorithm modified fragment in PRISM

P<=0.001 [ t rue U<=20 ((cont1=MAX_CONT) | (cont2=MAX_CONT)| (cont3=MAX_CONT))]

Figure 3.8: BPCTL formula in PRISM

Page 51: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

3.3 Experimental Results 39

/* returns the probability that p[i] becomes next (returns0 when a transition is not allowed); NPHIL is the numberof philosophers */

f u n c t i o n calc_prob(i : 1..NPHIL; next : 0..10) : prob;beginswitch p[i]/* p[i] corresponds to PRISM pi */...

/* this computes the probability of the first two rules ofFigure 3.7 */

case 6:i f (next = 1) then re turn 1.0 / NPHIL;

e l s e re turn 0.0;e n d i f;

/* this computes the probability of the second two rulesof Figure 3.7 */

case 7:i f (next = 1) then re turn 1.0 / NPHIL;

e l s e re turn 0.0;e n d i f;...

endswitch; end;

/* set of rules describing the system behavior */r u l e s e t philosophers : 1..NPHIL do

r u l e s e t next : 0..10 dor u l e "next"calc_prob(philosophers, next) ==>begin/* philosopher i changes state to next */p[i] := next;/* cont[i] corresponds to PRISM conti */i f (next = 1 & (p[i] = 6 | p[i] = 7) &

cont[i] != MAX_CONT)/* cont[i] incremented when there is a transition from

state 6 or 7 to state 1, and cont has not reached itssaturation value */

then cont[i] := cont[i] + 1;e n d i f;/* counter reset */i f (p[i] = 10 & next = 0) then cont[i] := 0;e n d i f;

end; end; end;

pctl [ t rue u n t i l <= 20( e x i s t s i : 1..NPHIL do (cont[i] = MAX_CONT) e n d e x i s t s)

] <= 0.001;

Figure 3.9: Pnueli-Zuck algorithm in FHP-Murϕ

Page 52: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

40 Chapter 3. Verification of Safety Properties

mathematical operations in the computation of the transition function next is hardly a problem for FHP-Murϕ, that succeeds in completing these verifications.

NPHIL MAX WAIT Result Murϕ memory PRISM memory Murϕ time PRISM time

3 3 false 2.000000e+02 9.057000e-01 5.197000e+01 1.487000e+00

3 4 false 2.000000e+02 1.684400e+00 5.261000e+01 2.507000e+00

4 3 false 2.000000e+02 2.810660e+01 2.429400e+02 2.87200e+01

4 4 false 2.000000e+02 6.626590e+01 2.441700e+02 7.111200e+01

5 3 false 2.000000e+02 9.168246e+02 1.408290e+03 1.023468e+03

5 4 false 2.000000e+02 N/A 1.412210e+03 N/A

8 3 false 1.000000e+03 N/A 2.137907e+05 N/A

Table 3.1: Experimental results for the verification of a finite horizon safety property on the Pnueli-Zuckprotocol. The experiments were carried out on a machine with 2 processors, both Pentium III 500MHz,with 2GB of RAM. Time is in seconds, memory occupations are in MB.

NPHIL MAX WAIT Result Murϕ memory PRISM memory Murϕ time PRISM time

3 3 false 8.000000e+02 3.906250e+01 1.040330e+03 8.455600e+01

3 4 true 8.000000e+02 7.014830e+01 1.041700e+03 1.211470e+02

4 3 false 8.000000e+02 N/A 3.430774e+04 N/A

Table 3.2: Experimental results for the verification of a finite horizon safety property on the Lehmann-Rabinprotocol. The experiments were carried out on the same machine of Table 3.1. Time is in seconds, memoryoccupations are in MB.

3.3.2 A “REAL WORLD” PROBABILISTIC HYBRID SYSTEM

In this section we show our experimental results on using FHP-Murϕ for the analysis of a real world hybridsystem. Namely, the Control System for the Gas Turbine of a 2MW Electric Co-generative Power Plant(ICARO) in operation at the ENEA Research Center of Casaccia (Italy).

Our control system (Turbogas Control System, TCS, in the following) is the heart of ICARO and is in-deed the most critical subsystem in ICARO. Unfortunately TCS is also the largest ICARO subsystem, thusmaking the use of model checking for such hybrid system a challenge.

TCS task is to maintain the ICARO parameters within the required safety ranges, when the user demandvaries. However, in [17] we showed that, if the speed of variation of the user demand for electric power(MAX D U in the following) is greater than or equal to 25 kW/sec, TCS fails in its task. This result has beenobtained by modeling TCS in a modified version of Murϕ, in which it is allowed to use finite precision realnumbers in the modeling.

We now want to know what is the probability that a finite execution of the TCS reaches an error state, whenthe user demand variation is modeled by a Markov Chain. Here, we say that a TCS state is an error state iffone of ICARO parameters is outside its given safety range.

To this end, let p(u, i) be a function defined as follows:

Page 53: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

3.3 Experimental Results 41

p(u, i) =

0.4 + β (u−u0)|u−u0|M2 if i = 1

0.2 if i = 0

0.4 + β (u0−u)|u−u0|M2 if i = −1

(3.8)

where M =MAX U is the maximum user demand value, u0 = M2 is the user demand setpoint, and β is a

verification parameter.

Denoting with u(t) the user demand value at time t, we can define the (stochastic) dynamics for the userdemand as follows:

u(t+ 1) =

min(u(t) + α,M) with probability p(u(t), 1)

u(t) with probability p(u(t), 0)

max(u(t) − α, 0) with probability p(u(t),−1)

(3.9)

where α =MAX D U.

In this way, we have that the further u(t) from u0, the higher the probability to return towards u0, i.e. todecrement u(t) if u(t) > u0 and to increment it otherwise.

To see that (3.9) is indeed a Markov Chain, we first have to point out that, since we discretize the timet, we have that (3.9) has indeed a finite number of states. Then, it is sufficient to observe that, for all β,the sum of the outgoing transitions is obviously 1. Moreover, since 0 ≤ (u(t)−u0)|u(t)−u0|

M2 ≤ 1, as longas −0.4 ≤ β ≤ 0.4 holds, all probability values are between 0 and 1. In our experiments, we always setβ = 0.4.

With FHP-Murϕ the definition of Markov Chain (3.9), starting from the TCS model, is quite simple. This isdone in Figure 3.10, where user demand(u, d u) computes p(u, d u) (3.8) and function make1stepupdates the system state, in particular updates u as described in (3.9).

r u l e s e t d_u : -1 .. 1 do/* disturbance d u takes values -1, 0 and 1 */

r u l e "time step" user_demand(u, d_u) ==>begin/* computes the TCS answer to the user demand u in a time

unit */make1step(u, d_u);

end;end; /* user demand disturbance */

Figure 3.10: Ruleset for TCS with probabilistic user demand

We are interested in cases where the error probability is greater than 0. From the results in [17] we knowthat this is the case if we choose MAX D U greater than or equal to 25 and the horizon value no smaller thanthe transition graph diameter.

In our experiments here we choose our horizon as follows. Let Diam(n) be the minimum number of states

needed to reach an error state when MAX D U = n. We set our horizon k to be equal to⌈

Diam(n)100

100. In

this way we check the error probability in the error neighborhood.

Our results are in Table 3.3. The first columns meaning is straightforward, while in the field “Probability”is shown the error probability, i.e. the value P [tt U≤k φ], being φ the atomic proposition denoting the error

Page 54: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

42 Chapter 3. Verification of Safety Properties

MAX D U Visited States Rules Fired k CPU Time Probability

35 2.226036e+06 6.602763e+06 1400 5.026302e+04 1.076644427e-04

45 1.834684e+06 5.439327e+06 1300 4.140315e+04 9.957147381e-05

50 8.318900e+04 2.462850e+05 900 2.212360e+03 3.984375e-03

Table 3.3: Experimental results for the verification of a finite horizon safety property on the TurbogasControl System. The experiments were carried out on a machine with 2 processors, both Pentium III500MHz, with 2GB of RAM. Time is in seconds.

states. As in Section 3.3.1, we used a machine with 2 processors (both INTEL Pentium III 500MHz) and2GB of RAM, and give to FHP-Murϕ the option-m500 to force it to use exactly 500 MB of RAM.

Table 3.3 allows us to evaluate the probability of an error state when MAX D U is greater than or equal to 25.Note that such a probability is rather small, suggesting that, in many cases, even if MAX D U is greater than25, TCS behavior may be acceptable. This kind of evaluations are not possible with the nondeterministicverification of TCS carried out in [17].

Page 55: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

CHAPTER 4

VERIFICATION OF BPCTL PROPERTIES

In this chapter, we move from the algorithm for finite horizon safety properties presented in Chapter 3 to analgorithm for all finite horizon properties, i.e. an algorithm able to verify all BPCTL formulas. In particular,by allowing the specification of formulas with nested untils, this algorithm is able to check robustness andreliability properties, as we will show in Section 4.2.

The chapter is organized as follows. In Section 4.1 we describe our algorithm. Namely, in Section 4.1.1 wegive a formal description of our algorithm; Section 4.1.2 provides three simple running examples; Section4.1.3 formally proves the algorithm correctness; finally, in Section 4.1.4 we sketch our implementation ofthe algorithm in Section 4.1.1 within the FHP-Murϕ verifier. Section 4.2 close the Chapter by showingsome meaningful experimental results and making a performance comparison with PRISM.

4.1 EXPLICIT BPCTL MODEL CHECKING

In this section we present an explicit algorithm to verify if a PFSS S = (S, q,A, next) satisfies a givenBPCTL formula F ; thus, we want to determine if S |= F holds.

By Definition 2.9, it is clear that the most difficult case in the verification of a BPCTL formula is to computethe truth value of U-subformulas. In Chapter 3, we solved a simplified version of this problem (consistingin forcing the subformulas of the given U-formula to be atomic propositions) by implementing a BreadthFirst (BF) visit of S state space.

However, suppose we have to verify a formula with nested U-formulas, which are exactly the kind offormulas defining the robustness and reliability properties we are interested in here. Thus, let F ≡[tt U≤k1 Φ1]wα, with Φ1 ≡ [tt U≤k2 φ]wβ , being φ an atomic proposition. To determine if S |= F(i.e. q |= F ) we have to check if t |= Φ1, for all states t that are reachable from q in at most k1 steps.This entails that we have to start, for all t, a nested BF visit. Fortunately, it is possible to avoid some ofthese nested visits, namely those starting from a state t such that t |= Φ1 has already been evaluated by apreceding nested call. In fact, we may store in a cache t, Φ1 and the truth value of t |= Φ1, and then reusethis information when t is reached again.

This suggests to extend this approach also to intermediate results. As an example, consider again theproblem of evaluating if t |= Φ1, and suppose that there exists a state r which is reachable from t with ndifferent paths π1, . . . , πn, all of length at most k2. Let 1 ≤ i ≤ n; if we store in RAM a cache maintainingr, Φ1, |πi| and pi = Pr[tt U≤k2−|πi| φ], then p1, . . . , pi may be used to avoid the nested call when r isreached via πi+1. Note that pi is the probability of a path formula, instead of a truth value, because thisallows us to make further optimizations.

However, this is not possible by using the BF visit of Chapter 3, which only allows us to compute, for all t,Pt[tt U

≤k2 φ]. Thus, the algorithm we propose is based on a Depth First (DF) visit of S. Moreover, it uses

43

Page 56: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

44 Chapter 4. Verification of BPCTL Properties

a cache to store intermediate results, in order to speed up the verification task. Finally, our DF algorithmmaintains some black-box properties of the BF algorithm in Chapter 3:

• it is disk based, i.e. stores part of the DF stack on disk. Since the DF stack is the only structure whichmay grow in our algorithm, this allows us to face the well known state explosion problem, becauseof the large size of modern hard disks;

• it trades memory with time, i.e. the more RAM available, the faster our computations. In fact, havingmore RAM available allows us to allocate a larger cache, so avoiding a higher number of nestedvisits.

4.1.1 ALGORITHM DESCRIPTION

In this section we give a formal description of the algorithm verifying a generic BPCTL formula. LetS = (S, q,A,next) be a PFSS and F be a BPCTL formula; we want to check if S |= F holds. As alreadysaid in Section 2.2.1 (see Theorem 2.4), this algorithm will consider only paths of finite length.

The main function BPCTL, taking S and F and returning true iff S |= F , is shown in Figure 4.1. Thisfunction uses, as auxiliary functions, the following ones:

BPCTL rec (Figure 4.1), is a recursive function that browses the syntactical structure of F , calling itselfor one of the other auxiliary functions.

evalX (Figure 4.1), evaluates X-formulas, i.e. checks if s |= [X Φ]wα, being s ∈ S. This function simplyvisits all s successors t1, . . . tn, properly incrementing the 0-initialized variable sum for each i suchthat ti 6|= Φ. In this way, if variable sum reaches a value p such that p w α, then true is returned,since Ps[X Φ] ≥ p w α. Otherwise, false is returned, since Ps[X Φ] < p @ α (supposing that @

is the symbol < when w is ≥, and ≤ when w is >). Note that, in this latter case, sum = Ps[X Φ].

evalU (Figure 4.2), is dedicated to the evaluation of U-formulas, i.e. checks if s |= [Φ U≤k Ψ]wα, beings ∈ S. To this end, it uses a cache C and the function DF Search.

DF Search (Figure 4.2), is an auxiliary function for evalU, performing a finite horizon DF visit of thePFSS S.

As already said, the most difficult case is the one concerning the evaluation of U-formulas. This com-putation is carried out by the two functions evalU and DF Search. DF Search computes the valuePs[Φ U≤k Ψ] by making a DF Search of the state space, starting from the state s; evalU simply callsDF Search. Both functions make use of a cache C, which is organized as follows. Each cache slot ofindex i contains:

• a state s (C[i].state in Figure 4.3);

• a U-formula F ≡ [Φ U≤k Ψ]wα (C[i].form);

• an integer h (C[i].horizon);

• Ps[Φ U≤h Ψ] (C[i].prob).

In this way, we exploit the recursiveness of the DF visit, which allows us to compute, for every state treached during the computation of s |= F , the value Pt[Φ U≤h Ψ], where h is the number of steps that t

Page 57: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

4.1 Explicit BPCTL Model Checking 45

/* Main function */bool BPCTL(PFSS S, formula F){Let S = (S, q,A, next);

/* make in the proper way the first call to BPCTL rec */re turn BPCTL_rec(S, q, F);

} /* BPCTL() */

/* BPCTL recursive step */bool BPCTL_rec(PFSS S, state s, formula F){

i f (F ≡ 1)re turn true;

e l s e i f (F i s an atomic proposition p)re turn p(s) = 1;

e l s e i f (F ≡ [X Φ]wα)re turn evalX(S, s, F);

e l s e i f (F ≡ [Φ U≤k Ψ]wα)re turn evalU(S, s, F);

/* recursive cases */e l s e i f (F ≡ ¬F1)

re turn !BPCTL_rec(S, s, F1);e l s e i f (F ≡ F1 ∧ F2)

re turn BPCTL_rec(S, s, F1) && BPCTL_rec(S, s, F2);} /* BPCTL_rec() */

/* Evaluate X-formulas */bool evalX(PFSS S, state s, formula F){Let S = (S, q,A, next);Let F ≡ [X Φ]wα;

sum = 0;/* variable sum accumulates Ps[F ] */foreach (s_next, a, p_next) in n e x t(s){

i f (BPCTL_rec(S, s_next, Φ)){sum = sum + p_next;i f (sum w α)

re turn true;} /* if */

} /* foreach */re turn f a l s e ;

} /* evalX() */

Figure 4.1: Functions BPCTL, BPCTL rec and evalX

Page 58: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

46 Chapter 4. Verification of BPCTL Properties

Cache C;

/* Evaluate U-formulas */bool evalU(PFSS S, state s, formula F){Let F ≡ [Φ U≤k Ψ]wα;(valid, result) = try_to_evaluate(C, s, F);i f (valid)/* it was possible to evaluate if s |= F by using only C */

re turn result;e l s e

re turn DF_Search(S, s, F, 0) w α;} /* evalU() */

/* Compute Ps[Φ U≤k−horizon Ψ] */double DF_Search(PFSS S, state s, formula F, i n t horizon){Let S = (S, q,A, next);

i f (BPCTL_rec(S, s, Ψ))prob = 1.0;

e l s e i f (horizon != k && !BPCTL_rec(S, s, Φ))prob = 0.0;

e l s e{/* prob accumulates Ps[Φ U≤k−horizon Ψ] */prob = 0.0;i f (horizon < k){

foreach (s_next, a, p_next) in n e x t(s){prob_tmp = present_cache(C, s_next, F, k - horizon - 1);i f (prob_tmp == -1) /* not found */prob = prob + p_next*DF_Search(S,s_next,F,horizon + 1);

e l s e/* here, prob tmp = Ps next[Φ U≤k−horizon−1 Ψ], so we can use it

instead of calling DF Search */prob = prob + p_next*prob_tmp;

i f (horizon == 0 && prob w α)re turn prob;

} /* foreach */} /* if */

} /* else *//* s exploration ended */insert_cache(C, s, F, k - horizon, prob);re turn prob;

} /* DF_Search() */

Figure 4.2: Functions evalU and DF Search

Page 59: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

4.1 Explicit BPCTL Model Checking 47

/* Check if s |= F using only the cache, where F is aU-subformula of the formula being verified */

(bool, bool) try_to_evaluate(Cache C, state s, formula F)/* The first bool returned is true iff it was possible to

evaluate s |= F by using only the cache; if the first boolis true, then the second is true iff s |= F */

{Let F ≡ [Φ U≤k Ψ]wα;i f (there i s no j such that

C[j].state == s && C[j].form == F)re turn ( f a l s e , _);/* since the first value is not true, it does not matter

which is the second one */e l s e{/* the same formula, starting from the same state, may

have been computed with different horizons */foreach j such that (C[j].state == s

&& C[j].form == F){

i f (C[j].horizon == k)re turn ( true , C[j].prob w α);

e l s e i f (C[j].horizon < k && C[j].prob w α)/* C[j].prob is computed with a smaller horizon, but is

already grater than α */re turn ( true , t rue);

e l s e i f (C[j].horizon>k && C[j].prob 6w α)/* C[j].prob is computed with a larger horizon, but is still

smaller than α */re turn ( true , f a l s e);

} /* foreach *//* unable to evaluate */re turn ( f a l s e , _);

} /* else */} /* try_to_evaluate() */

Figure 4.3: Function try to evaluate

Page 60: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

48 Chapter 4. Verification of BPCTL Properties

needs to reach the horizon (i.e. h = k − j, being j the number of steps from s to t). Thus, we avoid toperform already done computations, so saving time with a fixed amount of memory.

This saving may take place in two ways:

• when evalU calls try to evaluate (see Figure 4.3), to attempt to avoid a call to DF Search.The idea here is that, since Ps[Φ U≤h1 Ψ] ≤ Ps[Φ U≤h2 Ψ] when h1 < h2 (see Lemma 4.2), theneven if the searched pair (state, formula) is not present in the cache with the required horizon, wemay be able to say if s |= F (see Example 4.3);

• when DF Search calls present cache, to attempt to avoid a recursive call. In this case, therecursive call can be avoided only if we find in the cache the slot with the exact state, formula andhorizon, since here we need the exact probability value. Example 4.2 shows a case in which thishappens.

Finally, function insert cache, being slightly different from the usual implementation, is shown inFigure 4.4. When a free cache slot has not been found, a slot is overwritten only if it refers to the same pair(state, formula), and has a smaller horizon. In this way, we overwrite only information obtained with lesscomputations.

/* Store values in C */void insert_cache(Cache C, state s, formula F, i n t hor, doubleprob){/* standard hashing function */count = 0;h = hash(s, count);whi le (C[h] 6= ∅ && count <= max_chain_length){/* this loop searches a free slot among the ones that

correspond to the hash values of s */count = count + 1;h = hash(s, count);

} /* while */i f (C[h] == ∅)/* ok to insert in the slot h */C[h] = (s, F, hor, prob);

e l s e{

i f (C[h].state == s && C[h].form == F &&C[h].horizon < hor)

/* overwrite the previous contents: since hor is greaterthan C[h].horizon, prob is harder to recompute thanC[h].prob */

C[h] = (s, F, hor, prob);} /* else */

} /* insert_cache() */

Figure 4.4: Function insert cache

Page 61: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

4.1 Explicit BPCTL Model Checking 49

4.1.2 EXAMPLES

We now illustrate how our algorithm works by means of three simple examples. An animated presentationof these examples may be found in [50].

Example 4.1 illustrates only the basic mechanism of the DF visit, when carried out on a U-formula withoutnested U-formulas. To this end, we consider a version of the algorithm which does not use the cache;

Example 4.2 deals with the usage of the cache in function DF Search. Here, caching is useful for everytype of U-formula;

Example 4.3 shows how the cache is used by function try to evaluate. Here, caching is useful onlywith nested U-formulas.

Finally, in all the examples, states are labeled with their visiting order in the DF visit, and we denote withprobsi

the final value for the variable prob when DF Search is called on the state si.

Example 4.1. Suppose we are given the simple PFSS S of Figure 4.5 and the BPCTL formula F ≡[tt U≤2 φ]≥0.6, where φ ∈ is an atomic proposition such that φ(s1) = φ(s4) = φ(s7) = 1 and is 0on the other states (as shown in Figure 4.5). We want to verify if s0 |= F . In this example, we will executethe algorithm in Figure 4.9 (supposing that the call to function evalU made by BPCTL rec is replacedby the call to evalU nC, with the same parameters). This allows us to focus on the basic mechanism ofthe algorithm, since we do not use the cache.

Then, the computation of probs0is performed in the following way:

probs0→

1

3probs1

→1

3

→1

3+

1

3probs2

→1

3+

1

3

1

2probs3

→1

3+

1

3

1

2probs4

→1

3+

1

3

1

2(4.1)

→1

2+

1

3probs5

→1

2+

1

31probs6

→1

2

In fact, probs3= probs6

= 0, since s3 and s6 are reached with horizon = 2 and they do not satisfyφ. On the other hand, probs1

= probs4= 1, since φ(s1) = φ(s4) = 1. Moreover, s7 and s8 are never

reached, since s7 is only reachable from s1, that is not expanded since φ(s1) = 1, while s8 is beyond the Fhorizon, i.e. it is not reached in at most 2 steps from s0. So, the final result is that s0 6|= F , since 0.5 6≥ 0.6.

Note that, if the formula were F ≡ [tt U≤2 φ]≥0.5, i.e. if the probability bound was 0.5 instead of 0.6, thenneither s5 nor s6 would have been visited. In fact, the above computation would have returned true at theend of (4.1), since 1

3 + 13

12 = 0.5 ≥ 0.5.

Example 4.2. Suppose we are given the PFSS S partially shown in Figure 4.6 and the BPCTL formulaF ≡ [tt U≤k φ]≥0.9, where k > 3 and φ ∈ AP is an atomic proposition which is false in all the statesshown in Figure 4.6 (i.e., ∀0 ≤ i ≤ 6 φ(si) = 0). As in Example 4.1, we want to verify if s0 |= F .However, here we will use also the cache, and we suppose that the return prob; statement at the endof the foreach loop in DF Search is never executed.

We now focus on state s3, which is reached for the first time as successor of s2. Then, probs3is computed,

and the 4-tuple (s3, F, k − 3, p) is put on the cache, being p = probs3. When s3 is reached again as

Page 62: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

50 Chapter 4. Verification of BPCTL Properties

s0

s8

1

s2

s5

s1

φ

12

1

1

12

s6

s3

s7

φs4

1

1

1

1

φ

13

13

13

Figure 4.5: The PFSS of Example 4.1

successor of s4, a recursive visit of s3 should be performed to compute again probs3. However, the repe-

tition of the DF visit of s3 is avoided, since present cache(C,s3, F, k − 3) returns p (supposing that thecorresponding slot has not been overwritten in the meanwhile). Thus, the DF visit of s4 can directly use pto compute probs4

.

In a similar way, it is possible to avoid another DF visit of S starting from s4 (when s4 is reached again asa successor of s5), as well as the third one starting from s3 (when s3 is reached again as a successor of s6).

s0

s1

s4

s6

s2

s3

s5

12

12 1

1

1

12

12

12

12 ...

. . .

. . .

Figure 4.6: The PFSS of Example 4.2

Example 4.3. Suppose we are given the simple PFSS S of Figure 4.7 and the BPCTL formula Φg ≡[tt U≤2 Φn]≤0, where Φn ≡ [tt U≤2 φ]≥1 is a U-subformula and φ ∈ AP is an atomic proposition suchthat φ(s4) = 1 and ∀s 6= s4 φ(s) = 0 (as shown in Figure 4.7). As in Example 4.2, we want to verifyif s0 |= F , and we again suppose that the return statement at the end of the foreach statement inDF Search is never executed.

Differently from Examples 4.1 and 4.2, we now have to verify a U-formula Φg with a nested U-subformulaΦn. This entails that, during the DF visit of S to compute Ps0

[Φg], other nested DF visits are needed todetermine if the states s reachable from s0 verify s |= Φn:

1. DF Search(S, s0,Φn, 0) inside the call DF Search(S, s0,Φg, 0);

2. DF Search(S, s1,Φn, 0) inside the call DF Search(S, s1,Φg, 1);

3. DF Search(S, s2,Φn, 0) inside the call DF Search(S, s2,Φg, 2);

4. DF Search(S, s3,Φn, 0) inside the call DF Search(S, s3,Φg, 2);

5. DF Search(S, s3,Φn, 0) inside the call DF Search(S, s3,Φg, 1);

6. DF Search(S, s4,Φn, 0) inside the call DF Search(S, s4,Φg, 2);

Page 63: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

4.1 Explicit BPCTL Model Checking 51

The calls 1, 2, 3 and 6 are unavoidable, and are effectively performed (however, the call 6 immediatelyreturns 1, since φ(s4) = 1). These four DF visits also put onto the cache the final values they compute.Figure 4.8 show the evolution of the cache contents, with the simplifying assumption that all insertions aredone in successive slots. Namely, call 1 inserts slots C[0] through C[4], while call 2 inserts slots C[5] throughC[7]; finally, call 3 inserts the slot C[8].

The calls 4 and 5 are instead avoided. In fact, consider the call to evalU(S, s3,Φn), which should executethe call 4. However, before this latter call is made, try to evaluate(C,s3,Φn) is invoked, with the 4-tuple C[7] = (s3, Φn, 1, 1.0) present on the cache (see Figure 4.8). Here, function try to evaluatereturns true since, even if C[7].prob = 1 is computed with a smaller horizon than the required one(C[7].horizon = 1 < 2), we have that C[7].prob is already in the right relation (≥) with the probabilitybound (1) present in the formula Φn. In the same way, the successive call to try to evaluate(C,s3,Φn),using the same cache slot C[7], avoids the call 5.

12

s0

s2s1

s4s3

φ

12

12

1 1

1

12

Figure 4.7: The PFSS of Example 4.3

0 s0,Φn, 2,12

1 s1,Φn, 1, 0.0

2 s2,Φn, 0, 0.0

3 s3,Φn, 1, 1.0

4 s4,Φn, 0, 1.0 At the end of DF Search(S, s0,Φn, 0)

5 s1,Φn, 2,12

6 s2,Φn, 1, 0.0

7 s3,Φn, 1, 1.0 At the end of DF Search(S, s1,Φn, 0)

8 s2,Φn, 2, 0.0 At the end of DF Search(S, s2,Φn, 0)

9 s2,Φg , 0, 0.0 At the end of DF Search(S, s2,Φg, 2)

10 s3,Φg , 0, 1.0 At the end of DF Search(S, s3,Φg, 2)

11 s1,Φg , 1,12 At the end of DF Search(S, s1,Φg, 1)

12 s3,Φg , 1, 1.0 At the end of DF Search(S, s3,Φg, 1)

13 s0,Φg , 2,34 At the end of DF Search(S, s0,Φg, 0) (final)

Figure 4.8: Cache evolution for Example 4.3

4.1.3 ALGORITHM CORRECTNESS

Here we give a correctness proof of the algorithm shown in Section 4.1.1. We begin by proving the correct-ness of the algorithm without the cache usage, so dealing with functions evalU nC and DF Search nCof Figure 4.9 (we also suppose, of course, that BPCTL rec calls evalU nC instead of evalU).

We start with two general purpose lemmas.

Page 64: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

52 Chapter 4. Verification of BPCTL Properties

bool evalU_nC(PFSS S, state s, formula F){Let F ≡ [Φ U≤k Ψ]wα;

re turn DF_Search_nC(S, s, F, 0) w α;} /* evalU_nC() */

double DF_Search_nC(PFSS S, state s, formula F, i n t horizon){

i f (BPCTL_rec(S, s, Ψ))prob = 1.0;

e l s e i f (horizon!=k && !BPCTL_rec(S,s,Φ))prob = 0.0;

e l s e{prob = 0.0;i f (horizon < k){

foreach (s_next, a, p_next) in n e x t(s)prob = prob + p_next*DF_Search_nC(S,s_next,F,horizon+1);

i f (horizon == 0 && prob w α)re turn prob;

} /* if */} /* else */re turn prob;

} /* DF_Search_nC() */

Figure 4.9: Functions evalU nC and DF Search nC

Page 65: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

4.1 Explicit BPCTL Model Checking 53

Lemma 4.1. Let S = (S, q,A,next) be a PFSS, and let Φ,Ψ ∈ LBPCTL be BPCTL formulas. Then, forall s ∈ S such that s 6|= Ψ and s |= Φ, and for all i ∈ N such that i ≥ 1, we have that

Ps[Φ U≤i Ψ] =∑

(sh,ah,ph)∈next(s)

phPsh[Φ U≤i−1 Ψ]

Proof. Let Π(s,Φ,Ψ, i) =def {π ∈ Path(S, s) | π |= Φ U≤i Ψ}. Let next(s) = {(s1, a1, p1), . . . ,(sn, an, pn)}. Then,

Ps[Φ U≤i Ψ] =∑

π∈Π(s,Φ,Ψ,i)

P(π) =

(sh,ah,ph)∈next(s)

π ∈ Π(s, Φ, Ψ, i)

π(1) = sh

i−1∏

j=0

P(π(j), π(j + 1)) =

(sh,ah,ph)∈next(s)

π ∈ Π(s, Φ, Ψ, i)

π(1) = sh

P(π(0), π(1))

i−1∏

j=1

P(π(j), π(j + 1)) = (4.2)

(sh,ah,ph)∈next(s)

ph

π∈Π(sh,Φ,Ψ,i−1)

P(π) = (4.3)

(sh,ah,ph)∈next(s)

phPsh[Φ U≤i−1 Ψ]

Note that, in the passage from (4.2) to (4.3), we have used the hypothesis that π(0) 6|= Ψ and π(0) |= Φ.

Lemma 4.2. Let S = (S, q,A,next) be a PFSS, Φ,Ψ ∈ LBPCTL be BPCTL formulas, s ∈ S be a stateand h1 < h2 ∈ N be two integers. Then,

Ps[Φ U≤h1 Ψ] ≤ Ps[Φ U≤h2 Ψ]

Proof. By Definition 2.11, we have to prove that Prob{π ∈ Path(S, s) | π |= Φ U≤h1 Ψ} ≤ Prob{π ∈Path(S, s) | π |= Φ U≤h2 Ψ}, which can be done by showing that {π ∈ Path(S, s) | π |= Φ U≤h1 Ψ} ⊆{π ∈ Path(S, s) | π |= Φ U≤h2 Ψ}. So, we have to prove that, if π |= Φ U≤h1 Ψ, then π |= Φ U≤h2 Ψ,being π ∈ Path(S, s). By contradiction, suppose that π |= Φ U≤h1 Ψ and π 6|= Φ U≤h2 Ψ; byDefinition 2.9, this is equivalent to say that ∃h ≤ h1 : (π(h) |= Φ2 and ∀i < h π(i) |= Φ1) and∀h ≤ h2 (π(h) 6|= Φ2 or ∃i < h π(i) 6|= Φ1). Since h1 < h2, these two statements are in contradiction.

We now give two other useful and more specific lemmas.

Page 66: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

54 Chapter 4. Verification of BPCTL Properties

Lemma 4.3. Suppose that functionDF Search nC is called with parameters S = (S, q,A,next), s ∈ S,F ≡ [Φ U≤k Ψ]wα and 0. Then, a state t ∈ S is explored by function DF Search nC iff t is reachablefrom s in at most k steps.

Proof. Suppose that a state t is reachable from s in at most k steps. This implies that it exists a pathπ = s0s1 . . . sh such that s0 = s, sh = t and h ≤ k. This in turns entails that, for all 0 ≤ i < h,there exist a ∈ A and p ∈ (0, 1] such that next(si) 3 (si+1, a, p). Thus, the foreach loop of functionDF Search nC ensures that, for all i, DF Search nC is recursively called on si, and finally on t.

On the other hand, let t be a state explored by DF Search nC, and let h ∈ N

be the corresponding value of horizon. Thus, there must be a chain of callsDF Search nC(S, s0, F, 0), . . . , DF Search nC(S, sh, F, h), where s0 = s, sh = t and h ≤ k (thelast statement holds since the recursive call is made only if horizon < k). However, this calls chain maytake place only if, for all 0 ≤ i < h, there exist a ∈ A and p ∈ (0, 1] such that next(si) 3 (si+1, a, p).This implies that t is reachable from s in at most k steps.

Lemma 4.4. Suppose that functionDF Search nC is called with parameters S = (S, q,A,next), s ∈ S,F ≡ [Φ U≤k Ψ]wα and 0. Moreover, suppose that, for all t ∈ S that are reachable in k steps from s,BPCTL rec(S, t,Φ) and BPCTL rec(S, t,Ψ) return true iff, respectively, t |= Φ and t |= Ψ. Then, thiscall to DF Search nC will return Ps[Φ U≤k Ψ], or a value p such that Ps[Φ U≤k Ψ] ≥ p w α.

Proof. The proof is carried out in two steps. Initially, we assume that the last statement of the foreachloop in function DF Search nC (i.e., return prob) is never executed, so the DF visit is neverstopped before its termination; under this assumption, we show that DF Search nC will always returnPs[Φ U≤k Ψ]. In the second step we relax this assumption, so proving the whole Lemma. Moreover, in allthe proof we suppose that all the calls to function BPCTL rec made in DF Search nC always return thecorrect value, since this is implied by Lemma 4.3 and by the lemma hypothesis.

Thus, we now show that, if DF Search nC is called with parameters S, s, F and n, then it returnsPs[Φ U≤k−n Ψ]. Once we have showed this, we have obtained also the thesis since, in the first call, nis set to 0. The proof of such a statement is made by induction on k − n, which take values in the intervalfrom 0 (at the end of the recursive calls chain, when DF Search nC is called with n = k) to k (in the firstcall to DF Search nC, when n = 0).

For the recursion base we have to show that function DF Search nC, when called with parameters S,s ∈ S, F and n = k (so k − n = 0), returns Ps[Φ U≤0 Ψ]. By Definitions 2.9 and 2.11, we have thatPs[Φ U≤0 Ψ] = Prob{π ∈ Path(S, s) | π |= Φ U≤0 Ψ} = Prob{π ∈ Path(S, s) | s |= Ψ}. So, if s |= Ψ,we have that Ps[Φ U≤0 Ψ] = 1, otherwise Ps[Φ U≤0 Ψ] = 0. Indeed, function DF Search nC returns 1or 0, depending on the evaluation of s |= Ψ (no recursive call is made in this case).

For the induction step we know that, if DF Search nC is called with parameters S, s ∈ S, F and n ≤ k,then it returns Ps[Φ U≤k−n Ψ]. Suppose now that function DF Search nC is called with parameters S,s ∈ S, F and n− 1; thus, we have the following cases:

1. If s |= Ψ, then by Definitions 2.9 and 2.11, for all h ∈ N, Ps[Φ U≤h Ψ] = Prob{π ∈Path(S, s) | π |= Φ U≤h Ψ} = Prob{π ∈ Path(S, s) | true} = 1; in particular,Ps[Φ U≤k−n+1 Ψ] = 1, and in fact DF Search nC returns 1.

2. If s 6|= Ψ and s 6|= Φ, we analogously have that Ps[Φ U≤k−n+1 Ψ] = 0, and in fact DF Search nCreturns 0.

Page 67: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

4.1 Explicit BPCTL Model Checking 55

3. Otherwise, if s 6|= Ψ and s |= Φ, then we are in the hypothesis of Lemma 4.1, so

Ps[Φ U≤k−n+1 Ψ] =∑

(sh,ah,ph)∈next(s)

phPsh[Φ U≤k−n Ψ]. Since, by induction hypothesis, the

recursive calls to DF Search nC with parameters S, sh such that (sh, ah, ph) ∈ next(s), F and n

correctly return Psh[Φ U≤k−n Ψ], we have that

(sh,ah,ph)∈next(s)

phPsh[Φ U≤k−n Ψ] is correctly

returned.

Now, suppose that the return prob statement inside the foreach loop in function DF Search nC(we call I this statement) is eventually executed. If I were not executed, then the final value of prob wouldhave been Ps[Φ U≤k Ψ]. However, since prob is always incremented until it reaches this value, the valueof prob when I is executed will be p such that Ps[Φ U≤k Ψ] ≥ p w α.

Now we give the main correctness theorem for the algorithm without cache.

Theorem 4.5. Let F ∈ LBPCTL be a BPCTL formula to be verified in a PFSS S = (S, q,A,next). Then,BPCTL(S, F ) (where calls to evalU are replaced by calls to evalU nC) returns true iff S |= F .

Proof. Since S |= F iff q |= F in the Markov Chain Smc, to prove this theorem it is sufficient to show that,for all s ∈ S, BPCTL rec(S, s, F ) returns true iff s |= F .

The proof is by structural induction on F . Thus, we assume that ∀s ∈ S BPCTL(S, Fi) returns true iffs |= Fi is true for all subformulas Fi of F , and we show that ∀s ∈ S BPCTL(S, F ) returns true iff s |= F .

As induction basis, note that if F ≡ tt or F ≡ p ∈ AP (i.e., F does not contain any subformula), thentrue and p(s) is correctly returned, respectively. For the other cases, we have:

• if F ≡ F1 ∧ F2, then true is correctly returned iff s |= F1 and s |= F2 (in fact, by inductionhypothesis, BPCTL rec(S, s, F1) return true iff s |= F1 and analogously for F2);

• F ≡ [XΦ]wα, then function evalX is called. By induction hypothesis, for all sh, the recursive callsBPCTL rec(S, sh,Φ) made by evalX return true iff sh |= Φ, so we have that function evalX

computes, if the return true; statement is never executed, sum =∑

(sh,ah,ph)∈next(s) and sh|=Φ

ph =

Prob{π ∈ Path(S, s) | π(1) |= Φ} = Ps[X Φ]. Since sum 6w α, false is correctly re-turned. Otherwise, if the return true; statement is eventually executed, then we have thatPs[X Φ] ≥ sum w α, so true is correctly returned.

• F ≡ [Φ U≤kΨ]wα, then function DF Search nC is initially called with parameters S, s, F and 0.Since, by induction hypothesis, for all s ∈ S, BPCTL rec(S, s,Φ) (resp. BPCTL rec(S, s,Ψ)) returntrue iff s |= Φ (resp. s |= Ψ), we are in the hypothesis of Lemma 4.4, so DF Search nC returnsPs[Φ U≤kΨ] or a value p such that Ps[Φ U≤k Ψ] ≥ p w α. In both cases, after the comparison withα made in function evalU, we have that BPCTL rec will correctly return true iff s |= F .

Now, we are ready to prove the correctness of the whole algorithm. Before proving the correspondingtheorem, we have to give a lemma on the cache contents properties.

Page 68: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

56 Chapter 4. Verification of BPCTL Properties

Lemma 4.6. Let c = (s, F, h, p) be a slot of the cacheC, at any execution time. Then, if F ≡ [Φ U≤k Ψ]wα,we have that

p = Ps[Φ U≤h Ψ] (4.4)

Proof. The only function inserting values in the cache is DF Search, which performs the insertion asthe last but one statement. Let us consider the call to DF Search which inserts c in C. To demonstratethe Lemma it is sufficient to prove that the value of variable prob, immediately before the returning offunction DF Search, is exactly p = Ps[Φ U≤h Ψ]. This is done by induction on the number i of elementscurrently stored in C.

As induction basis, we prove that, if C does not contain any 4-tuple, then the value of prob is p =Ps[Φ U≤h Ψ]. This is true by Lemma 4.4, since in this case the cache is not used to determine thevalue of prob (each call to present cache returns −1).

As induction step, suppose that there are i tuples in C, each satisfying (4.4). This implies that, in the currentcall to DF Search, if present cache returns a value v 6= −1, then v will be the same returned by acall to function DF Search nC. Thus, DF Search has the same behavior as DF Search nC and, byLemma 4.4, it will return the same p = Ps[Φ U≤h Ψ].

Now, we can give our main theorem.

Theorem 4.7. Let F ∈ LBPCTL be a BPCTL formula to be verified in a PFSS S = (S, q,A,next). Then,BPCTL(S, F ) returns true iff S |= F .

Proof. Since Theorem 4.5 guarantees the correctness of the algorithm without the cache, we only have toprove the correctness of the caching strategy. To this end, we now analyze in detail the only two functionsin which the cache is used.

DF Search By Lemma 4.6 and its proof, it returns the same values of DF Search nC; by Theorem 4.5,this function works correctly.

evalU Here we have that some calls to DF Search are avoided, via function try to evaluate. Toprove that this does not affect the algorithm correctness, consider a generic call to evalU(S, s, F ),with F ≡ [Φ U≤k Ψ]wα, and suppose that there are n indices i1, . . . , in such that, for allj = 1, . . . , n, C[ij ].state = s and C[ij ].form = F . By Lemma 4.6, we have that C[ij ].prob =Ps[Φ1 U≤C[ij ].horizon Φ2] for all j = 1, . . . , n. Now, if n = 0 or none of the C[ij ] satisfy one ofthe three conditions inside the foreach loop of try to evaluate, then evalU will have thesame behavior of evalU nC, so by Theorem 4.5 the thesis is true. Otherwise, let ij be the first indexsuch that C[ij ] satisfy one of the three conditions inside the foreach loop of try to evaluate.Then, we have one of these three cases:

1. C[ij ].horizon = k; in this case, Ps[Φ1 U≤kΦ2] = C[ij ].prob w α is correctly returned.

2. C[ij ].horizon < k and (C[ij ].prob w α); in this case, by Lemma 4.2 we have thatPs[Φ1 U≤kΦ2] ≥ Ps[Φ1 U≤C[ij ].horizonΦ2] = C[ij ].prob w α, so true is correctly returned.

3. C[ij ].horizon > k and ¬(C[ij ].prob w α); in this case, by Lemma 4.2 we have thatPs[Φ1 U≤kΦ2] ≤ Ps[Φ1 U≤C[ij ].horizonΦ2] = C[ij ].prob @ α, so false is correctly re-turned (supposing that @ is the symbol < when w is ≥, and ≤ when w is >).

Page 69: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

4.1 Explicit BPCTL Model Checking 57

4.1.4 ALGORITHM IMPLEMENTATION

In this section we sketch our implementation of the algorithm given in Section 4.1.1 within the FHP-Murϕverifier described in Section 3.2.3. As in Section 3.2.3, we do not deal with the changes to Murϕ inputlanguage which are needed to define PFSSs and BPCTL formulas, since these details may be found inAppendix A.

The implementation of the verification algorithm follows the lines shown in Figures 4.1, 4.2, 4.3 and 4.4.The only adjustment is in function DF Search, which is not implemented using standard C recursion,since this should be not efficient. Thus, a stack has been implemented to explicitly handle the recursivecalls, by properly modifying the implementation of the DF visit in the original Murϕ. Since we are in abounded framework, the stack size is limited as follows.

Definition 4.1. Let stack size: LBPCTL → N be the function returning the stack size (i.e. the number ofstack entries) that is needed to verify a BPCTL formula Φ. Then stack size is defined as follows:

• stack size(tt) = stack size(p) = 0;

• stack size(Φ1 ∧ Φ2) = max{stack size(Φ1), stack size(Φ2)};

• stack size([XΦ]wα) = stack size(¬Φ) = stack size(Φ);

• stack size([Φ1 U≤kΦ2]wα) = max{stack size(Φ1), stack size(Φ2)} + k.

Hence, the amount of memory needed by the verification task is fixed, so we have that our real bottleneckis time, and not memory. However, to handle the case in which we need more memory than the availableone, we implemented the swap-to-disk mechanism stack cycling, which is also implemented in the DF-based verifier SPIN [34]. With this technique, only a part of the stack is maintained in By Definition2.9, it is clear that the most difficult case in the verification of a BPCTL formula is to compute the truthvalue of U-subformulas. This mechanism avoids too frequent disk accesses due to alternation of push-popoperations (thrashing). For exposition completeness, we show in Figure 4.10 the pseudocode of push andpop operations, and of the related functions.

In this way, we use RAM to store the cache and part of the DF stack. Our experiments show that typicallywe can take the RAM size for the DF stack as inversely proportional to the number of nested U-formulas(however, never more than half memory has been dedicated to the stack). In fact, the more nested U-formulas, the larger the cache, in order to speed up the verification process.

With respect to the algorithm described in Figures 4.1, 4.2, 4.3 and 4.4, our implementation introduces threeminor enhancements:

• We develop a mechanism allowing to terminate a DF visit before its “natural” termination, whilemaintaining the correctness of the value returned by evalU. The idea is that we want to stop a DFvisit exactly when the computed probability becomes greater than the given threshold. This is notwhat function DF Search in Figure 4.2 does, since it waits for the backtracking to level 0. Ourmechanism, instead, maintains the probability at the top level (i.e. at level 0) in a separate variableprob 0. To this end, we maintain also a variable prob path storing the probability of the pathfrom q to the current state (this path could also be obtained by chaining the states on the current DFstack). Then, prob 0 is incremented by prob path every time that prob is incremented. Afterevery prob 0 updating, we check if prob 0 is greater than the probability bound; if this is true, thesearch can safely be terminated.

• Moreover, we modify function insert cache of Figure 4.4 in order to take into account the casein which the same pair (state, BPCTL formula) has to be inserted in the cache with different horizons

Page 70: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

58 Chapter 4. Verification of BPCTL Properties

void init_stack(stack S, i n t mem_avail, i n t stack_length){

S.top = S.dsk2stck_cnt = S.stck2dsk_cnt = 0;i f (mem_avail >= stack_length*mem_for1entry)/* disk not needed, will never be used */S.size = stack_length;

e l s e{ /* mem_avail bytes of RAM will be used */S.size = mem_avail/mem_for1entry;round off by defect S.size to an even number;

} /* else */allocate S.size entries for S.entries;

} /* init_stack() */

void push(stack S, entry_type entry){

S.entries[S.top++] = entry;i f (S.top >= S.size) /* too many push, disk required */Stack2Disk();

} /* push() */

entry_type pop(stack S){

i f (stck2dsk_cnt != dsk2stck_cnt && top == 0)/* too many pop, disk required */Disk2Stack();

re turn S.entries[--S.top];} /* pop() */

/* Store on disk the first S.size/2 stack entries */void Stack2Disk(stack S){

S.stck2dsk_cnt++;write on disk the first half of S.entries;move the second half of S.entries in its first half;S.top = S.size/2;

} /* Stack2Disk() */

/* Retrieve the last S.size/2 stack entries from the disk */void Disk2Stack(stack S){

S.dsk2stck_cnt++;move the first half of S.entries in its second half;move the disk file pointer back of S.size/2 entries;copy from the disk file S.size/2 entries into the first halfof S.entries;reset the disk file pointer to the position preceding the readoperation;

S.top = S.size/2;} /* Disk2Stack() */

Figure 4.10: Push and pop operations in the stack cycling mechanism

Page 71: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

4.2 Experimental Results 59

(and probabilities). In fact, in this case, if these pairs are more than max chain length, someof these pairs will be surely overwritten, since the while statement of function insert cacheis bounded to max chain length iterations. To avoid this, we simply augment the maximumcollision chain (i.e., max chain length in Figure 4.4). Our experiments on this topic show thata good policy is to duplicate max chain length when it happens too frequently that a free slotis not found. Thus, if n is the number of calls to insert cache and k is the number of timesthat the while fails in finding a free slot (i.e., it ends with count = max chain length+ 1), thenmax chain length is duplicated if k

n> β. In our experiments, we always set β = 0.05.

• Finally, our implementation deals with all the possible comparisons between a path formula prob-ability and a real number, so we can verify properties of the type [·]<α or [·]≤α. We will use alsoproperties of this type in our experiments.

4.2 EXPERIMENTAL RESULTS

In this section, our goal is to show the effectiveness of our approach; to this end, we run two kinds ofexperiments.

First, in Section 4.2.1, we compare verifications of BPCTL formulas done by FHP-Murϕ with verificationsof the same models and formulas done by the probabilistic model checker PRISM [52].

Second, in Section 4.2.2, we run FHP-Murϕ to verify a robustness property on a quite large probabilistichybrid system.

4.2.1 PROBABILISTIC DINING PHILOSOPHERS

In this section we give our experimental results on using FHP-Murϕ on the probabilistic protocols includedin PRISM distribution [52]. As we did in Section 3.3.1, we do not consider the protocols that lead toMarkov Decision Processes or to Continuous Time Markov Chains, since FHP-Murϕ cannot directly dealwith them. Hence we only consider Pnueli-Zuck [51] and Lehmann-Rabin [45, 46] probabilistic diningphilosophers protocols. For both of these protocols, we use two versions: the one which can be found inthe PRISM distribution, and the modified version allowing quality of service properties verifications, as itis described in Section 3.3.1.

For what concerns the BPCTL properties to be verified, we proceed as follows. The BPCTL properties inthe PRISM distribution about these protocols are of the type ΦP ≡ φ → [tt U≤k ψ]≥α, where φ and ψ areatomic propositions. However, these formulas are not evaluated on the initial state (which is the standardPCTL semantics), but on all reachable states. To obtain a comparable result with FHP-Murϕ, we verify theproperty ΦM ≡ [tt U≤d ¬ΦP ]≤0 ≡ [tt U≤d (φ ∧ ¬[tt U≤kψ]≥α)]≤0, where d is the diameter of theprotocol state space, i.e. the length of the maximum path between two states. In this way, we have thatq |= ΦM (where q is the system initial state) iff, for all reachable states s, s |= ΦP .

Our results are in Tables 4.1 and 4.2. In these experiments, we always set k = 20, and we use a machinewith 2 processors (both INTEL Pentium III 500Mhz) and 2GB of RAM. The fields in Tables 4.1 and 4.2are straightforward, although it is necessary to remember that NPHIL denotes the number of philosophers(obviously, the larger NPHIL, the larger the number of reachable states). For what concerns the verificationoptions, we leave the default options for PRISM, and we give the option -m500 to FHP-Murϕ, to force itto use exactly 500 MB of RAM.

Note that, in these set of experiments, which do not involve mathematical operations, PRISM works betterthan FHP-Murϕ, which takes more time to complete the verifications.

Page 72: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

60 Chapter 4. Verification of BPCTL Properties

NPHIL Result Murϕ Mem PRISM Mem Murϕ Time PRISM Time

5 false 5.0e+2 1.70e+00 5.45e+01 2.00e+00

6 false 5.0e+2 1.43e+01 2.86e+02 1.26e+01

Table 4.1: Experimental results for the verification of a BPCTL property on the Pnueli-Zuck protocol as itis found in the PRISM distribution. The experiments were carried out on a machine with 2 processors, bothPentium III 500MHz, with 2GB of RAM. Time is in seconds, memory occupations are in MB.

NPHIL Result Murϕ Mem PRISM Mem Murϕ Time PRISM Time

3 true 5.0e+2 1.42e+00 1.81e+03 2.43e+00

4 true 5.0e+2 2.36e+01 1.25e+05 1.25e+02

Table 4.2: Experimental results for the verification of a BPCTL property on the Lehmann-Rabin protocolas it is found in the PRISM distribution. The experiments were carried out on the same machine of Table4.1. Time is in seconds, memory occupations are in MB.

NPHIL MAX WAIT Result Murϕ Mem PRISM Mem Murϕ Time PRISM Time

5 3 true 5.0e+2 9.17e+02 1.81e+03 2.75e+03

5 4 true 5.0e+2 N/A 1.79e+03 N/A

Table 4.3: Experimental results for the verification of a BPCTL property on the Pnueli-Zuck protocol as itwas modified in Section 3.3.1. The experiments were carried out on the same machine of Table 4.1. Timeis in seconds, memory occupations are in MB.

NPHIL MAX WAIT Result Murϕ Mem PRISM Mem Murϕ Time PRISM Time

3 4 true 5.0e+2 7.01e+01 1.17e+03 6.37e+02

4 3 true 5.0e+2 N/A 3.21e+04 N/A

Table 4.4: Experimental results for the verification of a BPCTL property on the Lehmann-Rabin protocolas it was modified in Section 3.3.1. The experiments were carried out on the same machine of Table 4.1.Time is in seconds, memory occupations are in MB.

Page 73: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

4.2 Experimental Results 61

For the modified version of the probabilistic dining philosophers, we verify a reliability property. In fact, inthese models there is a set o f error states, i.e. those satisfying a special atomic proposition φerr. Namely,φerr could be informally stated as “a philosopher does not eat for a too long time, and dies for starvation”.To define our reliability property, we introduce a new atomic proposition φund, which is a weaker versionof φerr. This means that, for all states s, if s satisfies φerr, then it satisfies also φund (informally, “aphilosopher does not eat for a long time, and he is in danger”). So, our undesired s tates are those satisfyingφund.

More in detail, suppose that φerr is defined by means of a constant kerr, denoting the maximum number oftimes that a philosopher can fail in getting both forks before dying (in our experiments, this kerr is namedMAX WAIT). On the other hand, φund is defined by means of a constant kund such that kund < kerr (inour experiments, we always took kund = kerr − 1). That is to say, when a philosopher fails for kund

consecutively times in getting both its forks, it reaches an undesired state (in which φund holds). Usingthe Murϕ syntax, we can define φerr as exists p: phil range do (wait[p] < MAX WAIT)endexists, while φund is exists p: phil range do (wait[p] < MAX WAIT MINOR)endexists (where MAX WAIT MINOR is kund).

Now, we want to say that, when an undesired state s is reached, then the system almost always reaches,from s and in a few steps, a non-error state. Then, our property states that there is a low probability that wereach in k1 steps a state s such that φund(s) holds, and there is not a high probability of reaching, from sand in k2 = k1

10 steps, a state t such that ¬φerr(t). The corresponding BPCTL formula is [tt U≤k1 (φund ∧¬[tt U≤k2¬φerr]≥1)]≤0. We give this BPCTL formula both to PRISM and FHP-Murϕ.

Our results are in Tables 4.3 and 4.4. In these experiments, we always set k1 = 20, and we use, as forthe experiments in Tables 4.1 and 4.4, a machine with 2 processors (both INTEL Pentium III 500Mhz) and2GB of RAM. NPHIL still indicates the number of philosophers, while MAX WAIT is maximum numberof times that a philosopher can fail in getting both forks before dying. For what concerns the verificationoptions, we again give the option -m500 to FHP-Murϕ, to force it to use exactly 500 MB of RAM. On theother hand, PRISM options are the default ones in the first row of Tables 4.3 and 4.4, while the “N/A” valuemeans that PRISM was unable to complete the verification. In this latter case, also the -m and -s options(totally MTBDD and algebraic verification algorithm respectively) have been used, with the same failingresult.

As already said in Section 3.3.1, this is due to the fact that these protocols requires some non-trivial math-ematical operations, that is exactly the case in which OBDDs, and therefore MTBDDs, reach their worstmemory occupation. On the contrary, mathematical operations in the computation of the transition functionnext is hardly a problem for FHP-Murϕ, that succeeds in completing these verifications.

4.2.2 A “REAL WORLD” PROBABILISTIC HYBRID SYSTEM

In this section we show our experimental results on using FHP-Murϕ for the analysis of the same realworld hybrid system we described in Section 3.3.2, namely the Control System for the Gas Turbine of a2MW Electric Co-generative Power Plant (ICARO) in operation at the ENEA Research Center of Casaccia(Italy).

Here, we want to prove that TCS satisfies a stronger property, which is not expressible using only finitehorizon safety formulas. To this end, in this section we verify if the TCS is robust, i.e. that the followingproperty holds: “if TCS reaches an undesired state, then it is able to return to a non-undesired state withan high probability”. Here, a state is considered an undesired state when it is outside a smaller safety rangethan the one defining the error states. More formally, let me,Me be the constants defining the safety range,i.e. error states are such that x /∈ [me,Me], where x is the controlled parameter. Then, we introduce twomore constants md,Md, such that an undesired state is such that x ∈ [me,md] ∪ [Md,Me]. This models

Page 74: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

62 Chapter 4. Verification of BPCTL Properties

the fact that the system may reach such a state, but it will crash if it stays in such a state for a too long time,since it is close to the error bounds me,Me.

Thus, our robustness property is equivalent to state the following: there is a low probability of reaching anundesired state s, such that there is not an high probability of reaching a non-undesired state from s. Therelative BPCTL formula is [tt U≤k1 (¬φ∧¬[tt U≤k2φ]≥1)]≤0.1, where φ defines the non-undesired states,and we suppose that the TCS is required to be robust with a 10% probability. The two constants k1 andk2 are chosen in such a way that k1 is sufficient to reach an undesired state (in our experiments, we took

k1 =⌈

Diam(n)100

100, where Diam(n) is the minimum number of states needed to reach an undesired state

when MAX D U = n), and k2 is not too high (in our experiments, we took k2 = k1

100 ).

Our results are in Table 4.5; the first columns meaning is straightforward, while in the field “Probability” isreported the value Pq [tt U

≤k1 (¬φ∧¬[tt U≤k2φ]≥1)], being q the system initial state (see Definition 2.11).Thus, the field “Probability” reports the probability of a robustness violation. As in Section 4.2.1, we useda machine with 2 processors (both INTEL Pentium III 500Mhz) and 2GB of RAM, and give to FHP-Murϕthe option-m500 to force it to use exactly 500 MB of RAM. The low values for the field “Probability”indicates that TCS is indeed robust; moreover, as it was expected, the probability of a failure increases withMAX D U.

MAX D U Visited States Rules Fired k1 CPU Time Probability

35 1.159160e+05 3.477480e+05 800 3.702400e+03 4.104681e-03

45 4.098000e+04 1.229400e+05 700 1.313900e+03 1.792883e-02

50 4.067700e+04 1.220310e+05 700 1.307850e+03 3.825000e-02

Table 4.5: Experimental results for the verification of a BPCTL property on the Turbogas Control System.The experiments were carried out on a machine with 2 processors, both Pentium III 500MHz, with 2GB ofRAM. Time is in seconds.

Page 75: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

CHAPTER 5

FHP-MURϕ LANGUAGE EXPRESSIVENESS

In this chapter we investigate some of the properties of the FHP-Murϕ input language, by using two math-ematical models of the language itself:

PFSS introduced in Definition 2.6; rather than a model of the language, it is a model of the structure usedduring the verification phase;

PRBTS introduced in Section 5.2 (Definition 5.1); it is indeed a model of the FHP-Murϕ input language.

As expected, these two models have the same expressive power, since both give rise to Markov Chains (Def-initions 2.7 and 5.3), and are both able to describe every Markov Chain, as will be proved in Propositions5.1 and 5.3.

This Chapter is organized as follows: in Section 5.1 it is shown that every Markov Chain can be described bymeans of a PFSS, while the remaining part if the chapter is dedicated to PRBTS. More in detail, in Section5.2 we introduce the PRBTSs, showing their definition and their main properties; Section 5.3 illustrates apossible use of PRBTSs. This Chapter ends with some examples of finite character SPs described via theFHP-Murϕ input language (Section 5.4).

5.1 MARKOV CHAINS AND PFSSS

In this section, we prove that each Markov Chain can be described by a PFSS; this is done in the followingproposition.

Proposition 5.1. Let M = (S,P, q) be a Markov Chain. Then it exists a PFSS S = (S, q,A,next) suchthat Smc = M.

Proof. Since the set of states and the starting state are the same, we just have to build up A and next in away such that Smc = M. In our construction, we use a singleton as set of labels, i.e. A = {a}. We definenext in the following way: for all s ∈ S, let ti ∈ S be the states such that P(s, ti) > 0; then, we posenext(s) = ∪i{(ti, a,P(s, ti))}.

Let Smc = (S,P′, q); we now show that Smc = M. To do this, we only have to prove that P′ = P. Tothis end, let s, t ∈ S be states; then, we have that P′(s, t) = p, where p is such that (t, a, p) ∈ next(s).However, since by construction p = P(s, t), we have the thesis.

Remark 5.1. Note that there are infinite PFSSs describing a given Markov Chain. In fact, consider againthe PFSS building in the proof of Proposition 5.1. For example, if we use two labels, i.e. A = {a1, a2}, we

could pose next(s) =(

∪i

{

(ti, a1,P(s,ti))

2

})

∪(

∪i

{

(ti, a2,P(s,ti))

2

})

, and we again have Smc = M.

63

Page 76: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

64 Chapter 5. FHP-Murϕ Language Expressiveness

5.2 PROBABILISTIC RULE BASED TRANSITION SYSTEMS

In Proposition 2.8 we showed that it is possible to analyze finite character SPs via reducing them to anequivalent Markov Chain. Since we know that we can describe Markov Chains in FHP-Murϕ, this allowsus to analyze finite character SPs with our tool. In this section, we want to directly show how FHP-Murϕinput language may describe a finite character SP. To this end, we need a new mathematical model of theFHP-Murϕ input language, in order to get more accuracy and closeness to the language than the PFSSstructure.

Here we formally define our mathematical model (called PRBTS) for the FHP-Murϕ input language, andwe show the relationships between PRBTSs and finite character SPs.

Definition 5.1. A Probabilistic Rule Based Transition System (shortened PRBTS in the following) S is a3-tuple (S,Rules, q), where S is a finite set (of states), q ∈ S and Rules is a finite set of pairs (p, f),with p being a function p : S → [0, 1] and f being a function f : S → S; moreover, for all s ∈ S,

(p,f)∈Rules

p(s) = 1.

Definition 5.2. An execution sequence (or path) in the PRBTS S = (S,Rules, q) is a nonempty finiteor infinite sequence π = s0s1s2 . . . where, for all i ≥ 0, there exists a pair (p, f) ∈ Rules, such thatf(si) = si+1 and p(si) > 0. If π is a path, we write π(k) for the state sk, and we write π|k for thesequence s0s1s2 . . . sk−1. The length of a finite path π = s0s1s2 . . . sk is k, i.e. the number of transitions,whereas the length of an infinite path is ∞; we denote with |π| the length of π.

As expected, to a PRBTS we can univocally associate a Markov Chain. This can be done as follows.

Definition 5.3. Let S = (S,Rules, q) be a PRBTS. The Markov Chain Smc = (S,P, q) associated with

S is defined as follows: P(s, t) =∑

(p,f)∈Ruless.t.f(s)=t

p(s) (taking as 0 a summation on an empty set).

Proposition 5.2. Let S = (S,Rules, q) be a PRBTS. Then, the Markov Chain Smc associated with S iswell defined.

Proof. To prove the thesis, we have to show that:

1. for all s, t ∈ S, P(s, t) ≥ 0; this comes from the fact that each P(s, t) is the sum of non-negativenumbers;

2. for all s ∈ S,∑

t∈S

P(s, t) = 1; in fact, for all s ∈ S we have that 1 =∑

(p,f)∈Rules

p(s) =

t∈S

(p,f)∈Ruless.t.f(s)=t

p(s) =∑

t∈S

P(s, t).

Finally, the following proposition show that every Markov Chain can be described by a PRBTS; this implies,by Proposition 5.1, that PFSS and PRBTS are equivalent formalisms.

Proposition 5.3. Let M = (S,P, q) be a Markov Chain. Then it exists a PRBTS S = (S,Rules, q) suchthat Smc = M.

Page 77: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

5.3 From Communicating Stochastic Processes to PRBTS 65

Proof. Since the set of states and the starting state are the same, we just have to build up Rules in away such that Smc = M. To this end, let next(s) = {t ∈ S | P(s, t) > 0} = {t1, . . . , tNs

} be,for all s ∈ S, the set of possible successors of s. This allows us to define a function f : S × N → Ssuch that f(s, i) = ti is i-th state in next(s), supposing that, for i > Ns, ti = tNs

1. Moreover, letN = maxs∈S{Ns} = maxs∈S{|next(s)|} be the maximum number of successors for a state in S.

Then, we pose Rules = {(p1, f1), . . . , (pN , fN)}, where, for all 1 ≤ i ≤ N , (pi, fi) are defined as follows.We pose fi(s) = f(s, i), while

pi(s) =

{

P(s, f(s, i)) if i ≤ Ns

0 otherwise

Let Smc = (S,P′, q); we now show that Smc = M. To do this, we only have to prove that P′ = P. To thisend, let s, t ∈ S be states. If P(s, t) = 0, then t /∈ next(s), so for all 1 ≤ i ≤ Ns we have that fi(s) 6= t,which implies P′(s, t) = 0. Otherwise, if P(s, t) > 0, let i be such that f(s, i) = t. Then, we have thatP′(s, t) = pi(s) = P(s, f(s, i)) = P(s, t).

Remark 5.2. As in Remark 5.1, there are infinite PRBTSs describing a given Markov Chain. As an example,we could define as many rules as the total number of states, composed by constant functions.

Note that a PRBTS may easily be defined by a program written in a suitable (e.g. C-like) programming lan-guage. This allows us to specify functions (p, f) ∈ Rules inside the program as functions or procedures.This makes their formulation parametric and concise. Indeed, we can state that a rule based (i.e. PRBTSoriented) approach to SP specification is, in many cases, exponentially shorter than a Markov Chain basedspecification approach. By a Markov Chain based specification approach we mean any language requiring,in many cases, an explicit (i.e. tabular) definition of the stochastic matrix of the input Markov Chain; thePRISM input language is an example of Markov Chain based approach.

In fact, by comparing the description of protocol LQS in Section 5.4.1 (with FHP-Murϕ, so with a PRBTS)with the description of the same protocol in PRISM (which is shown, for ITEM Q = 10, in Appendix C),we can see that the former is much shorter, more concise and more readable than the latter, since it does notgrow with the parameter ITEM Q.

5.3 FROM COMMUNICATING STOCHASTIC PROCESSES TO PRBTS

To exemplify the PRBTS usage as a low level definition language for SP, in this section we show how thedefinition of an SP S specified by means of Communicating Stochastic Processes can be translated into asuitable PRBTS.

Definition 5.4. A System of Communicating Stochastic Processes (SCSP) S is a 4-tuple (n, S,q,R),where:

• n is an integer (denoting the number of processes in our system);

• S = S1 × . . .×Sn is the Cartesian product of the finite sets (of states) S1, . . . , Sn, where Si denotesthe set of states of the i-th process;

1Indeed, here ti could be any state in next(s).

Page 78: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

66 Chapter 5. FHP-Murϕ Language Expressiveness

• q = (q1, . . . , qn) ∈ S is the initial state (constituted by the initial state of each Si);

• R = (R1, . . . ,Rn) is a n-tuple of sets such that, for all i = 1, . . . , n, Ri is a finite set of function

pairs (p, f) where p : S → [0, 1], f : S → Si, and∑

(p,f)∈Ri

p(s) = 1 holds for all 1 ≤ i ≤ n and for

all s ∈ S. Of course, Ri is the collection of rules defining the i-th process.

In the following we denote with boldface letters (e.g. x) elements of S = S1 × . . . × Sn and with xi thei-th component of x. We can define the transition relation of a SCSP assuming that processes are scheduledwith uniform probability (1/n if we have n processes).

Definition 5.5. Let S = (n, S,q,R) be a SCSP. The Markov Chain Smc = (S,P,q) associated with S is

defined as follows: P(s, t) =

n∑

i=1

(p,f)∈Ri s.t. (s1,...,si−1,f(s),si+1,...,sn)=t

p(s)

n(taking as 0 a summation

on an empty set).

Proposition 5.4. Let S = (n, S,q,R) be a SCSP. Then, the structure Smc = (S,P,q) associated with Sis indeed a Markov Chain.

Proof. To prove the thesis, we have to show that:

1. for all s, t ∈ S, P(s, t) ≥ 0; this comes from the fact that each P(s, t) is the sum of non-negativenumbers;

2. for all s ∈ S,∑

t∈S

P(s, t) = 1; in fact, for all s ∈ S we have that∑

t∈S

P(s, t) =

t∈S

n∑

i=1

(p,f)∈Ri s.t. (s1,...,si−1,f(s),si+1,...,sn)=t

p(s)

n=

1n

n∑

i=1

t∈S

(p,f)∈Ri s.t. (s1,...,si−1,f(s),si+1,...,sn)=t

p(s) = 1n

n∑

i=1

(p,f)∈Ri

p(s) = nn

= 1 .

Essentially PRBTS are (probabilistic) shared variable concurrent programs. Thus it is not surprising [38]that a SCSP can be transformed into a PRBTS using a suitable uniform probability scheduler. The followingdefinition shows how this can be done (e.g. along the lines in PRISM [52]).

Definition 5.6. Let S = (n, S,q,R) be a SCSP. We denote with Γ(S) the PRBTS (S,q,Rules) defined asfollows: Rules = ∪n

i=1 ∪(p,f)∈Ri{((λx.p(x)

n), f)}.

The following proposition follows immediately from the construction in Definition 5.6.

Proposition 5.5. Let S be a SCSP. Then Smc = Γ(S)mc.

Proof. Let Smc = (S,P,q) and Γ(S)mc = (S,P′,q). Since the set of states and the initial state arethe same in both cases, we only have to prove that P = P′. To this aim, let s, t ∈ S; then, P′(s, t) =

(p,f)∈Rules s.t.f(s)=t

p(s) =

n∑

i=1

(p,f)∈Ri s.t. (s1,...,si−1,f(s),si+1,...,sn)=t

p(s)

n= P(s, t).

Page 79: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

5.4 Two protocols in FHP-Murϕ 67

Note that the PRBTS transformation of a SCSP is not limited to the case in which the processes are sched-uled with a uniform probability. In fact, it is sufficient to modify Definition 5.6 in this way: Rules= ∪i=n

i=1 ∪(p,f)∈Ri{(λx.(s(i) · p(x)), f)}, where s is a function from {1, . . . , n} to [0, 1] denoting the

scheduling probability of the process i ∈ {1, . . . , n} (obviously, s must be such thatn∑

i=1

s(i) = 1).

5.4 TWO PROTOCOLS IN FHP-MURϕ

In this section we show how FHP-Murϕ can be used for automatic Finite Horizon Verification of PRBTS.

More specifically, we give two examples of our approach describing the behavior of two different queuingsystems, showing their implementation in FHP-Murϕ and sketching why they are more naturally describedin FHP-Murϕ than in PRISM.

Both examples describe queue systems with a certain probability that an element in the queue decides toleave the queue without having being served. This results in an error state.

5.4.1 A LENGTH-BASED QUEUE SYSTEM

The first system models a “Length-Based” Queue System (LQS in the following); its dynamics is describedbelow. In a generic state s, the following moves are allowed:

1. An enqueue operation. This operation is possible only if the queue is not full;

2. A dequeue operation. This operation is possible only if the queue is not empty;

3. Each element in the queue can depart from the queue (this results in an error state);

4. The system may remain in the same state s.

The probabilities of the preceding moves are as follows. Let n be the number of queue entries. Supposethat, in state s, h operations are allowed. We have that 1 ≤ h ≤ 3 + n, since each of the at most nelements in the queue can go in an error state. Then the probability of the first two moves (if they areallowed) is 1

h. The probability that a queue element i enters an error state is 1−e−j

h, where j is the number

of elements preceding i in the queue (i.e. the number of dequeue operations that i must wait for before it isits turn). This means that the more elements preceding i, the higher the probability that i leaves the queue.Finally, the probability that no operation is performed is the complement to 1 of the sum of the other definedprobabilities.

The implementation of such a system in FHP-Murϕ is quite simple. The queue is modeled with a circulararray managed by two pointers, head and tail. For each entry in the queue, we memorize if it is in acorrect state or in an error state (i.e. the element has left).

In Figure 5.1 we show the two main functions, prob trans and make trans, and how they are calledby the rule ‘‘main’’.

Function prob trans returns the outgoing probabilities from the current state s. The parameter i identi-fies the move whose probability has to be computed. Moreover, prob trans uses function prob err tocompute 1−e−j

h, where j is the number of elements preceding an element in the queue. On the other hand,

Page 80: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

68 Chapter 5. FHP-Murϕ Language Expressiveness

f u n c t i o n prob_trans(i : trans_allow_type) : real_type;begincalc_trans_allow(trans_allow, enq_deq);/* now, trans allow contains the number of all allowed

moves, while enq deq considers only the enqueue anddequeue operations */

i f (i >= trans_allow) then/* not allowed transition (i ranges on all the possible

transitions, but only a subset is allowed) */re turn 0.0;

e l s e /* allowed transitions */i f (i < enq_deq) then /* enqueue and dequeue */

re turn 1.0/trans_allow;e l s e i f (i < trans_allow - 1) then /* leave the queue */

re turn prob_err(i - enq_deq)/trans_allow;e l s e /* i = trans allow− 1; stay in the same state */

re turn 1.0 - sum_prob_prec();e n d i f; e n d i f; e n d i f;

end; /* prob_trans() */

procedure make_trans(i : trans_allow_type);begin/* the first part is the same as prob trans */calc_trans_allow(trans_allow, enq_deq);i f (i < trans_allow) then/* instead of computing probabilities, moves are done */

i f (!queue_empty() & i = 0) then/* dequeue is allowed and i indicates dequeue, thus

dequeue operation is performed */q[head] := noerr;head := head = ITEM_Q - 1? 0 : head + 1;

e l s e i f (!queue_full() & (enq_deq = 1? i = 0: i = 1)) then/* the same as above, but with the enqueue operation */q[tail] := noerr;tail := tail = ITEM_Q - 1? 0 : tail + 1;

e l s e i f (i != trans_allow - 1) then /* leave the queue */q[i - enq_deq] := err;

/* if i = trans allow− 1 no action is done */e n d i f; e n d i f; e n d i f; e n d i f;

end; /* make_trans() */

r u l e s e t i : trans_allow_type do/* general rule for the whole system */r u l e "main" prob_trans(i) ==>

begin make_trans(i); end;end; /* ruleset */

pctl [ t rue u n t i l <= STEPS( e x i s t s i : queue_range do q[i] = err e n d e x i s t s)

] <= 0.1;

Figure 5.1: FHP-Murϕ implementation sketch for LQS

Page 81: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

5.4 Two protocols in FHP-Murϕ 69

function make trans modifies state s so as to generate a next state. It uses the parameter i in the samemanner as prob trans.

Finally, the ruleset in Figure 5.1 calls the rule ‘‘main’’ with the different values for the variablei which are needed in functions prob trans and make trans.

For what regards the property to be verified, we want to check if that the probability of the event “forall states s that are reachable in STEPS steps, s is not an error state” is at most 0.1, where STEPS is aparameter of the verification.

5.4.2 A TIME-BASED SERVER-QUEUE SYSTEM

The second system models a “Time-Based” Server-Queue System (TSQS in the following). Differentlyfrom LQS, we now model not only the queue, but also the server status. Namely, in a generic TSQS state,there are two different sets of allowed moves. These two sets of moves alternate in execution paths, i.e. if astate t has been reached by an operation of the first set, then only actions of the second set are allowed fromt, and vice versa. More in detail, these are the two sets of moves:

• The first set just consists of the same enqueue, dequeue and null operations of LQS, plus the serverstatus changing. These transitions take place with uniform probability; namely, if n of these movesare allowed, then their probability is 1

n. However, the server status changing may be carried out in

different ways. In fact, we model the server status as a counter (s in Figures 5.2 and 5.3) rangingfrom 0 to MAX COUNT S, representing the time of service. If the server counter is 0, the server isfree, then a dequeue (on a nonempty queue) can be made. In this case, the server counter is setto MAX COUNT S; as already said, the probability of this transition is 1

n. Otherwise, if the server

counter is greater than 0, then it can be reset to 0 or simply decremented. The probabilities of thesetransitions are, respectively, 1

n· sMAX COUNT S

(i.e. the probability is proportional to the current servercounter value) and 1

n·(

1 − sMAX COUNT S

)

. This models the fact that the higher the time of service, thehigher the probability of returning free. Note that, the sum of these two probabilities is 1

n, i.e. the

overall probability for the server status change.

• The second set consists of moves updating a counter associated with each element in the queue, thusmodeling the time spent by the element in the queue. When this counter reaches a given maximumvalue (MAX COUNT Q), we are in an error state. The updating phase consists in k + 1 possibletransitions, where k is the number of elements currently in the queue. Namely, one of the k elementcounters can immediately reach MAX COUNT Q with probability directly proportional to the currentcounter value, while all the other counters are simply incremented. Moreover, the last possibilityconsists in incrementing all counters; the probability of this move is the complement to one of all theprevious ones. This models the fact that the higher the time spent in queue, the higher the probabilityto go away without being served.

The FHP-Murϕ implementation of TSQS is as simple as the LQS one, and it is sketched in Figures 5.2 and5.3. The data structures are essentially the same as in LQS: the only modification consists in maintaining acounter (and not a boolean) for each entry, and in adding a counter to model the server. The structure of thecode is the same as in Figure 5.1, so we only give functions prob trans and make trans.

For what regards the property to be verified, we want to check, analogously as for LQS, if that the probabilityof the event “for all states s that are reachable in STEPS of steps, s is not an error state” is at most 0.1,where STEPS is a parameter of the verification.

Note that both these TSQS and LQS are more difficult to write in the PRISM input language. In fact,PRISM only allows constant probabilities to be defined on transitions. On the other hand, here we have that

Page 82: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

70 Chapter 5. FHP-Murϕ Language Expressiveness

f u n c t i o n prob_trans(i : trans_allow) : real_type;begincalc_trans_allow(trans_allow);/* now, trans allow contains the number of allowed

transitions from the current state. trans allow isdifferent from n of Section 5.4.2, since the two serverstatus changing modalities are both counted */

i f (i >= trans_allow) then/* not allowed transition (i ranges on all the possible

transitions, but only a subset is allowed) */re turn 0.0;

e l s e/* modglob distinguish between the two set of moves */

i f (mod_glob = 0) then/* first set of moves */

i f (s > 0 & i < 2) then/* probabilities for server status changing *//* the server counter is modifiable only if it is

greater than 0 (thus, the server is busy) */i f (i = 1) then/* server counter to be decremented */

re turn (s/MAX_COUNT_S)/(trans_allow - 1);/* we divide by (trans allow− 1) because the first two

transitions are already complementary */e l s e/* i = 0: server counter to be reset */

re turn (1.0 - s/MAX_COUNT_S)/(trans_allow - 1);e n d i f;

e l s e/* probabilities for enqueue, dequeue and no operation *//* 1

nis returned; we only have to take care of the fact

that trans allow = n− 1 when s > 0, since both the twoserver status changing modalities are counted */

re turn 1.0/(s > 0? trans_allow - 1 : trans_allow);e n d i f;

e l s e /* mod glob = 1 *//* second set of moves */

i f (i != trans_allow - 1) then/* probability of one among the k moves of Section 5.4.2

(go to error) *//* entry(i) returns the i-th element in the queue */

re turn (q[entry(i)]/MAX_COUNT)/trans_allow;e l s e/* probability of k + 1-th move of Section 5.4.2 (all

counters incremented) */re turn 1.0 - sum_prob_prec();

e n d i f; e n d i f;e n d i f;

end; /* prob_trans() */

Figure 5.2: FHP-Murϕ implementation sketch for TSQS (1)

Page 83: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

5.4 Two protocols in FHP-Murϕ 71

/* auxiliary function, returns true if i indicates anenqueue */

f u n c t i o n it_is_time_to_enqueue(i : trans_allow) : boolean;begin

i f (queue_full()) then /* enqueue not allowed */re turn f a l s e ;

e l s e /* enqueue allowed, check i */i f (s > 0) then re turn (i > 3);e l s e

i f (queue_empty()) then re turn (i = 0);e l s e re turn (i < 2);e n d i f; e n d i f; e n d i f;

end; /* it_is_time_to_enqueue() */

procedure make_trans(i : trans_allow);begincalc_trans_allow(trans_allow);i f (i < num_trans_allow) then

i f (mod_glob = 0) theni f (s > 0 & i < 2) then s := (i = 1? s - 1 : 0);e l s e

i f (!queue_empty() & s = 0 & i = 0) thendequeue(); /* no matter what is dequeued */s := MAX_COUNT_S;

e l s ei f (it_is_time_to_enqueue(i)) thenenqueue(); /* no matter what is enqueued */

e n d i f; e n d i f; e n d i f;e l s e /* mod glob = 1 */

i f (i != num_trans_allow - 1) then/* entry(i) returns the i-th element in the queue */q[entry(i)] := MAX_COUNT;

e n d i f;f o r k : queue_range do

i f (in_queue(k) & q[k] != MAX_COUNT) thenq[k] := q[k] + 1;

e n d i f;endfor;

e n d i f;e n d i f; /* if i = trans allow− 1 no action is done *//* switch to the other set of moves */mod_glob := (mod_glob + 1) mod 2;

end; /* make_trans() */

pctl [ t rue u n t i l <= STEPS( e x i s t s i:queue_range do q[i] = MAX_COUNT e n d e x i s t s)

] <= 0.1;

Figure 5.3: FHP-Murϕ implementation sketch for TSQS (2)

Page 84: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

72 Chapter 5. FHP-Murϕ Language Expressiveness

the transition probabilities depends on the current state. Hence, to implement these protocols in PRISM,we are forced to list the values of the parameters from which they depend, and then to tabulate, for each ofthem, the transition probability values.

As an example, consider again LQS: to describe it with the PRISM input language, we have to list all thepossible values representing the number of elements preceding the current one, asking for each of them if itis the correct value; the result is shown in Figure 5.4 for a server with 4 entries. Note that the PRISM codein Figure 5.4 is not parametric, i.e. it is not sufficient to modify the ITEM Q parameter to obtain the modelfor the LQS with more than 4 entries; on the opposite, this is possible in FHP-Murϕ. In Appendix C weshow the PRISM source code for LQS with ITEM Q = 10.

Page 85: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

5.4 Two protocols in FHP-Murϕ 73

p r o b a b i l i s t i cc o n s t ITEM_Q = 4;

r a t e exp_f_1_d_4 = 0.15803013970713941960;// 1−e−1

4

r a t e exp_f_2_d_4 = 0.21616617919084682702;// 1−e−2

4r a t e a_third = 0.33333333333333333333;r a t e a_fourth = 0.25;

r a t e rem_1 = 0.34196986029286058040;//1 − 12 − 1−e−1

4

r a t e rem_2 = 0.37580368110201375338;//1 − 14 − 1−e−1

4 − 1−e−2

4module mainq0 : [0..1];// 0 : noerr; 1 : errq1 : [0..1];// 0 : noerr; 1 : errq2 : [0..1];// 0 : noerr; 1 : errq3 : [0..1];// 0 : noerr; 1 : errnum : [0..ITEM_Q - 1];// number of items in the queueh : [0..ITEM_Q - 1];// head of the queue// 2 moves (enqueue and nomove)[] (num = 0) -> 0.5 : (num’ = num+1) + 0.5 : (num’ = num);// 3 moves (enqueue, dequeue, nomove)[](num=1&h=ITEM_Q-1)->a_third:(num’=num+1)+

a_third:(num’=num-1&h’=0)+a_third:(num’=num);

[](num=1&h!=ITEM_Q-1)->a_third:(num’=num+1)+a_third:(num’=num-1&h’=h+1)+a_third:(num’=num);

// 4 moves (enqueue, dequeue, 1 item status change, nomove)[](num=2&h=0)->a_fourth:(num’=num+1)+

a_fourth:(num’=num-1&h’=1)+exp_f_1_d_4:(q1’=1)+rem_1:(num’=num);

[](num=2&h=1)->a_fourth:(num’=num+1)+a_fourth:(num’=num-1&h’=2)+exp_f_1_d_4:(q2’=1)+rem_1:(num’=num);

[](num=2&h=2)->a_fourth:(num’=num+1)+a_fourth:(num’=num-1&h’=3)+exp_f_1_d_4:(q3’=1)+rem_1:(num’=num);

[](num=2&h=3)->a_fourth:(num’=num+1)+a_fourth:(num’=num-1&h’=0)+exp_f_1_d_4:(q0’=1)+rem_1:(num’=num);

// 4 moves (dequeue, 2 items status change, nomove)[](num=3&h=0)->a_fourth:(num’=num-1&h’=1)+

exp_f_1_d_4:(q1’=1)+exp_f_2_d_4:(q2’=1)+rem_2:(num’=num);

[](num=3&h=1)->a_fourth:(num’=num-1&h’=2)+exp_f_1_d_4:(q2’=1)+exp_f_2_d_4:(q3’=1)+rem_2:(num’=num);

[](num=3&h=2)->a_fourth:(num’=num-1&h’=3)+exp_f_1_d_4:(q3’=1)+exp_f_2_d_4:(q0’=1)+rem_2:(num’=num);

[](num=3&h=3)->a_fourth:(num’=num-1&h’=0)+exp_f_1_d_4:(q0’=1)+exp_f_2_d_4:(q1’=1)+rem_2:(num’=num);

endmodule

Figure 5.4: PRISM implementation for LQS with 4 queue entries

Page 86: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor
Page 87: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

CHAPTER 6

CONCLUSIONS

In this Thesis, we have showed that it is possible, and most of all effective, to design algorithms of explicittype for Probabilistic Model Checking.

To this end, we presented two algorithms able to verify if a given a Markov Chain satisfies a given finitehorizon property. The first algorithm only deals with finite horizon safety properties, i.e. it may checkwhether the probability of reaching an error state in at most k steps is below a given threshold α. On theother hand, the second algorithm handles the full BPCTL (Bounded PCTL), so allowing to verify morecomplex properties, such as e.g. robustness in Discrete Time Probabilistic Hybrid Systems. Thus, both ouralgorithm work on bounded properties, i.e. they consider only system runs of finite length.

In order to show the effectiveness of our approach, we implemented our algorithms within a suitable ex-tension of the Murϕ verifier. We call FHP-Murϕ (Finite Horizon Probabilistic Murϕ) such extension ofthe Murϕ verifier. This allows us to make experiments, by comparing FHP-Murϕ with PRISM, a state-of-the-art symbolic model checker for Markov Chains. Our experimental results show that FHP-Murϕ caneffectively handle verifications for systems that are out of reach for PRISM, namely those involving arith-metic operations on the state variables. Moreover, we also showed how FHP-Murϕ have been successfullyused to verify interesting stochastic properties on a “real world” discrete time probabilistic hybrid system,namely the Control System of ICARO, a system in operation at the ENEA Research Center of Casaccia(Italy).

In conclusion, we have showed that the explicit approach to probabilistic model checking is feasible andeffective, and that FHP-Murϕ has to be considered among the available probabilistic model checkers.

6.1 FUTURE WORKS

A promising future works direction is to extend FHP-Murϕ, in order to make it more complete w.r.t.PRISM. In fact, PRISM can actually handle, besides Discrete Time Markov Chains, also Markov DecisionProcesses (MDP) and Continuous Time Markov Chains (CTMC). Moreover, on Discrete Time MarkovChains PRISM is able to verify any PCTL formula, including infinite horizon properties, while FHP-Murϕonly deals with bounded properties. However, PRISM always uses symbolic algorithms, so its approachworks well as long as the system dynamics does not involve heavy arithmetical computations. Thus, ex-tending our approach will probably enlarge the class of automatically verifiable probabilistic systems.

In particular, let us consider CTMCs, which is a widely used model for stochastic systems [8, 9, 29, 32, 36].In order to make FHP-Murϕ able to verify a finite horizon CSL properties Φ on a CTMC C, we mayapproximate C with a proper Discrete Time Markov Chain MC . Then, our algorithms may be applied toverify if Φ |= MC , and, finally, a performance comparison with PRISM may be carried out.

75

Page 88: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor
Page 89: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

APPENDIX A

FHP-MURϕ: THE INPUT LANGUAGE

Like the other explicit model checkers, a Murϕ verification is made of three commands:

1. the Murϕ compiler mu (which results from the make compilation of the files in the src directory inthe Murϕ distribution) is invoked on a file NFSS.m describing the NFSS to be analyzed. This gener-ates a file NFSS.C, containing the C++ code implementing the body of rules, start states, invariants,functions and procedures, plus other stuffs. Of course, it is possible to pass various options to mu,e.g. to enable hash compaction (-c).

2. the file NFSS.C generated in step 1 is compiled with the standard C++ compiler, setting as includingdirectory the include directory of the Murϕ distribution. This allows to use the main verificationroutines implemented in the files in the include directory. We call NFSS the compilation result.

3. to begin the verification, it is sufficient to launch the NFSS executable created in step 2. As in step 1,it is possible to pass various options to the verifier, e.g. to set the maximum RAM memory available(e.g. -mN , being N the available amount of RAM memory in megabytes).

To implement FHP-Murϕ, starting from the original Murϕ code, we modify both the files in the srcdirectory and in the include directory. In this appendix, we will show in detail the modifications done tofiles in the src directory, while in Appendix B we focus on the include directory

Thus, in this appendix, we give the technical details on how we modify the Murϕ input language in orderto make it able to define a Markov Chain. In Section A.1 we describe the modifications we have done to theMurϕ input language grammar, while in Section A.2 we show the Lex, Yacc and C++ code implementingsuch modifications, which is stored in the files in src directory.

A.1 AN OVERALL DESCRIPTION

To make the original Murϕ input language able to define Markov Chains, we modify it in the followingparts:

1. We add a probability specification to each start state;

2. We change the semantics of rules;

3. We allow to specify BPCTL properties (see Section 2.2).

To allow the specification of Discrete Time Stochastic Hybrid Systems, it is useful to have state variablesranging on real numbers. For this reason in the following we will consider the Murϕ version enhanced withfinite precision real numbers, as described in [17].

77

Page 90: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

78 Chapter A. FHP-Murϕ: the Input Language

In the following, to describe the new language, we give the BNF of the nonterminals we modified; as usual,we enclose with brackets [] the optional parts and with braces {} the optional parts which can be repeatedmore than one time. When brackets or braces are indeed part of the language, they will be preceded by abackslash \[\], \{\}. Moreover, nonterminals will be enclosed by angle brackets <>.

To add probabilities on rules, we modify the semantics of the simplerule nonterminal production ofthe Murϕ language grammar (Chapter 7 of the documentation [47]) as follows. The original production,without priority and fairness (not modified in our work), was

<simplerule> ::= rule [ <expr> ] ==> [ {<decl>} begin ] [ <stmts> ] end.

In FHP-Murϕ, we simply require the expression after the keyword rule (i.e. expr) to be a real expressionvalued in [0, 1], instead of a boolean as it is for Murϕ. FHP-Murϕ does not allow simultaneous use of bothboolean and probability based rules.

The above modification to <simplerule> has a deep impact on Murϕ semantics. In fact, with booleanrules, each state has a set of enabled transitions, leading to other states; the activation of a rule only dependson its condition being true or false. In our probabilistic setting, each Murϕ rule defines a pair (p, f) of thePRBTS being defined.

Finally, we modify the main <prog> nonterminal, to force each FHP-Murϕmodel to end with exactly oneBPCTL properties. Thus, we introduce a new nonterminal <bpctl>, defining the BPCTL language:

<bpctl> ::= pctl <bpctlformula>

<bpctl f> ::= <bpctl f> && <bpctl f>

| <bpctl f> || <bpctl f>

| !!<bpctl f>

| (<bpctl f>)

| <expr>

| \[ <bpctl f> UNTIL <= <expr> <bpctl f> \] w <expr>

| \[ NEXT <bpctl f> \] w <expr>

A.2 C++, LEX AND YACC CODE

We now present the modifications we did to the original Murϕ to implement our new input language. To doso, it was necessary to modify the code of some files in the src directory of the original Murϕ distribution.Here, we present only the modified parts, giving also the context in which they were done.

Finally, from a user point of view, the Murϕ compiler mu has been modified so as to include three newoptions:

1. --bpctl is the more important one, since it generates the C++ file for the probabilistic verification,starting from a PFSS model.

2. --probequalk is similar to the preceding one, but starts from a NFSS model. This is translated ina PFSS models by simply assuming that, if the current state has n outgoing edges, then each of thetransitions will have probability 1

n.

3. --probrules is the opposite of the preceding one: it takes a PFSS model and translates it in aNFSS (a rule is activated if its probability is strictly greater than zero).

Page 91: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

A.2 C++, Lex and Yacc Code 79

A.2.1 MODIFICATIONS TO MU.Y

%{

...

void pctlUntilError(bool is_real, bool is_int, bool has_value, doublevalue, bool is_int_buntil, bool has_value_buntil, i n t buntil){

Error.CondError(!is_real && !is_int, "Probability bound for pctlformulas must be real.");Error.CondError(!has_value, "Probability bound for pctl formulas mustbe constant.");

Error.CondError(value < 0.0 || value > 1.0, "Probability bound forpctl formulas must be in [0, 1].");Error.CondError(!is_int_buntil, "Bound for UNTIL must be integer.");i f (!Error.CondError(!has_value_buntil, "Bound for UNTIL must beconstant."))Error.CondError(buntil < 0, "Bound for UNTIL must be at least 0.");

}

void pctlNextError(bool is_real, bool is_int, bool has_value, doublevalue){

Error.CondError(!is_real && !is_int, "Probability bound for pctlformulas must be real.");Error.CondError(!has_value, "Probability bound for pctl formulas mustbe constant.");

Error.CondError(value < 0.0 || value > 1.0, "Probability bound forpctl formulas must be in [0, 1].");

}%}

...

%token<real> REALCONST%token REAL%token LOG%token LOG10%token EXP%token SIN%token COS%token TAN%token FABS%token FLOOR%token CEIL%token SQRT%token FMOD%token POW%token ASIN%token ACOS%token ATAN%token SINH%token COSH%token TANH

...

%left PCTLOR%left PCTLAND%left PCTLNOT

Page 92: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

80 Chapter A. FHP-Murϕ: the Input Language

...

%type <typedecl_p> realtype

...

%type <pctl_p> pctl pctlformula pctlU pctlX

...

/* Starting nonterminal */prog :

/* this is as before */{ symtab->pushscope(); }decls{ theprog->globals = symtab->getscope(); }procDecls{ theprog->procedures = symtab->getscope(); }rules{theprog->bits_in_world = offset;theprog->rules = $6;Error.CondError(!hasrule, "Program has no rules.");Error.CondError(!has_startstate,"Program has no startstates.");

}/* this is added */pctl{theprog->pctl_form = $8;symtab->popscope();Error.CondError(symtab->topscope() != 0, "Internal: Didn’t \

pop enough scopes.\nIf the model seems to be correct, you may have\improperly used a reserved word");

};

...

pctl : PCTL pctlformula semi{Error.CondError(!args->bpctl && !args->pmurphik,"PCTL formulas supported only with --bpctl or --pmurphik.");

$$ = $2;}| /* empty */{Error.CondError(args->bpctl || args->pmurphik,"PCTL formulas required with --bpctl and --pmurphik.");

$$ = NULL;};

pctlformula : pctlformula PCTLAND pctlformula{$$ = new pctl($1, $3, NULL, AND_PCTL, 0, NULL);}| pctlformula PCTLOR pctlformula{$$ = new pctl($1, $3, NULL, OR_PCTL, 0, NULL);

Page 93: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

A.2 C++, Lex and Yacc Code 81

}| pctlformula PCTLIMPLIES pctlformula{$$ = new pctl($1, $3, NULL, IMPL_PCTL, 0, NULL);

}| PCTLNOT pctlformula{$$ = new pctl($2, NULL, NULL, NOT_PCTL, 0, NULL);

}| ’(’ pctlformula ’)’{$$ = $2;

}| pctlU| pctlX{$$ = $1;

}| expr //atomic proposition{Error.CondError(!type_equal($1->gettype(), booltype),"Atomic propositions in BPCTL formulas have to be \

boolean expressions.");$$ = new pctl(NULL, NULL, $1, AP_PCTL, 0, NULL);

};

pctlU : ’[’ pctlformula UNTIL LEQ expr pctlformula ’]’ ’<’ expr{pctlUntilError(type_equal($9->gettype(), realtype),type_equal($9->gettype(), inttype), $9->hasvalue(),(double)$9->getvalue(), type_equal($5->gettype(), inttype),$5->hasvalue(), $5->getvalue());

$$ = new pctl($2, $6, NULL, UNTIL_PCTL, $5->getvalue(), $9);$$->op = PCTL_L;

}| ’[’ pctlformula UNTIL LEQ expr pctlformula ’]’ LEQ expr{pctlUntilError(type_equal($9->gettype(), realtype),type_equal($9->gettype(), inttype), $9->hasvalue(),(double)$9->getvalue(), type_equal($5->gettype(), inttype),$5->hasvalue(), $5->getvalue());

$$ = new pctl($2, $6, NULL, UNTIL_PCTL, $5->getvalue(), $9);$$->op = PCTL_LEQ;

}| ’[’ pctlformula UNTIL LEQ expr pctlformula ’]’ ’>’ expr{pctlUntilError(type_equal($9->gettype(), realtype),type_equal($9->gettype(), inttype), $9->hasvalue(),(double)$9->getvalue(), type_equal($5->gettype(), inttype),$5->hasvalue(), $5->getvalue());

$$ = new pctl($2, $6, NULL, UNTIL_PCTL, $5->getvalue(), $9);$$->op = PCTL_G;

}| ’[’ pctlformula UNTIL LEQ expr pctlformula ’]’ GEQ expr{pctlUntilError(type_equal($9->gettype(), realtype),type_equal($9->gettype(), inttype), $9->hasvalue(),(double)$9->getvalue(), type_equal($5->gettype(), inttype),$5->hasvalue(), $5->getvalue());

$$ = new pctl($2, $6, NULL, UNTIL_PCTL, $5->getvalue(), $9);$$->op = PCTL_GEQ;

};

pctlX : ’[’ NEXT pctlformula ’]’ ’<’ expr

Page 94: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

82 Chapter A. FHP-Murϕ: the Input Language

{pctlNextError(type_equal($6->gettype(), realtype),type_equal($6->gettype(), inttype), $6->hasvalue(),(double)$6->getvalue());

$$ = new pctl($3, NULL, NULL, NEXT_PCTL, 0, $6);$$->op = PCTL_L;

}| ’[’ NEXT pctlformula ’]’ LEQ expr{pctlNextError(type_equal($6->gettype(), realtype),type_equal($6->gettype(), inttype), $6->hasvalue(),(double)$6->getvalue());

$$ = new pctl($3, NULL, NULL, NEXT_PCTL, 0, $6);$$->op = PCTL_LEQ;

}| ’[’ NEXT pctlformula ’]’ ’>’ expr{pctlNextError(type_equal($6->gettype(), realtype),type_equal($6->gettype(), inttype), $6->hasvalue(),(double)$6->getvalue());

$$ = new pctl($3, NULL, NULL, NEXT_PCTL, 0, $6);$$->op = PCTL_G;

}| ’[’ NEXT pctlformula ’]’ GEQ expr{pctlNextError(type_equal($6->gettype(), realtype),type_equal($6->gettype(), inttype), $6->hasvalue(),(double)$6->getvalue());

$$ = new pctl($3, NULL, NULL, NEXT_PCTL, 0, $6);$$->op = PCTL_GEQ;

};

/* general expression. */expr :

...

| REALCONST{$$ = new expr( $1, realtype);

}| LOG ’(’ expr ’)’{$$ = new mathexpr($3,NULL,1);

}| LOG10 ’(’ expr ’)’{$$ = new mathexpr($3,NULL,2);

}| EXP ’(’ expr ’)’{$$ = new mathexpr($3,NULL,3);

}| SIN ’(’ expr ’)’{$$ = new mathexpr($3,NULL,4);

}| COS ’(’ expr ’)’{$$ = new mathexpr($3,NULL,5);

}| TAN ’(’ expr ’)’

Page 95: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

A.2 C++, Lex and Yacc Code 83

{$$ = new mathexpr($3,NULL,6);

}| FABS ’(’ expr ’)’{$$ = new mathexpr($3,NULL,7);

}| FLOOR ’(’ expr ’)’{$$ = new mathexpr($3,NULL,8);

}| CEIL ’(’ expr ’)’{$$ = new mathexpr($3,NULL,9);

}| SQRT ’(’ expr ’)’{$$ = new mathexpr($3,NULL,10);

}| FMOD ’(’ expr ’,’ expr ’)’{$$ = new mathexpr($3,$5,11);

}| POW ’(’ expr ’,’ expr ’)’{$$ = new mathexpr($3,$5,12);

}| ASIN ’(’ expr ’)’{$$ = new mathexpr($3,NULL,13);

}| ACOS ’(’ expr ’)’{$$ = new mathexpr($3,NULL,14);

}| ATAN ’(’ expr ’)’{$$ = new mathexpr($3,NULL,15);

}| SINH ’(’ expr ’)’{$$ = new mathexpr($3,NULL,16);

}| COSH ’(’ expr ’)’{$$ = new mathexpr($3,NULL,17);

}| TANH ’(’ expr ’)’{$$ = new mathexpr($3,NULL,18);

}

...

A.2.2 MODIFICATIONS TO MU.L

...

REAL ({DIGIT}+"."{DIGIT}+)"!!" { re turn( PCTLNOT ); }"->" { re turn( IMPLIES ); }

Page 96: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

84 Chapter A. FHP-Murϕ: the Input Language

"->>" { re turn( PCTLIMPLIES ); }"&&" { re turn( PCTLAND ); }"||" { re turn( PCTLOR ); }{REAL} {

sscanf( yytext, "%le", &(yylval.real) );re turn(REALCONST);

}

...

A.2.3 MODIFICATIONS TO LEXTABLE.C

...

lextable::lextable(){

...

/* IM: PCTL (until already present) */enter_reserved("pctl_next", NEXT);enter_reserved("pctl", PCTL);

enter_reserved("real",REAL);enter_reserved("log",LOG);enter_reserved("log10",LOG10);enter_reserved("exp",EXP);enter_reserved("sin",SIN);enter_reserved("cos",COS);enter_reserved("tan",TAN);enter_reserved("fabs",FABS);enter_reserved("floor",FLOOR);enter_reserved("ceil",CEIL);enter_reserved("sqrt",SQRT);enter_reserved("fmod",FMOD);enter_reserved("pow",POW);enter_reserved("asin",ASIN);enter_reserved("acos",ACOS);enter_reserved("atan",ATAN);enter_reserved("sinh",SINH);enter_reserved("cosh",COSH);enter_reserved("tanh",TANH);

}

A.2.4 MODIFICATIONS TO MU.H

...

// pctl extensionenum pctl_type {UNTIL_PCTL, NEXT_PCTL, AP_PCTL, AND_PCTL, OR_PCTL,IMPL_PCTL, NOT_PCTL};

enum pctl_ord {PCTL_L, PCTL_LEQ, PCTL_G, PCTL_GEQ};

...

Page 97: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

A.2 C++, Lex and Yacc Code 85

/********************class argclass-- command line argument handling-- a registry of command-line options.-- Argclass inspired by Andreas\’ code.********************/

c l a s s argclass{

i n t argc;char **argv;

p u b l i c:// variables/* name of the input file */char *filename;/* whether to print license */bool print_license;/* whether to print option */bool help;/* whether not to bitpack the state vector */bool no_compression;/* whether not to hashcompact states in hash tbl */bool hash_compression;/* IM: cached murphi */bool hash_cache;/* IM: disk murphi */bool hash_disk;/* IM: standard verification starting from probabilistic rules */bool prob_rules;/* IM: probabilistic murphi with finite horizon; now used only asinternal variable */

bool pmurphik;/* IM: probabilistic murphi with finite horizon, with booleanexpressions on rules */

bool probequalk;/* IM: bounded probabilistic model checking */bool bpctl;/* runtime checking? */c o n s t bool checking;/* suppress code generation for dead rules */bool remove_deadrule;/* symmetry algorithm number */i n t symmetry_algorithm_number;

// initializerargclass( i n t ac, char** av);

// supporting routineschar *NextFile();bool Flag(char *arg);void PrintInfo( void );void PrintOptions( void );void PrintLicense( void );

};

...

/********************Class program-- for storing parsed tree********************/

s t r u c t program :TNode{

i n t bits_in_world;ste *globals;

Page 98: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

86 Chapter A. FHP-Murϕ: the Input Language

ste *procedures;rule *rules;pctl *pctl_form; // IM: pctl formularulerec *rulelist;rulerec *startstatelist;rulerec *invariantlist;rulerec *fairnesslist;liverec *livenesslist;symmetryclass symmetry;

program( void ): globals(NULL), procedures(NULL),rules(NULL), rulelist(NULL), startstatelist(NULL),invariantlist(NULL), fairnesslist(NULL), livenesslist(NULL),pctl_form(NULL)

{}void make_state( i n t bits_in_world);v i r t u a l char *generate_code();

};

...

/********************Yacc’s YYSTYPE-- Yacc’s YYSTYPE, done here instead of in a %union in yacc-- so that we don’t get redefinitions when y.tab.c #include’s-- this which #include’s y_tab.h.********************/

union YYSTYPE { /* sloppy, sloppy, sloppy. Bleah. */TNode *node;expr *expr_p; // an expression.designator *desig_p; // a designator (l-value).decl *decl_p; // a declaration.typedecl *typedecl_p; // a type declaration.ste *ste_p; // a record field list or formal parameter liststmt *stmt_p; // a statement or sequence of statements.rule *rule_p; // a sequence of rules.pctl *pctl_p; // a sequence of rules.ifstmt *elsifs; // a sequence of elsif clauses.caselist *cases; // a sequence of cases of a switch statement.alias *aliases; // a sequence of alias bindings.i n t integer; // an integer constant.double real; // a real constantbool boolean; // a boolean value--used with INTERLEAVED.lexid *lex; // a lexeme, most usefully an ID.lexlist *lexlist_p; // a list of lexemes.char *string; // a string value.exprlist *exprlist_p; // a list of expressions.

};

A.2.5 MODIFICATIONS TO MU.C

...

argclass::argclass( i n t ac, char** av): argc(ac), argv(av), print_license(FALSE), help(FALSE),

checking(TRUE), no_compression(TRUE), hash_compression(FALSE),hash_disk(FALSE), hash_cache(FALSE), pmurphik(FALSE),probequalk(FALSE), bpctl(FALSE)

{bool initialized_filename = FALSE;

Page 99: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

A.2 C++, Lex and Yacc Code 87

i n t i;

i f (ac==1) { // if there is no argument, print helphelp = TRUE;PrintInfo();exit(1);

}f o r (i = 1; i < ac; i++) {

...

//im: finite horizon probabilistic murphi with boolean rulesi f (strcmp(av[i], "--probrules") == 0) {

i f (hash_cache == TRUE) {fprintf(stderr, "Option --probrules cannot be used with --cac\

he\.\n");exit(1);

}i f (hash_disk == TRUE) {fprintf(stderr, "Option --probrules cannot be used with --dis\

k.\n");exit(1);

}i f (prob_rules == TRUE) {fprintf(stderr, "Option --probrules cannot be used with --pro\

b.\n");exit(1);

}probequalk = TRUE;cont inue;

}

//im: normal verification algorithm, but probabilistic rulesi f (strcmp(av[i], "--prob") == 0) {

i f (bpctl == TRUE) {fprintf(stderr, "Option --prob cannot be used with --bpctl.\n\

");exit(1);

}i f (probequalk == TRUE) {fprintf(stderr, "Option --prob cannot be used with --probrule\

s.\n");exit(1);

}prob_rules = TRUE;cont inue;

}

//im: bounded probabilistic model checkingi f (strcmp(av[i], "--bpctl") == 0) {

i f (hash_cache == TRUE) {fprintf(stderr, "Option --bpctl cannot be used with --cache.\\

n");exit(1);

}i f (hash_disk == TRUE) {fprintf(stderr, "Option --bpctl cannot be used with --disk.\n\

");exit(1);

}i f (probequalk == TRUE) {fprintf(stderr, "Option --bpctl is actually not usable in con\

junction with --probequalk.\n");exit(1);

}

Page 100: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

88 Chapter A. FHP-Murϕ: the Input Language

i f (prob_rules == TRUE) {fprintf(stderr, "Option --bpctl cannot be used with --prob.\n\

");exit(1);

}bpctl = TRUE;cont inue;

}

...

} /* end for */i f (probequalk) {

i f (hash_compression) {fprintf(stderr, "\nWarning: option --probrules automatically di\

sables -c.\n\n");hash_compression = FALSE;}pmurphik = TRUE;

}

i f (bpctl && hash_compression) {fprintf(stderr, "\nWarning: option --bpctl automatically disable\

s -c.\n\n");hash_compression = FALSE;

}

i f (bpctl || prob_rules)pmurphik = TRUE;

...

void argclass::PrintOptions( void ){

printf("The options are shown as follows:\n\\n\\t-h \t\t \thelp\n\\t-l \t\t \tprint license\n\\t-b \t\t \tuse bit-compacted states\n\\t-c \t\t \tuse hash compaction\n\\t--cache \t\t \tuse simple state caching\n\\t--disk \t\t \tuse disk based caching\n\\t--probrules \t\t \tuse probabilistic murphi with boolean condi\tions\n\\t--prob \t\t \tuse standard verification starting from pro\babilistic rules\n\\t--bpctl \t\t \tbounded probabilistic model checking\n\\n\An argument without a leading ’-’ is taken to be the input filenam\e,\n\\twhich must end with ’.m’\n\");}

A.2.6 MODIFICATIONS TO RULE.H

...

Page 101: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

A.2 C++, Lex and Yacc Code 89

/********************class pctl********************/

s t r u c t pctl : p u b l i c TNode{expr *atomic_proposition;pctl_type pctltype;pctl *subformula1, *subformula2;pctl_ord op; /* comparison operator */double prob_bound;unsigned until_bound;/* code of the subformula in the PCTL formula synctactic tree */i n t code;

pctl(pctl *subf1, pctl *subf2, expr *ap, pctl_type pctltype,i n t until_bound, expr *prob_bound);

v i r t u a l char *generate_code();v i r t u a l void generate_atomic_subformulas(pctl *);i n l i n e c o n s t char *getstring(pctl_type);i n l i n e c o n s t char *getstring(pctl_ord);v i r t u a l void generate_non_atomic_subformulas(pctl *);

};

A.2.7 MODIFICATIONS TO RULE.C

...

simplerule::simplerule(ste *enclosures, expr *condition,ste *locals, stmt *body, bool unfair, i n t priority)

: rule(), name(name), enclosures(enclosures), condition(condition),locals(locals), body(body), condname(NULL), rulename(NULL),unfair(unfair), priority(priority)

{/* this was added */i f (condition != NULL && body != NULL){Error.CondError(condition->has_side_effects(),"Rule Condition must not have side effects.");

i f (args->bpctl && !args->probequalk){Error.CondError(!type_equal(condition->gettype(),realtype),"Condition for probabilistic rule must be a real expression.");

i f (condition->hasvalue() &&((condition->getrvalue()<0) || (condition->getrvalue()>1)))

Error.Error("Real condition for rule must be >=0 and <=1.");}e l s eError.CondError(!type_equal(condition->gettype(),booltype),"Condition for rule must be a boolean expression.");

}/* the rest of the function remains unchanged */NextSimpleRule = SimpleRuleList;SimpleRuleList = t h i s;

size = CountSize(enclosures);

// Rearrange enclosures so that the ones that are NOT// mentioned in the condition go firstrearrange_enclosures();

}

...

Page 102: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

90 Chapter A. FHP-Murϕ: the Input Language

/*********************class pctl

*********************/pctl::pctl(pctl *subf1, pctl *subf2, expr *ap, pctl_type pctltype,

i n t until_bound, expr *prob_bound): subformula1(subf1), subformula2(subf2), atomic_proposition(ap),

pctltype(pctltype), code(new_int()), until_bound(until_bound){Error.CondError(pctltype == AP_PCTL && ap->has_side_effects(),"Atomic propositions in PCTL formulas mustn’t have side effects.");

i f (prob_bound != NULL)/* this is a X- or a X-formula */t h i s ->prob_bound = prob_bound->getrvalue();

}

A.2.8 MODIFICATIONS TO DECL.H

...

c l a s s typedecl: p u b l i c decl{

...

enum typeclass {Real, Enum, Range, Array, MultiSet, MultiSetID,Record, Scalarset, Union, Error_type};

...

}

...

extern typedecl * realtype;

/* AP: declaration of realtypedecl (real type variable’s declaration)*/

c l a s s realtypedecl: p u b l i c typedecl{// accuracy is the number of decimal digit used to represent a real// exponent is the number of digit used for the exponenti n t accuracy,exponent;// maximum positive exponent value (negative is -exponent_value+1)i n t exponent_value;

p u b l i c:// initializerrealtypedecl( i n t ac, i n t ex);realtypedecl(expr *accuracy,expr *exponent);

// supporting routinesv i r t u a l typedecl *gettype(void) c o n s t {re turn realtype;};v i r t u a l typeclass gettypeclass() c o n s t { re turn Real; };v i r t u a l i n t getsize() c o n s t { re turn accuracy + exponent + 2; };v i r t u a l i n t getaccuracy() c o n s t { re turn accuracy; };v i r t u a l i n t getexponent() c o n s t { re turn exponent; };

Page 103: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

A.2 C++, Lex and Yacc Code 91

v i r t u a l void setexponentdigits(){

char buf[10];

sprintf(buf,"%+d", t h i s ->exponent_value);t h i s ->exponent = strlen(buf) - 1;

}v i r t u a l bool issimple() c o n s t { re turn TRUE; }

// code generationv i r t u a l char *generate_decl();

// classify scalarset types as useful or uselessv i r t u a l void setusefulness() {}

// classify variable typev i r t u a l bool HasConstant() c o n s t { re turn TRUE; }v i r t u a l bool HasScalarsetVariable() c o n s t { re turn FALSE; }v i r t u a l bool HasScalarsetArrayOfFree() c o n s t { re turn FALSE; }v i r t u a l bool HasScalarsetArrayOfS() c o n s t { re turn FALSE; }v i r t u a l bool HasScalarsetLeaf() c o n s t { re turn FALSE; }v i r t u a l bool HasMultisetOfFree() c o n s t { re turn FALSE; }v i r t u a l bool HasMultisetOfScalarset() c o n s t { re turn FALSE; }

// canonicalization code for symmetry// this is just for compatibility, we won’t show the implementationv i r t u a l void generate_permute_function();v i r t u a l void generate_simple_canon_function(symmetryclass&);v i r t u a l void generate_canonicalize_function(symmetryclass&);v i r t u a l void generate_simple_limit_function(symmetryclass&);v i r t u a l void generate_array_limit_function(symmetryclass&);v i r t u a l void generate_limit_function(symmetryclass&);v i r t u a l void generate_multisetlimit_function(symmetryclass&);

v i r t u a l charlist * generate_scalarset_list(charlist * sl);};

...

/********************class constdecl********************/

c l a s s constdecl: p u b l i c decl{

i n t value;double rvalue;typedecl *type;

p u b l i c:// initializerconstdecl( i n t value, typedecl * type);constdecl(expr * e);

// supporting routinesv i r t u a l decl_class getclass() c o n s t { re turn Const; };v i r t u a l typedecl *gettype() c o n s t { re turn type; }v i r t u a l i n t getvalue() c o n s t { re turn value; }v i r t u a l double getrvalue() c o n s t { re turn rvalue; }v i r t u a l designator *getdesignator(ste * origin) c o n s t{

i f ((type->gettype()) == (realtype->gettype()))re turn new designator(origin, type, FALSE, TRUE, FALSE, rvalue);

e l s ere turn new designator(origin, type, FALSE, TRUE, FALSE, value);

}

Page 104: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

92 Chapter A. FHP-Murϕ: the Input Language

// code generationv i r t u a l char *generate_decl();

};

A.2.9 MODIFICATIONS TO DECL.C

...

/* class realtypedecl */realtypedecl::realtypedecl( i n t ac, i n t ex): typedecl(),accuracy(ac),exponent_value(ex){

t h i s ->setexponentdigits(); // sets this->exponentnumbits = ( i n t) ceil( t h i s ->getsize() / 2.0) * 8;bitsalloc = numbits;

mu_type = "mu__real";}

realtypedecl::realtypedecl(expr *ac, expr *ex): typedecl(){Error.CondError(!type_equal( ac->gettype(), inttype),"Only integer accuracy allowed.");

Error.CondError(!type_equal( ex->gettype(), inttype),"Only integer exponent allowed.");

Error.CondError(!ac->hasvalue(),"Accuracy must be constant.");Error.CondError(!ex->hasvalue(),"Exponent must be constant.");Error.CondError((ac->getvalue()<1) || (ac->getvalue()>DBL_DIG),"Accuracy must be >= 1 and <= %d.",DBL_DIG);

Error.CondError((ex->getvalue()<10) ||(ex ->getvalue()>DBL_MAX_10_EXP),

"Exponent max value must be between 10 and %d.",DBL_MAX_10_EXP);

t h i s ->accuracy = ac->getvalue();t h i s ->exponent_value = ex->getvalue();t h i s ->setexponentdigits();//IM: sets this->exponent

t h i s ->numbits = ( i n t) ceil( t h i s ->getsize() / 2.0) * 8;t h i s ->bitsalloc = t h i s ->numbits;

mu_type = "mu__real";}

...

constdecl::constdecl(expr *e):decl(), type( e->gettype() ){Error.CondError(!e->hasvalue(), "CONST declaration requires constantexpression.");

i f (type_equal(e->gettype(),realtype))rvalue = e->getrvalue(); // now, a constant may be a real one

e l s evalue = e->getvalue();

}

...

typedecl *realtype = NULL; // AP: realtype’s initialization

Page 105: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

A.2 C++, Lex and Yacc Code 93

A.2.10 MODIFICATIONS TO EXPR.H

...

/********************class expr********************/

c l a s s expr: p u b l i c TNode{p r o t e c t e d:// variablesi n t value; /* value if it has one. */double rvalue; // real valuetypedecl *type; /* type of expression. */bool constval, sideeffects;

// initializer used by subclasses.expr(void);expr(typedecl * type, bool constval, bool sideeffects): type(type), constval(constval), sideeffects(sideeffects) {};

p u b l i c:

// initializerexpr(c o n s t i n t value, typedecl * c o n s t type);expr(c o n s t double value, typedecl * c o n s t type); // new constructor

// supporting routinestypedecl *gettype() c o n s t { re turn type; };v i r t u a l bool isquant() c o n s t { re turn FALSE; };v i r t u a l bool hasvalue() c o n s t { re turn constval; };// getrvalue() is similar to getvalue(), but returns doubledouble getrvalue() c o n s t { re turn rvalue; };v i r t u a l i n t getvalue() c o n s t { re turn value; };v i r t u a l bool islvalue() c o n s t { re turn FALSE; };v i r t u a l bool has_side_effects() c o n s t { re turn sideeffects; };v i r t u a l bool isdesignator() c o n s t { re turn FALSE; };v i r t u a l bool checkundefined() c o n s t { re turn FALSE; };

v i r t u a l stecoll* used_stes() c o n s t { re turn new stecoll; };

// code generationv i r t u a l char *generate_code();

};

// mathematical functions on doublesc l a s s mathexpr : p u b l i c expr{expr* arg1;expr* arg2;

p u b l i c:enum mathexprtype {mylog, mylog10, myexp, mysin, mycos, mytan,

myfabs, myfloor, myceil, mysqrt, myfmod, mypow,myasin, myacos, myatan, mysinh, mycosh, mytanh};

mathexprtype funtype;

mathexpr (expr* arg1,expr* arg2, i n t arg3);

mathexprtype getfuntype() {re turn funtype;};v i r t u a l char* generate_code();

};

...

Page 106: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

94 Chapter A. FHP-Murϕ: the Input Language

/********************class designator-- represented as a left-linear tree.********************/

c l a s s designator: p u b l i c expr{// variablesdesignator * left;ste * origin; /* an identifier; */expr * arrayref; /* an array reference. */ste * fieldref; /* a field reference. */bool lvalue;

// undefinedbool maybeundefined;

// class identifiersenum designator_class { Base, ArrayRef, FieldRef };designator_class dclass;

p u b l i c:// initializerdesignator(ste * origin, typedecl * type, bool islvalue,

bool isconst, bool maybeundefined, i n t val = 0);// this constructor is called by getdesignator() (constdecl)designator(ste * origin, typedecl * type, bool islvalue,

bool isconst, bool maybeundefined, double val);

designator(designator *left, expr *ar);designator(designator *left, lexid *fr);

// supporting routinesv i r t u a l bool islvalue() c o n s t { re turn lvalue; };ste *getbase( void ) c o n s t;v i r t u a l bool isdesignator() c o n s t { re turn TRUE; };v i r t u a l bool checkundefined() c o n s t { re turn maybeundefined; };

v i r t u a l stecoll* used_stes() c o n s t;

// code generationv i r t u a l char *generate_code();

};

A.2.11 MODIFICATIONS TO EXPR.C

...

expr::expr(c o n s t double value, typedecl * c o n s t type) // newconstructor:rvalue(value), type(type), constval(TRUE), sideeffects(FALSE){}

A.2.12 MODIFICATIONS TO CPP CODE.C

...

/* code for realtypedecl */char *realtypedecl::generate_decl(){

Page 107: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

A.2 C++, Lex and Yacc Code 95

i f (!declared) {/* Invent a name for the object, and a "mu_name" for

the declaration of the object in the generated code */i f ( name == NULL ) {name = tsprintf("_real_%d", tNum );mu_name = tsprintf("mu_%s",name);

}/* class name */fprintf(codefile,"class %s: public %s\n""{\n"" public:\n"" inline double operator=(double val) { return %s::operator=(va\

l); };\n"" inline double operator=(const %s& val) { return %s::operator=\

((double) val); };\n"" %s (char *name, int os): %s(%d,%d,%d,name, os){};\n"" %s (void): %s(%d,%d,%d) {};\n"" %s (double val): %s(%d,%d,%d,\"Parameter or function result.\

\", 0)\n"" {\n"" operator=(val);\n"" };\n"" char * Name() { return tsprintf(\"%%le\",value()); };\n",mu_name, mu_type, /* class name */mu_type,mu_name, mu_type,mu_name, mu_type,accuracy,exponent_value, numbits,mu_name, mu_type,accuracy,exponent_value, numbits,mu_name, mu_type,accuracy,exponent_value, numbits

);theprog->symmetry.generate_symmetry_function_decl();fprintf(codefile," virtual void MultisetSort() {};\n"" void print_statistic() {};\n""};\n\n"

);fprintf(codefile, "/*** end of real decl ***/\n");fprintf(codefile, "%s %s_undefined_var;\n\n", mu_name, mu_name);declared = TRUE;

}/* Should never use this as a return value expression */re turn "ERROR!";

}

...

/********************code for constdecl********************/

char *constdecl::generate_decl(){

i f (!declared) {i f (type_equal(type,realtype)) // real constant’s declarationfprintf(codefile, "const double %s = %+le;\n", mu_name, rvalue);

e l s efprintf(codefile, "const int %s = %d;\n", mu_name, value);

declared = TRUE;}re turn "ERROR!";

}

...

Page 108: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

96 Chapter A. FHP-Murϕ: the Input Language

/********************code for expr********************/

char *expr::generate_code(){

i f (constval)i f (type_equal(type,realtype))

re turn tsprintf("%le",rvalue); // value of a real constante l s e

re turn tsprintf("%d",value);e l s e {Error.Error("Internal: a basic expression that wasn’t a constant \

called expr::generate_code().");re turn "ERROR!";

}}

// for math functionschar *mathexpr::generate_code(){

i f (constval)re turn tsprintf("%le", rvalue);

swi tch (getfuntype()){

case mylog:{

i f (constval){

i f (type_equal(arg1->gettype(),realtype))re turn tsprintf("%le",log(arg1->getrvalue()));

e l s ere turn tsprintf("%le",log(arg1->getvalue()));

}e l s e

re turn tsprintf("log((double)%s)",arg1->generate_code());break;

}case mylog10:{

i f (constval){

i f (type_equal(arg1->gettype(),realtype))re turn tsprintf("%le",log10(arg1->getrvalue()));

e l s ere turn tsprintf("%le",log10(arg1->getvalue()));

}e l s e

re turn tsprintf("log10((double)%s)",arg1->generate_code());break;

}case myexp:{

i f (constval){

i f (type_equal(arg1->gettype(),realtype))re turn tsprintf("%le",exp(arg1->getrvalue()));

e l s ere turn tsprintf("%le",exp(arg1->getvalue()));

}e l s e

re turn tsprintf("exp((double)%s)",arg1->generate_code());break;

}case mysin:{

i f (constval){

i f (type_equal(arg1->gettype(),realtype))

Page 109: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

A.2 C++, Lex and Yacc Code 97

re turn tsprintf("%le",sin(arg1->getrvalue()));e l s e

re turn tsprintf("%le",sin(arg1->getvalue()));}e l s e

re turn tsprintf("sin((double)%s)",arg1->generate_code());break;

}case mycos:{

i f (constval){

i f (type_equal(arg1->gettype(),realtype))re turn tsprintf("%le",cos(arg1->getrvalue()));

e l s ere turn tsprintf("%le",cos(arg1->getvalue()));

}e l s e

re turn tsprintf("cos((double)%s)",arg1->generate_code());break;

}case mytan:{

i f (constval){

i f (type_equal(arg1->gettype(),realtype))re turn tsprintf("%le",tan(arg1->getrvalue()));

e l s ere turn tsprintf("%le",tan(arg1->getvalue()));

}e l s e

re turn tsprintf("tan((double)%s)",arg1->generate_code());break;

}case myfabs:{

i f (constval){

i f (type_equal(arg1->gettype(),realtype))re turn tsprintf("%le",fabs(arg1->getrvalue()));

e l s ere turn tsprintf("%le",fabs(arg1->getvalue()));

}e l s e

re turn tsprintf("fabs((double)%s)",arg1->generate_code());break;

}case myfloor:{

i f (constval){

i f (type_equal(arg1->gettype(),realtype))re turn tsprintf("%le",floor(arg1->getrvalue()));

e l s ere turn tsprintf("%le",floor(arg1->getvalue()));

}e l s e

re turn tsprintf("floor((double)%s)",arg1->generate_code());break;

}case myceil:{

i f (constval){

i f (type_equal(arg1->gettype(),realtype))re turn tsprintf("%le",ceil(arg1->getrvalue()));

e l s e

Page 110: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

98 Chapter A. FHP-Murϕ: the Input Language

re turn tsprintf("%le",ceil(arg1->getvalue()));}e l s e

re turn tsprintf("ceil((double)%s)",arg1->generate_code());break;

}case mysqrt:{

i f (constval){

i f (type_equal(arg1->gettype(),realtype))re turn tsprintf("%le",sqrt(arg1->getrvalue()));

e l s ere turn tsprintf("%le",sqrt(arg1->getvalue()));

}e l s e

re turn tsprintf("sqrt((double)%s)",arg1->generate_code());break;

}case myfmod:{

i f (constval){

i f (type_equal(arg1->gettype(),realtype)){

i f (type_equal(arg2->gettype(),realtype))re turn tsprintf("%le",fmod(arg1->getrvalue(),arg2->getrvalue()));

e l s ere turn tsprintf("%le",fmod(arg1->getrvalue(),arg2->getvalue()));

}e l s e{

i f (type_equal(arg2->gettype(),realtype))re turn tsprintf("%le",fmod(arg1->getvalue(),arg2->getrvalue()));

e l s ere turn tsprintf("%le",fmod(arg1->getvalue(),arg2->getvalue()));

}}e l s e

re turn tsprintf("fmod((double)%s,(double)%s)",arg1->generate_code(), arg2->generate_code());

break;}case mypow:{

i f (constval){

i f (type_equal(arg1->gettype(),realtype)){

i f (type_equal(arg2->gettype(),realtype))re turn tsprintf("%le",pow(arg1->getrvalue(),arg2->getrvalue()));

e l s ere turn tsprintf("%le",pow(arg1->getrvalue(),arg2->getvalue()));

}e l s e{

i f (type_equal(arg2->gettype(),realtype))re turn tsprintf("%le",pow(arg1->getvalue(),arg2->getrvalue()));

e l s ere turn tsprintf("%le",pow(arg1->getvalue(),arg2->getvalue()));

Page 111: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

A.2 C++, Lex and Yacc Code 99

}}e l s e

re turn tsprintf("pow((double)%s,(double)%s)",arg1->generate_code(), arg2->generate_code());

break;}case myasin:{

i f (constval){

i f (type_equal(arg1->gettype(),realtype))re turn tsprintf("%le",asin(arg1->getrvalue()));

e l s ere turn tsprintf("%le",asin(arg1->getvalue()));

}e l s e

re turn tsprintf("asin((double)%s)",arg1->generate_code());break;

}case myacos:{

i f (constval){

i f (type_equal(arg1->gettype(),realtype))re turn tsprintf("%le",acos(arg1->getrvalue()));

e l s ere turn tsprintf("%le",acos(arg1->getvalue()));

}e l s e

re turn tsprintf("acos((double)%s)",arg1->generate_code());break;

}case myatan:{

i f (constval){

i f (type_equal(arg1->gettype(),realtype))re turn tsprintf("%le",atan(arg1->getrvalue()));

e l s ere turn tsprintf("%le",atan(arg1->getvalue()));

}e l s e

re turn tsprintf("atan((double)%s)",arg1->generate_code());break;

}case mysinh:{

i f (constval){

i f (type_equal(arg1->gettype(),realtype))re turn tsprintf("%le",sinh(arg1->getrvalue()));

e l s ere turn tsprintf("%le",sinh(arg1->getvalue()));

}e l s e

re turn tsprintf("sinh((double)%s)",arg1->generate_code());break;

}case mycosh:{

i f (constval){

i f (type_equal(arg1->gettype(),realtype))re turn tsprintf("%le",cosh(arg1->getrvalue()));

e l s ere turn tsprintf("%le",cosh(arg1->getvalue()));

Page 112: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

100 Chapter A. FHP-Murϕ: the Input Language

}e l s e

re turn tsprintf("cosh((double)%s)",arg1->generate_code());break;

}case mytanh:{

i f (constval){

i f (type_equal(arg1->gettype(),realtype))re turn tsprintf("%le",tanh(arg1->getrvalue()));

e l s ere turn tsprintf("%le",tanh(arg1->getvalue()));

}e l s e

re turn tsprintf("tanh((double)%s)",arg1->generate_code());break;

}}

}

...

/********************code for arithexpr********************/

char *arithexpr::generate_code(){

i f (constval)i f (type_equal(type,realtype))// value of a real arithmetic expression (+,-)re turn tsprintf("%le", rvalue);

e l s ere turn tsprintf("%d", value);

e l s e {swi tch (op) {case ’+’:

re turn tsprintf("(%s) + (%s)",left->generate_code(),right->generate_code());

case ’-’:re turn tsprintf("(%s) - (%s)",left->generate_code(),right->generate_code());

d e f a u l t:Error.Error("Internal: bad operator in arithexpr::\

generate_code()");re turn "ERROR!";

}}

};

/********************code for unexpr********************/

char *unexpr::generate_code(){

i f (constval)i f (type_equal(type,realtype))// value of a real unary expressionre turn tsprintf("%le", rvalue);e l s ere turn tsprintf("%d", value);

e l s e {swi tch (op) {

Page 113: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

A.2 C++, Lex and Yacc Code 101

case ’+’:re turn left->generate_code();

case ’-’:re turn tsprintf(" - (%s)",left->generate_code());

d e f a u l t:Error.Error("Internal: bad operator in arithexpr::\

generate_code()");re turn "ERROR!";

}}

};

/********************code for mulexpr********************/

char *mulexpr::generate_code(){

i f (constval)i f (type_equal(type,realtype))// value of a real arithmetic expression (*,/)re turn tsprintf("%le", rvalue);

e l s ere turn tsprintf("%d", value);

e l s e {swi tch (op) {case ’*’:

re turn tsprintf("(%s) * (%s)",left->generate_code(),right->generate_code());

case ’/’:re turn tsprintf("(%s) / (%s)",left->generate_code(),right->generate_code());

case ’%’:/* doubled % to accomodate printf. */re turn tsprintf("(%s) %% (%s)",left->generate_code(),right->generate_code());

d e f a u l t:Error.Error("Internal: bad operator in mulexpr::\

generate_code()");re turn "ERROR!";

}}

}

...

/********************code for simplerule********************/

char *simplerule::generate_code(){fprintf(codefile,"/******************** RuleBase%d ********************/\n""class RuleBase%d\n""{\n""public:\n",rulenumber,rulenumber);

// priority function, added by Ulifprintf(codefile," int Priority()\n"

Page 114: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

102 Chapter A. FHP-Murϕ: the Input Language

" {\n"" return %d;\n"" }\n",priority);

// generate Name(r)fprintf(codefile," char * Name(unsigned r)\n"" {\n");

generate_rule_params_assignment( enclosures );fprintf(codefile," return tsprintf(\"%s", name);

generate_rule_params_printf( enclosures );fprintf(codefile,"\"");generate_rule_params_name( enclosures );fprintf(codefile, ");\n }\n");

// generate Condition(r)fprintf(codefile," bool Condition(unsigned r)\n"" {\n");

generate_rule_params_assignment( enclosures );generate_rule_params_choose( enclosures );generate_rule_aliases( enclosures );

i f (args->pmurphik){// condition return for probabilistic rules is "return prob > 0"i f (condition->hasvalue())fprintf(codefile,

" return %d;\n",condition->getrvalue() > 0);

e l s efprintf(codefile,

" return (%s > 0);\n",condition->generate_code());

}e l s efprintf(codefile,

" return %s;\n",condition->generate_code());

fprintf(codefile," }\n""\n");

// generate NextRule(r)i f (args->pmurphik && !args->prob_rules && !args->probequalk)/* it is necessary to have an additional output parameter for the

probability of the rule */fprintf(codefile,

" void NextRule(unsigned & what_rule, double & what_prob)\n"" {\n"" unsigned r = what_rule - %d;\n",maxrulenumber - getsize());

e l s efprintf(codefile,

" void NextRule(unsigned & what_rule)\n"" {\n"" unsigned r = what_rule - %d;\n",maxrulenumber - getsize());

generate_rule_params_assignment( enclosures );fprintf(codefile," while (what_rule < %d ",

Page 115: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

A.2 C++, Lex and Yacc Code 103

maxrulenumber );generate_rule_params_choose_exist( enclosures );fprintf(codefile,")\n {\n");

// Check if ‘‘dependent’’ choose parameters are therefprintf(codefile," if ( ( TRUE ");generate_rule_params_choose_all_in( dep_choose );fprintf(codefile," ) ) {\n");

// Check conditiongenerate_rule_aliases( enclosures );i f (args->pmurphik && !args->probequalk){

i f (condition->hasvalue()){fprintf(codefile,

" what_prob = %s;\n"" if (%d) {\n",condition->generate_code(),condition->getrvalue() > 0 );

}e l s e{fprintf(codefile,

" what_prob = %s;\n"" if ((what_prob < 0) || (what_prob > 1))\n"" { \n"" Error.Error(\"Condition of probabilistic rule %%s is not\

in range [0,1].\", this->Name(what_rule));\n"" return;\n"" }\n",condition->generate_code());

fprintf(codefile," if (what_prob > 0) {\n");}

}e l s e

fprintf(codefile," if (%s) {\n",condition->generate_code() );

// Check is ‘‘independent’’ choose parameters are therefprintf(codefile," if ( ( TRUE ");generate_rule_params_choose_all_in( indep_choose );fprintf(codefile," ) )\n");fprintf(codefile," return;\n");fprintf(codefile," else\n");fprintf(codefile," what_rule++;\n");fprintf(codefile," }\n");

fprintf(codefile," else\n");fprintf(codefile," what_rule += %d;\n",

indep_card);fprintf(codefile," }\n");

fprintf(codefile," else\n");fprintf(codefile," what_rule += %d;\n",

indep_card);

// End of Vitaly’s hacks

fprintf(codefile," r = what_rule - %d;\n",maxrulenumber - getsize());

generate_rule_params_simple_assignment( enclosures );fprintf(codefile,

" }\n"" }\n\n");

// generate Code(r)fprintf(codefile,

Page 116: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

104 Chapter A. FHP-Murϕ: the Input Language

" void Code(unsigned r)\n"" {\n");

generate_rule_params_assignment( enclosures );generate_rule_aliases( enclosures );locals->generate_decls();f o r (stmt *b = body; b != NULL; b = b->n e x t)b->generate_code();

fprintf(codefile," };\n""\n");

// generate Fair()i f (unfair)fprintf(codefile,

" bool UnFair()\n"" { return TRUE; }\n");

e l s efprintf(codefile,

" bool UnFair()\n"" { return FALSE; }\n");

// end declarationfprintf(codefile,"};\n");

re turn "ERROR!";}

...

/********************code for pctl

********************/

void pctl::generate_atomic_subformulas(pctl *formula){

i f (formula == NULL)re turn;

i f (formula->pctltype == AP_PCTL){fprintf(codefile, "bool mu_pctl_a_p%d()\n{\n", formula->code);char *temp = formula->atomic_proposition->generate_code();fprintf(codefile, "return %s;\n}\n", temp);

}e l s e{generate_atomic_subformulas(formula->subformula1);generate_atomic_subformulas(formula->subformula2);

}}

c o n s t char *pctl::getstring(pctl_type t){

swi tch(t){

case UNTIL_PCTL: re turn "UNTIL_PCTL";case NEXT_PCTL: re turn "NEXT_PCTL";case AP_PCTL: re turn "AP_PCTL";case AND_PCTL: re turn "AND_PCTL";case OR_PCTL: re turn "OR_PCTL";case IMPL_PCTL: re turn "IMPL_PCTL";case NOT_PCTL: re turn "NOT_PCTL";

Page 117: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

A.2 C++, Lex and Yacc Code 105

}}

c o n s t char *pctl::getstring(pctl_ord o){

swi tch(o){

case PCTL_L: re turn "PCTL_L";case PCTL_LEQ: re turn "PCTL_LEQ";case PCTL_G: re turn "PCTL_G";case PCTL_GEQ: re turn "PCTL_GEQ";

}}

void pctl::generate_non_atomic_subformulas(pctl *formula){

i f (formula == NULL)re turn;

generate_non_atomic_subformulas(formula->subformula1);generate_non_atomic_subformulas(formula->subformula2);i f (formula == t h i s)fprintf(codefile, "const pctlformrec mu_pctl_formula = {\n");

e l s efprintf(codefile, "const pctlformrec mu_pctl_formula%d = {\n",formula->code);

fprintf(codefile, "%s, ", getstring(formula->pctltype));i f (formula->pctltype != AP_PCTL)fprintf(codefile, "NULL, ");

e l s efprintf(codefile, "&mu_pctl_a_p%d, ", formula->code);

i f (formula->pctltype != NEXT_PCTL &&formula->pctltype != UNTIL_PCTL)

fprintf(codefile, "PCTL_L, 0.0, ");e l s efprintf(codefile, "%s, %lf, ", getstring(formula->op),formula->prob_bound);

fprintf(codefile, "%d, ", formula->until_bound);i f (formula->subformula1 == NULL)fprintf(codefile, "NULL, ");

e l s efprintf(codefile, "&mu_pctl_formula%d, ",formula->subformula1->code);

i f (formula->subformula2 == NULL)fprintf(codefile, "NULL");

e l s efprintf(codefile, "&mu_pctl_formula%d",formula->subformula2->code);

fprintf(codefile, "};\n");}

char *pctl::generate_code(){generate_atomic_subformulas( t h i s);generate_non_atomic_subformulas( t h i s);

re turn "ERROR!";}

...

i n t generate_ruleset(){

i n t i, r, max_r;simplerule * sr;

r = 0;

Page 118: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

106 Chapter A. FHP-Murϕ: the Input Language

max_r = 0;f o r (sr = simplerule::SimpleRuleList;

sr != NULL; sr = sr->NextSimpleRule){

i f (sr->getclass() == rule::Simple && sr != error_rule){sr->rulenumber = r++;max_r += sr->getsize(); sr->maxrulenumber = max_r;sr->generate_code();

}}

r = 0;fprintf(codefile,"class NextStateGenerator\n""{\n");

f o r (sr = simplerule::SimpleRuleList;sr != NULL; sr = sr->NextSimpleRule)

{i f (sr->getclass() == rule::Simple && sr != error_rule){fprintf(codefile," RuleBase%d R%d;\n",r,r);r++;

}}

fprintf(codefile,"public:\n");

// generate SetNextEnabledRule(r)i = 0; r = 0;i f (!args->pmurphik || args->probequalk || args->prob_rules)/* in pmurphik mode, SetNextEnabledRule will return also the

probability of the rule */fprintf(codefile,"void SetNextEnabledRule(unsigned & what_rule)\n""{\n"" category = CONDITION;\n");

e l s efprintf(codefile,"void SetNextEnabledRule(unsigned & what_rule, double & \

what_prob)\n""{\n"" category = CONDITION;\n");

f o r (sr = simplerule::SimpleRuleList;sr != NULL; sr = sr->NextSimpleRule)

{i f (sr->getclass() == rule::Simple && sr != error_rule){i f (args->pmurphik && !args->prob_rules && !args->probequalk){

i f (i != 0)fprintf(codefile," if (what_rule>=%d && what_rule<%d)\n"" { R%d.NextRule(what_rule, what_prob);\n"" if (what_rule<%d) return; }\n",i, i+sr->getsize(), r, i+sr->getsize());

e l s efprintf(codefile," if (what_rule<%d)\n"" { R%d.NextRule(what_rule, what_prob);\n"" if (what_rule<%d) return; }\n",i+sr->getsize(), r, i+sr->getsize());

r++; i+=sr->getsize();}e l s e{

Page 119: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

A.2 C++, Lex and Yacc Code 107

i f (i != 0)fprintf(codefile,

" if (what_rule>=%d && what_rule<%d)\n"" { R%d.NextRule(what_rule);\n"" if (what_rule<%d) return; }\n",i, i+sr->getsize(), r, i+sr->getsize());

e l s efprintf(codefile,

" if (what_rule<%d)\n"" { R%d.NextRule(what_rule);\n"" if (what_rule<%d) return; }\n",i+sr->getsize(), r, i+sr->getsize());

r++; i+=sr->getsize();}}

}fprintf(codefile,

"}\n");

// generate Condition(r)fprintf(codefile,

"bool Condition(unsigned r)\n""{\n"" category = CONDITION;\n");

i = 0; r = 0;f o r (sr = simplerule::SimpleRuleList;

sr != NULL; sr = sr->NextSimpleRule){

i f (sr->getclass() == rule::Simple && sr != error_rule){

i f (i != 0)fprintf(codefile,

" if (r>=%d && r<=%d) return R%d.Condition(r-%d);\n",i, i+sr->getsize()-1, r, i);

e l s efprintf(codefile,

" if (r<=%d) return R%d.Condition(r-%d);\n",i+sr->getsize()-1, r, i);

r++;i+=sr->getsize();

}}

fprintf(codefile,"Error.Notrace(\"Internal: NextStateGenerator -- checking condit\

ion for nonexisting rule.\");\n""}\n");

// generate Code(r)fprintf(codefile,

"void Code(unsigned r)\n""{\n");

i = 0; r = 0;f o r (sr = simplerule::SimpleRuleList;

sr != NULL; sr = sr->NextSimpleRule){

i f (sr->getclass() == rule::Simple && sr != error_rule){

i f (i != 0)fprintf(codefile,

" if (r>=%d && r<=%d) { R%d.Code(r-%d); return; } \n",i, i+sr->getsize()-1, r, i);

e l s efprintf(codefile,

" if (r<=%d) { R%d.Code(r-%d); return; } \n",

Page 120: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

108 Chapter A. FHP-Murϕ: the Input Language

i+sr->getsize()-1, r, i);r++;i+=sr->getsize();}}

fprintf(codefile,"}\n");

// generate Priority, added by Ulifprintf(codefile,

"int Priority(unsigned short r)\n""{\n");

i = 0; r = 0;f o r (sr = simplerule::SimpleRuleList;

sr != NULL; sr = sr->NextSimpleRule){

i f (sr->getclass() == rule::Simple && sr != error_rule){

i f (i != 0)fprintf(codefile," if (r>=%d && r<=%d) { return R%d.Priority(); } \n",i, i+sr->getsize()-1, r);

e l s efprintf(codefile," if (r<=%d) { return R%d.Priority(); } \n",i+sr->getsize()-1, r);

r++;i+=sr->getsize();

}}

fprintf(codefile,"}\n");

// generate Name(r)fprintf(codefile,"char * Name(unsigned r)\n""{\n");

i = 0; r = 0;f o r (sr = simplerule::SimpleRuleList;

sr != NULL; sr = sr->NextSimpleRule){

i f (sr->getclass() == rule::Simple && sr != error_rule){

i f (i != 0)fprintf(codefile,

" if (r>=%d && r<=%d) return R%d.Name(r-%d);\n",i, i+sr->getsize()-1, r, i);

e l s efprintf(codefile,

" if (r<=%d) return R%d.Name(r-%d);\n",i+sr->getsize()-1, r, i);

r++;i+=sr->getsize();}}

fprintf(codefile, " return NULL;\n"); // added by Ulifprintf(codefile,"}\n");

fprintf(codefile,"};\n");

re turn i;}

Page 121: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

A.2 C++, Lex and Yacc Code 109

...

char *program::generate_code(){

i n t count;

// headerfprintf(codefile,"/******************************\n");fprintf(codefile," Program \"%s\" compiled by \"%s\"\n",args->filename, MURPHI_VERSION );

fprintf(codefile, "\n");fprintf(codefile," Murphi Last Modified Date: \"%s\"\n",LAST_DATE);

fprintf(codefile," Murphi Last Compiled date: \"%s\"\n",__DATE__);

fprintf(codefile," ******************************/\n");fprintf(codefile, "\n");

// record the date of the compiler.fprintf(codefile,"/********************\n Parameter\n");fprintf(codefile," ********************/\n");i f (args->hash_disk || args->hash_cache || args->pmurphik ||

args->probequalk)fprintf(codefile,"#define MURPHI_VERSION \"%s\"\n",MURPHI_VERSION);

e l s efprintf(codefile,"#define MURPHI_VERSION \"Murphi Release \

3.1\"\n");

fprintf(codefile,"#define MURPHI_DATE \"%s\"\n", LAST_DATE);fprintf(codefile, "#define PROTOCOL_NAME \""); // added by Ulif o r ( i n t i=0, l=strlen(args->filename)-2; i<l; i++)fputc(args->filename[i], codefile);

fprintf(codefile, "\"\n#define BITS_IN_WORLD %d\n",bits_in_world);

i f (args->no_compression)fprintf(codefile, "#define ALIGN\n");

i f (args->hash_compression)fprintf(codefile, "#define HASHC\n");

i f (args->hash_disk)fprintf(codefile, "#define DISK_MURPHI\n");

i f (args->hash_cache)fprintf(codefile, "#define CACHED_MURPHI\n");

i f (args->pmurphik && !args->prob_rules)fprintf(codefile, "#define PMURPHIK\n");

i f (args->probequalk)fprintf(codefile, "#define PROBEQUALK\n");

i f (args->bpctl)fprintf(codefile, "#define BPCTL\n");

fprintf(codefile, "\n");

// include prologfprintf(codefile,"/********************\n Include\n");fprintf(codefile," ********************/\n");fprintf(codefile,"#include \"mu_prolog.inc\"\n");

/* generate dependent stuff. */fprintf(codefile,"\n/********************\n Decl declaration\n");fprintf(codefile," ********************/\n\n");i f (args->prob_rules)fprintf(codefile,"double what_prob;\n\n");

// typedecl declaration -- added to fixed a bugi f (typedecl::origin != NULL)typedecl::origin->generate_all_decl();

/* globals->generate_decls() gets done byprocedures->generate_decls */

Page 122: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

110 Chapter A. FHP-Murϕ: the Input Language

procedures->generate_decls();fprintf(codefile,"\n\n\n");

// generate the worldfprintf(codefile,"\n/********************\n The world\n");fprintf(codefile," ********************/\n");make_world(globals);fprintf(codefile,"\n");

// generate the codes for each rulefprintf(codefile,"\n/********************\n Rule declarations\n");fprintf(codefile," ********************/\n");

// for ( rule *r = rules;// r != NULL;// r = r->next )// r->generate_code();// fprintf(codefile,"\n\n\n");//// /* generate the lists of rules, startstate, and invariants. */// // generate the lists of rules// fprintf(codefile,"\n/********************\n Rule records\n");// fprintf(codefile," ********************/\n");// fprintf(codefile, "const rulerec rules[] = {\n");// count = rulelist->print_rules();// fprintf(codefile,"};\n");

count = generate_ruleset();fprintf(codefile, "const unsigned numrules = %d;\n", count );

fprintf(codefile,"\n/********************\n parameter\n");fprintf(codefile," ********************/\n");fprintf(codefile, "#define RULES_IN_WORLD %d\n", count );fprintf(codefile,"\n");

// generate the lists of startstatefprintf(codefile,"\n/********************\n Startstate records\n");fprintf(codefile," ********************/\n");

// fprintf(codefile, "const rulerec startstates[] = {\n");// count = startstatelist->print_rules();// fprintf(codefile,"};\n");count = generate_startstates();fprintf(codefile, "const rulerec startstates[] = {\n");simplerule * sr; /* this is to have probabilities on startstates */f o r (sr = simplerule::SimpleRuleList;

sr != NULL; sr = sr->NextSimpleRule){

i f (sr->getclass() == rule::Startstate){

i f ((args->pmurphik && !args->prob_rules) || args->bpctl ||args->probequalk)

fprintf(codefile,"{ NULL, NULL, NULL, FALSE, 1.0},\n");e l s efprintf(codefile,"{ NULL, NULL, NULL, FALSE},\n");

}}fprintf(codefile,"};\n");fprintf(codefile, "unsigned short StartStateManager::numstartstate\

s = %d;\n", count);

i f (!args->bpctl && !args->pmurphik){// generate the lists of invariantsfprintf(codefile,"\n/********************\n Invariant records\

\n");fprintf(codefile," ********************/\n");(void) generate_invariants();fprintf(codefile, "const rulerec invariants[] = {\n");

Page 123: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

A.2 C++, Lex and Yacc Code 111

count = invariantlist->print_rules();fprintf(codefile,"};\n");fprintf(codefile, "const unsigned short numinvariants = %d;\n",count );

// generate the special true function for livenessfprintf(codefile, "\n/******************/\n");fprintf(codefile, "bool mu__true_live() { return TRUE; }");fprintf(codefile, "\n/******************/\n");

// generate the lists of livenessesfprintf(codefile,"\n/********************\n Liveness records\n");fprintf(codefile," ********************/\n");fprintf(codefile, "const liverec livenesses[] = {\n");count = livenesslist->print_liverules();fprintf(codefile,"};\n");fprintf(codefile, "const unsigned short numlivenesses = %d;\n",count);

// if there is liveness property, define LIVENESS_CHECKINGi f (count>0)fprintf(codefile, "\n#define LIVENESS_CHECKING\n");

// generate the lists of fairstatesfprintf(codefile,"\n/********************\n Fairstates records\

\n");fprintf(codefile," ********************/\n");fprintf(codefile, "const rulerec fairnesses[] = {\n");count = fairnesslist->print_rules();fprintf(codefile,"};\n");fprintf(codefile, "const unsigned short numfairnesses = %d;\n",count);

}e l s e //IM: PCTL formula code{fprintf(codefile,"\n/********************\n PCTL formulas record\

s\n");fprintf(codefile," ********************/\n");(void) theprog->pctl_form->generate_code();

}// generate normalization/canonicalization function for scalarsetfprintf(codefile,"\n/********************\n Normal/Canonicalizati\

on for scalarset\n");fprintf(codefile," ********************/\n");symmetry.generate_code(globals);

// include prologfprintf(codefile,"\n/********************\n Include\n");fprintf(codefile," ********************/\n");

/* I\’ve decided to just #include it, so that I can foist off theproblem of finding the file to be included on the c++compiler. */

/* But the filename still should not be hardcoded. */fprintf(codefile,"#include \"mu_epilog.inc\"\n");

re turn "ERROR!";}

Page 124: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor
Page 125: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

APPENDIX B

FHP-MURϕ: THE VERIFIER

In this appendix, we will show the code implementing the two algorithms of Chapters 3 and 4. This hasbeen done by modifying the files in the include directory of the original Murϕ distribution (see theintroductive part of Appendix A); moreover, two files have been added. In FHP-Murϕ, the modified andadded files are paced in a separate subdirectory of include, which is named bpctl, with the exception ofmu real.h, mu real.C, mu prolog.inc and mu epilog.inc, which are stored in the includedirectory.

B.1 C++ CODE

As for Appendix A, we give only the modified (and added) files, together with the modifications context.

B.1.1 MODIFICATIONS TO MU PROLOG.INC

...

# i f defined(PMURPHIK)#ifndef gPercentActiveStates

#define gPercentActiveStates 0.5#endif

# e l s e#define gPercentActiveStates 0.1

# e n d i f

// for use in tsprintf# d e f i n e BUFFER_SIZE 1024

/****************************************Release information

****************************************//* last update */# d e f i n e INCLUDE_FILE_DATE "Oct 20 2001"

/* Murphi Version Number */# i f (defined(PMURPHIK) || defined(CACHED_MURPHI) ||

defined(DISK_MURPHI) || defined(BPCTL))#define INCLUDE_FILE_VERSION "Cached Murphi Release 5.2"

# e l s e#define INCLUDE_FILE_VERSION "Murphi Release 3.1"

# e n d i f

/****************************************Cached Murphi constants

****************************************//* max length of collision chain in cache */# d e f i n e MAX_HT_CHAIN_LENGTH 11

113

Page 126: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

114 Chapter B. FHP-Murϕ: the Verifier

/* max length of collision chain in cache when hash compaction isused */

# d e f i n e MAX_HT_CHAIN_LENGTH_HC 13/* length of split file segments */#define SPLITFILE_LEN (1024 * 0x100000L)

/****************************************main headers****************************************/

# i f defined(PMURPHIK)# i f defined(BPCTL)#include "bpctl/mu_verifier.h"

# e l s e#include "pmurphik/mu_verifier.h"

#endif# e l s e

#include "mu_verifier.h"# e n d i f

/****************************************other headers****************************************/

# i f d e f HASHC# i n c l u d e "mu_hash.h"# e n d i f

# i n c l u d e "mu_sym.h"

# i f defined(DISK_MURPHI)#include "murphi.disk/mu_util.h"

# e l s e# i f defined(CACHED_MURPHI)#include "murphi.cache/mu_util.h"

# e l s e# i f defined(PMURPHIK)#include "pmurphik/mu_util.h"# e l s e#include "mu_util.h"#endif

#endif# e n d i f

# i f defined(DISK_MURPHI)#include "murphi.disk/mu_io.h"

# e l s e# i f defined(CACHED_MURPHI)#include "murphi.cache/mu_io.h"

# e l s e# i f defined(PMURPHIK)# i f defined(BPCTL)#include "bpctl/mu_io.h"

# e l s e#include "pmurphik/mu_io.h"

#endif# e l s e#include "mu_io.h"#endif

#endif# e n d i f

# i f defined(DISK_MURPHI)#include "murphi.disk/mu_state.h"#include "murphi.disk/splitFile.h"#include "murphi.disk/mu_filterqueue.h"#include "murphi.disk/mu_system.h"

# e l s e

Page 127: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 115

# i f defined(CACHED_MURPHI)#include "murphi.cache/mu_state.h"#include "murphi.cache/mu_system.h"

# e l s e# i f defined(PMURPHIK)# i f defined(BPCTL)#include "splitFile.h"#include "bpctl/mu_state.h"#include "bpctl/mu_probstack.h"#include "bpctl/mu_system.h"# e l s e#include "pmurphik/mu_state.h"#include "pmurphik/mu_system.h"#endif

# e l s e#include "mu_state.h"#include "mu_system.h"

#endif#endif

# e n d i f

/****************************************real numbers extension****************************************/

# i n c l u d e "mu_real.h" //im

B.1.2 MODIFICATIONS TO MU EPILOG.ING

...

/****************************************header that depend on constantswhich is generated in the middle of the compiled program:RULES_IN_WORLD****************************************/

# i f defined(PMURPHIK)# i n c l u d e "pmurphik/mu_util_dep.h"# e l s e# i n c l u d e "mu_util_dep.h"# e n d i f

/****************************************supporting routines****************************************/

# i f d e f HASHC# i n c l u d e "mu_hash.C"# e n d i f

# i f defined(DISK_MURPHI)#include "murphi.disk/mu_util.C"

# e l s e# i f defined(PMURPHIK)# i f defined(BPCTL)#include "bpctl/mu_util.C"

# e l s e#include "pmurphik/mu_util.C"

#endif# e l s e#include "mu_util.C"

#endif# e n d i f

# i f defined(DISK_MURPHI)

Page 128: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

116 Chapter B. FHP-Murϕ: the Verifier

#include "murphi.disk/mu_io.C"# e l s e# i f defined(CACHED_MURPHI)#include "murphi.cache/mu_io.C"

# e l s e# i f defined(PMURPHIK)# i f defined(BPCTL)#include "bpctl/mu_io.C"

# e l s e#include "pmurphik/mu_io.C"

#endif# e l s e#include "mu_io.C"#endif

#endif# e n d i f

# i n c l u d e "mu_sym.C"

# i f defined(DISK_MURPHI)#include "murphi.disk/mu_state.C"#include "murphi.disk/splitFile.C"#include "murphi.disk/mu_filterqueue.C"#include "murphi.disk/mu_system.C"

# e l s e# i f defined(CACHED_MURPHI)#include "murphi.cache/mu_state.C"#include "murphi.cache/mu_system.C"

# e l s e# i f defined(PMURPHIK)

// #include "pmurphik/splitFile.C"# i f defined(BPCTL)#include "splitFile.C"#include "bpctl/mu_state.C"#include "bpctl/mu_probstack.C"#include "bpctl/mu_system.C"

# e l s e#include "pmurphik/mu_state.C"#include "pmurphik/mu_probqueue.C"#include "pmurphik/mu_system.C"

#endif# e l s e#include "mu_state.C"#include "mu_system.C"#endif

#endif# e n d i f

/****************************************real numbers extension****************************************/

# i n c l u d e "mu_real.C" //im

/****************************************main routines****************************************/

# i f defined(BPCTL)# i n c l u d e "bpctl/mu_verifier.C"# e l s e# i n c l u d e "mu_verifier.C"# e n d i f

Page 129: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 117

B.1.3 MODIFICATIONS TO MU REAL.H

...

# i f n d e f _REALCLASS_# d e f i n e _REALCLASS_

/* class mu__real’s declaration (base for real numbers) */c l a s s mu__real {

s t a t i c double undef_value; //undef_value for real type

void operator=(mu__real&);

p r o t e c t e d:// accuracy is the number of decimal digit used to represent a real// exponent is the number of digit used for the exponent

i n t accuracy,exponent;

// maximum positive exponent value (negative is -exponent_value+1)i n t exponent_value;

// if TRUE global variable, otherwise localbool in_world;

// offset in the state vector, size (both in bits)i n t offset,size;

// size in bytei n t size_in_byte;

// format_string_1 contains the format string used for write a// real number to the state vector// Ex: if accuracy = 6 then format_string_1 = "%+.5Le".

char format_string_1[10];

// format_string_2 contains the format string used for print// the value of a real variable (see function Print())// Ex: if name = "x" and accuracy = 6 then// format_string_2 = "x:%+.5Le"

char format_string_2[300];

// Note: the size of format_string_2 also depends on// the length of an identifier

# i f d e f ALIGNi n t byteOffset; // offset in state vector in bytes

# e n d i fbool initialized; // whether it is initialized in the startstate

// Uli: seems not to be used any moredouble cvalue; // contains value of local variable

p u b l i c:char *name; // name of the variablechar longname[BUFFER_SIZE / 4];

// constructorsmu__real( i n t accuracy, i n t exponent, i n t size,char *n, i n t os ): accuracy(accuracy),

exponent_value(exponent),size(size),initialized(FALSE)//exponent given to this->exponent_value and not to exponent{setexponentdigits(); //sets this->exponentset_formats_string();set_self(n, os);size_in_byte = div(size,8).quot;undefined();

};

mu__real( i n t accuracy, i n t exponent, i n t size): accuracy(accuracy), exponent_value(exponent), size(size),initialized(FALSE)

//exponent given to this->exponent_value and not to exponent

Page 130: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

118 Chapter B. FHP-Murϕ: the Verifier

{setexponentdigits();//sets this->exponentset_formats_string();set_self(NULL,0);size_in_byte = div(size,8).quot;undefined();

};

// Uli: - seems not to be used any more// - however, I left it here since it does the correct thingsmu__real( i n t accuracy, i n t precision, i n t size,double val): accuracy(accuracy), exponent_value(exponent), size(size)

//exponent given to this->exponent_value and not to exponent{setexponentdigits();//sets this->exponentset_self("Parameter or function result", 0);set_formats_string();operator=(val);size_in_byte = div(size,8).quot;

};

// Uli: this constructor is called implicitly for function results// by the code generated by the Murphi compilermu__real(c o n s t mu__real &src): accuracy(src.accuracy), exponent_value(src.exponent_value),size(src.size), in_world(FALSE)

//exponent given to this->exponent_value and not to exponent{setexponentdigits();//sets this->exponentset_formats_string(); //fixed, was after the call to valueset_self("Function result", 0);value(src.value()); // value() returning undefined valuessize_in_byte = div(size,8).quot;

};

// a destructor˜mu__real() {};

void setexponentdigits() //number of digits of exponent_value{

char buf[10];

sprintf(buf,"%+d",exponent_value);exponent = strlen(buf) - 1;

}

// routine for constructor usevoid set_self_ar( char *n1, char *n2, i n t os ) {

i n t l1 = strlen(n1), l2 = strlen(n2);strcpy( longname, n1 );longname[l1] = ’[’;strcpy( longname+l1+1, n2 );longname[l1+l2+1] = ’]’;longname[l1+l2+2] = 0;set_self( longname, os );

};

void set_self_2( char *n1, char *n2, i n t os ) {strcpy( longname, n1 );strcat( longname, n2 );set_self( longname, os );

};

void set_self( char *n, i n t os ) {name = n; offset = os;in_world = FALSE; // Uli: variables are local by default

# i f d e f ALIGNbyteOffset = offset/8;

Page 131: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 119

# e n d i f};

// assignmentdouble operator= (double val) { re turn value(val); }

# i f n d e f NO_RUN_TIME_CHECKINGvoid undef_error() c o n s t;i n l i n e operator double() c o n s t{

i f (isundefined())undef_error();

re turn value();};

# e l s ei n l i n e operator double() c o n s t { re turn value(); };

# e n d i f

// data access routines

i n l i n e void clear() { value((double)0); initialized = TRUE; };i n l i n e void undefine() { undefined(); initialized = TRUE; };i n l i n e void reset() { undefined(); initialized = FALSE; };

// routine for setting undef_valuei n l i n e s t a t i c double set_undef_value(){char buf[20];double x,y;

x = 0;sprintf(buf,"%+le",x);buf[0] = ’-’;sscanf(buf,"%le",&y);

re turn y;};

// routine for setting format_string_1 and format_string_2void set_formats_string(){char buf[10];

cout.setf(ios::scientific);cout.precision(8);

strcpy(format_string_1,"%+.");strcpy(format_string_2,"%s:");sprintf(buf,"%dle",accuracy - 1);strcat(format_string_1,buf);strcat(format_string_2,format_string_1);

};

// routine used to compact buf in order to store a double value in// size_in_byte byte of the state vectorunsigned char* compact_buf(char* buf){char aux_buf[100] = "\0";unsigned char* zip_buf;i n t diff_length;unsigned s h o r t i,offset;unsigned char c1,c2;

//initialed zip_bufzip_buf = (unsigned char*) malloc((size_in_byte+1)*

s i z e o f(unsigned char));i f (zip_buf == NULL)Error.Error("Error in compact_buf: unable to allocate memory.");

// aux_buf contains buf without ’.’ and ’e’strncpy(aux_buf,buf,2);strncat(aux_buf,buf+3,accuracy-1);// offset is used to handle the special case accuracy = 1

Page 132: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

120 Chapter B. FHP-Murϕ: the Verifier

offset = accuracy > 1 ? 3 : 2;strcat(aux_buf,buf+accuracy+offset);i f ((diff_length = strlen(aux_buf) - 2*size_in_byte)>0)// aux_buf needs more than ’size_in_byte’ byte;// this case can occur when value’s exponent// take up more than ’exponent’ byte;// the only thing to do is to verify that// whith a loss of accuracy value fits in state vector{// can’t have a number with accuracy less or equal to zeroi f ((diff_length - accuracy)>=0)Error.Error(tsprintf("Error in compact_buf: unable to store %s\

in state vector",buf));

strcpy(buf,""); // reset buf// copy aux_buf in buf with loss of accuracystrncat(buf,aux_buf,accuracy-diff_length+1);strcat(buf,aux_buf+accuracy+1);

strcpy(aux_buf,""); // reset aux_bufstrcpy(aux_buf,buf); // copy buf in aux_buf}

/* compacting aux_buf. This is the code:0 -> 0001 7 -> 10001 -> 0010 8 -> 10012 -> 0011 9 -> 10103 -> 0100 + -> 10114 -> 0101 - -> 11005 -> 0110 -> 1101 used when the aux_buf’s length is odd6 -> 0111Note: the code start with 0001 because ’\0’ is the nullcharacter of a string */

i f ((strlen(aux_buf) % 2) != 0) // aux_buf’s length is oddaux_buf[strlen(aux_buf)] = 13;// the auxiliary code is put in the last position of aux_buf// now, aux_buf’s length is even

aux_buf[strlen(aux_buf)] = ’\0’;

f o r (i=0;i<strlen(aux_buf);i+=2){

swi tch (aux_buf[i]) // setting c1{

case ’+’: {c1 = 11;break;}case ’-’: {c1 = 12;break;}d e f a u l t : {c1 = aux_buf[i] - ’0’ + 1;}

}swi tch (aux_buf[i+1]) // setting c2{

case ’+’: {c2 = 11;break;}case ’-’: {c2 = 12;break;}case 13: {c2 = 13;break;}d e f a u l t: {c2 = aux_buf[i+1] - ’0’ + 1;}

}

// now, c1 and c2 will take up a byte in zipbufc1 = (c1 << 4) | c2;zip_buf[i/2] = c1;}zip_buf[i/2] = ’\0’;re turn zip_buf;

};

// routine used to decompact buf in order to read a double value// from the state vectorchar* decompact_buf(unsigned char* buf) c o n s t{unsigned char c;

Page 133: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 121

char c1,c2;unsigned s h o r t i,j;char* unzip_buf;char aux_buf[100];

//initialed unzip_bufunzip_buf = (char*) malloc((accuracy+exponent+20)* s i z e o f(char));i f (unzip_buf == NULL)Error.Error("Error in decompact_buf: unable to allocate memory.");

j = 0;f o r (i=0;i<size_in_byte;i++){// decompacting in aux_bufc = buf[i];c1 = c >> 4;c2 = c & 0xF;

swi tch (c1) // setting c1{

case 11: {c1 = ’+’;break;}case 12: {c1 = ’-’;break;}d e f a u l t : {c1 = c1 + ’0’ - 1;}

}swi tch (c2) // setting c2{

case 11: {c2 = ’+’;break;}case 12: {c2 = ’-’;break;}case 13: {c2 = 13;break;}d e f a u l t: {c2 = c2 + ’0’ - 1;}

}aux_buf[j++] = c1;aux_buf[j++] = c2;

}aux_buf[j] = ’\0’;// now, we can build unzip_buf storing a double valuej = 0;f o r (i=0;i<strlen(aux_buf);i++){

i f (i == 2)unzip_buf[j++] = ’.’;

i f (((aux_buf[i] == ’+’) || (aux_buf[i] == ’-’)) && (i > 0))unzip_buf[j++] = ’e’;

i f (aux_buf[i] != 13)unzip_buf[j++] = aux_buf[i];

}unzip_buf[j] = ’\0’;re turn unzip_buf;

};

# i f d e f ALIGN// routine used to store a double value in the state vector when// the states aren’t bit-compactedvoid setreal(double value){char buf[100];unsigned char *zip_buf;unsigned s h o r t i;

sprintf(buf,format_string_1,value); // buf contains value

zip_buf = compact_buf(buf); // now, we can copy zip_buf in bitsf o r (i=0;i<size_in_byte;i++){workingstate->bits[i+byteOffset] = zip_buf[i];

}free(zip_buf);

};# e l s e

Page 134: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

122 Chapter B. FHP-Murϕ: the Verifier

// routine used to modify the struct where of position type on// the basis of offset’s valuei n l i n e void set_where( i n t offset,position& where) c o n s t{where.longoffset = offset / 32;where.shift1 = offset % 32;where.mask1 = (1<<8) - 1;where.mask1 <<= where.shift1;where.mask2 = 0;i f ((offset+8)/32 != where.longoffset){where.shift2 = 32-where.shift1;where.mask2 = (1<<(8-where.shift2)) - 1;}where.longoffset *= 4;

};

// routine used to store a double value in the state vector when// the states are bit-compacted (option -b)void setrealb (double value){char buf[100];unsigned char* zip_buf;unsigned s h o r t i;i n t os;position where;

sprintf(buf,format_string_1,value); // buf contains value

zip_buf = compact_buf(buf); // now, we can copy zip_buf in bits

// in order to store zip_buf in bits when the states are bit-// compacted we simply call set() size_in_byte timesos = offset;f o r (i=0;i<size_in_byte;i++){set_where(os,where);workingstate->set(&where,zip_buf[i]);os += 8;}free(zip_buf);

};# e n d i f

# i f d e f ALIGN// routine used to read a double value from the state vector when// the states aren’t bit-compacteddouble getreal(state* st) c o n s t{unsigned char buf[100];char* unzip_buf;double x;unsigned s h o r t i;

f o r (i=0;i<size_in_byte;i++){buf[i] = st->bits[i+byteOffset];}buf[i] = ’\0’;unzip_buf = decompact_buf(buf);sscanf(unzip_buf,"%le",&x);free(unzip_buf);re turn x;

};# e l s e// routine used to read a double value from the state vector when// the states are bit-compacted (option -b)double getrealb(state* st) c o n s t{unsigned char buf[100];char* unzip_buf;double x;

Page 135: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 123

unsigned s h o r t i;i n t os;position where;

// in order to read a double from bits when the states are bit-// compacted we simply call get() size_in_byte timesos = offset;f o r (i=0;i<size_in_byte;i++){set_where(os,where);buf[i] = st->get(&where);os += 8;

}buf[i] = ’\0’;unzip_buf = decompact_buf(buf);sscanf(unzip_buf,"%le",&x);free(unzip_buf);re turn x;

};# e n d i f

i n l i n e c o n s t double value() c o n s t{i f (in_world)

# i f d e f ALIGNre turn getreal(workingstate);

# e l s ere turn getrealb(workingstate);

# e n d i fe l s e

re turn cvalue;};

i n l i n e double value(double val){// fixed to manage exponent limitschar *buf, *tmp;i n t ex_value;

buf = tsprintf(format_string_1,val);i f (!(strcmp(buf,"+nan")) || !(strcmp(buf,"-nan")))Error.Error("Error in value(val): probably either division by \

zero.");i f (!(strcmp(buf,"+inf")) || !(strcmp(buf,"-inf")))Error.Error("Error in value(val): exponent out of bounds.");

tmp = strstr(buf, "e");sscanf(++tmp,"%d",&ex_value);//im: jump ’e’i f (ex_value < -exponent_value+1)val = (double)0;

e l s e i f (ex_value > exponent_value)Error.Error("Error in value(val): exponent %d out of bounds.",ex_value);

i f (in_world)# i f d e f ALIGN

setreal(val);# e l s e

setrealb(val);# e n d i f

e l s e{// used only in this case, setreal(b) doesn’t need thissscanf(buf,"%le",&val); // adjust precision of valuecvalue = val;

}free(buf);re turn val;

};

i n l i n e void undefined(){defined(FALSE);

Page 136: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

124 Chapter B. FHP-Murϕ: the Verifier

};

i n l i n e void defined(bool val){i f (!val)

i f (!in_world)cvalue = undef_value;

e l s e# i f d e f ALIGN

setreal(undef_value);# e l s e

setrealb(undef_value);# e n d i f};

i n l i n e bool defined() c o n s t{double x;char *buf1,*buf2;

bool isdefined;i f (in_world)

# i f d e f ALIGNx = getreal(workingstate);

# e l s ex = getrealb(workingstate);

# e n d i fe l s ex = cvalue;

buf1 = tsprintf("%+le",undef_value);buf2 = tsprintf("%+le",x);isdefined = strcmp(buf1,buf2);free(buf1);free(buf2);re turn (isdefined);

};

i n l i n e bool isundefined() c o n s t{re turn !(defined());

};

// printing, etc.v i r t u a l void print(){char c;

i f (defined()){printf(format_string_2,name,value());printf("\n");}e l s ecout << name << ":Undefined\n";

};

f r i e n d ostream& operator << (ostream& s, mu__real& val){i f (val.defined()) s << (double) val.value();

e l s e s << "Undefined" ;re turn s;

}

void print_diff(state *prev);

// transfer routinesvoid to_state(state *thestate){// Uli: copy value (which is probably undefined)double val = value();in_world = TRUE;value(val);

};

void from_state(state *thestate) {};

Page 137: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 125

// comparing routines, for symmetryf r i e n d i n t CompareWeight(mu__real& a, mu__real& b){

i f (!a.defined() && !b.defined())re turn 0;

e l s e i f (!a.defined())re turn -1;

e l s e i f (!b.defined())re turn 1;

e l s e i f (a.value()==b.value()) re turn 0;e l s e i f (a.value()>b.value()) re turn 1;e l s e re turn -1;

};

f r i e n d i n t Compare(mu__real& a, mu__real& b){

i f (!a.defined() && !b.defined())re turn 0;

e l s e i f (!a.defined())re turn -1;

e l s e i f (!b.defined())re turn 1;

e l s e i f (a.value()==b.value()) re turn 0;e l s e i f (a.value()>b.value()) re turn 1;e l s e re turn -1;

};v i r t u a l void MultisetSort(){};

};# e n d i f

B.1.4 MODIFICATIONS TO MU REAL.C

...

/* undef_value’s definition */double mu__real::undef_value = mu__real::set_undef_value();

B.1.5 MODIFICATIONS TO MU IO.H

...

/* Argclass inspired by Andreas\’ code. */c l a s s argclass{

i n t argc;char **argv;

p u b l i c:

// trace optionsargbool print_trace;argbool full_trace;argbool trace_all;argbool find_errors;argnum max_errors;

argnum verbose_from_state;argbool use_verbose_from_state;argstr verbose_file;

Page 138: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

126 Chapter B. FHP-Murϕ: the Verifier

// memory optionsargnum mem;

// progress report optionsargnum progress_count;argbool print_progress;

// main algorithm optionsargmain_alg main_alg;

// symmetry optionargbool symmetry_reduction;argbool multiset_reduction;argsym_alg sym_alg;argnum perm_limit;argbool debug_sym;

// Uli: hash compaction options# i f d e f HASHCargnum num_bits;argbool trace_file;

# e n d i f

// testing parameterargnum test_parameter1;argnum test_parameter2;

// miscelleneousargnum loopmax;argnum verbose;argbool no_deadlock;argbool print_options;argbool print_license;argbool print_rule;argbool print_hash;

// cached murphi optionsargnum max_collrate; // percent value: 90 -> 0.9argnum max_level; //maximum bfs level

// pmurphik optionsargbool swap_level;argbool queue_compr;argbool fpel;

// bpctl optionsargbool state_compr, ctrl_next, disable_exit, safety;

// simulationargbool simulate_prob;

// supporting routinesargclass( i n t ac, char** av);˜argclass() {};void ProcessOptions(string_iterator *options);bool Flag(char *arg);void PrintInfo( void );void PrintOptions( void );void PrintLicense( void );

};

/****************************************Printing functions.****************************************/

c l a s s ReportManager{

void print_trace_aux(StatePtr p); // changed by Ulip u b l i c:ReportManager();void CheckConsistentVersion();

Page 139: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 127

void StartSimulation();

void print_algorithm();void print_warning();void print_header( void );void print_trace_with_theworld();void print_trace_with_curstate();void print_progress( i n t level, bool forceprint = f a l s e ,

bool endlevel = f a l s e);void print_no_error( i n t );void print_summary(bool);void print_curstate( void );void print_dfs_deadlock( void );void print_retrack( void );void print_fire_startstate();void print_fire_rule();void print_fire_rule(double);void print_fire_rule_diff(state * s);void print_fire_rule_diff(state * s, double);void print_trace_all();void print_verbose_header();void print_hashtable();void print_final_report( i n t = 0);

};

B.1.6 MODIFICATIONS TO MU IO.C

...

// Pmurphik options# d e f i n e QUEUE_COMPRESSION_FLAG "-queuecomp"# d e f i n e SWAP_LEVEL_FLAG "-swaplevel"# d e f i n e FORCE_PRINTING_END_LEVEL "-fpel"// Bpctl verification options# d e f i n e SAFETY_ALGO "-safety"# d e f i n e COMPRESS_NEXT_FLAG "-comp_next"# d e f i n e CTRL_NEXT_STATES_FLAG "-ctrl_next"# d e f i n e VERBOSE_NUM "-verbose"# d e f i n e DISABLE_EXIT "-calc_prob"// simulation# d e f i n e SIMULATE_PROB "-simulate_prob"

...

/****************************************Implementation for the argclass class for handling runtimearguments.****************************************/

argclass::argclass( i n t ac, char** av): argc(ac), argv(av),print_trace (FALSE, "trace printing"),full_trace (FALSE, "printing diff/full states in trace"),trace_all (FALSE, "printing all states"),find_errors (FALSE, "continuing after error"),max_errors (DEFAULT_MAX_ERRORS, "maximum number of errors"),mem (DEFAULT_MEM, "memory allocation"),progress_count (1000, "progress count"),print_progress (TRUE, "progress printing"),main_alg (argmain_alg::Verify_bfs, "main algorithm"),

Page 140: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

128 Chapter B. FHP-Murϕ: the Verifier

loopmax (DEF_LOOPMAX,"maximium loop count"),verbose (0, "verbose"),verbose_from_state (0,"verbose controlled mode"),verbose_file ("","verbose controlled mode to file"),use_verbose_from_state (FALSE,"use verbose controlled mode"),no_deadlock (FALSE, "deadlock detection"),print_options (FALSE, "options printing"),print_license (FALSE, "license printing"),print_rule (FALSE, "rule information printing"),print_hash (FALSE, "hashtable information printing"),symmetry_reduction (TRUE, "symmetry option"),sym_alg (argsym_alg::Heuristic_Small_Mem_Canonicalize,

"symmetry algorithm"),perm_limit (10,"permutation limit"),multiset_reduction (TRUE, "multiset option"),test_parameter1 (100,"testing parameter1"),test_parameter2 (100,"testing parameter2"),

# i f d e f HASHCnum_bits (DEFAULT_BITS, "stored bits"), // added by Ulitrace_file (FALSE, "trace info file"),

# e n d i fdebug_sym (FALSE, "debug symmetry"),max_collrate (90,"max collision rate"),max_level (0,"max bfs level"),swap_level (FALSE, "swap only at BFS level changes"),simulate_prob (FALSE, "Make a simulation"),fpel (FALSE, "force printing end level"),queue_compr (FALSE, "compress the queue"),ctrl_next (FALSE, "control the sum of outgoing probabiliti\

es to be 1.0"),state_compr (FALSE, "compress the next states list"),disable_exit (FALSE, "calculates the correct probability for \

the outer probability"),safety (FALSE, "uses the BF algorithm for the safety ve\

rification"){string_iterator *temp = NULL;

temp = new arg_iterator(ac, av);ProcessOptions( temp );d e l e t e temp;temp = NULL;

# i f d e f HASHC// Uli: do not use trace info file in dfs casei f (main_alg.mode == argmain_alg::Verify_dfs) {

i f (trace_file.value) {d e l e t e TraceFile;trace_file.reset(FALSE);}

}

// Uli: check if trace is wanted but cannot be generatedi f (main_alg.mode == argmain_alg::Verify_bfs)

i f (print_trace.value && !trace_file.value)Error.Notrace("Cannot print error trace if you do not specify trace inf\

o file.");

// Uli: set number of bytes in trace info file// cannot be done earlier since number of bits may be unknowni f (trace_file.value) {TraceFile->setBytes( i n t(num_bits.value));print_trace.reset(TRUE);

}# e n d i f

// avoid mixing verbose and progress report

Page 141: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 129

i f (verbose.value) print_progress.set(FALSE);

i f (main_alg.mode != argmain_alg::Verify_bfs && find_errors.value)// changed by Uli{Error.Notrace("Please use -vbfs for finding multiple errors \

in single run.");}

i f (sym_alg.mode != argsym_alg::Heuristic_Small_Mem_Canonicalize&& perm_limit.value !=0)

{perm_limit.set(0);

}

i f (debug_sym.value) symmetry_reduction.reset(FALSE);

PrintInfo();}

...

void argclass::ProcessOptions(string_iterator *options){

char* option;bool no_verification = FALSE;unsigned long temp;char temp_str[256];

f o r ( options->start(); !options->done(); options->n e x t() ){option = options->value();

// cached murphi options begin

i f ( strncmp(option, MAX_COLLRATE_PREFIX,strlen(MAX_COLLRATE_PREFIX) ) == 0 )

{Error.Notrace("Option %s not available in BPMC", option);cont inue;

};

i f ( strncmp(option, MAX_LEVEL_PREFIX,strlen(MAX_LEVEL_PREFIX) ) == 0 )

{i f ( strlen(option) <= strlen(MAX_LEVEL_PREFIX) )/* We cannot have a space before the number */{sscanf( options->nextvalue(), "%s", temp_str );i f (isdigit(temp_str[0])){sscanf( temp_str, "%u", (unsigned long) &temp );options->n e x t();

}e l s e

Error.Notrace("Unrecognized bound for BPMC. Do ’%s -h’ f\or list of valid arguments.", argv[0]);

}e l s e{sscanf( options->value() + strlen(MAX_LEVEL_PREFIX), "%s",temp_str);

i f (isdigit(temp_str[0]))sscanf( temp_str, "%u", (unsigned long) &temp );

e l s eError.Notrace("Unrecognized bound for BPMC. Do ’%s -h’ for li\

st of valid arguments.", argv[0]);

Page 142: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

130 Chapter B. FHP-Murϕ: the Verifier

}i f (temp < 0)Error.Notrace("Invalid bound for BPMC. Valid values must be po\

sitive or zero");max_level.set(temp);cont inue;

};

// cached murphi options end

// pmurphik options begin

i f ( strcmp(option, QUEUE_COMPRESSION_FLAG) == 0 ){Error.Notrace("Option %s not available in BPMC", option);cont inue;

};

i f ( strcmp(option, SWAP_LEVEL_FLAG) == 0 ){Error.Notrace("Option %s not available in BPMC", option);cont inue;

};

i f ( strcmp(option, FORCE_PRINTING_END_LEVEL) == 0 ){fpel.set( t rue);cont inue;

};

// pmurphik options end

// bpctl options begin

i f ( strcmp(option, SAFETY_ALGO) == 0 ){safety.set( t rue);cont inue;

};

i f ( strcmp(option, CTRL_NEXT_STATES_FLAG) == 0 ){ctrl_next.set( t rue);cont inue;

};

i f ( strcmp(option, COMPRESS_NEXT_FLAG) == 0 ){state_compr.set( t rue);cont inue;

};

i f ( strcmp(option, DISABLE_EXIT) == 0 ){disable_exit.set( t rue);cont inue;

};

i f ( strcmp( option, VERBOSE_NUM ) == 0 ){

i f ( strlen(option) <= strlen(VERBOSE_NUM) )/* We cannot have a space before the number */{sscanf( options->nextvalue(), "%s", temp_str );i f (isdigit(temp_str[0])){sscanf( temp_str, "%u", (unsigned long) &temp );options->n e x t();

}e l s e

Page 143: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 131

Error.Notrace("Unrecognized verbose value. Do ’%s -h’ for \list of valid arguments.", argv[0]);

}e l s e{sscanf( options->value() + strlen(VERBOSE_NUM), "%s",temp_str );

i f (isdigit(temp_str[0]))sscanf( temp_str, "%u", (unsigned long) &temp );

e l s eError.Notrace("Unrecognized verbose value. Do ’%s -h’ for \

list of valid arguments.", argv[0]);}verbose.set(temp);cont inue;

}

i f ( strcmp( option, PRINT_10_FLAG ) == 0 ){progress_count.set(10);print_progress.set(TRUE);cont inue;

}i f ( strcmp( option, PRINT_100_FLAG ) == 0 ){progress_count.set(100);print_progress.set(TRUE);cont inue;

}i f ( strcmp( option, PRINT_1000_FLAG ) == 0 ){progress_count.set(1000);print_progress.set(TRUE);cont inue;

}i f ( strcmp( option, PRINT_10000_FLAG ) == 0 ){progress_count.set(10000);print_progress.set(TRUE);cont inue;

}i f ( strcmp( option, PRINT_100000_FLAG ) == 0 ){progress_count.set(100000);print_progress.set(TRUE);cont inue;

}i f ( strcmp( option, PRINT_NONE_FLAG ) == 0 ){print_progress.set(FALSE);cont inue;

}

// bpctl options end

// simulationi f ( strcmp(option, SIMULATE_PROB) == 0 ){simulate_prob.set(TRUE);cont inue;

};

/* we have to handle memory as a special case. */i f ( strncmp(option, MEM_MEG_PREFIX, 2 ) == 0 ){

i f ( strlen(option) <= strlen(MEM_MEG_PREFIX) )/* We cannot have a space before the number */{

Page 144: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

132 Chapter B. FHP-Murϕ: the Verifier

sscanf( options->nextvalue(), "%s", temp_str );i f (isdigit(temp_str[0])){sscanf( temp_str, "%u", (unsigned long) &temp );options->n e x t();

}e l s eError.Notrace("Unrecognized memory size. Do ’%s -h’ for li\

st of valid arguments.", argv[0]);}e l s e{sscanf( options->value() + strlen(MEM_MEG_PREFIX), "%s",temp_str );

i f (isdigit(temp_str[0]))sscanf( temp_str, "%u", (unsigned long) &temp );

e l s eError.Notrace("Unrecognized memory size. Do ’%s -h’ for li\

st of valid arguments.", argv[0]);}mem.set(temp * 0x100000L); /* times 1 Meg. */cont inue;

};i f ( strncmp(option, MEM_K_PREFIX, strlen(MEM_K_PREFIX) ) == 0 ){

i f ( strlen(option) <= strlen(MEM_K_PREFIX) )/* We cannot have a space before the number */{sscanf( options->nextvalue(), "%s", temp_str );i f (isdigit(temp_str[0])){sscanf( temp_str, "%u", (unsigned long) &temp );options->n e x t();

}e l s eError.Notrace("Unrecognized memory size. Do ’%s -h’ for li\

st of valid arguments.", argv[0]);}e l s e{sscanf( options->value() + strlen(MEM_K_PREFIX), "%s",temp_str );

i f (isdigit(temp_str[0]))sscanf( temp_str, "%u", (unsigned long) &temp );

e l s eError.Notrace("Unrecognized memory size. Do ’%s -h’ for li\

st of valid arguments.", argv[0]);}mem.set(temp * 0x400L); /* times 1 Kilobyte. */cont inue;

};

# i f d e f HASHC // never defined (disabled by --bpctl)// added by Ulii f ( strncmp(option, NUM_BITS_PREFIX,

strlen(NUM_BITS_PREFIX) ) == 0 ){

i f ( strlen(option) <= strlen(NUM_BITS_PREFIX) )// there is a space before the number{sscanf( options->nextvalue(), "%s", temp_str );i f (isdigit(temp_str[0])){sscanf( temp_str, "%u", (unsigned long) &temp );options->n e x t();

}e l s e

Page 145: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 133

Error.Notrace("Unrecognized number of bits.", argv[0]);}e l s e // no space{sscanf( options->value() + strlen(NUM_BITS_PREFIX), "%s",temp_str );

i f (isdigit(temp_str[0]))sscanf( temp_str, "%u", (unsigned long) &temp );

e l s eError.Notrace("Unrecognized number of bits.", argv[0]);

}i f (temp>64 || temp<1)Error.Notrace("Number of bits not allowed.");num_bits.set(temp);cont inue;

};

// added by Ulii f ( strncmp(option, TRACE_DIR_PREFIX,

strlen(TRACE_DIR_PREFIX) ) == 0 ){

i f ( strlen(option) <= strlen(TRACE_DIR_PREFIX) )// there is a space before the filename{sscanf( options->nextvalue(), "%s", temp_str );options->n e x t();}e l s e // no space{sscanf( options->value() + strlen(NUM_BITS_PREFIX), "%s",temp_str);

}TraceFile = new TraceFileManager(temp_str);trace_file.set(TRUE);cont inue;

};# e n d i f

i f ( strncmp(option, LOOPMAX_PREFIX,strlen(LOOPMAX_PREFIX) ) == 0 )

{Error.Notrace("Option %s not available in BPMC", option);

};i f ( strncmp(option, PERM_LIMIT, strlen(PERM_LIMIT) ) == 0 ){Error.Notrace("Option %s not available in BPMC", option);

};i f ( strncmp(option, TEST1_PREFIX, strlen(TEST1_PREFIX) ) == 0 ){Error.Notrace("Option %s not available in BPMC", option);

};i f ( strncmp(option, TEST2_PREFIX, strlen(TEST2_PREFIX) ) == 0 ){Error.Notrace("Option %s not available in BPMC", option);

};i f ( strcmp( option, SIMULATE_FLAG ) == 0 ){Error.Notrace("Option %s not available in BPMC", option);

}i f ( strcmp( option, VER ifY_FLAG ) == 0 ){Error.Notrace("Option %s not available in BPMC", option);

}i f ( strcmp( option, VER ifY_BFS_FLAG ) == 0 ){Error.Notrace("Option %s not available in BPMC", option);

}i f ( strcmp( option, VER ifY_DFS_FLAG ) == 0 )

Page 146: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

134 Chapter B. FHP-Murϕ: the Verifier

{Error.Notrace("Option %s not available in BPMC", option);}i f ( strcmp( option, NO_DEADLOCK_FLAG ) == 0 ){Error.Notrace("Option %s not available in BPMC", option);}i f ( strcmp( option, CONTINUE_AFTER_ERROR_FLAG ) == 0 ){Error.Notrace("Option %s not available in BPMC", option);}i f ( strncmp( option, MAX_NUM_ERRORS_PREFIX,

strlen(MAX_NUM_ERRORS_PREFIX) ) == 0 ){Error.Notrace("Option %s not available in BPMC", option);};

/* control frequency of printouts. */i f ( strcmp( option, VERBOSE_FLAG ) == 0 ){Error.Notrace("Option %s not available in BPMC", option);}i f ( strcmp ( option, VERBOSE_FROM ) == 0 ){Error.Notrace("Option %s not available in BPMC", option);}i f ( strcmp ( option, VERBOSE_FILE ) == 0 ){Error.Notrace("Option %s not available in BPMC", option);}

/* handle trace types. */i f ( strcmp( option, TRACE_VIOLATE_FLAG ) == 0 ){Error.Notrace("Option %s not available in BPMC", option);}i f ( strcmp( option, TRACE_D ifF_FLAG ) == 0 ){Error.Notrace("Option %s not available in BPMC", option);}i f ( strcmp( option, TRACE_FULL_FLAG ) == 0 ){Error.Notrace("Option %s not available in BPMC", option);}i f ( strcmp( option, TRACE_ALL_FLAG ) == 0 ){Error.Notrace("Option %s not available in BPMC", option);}i f ( strcmp( option, TRACE_NONE_FLAG ) == 0 ){Error.Notrace("Option %s not available in BPMC", option);}i f ( strcmp( option, HELP_FLAG ) == 0 ){print_options.set(TRUE);no_ver ification = TRUE;cont inue;

}i f ( strcmp( option, LICENSE_FLAG ) == 0 ){print_license.set(TRUE);cont inue;

}i f ( strcmp( option, PRINT_RULE_FLAG ) == 0 ){Error.Notrace("Option %s not available in BPMC", option);}i f ( strcmp( option, NO_SYM_FLAG ) == 0 ){

Page 147: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 135

Error.Notrace("Option %s not available in BPMC", option);}

i f ( strcmp( option, NO_MULTISET_FLAG ) == 0 ){Error.Notrace("Option %s not available in BPMC", option);}

i f ( strncmp(option, SYMMETRY_PREFIX,strlen(SYMMETRY_PREFIX) ) == 0 )

{Error.Notrace("Option %s not available in BPMC", option);

};

Error.Notrace("Unrecognized flag %s. Do ’%s -h’ for list o\f valid arguments.", option, argv[0]);

cont inue;}

i f (fpel.value && !safety.value)Error.Notrace("-fpel available only with -safety");

i f (no_verification)main_alg.set(argmain_alg::Nothing);

}

void argclass::PrintOptions( void ) // changes by Uli{cout << "Options:\n"

<< "1) General:\n"<< "\t-h help.\n"<< "\t-l print license.\n"<< "2) Verification Strategy\n"<< "\t-safety use bfs (safety properties only)\n"<< "\t-simulate_prob simulation\n"<< "3) Others Options: (default: -m8, -p3, -loop1000)\n"<< "\t-m<n> amount of memory for closed hash table in Mb.\\n"<< "\t-k<n> same, but in Kb.\n"<< "\t-p make verification verbose.\n"<< "\t-pfrom<n> make verification (via bfs) verbose from stat\e n.\n"<< "\t-p<n> report progress every 10ˆn events, n in 1..5.\\n"<< "\t-pn print no progress reports.\n"<< "\t-fpel force printing at end of level (only with -sa\fety)"<< "\t-pr print out rule information.\n"<< "\t-verbose<n> print infos on the algorithm execution.\n"<< "\t-calc_prob<n> computes the exact probability for the outer \BPCTL formula.\n"<< "4) Error Trace Handling: disabled\n"<< "5) Reduction Technique: disabled\n"<< "\n";}

...

/************************************************************/void ReportManager::print_header( void ) // changes by Uli{

cout << "\n====================================="<< "=====================================\n"<< MURPHI_VERSION << "\n"<< "Finite-state Concurrent System Verifier.\n"<< "\n"<< MURPHI_VERSION << " is based on Murphi release 3.1.\n"<< MURPHI_VERSION << " :\n"<< "Copyright (C) 2001 by E. Tronci, G. Della Penna, I. Mel\

Page 148: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

136 Chapter B. FHP-Murϕ: the Verifier

atti, B. Intrigila, M. Zilli.\n"<< "Murphi release 3.1 :\n"<< "Copyright (C) 1992 - 1999 by the Board of Trustees of\n"<< "Leland Stanford Junior University.\n"<< "\n====================================="<< "=====================================\n"<< "\nProtocol: " << PROTOCOL_NAME << "\n";

// cout.flush();// flushing cout had seemed to cause some weirdnesses.

}

...

void ReportManager::print_progress( i n t level, bool forceprint,bool endlevel )

{s t a t i c bool initialized = FALSE;

// pring progress report every <args->progress_count> new states// foundi f ((forceprint) || ( args->print_progress.value&& StateSet->NumElts() % args->progress_count.value == 0 )) {i f (!initialized) {cout << "\nProgress Report:\n\n";initialized = TRUE;}i f (args->safety.value && endlevel) {cout << "\n***************\n";cout << "Level " << StateSet->GetCurrentLevel() - 1 << " comple\

ted.\n\n";} e l s e {cout << "\t";cout << StateSet->NumElts() << " states explored in "<< SecondsSinceStart() << "s, with "<< Rules->NumRulesFired() << " rules fired.";

}i f (args->safety.value && !endlevel)cout << " Exploring level " << StateSet->GetCurrentLevel() << "."<< " Formula probability "<< setprecision(6) << setiosflags(ios::scientific)<< E_p<< setprecision(3) << resetiosflags(ios::scientific)<< ".\n";

e l s e i f (!args->safety.value) {cout << "Exploring level " << level << ".";i f (args->verbose.value > 3)cout << "\t\teffectiveness: "

<< StateSet->subf_cache->effectiveness() << "\n";}cout.flush();

}}

/************************************************************/void ReportManager::print_no_error( i n t reason ){cout << "\n====================================="

<< "=====================================\n"<< "\nResults:\n";

i f (reason==0)cout << "\n\tExploration complete.";

e l s e i f (reason==3)cout << "\n\tPCTL formula satisfied.";

e l s e i f (reason==4)cout << "\n\tPCTL formula not satisfied.";

Page 149: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 137

e l s e i f (reason==5)cout << "\n\tPCTL formula satisfied (max depth not reached).";

e l s e i f (reason==6)cout << "\n\tPCTL formula not satisfied (max depth not reached).";

}

/************************************************************/void ReportManager::print_summary(bool prob){

bool exist = FALSE;

i f (StateSet == NULL){

i f (args->max_level.value == 0)cout << "\n\tVerification horizon set to 0";

e l s ecout << "\n\tVerification of an atomic proposition";

cout << ": no state space exploration perfomed.\n";}e l s ecout << "\nState Space Explored:\n\n"

<< "\t"<< StateSet->NumElts() << " states, "<< Rules->NumRulesFired() << " rules fired in "<< SecondsSinceStart() << "s.\n"<< "\tLevels Explored: " << StateSet->GetCurrentLevel()-1<< "\n\n";

i f (prob) {# i f d e f HASHC

// Uli: print omission probabilitiesStateSet->PrintProb();

# e n d i f}

Rules->print_rules_information();theworld.print_statistic();

}

...

/************************************************************/void ReportManager::print_fire_startstate(){cout << "Firing startstate "

<< StartState->LastStateName()<< " with probability "<< StartState->LastStateProb()<< "\n"<< "Obtained state:\n";

theworld.print();cout << ’\n’;

}

/************************************************************/void ReportManager::print_fire_rule(double prob){cout << "Firing rule "

<< Rules->LastRuleName()<< " with probability "<< prob<< ’\n’<< "Obtained state:\n";

theworld.print();cout << ’\n’;

}

Page 150: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

138 Chapter B. FHP-Murϕ: the Verifier

/************************************************************/void ReportManager::print_fire_rule(){cout << "Firing rule "

<< Rules->LastRuleName()<< " with probability "<< Rules->LastRuleProb()<< ’\n’<< "Obtained state:\n";

theworld.print();cout << ’\n’;

}

/************************************************************/void ReportManager::print_fire_rule_diff(state * s, double prob){cout << "Firing rule "

<< Rules->LastRuleName()<< " with probability "<< prob<< ’\n’<< "Obtained state:\n";

theworld.print_diff(s);cout << ’\n’;

}

/************************************************************/void ReportManager::print_fire_rule_diff(state * s){cout << "Firing rule "

<< Rules->LastRuleName()<< " with probability "<< Rules->LastRuleProb()<< ’\n’<< "Obtained state:\n";

theworld.print_diff(s);cout << ’\n’;

}

B.1.7 MODIFICATIONS TO MU UTIL DEP.H

...

c l a s s setofrules{p r o t e c t e d:BIT_BLOCK bits[BLOCKS_IN_SETOFRULES];// to manage rules probabilitiesdouble probabilities[RULES_IN_WORLD];unsigned NumRules; // Uli: unsigned short -> unsigned

i n t Index( i n t i) c o n s t { re turn i / BITS( BIT_BLOCK ); };i n t Shift( i n t i) c o n s t { re turn i % BITS( BIT_BLOCK ); };i n t Get1( i n t i) c o n s t{ re turn ( bits[ Index(i) ] >> Shift(i) ) & 1; };void Set1( i n t i, i n t val) /* Set bit i to the low bit of val. */{

i f ( (val & 1) != 0 )bits[ Index(i) ] |= ( 1 << Shift(i));

e l s ebits [ Index(i) ] &= ˜( 1 << Shift(i));

};

Page 151: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 139

p u b l i c:

// set of rules manipulationf r i e n d setofrules interset(setofrules rs1, setofrules rs2);f r i e n d setofrules different(setofrules rs1, setofrules rs2);f r i e n d bool subset(setofrules rs1, setofrules rs2);

// conflict set manipulationf r i e n d setofrules conflict(unsigned rule);

setofrules(): NumRules(0){ f o r ( i n t i=0; i<BLOCKS_IN_SETOFRULES; i++) bits[i]=0;};

v i r t u a l ˜setofrules() {};

bool in( i n t rule) c o n s t { re turn (bool) Get1(rule); };void add( i n t rule, double prob = (double)1){

i f (!in(rule)){

Set1(rule,TRUE);NumRules++;}

probabilities[rule] = prob; // added probability};void remove( i n t rule){

i f (in(rule)){

Set1(rule,FALSE);NumRules--;}

}bool nonempty(){

re turn (NumRules!=0);};i n t size(){

re turn NumRules;};void print(){cout << "The set of rules =\t";f o r ( i n t i=0; i<RULES_IN_WORLD; i++)cout << (Get1(i)?1:0) << ’,’;

cout << "\n";};

// for simulationvoid removeall(){

f o r ( i n t i=0; i<RULES_IN_WORLD; i++)Set1(i,FALSE);

NumRules = 0;};

// for simulationvoid includeall(){

f o r ( i n t i=0; i<RULES_IN_WORLD; i++)Set1(i,TRUE);

NumRules = RULES_IN_WORLD;};unsigned getnthrule(unsigned rule){

unsigned r=0;i n t i=0;

Page 152: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

140 Chapter B. FHP-Murϕ: the Verifier

whi l e (1)i f (Get1(i) && r==rule)

{ Set1(i,FALSE); NumRules--; re turn (unsigned) i; }e l s e i f (Get1(i))

{ i++; r++; }e l s e

{ i++; }};// added probdouble prob( i n t rule){

re turn probabilities[rule];}

};

B.1.8 MODIFICATIONS TO MU UTIL.C

...

unsigned longNumStatesGivenBytes( unsigned long bytes ){

re turn (unsigned long)((double)bytes*gPercentActiveStates

/((state_probability_queue::BytesForOneState()) +state_probability_queue::BytesForOneState_hashtable()

));}

B.1.9 MODIFICATIONS TO MU VERIFIER.H

...

/* type definitions for PCTL formulas */enum pctl_type {UNTIL_PCTL, NEXT_PCTL, AP_PCTL, AND_PCTL, OR_PCTL,

IMPL_PCTL, NOT_PCTL};

enum pctl_ord {PCTL_L, PCTL_LEQ, PCTL_G, PCTL_GEQ};

s t r u c t pctlformrec { // record for PCTL formulapctl_type type;boolfunc condition;pctl_ord ord;double prob_bound;unsigned until_bound;c o n s t s t r u c t pctlformrec *subf1, *subf2;

};

B.1.10 MODIFICATIONS TO MU VERIFIER.C

...

Page 153: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 141

i n t main( i n t argc, char **argv){args = new argclass(argc, argv);Algorithm = new AlgorithmManager();

i f (!args->print_options.value) {i f (!args->simulate_prob.value) {

i f (args->safety.value) {i f (!Algorithm->IsSafety()) {cerr << "-safety is usable only with a finite horizon safety \

property" << endl;exit(1);

}Algorithm->verify_bfs();}e l s eAlgorithm->verify_bpmc();

}e l s eAlgorithm->simulate();

}

cout.flush();d e l e t e Algorithm; // fix: begin destruction chainexit(0);

}

B.1.11 MODIFICATIONS TO MU STATE.H

...

c l a s s aux_cache{randomGen random; // random number generator for random walk

// dataunsigned long table_size; /* max size of the hash table */state_prob_hor_form *table;/* pointer to the hash table */dynBitVec *Full; /* whether element table[i] is used. */unsigned long num_elts; /* number of elements in table */unsigned long num_collisions; /* number of collisions in hashing */unsigned long ht_overwrite; /* overwrites in caching. gdp */unsigned max_ht_chain_length;unsigned long num_called, num_failed;

// internal routines/* check if element table[i] is empty */bool is_empty( unsigned long i ){ re turn Full->get(i) == 0; };bool try_to_evaluate(state_prob_hor_form *, unsigned , bool&);

p u b l i c:// constructoraux_cache(unsigned long memory, unsigned max_ht_chain_length);

// destructorv i r t u a l ˜aux_cache();

double simple_was_present(state_prob_hor_form * in);bool insert(state_prob_hor_form * in);bool try_to_evaluate(state_prob_hor_form * in, bool& val);i n l i n e double effectiveness(){ re turn (double)num_failed/num_called; };

};

Page 154: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

142 Chapter B. FHP-Murϕ: the Verifier

B.1.12 MODIFICATIONS TO MU STATE.C

...

aux_cache::aux_cache(unsigned long memory_bytes,unsigned max_ht_chain_length)

: num_elts(0), num_collisions(0), ht_overwrite(0),max_ht_chain_length(max_ht_chain_length), num_called(0),num_failed(0)

{table_size = NextPrime((unsigned long)

(memory_bytes / s i z e o f(state_prob_hor_form)));table = new state_prob_hor_form [table_size];Full = new dynBitVec ( table_size );

}

aux_cache::˜aux_cache(){

d e l e t e[] table; // only works for newer g++ versionsd e l e t e Full;

}

boolaux_cache::try_to_evaluate(state_prob_hor_form * in, unsigned h,

bool& result){

i f (table[h]._horizon < in->_horizon &&table[h]._probability > in->_subformula->prob_bound)

{i f (in->_subformula->ord == PCTL_G){result = TRUE;re turn TRUE;

}e l s e i f (in->_subformula->ord == PCTL_LEQ){result = FALSE;re turn TRUE;

}}e l s e i f (table[h]._horizon < in->_horizon &&

table[h]._probability >= in->_subformula->prob_bound){

i f (in->_subformula->ord == PCTL_GEQ){result = TRUE;re turn TRUE;

}e l s e i f (in->_subformula->ord == PCTL_L){result = FALSE;re turn TRUE;

}}e l s e i f (table[h]._horizon > in->_horizon &&

table[h]._probability < in->_subformula->prob_bound){

i f (in->_subformula->ord == PCTL_L){result = TRUE;re turn TRUE;

}e l s e i f (in->_subformula->ord == PCTL_GEQ){result = FALSE;re turn TRUE;

}

Page 155: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 143

}e l s e i f (table[h]._horizon > in->_horizon &&

table[h]._probability <= in->_subformula->prob_bound){

i f (in->_subformula->ord == PCTL_LEQ){result = TRUE;re turn TRUE;

}e l s e i f (in->_subformula->ord == PCTL_G){result = FALSE;re turn TRUE;

}}re turn FALSE;

}

boolaux_cache::try_to_evaluate(state_prob_hor_form * in, bool& result){

unsigned long key = in->_state.hashkey();unsigned long h1 = key % table_size;unsigned long h2 = 1 + key % ( table_size - 1 );unsigned long h = h1;

unsigned long probe = 0;

// no hash compaction, uses double hashing

bool empty, equal= FALSE;

whi le (!(empty = is_empty(h)) &&!(equal = in->compare_st_form(&table[h])) &&(probe < max_ht_chain_length))

{h = (h1 + probe * h2) % table_size; // double hashingprobe++;

}whi le (!empty && equal && table[h]._horizon != in->_horizon){

i f (try_to_evaluate(in, h, result))re turn result;

h = (h1 + probe * h2) % table_size; // double hashingprobe++;i f (!(empty = is_empty(h)))equal = in->compare_st_form(&table[h]);

}i f (!empty && equal && table[h]._horizon == in->_horizon){

swi tch(in->_subformula->ord){

case PCTL_L :result = table[h]._probability < in->_subformula->prob_bound;break;

case PCTL_LEQ :result = table[h]._probability <= in->_subformula->prob_bound;break;

case PCTL_G :result = table[h]._probability > in->_subformula->prob_bound;break;

case PCTL_GEQ :result = table[h]._probability >= in->_subformula->prob_bound;break;

d e f a u l t :Error.Notrace("Internal error: invalid value %d for in->_s\

ubformula->ord", in->_subformula->ord);re turn FALSE;

}

Page 156: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

144 Chapter B. FHP-Murϕ: the Verifier

re turn TRUE;}e l s e

re turn FALSE;};

doubleaux_cache::simple_was_present(state_prob_hor_form * in){

unsigned long key = in->_state.hashkey();unsigned long h1 = key % table_size;unsigned long h2 = 1 + key % ( table_size - 1 );unsigned long h = h1;

unsigned long probe = 0;

// no hash compaction, uses double hashing

bool empty, equal= FALSE;

whi le (!(empty = is_empty(h)) &&!(equal = in->compare_no_prob(&table[h])) &&(probe < max_ht_chain_length))

{h = (h1 + probe * h2) % table_size; // double hashingnum_collisions++;probe++;

}i f (!empty && equal && table[h]._horizon == in->_horizon)

re turn table[h]._probability;e l s e

re turn -1.0;};

bool aux_cache::insert(state_prob_hor_form * in){

unsigned long key = in->_state.hashkey();unsigned long h1 = key % table_size;unsigned long h2 = 1 + key % ( table_size - 1 );unsigned long h = h1;

unsigned long probe = 0;

// no hash compaction, uses double hashing

bool empty, equal= FALSE;c o n s t f l o a t param = 0.05;

num_called++;

whi le (!(empty = is_empty(h)) &&!(equal = in->compare_no_prob(&table[h])) &&(probe < max_ht_chain_length))

{h = (h1 + probe * h2) % table_size; // double hashingnum_collisions++;probe++;

}i f (probe == max_ht_chain_length){num_failed++;i f (args->verbose.value > 3)printf("num_failed:%u num_called:%u NumStates:%lu\n",num_failed, num_called, StateSet->NumElts());

}i f (num_failed >= param*num_called){max_ht_chain_length *= 2;i f (args->verbose.value > 3)

Page 157: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 145

printf("\n\n\nmax_ht_changed from %u to %u\n\n\n\n",max_ht_chain_length/2, max_ht_chain_length);

i f (max_ht_chain_length >= table_size/2)re turn FALSE;

num_failed = num_called = 0;}i f (empty) /* Go ahead and insert the element. */{table[h] = *in;Full->set(h);num_elts++;re turn TRUE;

}e l s e i f (in->compare_st_form(&table[h]) &&

table[h]._horizon < in->_horizon){table[h] = *in;re turn TRUE;

}re turn TRUE;

};

B.1.13 ADDED FILE SPLITFILE.H

This was written by Giuseppe Della Penna.

...

# i f n d e f _SPLITFILE_# d e f i n e _SPLITFILE_

# d e f i n e DEFAULTDIR 0# d e f i n e FORWARD 1# d e f i n e BACKWARD 2

c l a s s splitFile {p u b l i c:splitFile(unsigned long splitsize, bool permanent = t rue);˜splitFile();bool open(char *filename, char* access);void close();unsigned long read(void * buffer, unsigned long size,

unsigned long count);unsigned long write(void * buffer, unsigned long size,

unsigned long count);unsigned long tell(unsigned long size=1);void seek(unsigned long size, unsigned long count, i n t from,

i n t direction=DEFAULTDIR);void seek(unsigned long count, i n t from);bool eof();char *getBaseFileName() {re turn _filename;}void setPermanent(bool perm) {_permanent = perm;}

p r o t e c t e d:void CreateNextPart();bool OpenNextPart();bool GotoNextPart(bool write_mode);i n l i n e unsigned long curfilepos();i n l i n e unsigned long getpartsize( i n t npart);unsigned long writebytes(void * buffer, unsigned long size);unsigned long readbytes(void * buffer, unsigned long size);

Page 158: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

146 Chapter B. FHP-Murϕ: the Verifier

bool seekbytes(unsigned long size, i n t direction, i n t & part,unsigned long& skip);

p r i v a t e:char _access[10];char _filename[1020];bool _permanent;FILE *parts[100];unsigned long partsize[100];i n t maxpart, curpart;unsigned long _splitsize;bool _eof;

/* check for type size invariants only once */s t a t i c bool sizechecks;

};# e n d i f

B.1.14 ADDED FILE SPLITFILE.C

This was written by Giuseppe Della Penna.

...

# d e f i n e min(a,b) (((a)<(b))?(a):(b))# d e f i n e max(a,b) (((a)>(b))?(a):(b))

//Max # of parts handled by the splitFile class//Adjust to match your needs# d e f i n e MAX_PARTS 200

# i n c l u d e "splitFile.h"

bool splitFile::sizechecks = f a l s e ;

/** Creates (but not opens) a spliFile.* The file will be subdivided in several files,* each with a length <= slitsize.* If permanent is false, the split file will be* deleted when closed.**/

splitFile::splitFile(unsigned long splitsize, bool permanent): _splitsize(splitsize), maxpart(-1), curpart(-1), _eof( t rue),

_permanent(permanent){

i f (sizechecks == f a l s e) {i f ( s i z e o f(char) != 1) {fprintf(stderr,"splitFile: error: sizeof(char) != 8");exit(10);}

i f ( s i z e o f(unsigned long) > s i z e o f(size_t)) {fprintf(stderr,"splitFile: waning: size_t type is smaller than \

unsigned long!");}

sizechecks= t rue;}

memset(parts,0, s i z e o f(FILE*)*MAX_PARTS);}

Page 159: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 147

splitFile::˜splitFile(){close();

}

void splitFile::CreateNextPart(){

char filename[1024];sprintf(filename,"%s.%02d",_filename,maxpart+1);

i f (maxpart >= MAX_PARTS) {fprintf(stderr,"splitFile: file %s has too many sections",filename);

exit(10);}

i f ((parts[++maxpart] = fopen(filename,_access))==NULL) {fprintf(stderr,"splitFile: error creating next section of file: \

%s", filename);exit(10);

}curpart=maxpart;partsize[curpart] = 0;

}

bool splitFile::OpenNextPart(){

char filename[1024];sprintf(filename,"%s.%02d",_filename,maxpart+1);unsigned long thispartsize;

FILE *dummy;

i f ((dummy=fopen(filename,"r"))==NULL) re turn f a l s e;fseek(dummy,0,SEEK_END);thispartsize = ftell(dummy);fclose(dummy);

i f (maxpart >= MAX_PARTS) {fprintf(stderr,"splitFile: file %s has too many sections",filename);

exit(10);}

i f ((parts[++maxpart] = fopen(filename,_access))==NULL) {fprintf(stderr,"splitFile: error opening next section of file: \

%s",filename);exit(10);

}

curpart=maxpart;partsize[curpart] = thispartsize;re turn true;

}

bool splitFile::GotoNextPart(bool write_mode){

i f (parts[curpart+1] == NULL) {i f (write_mode) CreateNextPart();e l s e re turn f a l s e ;

} e l s e {curpart+=1;fseek(parts[curpart],0,SEEK_SET);

}re turn true;

}

unsigned long splitFile::curfilepos(){

Page 160: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

148 Chapter B. FHP-Murϕ: the Verifier

re turn ftell(parts[curpart]);}

unsigned long splitFile::getpartsize( i n t npart){

re turn partsize[npart];}

bool splitFile::open(char *filename, char* access){strcpy(_access,access);strcpy(_filename,filename);i f (strchr(access,’r’)) whi le (OpenNextPart());i f (maxpart<0) CreateNextPart();curpart=0;

//if the file was opened with read as primary mode (r+)//then ignore the user specified permanent flag and do not delete//the opened file!i f (strchr(access,’r’)) setPermanent( t rue);re turn true;

}

void splitFile::close(){//all the file parts are opened and registered in the parts arraychar filename[1024];f o r( i n t i=0; i<=maxpart; i++) {

i f (parts[i]!=NULL) {fclose(parts[i]);i f (!_permanent) {sprintf(filename,"%s.%02d",_filename,i);remove(filename);

}}

}

memset(parts,0, s i z e o f(FILE*)*MAX_PARTS);maxpart = -1;curpart = -1;_eof = t rue;

}

/** splitFile read and write routines are identical to the* corresponding FILE* versions.**/

unsigned long splitFile::writebytes(void * buffer, unsigned long size){

unsigned long inthispart, towrite,totalwritten=0,reminder=0;unsigned long pp=0;

whi le(size>0) {inthispart= (_splitsize-curfilepos());towrite = min(size,inthispart);fwrite(((char*)buffer)+pp,1,towrite,parts[curpart]);size-=towrite;totalwritten+=towrite;pp+=towrite;

i f (ftell(parts[curpart])>partsize[curpart])partsize[curpart] = ftell(parts[curpart]);

i f (size>0) GotoNextPart( t rue);}

re turn totalwritten;}

Page 161: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 149

unsigned long splitFile::write(void * buffer, unsigned long size,unsigned long count)

{unsigned long totalwritten=0;unsigned long pp=0;

_eof= f a l s e;

whi le(count>totalwritten) {writebytes(((char*)buffer)+pp,size);pp+=size;totalwritten++;}

re turn totalwritten;}

unsigned long splitFile::readbytes(void * buffer, unsigned long size){

unsigned long inthispart, toread, read, totalread=0, reminder=0;unsigned long pp=0;

whi le(size>0) {inthispart = (partsize[curpart]-curfilepos());toread = min(size,inthispart);read = fread(((char*)buffer)+pp,1,toread,parts[curpart]);size-=read;totalread+=read;pp+=read;i f (size>0) {

i f (read==toread) {i f (!GotoNextPart( f a l s e)) {_eof= t rue;break;

}} e l s e {_eof= t rue;break;

}}

}

re turn totalread;}

unsigned long splitFile::read(void * buffer, unsigned long size,unsigned long count)

{unsigned long read, totalread=0;unsigned long pp=0;

whi le(count>totalread) {read = readbytes(((char*)buffer)+pp,size);pp+=read;i f (read!=size) break; //eoftotalread++;

}

re turn totalread;}

/** splitFile seek takes two unsigned parameters to specify* the position - like read and write.* The two-argument version assumes that the size is 1 byte* (so actually it works like the FILE* seek function)* To specify the seek direction, you can use the optional fourth* parameter and set it to FORWARD or BACKWARD (default is DEFAULDIR,

Page 162: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

150 Chapter B. FHP-Murϕ: the Verifier

see below).* WARNING: by default seeking from SEEK_END assumes backward direction* (i.e. you should not write seek(-5,SEEK_END) to move backward, but* seek(5,SEEK_END)), whileas SEEK_SET and SEEK_CUR assume FORWARDdirection.**/

void splitFile::seek(unsigned long count, i n t from){seek(1,count,from);

}

bool splitFile::seekbytes(unsigned long size, i n t direction, i n t & part, unsigned long& skip){

i n t i;

whi le(size>0) {i f (getpartsize(part)-skip > size) {skip += size;re turn true;

} e l s e {size -= (getpartsize(part)-skip);i f (direction == FORWARD) {

i f (part<maxpart) {skip = 0;part++;

} e l s e {skip = getpartsize(part);re turn f a l s e ;

}} e l s e i f (direction == BACKWARD) {

i f (part>0) {skip = 0;part--;

} e l s e {skip = 0;re turn f a l s e ;}

}}

}

re turn true;}

void splitFile::seek(unsigned long size, unsigned long count, i n t from, i n t direction){

i n t part, i;unsigned long skip=0;bool result= t rue;

i f (from == SEEK_SET) {part=0;i f (direction == DEFAULTDIR) direction=FORWARD;skip=0;

} e l s e i f (from == SEEK_END) {part=maxpart;i f (direction == DEFAULTDIR) direction=BACKWARD;skip=0;

} e l s e { //SEEK_CURpart=curpart;i f (direction == DEFAULTDIR) direction=FORWARD;i f (direction == FORWARD)skip = curfilepos();

e l s eskip = getpartsize(part) - curfilepos();

Page 163: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 151

}

f o r (i=0; (i<count) && result; i++)result = seekbytes(size,direction,part,skip);

curpart=part;

i f (direction == FORWARD) {fseek(parts[curpart],skip,SEEK_SET);

} e l s e i f (direction == BACKWARD) {fseek(parts[curpart],-skip,SEEK_END);

}

_eof= f a l s e;}

/** splitFile tell returns the number of blocks of the sepcified size* that precede the current file pointer. If size is not specified,* the default is 1 byte, so tell acts like the standard ftell* WARNING: if size is too small, the returned value may overflow* WARNING: if the current file pointer is not a multiple of size,* the returned value is rounded at the previous block.**/

unsigned long splitFile::tell(unsigned long size){

unsigned long total=0, skip=0;f o r ( i n t i = 0; i<curpart; i++) {total += (getpartsize(i)+skip) / size;skip = (getpartsize(i)+skip) % size;

}

re turn total+((curfilepos() + skip) / size);}

bool splitFile::eof(){

re turn _eof;}

B.1.15 ADDED FILE MU PROBSTACK.H

...

# i f n d e f PROBSTACK# d e f i n e PROBSTACK

# i n c l u d e "splitFile.h"

s t r u c t state_prob_rule {state _state;double _prob_reach, _prob_f;unsigned _rule;

state_prob_rule (state* s, double p_r, double p_f, unsigned r){_state = *s; _prob_reach=p_r; _prob_f=p_f; _rule=r;}

state_prob_rule () { };};

/****************************************The state stack.

****************************************/c l a s s state_prob_rule_stack{

Page 164: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

152 Chapter B. FHP-Murϕ: the Verifier

# i f d e f HASHCt y p e d e f unsigned long Unsigned32;

#endif

p r o t e c t e d:state_prob_rule* stateArray; /* The actual array. */

/* max total entries (RAM + disk) of stack (equal to the verificationhorizon) */

unsigned long max_active_states;/* index of the top of the stack */unsigned long front;/* size of the stack in RAM */unsigned long size;/* size for the stack cycling */unsigned long size_2;unsigned long num_elts;unsigned disk2stack_cnt, stack2disk_cnt;unsigned long mem_used;

splitFile *paging_file;

v i r t u a l void Stack2Disk();v i r t u a l void Disk2Stack();i n l i n e bool Stack2Disk_needed() {re turn front >= size;};i n l i n e bool Disk2Stack_needed(){ re turn stack2disk_cnt != disk2stack_cnt && front == 0; };

p u b l i c:// initializersstate_prob_rule_stack(unsigned long memory, unsigned long bound);

// destructorv i r t u a l ˜state_prob_rule_stack();

i n l i n e bool isempty(void){ re turn stack2disk_cnt != disk2stack_cnt && front == 0; };

i n l i n e unsigned long NumElts() {re turn num_elts;}

i n l i n e s t a t i c i n t BytesForOneState(void);

// storing and removing elementsv i r t u a l void push(state* e, double p_r, double p_f);v i r t u a l state *pop(double &p_r, double &p_f);v i r t u a l state *reset( long level);v i r t u a l state *top();v i r t u a l double update_prob(double prob);// hyp: this is called after the last popi n l i n e double final_prob() {re turn stateArray[front]._prob_f;};i n l i n e double get_prob() {re turn stateArray[front - 1]._prob_f;};i n l i n e unsigned long memory_used() {re turn mem_used;};

v i r t u a l unsigned NextRuleToTry();v i r t u a l void NextRuleToTry(unsigned r);

// printing routinevoid Print(void);v i r t u a l void print_capacity(void) {};

};

# e n d i f

# i f n d e f _FILTERQUEUE_# d e f i n e _FILTERQUEUE_

s t r u c t state_and_probability_pair {state _state;double _probability;

Page 165: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 153

state_and_probability_pair (state* s, double p){_state = *s; _probability=p;}

state_and_probability_pair () { };};

/****************************************The state queue.

****************************************/c l a s s state_probability_queue{# i f d e f HASHC

t y p e d e f unsigned long Unsigned32;# e n d i f

p r o t e c t e d:state_and_probability_pair* stateArray; /* The actual array. */state_and_probability_pair *table;

c o n s t unsigned long max_active_states; /* max size of queue */unsigned long front; /* index of first active state. */unsigned long rear; /* index of next free slot. */

unsigned long global_rear, global_front;unsigned long num_elts_head, num_elts_tail;unsigned long head_begin, tail_begin;unsigned long head_size, tail_size;

splitFile *paging_file_top, *paging_file_bottom;

bool hashtable_lookup(state_and_probability_pair* &in);void enqueue_commit( state_and_probability_pair* e );

dynBitVec *Full;

unsigned long hashtable_size;unsigned long hashtable_num_elts;

randomGen random;

p u b l i c:// initializersstate_probability_queue( unsigned long mas );

// destructorv i r t u a l ˜state_probability_queue();

// information interfacei n l i n e unsigned long MaxElts( void ) { re turn max_active_states; }unsigned long NumElts( void ){ re turn num_elts_head + num_elts_tail + global_rear +

global_front + hashtable_num_elts; }i n l i n e bool isempty( void );

i n l i n e s t a t i c i n t BytesForOneState( void );i n l i n e s t a t i c i n t BytesForOneState_hashtable( void );

// storing and removing elementsv i r t u a l bool enqueue( state* &e, double p );v i r t u a l state* dequeue( double &prob );v i r t u a l state* top( double &prob );

v i r t u a l void ReclaimFreeSpace();v i r t u a l void QueueEmptyFault();

i n l i n e void CheckTable();

v i r t u a l unsigned NextRuleToTry()// Uli: unsigned short -> unsigned{Error.Notrace("Internal: Getting next rule to try from a state q\

Page 166: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

154 Chapter B. FHP-Murϕ: the Verifier

ueue instead of a state stack.");re turn 0;

}v i r t u a l void NextRuleToTry(unsigned r){Error.Notrace("Internal: Setting next rule to try from a state q\

ueue instead of a state stack.");}

// printing routinevoid Print( void );v i r t u a l void print_capacity( void ){cout << "\t* Capacity of queue for breadth-first search:\n"<< "\t * " << max_active_states << " states in the queue.\n"<< "\t * " << hashtable_size << " states in the cache.\n"<< "\t * Change the constant gPercentActiveStates in mu_prolo\

g.inc\n"<< "\t to increase this, if necessary.\n";

}};

# e n d i f

B.1.16 ADDED FILE MU PROBSTACK.C

...

# i n c l u d e "mu_probstack.h"# i n c l u d e <math.h>

# d e f i n e min(a,b) (((a)<(b))?(a):(b))# d e f i n e max(a,b) (((a)>(b))?(a):(b))

# d e f i n e DBG 0# d e f i n e SPLITFILE_LEN (1024 * 0x100000L) /* 100MB */# d e f i n e SFS_PAGING_FILE "SFS_PAGING_FILE"

char *make_unique_filename(char *basepathname){

s t a t i c char filenamebuffer[500];

//Maybe I can add a random seed...sprintf(filenamebuffer,"%s_%s.swp", basepathname, PROTOCOL_NAME);

re turn filenamebuffer;}

state_prob_rule_stack::state_prob_rule_stack( unsigned long memory,unsigned long bound )

: max_active_states(bound), front(0), disk2stack_cnt(0),stack2disk_cnt(0), num_elts(0), mem_used(0)

{i f (memory >= max_active_states* s i z e o f(state_prob_rule)){size = size_2 = max_active_states;paging_file = NULL;

}e l s e{size = (unsigned)(memory/ s i z e o f(state_prob_rule));i f (size%2 == 1) size--;size_2 = size / 2;

paging_file = new splitFile(SPLITFILE_LEN, f a l s e );

Page 167: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 155

mem_used += s i z e o f(splitFile);

i f ( !(paging_file->open(make_unique_filename(SFS_PAGING_FILE),"w+b")))

Error.Notrace("Internal: Error creating paging file for s_f_s.");}

stateArray = new state_prob_rule[size];mem_used += size* s i z e o f(state_prob_rule);

}

state_prob_rule_stack::˜state_prob_rule_stack(){

d e l e t e[] stateArray;

i f (paging_file != NULL){paging_file->close();

d e l e t e paging_file;}

}

i n tstate_prob_rule_stack::BytesForOneState( void ){

re turn s i z e o f (state_prob_rule);}

voidstate_prob_rule_stack::Print( void ){

unsigned long i;

f o r( i = 0; i < front; i++ )cout << "ProbReach at " << i << ": " << stateArray[i]._prob_reach

<< "\n";}

void state_prob_rule_stack::push(state* e, double p_r, double p_f){

i f (Stack2Disk_needed())Stack2Disk();

stateArray[front]._state = *e;stateArray[front]._prob_reach = p_r;stateArray[front]._prob_f = p_f;stateArray[front]._rule = 0;front++;num_elts++;

}

state *state_prob_rule_stack::pop(double &p_r, double &p_f){

i f (Disk2Stack_needed())Disk2Stack();

front--;p_r = stateArray[front]._prob_reach;p_f = stateArray[front]._prob_f;num_elts--;

re turn &(stateArray[front]._state);}

state* state_prob_rule_stack::top(){

i f (Disk2Stack_needed())Disk2Stack();

re turn &(stateArray[front - 1]._state);}

Page 168: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

156 Chapter B. FHP-Murϕ: the Verifier

void state_prob_rule_stack::Stack2Disk(){stack2disk_cnt++;

paging_file->write(&stateArray[0], s i z e o f(state_prob_rule),size_2);

memmove(stateArray, &stateArray[size_2],size_2* s i z e o f(state_prob_rule));

front = size_2;}

void state_prob_rule_stack::Disk2Stack(){disk2stack_cnt++;

memmove(&stateArray[size_2], stateArray,size_2* s i z e o f(state_prob_rule));

paging_file->seek((stack2disk_cnt - disk2stack_cnt)*s i z e o f(state_prob_rule)*size_2, SEEK_SET);

paging_file->read(stateArray, s i z e o f(state_prob_rule), size_2);paging_file->seek((stack2disk_cnt - disk2stack_cnt)*

s i z e o f(state_prob_rule)*size_2, SEEK_SET);

front = size_2;}

unsigned state_prob_rule_stack::NextRuleToTry(){

i f (Disk2Stack_needed())Disk2Stack();

re turn stateArray[front - 1]._rule;}

void state_prob_rule_stack::NextRuleToTry(unsigned r){

i f (Disk2Stack_needed())Disk2Stack();

stateArray[front - 1]._rule = r;}

/* Assumption: the slot to update corresponds to front - 1 */double state_prob_rule_stack::update_prob(double p){

i f (Disk2Stack_needed())Disk2Stack();

stateArray[front - 1]._prob_f += p;

re turn stateArray[front - 1]._prob_f;}

state *state_prob_rule_stack::reset( long level){

i f (stack2disk_cnt != disk2stack_cnt){

f o r ( long i = level - 1; i >= -1; i--){

i f (Disk2Stack_needed())Disk2Stack();

front--;num_elts--;}

}e l s e

Page 169: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 157

{front -= level + 1;num_elts -= level + 1;

}re turn &(stateArray[front]._state);

}

# d e f i n e min(a,b) (((a)<(b))?(a):(b))# d e f i n e max(a,b) (((a)>(b))?(a):(b))

# d e f i n e DBG 0# d e f i n e SPLITFILE_LEN (1024 * 0x100000L) /* 100MB */# d e f i n e SFS_PAGING_FILE "SFS_PAGING_FILE"

# i f d e f MAX_HT_CHAIN_LENGTH# undef MAX_HT_CHAIN_LENGTH# e n d i f# d e f i n e MAX_HT_CHAIN_LENGTH 20

# d e f i n e SFQ_PAGING_FILE_TOP "SFQ_PAGING_FILE_1"# d e f i n e SFQ_PAGING_FILE_BOTTOM "SFQ_PAGING_FILE_2"# d e f i n e SSQ_PAGING_FILE_TOP "SSQ_PAGING_FILE_1"# d e f i n e SSQ_PAGING_FILE_BOTTOM "SSQ_PAGING_FILE_2"# d e f i n e SFQ_HISTORY_FILE "SFQ_HISTORY_FILE"

state_probability_queue::state_probability_queue(unsigned long mas): max_active_states((unsigned long)(mas * gPercentActiveStates)){

stateArray = new state_and_probability_pair[ max_active_states];

hashtable_size = NextPrime((unsigned long)mas);

table = new state_and_probability_pair[hashtable_size];

Full = new dynBitVec(hashtable_size);

paging_file_top = new splitFile(SPLITFILE_LEN, f a l s e);paging_file_bottom = new splitFile(SPLITFILE_LEN, f a l s e );

i f (!(paging_file_top->open(make_unique_filename(SFQ_PAGING_FILE_TOP), "w+b"))) {

Error.Notrace( "Internal: Error creating top paging file for s_f\_q.");}

i f (!(paging_file_bottom->open(make_unique_filename(SFQ_PAGING_FILE_BOTTOM),"w+b"))) {

Error.Notrace( "Internal: Error creating bottom paging file.");}

num_elts_head = num_elts_tail = 0;

head_begin = 0;tail_begin = max_active_states/2;

head_size = max_active_states/2;tail_size = max_active_states - head_size;

global_front=global_rear=front=rear=0;}

state_probability_queue::˜state_probability_queue(){

d e l e t e[] stateArray;d e l e t e[] table;d e l e t e Full;

paging_file_top->close(); //rmtmp();paging_file_bottom->close(); //rmtmp();

Page 170: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

158 Chapter B. FHP-Murϕ: the Verifier

d e l e t e paging_file_top;d e l e t e paging_file_bottom;

}

bool state_probability_queue::isempty( void ){

re turn (num_elts_head + num_elts_tail + global_rear +global_front + hashtable_num_elts) == 0;

}

i n tstate_probability_queue::BytesForOneState( void ) {

re turn s i z e o f(state_and_probability_pair);}

i n tstate_probability_queue::BytesForOneState_hashtable( void ) {

re turn s i z e o f(state_and_probability_pair);}

voidstate_probability_queue::Print( void ){

unsigned long i;

f o r( i = 0; i < num_elts_head; i++ ){// convert to print in unsigned long format?cout << "State " << i << " [" << head_begin+i << "]:\n";stateArray[ head_begin+i ]._state.print();}

f o r( i = 0; i < num_elts_tail; i++ ){// convert to print in unsigned long format?cout << "State " << i << " [" << tail_begin+i << "]:\n";stateArray[ tail_begin+i ]._state.print();}

}

boolstate_probability_queue::enqueue( state*& e, double p ){

i f (hashtable_num_elts >= hashtable_size) CheckTable();

state_and_probability_pair pair(e,p);state_and_probability_pair *ppair = &pair;

i f (!hashtable_lookup(ppair)) {ppair->_probability = p;e = &(ppair->_state);re turn true;

} e l s e {ppair->_probability+=p;e = &(ppair->_state);re turn f a l s e;

}}

voidstate_probability_queue::enqueue_commit(state_and_probability_pair

*e){

i f ( num_elts_tail >= tail_size ){//memory full: reclaim more space by swapping out the current//queueReclaimFreeSpace();

}

Page 171: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 159

/*at this point, ReclaimFreeSpace has obtained new space in thequeue and set the offsets (front, rear, ...) accordingly; so weproceed with the insertion without checking...

*/

stateArray[ tail_begin + rear ] = *e;rear++;num_elts_tail++;

}

state*state_probability_queue::dequeue( double &prob ){state* retval;

i f ( num_elts_head <= 0 ){QueueEmptyFault();

}

retval = &(stateArray[head_begin + front]._state);prob = stateArray[head_begin + front]._probability;

front++;num_elts_head--;

re turn retval;}

state*state_probability_queue::top( double &prob ){

i f ( num_elts_head <= 0 ){QueueEmptyFault();

}

prob = stateArray[head_begin + front]._probability;re turn &(stateArray[head_begin + front]._state);

}

void state_probability_queue::ReclaimFreeSpace(){global_rear += paging_file_bottom->write(&stateArray[tail_begin],

s i z e o f(state_and_probability_pair),tail_size);

num_elts_tail = 0;rear = 0;

}

void state_probability_queue::QueueEmptyFault(){//make sure we do not read garbage after the statessize_t read = paging_file_top->read(&stateArray[head_begin],

s i z e o f(state_and_probability_pair),min(global_front,head_size));

i f (read>0) { //ok, some states are swapped innum_elts_head = read;global_front -= read;

} e l s e i f (global_rear>0) {//paging_file_top is empty, but paging_file_bottom is not

splitFile *fswap;

//swap filesfswap= paging_file_top;paging_file_top = paging_file_bottom;

paging_file_bottom = fswap;

Page 172: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

160 Chapter B. FHP-Murϕ: the Verifier

//move to the beginning of the queuepaging_file_top->seek(0,SEEK_SET);paging_file_bottom->seek(0,SEEK_SET); //reset bottom queue

global_front = global_rear;global_rear = 0; //bottom file is empty

//now bottom entries are top entries and bottom file is empty.//Reload a block!size_t read = paging_file_top->read(&stateArray[head_begin],

s i z e o f(state_and_probability_pair),min(global_front,head_size));

num_elts_head = read;global_front -= read;

} e l s e i f (num_elts_tail >0){//paging_file_top AND paging_file_bottom are empty

/* the disk queue is ended. this means that the only stateswe have to explore are the ones in the current tail window */

unsigned long swap = tail_begin;tail_begin = head_begin;head_begin = swap;

swap=tail_size;tail_size = head_size;head_size = swap;

num_elts_head = num_elts_tail;num_elts_tail = 0;rear =0;

} e l s e {//no more states in both swap files, and the memory is empty://why do we call again?Error.Notrace( "Internal: Attempt to read an empty state queue.");

}

front = 0;}

boolstate_probability_queue::hashtable_lookup(state_and_probability_pair

*&in){

unsigned long key = in->_state.hashkey();unsigned long h1 = key % hashtable_size;unsigned long h2 = 1 + key % ( hashtable_size - 1 );unsigned long h = h1;

unsigned long probe = 0;// no hash compaction, uses double hashing

bool empty, equal= FALSE;

whi le ( !(empty = (Full->get(h) == 0)) &&!(equal = ( in->_state == table[h]._state )) &&( probe < MAX_HT_CHAIN_LENGTH ) )

{h = (h1 + probe * h2) % hashtable_size; // double hashingprobe++;

}i f (empty) /* Go ahead and insert the element. */{

table[h] = *in;in = &table[h];Full->set(h);hashtable_num_elts++;

Page 173: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 161

re turn FALSE;}e l s e i f (equal){in = &table[h];

re turn TRUE;}e l s e{//table is full,clear it!CheckTable();//the table now is empty: use the first slot available for//this stateh = h1 % hashtable_size;

table[h] = *in;in = &table[h];Full->set(h);hashtable_num_elts++;

re turn FALSE;}

re turn FALSE;}

void state_probability_queue::CheckTable(){//1. move all the table states in the queue

unsigned long moved=0;unsigned long i;

f o r (i=0 ; i< hashtable_size; i++) {i f (Full->get(i)==1) {enqueue_commit(&table[i]);moved++; //for dbg only

}}

//2. clear the table

Full->clearall();hashtable_num_elts=0;

}

B.1.17 MODIFICATIONS TO MU SYSTEM.H

...

c l a s s StateManager{state_set *the_states; // the set of states found.state_probability_queue *queue; // the queue for active states.state_prob_rule_stack *stack; // the stack for active states.unsigned long NumStates;

double harmonic(double n); // return harmonic number H_n

// Uli: for omission probability calculationlong statesCurrentLevel; // number of states in the level that

// is currently expandedlong statesNextLevel; // number of states in the next levellong currentLevel; // level that is currently expanded

// (startstates: level 0)

Page 174: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

162 Chapter B. FHP-Murϕ: the Verifier

double pno; // Pr(particular state not omitted)unsigned long num_elts; // number of states enququed so far

// (substitutes the_states->NumElts())

p u b l i c:StateManager(double , unsigned long, unsigned);˜StateManager();

// the cache for already computed subformulas probabilitiesaux_cache *subf_cache;unsigned Add(state * s, double p, bool valid, bool permanent);bool QueueIsEmpty();state * QueueTop(double &);state *QueueDequeue(double&, double&);state *QueueDequeue(double&);void QueuePush(state *, double , double);state * ResetQueue( long);double QueueUpdateProb(double);double QueueFinalProb();double QueueGetProb();unsigned NextRuleToTry(); // Uli: unsigned short -> unsignedvoid NextRuleToTry(unsigned r);

// Uli: routines for omission probability calculation & printingi n t CheckLevel();void PrintProb();

void print_capacity();void print_all_states();void print_trace(StatePtr p); // changes by Ulivoid print_trace_aux(StatePtr p);unsigned long NumElts();void IncrNumElts();unsigned long NumEltsReduced(); // Uliunsigned long QueueNumElts() {re turn queue->NumElts();}long GetCurrentLevel() {re turn currentLevel;}

};

// extern class StartStateGenerator;c l a s s StartStateGenerator;

/************************************************************/c l a s s StartStateManager{

s t a t i c unsigned s h o r t numstartstates;unsigned s h o r t what_startstate; // for info at ErrorStartStateGenerator * generator;randomGen random; // Uli: random number generator

p u b l i c:StartStateManager();state * RandomStartState();unsigned AllStartStates();state * NextStartState();state * StartState();char * LastStateName();// probabilistic counterpart of LastStateName()double LastStateProb();char * StateName(StatePtr p); // changes by Uli

};

// extern class NextStateGenerator;c l a s s NextStateGenerator;

/************************************************************/c l a s s RuleManager{

double what_prob; // probabilistic counterpart of what_ruleunsigned long rules_fired;

Page 175: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 163

unsigned long * NumTimesFired; /* array for storing the numberof times fired for each rule */

unsigned AllNextStates(setofrules * fire);randomGen random; // Uli: random number generator

unsigned what_rule; // for execution and info at ErrorNextStateGenerator * generator;

p u b l i c:RuleManager();˜RuleManager();state * RandomNextState();/* moved to the public part */setofrules * EnabledTransition();state * NextState();/* moved to the public part */state * SeqNextState(double&);unsigned AllNextStates();void ResetRuleNum();void SetRuleNum(unsigned r);void IncRuleNum();unsigned GetRuleNum();char * LastRuleName();// probabilistic counterpart of LastRuleName()double LastRuleProb();unsigned long NumRulesFired();void print_rules_information();void print_world_to_state(StatePtr p, bool fullstate);// changes by Uli

};

/************************************************************/c l a s s PropertyManager{

unsigned s h o r t what_invariant; // for info at Errorp u b l i c:PropertyManager();bool CheckInvariants();char * LastInvariantName();

};

/************************************************************/c l a s s SymmetryManager{state_set *debug_sym_the_states; // the set of states found withoutsym.

p u b l i c:SymmetryManager();

};

/************************************************************/c l a s s POManager // Partial Order{rule_matrix *conflict_matrix;

p u b l i c:POManager();

};

/************************************************************/c l a s s AlgorithmManager{p r i v a t e:

bool verify_bpmc_rec(state *, c o n s t pctlformrec *);bool evalX(state *, c o n s t pctlformrec *);bool evalU(state *, c o n s t pctlformrec *);i n t NumberUntil(c o n s t pctlformrec *, i n t);unsigned stack_size(c o n s t pctlformrec *);double update_prob_loc(bool , double , double);

Page 176: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

164 Chapter B. FHP-Murϕ: the Verifier

bool may_exit(c o n s t pctlformrec *, double , long);double fin_prob;

p u b l i c:AlgorithmManager();˜AlgorithmManager();// Added AlgorithmManager destructorvoid verify_bfs();void verify_dfs();void simulate();void verify_bpmc();bool IsSafety();

};

/************************************************************/// manager for all startstate related operationStartStateManager *StartState;// manager for all rule related operationRuleManager *Rules;// manager for all property related operationPropertyManager *Properties;// manager for all state related informationStateManager *StateSet;// manager for all symmetry informationSymmetryManager *Symmetry;// manager for all symmetry informationPOManager *PO;// manager for all diagnostic messagesReportManager *Reporter;// manager for all algorithm related issueAlgorithmManager *Algorithm;

// general error handler.Error_handler Error;// the record of the arguments.argclass *args;// current state at the beginning of the rule-firingstate *curstate;// probability of curstate at the beginning of the rule-firingdouble curstate_p;// probability for error statedouble E_p = 0;

// Uli: buffer for doing all state manipulationstate *c o n s t workingstate = new state;

// the set of global variables.world_class theworld;// working on startstate, rule or invarianti n t category;

# i f d e f HASHC// Uli: manager for trace info fileTraceFileManager* TraceFile;# e n d i f// Uli: number of the current state for trace info fileunsigned long NumCurState;

B.1.18 MODIFICATIONS TO MU SYSTEM.C

...

/************************************************************//* StateManager *//************************************************************/StateManager::StateManager(double fraction, unsigned long memory,

Page 177: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 165

unsigned horizon): NumStates(0), stack(NULL){

i f (args->safety.value) {NumStates = memory;queue = new state_probability_queue(NumStates);stack = NULL;

} e l s e {/* horizon is the number of transitions, here we need the number

of states */stack = new state_prob_rule_stack((unsigned long)

(fraction*memory), horizon+1);subf_cache = new aux_cache(memory - stack->memory_used(),

4*horizon);queue = NULL;

}}

StateManager::˜StateManager(){

i f (stack != NULL){

d e l e t e stack;d e l e t e subf_cache;

}i f (queue != NULL) d e l e t e queue;

}

unsigned StateManager::Add(state * s, double p, bool valid,bool permanent)

{i f (Properties->CheckInvariants()) {E_p += p;/* even if the max depth has not been reached, there cases in

which we can terminate */i f ( (mu_pctl_formula.ord == PCTL_G &&

E_p > mu_pctl_formula.prob_bound)|| (mu_pctl_formula.ord == PCTL_GEQ &&

E_p >= mu_pctl_formula.prob_bound))re turn 5; /* formula is valid, level not completed */

e l s ei f ( (mu_pctl_formula.ord == PCTL_L &&

E_p >= mu_pctl_formula.prob_bound)|| (mu_pctl_formula.ord == PCTL_LEQ &&

E_p > mu_pctl_formula.prob_bound))re turn 6; /* formula is not valid, level not completed */

re turn 0; //state not added}

bool notpresent = queue->enqueue(s,p);

i f (notpresent) {num_elts++;

i f ( args->trace_all.value ) Reporter->print_trace_all();

statesNextLevel++;Reporter->print_progress(currentLevel);re turn 1;

} e l s e re turn 0;}

bool StateManager::QueueIsEmpty(){

i f (stack)re turn stack->isempty();

e l s ere turn queue->isempty();

}

Page 178: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

166 Chapter B. FHP-Murϕ: the Verifier

state * StateManager::QueueTop(double &p){

i f (stack)re turn stack->top();

e l s ere turn queue->top(p);

}

state *StateManager::QueueDequeue(double &p_r, double &p_f){

re turn stack->pop(p_r, p_f);}

state *StateManager::QueueDequeue(double &p){

re turn queue->dequeue(p);}

state *StateManager::ResetQueue( long level){stack->reset(level);

}

void StateManager::QueuePush(state *s, double p_r, double p_f){

re turn stack->push(s, p_r, p_f);}

double StateManager::QueueFinalProb(){

re turn stack->final_prob();}

double StateManager::QueueGetProb(){

re turn stack->get_prob();}

// Uli: unsigned short -> unsignedunsigned StateManager::NextRuleToTry(){

re turn stack->NextRuleToTry();}

void StateManager::NextRuleToTry(unsigned r){stack->NextRuleToTry(r);

}

double StateManager::QueueUpdateProb(double p){

re turn stack->update_prob(p);}

# i n c l u d e <math.h>

double StateManager::harmonic(double n)// return harmonic number H_n{

re turn (n<1) ? 0 :log(n) + 0.577215665 + 1/(2*n) - 1/(12*n*n);

}

// check if we are done with the level currently expandedi n t StateManager::CheckLevel(){

i f (--statesCurrentLevel <= 0)// all the states of the current level have been expanded{//filter the level states & load the queue

Page 179: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 167

queue->CheckTable();

// proceed to next levelstatesCurrentLevel = statesNextLevel;statesNextLevel = 0;

// check if there are states in the following leveli f (statesCurrentLevel!=0){currentLevel++;i f (currentLevel > mu_pctl_formula.until_bound) {// stop exploration

i f ( (mu_pctl_formula.ord == PCTL_G &&E_p > mu_pctl_formula.prob_bound)

|| (mu_pctl_formula.ord == PCTL_GEQ &&E_p >= mu_pctl_formula.prob_bound)

|| (mu_pctl_formula.ord == PCTL_L &&E_p < mu_pctl_formula.prob_bound)

|| (mu_pctl_formula.ord == PCTL_LEQ &&E_p <= mu_pctl_formula.prob_bound))

re turn 3; /* formula is valid */e l s e

re turn 4; /* formula is not valid */}

}Reporter->print_progress(currentLevel, args->fpel.value, t rue);

}re turn 0;

} /* CheckLevel() */

# i f d e f HASHCvoid StateManager::PrintProb(){}

# e n d i f

void StateManager::print_capacity(){}

void StateManager::print_all_states(){}

unsigned long StateManager::NumElts(){

i f (stack)re turn NumStates;

e l s ere turn num_elts; //gdp

}

void StateManager::IncrNumElts(){NumStates++;

}

unsigned long StateManager::NumEltsReduced(){

re turn num_elts - (queue->NumElts() + statesNextLevel); //gdp}

void StateManager::print_trace_aux(StatePtr p) // changes by Uli{}

void StateManager::print_trace(StatePtr p){}

Page 180: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

168 Chapter B. FHP-Murϕ: the Verifier

/************************************************************//* StartStateManager *//************************************************************/StartStateManager::StartStateManager(){generator = new StartStateGenerator;

}

state *StartStateManager::RandomStartState(){what_startstate = (unsigned s h o r t)(random.n e x t()%numstartstates);re turn StartState();

}

unsignedStartStateManager::AllStartStates(){state *nextstate = NULL;double sop = (double)0; // sum of probability of startstatesunsigned ret;

f o r (what_startstate=0; what_startstate < numstartstates;what_startstate++)

{sop += startstates[what_startstate].prob_bound;nextstate = StartState();// nextstate points to internal data at theworld.getstate()i f ((ret = StateSet->Add(nextstate,

startstates[what_startstate].prob_bound,FALSE, TRUE)) > 1)

re turn ret;}i f (fabsl(sop - (double)1) >= 10*DBL_EPSILON)Error.Error("Sum of probability of start states is equal to %le.",sop);

re turn 0;}

state *StartStateManager::NextStartState(){

s t a t i c i n t next_startstate=0;i f (next_startstate >= numstartstates) re turn NULL;what_startstate = next_startstate++;re turn StartState();

}

state *StartStateManager::StartState(){state *next_state = NULL;

category = STARTSTATE;

// preparationtheworld.reset();

// fire state rulegenerator->Code(what_startstate);

// print verbose messagei f (args->verbose.value > 4 || args->use_verbose_from_state.value)Reporter->print_fire_startstate();

// Uli: invariant check moved

// Uli: mark as startstateworkingstate->previous.clear();

Page 181: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 169

re turn workingstate;}

char *StartStateManager::LastStateName(){

re turn generator->Name(what_startstate);}

doubleStartStateManager::LastStateProb(){

re turn startstates[what_startstate].prob_bound;}

char *StartStateManager::StateName(StatePtr p){state nextstate;i f (!p.isStart())Error.Notrace("Internal: Cannot find startstate name for non sta\

rtstate");f o r(what_startstate=0; what_startstate < numstartstates;what_startstate++)

{StartState();StateCopy(&nextstate, workingstate);

i f (StateEquivalent(&nextstate, p))re turn LastStateName();

}

Error.Notrace("Internal: Cannot find startstate name for funny st\artstate");

re turn NULL;}

/************************************************************//* RuleManager *//************************************************************/RuleManager::RuleManager() : rules_fired(0){NumTimesFired = new unsigned long [RULES_IN_WORLD];generator = new NextStateGenerator;

// initialize check timesfiredf o r ( i n t i=0; i<RULES_IN_WORLD; i++)NumTimesFired[i]=0;

};

RuleManager::˜RuleManager(){

d e l e t e[ OLD_GPP(RULES_IN_WORLD) ] NumTimesFired;}

voidRuleManager::ResetRuleNum(){what_rule = 0;

}

voidRuleManager::SetRuleNum(unsigned r){what_rule = r;

}

unsignedRuleManager::GetRuleNum(){

re turn what_rule;

Page 182: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

170 Chapter B. FHP-Murϕ: the Verifier

}

voidRuleManager::IncRuleNum(){what_rule++;

}

state *RuleManager::SeqNextState(double &nextprob){state * ret;

i f (!args->state_compr.value){//get the current rule number from the stackwhat_rule = StateSet->NextRuleToTry();//starting from what_rule, finds the next valid rule index (could//be also the current one)generator->SetNextEnabledRule(what_rule, nextprob);i f ( what_rule<numrules ){ret = NextState();//set the next rule number on the stackStateSet->NextRuleToTry(what_rule+1);re turn ret;

}e l s e

re turn NULL;}e l s e{

bool *what_rules = new bool[numrules];unsigned num_found = 0;unsigned to_be_found = StateSet->NextRuleToTry();double nextprob_sum;// buffer for workingstates t a t i c state *originalstate = new state;// state to be compareds t a t i c state *st_to_be_cmprd = new state;

f o r (unsigned i = 0; i < numrules; i++)what_rules[i] = f a l s e;

// make copy of workingstateStateCopy(originalstate, workingstate);f o r (what_rule = 0, generator->SetNextEnabledRule(what_rule,

nextprob);what_rule < numrules && num_found != to_be_found + 1;what_rule++,generator->SetNextEnabledRule(what_rule, nextprob))

{i f (!what_rules[what_rule]){

unsigned what_rule_tmp = what_rule;

i f (num_found == to_be_found)nextprob_sum = nextprob;

what_rules[what_rule] = t rue;ret = NextState();StateCopy(st_to_be_cmprd, ret);

// restore workingstateStateCopy(workingstate, originalstate);f o r (what_rule++, generator->SetNextEnabledRule(what_rule,

nextprob);what_rule < numrules;what_rule++,generator->SetNextEnabledRule(what_rule, nextprob))

{

Page 183: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 171

i f (!what_rules[what_rule]){ret = NextState();i f (StateCmp(ret, st_to_be_cmprd) == 0){what_rules[what_rule] = t rue;i f (num_found == to_be_found)nextprob_sum += nextprob;

}// restore workingstate

StateCopy(workingstate, originalstate);}

}what_rule = what_rule_tmp;num_found++;}

}i f (num_found != to_be_found + 1)ret = NULL;

e l s e{StateCopy(ret, st_to_be_cmprd);nextprob = nextprob_sum;

}StateSet->NextRuleToTry(to_be_found + 1);d e l e t e [] what_rules;re turn ret;

}}

state *RuleManager::RandomNextState(){

unsigned PickARule;setofrules ret;s t a t i c state *originalstate = new state;i n t i;double sop = 0.0;

// save workingstateStateCopy(originalstate, workingstate);

category = CONDITION;

what_prob = 0.0;

ret.removeall();

// record what kind of analysis is currently carried outcategory = CONDITION;

// get enabledf o r ( what_rule=0, i=0; what_rule<numrules; what_rule++){generator->SetNextEnabledRule(what_rule, what_prob);i f ( what_rule<numrules ) {cout << "Rule " << i++ << " with probability " << what_prob

<< endl;ret.add(what_rule, what_prob);sop += what_prob;

}}i f (fabsl(sop - (double)1) >= 10*DBL_EPSILON) {cout << "Sum of probabilities is " << sop << endl;exit(1);

}

cout << "Give a number between 0 and " << ret.size() - 1<< ": ";

cout.flush();

Page 184: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

172 Chapter B. FHP-Murϕ: the Verifier

scanf("%u", &PickARule);what_rule = ret.getnthrule(PickARule);what_prob = ret.prob(what_rule);category = RULE;generator->Code(what_rule);curstate = workingstate;

rules_fired++;

// print verbose messagei f (!args->full_trace.value)Reporter->print_fire_rule_diff(originalstate, what_prob);

e l s e Reporter->print_fire_rule(what_prob);

re turn curstate;}

unsignedRuleManager::AllNextStates(){setofrules * fire;

// get set of rules to firefire = EnabledTransition();

// generate the set of next statesre turn AllNextStates(fire);

}

/****************************************checks probability sum to be 1, and returnsnext states

****************************************/setofrules *RuleManager::EnabledTransition(){

s t a t i c setofrules ret;i n t p; // Priority of the current rule

# i f n d e f PROBEQUALKdouble sop = (double)0; // sum of probability of active transitions

# e n d i f

ret.removeall();

// record what kind of analysis is currently carried outcategory = CONDITION;

// get enabledf o r ( what_rule=0; what_rule<numrules; what_rule++){

# i f n d e f PROBEQUALKgenerator->SetNextEnabledRule(what_rule, what_prob);

# e l s egenerator->SetNextEnabledRule(what_rule);

# e n d i fi f ( what_rule<numrules ) {

# i f n d e f PROBEQUALKret.add(what_rule, what_prob);sop += what_prob;

# e l s eret.add(what_rule);

# e n d i f}

}# i f n d e f PROBEQUALK

i f (fabsl(sop - (double)1) >= 10*DBL_EPSILON){printf("Starting from state\n");theworld.print();Error.Error("Sum of probability of active transitions is equal to\

Page 185: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 173

%le.",sop);}

# e n d i fre turn &ret;

}

// Uli: corrected a memory-leak, improved performanceunsignedRuleManager::AllNextStates(setofrules * fire){// buffer for workingstates t a t i c state * originalstate = new state;state * nextstate;unsigned ret = 0;

// make copy of workingstateStateCopy(originalstate, workingstate);

f o r ( what_rule=0; what_rule<numrules; what_rule++){

i f (fire->in(what_rule)){/* save rule probability BEFORE updating the current state in

NextState(). This is needed since the probability of a rulecan be a function of the verifier state!

*/# i f n d e f PROBEQUALK

what_prob = fire->prob(what_rule);# e l s e

what_prob = ((double)1)/fire->size();# e n d i f

//get the state reached by the rule what_rulenextstate = NextState();

i f ((ret = StateSet->Add(nextstate, curstate_p* what_prob, TRUE,TRUE)) > 1)

re turn ret;// restore workingstateStateCopy(workingstate, originalstate);

}}re turn ret;

}

// the following global variables have been set:// theworld, curstate and what_rulestate *RuleManager::NextState(){

category = RULE;

// fire rulegenerator->Code(what_rule);rules_fired++;

// update timesfired recordNumTimesFired[what_rule]++;

// print verbose messagei f (args->verbose.value > 4 || (args->use_verbose_from_state.value

&& StateSet->NumElts() >= args->verbose_from_state.value))Reporter->print_fire_rule();

// get next state# i f d e f HASHC

i f (args->trace_file.value)workingstate->previous.set(NumCurState);

e l s e

Page 186: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

174 Chapter B. FHP-Murϕ: the Verifier

# e n d i fworkingstate->previous.set(curstate);

re turn workingstate;}

voidRuleManager::print_world_to_state(StatePtr p, bool fullstate){}

char *RuleManager::LastRuleName(){

re turn generator->Name(what_rule);}

doubleRuleManager::LastRuleProb(){

re turn what_prob;}

unsigned long RuleManager::NumRulesFired(){

re turn rules_fired;}

voidRuleManager::print_rules_information(){

bool exist;

i f (args->print_rule.value){

cout << "Rules Information:\n\n";f o r ( i n t i=0; i<RULES_IN_WORLD; i++)

cout << "\tFired " << NumTimesFired[i] << " times\t- Rule \""<< generator->Name(i)<< "\"\n";

}e l s e{

f o r ( i n t i=0; i<RULES_IN_WORLD; i++)i f (NumTimesFired[i]==0)exist = TRUE;i f (exist)

cout << "Analysis of State Space:\n\n"<< "\tThere are rules that are never fired.\n";

}}

/************************************************************//* PropertyManager *//************************************************************/PropertyManager::PropertyManager(){}

boolPropertyManager::CheckInvariants(){

re turn mu_pctl_formula.subf2->condition();}

char *PropertyManager::LastInvariantName(){

re turn "";}

Page 187: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 175

/************************************************************//* SymmetryManager *//************************************************************/SymmetryManager::SymmetryManager(){}

/************************************************************//* POManager *//************************************************************/POManager::POManager(){}

/************************************************************//* AlgorithmManager *//************************************************************/AlgorithmManager::AlgorithmManager(){// create managersStartState = new StartStateManager;Rules = new RuleManager;Reporter = new ReportManager;

# i f d e f HASHCh3 = new hash_function(BLOCKS_IN_WORLD);

# e n d i f

Reporter->CheckConsistentVersion();i f (args->main_alg.mode!=argmain_alg::Nothing)Reporter->print_header();

Reporter->print_algorithm();

i f (!args->simulate_prob.value && args->safety.value) {StateSet = new StateManager(0.0,

NumStatesGivenBytes(args->mem.value),0);

StateSet->print_capacity();} e l s e {StateSet = NULL;

}

Reporter->print_warning();

signal(SIGFPE, &catch_div_by_zero);

fin_prob = -1;};

// Added AlgorithmManager destructorAlgorithmManager::˜AlgorithmManager(){

d e l e t e StartState;d e l e t e Rules;d e l e t e Reporter;

# i f d e f HASHCd e l e t e h3;

# e n d i f

i f (StateSet != NULL) d e l e t e StateSet;};

/****************************************The BFS verification main routines:void verify_bfs_standard()-- future extension:-- void verify_bfs_gode_dl()-- void verify_bfs_sleepset_rr()

Page 188: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

176 Chapter B. FHP-Murϕ: the Verifier

-- void verify_bfs_gode_sleepset_dl()****************************************/

voidAlgorithmManager::verify_bfs(){// Use Global Variables: what_rule, curstate, theworld, queue,// the_statessetofrules fire; // set of rule to be firedunsigned ret;i n t clres;

// print verbose messagei f (args->verbose.value || args->verbose_from_state.value)Reporter->print_verbose_header();

cout.flush();

theworld.to_state(NULL); // trick : marks variables in world

// Generate all start statei f (ret = StartState->AllStartStates())clres = ret;

e l s e {

// level monitoringStateSet->CheckLevel();

// search state spacewhi le (!StateSet->QueueIsEmpty()){// get and remove a state from the queue// please make sure that global variable curstate does not change// throughout the iterationcurstate = StateSet->QueueDequeue(curstate_p);NumCurState++;StateCopy(workingstate, curstate);

// print verbose messagei f (args->verbose.value || args->use_verbose_from_state.value)Reporter->print_curstate();

// generate all next statei f ((clres = Rules->AllNextStates()) > 1)break;

// omission probability calculation and level monitoringi f ( (clres = StateSet->CheckLevel()) != 0)/* stop visit */

break;} // while

} // elseprintf("The probability of the formula is %.10lg\n", E_p);Reporter->print_final_report(clres);

}

/****************************************The DFS verification routine:void verify_dfs()-- not changed yet****************************************/

voidAlgorithmManager::verify_dfs(){}

bool AlgorithmManager::IsSafety(){

re turn (mu_pctl_formula.subf2 &&mu_pctl_formula.subf2->type == AP_PCTL &&

Page 189: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 177

mu_pctl_formula.subf1 &&mu_pctl_formula.subf1->type == AP_PCTL);

}

/****************************************The BPMC main verification routine:void verify_bpmc()****************************************/

void AlgorithmManager::verify_bpmc(){// print verbose messagei f (args->verbose.value > 4) Reporter->print_verbose_header();

theworld.to_state(NULL); // trick : marks variables in world

curstate = StartState->NextStartState(); //only one allowedfin_prob = -1;bool result = verify_bpmc_rec(curstate, &mu_pctl_formula);i f (fin_prob != -1)printf("The probability of the formula is %.10lg\n", fin_prob);

i f (result)Reporter->print_final_report(3);

e l s eReporter->print_final_report(4);

}

/****************************************The BPMC recursive verification routine:void verify_bpmc_rec()****************************************/

bool AlgorithmManager::verify_bpmc_rec(state *s,c o n s t pctlformrec *f)

{swi tch(f->type){

case AP_PCTL :StateCopy(workingstate, s);re turn f->condition();case AND_PCTL :re turn (verify_bpmc_rec(s, f->subf1) &&

verify_bpmc_rec(s, f->subf2));case OR_PCTL :re turn (verify_bpmc_rec(s, f->subf1) ||

verify_bpmc_rec(s, f->subf2));case IMPL_PCTL :re turn (!verify_bpmc_rec(s, f->subf1) ||

verify_bpmc_rec(s, f->subf2));case NOT_PCTL :re turn (!verify_bpmc_rec(s, f->subf1));case NEXT_PCTL :re turn (evalX(s, f));case UNTIL_PCTL :re turn (evalU(s, f));d e f a u l t :Error.Notrace("Internal error: invalid value %d for f->type",f->type);

re turn FALSE;}

}

bool AlgorithmManager::evalX(state *s, c o n s t pctlformrec *f){setofrules * fire;

StateCopy(workingstate, s);fire = Rules->EnabledTransition();

// buffer for workingstate

Page 190: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

178 Chapter B. FHP-Murϕ: the Verifier

s t a t i c state * originalstate = new state;state * nextstate;

// make copy of workingstateStateCopy(originalstate, workingstate);

double sum = 0.0;f o r (Rules->ResetRuleNum(); Rules->GetRuleNum() < numrules;

Rules->IncRuleNum()){

i f (fire->in(Rules->GetRuleNum())){nextstate = Rules->NextState();

i f (verify_bpmc_rec(nextstate, f->subf1))sum += fire->prob(Rules->GetRuleNum());

StateCopy(workingstate, originalstate); // restore workingstate}

}swi tch(f->ord){

case PCTL_L : re turn sum < f->prob_bound;case PCTL_LEQ : re turn sum <= f->prob_bound;case PCTL_G : re turn sum > f->prob_bound;case PCTL_GEQ : re turn sum >= f->prob_bound;d e f a u l t : Error.Notrace("Internal error: invalid value %d for\

f->ord", f->ord); re turn FALSE;}

}

i n t AlgorithmManager::NumberUntil(c o n s t pctlformrec *f, i n t ret){

i f (f->type == UNTIL_PCTL)ret++;

i f (f->subf1 != NULL)ret = NumberUntil(f->subf1, ret);

i f (f->subf2 != NULL)ret = NumberUntil(f->subf2, ret);

re turn ret;}

unsigned AlgorithmManager::stack_size(c o n s t pctlformrec *f){

i f (f->type != AP_PCTL){

unsigned k1 = stack_size(f->subf1);unsigned k2 = f->subf2 != NULL? stack_size(f->subf2) : 0;re turn f->until_bound + (k1 > k2 ? k1 : k2);

}e l s e

re turn 0;}

double AlgorithmManager::update_prob_loc(bool tmp_psi,double globreachprob,double cache_probability)

{double mult;

i f (cache_probability != -1.0)mult = cache_probability;

e l s e i f (!tmp_psi)mult = 0.0;

e l s emult = 1.0;

re turn globreachprob*mult;}

Page 191: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 179

bool AlgorithmManager::may_exit(c o n s t pctlformrec *f,double fin_prob_loc, long level)

{re turn (!args->disable_exit.value &&

(( (f->ord == PCTL_L && fin_prob_loc >= f->prob_bound)|| (f->ord == PCTL_LEQ && fin_prob_loc > f->prob_bound)|| (f->ord == PCTL_G && fin_prob_loc > f->prob_bound)|| (f->ord == PCTL_GEQ && fin_prob_loc >= f->prob_bound)) || (level == 0 &&( (f->ord == PCTL_L && fin_prob >= f->prob_bound)|| (f->ord == PCTL_LEQ && fin_prob > f->prob_bound)|| (f->ord == PCTL_G && fin_prob > f->prob_bound)|| (f->ord == PCTL_GEQ && fin_prob >= f->prob_bound))))

);}

/* It works only if there is only one initial state; the finalprobability of the formula will be put in fin_prob */

bool AlgorithmManager::evalU(state *s, c o n s t pctlformrec *f){

i f (StateSet == NULL){//int number_until = NumberUntil(f, 0);/* fraction of memory to be used for the stack */double fraction = 1.0 - NumberUntil(f, 0)/4.0;//double fraction = 0.7;StateSet = new StateManager((fraction >= 0.5? fraction : 0.5),

args->mem.value, stack_size(f));}state_prob_hor_form s_p_h_f(s, 0.0, f->until_bound, f);//unsigned ht_chain = 5*f->until_bound;bool result;i f (!StateSet->subf_cache->try_to_evaluate(&s_p_h_f, result)){state *nextstate;

curstate = s;StateCopy(workingstate, curstate);

i f (verify_bpmc_rec(curstate, f->subf2))fin_prob = 1.0;

e l s e i f (f->until_bound == 0 ||!verify_bpmc_rec(curstate, f->subf1))

fin_prob = 0.0;e l s e{/* level is a long because it refers to the unsigned

f->until_bound, but may be -1 */long level = 0;double nextprob, globreachprob = 1.0, fin_prob_loc = 0.0;bool tmp_psi, tmp_phi;

StateSet->IncrNumElts();StateSet->QueuePush(s, 1.0, 0.0);

whi le (level >= 0){

double dummy;

curstate = StateSet->QueueTop(dummy);StateCopy(workingstate, curstate);i f (args->ctrl_next.value)(void *)Rules->EnabledTransition();

nextstate = Rules->SeqNextState(nextprob);

Reporter->print_progress(level);

Page 192: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

180 Chapter B. FHP-Murϕ: the Verifier

/* assumption: it is effectively a Markov Chain */

i f (nextstate != NULL){s_p_h_f._state = *nextstate;s_p_h_f._horizon = f->until_bound - level - 1;s_p_h_f._subformula = f;s_p_h_f._probability =StateSet->subf_cache->simple_was_present(&s_p_h_f);

level++;i f (s_p_h_f._probability == -1.0){

i f (!(tmp_psi = verify_bpmc_rec(nextstate, f->subf2)) &&level != f->until_bound)tmp_phi = verify_bpmc_rec(nextstate, f->subf1);

StateSet->QueuePush(nextstate, nextprob, tmp_psi? 1.0 : 0.0);}e l s eStateSet->QueuePush(nextstate, nextprob,s_p_h_f._probability);

/* Alternatively, don’t push and don’t pop below... */globreachprob *= nextprob;

}

i f (nextstate == NULL || s_p_h_f._probability != -1.0 ||level == f->until_bound || tmp_psi || !tmp_phi)

{double formprob, reachprob;

--level;curstate = StateSet->QueueDequeue(reachprob, formprob);fin_prob_loc += update_prob_loc(tmp_psi, globreachprob,

s_p_h_f._probability);globreachprob /= reachprob;i f (level != -1){fin_prob = StateSet->QueueUpdateProb(reachprob*formprob);i f (may_exit(f, fin_prob_loc, level)){curstate = StateSet->ResetQueue(level);StateCopy(workingstate, curstate);/* to restore nextstate */fin_prob = fin_prob_loc;re turn (f->ord == PCTL_G || f->ord == PCTL_GEQ);

}}

s_p_h_f._probability = formprob;s_p_h_f._state = *curstate;s_p_h_f._horizon = f->until_bound - level - 1;s_p_h_f._subformula = f;i f (!StateSet->subf_cache->insert(&s_p_h_f))printf("WARNING: Too small cache size, computation may requi\

re a lot of time\n");tmp_psi = f a l s e; s_p_h_f._probability = -1.0;

}e l s eStateSet->IncrNumElts();

} // whilefin_prob = StateSet->QueueFinalProb();i f (args->verbose.value > 1)printf("\tThe probability of the formula is %.10lg\n",

fin_prob);} // elseswi tch(f->ord){

case PCTL_L : re turn fin_prob < f->prob_bound;

Page 193: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

B.1 C++ Code 181

case PCTL_LEQ : re turn fin_prob <= f->prob_bound;case PCTL_G : re turn fin_prob > f->prob_bound;case PCTL_GEQ : re turn fin_prob >= f->prob_bound;d e f a u l t : Error.Notrace("Internal error: invalid value %d for\

f->ord", f->ord); re turn FALSE;}

} // try_to_evaluate failede l s e re turn result; // try_to_evaluate succeeded

}

/****************************************The simulation main routine:void simulate()****************************************/

// Uli: added required call to theworld.to_state()voidAlgorithmManager::simulate(){// progress report must be printed out so as to make sense// otherwise, if there is no bug, the program just run on for ever// without any message.

// print verbose messagei f (args->verbose.value) Reporter->print_verbose_header();

Reporter->StartSimulation();

theworld.to_state(NULL); // trick: marks variables in world

// GetRandomStartState will choose a Startstate randomlycurstate = StartState->RandomStartState();

// simulatewhi le(1)curstate = Rules->RandomNextState();

}

Page 194: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor
Page 195: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

APPENDIX C

PRISM CODE FOR LQS WITH 10 ENTRIES

In the following we report the PRISM code for the LQS with 10 entries (see Sections 5.4.1 and 5.4.2).

p r o b a b i l i s t i c

c o n s t ITEM_Q = 10;c o n s t ITEM_Q_m_1 = 9;

//exp_f_x_d_y means 1−e−x

y

r a t e exp_f_1_d_4 = 0.15803013970713941960;r a t e exp_f_2_d_4 = 0.21616617919084682702;r a t e exp_f_1_d_5 = 0.12642411176571153568;r a t e exp_f_2_d_5 = 0.17293294335267746162;r a t e exp_f_3_d_5 = 0.19004258632642721140;r a t e exp_f_1_d_6 = 0.10535342647142627973;r a t e exp_f_2_d_6 = 0.14411078612723121801;r a t e exp_f_3_d_6 = 0.15836882193868934283;r a t e exp_f_4_d_6 = 0.16361406018521096995;r a t e exp_f_1_d_7 = 0.09030293697550823977;r a t e exp_f_2_d_7 = 0.12352353096619818687;r a t e exp_f_3_d_7 = 0.13574470451887657957;r a t e exp_f_4_d_7 = 0.14024062301589511710;r a t e exp_f_5_d_7 = 0.14189457900013064755;r a t e exp_f_1_d_8 = 0.07901506985356970980;r a t e exp_f_2_d_8 = 0.10808308959542341351;r a t e exp_f_3_d_8 = 0.11877661645401700712;r a t e exp_f_4_d_8 = 0.12271054513890822746;r a t e exp_f_5_d_8 = 0.12415775662511431661;r a t e exp_f_1_d_9 = 0.07023561764761751982;r a t e exp_f_2_d_9 = 0.09607385741815414534;r a t e exp_f_3_d_9 = 0.10557921462579289522;r a t e exp_f_4_d_9 = 0.10907604012347397996;r a t e exp_f_5_d_9 = 0.11036245033343494810;r a t e exp_f_6_d_9 = 0.11083569420259262684;r a t e exp_f_1_d_10 = 0.06321205588285576784;r a t e exp_f_2_d_10 = 0.08646647167633873081;r a t e exp_f_3_d_10 = 0.09502129316321360570;r a t e exp_f_4_d_10 = 0.09816843611112658197;r a t e exp_f_5_d_10 = 0.09932620530009145329;r a t e exp_f_6_d_10 = 0.09975212478233336415;r a t e exp_f_7_d_10 = 0.09990881180344454838;r a t e exp_f_8_d_10 = 0.09996645373720974881;r a t e a_third = 1/3;r a t e a_fourth = 0.25;r a t e a_fifth = 0.20;r a t e a_sixth = 1/6;r a t e a_seventh = 1/7;r a t e a_eigth = 1/8;r a t e a_nineth = 1/9;r a t e a_tenth = 1/10;//These constants are calculated to have the sum of probabilities// on exiting transitions equal to 1r a t e rem_1 = 0.34196986029286058040;r a t e rem_2 = 0.30064294488161100270;r a t e rem_3 = 0.31060035855518379130;

183

Page 196: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

184 Chapter C. PRISM code for LQS with 10 entries

r a t e rem_4 = 0.26188623861077552282;r a t e rem_5 = 0.19725692233296732550;r a t e rem_6 = 0.17561490342671166250;r a t e rem_7 = 0.15814460128059594786;r a t e rem_8 = 0.15817814754338619905;

module main

q0 : [0..1]; // 0 : noerr; 1 : errq1 : [0..1];q2 : [0..1];q3 : [0..1];q4 : [0..1];q5 : [0..1];q6 : [0..1];q7 : [0..1];q8 : [0..1];q9 : [0..1];num : [0..ITEM_Q_m_1];// number of items in the queueh : [0..ITEM_Q_m_1];// head of the queue

// 2 moves (enqueue and nomove)[] (num = 0) -> 0.5 : (num’ = num+1) + 0.5 : (num’ = num);

// 3 moves (enqueue, dequeue, nomove)[] (num = 1 & h = ITEM_Q-1) -> a_third : (num’ = num+1) +

a_third : (num’ = num-1 & h’ = 0) +a_third : (num’ = num);

[] (num = 1 & h != ITEM_Q-1) ->a_third : (num’ = num+1) +a_third : (num’ = num-1 & h’ = h+1) +a_third : (num’ = num);

// 4 moves// enqueue, dequeue, 1 item status change, nomove[] (num = 2 & h = 0) -> a_fourth : (num’ = num+1) +

a_fourth : (num’ = num-1 & h’ = 1) +exp_f_1_d_4 : (q1’ = 1) +rem_1 : (num’ = num);

[] (num = 2 & h = 1) -> a_fourth : (num’ = num+1) +a_fourth : (num’ = num-1 & h’ = 2) +exp_f_1_d_4 : (q2’ = 1) +rem_1 : (num’ = num);

[] (num = 2 & h = 2) -> a_fourth : (num’ = num+1) +a_fourth : (num’ = num-1 & h’ = 3) +exp_f_1_d_4 : (q3’ = 1) +rem_1 : (num’ = num);

[] (num = 2 & h = 3) -> a_fourth : (num’ = num+1) +a_fourth : (num’ = num-1 & h’ = 4) +exp_f_1_d_4 : (q4’ = 1) +rem_1 : (num’ = num);

[] (num = 2 & h = 4) -> a_fourth : (num’ = num+1) +a_fourth : (num’ = num-1 & h’ = 5) +exp_f_1_d_4 : (q5’ = 1) +rem_1 : (num’ = num);

[] (num = 2 & h = 5) -> a_fourth : (num’ = num+1) +a_fourth : (num’ = num-1 & h’ = 0) +exp_f_1_d_4 : (q6’ = 1) +rem_1 : (num’ = num);

[] (num = 2 & h = 6) -> a_fourth : (num’ = num+1) +a_fourth : (num’ = num-1 & h’ = 3) +exp_f_1_d_4 : (q7’ = 1) +rem_1 : (num’ = num);

[] (num = 2 & h = 7) -> a_fourth : (num’ = num+1) +a_fourth : (num’ = num-1 & h’ = 4) +exp_f_1_d_4 : (q8’ = 1) +rem_1 : (num’ = num);

[] (num = 2 & h = 8) -> a_fourth : (num’ = num+1) +a_fourth : (num’ = num-1 & h’ = 5) +exp_f_1_d_4 : (q9’ = 1) +

Page 197: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

185

rem_1 : (num’ = num);[] (num = 2 & h = 9) -> a_fourth : (num’ = num+1) +

a_fourth : (num’ = num-1 & h’ = 0) +exp_f_1_d_4 : (q0’ = 1) +rem_1 : (num’ = num);

// 5 moves// enqueue, dequeue, 2 item status change, nomove[] (num = 3 & h = 0) -> a_fifth : (num’ = num+1) +

a_fifth : (num’ = num-1 & h’ = 1) +exp_f_1_d_5 : (q1’ = 1) +exp_f_2_d_5 : (q2’ = 1) +rem_2 : (num’ = num);

[] (num = 3 & h = 1) -> a_fifth : (num’ = num+1) +a_fifth : (num’ = num-1 & h’ = 2) +exp_f_1_d_5 : (q2’ = 1) +exp_f_2_d_5 : (q3’ = 1) +rem_2 : (num’ = num);

[] (num = 3 & h = 2) -> a_fifth : (num’ = num+1) +a_fifth : (num’ = num-1 & h’ = 3) +exp_f_1_d_5 : (q3’ = 1) +exp_f_2_d_5 : (q4’ = 1) +rem_2 : (num’ = num);

[] (num = 3 & h = 3) -> a_fifth : (num’ = num+1) +a_fifth : (num’ = num-1 & h’ = 4) +exp_f_1_d_5 : (q4’ = 1) +exp_f_2_d_5 : (q5’ = 1) +rem_2 : (num’ = num);

[] (num = 3 & h = 4) -> a_fifth : (num’ = num+1) +a_fifth : (num’ = num-1 & h’ = 5) +exp_f_1_d_5 : (q5’ = 1) +exp_f_2_d_5 : (q6’ = 1) +rem_2 : (num’ = num);

[] (num = 3 & h = 5) -> a_fifth : (num’ = num+1) +a_fifth : (num’ = num-1 & h’ = 0) +exp_f_1_d_5 : (q6’ = 1) +exp_f_2_d_5 : (q7’ = 1) +rem_2 : (num’ = num);

[] (num = 3 & h = 6) -> a_fifth : (num’ = num+1) +a_fifth : (num’ = num-1 & h’ = 3) +exp_f_1_d_5 : (q7’ = 1) +exp_f_2_d_5 : (q8’ = 1) +rem_2 : (num’ = num);

[] (num = 3 & h = 7) -> a_fifth : (num’ = num+1) +a_fifth : (num’ = num-1 & h’ = 4) +exp_f_1_d_5 : (q8’ = 1) +exp_f_2_d_5 : (q9’ = 1) +rem_2 : (num’ = num);

[] (num = 3 & h = 8) -> a_fifth : (num’ = num+1) +a_fifth : (num’ = num-1 & h’ = 5) +exp_f_1_d_5 : (q9’ = 1) +exp_f_2_d_5 : (q0’ = 1) +rem_2 : (num’ = num);

[] (num = 3 & h = 9) -> a_fifth : (num’ = num+1) +a_fifth : (num’ = num-1 & h’ = 0) +exp_f_1_d_5 : (q0’ = 1) +exp_f_2_d_5 : (q1’ = 1) +rem_2 : (num’ = num);

// 6 moves// enqueue, dequeue, 3 item status change, nomove[] (num = 4 & h = 0) -> a_sixth : (num’ = num+1) +

a_sixth : (num’ = num-1 & h’ = 1) +exp_f_1_d_6 : (q1’ = 1) +exp_f_2_d_6 : (q2’ = 1) +exp_f_3_d_6 : (q3’ = 1) +rem_3 : (num’ = num);

[] (num = 4 & h = 1) -> a_sixth : (num’ = num+1) +

Page 198: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

186 Chapter C. PRISM code for LQS with 10 entries

a_sixth : (num’ = num-1 & h’ = 2) +exp_f_1_d_6 : (q2’ = 1) +exp_f_2_d_6 : (q3’ = 1) +exp_f_3_d_6 : (q4’ = 1) +rem_3 : (num’ = num);

[] (num = 4 & h = 2) -> a_sixth : (num’ = num+1) +a_sixth : (num’ = num-1 & h’ = 3) +exp_f_1_d_6 : (q3’ = 1) +exp_f_2_d_6 : (q4’ = 1) +exp_f_3_d_6 : (q5’ = 1) +rem_3 : (num’ = num);

[] (num = 4 & h = 3) -> a_sixth : (num’ = num+1) +a_sixth : (num’ = num-1 & h’ = 4) +exp_f_1_d_6 : (q4’ = 1) +exp_f_2_d_6 : (q5’ = 1) +exp_f_3_d_6 : (q6’ = 1) +rem_3 : (num’ = num);

[] (num = 4 & h = 4) -> a_sixth : (num’ = num+1) +a_sixth : (num’ = num-1 & h’ = 5) +exp_f_1_d_6 : (q5’ = 1) +exp_f_2_d_6 : (q6’ = 1) +exp_f_3_d_6 : (q7’ = 1) +rem_3 : (num’ = num);

[] (num = 4 & h = 5) -> a_sixth : (num’ = num+1) +a_sixth : (num’ = num-1 & h’ = 0) +exp_f_1_d_6 : (q6’ = 1) +exp_f_2_d_6 : (q7’ = 1) +exp_f_3_d_6 : (q8’ = 1) +rem_3 : (num’ = num);

[] (num = 4 & h = 6) -> a_sixth : (num’ = num+1) +a_sixth : (num’ = num-1 & h’ = 3) +exp_f_1_d_6 : (q7’ = 1) +exp_f_2_d_6 : (q8’ = 1) +exp_f_3_d_6 : (q9’ = 1) +rem_3 : (num’ = num);

[] (num = 4 & h = 7) -> a_sixth : (num’ = num+1) +a_sixth : (num’ = num-1 & h’ = 4) +exp_f_1_d_6 : (q8’ = 1) +exp_f_2_d_6 : (q9’ = 1) +exp_f_3_d_6 : (q0’ = 1) +rem_3 : (num’ = num);

[] (num = 4 & h = 8) -> a_sixth : (num’ = num+1) +a_sixth : (num’ = num-1 & h’ = 5) +exp_f_1_d_6 : (q9’ = 1) +exp_f_2_d_6 : (q0’ = 1) +exp_f_3_d_6 : (q1’ = 1) +rem_3 : (num’ = num);

[] (num = 4 & h = 9) -> a_sixth : (num’ = num+1) +a_sixth : (num’ = num-1 & h’ = 0) +exp_f_1_d_6 : (q0’ = 1) +exp_f_2_d_6 : (q1’ = 1) +exp_f_3_d_6 : (q2’ = 1) +rem_3 : (num’ = num);

// 7 moves// enqueue, dequeue, 4 item status change, nomove[] (num = 5 & h = 0) -> a_seventh : (num’ = num+1) +

a_seventh : (num’ = num-1 & h’ = 1) +exp_f_1_d_7 : (q1’ = 1) +exp_f_2_d_7 : (q2’ = 1) +exp_f_3_d_7 : (q3’ = 1) +exp_f_4_d_7 : (q4’ = 1) +rem_4 : (num’ = num);

[] (num = 5 & h = 1) -> a_seventh : (num’ = num+1) +a_seventh : (num’ = num-1 & h’ = 2) +exp_f_1_d_7 : (q2’ = 1) +exp_f_2_d_7 : (q3’ = 1) +exp_f_3_d_7 : (q4’ = 1) +

Page 199: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

187

exp_f_4_d_7 : (q5’ = 1) +rem_4 : (num’ = num);

[] (num = 5 & h = 2) -> a_seventh : (num’ = num+1) +a_seventh : (num’ = num-1 & h’ = 3) +exp_f_1_d_7 : (q3’ = 1) +exp_f_2_d_7 : (q4’ = 1) +exp_f_3_d_7 : (q5’ = 1) +exp_f_4_d_7 : (q6’ = 1) +rem_4 : (num’ = num);

[] (num = 5 & h = 3) -> a_seventh : (num’ = num+1) +a_seventh : (num’ = num-1 & h’ = 4) +exp_f_1_d_7 : (q4’ = 1) +exp_f_2_d_7 : (q5’ = 1) +exp_f_3_d_7 : (q6’ = 1) +exp_f_4_d_7 : (q7’ = 1) +rem_4 : (num’ = num);

[] (num = 5 & h = 4) -> a_seventh : (num’ = num+1) +a_seventh : (num’ = num-1 & h’ = 5) +exp_f_1_d_7 : (q5’ = 1) +exp_f_2_d_7 : (q6’ = 1) +exp_f_3_d_7 : (q7’ = 1) +exp_f_4_d_7 : (q8’ = 1) +rem_4 : (num’ = num);

[] (num = 5 & h = 5) -> a_seventh : (num’ = num+1) +a_seventh : (num’ = num-1 & h’ = 0) +exp_f_1_d_7 : (q6’ = 1) +exp_f_2_d_7 : (q7’ = 1) +exp_f_3_d_7 : (q8’ = 1) +exp_f_4_d_7 : (q9’ = 1) +rem_4 : (num’ = num);

[] (num = 5 & h = 6) -> a_seventh : (num’ = num+1) +a_seventh : (num’ = num-1 & h’ = 3) +exp_f_1_d_7 : (q7’ = 1) +exp_f_2_d_7 : (q8’ = 1) +exp_f_3_d_7 : (q9’ = 1) +exp_f_4_d_7 : (q0’ = 1) +rem_4 : (num’ = num);

[] (num = 5 & h = 7) -> a_seventh : (num’ = num+1) +a_seventh : (num’ = num-1 & h’ = 4) +exp_f_1_d_7 : (q8’ = 1) +exp_f_2_d_7 : (q9’ = 1) +exp_f_3_d_7 : (q0’ = 1) +exp_f_4_d_7 : (q1’ = 1) +rem_4 : (num’ = num);

[] (num = 5 & h = 8) -> a_seventh : (num’ = num+1) +a_seventh : (num’ = num-1 & h’ = 5) +exp_f_1_d_7 : (q9’ = 1) +exp_f_2_d_7 : (q0’ = 1) +exp_f_3_d_7 : (q1’ = 1) +exp_f_4_d_7 : (q2’ = 1) +rem_4 : (num’ = num);

[] (num = 5 & h = 9) -> a_seventh : (num’ = num+1) +a_seventh : (num’ = num-1 & h’ = 0) +exp_f_1_d_7 : (q0’ = 1) +exp_f_2_d_7 : (q1’ = 1) +exp_f_3_d_7 : (q2’ = 1) +exp_f_4_d_7 : (q3’ = 1) +rem_4 : (num’ = num);

// 8 moves// enqueue, dequeue, 5 item status change, nomove[] (num = 6 & h = 0) -> a_eigth : (num’ = num+1) +

a_eigth : (num’ = num-1 & h’ = 1) +exp_f_1_d_8 : (q1’ = 1) +exp_f_2_d_8 : (q2’ = 1) +exp_f_3_d_8 : (q3’ = 1) +exp_f_4_d_8 : (q4’ = 1) +exp_f_5_d_8 : (q5’ = 1) +rem_5 : (num’ = num);

Page 200: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

188 Chapter C. PRISM code for LQS with 10 entries

[] (num = 6 & h = 1) -> a_eigth : (num’ = num+1) +a_eigth : (num’ = num-1 & h’ = 2) +exp_f_1_d_8 : (q2’ = 1) +exp_f_2_d_8 : (q3’ = 1) +exp_f_3_d_8 : (q4’ = 1) +exp_f_4_d_8 : (q5’ = 1) +exp_f_5_d_8 : (q6’ = 1) +rem_5 : (num’ = num);

[] (num = 6 & h = 2) -> a_eigth : (num’ = num+1) +a_eigth : (num’ = num-1 & h’ = 3) +exp_f_1_d_8 : (q3’ = 1) +exp_f_2_d_8 : (q4’ = 1) +exp_f_3_d_8 : (q5’ = 1) +exp_f_4_d_8 : (q6’ = 1) +exp_f_5_d_8 : (q7’ = 1) +rem_5 : (num’ = num);

[] (num = 6 & h = 3) -> a_eigth : (num’ = num+1) +a_eigth : (num’ = num-1 & h’ = 4) +exp_f_1_d_8 : (q4’ = 1) +exp_f_2_d_8 : (q5’ = 1) +exp_f_3_d_8 : (q6’ = 1) +exp_f_4_d_8 : (q7’ = 1) +exp_f_5_d_8 : (q8’ = 1) +rem_5 : (num’ = num);

[] (num = 6 & h = 4) -> a_eigth : (num’ = num+1) +a_eigth : (num’ = num-1 & h’ = 5) +exp_f_1_d_8 : (q5’ = 1) +exp_f_2_d_8 : (q6’ = 1) +exp_f_3_d_8 : (q7’ = 1) +exp_f_4_d_8 : (q8’ = 1) +exp_f_5_d_8 : (q9’ = 1) +rem_5 : (num’ = num);

[] (num = 6 & h = 5) -> a_eigth : (num’ = num+1) +a_eigth : (num’ = num-1 & h’ = 0) +exp_f_1_d_8 : (q6’ = 1) +exp_f_2_d_8 : (q7’ = 1) +exp_f_3_d_8 : (q8’ = 1) +exp_f_4_d_8 : (q9’ = 1) +exp_f_5_d_8 : (q0’ = 1) +rem_5 : (num’ = num);

[] (num = 6 & h = 6) -> a_eigth : (num’ = num+1) +a_eigth : (num’ = num-1 & h’ = 3) +exp_f_1_d_8 : (q7’ = 1) +exp_f_2_d_8 : (q8’ = 1) +exp_f_3_d_8 : (q9’ = 1) +exp_f_4_d_8 : (q0’ = 1) +exp_f_5_d_8 : (q1’ = 1) +rem_5 : (num’ = num);

[] (num = 6 & h = 7) -> a_eigth : (num’ = num+1) +a_eigth : (num’ = num-1 & h’ = 4) +exp_f_1_d_8 : (q8’ = 1) +exp_f_2_d_8 : (q9’ = 1) +exp_f_3_d_8 : (q0’ = 1) +exp_f_4_d_8 : (q1’ = 1) +exp_f_5_d_8 : (q2’ = 1) +rem_5 : (num’ = num);

[] (num = 6 & h = 8) -> a_eigth : (num’ = num+1) +a_eigth : (num’ = num-1 & h’ = 5) +exp_f_1_d_8 : (q9’ = 1) +exp_f_2_d_8 : (q0’ = 1) +exp_f_3_d_8 : (q1’ = 1) +exp_f_4_d_8 : (q2’ = 1) +exp_f_5_d_8 : (q3’ = 1) +rem_5 : (num’ = num);

[] (num = 6 & h = 9) -> a_eigth : (num’ = num+1) +a_eigth : (num’ = num-1 & h’ = 0) +exp_f_1_d_8 : (q0’ = 1) +exp_f_2_d_8 : (q1’ = 1) +

Page 201: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

189

exp_f_3_d_8 : (q2’ = 1) +exp_f_4_d_8 : (q3’ = 1) +exp_f_5_d_8 : (q4’ = 1) +rem_5 : (num’ = num);

// 9 moves// enqueue, dequeue, 6 item status change, nomove[] (num = 7 & h = 0) -> a_nineth : (num’ = num+1) +

a_nineth : (num’ = num-1 & h’ = 1) +exp_f_1_d_9 : (q1’ = 1) +exp_f_2_d_9 : (q2’ = 1) +exp_f_3_d_9 : (q3’ = 1) +exp_f_4_d_9 : (q4’ = 1) +exp_f_5_d_9 : (q5’ = 1) +exp_f_6_d_9 : (q6’ = 1) +rem_6 : (num’ = num);

[] (num = 7 & h = 1) -> a_nineth : (num’ = num+1) +a_nineth : (num’ = num-1 & h’ = 2) +exp_f_1_d_9 : (q2’ = 1) +exp_f_2_d_9 : (q3’ = 1) +exp_f_3_d_9 : (q4’ = 1) +exp_f_4_d_9 : (q5’ = 1) +exp_f_5_d_9 : (q6’ = 1) +exp_f_6_d_9 : (q7’ = 1) +rem_6 : (num’ = num);

[] (num = 7 & h = 2) -> a_nineth : (num’ = num+1) +a_nineth : (num’ = num-1 & h’ = 3) +exp_f_1_d_9 : (q3’ = 1) +exp_f_2_d_9 : (q4’ = 1) +exp_f_3_d_9 : (q5’ = 1) +exp_f_4_d_9 : (q6’ = 1) +exp_f_5_d_9 : (q7’ = 1) +exp_f_6_d_9 : (q8’ = 1) +rem_6 : (num’ = num);

[] (num = 7 & h = 3) -> a_nineth : (num’ = num+1) +a_nineth : (num’ = num-1 & h’ = 4) +exp_f_1_d_9 : (q4’ = 1) +exp_f_2_d_9 : (q5’ = 1) +exp_f_3_d_9 : (q6’ = 1) +exp_f_4_d_9 : (q7’ = 1) +exp_f_5_d_9 : (q8’ = 1) +exp_f_6_d_9 : (q9’ = 1) +rem_6 : (num’ = num);

[] (num = 7 & h = 4) -> a_nineth : (num’ = num+1) +a_nineth : (num’ = num-1 & h’ = 5) +exp_f_1_d_9 : (q5’ = 1) +exp_f_2_d_9 : (q6’ = 1) +exp_f_3_d_9 : (q7’ = 1) +exp_f_4_d_9 : (q8’ = 1) +exp_f_5_d_9 : (q9’ = 1) +exp_f_6_d_9 : (q0’ = 1) +rem_6 : (num’ = num);

[] (num = 7 & h = 5) -> a_nineth : (num’ = num+1) +a_nineth : (num’ = num-1 & h’ = 0) +exp_f_1_d_9 : (q6’ = 1) +exp_f_2_d_9 : (q7’ = 1) +exp_f_3_d_9 : (q8’ = 1) +exp_f_4_d_9 : (q9’ = 1) +exp_f_5_d_9 : (q0’ = 1) +exp_f_6_d_9 : (q1’ = 1) +rem_6 : (num’ = num);

[] (num = 7 & h = 6) -> a_nineth : (num’ = num+1) +a_nineth : (num’ = num-1 & h’ = 3) +exp_f_1_d_9 : (q7’ = 1) +exp_f_2_d_9 : (q8’ = 1) +exp_f_3_d_9 : (q9’ = 1) +exp_f_4_d_9 : (q0’ = 1) +exp_f_5_d_9 : (q1’ = 1) +

Page 202: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

190 Chapter C. PRISM code for LQS with 10 entries

exp_f_6_d_9 : (q2’ = 1) +rem_6 : (num’ = num);

[] (num = 7 & h = 7) -> a_nineth : (num’ = num+1) +a_nineth : (num’ = num-1 & h’ = 4) +exp_f_1_d_9 : (q8’ = 1) +exp_f_2_d_9 : (q9’ = 1) +exp_f_3_d_9 : (q0’ = 1) +exp_f_4_d_9 : (q1’ = 1) +exp_f_5_d_9 : (q2’ = 1) +exp_f_6_d_9 : (q3’ = 1) +rem_6 : (num’ = num);

[] (num = 7 & h = 8) -> a_nineth : (num’ = num+1) +a_nineth : (num’ = num-1 & h’ = 5) +exp_f_1_d_9 : (q9’ = 1) +exp_f_2_d_9 : (q0’ = 1) +exp_f_3_d_9 : (q1’ = 1) +exp_f_4_d_9 : (q2’ = 1) +exp_f_5_d_9 : (q3’ = 1) +exp_f_6_d_9 : (q4’ = 1) +rem_6 : (num’ = num);

[] (num = 7 & h = 9) -> a_nineth : (num’ = num+1) +a_nineth : (num’ = num-1 & h’ = 0) +exp_f_1_d_9 : (q0’ = 1) +exp_f_2_d_9 : (q1’ = 1) +exp_f_3_d_9 : (q2’ = 1) +exp_f_4_d_9 : (q3’ = 1) +exp_f_5_d_9 : (q4’ = 1) +exp_f_6_d_9 : (q5’ = 1) +rem_6 : (num’ = num);

// 10 moves// enqueue, dequeue, 7 item status change, nomove[] (num = 8 & h = 0) -> a_tenth : (num’ = num+1) +

a_tenth : (num’ = num-1 & h’ = 1) +exp_f_1_d_10 : (q1’ = 1) +exp_f_2_d_10 : (q2’ = 1) +exp_f_3_d_10 : (q3’ = 1) +exp_f_4_d_10 : (q4’ = 1) +exp_f_5_d_10 : (q5’ = 1) +exp_f_6_d_10 : (q6’ = 1) +exp_f_7_d_10 : (q7’ = 1) +rem_7 : (num’ = num);

[] (num = 8 & h = 1) -> a_tenth : (num’ = num+1) +a_tenth : (num’ = num-1 & h’ = 2) +exp_f_1_d_10 : (q2’ = 1) +exp_f_2_d_10 : (q3’ = 1) +exp_f_3_d_10 : (q4’ = 1) +exp_f_4_d_10 : (q5’ = 1) +exp_f_5_d_10 : (q6’ = 1) +exp_f_6_d_10 : (q7’ = 1) +exp_f_7_d_10 : (q8’ = 1) +rem_7 : (num’ = num);

[] (num = 8 & h = 2) -> a_tenth : (num’ = num+1) +a_tenth : (num’ = num-1 & h’ = 3) +exp_f_1_d_10 : (q3’ = 1) +exp_f_2_d_10 : (q4’ = 1) +exp_f_3_d_10 : (q5’ = 1) +exp_f_4_d_10 : (q6’ = 1) +exp_f_5_d_10 : (q7’ = 1) +exp_f_6_d_10 : (q8’ = 1) +exp_f_7_d_10 : (q9’ = 1) +rem_7 : (num’ = num);

[] (num = 8 & h = 3) -> a_tenth : (num’ = num+1) +a_tenth : (num’ = num-1 & h’ = 4) +exp_f_1_d_10 : (q4’ = 1) +exp_f_2_d_10 : (q5’ = 1) +exp_f_3_d_10 : (q6’ = 1) +exp_f_4_d_10 : (q7’ = 1) +exp_f_5_d_10 : (q8’ = 1) +

Page 203: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

191

exp_f_6_d_10 : (q9’ = 1) +exp_f_7_d_10 : (q0’ = 1) +rem_7 : (num’ = num);

[] (num = 8 & h = 4) -> a_tenth : (num’ = num+1) +a_tenth : (num’ = num-1 & h’ = 5) +exp_f_1_d_10 : (q5’ = 1) +exp_f_2_d_10 : (q6’ = 1) +exp_f_3_d_10 : (q7’ = 1) +exp_f_4_d_10 : (q8’ = 1) +exp_f_5_d_10 : (q9’ = 1) +exp_f_6_d_10 : (q0’ = 1) +exp_f_7_d_10 : (q1’ = 1) +rem_7 : (num’ = num);

[] (num = 8 & h = 5) -> a_tenth : (num’ = num+1) +a_tenth : (num’ = num-1 & h’ = 0) +exp_f_1_d_10 : (q6’ = 1) +exp_f_2_d_10 : (q7’ = 1) +exp_f_3_d_10 : (q8’ = 1) +exp_f_4_d_10 : (q9’ = 1) +exp_f_5_d_10 : (q0’ = 1) +exp_f_6_d_10 : (q1’ = 1) +exp_f_7_d_10 : (q2’ = 1) +rem_7 : (num’ = num);

[] (num = 8 & h = 6) -> a_tenth : (num’ = num+1) +a_tenth : (num’ = num-1 & h’ = 3) +exp_f_1_d_10 : (q7’ = 1) +exp_f_2_d_10 : (q8’ = 1) +exp_f_3_d_10 : (q9’ = 1) +exp_f_4_d_10 : (q0’ = 1) +exp_f_5_d_10 : (q1’ = 1) +exp_f_6_d_10 : (q2’ = 1) +exp_f_7_d_10 : (q3’ = 1) +rem_7 : (num’ = num);

[] (num = 8 & h = 7) -> a_tenth : (num’ = num+1) +a_tenth : (num’ = num-1 & h’ = 4) +exp_f_1_d_10 : (q8’ = 1) +exp_f_2_d_10 : (q9’ = 1) +exp_f_3_d_10 : (q0’ = 1) +exp_f_4_d_10 : (q1’ = 1) +exp_f_5_d_10 : (q2’ = 1) +exp_f_6_d_10 : (q3’ = 1) +exp_f_7_d_10 : (q4’ = 1) +rem_7 : (num’ = num);

[] (num = 8 & h = 8) -> a_tenth : (num’ = num+1) +a_tenth : (num’ = num-1 & h’ = 5) +exp_f_1_d_10 : (q9’ = 1) +exp_f_2_d_10 : (q0’ = 1) +exp_f_3_d_10 : (q1’ = 1) +exp_f_4_d_10 : (q2’ = 1) +exp_f_5_d_10 : (q3’ = 1) +exp_f_6_d_10 : (q4’ = 1) +exp_f_7_d_10 : (q5’ = 1) +rem_7 : (num’ = num);

[] (num = 8 & h = 9) -> a_tenth : (num’ = num+1) +a_tenth : (num’ = num-1 & h’ = 0) +exp_f_1_d_10 : (q0’ = 1) +exp_f_2_d_10 : (q1’ = 1) +exp_f_3_d_10 : (q2’ = 1) +exp_f_4_d_10 : (q3’ = 1) +exp_f_5_d_10 : (q4’ = 1) +exp_f_6_d_10 : (q5’ = 1) +exp_f_7_d_10 : (q6’ = 1) +rem_7 : (num’ = num);

// dequeue, 8 items status change, nomove[] (num = 9 & h = 0) -> a_tenth : (num’ = num-1 & h’ = 1) +

exp_f_1_d_10 : (q1’ = 1) +exp_f_2_d_10 : (q2’ = 1) +exp_f_3_d_10 : (q3’ = 1) +exp_f_4_d_10 : (q4’ = 1) +

Page 204: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

192 Chapter C. PRISM code for LQS with 10 entries

exp_f_5_d_10 : (q5’ = 1) +exp_f_6_d_10 : (q6’ = 1) +exp_f_7_d_10 : (q7’ = 1) +exp_f_8_d_10 : (q8’ = 1) +rem_8 : (num’ = num);

[] (num = 9 & h = 1) -> a_tenth : (num’ = num-1 & h’ = 2) +exp_f_1_d_10 : (q2’ = 1) +exp_f_2_d_10 : (q3’ = 1) +exp_f_3_d_10 : (q4’ = 1) +exp_f_4_d_10 : (q5’ = 1) +exp_f_5_d_10 : (q6’ = 1) +exp_f_6_d_10 : (q7’ = 1) +exp_f_7_d_10 : (q8’ = 1) +exp_f_8_d_10 : (q9’ = 1) +rem_8 : (num’ = num);

[] (num = 9 & h = 2) -> a_tenth : (num’ = num-1 & h’ = 3) +exp_f_1_d_10 : (q3’ = 1) +exp_f_2_d_10 : (q4’ = 1) +exp_f_3_d_10 : (q5’ = 1) +exp_f_4_d_10 : (q6’ = 1) +exp_f_5_d_10 : (q7’ = 1) +exp_f_6_d_10 : (q8’ = 1) +exp_f_7_d_10 : (q9’ = 1) +exp_f_8_d_10 : (q0’ = 1) +rem_8 : (num’ = num);

[] (num = 9 & h = 3) -> a_tenth : (num’ = num-1 & h’ = 4) +exp_f_1_d_10 : (q4’ = 1) +exp_f_2_d_10 : (q5’ = 1) +exp_f_3_d_10 : (q6’ = 1) +exp_f_4_d_10 : (q7’ = 1) +exp_f_5_d_10 : (q8’ = 1) +exp_f_6_d_10 : (q9’ = 1) +exp_f_7_d_10 : (q0’ = 1) +exp_f_8_d_10 : (q1’ = 1) +rem_8 : (num’ = num);

[] (num = 9 & h = 4) -> a_tenth : (num’ = num-1 & h’ = 5) +exp_f_1_d_10 : (q5’ = 1) +exp_f_2_d_10 : (q6’ = 1) +exp_f_3_d_10 : (q7’ = 1) +exp_f_4_d_10 : (q8’ = 1) +exp_f_5_d_10 : (q9’ = 1) +exp_f_6_d_10 : (q0’ = 1) +exp_f_7_d_10 : (q1’ = 1) +exp_f_8_d_10 : (q2’ = 1) +rem_8 : (num’ = num);

[] (num = 9 & h = 5) -> a_tenth : (num’ = num-1 & h’ = 0) +exp_f_1_d_10 : (q6’ = 1) +exp_f_2_d_10 : (q7’ = 1) +exp_f_3_d_10 : (q8’ = 1) +exp_f_4_d_10 : (q9’ = 1) +exp_f_5_d_10 : (q0’ = 1) +exp_f_6_d_10 : (q1’ = 1) +exp_f_7_d_10 : (q2’ = 1) +exp_f_8_d_10 : (q3’ = 1) +rem_8 : (num’ = num);

[] (num = 9 & h = 6) -> a_tenth : (num’ = num-1 & h’ = 3) +exp_f_1_d_10 : (q7’ = 1) +exp_f_2_d_10 : (q8’ = 1) +exp_f_3_d_10 : (q9’ = 1) +exp_f_4_d_10 : (q0’ = 1) +exp_f_5_d_10 : (q1’ = 1) +exp_f_6_d_10 : (q2’ = 1) +exp_f_7_d_10 : (q3’ = 1) +exp_f_8_d_10 : (q4’ = 1) +rem_8 : (num’ = num);

[] (num = 9 & h = 7) -> a_tenth : (num’ = num-1 & h’ = 4) +exp_f_1_d_10 : (q8’ = 1) +exp_f_2_d_10 : (q9’ = 1) +exp_f_3_d_10 : (q0’ = 1) +

Page 205: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

193

exp_f_4_d_10 : (q1’ = 1) +exp_f_5_d_10 : (q2’ = 1) +exp_f_6_d_10 : (q3’ = 1) +exp_f_7_d_10 : (q4’ = 1) +exp_f_8_d_10 : (q5’ = 1) +rem_8 : (num’ = num);

[] (num = 9 & h = 8) -> a_tenth : (num’ = num-1 & h’ = 5) +exp_f_1_d_10 : (q9’ = 1) +exp_f_2_d_10 : (q0’ = 1) +exp_f_3_d_10 : (q1’ = 1) +exp_f_4_d_10 : (q2’ = 1) +exp_f_5_d_10 : (q3’ = 1) +exp_f_6_d_10 : (q4’ = 1) +exp_f_7_d_10 : (q5’ = 1) +exp_f_8_d_10 : (q6’ = 1) +rem_8 : (num’ = num);

[] (num = 9 & h = 9) -> a_tenth : (num’ = num-1 & h’ = 0) +exp_f_1_d_10 : (q0’ = 1) +exp_f_2_d_10 : (q1’ = 1) +exp_f_3_d_10 : (q2’ = 1) +exp_f_4_d_10 : (q3’ = 1) +exp_f_5_d_10 : (q4’ = 1) +exp_f_6_d_10 : (q5’ = 1) +exp_f_7_d_10 : (q6’ = 1) +exp_f_8_d_10 : (q7’ = 1) +rem_8 : (num’ = num);

endmodule

Page 206: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

194 Chapter C. PRISM code for LQS with 10 entries

Page 207: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

REFERENCES

[1] AZIZ, A., SANWAL, K., SINGHAL, V., AND BRAYTON, R. Model-checking continuous-time markovchains. ACM Trans. Comput. Logic 1, 1 (2000), 162–170.

[2] BAIER, C., CLARKE, E. M., HARTONAS-GARMHAUSEN, V., KWIATKOWSKA, M., AND RYAN,M. Symbolic model checking for probabilistic processes. In Automata, Languages and Program-ming, 24th International Colloquium, ICALP’97, Bologna, Italy, 7-11 July 1997, Proceedings (1997),P. Degano, R. Gorrieri, and A. Marchetti-Spaccamela, Eds., vol. 1256 of Lecture Notes in ComputerScience, Springer, pp. 430–440.

[3] BEHRENDS, E. Introduction to Markov Chains. Vieweg, 2000.

[4] BIANCO, AND DE ALFARO. Model checking of probabilistic and nondeterministic systems. In Foun-dations of Software Technology and Theoretical Computer Science, 15th Conference, Bangalore, In-dia, December 18-20, 1995, Proceedings (1995), P. S. Thiagarajan, Ed., vol. 1026 of Lecture Notes inComputer Science, Springer, pp. 499–513.

[5] BRYANT, R. Graph-based algorithms for boolean function manipulation. IEEE Trans. on ComputersC-35, 8 (Aug 1986), 677–691.

[6] BURCH, J. R., CLARKE, E. M., MCMILLAN, K. L., DILL, D. L., AND HWANG, L. J. Symbolicmodel checking: 1020 states and beyond. Inf. Comput. 98, 2 (1992), 142–170.

[7] C. BAIER, J. K., AND HERMANNS, H. Approximate symbolic model checking of continuous-timemarkov chains. In CONCUR ’99: Concurrency Theory, 10th International Conference, Eindhoven,The Netherlands, August 24-27, 1999, Proceedings (1999), J. C. M. Baeten and S. Mauw, Eds.,vol. 1664 of Lecture Notes in Computer Science, Springer, pp. 146–161.

[8] CIARDO, G., AND TILGNER, M. On the use of Kronecker operators for the solution of general-ized stocastic Petri nets. ICASE Report 96-35, Institute for Computer Applications in Science andEngineering, 1996.

[9] CIARDO, G., AND TRIVEDI, K. A decomposition approach for stochastic reward net models. Per-formance Evaluation 18, 1 (1993), 37–59.

[10] CLARKE, E. M., EMERSON, E. A., AND SISTLA, A. P. Automatic verification of finite-state con-current systems using temporal logic specifications. ACM Trans. Program. Lang. Syst. 8, 2 (1986),244–263.

[11] CLARKE, E. M., GRUMBERG, O., AND PELED, D. A. Model Checking. The MIT Press, 1999.

[12] CLARKE, E. M., MCMILLAN, K. L., ZHAO, X., FUJITA, M., AND YANG, J. Spectral transformsfor large boolean functions with applications to technology mapping. In Proceedings of the 30thinternational on Design automation conference (1993), ACM Press, pp. 54–60.

[13] COURCOUBETIS, C., AND YANNAKAKIS, M. Verifying temporal properties of finite-state proba-bilistic programs. In Proceedings of the IEEE Conference on Decision and Control (Piscataway, NJ,1988), IEEE Press, pp. 338–345.

[14] COURCOUBETIS, C., AND YANNAKAKIS, M. The complexity of probabilistic verification. J. ACM42, 4 (1995), 857–907.

Page 208: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

196 REFERENCES

[15] DAWS, C., KWIATKOWSKA, M., AND NORMAN, G. Automatic verification of the IEEE 1394 rootcontention protocol with KRONOS and PRISM. In Proc. 7th International Workshop on FormalMethods for Industrial Critical Systems (FMICS’02) (2002), R. Cleaveland and H. Garavel, Eds.,vol. 66.2 of Electronic Notes in Theoretical Computer Science, Elsevier.

[16] DE ALFARO, L. Formal verification of performance and reliability of real-time systems. Tech. Rep.STAN-CS-TR-96-1571, Stanford University, 1996.

[17] DELLA PENNA, G., INTRIGILA, B., MELATTI, I., MINICHINO, M., CIANCAMERLA, E., PARISSE,A., TRONCI, E., AND VENTURINI ZILLI, M. Automatic verification of a turbogas control systemwith the murϕ verifier. In Hybrid Systems: Computation and Control, 6th International Workshop,HSCC 2003 Prague, Czech Republic, April 3-5, 2003, Proceedings (2003), O. Maler and A. Pnueli,Eds., vol. 2623 of Lecture Notes in Computer Science, Springer, pp. 141–155.

[18] DELLA PENNA, G., INTRIGILA, B., MELATTI, I., TRONCI, E., AND VENTURINI ZILLI, M. Finitehorizon analysis of markov chains with the murϕ verifier. In Correct Hardware Design and Verifica-tion Methods, 12th IFIP WG 10.5 Advanced Research Working Conference, CHARME 2003, L’Aquila,Italy, October 21-24, 2003, Proceedings (2003), D. Geist and E. Tronci, Eds., vol. 2860 of LectureNotes in Computer Science, Springer, pp. 394–409.

[19] DELLA PENNA, G., INTRIGILA, B., MELATTI, I., TRONCI, E., AND VENTURINI ZILLI, M. Fi-nite horizon analysis of stochastic systems with the murϕ verifier. In Theoretical Computer Sci-ence, 8th Italian Conference, ICTCS 2003, Bertinoro, Italy, October 13-15, 2003, Proceedings (2003),C. Blundo and C. Laneve, Eds., vol. 2841 of Lecture Notes in Computer Science, Springer, pp. 58–71.

[20] DELLA PENNA, G., INTRIGILA, B., MELATTI, I., TRONCI, E., AND VENTURINI ZILLI, M.Bounded probabilistic model checking with the murϕ verifier. In Formal Methods in Computer-AidedDesign, 5th International Confrence, FMCAD 2004, Austin, Texas, USA, November 15-17, 2004, Pro-ceedings (2004), A. J. Hu and A. K. Martin, Eds., vol. 3312 of Lecture Notes in Computer Science,Springer, pp. 214–229.

[21] DELLA PENNA, G., INTRIGILA, B., MELATTI, I., TRONCI, E., AND VENTURINI ZILLI, M. Ex-ploiting transition locality in automatic verification of finite state concurrent systems. STTT 6, 4(2004), 320–341.

[22] DILL, D. L., DREXLER, A. J., HU, A. J., AND YANG, C. H. Protocol verification as a hardwaredesign aid. In Proceedings of the 1991 IEEE International Conference on Computer Design on VLSIin Computer & Processors (1992), IEEE Computer Society, pp. 522–525.

[23] E `MC2 Web Page: http://www7.informatik.uni-erlangen.de/etmcc, 2005.

[24] FHP-Murϕ Web Page: http://www.di.univaq.it/melatti/FHPMurphi/, 2004.

[25] HANSSON, H. Time and Probability in Formal Design of Distributed Systems. Elsevier, 1994.

[26] HANSSON, H., AND JONSSON, B. A logic for reasoning about time and probability. Formal Aspectsof Computing 6, 5 (1994), 512–535.

[27] HART, S., AND SHARIR, M. Probabilistic temporal logics for finite and bounded models. In Proceed-ings of the sixteenth annual ACM symposium on Theory of computing (1984), ACM Press, pp. 1–13.

[28] HARTONAS-GARMHAUSEN, V., CAMPOS, S. V. A., AND CLARKE, E. M. Probverus: Probabilisticsymbolic model checking. In Formal Methods for Real-Time and Probabilistic Systems, 5th Interna-tional AMAST Workshop, ARTS’99, Bamberg, Germany, May 26-28, 1999. Proceedings (1999), J.-P.Katoen, Ed., vol. 1601 of Lecture Notes in Computer Science, Springer, pp. 96–110.

[29] HAVERKORT, B., HERMANNS, H., AND KATOEN, J.-P. On the use of model checking techniques fordependability evaluation. In Proc. 19th IEEE Symposium on Reliable Distributed Systems (SRDS’00)(Erlangen, Germany, October 2000), pp. 228–237.

Page 209: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

REFERENCES 197

[30] HERAULT, T., LASSAIGNE, R., MAGNIETTE, F., AND PEYRONNET, S. Approximate probabilis-tic model checking. In Verification, Model Checking, and Abstract Interpretation, 5th InternationalConference, VMCAI 2004, Venice, January 11-13, 2004, Proceedings (2004), B. Steffen and G. Levi,Eds., vol. 2937 of Lecture Notes in Computer Science, Springer, pp. 73–84.

[31] HERMANNS, H., KATOEN, J.-P., MEYER-KAYSER, J., AND SIEGLE, M. A tool for model-checkingmarkov chains. Software Tools for Technology Transfer 4, 2 (Feb 2003), 153–172.

[32] HERMANNS, H., MEYER-KAYSER, J., AND SIEGLE, M. Multi terminal binary decision diagramsto represent and analyse continuous time Markov chains. In Proc. 3rd International Workshop onNumerical Solution of Markov Chains (NSMC’99) (1999), B. Plateau, W. Stewart, and M. Silva, Eds.,Prensas Universitarias de Zaragoza, pp. 188–207.

[33] HOLZMANN, G. J. Design and Validation of Computer Protocols. Prentice Hall, New Jersey, 1991.

[34] HOLZMANN, G. J. The spin model checker. IEEE Trans. on Software Engineering 23, 5 (May 1997),279–295.

[35] HU, A. J., YORK, G., AND DILL, D. L. New techniques for efficient verification with implicitlyconjoined bdds. In DAC ’94: Proceedings of the 31st annual conference on Design automation (NewYork, NY, USA, 1994), ACM Press, pp. 276–282.

[36] IBE, O., AND TRIVEDI, K. Stochastic Petri net models of polling systems. IEEE Journal on SelectedAreas in Communications 8, 9 (1990), 1649–1657.

[37] KATOEN, J.-P., KWIATKOWSKA, M. Z., NORMAN, G., AND PARKER, D. Faster and symbolicctmc model checking. In Process Algebra and Probabilistic Methods, Performance Modeling andVerification: Joint International Workshop, PAPM-PROBMIV 2001, Aachen, Germany, September12-14, 2001, Proceedings (2001), L. de Alfaro and S. Gilmore, Eds., vol. 2165 of Lecture Notes inComputer Science, Springer, pp. 23–38.

[38] KRZYSZTOF, R. A., AND OLDEROG, E.-R. Verification of sequential and concurrent programs.Springer-Verlag New York, Inc., 1991.

[39] KWIATKOWSKA, M., NORMAN, G., AND PARKER, D. PRISM: Probabilistic symbolic modelchecker. In Computer Performance Evaluation, Modelling Techniques and Tools 12th InternationalConference, TOOLS 2002, London, UK, April 14-17, 2002, Proceedings (2002), T. Field, P. G. Har-rison, J. T. Bradley, and U. Harder, Eds., vol. 2324 of Lecture Notes in Computer Science, Springer,pp. 200–204.

[40] KWIATKOWSKA, M., NORMAN, G., AND PARKER, D. Probabilistic symbolic model checking withPRISM: A hybrid approach. In Tools and Algorithms for the Construction and Analysis of Systems,8th International Conference, TACAS 2002, Held as Part of the Joint European Conference on Theoryand Practice of Software, ETAPS 2002, Grenoble, France, April 8-12, 2002, Proceedings (2002), J.-P.Katoen and P. Stevens, Eds., vol. 2280 of Lecture Notes in Computer Science, Springer, pp. 52–66.

[41] KWIATKOWSKA, M. Z., NORMAN, G., AND SEGALA, R. Automated verification of a randomizeddistributed consensus protocol using cadence smv and prism. In Computer Aided Verification, 13thInternational Conference, CAV 2001, Paris, France, July 18-22, 2001, Proceedings (2001), vol. 2102of Lecture Notes in Computer Science, Springer, pp. 194–206.

[42] LAROUSSINIE, F., AND SPROSTON, J. Model checking durational probabilistic systems. In Foun-dations of Software Science and Computational Structures, 8th International Conference, FOSSACS2005, Held as Part of the Joint European Conferences on Theory and Practice of Software, ETAPS2005, Edinburgh, UK, April 4-8, 2005, Proceedings (2005), V. Sassone, Ed., vol. 3441 of LectureNotes in Computer Science, Springer, pp. 140–154.

Page 210: Dissertation Explicit Algorithms for Probabilistic Model Checking Igor

198 REFERENCES

[43] LARSEN, K. G., PETTERSSON, P., AND YI, W. UPPAAL: Status and developments. In Com-puter Aided Verification, 9th International Conference, CAV ’97, Haifa, Israel, June 22-25, 1997,Proceedings (1997), O. Grumberg, Ed., vol. 1254 of Lecture Notes in Computer Science, Springer,pp. 456–459.

[44] LARSEN, K. G., AND SKOU, A. Bisimulation through probabilistic testing. Inf. Comput. 94, 1(1991), 1–28.

[45] LEHMANN, D., AND RABIN, M. On the advantages of free choice: A symmetric fully distributedsolution to the dining philosophers problem (extended abstract). In Proc. 8th Symposium on Principlesof Programming Languages (1981), pp. 133–138.

[46] LYNCH, N., SAIAS, I., AND SEGALA, R. Proving time bounds for randomized distributed algo-rithms. In Proceedings of the thirteenth annual ACM symposium on Principles of distributed comput-ing (1994), ACM Press, pp. 314–323.

[47] Murphi Web Page: http://sprout.stanford.edu/dill/murphi.html, 2004.

[48] NuSMV Web Page: http://nusmv.irst.itc.it/, 2004.

[49] PAPOULIS, A. Probability, Random Variables and Stochastic Processes. McGraw-Hill Inc., 1965.

[50] Animated presentation for the examples of Section 4.1.2: http://www.di.univaq.it/melatti/ExamplesThesis,2005.

[51] PNUELI, A., AND ZUCK, L. Verification of multiprocess probabilistic protocols. Distrib. Comput. 1,1 (1986), 53–72.

[52] PRISM Web Page: http://www.cs.bham.ac.uk/∼dxp/prism/, 2004.

[53] SEGALA, R., AND LYNCH, N. Probabilistic simulations for probabilistic processes. In CONCUR ’94,Concurrency Theory, 5th International Conference, Uppsala, Sweden, August 22-25, 1994, Proceed-ings (1994), B. Jonsson and J. Parrow, Eds., vol. 836 of Lecture Notes in Computer Science, Springer,pp. 481–496.

[54] SHMATIKOV, V. Probabilistic analysis of anonymity. In Proceedings of the 15th IEEE ComputerSecurity Foundations Workshop (CSFW’02) (2002), IEEE Computer Society, p. 119.

[55] Eric W. Weisstein. ”Sigma-Algebra”. From MathWorld–A Wolfram Web Resource.http://mathworld.wolfram.com/sigma-algebra.html, 2005.

[56] SMV Web Page: http://www-2.cs.cmu.edu/∼modelcheck/smv.html, 2004.

[57] SPIN Web Page: http://spinroot.com, 2004.

[58] STERN, U., AND DILL, D. L. A new scheme for memory-efficient probabilistic verification. InIFIP TC6/WG6.1 Joint International Conference on: Formal Description Techniques for DistributedSystems and Communication Protocols, and Protocol Specification, Testing, and Verification (1996),R. Gotzhein and J. Bredereke, Eds., vol. 69 of IFIP Conference Proceedings, Kluwer, pp. 333–348.

[59] STEWART, W. J. Introduction to the Numerical Solution of Markov Chains. Princeton UniversityPress, 1994.

[60] TwoTowers Web Page: http://www.sti.uniurb.it/bernardo/twotowers/, 2004.

[61] UPPAAL Web Page: http://www.docs.uu.se/docs/rtmv/uppaal/, 2004.

[62] VARDI, M. Automatic verification of probabilistic concurrent finite-state programs. In 26th An-nual Symposium on Foundations of Computer Science (Portland, Oregon, Oct 1985), IEEE CS Press,pp. 327–338.