620 lines
19 KiB
Org Mode
620 lines
19 KiB
Org Mode
# SCHELETRO:
|
||
|
||
# * Algoritmo 3.5
|
||
# Due processi iterano all'infinito seguendo questo pseudocodice
|
||
|
||
# #+BEGIN_SRC
|
||
# #+END_SRC
|
||
|
||
# ** NuSMV
|
||
# Si e` deciso di modellare l'algoritmo usando per ognuno dei due
|
||
# processi ...
|
||
# | CODE
|
||
# #+include 3.2.b.smv
|
||
|
||
# ** GreatSPN
|
||
# ** TODO CCS
|
||
# ** Risultati
|
||
Nella tabella mostriamo i risultati ottenuti
|
||
| | NuSMV | GreatSPN |
|
||
|---------------------+-------+----------|
|
||
| Mutua Esclusione | | |
|
||
| Assenza di deadlock | | |
|
||
| No Starvation | | |
|
||
* TODO [1/7]
|
||
- [X] Cosa significa FAIRNESS running alla fine dei .smv
|
||
- [ ] Riformula liveness
|
||
- [ ] chiedi a lei di safety, liveness, fairness
|
||
- [ ] Vedi necessita` di Sync e /
|
||
- [ ] Finisci tutto con algebra dei processi
|
||
- [ ] Reachability graph vs Derivation Graph
|
||
- [ ] Controlla in 3.6 Starvation: nusmv no, greatspn si`
|
||
- [ ] 3.6, dealock: correttezza spiegazione della differenza greatspn nusmv?
|
||
- [ ] 3.6, starvation: perche` nusmv con processi non ha starvation?
|
||
- [ ] 3.6, Amparore ha detto che deadlock: AG(EF(#critical_P == 1)) ??
|
||
- [ ] 3.6, inserisci controesempi dove necessario
|
||
|
||
NOTA: nel caso di Ampararore, la formula:
|
||
| da qualsiasi stato e` sempre possibile arrivare a critical_P == 1
|
||
|
||
* TODO Proprieta` del modello
|
||
|
||
Ogni modello successivamente mostrato rispetta le seguenti proprieta`:
|
||
Siano /p/ e /q/ due generici processi,
|
||
1. Mutua esclusione (safety): garantisce che al piu` un solo processo e` nella
|
||
sezione critica ad ogni istante
|
||
| G (¬cₚ∨¬c_{q})
|
||
2. Assenza di deadlock (liveness): ogni qualvolta un processo e` in
|
||
attesa di entrare nella sezione critica, eventualmente verra`
|
||
concesso ad un processo di entrare nella sezione critica
|
||
| G(wₚ → F(cₚ∨c_{q})
|
||
3. Assenza di starvation individuale (strong fairness): ogni qualvolta un processo e` in
|
||
attesa di entrare nella sezione critica, eventualmente gli verra` concesso
|
||
| G(wₚ → Fcₚ)
|
||
Possiamo convertire queste tre formule LTL in formule equivalenti CTL
|
||
anteponendo l'operatore di stato A:
|
||
| AG (¬cₚ∨¬c_{q})
|
||
| AG(wₚ → AF(cₚ∨c_{q})
|
||
| AG(wₚ → AFcₚ)
|
||
Benche` non tutte le formule LTL possono essere convertite in una
|
||
formula CTL equivalente anteponendo ad ogni operatore temporale
|
||
l'operatore di stato A, per queste tre proprieta` possiamo.
|
||
|
||
* Algoritmo 3.2
|
||
Due processi iterano all'infinito seguendo questo pseudocodice
|
||
|
||
#+BEGIN_SRC
|
||
while true:
|
||
non-critical section
|
||
await turn = ID
|
||
critical section
|
||
turn <- (ID%2)+1
|
||
#+END_SRC
|
||
|
||
** NuSMV
|
||
Si e` deciso di modellare l'algoritmo usando per ognuno dei due
|
||
processi un'enumerazione di 4 stati ed una variabile turno di tipo intero.
|
||
| state: {begin, wait, critical, done};
|
||
#+include 3.2.b.smv
|
||
** GreatSPN
|
||
Il codice utilizzato per le proprieta` CTL e` il seguente:
|
||
#+BEGIN_SRC
|
||
AG(!(#Critical_P == 1) || !(#Critical_Q == 1)) = true
|
||
AG ((#Wait_P==1 || \#Wait_Q == 1) -> AF (#Critical_P == 1 || \#Critical_Q == 1)) = false
|
||
AG (#Wait_P==1 -> AF (#Critical_P == 1)) = false
|
||
#+END_SRC
|
||
[[./3.2.jpg]]
|
||
** TODO CCS
|
||
** Risultati
|
||
Nella tabella mostriamo i risultati ottenuti
|
||
| | NuSMV | GreatSPN |
|
||
|---------------------+-------+----------|
|
||
| Mutua Esclusione | True | True |
|
||
| Assenza di deadlock | False | False |
|
||
| No Starvation | False | False |
|
||
Il risultato della possibilita` di deadlock non deve
|
||
stupire: la specifica non obbliga un processo a terminare la fase
|
||
begin.
|
||
Ne segue che anche l'assenza di starvation individuale non e`
|
||
garantita.
|
||
NuSMV conferma quanto detto mostrandoci un trace che fa da
|
||
controesempio alla formula CTL:
|
||
#+BEGIN_SRC
|
||
-- specification AG ((p.state = wait | q.state = wait) -> AF (p.state = critical | q.state = critical)) is false
|
||
-- as demonstrated by the following execution sequence
|
||
Trace Description: CTL Counterexample
|
||
Trace Type: Counterexample
|
||
-> State: 1.1 <-
|
||
turn = 1
|
||
p.state = begin
|
||
q.state = begin
|
||
-- Loop starts here
|
||
-> State: 1.2 <-
|
||
q.state = wait
|
||
-> State: 1.3 <-
|
||
#+END_SRC
|
||
Si vede che il processo q rimane nella fase begin e p, dopo essere
|
||
entrato nella regione critica una volta, rimane bloccato in begin.
|
||
Lo stesso trace mostra la possibilita` di starvation del processo.
|
||
La rete modellata con GreatSPN ci conferma quanto visto con NuSMV.
|
||
|
||
Prendiamo in considerazione la seguente formula CTL
|
||
| AG (wₚ -> EF cₚ)
|
||
Sia GreatSPN che NuSMV ci mostrano che il sistema modellato rispetta
|
||
questa proprieta`. Questo significa che un processo in attesa di
|
||
entrare nella sezione critica ha la possibilita` di compiere
|
||
progresso, ma solo nel caso in cui, come si intuisce dal controesempio
|
||
precedente, l'altro processo decida di entrare in attesa a sua volta.
|
||
|
||
* Algoritmo 3.5
|
||
Due processi iterano all'infinito seguendo questo pseudocodice
|
||
|
||
#+BEGIN_SRC
|
||
while true:
|
||
await turn = ID
|
||
turn <- (ID%2)+1
|
||
#+END_SRC
|
||
|
||
** NuSMV
|
||
Si e` deciso di modellare l'algoritmo usando per ognuno dei due
|
||
processi un'enumerazione di due stati e un contatore di turni intero
|
||
| state: {await, done};
|
||
#+include 3.5.b.smv
|
||
|
||
** GreatSPN
|
||
Il codice utilizzato per le proprieta` CTL e` il seguente:
|
||
#+BEGIN_SRC
|
||
AG(!(#Await_P == 1) || !(#Await_Q == 1)) = true
|
||
AG ((#Wait_P==1 || \#AWait_Q == 1) -> AF (#Done_P == 1 || \#Done_Q == 1)) = false
|
||
AG (#Await_P==1 -> AF (#Done_P == 1)) = false
|
||
#+END_SRC
|
||
[[./3.5.jpg]]
|
||
** TODO CCS
|
||
** Risultati
|
||
Nella tabella mostriamo i risultati ottenuti
|
||
| | NuSMV | GreatSPN |
|
||
|---------------------+-------+----------|
|
||
| Mutua Esclusione | true | true |
|
||
| Assenza di deadlock | false | false |
|
||
| No Starvation | false | false |
|
||
I risultati confermano il fatto che questo algoritmo e` solamente una
|
||
versione semplificata del precedente (/begin/ e /wait/ sono stati fusi
|
||
in await e /done/ rimosso) e pertanto il trace di controesempio
|
||
fornito da NuSMV e da GreatSPN presentano riflettono i risultati di
|
||
questa semplificazione.
|
||
- Possibilita` di deadlock:
|
||
#+BEGIN_SRC
|
||
– specification AG ((p.state = await | q.state = await) -> AF (p.state = done | q.state = done)) is false
|
||
– as demonstrated by the following execution sequence
|
||
Trace Description: CTL Counterexample
|
||
Trace Type: Counterexample
|
||
– Loop starts here
|
||
-> State: 1.1 <-
|
||
turn = 1
|
||
p.state = await
|
||
q.state = await
|
||
-> State: 1.2 <-
|
||
#+END_SRC
|
||
- Possibilita` di starvation: i processi non compiono progresso
|
||
iterando infinite volte su /await/.
|
||
#+BEGIN_SRC
|
||
– specification AG (p.state = await -> AF p.state = done) is false
|
||
– as demonstrated by the following execution sequence
|
||
Trace Description: CTL Counterexample
|
||
Trace Type: Counterexample
|
||
– Loop starts here
|
||
-> State: 2.1 <-
|
||
turn = 1
|
||
p.state = await
|
||
q.state = await
|
||
-> State: 2.2 <-
|
||
#+END_SRC
|
||
#+BEGIN_SRC
|
||
– specification AG (q.state = await -> AF q.state = done) is false
|
||
– as demonstrated by the following execution sequence
|
||
Trace Description: CTL Counterexample
|
||
Trace Type: Counterexample
|
||
– Loop starts here
|
||
-> State: 3.1 <-
|
||
turn = 1
|
||
p.state = await
|
||
q.state = await
|
||
-> State: 3.2 <-
|
||
– specification AG (q.state = await -> EF q.state = done) is true
|
||
#+END_SRC
|
||
- Possibilita` di compiere progresso:
|
||
#+BEGIN_SRC
|
||
specification AG (q.state = await -> EF q.state = done) is true
|
||
#+END_SRC
|
||
|
||
* Algoritmo 3.6
|
||
Due processi iterano all'infinito seguendo questo pseudocodice
|
||
#+BEGIN_SRC
|
||
while true:
|
||
non-critical section
|
||
await wantQ = false
|
||
wantP <- true
|
||
critical section
|
||
wantP <- false
|
||
#+END_SRC
|
||
|
||
** NuSMV
|
||
Si e` deciso di modellare l'algoritmo usando per ognuno dei due
|
||
processi usando 5 stati per ogni processo
|
||
| state: {local, await, critical, setTrue, setFalse};
|
||
#+include 3.6.smv
|
||
|
||
** GreatSPN
|
||
Il codice utilizzato per le proprieta` CTL e` il seguente:
|
||
#+BEGIN_SRC
|
||
AG(!(#critical_P == 1) || !(#critical_Q == 1))
|
||
AG ((#await_P==1 || \#await_Q == 1) -> AF (#critical_P == 1 || \#critical_Q == 1))
|
||
AG (#await_P==1 -> AF (#critical_P == 1))
|
||
#+END_SRC
|
||
[[./3.6.jpg]]
|
||
|
||
** TODO CCS
|
||
** TODO Risultati
|
||
Nella tabella mostriamo i risultati ottenuti
|
||
| | NuSMV | GreatSPN |
|
||
|---------------------+-------+----------|
|
||
| Mutua Esclusione | false | false |
|
||
| Assenza di deadlock | true | false |
|
||
| No Starvation | true | false |
|
||
|
||
L'incoerenza del risultato dell'assenza di deadlock e` spiegabile dal
|
||
fatto che nel caso di NuSMV non e` possibile che un processo rimanga
|
||
nel primo stato (/local/) per un tempo indefinito mentre nel caso di
|
||
GreatSPN e` possibile che il processo P vada nello spazio await e il
|
||
processo Q decida di rimanere nel loop /local_Q/ all'infinito.
|
||
Notiamo che se forziamo i processi a fare del progresso dallo stato
|
||
/local/, allora la formula CTL
|
||
| G(wₚ → F(cₚ∨c_{q})
|
||
risulta rispettata.
|
||
Ancora meglio, piuttosto che rimuovere una transizione possibile,
|
||
possiamo restringere la verifica dell'assenza di deadlock alla
|
||
seguente formula CTL
|
||
| AG (wₚ → EF (cₚ || c_{q}))
|
||
| AG(#await_P == 1 -> EF(#critical_Q==1 || \#critical_P == 1))
|
||
che risulta rispettata.
|
||
* Algoritmo 3.8
|
||
Due processi iterano all'infinito seguendo questo pseudocodice
|
||
|
||
#+BEGIN_SRC
|
||
while true:
|
||
non-critical section
|
||
wantP <- true
|
||
await wantQ = false
|
||
critical section
|
||
wantP <- false
|
||
#+END_SRC
|
||
|
||
** NuSMV
|
||
Si e` deciso di modellare l'algoritmo allo stesso modo del precedente.
|
||
#+include 3.8.b.smv
|
||
** GreatSPN
|
||
Il codice utilizzato per le proprieta` CTL e` il seguente:
|
||
#+BEGIN_SRC
|
||
AG(!(#critical_P == 1) || !(#critical_Q == 1))
|
||
AG ((#await_P==1 || \#await_Q == 1) -> AF (#critical_P == 1 || \#critical_Q == 1))
|
||
AG (#await_P==1 -> AF (#critical_P == 1))
|
||
AG (#await_Q==1 -> AF (#critical_Q == 1))
|
||
#+END_SRC
|
||
Inoltre, per confermare alcune ipotesi, si e` testata anche la
|
||
seguente formula CTL:
|
||
| AG(#await_P == 1 -> EF(#critical_Q==1 || \#critical_P == 1))
|
||
che conferma la presenza di deadlock causata dalle due variabili booleane.
|
||
[[./3.8.jpg]]
|
||
** TODO CCS
|
||
** Risultati
|
||
Nella tabella mostriamo i risultati ottenuti
|
||
| | NuSMV | GreatSPN |
|
||
|---------------------+-------+----------|
|
||
| Mutua Esclusione | True | True |
|
||
| Assenza di deadlock | False | False |
|
||
| No Starvation | False | False |
|
||
Questo algoritmo rispetto al precedente garantisce la mutua
|
||
esclusione, ma non ci permette di evitare il deadlock (e di
|
||
conseguenza neanche la starvation individuale).
|
||
|
||
Di seguito riportiamo la traccia di NuSMV che mostra che il deadlock
|
||
avviene quando i progetti eseguono /setTrue/ nello stesso momento.
|
||
#+BEGIN_SRC
|
||
-- specification AG ((p.state = await | q.state = await) -> AF (p.state = critical | q.state = critical)) is false
|
||
-- as demonstrated by the following execution sequence
|
||
Trace Description: CTL Counterexample
|
||
Trace Type: Counterexample
|
||
-> State: 1.1 <-
|
||
wantP = FALSE
|
||
wantQ = FALSE
|
||
p.state = local
|
||
q.state = local
|
||
-> State: 1.2 <-
|
||
p.state = setTrue
|
||
q.state = setTrue
|
||
-- Loop starts here
|
||
-> State: 1.3 <-
|
||
wantP = TRUE
|
||
wantQ = TRUE
|
||
p.state = await
|
||
q.state = await
|
||
-> State: 1.4 <-
|
||
#+END_SRC
|
||
Mostriamo invece il controesempio generato da GreatSPN che ci mostra
|
||
una condizione di starvation individuale, dove, come in precedenza, il
|
||
processo Q rimane in /local_Q/.
|
||
#+BEGIN_SRC
|
||
Generated counter-example:
|
||
==================================== Trace ====================================
|
||
Initial state is: local_P(1), wantP_FALSE(1), wantQ_FALSE(1), local_Q(1)
|
||
Initial state satisfies: E F (not ((not (await_P = 1)) or (not E G (not (critical_P = 1))))).
|
||
|
||
1: local_P(1), wantP_FALSE(1), wantQ_FALSE(1), local_Q(1)
|
||
State 1. satisfies: ((not (await_P = 1)) or (not E G (not (critical_P = 1)))).
|
||
|
||
1.1: local_P(1), wantP_FALSE(1), wantQ_FALSE(1), local_Q(1)
|
||
State 1.1. does not satisfy: (await_P = 1).
|
||
|
||
2: SetTrue_P(1), wantP_FALSE(1), wantQ_FALSE(1), local_Q(1)
|
||
State 2. satisfies: ((not (await_P = 1)) or (not E G (not (critical_P = 1)))).
|
||
|
||
2.1: SetTrue_P(1), wantP_FALSE(1), wantQ_FALSE(1), local_Q(1)
|
||
State 2.1. does not satisfy: (await_P = 1).
|
||
|
||
3: wantP_TRUE(1), await_P(1), wantQ_FALSE(1), local_Q(1)
|
||
State 3. does not satisfy: ((not (await_P = 1)) or (not E G (not (critical_P = 1)))).
|
||
|
||
3.1: wantP_TRUE(1), await_P(1), wantQ_FALSE(1), local_Q(1)
|
||
State 3.1.L. satisfies: (await_P = 1).
|
||
|
||
State 3.1.R. satisfies: E G (not (critical_P = 1)). Start of loop.
|
||
|
||
3.1.R.1: wantP_TRUE(1), await_P(1), wantQ_FALSE(1), local_Q(1)
|
||
State 3.1.R.1. does not satisfy: (critical_P = 1).
|
||
|
||
3.1.R.2: loop back to state 3.1.R.1.
|
||
#+END_SRC
|
||
|
||
* Algoritmo 3.9
|
||
Due processi iterano all'infinito seguendo questo pseudocodice
|
||
|
||
#+BEGIN_SRC
|
||
while true:
|
||
non-critical section
|
||
wantP <- true
|
||
while wantQ
|
||
wantP <- false
|
||
wantP <- true
|
||
critical section
|
||
wantP <- false
|
||
#+END_SRC
|
||
(l'altro processo segue uno pseudocodice simmetrico)
|
||
|
||
** NuSMV
|
||
Si e` deciso di modellare l'algoritmo usando per ognuno dei due
|
||
processi utilizzando l'espressione /process/ per simulare di NuSMV e
|
||
per ciascun process una variabile /state/ di tipo enumerazione
|
||
| state: {local, critical, setTrue, setFalse, resetTrue, resetFalse};
|
||
Benche` non fosse necessario distinguere il set della variabile
|
||
booleana /wantP/, si e` preferito farlo in quanto l'enumerazione di
|
||
tutti gli stati possibili, come evidenziato dal codice che segue, non
|
||
risulta complesso.
|
||
#+include 3.9.smv
|
||
|
||
** GreatSPN
|
||
Il codice utilizzato per le proprieta` CTL e` il seguente:
|
||
#+BEGIN_SRC
|
||
AG(!(#critical_P == 1) || !(#critical_Q == 1))
|
||
AG ((#setTrue_P==1 || \#setTrue_Q == 1) -> AF (#critical_P == 1 || \#critical_Q == 1))
|
||
AG (#setTrue_P==1 -> AF (#critical_P == 1))
|
||
AG (#setTrue_Q==1 -> AF (#critical_Q == 1))
|
||
#+END_SRC
|
||
Inoltre, per confermare alcune ipotesi, si e` testata anche la
|
||
seguente formula CTL:
|
||
| AG(#setTrue_P == 1 -> EF(#critical_Q==1 || \#critical_P == 1))
|
||
che conferma la presenza di deadlock causata dalle due variabili
|
||
booleane.
|
||
[[./3.9.jpg]]
|
||
** TODO CCS
|
||
** Risultati
|
||
Nella tabella mostriamo i risultati ottenuti
|
||
| | NuSMV | GreatSPN |
|
||
|---------------------+-------+----------|
|
||
| Mutua Esclusione | true | true |
|
||
| Assenza di deadlock | false | false |
|
||
| No Starvation | false | false |
|
||
|
||
Il deadlock si verifica quando i entrambe le variabili booleane sono
|
||
uguali a /true/.
|
||
Ad esempio, se si esegue in locksetop il loop con la
|
||
condizione booleana sulla variabile dell'altro processo, si verifica
|
||
la condizione di deadlock.
|
||
Viene riportato il trace di NuSMV che conferma questa ipotesi.
|
||
GreatSPN fallisce per mancanza di RAM sulla macchina usata ma e`
|
||
facile riprodurre il deadlock manualmente.
|
||
#+BEGIN_SRC
|
||
-- specification AG ((p.state = setTrue | q.state = setTrue) -> AF (p.state = critical | q.state = critical)) is false
|
||
-- as demonstrated by the following execution sequence
|
||
Trace Description: CTL Counterexample
|
||
Trace Type: Counterexample
|
||
-> State: 1.1 <-
|
||
wantP = FALSE
|
||
wantQ = FALSE
|
||
p.state = local
|
||
q.state = local
|
||
-> Input: 1.2 <-
|
||
_process_selector_ = p
|
||
running = FALSE
|
||
q.running = FALSE
|
||
p.running = TRUE
|
||
-> State: 1.2 <-
|
||
p.state = setTrue
|
||
-> Input: 1.3 <-
|
||
-> State: 1.3 <-
|
||
wantP = TRUE
|
||
p.state = critical
|
||
-> Input: 1.4 <-
|
||
-> State: 1.4 <-
|
||
p.state = setFalse
|
||
-> Input: 1.5 <-
|
||
_process_selector_ = q
|
||
q.running = TRUE
|
||
p.running = FALSE
|
||
-> State: 1.5 <-
|
||
q.state = setTrue
|
||
-> Input: 1.6 <-
|
||
-> State: 1.6 <-
|
||
wantQ = TRUE
|
||
q.state = resetFalse
|
||
-> Input: 1.7 <-
|
||
_process_selector_ = p
|
||
q.running = FALSE
|
||
p.running = TRUE
|
||
-> State: 1.7 <-
|
||
wantP = FALSE
|
||
p.state = local
|
||
-> Input: 1.8 <-
|
||
-> State: 1.8 <-
|
||
p.state = setTrue
|
||
-> Input: 1.9 <-
|
||
-- Loop starts here
|
||
-> State: 1.9 <-
|
||
wantP = TRUE
|
||
p.state = resetFalse
|
||
-> Input: 1.10 <-
|
||
_process_selector_ = q
|
||
q.running = TRUE
|
||
p.running = FALSE
|
||
-> State: 1.10 <-
|
||
wantQ = FALSE
|
||
q.state = resetTrue
|
||
-> Input: 1.11 <-
|
||
-- Loop starts here
|
||
-> State: 1.11 <-
|
||
wantQ = TRUE
|
||
q.state = resetFalse
|
||
-> Input: 1.12 <-
|
||
_process_selector_ = p
|
||
q.running = FALSE
|
||
p.running = TRUE
|
||
-> State: 1.12 <-
|
||
wantP = FALSE
|
||
p.state = resetTrue
|
||
-> Input: 1.13 <-
|
||
-- Loop starts here
|
||
-> State: 1.13 <-
|
||
wantP = TRUE
|
||
p.state = resetFalse
|
||
-> Input: 1.14 <-
|
||
_process_selector_ = q
|
||
q.running = TRUE
|
||
p.running = FALSE
|
||
-> State: 1.14 <-
|
||
wantQ = FALSE
|
||
q.state = resetTrue
|
||
-> Input: 1.15 <-
|
||
-- Loop starts here
|
||
-> State: 1.15 <-
|
||
wantQ = TRUE
|
||
q.state = resetFalse
|
||
-> Input: 1.16 <-
|
||
_process_selector_ = p
|
||
q.running = FALSE
|
||
p.running = TRUE
|
||
-> State: 1.16 <-
|
||
wantP = FALSE
|
||
p.state = resetTrue
|
||
-> Input: 1.17 <-
|
||
-> State: 1.17 <-
|
||
wantP = TRUE
|
||
p.state = resetFalse
|
||
#+END_SRC
|
||
Di seguito il trace che conferma la presenza di starvation
|
||
individuale, sia in GreatSPN che NuSMV.
|
||
#+BEGIN_SRC
|
||
Generated counter-example:
|
||
==================================== Trace ====================================
|
||
Initial state is: local_Q(1), wantQ_FALSE(1), wantP_FALSE(1), local_P(1)
|
||
Initial state satisfies: E F (not ((not (setTrue_Q = 1)) or (not E G (not (critical_Q = 1))))).
|
||
|
||
1: local_Q(1), wantQ_FALSE(1), wantP_FALSE(1), local_P(1)
|
||
State 1. satisfies: ((not (setTrue_Q = 1)) or (not E G (not (critical_Q = 1)))).
|
||
|
||
1.1: local_Q(1), wantQ_FALSE(1), wantP_FALSE(1), local_P(1)
|
||
State 1.1. does not satisfy: (setTrue_Q = 1).
|
||
|
||
2: setTrue_Q(1), wantQ_FALSE(1), wantP_FALSE(1), local_P(1)
|
||
State 2. does not satisfy: ((not (setTrue_Q = 1)) or (not E G (not (critical_Q = 1)))).
|
||
|
||
2.1: setTrue_Q(1), wantQ_FALSE(1), wantP_FALSE(1), local_P(1)
|
||
State 2.1.L. satisfies: (setTrue_Q = 1).
|
||
|
||
State 2.1.R. satisfies: E G (not (critical_Q = 1)). Start of loop.
|
||
|
||
2.1.R.1: setTrue_Q(1), wantQ_FALSE(1), wantP_FALSE(1), local_P(1)
|
||
State 2.1.R.1. does not satisfy: (critical_Q = 1).
|
||
|
||
2.1.R.2: loop back to state 2.1.R.1.
|
||
#+END_SRC
|
||
#+BEGIN_SRC
|
||
-- specification AG (q.state = setTrue -> AF q.state = critical) is false
|
||
-- as demonstrated by the following execution sequence
|
||
Trace Description: CTL Counterexample
|
||
Trace Type: Counterexample
|
||
-> State: 3.1 <-
|
||
wantP = FALSE
|
||
wantQ = FALSE
|
||
p.state = local
|
||
q.state = local
|
||
-> Input: 3.2 <-
|
||
_process_selector_ = q
|
||
running = FALSE
|
||
q.running = TRUE
|
||
p.running = FALSE
|
||
-> State: 3.2 <-
|
||
q.state = setTrue
|
||
-> Input: 3.3 <-
|
||
_process_selector_ = p
|
||
q.running = FALSE
|
||
p.running = TRUE
|
||
-> State: 3.3 <-
|
||
p.state = setTrue
|
||
-> Input: 3.4 <-
|
||
-> State: 3.4 <-
|
||
wantP = TRUE
|
||
p.state = critical
|
||
-> Input: 3.5 <-
|
||
_process_selector_ = q
|
||
q.running = TRUE
|
||
p.running = FALSE
|
||
-> State: 3.5 <-
|
||
wantQ = TRUE
|
||
q.state = resetFalse
|
||
-> Input: 3.6 <-
|
||
_process_selector_ = p
|
||
q.running = FALSE
|
||
p.running = TRUE
|
||
-- Loop starts here
|
||
-> State: 3.6 <-
|
||
p.state = setFalse
|
||
-> Input: 3.7 <-
|
||
_process_selector_ = main
|
||
running = TRUE
|
||
p.running = FALSE
|
||
-- Loop starts here
|
||
-> State: 3.7 <-
|
||
-> Input: 3.8 <-
|
||
_process_selector_ = q
|
||
running = FALSE
|
||
q.running = TRUE
|
||
-> State: 3.8 <-
|
||
wantQ = FALSE
|
||
q.state = resetTrue
|
||
-> Input: 3.9 <-
|
||
_process_selector_ = p
|
||
q.running = FALSE
|
||
p.running = TRUE
|
||
-> State: 3.9 <-
|
||
wantP = FALSE
|
||
p.state = local
|
||
-> Input: 3.10 <-
|
||
-> State: 3.10 <-
|
||
p.state = setTrue
|
||
-> Input: 3.11 <-
|
||
-> State: 3.11 <-
|
||
wantP = TRUE
|
||
p.state = critical
|
||
-> Input: 3.12 <-
|
||
_process_selector_ = q
|
||
q.running = TRUE
|
||
p.running = FALSE
|
||
-> State: 3.12 <-
|
||
wantQ = TRUE
|
||
q.state = resetFalse
|
||
-> Input: 3.13 <-
|
||
_process_selector_ = p
|
||
q.running = FALSE
|
||
p.running = TRUE
|
||
-> State: 3.13 <-
|
||
p.state = setFalse
|
||
#+END_SRC
|