Example: Infinite Split and Merge #define N 128 #define size 16 chan in = [size] of {short}; chan large = [size] of {short}; chan small = [size] of {short}; proctype split() {short cargo; do :: in?cargo -> if :: (cargo >= N) -> large!cargo :: (cargo small!cargo fi od} proctype merge() { short cargo; do :: if :: large?cargo :: small?cargo fi; in!cargo od} init {in!345; in!12; in!6777; in!32; in!0; run split(); run merge()}
2 Data Types Basic bit byte short- (2^15)-1.. (2^15)-1 int - (2^31)-1.. (2^31)-1 Arrays byte state[N]state[0].. State[N-1] Enumerated Type mtype = {one, two, three, ok, ready, ack, message} one mtype definition, at most 256 symbolic constants Structures typedef Msg { byte a[3], b; chan p } Msg x; x.a[1]
3 Exercise Develop a Promela description of the following: There are 3 worker processes and 1 hammer. A worker’s arm can be up or down; his/her arm can only go down (i.e. work!) when the worker has the hammer. When the worker has finished working, he/she passes the hammer to another worker. Assume mtype ={hammer, up, down}
4 Workers mtype ={hammer, up, down} chan one= [1] of {mtype}; chan two = [1] of {mtype}; chan three= [1] of {mtype}; proctype worker(chan mine, a, b) {mtype m; mtype arm = up; idle: mine?m; goto work; work: arm = down; if :: atomic {a!hammer; arm = up; goto idle} :: atomic {b!hammer; arm = up; goto idle} fi } init { atomic { run worker(one,two,three); run worker(two, three,one); run worker(three,one,two); one!hammer }
5 Exercise Develop a Promela description of the following: Now a worker needs both a hammer and a mallet to work and must have received the hammer first. He/she can pass the tools one at a time, randomly. Assume mtype ={hammer, up, down,mallet}
6 Workers II mtype ={hammer, mallet, up, down}... proctype worker(chan mine, a, b; bit tools) {mtype m; mtype arm = up; idle: mine?m; if :: m == hammer -> tools = tools+1; goto idle; :: m == mallet -> if :: tools== 0 -> if :: atomic {a!m; goto idle} :: atomic {b!m; goto idle} fi :: tools== 1 -> tools = 0; goto work fi work: arm = down; arm = up; if :: a!hammer; a!mallet :: b!hammer; a!mallet :: a!hammer; b!mallet … /*8 possibilities */ fi goto idle }
7 Process identifiers Every process instance has a unique, positive instantiation number, returned by run: short pid1 = -1; short pid2 = -1; short pid3 = -1; init { run semaphore(); pid1 = run user(); pid2 = run user(); pid3 = run user() } Uses enabled(pid) true if process is enabled cannot use with synchronous communication pcvalue(pid) returns number of state that process with no. pid is in remote reference true if process with no. pid of type procname is at label