“Model Checking Hw-Hume” by Gudmund Grov

Supervised by Dr. Andrew Ireland and Dr. Greg Michaelson Second Reader Dr. Phil Trinder MSc in Distributed and Multimedia Information Systems School of Mathematical and Computer Sciences Heriot-Watt University Edinburgh September 2004

Abstract Safety-critical software systems play an important part in a modern world. Many of those systems, such as control systems in cars and planes, we basically put our lives in the hand of every day, and thus must be proven to act correctly. These high integrity software systems call for effective analysis. HUME is a programming language supporting such analysis, and is targeted at safety-critical systems. But support for verification is missing in HUME. This project aims to fill this gap, by exploring the use of HUME with an off-the-shelf design verification system called SPIN. Rules for translating a subset of HUME into the notation required by SPIN is created and implemented. A set of examples is then translated an verified with SPIN, and an analysis, which empirically scrutinises the translation and verification results, is conducted.

Declaration I, Gudmund Grov, hereby declare that the work presented in this thesis was carried out by myself at Heriot-Watt University, except where references have been made. This thesis has not been submitted for any other degree.

Gudmund Grov (Candidate)

i

Acknowledgements First of all I would like to express my thanks to my two dissertation supervisors, Dr. Greg Michaelson and Dr. Andrew Ireland. I would like to thank them for all the help, encouragements and guidance throughout this project. I would also like to thank Neil Jones, Ellen Coats and Benjamin Gorry for the help with proof reading and general help with my English. I would also like to thank Chunxu Liu, for letting me use his lexical and syntax analysis on HUME, and Kevind Hammond for the use of the HUME parser. I would like to express my respect to the late Mr. Tore Westerlund, and thank him for all the help I received when applying to this University. Special thanks also goes to my family, and especially my parents, for their encouragement and support during my studies.

ii

Contents List of Figures

vii

List of Tables

ix

1

. . . . . . .

1 1 2 3 3 4 4 4

2

3

Introduction 1.1 Content and Context . . . . . . . . . . . . 1.2 Structure of the Thesis . . . . . . . . . . . 1.3 Introduction to Formal Methods . . . . . . 1.3.1 Formal Verification . . . . . . . . . 1.4 Model Checking Hume using Spin . . . . . 1.4.1 Why Use Spin as a Model Checker 1.5 Related Work . . . . . . . . . . . . . . . . Hume Overview 2.1 Introduction . . . . . . . . . 2.2 Hume Design . . . . . . . . 2.3 Types . . . . . . . . . . . . 2.4 The Declaration Language . 2.5 The Expression Language . . 2.6 The Coordination Language 2.6.1 Boxes . . . . . . . . 2.6.2 Wiring . . . . . . . 2.7 Execution Model . . . . . . 2.8 Overview of Hw-Hume . . . 2.8.1 Design . . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

6 6 6 7 7 8 9 9 9 10 10 10

Promela Overview 3.1 Introduction . . . . . . . . . . . . . . . . . . . 3.2 Data Objects . . . . . . . . . . . . . . . . . . . 3.2.1 Structured Types . . . . . . . . . . . . 3.3 Processes . . . . . . . . . . . . . . . . . . . . 3.4 Message Channels . . . . . . . . . . . . . . . 3.5 Execution Rules . . . . . . . . . . . . . . . . . 3.6 Control Flow . . . . . . . . . . . . . . . . . . 3.7 Predefined Statements, Variables and Functions 3.8 Specifying Behaviour . . . . . . . . . . . . . . 3.9 Introduction to Spin . . . . . . . . . . . . . . . 3.9.1 Spin Structure . . . . . . . . . . . . . 3.9.2 Execution Rules . . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

15 15 15 16 16 17 18 18 20 20 21 22 22

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

iii

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

4

5

6

Translating Hw-Hume into Promela 4.1 Introduction . . . . . . . . . . . . . . . . 4.1.1 Structure of the Promela Program 4.2 Data Types . . . . . . . . . . . . . . . . 4.3 Values . . . . . . . . . . . . . . . . . . . 4.4 Names . . . . . . . . . . . . . . . . . . . 4.5 Channels . . . . . . . . . . . . . . . . . 4.5.1 Control Channels . . . . . . . . . 4.5.2 Interprocess Communication . . . 4.6 Processes . . . . . . . . . . . . . . . . . 4.6.1 Process Prelude . . . . . . . . . . 4.6.2 Variable Declaration . . . . . . . 4.6.3 Process Body . . . . . . . . . . . 4.6.4 Matches . . . . . . . . . . . . . . 4.7 The Control Process . . . . . . . . . . . . 4.8 Stream Processes . . . . . . . . . . . . . 4.8.1 Input Streams . . . . . . . . . . . 4.8.2 Output Streams . . . . . . . . . . 4.9 The Init Process . . . . . . . . . . . . . . 4.10 Using the Translation Rules . . . . . . . . 4.10.1 Process Prelude . . . . . . . . . . 4.10.2 Variable Declarations . . . . . . . 4.10.3 Process Body . . . . . . . . . . . 4.10.4 The Promela Process . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

23 23 23 24 24 25 25 25 26 27 28 28 29 31 32 33 33 35 38 39 40 41 41 44

The Hw-Hume to Promela Translator 5.1 Introduction . . . . . . . . . . . . 5.2 Requirements . . . . . . . . . . . 5.3 Design . . . . . . . . . . . . . . . 5.3.1 Lexical/Syntax Analysis . 5.3.2 Abstract Syntax Tree . . . 5.3.3 Code Generation . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

45 45 45 46 47 48 48

Evaluation 6.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2 Example 1: A Half Adder . . . . . . . . . . . . . . . . . . . 6.3 Example 2: An XOR and an AND Gate Forming a Deadlock 6.4 Example 3: Full Adder from Truth Table . . . . . . . . . . . 6.5 Example 4: Full Adder as Half Adders and OR gate . . . . . 6.6 Example 5: Full Adder as XOR, AND and OR gates . . . . 6.7 Example 6-9: Connecting Adders . . . . . . . . . . . . . . 6.8 Example 10: Debugging with Spin . . . . . . . . . . . . . . 6.8.1 Specifying Behaviour . . . . . . . . . . . . . . . . . 6.9 Analysis of the Verification Result . . . . . . . . . . . . . . 6.9.1 Verification . . . . . . . . . . . . . . . . . . . . . . 6.9.2 Time Consumption . . . . . . . . . . . . . . . . . . 6.9.3 Number of Code Lines . . . . . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

49 49 49 51 52 52 53 53 54 57 59 60 60 61

. . . . . .

. . . . . .

. . . . . .

. . . . . .

7

Conclusion 7.1 Introduction . . . . . . . . . . 7.2 The Analysis . . . . . . . . . 7.2.1 Verification Result . . 7.2.2 Time Consumption . . 7.2.3 Number of Code Lines 7.3 Translation Rules . . . . . . . 7.4 The Translator . . . . . . . . . 7.5 Future Work . . . . . . . . . . 7.5.1 Short Term . . . . . . 7.5.2 Long Term . . . . . . 7.6 Conclusion . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

63 63 63 63 63 64 64 64 65 65 65 66

Bibliography

67

Appendices

70

A Abstract Syntax for Hw-Hume A.1 Programs and Modules . . A.2 Declaration Language . . . A.3 Types . . . . . . . . . . . A.4 Expression Language . . . A.5 Coordination Language . . A.5.1 Boxes . . . . . . . A.5.2 Wiring . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

B Translation Rules for Hw-Hume B.1 Introduction . . . . . . . . . . . . . . . . B.1.1 Structure of the Promela Program B.2 Data Types . . . . . . . . . . . . . . . . B.3 Values . . . . . . . . . . . . . . . . . . . B.4 Names . . . . . . . . . . . . . . . . . . . B.5 Channels . . . . . . . . . . . . . . . . . B.5.1 Control Channels . . . . . . . . . B.5.2 Interprocess Communication . . . B.6 Processes . . . . . . . . . . . . . . . . . B.6.1 Process Prelude . . . . . . . . . . B.6.2 Variable Declarations . . . . . . . B.6.3 Process Body . . . . . . . . . . . B.7 The Control Process . . . . . . . . . . . . B.8 Stream Processes . . . . . . . . . . . . . B.8.1 Input Streams . . . . . . . . . . . B.8.2 Output Streams . . . . . . . . . . B.9 The Init Process . . . . . . . . . . . . . . B.9.1 Initialisation of Channels . . . . . B.9.2 Instantiate Processes . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

75 . 75 . 75 . 76 . 78 . 79 . 79 . 79 . 81 . 83 . 83 . 85 . 86 . 93 . 95 . 97 . 99 . 102 . 103 . 104

C User Guidelines for the Translator C.1 Generating Promela Code . . . C.2 Random Simulation . . . . . . C.3 Verifying Model . . . . . . . . C.4 Guided Simulation . . . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . . . . .

. . . .

. . . . . . .

. . . .

. . . . . . .

70 70 70 71 71 72 72 73

. . . . . . .

. . . .

. . . . . . .

. . . .

. . . .

106 106 107 107 108

D Hume Examples 109 D.1 Running the Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 E Promela Examples 112 E.1 A Simple Baker Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 E.2 A More Advanced Baker Example . . . . . . . . . . . . . . . . . . . . . . . . . . 113 F Hw-Hume Examples F.1 Example 1: A Half Adder . . . . . . . . . . . . . . . . . . . F.2 Example 2: An XOR and an AND Gate Forming a Deadlock F.3 Example 3: Full Adder from Truth Table . . . . . . . . . . . F.4 Example 4: Full Adder as Half Adders and OR Gates . . . . F.5 Example 5: Full Adder as XOR, AND and OR Gates . . . . F.6 Connecting Adders . . . . . . . . . . . . . . . . . . . . . . F.6.1 Example 6: A Two Bit Adder . . . . . . . . . . . . F.6.2 Example 7: A Three Bit Adder . . . . . . . . . . . . F.6.3 Example 8: A Four Bit Adder . . . . . . . . . . . . F.6.4 Example 9: A Five Bit Adder . . . . . . . . . . . . F.7 Example 10: Debugging with Spin . . . . . . . . . . . . . . F.7.1 The First Version of the Counter . . . . . . . . . . . F.7.2 The Second Version of the Counter . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

116 116 117 118 119 120 121 121 123 125 127 129 129 130

G Translation Examples 132 G.1 Example 1: The Half Adder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 G.2 Example 3: Full Adder from Truth Table . . . . . . . . . . . . . . . . . . . . . . . 135 G.3 Example 4: Full Adder as Half Adders and OR Gates . . . . . . . . . . . . . . . . 137 H Verification Result H.1 Example 1: Half Adder . . . . . . . . . . . . . . . . . . . . H.2 Example 2: An XOR and an AND Gate Forming a Deadlock H.3 Example 3: Full Adder from Truth Table . . . . . . . . . . . H.4 Example 4: Full Adder as Half Adders and OR Gates . . . . H.5 Example 5: Full Adder as XOR, AND and OR Gates . . . . H.6 Connecting Adders . . . . . . . . . . . . . . . . . . . . . . H.6.1 Example 6: A Two Bit Adder . . . . . . . . . . . . H.6.2 Example 7: A Three Bit Adder . . . . . . . . . . . . H.6.3 Example 8: A Four Bit Adder . . . . . . . . . . . . H.6.4 Example 9: A Five Bit Adder . . . . . . . . . . . . H.7 Example 10: Debugging with Spin . . . . . . . . . . . . . . H.7.1 The Counter with an Error Injected . . . . . . . . . H.7.2 The Updated Counter . . . . . . . . . . . . . . . . . H.7.3 Specifying Behaviour . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

141 141 142 143 144 145 146 146 148 150 152 153 153 154 155

List of Figures 1.1

Structure of the Thesis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.1 2.2 2.3 2.4 2.5 2.6

Basic Data Types [25] . . . . . . . . . . . . . Logic Diagram of a Half Adder . . . . . . . . Truth Table for Half Adder . . . . . . . . . . Half Adder in Hw-Hume . . . . . . . . . . . Source Code of the Half Adder in Hw-Hume Running the Half Adder . . . . . . . . . . . .

. . . . . .

7 11 11 11 12 14

3.1 3.2

Basic Data Types [18] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . The Spin Structure [20] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

15 22

4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10 4.11 4.12 4.13 4.14 4.15 4.16 4.17 4.18 4.19 4.20 4.21 4.22 4.23 4.24 4.25 4.26 4.27 4.28 4.29 4.30

The Structure of the Translation . . . . . . . . . . . . . . . . . . Source Code for the ‘gen’ Box . . . . . . . . . . . . . . . . . . . Creating Control Channels . . . . . . . . . . . . . . . . . . . . . All the Control Channels in the Half Adder . . . . . . . . . . . . Creating Channels for Interprocess Communication . . . . . . . . Channels for Interprocess Communication in the Half Adder . . . The ‘show’ Box . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating The Process Prelude . . . . . . . . . . . . . . . . . . . . Creating Variable Declaration . . . . . . . . . . . . . . . . . . . . General Body Code . . . . . . . . . . . . . . . . . . . . . . . . . Fair Matching . . . . . . . . . . . . . . . . . . . . . . . . . . . . Unfair Matching . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating Channels for Matching . . . . . . . . . . . . . . . . . . Creating Values in Matches . . . . . . . . . . . . . . . . . . . . . The ‘show1’ Process . . . . . . . . . . . . . . . . . . . . . . . . Creating the Control Process . . . . . . . . . . . . . . . . . . . . The Control Process . . . . . . . . . . . . . . . . . . . . . . . . . The Modified ‘gen’ Box . . . . . . . . . . . . . . . . . . . . . . Creating the Reference to the Stream for the Input Stream Process Creating the Reference to the Input Stream Variables . . . . . . . Creating the Input Stream Body . . . . . . . . . . . . . . . . . . The Input Stream Process . . . . . . . . . . . . . . . . . . . . . . The Output Stream Declarations . . . . . . . . . . . . . . . . . . Creating the Reference to the Output Stream Channel . . . . . . . Creating the Output Stream Variables . . . . . . . . . . . . . . . Creating the Main Body of the Output Stream Process . . . . . . . The Output Stream Process . . . . . . . . . . . . . . . . . . . . . Creating the Channel Initialisation . . . . . . . . . . . . . . . . . Creating the Instantiation of Processes . . . . . . . . . . . . . . . The Init Process . . . . . . . . . . . . . . . . . . . . . . . . . . .

24 25 26 26 27 27 28 28 29 29 30 30 31 32 32 33 33 34 34 35 35 36 36 37 37 37 38 38 39 39

vii

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2

4.31 The Hume Code of the ‘NOT’ gate . . . . . . . . . . . . . . . . . . . . . . . . . . 4.32 The Promela Representation of the ‘NOT’ Gate . . . . . . . . . . . . . . . . . . .

40 44

5.1 5.2 5.3 5.4 5.5

Use Case Diagram of Translator Activity Diagram of Translator . The Translator . . . . . . . . . . Part of Abstract Syntax Tree . . Class Diagram . . . . . . . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

46 47 47 48 48

6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9 6.10 6.11 6.12 6.13 6.14 6.15 6.16 6.17 6.18 6.19 6.20 6.21 6.22 6.23 6.24 6.25 6.26

Running the Half Adder . . . . . . . . . . . . . . . . . . . . . . . . . . Output when Verifying Half Adder . . . . . . . . . . . . . . . . . . . . Time Elapsed when Verifying Half Adder . . . . . . . . . . . . . . . . An ‘AND’ and an ‘XOR’ Gate Creating a Deadlock . . . . . . . . . . . Output when Verifying Deadlock Example . . . . . . . . . . . . . . . . Output when Running Guided Simulation on Deadlock Example . . . . A Full Adder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Full Adder from a Truth Table . . . . . . . . . . . . . . . . . . . . . . Full Adder as Half Adders and OR gate . . . . . . . . . . . . . . . . . Full Adder as XOR, AND and OR gates . . . . . . . . . . . . . . . . . Example 6: A Two Bit Adder . . . . . . . . . . . . . . . . . . . . . . . The Digit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Truth Table for a Digit . . . . . . . . . . . . . . . . . . . . . . . . . . The Counter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Output when Verifying the Counter . . . . . . . . . . . . . . . . . . . . Running the Counter in Guided Simulation . . . . . . . . . . . . . . . Output when Verifying the Updated Counter . . . . . . . . . . . . . . . Declaring the Properties . . . . . . . . . . . . . . . . . . . . . . . . . Never Claim for Desired Behavoiur . . . . . . . . . . . . . . . . . . . Output when Verifying Desired Behaviour . . . . . . . . . . . . . . . . Output when Verifying Error Behaviour . . . . . . . . . . . . . . . . . Relationship between State Vector and Box Instances . . . . . . . . . . Relationship between Number of Transitions and Box Instances . . . . Relationship between Verification Time and Hw-Hume Box Instances . Relationship between Time, Processes and Channels . . . . . . . . . . Relationship between Code Lines Factor and Number of Box Instances

. . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . .

50 50 50 51 51 51 52 52 53 53 54 54 55 55 56 56 57 57 58 58 58 60 60 61 61 62

B.1 The Structure of the Translation . . . . . . . . . . . . . . . . . . . . . . . . . . .

76

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

D.1 A Hume Counter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 E.1 The LTL Editor in XSpin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

List of Tables 6.1 6.2

Translation and Verification Data . . . . . . . . . . . . . . . . . . . . . . . . . . . Data Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

ix

59 59

Chapter 1

Introduction 1.1 Content and Context There is a growing need to be able to verify that systems act correctly according to their requirements. There is also a tendency that more and more systems are distributed and run concurrently, which complicates the verification. Such high integrity software systems need effective static analysis. A static analysis is an analysis that is performed without running the code. Model checking is an automatic static analysis technique for verifying concurrent systems. One such model checker is SPIN [32]. A model that needs to be verified in SPIN, must be specified in the PROMELA modelling language. HUME [33] is a functional programming language, currently being developed at Heriot-Watt University and the University of St Andrews. Functional programming languages are entirely descriptive. The programming is performed by describing objects, which will have many sub-descriptions embedded in them [13]. The programming is mainly to build these descriptions and use the computer to evaluate expressions. The programmer constructs functions to solve problems, using a notation that obeys normal mathematical principles. The computer then evaluates the expressions and prints out the result [6]. HUME supports static analysis, but verification is missing. The verification can be achieved by applying a model checker to HUME. To model check HUME programs, they have to be translated into a format accepted by a model checker, e.g. PROMELA for SPIN. Translating full HUME into PROMELA would be beyond the scope of this project. As a result a subset of HUME, known as Hardware-HUME (HW-HUME), has been defined. The objective of the project is to define the semantic rules for this translation from HW-HUME to PROMELA, and implement the rules in a program that automates the translation process. The program should also include features to verify and simulate the models, using SPIN automatically. The resulting PROMELA code should be scrutinised and compared to the HW-HUME code. An analysis of the verification result should also be explored. Key aspects are the code sizes, the amount of work and the time required for translation as well as verification of the HW-HUME models. The possibilities with using the SPIN model checker to model check HW-HUME programs should also be examined.

1

1.2 Structure of the Thesis Chapter 1, introduces the concept and context of the project, and defines the structure of the thesis. It provides an overview of formal methods, and a more detailed introduction to formal verification and model checking, which are specially relevant to this project. Chapter 2 presents an overview of the HUME programming language. It focuses on the programming aspects required to understand the rest of the thesis, but not the background or underlying theory of HUME. In this chapter HW-HUME is defined and explained using an example. Chapter 3 contains an overview of the PROMELA modelling language, and a short introduction to the SPIN model checker. In the PROMELA section the focus is to gain enough knowledge to understand the translation process. Chapter 4 describes the translation from HW-HUME into PROMELA using an example. All the translation rules are found in appendix B. These are used in the explanation. The chapter also shows how to use these rules directly through a simple example. Chapter 5 describes ‘hwhpromela’. This is a JAVA program that implements the translation rules defined in appendix B. It automates the HW-HUME to PROMELA translation, and can be used to verify and simulate the generated models. Chapter 6 evaluates the translation and verification. This is achieved by using ‘hwhpromela’ to translate and verify a range of examples. An analysis of the different aspects of the translation and verification is then conducted based on the results of the translations and verifications. Chapter 7 concludes the thesis, discusses the results and looks at future works.

Figure 1.1: Structure of the Thesis

Figure 1.1 illustrates the structure of the chapters. As the figure shows, the chapters must be read in a sequential order. The only chapters that do not depend on each other are the HUME and PROMELA overviews, conducted in chapter 2 and 3 respectively.

1.3 Introduction to Formal Methods There is an increasing need to construct software and hardware systems that operate reliably despite their complexity. Systems are widely used in applications where failure is unacceptable. Obvious examples are telephone switching networks, medical instruments and for traffic control [8]. As more computer systems control our everyday life, the demand for ensuring that they are correct increases. Such Systems tend to be more distributed, making them more complex, and consequently, more exposed to errors. Due to this it is important to develop methods and tools that ensure the correctness of the systems [8]. There are many examples where such correctness was not ensured and things did not work as they should have done. One of the most famous is the Ariane 5 accident in 1996, where the Ariane rocket crashed after just 39 seconds on its maiden trip. The total cost for the European Space Agency was in the order of $7 billion[15]. Formal methods are mathematically-based language techniques and tools for specifying and verifying systems [9]. There is a separation between formal specification and formal verification, where the first is the process of describing a system and its desired properties and the latter is concerned with the analysis of the specification.

1.3.1 Formal Verification There are four different principal validation methods for complex hardware and software systems, known as simulation, testing, deductive verification and model checking. Simulation is “testing” an abstraction of a model, while testing is performed on the actual product. Both methods typically involve providing certain inputs to the system and observing and analysing the output. Deductive verification is the use of axioms and proof rules to prove the correctness of systems [8]. It involves finding a mathematical proof of a property in the system [9]. Model checking is a technique involving building a finite model of a system, and then checking if the desired properties hold in that specific model. [9]. Automata forms the basis of the models used to specify the behaviour of the systems to be validated during model checking [5]. Berard [5] gives a good introduction to automata. Model Checking Model checking is an automatic technique for verifying finite state concurrent systems. By only using finite systems, the verification can be performed automatically. Normally model checking uses an exhaustive search of the state space of a system to determine if some specifications are true or not. The process of model checking a design is concerned with three tasks, known as modelling, specification and verification [8]. Modelling is first applied. It involves converting a design into a formalism accepted by a model checking tool. This process often requires that an abstraction of the system is used due to limitations on time and memory. Specification is then performed. It is concerned with defining the properties to verify. This specification is usually given in some logical formalism, most commonly temporal logic.

Verification is the last task and involves searching the model to see if it violates the specification. This process is ideally automatic. In most cases where the verifier fails an error trace is provided back to the user. The user can then use this to find the error.

1.4 Model Checking Hume using Spin Model checking is traditionally performed in the modelling stage of a methodology. The system that is being developed is first modelled. A model checker can then be applied to find errors in the design of the system. If the model checker succeeds, the system is then proved to be correct, providing it is correctly implemented. As modern high level languages can be parallel, multithreaded and distributed, they are more exposed to errors than traditional sequential programs. The implementation should therefore also be verified, to prove that the system is correct. HUME programs consist of a set of communicating finite state automata. All errors in such concurrent systems are difficult to find using traditional debugging facilities. To prove that a system is error free a model checker can be applied to the system at the end. It can then verify that the system does not contain any errors.

1.4.1 Why Use Spin as a Model Checker To be able to model check HUME, there are two completely different approaches. - A model checker that uses HUME source code as an input notion can be implemented. - HUME can be translated into an input language of a known model checker. Since a large range of model checkers are already available, and have been developed over a period of years and even decades, the first approach would be “reinventing the wheel”, providing it is not a customisation of an already existing model checker. The problem with the other approach is the language coverage. For each feature in HUME, a counterpart must be found in the destination language. The problem is that the work carried out for proving programs to be correct has been devoted to special languages differing from main stream programming languages. Examples are formal specification languages, purely logic based languages and, for model checkers, guarded command languages [35]. It is problematic to find features that resemble the features in HUME in such languages. SPIN uses PROMELA as an input language. It is a modelling language with a C like syntax, which makes it easier to translate compared to many other languages. Due to the close resemblance to a programming language, this approach has been chosen for this project.

1.5 Related Work There is currently research on both HUME and SPIN. Several projects exists concerned with verifying high level languages. Most of them are concerned with the translation of programming languages (mostly JAVA) into a notation accepted by one or more already existing verifiers. A selection of such projects are:

JAVA PATHFINDER translates a given JAVA program into PROMELA. It has been been developed by NASA [17], for the Mars Exploration Rover [30]. In JAVA PATHFINDER 1 high-level JAVA source code were translated into PROMELA, and in PATHFINDER 2 a new model checker was developed in which a JAVA virtual machine interpreted the source code. [35, 30]. BANDERA , developed at Kansas State University, USA, is tool that takes JAVA source code as input and generates a program model in one of several different verification tools. It also maps the output from the verification back to the original source code [3, 11]. The BANDERA tool uses the JAVA byte code [35]. BLAST (Berkeley Lazy Abstraction Software Verification Tool) is a software model checker for C programs developed at University of California, Berkeley, USA. [7] A HUME to JAVA translator is being created in the Dependable Systems Group at Heriot-Watt University simultaneously to this project . The lexical and syntax analysis from this project has been used in the ‘hwhpromela’ program. An ESTELLE to PROMELA compiler was created at Heriot-Watt University in 1994 as a Master of Philosophy (MPhil) thesis [1]. A LOTOS to PROMELA translator was also created at Heriot-Watt University the same year. This was also an MPhil thesis [27]. Since SPIN is developing all the time, the last two projects must be considered out of date. SPIN has evolved considerably over the last decade since the projects were conducted. However, some notes from these projects might be relevant and should be considered. Key aspects are the problems which occurred, and how or if they were solved. Two projects of particular interest are the JAVA PATHFINDER and the BANDERA project. The first version of the JAVA PATHFINDER was a direct translation of a JAVA source code, while in the second version a new model checker was developed. The second version was developed since not all features in JAVA could be represented in SPIN. This dilemma will probably arise in a full HUME to SPIN translation and must be considered. BANDERA integrates several different verification mechanisms, which may be the result also for HUME. The HUME to PROMELA translation is also of special interest, since the JAVA representation of HUME can give some ideas. An interesting experiment would be to translate HUME to JAVA, and then use the JAVA PATHFINDER and compare the result with the result from a direct HUME to PROMELA translation. All these features must however be considered future work, since they are beyond the scope of this project.

Chapter 2

Hume Overview 2.1 Introduction HUME (Higher-order Unified MEta-language) is named after the Scottish philosopher David Hume. It is a strongly typed, functionally-based language with an integrated tool set for developing, proving and assessing concurrent, resource-limited systems [25]. The focus of HUME is on high reliability applications.

2.2 Hume Design Finite state automata(FSA) has been used as a starting point for the design of HUME . It is based on a generalisation of standard FSA transition notation, to make full HUME Turing-Complete [16]. HUME introduces concurrent processing through boxes. A box is an FSA - an abstraction of a process describing the link between its input and output in terms of functional expressions, and which provides exception handling facilities including timeouts and system exceptions[25]. Concurrent processing is achieved by wiring multiple communicating FSA [16]. HUME separates the expression and the coordination aspects of the language. Both the expression language and the coordination language share a rich, polymorphic type system [16]. This gives HUME a layered structure: The expression language is the inner layer. It describes input/output transitions within boxes [16]. It is a purely functional language with strict semantics. It is intended to be used for the description of single, one-shot, non-reentrant processes. It has a subset with statically provable properties of determinism, termination and bounded time and space behaviour. Values and functions are defined in the expression language [25]. The coordination language is the middle layer. It describes external properties and configurations of boxes. It links functions into potential concurrent processes. It is a finite state language for the description of multiple, interacting, re-entrant processes built from the expression language. It is designed to have statically provable properties that include both process equivalence and safety properties. Inputs and outputs between boxes are then wired together.

6

The declaration language is the outer layer. It is a static language that introduces types and values that scope over the coordination and expression language. [25]

2.3 Types Type bool char unicode word hprecisioni int hprecisioni nat hprecisioni float hprecisioni fixed hprecisioni [(2|10|16) [ ** hexponenti ] ] exact

Description boolean value (true or false) 8 bit ISO Latin-1 16 bit Unicode bits of specified size integers of specified size natural numbers floating point number fixed exponent real of specified bit exact real number hprecisioni ::= 0 | . . . | 64

Figure 2.1: Basic Data Types [25]

Table 2.1 contains all the base types in HUME. A bool is a boolean value that can contain the values true or false. HUME has two character values, an 8 bit ASCII code char, and a 16 bit Unicode type named unicode. The type word is a sequence of bits, while int also supports negative integers. The nat type is used to represent natural numbers, and float is used for floating point numbers. The type fixed is a fixed exponent real of a specified bit size. The size of the type must be specified when these types are declared. The size can range from 1 to 64 bits inclusively. HUME also supports a set of structured types. For instance a vector is a fixed length sequence of uniform type. The declaration vector 1 . . 1 2 of i n t 1 ;

declares a vector with a buffer size of 12 elements. The elements in the vector must be a 1 bit integer. A tuple is a fixed length sequence of uniform type. The declaration ( i n t 3 2 , char )

declares a tuple consisting of a 32 bit integer and a character. HUME also contains a list type which is a variable length sequence of uniform type.

2.4 The Declaration Language The declaration layer is used by both the coordination and the expression layer. Box and wiring declarations associate the declaration layer with the coordination layer, while the expression layer uses the declaration layer for function and simple values declarations. Values in HUME can be declared to be constant by using the constant keyword as a prefix in the value declaration. A constant is calculated at compile-time, and adds the constraint that the values

must be simple calculations. The functions introduced may be recursive and mutually recursive. The following example defines a recursive function that calculates the factorial of a number n: f a c : : word 3 2 − > word 3 2 ; fac 0 = 1; fac n = n ∗ fac ( n −1);

The input and outputs of the function in the example are of type word 32. If the input is 0, 1 is returned. If not, the input value is multiplied by the result of a recursive function call with the input decremented by 1 as argument. Three kinds of type declarations are supported in HUME. The data keyword is used to define a set of enumerated types, each separated by a vertical bar ‘|’. E.g. data STATUS = GO | STOP ;

creates a new type STATUS, which can have the values GO or STOP. Constructors are used to build new data structures. They are created with union declarations. Tuples, lists and vectors are created a similar way in the expression layer. union SIGN = Even i n t 3 2 | Odd i n t 3 2 ;

The type declaration declares a named type equivalent to a pre-existing type. The declaration t y p e B i t = word 1 ;

declares the type ‘Bit’ to be equivalent to word 1.

2.5 The Expression Language The expression layer is a purely functional layer, where expressions follow a strict evaluation order. Constants and variables can be defined. Constants are constant values of the basic HUME types. Variables are declared either in function declaration, constant declarations or pattern matches. Case expressions are matched in a top-to-bottom and left-to-right order. One or more of the patterns must be matched. A wild card ‘ ’ or a variable matches any value. Each match is separated by a vertical bar ‘|’. The following example uses a case expression to implement the factorial function. fac n = case n of 0 − > 1 | n −> n ∗ fac ( n −1);

A special type of case-expressions are conditionals. They demand that the expression being discriminated must be of type bool and must include two alternatives, depending on whether the result of the expression is true or false. This is the case with the previously defined factorial function hence it can be written as follows: f a c n = i f n ==0 then 1 e l s e n ∗ f a c ( n − 1 ) ;

Local declarations are used to bind one or more variables to expressions within a limited scope. A local declaration is performed using the let keyword. l e t f = fac n in ( . . . ) ;

In the the example the variable ‘f’ will contain the result of the factorial of ‘n’, in the expressions enclosed by the parentheses.

2.6 The Coordination Language A HUME program consists of a set of boxes with a defined set of inputs and outputs. Boxes are generalised finite state machines, where their transitions are defined by patterns on the inputs. Boxes are connected to each other, streams and ports by wiring them together.

2.6.1 Boxes A box has a prelude where its unique name is specified. The prelude has a set of inputs and outputs. The inputs and outputs can be of any HUME type except functions and exceptions. The body of a box consists of a set of matches, that are matched with the the input values. The types between the patterns that are matched and the input values must correspond. Each match is separated by a vertical bar ‘|’. The matches can be either fair or unfair. Unfair matches are specified by the match keyword. The matches are then performed in a sequential top-to-bottom left-to-right order. Fair matching is specified by using the fair keyword, and guarantees that each rule is given an equal probability of being matched [26]. The box declaration box Ex i n ( a , b : : word 1 ) o u t ( c , d : : word 1 ) match (1,∗) −> (∗,0) | (∗, n) −> (n +1,∗) ;

declares a box called ‘Ex’. The box has two input values ‘a’ and ‘b’, of which both are one bit positive integers. The two outputs ‘c’ and ‘d’ are of the same type. The match keyword implies that the matching is performed in a top-to-bottom order. The first of the two matches, only checks the first input element. The wild card ‘*’ used on the second input in the pattern match, implies that the input is ignored. On the right hand side of the arrow ‘→’, the output is generated. The first output is also a wild card, which implies that no output is generated. In the second output ‘0’ is sent. The second match introduces variables. The first input is ignored, and the value in the second is assigned to the variable ‘n’. In the first output ‘n’ incremented by one is sent. HUME boxes also support timeouts and exception. An exception is raised and for each exception a handler must be specified.

2.6.2 Wiring Each box must have a corresponding wire declaration. For each variable in the input and output elements of the box, a source and destination respectively, must be specified. The source or destination can be another variable in a box, a stream or a port. In the case of the ‘Ex’ box, the wire declaration w i r e Ex ( Ex . c i n i t i a l l y 1 , Ex . d ) ( Ex . a , Ex . b ) ;

wires the output element ‘c’ to the a input element of ‘a’ of the same box. The initially keyword specifies that the initial value of c is ‘1’. The output element ‘d’ is wired to ‘b’, without defining any initial value. HUME includes a template mechanism to give structure to a box. To create a template the box keyword at the beginning of a box declaration is replaced by the template keyword. To use a

template, a box must be instantiated from the templates. If the ‘Ex’ box was declared as a template instead of a box, the statement i n s t a n t i a t e Ex a s temp1 ;

would create a box instance of the template, called ‘temp1’. A box or a template can also be replicated. The following example shows how the ‘Ex’ box can be replicated. This will create two new boxes, called ‘b1’ and ‘b2’, which are identical to ‘Ex’. r e p l i c a t e Ex a s b ∗ 2 ;

HUME supports input streams and output streams. To read from or write to a stream, the stream must first be declared. A box can then wired to the declared stream, in a wire declaration. The following example creates an output stream called ‘output’ that writes to standard output. stream o u t p u t t o ” s t d o u t ” ;

2.7 Execution Model Each box in HUME executes in a sequential order. The first box defined executes first. When the box has finished executing one run, the next box executes one run, and so on. When the last box has finished one run, the first box gains the control again. At the end of an execution cycle a box can be in three different states [24]: Runnable means that the box completed successfully. Match fail means that the box lacked appropriate inputs. That is no inputs matched the patterns defined and hence no output is generated. Blocked means that the box completed, but is blocked since some outputs from the previous cycle were not consumed. On the next cycle, the box will again attempt to send to the outputs.

2.8 Overview of Hw-Hume Hardware-HUME (HW-HUME), is a subset of Hume specifically targeted at modelling hardware systems. Only a subset of all types in HUME are supported in HW-HUME. The supported base types are int and char, while tuple is the only supported structured type. In the declaration language a new type can be declared, together with output streams, boxes and wires. In the expression language only variables and constants may be used for both pattern matches and the expressions that generate output from boxes. The coordination language defines boxes and wires. As input and output for a box, only the supported types can be used. A pattern consists of one or more constants and/or variables. The expression used to define the output contains one or more constants and/or variables.

2.8.1 Design The design of HW-HUME is described by using an example of a half adder. A half adder is designed to combine two binary digits and produce a carry and a sum. There are several ways of creating a

half adder. Two examples are by using a truth table or by combining an ‘XOR’ and an ‘AND’ gate. The latter approach is used in this example. C

S

B

A

Figure 2.2: Logic Diagram of a Half Adder

Figure 2.2 illustrates a two bit half adder using a logic diagram. Both the XOR and the AND gate accepts the same two binary digits as input. The XOR gate produces the sum, while the AND gate produces the carry. The possible combinations and results are shown in figure 2.3.

A 0 1 0 1

B 0 0 1 1

Sum 0 1 1 0

Carry 0 0 0 1

Figure 2.3: Truth Table for Half Adder

t y

gen t'

x x fanout

y y

x z

and x1 y1 x2 y2

s

c

show y xor

x

s std_out output

z

Figure 2.4: Half Adder in Hw-Hume

Figure 2.4 models the HW-HUME program that represents the half adder in figure 2.2. The program consists of 5 boxes, in addition to the output stream. ‘gen’ is used to generate the binary input digits. In HW-HUME output from a box can only be wired to one destination. In the half adder the digits have to be wired to both the XOR and the AND gate. ‘fanout’ is used as a bridge that wires the input to both the gates. At the end the sum and carry is written to the standard output. The same way that the output of a box can only be wired to one destination, the output stream can only be wired with one FSA. To be able to write out the sum and the carry, the output of the ‘xor’ and ‘and’

boxes are wired to ‘show’. ‘show’ wires the two values to the output stream at the end.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

t y p e B i t = word 1 ; box gen in ( t : : i n t 6 4 ) out ( t ’ : : i n t 6 4 , x , y : : B i t ) match 0 −> (1,0,0) | 1 −> (2,0,1) | 2 −> (3,1,0) | 3 −> (0,1,1); box f a n o u t in ( x , y : : Bit ) o u t ( x1 , y1 , x2 , y2 : : B i t ) match (x,y) −> (x, y,x ,y ); box x o r in ( x , y : : Bit ) out ( z : : B i t ) match (0,0) −> 0 | (0,1) −> 1 | (1,0) −> 1 | (1,1) −> 0; box and in ( x , y : : Bit )

29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55

out ( z : : B i t ) match (0,0) −> 0 | (0,1) −> 0 | (1,0) −> 0 | (1,1) −> 1; box show in ( s , c : : Bit ) o u t ( s c : : ( B i t , B i t , char ) ) match ( s , c ) −> ( s , c ,’\ n ’); stream o u t p u t t o ” s t d o u t ” ; w i r e gen ( gen . t ’ i n i t i a l l y 0 ) ( gen . t , f a n o u t . x , fanout . y ) ; w i r e f a n o u t ( gen . x , gen . y ) ( xor . x , xor . y , and . x , and . y ) ; w i r e x o r ( f a n o u t . x1 , f a n o u t . y1 ) ( show . s ) ; w i r e and ( f a n o u t . x2 , f a n o u t . y2 ) ( show . c ) ; w i r e show ( x o r . z , and . z ) ( output ) ;

Figure 2.5: Source Code of the Half Adder in Hw-Hume

Figure 2.5 shows the HW-HUME source code of the half adder. This is used for reference when explaining the design of HW-HUME, and the translation to PROMELA in a later chapter. Note that the line numbers are not part of the source code. Types HW-HUME supports three base types. They are word, integers and characters. All these types are used in the example. Of the structure types, tuples are allowed, which are also included in the example. Line 1 declares that the type Bit is a word of 1 bit. All boxes uses the Bit type. Lines 4 and 5 declare that a 64 bit int is input and output respectively of the box. Line 38 declares that the output of the show box is a tuple that contains a char. The tuple consists of two Bit types, and the character. Line 40 shows that the only char that is used is the newline escape sequence ‘\n’.

Declaration Layer In HW-HUME four different declarations are allowed. They are the type declaration, box declarations, wire declarations and stream declarations. The example illustrates use of all the types. Line 1 illustrates the type declaration of a new type using the type keyword. It declares that the new type Bit is word using 1 bit. Lines 3 - 40 hold all the box declarations. Lines 44 - 55 hold the wire declarations corresponding to the box declarations. Line 42 holds an output stream declaration, saying that output is wired to standard output. Expression Layer HW-HUME consists of boxes wired together. Other parts of full HUME, like functions, have been removed. The body of the boxes only matches simple inputs, represented either as constants or as variables. This is also the case for the expressions that generate the output. The wild card ‘*’ represents that the input is ignored, is not allowed. The wild card can also be used to represent that no output is generated. This neither allowed in HW-HUME. Constructors, case expressions, conditionals and local declarations are also removed from full HUME. Line 7 - 10 shows an example of using just constants in the body of a box. Line 16 illustrates the use of variables in body of the box. Coordination Layer HW-HUME supports both boxes and templates, together with the wire declaration that wires a box to a box or a stream. Lines 3 - 10 declare the ‘gen’ box. It is a HW-HUME box consisting only of constants that are being matched to the input of the box. The type of the pattern on lines 7 - 10 that are matched, must correspond to the type in the input definition on line 4. The output, which is on the left hand side of the arrow ‘→’ must be of the same type as the corresponding types declared on line 5. Lines 44 - 46 hold the wire declaration that wires the ‘gen’ box. It has the same name as the box. It uses the initially keyword to set the initial value of the input variable to ‘0’.

Running the Program Figure 2.6 displays the output when running the half adder program. Note that the line numbers are used as reference and not part of the output. A program in HW-HUME is started the same way as a normal HUME program, by typing hume followed by the filename in a terminal. The program is terminated by pressing Ctrl-C. The figure shows two complete runs of each box. Lines 5 - 8 display the first run, and line 9 12 the second. The left side is the sum and the right side is the carry. When comparing the outputs with the truth table in figure 2.3, one can see that they are all identical.

1 2 3 4 5 6 7

$ hume h a l f . hume HUME 0 . 1 Tuesday 0 8 June , 2 0 0 4 , 1 6 : 3 1 RUNNING 0 0 1 0 1 0

8 9 10 11 12 13 14

0 1 0 0 1 0 1 0 0 1 . . . hume : i n t e r r u p t e d

Figure 2.6: Running the Half Adder

Chapter 3

Promela Overview 3.1 Introduction SPIN is a tool developed by Gerard. J. Holzmann at Bell Labs, USA, for which he received the ACM award [4]. It was designed to simulate and verify asynchronous process systems, with a focus on the interaction between processes[5, 20]. PROMELA is an imperative language, with a syntax that resembles C, and is used to specify the models SPIN is verifying [5]. SPIN is typically used to check for deadlocks, unspecified receptions and inexcusable code [19]. A SPIN model 1 consists of processes, message channels and variables[14]. Only a short introduction is given to PROMELA and SPIN . There are many books and articles that give deeper introductions on the subjects, many of which are available from SPIN’s homepage [32]. Note that SPIN is constantly being redeveloped and changed. Throughout this thesis version 4.1.3 from 24 April 2004 has been used and described. This version might differ from other versions of the tool.

3.2 Data Objects Type bit bool byte chan mtype pid short int unsigned

Typical Range 0,1 true, false 0..255 1..255 1..255 0..255 −215 ..215 − 1 −231 ..231 − 1 0..2n − 1

Figure 3.1: Basic Data Types [18]

In PROMELA a data type can be declared as either global or process local. Table 3.1 contains all the 1

Both the terms Spin model and Promela model are used to describe a model specified in Promela

15

basic data types in PROMELA. A bit can, like the name implies, be ‘0’ or ‘1’. A bool is a boolean value, which is either ‘true’ or ‘false’. A byte is an 8 bit numerical value, which can be in the range of ‘0’ to ‘255’. A message channel is identified by chan, and can contain 1 to 255 values (Please see section 3.4). An mtype is used to define enumerated types. Only one mtype can be declared using one or more declarations, and can hold a maximum of 255 values. It must be globally declared. A set of symbolic constants are declared as follows: mtype = { GO

, STOP , ERROR } ;

where each constant is separated by a comma. A variable holding such a constant must be of type mtype as illustrated below. mtype s t a t u s = GO;

A pid is assigned to each process, and is a numerical value from 0 to 255. PROMELA has two integer values - a 16 bit short and a 32 bit int. In the unsigned type the bit size of the type used must be specified. unsigned B i t : 1 = 0 ;

declares an unsigned value with the name ‘Bit’, the size of 1 bit, and with an initial value ‘0’. Constants are declared using a C style macro. The following declaration declares the constant ‘TRUE’ to have the value ‘1’. # d e f i n e TRUE 1

3.2.1 Structured Types PROMELA supports arrays and a mechanism for defining new records of variables. The array declaration byte a [ 3 ] = 2 ;

declares an array called ‘a’ of type byte with the 3 buffers, and the initial value is set to ‘2’. An element in the array is referred to in the same way as in C, by specifying the name and position in the array. A new record of structured types is declared using the typedef keyword. The following example will create a new record consisting of two bytes and an int: typedef myrecord { byte a , b ; mtype c } ;

A variable inside the record is reached using a dot ‘.’ notation. E.g. m y r e c o r d . c = ERROR ;

A channel can also be used as a structured type (section 3.4).

3.3 Processes A PROMELA model normally consists of a set of concurrent processes, each of them being a finite state automata (FSA). A process is declared using the proctype keyword, and is started with the run statement. The process can also accept a defined set of parameters. The declaration

p r o c t y p e s i m p l e ( chan o u t ; b y t e a , b ) { skip ; }

creates a process named ‘simple’. As parameters it accepts a channel named ‘out’, and two bytes ‘a’ and ‘b’. The process body only includes a skip statement, which does not do anything. If the active keyword is used as a prefix in the proctype declaration one process is initialised in the initial state. This cannot however accept any parameters. If n processes should be instantiated, where n is a positive integer, [n] must be appended after the active keyword. The following example creates three processes. a c t i v e [ 3 ] proctype simple ( ) { skip ; }

Another way to instantiate a process is by using the run command in a different process. The init process can be compared to the main method in JAVA and C. It is created in the initial state. In the following init process the simple process is instantiated. Note that the variables ‘a’, ‘c’ and ‘d’ must be declared to be channels and bytes. init { run s i m p l e ( a , c , d ) ; }

Note that semicolons ‘;’ or arrows ‘→’ are used to separate statements.

3.4 Message Channels A message channel is typically used to represent interprocess communication. The declaration chan q = [ 5 ] o f { b y t e , i n t }

declares a channel called ‘q’ which can hold 5 messages at a given time. Each message consists of a byte and an int. It is possible to send to a channel and receive from a channel. Expressions are sent to a channel by using the send ‘!’ operator. The statement q!a ,b

sends ‘a’ and ‘b’ to the channel. The variable ‘a’ must be declared to be of type byte and‘’b’ must be of type int. The send statement is only executable if the channel ‘q’ is not full, i.e. all buffers are not used. If it is full, the process trying to write to it is blocked. To receive a message from a channel the receive ‘?’ operator is used : q? c , d

The values in the message are stored into the variables ‘c’ and ‘d’ which must be declared to be of type byte and int respectively. The statement is executable only if the channel ‘q’ is not empty. If it is empty the process trying to read a message is blocked. Note that if ‘a’ and ‘b’ were replaced by constants, the process would be blocked if the message didn’t match them. Rendezvous communication (synchronous communication) is possible by giving a channel the buffer size of 0. The statement chan r = [ 0 ] o f { b y t e , i n t }

declares the channel ‘r’ to be a synchronous channel holding the same types as ‘q’. The capacity of ‘r’ is zero, which means it can pass, but not store, messages. The communication is now binary. A process sending a message to ‘r’ is blocked until another process tries to receive the message. At the same side a process trying to receive a message from ‘r’ is blocked until another process sends to the channel. It is also possible to use a channel as a structured type. A channel will have the same semantics as a FIFO (First In First Out) queue. An expression is added to the channel by sending and read by receiving. Channels can also be used to represent other data structures. A sorted send operation, insert a message in a different order and a random receive looks at all messages, and not only the first. The first match is then received. There is also a method to check if a received operation is possible, without the process being blocked. This is achieved by enclosing the right hand side of the receive operator ‘?’ in brackets ‘[]’. If it succeeds ‘1’ (true) is returned, if it fails it returns ‘0’ (false). In the following statement it is checked if a and b can be read from the channel. If the operation is possible, ‘1’ is returned, but the messages remains in the channel. If it fails, ‘0’ is returned. q?[ a , b ]

PROMELA includes a predefined function len(channel name), which returns the number of messages currently included in the channel. PROMELA also includes the functions empty(channel name), nempty(channel name), full(channel name) and nfull(channel name).

3.5 Execution Rules Any statement in PROMELA is either executable or blocked. A statement is executable if it evaluates to true, or equivalently to a non-zero integer value. Print statements and assignments are always executable. Statements are separated by a semicolon ‘;’ or an arrow ‘→’. A consequence of this is that if a process reaches a statement that can’t be executed and hence is blocked, the process also blocks; this leads to the busy wait loop while ( a ! = b ) skip ;

has exactly the same effect as the statement ( a == b )

which is blocked until it returns true. For assigning values the following assignments are valid in PROMELA. a = a + 1 ; a + + ; a = a − 1 ; a −−;

PROMELA also support conditional expression. To avoid confusion with reading input from channels, the PROMELA has the following form: ( expr1 −> expr2 : expr3 )

3.6 Control Flow PROMELA includes the following compound statements which are used to control the flow of a model:

Atomic sequences are sequences of statements that are defined to be uninterruptible. This means that as soon as the first statement in a atomic sequence is executed, no other process can interrupt until the last statement has completed its execution. It can only interrupt if a statement in the atomic sequence is unexecutable. An atomic sequence is defined using the atomic keyword. atomic { statement1 ; . . . ; statementn }

Deterministic steps are similar to atomic sequences. However, in deterministic steps the sequence is always executed as if it were a single statement. It is defined by specifying a d step sequence. d step { statement1 ; . . . ; statementn }

Selections in PROMELA are defined using the if keyword, and are ended by the fi keyword. Each option has a prefix of two colons ‘::’. if : : ( guard1 ) −> option1 : : ( guard2 ) −> option2 [ : : e l s e −> d e f a u l t o p t i o n ] fi

An option in the selection can only be chosen if the first statement, the guard, is executable. The different guards do not have to be mutually exclusive. In the case where they are not, one of the executable options is chosen nondeterministically. An optimal else statement can also be used. An else statement becomes executable only if no other statements are. The selection can only contain one else condition. Repetitions follow the same syntax as selections, however they are started by the do keyword and ended with the od keyword. do :: :: :: [:: od

( guard1 ) −> option1 ( guard2 ) −> option2 ( g u a r d 3 ) − > break e l s e −> d e f a u l t o p t i o n ]

The loop is broken using the special break statement, or by goto a label. Goto and labels can be used to control the process flow. A label is an identifier followed by a colon ‘:’. Labels starting with end, progress or accept have a special meaning in PROMELA, covered later in the chapter. The goto keyword followed by the label name, will force the program control to go to the first statement after the label. This approach can also be used to define repetitions, as the following example shows. label name :

statement1 ; . . . ; statementn ; goto l a b e l n a m e

Inline definitions are created using the inline keyword i n l i n e name ( p a r a m e t e r l i s t ) { statement1 ; . . . ; statementn ; }

The PROMELA parser simply replaces each point of invocation of an inline with the text inside it. The types in the parameterlist are not specified, only the variable name.

3.7 Predefined Statements, Variables and Functions PROMELA includes several predefined statements, functions and variables. One of them is the printf function that prints a string to the screen. The basic statement p r i n t f ( ” Value : % d \ n ” , a )

prints out the string Value: followed by the value of the variable called a. It also ends the line. There is also a printm variant, that prints the symbolic name of an mtype. The ‘ ’ variable is a write-only variable, and is mainly used for so called “do not care values”.‘ pid’ is of type pid and can be used in each process to reference their own unique process number.

3.8 Specifying Behaviour There are several ways of specifying the desired and error behaviour of the model. When model checking there is a separation between safety, liveness and fairness properties. A safety property expresses something that never occurs under certain conditions [5]. An example of a safety property is a deadlock. A liveness property expresses something that will ultimately occur on certain conditions [5]. There are also several examples of liveness properties. One example is “in a traffic light the light will eventually turn green”. A fairness property expresses that under certain circumstances something will or will not occur infinitely often [5]. SPIN includes the following means to specify behaviour: Basic assertions are the simplest form and have the syntax assert ( expression )

Basic assertions are always executable, and must always evaluate to true. They can be checked at any time, and if they evaluate to false an error message is printed out. End state labels are meta labels starting with the ‘end’ prefix. It is a special kind of label used when SPIN is run in verification mode. End state labels are used to distinguish valid system end states from invalid ones when checking for deadlocks. Progress state labels are also meta labels, but starting with the ‘progress’ prefix. These labels are used to mark statements that accomplish something desirable, i.e. that the process is making

progress. The labels can be used to verify that every possible execution cycle passes through the progress label at least once. Accept state labels are meta labels starting with ‘accept’. The presence of an accept state label expresses that there should not be any executions that pass through an accept state label infinitely often. Never claims are used to check properties at every execution step of a system. The are normally used to specify behaviour that should never occur. A never claim has the following syntax: never { statement1 ; . . . ; statementn ; }

The code in the never claim is executed before and after each statement execution. A claim termination, i.e. reach the end of the code, indicates that an error behaviour has occurred. Trace assertions expresses properties of message channels. It has the following syntax: trace { statement1 ; . . . ; statementn ; }

They apply only to send and receive operations on message channels, and can be used to specify a specific relative order in which these operations must be performed. Sequences that should not occur can be specified by replacing trace with notrace. Temporal Logic is a formalism for describing a sequence of transitions between states in a system [8]. It is the branch of logic that allows one to reason about both causal and temporal relations of properties [20]. It has been proven to be of use for specifying concurrent systems, because they can describe the ordering of events in time without introducing time explicitly [8]. A special form of temporal logic, known as linear temporal logic (LTL), is used in SPIN to specify properties. By using LTL, properties that cannot be expressed using claims can be expressed. For instance suppose we want to model that every time a door opens it will eventually close. If ‘p’ implies that the door opens and ‘q’ that it closes, the following LTL formula specifies that each time a door opens, it will eventually close. (p → 

q)

The ‘ ’ denotes always, the ‘→’ denotes implication and the ‘ ’ denotes eventually. The 

sentence is then read “always if p then eventually q”.

3.9 Introduction to Spin SPIN is a system that supports the design and verification of asynchronous process systems [20]. SPIN is the tool used to check the verification model, specified using the PROMELA specification language.

The name of SPIN was originally chosen as an acronym for Simple PROMELA INterpreter[18]. SPIN has now outgrown that term, but the name has remained. SPIN can be used in two different modes. It can either be used as a simulator or as a verifier [18]. For proving that properties hold the verifier must be used, while the simulator is used mainly for debugging and error identification and correction.

3.9.1 Spin Structure Figure 3.2 is shows the basic structure of the SPIN model checker. An optimal graphical front-end called XSPIN can be used with SPIN. A good feature in XSPIN is the LTL editor, which simplifies the inclusion of LTL formula in a SPIN model. A more detailed introduction to how to use the tool can be found in [18]. There are also other GUI that can be used. One of them is JSPIN[23]. First the PROMELA code is parsed, so it can be used. If LTL has been used this must be parsed separately and appended to the model. Syntax errors must then be checked before SPIN enters either the simulation mode or the verification mode. Typically the model is first used in simulation mode for debugging. To be able to prove the specified properties the model must be executed in verification mode. If an error behaviour is found, the verifier produces an output trail which the interactive simulator can use to find the error.

Figure 3.2: The Spin Structure [20]

3.9.2 Execution Rules In SPIN the next statement to be executed is the next in a randomly selected runnable process. Depending on the mode, and the arguments to SPIN, the selection of the statement to be executed differs. In simulation mode the user can select between random, interactive and guided simulation. In random simulation the statement to be executed is always decided randomly. In interactive simulation the user interacts with the program and chooses the next statement that SPIN should execute. In guided simulation SPIN starts from a failed validation, and follows the same path in order to find the error. In verification mode all possible paths are searched.

Chapter 4

Translating Hw-Hume into Promela 4.1 Introduction This chapter explains the translation from a HW-HUME program into PROMELA. The semantic rules for the translation are described in appendix B. The appendix includes a more formal presentation of the translation, and is referred to throughout the chapter. The first sections of the chapter follow the structure of the appendix. In these sections the half adder from section 2.8 is used as an example to illustrate the translation to PROMELA. The logic diagram of the half adder is illustrated in 2.2 on page 11, while figure 2.4 on page 11 models the half adder for HW-HUME. The HW-HUME source code is listed in figure 2.5 on page 12. Section G.1 in appendix G lists the generated PROMELA code. Several other examples have also been translated. Appendix F contains the listings for the HW-HUME source code, while appendix G holds the generated PROMELA code. All the translation rules are found in appendix B. A rule taxonomy has been introduced, where the rules are classified according to their context. A special rule classification. The syntax for each rule used is:

font

is used to refer to a particular

Ruletype ~ hHW-HUME codei  7→ hPROMELA codei | Reference ~ hargumentsi  The HW-HUME code is on the right hand side of the mapping arrow ‘7→’, and the result of using the rule is on the left hand side. The HW-HUME code is enclosed by semantic brackets ‘~ ’. The right hand side may contain PROMELA code, and references to other rules. The references use the semantic brackets to enclose the parameters. A bold font is used for the PROMELA code produced from the rules. Each rule contains a reference to the rule number in appendix B. In section 4.10 a simple ‘nor’ gate has been translated by using the translation rules.

4.1.1 Structure of the Promela Program In a PROMELA model all the global variables used by a process must be declared before they are used. In the translation the only global variables are channels. The PROMELA representation of the HW-HUME program has two semantically different channels. There is a need to translate the execution model in HW-HUME into the PROMELA model. This is solved by a synchronous channel from a special control process to each of the processes. The 23

1. Channel Declaration 1.1 Control Channels

1.2 Interprocess Channels

2. Process Declaration

3. Control Process Declaration

4. Stream Process Declaration 4.1 Input Streams

4.2 Output Streams

5. Init Process Declaration

Figure 4.1: The Structure of the Translation

enumerated type used in this channel must also be declared. The other channels are used for the interprocess communication. Each HW-HUME box is represented in PROMELA by a process. The boxes are translated into PROMELA processes after the channel declarations. The control process used for the synchronisation between the processes is then created. In HW-HUME input streams and output streams are allowed. The streams are represented as processes in PROMELA. At the end the init process is created. Figure E.1 illustrates the order of the PROMELA code in the created file. The code is consequently created in the same order. This structure is followed throughout the chapter.

4.2 Data Types In appendix B Types denotes the rules for translating the data types from HW-HUME into PROMELA. The base types word, int, and char are included in HW-HUME. The word and int types are represented in PROMELA by using bit, short or int, depending on the bit size of the type. A PROMELA byte can also be used to represent a word. For characters the Unicode representation is used, since characters cannot be represented in PROMELA. As a consequence the characters are translated into a PROMELA short. For tuples, each item in the tuple is translated separately, and all the items are separated by a comma. This translation is performed since channels are used to represent structured types in the PROMELA representation. In a channel, each item is separated by a comma. Section B.2 defines Types , and includes a discussion on the choices made.

4.3 Values While Types translates the type declaration, Values translates the instances of the different values. For the two HW-HUME integer representations, word and int, the PROMELA representation uses the same value as in HW-HUME. SPIN will automatically truncate the values to ‘0’ if they exceeds the

maximum size. Characters are translated to a positive integer holding an Unicode. Escape sequence will be given a unique negative value. Tuples are translated the same way as in Types , where each

item is separated by a comma. Section B.3 defines Values .

4.4 Names In most cases the names used in HW-HUME can be used directly in PROMELA. However, there are two exceptions. The first exception is the terminals. The set of terminals included in PROMELA differs from the set in HW-HUME. If a non-terminal in HW-HUME is a terminal in PROMELA, ‘1’ is appended at the end of the name in the translation. The second exception is the single quotation mark ’. It is possible to use this in HW-HUME names, but not in PROMELA. In the translation each quotation mark is replaced by the letter ‘q’.

Names is defined in section B.4, and ensures that the names in

PROMELA are valid.

4.5 Channels The first piece of PROMELA code that is created is the channels. There are two semantically different channels, the control channels and the channels used for the interprocess communication. In both cases the ‘gen’ box from the example is used for illustration. Figure 4.2 lists the HW-HUME source code for the box.

1 2 3 4 5 6 7 8

box gen in ( t : : i n t 6 4 ) out ( t ’ : : i n t 6 4 , x , y : : B i t ) match 0 −> (1,0,0) | 1 −> (2,0,1) | 2 −> (3,1,0) | 3 −> (0,1,1);

Figure 4.2: Source Code for the ‘gen’ Box

4.5.1 Control Channels The semantics for control channels are denoted by

ControlChan

in section B.5.1. The control

channels are used to coerce all processes to run in a sequential order, which is the execution model found in HW-HUME. This is achieved by using a sequential channel between a special control process and each process. Before each run a process has to wait for a ‘BEGIN’ signal from the control process, and is consequently blocked until the message is received. When the process receives the message and has finished one run, an ‘END’ signal is returned to the control process, indicating that the run is finished, and the process returns to the initial state where it waits to receive a ‘BEGIN’ message again.

In the PROMELA representation a process is created for each box and each stream. For each of the processes a synchronous channel must be created. To make the code more readable a PROMELA mtype is used as a message in the channels. The mtype holds a ‘BEGIN’ and ‘END’ type, and is first declared. The declaration is followed by the creation of a control channel for each box and each stream. In both cases the name of the box/stream followed by ‘ control’ is used as a channel name.

Names must be applied to ensure that the names are valid PROMELA. Figure 4.3 illustrates this, by showing how the channel for the ‘gen’ box is created. The left hand side of the thick dashed line is the HW-HUME code, and the right hand side is the corresponding PROMELA code. This syntax has been used in all translation illustrations in this chapter.

Figure 4.3: Creating Control Channels

Figure 4.4 lists all the control channels in the PROMELA model, together with the mtype declaration. Note that on line 7 the HW-HUME name ‘show’ has been replaced by ‘show1’. The reason is that ‘show’ is a terminal in PROMELA, and Names consequently appends ‘1’ at the end of it. 1 2 3 4 5 6 7 8

mtype = { BEGIN , END } ; chan chan chan chan chan chan

g e n c o n t r o l = [ 0 ] o f { mtype } ; f a n o u t c o n t r o l = [ 0 ] o f { mtype } ; x o r c o n t r o l = [ 0 ] o f { mtype } ; a n d c o n t r o l = [ 0 ] o f { mtype } ; s h o w 1 c o n t r o l = [ 0 ] o f { mtype } ; o u t p u t c o n t r o l = [ 0 ] o f { mtype } ;

Figure 4.4: All the Control Channels in the Half Adder

4.5.2 Interprocess Communication In HW-HUME, boxes communicates with each other, and streams, by wiring them together. In a wire an input or output variable in the box is wired to another output or input variable in a box, or to a stream. Note that an input variable is wired to an output variable or an input stream, and an output variable is wired to an input variable or an output stream. In the PROMELA representation of HW-HUME, channels are used to represent the interprocess communication. For each output variable in a box a channel is created. Each channel is given the name of the box followed by an underscore ‘ ’ and then the name of the variable.

Names

must be applied to both the HW-HUME box and variable name to ensure a valid PROMELA name. The message type in the channel is the PROMELA representation of the HW-HUME variable’s type. To obtain the PROMELA representation,

Types

is applied to the HW-HUME type. The length of the

channel is 1, which resembles a HW-HUME wire. Figure 4.8 illustrates the creation of the channel for the t’ variable in ‘gen’. Note that Names replaces the single quotation mark ’ with the letter ‘q’.

Figure 4.5: Creating Channels for Interprocess Communication

Since the output variables in HW-HUME boxes are used to generate the channels, and output streams do not generate any input to other processes, no channels are created from a HW-HUME output stream. Input streams generate exactly one output. A channel must be generated for that input. The channel is given the name of the input stream, followed by ‘ out’. Again Names must be applied to the name of the stream. The creation of this stream is more cumbersome than in the illustrated example. The reason for this is that to find the type of the stream, the wire and box declaration that use the stream are required. The semantics for the interprocess communication is denoted by Chan and is described in section B.5.2. Figure 4.6 shows all the PROMELA channels that are created for the interprocess communication in the half adder example.

1 2 3 4 5 6 7 8 9 10

chan chan chan chan chan chan chan chan chan chan

gen tq = [ 1 ] of { i n t } ; gen x = [ 1 ] of { b i t } ; gen y = [ 1 ] of { b i t } ; fanout x1 = [ 1 ] of { b i t fanout y1 = [ 1 ] of { b i t fanout x2 = [ 1 ] of { b i t fanout y2 = [ 1 ] of { b i t xor z = [ 1 ] of { b i t } ; and z = [ 1 ] of { b i t } ; show1 sc = [ 1 ] of { b i t

}; }; }; };

, bit , short } ;

Figure 4.6: Channels for Interprocess Communication in the Half Adder

4.6 Processes When all channels have been created the HW-HUME boxes are translated into PROMELA processes. This part of the translation is quite cumbersome. Therefore it has been divided into three different parts. The first part, denoted by

Prelude , creates the prelude, or the signature, of the process.

In

HW-HUME variables are declared in a pattern match. In PROMELA they must be declared before they can be used. The second part of the translation process declares these variables, and is denoted by

Vars .

The last part creates the main body of the process. This part is denoted by

Body .

In

that part it translates the matches and synchronises the process with the control process. The HWHUME ‘show’ box, displayed in figure 4.7, is used to illustrate the translation of HW-HUME boxes to PROMELA processes.

1 2 3 4 5

Proc denotes the process creation. The rules are defined in section B.6.

box show in ( s , c : : Bit ) o u t ( s c : : ( B i t , B i t , char ) ) match ( s , c ) −> ( s , c ,’\ n ’);

Figure 4.7: The ‘show’ Box

4.6.1 Process Prelude A PROMELA process is identified by the proctype keyword, followed by the name of the process. The PROMELA process name is the HW-HUME name, translated by using Names . The process signature also includes a parameter list. It contains the input, output and control channels, thus all parameters are of type chan. The init process is responsible for mapping the correct channels to the correct processes (see section 4.9). In the parameter list all input channels are created from the input variables in the HW-HUME box prelude. One channel is created for each variable. Each channel is given the name ‘in’ followed by a number indicating the relative position of the input variable. The output channels are created in the same manner, with the difference being that each channel is created from the output variable in the HW-HUME box prelude. The name of each output channel is ‘out’ followed by a number indicating its relative position of the output variable. At the end of the parameter list, the control channel is defined. It is given the name ‘control’. Figure 4.8 illustrates the creation of the prelude of the ‘show’ box.

Prelude in section B.6.1 defines the creation of the

process prelude.

Figure 4.8: Creating The Process Prelude

4.6.2 Variable Declaration In PROMELA all variables must be declared before they can be used. To define a variable the name and type of the variable are needed. The name is obtained from a pattern match, while the type is

acquired by using the input element of the box prelude. For each variable declaration in a pattern match, the corresponding type must be identified from the box prelude. The ‘show’ box includes two variables ‘s’ and ‘c’, for which figure 4.9 illustrates the translation. Note that for each variable in a pattern match, the type from the corresponding input variable in the input element must be obtained. This is achieved by keeping track of the relative position of the two elements. In a process a variable can only be declared once.

Vars in section B.6.2 defines the semantics for the variable

declarations.

Figure 4.9: Creating Variable Declaration

4.6.3 Process Body The process body is defined by Body .There are two semantically different bodies, using fair or unfair matching. In both cases however, the process must be synchronised with all the other processes via the control process. This is achieved by first receiving a ‘BEGIN’ message from the control message, and returning an ‘END’ message when one run is completed. The process then waits for a new ‘BEGIN’ message, as illustrated in figure 4.10. To gain infinite repetition a ‘start’ label and the goto statement is used. The ‘finish’ label is used when the input does not match any of the patterns.

1 2 3 4 5 6 7 8

start : c o n t r o l ?BEGIN ;
finish : c o n t r o l !END; goto s t a r t ;

Figure 4.10: General Body Code The HW-HUME boxes that use fair matching will have a different main body than the boxes using unfair matching. However, the translation of each match is similar. Section B.6.3 describes the creation of the main body of a process.

Fair Matching Fair matching is denoted by Fair . In HW-HUME fair matching is specified by the fair keyword. In PROMELA the fair matching is achieved with an if clause. Each match is an option in the if clause, specified with a double colon ‘::’ prefix. The first statement in a match is called the guard condition. If it succeeds the rest of the statement in that option is executed. The guard condition in the PROMELA for HW-HUME implementation is to check if the receive operation succeeds on the input channels. The guard conditions do not have to be mutually exclusive. If several of the options succeed, one of them is randomly selected, giving the if clause a non-deterministic and fair nature.

Figure 4.11: Fair Matching

In PROMELA the process will be blocked if none of the guard conditions succeed when the input is matched. In HW-HUME the only thing that happens is that no output is generated and the next box starts executing. To translate this behaviour into the PROMELA model, an else statement is appended after the last match. The code that follows will execute if all other guard conditions fail. In the else option the process control is redirected to the ‘finish’ label using the goto statement. The ‘finish’ label is placed right after the point the if clause ends. This approach is illustrated with two matches in figure 4.11. Unfair Matching Unfair matching is denoted by

Unfair

and is more cumbersome to translate than fair matching.

Unfair matching is identified by the match keyword in the box body, and is performed in a top to bottom order, giving it a deterministic nature. This cannot be represented directly in PROMELA hence it must be manually implemented. The solution is to use a set of if-else statements, as figure 4.12 shows.

Figure 4.12: Unfair Matching

The first match has a different semantics since it does not start with an else statement. The fact that an if statement has to be ended with a fi statement complicates the translation further. The reason for this is that for each match, the code for all the following matches must be translated before the match can be ended with the fi statement. The figure shows this with the first if statement being ended with the fi statement, after all the code for the second match. As for Fair , the last if statement is ended with an else statement that redirects process control to the ‘finish’ label using the goto statement. This will happen if none of the options match the input.

4.6.4 Matches The translation of one match is denoted by Match . Match uses matches and Exp to translate the expression that generates output.

Patt

for translating pattern

The ‘show’ box in figure 4.7 uses unfair matching. However, in this special case it does not really matter since the box only contains one match. In the PROMELA representation a pattern is matched by checking the input channels. The inputs are then received and omitted from the input channels, followed by sending the outputs to the output channels. The ‘show’ box contains two input variables and one output variable. Therefore in the PROMELA process prelude, two input channels ‘in1’ and ‘in2’ and one output channel ‘out1’ were created. These channels are used.

Figure 4.13: Creating Channels for Matching

The output of the box is a tuple. This is not reflected in the match obtained from the body element, as figure 4.7 shows. This complicates the translation, since the box prelude must be used during the translation of each match, as the prelude keeps track of the type of the variable, i.e. whether or not the type is a tuple. If it is a tuple, all the values are sent over the same channel. If it is not a tuple they are sent on different channels. Figure 4.13 shows the prelude for the ‘show’ box and illustrates how this is created in PROMELA. The translation of the values is ignored in the figure. In the match in figure 4.13, the channels are first checked to test if the operation succeeds. The testing is achieved by enclosing the right hand side of the receive operator ‘?’ in brackets ‘[ ]’. This test is the guard condition. An arrow ‘→’ separates it from the rest of the body. If the guard condition succeeds the values are read and omitted from the channel, and the output is sent to the output channel. The channel references are created based on the variables in the box prelude. The input channels only hold base values, which makes the translation operation straightforward. The tuple in the output is more cumbersome to translate. Figure 4.14 illustrates the translation of it.

Figure 4.14: Creating Values in Matches

In the PROMELA code on the right hand side of the thick dashed line, each element in the expression is separated by a comma. During the translation the output element in the box prelude is traversed. For each variable in the output element, the corresponding element in the match is obtained, and translated using Values . If the element is a tuple, as the case in figure 4.14, each element in the tuple is translated separately. Each of the element is then appended to the right hand side of the send operator ‘!’ of the output channel, separated by a comma. The variables ‘s’ and ‘c’ use the same name in PROMELA as in HW-HUME. The newline escape sequence character however, is translated into the numeric value ‘-1’, as defined in Values . Figure 4.15 shows the ‘show’ process. It is the PROMELA representation of the ‘show’ box listed in figure 4.7.

1 2 3 4 5 6 7 8 9 10 11 12 13

p r o c t y p e show1 ( chan i n 1 , i n 2 , o u t 1 , control ) { bit s ; bit c ; start : c o n t r o l ?BEGIN ; if : : ( i n 1 ? [ s ] && i n 2 ? [ c ] ) − > i n 1 ? s ; i n 2 ? c ; o u t 1 ! s , c , − 1 ; : : e l s e goto f i n i s h fi ; finish : c o n t r o l !END; goto s t a r t ; }

Figure 4.15: The ‘show1’ Process

4.7 The Control Process The creation of the control process is denoted by Control . The control process is used to coerce the execution model in HW-HUME into the PROMELA model. Each run in a process will then execute in a sequential order, starting with the process that was first declared. The stream processes also follow this execution model. Since a HW-HUME box was used as an example when illustrating the creation of a channel, the ‘output’ stream is used in figure 4.16.

As shown in the figure the name of the process followed by ‘ control’ identifies the channel. For processes generated from HW-HUME boxes, the box name is also used. Names ensures that the name is valid PROMELA.

Figure 4.16: Creating the Control Process

First a ‘BEGIN’ message is sent to the channel, and then the control process is blocked until an ‘END’ message is returned. It is blocked because the channel is synchronous. Since the other processes must receive a ‘BEGIN’ message before they can execute, the process that last received a ‘BEGIN’ message is the only runnable process. The control process for the half adder example is shown in figure 4.17.

1 2 3 4 5 6 7 8 9 10

Control

is defined in section B.7.

a c t i v e proctype C o n t r o l ( ) { do : : g e n c o n t r o l ! BEGIN ; g e n c o n t r o l ?END; f a n o u t c o n t r o l ! BEGIN ; f a n o u t c o n t r o l ?END; x o r c o n t r o l ! BEGIN ; x o r c o n t r o l ?END; a n d c o n t r o l ! BEGIN ; a n d c o n t r o l ?END; s h o w 1 c o n t r o l ! BEGIN ; s h o w 1 c o n t r o l ?END; o u t p u t c o n t r o l ! BEGIN ; o u t p u t c o n t r o l ?END; od ; }

Figure 4.17: The Control Process

4.8 Stream Processes HW-HUME supports both input streams and output streams. In both cases the stream declaration, the wire declaration that wires the stream to a box, and the box declaration that uses the stream, are required to create the PROMELA process. declarations.

Stream

Stream is used to obtain the elements required from these

is also used when generating the channels for interprocess communication

for input streams. This is defined in section B.8.

4.8.1 Input Streams The half adder model does not include any input stream. To explain input streams a few modification have been applied to the model in figure 2.5. An input stream has been introduced and the input for the ‘gen’ box is obtained from that stream. The source of the stream is the standard input.

The output that ‘gen’ wires to itself in figure 2.5 has also been removed. Figure 4.18 illustrates the modification applied to the model in figure 2.5. These declarations are found using Stream .

Stream also extracts the elements required from each of the declarations. 1 2 3 4 5 6 7 8 9 10 11 12

box gen in ( t : : i n t 6 4 ) out ( x , y : : B i t ) match 0 −> (0,0) | 1 −> (0,1) | 2 −> (1,0) | 3 −> (1,1) ; stream i n p u t from ” s t d i n ” ; w i r e gen ( i n p u t ) ( f a n o u t . x , f a n o u t . y ) ;

Figure 4.18: The Modified ‘gen’ Box A PROMELA model has to be run in a closed environment to be verified with SPIN. As a consequence the model cannot accept any input from the environment (users or files). An input stream in HW-HUME streams values from the environment, and thus it cannot be allowed in PROMELA . In the PROMELA representation this is solved by creating a process that simulates the input from the users. Since only integer values are allowed in PROMELA for HW-HUME, the simulator simply uses variables that are incremented by one each run, and sent to the output stream. The PROMELA “input stream process” uses the same name as the input stream in HW-HUME. The created process does not have any parameters, and is declared to be active to initially instantiate a process. Inside the process the output channel where the stream is sending the values, is obtained. The name of the channel is the name of the input stream, followed by ‘ out’. The variable ‘out’ is set to refer to the channel, as shown in figure 4.19.

Figure 4.19: Creating the Reference to the Stream for the Input Stream Process

In each run, the input stream sends the current values of the declared variables to the output channel, and increments the variables by one. There will always be one or more variables. To create the variables, the input variable in in the HW-HUME box that the stream is wired to is used. This is shown in figure 4.20. As the figure illustrates, each variable is given the name ‘var’, followed by an unique number indicating its position in the input variable of the HW-HUME box that it was translated from. In this example it is only a base type, but if it was a tuple several variables would have been created.

Types

Figure 4.20: Creating the Reference to the Input Stream Variables

is used to obtain the correct PROMELA type. The last part of the process is the main body. It follows the same execution model as the other processes, i.e. it must receive a ‘BEGIN’ message before each run, and send an ‘END’ message at the end of each run. This has already been shown for the processes generated from boxes (figure 4.10). In the main body the process first checks if the channel can be sent to. It can only be sent to if the channel is empty. This is achieved with the predefined ‘empty()’ function. If it succeeds the variables are sent to the output stream, and incremented by one. Figure 4.21 illustrates how this code is generated.

Figure 4.21: Creating the Input Stream Body

As the figure illustrates, the expression type of the variable in the box that uses the stream is used to refer to the variable. This because the variable might be a tuple. For each element in the expression type, ‘var’ followed by a number indicating the position (in the tuple) is appended to the right hand side of the send operator ‘!’. Each element is separated by a comma. The variables are also incremented by one after the send statement has succeeded. Figure 4.22 contains the generated PROMELA code that simulates the user input in the updated half adder example listed in figure 4.18. The translation of input streams is denoted by InStream and defined in section B.8.1.

4.8.2 Output Streams The half adder includes an output stream. It is named ‘output’ and prints the values to standard output. The stream is used by wiring the output from the ‘show’ box to the stream. The stream declaration, together with the wire and box declaration for ‘show’, are required to translate the stream. The elements are shown in figure 4.23. Since an output stream cannot manipulate a model, it is allowed during verification in SPIN. However, PROMELA only supports streams to standard output. Consequently all output streams will

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

a c t i v e proctype i n p u t ( ) { chan o u t = i n p u t o u t ; i n t var1 = 0 ; start : i n p u t c o n t r o l ?BEGIN ; if : : ( empty ( o u t ) ) − > o u t ! v a r 1 ; v a r 1 ++; : : e l s e goto f i n i s h fi ; finish : i n p u t c o n t r o l !END; goto s t a r t ; }

Figure 4.22: The Input Stream Process

1 2 3 4 5 6 7 8 9

box show in ( s , c : : Bit ) o u t ( s c : : ( B i t , B i t , char ) ) match ( s , c ) −> ( s , c ,’\ n ’); stream o u t p u t t o ” s t d o u t ” ; w i r e show ( x o r . z , and . z ) ( o u t p u t ) ;

Figure 4.23: The Output Stream Declarations be sent to standard output, regardless of the destination in the HW-HUME model. To verify the model in SPIN, the destination of a stream is not important, only the existence of the stream. This implies that nothing important will be abstracted away in this modification. As for input streams, an output stream is translated into a PROMELA process. This translation is denoted by OutStream . To obtain all the required elements it uses Stream . An output stream process is very similar to an input stream process. It only has some minor modifications. As with the input stream, the process uses the same name as the HW-HUME stream, ensured to be valid PROMELA by using Names . It does not have any parameters. It uses the active keyword as a prefix to initially instantiate a process. The channel from which the stream receives the messages must be obtained. This is achieved by using the variable that is wired to the stream. This is illustrated in figure 4.24. As the figure shows, the channel is called ‘in’ and

Names

is used to ensure that the name is

a valid PROMELA name. The process receives values from the channel and assigns them to a set of variables. These variables must be declared. This is achieved in the same way as the input stream process. The only difference is that the variables are not initialised. This is illustrated in figure 4.25. The figure shows the translation of a tuple. For each element in the tuple a variable is created

Figure 4.24: Creating the Reference to the Output Stream Channel

Figure 4.25: Creating the Output Stream Variables

with the name ‘var’, followed by an integer indicating the position in the tuple.

Types

is used to

obtain the correct PROMELA type. Also note that the type ‘Bit’ is of type ‘word 1’. In the main body of the process it is first checked if it is possible to read from the input channel, achieved by enclosing the right hand side of the receive operator ‘?’ in brackets ‘[ ]’. If this succeeds the content of the message is assigned to the declared variables and printed to standard output using the predefined ‘printf()’ function. This is illustrated in figure 4.26.

Figure 4.26: Creating the Main Body of the Output Stream Process

Each PROMELA variable created from the tuple in the figure is separated by a comma when it is read from the channel. This is the case both in the guard condition where the channel is just checked, and when the channel is actually read from. In the ‘printf()’ function, ‘%d’ must be used in the string to reference a variable, which is in the variable list following the string. This means that for each variable ‘%d’ must be added to the string, and a reference to the variable must be added to the parameter list following the string. Figure 4.27 lists the the source code of the PROMELA process

created from the HW-HUME ‘output’ stream declaration.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

OutStream is defined in section B.8.2.

a c t i v e proctype o u t p u t ( ) { chan i n = s h o w 1 s c ; b i t var1 ; b i t var2 ; short var3 ; start : o u t p u t c o n t r o l ?BEGIN ; if : : ( in ?[ var1 , var2 , var3 ] ) − > in ? var1 , var2 , var3 ; p r i n t f (”%d %d %d \ n ” , v a r 1 , v a r 2 , v a r 3 ) : : e l s e goto f i n i s h fi ; o u t p u t c o n t r o l !END; goto s t a r t ; }

Figure 4.27: The Output Stream Process

4.9 The Init Process The creation of the init process is denoted by Init and is divided into two distinct parts. The first part is concerned with initialising the channels, denoted by ChanInit . It is applied when an initial

value is specified with the initially keyword in a HW-HUME wire declaration. In the half adder, only the input channel of the ‘gen’ box has an initial value. Figure 4.28 illustrates the initialisation of that channel.

Figure 4.28: Creating the Channel Initialisation

Note that

Names

is applied to the names, and

Values

to the value to ensure that the created

code is valid PROMELA. If Names had not been used on the t’ variable, SPIN would have produced a syntax error, since quotation marks are not allowed. The second part of the init process is the instantiation of the processes. This is denoted by

ProcInst . When instantiating a process the corresponding channels must be obtained, and sent as actual parameters. Since the channels were created based on the output variables in the box prelude, the output channels can be created based on the same elements. To obtain the input channels, the

corresponding wire declaration is used. The name of the control channel is simply the box/wire name followed by ‘ control’. Figure 4.29 instantiates the ‘gen’ process.

Figure 4.29: Creating the Instantiation of Processes As shown in the figure, Names must be applied to all the names. The process name is created based on the name of the wire. This is also used as a prefix to all the variables when creating the output channels. This cannot be applied when obtaining the input channels. This is because the input can descend from other processes, even though in this example the input descends from itself. Figure 4.30 contains the init process. The creation of the init process is denoted in section B.9. 1 2 3 4 5 6 7 8 9 10 11

init { gen tq !0; run gen ( g e n t q , g e n t q , g e n x , g e n y , g e n c o n t r o l ) ; run f a n o u t ( g e n x , g e n y , f a n o u t x 1 , f a n o u t y 1 , fanout x2 , fanout y2 , fanout control ) ; run x o r ( f a n o u t x 1 , f a n o u t y 1 , x o r z , x o r c o n t r o l ) ; run and ( f a n o u t x 2 , f a n o u t y 2 , a n d z , a n d c o n t r o l ) ; run show1 ( x o r z , a n d z , s h o w 1 s c , s h o w 1 c o n t r o l ) ; }

Figure 4.30: The Init Process

4.10 Using the Translation Rules In this section a simple ‘not’ gate is translated by applying the translation rules defined in appendix B. The syntax for translation is described in the introduction. The rule number used is enclosed in parentheses on the right side of the rule. Figure 4.31 lists the source code of the HW-HUME ‘not’ box declaration that is translated. The creation of a PROMELA process from a box is divided into three distinct steps. First the prelude is created. If there are any variables, they are then declared. At the end the main body is created. The two last steps are inside the body of the process, which are enclosed by brackets ‘{}’.

Proc ~ hboxdecli  7→ Prelude ~ hboxdecli  { Vars ~ hboxdecli  Body ~ hboxdecli  }

(35)

box n o t in ( a : : i n t 1 ) out ( a ’ : : i n t 1 ) fair 0 −> 1| 1 −> 0;

Figure 4.31: The Hume Code of the ‘NOT’ gate

4.10.1 Process Prelude The creation of the PROMELA process prelude is divided into two parts, the creation of the process name, and the creation of the parameter list.

Prelude ~ hboxdecli  7→ Prelude ~ name hboxdecli  Prelude ~ param hboxdecli 

(36)

Name Definition The name definition starts with the proctype keyword which identifies that a process is being declared.

Names is used on the box name to ensure that the translated name is valid PROMELA.

Prelude ~ name box hboxidi hpreludei hbodyi  7→ proctype Names ~ Names ~ not  7→ not

hboxidi 

(37) (19,20)

Defining Parameters The parameters for the PROMELA process are created using the prelude of the box.

Prelude ~ param box hboxidi hpreludei hbodyi  7→ Prelude ~ hpreludei 

(38)

To create the input channels, the input elements are used, and to create the output channels the output elements are used. In this case there is only one of each, in addition to the control channel. The control channel uses the name ‘control’.

Prelude ~

in ( a :: int 1 ) out ( a’ :: int 1)  7→ ( chan Prelude ~ in a :: int 1  , Prelude ~ out a’ :: int 1  , control )

(39)

Each input channel is given the name ‘in’ followed by a number indicating the position in the list. The HW-HUME box only has one input element, which is given the name ‘in1’ in the PROMELA representation.

Prelude ~ in a :: int 1  7→ Prelude ~ in a  Prelude ~ in a  7→ in1

(41) (42)

The input channels are created in a similar manner. There is only one output channel, which is named ‘out1’.

Prelude ~ out a’ :: int 1  7→ Prelude ~ out a’  Prelude ~ out a’  7→ out1

(44) (45)

Summary The creation of the process prelude is summarised in the following rule. Note that this is not a defined rule in the appendix. It is only used to summarise the first part of the process creation.

Prelude ~ hboxdecli  7→ proctype not (chan in1, out1, control) 4.10.2 Variable Declarations To create a variable the expression types of the input elements, together with the box matches, are required. In the ‘not’ gate there is only one input element, which is extracted.

Vars ~ box hboxidi hpreludei hbodyi  7→ Vars ~ hpreludei hbodyi  Vars ~ in ( a :: int 1 ) out ( a’ :: int 1 ) fair hboxmatchesi  7→ Vars ~ a :: int 1 hboxmatchesi  Vars ~ a :: int 1 hboxmatchesi  7→ Vars ~ int 1 hboxmatchesi 

(46) (47) (49)

During the creation of variable declarations, the pattern in each match must be scrutinised for variables. The ‘not’ gate contains two matches which are separated recursively and examined independently. For each match, the pattern, which is on the right hand side of the arrow ‘→’ is extracted. If the pattern type is a variable, the variable must be declared. For both matches, this is not the case hence no variables are declared.

Vars ~ int 1 0 → 1|1 → 0  7→ Vars ~ int 1 0 → 1 Vars ~ int 1 1 → 0  Vars ~ int 10 → 1  7→ Vars ~ int 1 0  Vars ~ int 11 → 0  7→ Vars ~ int 1 1 

(50) (51) (51)

Summary As for the process prelude, the variable declaration has been summarised in a rule. Since the body of the box did not contain any variable, no variable declarations are performed. This is indicated with an epsilon ‘ε’.

Vars ~ hboxdecli  7→ ε 4.10.3 Process Body There are two semantically different bodies that can be created, depending on whether fair or unfair matching is applied. Regardless of the matching form, the synchronisation with the control process is identical.

Body ~ box hboxidi hpreludei hbodyi  7→ start: control?BEGIN; Body ~ hpreludei hbodyi  finish: control!END;

goto start;

(55)

The ‘not’ gate uses fair matching, where each match is an option in an if clause. The if clause is created, together with the else option handling the case where the input does not match any of the options.

Body ~ hpreludei fair hboxmatchesi  7→ Fair ~ hpreludei fair hboxmatchesi  Fair ~ hpreludei fair hboxmatchesi 

(56)

7→ if

Fair ~ hpreludei hboxmatchesi  :: else goto finish fi;

(58)

The two matches are separated recursively, and examined independently.

Fair ~ hpreludei 0 → 1|1 → 0  7→ Fair ~ hpreludei 0 → 1  Fair ~ hpreludei 1 → 0 

(59)

Each match is an option in the if clause, identified by using two colons ‘::’ as a prefix. The match is separated with the guard condition on the left hand side of the arrow ‘→’, which checks the channels, and the right hand side of the arrow, which receives and omits the input from the input channel and sends the output to the output channels. The guard condition is enclosed by parentheses.

Fair ~ hpreludei 0 → 1  7→ :: Match ~ hpreludei 0 → 1  Match ~ in(a::int 1) out(a’::int 1) 0 → 1  7→ ( Patt ~ a::int 1 0  ) → Exp ~ a::int 1 0  Exp ~ a’::int 1 1 

(60) (64)

The right hand side of the receive operator ‘?’ in the guard condition is enclosed by brackets ‘[ ]’. In this example there is only one input channel, holding one base value.

Patt ~ a::int 1 0  7→ in1?[ Patt ~ int 1 0  ] Patt ~ int 1 0  7→ Values ~ 0  Values ~ 0  7→ 0

(68) (70) (11)

The operation that receives the values is almost identical to the guard condition with the difference being that the brackets are removed.

Exp ~ a::int 1 0  7→ in1? Patt ~ int 1 0 ; Patt ~ int 1 0  7→ Values ~ 0  Values ~ 0  7→ 0

(74) (70) (11)

The code that produces the output is generated in similar way as the “input code”. The name of the only output channel in the process is ‘out1’, and the send operator ‘!’ is used instead of the receive operator.

Exp ~ a’::int 1 1  7→ out1! Exp ~ int 1 1 ; Exp ~ int 1 1  7→ Values ~ 1  Values ~ 1  7→ 1

(78) (80) (11)

The generation of the second match is identical to the generation of the first match. The guard condition on the right hand side of the arrow is enclosed by parentheses.

Fair ~ hpreludei 0 → 1  7→ :: Match ~ hpreludei 1 → 0  Match ~ in(a::int 1) out(a’::int 1) 1 → 0  7→ ( Patt ~ a::int 1 1  ) → Exp ~ a::int 1 1  Exp ~ a’::int 1 0 

(60) (64)

The guard condition is first created, by enclosing the right hand side of the receive operator ‘?’ in brackets.

Patt ~ a::int 1 1  7→ in1?[ Patt ~ int 1 1  ] Patt ~ int 1 1  7→ Values ~ 1  Values ~ 1  7→ 1

(78) (80) (11)

The code that receives the value from the input channel is then created.

Exp ~ a::int 1 1  7→ in1? Patt ~ int 1 1 ; Patt ~ int 1 1  7→ Values ~ 1  Values ~ 1  7→ 1

(74) (70) (11)

At the end the code that sends the output to the output channel is created.

Exp ~ a’::int 1 0  7→ out1! Exp ~ int 1 0 ; Exp ~ int 1 0  7→ Values ~ 0  Values ~ 0  7→ 0

(78) (80) (11)

Summary The “summary rule” illustrates that the creation of a the process body is the most demanding part of the translation of a HW-HUME box into PROMELA. Compared to the other parts the number of code lines created is far greater. The amount of rules used to create the code is also superior compared to the other two parts.

Body ~

hboxdecli  7→ start: control?BEGIN; if :: ( in1?[0] ) → in1?0; out1!1; :: ( in1?[1] ) → in1?1; out1!0; :: else goto finish fi; finish: control!END; goto start;

4.10.4 The Promela Process Figure 4.32 summarises the translation of the HW-HUME ‘not’ gate by listing the created PROMELA representation. An important detail is the amount of PROMELA code required to represent the simple HW-HUME example. This is discussed in chapter 6.

p r o c t y p e n o t ( chan i n 1 , o u t 1 , control ) { start : c o n t r o l ?BEGIN ; if : : ( in1 ? [ 0 ] ) − > in1 ? 0 ; out1 ! 1 ; : : ( in1 ? [ 1 ] ) − > in1 ? 1 ; out1 ! 0 ; : : e l s e goto f i n i s h fi ; finish : c o n t r o l !END; goto s t a r t ; }

Figure 4.32: The Promela Representation of the ‘NOT’ Gate

Chapter 5

The Hw-Hume to Promela Translator 5.1 Introduction This chapter describes the ‘hwhpromela’ program. The program is used to model check HW-HUME models. This is achieved by first translating the HW-HUME source code into PROMELA. The user can then decide whether or not to use SPIN to verify or simulate the model. The program implements the semantic rules introduced in chapter 4. Since this is the main objective of the program, and the translation rules are already thoroughly described, the documentation is relative superficial. Appendix C contains the user guide for the program.

5.2 Requirements Due to the task, size and nature of the program the functional and non-functional requirements have not been separated. The program has the following requirements to the system: - The program has only been tested on a JAVAVirtual Machine (JVM) running on a LINUX system, and therefore there are no guarantees that it will work on other platforms. - The program uses the HUME parser (hparse), written in HASKELL , when parsing the HW-HUME code. The parser must be available for the program to work correctly. - SPIN is used to validate and simulate the generated model, and must be available. Also note that the different versions of SPIN vary. The program has only been tested with SPIN version 4.1.3 from 24 April 2004. The main task of the program is to automate the rules from chapter 4, and make the source code as close to the rules as possible. The rules are defined in appendix B. The program has the following functional and non-functional requirements: - The interface of the program should be a simple command based interface if possible. - By specifying a HW-HUME filename, the program should use the file as input, and generate a corresponding PROMELA model, which is written to a different file with a different file extension. 45

- The user should be able to simulate or verify the generated model, and should be able to run a guided simulation if a verification fails. - The program should output the translation time after a translation is performed. If a model is verified the verification and total runtime should be returned as well.

Figure 5.1: Use Case Diagram of Translator

Figure 5.1 shows the different options of the program, by using an UML use-case diagram 1 : Generate PROMELA code is the main task of the translator. The translator accepts as input a HWHUME file, and translates it into a PROMELA file. The ‘.hume’ file extension is replaced by a ‘.pml’ extension. If the file extension on the HW-HUME file is not ‘.hume’, ‘.pml’ is simply appended to end of the HW-HUME filename in the PROMELA file. The translation time is returned to the user when the translation finishes. Random simulation of the SPIN model is concerned with running SPIN in a random simulation mode after the HW-HUME model is translated. During random simulation the next statement in a randomly selected process is always chosen for execution. Verify the SPIN model is the option that verifies the model after the HW-HUME is translated. The result of the verification is returned back to the user, together with the translation time, verification time and the total time used. Guided simulation of SPIN model can only be performed if a verification from an earlier run failed.

5.3 Design Figure 5.2 illustrates the different states of the program using an UML activity diagram. As the diagram shows, the activities of the program depend on the input arguments from the user. The arguments are represented in the figure with the variable ‘args’. If ‘-g’ is used as an argument, the ‘hwhpromela’ will start SPIN and run the guided simulation without any translation. If not, the specified HW-HUME program is first translated. The HUME parser is used during this activity. After the HW-HUME program has been translated, the PROMELA representation of it is created. If no 1

For a good introduction on UML please see [12]

arguments are specified, the program terminates after this step. If ‘-v’ is specified, the generated PROMELA program is verified using SPIN. SPIN will only search for deadlocks. If ‘-r’ is specified, the generated PROMELA program is run using random simulation.

Figure 5.2: Activity Diagram of Translator

Figure 5.3 illustrates the stages of the translation from HW-HUME into PROMELA. The process is divided into four distinct parts. First the lexical and syntax analysis is performed. It accepts a HWHUME program as input, and parses it first using the HUME parser. This is covered in section 5.3.1. The result of the lexical and syntax analysis is used to create the abstract syntax tree, covered in section 5.3.2. The abstract syntax tree is then used to generate the PROMELA code, which is explained in section 5.3.3. JAVA2 has been used to implement the translator.

Figure 5.3: The Translator

5.3.1 Lexical/Syntax Analysis For the syntax and semantics analysis, JAVA Compiler Compiler( JAVACC )[21] has been used. JAVACC is a JAVA version of the Lex and Yacc[31] tools. 2

An introduction on using Java to write compilers is given in [2]

JAVACC is the most popular parser generator for use in JAVA applications. The parser generator is a tool that reads a grammar specification and converts it into a JAVA program that can recognise matches to the grammar [21]. The lexical and syntax analysis had already been done by Chunxu Liu. This version has been used in the translator.

5.3.2 Abstract Syntax Tree The JAVACC utility includes a mechanism to create an abstract syntax tree (AST). It is a preprocessor for JAVACC that is run before the JAVACC parser. The utility is called JJTREE . The output of JJTREE is used as input to the JAVACC utility. It inserts parse tree building actions in the JAVACC source (The grammar file). The grammar file is then used as input in JAVACC [22]. Figure 5.4 illustrates a part of the abstract syntax tree when parsing the half adder example from figure 2.5. The figure illustrates the iteration to the name of the ‘gen’ box. The root node of the tree is ‘Decls’. It contains a set of ‘Decl’ nodes, which in this case hold a ‘BoxDecl’, that declares the ‘gen’ box. The ‘BoxId’ node holds the name of the box, which is ‘gen’. The AST follows the structure defined in HUME. Appendix A contains the abstract syntax for HW-HUME, which holds a subset of the AST in full HUME.

Figure 5.4: Part of Abstract Syntax Tree

5.3.3 Code Generation In the code generation step the PROMELA code is generated, and written to a file. It implements the translation rules defined in appendix B. One JAVA method is created, where possible, for each rule defined in the appendix. In the methods the HW-HUME elements are obtained by traversing the AST, illustrated in figure 5.4. This is then translated into PROMELA. The class diagram in figure 5.5 shows how the ‘hwhpromela’ class uses the AST like a “black box”. All methods are implemented in the ‘hwhpromela’ class.

Figure 5.5: Class Diagram

Chapter 6

Evaluation 6.1 Introduction This chapter presents an evaluation of the translation and the verification results. The evaluation is conducted based on experiments with a set of HW-HUME examples. They are translation and verified using the ‘hwhpromela’ program. The evaluations scrutinises the time used for the translation and verification, the amount of work required by the verifier, and the difference in code size between the HW-HUME and PROMELA model. The first sections introduces the examples, and the last section contains the actual analysis. Appendix F contains the HW-HUME source code for the examples used. The generated PROMELA code is listed in appendix G, and appendix H includes the outputs from the verifications. The generated PROMELA source code for examples 1, 3 and 4 are listed in appendix G. Due to the size of the PROMELA code, the source code for the rest of the examples have not been included. Note that the line numbers in the figures in this chapter containing verification outputs are not part of the outputs, if not specified.

6.2 Example 1: A Half Adder The first HW-HUME model that is verified is the half adder used as an example in the previous chapters. The full HW-HUME source code is listed in figure 2.5 on page 12. The PROMELA source code of the translation is listed in section G.1. Figure 6.1 displays the output when running the program in a random simulation mode, by using the ‘-r’ argument in ‘hwhpromela’. As in figure 2.6 on page 14 that runs the HW-HUME version of the program, the output displays the first two runs. Lines 3 to 6 shows the first run and lines 7 to 10 the second. The output is almost the same as the output of the first and second runs in HW-HUME, shown in figure 2.6. The only difference is that each line ends with ‘-1’. This is simply the PROMELA translation of the newline escape sequence. Figure 6.2 contains parts of the output when validating the half adder using ‘hwhpromela’. The complete output is listed in section H.1. Line 1 indicates that a full state space search is explored. In line 2 the minus sign ‘-’ indicates that no never claim or LTL formula has been used 1 . Line 4 indicates that a check for acceptance or 1

LTL formulae are translated into never claims in the LTL parser.

49

1 2 3 4 5 6

$ j a v a hwhpromela − r h a l f . hume h a l f . pml g e n e r a t e d 0 0 −1 1 0 −1 1 0 −1 0 1 −1

7 8 9 10 11

0 1 1 0 .

0 0 0 1 .

−1 −1 −1 −1 .

Figure 6.1: Running the Half Adder 1 2 3 4 5 6 7 8 9 10 11

Full s t a t e s p a c e search for : never claim assertion violations acceptance cycles i n v a l i d end s t a t e s

− ( none s p e c i f i e d ) + − ( not s e l e c te d ) +

S t a t e −vector 1 5 6 byte , depth reached 2 7 5 , e r r o r s : 0 217 s t a t e s , stored 1 s t a t e s , matched 2 1 8 t r a n s i t i o n s ( = s t o r e d +m a t c h e d ) 0 atomic s t e p

Figure 6.2: Output when Verifying Half Adder non-progress cycles was not conducted. The plus sign ‘+’ on lines 3 and 5 indicate that a search for assertion violation and invalid end states (deadlocks) has been conducted [18]. Line 7 specifies that the complete description of a global system state requires 156 bytes, and the longest depth-first search path uses 275 transitions from the root. No errors were found, hence the verification succeeded. Line 8 declares that 217 unique global system states were stored in the state space, and line 9 declares that in one case the search returned to a previously visited state. Line 10 declares that a total of 218 transitions were explored in the search. This number indicates the amount of work performed in the verification. None of the transitions were in an atomic sequence [18]. After the verification is completed ‘hwhpromela’ displays the time elapsed to translate and verify the HW-HUME model. This part of the output is shown in figure 6.3. −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− T r a n s l a t i o n S u c c e s s f u l : V e r i f i c a t i o n Completed −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− Fi le Generated : h a l f . pml T r a n s l a t i o n Time : 4 0 9 ms V e r i f i c a t i o n Time : 3 3 1 0 ms T o t a l Running Time : 3 7 1 9 ms −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

Figure 6.3: Time Elapsed when Verifying Half Adder

6.3 Example 2: An XOR and an AND Gate Forming a Deadlock Example 1 illustrated a working model without any errors. However, the reason to translate the HW-HUME model into PROMELA, is to be able to use SPIN to verify if the model includes any errors. As an example with an error, the half adder example has been modified. One of the outputs in the ‘xor’ gate has been used as input to the ‘and’ gate and the other way around. This is illustrated in figure 6.4.

Figure 6.4: An ‘AND’ and an ‘XOR’ Gate Creating a Deadlock

The HW-HUME source code for this example is listed in section F.2. When verifying the model using ‘hwhpromela’, the verification fails. The part of the output showing this is listed in figure 6.5. The full verification output is listed in section H.2. Note that only one error is found. The objective of the verifier is to prove that a model contains errors. As soon as one error is found, the verifier normally stops executing. It has then succeeded in its task, and there is no need to continue. S t a t e −vector 1 3 2 byte , depth reached 4 6 , e r r o r s : 1 36 s t a t e s , stored 0 s t a t e s , matched 3 6 t r a n s i t i o n s ( = s t o r e d +m a t c h e d ) 0 atomic s t e p s

Figure 6.5: Output when Verifying Deadlock Example Figure 6.6 shows the part of the output where the deadlock occurs. In the output the number on the left hand side reflects the step number of an operation. As shown in the output, the model is deadlock when ‘gen’ tries to send a value to the first output channel. The previous value has not been removed from the channel, and ‘gen’ cannot send the new value to the output channel. 45: 46: 47:

proc 3 ( gen ) proc 3 ( gen ) proc 0 ( Control ) transition failed s p i n : t r a i l ends a f t e r 4 7

. . . . . . . . .

[ in1 ?1] [ out1 ! 2 ] [ g e n c o n t r o l ?END]

steps

Figure 6.6: Output when Running Guided Simulation on Deadlock Example

6.4 Example 3: Full Adder from Truth Table The problem with half adder is that it does not accept any carry input. A full adder is an extension of the half adder that accepts a carry input. A set of full adders can then be connected, by connecting the output carry of one adder to the input of another. Figure 6.7 illustrates a full adder as a “black box”.

Figure 6.7: A Full Adder

There are several ways to represent a full adder in HW-HUME. In this example it is represented from a truth table. Figure 6.8 shows the HW-HUME model of the full adder. The full adder is represented as a box called ‘adder’, that holds the truth table, and uses it to generate the ‘sum’ and ‘carry’ bits. The ‘gen’ box generates the different inputs, and ‘show’ redirects the result to standard output. The full HW-HUME source code is listed in section F.3, the generated PROMELA code is listed in section G.2, and the verification output in section H.3. The verification succeeded without errors.

Figure 6.8: Full Adder from a Truth Table

6.5 Example 4: Full Adder as Half Adders and OR gate A full adder can also be represented by using two half adders and an ‘or’ gate. The HW-HUME model in 6.9 shows such a system. The ‘gen’ box generates the two binary numbers which are added, together with a carry bit. The first half adder receives the two binary numbers as input and wires the sum to the input of the second half adder. The other input for the second adder is the carrier from the ‘gen’ box. The sum of the second adder is then the sum of the complete adder. The carry from both half adders are wired to an ‘or’ box. If one of them is ‘1’ the carry from the full adder is ‘1’. The HW-HUME source code is listed in section F.4, and the translated PROMELA version of it in section G.3. The output from the verification is shown in section H.4. The verification succeeded without any errors.

Figure 6.9: Full Adder as Half Adders and OR gate

6.6 Example 5: Full Adder as XOR, AND and OR gates In example 4 the half adders were implemented using a truth table. However, each half adder can be decomposed into ‘xor’ and ‘and’ gates, the same way example 1 represented the half adder. Figure 6.10 displays the HW-HUME model of the adder created this way.

Figure 6.10: Full Adder as XOR, AND and OR gates

The full HW-HUME source code is listed in section F.5, and the output of the verification is listed in section H.5. The verification succeeded.

6.7 Example 6-9: Connecting Adders In the examples in this section several adders are connected to increase the size of the programs. The results are then analysed in section 6.9. Four different adders have been created. They can add two, three, four and five bits respectively. The HW-HUME source code is found in section F.6 and the verification results in section H.6. Example 6 connects two adders by connecting the output carrier from the first adder to the input carrier of the second adder. This will form a two bit adder. The adder is illustrated in figure 6.11. Note that this is a simplification of the HW-HUME model. Each adder is based on example 5, which

Figure 6.11: Example 6: A Two Bit Adder

creates the adder by using ‘and’, ‘xor’ and ‘or’ gates. In addition each adder has an associated ‘gen’ box. In total, the PROMELA model generated from the HW-HUME model includes 21 processes and 52 channels. The verification of the two bit adder succeeded. Example 7 appends another adder to example 6, and by doing so, creates a three bit adder. The translated PROMELA model of the adder uses 29 processes and 76 channels. This verification also succeeded without any errors. Example 8 creates a four bit adder by connecting another adder to example 7. The PROMELA translated from the HW-HUME model of the adder consists of in total 37 processes and 100 channels. The verification of this model succeeded. Example 9 is created by appending another adder to example 8. This will create a five bit adder. The PROMELA model translated from the HW-HUME model uses a total of 45 processes and 124 channels. In this example the state vector in the verification was too small, and the verification consequently failed.

6.8 Example 10: Debugging with Spin Example 10 creates a 3 bit counter. Since it uses 3 bits, it counts from 0 to 7. Each bit is represented by a ‘digit’ box. Figure 6.12 shows such a ‘digit’.

Figure 6.12: The Digit

The box has two inputs, ‘clk’ and ‘a’, and two outputs, ‘ clk‘ ’ and ‘q’. The ‘a’ input is the current state of the ‘digit’. The output ‘q’ is also the state of ‘digit’, and is wired to the ‘fanout’ box. This box simply wires the one input to two identical outputs. This must be performed since all

wires in HW-HUME have a 1:1 relationship, and the output needs to be wired to two different boxes. One of the outputs of ‘fanout’ is wired back to ‘digit’, since it needs to remember its state. The other input ‘clk’ is used to change the state of the ‘digit’. If the value is ‘1’ the state will change. The other output is ‘clk‘’, and holds the carrier. Figure 6.13 contains the truth table for the ‘digit’. The box is implemented as a truth table.

clk 0 1 0 1

a 0 0 1 1

q 0 1 1 0

clk’ 0 0 0 1

Figure 6.13: Truth Table for a Digit

To create a 3 bit counter, three ‘digits’ are wired together. Figure 6.14 displays the HW-HUME model of the counter. The source of the ‘clk’ input in the first ‘digit’ is a box ‘clock’. This box receives the input from the last ‘digit’ box. When it receives the input, it signifies that one run has completed, and all ‘digits’ are updated. Each time ‘clock’ receives inputs, it sends ‘1’ to the first ‘digit’, forcing it to change state - hence the counter is either incremented by 1 or reset back to ‘0’. The carrier output ‘clk‘’ from the first ‘digit’ is wired to the next ‘digit’. The ‘clk‘ ’ output of this ‘digit’ is then wired to the ‘clk’ input of the last box, which wires its ‘clk‘’ output back to ‘clock’. The ‘q’ output of each ‘digit’, which holds the current state, is wired to a ‘fanout’ box, which wires one of the outputs to ‘show’. The ‘show’ box converts the binary number, created from the three ‘digits’, into a decimal format, and wires it to the standard output.

Figure 6.14: The Counter

The HW-HUME source code of the counter is listed in section F.7.1. When the counter reaches ‘4’, it for some reason hangs and stops counting. SPIN is applied to the model to find the error. The HWHUME model is verified by using the ‘-v’ argument when the model is run through ‘hwhpromela’. Figure 6.15 contains parts of the output when running the verifier. The full output can be obtained from section H.7.1. As line 1 in the figure shows, the model contains a deadlock (error). When a verification fails

1 2 3 4

S t a t e −vector 2 0 8 byte , depth reached 5 2 8 , e r r o r s : 1 412 s t a t e s , stored 0 s t a t e s , matched 4 1 2 t r a n s i t i o n s ( = s t o r e d +m a t c h e d )

Figure 6.15: Output when Verifying the Counter in SPIN, an error trail specifying the path of the error is generated. By running a guided simulation, this trail is followed to track down the error. In ‘hwhpromela’ the guided simulation is run on the HW-HUME model by using the ‘-g’ argument. In figure 6.16 the interesting parts of the output from the guided simulation have been extracted.

468: 469: . . . 476: 477: . . . 524: 525: . . . 528: 529:

proc proc

4 ( show1 ) 4 ( show1 )

. . . . . .

[ c o n t r o l ?BEGIN ] [ else ]

proc proc

4 ( show1 ) 4 ( show1 )

. . . . . .

[ else ] [ c o n t r o l !END]

proc proc

0 ( Control ) . . . 8 ( f1 ) . . .

[ f 1 c o n t r o l ! BEGIN ] [ c o n t r o l ?BEGIN ]

proc 8 ( f1 ) . . . [ out1 ! a ] proc 0 ( Control ) . . . [ f 1 c o n t r o l ?END] transition failed s p i n : t r a i l ends a f t e r 5 2 9 s t e p s

Figure 6.16: Running the Counter in Guided Simulation

The numbers on the left hand side reflects the step number of the different operations, and are part of the generated output. The verification fails after step 529. The error is that the ‘Control’ box does not receive the ‘END’ message back from the ‘f1’ process. Step 528 sends a value to the first output channel. As figure 6.14 shows, the ‘f1’ process has two output channels. This indicates that the problem is that ‘f1’ cannot send to the second output channel. This will happen if the last value sent was not removed from the channel. The box that receives this output is the ‘show’ box. Since it is not permitted to ignore inputs in HW-HUME, the only reason for this error, is that the input in the previous run did not match any of the patterns. This is confirmed by scrutinising the error trail in steps 468 to 477. It shows that only the else clauses were used, and hence no input matched, and the value remained in the channel. The error was that the binary representation of ‘3’(‘011’) was used to represent ‘5’(‘101’) in the pattern. Consequently none of the patterns matched ‘5’. The updated source code with the fixed error is listed in section F.7.2. Figure 6.17 illustrates part of the output when verifying the updated counter. The full output is listed in section H.7.2. As line 1 in the figure illustrates, the model did not contain any errors.

S t a t e −vector 2 0 8 byte , depth reached 7 4 5 , e r r o r s : 0 583 s t a t e s , stored 1 s t a t e s , matched 5 8 4 t r a n s i t i o n s ( = s t o r e d +m a t c h e d )

Figure 6.17: Output when Verifying the Updated Counter

6.8.1 Specifying Behaviour Until now SPIN has only been used to find deadlocks in a model. SPIN is much more powerful than just that. One feature, explained in chapter 3, is the linear temporal logic (LTL) where the order of events can be specified. To specify this, the PROMELA source code must edited. In addition the LTL properties must be defined. To illustrate the possibilities of SPIN, the following property is verified: “Each time the value of the counter is seven it will eventually be set to zero” To be able to express this in the PROMELA model, a global variable holding the current value of the counter must be created. Each time the value is read by the ‘output’ process that prints the value to the standard output, the global variable must be updated. 1 2 3 4

# define p ( value == 7) # define q ( value == 0) byte value = 0 ;

Figure 6.18: Declaring the Properties Figure 6.18 contains the declarations that have to be made in the PROMELA code. The variable ‘value’, declared on line 4, must be updated each time the counter is updated. ‘p’ is the event that the counter is ‘7’, and ‘q’ is the event that the counter is ‘0’. These events can also be specified in the LTL-editor in XSPIN. Desired Behaviour The behaviour defined is the desired behaviour. The following linear temporal logic formula expresses this behaviour:

(p → 

q)

SPIN will then transform this formula into a never claim. The claim is shown in figure 6.19. As described in chapter 3, never claims specify behaviour that should never occur. As a consequence the never claim describes what should not happen, which is the negation of the specified behaviour. This is achieved by using the not operator ‘!’ in front of the claim, as line 1 shows. Figure 6.20 contains parts of the output from the verification. The plus sign ‘+’ at the end of line 2, indicates that the never claims are included in the verification. Line 7 specifies that the model contains no errors. The complete output is listed in section H.7.3.

1 2 3 4 5 6 7 8 9 10 11

never { T0 init :

/∗ !([]

( p −>

<>

q)) ∗/

if : : ( ! ( ( q ) ) & & ( p ) ) − > goto a c c e p t S 4 : : ( 1 ) − > goto T 0 i n i t fi ; accept S4 : if : : ( ! ( ( q ) ) ) − > goto a c c e p t S 4 fi ; }

Figure 6.19: Never Claim for Desired Behavoiur 1 2 3 4 5 6 7 8 9 10

Full s t a t e s p a c e search for : never claim assertion violations acceptance cycles i n v a l i d end s t a t e s

+ + ( i f within scope of claim ) + ( fairness disabled ) − ( d i s a b l e d by n e v e r c l a i m )

S t a t e −vector 2 1 2 byte , depth reached 1 3 4 6 , e r r o r s : 0 658 s t a t e s , stored ( 7 2 4 v i s i t e d ) 130 s t a t e s , matched 8 5 4 t r a n s i t i o n s ( = v i s i t e d +m a t c h e d )

Figure 6.20: Output when Verifying Desired Behaviour Error Behaviour Error behaviour, i.e. behaviour that should never happen, can also be specified. In this case the error behaviour can be defined as follows: “Eventually it should not happen that when the value of the counter is seven it will eventually be set to zero” When using the same definition of ‘p’ and ‘q’ as earlier, the following linear temporal logic formula expresses the error behaviour: 

!(p → 

q)

Parts of the output from the verification are listed in figure 6.21. The full output from XSPIN, together with the generated never claim, are listed in section H.7.3. Note that the never claim (see line 2 in figure 6.20) is also enabled in this example. S t a t e −vector 2 1 2 byte , depth reached 1 3 4 6 , e r r o r s : 0 658 s t a t e s , stored ( 7 2 4 v i s i t e d ) 130 s t a t e s , matched 8 5 4 t r a n s i t i o n s ( = v i s i t e d +m a t c h e d )

Figure 6.21: Output when Verifying Error Behaviour

6.9 Analysis of the Verification Result

1: Half Adder 2: Deadlock 3: Adder 1 4: Adder 2 5: Adder 3 6: Two Bit 7: Three Bit 8: Four Bit 9: Five Bit 10: Counter Average

Verification Vector Work 156 218 132 36 120 302 156 414 256 694 456 1273 652 1852 848 2431 1028 208 584

Time Consumption (ms) Translate Verify Sum 468 3411 3879 254 3153 3407 319 3371 3690 369 4054 4423 414 5735 6149 394 8297 8691 414 11458 11872 597 15942 16539 770 380 4723 5103

Lines Of Code

HW-HUME

PROMELA

50 41 41 50 73 94 112 130 148 51

183 159 153 202 312 549 786 1023 1260 312

Factor 3.66 3.88 3.73 4.04 4.27 5.84 7.02 7.87 8.51 6.12 5.49

Table 6.1: Translation and Verification Data

Table 6.1 contains data collected from the translation and verification processes. The first column refers to the examples in the previous sections. The analysis has been divided into three distinct parts, which are the verification, the time consumption and the code size. The table follows this structure. The second column holds the size of the state vector in the verification. This size is in bytes. The third column, named work, is the number of transitions explored in the search. This number illustrates the amount of work performed in the verification. The next three columns contain the time consumptions. In all cases the time is shown in milliseconds. The time is divided into translation time, verification time and total runtime. The last three columns look at the size of the source code in HW-HUME and PROMELA. The last column, factor, illustrates the relationship between them (PROMELA /HW-HUME). HW-HUME 5: 6: 7: 8: 9:

Adder Two Bit Adder Three Bit Adder Four Bit Adder Five Bit Adder

Box 3 3 4 5 6

Temp.Inst. 6 14 21 28 35

PROMELA Total 9 17 25 33 41

Process 13 21 29 37 45

Chan 28 52 76 100 124

Total 41 73 105 137 169

Time 6149 8691 11872 16539

Factor 4.27 5.84 7.02 7.87 8.51

Table 6.2: Data Objects

Table 6.2 only looks at example 5 to 9, which respectively are 1,2,3,4 and 5 bit adders. It examines the data object representations in HW-HUME and PROMELA. In HW-HUME it looks at the number of boxes, how many instances of templates, and the sum of these two values. In PROMELA the number of processes and channels are defined. The time is the total running time and factor has the same meaning as in table 6.1.

6.9.1 Verification There tends to be a relationship between the amount of work (number of transitions) and the size of the state vector. However, this is quite natural, since the more transitions the more space is required to represent them.

Figure 6.22: Relationship between State Vector and Box Instances

Of particular interests in this special case, is the relationship between the number of box instances in HW-HUME and the number of transitions and the size of the state vector. The number of templates is of little interests, since it is only when a template is instantiated that it is actually translated into PROMELA. Figure 6.22 graphically illustrates the relationship between the state vector and number of box instances, and figure 6.23 illustrates the relationship the number of transition and the number of box instances. An interesting result is that both for the space vector and for the number of transitions, the relationship seems to be linear. This leads to the size of the state vector and the number of transitions increasing linearly with the number of box instances. Most boxes are relatively small and simple, and behaves similarly. This is probably the reason for the linearity. Each time a new box is introduced, the amount of work (number of transitions) increases with the same factor.

Figure 6.23: Relationship between Number of Transitions and Box Instances

6.9.2 Time Consumption As table 6.1 shows, the translation time is relatively stable, using around 0.5 seconds, regardless of the code size of the HW-HUME or PROMELA model. The implies that the translation process do not require a lot of work, and most of the work is reading the source file (HW-HUME), and writing to the destination file (PROMELA).

Figure 6.24: Relationship between Verification Time and Hw-Hume Box Instances

The verification time increases when the total instances of HW-HUME boxes increases. Figure 6.24 illustrates the relationship between the running time (in seconds) and the total number of box instances. The figure shows that the running time increases exponentially rather than in a linear fashion

Figure 6.25: Relationship between Time, Processes and Channels

Figure 6.25 illustrates the relationship that the verification time has with the two global objects in PROMELA, which are channels and processes. From figure 6.25 you could assume that the number of communication links (channels) have a greater impact on the verification than the processes. It looks like introducing a greater amount of communication between process, will have a greater impact on the verification time, compared to introducing a greater amount of boxes.

6.9.3 Number of Code Lines When examining table 6.1 a big difference between the number of source code lines in HW-HUME and PROMELA can be seen. On average, for each code line of HW-HUME, PROMELA needs 5.49 lines to specify the same. From the same figure you can see that this factor tends to increase when the size of the example increases. Figure 6.26 graphically displays the relationship between the number of boxes and template instances and the factor indicating the relationship between the size of the HWHUME and PROMELA code. The function tends to increase monotonically toward a constant value, when the number of box instances increases. Why this happens is difficult to say. It is important to realise that the size of the examples used in the analysis were relatively small, and the results from larger scale programs might differ. There are many reasons for the code size of PROMELA begin on average 5.49 times greater than

Figure 6.26: Relationship between Code Lines Factor and Number of Box Instances

the HW-HUME code. As figure 6.26 illustrates, the factor increases with the number of box instances in HW-HUME. Table 6.2 shows that the number of boxes are stable, while the number of template instances increases in the examples. From one template, all instantiations are created on the same line, and one extra line is required for wiring each instance. The PROMELA representation of a template instance is a process. This process, and the corresponding channels, must be declared. This is probably the main reason, since a process declaration requires a significant amount of space. Another reason is that the execution model in HW-HUME must be coerced into the PROMELA version. To achieve this, a separate control process must be created, and each process must be synchronised with it. The channels that are used for this synchronisation must also be created. This code is not found in HW-HUME. Inside the boxes variables must also be specifically declared. In HW-HUME this is achieved directly in the pattern matches. For the interprocess communication one channel has to be created for each variable. In HWHUME it is sufficient with a wire declaration per box. Each stream in HW-HUME is created by a one line declaration. In PROMELA an entire process must be created, which also must be synchronised with the other processes. For input streams a channel must be created in addition. As a general conclusion the PROMELA code translated is “PROMELA for HW-HUME” and not PROMELA. If the same program were directly implemented in PROMELA, and not a translation from HW-HUME, the number of code lines would decrease dramatically. However, this would not reflect the HW-HUME program. To reflect it all the features mentioned are required.

Chapter 7

Conclusion 7.1 Introduction This chapter discusses various aspects of the project and looks at which would be feasible for future research. The discussion has been divided into the translation and verification, and the actual program developed.

7.2 The Analysis The verification results in the validation chapter provide empirical evidence as to the correctness of the translation. For all features in HW-HUME, a corresponding feature was found in PROMELA. The results from the verifications were as expected. In both cases where a deadlock was injected, SPIN was able to detect it. The generated PROMELA program had in all cases the same behaviour when simulated, as the HW-HUME program from which it was generated when executed. In the working HUME examples, no deadlock where found by the verifier, and the temporal properties was proven where defined.

7.2.1 Verification Result To break down SPIN with the default size of the state vector, a total of 45 processes and 124 channels were required. The biggest verified model used a total of 37 boxes and 100 channels. An interesting result from the verification was that the relationship between the amount of instantiated boxes in HW-HUME (processes in PROMELA) and the amount of work performed by the verifier was linear. The reason is most likely that all the boxes were of similar size in the examples used. However, since HW-HUME is targeted at modelling hardware systems, this is what you would expect in most of the cases. The story for full HUME is different, and this might give a different relationship.

7.2.2 Time Consumption The translation time was in all cases relative stable, using around 0.5 seconds, regardless of the size of the HW-HUME model. This denotes that the amount of work required to translate is relatively low, and most of the work is to read and write to a the source and destination files. An interesting result

63

from the verification was that it seemed that the amount of interprocess communication affected the verification time more than the number of boxes. This is interesting since in distributed systems the amount of message passing between processes is in most cases the bottle neck. The system with the lowest amount of messages passed is normally the most efficient one.

7.2.3 Number of Code Lines As expected, the number of code lines required to represent HW-HUME models in PROMELA was larger than the number of code lines in HW-HUME. But that the difference between them was as big as a factor of 5.59 was much more than assumed. The main reason for the big difference is the use of templates. The examples have relied heavily on the use of templates. This would be the case when modelling hardware systems, which would make HUME very good for that task. However, in full HUME you would expect this factor to be lower.

7.3 Translation Rules The notation used to express the translation rules were adequate in most cases. Though in some cases it did not have the expressive power required, and it had to be used to express something that it was not meant for. One such example is rule 42, on page 84. In that example the rule had to be used to express the position of a variable in a list, which it isn’t meant for. Another example is rule 54, where a condition is applied to the rule. Another expression form could probably have been used to formalise the rules further in those cases.

7.4 The Translator The translator behaves exactly the way it is supposed to do according to the design documentation and requirements. It has a simple user interface, and implement all the translation rules specified, which was the main objective. It also includes the required functions to simulate and verify the programs without the user having to use SPIN. As a consequence, the user needs no understanding and knowledge of SPIN or PROMELA. What the translator does not do is to let the user specify any properties that needs to be validated. If the user wishes to do so, the HW-HUME source must first be translated into PROMELA using the translator. Then the translated PROMELA code must be ran directly in SPIN or XSPIN, where the user can specify the error or desired behaviour. As a consequence the user must be familiar with SPIN and/or XSPIN. As the translator behaves at present, it only explores a small portion of the possibilities with the SPIN model checker. The programming language used to implement the translator was not necessarily the right one to use for such a problem. By using JAVA the defined rules could not be implemented directly. Where possible it has been attempted to implement a method resembling a rule, but in some cases this was impossible. One method could in some case implement several rules, and in some cases several methods were used to implement one rule. However, semantically the program does the same as the rules specified. This behaviour was calculated at the start of the implementation of the translator. Even if JAVA is a strictly object oriented

language the implementation was not carried out in an object oriented manner, since the implementation had to be as close to the rules as possible. Hence, JAVA was not used in the way in which it was intended to be. The reason for choosing JAVA was that the lexical and syntax analysis had already been done. However, by using languages like HASKELL [6] or PROLOG[10] a more direct implementation of the rules could have been obtained.

7.5 Future Work The future work has been divided up into what could be achieved in a short time, and what requires longer to complete. It addresses both the theoretical part, and the implementation of tools using the theory.

7.5.1 Short Term Continued translation of full HUME in the same way HW-HUME has been translated. The work has been started, but the translation rules for the aspects of HUME not covered by HW-HUME must be created. Full HUME includes features that are not found in model checking input languages like PROMELA. However, the notation of PROMELA resembles a programming language more than a modelling language [35]. Nevertheless, PROMELA has for instance no representation of floating point numbers that is found in HUME. Not being able for find a resembling representation of such aspects was the reason for the JAVA PATHFINDER [35] in version 2 which used a specialised model checker compared to the first version, which was a direct JAVA to PROMELA translation. By changing the implementation language to HASKELL or PROLOG in the translator a more direct implementation of the rules can be obtained. This implementation will most likely be more dynamic and easier to change. This should be applied if full HUME is translated into PROMELA. A comparison of the generated PROMELA code with the code created from a HUME → JAVA → PROMELA using the HUME to JAVA translator and JAVA PATHFINDER , could be carried out. This can help and support both the HUME to JAVA and the HUME to PROMELA projects. Implementing a graphical user interface (GUI) including a method to specify desired or error behaviour using linear temporal logic, would mean that user never had to see SPIN or PROMELA.

7.5.2 Long Term Other ways of verifying HUME should be considered. This could be alone or may be integrated to the SPIN approach. For instance, SPIN can be used to verify the box communication (expression layer) in HUME while a theorem prover can be used to verify the functionality of boxes. There is a current trend to such integration. E.g. the Stanford Temporal Prover (STeP)[34, 29] combines model checking with deductive methods when verifying systems. Another approach could be to customise SPIN for HUME, in the same way as the JAVA PATHFINDER version 2.

Upgrading HUME to specify error or desired behaviour would be an alternative to create a tool that specifies these properties, as described in the short term part. HUME can be extended so these properties can be programmed directly in the HUME source file, and then translated into the PROMELA counterpart. These properties can then be verified using SPIN. A PROMELA to HUME translator is an interesting idea. A system model can be created and verified using PROMELA. It can then be translated into HUME for implementation. The problem is that much of HUME’s expressive power will then be lost, since many of the aspects of HUME cannot be expressed in PROMELA, PROMELA only being a modelling language. One idea might be to only generate HUME skeletons for the boxes and communication links, and then implement the bodies of the boxes. Abstraction must be considered. The state explosion problem will eventually appear when the HUME programs increases in size. Finding a correct representation for all features of HUME in PROMELA might turn out to be too cumbersome or even insoluble. Both the ESTELLE to PROMELA [1] and the LOTOS to PROMELA [27] have this problem as well as the JAVA PATHFINDER. A solution might be to abstract at the features that cannot be represented, and use SPIN on the rest.

7.6 Conclusion The development of high integrity software systems calls for a wide range of tools and techniques, in particular, programming languages like HUME, that enable the use of a statically analysis techniques. However, HUME lacks the support of verification. In this project an investigation of the use of the SPIN verification system with HUME is conducted. It is resolved by translating a subset of HUME, known as HW-HUME, into the notation accepted by SPIN. The result of the translation is then verified. An empirical analysis performed on the translation and verification result led to a promising result for this combination. The analysis also provided some interesting relationships between HUME and the verification time and workload.

Bibliography [1] A. G. Kaloxylos. An Estelle to Promela Compiler. Master’s thesis, Heriot-Watt University, 1994. [2] Andrew W. Appel. Modern Compiler Implementation in Java: Basic Techniques. Cambridge University Press, 1997. [3] Bandera Project Homepage. http://bandera.projects.cis.ksu.edu/. August 2004. [4] Bell-Labs News:

Gerard Holzmann Wins Prestigious ACM Software System Award.

http://www.bell-labs.com/news/2002/march/holzmann.html. August 2004. [5] B. Berard, M. Bidoit, A.Finkel, F. Laroussinie, A. Petit, L. Petrucci, Ph. Schnoebelen, and P. McKenzie. Systems and Software Verification: Model-Checking Techniques and Tools. Springer, 2001. [6] Richard J. Bird. Introduction to Functional Programming using Haskell. Prentice-Hall Series in Computer Science. Prentice-Hall Europe, London, UK, second edition, 1998. [7] BLAST Project Homepage. http://www-cad.eecs.berkeley.edu/ tah/blast/. August 2004. [8] Edmund M. Clarke, Orna Grumberg, and Doron A. Peled. Model Checking. The MIT Press, Cambridge, Massachusetts, 1999. [9] Edmund M. Clarke and Jeannette M. Wing. Formal Methods: State of the Art and Future Directions. ACM Computing Surveys, 28(4):626–643, 1996. [10] William F. Clocksin and Christopher S. Mellish. Programming in PROLOG: Using the ISO Standard. Springer-Verlag Berlin, fifth edition, 2003. [11] James C. Corbett, Matthew B. Dwyer, John Hatcliff, Shawn Laubach, Corina S. P˘as˘areanu, Robby, and Hongjun Zheng. Bandera: Extracting Finite-State Models from Java Source Code. In International Conference on Software Engineering, pages 439–448, 2000. [12] Martin Fowler and Kendall Scott. UML Distilled: Applying the Standard Object Modeling Language. The Addison-Wesley Object Technology Series. Addison Wesley Longman, Inc., 1997. [13] Functional Programming at the University of St Andrews. http://www-fp.dcs.st-and.ac.uk/. August 2004. 67

[14] Rob Gerth. Concise Promela Reference. http://spinroot.com/spin/Man/Quick.html, 1997. [15] James Gleich. A Bug and a Crash: Sometimes a Bug Is More Than a Nuisance. New York Times, December 1996. [16] Greg Michaelson and Kevin Hammond and Jocelyn Serot. The Finite State-Ness of FSMHume. In Draft paper submitted to TFP 2003; Symposium on Trends in Functional Programming, Edinburgh, Scotland, September 2003, 2004. [17] Klaus Havelund and Thomas Pressburger.

Model Checking Java Programs Using Java

PathFinder. International Journal on Software Tools for Technology Transfer, 2(4), April 2000., 1998. [18] G. J. Holzmann. The Spin Model Checker, Primer and Reference Manual. Addison-Wesley, Reading, Massachusetts, 2003. [19] Gerard J. Holzmann. Basic Spin Manual. http://spinroot.com/spin/Man/Manual.html, October 1995. [20] Gerard J. Holzmann. The Model Checker SPIN. Software Engineering, 23(5):279–295, 1997. [21] JavaCC Home Page. https://javacc.dev.java.net/. August 2004. [22] JavaCC: JJTree Reference. https://javacc.dev.java.net/doc/jtree.html. August 2004. [23] jSpin - A Java GUI for Spin. http://stwww.weizmann.ac.il/g-cs/benari/jspin/index.htm. August 2004. [24] Greg Michaelson and Kevin Hammond. The Hume Manual, Version 0.1. http://www-fp.dcs.stand.ac.uk/hume/downloads/index.html, 2004. [25] Greg Michaelson and Kevin Hammond. The Hume Report Version 0.2. http://www-fp.dcs.stand.ac.uk/hume/downloads/index.html, 2004. [26] Greg Michaelson and Kevin Hammond. The Hume Report Version 0.3. http://www-fp.dcs.stand.ac.uk/hume/downloads/index.html, 2004. [27] N. Petalidis. Translating Lotos Specifications Into Promela. Master’s thesis, Heriot-Watt University, 1994. [28] Hanne Riis Nielson and Flemming Nielson. Semantics with Applications: A Formal Introduction. Wiley Series in Data Communications and Networking for Computer Progammers. wiley, chichester, 1992. [29] Nikolaj Bjorner and Anca Browne and Michael Colon and Bernd Finkbeiner and Zohar Manna and Henny Sipma and Tomas Uribe. Verifying Temporal Properties of Reactive Systems: A STeP Tutorial. Kluwer Academic Publishers, 2000. [30] Patrick Regan and Scott Hamilton. NASA’s Mission Reliable. Innovative Technology for Computer Professionals: Computer, January 2004.

[31] Robin Hunter. The Essence of Compilers. Prentice-Hall, 1999. [32] Spin Home Page. http://spinroot.com/spin/. August 2004. [33] The Hume Language: Home Page. http://www-fp.dcs.st-and.ac.uk/hume/. August 2004. [34] The Stanford Temporal Prover (STeP). http://www-step.stanford.edu/. August 2004. [35] Willem Visser, Klaus Havelund, Guillaume Brat, and SeungJoon Park. Model Checking Programs. In IEEE International Conference on Automated Software Engineering (ASE) , September 2000.

Appendix A

Abstract Syntax for Hw-Hume Backus Naur Form, or just BNF notation, is used to describe the abstract syntax of HW-HUME. The syntax is based on the syntax for full HUME [25]. The same names have been used to describe the nonterminals as in [25]. Bold text is used when representing terminals, and vertical bars ’|’ indicate alternatives. Optimal constructs are enclosed in brackets ’[ ]’ and parentheses ’( )’ indicate grouping. Ellipses ’. . . ’ indicate obvious repetitions. Each syntax definition has been named Definition #, where ’#’ is an unique number. This has been done so they can be easily referred to in later chapters.

A.1

Programs and Modules

A program in HW-HUME starts with the program keyword. Definition 1

A.2

hprogrami

::=

program hdeclsi

Declaration Language

Each declaration in HW-HUME is separated by a semi colon ’;’. Definition 2

hdeclsi

::=

hdecl0 i ; ... ; hdecln i

n>0

Compared to HUME only a restricted set of types are allowed in HW-HUME . The type declaration is allowed to declare a new data, stream together with box and wire declarations are allowed. hdecli Definition 3

::= | | |

type htypeidi hvaridi = htypei stream hiodesi hboxdecli hwiringdecli

HW-HUME supports both input streams specified by from and output streams specified by to. Definition 4

hiodesi

::=

hstreamidi ( from | to ) hstringi 70

A.3

Types

Definition 5

htypei

::= |

hexprtypei stream hexprtypei

- stream type

An expression type can either be a base type, or a tuple of types. In the latter case it cannot be an empty tuple.

Definition 6

::= |

hexprtypei

- base type - tuple

hbasetypei ( htypei , htypesi )

In the list of types each type is separated by a comma ’,’. The list can however be empty, i.e. consist of 0 items. Definition 7

htypesi

::=

htype0 i , . . . , htypen i

n>0

HW-HUME supports a subset of the types found in full HUME . Only word, int and char are supported. For the two first types the number of bits required must be specified. hbasetypei Definition 8

::= | |

word hprecisioni int hprecisioni char

In the word and int types, the number of bits that may be used for the representation must be a number between 1 and 64 inclusively. Definition 9

A.4

::=

hprecisioni

1 | ... | 64

Expression Language

The expression language is stripped down to only include variables, constants and tuples. Hence function and constructor applications are removed. The same applies to local definitions, arithmetic, case expression and conditionals. Also types coercions , timeouts and exceptions are removed. Lists and vector are not allowed either. Macro expansions are not supported, neither are ignored output. Empty tuples are not allowed either. hexpri Definition 10

::= | | |

hconstanti hvaridi ( hexpri , hexprsi ) ( hexpri )

- variable/constant - tuple - grouping

In an expression list, each expression is separated by a comma. The list can be empty. Definition 11

hexprsi

::=

hexpr0 i , . . . , hexprn i

n>0

The matches are only used in the box body in HW-HUME . Each match is separated by a vertical bar ’|’, and at least one must be present. Definition 12

::=

hmatchesi

hmatch0 i | . . . | hmatchn i

n>0

Each match is formed by a pattern that must be matched and an expression separated by an arrow. Definition 13

::=

hmatchi

hpatti → hexpri

As with expressions, patterns are stripped down to only variables, constants and tuples. hpatti Definition 14

::= | | |

hconstanti hvaridi ( hpatti , hpattsi ) ( hpatti )

- variable - tuple pattern - grouping

Each pattern is separated by a comma ’,’ and the list of pattern may be empty. Definition 15

A.5

hpattsi

::=

hpatt0 i , . . . , hpattn i

n>0

Coordination Language

The coordination layer is built up by boxes and wiring.

A.5.1 Boxes A box declaration in HW-HUME consists of the same elements as in full HUME . It starts with the box keyword followed by the id of the box, the box prelude, and at the end the body of the box.

Definition 16

hboxdecli

::=

box hboxidi hpreludei hbodyi

As in full HUME, the prelude defines the input and output types of the box, each specified in an inoutlist.

Definition 17

hpreludei

::=

in ( hinouti , hinoutlisti ) out ( hinouti , hinoutlisti )

The inoutlist contains a set of inout items, each separated by a comma ’,’. The list must have at least one inout item. Definition 18

hinoutlisti

::=

hinout0 i , . . . , hinoutn i

n>0

The inout definition has been changed slightly, compared to the one found for full HUME in [25]. This is to be able to express the translation semantics, when translating to PROMELA . The difference is the extra varidlist element. An inout element may consist of several varid elements, but at least one.

Definition 19

hinouti

::=

hvaridi , hvaridlisti :: hexprtypei

In the varidlist each varid element is separated by a comma ’,’ and the list may be empty. Definition 20

::=

hvaridlisti

hvarid0 i , . . . , hvaridn i

n>0

In the body of the box, it is first specified whether fair or unfair matching is used. Fair matching is specified by using the fair keyword, and unfair matching is specified by the match keyword. This is followed by a boxmatches element. Definition 21

hbodyi

::=

( match | fair ) hboxmatchesi

The boxmatches element is identical to the matches element defined in definition 12. Definition 22

::=

hboxmatchesi

hmatchi | hmatchesi

A.5.2 Wiring The other part of the coordination layer are the wiring declarations. The allowed wiring declarations are a subtype of what is allowed in full HUME [25]. The legal constructs are the instantiate sentence to instantiate a template, together with the template declaration and wire declaration. Replications of boxes are not allowed, nor are macros or initial declarations. Repeated wiring declarations are also illegal. ::= | |

hwiringdecli Definition 23

instantiate hwireidi as hboxidi [ * hintconsti ] htemplatedecli hwiredecli

Template declarations are performed in the same way as box declarations with the only difference being that the box keyword is replaced by the template keyword. Definition 17 defines the prelude, while definition 21 defines the body. Definition 24

htemplatedecli

::=

template htemplateidi hpreludei hbodyi

The wire declaration starts with the wire keyword. This is followed by the id of the wire, which must be the same as the id of the corresponding box. Next the sources of the input of the corresponding box, followed by the destinations of the output of the box. Definition 25

hwiredecli

::=

wire hwireidi hsourcesi hdestsi

The sources consist of a link element followed by link list element, inside parentheses. This definition is changed compared to full HUME [25]. Definition 26

hsourcesi

::=

( hlinki , hlinklisti )

The dests has the same syntax as the sources element.

Definition 27

::=

hdestsi

( hlinki , hlinklisti )

The linklist element is not in the full HUME specification. It is a list of link elements, where each element is separated by a comma ’,’. The list may be an empty list. Definition 28

hlinklisti

::=

hlink0 i , . . . , hlinkn i

n>0

The link element is made up by a link specification element and a link properties element. Definition 29

hlinki

::=

hlinkspeci hlinkpropsi

A link specification is either a connection, which is to a box, or it is a stream identification, that is the name of the stream.

Definition 30

hlinkspeci

::= |

hconnectioni hstreamidi

In a connection a dot notation ’.’ is used to find the correct variable in the correct box. The box is identified by it’s unique id and the variable by it’s unique id in the box. Definition 31

hconnectioni

::=

hboxidi . hvaridi

The linkprops element is made of 0 or more linkprop elements - hence it may be empty. Definition 32

hlinkpropsi

::=

hlinkprop0 i . . . hlinkpropn i

n>0

The only allowed linkprop element is to set the initial value. This is done by using the initially keyword. Definition 33

hlinkpropi

::=

initially hexpri

Appendix B

Translation Rules for Hw-Hume B.1 Introduction This chapter describes the translation rules from HW-HUME to PROMELA. The syntax used to describe the semantics in the translation is based on [28]. The syntax is as follows: Rule #

Ruletype ~ hHW-HUME codei  7→ hPROMELA codei | Reference ~ hargumentsi 

Each semantic rule has a number, indicated by ‘#’. This is used to refer to the rule in the text. The rule is also of a certain rule type, so the rules of the same kind can be grouped together. The HW-HUME code is inside the semantic brackets ‘~ ’. The corresponding PROMELA code is on the right hand side of the arrow. This side can also contain references to other rules, specified by the rule type, and the arguments inside the semantic brackets ‘~ ’. Terminals in the text are marked with bold text, and a special font is used to reference rules and rule types. E.g. when in the text it is stated that Ruletype2 is used, it indicates that the rule with that set of arguments of the specified rule type is called. If several rules have the same parameters, both are used unless specified otherwise. In some rules an item with the form helement hii i might appear. In this case hii represents the relative position of the element. For instance in a tuple it can represent the position of the element. The text also contains references to the abstract syntax. Each syntax definition had the name definition followed by the definition number. The HW-HUME abstract syntax is defined in appendix A.

B.1.1

Structure of the Promela Program

Figure B.1 shows the structure of the PROMELA program. All the channels must be declared first in the file. The channels are used for the interprocess communication. This is described in section B.5. The next step is to create all the processes. They are the PROMELA representation of a HW-HUME box1 .

The process declaration is explained in section B.6.

In HW-HUME each process executes sequentially while PROMELA processes execute concurrently. A special control process, forcing the PROMELA model to execute the same way as HW-HUME, is 1

Note that templates are instantiated into boxes. This is handles by the Hume parser, and is not considered.

75

1. Channel Declaration 1.1 Control Channels

1.2 Interprocess Channels

2. Process Declaration

3. Control Process Declaration

4. Stream Process Declaration 4.1 Input Streams

4.2 Output Streams

5. Init Process Declaration

Figure B.1: The Structure of the Translation

therefore created. This is explained in section B.7. HW-HUME supports input streams and output streams. Input streams are replaced by a simulator process that simulates the user inputs. As in HW-HUME, a process is used to represent an output stream. Section B.8 describes these processes. Section B.9 describes the declaration of the init process that instantiates all the processes, and initialises the channels with an initial value if it is specified in HW-HUME.

B.2 Data Types In model checking memory usage is one of the biggest problems. Therefore it is important to use the smallest data types possible. However, the data types must also correspond to the HW-HUME data types. The semantic rules for translating data types from HW-HUME to PROMELA is defined by

Types :

Types : HW-HUME Data Types ,→ PROMELA Data Types Figure 2.1 in chapter 2 contains the base types in HUME. Figure 3.1 in chapter 3 displays the base types in PROMELA. HW-HUME only contains a subset of the base types found in HUME. These are defined in definition 8 on page 71. A word is a positive integer value, where the number of bits must be a specified value ranging from ‘1’ to ‘64’ inclusively. If the value is one bit, the PROMELA type bit is used. Rule 1

Types ~ word 1  7→ bit

For values up to one byte (8 bits) the PROMELA type byte is used. It is a positive integer value of 8 bits.

Rule 2

Types ~ word 2 | . . . | 8  7→ byte

If the bit size of the integer is between 9 and 16 bits, the short value is used. Rule 3

Types ~ word 9 | . . . | 16  7→ short

For any values bigger than 16 bits, the PROMELA int value is used. It is only 32 bits, so for any values where the bit size is bigger, the values will not correspond. SPIN will automatically truncate the value to ‘0’ if the value exceeds 32 bits. Rule 4

Types ~ word 17 | . . . | 64  7→ int

A different approach would be to represent a word bigger than 32 bits with a typedef, containing two values, or just use two values. The problem is that this will complicate all other operations, without helping the main issue, which is to mainly model check the interaction between the boxes in HW-HUME. The approach formalised in rule 4 will be closer to the HW-HUME model. Rule 5 to 7 defines the semantics for translating integers. In HW-HUME an integer is constructed by specifying int followed by the bit size of the integer. Like with the word type, it is important to keep the type representation as small as possible. The PROMELA type bit is used for 1 bit integers. Rule 5

Types ~ int 1  7→ bit

PROMELA has a 16 bit integer representation called short. This is used for bit sizes ranging from 2 to 16 bits. Note that the type byte that was used for the word type cannot be used since it can only hold positive integers. Rule 6

Types ~ int 2 | .. | 16  7→ short

The largest possible PROMELA representation of an integer is a 32 bit int. Like for word, the HWHUME int type can use up to 64 bits. This problem is solved the same way as with the word type, i.e. truncate the value to ‘0’ if it exceeds 32 bits. Rule 7

Types ~ int 17 | .. | 64  7→ int

There is no representation for characters in the PROMELA language, as there is in HW-HUME. Removing all characters will take away too much from the PROMELA model compared to the HW-HUME model, and will not give a satisfying result. Each character has a special code called ASCII code or Unicode, which is a numeric value. Representing the character with the ASCII code will give a satisfying PROMELA model, that corresponds with the model in HW-HUME. A Unicode value uses 16 bit, which can be represented by a PROMELA short type. Rule 8

Types ~ char  7→ short

Tuples are the only structured type allowed in HW-HUME. There can either be represented by declaring a new structured type in PROMELA using a typedef declaration, or as a channel. Tuples are only used when boxes are communicating, which means the best result is achieved by using channels. In channels each type is separated by a comma, therefore to translate a tuple, each item in the tuple must be translated independently, and a list of the translated items, separated by a comma must be returned. In a tuple the items are enclosed by parentheses. These are removed.

Rule 9

Types ~

( hexprtypei )  7→

Types ~

hexprtypei 

The tuple is then recursively traversed, and each type is individually translated, divided by a comma. The full list is returned. Rule 10

Types ~ 7→

htypei , htypesi  htypei  , Types ~ htypesi 

Types ~

B.3 Values The semantic rules Types is concerned with translating the declaration of the types. An instance of a type contains a value, which must be translated to a correct PROMELA representation. The semantic rules for this translation are defined by Values :

Values : HW-HUME Values ,→ PROMELA Values The values in HW-HUME are either numeric or characters. The two numeric values, i.e. int and word, will be using the same values in PROMELA as in HW-HUME , regardless of size. SPIN will automatically truncate the value to 0, when it is out of bounds. Rule 11

Values ~

hinti  7→ hinti

Rule 12

Values ~

hwordi  7→ hwordi

Characters, on the other hand, cannot be used directly in PROMELA. Rule 8 states that the Unicode value is used to represent the character in PROMELA, which uses a 16 bit short for representation. Consequently the HW-HUME char must be translated to a short. Rule 13

Values ~

hchari  7→ hshorti

In HW-HUME there are two exceptions to rule 13. These are the escape sequences, which do not have a Unicode value, and must be given an unique value. The valid escape sequences in HW-HUME are newline ‘\n’ and tabulator ‘\t’. Since a Unicode value is always positive, these types will be given the values ‘-1’ and ‘-2’ respectively. These two rules override rule 13. Rule 14

Values ~

‘\n’  7→ −1

Rule 15

Values ~

‘\t’  7→ −2

When it is possible variables will have the same names in PROMELA as in HW-HUME. In some cases the names have to be changed slightly to be valid PROMELA.

Names

is applied to ensure that the

name is valid. Rule 16

Values ~

hvaridi  7→

Names ~

hvaridi 

If the value is a tuple it is enclosed by parentheses. These are removed in rule 17. Rule 17

Values ~

( htypesi )  7→

Values ~

htypesi 

A tuple can contain several values. If this is the case each value will be translated independently. A list of all translated types, separated by a comma, is then returned as rule 18 formalises. Rule 18

Values ~

htypei , htypesi  7→

Values ~

htypei  , Values ~ htypesi 

B.4 Names Some names allowed in HW-HUME are ineligible in PROMELA. This can be names used for boxes, wiring, variables, and so on. PROMELA names.

Names denotes the semantics for the translating the names into valid

Names : HUME Names ,→ PROMELA Names There are two different cases where the HW-HUME name is disallowed in PROMELA. The first case is the set of terminals (keywords), which in PROMELA differs from the set of terminals in HW-HUME. PROMELA includes the following set of terminals: hterminali ::= active | assert | atomic | bit | bool | break | byte | chan | c code | c decl | c expr | c state | c track | chan | D proctype | do | d step | else | empty | enabled | eval | false | fi | full | goto | hidden | if | init | inline | int | len | local | mtype | nempty | never | nfull | notrace | np | od | of | pc value | pid | printf | printm | priority | proctype | provided | run | short | show | skip | timeout | trace | true | typedef | unless | unsigned | xr | xs All that has to be done to translate a terminal to a non-terminal is to append a character to the name, providing the new word is not a terminal. If ‘1’ is appended to the end of a terminal, this will not happen since there are no terminals ending in ‘1’. Rule 19

Names ~

hterminali  7→ hterminali1

HW-HUME allows the use of a single quotation mark in a name. In PROMELA names quotation marks are eligible, and so need to be handled. Rule 20 replaces each quotation mark with the letter ‘q’ to make it valid. Rule 20

Names ~

hstringi’hstringi  7→ hstringiqhstringi

B.5 Channels Channels are used in two semantically different cases, control channels and interprocess communication.

ControlChan constitutes the communication with the control process that uses semaphores

to enforce the HW-HUME execution model into the PROMELA model (Section B.5.1). Channels are also used for the interprocess communication specified by the wiring in HW-HUME. Chan constitutes the semantics for these channels, and is defined in section B.5.2.

B.5.1

Control Channels

A control process is used to convert the HW-HUME execution model into the PROMELA model. The control process communicates with each process using a synchronous channel. This section contains the semantics for the channels, and

ControlProc

in section B.7 contains the semantics for the

control process. Each channel is a synchronous channel that contains an enumerated type (mtype). Each channel has the following syntax:

chan < i d > c o n t r o l = [ 0 ] o f { mtype } ;

The hidi element represents the name of the process, extracted from a wire or stream declaration.

ControlChan denotes the semantics of the control channels.

ControlChan : HUME ,→ PROMELA Channel One channel must be created for each process, including the stream processes. The message sent over the channels is of type mtype, which is the enumerated type in PROMELA. The execution model found in HW-HUME is reached by using a control process that sends a ‘BEGIN’ message using the synchronous control channel to a process when it is the process’ turn to execute. When the process has finished one run, it returns an ‘END’ message back to the control process using the same channel. Then the process is blocked until it receives a new ‘BEGIN’ message. This implies that the enumerated type holds two values ‘BEGIN’ and ‘END’ and is declared as follows:

mtype = { BEGIN , END } ;

The wire declaration is used to create a control channel for a HW-HUME box. For a stream, the stream declaration is used. In addition the mtype must be declared. Recursion is used by iterating through all declarations to ensure that all the channels are created. To be sure that the mtype is declared only once , the first run declares it and calls the rule that traverses the declarations. Rule 21

ControlChan ~ hdeclsi 

7→ mtype = { BEGIN , END }; ControlChan ~ dec hdeclsi 

If a wire declaration is found the correct rule has to be applied. Recursion is used to ensure that the other declarations are found. Rule 22

ControlChan ~ dec hwiredecli; hdeclsi  7→ ControlChan ~ hwiredecli  ControlChan ~ dec hdeclsi 

A control channel must also be created for stream declarations. Like the previous rule, the rule is recursive to make sure that all channels are created. Rule 23

ControlChan ~ dec hstreamdecli; hdeclsi  7→ ControlChan ~ hstreamdecli  ControlChan ~ dec hdeclsi 

The following rule defines the creation of a channel from a wire declaration. The name of the wire is used to ensure that the channel name is unique.

Names is used to ensure that the name is valid

PROMELA. Rule 24

ControlChan ~ wire hwireidi hsourcesi hdestsi  7→ chan Names ~ hwireidi  control = [ 0 ] of { mtype };

Control channels must also be created for each input and output stream process. As the previous rule used the wire name, so the stream name is used to make sure that the name is unique. Rule 25 and 26 create the control channels for input and output streams respectively. Rule 25

ControlChan ~ stream hstreamidi from hstringi  7→ chan Names ~ hstreamidi  control = [ 0 ] of { mtype };

Rule 26

ControlChan ~ stream hstreamidi to hstringi  7→ chan Names ~ hstreamidi  control = [ 0 ] of { mtype };

B.5.2

Interprocess Communication

A HW-HUME program consist of a set of boxes. The boxes are connected to each other or to streams by using wiring declarations. In PROMELA interprocess communication is achieved using channels. Each channel created from a box declaration has the following syntax (the stream channels will have a different syntax, shown later):

chan < b o x i d> < v a r i d > = [ 1 ] o f < e x p r t y p e >;

In HW-HUME each box has a corresponding wire declaration, which defines the source of the inputs and the destination of the outputs. In addition, the box specifies the inputs and outputs in its prelude. This suggests that there are four different sources for creating the channels in PROMELA. The problem with using the wire declaration is that it doesn’t specify the types sent over the channel. This implies that only the input and output of the box can be used. In the translation the output of the box has been chosen. For each variable in each box output-element, a channel is created. The semantic rules for creating the channels used for interprocess communication is denoted by Chan .

Chan : HW-HUME Interprocess Communication ,→ PROMELA Channels First all the box declarations must be found, and the correct rule must be applied to it. In rule 27 this is accomplished by recursively iterating all declarations. Rule 27

Chan ~ hboxdecli; hdeclsi  7→ Chan ~ hboxdecli  Chan ~ hdeclsi 

In each box declaration only the unique name of the box, together with the output-items are required to create the channels, as formalised in rule 28. Rule 28

Chan ~ 7→

box hboxidi in ( hinoutlist1 i ) out ( hinoutlist2 i ) hbodyi  hboxidi hinoutlist2 i 

Chan ~

Definition 18 defines the syntax for the list with the out-items. Each of these items is separated by a comma. As rule 29 shows, recursion is used to iterate through each item in the list. The correct rule is then applied to each item separately. Rule 29

Chan ~ hboxidi hinouti , hinoutlisti  7→ Chan ~ hboxidi hinouti  Chan ~ hboxidi hinoutlisti



Each output-element has a list of minimum one variable name, and the expression type, separated by two colons ‘::’. A channel must be created for each variable, therefore each variable must be translated separately. The box name and type is also required. Rule 30 iterates the list and calls the correct rule with the specified arguments.

Rule 30

Chan ~ hboxidi hvaridi , hvaridlisti :: hexprtypei  7→ Chan ~ hboxidi hvaridi hexprtypei  Chan ~ hboxidi hvaridlisti::hexprtypei 

Rule 31 creates the PROMELA channel. It has the syntax specified in the beginning of the section. Names is used to get a legal PROMELA name for the box name and variable name, while Types is used to get the corresponding PROMELA data type.

Rule 31

Chan ~ hboxidi hvaridi hexprtypei  7→ chan Names ~ hboxidi  Names ~ = [1] of { Types ~ h exprtype i  };

hvaridi 

In addition to the communication between boxes in HW-HUME, there are communication links to the streams. In PROMELA the streams are represented as processes, and channels must be created between the process that uses the stream process, and the stream process itself. Note that in HWHUME the relationship to a stream is a 1:1 relationship. This implies that only one box can be wired to a stream. Since the channels are created from the output of HW-HUME boxes, the channel used by an output stream process is already created. Hence channels are only created for the input stream processes. The channel created from an input stream has the following syntax:

chan < s t r e a m i d> o u t = [ 1 ] o f < e x p r t y p e >;

The name of the channel is the stream followed by ‘ out’, thus the name of stream is required. The correct expression type is also required. This is found in the prelude of the box that uses the stream. Rule 32 finds all input streams using recursion. To be able to create the channel the type is required. This is defined in the box declaration that uses the stream. To find the type

Stream

defined in

section B.8 is used. Rule 32

Chan ~ stream hstreamidi from hstringi; hdeclsi  7→ Chan ~ stream Stream ~ stream hstreamidi from hstringi; hdeclsi 



The inputs in rule 33, except the stream keyword, are returned when using Stream . The rule creates

the PROMELA code using the defined syntax. It uses Names to ensure that the stream name is a valid

PROMELA name, and Types to get the PROMELA type corresponding to the one found in HW-HUME . Rule 33

Chan ~ stream hwireidi hstreamidi hvaridi hexprtypei  7→ chan Names ~ hstreamidi  out = [1] of { Types ~ hexprtypei  };

B.6 Processes This section declares the rules for translating HW-HUME boxes into PROMELA processes.

Proc de-

notes the semantics for this translation.

Proc : HW-HUME Boxes ,→ PROMELA Processes It is a cumbersome process to translate the HW-HUME boxes into PROMELA processes, and thus it has been divided into three different parts, giving the process the following syntax:

< p r o c e s s p r e l u d e >{ < p r o c e s s body> }

The process prelude, declared in section B.6.1, creates the signature of the process. The variable declaration declares the variables, if the process contains variables, and process body is concerned with creating the main body of the process. The two last parts are created in section B.6.2 and B.6.3 respectively. Rule 35 formalises this, while rule 34 traverses all declarations to obtain all the box declarations.

Prelude denotes the creation of the process prelude, Vars

the variable declaration,

and Body the creation of the main body of the process. Rule 34

Rule 35

B.6.1

Proc ~ Proc ~ 7→

hboxdecli; hdeclsi  7→

Proc ~ hboxdecli  Proc ~ hdeclsi 

hboxdecli  Prelude ~ hboxdecli  { Vars ~ hboxdecli  Body ~ hboxdecli  }

Process Prelude

The signature or prelude of the process is divided into two different parts. This first defines the process name and then declares the formal parameters of the process. The process prelude has the following syntax: p r o c t y p e < p r o c e s s i d > ( chan < p a r a m e t e r l i s t > )

The process name is the same as the box name, and all parameters are channels.

Prelude denotes

the semantics for the process prelude.

Prelude : HW-HUME Box ,→ PROMELA Process Prelude The creation of the process name and the formal parameter declaration are separated out into two different parts, as shown in rule 36. The next section describes the first part, and the section after describes the second part. Rule 36

Prelude ~ hboxdecli  7→ Prelude ~ name hboxdecli  Prelude ~

param hboxdecli 

Name Definition The name of a PROMELA process is the name of the corresponding HW-HUME box. To ensure that the name is a valid PROMELA name, Names is applied. To declare that it is a process, the proctype keyword starts the declaration. Rule 37 formalises this. Rule 37

Prelude ~ name box hboxidi hpreludei hbodyi

 7→ proctype Names ~ hboxidi 

Defining Parameters The parameterlist is created based on the input and output elements in the prelude of a HW-HUME box. Rule 38 extracts the prelude from the box declaration. Rule 38

Prelude ~

param box hboxidi hpreludei hbodyi  7→ Prelude ~ hpreludei 

Rule 39 shows the creation of the parameterlist in PROMELA. All parameters are channels - hence the list must start with the chan keyword. The input channels, i.e. the channels that are read from, are created from the input element in the prelude of a HW-HUME box, while the output channels, which are written to, are created from the output element in the prelude. In addition, each PROMELA process also includes a channel called ‘control’, used to coerce the HW-HUME execution model onto the PROMELA model. Each item in the parameterlist is separated by a comma and the parameterlist is enclosed by parentheses. Rule 39

Prelude ~

in ( hinoutlist1 i ) out (hinoutlist2 i)  7→ ( chan Prelude ~ in hinoutlist1 i  , Prelude ~ out hinoutlist2 i  , control )

The input channels are created from the list of input items in the HW-HUME box prelude. Each input item is separated by a comma. Rule 40 traverses the list and manages each input separately. In the parameterlist for the PROMELA process each channel is also separated by a comma. Rule 40

Prelude ~ in hinouti , hinoutlisti  7→ Prelude ~ in hinouti  , Prelude ~

in hinoutlisti 

Only the variable name is used to declare a channel. Rule 41 extracts all variable names from the input-element. Rule 41

Prelude ~ in hvaridi , hvaridlisti :: hexprtypei  7→ Prelude ~ in hvaridi  , Prelude ~ in hvaridlisti :: hexprtypei



The input channels will be given the name in n , where n is a numeric value reflecting the variable’s relative position in the input list starting with ‘1’. E.g. if a box has three inputs the list “in1, in2, in3” is generated. This is illustrated in rule 42. Rule 42

Prelude ~

in hvaridhii i  7→ inhii

The output channels are created the same way as input channels, with the only differences being that the list of output items is used instead and the name starts with ‘out’. Rule 43 is the output version of rule 40.

Rule 43

Prelude ~ out hinouti , hinoutlisti  7→ Prelude ~ out hinouti  , Prelude ~

out hinoutlisti 

In same way as the previous rule corresponded to rule 40, rule 44 correspond to rule 41. Rule 44

Prelude ~ out hvaridi , hvaridlisti :: hexprtypei  7→ Prelude ~ out hvaridi  , Prelude ~ out hvaridlisti :: hexprtypei 

Each output channel are given the name out n , where n reflects the relative position, the same way as it does for input channels. This is formalised in rule 45. Rule 45

B.6.2

Prelude ~ out hvaridhii i

 7→ outhii

Variable Declarations

In HW-HUME variables are declared in the pattern matches. This cannot be done in PROMELA, since variables cannot be used before they are declared. The variables have to be declared before the process enters its main loop. The variables are declared by going through all pattern matches. If a variable is found, and it is not already declared, the process prelude is used to declare it. The semantics for creating the variables are denoted by Vars .

Vars : HW-HUME ,→ PROMELA Variable Declaration To declare a variable the variable name and data type must be known. In HW-HUME the variable name is declared in a pattern match, which is in the box body, and the data type is declared in the box prelude. Rule 46 extracts these elements from the box declaration. Rule 46

Vars ~ box hboxidi hpreludei hbodyi 7→ Vars ~ hpreludei hbodyi 



Rule 47 extract the list with the input-items from the prelude. The output items are not required since variables are declared in the pattern matches. The boxmatches element is extracted from the body. Rule 47

Vars ~ 7→

in ( hinoutlist1 i ) out ( hinoutlist2 i ( match | fair ) hboxmatchesi )  Vars ~ hinoutlist1 i hboxmatchesi 

When declaring the variables, the data type of the variable in the prelude is used. For a variable declaration in a pattern match in HW-HUME, the expression type in the same position must be found. This implies that for all patterns the corresponding expression type must be obtained. First each input element is extracted. Rule 48

Vars ~ hinouti , hinoutlisti hboxmatchesi  7→ Vars ~ hinouti hboxmatchesi  Vars ~

hinoutlisti hboxmatchesi 

In each input element all expression types are located by traversing the list of variables.

Vars ~ Rule 49

7→

hvaridi , hvaridlisti :: hexprtypei hboxmatchesi  hexprtypei hboxmatchesi  hvaridlisti :: hexprtypei hboxmatchesi 

Vars ~ Vars ~

The next step is to iterate through all the matches, as performed in rule 50. Rule 50

Vars ~ 7→

hexprtypei hmatchi | hmatchesi  Vars ~ hexprtypei hmatchi  Vars ~ hexprtypei hmatchesi 

A match is built up by a pattern that the input is compared with, and if they match, an expression generates the output. The pattern and expression are separated by an arrow ‘→’. Only the pattern is required, which rule 51 extracts from the match. Rule 51

Vars ~

hexprtypei hpatti → hexpri  7→

Vars ~

hexprtypei hpatti 

The pattern may be a tuple, enclosed by parentheses. If that is the case, the parentheses are removed.

Rule 52

Vars ~

hexprtypei ( hpatti )  7→ Vars ~ hexprtypei hpatti 

In rule 53 hii and h ji reflects the respective positions of the expression type and the pattern. The rule finds the pattern that matches the expression. If the current pattern is not in the correct position, the rule checks the next pattern. If it matches, the rule that creates the PROMELA code is called. if [ hii ≡ h ji ]

Rule 53

else

Vars ~

hexprtypehii i hpatth ji i , hpattsi  7→ Vars ~ hexprtypehii i hpatth ji i 

Vars ~

hexprtypehii i hpatth ji i , hpattsi  7→ Vars ~ hexprtypehii i hpattsi 

Definition 14 defines the syntax of a pattern. A pattern can be of a variable type. It is only if this is the case that the variable is declared. A variable can only be declared once, which rule 54 takes care of. Note that the declarations are per process, and not for the entire model. This means the same declarations are allowed in different processes. Rule 54

B.6.3

if [ hnot declaredi ]

Vars ~

hexprtypei hvaridi  7→

Types ~

hexprtypei  Names ~ hvaridi  ;

Process Body

The body of a HW-HUME box consists of a set of matches that are compared to the inputs of the box, and generates output based on the input. There are two semantically different approaches in the order of the matches. Fair matching is the first and is introduced by the fair keyword. The last selected match is always compared first with the inputs. Unfair matching or sequential matching is performed in a top to bottom order. It is introduced by the match keyword. Regardless of the match type the PROMELA process representing a HW-HUME box must be synchronised with the control process to coerce the same execution order as in HW-HUME. The general PROMELA code for a HW-HUME box body is:

start : c o n t r o l ?BEGIN ; < F a i r M a t c h i n g > | < U n f a i r M a t c h i n g> finish : c o n t r o l !END; goto s t a r t ;

The synchronisation with the control process is achieved by receiving a ‘BEGIN’ message prior to each run, and sending an ‘END’ message to the synchronous control channel. The ‘start’ label and the ‘goto’ statement ensures infinite repetitions. The ‘finish’ label is used to exit the matching part if the input does not match any of the input. The semantics of the process body is denoted by Body :

Body : HUME ,→ PROMELA Process Body Rule 55 has the box declaration as an argument. Both the prelude and the body elements are required to create the PROMELA code. The rule extracts these elements, and generates the PROMELA code that is independent of the matching form.

Body ~

box hboxidi hpreludei hbodyi  7→ start: control?BEGIN; Body ~ hpreludei hbodyi  finish: control!END; goto start;

Rule 55

Fair and unfair matching have completely different semantics. Therefore the semantics of the PROMELA code differs.

Fair

handles the fair matching, and Unfair handles unfair matching. This

is formalised in the following two rules. Rule 56

Body ~

Rule 57

Body ~

hpreludei fair hboxmatchesi  7→ Fair ~ hpreludei fair hboxmatchesi 

hpreludei match hboxmatchesi  7→ Unfair ~ hpreludei unfair hboxmatchesi 

Fair Matching In fair matching the last pattern matched is chosen first to be matched with the inputs. In PROMELA this can be represented by the non-deterministic if clause. The if clause includes a set of options, where one of the options that satisfies the condition is randomly chosen. The first statement in the option is called the guard condition. If it succeeds the option is satisfied, and the rest of the statements in that option are executed. The syntax of a PROMELA process main body using fair matching is as follows:

if : : < match1> : : < match2> ... : : < matchn> : : e l s e goto f i n i s h fi ;

In the code, each match has two colons as prefix. If no match succeeds, the PROMELA process will be blocked until one does. In HW-HUME it will simply do nothing, and give the control to the next box. In the next run it will start at the beginning again. To gain the same behaviour in PROMELA, the goto statement has been used together with the else keyword. The process will exit the if statement, and go to the ‘finish’ label, which is just after the if statement, if all other matches fails.

Fair

denotes

the semantics for fair matching.

Fair : HW-HUME Fair Matches ,→ PROMELA Nondeterministic Rule 58 creates the if clause enclosing all the matches. The rule also calls the rule that creates the PROMELA code for each match. To end the if clause fi must be used. Rule 58

Fair ~ hpreludei fair hboxmatchesi  7→ if Fair ~ hpreludei hboxmatchesi

 ::else goto finish fi;

A boxmatches element consists of one or more match elements, each separated by a vertical bar ‘|’. Definition 22 defines that the boxmatches-element is built up of a match and a matches element, where the latter consist of zero or more match-elements. Rule 59 obtains all match-elements, and handle them separately. Rule 59

Fair ~ hpreludei hmatchi | hmatchesi  7→ Fair ~ hpreludei hmatchi  Fair ~ hpreludei hmatchesi



The PROMELA code for one specific match is identical for both fair and unfair matching. In both cases

Match

is used. Rule 60 uses

Match

to create the code. Each match has a double colon

prefix, to separate them from each other in the if clause. Rule 60

Fair ~ hpreludei hmatchi

 7→ ::

Match ~

hpreludei hmatchi 

Unfair Matching When using unfair matching, the matches are selected in a top to bottom order, which gives it a deterministic nature. In PROMELA there is no deterministic selection structure - hence it has to be manually implemented. This can be achieved by using a set of if-else clauses, where each if clause has exactly one option, including a match, and the else clause contains another if-else clause with exactly one option, which holds the next match. One if-else clause will then be created for all matches, except the last one which only has an if clause. The following PROMELA code illustrates this with two matches as example. Like in Fair , if none of the matches succeeds the process control is redirected to the ‘finish’ label.

if : : < match1> : : else if : : < match2> : : e l s e goto f i n i s h fi ; fi ;

Unfair

denotes the semantics for the unfair matching.

Unfair : HW-HUME Unfair Matches ,→ PROMELA Deterministic The semantics for unfair matches are more cumbersome than for fair matches. The first match is different from the rest, since it doesn’t start with an else clause. Rule 61 uses Match to create the PROMELA code for the first match, and calls the rule that creates the PROMELA code for the rest of the matches. Rule 61

Unfair ~ hpreludei match hmatchi | hmatchesi  7→ if :: Match ~ hpreludei hmatchi  Unfair ~ hpreludei hmatchesi  fi;

Rule 62 and 63 creates the PROMELA code for the rest of the matches. This is achieved by recursively iterating the match elements. Note that the fi statement ends the if clause. Note that if the matcheselement is not empty, the PROMELA code for the succeeding matches must be generated before the fi statement of one match. Rule 62

Unfair ~ hpreludei hmatchi | hmatchesi  7→ :: else if :: Match ~ hpreludei hmatchi  Unfair ~ hpreludei hmatchesi

 fi;

Rule 63 creates the PROMELA code for the last match, when the matches element is empty. The case with no matches is handled here by forcing the process control to the ‘finish’ label with the goto statement. Rule 63

Unfair ~ hpreludei hmatchi  7→ :: else if :: Match ~ hpreludei hmatchi

 :: else goto finish fi;

Matches Tuples complicate the translation of box matches. The problem is that both in the pattern matches and the expressions that generates the output, the expression type is not specified. There is then no way to tell whether a pattern/expression is part of a tuple or not. In “PROMELA for HW-HUME” values in a tuple are written to the same channel, which implies that the knowledge of the expression type is required. A consequence is that the prelude, where the expression type is defined, must be used. Each match has the following PROMELA syntax:

( i n 1 ?[< p a t t 1 > ] & & . . . & & inm ?[< p a t t n > ] ) −> i n 1 ?< p a t t > ; . . . ; i n n ?< p a t t n >; o u t 1 !< e x p r 1 > ; . . . ; o u t i !< e x p r j >;

In the guard condition of a PROMELA match, enclosed by the parentheses, each channel is tested to see if the read operation succeeds. This is achieved by enclosing the right hand side of the read operator ‘?’ in square brackets ‘[ ]’. Note that the number of input channels (‘m’), and the number of patterns (‘n’), might differ due to the use of tuples. If the guard condition succeeds, the values are read from the tuples and the output is sent to the output. The number of output channels (‘i’) and expressions (‘j’) may also differ.

Match denotes the semantics for the matches.

Match : HW-HUME Matches ,→ PROMELA Matches Rule 64 generates the PROMELA code for a match. As input it takes the box prelude, which consist of the list of input-items and the list of output-items, together with the HW-HUME match item. The PROMELA code is divided into three parts. First the guard condition is created using Patt . The guard condition checks if the read operations on the input channels are possible. The guard condition is enclosed by parenthesis. The guard condition is separated from the rest of the statements by an arrow. If the guard condition succeeds, the channels are read from, and the output is sent to the output channels. Reading and omitting values from the input channels and sending the output to the output channels are accomplished using Exp . For all operations the process prelude must be used. For checking and reading from channels the list with the input-elements is required, and to generate the output, the list of output-elements is needed. The rule extracts the correct element in the three different cases.

Match ~

in ( hinoutlist1 i ) out ( hinoutlist2 i hpatti → hexpri  7→ ( Patt ~ hinoutlist1 i hpatti  ) → Exp ~ hinoutlist1 i hpatti  Exp ~ hinoutlist2 i hexpri 

Rule 64

Pattern Matching The pattern matching section is concerned with creating the guard condition. The guard condition has the following syntax in PROMELA: ( i n 1 ?[< p a t t 1 > ] & & . . . & & inm ?[< p a t t n > ] )

The code was explained in the previous section (Match ). The semantics for pattern matches are

denoted by Patt .

Patt : HW-HUME Patterns ,→ PROMELA Guard Condition If the pattern consist of more than one input element, it is surrounded by parenthesis, which are removed in rule 65. Rule 65

Patt ~

hinoutlisti ( hpatti )  7→

Patt ~

hinoutlisti hpatti 

To create the PROMELA code, the expression type in the input element list in the process prelude is first obtained. The list of patterns is then traversed to find the corresponding pattern. This approach will handle the “tuple-problem” described earlier. Rule 66 iterates recursively through the input element list, and handles each input element individually. Rule 66

Patt ~ 7→

hinouti , hinoutlisti hpatti  Patt ~ hinouti hpatti  Patt ~ hinoutlisti hpatti 

Each input element includes a list of one or more variable name elements. Rule 67 recursively separates out each of them. In the guard condition each statement is separated by two ampersands ‘&&’, as the rule shows.

Patt ~

hvaridi , hvaridlisti :: hexprtypei hpatti  7 → Patt ~ hvaridi :: hexprtypei hpatti  && Patt ~ hvaridlisti :: hexprtypei hpatti 

Rule 67

Rule 68 creates the PROMELA code that checks one channel. The channel name is ‘in’ followed by a number reflecting the relative position of the variable name in the process prelude. A different rule creates the expression on the right hand side of the receive operator ‘?’ since it might be a tuple. Since the channel is only checked, and the values are not omitted from the channel, the expression on the right hand side is enclosed by square brackets. Rule 68

Patt ~

hvaridhii i :: hexprtypei hpatti  7→ inhii ? [ Patt ~ hexprtypei hpatti  ]

If the expression type is a tuple, each type is considered separately. In the created PROMELA code a comma will separate each element. Rule 69 illustrates this by using recursion when traversing the type-element list. Rule 69

Patt ~ htypei , htypesi hpatti  7→ Patt ~ htypei hpatti  , Patt ~ htypesi hpatti 

If the expression type is not a tuple, it must be a base type. If this is the case the pattern corresponding to the type must be found. Rule 70 uses recursion to find the pattern. The rule recursively iterates through the pattern-list. If it finds the pattern corresponding to the expression type, Values is used to translate the HW-HUME pattern to the PROMELA representation. If does not correspond, the pattern is checked using recursion. Note that hii represents the position of the base type in the prelude, and h ji represents the position in the pattern. if [ hii ≡ h ji ]

Rule 70

else

Patt ~ hbasetypehii i hpatth ji i , hpattsi

 7→ Values ~ hpatth ji i 

Patt ~ hbasetypehii i hpatth ji i , hpattsi

 7→ Patt ~ hbasetypehii i hpattsi 

Expressions In this section the PROMELA code on the right hand side of the arrow in a match is created. Both the PROMELA code that reads the values from the input channels, and the code to write to the output channels. The semantics are denoted by Exp .

Exp : HW-HUME Expressions ,→ PROMELA Expressions The first thing to do is to read the values from the input channel. The rules here will be almost identical to all the rules in

Patt .

The only difference is that each statement is separated by a

semicolon instead of the two ampersands, and the square brackets enclosing the values are removed. This will give the PROMELA code the following syntax: i n 1 ?< p a t t 1 > ; . . . ; inm?< p a t t n >

Like for rule 65 the parenthesis surrounding the patterns are removed if they exist. Rule 71

Exp ~

hinoutlisti ( hpatti )  7→

Exp ~

hinoutlisti hpatti 

Rule 72 is identical to rule 66. Rule 72

Exp ~

hinouti , hinoutlisti hpatti  7→ Exp ~ hinouti hpatti  Exp ~ hinoutlisti hpatti 

When reading from channels each operation is separated by a semicolon, compared to two ampersands like in Patt . This is the only difference between rule 73 and rule 67.

Exp ~ 7→

Rule 73

hvaridi , hvaridlisti :: hexprtypei hpatti  Exp ~ hvaridi :: hexprtypei hpatti  ; Exp ~ hvaridlisti :: hexprtypei hpatti 

Rule 74 removes the square brackets surrounding the pattern. This is the only difference from rule 68. It uses Patt to fetch the correct PROMELA values from the pattern. Rule 74

Exp ~

hvaridhii i :: hexprtypei hpatti  7→ inhii ?

Patt ~ hexprtypei hpatti 

Creating the output channels is a similar operation as used in Patt . The main difference is that the pattern element is replaced by an expression element, which is similar. The list of input elements is replaced by the list of output elements. Each statement is separated with a semicolon and not two ampersands. The channel name starts with ‘out’ and not ‘in’, and the read operator ‘?’ is replaced with the write operator ‘!’. The syntax is as follows: o u t 1 !< e x p r 1 > ; . . . ; outm !< e x p r n >;

As for rule 65, which removed the parentheses surrounding the patterns if they exists, rule 75 removes the parentheses enclosing the expression. Rule 75

Exp ~

hinoutlisti ( hexpri )  7→

Exp ~

hinoutlisti hexpri 

Rule 76 iterates recursively through the list of output elements the same way as rule 66 does with input elements. Rule 76

Exp ~

hinouti , hinoutlisti hexpri  7→ Exp ~ hinouti hexpri  Exp ~ hinoutlisti hexpri 

Each statement is separated by a semicolon. Rule 77 obtains each variable name in the outputelement list, and separates them with a semicolon. The rule is similar to rule 67.

Exp ~ 7→

Rule 77

hvaridi , hvaridlisti :: hexprtypei hexpri  Exp ~ hvaridi :: hexprtypei hexpri  ; Exp ~ hvaridlisti :: hexprtypei hexpri 

Rule 78 creates the PROMELA code that writes to the output channel. The channel name is ‘out’ followed by a number representing the relative position in output-element list. The send operator ‘!’ sends the right hand side of the operator to the channel of the left hand side. Rule 78

Exp ~

hvaridhii i :: hexprtypei hexpri  7→ outhii !

Exp ~ hexprtypei hexpri 

Rules 79 and 80 find the PROMELA representation of the expression. The only difference between the two rules and rules 69 and 70 in Patt is that ‘pattern’ is replaced by ‘expression’ in the arguments to the rule. Rule 79

Exp ~ htypei , htypesi hexpri  7→ Exp ~ htypei hexpri  , Exp ~ htypesi hexpri  if [ hii ≡ h ji ]

Rule 80

else

Exp ~ hbasetypehii i hexprh ji i , hexprsi

 7→ Values ~ hexprh ji i 

Exp ~ hbasetypehii i hexprh ji i , hexprsi

 7→ Exp ~ hbasetypehii i hexprsi 

B.7 The Control Process In HW-HUME each box executes sequentially, starting with the first declared box. It finishes one run, and then the next declared box finishes one run. When the last declared box has finished its run, the first starts the next run. This is explained in detail in section 2.7. In SPIN the next statement to be executed is the next statement in a randomly selected process. When performing a full verification all possible execution trails are tried. The SPIN execution model is explained in detail in section 3.9.2. The control process is a process which by using rendezvous communication implement semaphores that coerce the HW-HUME execution model into the PROMELA model. The stream processes also implements the execution model. The control process has the PROMELA syntax: a c t i v e proctype C o n t r o l ( ) { do : : [ for each p r o c e s s ] c o n t r o l ! BEGIN ; < b o x i d> c o n t r o l ?END; [ f o r e a c h o u t p u t stream ] < s t r e a m i d> c o n t r o l ! BEGIN ; < s t r e a m i d> c o n t r o l ?END; od ; }

The main body of the process is inside a do loop, which it never leaves, and therefore the process will never terminate. Inside the loop a ‘BEGIN’ message is first sent to the first channel, which

is the control channel to the first process. The control process then receives an ‘END’ message back on the same channel. Since a rendezvous channel is used, the control process is blocked until it receives the message. When it is received it means that the process has finished one run. A ‘BEGIN’ message is then sent to the next process, and so on. Note that the order of the processes is important. The order must be the same as the order they are declared in the HW-HUME source code. When all processes, including the stream processes, have finished one run, the first process starts the second run, and so on. This will repeat itself infinitely. The PROMELA processes now executes sequentially, like HW-HUME boxes. When declaring the control process the proctype uses the active keyword as a prefix which will instantiate one process.

ControlProc denotes the semantics for the

control process.

ControlProc : HW-HUME ,→ PROMELA Control Process For each wire and stream declaration, a control channel must be set up in the program loop. Recursion is used to find these declarations. First the control process signature and do loop must be created. Rule 81 creates these and calls the rule that creates the main body. Rule 81

ControlProc ~

hdeclsi  7→ active proctype Control(){ do ::

ControlProc ~ control hdeclsi

 od; }

Each time a wire declaration is found the rule to set up a channel is called. Rule 82

ControlProc ~ control hwiredecli ; hdeclsi  7→ ControlProc ~ hwiredecli  ControlProc ~ control hdeclsi



As in the previous rule, each time a stream declaration is located, the correct rule to create the PROMELA code is called. Rule 83

ControlProc ~ control hstreamdecli ; hdeclsi  7→ ControlProc ~ hstreamdecli  ControlProc ~ control hdeclsi



For each wire declaration a control channel has been created in section B.5.1. The name of the channel is the wire name with postfix ‘ control’.

Names is used to ensure that the name is a valid

PROMELA name. First the ‘BEGIN’ message is sent to the channel, before the process waits for an ‘END’ message on the channel, as shown in rule 84.

Rule 84

ControlProc ~ wire hwireidi hsourcesi hdestsi  7→ Names ~ hwireidi  control ! BEGIN ; Names ~ hwireidi  control ? END ;

Rule 85 and 86 achieves the same for streams as rule 84 did for channels. The rules uses the stream name, together with Names which ensures the name is valid PROMELA .

Rule 85

ControlProc ~ stream hstreamidi from hstringi  7→ Names ~ hstreamidi  control ! BEGIN ; Names ~ hstreamidi  control ? END ;

Rule 86

ControlProc ~ stream hstreamidi to hstringi  7→ Names ~ hstreamidi  control ! BEGIN ; Names ~ hstreamidi  control ? END ;

B.8 Stream Processes HW-HUME allows both input and output streams. To be able to model check the PROMELA model it must be in a closed environment, meaning that input from the user is not allowed. As a result the user input is replaced by a process that simulates user input. Section B.8.1 describes this process. Output streams cannot manipulate the model, and are therefore allowed. To make the PROMELA model as analogous as possible to the HW-HUME model, the output stream is represented as a process. Section B.8.2 describes the output streams. To be able to create both types of streams, elements in the stream declaration, the wire declaration that wires the stream to a box, and the box declaration that uses the stream are required.

Stream denotes the semantics to find the required elements.

Stream : HW-HUME ,→ Stream Rules The initial rule accepts as argument a stream declaration, together with the all the other declarations. It then iterates through all declarations after wire declarations, and calls the next rule with the wire declaration added to the argument list. From the stream declaration the name of the stream is extracted, together with the ‘from | to’ element that indicates the type of stream.

Rule 87

Stream ~ stream hstreamidi ( from | to ) hstringi; hwiredecli; hdeclsi  7→ Stream ~ ( from | to ) hstreamidi hwiredecli hdeclsi  Stream ~ stream hstreamidi ( from | to ) hstringi; hdeclsi 

If the stream is an input stream, indicated by the ‘from’ keyword, the sources element is obtained from the stream. Rule 88

Stream ~ from hstreamidi wire hwireidi hsourcesi hdestsi hdeclsi 7→ Stream ~ from hstreamidi hwireidi hsourcesi hdeclsi 



If the stream is an output stream, the destinations elements is obtained. Output streams are identified by the ‘to’ keyword. Rule 89

Stream ~ to hstreamidi wire hwireidi hsourcesi hdestsi hdeclsi  7→ Stream ~ to hstreamidi hwireidi hdestsi hdeclsi 

Both sources and destinations elements contains a list of minimum one link elements, enclosed by parentheses. These are removed. Rule 90

Stream ~ ( from | to ) hstreamidi hwireidi ( hlinki , hlinklisti ) hdeclsi  7→ Stream ~ ( from | to ) hstreamidi hwireidi hlinki , hlinklisti hdeclsi 

Rule 91 iterates through the list with all link elements. Each link element is treated separately.

Rule 91

Stream ~ ( from | to ) hstreamidihwireidi hlinki , hlinklisti hdeclsi  7→ Stream ~ ( from | to ) hstreamidi hwireidi hlinki hdeclsi  Stream ~ ( from | to ) hstreamidi hwireidi hlinklisti hdeclsi 

A link element is either a connection, i.e. a reference to an input/output variable in a box, or a stream name. Only if the link is a stream, and the name of stream is equivalent to the name of the stream in stream declaration, does processing continue.

if [ hstreamid1 i ≡ hstreamid2 i ]

Rule 92

Stream ~ ( from | to ) hstreamid1 i hwireidi hstreamid2 i hdeclsi  7→ Stream ~ ( from | to ) hwireidi hstreamid 2 i hdeclsi 

After the wire declaration elements are extracted, the correct box declaration must be obtained. This is achieved in rule 93, which traverses the declarations after box declarations. Each time a box declaration is found the next rule is called, with the box declaration appended to the argument list.

Rule 93

Stream ~ ( from | to ) hwireidi hstreamidi hboxdecli; hdeclsi  7→ Stream ~ ( from | to ) hwireidi hstreamidi hboxdecli  Stream ~ ( from | to ) hwireidi hstreamidi hdeclsi 

If the box name is the same as the name of the wire, then the box is the box that corresponds to the wire. Only then will processing continue. Only the prelude is required from the box declaration, and this is extracted. if [ hwireidi ≡ hboxidi ]

Rule 94

Stream ~ ( from | to ) hwireidi hstreamidi box hboxidi hpreludei hbodyi 7→ Stream ~ ( from | to ) hwireidi hstreamidi hpreludei 



The prelude consists of the declaration of the input and output elements. If the stream is an input stream, indicated by the ‘from’ keyword, the input elements are extracted. This is formalised in rule 95. Rule 95

Stream ~ from hwireidi hstreamidi in ( hinoutlist 1 i ) out ( hinoutlist2 i ) 7→ Stream ~ hwireidi hstreamidi hinoutlist 1 i 



Output streams are indicated by the ‘to’ keyword. In this case the output elements must be extracted from the prelude, like rule 96 illustrates. Rule 96

Stream ~ to hwireidi hstreamidi in ( hinoutlist1 i ) out ( hinoutlist2 i ) 7→ Stream ~ hwireidi hstreamidi hinoutlist 2 i 



The list with the input or output elements is traversed in 97. Each element is dealt with individually.

Rule 97

Stream ~ hwireidi hstreamidi hinouti , hinoutlisti  7→ Stream ~ hwireidi hstreamidi hinouti  Stream ~ hwireidi hstreamidi hinoutlisti 

In the input and output elements, each variable is handled independently. The expression type is also required.

Rule 98

Stream ~ hwireidi hstreamidi hvaridi , hvaridlisti :: hexprtypei  7→ Stream ~ hwireidi hstreamidi hvaridi :: hexprtypei  Stream ~ hwireidi hstreamidi hvaridlisti :: hexprtypei 

hii and h ji in rule 99 reflect the relative position in the list. If these values are equal the rule returns all arguments. If they are not equal, nothing is returned. if [ hii ≡ h ji ]

Rule 99

Stream ~ hwireidi hstreamidhii i hvaridi hexprtypeh ji i 7→ hwireidi hstreamidhii i hvaridi hexprtypeh ji i



B.8.1

Input Streams

To be able to model check a model, the model has to be closed from its environment. By closed it is implied that the model cannot accept any input from the environment, i.e. the environment cannot manipulate the model. To be able to verify a model all possible runs must be tested. Since there is no way to control the user inputs, this will be impossible. The solution when the HW-HUME model requires input from the user is to create a process that simulates the input. The simulation process in PROMELA has the syntax: a c t i v e proctype process name ( ) { start : c o n t r o l ?BEGIN ; if : : ( nempty ( o u t ) ) − > o u t !< v a r s > ; < i n c r e a s e v a r s >; : : e l s e goto f i n i s h fi ; finish : c o n t r o l !END; goto s t a r t ; }

InStream denotes the semantics for simulating the HW-HUME input stream in PROMELA.

InStream : HW-HUME Input Stream ,→ PROMELA Input Stream Process The rule that creates the simulator (rule 100) accepts an input stream, together with a list of all the other declarations as arguments. Since the simulator has not got any parameters, the active keyword is used as a prefix in the process signature. This will instantiate one process. The process has the same name as the stream.

Names

ensures that the name is valid PROMELA . Rule 101 creates the

body. To extract all the elements needed, rule 100 uses Stream .

Rule 100

InStream ~ stream hstreamidi from hstringi; hdeclsi  7→ active proctype Names ~ hstreamidi  (){ Instream ~ Stream ~ stream hstreamidi from hstringi; hdeclsi  InStream ~ hdeclsi 

}

The body of the simulator is created in rule 101. As an argument it accepts the elements created by

Stream . In the body the output channel and the variables must be declared. Rule 102 and rule 103 respectively declares these. The stream processes also follow the HW-HUME execution model, i.e. they executes in a sequential order, which means that a ‘BEGIN’ message must be received from the control process before each run, and an ‘END’ message must be returned after. The control channels are already declared in section B.5.1. The name of the channel is the stream name followed by ‘ out’.

Names ensures that it uses a

valid PROMELA name. Labels and the goto statement is used in the body, and an if statement is used to check if the output can be written to. The main body is created in rule 106.

Rule 101

InStream ~ hwireidi hstreamidi hvaridi hexprtypei  7→ InStream ~ chan hstreamidi  InStream ~ vars hexprtypei  start: Names ~ hstreamidi  control ? BEGIN; if :: InStream ~ body hexprtypei  ::else goto finish fi; finish: Names ~ hstreamidi  control ! END; goto start;

Channel Declaration In rule 102 the name of the stream is used to refer the variable out to the correct channel. The channel has the name of the stream followed by ‘ out’.

Names

ensures that the name is valid

PROMELA. Rule 102

Instream ~ chan hstreamidi  7→ chan out = Names ~ hstreamidi  out;

Variable Declaration The simulator uses variables when simulating an input stream. The simulator creates the variables corresponding to the type of the input variable in the box that actually uses the stream. The rule accepts this variable as an argument. Since only numeric values are used in “PROMELA for HW-HUME”, different input are simulated in each run by incrementing each variable by ‘1’. The name of the variable is var, followed by a number representing the relative position of the variable, starting at ‘1’. The variable’s initial value is set to ‘0’, as shown in rule 103. Rule 103

InStream ~ vars hbasetypehii i  7→ Types ~ hbasetypehii i  varhii = 0;

If the variable is a tuple it is enclosed by parentheses. These are then removed. A variable is created for each of the types in the tuple, as the following two rules formalises. Rule 104

InStream ~ vars ( htypei , htypesi )  7→ InStream ~ vars htypei  InStream ~ vars htypesi 

Rule 105

InStream ~ vars htypei , htypesi  7→ InStream ~ vars htypei  InStream ~ vars htypesi 

Body Definition The main body of the process body is divided into three parts. First the process checks if the channel is empty. This is applied by using the built-in ‘empty()’ function, which returns true if the channel is empty. If it succeeds the current value of the variable(s) are sent over the channel, as shown in rule 108. The last part is to increment all variables by one. Rule 110 denotes this operation. Each operation is separated by a semicolon.

InStream ~ body hexprtypei  Rule 106

7→ ( empty( out ) ) → out ! InStream ~ send hexprtypei ; InStream ~ inc hexprtypei ;

For each value, var followed the an integer indicated the variables position, is used to send the current value of the specified variable to the stream.

Rule 107

InStream ~ send hbasetypehii i  7→ varhii

If the variable is a tuple, each value is considered separately, and these are separated by commas. Rule 108

InStream ~ send ( htypei , htypesi )  7→ InStream ~ send htypei  , InStream ~ send htypesi 

Rule 109

InStream ~ send htypei , htypesi  7→ InStream ~ send htypei  , InStream ~ send htypesi 

The last part of the main body of the process body increments the values by one. The ‘hvarnamei++’ assignment is allowed in PROMELA [18], and is used for each of the variables. A semicolon separates each assignment. Rule 110

InStream ~ inc hbasetypehii i  7→ Types ~ hbasetypehii i  varhii++;

For tuples each value is dealt with independently. Rule 111

InStream ~ inc ( htypei , htypesi )  7→ InStream ~ inc htypei  InStream ~ inc htypesi 

Rule 112

InStream ~ inc htypei , htypesi  7→ InStream ~ inc htypei  InStream ~ inc htypesi 

B.8.2

Output Streams

An output stream in HW-HUME is a finite state automaton, which a box is wired to. The same model is used in the PROMELA representation of HW-HUME. Since output streams cannot manipulate the model, they are also allowed in SPIN’s verification mode. In PROMELA all output streams, regardless of their destinations in HW-HUME, are written to standard output. Since HW-HUME is translated to PROMELA to be able to model check it, the destination of the stream is unimportant. The only thing that is important that is exists. The syntax of a PROMELA output stream is quite similar to an input stream. The main difference is in the main body. a c t i v e proctype process name ( ) { start : c o n t r o l ?BEGIN ; if : : ( i n ?[< v a r s > ] ) − > i n ?< v a r s >; p r i n t f (”%d . . . % d \ n ” , < v a r i a b l e s > ) ; : : e l s e goto f i n i s h fi ; finish : c o n t r o l !END; goto s t a r t ; }

The creation of the PROMELA output stream process from a HW-HUME output stream is denoted by

OutStream .

OutStream : HW-HUME Output Stream ,→ PROMELA Output Stream Process Rule 113 creates the output stream. The only difference compared to an input stream is that the rule accepts an input stream as an argument, instead of an output stream, together with the rest of the declarations. The active prefix is used to instantiate a process, and Names is used to create a valid PROMELA name. As for the input stream rule (rule 100), it uses Stream to extract the required

elements. Note that the rule iterates through all declarations so all output stream declarations are gained and translated.

Rule 113

OutStream ~ stream hstreamidi to hstringi; hdeclsi  7→ active proctype Names ~ hstreamidi  (){ Outstream ~ Stream ~ stream hstreamidi to hstringi; hdeclsi  OutStream ~ hdeclsi 

}

The elements Stream extracts from the declarations are used as arguments to rule 114. As for input streams (rule 101) the channel and variables are first declared. The stream process uses the same execution model as “normal” processes - by synchronising with a rendezvous channel to the control process.

Names is used to obtain the correct name. Labels, the goto statement and the if clause are

used for control flow. Rule 119 creates the main body.

Rule 114

OutStream ~ hwireidi hstreamidi hvaridi hexprtypei  7→ OutStream ~ chan hwireidi hvaridi  OutStream ~ vars hexprtypei  start: Names ~ hstreamidi  control ? BEGIN; if :: OutStream ~ body hexprtypei  :: else goto finish fi; finish: Names ~ hstreamidi  control ! END; goto start;

Channel Declaration In rule 115 the variable in is defined and declared to reference the input channel. This is defined by the box name and variable that writes to the output stream. This channel is already created (section B.5.2). The rule uses Names to ensure that the name is correct. Rule 115

Outstream ~ chan hwireidi hvaridi  7→ chan in = Names ~ hwireidi  Names ~

hvaridi ;

Variable Declaration The rules for creating the variables are almost identical to the rules that create the variables for the input stream process (rule 103 - 105). The only difference is that in rule 116 the variables are not given an initial value. Rule 116

OutStream ~ vars hbasetypehii i  7→ Types ~ hbasetypehii i  varhii;

Rule 117

OutStream ~ vars ( htypei , htypesi )  7→ OutStream ~ vars htypei  OutStream ~ vars htypesi 

Rule 118

OutStream ~ vars htypei , htypesi  7→ OutStream ~ vars htypei  OutStream ~ vars htypesi 

Body Definition The semantics of the body of the output stream are completely different from the input stream. The body is divided into two parts. First the values that are to be written to the standard-output are read from the channel, and assigned to the declared variables. Then the values are printed to the screen. This is illustrated in rule 119.

Rule 119

OutStream ~ body hexprtypei  7→ OutStream ~ readchan hexprtypei  OutStream ~ print hexprtypei 

When reading from the channel, the process first checks if it is possible. This is achieved by using square brackets around the variable. This is called the guard condition. If it succeeds, the expressions on the hand right side of the arrow ‘→’ in rule 120 are executed. The channel is then actually read from, and the values in the channel are assigned to the variables. A semicolon is used at the end of each expression to separate it from the next.

Rule 120

OutStream ~ readchan hexprtypei  7→ ( in ? [ OutStream ~ read hexprtypei  ] ) → in ? OutStream ~ read hexprtypei ;

Rule 121 obtains the correct name of a base type. The name is var, followed by a number indicating the relative position of the variable. Rule 121

OutStream ~ read hbasetypehii i  7→

varhii

The type in the channel may be a tuple, in which case rules 122 and 123 traverse the tuple to extract the different types. Each value is considered separately, separated by a comma. This will form a list on the right hand side of the read operator ‘?’. Rule 122

OutStream ~ read ( htypei , htypesi )  7→ OutStream ~ read htypei  , OutStream ~ read htypesi 

Rule 123

OutStream ~ read htypei , htypesi  7→ OutStream ~ read htypei  , OutStream ~ read htypesi 

The last part of the output stream body is where the values read from the channel are printed to standard-output. This is achieved by using the built in ‘printf()’ function. It is a statement that is always executable. The parameters for the ‘printf()’ function are a string followed by a list of variables. The variables are referred to in the string using conversion specifications [18]. Rule 124 creates the print statement. To force each printing to be on separate lines it uses the newline escape sequence ‘\n’. The rule uses rules 125 - 127 to create the references, and rules 121 - 123 to create the variable list.

Rule 124

OutStream ~ print hexprtypei  7→ printf(” OutStream ~ refs hexprtypei  \n” , OutStream ~ read hexprtypei  );

Rule 125 creates a reference in the string in the argument of the PROMELA ‘printf()’ function. For each base type it returns ‘%d’, which is the conversion specification for an integer.

Rule 125

OutStream ~ refs hbasetypei  7→

%d

If the type is a tuple, each item is independently translated. Rule 126

OutStream ~ refs ( htypei , htypesi )  7→ OutStream ~ vars htypei  OutStream ~ vars htypesi 

Rule 127

OutStream ~ refs htypei , htypesi  7→ OutStream ~ refs htypei  OutStream ~ refs htypesi 

B.9 The Init Process By using the init keyword in PROMELA , a process where the behaviour is active in the initial system state is declared. This can be compared to the main method found in C/C++ and JAVA. In the HW-HUME to PROMELA translation two distinct operations must be accomplished in the initial system state. Firstly all the channels must be given their initial value if one is specified in HW-HUME. The second objective is to instantiate all the processes with the correct channels as parameters. The PROMELA syntax of the init process is as follows: init { }

The process is separated into the two specified parts. instantiates the processes.

Init

ChanInit initialises the channels and ProcInst

denotes the semantic for the entire init process.

Init : HW-HUME ,→ PROMELA Initialisation In Init all channels are first initialised, followed by the instantiation of the processes, as shown in rule 128. The rule starts with the init keyword. The rules are enclosed by brackets ‘{ }’ that hold the body of the init process. Rule 128

Init ~ hdeclsi  7→

init { Init ~ chan hdeclsi  Init ~ proc hdeclsi  }

To be able to initialise the channels, all the wire declarations are necessary. These are obtained by recursively traversing all declarations. This is shown rule 129, where

ChanInit

are used for

creating the PROMELA code. Rule 129

Init ~ chan hwiredecli; hdeclsi  7→ ChanInit ~

When all channels are initialised,

Init

hwiredecli  Init ~ chan hdeclsi 

instantiates the processes. To be able to do so, the wire

declarations, together with the corresponding box declaration are required. Rule 130 finds all wire declarations using recursion, and calls the rule to find the corresponding box declaration.

Rule 130

Init ~ proc hwiredecli; hdeclsi  7→ Init ~ proc hwiredecli hdeclsi  Init ~ proc hdeclsi 

Using recursion on the declarations, rule 131 finds all box declarations, and calls the rule that checks if the box declaration corresponds to the wire declaration. Rule 131

Init ~ proc hwiredecli hboxdecli; hdeclsi  7→ Init ~ proc hwiredecli hboxdecli  Init ~ proc hwiredecli hdeclsi 

If the name of the wire is the same as the box name, they correspond.

ProcInst

is then used to

instantiate the processes. If they don’t match, nothing happens. if [ hwireidi ≡ hboxidi ]

Rule 132

B.9.1

Init ~ wire hwireidi hsourcesi hdestsi box hboxidi hpreludei hbodyi  7→ ProcInst ~ wire hwireidi hsourcesi hdestsi box hboxidi hpreludei hbodyi 

Initialisation of Channels

In HW-HUME inputs to boxes can be given initial values in the wire declaration. This is a link property specified by the initially keyword followed by the initial value (Please see definition 25, 32 and 33). In PROMELA the initial values are set using the send operator ‘!’ on the channel, followed by the PROMELA representation of the value.

ChanInit denotes the semantics for this initialisation.

ChanInit : HUME Wire Initialisation ,→ PROMELA Channel Initialisation Rule 133 accepts a wire declaration as parameter. Since the initial value is specified in the input of a channel, only the element including the sources is required. Rule 133

ChanInit ~ wire hwireidi hsourcesi hdestsi

 7→ ChanInit ~ hsourcesi 

The element that holds all the sources is a least of at list one link element, enclosed by parentheses. Rule 134 removes the parentheses. Rule 134

ChanInit ~ ( hlinki , hlinklisti )  7→ ChanInit ~

hlinki , hlinklisti 

The list of the link element is traversed, and each link-element is considered individually, as shown in rule 135. Rule 135

ChanInit ~ hlinki , hlinklisti  7→ ChanInit ~ hlinki  ChanInit ~

hlinklisti 

Rule 136 creates the PROMELA code that initialises a channel. Note that there is no rule to handle link-elements where the ‘initially’ keyword is not present - hence no PROMELA code is generated in that case. If initially is present rule 136 uses

Names

on the box and variable name to obtain the

valid PROMELA name. The two elements are separated by an underscore ‘ ’. To initialise the channel the PROMELA version of the value, created with the help of Values , is sent to the channel using the send operator ‘!’. A semicolon is used at the end of the statement to separate it from the next. Rule 136

ChanInit ~ hboxidi.hvaridi initially hexpri  7→ Names ~ hboxidi  Names ~ hvaridi

!

Values ~

hexpri  ;

B.9.2

Instantiate Processes

To be able to specify the parameters when creating a new process the run operator must be used. It takes as arguments the name of the already declared proctype, and a list of parameters. A process identified by the specified name, with the specified arguments, is then created. Each PROMELA process instantiation will then have the following syntax. run p r o c e s s n a m e ( chan

, < output > , < control > );

All parameters are channels. The process has a set of input channels that are read from, a set of output channels that are written to, and a control channel to synchronise with the other processes. To be able to create the processes, references to all input and output channels must be obtained. Since the output channels are generated based on the variables in the output-element list of a HWHUME box, the box declaration is used to find the output channels. The source element in the wire declaration specifies the source box and variables of the inputs. This is used to create the input channels. The control channel is created based on the box/wire name.

ProcInit

denotes the

semantics for creating the processes.

ProcInit : HW-HUME ,→ PROMELA Process Instantiation Rule 137 accepts the box declaration and corresponding wire declaration as arguments. The rule extracts the prelude from the box declaration, which is used to create the output channels. Rule 137

ProcInst ~ box hboxidi hpreludei hbodyi hwiredecli 7→ ProcInst ~ hpreludei hwiredecli 



Rule 138 extracts the name and the source element from the wire declaration. The latter is used to obtain the input channels. Rule 138

ProcInst ~ hpreludei wire hwireidi hsourcesi hdestsi 7→ ProcInst ~ hpreludei hwireidi hsourcesi 



Rule 139 creates the PROMELA code. The run operator is used to create a process in PROMELA. The wire name is used, together with Names , to instantiate the correct process. The chan keyword in the parameterlist indicates that channels are used as parameters. This is followed by references to the input and the output channels. At the end of the parameterlist is the reference to the control channel. Each control channel has the process name followed by ‘ control’. The correct process name is created using Names .

ProcInst ~ Rule 139

hpreludei hwireidi hsourcesi  7 → run Names ~ hwireidi  ( chan ProcInit ~ hsourcesi  ProcInit ~ hwireidi hpreludei  Names ~ hwireidi  control )

Rule 140 - 144 creates the input channels. Rule 140 uses the sources elements, which consist of a set of link elements, enclosed by parentheses. The rule removes the parentheses. Rule 140

ProcInst ~

( hlinki , hlinklisti )  7→ ProcInst ~ hlinki , hlinklisti 

The list of link elements is traversed recursively. The correct PROMELA channel is then obtained individually, as illustrated in rule 141. Rule 141

ProcInst ~

hlinki , hlinklisti  7→ ProcInst ~ hlinki  , ProcInst ~ hlinklisti 

Only the link specification is required from the link-element. Rule 142 extracts this element from the link-element. Rule 142

ProcInst ~

hlinkspeci hlinkpropi  7→

ProcInst ~

hlinkspeci 

The link specification can either be a connection or a stream name. Rule 143 generates the PROMELA name of the channel. This is done using the name of box and the variable, separated by an underscore.

Names is used to obtain a valid PROMELA name.

Rule 143

ProcInst ~

hboxidi.hvaridi  7→

Names ~

hboxidi 

Names ~

hvaridi 

In the case of the link specification being a stream name, the PROMELA name of the channel is the stream name followed by ‘ out’. As rule 144 shows, Names is used to ensure that the stream name is a valid PROMELA name. Rule 144

ProcInst ~

hstreamidi  7→

Names ~

hstreamidi  out

Rule 145 - 148 creates the output channels. Rule 145 accepts as arguments the name of the wire and the prelude of the box. In the prelude only the list with the output elements is required. This is extracted by the rule. Rule 145

ProcInst ~ hwireidi in ( hinoutlist1 i ) out (hinoutlist2 i) 7→ ProcInst ~ hwireidi hinoutlist2 i 



Rule 146 uses recursion to separate each output-element in the list. The channels for each such element are found separately. Rule 146

ProcInst ~ hwireidi hinouti , hinoutlisti  7→ ProcInst ~ hwireidi hinouti  , ProcInst ~

hwireidi hinoutlisti 

An output element may have several variables. The channels for each variable must be found. Rule 147 finds each variable, and calls the method that creates the PROMELA code.

Rule 147

ProcInst ~ hwireidi hvaridi , hvaridlisti :: hexprtypei  7→ ProcInst ~ hwireidi hvaridi :: hexprtypei  , ProcInst ~ hwireidi hvaridlisti :: hexprtypei 

Rule 148 generates the PROMELA code. When the channels are created they are given the name of the box and the variable, separated by an underscore.

Names

ensures that the names are valid

PROMELA. Rule 148 uses this to find the channel. Rule 148

ProcInst ~ hwireidi hvaridi::hexprtypei  7→ Names ~ hwireidi  Names ~ hvaridi



Appendix C

User Guidelines for the Translator As the use case in figure 5.1 on page 46 shows, the program has four different options. This appendix contains the user guidelines for running the program with the different options. The general syntax for running the JAVA program is: $ java hwhpromela [ -r | -g | -v ] The program accepts three optimal arguments in addition to specifying the name of the HW-HUME file to be translated. If the command violates this syntax, an error message is returned as shown below. $ java hwhpromela -rg half.hume Usage:

C.1

java hwhpromela [-r | -g | -v]

Generating Promela Code

One option is to only translate the HW-HUME code into PROMELA code. To perform this operation the program must be executed without specifying any of the optimal arguments: $ java hwhpromela When the program is finished executing, a message displaying whether the operations were successful or not is returned, together with the translation time and name of the generated PROMELA file.The following example shows the successful translation of the half adder:

106

$ j a v a hwhpromela h a l f . hume −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− Translation Successful −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− File Generated : h a l f . pml T r a n s l a t i o n Time : 2 3 6 ms −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

C.2

Random Simulation

To run a random simulation on the generated PROMELA code the ‘-r’ argument must be provided: $ java hwhpromela -r model.hume The simulation is terminated by terminating the ‘hwhpromela’ program, achieved by pressing ‘CtrlC’. The program uses SPIN to run the simulation. This implies that the result is equivalent to first translate the HW-HUME program followed by running SPIN as illustrated below: $ java hwhpromela model.hume $ spin model.pml The following example shows the beginning of the output when performing a random simulation of the half adder in ’hwhpromela’:

$ j a v a hwhpromela − r h a l f . hume 0 0 −1 1 0 −1 1 0 −1 0 1 −1 0 0 −1 1 0 −1 1 0 −1 0 1 −1 0 0 −1 1 0 −1 . . .

C.3

Verifying Model

If the user wishes to verify the model after the translation, which would normally be the reason for the translation, the ‘-v’ argument must be applied:

$ java hwhpromela -v model.hume The verification is also terminated by pressing ‘Ctrl-C’. In the verification the PROMELA code is first translated to ANSI C, then compiled using the ‘cc’ compiler in UNIX and at the generated C program is then executed. Issuing the following commands is equivalent to running ‘hwhpromela’ with the ‘-v’ argument: $ $ $ $

java hwhpromela model.hume spin -a model.pml cc -o pan pan.c ./pan

Appendix H includes the output from verifying a set of HW-HUME examples.

C.4

Guided Simulation

The last option is to run a guided simulation on a previously failed verification. A trail created by the failed verification is used. In ‘hwhpromela’, a guided simulation is achieved with the ‘-g’ argument. $ java hwhpromela -g model.hume The simulation is also terminated by pressing ‘Ctrl-C’. When using this option no code is translated. The result is therefore equivalent to running the guided simulation in SPIN directly. $ spin -t -p model.pml

Appendix D

Hume Examples This appendix explains the use of HUME with an example of a simple counter. The features in the example are explained in chapter 2. n

gen n -> (n+1,(n,'\n')) n'

shown output

std_out

Figure D.1: A Hume Counter

Figure D.1 illustrates a counter in HUME. It consists of one box that takes a number as input. The number, incremented by one, is sent back to the input in addition to the standard output. The example is from ‘The Hume Manual’ [24]. The following listing shows the complete HUME code for the counter: 1 2 3 4 5 6 7 8 9 10 11

program stream o u t p u t t o ” s t d o u t ” ; box i n c in ( n : : i n t 6 4 ) o u t ( n ’ : : i n t 6 4 , shown : : ( i n t 6 4 , char ) ) match n −> ( n +1,( n , ’ \ n ’ ) ) ; wire i n c ( i n c . n ’ i n i t i a l l y 0 ) ( i n c . n , o u t p u t ) ;

Line 3 declares that output is associated with standard output ‘std out’. Line 5 - 9 declares the inc box. Line 5 specifies that the unique name of the box is ‘inc’. Line 6 declares that the box has a 64 bit integer as input called ‘n’. Line 7 declares the outputs. ‘n’‘ 109

is a 64 bit integer, and ‘shown’ is a tuple consisting of a 64 bit integer and a character. Line 8 declares the start of the matches, and that unfair matching is used. Line 9 holds the only match in the model. The input is assigned to the variable ‘n’, if there is an input. Next the right hand side is evaluated. Output ‘n’‘ is is the input incremented by one. The tuple ’shown’ holds the old value of ‘n’, together with the newline escape sequence character. Line 11 is the wire declaration for the box. It defines that the source of the input of the box is the ‘n’‘ variable in the same box. It also sets the initial value of the input to be zero ‘0’. The first output, ‘n’‘, is wired to the ‘n’ input in the same box. The tuple ‘shown’ is wired to ‘output’, which is the standard output.

D.1 Running the Program The output below is generated when the the program is run in continuous mode. This is achieved with the hume inc.hume command. The program is stopped by pressing Ctrl-C. Note that the line numbers are not part of the HUME output. $ hume i n c . hume HUME 0 . 1 Tuesday 0 8 June , 2 0 0 4 , 1 6 : 3 1 RUNNING 0 1 2 3 4 5 6 7 ... hume : i n t e r r u p t e d

HUME can also be run in stepped mode. In this mode some extra information is printed out together with the the defined outputs. All boxes execute one run, and wait for the user to press the ‘enter’ button. Stepped mode is achieved by the ‘-t’ argument. The command hume -t inc.hume run the example in stepped mode, and generates the following output: 1 2 3 4 5 6 7 8 9 10 11 12 13 14

$ hume − t i n c . hume HUME 0 . 1 Tuesday 0 8 June , 2 0 0 4 , 1 6 : 3 1 STEPPING module stream o u t p u t t o ” s t d o u t ” ; box i n c in ( ” n ” : : i n t 6 4 ) out ( ” n ’ ” : : i n t 6 4 , ” shown ” : : ( i n t 6 4 , char ) ) unfair n −> ((+ n 1 ) , ( n ,’\ n ’ ) ) ; wire i n c ( inc . n ’ i n i t i a l l y 0)

15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

( inc . n , output ) 0 i n c : RUNNABLE wires : inc . n ’ :1 NEXT> 1 i n c : RUNNABLE wires : inc . n ’ :2 NEXT> 2 i n c : RUNNABLE wires : inc . n ’ :3 NEXT> 3 i n c : RUNNABLE wires : inc . n ’ :4 hume : i n t e r r u p t e d

Appendix E

Promela Examples This appendix includes two examples of PROMELA models. The examples can be used together with chapter 3 that describes the PROMELA language.

E.1 A Simple Baker Example The following code is a very simple PROMELA model consisting of two interacting processes. One process is the baker that bakes a cake, and the other process is a customer that eats the cake. They interact in a sequential manner, i.e. first a cake is baked, then it is eaten, then a new cake is baked and so on. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

mtype = { B a k i n g , E a t i n g } ; mtype t u r n = B a k i n g ; a c t i v e proctype Baker ( ) { do : : ( t u r n == Baking ) −> p r i n t f ( ” B a k e r : B a k i n g Cake \ n ” ) ; turn = Eating ; od ; } a c t i v e proctype Customer ( ) { do : : ( t u r n == E a t i n g ) −> p r i n t f ( ” C u s t o m e r : E a t i n g Cake \ n ” ) ; t u r n = Baking ; od ; }

Line 1 declares that the enumerated type, mtype, holds the two values ’Baking’ and ’Eating’. Line 2 creates a global variable ’turn’ of the enumerated type, and initialises it to ’Baking’. Lines 4 - 10 declare the ’Baker’ process. It runs in a infinite loop. First it waits for it’s turn. The process is blocked on line 6 until ’turn’ holds the value ’Baking’. When this happens, it prints out the “Baker: Baking Cake” message, sets the ’turn’ variable to ’Eating’ and returns to line

112

6 where it is blocked until ’turn’ is set to ’Baking’ again. By using the active keyword in the process prelude one process is initially created. Lines 12 - 18 declare the ’Customer’ process. It is similar to the ’Baker’ process. It uses the same global ’turn’ variable to check if a cake is ready to be eaten. When it is, it prints out the message “Customer: Eating Cake”, sets the ’turn’ value to ’Baking’ and is blocked again on line 14 until ’turn’ is set to ’Eating’. The program can be run in a random simulation mode by using the spin command. When running the example in a random simulation mode using SPIN, the following output is generated:

$ s p i n b a k e r . pml Baker : Baking Customer : Baker : Baking Customer : Baker : Baking Customer : Baker : Baking Customer : Baker : Baking Customer : Baker : Baking Customer : Baker : Baking Customer : . . .

Cake Eating Cake Eating Cake Eating Cake Eating Cake Eating Cake Eating Cake Eating

Cake Cake Cake Cake Cake Cake Cake

Figure E.1 illustrates the use of XSPIN with the example. XSPIN is used to validate a linear temporal formula (LTL) expressing that when a baker bakes a cake it will eventually be eaten by a customer. If ‘p’ is defined as a baker is baking a cake (‘turn’ is set to baking) and ‘q’ expresses that the customer is eating the cake (‘turn’ is set to eating), this can expressed as follows in LTL:

(p → 

q)

In figure E.1 this is expressed and verified in XSPIN using the LTL editor which is included in the XSPIN tool. The formula is entered, and the required variables are defined. First the LTL formula is translated into a never claim. Then it is verified. Note the desired behaviour is verified. This is the behaviour that should be valid for all executions. An error behaviour is the behaviour that should never happen in any executions.

E.2 A More Advanced Baker Example The next example introduces another baker and three more customers. To synchronise the process to make sure that only one baker or one customer is active at a given time, a single variable is not enough. The mtype is extended by adding another value ‘None’, indicating that nobody is currently active. A variable ‘who’ is introduced, and contains the pid number of the process who is currently active. To ensure that only one process is active a given time, two inline definitions have been

Figure E.1: The LTL Editor in XSpin

created. On lines 5 to 7 an inline declaration that requests a lock is created. Each process must call this before it can execute. When the process is finished it uses the inline declaration on lines 9 to 11. There the process releases the lock. All processes include a local assertion, which checks that the ‘who’ variable, which holds the current active processor, holds the process number to itself. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

mtype = { B a k i n g , E a t i n g , None } ; mtype t u r n = B a k i n g ; p i d who ; i nl i ne requestLock ( x , y , z ) { a t o m i c { x = = y − > x = z ; who = }

pid }

inline releaseLock (x , y ){ a t o m i c { x = y ; who = 0 } } a c t i v e [ 2 ] proctype Baker ( ) { do : : r e q u e s t L o c k ( t u r n , B a k i n g , None ) − > p r i n t f ( ” B a k e r %d : B a k i n g Cake \ n ” , a s s e r t ( who = = p i d ) ; releaseLock ( turn , Eating ) od ; }

pid );

22 23 24 25 26 27 28 29

a c t i v e [ 3 ] proctype Customer ( ) { do : : r e q u e s t L o c k ( t u r n , E a t i n g , None ) − > p r i n t f ( ” C u s t o m e r %d : E a t i n g Cake \ n ” , a s s e r t ( who = = p i d ) ; r e l e a s e L o c k ( t u r n , Baking ) od ; }

pid ) ;

The process that is currently ‘active’ prints out its process number, and whether it is baking or eating. The following output is extracted from a random simulation of the example: $ s p i n b a k e r . pml B a k e r 0 : B a k i n g Cake C u s t o m e r 3 : E a t i n g Cake B a k e r 1 : B a k i n g Cake C u s t o m e r 3 : E a t i n g Cake B a k e r 1 : B a k i n g Cake C u s t o m e r 3 : E a t i n g Cake B a k e r 0 : B a k i n g Cake C u s t o m e r 2 : E a t i n g Cake B a k e r 0 : B a k i n g Cake C u s t o m e r 3 : E a t i n g Cake B a k e r 0 : B a k i n g Cake C u s t o m e r 3 : E a t i n g Cake B a k e r 1 : B a k i n g Cake C u s t o m e r 3 : E a t i n g Cake B a k e r 1 : B a k i n g Cake C u s t o m e r 4 : E a t i n g Cake

Appendix F

Hw-Hume Examples Chapter 6 evaluates the translation rules and the ‘hwhpromela’ program, which implements the rules. The evaluation is based on the translation and verification of a set of HW-HUME examples. The translation and verification is done with the ‘hwhpromela’ translator. This appendix contains the HW-HUME source code used in the examples in chapter 6. Please note that in the source code listings, the line numbers are not part of the HW-HUME source code:

F.1 Example 1: A Half Adder Example 1 is the half adder that has been used for illustrations throughout the thesis. It has been constructed by using an ‘xor’ and an ‘and’ gate. t y p e B i t = word 1 ; box gen in ( t : : i n t 6 4 ) out ( t ’ : : i n t 6 4 , x , y : : B i t ) match 0 −> (1,0,0) | 1 −> (2,0,1) | 2 −> (3,1,0) | 3 −> (0,1,1); box f a n o u t in ( x , y : : Bit ) o u t ( x1 , y1 , x2 , y2 : : B i t ) match (x , y ) −> ( x , y , x , y ); box x o r in ( x , y : : Bit ) out ( z : : B i t ) match (0,0) −> 0 | (0,1) −> 1 | (1,0) −> 1 | (1,1) −> 0; box and in ( x , y : : Bit ) out ( z : : B i t )

116

match (0,0) (0,1) (1,0) (1,1)

−> −> −> −>

0 | 0 | 0 | 1;

box show in ( z , c : : Bit ) o u t ( z c : : ( B i t , B i t , char ) ) match ( z , c ) −> ( z , c ,’\ n ’ ) ; stream o u t p u t t o ” s t d o u t ” ; wire wire wire wire wire

gen ( gen . t ’ i n i t i a l l y 0 ) ( gen . t , f a n o u t . x , f a n o u t . y ) ; f a n o u t ( gen . x , gen . y ) ( x o r . x , x o r . y , and . x , and . y ) ; x o r ( f a n o u t . x1 , f a n o u t . y1 ) ( show . z ) ; and ( f a n o u t . x2 , f a n o u t . y2 ) ( show . c ) ; show ( x o r . z , and . z ) ( o u t p u t ) ;

F.2 Example 2: An XOR and an AND Gate Forming a Deadlock The second example is the ‘xor’ and an ‘and’ gate which forms a deadlock. This deadlock illustrated in figure 6.4 on page 51. The following listing contains the source code of the HW-HUME implementation creating the deadlock: t y p e B i t = word 1 ; box gen in ( t : : i n t 6 4 ) out ( t ’ : : i n t 6 4 , x , y : : B i t ) match 0 −> (1,0,0) | 1 −> (2,0,1) | 2 −> (3,1,0) | 3 −> (0,1,1); box x o r in ( x , y : : Bit ) o u t ( z1 , z2 : : B i t ) match (0,0) −> (0,0) | (0,1) −> (1,1) | (1,0) −> (1,1) | (1,1) −> (0,0); box and in ( x , y : : Bit ) o u t ( z1 , z2 : : B i t ) match (0,0) −> (0,0) | (0,1) −> (0,0) | (1,0) −> (0,0) | (1,1) −> (1,1); box show in ( z , c : : Bit )

o u t ( z c : : ( B i t , B i t , char ) ) match ( z , c ) −> ( z , c ,’\ n ’ ) ; stream o u t p u t t o ” s t d o u t ” ; wire wire wire wire

gen ( gen . t ’ i n i t i a l l y 0 ) ( gen . t , x o r . x , and . x ) ; x o r ( gen . x , and . z2 ) ( show . z , and . y ) ; and ( gen . y , x o r . z2 ) ( show . c , x o r . y ) ; show ( x o r . z1 , and . z1 ) ( o u t p u t ) ;

F.3 Example 3: Full Adder from Truth Table The third example is a full adder created by using a HW-HUME box to represent a truth table. Figure 6.8 on page 52 models the adder as it is implemented in HW-HUME. The following listing contains the HW-HUME source code: type B i t = i n t 1 ; box gen in ( t : : i n t 6 4 ) out ( t ’ : : i n t 6 4 , x , y , c : : B i t ) match 0 −> (1,0,0,0) | 1 −> (2,0,1,0) | 2 −> (3,1,0,0) | 3 −> (4,1,1,0) | 4 −> (5,0,0,1) | 5 −> (6,0,1,1) | 6 −> (7,1,0,1) | 7 −> (0,1,1,1); box a d d e r in ( x , y , c : : Bit ) out ( s , c ’ : : B i t ) match (0,0,0) −> (0,0) (0,1,0) −> (1,0) (1,0,0) −> (1,0) (1,1,0) −> (0,1) (0,0,1) −> (1,0) (0,1,1) −> (0,1) (1,0,1) −> (0,1) (1,1,1) −> (1,1)

| | | | | | | ;

box show in ( s , c : : Bit ) o u t ( s c : : ( B i t , B i t , char ) ) match ( s , c ) −> ( s , c ,’\ n ’ ) ; stream o u t p u t t o ” s t d o u t ” ; w i r e gen ( gen . t ’ i n i t i a l l y 0 ) ( gen . t , a d d e r . x , a d d e r . y , a d d e r . c ) ; w i r e a d d e r ( gen . x , gen . y , gen . c ) ( show . s , show . c ) ; w i r e show ( a d d e r . s , a d d e r . c ’ ) ( o u t p u t ) ;

F.4 Example 4: Full Adder as Half Adders and OR Gates The forth example is also an implementation of a full adder. However, in this case it is implemented by using two ‘half adders’ and an ‘or’ gate. The adder is modelled in figure 6.9 on page 53. The following source code contains the implementation of the adder: type B i t = i n t 1 ; box gen in ( t : : i n t 6 4 ) out ( t ’ : : i n t 6 4 , x , y , c : : B i t ) match 0 −> (1,0,0,0) | 1 −> (2,0,1,0) | 2 −> (3,1,0,0) | 3 −> (4,1,1,0) | 4 −> (5,0,0,1) | 5 −> (6,0,1,1) | 6 −> (7,1,0,1) | 7 −> (0,1,1,1); template h a l f 2 in ( x , y : : Bit ) out ( s , c : : B i t ) match (0,0) −> (0,0) | (0,1) −> (1,0) | (1,0) −> (1,0) | (1,1) −> (0,1); i n s t a n t i a t e h a l f 2 as h ∗ 2 ; box o r in ( x , y : : Bit ) out ( z : : B i t ) match (0,0) −> 0 | (0,1) −> 1 | (1,0) −> 1 | (1,1) −> 1; box show in ( s , c : : Bit ) o u t ( s c : : ( B i t , B i t , char ) ) match ( s , c ) −> ( s , c ,’\ n ’ ) ; stream o u t p u t t o ” s t d o u t ” ; wire wire wire wire wire

gen ( gen . t ’ i n i t i a l l y 0 ) ( gen . t , h1 . x , h1 . y , h2 . x ) ; h1 ( gen . x , gen . y ) ( h2 . y , o r . x ) ; h2 ( gen . c , h1 . s ) ( show . s , o r . y ) ; o r ( h1 . c , h2 . c ) ( show . c ) ; show ( h2 . s , o r . z ) ( o u t p u t ) ;

F.5 Example 5: Full Adder as XOR, AND and OR Gates The fifth example is the last implementation of a full adder. It is created by using ‘xor’, ‘and’ and ‘or’ gates as illustrated in figure 6.10 on page 53. The following listing contains the HW-HUME source code of the adder: type B i t = i n t 1 ; box gen in ( t : : i n t 6 4 ) out ( t ’ : : i n t 6 4 , x , y , c : : B i t ) match 0 −> (1,0,0,0) | 1 −> (2,0,1,0) | 2 −> (3,1,0,0) | 3 −> (4,1,1,0) | 4 −> (5,0,0,1) | 5 −> (6,0,1,1) | 6 −> (7,1,0,1) | 7 −> (0,1,1,1); template fanout in ( x , y : : Bit ) o u t ( x1 , y1 , x2 , y2 : : B i t ) match (x , y ) −> ( x , y , x , y ); i n s t a n t i a t e f a n o u t as f ∗2; template xor in ( x , y : : Bit ) out ( z : : B i t ) match (0,0) −> 0 | (0,1) −> 1 | (1,0) −> 1 | (1,1) −> 0; i n s t a n t i a t e xor as x ∗2; t e m p l a t e and in ( x , y : : Bit ) out ( z : : B i t ) match (0,0) −> 0 | (0,1) −> 0 | (1,0) −> 0 | (1,1) −> 1; i n s t a n t i a t e and a s a ∗ 2 ; box o r in ( x , y : : Bit ) out ( z : : B i t ) match (0,0) −> 0 | (0,1) −> 1 | (1,0) −> 1 | (1,1) −> 1;

box show in ( s , c : : Bit ) o u t ( s c : : ( B i t , B i t , char ) ) match ( s , c ) −> ( s , c ,’\ n ’ ) ; stream o u t p u t t o ” s t d o u t ” ; wire wire wire wire wire wire wire wire wire

gen ( gen . t ’ i n i t i a l l y 0 ) ( gen . t , f 1 . x , f 1 . y , f 2 . x ) ; f 1 ( gen . x , gen . y ) ( x1 . x , x1 . y , a1 . x , a1 . y ) ; x1 ( f 1 . x1 , f 1 . y1 ) ( f 2 . y ) ; a1 ( f 1 . x2 , f 1 . y2 ) ( o r . x ) ; f 2 ( gen . c , x1 . z ) ( x2 . x , x2 . y , a2 . x , a2 . y ) ; x2 ( f 2 . x1 , f 2 . y1 ) ( show . s ) ; a2 ( f 2 . x2 , f 2 . y2 ) ( o r . y ) ; o r ( a1 . z , a2 . z ) ( show . c ) ; show ( x2 . z , o r . z ) ( o u t p u t ) ;

F.6 Connecting Adders This section contains the source code when connected adders to created multi bit adders. This is described in section 6.7. Figure 6.11 illustrates the connection, by showing a two bit adder. The following sections include the source code of a two, three, four and five bit adder.

F.6.1 Example 6: A Two Bit Adder The following listing contains the HW-HUME source code of a two bit adder: type B i t = i n t 1 ; box gen1 in ( t : : i n t 6 4 ) out ( t ’ : : i n t 6 4 , x , y , c : : B i t ) match 0 −> (1,0,0,0) | 1 −> (2,0,1,0) | 2 −> (3,1,0,0) | 3 −> (4,1,1,0) | 4 −> (5,0,0,1) | 5 −> (6,0,1,1) | 6 −> (7,1,0,1) | 7 −> (0,1,1,1); box gen2 in ( t : : i n t 6 4 ) out ( t ’ : : i n t 6 4 , x , y : : B i t ) match 0 −> (1,0,0) | 1 −> (2,0,1) | 2 −> (3,1,0) | 3 −> (0,1,1) ; template fanout in ( x , y : : Bit ) o u t ( x1 , y1 , x2 , y2 : : B i t ) match

(x , y ) −> ( x , y , x , y ); i n s t a n t i a t e f a n o u t as f ∗4; template xor in ( x , y : : Bit ) out ( z : : B i t ) match (0,0) −> 0 | (0,1) −> 1 | (1,0) −> 1 | (1,1) −> 0; i n s t a n t i a t e xor as x ∗4; t e m p l a t e and in ( x , y : : Bit ) out ( z : : B i t ) match (0,0) −> 0 | (0,1) −> 0 | (1,0) −> 0 | (1,1) −> 1; i n s t a n t i a t e and a s a ∗ 4 ; template or in ( x , y : : Bit ) out ( z : : B i t ) match (0,0) −> 0 | (0,1) −> 1 | (1,0) −> 1 | (1,1) −> 1; i n s t a n t i a t e or as o ∗2; box show in ( s1 , s2 , c : : B i t ) o u t ( s s c : : ( B i t , B i t , B i t , char ) ) match ( a , b , c ) −> ( a , b , c ,’\ n ’ ) ; stream o u t p u t t o ” s t d o u t ” ; wire wire wire wire wire wire wire wire

gen1 ( gen1 . t ’ i n i t i a l l y 0 ) ( gen1 . t , f 1 . x , f 1 . y , f 2 . x ) ; f 1 ( gen1 . x , gen1 . y ) ( x1 . x , x1 . y , a1 . x , a1 . y ) ; x1 ( f 1 . x1 , f 1 . y1 ) ( f 2 . y ) ; a1 ( f 1 . x2 , f 1 . y2 ) ( o1 . x ) ; f 2 ( gen1 . c , x1 . z ) ( x2 . x , x2 . y , a2 . x , a2 . y ) ; x2 ( f 2 . x1 , f 2 . y1 ) ( show . s 1 ) ; a2 ( f 2 . x2 , f 2 . y2 ) ( o1 . y ) ; o1 ( a1 . z , a2 . z ) ( f 4 . x ) ;

wire wire wire wire wire wire wire wire

gen2 ( gen2 . t ’ i n i t i a l l y 0 ) ( gen2 . t , f 3 . x , f 3 . y ) ; f 3 ( gen2 . x , gen2 . y ) ( x3 . x , x3 . y , a3 . x , a3 . y ) ; x3 ( f 3 . x1 , f 3 . y1 ) ( f 4 . y ) ; a3 ( f 3 . x2 , f 3 . y2 ) ( o2 . x ) ; f 4 ( o1 . z , x3 . z ) ( x4 . x , x4 . y , a4 . x , a4 . y ) ; x4 ( f 4 . x1 , f 4 . y1 ) ( show . s 2 ) ; a4 ( f 4 . x2 , f 4 . y2 ) ( o2 . y ) ; o2 ( a3 . z , a4 . z ) ( show . c ) ;

w i r e show ( x2 . z , x4 . z , o2 . z ) ( o u t p u t ) ;

F.6.2 Example 7: A Three Bit Adder The following listing contains the HW-HUME source code of a three bit adder: type B i t = i n t 1 ; box gen1 in ( t : : i n t 6 4 ) out ( t ’ : : i n t 6 4 , x , y , c : : B i t ) match 0 −> (1,0,0,0) | 1 −> (2,0,1,0) | 2 −> (3,1,0,0) | 3 −> (4,1,1,0) | 4 −> (5,0,0,1) | 5 −> (6,0,1,1) | 6 −> (7,1,0,1) | 7 −> (0,1,1,1); box gen2 in ( t : : i n t 6 4 ) out ( t ’ : : i n t 6 4 , x , y : : B i t ) match 0 −> (1,0,0) | 1 −> (2,0,1) | 2 −> (3,1,0) | 3 −> (0,1,1) ; box gen3 in ( t : : i n t 6 4 ) out ( t ’ : : i n t 6 4 , x , y : : B i t ) match 0 −> (1,0,0) | 1 −> (2,0,1) | 2 −> (3,1,0) | 3 −> (0,1,1) ; template fanout in ( x , y : : Bit ) o u t ( x1 , y1 , x2 , y2 : : B i t ) match (x , y ) −> ( x , y , x , y ); i n s t a n t i a t e f a n o u t as f ∗6; template xor in ( x , y : : Bit ) out ( z : : B i t ) match (0,0) −> 0 | (0,1) −> 1 | (1,0) −> 1 | (1,1) −> 0; i n s t a n t i a t e xor as x ∗6; t e m p l a t e and

in ( x , y : : Bit ) out ( z : : B i t ) match (0,0) −> 0 | (0,1) −> 0 | (1,0) −> 0 | (1,1) −> 1; i n s t a n t i a t e and a s a ∗ 6 ; template or in ( x , y : : Bit ) out ( z : : B i t ) match (0,0) −> 0 | (0,1) −> 1 | (1,0) −> 1 | (1,1) −> 1; i n s t a n t i a t e or as o ∗3; box show in ( s1 , s2 , s3 , c : : B i t ) o u t ( s s c : : ( B i t , B i t , B i t , B i t , char ) ) match ( a , b , c , carry ) −> ( a , b , c , carry ,’\ n ’ ) ; stream o u t p u t t o ” s t d o u t ” ; wire wire wire wire wire wire wire wire

gen1 ( gen1 . t ’ i n i t i a l l y 0 ) ( gen1 . t , f 1 . x , f 1 . y , f 2 . x ) ; f 1 ( gen1 . x , gen1 . y ) ( x1 . x , x1 . y , a1 . x , a1 . y ) ; x1 ( f 1 . x1 , f 1 . y1 ) ( f 2 . y ) ; a1 ( f 1 . x2 , f 1 . y2 ) ( o1 . x ) ; f 2 ( gen1 . c , x1 . z ) ( x2 . x , x2 . y , a2 . x , a2 . y ) ; x2 ( f 2 . x1 , f 2 . y1 ) ( show . s 1 ) ; a2 ( f 2 . x2 , f 2 . y2 ) ( o1 . y ) ; o1 ( a1 . z , a2 . z ) ( f 4 . x ) ;

wire wire wire wire wire wire wire wire

gen2 ( gen2 . t ’ i n i t i a l l y 0 ) ( gen2 . t , f 3 . x , f 3 . y ) ; f 3 ( gen2 . x , gen2 . y ) ( x3 . x , x3 . y , a3 . x , a3 . y ) ; x3 ( f 3 . x1 , f 3 . y1 ) ( f 4 . y ) ; a3 ( f 3 . x2 , f 3 . y2 ) ( o2 . x ) ; f 4 ( o1 . z , x3 . z ) ( x4 . x , x4 . y , a4 . x , a4 . y ) ; x4 ( f 4 . x1 , f 4 . y1 ) ( show . s 2 ) ; a4 ( f 4 . x2 , f 4 . y2 ) ( o2 . y ) ; o2 ( a3 . z , a4 . z ) ( f 6 . x ) ;

wire wire wire wire wire wire wire wire

gen3 ( gen3 . t ’ i n i t i a l l y 0 ) ( gen3 . t , f 5 . x , f 5 . y ) ; f 5 ( gen3 . x , gen3 . y ) ( x5 . x , x5 . y , a5 . x , a5 . y ) ; x5 ( f 5 . x1 , f 5 . y1 ) ( f 6 . y ) ; a5 ( f 5 . x2 , f 5 . y2 ) ( o3 . x ) ; f 6 ( o2 . z , x5 . z ) ( x6 . x , x6 . y , a6 . x , a6 . y ) ; x6 ( f 6 . x1 , f 6 . y1 ) ( show . s 3 ) ; a6 ( f 6 . x2 , f 6 . y2 ) ( o3 . y ) ; o3 ( a5 . z , a6 . z ) ( show . c ) ;

w i r e show ( x2 . z , x4 . z , x6 . z , o3 . z ) ( o u t p u t ) ;

F.6.3 Example 8: A Four Bit Adder The following listing contains the HW-HUME source code of a four bit adder: type B i t = i n t 1 ; box gen1 in ( t : : i n t 6 4 ) out ( t ’ : : i n t 6 4 , x , y , c : : B i t ) match 0 −> (1,0,0,0) | 1 −> (2,0,1,0) | 2 −> (3,1,0,0) | 3 −> (4,1,1,0) | 4 −> (5,0,0,1) | 5 −> (6,0,1,1) | 6 −> (7,1,0,1) | 7 −> (0,1,1,1); box gen2 in ( t : : i n t 6 4 ) out ( t ’ : : i n t 6 4 , x , y : : B i t ) match 0 −> (1,0,0) | 1 −> (2,0,1) | 2 −> (3,1,0) | 3 −> (0,1,1) ; box gen3 in ( t : : i n t 6 4 ) out ( t ’ : : i n t 6 4 , x , y : : B i t ) match 0 −> (1,0,0) | 1 −> (2,0,1) | 2 −> (3,1,0) | 3 −> (0,1,1) ; box gen4 in ( t : : i n t 6 4 ) out ( t ’ : : i n t 6 4 , x , y : : B i t ) match 0 −> (1,0,0) | 1 −> (2,0,1) | 2 −> (3,1,0) | 3 −> (0,1,1) ; template fanout in ( x , y : : Bit ) o u t ( x1 , y1 , x2 , y2 : : B i t ) match (x , y ) −> ( x , y , x , y ); i n s t a n t i a t e f a n o u t as f ∗8; template xor in ( x , y : : Bit ) out ( z : : B i t ) match (0,0) −> 0 | (0,1) −> 1 | (1,0) −> 1 | (1,1) −> 0;

i n s t a n t i a t e xor as x ∗8; t e m p l a t e and in ( x , y : : Bit ) out ( z : : B i t ) match (0,0) −> 0 | (0,1) −> 0 | (1,0) −> 0 | (1,1) −> 1; i n s t a n t i a t e and a s a ∗ 8 ; template or in ( x , y : : Bit ) out ( z : : B i t ) match (0,0) −> 0 | (0,1) −> 1 | (1,0) −> 1 | (1,1) −> 1; i n s t a n t i a t e or as o ∗4; box show in ( s1 , s2 , s3 , s4 , c : : B i t ) o u t ( s s c : : ( B i t , B i t , B i t , B i t , B i t , char ) ) match ( a , b , c , d , carry ) −> ( a , b , c , d , carry ,’\ n ’ ) ; stream o u t p u t t o ” s t d o u t ” ; wire wire wire wire wire wire wire wire

gen1 ( gen1 . t ’ i n i t i a l l y 0 ) ( gen1 . t , f 1 . x , f 1 . y , f 2 . x ) ; f 1 ( gen1 . x , gen1 . y ) ( x1 . x , x1 . y , a1 . x , a1 . y ) ; x1 ( f 1 . x1 , f 1 . y1 ) ( f 2 . y ) ; a1 ( f 1 . x2 , f 1 . y2 ) ( o1 . x ) ; f 2 ( gen1 . c , x1 . z ) ( x2 . x , x2 . y , a2 . x , a2 . y ) ; x2 ( f 2 . x1 , f 2 . y1 ) ( show . s 1 ) ; a2 ( f 2 . x2 , f 2 . y2 ) ( o1 . y ) ; o1 ( a1 . z , a2 . z ) ( f 4 . x ) ;

wire wire wire wire wire wire wire wire

gen2 ( gen2 . t ’ i n i t i a l l y 0 ) ( gen2 . t , f 3 . x , f 3 . y ) ; f 3 ( gen2 . x , gen2 . y ) ( x3 . x , x3 . y , a3 . x , a3 . y ) ; x3 ( f 3 . x1 , f 3 . y1 ) ( f 4 . y ) ; a3 ( f 3 . x2 , f 3 . y2 ) ( o2 . x ) ; f 4 ( o1 . z , x3 . z ) ( x4 . x , x4 . y , a4 . x , a4 . y ) ; x4 ( f 4 . x1 , f 4 . y1 ) ( show . s 2 ) ; a4 ( f 4 . x2 , f 4 . y2 ) ( o2 . y ) ; o2 ( a3 . z , a4 . z ) ( f 6 . x ) ;

wire wire wire wire wire wire wire wire

gen3 ( gen3 . t ’ i n i t i a l l y 0 ) ( gen3 . t , f 5 . x , f 5 . y ) ; f 5 ( gen3 . x , gen3 . y ) ( x5 . x , x5 . y , a5 . x , a5 . y ) ; x5 ( f 5 . x1 , f 5 . y1 ) ( f 6 . y ) ; a5 ( f 5 . x2 , f 5 . y2 ) ( o3 . x ) ; f 6 ( o2 . z , x5 . z ) ( x6 . x , x6 . y , a6 . x , a6 . y ) ; x6 ( f 6 . x1 , f 6 . y1 ) ( show . s 3 ) ; a6 ( f 6 . x2 , f 6 . y2 ) ( o3 . y ) ; o3 ( a5 . z , a6 . z ) ( f 8 . x ) ;

w i r e gen4 ( gen4 . t ’ i n i t i a l l y 0 ) ( gen4 . t , f 7 . x , f 7 . y ) ; w i r e f 7 ( gen4 . x , gen4 . y ) ( x7 . x , x7 . y , a7 . x , a7 . y ) ; w i r e x7 ( f 7 . x1 , f 7 . y1 ) ( f 8 . y ) ;

wire wire wire wire wire

a7 ( f 7 . x2 , f 7 . y2 ) ( o4 . x ) ; f 8 ( o3 . z , x7 . z ) ( x8 . x , x8 . y , a8 . x , a8 . y ) ; x8 ( f 8 . x1 , f 8 . y1 ) ( show . s 4 ) ; a8 ( f 8 . x2 , f 8 . y2 ) ( o4 . y ) ; o4 ( a7 . z , a8 . z ) ( show . c ) ;

w i r e show ( x2 . z , x4 . z , x6 . z , x8 . z , o4 . z ) ( o u t p u t ) ;

F.6.4 Example 9: A Five Bit Adder The following listing contains the HW-HUME source code of a five bit adder: type B i t = i n t 1 ; box gen1 in ( t : : i n t 6 4 ) out ( t ’ : : i n t 6 4 , x , y , c : : B i t ) match 0 −> (1,0,0,0) | 1 −> (2,0,1,0) | 2 −> (3,1,0,0) | 3 −> (4,1,1,0) | 4 −> (5,0,0,1) | 5 −> (6,0,1,1) | 6 −> (7,1,0,1) | 7 −> (0,1,1,1); box gen2 in ( t : : i n t 6 4 ) out ( t ’ : : i n t 6 4 , x , y : : B i t ) match 0 −> (1,0,0) | 1 −> (2,0,1) | 2 −> (3,1,0) | 3 −> (0,1,1) ; box gen3 in ( t : : i n t 6 4 ) out ( t ’ : : i n t 6 4 , x , y : : B i t ) match 0 −> (1,0,0) | 1 −> (2,0,1) | 2 −> (3,1,0) | 3 −> (0,1,1) ; box gen4 in ( t : : i n t 6 4 ) out ( t ’ : : i n t 6 4 , x , y : : B i t ) match 0 −> (1,0,0) | 1 −> (2,0,1) | 2 −> (3,1,0) | 3 −> (0,1,1) ; box gen5 in ( t : : i n t 6 4 ) out ( t ’ : : i n t 6 4 , x , y : : B i t ) match 0 −> (1,0,0) |

1 −> (2,0,1) | 2 −> (3,1,0) | 3 −> (0,1,1) ; template fanout in ( x , y : : Bit ) o u t ( x1 , y1 , x2 , y2 : : B i t ) match (x , y ) −> ( x , y , x , y ); i n s t a n t i a t e f a n o u t as f ∗10; template xor in ( x , y : : Bit ) out ( z : : B i t ) match (0,0) −> 0 | (0,1) −> 1 | (1,0) −> 1 | (1,1) −> 0; i n s t a n t i a t e xor as x ∗10; t e m p l a t e and in ( x , y : : Bit ) out ( z : : B i t ) match (0,0) −> 0 | (0,1) −> 0 | (1,0) −> 0 | (1,1) −> 1; i n s t a n t i a t e and a s a ∗ 1 0 ; template or in ( x , y : : Bit ) out ( z : : B i t ) match (0,0) −> 0 | (0,1) −> 1 | (1,0) −> 1 | (1,1) −> 1; i n s t a n t i a t e or as o ∗5; box show in ( s1 , s2 , s3 , s4 , s5 , c : : B i t ) o u t ( s s c : : ( B i t , B i t , B i t , B i t , B i t , B i t , char ) ) match ( a , b , c , d , e , carry ) −> ( a , b , c , d , e , carry ,’\ n ’ ) ; stream o u t p u t t o ” s t d o u t ” ; wire wire wire wire wire wire wire wire

gen1 ( gen1 . t ’ i n i t i a l l y 0 ) ( gen1 . t , f 1 . x , f 1 . y , f 2 . x ) ; f 1 ( gen1 . x , gen1 . y ) ( x1 . x , x1 . y , a1 . x , a1 . y ) ; x1 ( f 1 . x1 , f 1 . y1 ) ( f 2 . y ) ; a1 ( f 1 . x2 , f 1 . y2 ) ( o1 . x ) ; f 2 ( gen1 . c , x1 . z ) ( x2 . x , x2 . y , a2 . x , a2 . y ) ; x2 ( f 2 . x1 , f 2 . y1 ) ( show . s 1 ) ; a2 ( f 2 . x2 , f 2 . y2 ) ( o1 . y ) ; o1 ( a1 . z , a2 . z ) ( f 4 . x ) ;

w i r e gen2 ( gen2 . t ’ i n i t i a l l y 0 ) ( gen2 . t , f 3 . x , f 3 . y ) ;

wire wire wire wire wire wire wire

f 3 ( gen2 . x , gen2 . y ) ( x3 . x , x3 . y , a3 . x , a3 . y ) ; x3 ( f 3 . x1 , f 3 . y1 ) ( f 4 . y ) ; a3 ( f 3 . x2 , f 3 . y2 ) ( o2 . x ) ; f 4 ( o1 . z , x3 . z ) ( x4 . x , x4 . y , a4 . x , a4 . y ) ; x4 ( f 4 . x1 , f 4 . y1 ) ( show . s 2 ) ; a4 ( f 4 . x2 , f 4 . y2 ) ( o2 . y ) ; o2 ( a3 . z , a4 . z ) ( f 6 . x ) ;

wire wire wire wire wire wire wire wire

gen3 ( gen3 . t ’ i n i t i a l l y 0 ) ( gen3 . t , f 5 . x , f 5 . y ) ; f 5 ( gen3 . x , gen3 . y ) ( x5 . x , x5 . y , a5 . x , a5 . y ) ; x5 ( f 5 . x1 , f 5 . y1 ) ( f 6 . y ) ; a5 ( f 5 . x2 , f 5 . y2 ) ( o3 . x ) ; f 6 ( o2 . z , x5 . z ) ( x6 . x , x6 . y , a6 . x , a6 . y ) ; x6 ( f 6 . x1 , f 6 . y1 ) ( show . s 3 ) ; a6 ( f 6 . x2 , f 6 . y2 ) ( o3 . y ) ; o3 ( a5 . z , a6 . z ) ( f 8 . x ) ;

wire wire wire wire wire wire wire wire

gen4 ( gen4 . t ’ i n i t i a l l y 0 ) ( gen4 . t , f 7 . x , f 7 . y ) ; f 7 ( gen4 . x , gen4 . y ) ( x7 . x , x7 . y , a7 . x , a7 . y ) ; x7 ( f 7 . x1 , f 7 . y1 ) ( f 8 . y ) ; a7 ( f 7 . x2 , f 7 . y2 ) ( o4 . x ) ; f 8 ( o3 . z , x7 . z ) ( x8 . x , x8 . y , a8 . x , a8 . y ) ; x8 ( f 8 . x1 , f 8 . y1 ) ( show . s 4 ) ; a8 ( f 8 . x2 , f 8 . y2 ) ( o4 . y ) ; o4 ( a7 . z , a8 . z ) ( f 1 0 . x ) ;

wire wire wire wire wire wire wire wire

gen5 ( gen5 . t ’ i n i t i a l l y 0 ) ( gen5 . t , f 9 . x , f 9 . y ) ; f 9 ( gen5 . x , gen5 . y ) ( x9 . x , x9 . y , a9 . x , a9 . y ) ; x9 ( f 9 . x1 , f 9 . y1 ) ( f 1 0 . y ) ; a9 ( f 9 . x2 , f 9 . y2 ) ( o5 . x ) ; f 1 0 ( o4 . z , x9 . z ) ( x10 . x , x10 . y , a10 . x , a10 . y ) ; x10 ( f 1 0 . x1 , f 1 0 . y1 ) ( show . s 5 ) ; a10 ( f 1 0 . x2 , f 1 0 . y2 ) ( o5 . y ) ; o5 ( a9 . z , a10 . z ) ( show . c ) ;

w i r e show ( x2 . z , x4 . z , x6 . z , x8 . z , x10 . z , o5 . z ) ( o u t p u t ) ;

F.7 Example 10: Debugging with Spin Example ten is used to illustrate the possibilities when using SPIN to model check HW-HUME programs. There are two versions of the HW-HUME source code. The first version, listed in section F.7.1, contains an error, and in the second version, listed in section F.7.2, the error has been corrected.

F.7.1 The First Version of the Counter The following listing contains the HW-HUME of the first version of the counter. The example contains an error. t y p e B i t = word 1 ; box c l o c k in ( a : : Bit ) out ( a ’ : : B i t ) match a −> 1;

template d i g i t in ( a , clk : : Bit ) out ( c l k ’ , q : : B i t ) match (0,0) −> (0,0) | (1,0) −> (0,1) | (0,1) −> (0,1) | (1,1) −> (1,0) ; i n s t a n t i a t e d i g i t as d ∗3; template fanout in ( x : : Bit ) o u t ( x1 , x2 : : B i t ) match a −> ( a , a ); i n s t a n t i a t e f a n o u t as f ∗3; box show i n ( d1 , d2 , d3 : : B i t ) o u t ( show : : ( word 3 , char ) ) match (0,0,0) −> (0,’\n ’ ) | (1,0,0) −> (1,’\n ’ ) | (0,1,0) −> (2,’\n ’ ) | (1,1,0) −> (3,’\n ’ ) | (0,0,1) −> (4,’\n ’ ) | (1,1,0) −> (5,’\n ’ ) | (0,1,1) −> (6,’\n ’ ) | (1,1,1) −> (7,’\n ’) ; stream o u t p u t t o ” s t d o u t ” ; wire wire wire wire wire wire wire wire

c l o c k ( d3 . c l k ’ i n i t i a l l y 1 ) ( d1 . c l k ) ; d1 ( f 1 . x1 , c l o c k . a ’ ) ( d2 . c l k , f 1 . x ) ; d2 ( f 2 . x1 , d1 . c l k ’ ) ( d3 . c l k , f 2 . x ) ; d3 ( f 3 . x1 , d2 . c l k ’ ) ( c l o c k . a , f 3 . x ) ; f 1 ( d1 . q i n i t i a l l y 0 ) ( d1 . a , show . d1 ) ; f 2 ( d2 . q i n i t i a l l y 0 ) ( d2 . a , show . d2 ) ; f 3 ( d3 . q i n i t i a l l y 0 ) ( d3 . a , show . d3 ) ; show ( f 1 . x2 , f 2 . x2 , f 3 . x2 ) ( o u t p u t ) ;

F.7.2 The Second Version of the Counter In the second version of the counter, the error has been fixed. The following listing contains the error free source code. t y p e B i t = word 1 ; box c l o c k in ( a : : Bit ) out ( a ’ : : B i t ) match a −> 1;

template d i g i t

in ( a , clk : : Bit ) out ( c l k ’ , q : : B i t ) match (0,0) −> (0,0) | (1,0) −> (0,1) | (0,1) −> (0,1) | (1,1) −> (1,0) ; i n s t a n t i a t e d i g i t as d ∗3; template fanout in ( x : : Bit ) o u t ( x1 , x2 : : B i t ) match a −> ( a , a ); i n s t a n t i a t e f a n o u t as f ∗3; box show i n ( d1 , d2 , d3 : : B i t ) o u t ( show : : ( word 3 , char ) ) match (0,0,0) −> (0,’\n ’ ) | (1,0,0) −> (1,’\n ’ ) | (0,1,0) −> (2,’\n ’ ) | (1,1,0) −> (3,’\n ’ ) | (0,0,1) −> (4,’\n ’ ) | (1,0,1) −> (5,’\n ’ ) | (0,1,1) −> (6,’\n ’ ) | (1,1,1) −> (7,’\n ’) ; stream o u t p u t t o ” s t d o u t ” ; wire wire wire wire wire wire wire wire

c l o c k ( d3 . c l k ’ i n i t i a l l y 1 ) ( d1 . c l k ) ; d1 ( f 1 . x1 , c l o c k . a ’ ) ( d2 . c l k , f 1 . x ) ; d2 ( f 2 . x1 , d1 . c l k ’ ) ( d3 . c l k , f 2 . x ) ; d3 ( f 3 . x1 , d2 . c l k ’ ) ( c l o c k . a , f 3 . x ) ; f 1 ( d1 . q i n i t i a l l y 0 ) ( d1 . a , show . d1 ) ; f 2 ( d2 . q i n i t i a l l y 0 ) ( d2 . a , show . d2 ) ; f 3 ( d3 . q i n i t i a l l y 0 ) ( d3 . a , show . d3 ) ; show ( f 1 . x2 , f 2 . x2 , f 3 . x2 ) ( o u t p u t ) ;

Appendix G

Translation Examples This appendix holds the PROMELA source code created in the examples used in chapter 6. In that chapter the evaluation of the rules and ‘hwhpromela’ program is performed. The source code is the result of translating the HW-HUME source code using ‘hwhpromela’. The HW-HUME code is listed in appendix F. Due to the size of the generated PROMELA code, only example one, three and four have been included. Note that the code has been slightly modified compared to the code ‘hwhpromela’ generated. This modification only includes removal of white space to save space and some additional new lines.

G.1 Example 1: The Half Adder The first example is the half adder that has been used throughout the entire thesis. The slightly modified PROMELA code generated from ‘hwhpromela’ is listed below: mtype = { BEGIN , END } ; chan o u t p u t c o n t r o l = [ 0 ] o f { mtype } ; chan g e n c o n t r o l = [ 0 ] o f { mtype } ; chan f a n o u t c o n t r o l = [ 0 ] o f { mtype } ; chan x o r c o n t r o l = [ 0 ] o f { mtype } ; chan a n d c o n t r o l = [ 0 ] o f { mtype } ; chan s h o w 1 c o n t r o l = [ 0 ] o f { mtype } ; chan g e n t q = [ 1 ] o f { i n t } ; chan g e n x = [ 1 ] o f { b i t } ; chan g e n y = [ 1 ] o f { b i t } ; chan f a n o u t x 1 = [ 1 ] o f { b i t } ; chan f a n o u t y 1 = [ 1 ] o f { b i t } ; chan f a n o u t x 2 = [ 1 ] o f { b i t } ; chan f a n o u t y 2 = [ 1 ] o f { b i t } ; chan x o r z = [ 1 ] o f { b i t } ; chan a n d z = [ 1 ] o f { b i t } ; chan s h o w 1 z c = [ 1 ] o f { b i t , b i t , s h o r t } ; p r o c t y p e gen ( chan i n 1 , o u t 1 , o u t 2 , o u t 3 , control ) { start : c o n t r o l ?BEGIN ; if : : ( in1 ? [ 0 ] ) − > in1 ? 0 ; out1 ! 1 ; out2 ! 0 ; out3 ! 0 ; : : else if : : ( in1 ? [ 1 ] ) − > in1 ? 1 ; out1 ! 2 ; out2 ! 0 ; out3 ! 1 ; : : else if

132

: : ( in1 ? [ 2 ] ) − > in1 ? 2 ; out1 ! 3 ; out2 ! 1 ; out3 ! 0 ; : : else if : : ( in1 ? [ 3 ] ) − > in1 ? 3 ; out1 ! 0 ; out2 ! 1 ; out3 ! 1 ; : : e l s e goto f i n i s h fi ; fi ; fi ; fi ; finish : c o n t r o l !END; goto s t a r t ; } p r o c t y p e f a n o u t ( chan i n 1 , i n 2 , o u t 1 , o u t 2 , o u t 3 , o u t 4 , control ) { bit x ; bit y ; start : c o n t r o l ?BEGIN ; if : : ( in1 ? [ x ] && in2 ? [ y ] ) − > in1 ?x ; in2 ?y ; out1 ! x ; out2 ! y ; out3 ! x ; out4 ! y ; : : e l s e goto f i n i s h fi ; finish : c o n t r o l !END; goto s t a r t ; } p r o c t y p e x o r ( chan i n 1 , i n 2 , o u t 1 , control ) { start : c o n t r o l ?BEGIN ; if : : ( in1 ?[0] && in2 ? [ 0 ] ) − > in1 ? 0 ; in2 ? 0 ; out1 ! 0 ; : : else if : : ( in1 ?[0] && in2 ? [ 1 ] ) − > in1 ? 0 ; in2 ? 1 ; out1 ! 1 ; : : else if : : ( in1 ?[1] && in2 ? [ 0 ] ) − > in1 ? 1 ; in2 ? 0 ; out1 ! 1 ; : : else if : : ( in1 ?[1] && in2 ? [ 1 ] ) − > in1 ? 1 ; in2 ? 1 ; out1 ! 0 ; : : e l s e goto f i n i s h fi ; fi ; fi ; fi ; finish : c o n t r o l !END; goto s t a r t ; } p r o c t y p e and ( chan i n 1 , i n 2 , o u t 1 , control ) { start : c o n t r o l ?BEGIN ; if : : ( in1 ?[0] && in2 ? [ 0 ] ) − > in1 ? 0 ; in2 ? 0 ; out1 ! 0 ; : : else if : : ( in1 ?[0] && in2 ? [ 1 ] ) − > in1 ? 0 ; in2 ? 1 ; out1 ! 0 ; : : else if : : ( in1 ?[1] && in2 ? [ 0 ] ) − > in1 ? 1 ; in2 ? 0 ; out1 ! 0 ; : : else if : : ( in1 ?[1] && in2 ? [ 1 ] ) − > in1 ? 1 ; in2 ? 1 ; out1 ! 1 ; : : e l s e goto f i n i s h fi ; fi ; fi ;

fi ; finish : c o n t r o l !END; goto s t a r t ; } p r o c t y p e show1 ( chan i n 1 , i n 2 , o u t 1 , control ) { bit z ; bit c ; start : c o n t r o l ?BEGIN ; if : : ( in1 ? [ z ] && in2 ? [ c ] ) − > in1 ? z ; in2 ? c ; out1 ! z , c , − 1 ; : : e l s e goto f i n i s h fi ; finish : c o n t r o l !END; goto s t a r t ; } a c t i v e proctype C o n t r o l ( ) { do : : g e n c o n t r o l ! BEGIN ; g e n c o n t r o l ?END; f a n o u t c o n t r o l ! BEGIN ; f a n o u t c o n t r o l ?END; x o r c o n t r o l ! BEGIN ; x o r c o n t r o l ?END; a n d c o n t r o l ! BEGIN ; a n d c o n t r o l ?END; s h o w 1 c o n t r o l ! BEGIN ; s h o w 1 c o n t r o l ?END; o u t p u t c o n t r o l ! BEGIN ; o u t p u t c o n t r o l ?END; od ; } a c t i v e proctype o u t p u t ( ) { chan i n = s h o w 1 z c ; b i t var1 ; b i t var2 ; short var3 ; start : o u t p u t c o n t r o l ?BEGIN ; if : : ( in ?[ var1 , var2 , var3 ] ) − > in ? var1 , var2 , var3 ; p r i n t f ( ” % d %d %d \ n ” , v a r 1 , v a r 2 , v a r 3 ) : : e l s e goto f i n i s h fi ; finish : o u t p u t c o n t r o l !END; goto s t a r t ; } init { gen tq !0; run gen ( g e n t q , run f a n o u t ( g e n x fanout run x o r ( f a n o u t x 1 run and ( f a n o u t x 2 run show1 ( x o r z , }

gen tq , gen x , gen y , g e n c o n t r o l ) ; , gen y , fanout x1 , fanout y1 , fanout x2 , y2 , fanout control ) ; , fanout y1 , xor z , xor control ) ; , fanout y2 , and z , a n d c o n t r o l ) ; and z , show1 zc , s h o w 1 c o n t r o l ) ;

G.2 Example 3: Full Adder from Truth Table The following listing is the PROMELA represention of example three. The example is a full adder implemented as a truth table. It is a slightly modified version of the code generated from ‘hwhpromela’. The only modifications applied to it, are the removal of white space, and some newline insertions. mtype = { BEGIN , END } ; chan o u t p u t c o n t r o l = [ 0 ] o f { mtype } ; chan g e n c o n t r o l = [ 0 ] o f { mtype } ; chan a d d e r c o n t r o l = [ 0 ] o f { mtype } ; chan s h o w 1 c o n t r o l = [ 0 ] o f { mtype } ; chan g e n t q = [ 1 ] o f { i n t } ; chan g e n x = [ 1 ] o f { b i t } ; chan g e n y = [ 1 ] o f { b i t } ; chan g e n c = [ 1 ] o f { b i t } ; chan a d d e r s = [ 1 ] o f { b i t } ; chan a d d e r c q = [ 1 ] o f { b i t } ; chan s h o w 1 s c = [ 1 ] o f { b i t , b i t , s h o r t } ; p r o c t y p e gen ( chan i n 1 , o u t 1 , o u t 2 , o u t 3 , o u t 4 , control ) { start : c o n t r o l ?BEGIN ; if : : ( in1 ? [ 0 ] ) − > in1 ? 0 ; out1 ! 1 ; out2 ! 0 ; out3 ! 0 ; out4 ! 0 ; : : else if : : ( in1 ? [ 1 ] ) − > in1 ? 1 ; out1 ! 2 ; out2 ! 0 ; out3 ! 1 ; out4 ! 0 ; : : else if : : ( in1 ? [ 2 ] ) − > in1 ? 2 ; out1 ! 3 ; out2 ! 1 ; out3 ! 0 ; out4 ! 0 ; : : else if : : ( in1 ? [ 3 ] ) − > in1 ? 3 ; out1 ! 4 ; out2 ! 1 ; out3 ! 1 ; out4 ! 0 ; : : else if : : ( in1 ? [ 4 ] ) − > in1 ? 4 ; out1 ! 5 ; out2 ! 0 ; out3 ! 0 ; out4 ! 1 ; : : else if : : ( in1 ? [ 5 ] ) − > in1 ? 5 ; out1 ! 6 ; out2 ! 0 ; out3 ! 1 ; out4 ! 1 ; : : else if : : ( in1 ? [ 6 ] ) − > in1 ? 6 ; out1 ! 7 ; out2 ! 1 ; out3 ! 0 ; out4 ! 1 ; : : else if : : ( in1 ? [ 7 ] ) − > in1 ? 7 ; out1 ! 0 ; out2 ! 1 ; out3 ! 1 ; out4 ! 1 ; : : e l s e goto f i n i s h fi ; fi ; fi ; fi ; fi ; fi ; fi ; fi ; finish : c o n t r o l !END; goto s t a r t ; }

p r o c t y p e a d d e r ( chan i n 1 , i n 2 , i n 3 , o u t 1 , o u t 2 , control ) { start : c o n t r o l ?BEGIN ; if : : ( in1 ?[0] && in2 ?[0] && in3 ? [ 0 ] ) − > in1 ? 0 ; in2 ? 0 ; in3 ?0; out1 ! 0 ; out2 ! 0 ; : : else if : : ( in1 ?[0] && in2 ?[1] && in3 ? [ 0 ] ) − > in1 ? 0 ; in2 ? 1 ; in3 ?0; out1 ! 1 ; out2 ! 0 ; : : else if : : ( in1 ?[1] && in2 ?[0] && in3 ? [ 0 ] ) − > in1 ? 1 ; in2 ? 0 ; in3 ?0; out1 ! 1 ; out2 ! 0 ; : : else if : : ( in1 ?[1] && in2 ?[1] && in3 ? [ 0 ] ) − > in1 ? 1 ; in2 ? 1 ; in3 ?0; out1 ! 0 ; out2 ! 1 ; : : else if : : ( in1 ?[0] && in2 ?[0] && in3 ? [ 1 ] ) − > in1 ? 0 ; in2 ? 0 ; in3 ?1; out1 ! 1 ; out2 ! 0 ; : : else if : : ( in1 ?[0] && in2 ?[1] && in3 ? [ 1 ] ) − > in1 ? 0 ; in2 ? 1 ; in3 ?1; out1 ! 0 ; out2 ! 1 ; : : else if : : ( in1 ?[1] && in2 ?[0] && in3 ? [ 1 ] ) − > in1 ? 1 ; in2 ? 0 ; in3 ?1; out1 ! 0 ; out2 ! 1 ; : : else if : : ( in1 ?[1] && in2 ?[1] && in3 ? [ 1 ] ) − > in1 ? 1 ; in2 ?1; in3 ?1; out1 ! 1 ; out2 ! 1 ; : : e l s e goto f i n i s h fi ; fi ; fi ; fi ; fi ; fi ; fi ; fi ; finish : c o n t r o l !END; goto s t a r t ; } p r o c t y p e show1 ( chan i n 1 , i n 2 , o u t 1 , control ) { bit s ; bit c ; start : c o n t r o l ?BEGIN ; if : : ( in1 ? [ s ] && in2 ? [ c ] ) − > in1 ? s ; in2 ? c ; out1 ! s , c , − 1 ; : : e l s e goto f i n i s h fi ; finish : c o n t r o l !END; goto s t a r t ; }

a c t i v e proctype C o n t r o l ( ) { do : : g e n c o n t r o l ! BEGIN ; g e n c o n t r o l ?END; a d d e r c o n t r o l ! BEGIN ; a d d e r c o n t r o l ?END; s h o w 1 c o n t r o l ! BEGIN ; s h o w 1 c o n t r o l ?END; o u t p u t c o n t r o l ! BEGIN ; o u t p u t c o n t r o l ?END; od ; } a c t i v e proctype o u t p u t ( ) { chan i n = s h o w 1 s c ; b i t var1 ; b i t var2 ; short var3 ; start : o u t p u t c o n t r o l ?BEGIN ; if : : ( in ?[ var1 , var2 , var3 ] ) − > in ? var1 , var2 , var3 ; p r i n t f ( ” % d %d %d \ n ” , v a r 1 , v a r 2 , v a r 3 ) : : e l s e goto f i n i s h fi ; finish : o u t p u t c o n t r o l !END; goto s t a r t ; } init { gen run run run }

tq !0; gen ( g e n t q , g e n t q , g e n x , g e n y , g e n c , g e n c o n t r o l ) ; adder ( gen x , gen y , gen c , adder s , adder cq , a d d e r c o n t r o l ) ; show1 ( a d d e r s , a d d e r c q , s h o w 1 s c , s h o w 1 c o n t r o l ) ;

G.3 Example 4: Full Adder as Half Adders and OR Gates Example four is the last example included in this appendix. The full adder is here represented using ‘half adders’ and ‘or’ gates. The slightly modified PROMELA version is listed below: mtype = { BEGIN , END } ; chan o u t p u t c o n t r o l = [ 0 ] o f { mtype } ; chan g e n c o n t r o l = [ 0 ] o f { mtype } ; chan h 1 c o n t r o l = [ 0 ] o f { mtype } ; chan h 2 c o n t r o l = [ 0 ] o f { mtype } ; chan o r c o n t r o l = [ 0 ] o f { mtype } ; chan s h o w 1 c o n t r o l = [ 0 ] o f { mtype } ; chan g e n t q = [ 1 ] o f { i n t } ; chan g e n x = [ 1 ] o f { b i t } ; chan g e n y = [ 1 ] o f { b i t } ; chan g e n c = [ 1 ] o f { b i t } ; chan o r z = [ 1 ] o f { b i t } ; chan s h o w 1 s c = [ 1 ] o f { b i t , b i t , s h o r t } ; chan h 1 s = [ 1 ] o f { b i t } ; chan h 1 c = [ 1 ] o f { b i t } ; chan h 2 s = [ 1 ] o f { b i t } ; chan h 2 c = [ 1 ] o f { b i t } ; p r o c t y p e gen ( chan i n 1 , o u t 1 , o u t 2 , o u t 3 , o u t 4 , start :

control ) {

c o n t r o l ?BEGIN ; if : : ( in1 ? [ 0 ] ) − > in1 ? 0 ; out1 ! 1 ; out2 ! 0 ; out3 ! 0 ; out4 ! 0 ; : : else if : : ( in1 ? [ 1 ] ) − > in1 ? 1 ; out1 ! 2 ; out2 ! 0 ; out3 ! 1 ; out4 ! 0 ; : : else if : : ( in1 ? [ 2 ] ) − > in1 ? 2 ; out1 ! 3 ; out2 ! 1 ; out3 ! 0 ; out4 ! 0 ; : : else if : : ( in1 ? [ 3 ] ) − > in1 ? 3 ; out1 ! 4 ; out2 ! 1 ; out3 ! 1 ; out4 ! 0 ; : : else if : : ( in1 ? [ 4 ] ) − > in1 ? 4 ; out1 ! 5 ; out2 ! 0 ; out3 ! 0 ; out4 ! 1 ; : : else if : : ( in1 ? [ 5 ] ) − > in1 ? 5 ; out1 ! 6 ; out2 ! 0 ; out3 ! 1 ; out4 ! 1 ; : : else if : : ( in1 ? [ 6 ] ) − > in1 ? 6 ; out1 ! 7 ; out2 ! 1 ; out3 ! 0 ; out4 ! 1 ; : : else if : : ( in1 ? [ 7 ] ) − > in1 ? 7 ; out1 ! 0 ; out2 ! 1 ; out3 ! 1 ; out4 ! 1 ; : : e l s e goto f i n i s h fi ; fi ; fi ; fi ; fi ; fi ; fi ; fi ; finish : c o n t r o l !END; goto s t a r t ; } p r o c t y p e o r ( chan i n 1 start : c o n t r o l ?BEGIN ; if : : ( in1 ?[0] && in2 : : else if : : ( in1 ?[0] : : else if ::( ::

, in2 , out1 ,

control ) {

? [ 0 ] ) − > in1 ? 0 ; in2 ? 0 ; out1 ! 0 ; && in2 ? [ 1 ] ) − > in1 ? 0 ; in2 ? 1 ; out1 ! 1 ; in1 ?[1] && in2 ? [ 0 ] ) − > in1 ? 1 ; in2 ? 0 ; out1 ! 1 ; else if : : ( in1 ?[1] && in2 ? [ 1 ] ) − > in1 ? 1 ; in2 ? 1 ; out1 ! 1 ; : : e l s e goto f i n i s h fi ;

fi ; fi ; fi ; finish : c o n t r o l !END; goto s t a r t ; } p r o c t y p e show1 ( chan i n 1 , i n 2 , o u t 1 , bit s ; bit c ; start :

control ) {

c o n t r o l ?BEGIN ; if : : ( in1 ? [ s ] && in2 ? [ c ] ) − > in1 ? s ; in2 ? c ; out1 ! s , c , − 1 ; : : e l s e goto f i n i s h fi ; finish : c o n t r o l !END; goto s t a r t ; } p r o c t y p e h1 ( chan i n 1 start : c o n t r o l ?BEGIN ; if : : ( in1 ?[0] && in2 : : else if : : ( in1 ?[0] : : else if ::( ::

, in2 , out1 , out2 ,

control ) {

? [ 0 ] ) − > in1 ? 0 ; in2 ? 0 ; out1 ! 0 ; out2 ! 0 ; && in2 ? [ 1 ] ) − > in1 ? 0 ; in2 ? 1 ; out1 ! 1 ; out2 ! 0 ; in1 ?[1] && in2 ? [ 0 ] ) − > in1 ? 1 ; in2 ? 0 ; out1 ! 1 ; out2 ! 0 ; else if : : ( in1 ?[1] && in2 ? [ 1 ] ) − > in1 ? 1 ; in2 ?1; out1 ! 0 ; out2 ! 1 ; : : e l s e goto f i n i s h fi ;

fi ; fi ; fi ; finish : c o n t r o l !END; goto s t a r t ; } p r o c t y p e h2 ( chan i n 1 start : c o n t r o l ?BEGIN ; if : : ( in1 ?[0] && in2 : : else if : : ( in1 ?[0] : : else if ::( ::

, in2 , out1 , out2 ,

control ) {

? [ 0 ] ) − > in1 ? 0 ; in2 ? 0 ; out1 ! 0 ; out2 ! 0 ; && in2 ? [ 1 ] ) − > in1 ? 0 ; in2 ? 1 ; out1 ! 1 ; out2 ! 0 ; in1 ?[1] && in2 ? [ 0 ] ) − > in1 ? 1 ; in2 ? 0 ; out1 ! 1 ; out2 ! 0 ; else if : : ( in1 ?[1] && in2 ? [ 1 ] ) − > in1 ? 1 ; in2 ?1; out1 ! 0 ; out2 ! 1 ; : : e l s e goto f i n i s h fi ;

fi ; fi ; fi ; finish : c o n t r o l !END; goto s t a r t ; } a c t i v e proctype C o n t r o l ( ) { do : : g e n c o n t r o l ! BEGIN ; g e n c o n t r o l ?END; h 1 c o n t r o l ! BEGIN ; h 1 c o n t r o l ?END; h 2 c o n t r o l ! BEGIN ; h 2 c o n t r o l ?END; o r c o n t r o l ! BEGIN ; o r c o n t r o l ?END; s h o w 1 c o n t r o l ! BEGIN ; s h o w 1 c o n t r o l ?END; o u t p u t c o n t r o l ! BEGIN ; o u t p u t c o n t r o l ?END; od ;

} a c t i v e proctype o u t p u t ( ) { chan i n = s h o w 1 s c ; b i t var1 ; b i t var2 ; short var3 ; start : o u t p u t c o n t r o l ?BEGIN ; if : : ( in ?[ var1 , var2 , var3 ] ) − > in ? var1 , var2 , var3 ; p r i n t f ( ” % d %d %d \ n ” , v a r 1 , v a r 2 , v a r 3 ) : : e l s e goto f i n i s h fi ; finish : o u t p u t c o n t r o l !END; goto s t a r t ; } init { gen run run run run run }

tq !0; gen ( g e n t q , g e n t q , g e n x , g e n y , g e n c , g e n c o n t r o l ) ; or ( h1 c , h2 c , or z , o r c o n t r o l ) ; show1 ( h 2 s , o r z , s h o w 1 s c , s h o w 1 c o n t r o l ) ; h1 ( g e n x , g e n y , h 1 s , h 1 c , h 1 c o n t r o l ) ; h2 ( g e n c , h 1 s , h 2 s , h 2 c , h 2 c o n t r o l ) ;

Appendix H

Verification Result This appendix contains the verification result, when verifying the PROMELA model translated from HW-HUME using ‘hwhpromela’. The verifications are conducted in chapter 6. The HW-HUME source code is listed in appendix F while the a few of the PROMELA translations are listed in appendix G. Due the size of the PROMELA code, only a selected range of the source code is included. Please note that the line numbers in the listings are not part of the verification output.

H.1 Example 1: Half Adder The half adder source code is listed in section G.1. When verifying the example with ‘hwhpromela’, the following output is generated: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29

$ j a v a hwhpromela − v h a l f . hume ( Spin Version 4 . 1 . 3 −− 24 A p r i l 2 0 0 4 ) + P a r t i a l Order Reduction Full s t a t e s p a c e search for : never claim assertion violations acceptance cycles i n v a l i d end s t a t e s

− ( none s p e c i f i e d ) + − ( not s e le c t e d ) +

S t a t e −vector 1 5 6 byte , depth reached 2 7 5 , e r r o r s : 0 217 s t a t e s , stored 1 s t a t e s , matched 2 1 8 t r a n s i t i o n s ( = s t o r e d +m a t c h e d ) 0 atomic s t e p s hash c o n f l i c t s : 0 ( r e s o l v e d ) ( max s i z e 2 ˆ 1 8 s t a t e s ) u n r e a c h e d i n p r o c t y p e gen l i n e 4 5 , s t a t e 3 7 , ” − end −” ( 1 of 3 7 s t a t e s ) unreached in proctype f a n o u t l i n e 6 4 , s t a t e 1 5 , ” − end −” ( 1 of 1 5 s t a t e s ) unreached in proctype xor l i n e 9 0 , s t a t e 3 3 , ” − end −” ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e and l i n e 1 1 6 , s t a t e 3 3 , ” − end −”

141

30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e show1 l i n e 1 3 5 , s t a t e 1 2 , ” − end −” ( 1 of 1 2 s t a t e s ) unreached in proctype C o n t r o l l i n e 1 5 0 , s t a t e 1 6 , ” − end −” ( 1 of 1 6 s t a t e s ) unreached in proctype o u t p u t l i n e 1 7 1 , s t a t e 1 1 , ” − end −” ( 1 of 1 1 s t a t e s ) unreached in proctype : i n i t : ( 0 of 7 s t a t e s ) −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− T r a n s l a t i o n S u c c e s s f u l : V e r i f i c a t i o n Completed −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− Fi le Generated : h a l f . pml T r a n s l a t i o n Time : 4 0 9 ms V e r i f i c a t i o n Time : 3 3 1 0 ms T o t a l Running Time : 3 7 1 9 ms −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

Line 1 shows the command applied to ‘hwhpromela’ to verify the half adder. Line 2 lists the name of the generated file, which is ‘half.pml’. The meaning of the output in line 6 to 17 is already described in chapter 6. Line 18 is only interesting when using algorithms other than the default. The rest of the verification output lists all the unreached states. Since this is a full space search that ran to completion, this means that these transitions are unreachable and constitute dead code in the model [18]. As the listing illustrates, all the processes except the init process, have one unreachable state, which is the end of the code for the process. This makes sense this since all processes have an infinite number of runs, and will never exit the process - hence it will never reach the end of it.

H.2 Example 2: An XOR and an AND Gate Forming a Deadlock The following output is generated when validating example two. Line 14 specifies that the example contains a deadlock, and line 3 states the filename of the generated trail. Lines 23 to 30 inclusively contain the statistics of the time consumption and is not part of the SPIN output. It is created by the ‘hwhpromela’ program. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

$ j a v a hwhpromela − v d e a d l o c k . hume pan : i n v a l i d end s t a t e ( a t d e p t h 4 6 ) pan : w r o t e d e a d l o c k . pml . t r a i l ( Spin Version 4 . 1 . 3 −− 24 A p r i l 2 0 0 4 ) Warning : S e a r c h n o t c o m p l e t e d + P a r t i a l Order Reduction Full s t a t e s p a c e search for : never claim assertion violations acceptance cycles i n v a l i d end s t a t e s

− ( none s p e c i f i e d ) + − ( not s e le c t e d ) +

S t a t e −vector 1 3 2 byte , depth reached 4 6 , e r r o r s : 1 36 s t a t e s , stored 0 s t a t e s , matched

17 18 19 20 21 22 23 24 25 26 27 28 29 30

3 6 t r a n s i t i o n s ( = s t o r e d +m a t c h e d ) 0 atomic s t e p s hash c o n f l i c t s : 0 ( r e s o l v e d ) ( max s i z e 2 ˆ 1 8 s t a t e s )

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− T r a n s l a t i o n S u c c e s s f u l : V e r i f i c a t i o n Completed −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− Fi le Generated : d e a d l o c k . pml T r a n s l a t i o n Time : 2 4 6 ms V e r i f i c a t i o n Time : 3 1 0 7 ms T o t a l Running Time : 3 3 5 3 ms −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

H.3 Example 3: Full Adder from Truth Table When validating example three, which is the full adder created by using a truth table, the output listed below is generated. Line 11 specifies that the verification completed successfully and without any errors. Lines 37 to 44 inclusively hold the time statistics from the verification, generated by ‘hwhpromela’. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

$ j a v a hwhpromela − v a d d e r 1 . hume ( Spin Version 4 . 1 . 3 −− 24 A p r i l 2 0 0 4 ) + P a r t i a l Order Reduction Full s t a t e s p a c e search for : never claim assertion violations acceptance cycles i n v a l i d end s t a t e s

− ( none s p e c i f i e d ) + − ( not s e le c t e d ) +

S t a t e −vector 1 2 0 byte , depth reached 3 7 1 , e r r o r s : 0 301 s t a t e s , stored 1 s t a t e s , matched 3 0 2 t r a n s i t i o n s ( = s t o r e d +m a t c h e d ) 0 atomic s t e p s hash c o n f l i c t s : 0 ( r e s o l v e d ) ( max s i z e 2 ˆ 1 8 s t a t e s ) u n r e a c h e d i n p r o c t y p e gen l i n e 5 2 , s t a t e 7 7 , ” − end −” ( 1 of 7 7 s t a t e s ) unreached in proctype adder l i n e 9 0 , s t a t e 7 7 , ” − end −” ( 1 of 7 7 s t a t e s ) u n r e a c h e d i n p r o c t y p e show1 l i n e 1 0 9 , s t a t e 1 2 , ” − end −” ( 1 of 1 2 s t a t e s ) unreached in proctype C o n t r o l l i n e 1 2 2 , s t a t e 1 2 , ” − end −” ( 1 of 1 2 s t a t e s ) unreached in proctype o u t p u t l i n e 1 4 3 , s t a t e 1 1 , ” − end −” ( 1 of 1 1 s t a t e s ) unreached in proctype : i n i t : ( 0 of 5 s t a t e s )

36 37 38 39 40 41 42 43 44

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− T r a n s l a t i o n S u c c e s s f u l : V e r i f i c a t i o n Completed −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− Fi le Generated : a d d e r 1 . pml T r a n s l a t i o n Time : 5 0 8 ms V e r i f i c a t i o n Time : 3 0 9 3 ms T o t a l Running Time : 3 6 0 1 ms −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

H.4 Example 4: Full Adder as Half Adders and OR Gates Example four is a full adder created by using ‘half adders’ and ‘or’ gates. The output generated when validating the adder, is listed below. Line 11 states that no errors were found, and lines 46 to 53 inclusively contain the time statistics generated by ‘hwhpromela’. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41

$ j a v a hwhpromela − v a d d e r 2 . hume ( Spin Version 4 . 1 . 3 −− 24 A p r i l 2 0 0 4 ) + P a r t i a l Order Reduction Full s t a t e s p a c e search for : never claim assertion violations acceptance cycles i n v a l i d end s t a t e s

− ( none s p e c i f i e d ) + − ( not s e le c t e d ) +

S t a t e −vector 1 5 6 byte , depth reached 5 1 9 , e r r o r s : 0 413 s t a t e s , stored 1 s t a t e s , matched 4 1 4 t r a n s i t i o n s ( = s t o r e d +m a t c h e d ) 0 atomic s t e p s hash c o n f l i c t s : 0 ( r e s o l v e d ) ( max s i z e 2 ˆ 1 8 s t a t e s ) u n r e a c h e d i n p r o c t y p e gen l i n e 5 7 , s t a t e 7 7 , ” − end −” ( 1 of 7 7 s t a t e s ) unreached in proctype or l i n e 7 2 , s t a t e 1 8 , ” in1 ?1” l i n e 7 2 , s t a t e 1 9 , ” in2 ?1” l i n e 7 2 , s t a t e 2 0 , ” out1 !1” l i n e 8 3 , s t a t e 3 3 , ” − end −” ( 4 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e show1 l i n e 1 0 2 , s t a t e 1 2 , ” − end −” ( 1 of 1 2 s t a t e s ) u n r e a c h e d i n p r o c t y p e h1 l i n e 1 2 8 , s t a t e 3 7 , ” − end −” ( 1 of 3 7 s t a t e s ) u n r e a c h e d i n p r o c t y p e h2 l i n e 1 5 4 , s t a t e 3 7 , ” − end −” ( 1 of 3 7 s t a t e s ) unreached in proctype C o n t r o l l i n e 1 6 9 , s t a t e 1 6 , ” − end −” ( 1 of 1 6 s t a t e s ) unreached in proctype o u t p u t l i n e 1 9 0 , s t a t e 1 1 , ” − end −”

42 43 44 45 46 47 48 49 50 51 52 53

( 1 of 1 1 s t a t e s ) unreached in proctype : i n i t : ( 0 of 7 s t a t e s ) −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− T r a n s l a t i o n S u c c e s s f u l : V e r i f i c a t i o n Completed −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− Fi le Generated : a d d e r 2 . pml T r a n s l a t i o n Time : 3 1 2 ms V e r i f i c a t i o n Time : 4 1 2 6 ms T o t a l Running Time : 4 4 3 8 ms −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

H.5 Example 5: Full Adder as XOR, AND and OR Gates In example five the adder has been created by connecting a set of ‘xor’,‘and’ and ‘or’ gates. The output shown below was generated from the verification in SPIN. The verification succeeded without any errors, as line 11 illustrates. The time statistics generated by ‘hwhpromela’ are listed on line 57 to 64 inclusively. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37

$ j a v a hwhpromela − v a d d e r 3 . hume ( Spin Version 4 . 1 . 3 −− 24 A p r i l 2 0 0 4 ) + P a r t i a l Order Reduction Full s t a t e s p a c e search for : never claim assertion violations acceptance cycles i n v a l i d end s t a t e s

− ( none s p e c i f i e d ) + − ( not s e le c t e d ) +

S t a t e −vector 2 5 6 byte , depth reached 8 7 1 , e r r o r s : 0 693 s t a t e s , stored 1 s t a t e s , matched 6 9 4 t r a n s i t i o n s ( = s t o r e d +m a t c h e d ) 0 atomic s t e p s hash c o n f l i c t s : 0 ( r e s o l v e d ) ( max s i z e 2 ˆ 1 8 s t a t e s ) u n r e a c h e d i n p r o c t y p e gen l i n e 6 9 , s t a t e 7 7 , ” − end −” ( 1 of 7 7 s t a t e s ) unreached in proctype or l i n e 8 4 , s t a t e 1 8 , ” in1 ?1” l i n e 8 4 , s t a t e 1 9 , ” in2 ?1” l i n e 8 4 , s t a t e 2 0 , ” out1 !1” l i n e 9 5 , s t a t e 3 3 , ” − end −” ( 4 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e show1 l i n e 1 1 4 , s t a t e 1 2 , ” − end −” ( 1 of 1 2 s t a t e s ) unreached in proctype f1 l i n e 1 3 3 , s t a t e 1 5 , ” − end −” ( 1 of 1 5 s t a t e s ) unreached in proctype f2 l i n e 1 5 2 , s t a t e 1 5 , ” − end −” ( 1 of 1 5 s t a t e s ) u n r e a c h e d i n p r o c t y p e x1

38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64

l i n e 1 7 8 , s t a t e 3 3 , ” − end −” ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e x2 l i n e 2 0 4 , s t a t e 3 3 , ” − end −” ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e a1 l i n e 2 3 0 , s t a t e 3 3 , ” − end −” u n r e a c h e d i n p r o c t y p e a2 l i n e 2 5 6 , s t a t e 3 3 , ” − end −” ( 1 of 3 3 s t a t e s ) unreached in proctype C o n t r o l l i n e 2 7 5 , s t a t e 2 4 , ” − end −” ( 1 of 2 4 s t a t e s ) unreached in proctype o u t p u t l i n e 2 9 6 , s t a t e 1 1 , ” − end −” ( 1 of 1 1 s t a t e s ) unreached in proctype : i n i t : ( 0 of 1 1 s t a t e s ) −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− T r a n s l a t i o n S u c c e s s f u l : V e r i f i c a t i o n Completed −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− Fi le Generated : a d d e r 3 . pml T r a n s l a t i o n Time : 3 4 3 ms V e r i f i c a t i o n Time : 4 9 9 0 ms T o t a l Running Time : 5 3 3 3 ms −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

H.6 Connecting Adders Examples six to nine are used to test the translation and verification on bigger models. The models are created on the basis of example five. Several such adders are connected together to create two, three, four and five bit adders.

H.6.1 Example 6: A Two Bit Adder In example six, two adders are connected to create a two bit adder. As line 11 states SPIN handled the size, and the model verified without any errors. Lines 85 to 92 inclusively hold the time statistics generated by ‘hwhpromela’. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

$ j a v a hwhpromela − v t w o b i t a d d e r . hume ( Spin Version 4 . 1 . 3 −− 24 A p r i l 2 0 0 4 ) + P a r t i a l Order Reduction Full s t a t e s p a c e search for : never claim assertion violations acceptance cycles i n v a l i d end s t a t e s

− ( none s p e c i f i e d ) + − ( not s e le c t e d ) +

S t a t e −vector 4 5 6 byte , depth reached 1 5 9 4 , e r r o r s : 0 1272 s t a t e s , s t o r e d 1 s t a t e s , matched 1 2 7 3 t r a n s i t i o n s ( = s t o r e d +m a t c h e d ) 0 atomic s t e p s

16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78

hash c o n f l i c t s : 0 ( r e s o l v e d ) ( max s i z e 2 ˆ 1 8 s t a t e s ) u n r e a c h e d i n p r o c t y p e gen1 l i n e 9 3 , s t a t e 7 7 , ” − end −” ( 1 of 7 7 s t a t e s ) u n r e a c h e d i n p r o c t y p e gen2 l i n e 1 1 9 , s t a t e 3 7 , ” − end −” ( 1 of 3 7 s t a t e s ) u n r e a c h e d i n p r o c t y p e show1 l i n e 1 3 9 , s t a t e 1 3 , ” − end −” ( 1 of 1 3 s t a t e s ) unreached in proctype f1 l i n e 1 5 8 , s t a t e 1 5 , ” − end −” ( 1 of 1 5 s t a t e s ) unreached in proctype f2 l i n e 1 7 7 , s t a t e 1 5 , ” − end −” ( 1 of 1 5 s t a t e s ) unreached in proctype f3 l i n e 1 9 6 , s t a t e 1 5 , ” − end −” ( 1 of 1 5 s t a t e s ) unreached in proctype f4 l i n e 2 1 5 , s t a t e 1 5 , ” − end −” ( 1 of 1 5 s t a t e s ) u n r e a c h e d i n p r o c t y p e x1 l i n e 2 4 1 , s t a t e 3 3 , ” − end −” ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e x2 l i n e 2 6 7 , s t a t e 3 3 , ” − end −” ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e x3 l i n e 2 9 3 , s t a t e 3 3 , ” − end −” ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e x4 l i n e 3 1 9 , s t a t e 3 3 , ” − end −” ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e a1 l i n e 3 4 5 , s t a t e 3 3 , ” − end −” ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e a2 l i n e 3 7 1 , s t a t e 3 3 , ” − end −” ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e a3 l i n e 3 9 7 , s t a t e 3 3 , ” − end −” ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e a4 l i n e 4 2 3 , s t a t e 3 3 , ” − end −” ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e o1 l i n e 4 3 8 , s t a t e 1 8 , ” in1 ?1” l i n e 4 3 8 , s t a t e 1 9 , ” in2 ?1” l i n e 4 3 8 , s t a t e 2 0 , ” out1 !1” l i n e 4 4 9 , s t a t e 3 3 , ” − end −” ( 4 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e o2 l i n e 4 6 4 , s t a t e 1 8 , ” in1 ?1” l i n e 4 6 4 , s t a t e 1 9 , ” in2 ?1” l i n e 4 6 4 , s t a t e 2 0 , ” out1 !1” l i n e 4 7 5 , s t a t e 3 3 , ” − end −” ( 4 of 3 3 s t a t e s ) unreached in proctype C o n t r o l l i n e 5 0 2 , s t a t e 4 0 , ” − end −” ( 1 of 4 0 s t a t e s )

79 80 81 82 83 84 85 86 87 88 89 90 91 92

unreached in proctype o u t p u t l i n e 5 2 4 , s t a t e 1 1 , ” − end −” ( 1 of 1 1 s t a t e s ) unreached in proctype : i n i t : ( 0 of 2 0 s t a t e s ) −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− T r a n s l a t i o n S u c c e s s f u l : V e r i f i c a t i o n Completed −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− Fi le Generated : t w o b i t a d d e r . pml T r a n s l a t i o n Time : 3 9 4 ms V e r i f i c a t i o n Time : 8 2 9 7 ms T o t a l Running Time : 8 6 9 1 ms −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

H.6.2 Example 7: A Three Bit Adder The three bit adder in example seven is created by appending another adder to example six. By doing so, an even bigger model is created. However, as line 12 in the following output shows, the verification succeeded without any errors. Lines 113 to 120 inclusively show the time statistics generated by ‘hwhpromela’. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36

$ j a v a hwhpromela − v t h r e e b i t a d d e r . hume h i n t : t h i s s e a r c h i s more e f f i c i e n t i f pan . c i s c o m p i l e d −DSAFETY ( Spin Version 4 . 1 . 3 −− 24 A p r i l 2 0 0 4 ) + P a r t i a l Order Reduction Full s t a t e s p a c e search for : never claim assertion violations acceptance cycles i n v a l i d end s t a t e s

− ( none s p e c i f i e d ) + − ( not s e le c t e d ) +

S t a t e −vector 6 5 2 byte , depth reached 2 3 1 7 , e r r o r s : 0 1851 s t a t e s , s t o r e d 1 s t a t e s , matched 1 8 5 2 t r a n s i t i o n s ( = s t o r e d +m a t c h e d ) 0 atomic s t e p s hash c o n f l i c t s : 0 ( r e s o l v e d ) ( max s i z e 2 ˆ 1 8 s t a t e s ) u n r e a c h e d i n p r o c t y p e gen1 line 117, state 77, ( 1 of 7 7 s t a t e s ) u n r e a c h e d i n p r o c t y p e gen2 line 143, state 37, ( 1 of 3 7 s t a t e s ) u n r e a c h e d i n p r o c t y p e gen3 line 169, state 37, ( 1 of 3 7 s t a t e s ) u n r e a c h e d i n p r o c t y p e show1 line 190, state 14, ( 1 of 1 4 s t a t e s ) unreached in proctype f1 line 209, state 15, ( 1 of 1 5 s t a t e s ) unreached in proctype f2 line 228, state 15,

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99

( 1 of 1 5 s t a t e s ) unreached in proctype f3 line 247, state 15, ( 1 of 1 5 s t a t e s ) unreached in proctype f4 line 266, state 15, ( 1 of 1 5 s t a t e s ) unreached in proctype f5 line 285, state 15, ( 1 of 1 5 s t a t e s ) unreached in proctype f6 line 304, state 15, ( 1 of 1 5 s t a t e s ) u n r e a c h e d i n p r o c t y p e x1 line 330, state 33, ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e x2 line 356, state 33, ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e x3 line 382, state 33, ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e x4 line 408, state 33, ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e x5 line 434, state 33, ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e x6 line 460, state 33, ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e a1 line 486, state 33, ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e a2 line 512, state 33, ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e a3 line 538, state 33, ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e a4 line 564, state 33, ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e a5 line 590, state 33, ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e a6 line 616, state 33, ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e o1 line 631, state 18, line 631, state 19, line 631, state 20, line 642, state 33, ( 4 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e o2 line 657, state 18, line 657, state 19, line 657, state 20, line 668, state 33, ( 4 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e o3 line 683, state 18,

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” in1 ?1” ” in2 ?1” ” out1 !1” ” − end −”

” in1 ?1” ” in2 ?1” ” out1 !1” ” − end −”

” in1 ?1”

100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120

l i n e 6 8 3 , s t a t e 1 9 , ” in2 ?1” l i n e 6 8 3 , s t a t e 2 0 , ” out1 !1” l i n e 6 9 4 , s t a t e 3 3 , ” − end −” ( 4 of 3 3 s t a t e s ) unreached in proctype C o n t r o l l i n e 7 2 9 , s t a t e 5 6 , ” − end −” ( 1 of 5 6 s t a t e s ) unreached in proctype o u t p u t l i n e 7 5 2 , s t a t e 1 1 , ” − end −” ( 1 of 1 1 s t a t e s ) unreached in proctype : i n i t : ( 0 of 2 9 s t a t e s ) −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− T r a n s l a t i o n S u c c e s s f u l : V e r i f i c a t i o n Completed −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− Fi le Generated : t h r e e b i t a d d e r . pml T r a n s l a t i o n Time : 4 1 4 ms V e r i f i c a t i o n Time : 1 1 4 5 8 ms T o t a l Running Time : 1 1 8 7 2 ms −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

H.6.3 Example 8: A Four Bit Adder In example eight another adder is appended to the previous example, creating a four bit adder. As line 12 shows, the verification completed successfully, without any errors. Lines 134 to 141 inclusively hold the time statistics ‘hwhpromela’ created. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

$ j a v a hwhpromela − v f o u r b i t a d d e r . hume h i n t : t h i s s e a r c h i s more e f f i c i e n t i f pan . c i s c o m p i l e d −DSAFETY ( Spin Version 4 . 1 . 3 −− 24 A p r i l 2 0 0 4 ) + P a r t i a l Order Reduction Full s t a t e s p a c e search for : never claim assertion violations acceptance cycles i n v a l i d end s t a t e s

− ( none s p e c i f i e d ) + − ( not s e le c t e d ) +

S t a t e −vector 8 4 8 byte , depth reached 3 0 4 0 , e r r o r s : 0 2430 s t a t e s , s t o r e d 1 s t a t e s , matched 2 4 3 1 t r a n s i t i o n s ( = s t o r e d +m a t c h e d ) 0 atomic s t e p s hash c o n f l i c t s : 0 ( r e s o l v e d ) ( max s i z e 2 ˆ 1 8 s t a t e s ) u n r e a c h e d i n p r o c t y p e gen1 line 141, state 77, ( 1 of 7 7 s t a t e s ) u n r e a c h e d i n p r o c t y p e gen2 line 167, state 37, ( 1 of 3 7 s t a t e s ) u n r e a c h e d i n p r o c t y p e gen3 line 193, state 37, ( 1 of 3 7 s t a t e s ) u n r e a c h e d i n p r o c t y p e gen4 line 219, state 37,

” − end −”

” − end −”

” − end −”

” − end −”

31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93

( 1 of 3 7 s t a t e s ) u n r e a c h e d i n p r o c t y p e show1 line 241, state 15, ( 1 of 1 5 s t a t e s ) unreached in proctype f1 line 260, state 15, ( 1 of 1 5 s t a t e s ) unreached in proctype f2 line 279, state 15, ( 1 of 1 5 s t a t e s ) unreached in proctype f3 line 298, state 15, ( 1 of 1 5 s t a t e s ) unreached in proctype f4 line 317, state 15, ( 1 of 1 5 s t a t e s ) unreached in proctype f5 line 336, state 15, ( 1 of 1 5 s t a t e s ) unreached in proctype f6 line 355, state 15, ( 1 of 1 5 s t a t e s ) unreached in proctype f7 line 374, state 15, ( 1 of 1 5 s t a t e s ) unreached in proctype f8 line 393, state 15, ( 1 of 1 5 s t a t e s ) u n r e a c h e d i n p r o c t y p e x1 line 419, state 33, ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e x2 line 445, state 33, ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e x3 line 471, state 33, ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e x4 line 497, state 33, ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e x5 line 523, state 33, ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e x6 line 549, state 33, ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e x7 line 575, state 33, ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e x8 line 601, state 33, ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e a1 line 627, state 33, ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e a2 line 653, state 33, ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e a3 line 679, state 33, ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e a4 line 705, state 33,

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

” − end −”

94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141

( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e a5 l i n e 7 3 1 , s t a t e 3 3 , ” − end −” ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e a6 l i n e 7 5 7 , s t a t e 3 3 , ” − end −” ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e a7 l i n e 7 8 3 , s t a t e 3 3 , ” − end −” ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e a8 l i n e 8 0 9 , s t a t e 3 3 , ” − end −” ( 1 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e o1 l i n e 8 2 4 , s t a t e 1 8 , ” in1 ?1” l i n e 8 2 4 , s t a t e 1 9 , ” in2 ?1” l i n e 8 2 4 , s t a t e 2 0 , ” out1 !1” l i n e 8 3 5 , s t a t e 3 3 , ” − end −” ( 4 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e o2 l i n e 8 5 0 , s t a t e 1 8 , ” in1 ?1” l i n e 8 5 0 , s t a t e 1 9 , ” in2 ?1” l i n e 8 5 0 , s t a t e 2 0 , ” out1 !1” l i n e 8 6 1 , s t a t e 3 3 , ” − end −” ( 4 of 3 3 s t a t e s ) u n r e a c h e d i n p r o c t y p e o4 l i n e 9 0 2 , s t a t e 1 8 , ” in1 ?1” l i n e 9 0 2 , s t a t e 1 9 , ” in2 ?1” l i n e 9 0 2 , s t a t e 2 0 , ” out1 !1” l i n e 9 1 3 , s t a t e 3 3 , ” − end −” ( 4 of 3 3 s t a t e s ) unreached in proctype C o n t r o l l i n e 9 5 6 , s t a t e 7 2 , ” − end −” ( 1 of 7 2 s t a t e s ) unreached in proctype o u t p u t l i n e 9 8 0 , s t a t e 1 1 , ” − end −” ( 1 of 1 1 s t a t e s ) unreached in proctype : i n i t : ( 0 of 3 8 s t a t e s ) −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− T r a n s l a t i o n S u c c e s s f u l : V e r i f i c a t i o n Completed −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− Fi le Generated : f o u r b i t a d d e r . pml T r a n s l a t i o n Time : 5 9 7 ms V e r i f i c a t i o n Time : 1 5 9 4 2 ms T o t a l Running Time : 1 6 5 3 9 ms −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

H.6.4 Example 9: A Five Bit Adder Example nine appends another adder to the four bit adder in example eight, and by doing so, creates a five bit adder. As line 16 in the following output shows, the verification then failed. Line 2 of the output states that the reason for the failure is the size of the state vector. To verify the example the maximum size of it must be increased, which is a configuration issue in SPIN. Lines 25 to 32 inclusively hold the time statistics ‘hwhpromela’ generated.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32

$ j a v a hwhpromela − v f i v e b i t a d d e r . hume pan : e r r o r , VECTORSZ t o o s m a l l , r e c o m p i l e pan . c w i t h −DVECTORSZ=N w i t h N>1028 pan : a b o r t i n g ( a t d e p t h 4 3 ) pan : w r o t e f i v e b i t a d d e r . pml . t r a i l ( Spin Version 4 . 1 . 3 −− 24 A p r i l 2 0 0 4 ) Warning : S e a r c h n o t c o m p l e t e d + P a r t i a l Order Reduction Full s t a t e s p a c e search for : never claim assertion violations acceptance cycles i n v a l i d end s t a t e s

− ( none s p e c i f i e d ) + − ( not s e le c t e d ) +

S t a t e −vector 1 0 2 8 byte , depth reached 4 3 , e r r o r s : 1 44 s t a t e s , stored 0 s t a t e s , matched 4 4 t r a n s i t i o n s ( = s t o r e d +m a t c h e d ) 0 atomic s t e p s hash c o n f l i c t s : 0 ( r e s o l v e d ) ( max s i z e 2 ˆ 1 8 s t a t e s )

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− T r a n s l a t i o n S u c c e s s f u l : V e r i f i c a t i o n Completed −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− Fi le Generated : f i v e b i t a d d e r . pml T r a n s l a t i o n Time : 7 7 0 ms V e r i f i c a t i o n Time : 1 7 8 6 6 ms T o t a l Running Time : 1 8 6 3 6 ms −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

H.7 Example 10: Debugging with Spin Example ten is used to show the possibilities gained by using SPIN to model check HW-HUME programs. First it uses ‘hwhpromela’ and SPIN to obtain and correct an error injected into the HW-HUME model. The model is a three bit counter. The example also illustrates the use of linear temporal logic to specify the order of events, and verify that the model corresponds to the specification.

H.7.1 The Counter with an Error Injected The first version of the counter example had an error injected. Line 14 in the following output, shows that SPIN found the error. 1 2 3 4 5 6 7 8

$ j a v a hwhpromela − v c o u n t e r . hume pan : i n v a l i d end s t a t e ( a t d e p t h 5 2 8 ) pan : w r o t e c o u n t e r . pml . t r a i l ( Spin Version 4 . 1 . 3 −− 24 A p r i l 2 0 0 4 ) Warning : S e a r c h n o t c o m p l e t e d + P a r t i a l Order Reduction Full s t a t e s p a c e search for :

9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

never claim assertion violations acceptance cycles i n v a l i d end s t a t e s

− ( none s p e c i f i e d ) + − ( not s e le c t e d ) +

S t a t e −vector 2 0 8 byte , depth reached 5 2 8 , e r r o r s : 1 412 s t a t e s , stored 0 s t a t e s , matched 4 1 2 t r a n s i t i o n s ( = s t o r e d +m a t c h e d ) 0 atomic s t e p s hash c o n f l i c t s : 0 ( r e s o l v e d ) ( max s i z e 2 ˆ 1 8 s t a t e s )

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− T r a n s l a t i o n S u c c e s s f u l : V e r i f i c a t i o n Completed −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− Fi le Generated : c o u n t e r . pml T r a n s l a t i o n Time : 3 4 2 ms V e r i f i c a t i o n Time : 4 3 7 0 ms T o t a l Running Time : 4 7 1 2 ms −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

H.7.2 The Updated Counter By using the error trail in a guided simulation, the source of the error was found and the HWHUME model was corrected. The following listing shows the output from the updated version of the counter. As line 11 states, the counter did not include any errors. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29

$ j a v a hwhpromela − v c o u n t e r . hume ( Spin Version 4 . 1 . 3 −− 24 A p r i l 2 0 0 4 ) + P a r t i a l Order Reduction Full s t a t e s p a c e search for : never claim assertion violations acceptance cycles i n v a l i d end s t a t e s

− ( none s p e c i f i e d ) + − ( not s e le c t e d ) +

S t a t e −vector 2 0 8 byte , depth reached 7 4 5 , e r r o r s : 0 583 s t a t e s , stored 1 s t a t e s , matched 5 8 4 t r a n s i t i o n s ( = s t o r e d +m a t c h e d ) 0 atomic s t e p s hash c o n f l i c t s : 0 ( r e s o l v e d ) ( max s i z e 2 ˆ 1 8 s t a t e s ) unreached in proctype clock l i n e 4 4 , s t a t e 1 1 , ” − end −” ( 1 of 1 1 s t a t e s ) u n r e a c h e d i n p r o c t y p e show1 l i n e 8 2 , s t a t e 6 9 , ” − end −” ( 1 of 6 9 s t a t e s ) u n r e a c h e d i n p r o c t y p e d1 l i n e 9 1 , s t a t e 4 , ” in2 ?0” l i n e 9 3 , s t a t e 1 0 , ” in2 ?0” l i n e 9 3 , s t a t e 1 1 , ” out1 !0” l i n e 1 0 8 , s t a t e 3 7 , ” − end −”

30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62

( 4 of 3 7 s t a t e s ) u n r e a c h e d i n p r o c t y p e d2 l i n e 1 3 4 , s t a t e 3 7 , ” − end −” ( 1 of 3 7 s t a t e s ) u n r e a c h e d i n p r o c t y p e d3 l i n e 1 6 0 , s t a t e 3 7 , ” − end −” ( 1 of 3 7 s t a t e s ) unreached in proctype f1 l i n e 1 7 8 , s t a t e 1 2 , ” − end −” ( 1 of 1 2 s t a t e s ) unreached in proctype f2 l i n e 1 9 6 , s t a t e 1 2 , ” − end −” ( 1 of 1 2 s t a t e s ) unreached in proctype f3 l i n e 2 1 4 , s t a t e 1 2 , ” − end −” ( 1 of 1 2 s t a t e s ) unreached in proctype C o n t r o l l i n e 2 3 2 , s t a t e 2 2 , ” − end −” ( 1 of 2 2 s t a t e s ) unreached in proctype o u t p u t l i n e 2 5 2 , s t a t e 1 1 , ” − end −” ( 1 of 1 1 s t a t e s ) unreached in proctype : i n i t : ( 0 of 1 3 s t a t e s ) −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− T r a n s l a t i o n S u c c e s s f u l : V e r i f i c a t i o n Completed −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− Fi le Generated : c o u n t e r . pml T r a n s l a t i o n Time : 3 4 7 ms V e r i f i c a t i o n Time : 4 4 2 1 ms T o t a l Running Time : 4 7 6 8 ms −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

H.7.3 Specifying Behaviour SPIN is much more powerful than to just find deadlocks. Certain required behaviour can be specified, and SPIN can be used to check if the model violates this behaviour. In this example the behaviour is specified by using linear temporal logic (LTL), where the order of events can be reasoned. LTL can be used to specify both desired behaviour and error behaviour. The next section uses both ways to specify the same behaviour. The requirement is that when the counter reaches seven it will eventually be set to zero. Desired Behaviour The desired behaviour is that the counter should always be set to zero, when the counter reaches one. The following output is the output generated when using XSPIN to specify and validate the behaviour. Lines 1 and 2 declare the two events, and line 4 holds the desired LTL property. In order to validate an LTL property, SPIN translates the LTL property into a never claim. Lines 10 to 20 show the generated never claim. Note that since the claim specifies what should not happen the LTL property on line 4 is negated in the claim on line 6. Line 39 declares that the verification completed successfully. Since ‘hwhpromela’ was not used, no time statistics were created.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63

# define p ( value == 7) # define q ( value == 0) /∗ ∗ F o r m u l a As Typed : [ ] ( p − > <> q ) ∗ The Never Claim Below C o r r e s p o n d s ∗ To The N e g a t e d F o r m u l a ! ( [ ] ( p − > <> q ) ) ∗ ( f o r m a l i z i n g v i o l a t i o n s of the o r i g i n a l ) ∗/ never { T0 init :

/∗ !([]

( p −>

<>

q )) ∗/

if : : ( ! ( ( q ) ) & & ( p ) ) − > goto a c c e p t S 4 : : ( 1 ) − > goto T 0 i n i t fi ; accept S4 : if : : ( ! ( ( q ) ) ) − > goto a c c e p t S 4 fi ; } # i f d e f NOTES Use Load t o open a f i l e o r a t e m p l a t e . # endif # i f d e f RESULT w a r n i n g : f o r p . o . r e d u c t i o n t o be v a l i d t h e n e v e r c l a i m must be s t u t t e r −invarian t ( n e v e r c l a i m s g e n e r a t e d from LTL f o r m u l a e a r e s t u t t e r − i n v a r i a n t ) d e p t h 1 3 3 1 : Claim r e a c h e d s t a t e 9 ( l i n e 2 9 3 ) ( Spin Version 4 . 1 . 3 −− 24 A p r i l 2 0 0 4 ) + P a r t i a l Order Reduction Full s t a t e s p a c e search for : never claim assertion violations acceptance cycles i n v a l i d end s t a t e s

+ + ( i f within scope of claim ) + ( fairness disabled ) − ( d i s a b l e d by n e v e r c l a i m )

S t a t e −vector 2 1 2 byte , depth reached 1 3 4 6 , e r r o r s : 0 658 s t a t e s , stored ( 7 2 4 v i s i t e d ) 130 s t a t e s , matched 8 5 4 t r a n s i t i o n s ( = v i s i t e d +m a t c h e d ) 0 atomic s t e p s hash c o n f l i c t s : 0 ( r e s o l v e d ) ( max s i z e 2 ˆ 1 9 s t a t e s ) S t a t s on memory u s a g e ( i n M e g a b y t e s ) : 0.145 e q u i v a l e n t memory u s a g e f o r s t a t e s ( s t o r e d ∗( S t a t e −vector + overhead ) ) 0.284 a c t u a l memory u s a g e f o r s t a t e s ( unsuccessful compression : 196.29%) S t a t e −vector as s t o r e d = 4 2 4 byte + 8 byte overhead 2.097 memory u s e d f o r h a s h t a b l e ( − w19 ) 0.320 memory u s e d f o r DFS s t a c k ( − m10000 ) 2.622 t o t a l a c t u a l memory u s a g e unreached in proctype clock l i n e 4 8 , ” pan . ” , s t a t e 1 1 , ” − end −” ( 1 of 1 1 s t a t e s ) u n r e a c h e d i n p r o c t y p e show1 l i n e 8 6 , ” pan . ” , s t a t e 6 9 , ” − end −” ( 1 of 6 9 s t a t e s ) u n r e a c h e d i n p r o c t y p e d1

64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99

l i n e 9 5 , ” pan . ” , s t a t e 4 , ” in2 ?0” l i n e 9 7 , ” pan . ” , s t a t e 1 0 , ” in2 ?0” l i n e 9 7 , ” pan . ” , s t a t e 1 1 , ” out1 !0” l i n e 1 1 2 , ” pan . ” , s t a t e 3 7 , ” − end −” ( 4 of 3 7 s t a t e s ) u n r e a c h e d i n p r o c t y p e d2 ” , s t a t e 3 7 , ” − end −” l i n e 1 3 8 , ” pan . ( 1 of 3 7 s t a t e s ) u n r e a c h e d i n p r o c t y p e d3 l i n e 1 6 4 , ” pan . ” , s t a t e 3 7 , ” − end −” ( 1 of 3 7 s t a t e s ) unreached in proctype f1 l i n e 1 8 2 , ” pan . ” , s t a t e 1 2 , ” − end −” ( 1 of 1 2 s t a t e s ) unreached in proctype f2 l i n e 2 0 0 , ” pan . ” , s t a t e 1 2 , ” − end −” ( 1 of 1 2 s t a t e s ) unreached in proctype f3 l i n e 2 1 8 , ” pan . ” , s t a t e 1 2 , ” − end −” ( 1 of 1 2 s t a t e s ) unreached in proctype C o n t r o l ” , s t a t e 2 2 , ” − end −” l i n e 2 3 6 , ” pan . ( 1 of 2 2 s t a t e s ) unreached in proctype o u t p u t l i n e 2 5 6 , ” pan . ” , s t a t e 1 2 , ” − end −” ( 1 of 1 2 s t a t e s ) unreached in proctype : i n i t : ( 0 of 1 3 s t a t e s ) unreached in proctype : never : l i n e 2 9 6 , ” pan . ” , s t a t e 1 1 , ” − end −” ( 1 of 1 1 s t a t e s ) 0 . 0 2 u s e r 0 . 0 0 s y s t e m 0 : 0 0 . 0 2 e l a p s e d 68%CPU ( 0 a v g t e x t +0 a v g d a t a 0 m a x r e s i d e n t ) k 0 i n p u t s +0 o u t p u t s ( 1 3 2 m a j o r +637 m i n o r ) p a g e f a u l t s 0 swaps # endif

Error Behaviour When specifying desired behaviour, the behaviour that should always happen is defined. When specifying error behaviour the events that should never occur is defined. The error behaviour in the counter example is that the counter is eventually not set to zero when it reaches seven. The following output is generated by XSPIN when verifying the error behaviour. Line 1 and 2 holds the two events, and line 4 holds the LTL property. In lines 7 to 17 the never claim is created. Note that since this is an error behaviour the LTL property is not negated on line 7. Line 36 shows that the verification completed successfully without any errors. Since XSPIN, and not ‘hwhpromela’, was used, the time statistics were not created. 1 2 3 4 5 6 7 8

# define p ( value == 7) # define q ( value == 0) /∗ ∗ F o r m u l a As Typed : < > ∗/ never { T0 init :

/∗ (<>

!

( p −>

!

<>

( p −>

q)) ∗/

<>

q)

9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71

if : : ( ! ( ( q ) ) & & ( p ) ) − > goto a c c e p t S 4 : : ( 1 ) − > goto T 0 i n i t fi ; accept S4 : if : : ( ! ( ( q ) ) ) − > goto a c c e p t S 4 fi ; } # i f d e f NOTES Use Load t o open a f i l e o r a t e m p l a t e . # endif # i f d e f RESULT w a r n i n g : f o r p . o . r e d u c t i o n t o be v a l i d t h e n e v e r c l a i m must be s t u t t e r −invarian t ( n e v e r c l a i m s g e n e r a t e d from LTL f o r m u l a e a r e s t u t t e r − i n v a r i a n t ) d e p t h 1 3 3 1 : Claim r e a c h e d s t a t e 9 ( l i n e 2 9 0 ) ( Spin Version 4 . 1 . 3 −− 24 A p r i l 2 0 0 4 ) + P a r t i a l Order Reduction Full s t a t e s p a c e search for : never claim assertion violations acceptance cycles i n v a l i d end s t a t e s

+ + ( i f within scope of claim ) + ( fairness disabled ) − ( d i s a b l e d by n e v e r c l a i m )

S t a t e −vector 2 1 2 byte , depth reached 1 3 4 6 , e r r o r s : 0 658 s t a t e s , stored ( 7 2 4 v i s i t e d ) 130 s t a t e s , matched 8 5 4 t r a n s i t i o n s ( = v i s i t e d +m a t c h e d ) 0 atomic s t e p s hash c o n f l i c t s : 0 ( r e s o l v e d ) ( max s i z e 2 ˆ 1 9 s t a t e s ) S t a t s on memory u s a g e ( i n M e g a b y t e s ) : 0.145 e q u i v a l e n t memory u s a g e f o r s t a t e s ( s t o r e d ∗( S t a t e −vector + overhead ) ) 0.284 a c t u a l memory u s a g e f o r s t a t e s ( unsuccessful compression : 196.29%) S t a t e −vector as s t o r e d = 4 2 4 byte + 8 byte overhead 2.097 memory u s e d f o r h a s h t a b l e ( − w19 ) 0.320 memory u s e d f o r DFS s t a c k ( − m10000 ) 2.622 t o t a l a c t u a l memory u s a g e unreached in proctype clock l i n e 4 8 , ” pan . ” , s t a t e 1 1 , ” − end −” ( 1 of 1 1 s t a t e s ) u n r e a c h e d i n p r o c t y p e show1 l i n e 8 6 , ” pan . ” , s t a t e 6 9 , ” − end −” ( 1 of 6 9 s t a t e s ) u n r e a c h e d i n p r o c t y p e d1 l i n e 9 5 , ” pan . ” , s t a t e 4 , ” in2 ?0” l i n e 9 7 , ” pan . ” , s t a t e 1 0 , ” in2 ?0” l i n e 9 7 , ” pan . ” , s t a t e 1 1 , ” out1 !0” l i n e 1 1 2 , ” pan . ” , s t a t e 3 7 , ” − end −” ( 4 of 3 7 s t a t e s ) u n r e a c h e d i n p r o c t y p e d2 l i n e 1 3 8 , ” pan . ” , s t a t e 3 7 , ” − end −” ( 1 of 3 7 s t a t e s ) u n r e a c h e d i n p r o c t y p e d3 l i n e 1 6 4 , ” pan . ” , s t a t e 3 7 , ” − end −” ( 1 of 3 7 s t a t e s )

72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96

unreached in proctype f1 l i n e 1 8 2 , ” pan . ” , s t a t e 1 2 , ” − end −” ( 1 of 1 2 s t a t e s ) unreached in proctype f2 l i n e 2 0 0 , ” pan . ” , s t a t e 1 2 , ” − end −” ( 1 of 1 2 s t a t e s ) unreached in proctype f3 l i n e 2 1 8 , ” pan . ” , s t a t e 1 2 , ” − end −” ( 1 of 1 2 s t a t e s ) unreached in proctype C o n t r o l l i n e 2 3 6 , ” pan . ” , s t a t e 2 2 , ” − end −” ( 1 of 2 2 s t a t e s ) unreached in proctype o u t p u t ” , s t a t e 1 2 , ” − end −” l i n e 2 5 6 , ” pan . ( 1 of 1 2 s t a t e s ) unreached in proctype : i n i t : ( 0 of 1 3 s t a t e s ) unreached in proctype : never : l i n e 2 9 3 , ” pan . ” , s t a t e 1 1 , ” − end −” ( 1 of 1 1 s t a t e s ) 0 . 0 1 u s e r 0 . 0 2 s y s t e m 0 : 0 0 . 0 4 e l a p s e d 68%CPU ( 0 a v g t e x t +0 a v g d a t a 0 m a x r e s i d e n t ) k 0 i n p u t s +0 o u t p u t s ( 1 3 2 m a j o r +637 m i n o r ) p a g e f a u l t s 0 swaps # endif

Model Checking Hw-Hume

School of Mathematical and Computer Sciences ... thesis has not been submitted for any other degree. .... 4.6.2 Variable Declaration . ... 4.8.2 Output Streams . ...... PROMELA translator was also created at Heriot-Watt University the same year.

1MB Sizes 0 Downloads 453 Views

Recommend Documents

Model Checking
where v1, v2, . . . . v represents the current state and v., v, ..., v, represents the next state. By converting this ... one register is eventually equal to the sum of the values in two other registers. In such ... atomic proposition names. .... If

Regular Model Checking
sets of states and the transition relation are represented by regular sets. Major ... [C] Ahmed Bouajjani, Bengt Jonsson, Marcus Nilsson, and Tayssir Touili. Regu- lar model checking. In Proc. 12th Int. Conf. on Computer Aided Verification, ..... hav

Parameterized Model Checking of Fine Grained Concurrency
implementation of multi-threaded programs. Their efficiency is achieved by using .... Unbounded threads: We show how concurrent list based set data structures.

Model Checking Secondary Relations
be put to use to query mildly context-sensitive secondary relations with ... mally considered a powerful query language, is too weak to capture these phenom-.

A primer on model checking
Software systems for model checking have become a cornerstone of both ..... Aside from the standard features of an environment (file handling, editing and ...

Statistical Model Checking for Cyber-Physical Systems
The autopilot is a software which provides inputs to the aircraft's engines and flight control surfaces (e.g., ..... Therefore, instead of try- ing to come up with the optimal density, it may be preferable to search in a ..... optimization. Methodolo

Bayesian Statistical Model Checking with Application to ...
Jan 13, 2010 - discrete-time hybrid system models in Stateflow/Simulink: a fuel control system .... Formally, we start with a definition of a deterministic automaton. ...... demos.html?file=/products/demos/shipping/simulink/sldemo fuelsys.html .

Statistical Model Checking for Markov Decision ...
Programming [18] works in a setting similar to PMC. It also uses simulation for ..... we use the same input language as PRISM, many off-the-shelf models and case ... http://www.prismmodelchecker.org/casestudies/index.php. L resulting in the ...

Symbolic Model Checking of Signaling Pathways ... - Semantic Scholar
ply Model Checking to the study of a biological system ... of hardware, digital circuits, and software designs. Given .... This is in accord with evidence from cancer.

Model Checking Temporal Logics of Knowledge Via ...
of knowledge, distributed AI. Received 14 ... the use of the technology in fields of AI such as planning ...... We directly use the MCK input file of this protocol in the.

Model Checking Temporal Logics of Knowledge in ...
As for future work, we are interested in providing au- tomated support for the analysis of knowledge in distributed system protocols and game theoretic examples, ...

A Bayesian Approach to Model Checking Biological ...
1 Computer Science Department, Carnegie Mellon University, USA ..... 3.2 also indicates an objective degree of confidence in the accepted hypothesis when.

Model Checking-Based Genetic Programming with an Application to ...
ing for providing the fitness function has the advantage over testing that all the executions ...... In: Computer Performance Evaluation / TOOLS 2002, 200–204. 6.

handling concatenation in trace- and model-checking
For model-checking, i.e. the verification of a system's model against a specifica- tion, we examine behavioural .... the way the file system was implemented, the directory structure could only grow larger, because the ..... is different from call-sta

Geometric Model Checking: An Automatic Verification ...
based embedded systems design, where the initial program is subject to a series of transformations to .... It is required to check that the use of the definition and operand variables in the ..... used when filling the buffer arrays. If a condition d

A Model Checking Methodology for Embedded Systems
time-to-market for embedded systems have made the challenge of properly .... notice that the signature and behavior descriptions along with the transitions ...

Symbolic Model Checking of Signaling Pathways ... - Semantic Scholar
sired temporal logic properties of the HMGB1 model. The. Boolean network modeling and Model Checking provide an alternative way and new insights into the study of the. HMGB1 signaling pathway in pancreatic cancer. Keywords: Model Checking, HMGB1, Sig

A Bayesian Approach to Model Checking Biological ...
of the system interact and evolve by obeying a set of instructions or rules. In contrast to .... because one counterexample to φ is not enough to answer P≥θ(φ).

Checking out Textbooks Checking In Textbooks
(Note: You will need a barcode scanner to use the Destiny Textbook Checkout Manager. Your department has a number of scanners that you may use to check ...

Telephoning- Dictating & Checking/Clarifying - UsingEnglish.com
Mar 30, 2014 - will dictate before you start speaking, and/ or check with your business card, the internet etc. See the ... Website or particular webpage. Postal .... Do the same with your own real model numbers, dimensions, etc. Written by ...