Google
 

Trailing-Edge - PDP-10 Archives - decuslib20-03 - decus/20-0078/demos/qsim.sim
There are 4 other files named qsim.sim in the archive. Click here to see a list.
00100	BEGIN OPTIONS(/L); COMMENT display queue simulation;
00149	EXTERNAL TEXT PROCEDURE frontstrip, upcase, tmpin,
00201	scanto, storbokstav;
00300	EXTERNAL CHARACTER PROCEDURE getch, fetchar;
00400	EXTERNAL PROCEDURE depchar, forceout, outstring;
00500	EXTERNAL BOOLEAN PROCEDURE dotypeout, tmpout, meny;
00600	EXTERNAL INTEGER PROCEDURE trmop, gettab, checkreal, checkint;
00700	EXTERNAL REAL PROCEDURE clocktime;
00800	EXTERNAL PROCEDURE echo, abort, outchr;
00900	EXTERNAL CLASS vista, form, termty;
01000	INTEGER width, height, open_duration, open_time, close_time,
01100	terminal_type, english;
01200	BOOLEAN monitorecho, sim_started;
01300	TEXT message_total, message_arrival, message_between,
01400	message_wait;
01500	
01600	PROCEDURE inita_global;
01700	BEGIN CHARACTER c;
01800	 width:= 39; height:= 20;
01900	 monitorecho:= FALSE;
02000	 open_duration:= 240; open_time:= 480;
02100	 close_time:= open_time+open_duration;
02200	 IF english = 0 THEN
02300	 BEGIN
02400	  ask: outtext("Swedish or English?"); outimage;
02500	  inimage; c:= inchar;
02600	  IF c = 'E' OR c = 'e' THEN english:= 1
02700	  ELSE IF c = 'S' OR c = 's' THEN english := -1
02800	  ELSE GOTO ask;
02900	  message_total:- copy(IF english = 1 THEN
03000	  "During the day" ELSE "Tot under dagen");
03100	  message_arrival:- copy(IF english = 1 THEN
03200	  "Patient arrival" ELSE "N{r pat. kommer");
03300	  message_between:- copy(IF english = 1 THEN
03400	  "Between 0 and 999" ELSE "Mellan 0 och 999");
03500	  message_wait:- copy(IF english = 1 THEN
03600	  "Idling cost" ELSE "V{ntekostnad");
03700	 END;
03800	END;
     
03900	form CLASS queue_data;
04000	BEGIN
04100	 REF (side_data) left, right;
04200	 REF (statistics_field) doctor_value, patient_value;
04300	
04400	 CLASS side_data(wait_pos, cost_pos, offset);
04500	 INTEGER wait_pos, cost_pos, offset;
04600	 BEGIN
04700	  CHARACTER last_name;
04800	  INTEGER randno_doc, randno_pat;
04900	  INTEGER room_left, room_mid, room_right;
05000	  INTEGER numbers_at_open, doc_wait_sum, pat_wait_sum;
05100	  REF (updatefield) arrival_interval, number_of_patients;
05200	  PROCEDURE putstat;
05300	  BEGIN
05400	   move_the_cursor_to(wait_pos,16);
05500	   outint(doc_wait_sum,5);
05600	   move_the_cursor_to(wait_pos,17);
05700	   outint(pat_wait_sum,5);
05800	   move_the_cursor_to(wait_pos,19);
05900	   outint(doc_wait_sum+pat_wait_sum,5);
06000	   move_the_cursor_to(cost_pos,16);
06100	   outint(doc_wait_sum*doctor_value.intvalue,6);
06200	   move_the_cursor_to(cost_pos,17);
06300	   outint(pat_wait_sum*patient_value.intvalue,6);
06400	   move_the_cursor_to(cost_pos,19);
06500	   outint(doc_wait_sum*doctor_value.intvalue
06600	   + pat_wait_sum*patient_value.intvalue,6);
06700	  END;
06800	  last_name:= 'z';
06900	  room_left:= offset+6; room_right:= offset+15;
07000	  room_mid:= offset+8;
07100	 END;
07200	
07300	 PROCEDURE inita_sides;
07400	 BEGIN
07500	  left:- NEW side_data(7,0,0);
07600	  right:- NEW side_data(25,31,20);
07700	  left.arrival_interval:- NEW updatefield(1,3,NOTEXT,3,' ',
07800	  message_arrival,0,999,message_between,left);
07900	  right.arrival_interval:- NEW updatefield(27,3,NOTEXT,3,' ',
08000	  message_arrival,0,999,message_between,right);
08100	  left.number_of_patients:- NEW updatefield(1,4,NOTEXT,3,' ',
08200	  message_total,0,999,message_between,left);
08300	  right.number_of_patients:- NEW updatefield(30,4,NOTEXT,3,' ',
08400	  message_total,0,999,message_between,right);
08500	  doctor_value:- NEW statistics_field(24,13,NOTEXT,4,' ',
08600	  message_wait,0,9999,message_between);
08700	  patient_value:- NEW statistics_field(24,14,NOTEXT,4,' ',
08800	  message_wait,0,9999,message_between);
08900	  left.randno_doc:= clocktime;
09000	  IF mod(left.randno_doc,2) = 0 THEN left.randno_doc:=
09100	  left.randno_doc+1;
09200	  right.randno_doc:= left.randno_doc;
09300	  left.randno_pat:= left.randno_pat+2;
09400	  right.randno_pat:= left.randno_pat;
09500	 END;
09600	
09700	 PROCEDURE start_screen;
09800	 IF english = 1 THEN
09900	 BEGIN
10000	  screen[00]:= "Sim-time  7:52                       ";
10100	  screen[01]:= "Open time 8.00      Close time 12:00 ";
10200	  screen[02]:= "Mean treatment time 15 min/patient   ";
10300	  screen[03]:= "      min  Arrival interval     min  ";
10400	  screen[04]:= "       Number of pat. called         ";
10500	  screen[05]:= "       Number of pat. at open        ";
10600	  screen[06]:= "-------   -------   -------   -------";
10700	  screen[07]:= "!               !   !               !";
10800	  screen[08]:= "!               !   !               !";
10900	  screen[09]:= "!               !   !               !";
11000	  screen[10]:= "-------===-------   -------===-------";
11100	  screen[11]:= "!  O            !   !  O            !";
11200	  screen[12]:= "-------   -------   -------   -------";
11300	  screen[13]:= "Value of doctor's time:       $/hour ";
11400	  screen[14]:= "Value of patient's time:      $/hour ";
11500	  screen[15]:= "    $    min  Wait time    min     $ ";
11600	  screen[16]:= "               Doctor                ";
11700	  screen[17]:= "              Patients               ";
11800	  screen[18]:= "-------------------------------------";
11900	  screen[19]:= "                 Sum                 ";
12000	 END ELSE
12100	 BEGIN
12200	  screen[00]:= "Klockan:  7:52                       ";
12300	  screen[01]:= "@ppnas kl 8.00       St{ngs kl 12:00 ";
12400	  screen[02]:= "Medelbehandlingstid 15 min/patient   ";
12500	  screen[03]:= "      min  Ankomstintervall     min  ";
12600	  screen[04]:= "       Antal kallade patienter       ";
12700	  screen[05]:= "       Antal pat. vid `ppning        ";
12800	  screen[06]:= "-------   -------   -------   -------";
12900	  screen[07]:= "!               !   !               !";
13000	  screen[08]:= "!               !   !               !";
13100	  screen[09]:= "!               !   !               !";
13200	  screen[10]:= "-------===-------   -------===-------";
13300	  screen[11]:= "!  O            !   !  O            !";
13400	  screen[12]:= "-------   -------   -------   -------";
13500	  screen[13]:= "V{rde p} l{karens tid:        kr/tim ";
13600	  screen[14]:= "V{rde, patienternas tid:      kr/tim ";
13700	  screen[15]:= "    kr   min  V{ntetid     min     kr";
13800	  screen[16]:= "               L{karen               ";
13900	  screen[17]:= "             Patienterna             ";
14000	  screen[18]:= "-------------------------------------";
14100	  screen[19]:= "                Summa                ";
14200	 END;
14300	
14400	 intfield CLASS updatefield(side); REF (side_data) side;
14500	 IF sim_started THEN GOTO start ELSE
14600	 INSPECT side DO
14700	 BEGIN COMMENT update dependent value when new data is input;
14800	  numbers_at_open:= number_of_patients.intvalue
14900	  - open_duration/arrival_interval.intvalue;
15000	  move_the_cursor_to(number_of_patients.h,5);
15100	  outint(numbers_at_open,3);
15200	 END;
15300	
15400	 intfield CLASS statistics_field;
15500	 BEGIN COMMENT update statistics when new weights are input;
15600	  REF (side_data) side;
15700	  FOR side:- left, right DO side.putstat;
15800	 END;
15900	
16000	 PROCEDURE blip(c,h,v);
16100	 INTEGER h, v; CHARACTER c;
16200	 BEGIN
16300	  set_char_on_screen(c,h,v);
16400	  outchr(sysout,fill,10);
16500	  set_char_on_screen(' ',h,v);
16600	 END;
16700	
16800	 PROCEDURE bleep(c,h,v);
16900	 INTEGER h, v; CHARACTER c;
17000	 BEGIN
17100	  set_char_on_screen(c,h,v);
17200	  outchr(sysout,fill,50);
17300	  set_char_on_screen(' ',h,v);
17400	 END;
17500	END of queue_data;
     
17600	start:
17700	inita_global;
17800	queue_data
17900	(width, height, sysin, sysout, monitorecho, terminal_type,
18000	NOTEXT, NOTEXT)
18100	BEGIN
     
18200	 simulation CLASS sim_data;
18300	 BEGIN
18400	  REF (simulation_side) sim_left, sim_right, sim_side;
18500	
18600	  CLASS simulation_side(side); REF (side_data) side;
18700	  BEGIN
18800	   REF (head) waiting;
18900	   REF (sided_process) doc;
19000	   waiting:- NEW head;
19100	  END;
19200	
19300	  process CLASS sided_process(side, sim_side);
19400	  REF (side_data) side; REF(simulation_side) sim_side;
19500	  BEGIN
19600	  END;
19700	
19800	  sided_process CLASS doctor_data;
19900	  BEGIN
20000	   REAL start_of_wait;
20100	  END;
20200	
20300	  sided_process CLASS patient_data;
20400	  BEGIN
20500	   INTEGER placeh, placev; REAL start_of_wait;
20600	   CHARACTER myname;
20700	  END;
20800	
20900	  PROCEDURE inita_sim_data;
21000	  BEGIN
21100	   sim_started:= FALSE; terminal_type:= terminaltype;
21200	   start_screen; inita_sides;
21300	   show_page; restore_the_whole_screen;
21400	   ask_page;
21500	   hold(open_time-8); sim_started:= TRUE;
21600	   sim_left:- NEW simulation_side(left);
21700	   sim_right:- NEW simulation_side(right);
21800	  END;
21900	
22000	 END of sim_data;
     
22100	 sim_data CLASS sim_actions;
22200	 BEGIN
22300	
22400	  BOOLEAN PROCEDURE none_is_waiting;
22500	  none_is_waiting:= sim_left.waiting.empty AND
22600	  sim_right.waiting.empty;
22700	
22800	  PROCEDURE close_office; ACTIVATE main;
22900	
23000	  doctor_data CLASS doctor_actions;
23100	  BEGIN
23200	
23300	   PROCEDURE open_door;
23400	   INSPECT side DO
23500	   BEGIN
23600	    bleep('*',room_mid,12); bleep('*',room_mid,11);
23700	    set_char_on_screen('*',room_mid,11);
23800	    hold(2.0); set_char_on_screen(' ',room_mid,11);
23900	    blip('*',room_mid,10); blip('*',room_mid+1,10);
24000	    blip('*',room_mid,10); blip('*',room_mid-1,10);
24100	    bleep('*',room_mid-1,11); bleep('*',room_mid-2,11);
24200	    bleep('*',room_mid-3,11); bleep('*',room_mid-4,11);
24300	    set_char_on_screen('*',room_mid-6,11);
24400	   END;
24500	
24600	   PROCEDURE treat_patient(patient, duration);
24700	   REAL duration;
24800	   REF (patient_actions) patient;
24900	   BEGIN
25000	    ACTIVATE patient; COMMENT into office;
25100	    hold(duration); COMMENT hold during treatment;
25200	    ACTIVATE patient; COMMENT out of office;
25300	   END;
25400	
25500	   PROCEDURE doctor_wait;
25600	   BEGIN
25700	    IF time > close_time AND none_is_waiting
25800	    THEN close_office;
25900	    start_of_wait:= time;
26000	    passivate;
26100	    side.doc_wait_sum:=
26200	    side.doc_wait_sum+time-start_of_wait;
26300	   END;
26400	  END of doctor_actions;
26500	
26600	  patient_data CLASS patient_actions;
26700	  BEGIN
26800	
26900	   PROCEDURE find_seat;
27000	   INSPECT side DO
27100	   BEGIN INTEGER i;
27200	    last_name:= IF last_name = 'z' THEN 'a'
27300	    ELSE char(rank(last_name)+1);
27400	    myname:= last_name;
27500	    WHILE TRUE DO
27600	    BEGIN
27700	     FOR placev:= 7,9 DO
27800	     FOR placeh:= offset+1 STEP 1 UNTIL room_left,
27900	     offset+10 STEP 1 UNTIL room_right DO
28000	     IF get_char_from_screen(placeh,placev) = ' ' THEN
28100	     GOTO seat_found;
28200	     hold(5);
28300	    END;
28400	    seat_found:
28500	    bleep(myname,room_mid,6);
28600	    blip(myname,room_mid,7);
28700	    blip(myname,room_mid,8);
28800	    FOR i:= room_mid STEP 1 UNTIL placeh DO
28900	    blip(myname,i,8);
29000	    FOR i:= room_mid STEP -1 UNTIL placeh DO
29100	    blip(myname,i,8);
29200	    set_char_on_screen(myname,placeh,placev);
29300	   END of find_seat;
29400	
29500	   PROCEDURE patient_announce;
29600	   ACTIVATE sim_side.doc DELAY 0;
29700	
29800	   PROCEDURE patient_wait;
29900	   BEGIN
30000	    start_of_wait:= time;
30100	    wait(sim_side.waiting); out;
30200	    side.pat_wait_sum:= side.pat_wait_sum
30300	    + time - start_of_wait;
30400	    side.putstat;
30500	   END;
30600	
30700	   PROCEDURE to_doctor;
30800	   INSPECT side DO
30900	   BEGIN INTEGER i;
31000	    set_char_on_screen(' ',placeh,placev);
31100	    FOR i:= placeh STEP 1 UNTIL room_mid DO
31200	    blip(myname,i,8);
31300	    FOR i:= placeh STEP -1 UNTIL room_mid DO
31400	    blip(myname,i,8);
31500	    blip(myname,room_mid,8);
31600	    blip(myname,room_mid,9);
31700	    blip(myname,room_mid,10);
31800	    blip(myname,room_mid,11);
31900	    blip(myname,room_mid-1,11);
32000	    set_char_on_screen(myname,room_mid-2,11);
32100	    passivate;
32200	   END;
32300	
32400	   PROCEDURE from_doctor;
32500	   INSPECT side DO
32600	   BEGIN
32700	    set_char_on_screen(' ',room_mid-2,11);
32800	    blip(myname,room_mid-1,11);
32900	    blip(myname,room_mid,11);
33000	    bleep(myname,room_mid,12);
33100	   END;
33200	  END of patient_actions;
33300	
33400	  PROCEDURE treat_results;
33500	  BEGIN
33600	   dotypeout(sysout);
33700	   WHILE TRUE DO
33800	   resume(doctor_value);
33900	  END;
34000	
34100	  process CLASS clock;
34200	  WHILE TRUE DO
34300	  BEGIN move_the_cursor_to(9,0); outint(entier(time/60),2);
34400	   outchar(':'); outint(mod(time,60),2);
34500	   IF get_char_from_screen(12,0) = ' ' THEN
34600	   set_char_on_screen('0',12,0);
34700	   hold(1);
34800	  END;
34900	
35000	 END of sim_actions;
     
40000	 sim_actions
40100	 BEGIN
40200	  doctor_actions CLASS doctor;
40300	  BEGIN open_door;
40400	   WHILE TRUE DO
40500	   INSPECT sim_side.waiting.first WHEN patient DO
40600	   treat_patient(THIS patient, negexp(1/15,side.randno_doc))
40700	   OTHERWISE doctor_wait;
40800	  END;
40900	
41000	  sided_process CLASS door;
41100	  INSPECT side DO
41200	  BEGIN
41300	   WHILE time < close_time DO
41400	   BEGIN
41500	    hold(arrival_interval.intvalue);
41600	    ACTIVATE NEW patient(side,sim_side);
41700	    hold(arrival_interval.intvalue);
41800	   END;
41900	  END of door;
42000	
42100	  patient_actions CLASS patient;
42200	  BEGIN hold(normal(5,7,side.randno_pat));
42300	   find_seat;
42400	   patient_announce;
42500	   patient_wait;
42600	   to_doctor;
42700	   from_doctor;
42800	  END;
42900	
43000	  PROCEDURE perform_simulation;
43100	  BEGIN
43200	   start_simulation;
43300	   treat_results;
43400	  END;
43500	
43600	  PROCEDURE start_simulation;
43700	  BEGIN
43800	   inita_sim_data;
43900	   FOR sim_side:- sim_left, sim_right DO
44000	   INSPECT sim_side DO
44100	   BEGIN INTEGER i;
44200	    doc:- NEW doctor(side,sim_side);
44300	    ACTIVATE doc DELAY 8;
44400	    FOR i:= side.numbers_at_open STEP -1
44500	    UNTIL 1 DO ACTIVATE NEW patient(side,sim_side);
44600	    ACTIVATE NEW door(side,sim_side);
44700	   END;
44800	   ACTIVATE NEW clock;
44900	   passivate;
45000	  END;
45100	
45200	  perform_simulation;
45300	 END of block prefixed by sim_actions;
45400	END of block prefixed by queue_data;
45500	END of the whole program;