3 UNIT PRIORITYQUEUE: CLASS;
\r
4 (* HEAP AS BINARY LINKED TREE WITH FATHER LINK*)
\r
8 UNIT QUEUEHEAD: CLASS;
\r
9 (* HEAP ACCESING MODULE *)
\r
12 UNIT MIN: FUNCTION: ELEM;
\r
14 IF ROOT=/= NONE THEN RESULT:=ROOT.EL FI;
\r
17 UNIT INSERT: PROCEDURE(R:ELEM);
\r
18 (* INSERTION INTO HEAP *)
\r
24 ROOT.LEFT,ROOT.RIGHT,LAST:=ROOT
\r
45 CALL CORRECT(R,FALSE)
\r
48 UNIT DELETE: PROCEDURE(R: ELEM);
\r
65 LAST.NS:= LAST.NS-1;
\r
68 IF X.LESS(X.UP) THEN CALL CORRECT(X.EL,FALSE)
\r
69 ELSE CALL CORRECT(X.EL,TRUE) FI;
\r
72 UNIT CORRECT: PROCEDURE(R:ELEM,DOWN:BOOLEAN);
\r
73 (* CORRECTION OF THE HEAP WITH STRUCTURE BROKEN BY R *)
\r
74 VAR X,Z:NODE,T:ELEM,FIN,LOG:BOOLEAN;
\r
79 IF Z.NS =0 THEN FIN:=TRUE ELSE
\r
80 IF Z.NS=1 THEN X:=Z.LEFT ELSE
\r
81 IF Z.LEFT.LESS(Z.RIGHT) THEN X:=Z.LEFT ELSE X:=Z.RIGHT
\r
83 IF Z.LESS(X) THEN FIN:=TRUE ELSE
\r
94 IF X=NONE THEN LOG:=TRUE ELSE LOG:=X.LESS(Z); FI;
\r
103 IF X=NONE THEN LOG:=TRUE ELSE LOG:=X.LESS(Z);
\r
112 UNIT NODE: CLASS (EL:ELEM);
\r
113 (* ELEMENT OF THE HEAP *)
\r
114 VAR LEFT,RIGHT,UP: NODE, NS:INTEGER;
\r
115 UNIT LESS: FUNCTION(X:NODE): BOOLEAN;
\r
117 IF X= NONE THEN RESULT:=FALSE
\r
118 ELSE RESULT:=EL.LESS(X.EL) FI;
\r
123 UNIT ELEM: CLASS(PRIOR:REAL);
\r
124 (* PREFIX OF INFORMATION TO BE STORED IN NODE *)
\r
126 UNIT VIRTUAL LESS: FUNCTION(X:ELEM):BOOLEAN;
\r
128 IF X=NONE THEN RESULT:= FALSE ELSE
\r
129 RESULT:= PRIOR< X.PRIOR FI;
\r
132 LAB:= NEW NODE(THIS ELEM);
\r
140 UNIT SIMULATION: PRIORITYQUEUE CLASS;
\r
141 (* THE LANGUAGE FOR SIMULATION PURPOSES *)
\r
143 VAR CURR: SIMPROCESS, (*ACTIVE PROCESS *)
\r
144 PQ:QUEUEHEAD, (* THE TIME AXIS *)
\r
145 MAINPR: MAINPROGRAM;
\r
148 UNIT SIMPROCESS: COROUTINE;
\r
149 (* USER PROCESS PREFIX *)
\r
150 VAR EVENT, (* ACTIVATION MOMENT NOTICE *)
\r
151 EVENTAUX: EVENTNOTICE,
\r
152 (* THIS IS FOR AVOIDING MANY NEW CALLS AS AN RESULT OF *)
\r
153 (* SUBSEQUENT PASSIVATIONS AND ACTIVATIONS *)
\r
156 UNIT IDLE: FUNCTION: BOOLEAN;
\r
158 RESULT:= EVENT= NONE;
\r
161 UNIT TERMINATED: FUNCTION :BOOLEAN;
\r
166 UNIT EVTIME: FUNCTION: REAL;
\r
167 (* TIME OF ACTIVATION *)
\r
169 IF IDLE THEN CALL ERROR1;
\r
171 RESULT:= EVENT.EVENTTIME;
\r
174 UNIT ERROR1:PROCEDURE;
\r
177 WRITELN(" AN ATTEMPT TO ACCESS AN IDLE PROCESS TIME");
\r
180 UNIT ERROR2:PROCEDURE;
\r
183 WRITELN(" AN ATTEMPT TO ACCESS A TERMINATED PROCESS TIME");
\r
195 UNIT EVENTNOTICE: ELEM CLASS;
\r
196 (* A PROCESS ACTIVATION NOTICE TO BE PLACED ONTO THE TIME AXIS PQ *)
\r
197 VAR EVENTTIME: REAL, PROC: SIMPROCESS;
\r
199 UNIT VIRTUAL LESS: FUNCTION(X: EVENTNOTICE):BOOLEAN;
\r
200 (* OVERWRITE THE FORMER VERSION CONSIDERING EVENTTIME *)
\r
202 IF X=NONE THEN RESULT:= FALSE ELSE
\r
203 RESULT:= EVENTTIME< X.EVENTTIME OR
\r
204 (EVENTTIME=X.EVENTTIME AND PRIOR< X.PRIOR); FI;
\r
210 UNIT MAINPROGRAM: SIMPROCESS CLASS;
\r
211 (* IMPLEMENTING MASTER PROGRAM AS A PROCESS *)
\r
213 DO ATTACH(MAIN) OD;
\r
216 UNIT TIME:FUNCTION:REAL;
\r
217 (* CURRENT VALUE OF SIMULATION TIME *)
\r
219 RESULT:=CURRENT.EVTIME
\r
222 UNIT CURRENT: FUNCTION: SIMPROCESS;
\r
223 (* THE FIRST PROCESS ON THE TIME AXIS *)
\r
228 UNIT SCHEDULE: PROCEDURE(P:SIMPROCESS,T:REAL);
\r
229 (* ACTIVATION OF PROCESS P AT TIME T AND DEFINITION OF "PRIOR"- PRIORITY *)
\r
230 (* WITHIN TIME MOMENT T *)
\r
232 IF T<TIME THEN T:= TIME FI;
\r
233 IF P=CURRENT THEN CALL HOLD(T-TIME) ELSE
\r
234 IF P.IDLE AND P.EVENTAUX=NONE THEN (* HAS NOT BEEN SCHEDULED YET*)
\r
235 P.EVENT,P.EVENTAUX:= NEW EVENTNOTICE(RANDOM);
\r
238 IF P.IDLE (* P HAS ALREADY BEEN SCHEDULED *) THEN
\r
239 P.EVENT:= P.EVENTAUX;
\r
240 P.EVENT.PRIOR:=RANDOM;
\r
242 (* NEW SCHEDULING *)
\r
243 P.EVENT.PRIOR:=RANDOM;
\r
244 CALL PQ.DELETE(P.EVENT)
\r
246 P.EVENT.EVENTTIME:= T;
\r
247 CALL PQ.INSERT(P.EVENT) FI;
\r
250 UNIT HOLD:PROCEDURE(T:REAL);
\r
251 (* MOVE THE ACTIVE PROCESS T MINUTES BACK ALONG PQ *)
\r
252 (* REDEFINE PRIOR *)
\r
254 CALL PQ.DELETE(CURRENT.EVENT);
\r
255 CURRENT.EVENT.PRIOR:=RANDOM;
\r
256 IF T<0 THEN T:=0; FI;
\r
257 CURRENT.EVENT.EVENTTIME:=TIME+T;
\r
258 CALL PQ.INSERT(CURRENT.EVENT);
\r
259 CALL CHOICEPROCESS;
\r
262 UNIT PASSIVATE: PROCEDURE;
\r
263 (* REMOVE THE ACTVE PROCESS FROM PQ AND ACTIVATE THE NEXT ONE *)
\r
265 CALL PQ.DELETE(CURRENT.EVENT);
\r
266 CURRENT.EVENT:=NONE;
\r
270 UNIT RUN: PROCEDURE(P:SIMPROCESS);
\r
271 (* ACTIVATE P IMMEDIATELY AND DELAY THE FORMER FIRST PROCESS BY REDEFINING*)
\r
274 CURRENT.EVENT.PRIOR:=RANDOM;
\r
277 P.EVENT.EVENTTIME:=TIME;
\r
278 CALL PQ.CORRECT(P.EVENT,FALSE)
\r
280 IF P.EVENTAUX=NONE THEN
\r
281 P.EVENT,P.EVENTAUX:=NEW EVENTNOTICE(0);
\r
282 P.EVENT.EVENTTIME:=TIME;
\r
284 CALL PQ.INSERT(P.EVENT)
\r
286 P.EVENT:=P.EVENTAUX;
\r
288 P.EVENT.EVENTTIME:=TIME;
\r
290 CALL PQ.INSERT(P.EVENT);
\r
292 CALL CHOICEPROCESS;
\r
295 UNIT CANCEL:PROCEDURE(P: SIMPROCESS);
\r
296 (* REMOVE PROCESS P FROM PQ AND CONTINUE SIMULATION *)
\r
298 IF P= CURRENT THEN CALL PASSIVATE ELSE
\r
299 CALL PQ.DELETE(P.EVENT);
\r
303 UNIT CHOICEPROCESS:PROCEDURE;
\r
304 (* CHOOSE THE FIRST PROCESS FROM PQ TO BE ACTIVATED *)
\r
308 CURR:= PQ.MIN QUA EVENTNOTICE.PROC;
\r
310 WRITE(" ERROR IN THE HEAP"); WRITELN;
\r
312 ELSE ATTACH(CURR); FI;
\r
316 PQ:=NEW QUEUEHEAD; (* SIMULATION TIME AXIS*)
\r
317 CURR,MAINPR:=NEW MAINPROGRAM;
\r
318 MAINPR.EVENT,MAINPR.EVENTAUX:=NEW EVENTNOTICE(0);
\r
319 MAINPR.EVENT.EVENTTIME:=0;
\r
320 MAINPR.EVENT.PROC:=MAINPR;
\r
321 CALL PQ.INSERT(MAINPR.EVENT);
\r
322 (* THE FIRST PROCESS TO BE ACTIVATED IS MAIN PROGRAM *)
\r
329 UNIT LISTS:SIMULATION CLASS;
\r
330 (* WE WISH TO USE LISTS FOR QUEUEING PROCESSES DURING SIMULATION*)
\r
332 UNIT LINKAGE:CLASS;
\r
333 (*WE WILL USE TWO WAY LISTS *)
\r
334 VAR SUC1,PRED1:LINKAGE;
\r
336 UNIT HEAD:LINKAGE CLASS;
\r
337 (* EACH LIST WILL HAVE ONE ELEMENT ESTABLISHED *)
\r
338 UNIT FIRST:FUNCTION:LINK;
\r
340 IF SUC1 IN LINK THEN RESULT:=SUC1
\r
341 ELSE RESULT:=NONE FI;
\r
343 UNIT EMPTY:FUNCTION:BOOLEAN;
\r
345 RESULT:=SUC1=THIS LINKAGE;
\r
348 SUC1,PRED1:=THIS LINKAGE;
\r
351 UNIT LINK:LINKAGE CLASS;
\r
352 (* ORDINARY LIST ELEMENT PREFIX *)
\r
353 UNIT OUT:PROCEDURE;
\r
355 IF SUC1=/=NONE THEN
\r
358 SUC1,PRED1:=NONE FI;
\r
360 UNIT INTO:PROCEDURE(S:HEAD);
\r
365 IF S.SUC1=/=NONE THEN
\r
368 PRED1.SUC1:=THIS LINKAGE;
\r
369 S.PRED1:=THIS LINKAGE;
\r
374 UNIT ELEM:LINK CLASS(SPROCESS:SIMPROCESS);
\r
375 (* USER DEFINED PROCESS WILL BE JOINED INTO LISTS *)
\r
381 unit numero : class(val : real;choix:integer);
\r
385 unit liste : class;
\r
386 var tete, queue : numero;
\r
389 unit listevide : function : boolean;
\r
391 if tete = NONE then result := true fi
\r
394 unit supprime : procedure(inout valeur:real;inout choix:integer);
\r
410 unit ajout : procedure(e : real;choix:integer);
\r
413 if listevide then tete, queue := new numero(e,choix)
\r
414 else aux := new numero(e,choix);
\r
420 unit member : function(e : integer) : boolean;
\r
423 if listevide then exit fi;
\r
425 do if aux = NONE then exit fi;
\r
426 if aux.val = e then result := true;
\r
428 else aux := aux.next
\r
433 unit delliste : procedure;
\r
436 do if listevide then exit fi;
\r
446 unit station : LISTS class;
\r
447 unit prioritaire:procedure;
\r
452 numero_prioritaire:=1;
\r
453 for i:=2 to nombre_machine
\r
455 if( contenu(i)<min )
\r
458 numero_prioritaire:=i
\r
462 unit arrivee_client:simprocess class(nombre_machine,nombre_client:integer);
\r
466 for i:=1 to nombre_client
\r
468 if( random*10 < 10 )
\r
470 (* choix machine *)
\r
472 writeln("ARRIVEE : nouveau client sur machine ",
\r
473 numero_prioritaire);
\r
477 call l(numero_prioritaire).ajout(time,1);
\r
479 if( r*10 >= 3 ) AND (r*10 < 6 )
\r
481 call l(numero_prioritaire).ajout(time,2);
\r
485 call l(numero_prioritaire).ajout(time,3);
\r
488 contenu(numero_prioritaire):=contenu(numero_prioritaire)+1;
\r
489 call hold((nombre_machine+1)*base_temps);
\r
495 writeln("ARRIVEE : FIN DES ARRIVEES");
\r
497 call hold((nombre_machine+1)*base_temps);
\r
499 end arrivee_client;
\r
501 unit machine:simprocess class(base_temps,numero:integer);
\r
503 total,nombre,heure,valeur:real,
\r
508 while( ( termine = 0 ) OR ( not l(numero).listevide) )
\r
510 if( not l(numero).listevide )
\r
512 writeln("MACHINE nø",numero," : mise en marche. ");
\r
514 call l(numero).supprime(valeur,choix);
\r
515 writeln("MACHINE nø",numero," : client arrive a ",valeur);
\r
516 writeln("MACHINE nø",numero," : client servit a ",heure);
\r
517 total:=total+(heure-valeur);
\r
519 nbre_client(numero):=nbre_client(numero)+1;
\r
520 writeln(" MMMMMMMMMMMMMMMMMMMMMMMMM choix :",choix);
\r
524 writeln(" MACHINE nø",numero," : prelavage de la voiture ",
\r
526 call hold(5*(nombre_machine+1)*base_temps);
\r
530 writeln(" MACHINE nø",numero," : lavage de la voiture ",nombre);
\r
531 call hold(10*(nombre_machine+1)*base_temps);
\r
535 writeln(" MACHINE nø",numero," : lustrage de la voiture ",
\r
537 call hold(10*(nombre_machine+1)*base_temps);
\r
541 writeln(" MACHINE nø",numero," : rincage de la voiture ",nombre);
\r
542 contenu(numero):=contenu(numero)-1;
\r
546 call hold(5*(nombre_machine+1)*base_temps);
\r
550 writeln("MACHINE nø",numero," : mise a jour resultat -->",total/nombre);
\r
551 resultat(numero):=total/nombre;
\r
554 writeln("MACHINE nø",numero," ARRET DE LA MACHINE");
\r
556 call hold((nombre_machine+1)*base_temps);
\r
564 k,termine,numero_prioritaire:integer,
\r
565 contenu:arrayof integer,
\r
566 fini,nombre_machine,nombre_client,numero_machine:integer,
\r
567 resultat:arrayof real,
\r
568 moyenne,base_temps,base_temps2:real,
\r
569 nbre_client:arrayof integer;
\r
573 UNIT GENERATOR:SIMPROCESS CLASS;
\r
576 for k:=1 to nombre_machine
\r
578 CALL SCHEDULE(NEW machine(base_temps,k),TIME+k*base_temps);
\r
580 CALL SCHEDULE(NEW arrivee_client(nombre_machine,nombre_client),
\r
581 TIME+k*base_temps);
\r
585 write("MAIN : donner le nombre de machines:");
\r
586 readln(nombre_machine);
\r
587 write("MAIN : donner le nombre de clients:");
\r
588 readln(nombre_client);
\r
589 write("MAIN : donner la base de temps:");
\r
590 readln(base_temps);
\r
591 write("MAIN : donner la tempo du main:");
\r
592 readln(base_temps2);
\r
595 numero_prioritaire:=1;
\r
596 array nbre_client dim(1:nombre_machine);
\r
597 array contenu dim(1:nombre_machine);
\r
598 array l dim (1:nombre_machine);
\r
599 array resultat dim (1:nombre_machine);
\r
600 for k:=1 to nombre_machine
\r
605 for k:=1 to nombre_machine
\r
612 CALL SCHEDULE(NEW GENERATOR,TIME);
\r
614 while (fini<nombre_machine)
\r
616 call hold(base_temps2);
\r
619 for k:=1 to nombre_machine
\r
621 writeln("MAIN: resultat machine numero ",k," = ",resultat(k));
\r
622 writeln("MAIN : nombre de client machine numero ",k," = ",
\r
624 moyenne:=moyenne+resultat(k);
\r
626 writeln("MAIN : le temps d'attente moyen pour laver sa voiture est ",
\r
627 moyenne/nombre_machine);
\r