program bank22; begin pref IIUWGraph BLOCK (* SYMULACJA PRACY BANKU *) (* dolaczone funkcje graficzne *) (****************************************************************************) unit kasa:procedure(nr:integer); var i:integer; begin i:=71+(nr-1)*56; call move(10,i); call draw(10,i+36); call draw(56,i+36); call draw(56,i); call draw(10,i); (*call vfill(i+36); call hfill(46); call move(10,i+36); call hfill(46); call move(46,i); call vfill(i+36);*) call move(13,i+7); call outstring("Desk"); call move(13,i+21); call outstring("No"); call move(38,i+18); (* call hascii(0); *) call hascii(nr+48); end kasa; (****************************************************************************) unit klient:procedure(nr,kasa:integer;inout kl:integer); var i,j,k,p:integer; begin kl:=kl+1; j:=85+(kasa-1)*56; i:=54+(nr-1)*26; call move(i,j-4); call hfill(i+24); call vfill(j+12); call move(i,j+12); call hfill(i+24); call move(i+24,j-4); call vfill(j+12); call move(i+4,j); k:=kl div 10; p:=kl mod 10; if k>0 then (* call hascii(0); *) call hascii(k+48); call move(i+12,j); (* call hascii(0); *) call hascii(p+48); else call move(i+8,j); (* call hascii(0); *) call hascii(p+48); fi; end klient; (****************************************************************************) unit obsluzony:procedure(nr,kasa:integer); var j:integer,pom:arrayof integer; begin j:=85+(kasa-1)*56; call move(80,j-5); pom:=getmap(199,j+14); call xormap(pom); call move(54,j-5); call putmap(pom); kill(pom); end obsluzony; (****************************************************************************) unit ramka:procedure; var i:integer; begin call move(0,0); call vfill(347); call hfill(719); call move(719,0); call vfill(347); call move(0,347); call hfill(719); call move(0,63); call hfill(719); call move(200,63); call vfill(347); call move(200,337); call hfill(719); call move(195,4); call outstring(" SIMULATION PROGRAM - BANK "); call move(0,14); call hfill(719); for i:=1 to 5 do call kasa(i) od ; call move(5,19); call outstring("This program simulates a bank department with 5 desks "); call outstring("served by 5 cashiers "); call move(5,29); call outstring("Customers arrive at random. The service time is also random "); call move(5,39); call outstring("as well as its account and the sum to be paid "); call move(5,49); end ramka; (****************************************************************************) unit zwieksz:procedure(inout linia:integer); var pom:arrayof integer; begin linia:=linia+10; if linia>=326 then call move(205,65); pom:=getmap(718,325); call xormap(pom); linia:=66; fi; kill(pom); end zwieksz; (****************************************************************************) unit piszczas:procedure(t:real); var d,p,i:integer,r,x:real; begin x:=inxpos+16; p:=entier(t); for i:=1 to 3 do d:=p mod 10; call move(x,inypos); call hascii(0);call hascii(d+48); x:=x-8; p:=p div 10; if p=0 then exit fi; od; x:=x+(i+1)*8; call move(x,inypos); call hascii(0);call hascii(ord('.')); r:=t*1000; r:=r-(p*1000); p:=entier(r); x:=x+24; call move(x,inypos); for i:=1 to 3 do d:=p mod 10; call move(x,inypos); call hascii(0); call hascii(d+48); x:=x-8; p:=p div 10; od; call move(x+32,inypos); end piszczas; (****************************************************************************) UNIT PRIORITYQUEUE: CLASS; (* HEAP AS BINARY LINKED TREE WITH FATHER LINK*) UNIT QUEUEHEAD: CLASS; (* HEAP ACCESING MODULE *) VAR LAST,ROOT:NODE; UNIT MIN: FUNCTION: ELEM; BEGIN IF ROOT=/= NONE THEN RESULT:=ROOT.EL FI; END MIN; UNIT INSERT: PROCEDURE(R:ELEM); (* INSERTION INTO HEAP *) VAR X,Z:NODE; BEGIN X:= R.LAB; IF LAST=NONE THEN ROOT:=X; ROOT.LEFT,ROOT.RIGHT,LAST:=ROOT ELSE IF LAST.NS=0 THEN LAST.NS:=1; Z:=LAST.LEFT; LAST.LEFT:=X; X.UP:=LAST; X.LEFT:=Z; Z.RIGHT:=X; ELSE LAST.NS:=2; Z:=LAST.RIGHT; LAST.RIGHT:=X; X.RIGHT:=Z; X.UP:=LAST; Z.LEFT:=X; LAST.LEFT.RIGHT:=X; X.LEFT:=LAST.LEFT; LAST:=Z; FI FI; CALL CORRECT(R,FALSE) END INSERT; UNIT DELETE: PROCEDURE(R: ELEM); VAR X,Y,Z:NODE; BEGIN X:=R.LAB; Z:=LAST.LEFT; IF LAST.NS =0 THEN Y:= Z.UP; Y.RIGHT:= LAST; LAST.LEFT:=Y; LAST:=Y; ELSE Y:= Z.LEFT; Y.RIGHT:= LAST; LAST.LEFT:= Y; FI; Z.EL.LAB:=X; X.EL:= Z.EL; LAST.NS:= LAST.NS-1; R.LAB:=Z; Z.EL:=R; IF X.LESS(X.UP) THEN CALL CORRECT(X.EL,FALSE) ELSE CALL CORRECT(X.EL,TRUE) FI; END DELETE; UNIT CORRECT: PROCEDURE(R:ELEM,DOWN:BOOLEAN); (* CORRECTION OF THE HEAP WITH STRUCTURE BROKEN BY R *) VAR X,Z:NODE,T:ELEM,FIN,LOG:BOOLEAN; BEGIN Z:=R.LAB; IF DOWN THEN WHILE NOT FIN DO IF Z.NS =0 THEN FIN:=TRUE ELSE IF Z.NS=1 THEN X:=Z.LEFT ELSE IF Z.LEFT.LESS(Z.RIGHT) THEN X:=Z.LEFT ELSE X:=Z.RIGHT FI; FI; IF Z.LESS(X) THEN FIN:=TRUE ELSE T:=X.EL; X.EL:=Z.EL; Z.EL:=T; Z.EL.LAB:=Z; X.EL.LAB:=X FI; FI; Z:=X; OD ELSE X:=Z.UP; IF X=NONE THEN LOG:=TRUE ELSE LOG:=X.LESS(Z); FI; WHILE NOT LOG DO T:=Z.EL; Z.EL:=X.EL; X.EL:=T; X.EL.LAB:=X; Z.EL.LAB:=Z; Z:=X; X:=Z.UP; IF X=NONE THEN LOG:=TRUE ELSE LOG:=X.LESS(Z); FI; OD FI; END CORRECT; END QUEUEHEAD; UNIT NODE: CLASS (EL:ELEM); (* ELEMENT OF THE HEAP *) VAR LEFT,RIGHT,UP: NODE, NS:INTEGER; UNIT LESS: FUNCTION(X:NODE): BOOLEAN; BEGIN IF X= NONE THEN RESULT:=FALSE ELSE RESULT:=EL.LESS(X.EL) FI; END LESS; END NODE; UNIT ELEM: CLASS(PRIOR:REAL); (* PREFIX OF INFORMATION TO BE STORED IN NODE *) VAR LAB: NODE; UNIT VIRTUAL LESS: FUNCTION(X:ELEM):BOOLEAN; BEGIN IF X=NONE THEN RESULT:= FALSE ELSE RESULT:= PRIOR< X.PRIOR FI; END LESS; BEGIN LAB:= NEW NODE(THIS ELEM); END ELEM; END PRIORITYQUEUE; UNIT SIMULATION: PRIORITYQUEUE CLASS; (* THE LANGUAGE FOR SIMULATION PURPOSES *) VAR CURR: SIMPROCESS, (*ACTIVE PROCESS *) PQ:QUEUEHEAD, (* THE TIME AXIS *) MAINPR: MAINPROGRAM; UNIT SIMPROCESS: COROUTINE; (* USER PROCESS PREFIX *) VAR EVENT, (* ACTIVATION MOMENT NOTICE *) EVENTAUX: EVENTNOTICE, (* THIS IS FOR AVOIDING MANY NEW CALLS AS AN RESULT OF *) (* SUBSEQUENT PASSIVATIONS AND ACTIVATIONS *) FINISH: BOOLEAN; UNIT IDLE: FUNCTION: BOOLEAN; BEGIN RESULT:= EVENT= NONE; END IDLE; UNIT TERMINATED: FUNCTION :BOOLEAN; BEGIN RESULT:= FINISH; END TERMINATED; UNIT EVTIME: FUNCTION: REAL; (* TIME OF ACTIVATION *) BEGIN IF IDLE THEN CALL ERROR1; FI; RESULT:= EVENT.EVENTTIME; END EVTIME; UNIT ERROR1:PROCEDURE; BEGIN ATTACH(MAIN); call groff; WRITELN(" AN ATTEMPT TO ACCESS AN IDLE PROCESS TIME"); END ERROR1; UNIT ERROR2:PROCEDURE; BEGIN ATTACH(MAIN); call groff; WRITELN(" AN ATTEMPT TO ACCESS A TERMINATED PROCESS TIME"); END ERROR2; BEGIN RETURN; INNER; FINISH:=TRUE; CALL PASSIVATE; CALL ERROR2; END SIMPROCESS; UNIT EVENTNOTICE: ELEM CLASS; (* A PROCESS ACTIVATION NOTICE TO BE PLACED ONTO THE TIME AXIS PQ *) VAR EVENTTIME: REAL, PROC: SIMPROCESS; UNIT VIRTUAL LESS: FUNCTION(X: EVENTNOTICE):BOOLEAN; (* OVERWRITE THE FORMER VERSION CONSIDERING EVENTTIME *) BEGIN IF X=NONE THEN RESULT:= FALSE ELSE RESULT:= EVENTTIME< X.EVENTTIME OR (EVENTTIME=X.EVENTTIME AND PRIOR< X.PRIOR); FI; END LESS; END EVENTNOTICE; UNIT MAINPROGRAM: SIMPROCESS CLASS; (* IMPLEMENTING MASTER PROGRAM AS A PROCESS *) BEGIN DO ATTACH(MAIN) OD; END MAINPROGRAM; UNIT TIME:FUNCTION:REAL; (* CURRENT VALUE OF SIMULATION TIME *) BEGIN RESULT:=CURRENT.EVTIME END TIME; UNIT CURRENT: FUNCTION: SIMPROCESS; (* THE FIRST PROCESS ON THE TIME AXIS *) BEGIN RESULT:=CURR; END CURRENT; UNIT SCHEDULE: PROCEDURE(P:SIMPROCESS,T:REAL); (* ACTIVATION OF PROCESS P AT TIME T AND DEFINITION OF "PRIOR"- PRIORITY *) (* WITHIN TIME MOMENT T *) BEGIN IF T