Skip to content

Commit

Permalink
Revising for tomorrow's lecture
Browse files Browse the repository at this point in the history
  • Loading branch information
achlipala committed Feb 13, 2022
1 parent 22118d9 commit 0cba7c9
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 12 deletions.
13 changes: 4 additions & 9 deletions TransitionSystems.v
Original file line number Diff line number Diff line change
Expand Up @@ -411,17 +411,14 @@ Definition increment2_sys := parallel increment_sys increment_sys.
* added to the shared counter so far. *)
Definition contribution_from (pr : increment_program) : nat :=
match pr with
| Unlock => 1
| Done => 1
| Unlock | Done => 1
| _ => 0
end.

(* Second big idea: the program counter also tells us whether a thread holds the lock. *)
Definition has_lock (pr : increment_program) : bool :=
match pr with
| Read => true
| Write _ => true
| Unlock => true
| Read | Write _ | Unlock => true
| _ => false
end.

Expand All @@ -435,11 +432,9 @@ Definition shared_from_private (pr1 pr2 : increment_program) :=
* e.g. that they shouldn't both be in the critical section at once. *)
Definition instruction_ok (self other : increment_program) :=
match self with
| Lock => True
| Read => has_lock other = false
| Lock | Done => True
| Read | Unlock => has_lock other = false
| Write n => has_lock other = false /\ n = contribution_from other
| Unlock => has_lock other = false
| Done => True
end.

(** Now we have the ingredients to state the invariant. *)
Expand Down
5 changes: 2 additions & 3 deletions frap_book.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1458,7 +1458,7 @@ \section{Invariants}
\end{eqnarray*}

It is an almost-routine exercise to prove that $I$ really is an invariant, using Theorem \ref{invariant_induction}.
The key new ingredient we need is \emph{inversion}, a principle for deducing which inference rules may have been used to prove a fact.
The key new ingredient we need is \emph{inversion}, a principle for deducing which inference rules may have been used to prove a fact.\index{inversion}

For instance, at one point in the proof, we need to draw a conclusion from a premise $s \in \mathcal F_0$, meaning that $s$ is an initial state.
By inversion, because set $\mathcal F_0$ is defined by a single inference rule, that rule must have been used to conclude the premise, so it must be that $s = \mathsf{WithAccumulator}(n_0, 1)$.
Expand Down Expand Up @@ -1544,6 +1544,7 @@ \section{An Example with a Concurrent Program}
The meaning of \texttt{lock()} and \texttt{unlock()} is as usual\index{locks}, where at most one thread can hold the lock at once, claiming it via \texttt{lock()} and relinquishing it via \texttt{unlock()}.
When variable \texttt{global} is initialized to 0 and $n$ threads run this code at once and all terminate, we expect that \texttt{global} finishes with value $n$.
Of course, bugs in this program, like forgetting to include the locking, could lead to all sorts of wrong answers, with any value between 1 and $n$ possible with the right demonic thread interleaving.
(Here ``demonic'' refers to consideration of worst-case behavior, with respect to the desired correctness property.)\index{demonic choice}

\encoding
To prove that we got the program right, let's formalize it as a transition system. First, our state set:
Expand All @@ -1561,11 +1562,9 @@ \section{An Example with a Concurrent Program}
In particular, we will define a transition system for a single thread as $\mathcal L = \angled{(\mathbb N \times \mathbb B) \times P, \mathcal L_0, \to_{\mathcal L}}$.
We define the state to include not only the thread-local state $P$ but also the value of \texttt{global} (in $\mathbb N$) and whether the lock is currently taken (in $\mathbb B$, the Booleans, with values $\top$ [true] and $\bot$ [false]).
There is one designated initial state.

$$\infer{((0, \bot), \mathsf{Lock}) \in \mathcal L_0}{}$$

Four inference rules explain the four transitions between program counters that a single thread can make, reading and writing shared state as needed.

$$\infer{((g, \bot), \mathsf{Lock}) \to_{\mathcal L} ((g, \top), \mathsf{Read})}{}
\quad \infer{((g, \ell), \mathsf{Read}) \to_{\mathcal L} ((g, \ell), \mathsf{Write}(g))}{}$$
$$\infer{((g, \ell), \mathsf{Write}(n)) \to_{\mathcal L} ((n+1, \ell), \mathsf{Unlock})}{}
Expand Down

0 comments on commit 0cba7c9

Please sign in to comment.