-- A CSP specification and refinement of a scheduler


-- ProB: psize = 5: about 9 Seconds on MacbookPro 2.33 Ghz, psize=6 66 seconds
-- FDR: psize = 5:  quickly, psize=6 failed to compile ISM (even with unlimit) on MacbookPro 2.33 Ghz
 
psize = 5
PID = {1..psize}
channel new : PID
channel delete : PID
channel ready : PID
channel enter : PID
channel leave : PID

-- Specification

NEWPROC(p) = new.p -> PROC(p)

PROC(p) =  
    ready.p -> enter.p -> leave.p -> PROC(p)
    [] delete.p -> NEWPROC(p)

MUTEX = enter?p -> leave.p -> MUTEX

SCHEDULER0 = 
(||| p:PID @ NEWPROC(p)) [| {| enter, leave |} |]  MUTEX

-- Refinement

QUEUE(q) = 
       #q<psize & ready?p -> QUEUE(q^<p>)
    [] q!=<> & enter.head(q)   -> QUEUE(tail(q))   
    
SCHEDULER1 = 
((||| p:PID @ NEWPROC(p)) [| {| enter, leave |} |]  MUTEX)
      [| {| ready, enter |} |] QUEUE(<>)

assert SCHEDULER0 [T= SCHEDULER1

MAIN = SCHEDULER1

-- Trace Check Generated by ProB:
PROB_TEST_TRACE = new.3 -> ready.3 -> enter.3 -> leave.3 -> new.4 -> new.5 -> delete.4 -> ready.3 -> new.1 -> ready.1 -> enter.3 -> leave.3 -> enter.1 -> leave.1 -> ready.5 -> ready.3 -> ready.1 -> new.4 -> delete.4 -> enter.5 -> new.4 -> new.2 -> ready.2 -> leave.5 -> enter.3 -> leave.3 -> enter.1 -> leave.1 -> STOP

assert MAIN [T= PROB_TEST_TRACE

