/** Concurrency: State Models and Java Programs
 *             Jeff Magee and Jeff Kramer
 *  
 */

const N = 4
range T = 0..N
set VarAlpha = {value.{read[T],write[T],
		       acquire,release}
	       }

VAR = VAR[0],
VAR[u:T] = (read[u]->VAR[u] | write[v:T]->VAR[v]).

LOCK = (acquire->release->LOCK).
||LOCKVAR = (LOCK || VAR).

TURNSTILE = (go    -> RUN),
RUN       = (arrive-> INCREMENT
            |end   -> TURNSTILE),
INCREMENT = (value.acquire
             -> value.read[x:T]->value.write[x+1]
             ->value.release->RUN
            )+VarAlpha.

||GARDEN = (east:TURNSTILE || west:TURNSTILE 
            || {east,west,display}::value:LOCKVAR)
            /{go /{east,west}.go,
              end/{east,west}.end}.

TEST       = TEST[0],
TEST[v:T]  = (when (v<N){east.arrive,west.arrive}->TEST[v+1] 
             | end->CHECK[v]
             ),
CHECK[v:T] = (display.value.read[u:T] -> 
               (when (u==v) right -> TEST[v]
               |when (u!=v) wrong -> ERROR)
             )+{display.{VarAlpha}}.

menu RUN = {east.arrive,west.arrive,end,go,display.value.read[u:T]}

||TESTGARDEN = (GARDEN || TEST).
