UniTO/anno3/vpc/consegne/3/analisi.org

1073 lines
33 KiB
Org Mode
Raw Permalink Normal View History

2020-05-22 12:15:33 +02:00
#+TITLE: Esercizio di analisi degli algoritmi di mutua esclusione
#+AUTHOR: Francesco Mecca
#+EMAIL: me@francescomecca.eu
#+LANGUAGE: en
#+LaTeX_CLASS: article
#+LaTeX_HEADER: \linespread{1.25}
#+LaTeX_HEADER: \usepackage{pdfpages}
2020-05-21 13:57:43 +02:00
#+LaTeX_HEADER: \usepackage{comment}
#+LaTeX_HEADER: \usepackage{regexpatch,fancyvrb,xparse}
#+LaTeX_HEADER: \makeatletter
#+LaTeX_HEADER: \usepackage{pdfpages}
#+LaTeX_HEADER: \let\do@footnotetext\@footnotetext
#+LaTeX_HEADER: \regexpatchcmd{\do@footnotetext}
#+LaTeX_HEADER: {\c{insert}\c{footins}\cB.(.*)\cE.}
#+LaTeX_HEADER: {\1\c{egroup}}
#+LaTeX_HEADER: {}{}
#+LaTeX_HEADER: \def\@footnotetext{\insert\footins\bgroup\@makeother\#\do@footnotetext}
#+LaTeX_HEADER: \newcommand{\ttvar}{\begingroup\@makeother\#\@ttvar}
#+LaTeX_HEADER: \newcommand{\@ttvar}[1]{\ttfamily\detokenize{#1}\endgroup}
#+LaTeX_HEADER: \makeatother
#+LaTeX_HEADER: \usepackage{listings}
#+LaTeX_HEADER: \lstset{
#+LaTeX_HEADER: basicstyle=\small\ttfamily,
#+LaTeX_HEADER: columns=flexible,
#+LaTeX_HEADER: breaklines=true
#+LaTeX_HEADER: }
2020-05-22 12:15:33 +02:00
#+EXPORT_SELECT_TAGS: export
#+EXPORT_EXCLUDE_TAGS: noexport
#+OPTIONS: H:2 toc:nil \n:nil @:t ::t |:t ^:{} _:{} *:t TeX:t LaTeX:t
#+STARTUP: showall
2020-05-21 13:57:43 +02:00
\begin{comment}
2020-05-08 15:30:53 +02:00
NOTA: nel caso di Ampararore, la formula:
2020-05-21 13:57:43 +02:00
| AG(EF(critical_P == 1))
2020-05-08 15:30:53 +02:00
| da qualsiasi stato e` sempre possibile arrivare a critical_P == 1
2020-05-21 13:57:43 +02:00
\end{comment}
2020-05-06 17:10:03 +02:00
2020-05-21 13:57:43 +02:00
* Proprieta` del modello
2020-05-05 22:00:56 +02:00
Ogni modello successivamente mostrato rispetta le seguenti proprieta`:
2020-05-21 13:57:43 +02:00
siano /p/ e /q/ due generici processi,
1. Mutua esclusione: garantisce che al piu` un solo processo e` nella
sezione critica ad ogni istante. E` una proprieta` di safety.
2020-05-05 22:00:56 +02:00
| G (¬cₚ¬c_{q})
2020-05-21 13:57:43 +02:00
2. Assenza di deadlock: ogni qualvolta un processo e` in
2020-05-05 22:00:56 +02:00
attesa di entrare nella sezione critica, eventualmente verra`
2020-05-21 13:57:43 +02:00
concesso ad un processo di entrare nella sezione critica. E` una
proprieta` di liveness.
| G((wₚw_{q}) → F(cₚc_{q}))
3. Assenza di starvation individuale: ogni qualvolta un processo e` in
attesa di entrare nella sezione critica, eventualmente gli verra`
concesso.
2020-05-06 17:10:03 +02:00
| G(wₚ → Fcₚ)
2020-05-21 13:57:43 +02:00
Rispetto all'assenza di deadlock, e` una proprieta` di
liveness ancora piu` forte della precedente.
| ∀p, G(wₚ → Fcₚ)
2020-05-05 22:00:56 +02:00
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})
2020-05-06 17:10:03 +02:00
| AG(wₚ → AFcₚ)
2020-05-05 22:00:56 +02:00
Benche` non tutte le formule LTL possono essere convertite in una
formula CTL equivalente anteponendo ad ogni operatore temporale
2020-05-06 17:10:03 +02:00
l'operatore di stato A, per queste tre proprieta` possiamo.
2020-05-21 13:57:43 +02:00
Si specifica che i processi non sono forzati a progredire al di fuori
della regione critica (possono rimanere per un tempo indeterminato
nella sezione /azione locale lₚ/) e quindi:
| G((wₚw_{q}) → F(cₚc_{q}) = false → G((lₚl_{q}) → F(cₚc_{q})
| G((lₚl_{q}) → F(cₚc_{q}) = true → G((wₚw_{q}) → F(cₚc_{q})
2020-05-05 22:00:56 +02:00
2020-05-06 17:10:03 +02:00
* 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};
2020-05-22 12:48:27 +02:00
2020-05-21 13:57:43 +02:00
\hrulefill
\lstinputlisting[breaklines]{3.2.b.smv}
\hrulefill
2020-05-07 17:47:52 +02:00
** GreatSPN
Il codice utilizzato per le proprieta` CTL e` il seguente:
#+BEGIN_SRC
2020-05-21 13:57:43 +02:00
AG(!(#P3 == 1) || !(#P4 == 1))
AG ((#P1==1 || #Q1 == 1) -> AF (#P3 == 1 || #Q3 == 1))
AG (#P1==1 -> AF (#P3 == 1))
AG (#Q1==1 -> AF (#Q3 == 1))
AG (#Q1==1 -> EF (#Q3 == 1))
2020-05-07 17:47:52 +02:00
#+END_SRC
2020-05-22 00:15:00 +02:00
#+CAPTION: Rete 3.2
2020-05-21 13:57:43 +02:00
\includepdf{3.2.jpg}
** Algebra dei processi
2020-05-21 19:27:27 +02:00
Riportiamo il modello dell'algoritmo 3.2 secondo l'algebra dei
2020-05-21 23:34:22 +02:00
processi CSP.
2020-05-21 19:27:27 +02:00
| System = {(P₁ \vert{}\vert{} Q₁) \vert{}\vert{} Tₚ} \ttvar{/ }Sync
2020-05-22 12:48:27 +02:00
| Act = {localₚ, local_{q}, criticalₚ, critical_{q}}
2020-05-21 13:57:43 +02:00
| Sync = {isₚ, is_{q}, setₚ, set_{q}}
| Tₚ ::= isₚ.Tₚ + setₚ.Tₚ + set_{q}.T_{q}
| T_{q} ::= is_{q}.T_{q} + setₚ.Tₚ + set_{q}.T_{q}
| P₁ ::= localₚ.P₂ + localₚ.P₁
| P₂ ::= isₚ.P₃
| P₃ ::= criticalₚ.P₄
| P₄ ::= set_{q}.P₁
| Q₁ ::= local_{q}.Q₂ + local_{q}.Q₁
| Q₂ ::= is_{q}.Q₃
| Q₃ ::= critical_{q}.Q₄
| Q₄ ::= set_{p}.Q₁
2020-05-22 12:15:33 +02:00
Seguono il Reachability Graph costruito con GreatSPN e il Derivation Graph.
2020-05-21 13:57:43 +02:00
2020-05-22 00:15:00 +02:00
#+CAPTION: Reachability Graph 3.2
2020-05-21 19:27:27 +02:00
\includepdf{rg_3.2.jpg}
2020-05-22 00:15:00 +02:00
#+CAPTION: Derivation Graph 3.2
2020-05-21 19:27:27 +02:00
\includepdf{derivation_3.2.jpg}
2020-05-21 13:57:43 +02:00
2020-05-07 17:47:52 +02:00
** Risultati
2020-05-06 17:10:03 +02:00
Nella tabella mostriamo i risultati ottenuti
| | NuSMV | GreatSPN |
|---------------------+-------+----------|
2020-05-07 17:47:52 +02:00
| Mutua Esclusione | True | True |
| Assenza di deadlock | False | False |
| No Starvation | False | False |
2020-05-06 17:10:03 +02:00
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:
2020-05-22 12:48:27 +02:00
\hrulefill
2020-05-06 17:10:03 +02:00
#+BEGIN_SRC
2020-05-22 12:48:27 +02:00
-- specification
AG (p.state = wait -> AF (p.state = critical | q.state = critical)) is false
2020-05-06 17:10:03 +02:00
-- as demonstrated by the following execution sequence
2020-05-21 13:57:43 +02:00
Trace Description: CTL Counterexample
Trace Type: Counterexample
2020-05-06 17:10:03 +02:00
-> State: 1.1 <-
turn = 1
p.state = begin
q.state = begin
2020-05-21 13:57:43 +02:00
-> Input: 1.2 <-
_process_selector_ = p
running = FALSE
q.running = FALSE
p.running = TRUE
2020-05-06 17:10:03 +02:00
-> State: 1.2 <-
2020-05-21 13:57:43 +02:00
p.state = wait
-> Input: 1.3 <-
2020-05-06 17:10:03 +02:00
-> State: 1.3 <-
2020-05-21 13:57:43 +02:00
p.state = critical
-> Input: 1.4 <-
-> State: 1.4 <-
p.state = done
-> Input: 1.5 <-
-> State: 1.5 <-
turn = 2
p.state = begin
-> Input: 1.6 <-
-- Loop starts here
-> State: 1.6 <-
p.state = wait
-> Input: 1.7 <-
_process_selector_ = q
q.running = TRUE
p.running = FALSE
-- Loop starts here
-> State: 1.7 <-
-> Input: 1.8 <-
_process_selector_ = p
q.running = FALSE
p.running = TRUE
-- Loop starts here
-> State: 1.8 <-
-> Input: 1.9 <-
_process_selector_ = main
running = TRUE
p.running = FALSE
-> State: 1.9 <-
2020-05-06 17:10:03 +02:00
#+END_SRC
2020-05-22 12:48:27 +02:00
\hrulefill
\clearpage
La traccia mostra che il processo q rimane nella fase begin e p, dopo essere
2020-05-06 17:10:03 +02:00
entrato nella regione critica una volta, rimane bloccato in begin.
Lo stesso trace mostra la possibilita` di starvation del processo.
2020-05-07 17:47:52 +02:00
La rete modellata con GreatSPN ci conferma quanto visto con NuSMV.
2020-05-21 13:57:43 +02:00
Inoltre il trace di GreatSPN ci mostra che non potendo forzare la
fairness del modello, i processi possono iterare indefinitamente
nella transizione iniziale, impedendo quindi il progresso dell'altro
processo.
2020-05-22 12:48:27 +02:00
\hrulefill
2020-05-21 13:57:43 +02:00
#+BEGIN_SRC
Initial state is: P1(1), Turn_P(1), Q1(1)
Initial state satisfies: E F (not ((not (Q1 = 1)) or (not E G (not (Q3 = 1))))).
1: P1(1), Turn_P(1), Q1(1)
State 1. does not satisfy: ((not (Q1 = 1)) or (not E G (not (Q3 = 1)))).
1.1: P1(1), Turn_P(1), Q1(1)
State 1.1.L. satisfies: (Q1 = 1).
State 1.1.R. satisfies: E G (not (Q3 = 1)). Start of loop.
1.1.R.1: P1(1), Turn_P(1), Q1(1)
State 1.1.R.1. does not satisfy: (Q3 = 1).
1.1.R.2: loop back to state 1.1.R.1.
#+END_SRC
2020-05-07 17:47:52 +02:00
2020-05-22 12:48:27 +02:00
\hrulefill
\clearpage
2020-05-07 17:47:52 +02:00
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};
2020-05-22 12:48:27 +02:00
Non si e` utilizzata la direttiva /process/ di NuSMV dato che un
automa a stati finiti e` sufficiente a dimostrare le proprieta` del
modello.
2020-05-21 13:57:43 +02:00
\hrulefill
\lstinputlisting[breaklines]{3.5.smv}
\hrulefill
2020-05-22 12:15:33 +02:00
\clearpage
2020-05-07 17:47:52 +02:00
** GreatSPN
Il codice utilizzato per le proprieta` CTL e` il seguente:
#+BEGIN_SRC
AG(!(#Await_P == 1) || !(#Await_Q == 1)) = true
2020-05-21 13:57:43 +02:00
AG ((#Wait_P==1 || #Await_Q == 1) -> AF (#Done_P == 1 || #Done_Q == 1)) = false
2020-05-07 17:47:52 +02:00
AG (#Await_P==1 -> AF (#Done_P == 1)) = false
#+END_SRC
2020-05-22 00:15:00 +02:00
#+CAPTION: Rete 3.5
2020-05-22 12:15:33 +02:00
[[./3.5.jpg]]
2020-05-21 13:57:43 +02:00
2020-05-07 17:47:52 +02:00
** 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 <-
#+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
2020-05-21 13:57:43 +02:00
processi usando 5 stati
2020-05-08 12:32:56 +02:00
| state: {local, await, critical, setTrue, setFalse};
2020-05-21 13:57:43 +02:00
\hrulefill
\lstinputlisting[breaklines]{3.6.b.smv}
\hrulefill
2020-05-22 12:48:27 +02:00
\clearpage
2020-05-07 17:47:52 +02:00
** GreatSPN
2020-05-08 12:32:56 +02:00
Il codice utilizzato per le proprieta` CTL e` il seguente:
#+BEGIN_SRC
2020-05-21 13:57:43 +02:00
AG (!(#P4 == 1) || !(#Q4 == 1))
AG ((#P2==1 || #Q2 == 1) -> AF (#P4 == 1 || #Q4 == 1))
AG (#P1 == 1 -> EF(#Q4==1 || #Q4 == 1))
AG (#P2 == 1 -> AF (#P4 == 1))
AG (#Q2 == 1 -> AF (#Q4 == 1))
2020-05-08 12:32:56 +02:00
#+END_SRC
2020-05-22 00:15:00 +02:00
#+CAPTION: Rete 3.6
2020-05-21 13:57:43 +02:00
\includepdf{3.6.jpg}
** Algebra dei processi
2020-05-21 19:27:27 +02:00
L'algoritmo 3.6 modellato secondo NuSMV e GreatSPN mostra che non c'e`
la mutua esclusione.
Questo viene evidenziato anche dal fatto che i nodi del Reachability
Graph corrispondo al prodotto cartesiano P×Q.
Anche il Derivation Graph del modello in algebra dei processi ha 25
nodi ed e` equivalente al Reachability Graph.
2020-05-21 13:57:43 +02:00
2020-05-21 19:27:27 +02:00
| System = {(P₁ \vert{}\vert{} Q₁) \vert{}\vert{} (Wantₚ₀ \vert{}\vert{} Want_{q}₀)} \ttvar{/ }Sync
2020-05-21 13:57:43 +02:00
| Sync = { isTrueₚ, isFalseₚ, setTrueₚ, setFalseₚ,
| \enspace{}\quad{}\quad{} isTrue_{q}, isFalse_{q}, setTrue_{q}, setFalse_{q} }
| S = {localₚ, criticalₚ, local_{q}, critical_{q}}
| Wantₚ₁ ::= isTrueₚ.Wantₚ₁ + setTrueₚ.Wantₚ₁ + setFalseₚ.Wantₚ₀
| Wantₚ₀ ::= isFalseₚ.Wantₚ₀ + setFalseₚ.Wantₚ₀ + setTrueₚ.Wantₚ₁
| P₁ ::= localₚ.P₁ + localₚ.P₂
| P₂ ::= isFalse_{q}.P₃
| P₃ ::= setTrueₚ.P₄
| P₄ ::= criticalₚ.P₅
| P₅ ::= setFalseₚ.P₁
| Want_{q}₁ ::= isTrue_{q}.Want_{q}₁ + setTrue_{q}.Want_{q}₁ + setFalse_{q}.Want_{q}₀
| Want_{q}₀ ::= isFalse_{q}.Want_{q}₀ + setFalse_{q}.Want_{q}₀ + setTrue_{q}.Want_{q}₁
| Q₁ ::= local_{q}.Q₁ + local_{q}.Q₂
| Q₂ ::= isFalse_{p}.Q₃
| Q₃ ::= setTrue_{q}.Q₄
| Q₄ ::= critical_{q}.Q₅
| Q₅ ::= setFalse_{q}.Q₁
2020-05-22 12:15:33 +02:00
Seguono il Reachability Graph costruito con GreatSPN e il Derivation Graph.
2020-05-08 12:32:56 +02:00
2020-05-21 13:57:43 +02:00
2020-05-22 00:15:00 +02:00
#+CAPTION: Reachability Graph 3.6
2020-05-21 19:27:27 +02:00
\includepdf{rg_3.6.jpg}
2020-05-22 00:15:00 +02:00
#+CAPTION: Derivation Graph 3.6
2020-05-21 19:27:27 +02:00
\includepdf{derivation_3.6.jpg}
2020-05-21 13:57:43 +02:00
** Risultati
2020-05-08 12:32:56 +02:00
Nella tabella mostriamo i risultati ottenuti
| | NuSMV | GreatSPN |
|---------------------+-------+----------|
| Mutua Esclusione | false | false |
| Assenza di deadlock | true | false |
2020-05-21 13:57:43 +02:00
| No Starvation | false | false |
Il trace di NuSMV mostra che la mutua esclusione puo` non essere
rispettata dato che le due variabili /wantP/ e /wantQ/ possono essere
contemporaneamente false.
2020-05-22 12:48:27 +02:00
\hrulefill
2020-05-21 13:57:43 +02:00
#+BEGIN_SRC
-- specification AG (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 = await
-> Input: 1.3 <-
-> State: 1.3 <-
p.state = setTrue
-> Input: 1.4 <-
_process_selector_ = q
q.running = TRUE
p.running = FALSE
-> State: 1.4 <-
q.state = await
-> Input: 1.5 <-
-> State: 1.5 <-
q.state = setTrue
-> Input: 1.6 <-
_process_selector_ = p
q.running = FALSE
p.running = TRUE
-> State: 1.6 <-
wantP = TRUE
p.state = critical
-> Input: 1.7 <-
_process_selector_ = q
q.running = TRUE
p.running = FALSE
-> State: 1.7 <-
wantQ = TRUE
q.state = critical
#+END_SRC
2020-05-22 12:48:27 +02:00
\hrulefill
\clearpage
2020-05-08 12:32:56 +02:00
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
2020-05-21 13:57:43 +02:00
| AG(wₚ → AF(cₚc_{q})
2020-05-08 12:32:56 +02:00
risulta rispettata.
Ancora meglio, piuttosto che rimuovere una transizione possibile,
possiamo restringere la verifica dell'assenza di deadlock alla
seguente formula CTL
2020-05-22 12:15:33 +02:00
| AG (wₚ → EF (cₚ \vert{}\vert{} c_{q}))
| AG(#await_P\space== 1 -> EF(#critical_Q==1 \vert{}\vert{} #critical_P == 1))
2020-05-08 12:32:56 +02:00
che risulta rispettata.
2020-05-21 13:57:43 +02:00
L'assenza di starvation individuale non e` rispettata ne` in NuSmv ne` in
GreatSPN in quanto e` possibile che uno dei due processi continui ad
accedere alla sezione critica senza permettere allaltro di fare lo
stesso.
2020-05-22 12:48:27 +02:00
\hrulefill
2020-05-21 13:57:43 +02:00
#+BEGIN_SRC
-- specification AG (q.state = await -> 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
-- Loop starts here
-> State: 3.2 <-
q.state = await
-> Input: 3.3 <-
_process_selector_ = p
q.running = FALSE
p.running = TRUE
-> State: 3.3 <-
p.state = await
-> Input: 3.4 <-
-> State: 3.4 <-
p.state = setTrue
-> Input: 3.5 <-
-> State: 3.5 <-
wantP = TRUE
p.state = critical
-> Input: 3.6 <-
_process_selector_ = q
q.running = TRUE
p.running = FALSE
-> State: 3.6 <-
-> Input: 3.7 <-
_process_selector_ = p
q.running = FALSE
p.running = TRUE
-> State: 3.7 <-
p.state = setFalse
-> Input: 3.8 <-
-> State: 3.8 <-
wantP = FALSE
p.state = local
#+END_SRC
2020-05-22 12:48:27 +02:00
\hrulefill
\clearpage
2020-05-08 19:23:51 +02:00
* 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.
2020-05-22 12:15:33 +02:00
2020-05-21 13:57:43 +02:00
\hrulefill
\lstinputlisting[breaklines]{3.8.smv}
\hrulefill
2020-05-22 12:15:33 +02:00
\clearpage
2020-05-08 19:23:51 +02:00
** GreatSPN
Il codice utilizzato per le proprieta` CTL e` il seguente:
#+BEGIN_SRC
AG(!(#critical_P == 1) || !(#critical_Q == 1))
2020-05-21 13:57:43 +02:00
AG ((#await_P==1 || #await_Q == 1) -> AF (#critical_P == 1 || #critical_Q == 1))
2020-05-08 19:23:51 +02:00
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:
2020-05-21 13:57:43 +02:00
#+BEGIN_SRC
2020-05-22 12:48:27 +02:00
AG(#await_P == 1 -> EF(#critical_Q==1 \vert{}\vert{} #critical_P == 1))
2020-05-21 13:57:43 +02:00
#+END_SRC
2020-05-08 19:23:51 +02:00
che conferma la presenza di deadlock causata dalle due variabili booleane.
2020-05-22 00:15:00 +02:00
#+CAPTION: Rete 3.8
2020-05-22 12:15:33 +02:00
[[./3.8.jpg]]
2020-05-08 19:23:51 +02:00
** 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.
2020-05-22 12:48:27 +02:00
\hrulefill
2020-05-08 19:23:51 +02:00
#+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
2020-05-21 13:57:43 +02:00
Trace Description: CTL Counterexample
Trace Type: Counterexample
2020-05-08 19:23:51 +02:00
-> State: 1.1 <-
wantP = FALSE
wantQ = FALSE
p.state = local
q.state = local
2020-05-21 13:57:43 +02:00
-> Input: 1.2 <-
_process_selector_ = p
running = FALSE
q.running = FALSE
p.running = TRUE
2020-05-08 19:23:51 +02:00
-> State: 1.2 <-
p.state = setTrue
2020-05-21 13:57:43 +02:00
-> Input: 1.3 <-
2020-05-08 19:23:51 +02:00
-> State: 1.3 <-
wantP = TRUE
p.state = await
2020-05-21 13:57:43 +02:00
-> Input: 1.4 <-
_process_selector_ = q
q.running = TRUE
p.running = FALSE
2020-05-08 19:23:51 +02:00
-> State: 1.4 <-
2020-05-21 13:57:43 +02:00
q.state = setTrue
-> Input: 1.5 <-
-- Loop starts here
-> State: 1.5 <-
wantQ = TRUE
q.state = await
-> Input: 1.6 <-
_process_selector_ = p
q.running = FALSE
p.running = TRUE
-- Loop starts here
-> State: 1.6 <-
-> Input: 1.7 <-
_process_selector_ = main
running = TRUE
p.running = FALSE
-- Loop starts here
-> State: 1.7 <-
-> Input: 1.8 <-
_process_selector_ = q
running = FALSE
q.running = TRUE
-- Loop starts here
-> State: 1.8 <-
-> Input: 1.9 <-
_process_selector_ = p
q.running = FALSE
p.running = TRUE
-- Loop starts here
-> State: 1.9 <-
-> Input: 1.10 <-
_process_selector_ = main
running = TRUE
p.running = FALSE
-> State: 1.10 <-
2020-05-08 19:23:51 +02:00
#+END_SRC
2020-05-22 12:48:27 +02:00
\hrulefill
\clearpage
2020-05-08 19:23:51 +02:00
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/.
2020-05-22 12:48:27 +02:00
\hrulefill
2020-05-08 19:23:51 +02:00
#+BEGIN_SRC
Generated counter-example:
==================================== Trace ====================================
Initial state is: local_P(1), wantP_FALSE(1), wantQ_FALSE(1), local_Q(1)
2020-05-21 13:57:43 +02:00
Initial state satisfies:
E F (not ((not (await_P = 1)) or (not E G (not (critical_P = 1))))).
2020-05-08 19:23:51 +02:00
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
2020-05-22 12:48:27 +02:00
\hrulefill
\clearpage
2020-05-08 19:23:51 +02:00
* 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.
2020-05-22 12:48:27 +02:00
2020-05-21 13:57:43 +02:00
\hrulefill
\lstinputlisting[breaklines]{3.9.smv}
\hrulefill
2020-05-22 12:48:27 +02:00
\clearpage
2020-05-08 19:23:51 +02:00
** GreatSPN
Il codice utilizzato per le proprieta` CTL e` il seguente:
#+BEGIN_SRC
AG(!(#critical_P == 1) || !(#critical_Q == 1))
2020-05-21 13:57:43 +02:00
AG ((#setTrue_P==1 || #setTrue_Q == 1) -> AF (#critical_P == 1 || #critical_Q == 1))
2020-05-08 19:23:51 +02:00
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:
2020-05-21 13:57:43 +02:00
| AG(#setTrue_P == 1 -> EF(#critical_Q==1 || #critical_P == 1))
2020-05-08 19:23:51 +02:00
che conferma la presenza di deadlock causata dalle due variabili
booleane.
2020-05-22 00:15:00 +02:00
#+CAPTION: Rete 3.9
2020-05-21 13:57:43 +02:00
\includepdf{3.9.jpg}
2020-05-08 19:23:51 +02:00
** 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.
2020-05-22 12:48:27 +02:00
\hrulefill
2020-05-08 19:23:51 +02:00
#+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
2020-05-22 12:48:27 +02:00
\hrulefill
\clearpage
2020-05-08 19:23:51 +02:00
Di seguito il trace che conferma la presenza di starvation
individuale, sia in GreatSPN che NuSMV.
2020-05-22 12:48:27 +02:00
\hrulefill
2020-05-08 19:23:51 +02:00
#+BEGIN_SRC
Generated counter-example:
==================================== Trace ====================================
Initial state is: local_Q(1), wantQ_FALSE(1), wantP_FALSE(1), local_P(1)
2020-05-21 13:57:43 +02:00
Initial state satisfies:
E F (not ((not (setTrue_Q = 1)) or (not E G (not (critical_Q = 1))))).
2020-05-08 19:23:51 +02:00
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
2020-05-22 12:48:27 +02:00
\hrulefill
\clearpage
\hrulefill
2020-05-08 19:23:51 +02:00
#+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
2020-05-22 12:48:27 +02:00
\hrulefill
\clearpage
2020-05-21 13:57:43 +02:00
* Algoritmo di Dekker per la mutua esclusione
Due processi iterano all'infinito seguendo questo pseudocodice
#+BEGIN_SRC
while true:
non-critical section
wantP <- true
while wantQ:
if turn = 2:
wantp <- false
await turn = 1
wantp <- true
critical section
turn <- 2
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 usando 9 stati
2020-05-22 12:48:27 +02:00
- state: {local, set_true, while, loop_set_false, await,
loop_set_true, critical, switch_turn, set_false};
2020-05-21 13:57:43 +02:00
\hrulefill
\lstinputlisting[breaklines]{dekker_WN.smv}
\hrulefill
2020-05-22 12:48:27 +02:00
\clearpage
2020-05-21 13:57:43 +02:00
** GreatSPN
Il codice utilizzato per le proprieta` CTL e` il seguente:
#+BEGIN_SRC
AG(!(#critical_P == 1) || !(#critical_Q == 1))
AG ((#local_P==1 || #local_Q == 1) -> AF (#critical_P == 1 || \#critical_Q == 1))
AG (#local_P==1 -> AF (#critical_P == 1))
AG (#local_Q==1 -> AF (#critical_Q == 1))
#+END_SRC
2020-05-22 00:15:00 +02:00
#+CAPTION: Rete 3.10
2020-05-21 13:57:43 +02:00
\includepdf{dekker.jpg}
Ci aspettiamo che come in precedenza ci sia deadlock perche` viene
data ai processi la possibilita` di rimanere su /local/.
Forzando i processi a fare del progresso dallo stato
/local/, allora la formula CTL
2020-05-22 12:15:33 +02:00
| AG((lₚ \vert{}\vert{} l_{q}) → AF(cₚc_{q})
2020-05-21 13:57:43 +02:00
risulta rispettata.
Ancora meglio, piuttosto che rimuovere una transizione possibile,
possiamo restringere la verifica dell'assenza di deadlock alla
seguente formula CTL
2020-05-22 12:15:33 +02:00
| AG (wₚ → EF (cₚ \vert{}\vert{} c_{q}))
| AG(#await_P\space== 1 -> EF(#critical_Q==1 \vert{}\vert{} #critical_P == 1))
2020-05-21 13:57:43 +02:00
che risulta rispettata.
C'e` possibilita` di starvation individuale perche` a differenza di
NuSMV non possiamo rispettare il requisito di fairness.
** Risultati
Nella tabella sono mostrati i risultati ottenuti
| | NuSMV | GreatSPN |
|---------------------+-------+----------|
| Mutua Esclusione | true | true |
| Assenza di deadlock | true | false |
| No Starvation | true | false |
2020-05-21 19:59:25 +02:00
2020-05-21 23:34:22 +02:00
* Equivalenza in algebra dei processi
2020-05-21 19:59:25 +02:00
Precedentemente abbiamo modellato usando l'algebra dei processi
l'algoritmo 3.2 e l'algoritmo 3.6.
Entrambi hanno le seguenti azioni:
| S = {localₚ, criticalₚ, local_{q}, critical_{q}} {τ}
2020-05-21 23:34:22 +02:00
** Bisimulazione
2020-05-21 20:42:06 +02:00
Si applica l'algoritmo del partizionamento per verificare
l'equivalenza tramite bisimulazione.
Questo lo stato iniziale
2020-05-21 20:54:06 +02:00
| {S0, R0}, {S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12, S14, S13
2020-05-21 20:42:06 +02:00
| R1, R2, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15,
| R16, R17, R18, R19, R20, R21, R22, R23, R24}
Applico lo split considerando l'azione /criticalₚ/
| {S0, R0}, {S4, S5, R4, R14, R18, R19, R24}
2020-05-21 20:54:06 +02:00
| {S1, S2, S3, S6, S7, S8, S9, S10, S11, S12, S14, R1, R2, R3, R5, R6,
2020-05-21 20:42:06 +02:00
| R7, R8, R9, R10, R11, R12, R13, R15, R16, R17, R20, R21, R22, R23}
Applico lo split considerando l'azione /critical_{q}/
2020-05-21 20:54:06 +02:00
| {S0, R0}, {S4, S5, R4, R14, R19, R24}, {R18}, {S11, S13, R9, R11, R16, R22}
| {S1, S2, S3, S6, S7, S8, S9, S10, S12, S14, R1, R2, R3, R5, R6,
2020-05-21 20:42:06 +02:00
| R7, R8, R10, R12, R13, R15, R17, R20, R21, R23}
Notiamo che R18 compare come unico elemento di un insieme. Benche`
l'algoritmo non sia terminato, questo ci basta per concludere che non
c'e` bisimulazione fra i due algoritmi. Nell'algoritmo 3.2 non compare
nessuno stato da cui e` possibile effettuare l'azione /criticalₚ/ o
l'azione /critical_{q}/. Questo risultato si poteva dedurre dal fatto
che l'algoritmo 3.6 a differenza del 3.2 non rispetta la mutua
esclusione e quindi vi sono degli stati non rappresentabili nel
modello dell'algoritmo 3.2. Si noti che non e` strettamente necessario
mascherare le azioni /isₚ/, /is_/q/, /setₚ/, set_/q/ in quanto
presenti in entrambi i modelli. Nel caso di bisimulazione fra due
modelli, l'algoritmo raggiunge la terminazione quando non e` piu`
possibile partizionare gli insieme in base alle azioni comuni e
abbiamo come risultato che in ogni set compare uno stato di un modello
insieme ad uno o piu` stati dell'altro.
2020-05-21 23:34:22 +02:00
** Trace equivalence
La trace equivalence e` piu` debole della bisimulation equivalence:
| p q → p ⋍_{T} q
ma non viceversa
| p q ↛ p ⋍_{T} q
2020-05-22 00:15:00 +02:00
Dato che l'algoritmo 3.6 non rispetta la mutua esclusione,
possiamo affermare che una sequenza /s/ dove /criticalₚ/ e /critical_{q}/
2020-05-21 23:34:22 +02:00
appaiono in successione, non e` una sequenza valida per il modello
dell'algoritmo 3.2 ma lo e` per il modello dell'algoritmo 3.6.
| s = ...criticalₚcritical_{q}...
| s = ...critical_{q}criticalₚ...
Questo ci permette di dire che non c'e` trace equivalence fra i due modelli.
2020-05-21 23:11:30 +02:00
* Riduzione
Le reti dell'algoritmo 3.6 e 3.8 differiscono per la successione delle
istruzioni di /setTrue/ e /await/ e permettono simmetricamente le
stesse riduzioni:
| rete 3.6 | rete 3.8 |
|---------------------+--------------------------------------|
| rimozione self loop | rimozione self loop |
| fusione posti P1-P2 | fusione posti local_P, setTrue_P |
| fusione posti P4-P5 | fusione posti critical_P, setFalse_P |
| fusione posti Q1-Q2 | fusione posti local_Q, setTrue_Q |
| fusione posti Q4-Q5 | fusione posti critical_Q, setFalse_Q |
Riportiamo le immagini delle due reti ridotte.
Le transizioni relative a /setTrue/ e /await/ non sono riducibili in
quanto hanno archi uscenti. Possiamo affermare che le due reti non
2020-05-22 00:15:00 +02:00
sono equivalenti, come era deducibile dal fatto che rispettano diverse
proprieta`.
#+CAPTION: Riduzione rete 3.6
2020-05-21 23:11:30 +02:00
[[./ridotto_3.6.jpg]]
2020-05-22 00:15:00 +02:00
#+CAPTION: Riduzione rete 3.8
2020-05-21 23:11:30 +02:00
[[./ridotto_3.8.jpg]]