-
Notifications
You must be signed in to change notification settings - Fork 0
/
project.xml
495 lines (464 loc) · 19.5 KB
/
project.xml
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
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
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE nta PUBLIC '-//Uppaal Team//DTD Flat System 1.6//EN' 'http://www.it.uu.se/research/group/darts/uppaal/flat-1_6.dtd'>
<nta>
<declaration>const int nSlots = 105; // Number of slots
const int nPS = 6; // Number of processing stations
const int nObj = 3; // Number of object
/*** TYPES ************************************************************/
typedef int[0, nSlots - 1] id_slot;
typedef int[0, nPS - 1] id_ps;
typedef int[0, nObj - 1] id_obj;
/*** PARAMETERS *******************************************************/
const int inverseSpeed = 10; // conveyor belt speed in [time units / slot]
// Processing station position
const id_slot SLOTS_BEFORE_PS[nPS] = {15, 35, 63, 71, 92, 103}; // id of slot before each processing station
const id_slot SLOTS_AFTER_PS[nPS] = {16, 36, 64, 72, 93, 104}; // id of slot after each processing station
// Processing time parameters of processing stations
const int PS_TIME[nPS] = {100, 100, 100, 100, 100, 100};
// Parameters of sensors guarding the queues of the processing stations
const int nSensorQueue = 5; // number of sensors
const id_slot SENSOR_QUEUE_INDEXES[nSensorQueue] = {1, 22, 65, 80, 99}; // indexes of slots with a sensor
const int PS_SENSOR_QUEUE_TO_LISTEN[nPS] = {1, 3, 2, 4, 4, 0}; // sensor listened by each processing station
// Parameters of sensors guarding the entrances of the processing stations
const int nSensorPS = nPS; // number of sensors
const id_slot SENSOR_PS_INDEXES[nSensorPS] = {13, 33, 62, 69, 90, 102}; // indexes of slot with a sensor
const id_ps SENSOR_PS_LISTENED_PS[nSensorPS] = {0, 1, 2, 3, 4, 5}; // processing station listened by each sensor
/*** CHANNELS *********************************************************/
urgent chan freePS[nPS], // synchronize a processing station and the object exiting it
busyPS[nPS], // synchronize an object entering a processing station and the processing station
finishProcessing[nPS], // synchronize a processing station and the processed object object when the processing is finished
freeSlot[nSlots], // synchronize an object exiting a slot and the slot
busySlot[nSlots]; // synchronize an object entering a slot and the slot
broadcast chan shift; // synchronize the conveyor belt movement with all the others movements (i.e. changing slot, enter and exit a processing station)
/*** GLOABAL VARIABLES AND FUNCTIONS **********************************/
bool sensorPS[nPS]; // sensors guarding the entrances of the processing stations
bool sensorQueue[nSlots]; // sensors guarding the queues of the processing stations (we create a sensor for each slot because we use it for some verification tests)
/*
Return true if after the taken slot the is a slot, flase otherwise (i.e. there is a processing station)
*/
bool isNextSlot(id_slot slot) {
return !exists(i : id_ps) SLOTS_BEFORE_PS[i] == slot;
}
/*
Choose a direction at the crossroad
*/
bool branchSwitch = false; // randomly switched by the conveyor belt
int controller() {
if(branchSwitch) {
return 62;
}
return 77;
}
/*
Return the next slot of a slot
(If after slot there is a processing station the returned value is meaningless, check using isNextSlot)
(Modify this function to change the conveyor belt shape)
*/
id_slot nextSlot(id_slot slot) {
if(exists(i : id_ps) SLOTS_BEFORE_PS[i] == slot) // processing station
return 0; // meaningless value (should not be executed)
if(slot == 104) // end
return 0;
if(slot == 61) // crossroads
return controller();
if(slot == 76) // join
return 97;
return slot + 1;
}
/*
Return the next slot of a processing station
*/
id_slot nextSlotPS(id_ps ps) {
return SLOTS_AFTER_PS[ps];
}
/*
Return the next processing station of a slot
(If after slot there is another slot the returned value is meaningless, check using isNextSlot)
*/
id_ps nextPS(id_slot slot) {
int i = 0;
for(i = 0; i < nPS; i++)
if(SLOTS_BEFORE_PS[i] == slot)
return i;
return 0; // meaningless value (should not be executed)
}
</declaration>
<template>
<name>ConveyorBelt</name>
<parameter>int inverseSpeed</parameter>
<declaration>clock t = 0; // clock that controls the conveyor belt movement
/*
randomly cahnge the direction to take ad the crossroad
*/
void setBranchSwitch() {
branchSwitch = !branchSwitch;
}
</declaration>
<location id="id0" x="8" y="4">
<label kind="invariant" x="-10" y="17">t <= inverseSpeed</label>
</location>
<init ref="id0"/>
<transition id="id1">
<source ref="id0"/>
<target ref="id0"/>
<label kind="guard" x="-255" y="-42">t >= inverseSpeed</label>
<label kind="synchronisation" x="-255" y="-25">shift!</label>
<label kind="assignment" x="-255" y="-8">t = 0,
setBranchSwitch()</label>
<nail x="-110" y="76"/>
<nail x="-110" y="-76"/>
</transition>
</template>
<template>
<name>Object</name>
<parameter>const id_obj id</parameter>
<declaration>bool inSlot = false; // true if the object is in a slot
id_slot slot = 0; // id of the current slot
id_slot next = 0; // id of the next slot
bool inPS = false; // true if the object is in a processing station
id_ps ps = 0; // if of the current processing station</declaration>
<location id="id2" x="-3068" y="-2813">
<name x="-3128" y="-2805">slotted</name>
</location>
<location id="id3" x="-2720" y="-2813">
<committed/>
</location>
<location id="id4" x="-3629" y="-2813">
<name x="-3646" y="-2847">start</name>
</location>
<location id="id5" x="-3204" y="-3060">
<committed/>
</location>
<location id="id6" x="-2924" y="-3060">
<name x="-2934" y="-3094">readyChangingSlot</name>
</location>
<location id="id7" x="-2448" y="-2813">
<name x="-2482" y="-2847">readyEnterPS</name>
</location>
<location id="id8" x="-2125" y="-2813">
<name x="-2135" y="-2847">inProcessing</name>
</location>
<location id="id9" x="-2448" y="-2592">
<committed/>
</location>
<location id="id10" x="-2720" y="-2592">
<name x="-2771" y="-2575">readyEnterSlot</name>
</location>
<location id="id11" x="-3391" y="-2813">
<name x="-3434" y="-2847">readyEnterSystem</name>
</location>
<location id="id12" x="-2125" y="-2592">
<name x="-2125" y="-2575">endedProcessing</name>
</location>
<init ref="id4"/>
<transition id="id13">
<source ref="id8"/>
<target ref="id12"/>
<label kind="synchronisation" x="-2116" y="-2720">finishProcessing[ps]?</label>
</transition>
<transition id="id14">
<source ref="id12"/>
<target ref="id9"/>
<label kind="synchronisation" x="-2371" y="-2618">busySlot[nextSlotPS(ps)]!</label>
<label kind="assignment" x="-2371" y="-2584">next = nextSlotPS(ps)</label>
</transition>
<transition id="id15">
<source ref="id11"/>
<target ref="id2"/>
<label kind="synchronisation" x="-3264" y="-2839">shift?</label>
<label kind="assignment" x="-3264" y="-2813">slot = 0,
inSlot = true</label>
</transition>
<transition id="id16">
<source ref="id4"/>
<target ref="id11"/>
<label kind="synchronisation" x="-3553" y="-2839">busySlot[0]!</label>
</transition>
<transition id="id17">
<source ref="id10"/>
<target ref="id2"/>
<label kind="synchronisation" x="-3000" y="-2618">shift?</label>
<label kind="assignment" x="-3000" y="-2592">slot = next,
inPS = false,
inSlot= true</label>
<nail x="-3069" y="-2592"/>
</transition>
<transition id="id18">
<source ref="id9"/>
<target ref="id10"/>
<label kind="synchronisation" x="-2626" y="-2618">freePS[ps]?</label>
</transition>
<transition id="id19">
<source ref="id7"/>
<target ref="id8"/>
<label kind="synchronisation" x="-2346" y="-2839">shift?</label>
<label kind="assignment" x="-2363" y="-2813">ps = nextPS(slot),
inPS = true,
inSlot=false</label>
</transition>
<transition id="id20">
<source ref="id3"/>
<target ref="id7"/>
<label kind="synchronisation" x="-2652" y="-2839">freeSlot[slot]!</label>
</transition>
<transition id="id21">
<source ref="id6"/>
<target ref="id2"/>
<label kind="synchronisation" x="-2983" y="-2949">shift?</label>
<label kind="assignment" x="-2992" y="-2932">slot = next</label>
</transition>
<transition id="id22">
<source ref="id5"/>
<target ref="id6"/>
<label kind="synchronisation" x="-3119" y="-3085">freeSlot[slot]!</label>
</transition>
<transition id="id23">
<source ref="id2"/>
<target ref="id5"/>
<label kind="guard" x="-3306" y="-2991">isNextSlot(slot)</label>
<label kind="synchronisation" x="-3366" y="-2966">busySlot[nextSlot(slot)]!</label>
<label kind="assignment" x="-3349" y="-2941">next = nextSlot(slot)</label>
</transition>
<transition id="id24">
<source ref="id2"/>
<target ref="id3"/>
<label kind="guard" x="-2949" y="-2864">!isNextSlot(slot)</label>
<label kind="synchronisation" x="-2949" y="-2839">busyPS[nextPS(slot)]!</label>
</transition>
</template>
<template>
<name>Slot</name>
<parameter>const id_slot id</parameter>
<declaration>/*
return true if this slot has a sensor guarding the entrance of a processing station
*/
bool needsToListen(){
return exists(i : int[0, nSensorPS - 1]) SENSOR_PS_INDEXES[i] == id;
}
/*
Return the processing station's id this slot needs to guard the entrance
(If this slot has not a sensor guarding the entrance of a processing station the returned value is meaningless, check using needsToListen)
*/
id_ps psToListen(){
int i = 0;
for(i = 0; i < nSensorPS; i++)
if(SENSOR_PS_INDEXES[i] == id)
return SENSOR_PS_LISTENED_PS[i];
return 0; // meaningless value because slot do not have this type of sensor
}
bool hasSensorPS = needsToListen(); // true if this slot has a sensor guarding the entrance of a processing station
id_ps psListened = psToListen(); // processing station's id this slot needs to guard the entrance (if hasSensorPS is false, this value is meaningless)
</declaration>
<location id="id25" x="-901" y="-136">
<name x="-952" y="-144">free</name>
</location>
<location id="id26" x="127" y="-136">
<name x="152" y="-144">occupied</name>
</location>
<location id="id27" x="-416" y="-459">
<name x="-484" y="-493">readyToBeOccupied</name>
</location>
<location id="id28" x="-416" y="187">
<name x="-458" y="204">readyToBeFree</name>
</location>
<location id="id29" x="442" y="-136">
<committed/>
</location>
<init ref="id25"/>
<transition id="id30">
<source ref="id27"/>
<target ref="id26"/>
<label kind="guard" x="-187" y="-382">hasSensorPS</label>
<label kind="synchronisation" x="-187" y="-365">shift?</label>
<label kind="assignment" x="-187" y="-348">sensorPS[psListened] = true</label>
</transition>
<transition id="id31">
<source ref="id29"/>
<target ref="id26"/>
<label kind="assignment" x="212" y="-221">sensorQueue[id] = true</label>
<nail x="280" y="-204"/>
</transition>
<transition id="id32">
<source ref="id26"/>
<target ref="id29"/>
<label kind="synchronisation" x="263" y="-68">shift?</label>
<nail x="280" y="-68"/>
</transition>
<transition id="id33">
<source ref="id28"/>
<target ref="id27"/>
<label kind="guard" x="-595" y="-161">hasSensorPS imply
!sensorPS[psListened]</label>
<label kind="synchronisation" x="-527" y="-118">busySlot[id]?</label>
</transition>
<transition id="id34">
<source ref="id28"/>
<target ref="id25"/>
<label kind="synchronisation" x="-961" y="-68">shift?</label>
<nail x="-901" y="187"/>
</transition>
<transition id="id35">
<source ref="id26"/>
<target ref="id28"/>
<label kind="synchronisation" x="135" y="128">freeSlot[id]?</label>
<label kind="assignment" x="136" y="145">sensorQueue[id] = false</label>
<nail x="127" y="187"/>
</transition>
<transition id="id36">
<source ref="id27"/>
<target ref="id26"/>
<label kind="guard" x="-85" y="-501">!hasSensorPS</label>
<label kind="synchronisation" x="-76" y="-484">shift?</label>
<nail x="127" y="-459"/>
</transition>
<transition id="id37">
<source ref="id25"/>
<target ref="id27"/>
<label kind="guard" x="-1079" y="-416">hasSensorPS imply
!sensorPS[psListened]</label>
<label kind="synchronisation" x="-1079" y="-373">busySlot[id]?</label>
<nail x="-901" y="-459"/>
</transition>
</template>
<template>
<name x="5" y="5">ProcessingStation</name>
<parameter>const id_ps id</parameter>
<declaration>clock t; // clock used to count the passed processing time
int processingTime = PS_TIME[id]; // used to contain the needed time to process an object
id_slot sensorQueue_id = SENSOR_QUEUE_INDEXES[PS_SENSOR_QUEUE_TO_LISTEN[id]]; // sensor queue this processing station needs to listen
/*
Return true when the sensor queue it needs to listen is telling the the queue is full (or the sensor is in false positive)
*/
bool isNextQueueFull() {
return sensorQueue[sensorQueue_id];
}
</declaration>
<location id="id38" x="399" y="-68">
<name x="389" y="-102">free</name>
</location>
<location id="id39" x="399" y="255">
<name x="357" y="272">processingOrWaitingForSensor</name>
<label kind="invariant" x="357" y="289">t <= processingTime || isNextQueueFull()</label>
</location>
<location id="id40" x="-204" y="255">
<name x="-348" y="246">endedProcessing</name>
</location>
<location id="id41" x="-204" y="-68">
<name x="-272" y="-110">readyToBeFree</name>
</location>
<location id="id42" x="637" y="85">
<name x="627" y="51">readyToStartProcessing</name>
</location>
<location id="id43" x="93" y="255">
<committed/>
</location>
<init ref="id38"/>
<transition id="id44">
<source ref="id41"/>
<target ref="id42"/>
<label kind="synchronisation" x="144" y="17">busyPS[id]?</label>
</transition>
<transition id="id45">
<source ref="id39"/>
<target ref="id43"/>
<label kind="guard" x="161" y="212">t >= processingTime &&
!isNextQueueFull()</label>
</transition>
<transition id="id46">
<source ref="id43"/>
<target ref="id40"/>
<label kind="synchronisation" x="-127" y="229">finishProcessing[id]!</label>
</transition>
<transition id="id47">
<source ref="id42"/>
<target ref="id39"/>
<label kind="synchronisation" x="510" y="178">shift?</label>
<label kind="assignment" x="510" y="195">t = 0</label>
</transition>
<transition id="id48">
<source ref="id38"/>
<target ref="id42"/>
<label kind="synchronisation" x="510" y="-17">busyPS[id]?</label>
</transition>
<transition id="id49">
<source ref="id41"/>
<target ref="id38"/>
<label kind="synchronisation" x="76" y="-93">shift?</label>
</transition>
<transition id="id50">
<source ref="id40"/>
<target ref="id41"/>
<label kind="synchronisation" x="-297" y="68">freePS[id]!</label>
<label kind="assignment" x="-374" y="85">sensorPS[id] = false</label>
</transition>
</template>
<system>// Place template instantiations here.
conveyorBelt = ConveyorBelt(10);
// List one or more processes to be composed into a system.
system Slot, ProcessingStation, Object, conveyorBelt;
</system>
<queries>
<option key="--diagnostic" value="1"/>
<query>
<formula>A[] forall (id_0:id_obj) forall (id_1:id_obj) (id_0 != id_1 && Object(id_0).inPS && Object(id_1).inPS) imply Object(id_0).ps != Object(id_1).ps</formula>
<comment>1. it never happens that a station holds more than 1 piece;</comment>
<option key="--exploration" value="0"/>
<option key="--diagnostic" value="1"/>
<result outcome="success" type="quality" timestamp="2023-07-20 18:53:31 +0200">
<option key="--exploration" value="0"/>
<option key="--diagnostic" value="1"/>
</result>
</query>
<query>
<formula>A[] forall (id_0:id_obj) forall (id_1:id_obj) (id_0 != id_1 && Object(id_0).inSlot && Object(id_1).inSlot) imply Object(id_0).slot!=Object(id_1).slot</formula>
<comment>2. it never happens that two pieces occupy the same belt slot;</comment>
<option key="--exploration" value="0"/>
<option key="--diagnostic" value="1"/>
<result outcome="success" type="quality" timestamp="2023-07-20 18:53:45 +0200">
<option key="--exploration" value="0"/>
<option key="--diagnostic" value="1"/>
</result>
</query>
<query>
<formula>A[] !sensorQueue[SENSOR_QUEUE_INDEXES[0]-1] && !sensorQueue[SENSOR_QUEUE_INDEXES[1]-1] && !sensorQueue[SENSOR_QUEUE_INDEXES[2]-1] && !sensorQueue[SENSOR_QUEUE_INDEXES[3]-1] && !sensorQueue[ SENSOR_QUEUE_INDEXES[4]-1]</formula>
<comment>3. no queue ever exceeds the maximum allowed length;</comment>
<option key="--exploration" value="0"/>
<option key="--diagnostic" value="1"/>
<result outcome="success" type="quality" timestamp="2023-07-20 18:54:04 +0200">
<option key="--exploration" value="0"/>
<option key="--diagnostic" value="1"/>
</result>
</query>
<query>
<formula>A[] not deadlock</formula>
<comment>4. the plant never incurs in deadlock.</comment>
<option key="--exploration" value="0"/>
<option key="--diagnostic" value="1"/>
<result outcome="success" type="quality" timestamp="2023-07-20 18:54:34 +0200">
<option key="--exploration" value="0"/>
<option key="--diagnostic" value="1"/>
</result>
</query>
<query>
<formula>conveyorBelt.t == 0 --> conveyorBelt.t == inverseSpeed</formula>
<comment>The time flows (i.e. Zeno path free)</comment>
<result outcome="success" type="quality" timestamp="2023-07-20 18:55:35 +0200">
<option key="--diagnostic" value="1"/>
</result>
</query>
<query>
<formula>(Object(0).slot == 0 && Object(0).inSlot == true) --> (Object(0).slot == 104 && Object(0).inSlot == true)</formula>
<comment>4. the plant never incurs in deadlock excluding infinite loop (part 1)</comment>
<result outcome="success" type="quality" timestamp="2023-07-20 18:56:43 +0200">
<option key="--diagnostic" value="1"/>
</result>
</query>
<query>
<formula>(Object(0).slot == 104 && Object(0).inSlot == true) --> (Object(0).slot == 0 && Object(0).inSlot == true)</formula>
<comment>4. the plant never incurs in deadlock excluding infinite loop (part 2)</comment>
<result outcome="success" type="quality" timestamp="2023-07-20 18:56:56 +0200">
<option key="--diagnostic" value="1"/>
</result>
</query>
</queries>
</nta>