| 159 | | The result of this command is shown in Figure 4.2. The output indicates that a minimal counterexample has length 14, i.e., involves 15 states and 14 transitions (the depth of 19 is five more than 14). It was the 2nd and shortest trace found. It was deemed equivalent to the earlier traces and hence the earlier ones were discarded and only this one saved. We can replay the trace with the command |
| | 159 | which results in the output |
| | 160 | |
| | 161 | {{{ |
| | 162 | CIVL v1.18+ of 2018-12-28 -- http://vsl.cis.udel.edu/civl |
| | 163 | |
| | 164 | Violation 0 encountered at depth 21: |
| | 165 | CIVL execution violation (kind: DEADLOCK, certainty: PROVEABLE) |
| | 166 | at diningBad.cvl:20.32-32 |
| | 167 | $parfor(int i: 0..n-1) dine(i); |
| | 168 | ^ |
| | 169 | |
| | 170 | A deadlock is possible: |
| | 171 | Path condition: true |
| | 172 | Enabling predicate: false |
| | 173 | process p0 (id=0): false |
| | 174 | process p1 (id=1): false |
| | 175 | process p2 (id=2): false |
| | 176 | |
| | 177 | Call stacks: |
| | 178 | process 0: |
| | 179 | main at diningBad.cvl:20.32 ";" |
| | 180 | process 1: |
| | 181 | dine at diningBad.cvl:12.4-8 "$when" called from |
| | 182 | _par_proc0 at diningBad.cvl:20.25-28 "dine" |
| | 183 | process 2: |
| | 184 | dine at diningBad.cvl:12.4-8 "$when" called from |
| | 185 | _par_proc0 at diningBad.cvl:20.25-28 "dine" |
| | 186 | |
| | 187 | Logging new entry 0, writing trace to CIVLREP/diningBad_0.trace |
| | 188 | Restricting search depth to 20 |
| | 189 | |
| | 190 | Violation 1 encountered at depth 16: |
| | 191 | CIVL execution violation (kind: DEADLOCK, certainty: PROVEABLE) |
| | 192 | at diningBad.cvl:20.32-32 |
| | 193 | $parfor(int i: 0..n-1) dine(i); |
| | 194 | ^ |
| | 195 | |
| | 196 | A deadlock is possible: |
| | 197 | Path condition: true |
| | 198 | Enabling predicate: false |
| | 199 | process p0 (id=0): false |
| | 200 | process p1 (id=1): false |
| | 201 | process p2 (id=2): false |
| | 202 | |
| | 203 | Call stacks: |
| | 204 | process 0: |
| | 205 | main at diningBad.cvl:20.32 ";" |
| | 206 | process 1: |
| | 207 | dine at diningBad.cvl:12.4-8 "$when" called from |
| | 208 | _par_proc0 at diningBad.cvl:20.25-28 "dine" |
| | 209 | process 2: |
| | 210 | dine at diningBad.cvl:12.4-8 "$when" called from |
| | 211 | _par_proc0 at diningBad.cvl:20.25-28 "dine" |
| | 212 | |
| | 213 | New log entry is equivalent to previously encountered entry 0 |
| | 214 | Length of new trace (16) is less than length of old (21): replacing old with new... |
| | 215 | Restricting search depth to 15 |
| | 216 | |
| | 217 | === Source files === |
| | 218 | diningBad.cvl (diningBad.cvl) |
| | 219 | |
| | 220 | |
| | 221 | === Command === |
| | 222 | civl verify -inputB=5 -min diningBad.cvl |
| | 223 | |
| | 224 | === Stats === |
| | 225 | time (s) : 1.46 |
| | 226 | memory (bytes) : 163053568 |
| | 227 | max process count : 6 |
| | 228 | states : 96 |
| | 229 | states saved : 77 |
| | 230 | state matches : 2 |
| | 231 | transitions : 91 |
| | 232 | trace steps : 64 |
| | 233 | valid calls : 334 |
| | 234 | provers : cvc4, z3 |
| | 235 | prover calls : 4 |
| | 236 | |
| | 237 | === Result === |
| | 238 | The program MAY NOT be correct. See CIVLREP/diningBad_log.txt |
| | 239 | }}} |
| | 240 | |
| | 241 | The output indicates that a minimal counterexample consists of 16 execution steps. It was the second and shortest trace found. It was deemed equivalent to the earlier traces and hence the earlier ones were discarded and only this one saved. We can replay the trace with the command |
| 165 | | The result of this command is shown in Figure 4.3. The output indicates that a deadlock has been found involving 2 philosophers. The trace has 15 transitions; after the initialization sequence, each philosopher picks up her left fork. |
| | 247 | which results in the output |
| | 248 | |
| | 249 | {{{ |
| | 250 | CIVL v1.18+ of 2018-12-28 -- http://vsl.cis.udel.edu/civl |
| | 251 | |
| | 252 | Initial state: |
| | 253 | |
| | 254 | State (id=9) |
| | 255 | | Path condition |
| | 256 | | | true |
| | 257 | | Dynamic scopes |
| | 258 | | | dyscope d0 (parent=NULL, static=1) |
| | 259 | | | | variables |
| | 260 | | | | | B = NULL |
| | 261 | | | | | n = NULL |
| | 262 | | | | | forks = NULL |
| | 263 | | Process states |
| | 264 | | | process 0 |
| | 265 | | | | call stack |
| | 266 | | | | | Frame[function=main, location=0, diningBad.cvl:1.15 "4", dyscope=d0] |
| | 267 | |
| | 268 | Executed by p0 from State (id=9) |
| | 269 | 0->1: B=5 at diningBad.cvl:1.0-15 "$input int B = 4" |
| | 270 | 1->2: n=InitialValue(n) [n:=X_n] at diningBad.cvl:2.0-11 "$input int n" |
| | 271 | 2->3: $assume((2<=X_n)&&(X_n<=5)) at diningBad.cvl:3.0-20 "$assume(2<=n && n ... )" |
| | 272 | 3->4: forks=InitialValue(forks) [forks:=(boolean[X_n]) ($lambda i: int. false)] at diningBad.cvl:5.0-13 "_Bool forks[n]" |
| | 273 | --> State (id=18) |
| | 274 | |
| | 275 | Step 1: Executed by p0 from State (id=18) |
| | 276 | 4->5: $elaborate_domain(($domain(1))(0..X_n-1#1)) [$assume(0==(X_n - 2))] at diningBad.cvl:19.14-19 "0..n-1" |
| | 277 | --> State (id=22) |
| | 278 | |
| | 279 | Step 2: Executed by p0 from State (id=22) |
| | 280 | 5->6: LOOP_BODY_ENTER (guard: ($domain(1))(0..1#1) has next for (NULL)) at diningBad.cvl:19.14-19 "0..n-1" |
| | 281 | 6->7: NEXT of (NULL) in ($domain(1))(0..1#1) [i:=0] at diningBad.cvl:19.2-5 "$for" |
| | 282 | --> State (id=26) |
| | 283 | |
| | 284 | Step 3: Executed by p0 from State (id=26) |
| | 285 | 7->5: forks[0]=true at diningBad.cvl:19.22-civlc.cvh:10.14 "forks[i] = 1" |
| | 286 | --> State (id=29) |
| | 287 | |
| | 288 | Step 4: Executed by p0 from State (id=29) |
| | 289 | 5->6: LOOP_BODY_ENTER (guard: ($domain(1))(0..1#1) has next for (0)) at diningBad.cvl:19.14-19 "0..n-1" |
| | 290 | 6->7: NEXT of (0) in ($domain(1))(0..1#1) [i:=1] at diningBad.cvl:19.2-5 "$for" |
| | 291 | --> State (id=33) |
| | 292 | |
| | 293 | Step 5: Executed by p0 from State (id=33) |
| | 294 | 7->5: forks[1]=true at diningBad.cvl:19.22-civlc.cvh:10.14 "forks[i] = 1" |
| | 295 | --> State (id=36) |
| | 296 | |
| | 297 | Step 6: Executed by p0 from State (id=36) |
| | 298 | 5->8: LOOP_BODY_EXIT (guard: !($domain(1))(0..1#1) has next for (1)) at diningBad.cvl:19.14-19 "0..n-1" |
| | 299 | --> State (id=38) |
| | 300 | |
| | 301 | Step 7: Executed by p0 from State (id=38) |
| | 302 | 8->9: $elaborate_domain(($domain(1))(0..1#1)) [$assume(true)] at diningBad.cvl:20.17-22 "0..n-1" |
| | 303 | 9->10: $parfor(i0: ($domain(1))(0..1#1)) $spawn _par_proc0(i0) at diningBad.cvl:20.2-8 "$parfor" |
| | 304 | 10->11: _civl_ir1=0 at diningBad.cvl:20.32 ";" |
| | 305 | --> State (id=52) |
| | 306 | |
| | 307 | Step 8: Executed by p0 from State (id=52) |
| | 308 | 11->12: LOOP_BODY_ENTER (guard: 0<2) at diningBad.cvl:20.32 ";" |
| | 309 | --> State (id=54) |
| | 310 | |
| | 311 | Step 9: Executed by p1 from State (id=54) |
| | 312 | 23->15: dine(0) at diningBad.cvl:20.25-31 "dine(i)" |
| | 313 | 15->16: left=0 at diningBad.cvl:8.2-14 "int left = id" |
| | 314 | 16->17: right=(0+1)%2 [right:=1] at diningBad.cvl:9.2-25 "int right = (id ... n" |
| | 315 | --> State (id=61) |
| | 316 | |
| | 317 | Step 10: Executed by p1 from State (id=61) |
| | 318 | 17->18: LOOP_BODY_ENTER (guard: 1!=0) at diningBad.cvl:10.9 "1" |
| | 319 | --> State (id=63) |
| | 320 | |
| | 321 | Step 11: Executed by p2 from State (id=63) |
| | 322 | 23->15: dine(1) at diningBad.cvl:20.25-31 "dine(i)" |
| | 323 | 15->16: left=1 at diningBad.cvl:8.2-14 "int left = id" |
| | 324 | 16->17: right=(1+1)%2 [right:=0] at diningBad.cvl:9.2-25 "int right = (id ... n" |
| | 325 | --> State (id=70) |
| | 326 | |
| | 327 | Step 12: Executed by p2 from State (id=70) |
| | 328 | 17->18: LOOP_BODY_ENTER (guard: 1!=0) at diningBad.cvl:10.9 "1" |
| | 329 | --> State (id=72) |
| | 330 | |
| | 331 | Step 13: Executed by p1 from State (id=72) |
| | 332 | 18->19: forks[0]=false at diningBad.cvl:11.24-civlc.cvh:12.15 "forks[left] = 0" |
| | 333 | --> State (id=75) |
| | 334 | |
| | 335 | Step 14: Executed by p2 from State (id=75) |
| | 336 | 18->19: forks[1]=false at diningBad.cvl:11.24-civlc.cvh:12.15 "forks[left] = 0" |
| | 337 | --> State (id=78) |
| | 338 | |
| | 339 | Step 15: |
| | 340 | State (id=78) |
| | 341 | | Path condition |
| | 342 | | | true |
| | 343 | | Dynamic scopes |
| | 344 | | | dyscope d0 (parent=NULL, static=1) |
| | 345 | | | | variables |
| | 346 | | | | | B = 5 |
| | 347 | | | | | n = 2 |
| | 348 | | | | | forks = {[0]=false, [1]=false} |
| | 349 | | | dyscope d1 (parent=d0, static=4) |
| | 350 | | | | variables |
| | 351 | | | | | i = 1 |
| | 352 | | | | | __LiteralDomain_counter0__ = NULL |
| | 353 | | | dyscope d2 (parent=d0, static=7) |
| | 354 | | | | variables |
| | 355 | | | | | _dom_size0 = 2 |
| | 356 | | | | | _par_procs0 = {[0]=p1, [1]=p2} |
| | 357 | | | dyscope d3 (parent=d0, static=8) |
| | 358 | | | | variables |
| | 359 | | | | | i = 0 |
| | 360 | | | dyscope d4 (parent=d0, static=8) |
| | 361 | | | | variables |
| | 362 | | | | | i = 1 |
| | 363 | | | dyscope d5 (parent=d2, static=9) |
| | 364 | | | | variables |
| | 365 | | | | | _civl_ir1 = 0 |
| | 366 | | | dyscope d6 (parent=d5, static=10) |
| | 367 | | | | variables |
| | 368 | | | dyscope d7 (parent=d0, static=3) |
| | 369 | | | | variables |
| | 370 | | | | | id = 0 |
| | 371 | | | dyscope d8 (parent=d7, static=12) |
| | 372 | | | | variables |
| | 373 | | | | | left = 0 |
| | 374 | | | | | right = 1 |
| | 375 | | | dyscope d9 (parent=d0, static=3) |
| | 376 | | | | variables |
| | 377 | | | | | id = 1 |
| | 378 | | | dyscope d10 (parent=d9, static=12) |
| | 379 | | | | variables |
| | 380 | | | | | left = 1 |
| | 381 | | | | | right = 0 |
| | 382 | | Process states |
| | 383 | | | process 0 |
| | 384 | | | | call stack |
| | 385 | | | | | Frame[function=main, location=12, diningBad.cvl:20.32 ";", dyscope=d6] |
| | 386 | | | process 1 |
| | 387 | | | | call stack |
| | 388 | | | | | Frame[function=dine, location=19, diningBad.cvl:12.4-8 "$when", dyscope=d8] |
| | 389 | | | | | Frame[function=_par_proc0, location=23, diningBad.cvl:20.25-28 "dine", dyscope=d3] |
| | 390 | | | process 2 |
| | 391 | | | | call stack |
| | 392 | | | | | Frame[function=dine, location=19, diningBad.cvl:12.4-8 "$when", dyscope=d10] |
| | 393 | | | | | Frame[function=_par_proc0, location=23, diningBad.cvl:20.25-28 "dine", dyscope=d4] |
| | 394 | |
| | 395 | Violation of Deadlock found in (id=78): |
| | 396 | A deadlock is possible: |
| | 397 | Path condition: true |
| | 398 | Enabling predicate: false |
| | 399 | process p0 (id=0): false |
| | 400 | process p1 (id=1): false |
| | 401 | process p2 (id=2): false |
| | 402 | |
| | 403 | Trace ends after 15 trace steps. |
| | 404 | Violation(s) found. |
| | 405 | |
| | 406 | === Source files === |
| | 407 | diningBad.cvl (diningBad.cvl) |
| | 408 | |
| | 409 | |
| | 410 | === Command === |
| | 411 | civl replay -showTransitions diningBad.cvl |
| | 412 | |
| | 413 | === Stats === |
| | 414 | time (s) : 1.44 |
| | 415 | memory (bytes) : 163053568 |
| | 416 | max process count : 3 |
| | 417 | states : 27 |
| | 418 | valid calls : 100 |
| | 419 | provers : cvc4, z3 |
| | 420 | prover calls : 4 |
| | 421 | }}} |
| | 422 | |
| | 423 | The output indicates that a deadlock has been found involving 2 philosophers. After the initialization sequence, each philosopher picks up her left fork. |