ExtremaFindingRefined.casm //(by Jacopo Soldani Pisa 2014) \\concurrent asynchronous version use Standard use TabBlocks use Queue use SchedulingPolicies //We remove the scheduling policy so that only a subset of //the agents will be executed. In this way we obtain an //asynch. system //option SchedulingPolicies.policy allfirst enum STATES = {ACTIVE, INACTIVE} function mode : Agents -> STATES function rightMsg : Agents -> NUMBER function leftMsg : Agents -> NUMBER function id : Agents -> NUMBER function isLargest : Agents -> BOOLEAN function notified : Agents -> BOOLEAN function leftMsgs : Agents -> QUEUE function rightMsgs : Agents -> QUEUE function pos : Agents -> NUMBER derived N = 4 derived processes = {a | a in Agents with pos(a) != undef} derived l(p) = pick proc in processes with pos(proc) = (pos(p)-1+N) % N derived r(p) = pick proc in processes with pos(proc) = (pos(p)+1) % N derived largerMsgReceived = rightMsg(self) > id(self) or leftMsg(self) > id(self) derived myMsgReceived = rightMsg(self) = id(self) or leftMsg(self) = id(self) init InitiateState rule ExtremaFinding = if mode(self) = ACTIVE then if not isLargest(self) then enqueue id(self) into rightMsgs(l(self)) enqueue id(self) into leftMsgs(r(self)) if leftMsgs(self)!=[] and rightMsgs(self)!=[] then seq dequeue rightMsg(self) from rightMsgs(self) dequeue leftMsg(self) from leftMsgs(self) next if largerMsgReceived then mode(self) := INACTIVE if myMsgReceived then isLargest(self):=true notified(r(self)) := true if mode(self) = INACTIVE then if notified(self) then notified(r(self)) := true else EnqueueMessages if isLargest(self) and notified(self) then print "Extrema found!!!" StopASM rule EnqueueMessages = if leftMsgs(self)!=[] and rightMsgs(self)!=[] then seq dequeue rightMsg(self) from rightMsgs(self) dequeue leftMsg(self) from leftMsgs(self) next enqueue rightMsg(self) into rightMsgs(l(self)) enqueue leftMsg(self) into leftMsgs(r(self)) rule InitiateState = //We will employ n,m to generate different ids (for each process p) choose n in {11*N,13*N,17*N} do choose m in {11*N,13*N,17*N} do forall i in [0..(N-1)] do extend Agents with p do program(p) := @ExtremaFinding pos(p) := i id(p) := (i+n+m) % N + 1 mode(p) := ACTIVE notified(p) := false isLargest(p) :=false rightMsg(p) := (i+n+m) % N + 1 leftMsg(p) := (i+n+m) % N + 1 leftMsgs(p) := [] rightMsgs(p) := [] program(self) := undef rule StopASM = forall m in Agents do program(m) := undef