block (*_______________________________________________________*) (* SYMULACJA RUCHU ULICZNEGO *) (*_______________________________________________________*) (* simulation class *) unit fifo:class; (* the type implementing fifo - queues *) hidden front, rear; signal fifoempty; var front, rear:fifoel; unit fifoel : class; var succ:fifoel; unit into:procedure(q:fifo); begin if q.front = none then q.front,q.rear := this fifoel else q.rear.succ, q.rear :=this fifoel fi end into; end fifoel; unit outfirst:procedure; begin if front = none then raise fifoempty else if rear = front then rear,front := none else front:=front.succ fi fi end outfirst; unit empty:function:boolean; begin result := front=none end empty; unit first:function:fifoel; begin result := front end first; unit cardinal:function:integer; var i:integer, aux:fifoel; begin aux := front; while aux =/= none do i:=i+1; aux:=aux.succ od; result := i end cardinal; end fifo; unit priorityqueue: fifo class; (* heap as binary linked tree with father link*) hidden node; unit queuehead: class; (* heap accessing module *) hidden last, root; 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; if x=root and root.ns=0 then root,last:= none else 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; 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 *) taken queuehead, elem, fifoel; hidden pq, curr, eventnotice, mainprogram, choiceprocess; var curr : simprocess, (*active process *) pq :queuehead, (* the time axis *) mainpr: mainprogram; unit simprocess:fifoel coroutine; (* user process prefix *) var event, (* activation moment notice *) eventpom: eventnotice, (* this is for avoiding many new calls as an result *) (* of subsequent passivations and activations *) finish: boolean; signal termproc, idleproc; 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 raise idleproc fi; result:= event.eventtime; end evtime; handlers (* default handlers for signals termproc and idleproc *) when termproc: writeln(" simprocess is terminated "); attach(mainpr); when idleproc: writeln(" simprocess is idle "); attach(mainpr); end handlers; begin return; inner; finish:=true; call passivate; raise termproc 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 programm 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 *) begin if t