System: simulator

Directory path: /home/oo1/oo1home/mt1/le_demos/mfg_simulator/

Created on: Wed Aug 26 15:48:06 2015

HAMILTON TECHNOLOGIES INC. Collector Version: 6.1; Copyright 1991-2015.

This system has been defined in USL, automatically analyzed, automatically generatated/resource allocated (RAT)ed to C code, and automatically documented in HTML using the 001 Toolsuite.

CONTENTS

Manufacturing Simulation Example System

TOPICS ADDRESSED

* In-Depth Modeling Techniques of real-world processes.

INTRODUCTION

This system presents a pure logical model of a manufacturing process. The model uses a discrete-event style algorithm having a queue of events, a queue of ready jobs and a set of available machines. It also maintains a history of the jobs as they are processed by machines with the appropriate capabilities.

DETAILED ALGORITHM DESCRIPTION

The following description assumes that you have a graphical representation of the TMap handy, SimDB TMap.

The manufacturing simulator database, SimDB, is decomposed as a set of Events, a set of Machines, a ReadyQ and a History. Events is a queue of events currently being processed. Each Event in Events, has an associated Time that is relative to a preceding Event being processed. Time, here, is represented by a natural number (Nat). Each Event can be classified to be one of two EventTypes, a Job or a Machine event. An Event that is a Job EventType is used to simulate Jobs that are to be processed by a Machine. A job to be processed on a particular machine type (machType) is put onto the readyQ to wait for a free machine with a priority given to it by the readyQ. The events queue is set up to have an initial set of Job Events to be simulated. A Machine EventType represents a machine performing an operation (a jobProcess jobOperation) on a Job object. Completion of the jobProcess jobOperation will release the machine for another job. When all jobProcess jobOperations of a job are completed, the job is put into History.

To start the simulation, the Events queue is populated with an initial set of Events as Job EventTypes (that are loaded from a file of Jobs). The Machines that can be used to process Jobs are also loaded from a file at the start of the simulation. The current time of the simulation is updated as each Job Event is removed from the Events queue. The simulation time (initially set to zero) is updated by using the relative time of an Event to an earlier Event; or, if the event is concurrent with the last event to be scheduled, the simulation time is not changed.

When an Event is removed from the Events queue, it is checked to determine if it is a Job event or a Machine Event. If the event removed is a Machine (EventType), the Machine is returned to the set of available Machine resources. If it is a Job Event, then this Event is placed on the ReadyQ and receives the current Priority of the ReadyQ incremented by “1”. The priority number (a Nat) of the ReadyQ initially starts at “0” and then for each job put onto the readyQ is incremented by “1”.

When the right Machine resource is available, the Job is allocated to the Machine by removing the Job from the ReadyQ and putting the Job into the Job place-holder within a Machine object. This placeholder mimics the logic of a physical place for putting a job on a machine. Jobs can only be processed on Machines that have a matching MachType (Str). The Machine that is to process the Job must also have a machine capability (i.e. a Capa Name) that matches the jobOperation Name of a JobProcess that is to be performed on a Part object whose manufacturing is being simulated. After a Job is allocated to a Machine, the Machine is removed from the set of available Machines and a Machine EventType of Event is made. This new Machine Event is given a relative time from the current simulation time (offset) into the future, designating when the Machine will become free and available to process the next highest priority Job. This Machine event is scheduled by inserting it into the Events queue at a time and position relative to an earlier Event. The time of the Event and surrounding Event times are adjusted if necessary to make this insertion.

Concurrent Events are represented as neighboring Events that have relative times of zero. As a Job moves from Machine to Machine, dictated by its jobProcess jobOperation sequence, its Times are updated (e.g., processtime} to keep track of its timing behavior as it flows through the manufacturing system of Machines. After the last jobOperation of a JobProcess of a Part has been completed, the Job is removed from a Machine and transferred to the History set of Jobs. After the simulation is complete, simulation reports can be made by accessing the Job time information of the History of Jobs.

Overview of Models

The following section gives an overview of the functionality of the system. The functions in the overview are listed in the order in which they first appear.

TMAP

OPERATIONS and STRUCTURES

1 simulator.

simulator processes a simulation database that is loaded from a file named "./input.simdb.omap". The user then is free to edit and store the simulation database before a run. The database queues are examined to determine which events to process. This is repeated until both queues are empty. When the simulation is complete, the results are presented to the user running the simulation. And finally, the results (which may have been edited by the user) are stored to disk in the file named "./output.simdb.omap".

(simulator.c)

simulator uses os0 (which is of type os) to produce os (which is of type os). Following is a list of the types of objects being used by this FMap:

Interface: os:os=simulator(os0:os)

Create the STRing object omapPATH with the value "./input.". Create the STRing object displayPATH with the value "./input.". The function Simulate is to be repeated. is_Finished checks if both the ready queue and the events queue of the simulation database (S0) are empty. If they are, then isf will be "TRUE"; otherwise, it will be "FALSE".The decision, end_or_not, chooses one of the following alternatives based on the result of copy:boolean: Do_Next_Event or clone1:SimDB.

If copy:boolean (of end_or_not) returns FALSE, then Do_Next_Event is done as follows. Process_Queue processes the events queue of the simulation database, S0, resulting in S1. An event is selected. If the event is a job, then it is put onto the readyQ. If the event is a machine event, then a machine resource is released for use by other jobs. Do_Events processes the jobs on the ready queue of the simulation database, S1, resulting in Sn. If the ready jobs to be processed is empty, S1 is returned as Sn with no change. If there are more jobs that are ready than can be handled by the set of available machines in the resource pool, those remaining jobs will be processed in a successive interation of the simulation, once allocated machines have been put back into the resource pool. Repeat the ancestor function Simulate with the following input changes: replace S0 with Sn.

If copy:boolean (of end_or_not) returns TRUE, then clone1:SimDB is done as follows. S is assigned to be the same object as S0. Create the STRing object storepath with the value "./output.". Ignore Sx and identify os as the same object as os0.

1.1 loadeditstoredisplay.

loadeditstoredisplay loads an object of type TYPE using the path, omappath. Once loaded, the object is displayed using the configuration in a display file:

displaypath/typename.omap

After the user has a chance to edit the OMap, it is stored to disk and the result is returned as t.

()

loadeditstoredisplay uses omappath (which is of type str) and displaypath (which is of type str) to produce t (which is of type Any). Following is a list of the types of objects being used by this FMap:

Function, readtmap:TYPE, uses inputs: os to produce: tm (of type tmap). Object typenm is the node name of the TMap object tm. Create the STRing object fnm0 with the value ".omap". Concatenate typenm with fnm0 as indicated by "<". Object dfnm is a copy of the STRing object omfnm0. Concatenate omappath with omfnm0 as indicated by "<". ***** NOT DOCUMENTED --> Case_Str *****om0 is the OMap read from the file specified by object omfnm2. tm specifies the top node TMap that was used to originally store the OMap to file. If the file specified does not exists, the OMap editor is invoked. The decision, reject_or_not, chooses one of the following alternatives based on the result of isreject:omap: clone1:omap or load_rejected.

If isreject:omap (of reject_or_not) returns FALSE, then clone1:omap is done as follows. om1 is assigned to be the same object as om0.

If isreject:omap (of reject_or_not) returns TRUE, then load_rejected is done as follows. Function, k:TYPE, uses inputs: omfnm2 to produce: new_object (of type Any). Function, convert:omap:TYPE, uses inputs: new_object to produce: om1 (of type omap). Concatenate displaypath with dfnm as indicated by "<". Concatenate ".display" with dfnm1 as indicated by ">". Use the omap editor to provide the user with an interactive edit session for the input omap, om1. The file, dfnm2, is used to provide layout information for the initial display. The output omap, om2, is an updated version of om1, based on the edit session. OMap object om2 is stored to the file specified by object omfnm2. b2 is set to 'TRUE' if the operation completes successfully, 'FALSE' otherwise. Ignore b2 and identify om3 as the same object as om2. Function, convert:TYPE:omap, uses inputs: om3 to produce: t (of type Any).

1.2 is_finished.

is_finished checks if both the ready queue and the events queue of the simulation database (SDB) are empty. If they are, then finished will be "TRUE"; otherwise, it will be "FALSE".

(is_finished.c)

is_finished uses SDB (which is of type SimDB) to produce finished (which is of type boolean). Following is a list of the types of objects being used by this FMap:

Interface: finished:boolean=is_Finished(SDB:SimDB)

If readyJobs is an empty set, then emptyRQ is "TRUE"; otherwise it is "FALSE". Move to events, events, of SimDB, SDB. If events is an empty set, then emptyEs is "TRUE"; otherwise it is "FALSE". If the BOOLEANs emptyEs and emptyRQ are both 'TRUE', then finished is 'TRUE'; otherwise, it is 'FALSE'.

1.2.1 to_2.

to_2 goes to the 1, a Any, of 3, a Any.

()

to_2 uses 3 (which is of type Any) to produce 1 (which is of type Any). All objects in this FMap are of type Any. Function, moveto:2:3, uses inputs: 3 to produce: 2 (of type Any). Function, moveto:1:2, uses inputs: 2 to produce: 1 (of type Any).

1.3 process_queue.

process_queue processes the events queue of the simulation database, simDB, resulting in S. An event is selected. If the event is a job, then it is put onto the readyQ. If the event is a machine event, then a machine resource is released for use by other jobs.

(process_queue.c)

process_queue uses simDB (which is of type SimDB) to produce S (which is of type SimDB). Following is a list of the types of objects being used by this FMap:

Interface: S:SimDB=Process_Queue(simDB:SimDB)

Move to events, Es, of SimDB, simDB. The decision, isEventsQueueEmpty_or_not, chooses one of the following alternatives based on the result of isEmpty:events: EventsQueueNOTempty or clone1:SimDB.

If isEmpty:events (of isEventsQueueEmpty_or_not) returns FALSE, then EventsQueueNOTempty is done as follows. Select_Event removes an event E from the events queue of the simulation database simDB. The simulation clock time of simDB is revised by adding the event time of E to simDB's clock time to get an updated simDB simulation clock time for S0. Move to eventtype, et, of an_event, E. The decision, isReadyJob_or_ReleaseResourceEvent, chooses one of the following alternatives based on the result of is:Job:eventtype: Release_Resource or Put_Onto_ReadyQ.

If is:Job:eventtype (of isReadyJob_or_ReleaseResourceEvent) returns FALSE, then Release_Resource is done as follows. Release_Resource returns the machine associated with E to the set of free machines after it has finished processing. The jobProcess is evaluated to determine if all of the jobOperations have been completed. If so, then the history is updated; otherwise, the job with its next jobOperation is inserted into the ready queue according to its original priority. This results in S0 being updated to be S.

If is:Job:eventtype (of isReadyJob_or_ReleaseResourceEvent) returns TRUE, then Put_Onto_ReadyQ is done as follows. Put_Onto_ReadyQ updates the simulation database, S0, readyQ with an_event, E, job eventtype. First, the current simulation readytime is assigned to the job. Then, a new readyQ priority is made by adding a "1" to the current, old priority. This new priority is then assigned to the job. Finally, the job that was removed from the E and now deemed to be a ready job is inserted at the end of the jobs of the readyQ. The simulation database, S, containing this updated reayQ is returned as output to Put_Onto_ReadyQ.

If isEmpty:events (of isEventsQueueEmpty_or_not) returns TRUE, then clone1:SimDB is done as follows. S is assigned to be the same object as simDB.

1.3.1 select_event.

select_event removes an event E from the events queue of the simulation database S0. The simulation clock time of S0 is revised by adding the event time of E to S0's clock time to get an updated S0 simulation clock time for S.

(select_event.c)

select_event uses S0 (which is of type SimDB) to produce S (which is of type SimDB) and E (which is of type an_event). Following is a list of the types of objects being used by this FMap:

Interface: S:SimDB=Select_Event(S0:SimDB)

Move to events, Es, of SimDB, S0. Es0 is the same object as Es with its current element located at "0". Remove the element E from the Events set Es0 in the direction indicated by "R" from the current element. Es0 now becomes Es1. Go upto the SimDB, S1, containing Es1. Move to time, relative_time, of an_event, E. Get oldtime (a nat) from S1 (a SimDB). S1 now becomes S2. Add relative_time and oldtime (both NATural numbers) to get newtime. Put newtime (a nat) into S2 (a SimDB) to produce S.

1.3.2 release_resource.

release_resource returns the machine associated with event to the set of free machines after it has finished processing. The jobProcess is evaluated to determine if all of the jobOperations have been completed. If so, then the history is updated; otherwise, the job with its next jobOperation is inserted into the ready queue according to its original priority. This results in simDB being updated to be S.

(release_resource.c)

release_resource uses simDB (which is of type SimDB) and event (which is of type an_event) to produce S (which is of type SimDB). Following is a list of the types of objects being used by this FMap:

Interface: S:SimDB=Release_Resource_Event(simDB:SimDB)

Move to eventtype, et, of an_event, event. Get M0 (a machine) from et (a eventtype). et now becomes et1. Ignore et1 and identify M1 as the same object as M0. Get J0 (a job) from M1 (a machine). M1 now becomes M2. Move to time, endtime, of SimDB, simDB. Job_State_Update is stubbed out.Move to jobprocess, P, of job, J1. Machine_State_Update currently just returns M2 to the resource pool of simDB resulting in S1. Further expansion of this FMap could update the utilization time of the machine so that later analysis could determine how often it was used.The decision, JobProcessFinished_or_not, chooses one of the following alternatives based on the result of atnull:jobprocess: Priority_Insert or Update_History.

If atnull:jobprocess (of JobProcessFinished_or_not) returns FALSE, then Priority_Insert is done as follows. Priority_Insert recursively goes through the ready jobs of the readyQ of S1 in order to insert a new job, J1, into the ready queue. Each job has an priority number (represented as a Nat) indicating its importance. Lower priority numbers are more important than higher priority numbers. When a larger priority numbered job (i.e., a job of less importance) is found, then the new job is inserted to the left, before, the lower priority job in the ready job queue. This results in an updated simulation database S.

If atnull:jobprocess (of JobProcessFinished_or_not) returns TRUE, then Update_History is done as follows. Update_History logs the job completion time, endtime of J1, by putting endtime into times of the completed job, J1. Then, the simulation database, S1, is updated by inserting the finished job into the history of S1 resulting in S.

1.3.2.1 job_state_update.

job_state_update is stubbed out.

(job_state_update.c)

job_state_update uses time (which is of type nat), machine (which is of type machine) and job (which is of type job) to produce J (which is of type job). Following is a list of the types of objects being used by this FMap:

Interface: J:job=Job_State_Update(time:nat,machine:machine)

Ignore time and identify M as the same object as machine. Ignore M and identify J as the same object as job.

1.3.2.2 machine_state_update.

machine_state_update currently just returns machine to the resource pool of simDB resulting in S. Further expansion of this FMap could update the utilization time of the machine so that later analysis could determine how often it was used.

( machine_state_update.c)

machine_state_update uses time (which is of type nat), machine (which is of type machine) and simDB (which is of type SimDB) to produce S (which is of type SimDB). Following is a list of the types of objects being used by this FMap:

Interface: S:SimDB=Machine_State_Update(time:nat,machine:machine)

Ignore time and identify simDB1 as the same object as simDB. Move to machines, Ms, of SimDB, simDB1. Insert a new element machine into Ms, in the ">" direction from the current element, to get Ms1. Go upto the SimDB, S, containing Ms1.

1.3.2.3 priority_insert.

priority_insert recursively goes through the ready jobs of the readyQ of simDB in order to insert a new job, job, into the ready queue. Each job has an priority number (represented as a Nat) indicating its importance. Lower priority numbers are more important than higher priority numbers. When a larger priority numbered job (i.e., a job of less importance) is found, then the new job is inserted to the left, before, the lower priority job in the ready job queue. This results in an updated simulation database S.

(priority_insert.c)

priority_insert uses job (which is of type job) and simDB (which is of type SimDB) to produce S (which is of type SimDB). Following is a list of the types of objects being used by this FMap:

Interface: S:SimDB=Priority_Insert(job:job)

Move to readyQ, RQ, of SimDB, simDB. Move to jobs, RJs0, of readyQ, RQ. The decision, empty_readyJobs_or_NOT, chooses one of the following alternatives based on the result of isEmpty:jobs: isNOT_empty or insert:jobs.

If isEmpty:jobs (of empty_readyJobs_or_NOT) returns FALSE, then isNOT_empty is done as follows. Move to priority, priority, of job, job. Set RJs0, a Jobs set, to the next element in the " <" direction. RJs0 now becomes RJs1. The function MOVE_TO_INSERT is to be repeated. The decision, MOVE_TO_INSERT, chooses one of the following alternatives based on the result of atnull:jobs: not_atNULL or insert:jobs.

If atnull:jobs (of MOVE_TO_INSERT) returns FALSE, then not_atNULL is done as follows. Move to the current job element RJ of the Jobs set RJs1. Move to priority, RJpriority, of job, RJ. The decision, INSERT_or_not, chooses one of the following alternatives based on the result of LT:Nat: continue_moving_to_insert or insert:jobs.

If LT:Nat (of INSERT_or_not) returns FALSE, then continue_moving_to_insert is done as follows. Set RJs1, a Jobs set, to the next element in the "R" direction. RJs1 now becomes RJsn. Repeat the ancestor function MOVE_TO_INSERT with the following input changes: replace job with job, priority with priority and RJs1 with RJsn.

If LT:Nat (of INSERT_or_not) returns TRUE, then insert:jobs is done as follows. Insert a new element job into RJs1, in the "L" direction from the current element, to get RJs.

If atnull:jobs (of MOVE_TO_INSERT) returns TRUE, then insert:jobs is done as follows. Insert a new element job into RJs1, in the ">" direction from the current element, to get RJs.

If isEmpty:jobs (of empty_readyJobs_or_NOT) returns TRUE, then insert:jobs is done as follows. Insert a new element job into RJs0, in the "R" direction from the current element, to get RJs. Go upto the readyQ, RQ1, containing RJs. Go upto the SimDB, S, containing RQ1.

1.3.2.4 update_history.

update_history logs the job completion time, endtime of job, by putting endtime into times of the completed job, job. Then, the simulation database, simDB, is updated by inserting the finished job into the history of simDB resulting in S.

(update_history.c)

update_history uses endtime (which is of type nat), job (which is of type job) and simDB (which is of type SimDB) to produce S (which is of type SimDB). Following is a list of the types of objects being used by this FMap:

Interface: S:SimDB=Update_History(endtime:nat,job:job)

Move to times, Ts, of job, job. Put endtime (a nat) into Ts (a times) to produce Ts1. Go upto the job, J, containing Ts1. Move to history, H, of SimDB, simDB. Insert a new element J into H, in the "L" direction from the current element, to get H1. Go upto the SimDB, S, containing H1.

1.3.3 put_onto_readyq.

put_onto_readyq updates the simulation database, simDB, readyQ with an_event, event, job eventtype. First, the current simulation readytime is assigned to the job. Then, a new readyQ priority is made by adding a "1" to the current, old priority. This new priority is then assigned to the job. Finally, the job that was removed from the event and now deemed to be a ready job is inserted at the end of the jobs of the readyQ. The simulation database, S, containing this updated reayQ is returned as output to Put_Onto_ReadyQ.

(put_onto_readyq.c)

put_onto_readyq uses simDB (which is of type SimDB) and event (which is of type an_event) to produce S (which is of type SimDB). Following is a list of the types of objects being used by this FMap:

Interface: S:SimDB=Put_Onto_ReadyQ(simDB:SimDB)

Move to time, readytime, of SimDB, simDB. Move to eventtype, et, of an_event, event. Get J0 (a job) from et (a eventtype). et now becomes et1. Move to times, Ts, of job, J0. Put readytime (a nat) into Ts (a times) to produce Ts1. Go upto the job, J, containing Ts1. Move to readyQ, RQ0, of SimDB, simDB. Get OldPriority (a nat) from RQ0 (a readyQ). RQ0 now becomes RQ1. Add "1" and OldPriority (both NATural numbers) to get newpriority. Put newpriority (a nat) into RQ1 (a readyQ) to produce RQ2. Put newpriority (a nat) into J (a job) to produce RJ. Move to jobs, RJs, of readyQ, RQ2. Insert a new element RJ into RJs, in the ">" direction from the current element, to get RJs1. Go upto the readyQ, RQ, containing RJs1. Go upto the SimDB, S, containing RQ.

1.4 do_events.

do_events processes the jobs on the ready queue of the simulation database, simDB, resulting in S. If the ready jobs to be processed is empty, simDB is returned as S with no change. If there are more jobs that are ready than can be handled by the set of available machines in the resource pool, those remaining jobs will be processed in a successive interation of the simulation, once allocated machines have been put back into the resource pool.

(do_events.c)

do_events uses simDB (which is of type SimDB) to produce S (which is of type SimDB). Following is a list of the types of objects being used by this FMap:

Interface: S:SimDB=Do_Events(simDB:SimDB)

Move to readyQ, RQ, of SimDB, simDB. Move to jobs, readyJobs, of readyQ, RQ. The decision, empty_or_not, chooses one of the following alternatives based on the result of isempty:jobs: not_empty or clone1:SimDB.

If isempty:jobs (of empty_or_not) returns FALSE, then not_empty is done as follows. Move to machines, Ms0, of SimDB, simDB. Move to events, Es0, of SimDB, simDB. RJs1 is the same object as readyJobs with its current element located at "1". The function FOR_ALL is to be repeated. The decision, FOR_ALL, chooses one of the following alternatives based on the result of atnull:jobs: More_ready_jobs_to_process or Done.

If atnull:jobs (of FOR_ALL) returns FALSE, then More_ready_jobs_to_process is done as follows. Do_Ready_Job determines if there is a free machine in Ms0 to perform the current job in the ready queue RJs1. If the job can be done by a machine, then the machine is removed from the resource pool; and, the ready job is removed from the readyQ. The ready job is put in a Machine EventType Event. This event is then scheduled based on its runtime and the set of current events being worked on by other machines. On success, the new states of the readyQ (RJs2), the events queue (Esn) and machine resource pool (Msn) are returned. In the case when no machine in the resource pool is able to do the ready job, no changes are made to RJs1, Es0 and Ms0. Set RJs2, a Jobs set, to the next element in the "R" direction. RJs2 now becomes RJsn. Repeat the ancestor function FOR_ALL with the following input changes: replace RJs1 with RJsn, Es0 with Esn and Ms0 with Msn.

If atnull:jobs (of FOR_ALL) returns TRUE, then Done is done as follows. Go upto the readyQ, RQ1, containing RJs1. Go upto the SimDB, S1, containing RQ1. Ignore Es0 and identify S2 as the same object as S1. Ignore Ms0 and identify S as the same object as S2.

If isempty:jobs (of empty_or_not) returns TRUE, then clone1:SimDB is done as follows. S is assigned to be the same object as simDB.

1.4.1 do_ready_job.

do_ready_job determines if there is a free machine in Ms0 to perform the current job in the ready queue ReadyJobs. If the job can be done by a machine, then the machine is removed from the resource pool; and, the ready job is removed from the readyQ. The ready job is put in a Machine EventType Event. This event is then scheduled based on its runtime and the set of current events being worked on by other machines. On success, the new states of the readyQ (RJs), the events queue (Es) and machine resource pool (Ms) are returned. In the case when no machine in the resource pool is able to do the ready job, no changes are made to ReadyJobs, Es0 and Ms0.

(do_ready_job.c)

do_ready_job uses ReadyJobs (which is of type Jobs), Es0 (which is of type Events) and Ms0 (which is of type machines) to produce RJs (which is of type Jobs), Es (which is of type Events) and Ms (which is of type machines). Following is a list of the types of objects being used by this FMap:

Interface: RJs:Jobs, Es:Events=Do_Ready_Job(ReadyJobs:Jobs,Es0:Events)

Move to the current job element J of the Jobs set ReadyJobs. Get_Free_Machine finds a machine from the machine resource pool, Ms0. which can perform the current jobProcess jobOperation of J. M will be the machine and Ms will be the resource pool with M removed. If there is no machine available, then M will have a reject value. This reject value can then be used by the calling FMap to determine if there was a free machine.The decision, NoMachAvail_or_MachIsAvail, chooses one of the following alternatives based on the result of isreject:machine: Machine_is_available or NoMachineAvailable.

If isreject:machine (of NoMachAvail_or_MachIsAvail) returns FALSE, then Machine_is_available is done as follows. Set ReadyJobs, a Jobs set, to the next element in the "L" direction. ReadyJobs now becomes RJs1. Remove the element job from the Jobs set RJs1 in the direction indicated by "R" from the current element. RJs1 now becomes RJs. Compute_Run_Time computes the RT a machine takes to perform a jobOperation of a job, job. This is computed by finding the capability needed by the machine, M, to perform the job operation. Given the M's capabilty time and the number of units of work needed by the job operation, the RT = "thenumberofunits" times "thecapabilitytimeperunit". Note that different machines having the same capability to process a job operation may have a different time per unit of work. In the current system this has not been considered; but the system could be revised to take this into account. If this were to be done, one would want to revise "Will_Machine_Do_Job" to select the machine with the capability that best suites the chriteria needed by a particular job.

If the machine does not have the expected capability, runtime is set to "0". Note, that this should never happen, since the function, Will_Machine_Do_Job, has evaluated the machine to see if it is the right machine type to do the job; and in addition that it has the capability to perform the job operation.

Compute_Process_Time updates the amount of processtime that a job, job, has been in processing using RT. Each time a job operation is processed by a machine, another increment of processing time is added to the processtime of a job. When all of the job operations for a particular job have been completed and the job is put into History, processtime will be the cumulation of all of the runtimes on the machines that were needed to process a job. Once the processtime of a job is updated here for this particular RT, it returned as job1. Allocate_Job allocates the next jobprocess of a job, job1, to the machine, M. After going to the next job operation of the jobprocess set, the currency is implicily set to this next job operation. This is done using a "moveto:joboperation,jobprocess" ... "upto:jobprocess,joboperation" sequence. The upto operator sets the currency implicitly. This allocation results in a new machine event FME to be scheduled. Schedule_Event looks at each job in the events queue recursively summing the relative times of each event. When this sum is greater than the input time, RT, then FME is inserted into the queue. This results in an updated events queue, Es.

If isreject:machine (of NoMachAvail_or_MachIsAvail) returns TRUE, then NoMachineAvailable is done as follows. Es is assigned to be the same object as Es0. RJs is assigned to be the same object as ReadyJobs.

1.4.1.1 get_free_machine.

get_free_machine finds a machine from the machine resource pool, machines. which can perform the current jobProcess jobOperation of job. M will be the machine and Ms will be the resource pool with M removed. If there is no machine available, then M will have a reject value. This reject value can then be used by the calling FMap to determine if there was a free machine.

(get_free_machine.c)

get_free_machine uses job (which is of type job) and machines (which is of type machines) to produce M (which is of type machine) and Ms (which is of type machines). Following is a list of the types of objects being used by this FMap:

Interface: M:machine=Get_Free_Machine(job:job)

The decision, Get_Free_Machine, chooses one of the following alternatives based on the result of isempty:machines: machine_could_be_available or No_machines_available.

If isempty:machines (of Get_Free_Machine) returns FALSE, then machine_could_be_available is done as follows. Set machines, a machines set, to the next element in the "<" direction. machines now becomes Ms1. The function FIND is to be repeated. The decision, FIND, chooses one of the following alternatives based on the result of atnull:machines: Look_More or atnull.

If atnull:machines (of FIND) returns FALSE, then Look_More is done as follows. Move to the current machine element M0 of the machines set Ms1. Will_Machine_Do_Job examines the MachType of the machine, M0, to make sure that it is appropriate for the current jobProcess jobOperation of the job, job, to be performed. If it is, and further validation shows that the machine has the capability to perform the jobOperation, then willdo will be set to "TRUE"; otherwise it is set to "FALSE". The decision, WillDoJob_or_NOT, chooses one of the following alternatives based on the result of clone1:any: If willdo is a "TRUE" Boolean or a NATural number with the value "1", then WillDoJob_or_NOT decides to do WillNOT_do_Job_operation; otherwise, WillDoJob_or_NOT is done.

If clone1:any (of WillDoJob_or_NOT) returns FALSE, then WillNOT_do_Job_operation is done as follows. Set Ms1, a machines set, to the next element in the "R" direction. Ms1 now becomes Msn. Repeat the ancestor function FIND with the following input changes: replace job with job and Ms1 with Msn.

If clone1:any (of WillDoJob_or_NOT) returns TRUE, then WillDoJob is done as follows. Set Ms1, a machines set, to the next element in the "L" direction. Ms1 now becomes Msm. Remove the element M from the machines set Msm in the direction indicated by "R" from the current element. Msm now becomes Ms.

If atnull:machines (of FIND) returns TRUE, then atnull is done as follows. Ms is assigned to be the same object as Ms1. Set M (a machine) to have the value Reject.

If isempty:machines (of Get_Free_Machine) returns TRUE, then No_machines_available is done as follows. Ms is assigned to be the same object as machines. Set M (a machine) to have the value Reject.

1.4.1.1.1 will_machine_do_job.

will_machine_do_job examines the MachType of the machine, mach, to make sure that it is appropriate for the current jobProcess jobOperation of the job, job, to be performed. If it is, and further validation shows that the machine has the capability to perform the jobOperation, then willdo will be set to "TRUE"; otherwise it is set to "FALSE".

( will_machine_do_job.c)

will_machine_do_job uses job (which is of type job) and mach (which is of type machine) to produce willdo (which is of type boolean). Following is a list of the types of objects being used by this FMap:

Interface: willdo:boolean=Will_Machine_Do_Job(job:job)

Move to jobprocess, process, of job, job. Move to the current jobOperation element jobOp of the jobProcess set process. Move to machtype, jobOpMachType, of jobOperation, jobOp. Move to machtype, machtype, of machine, mach. The decision, SameMachType_or_NOT, chooses one of the following alternatives based on the result of NOCaseEQ:Str: KF:boolean or Same_MachType.

If NOCaseEQ:Str (of SameMachType_or_NOT) returns FALSE, then KF:boolean is done as follows. Assign the value of willdo to be 'FALSE'.

If NOCaseEQ:Str (of SameMachType_or_NOT) returns TRUE, then Same_MachType is done as follows. Move to capabilities, capas, of machine, mach. Move to name, opNM, of jobOperation, jobOp. Does_Op_Match_Capability examines capas for a capability with the same name as opNM, the jobOperation name. If the capability exists, then willdo will be "TRUE"; otherwise it will be "FALSE".

1.4.1.1.1.1 does_op_match_capability.

does_op_match_capability examines capabilities for a capability with the same name as OpName, the jobOperation name. If the capability exists, then B will be "TRUE"; otherwise it will be "FALSE".

( does_op_match_capability.c)

does_op_match_capability uses OpName (which is of type str) and capabilities (which is of type Capabilities) to produce B (which is of type boolean). Following is a list of the types of objects being used by this FMap:

Interface: B:boolean=Does_Op_Match_Capability(OpName:str)

Cs is the same object as capabilities with its current element located at "1". The function find_a_match is to be repeated. The decision, find_a_match, chooses one of the following alternatives based on the result of atnull:capabilities: Look_more or KF:boolean.

If atnull:capabilities (of find_a_match) returns FALSE, then Look_more is done as follows. Move to the current Capability element c of the Capabilities set Cs. Move to name, cName, of Capability, c. The decision, found_or_not, chooses one of the following alternatives based on the result of NOCaseEQ:Str: NOT_found or KT:boolean.

If NOCaseEQ:Str (of found_or_not) returns FALSE, then NOT_found is done as follows. Set Cs, a Capabilities set, to the next element in the "R" direction. Cs now becomes Csn. Repeat the ancestor function find_a_match with the following input changes: replace OpName with OpName and Cs with Csn.

If NOCaseEQ:Str (of found_or_not) returns TRUE, then KT:boolean is done as follows. Assign the value of B to be 'TRUE'.

If atnull:capabilities (of find_a_match) returns TRUE, then KF:boolean is done as follows. Assign the value of B to be 'FALSE'.

1.4.1.2 compute_run_time.

compute_run_time computes the runtime a machine takes to perform a jobOperation of a job, job. This is computed by finding the capability needed by the machine, machine, to perform the job operation. Given the machine's capabilty time and the number of units of work needed by the job operation, the runtime = "thenumberofunits" times "thecapabilitytimeperunit". Note that different machines having the same capability to process a job operation may have a different time per unit of work. In the current system this has not been considered; but the system could be revised to take this into account. If this were to be done, one would want to revise "Will_Machine_Do_Job" to select the machine with the capability that best suites the chriteria needed by a particular job.

If the machine does not have the expected capability, runtime is set to "0". Note, that this should never happen, since the function, Will_Machine_Do_Job, has evaluated the machine to see if it is the right machine type to do the job; and in addition that it has the capability to perform the job operation.

(compute_run_time.c)

compute_run_time uses job (which is of type job) and machine (which is of type machine) to produce runtime (which is of type nat). Following is a list of the types of objects being used by this FMap:

Interface: runtime:nat=Compute_Run_Time(job:job)

Move to jobprocess, P, of job, job. Move to the current jobOperation element op of the jobProcess set P. Move to name, nm, of jobOperation, op. Move to capabilities, cs, of machine, machine. locate_capability_by_name finds the first capability of the set capabilities, s, that matches some criteria using the input, nm. Matching is done using Check_if_machine_has_operation_capa with the following interface: Boolean=Match?(capability,nm).

If a capability is found, then it is returned as capa. If a capability is not found, a REJECT capability is returned for capa.

Move to name, capaNM, of Capability, c. If the objects nm and capaNM have the same seqence of characters (irrespective of case), then hasOP is 'TRUE', otherwise, it is 'FALSE'. The decision, isreject_or_not, chooses one of the following alternatives based on the result of isreject:capability: number_of_unites_times_the_amount_of_time_per_unit or K:nat.

If isreject:capability (of isreject_or_not) returns FALSE, then number_of_unites_times_the_amount_of_time_per_unit is done as follows. Move to units, units, of jobOperation, op. Move to time, TimePerUnit, of Capability, capa. Multiply units and TimePerUnit (both NATural numbers) to get runtime.

If isreject:capability (of isreject_or_not) returns TRUE, then K:nat is done as follows. Create the NATural number object runtime with the value "0".

1.4.1.2.1 findel_1.

findel_1 finds the first element of the set set, s, that matches some criteria using the input, 1. Matching is done using MATCH with the following interface: Boolean=Match?(element,1).

If a element is found, then it is returned as e. If a element is not found, a REJECT element is returned for e.

()

findel_1 uses s (which is of type Any) and 1 (which is of type Any) to produce e (which is of type Any). Following is a list of the types of objects being used by this FMap:

Interface: e:Any=findEL_1(s:Any)

Function, isempty:set, uses inputs: s to produce: isE (of type boolean). Function, isNULL:set, uses inputs: s to produce: isN (of type boolean). Function, isreject:set, uses inputs: s to produce: isR (of type boolean). If isN or isE is 'TRUE', then orNE is 'TRUE'; otherwise, it is 'FALSE'. If isR or orNE is 'TRUE', then b0 is 'TRUE'; otherwise, it is 'FALSE'. The decision, isempty_or_not, chooses one of the following alternatives based on the result of clone1:any: If b0 is a "TRUE" Boolean or a NATural number with the value "1", then isempty_or_not decides to do isnot_empty; otherwise, isempty_or_not is done.

If clone1:any (of isempty_or_not) returns FALSE, then isnot_empty is done as follows. Locate element 1 of s which will now become s1 with a new currency. The function UNTIL is to be repeated. Function, atnull:set, uses inputs: s1 to produce: atn (of type Any). The decision, atnull_or_not, chooses one of the following alternatives based on the result of clone1:any: If atn is a "TRUE" Boolean or a NATural number with the value "1", then atnull_or_not decides to do not_atnull; otherwise, atnull_or_not is done.

If clone1:any (of atnull_or_not) returns FALSE, then not_atnull is done as follows. Function, moveto:set, uses inputs: s1 to produce: e1 (of type Any).

Plugin Interface: b:Any=MATCH(e1:Any)

The decision, match_or_not, chooses one of the following alternatives based on the result of clone1:any: If b is a "TRUE" Boolean or a NATural number with the value "1", then match_or_not decides to do does_not_match; otherwise, match_or_not is done.

If clone1:any (of match_or_not) returns FALSE, then does_not_match is done as follows. Function, next:set, uses inputs: r and s1 to produce: sn (of type Any). Repeat the ancestor function UNTIL with the following input changes: replace s1 with sn and 1 with 1.

If clone1:any (of match_or_not) returns TRUE, then clone1:any is done as follows. e is assigned to be the same object as e1.

If clone1:any (of atnull_or_not) returns TRUE, then kreject:element is done as follows. Function, kreject:element, uses inputs: s1 to produce: e (of type Any).

If clone1:any (of isempty_or_not) returns TRUE, then kreject:element is done as follows. Function, kreject:element, uses inputs: s to produce: e (of type Any).

1.4.1.3 compute_process_time.

compute_process_time updates the amount of processtime that a job, job, has been in processing using runtime. Each time a job operation is processed by a machine, another increment of processing time is added to the processtime of a job. When all of the job operations for a particular job have been completed and the job is put into History, processtime will be the cumulation of all of the runtimes on the machines that were needed to process a job. Once the processtime of a job is updated here for this particular runtime, it returned as J.

( compute_process_time.c)

compute_process_time uses job (which is of type job) and runtime (which is of type nat) to produce J (which is of type job). Following is a list of the types of objects being used by this FMap:

Interface: J:job=Compute_Process_Time(job:job)

Move to times, Ts, of job, job. Get Ptime (a nat) from Ts (a times). Ts now becomes Ts1. Add Ptime and runtime (both NATural numbers) to get Ptime1. Put Ptime1 (a nat) into Ts1 (a times) to produce Ts2. Go upto the job, J, containing Ts2.

1.4.1.4 allocate_job.

allocate_job allocates the next jobprocess of a job, job, to the machine, mach. After going to the next job operation of the jobprocess set, the currency is implicily set to this next job operation. This is done using a "moveto:joboperation,jobprocess" ... "upto:jobprocess,joboperation" sequence. The upto operator sets the currency implicitly. This allocation results in a new machine event E to be scheduled.

(allocate_job.c)

allocate_job uses job (which is of type job) and mach (which is of type machine) to produce E (which is of type an_event). Following is a list of the types of objects being used by this FMap:

Interface: E:an_event=Allocate_Job(job:job)

Move to jobprocess, process, of job, job. Set process, a jobProcess set, to the next element in the "R" direction. process now becomes p0. Move to the current jobOperation element op of the jobProcess set p0. Go from the current jobOperation element named op upto the containing jobProcess set named p. The current element of p is now op. Go upto the job, J2, containing p. Put J2 (a job) into mach (a machine) to produce M1. Create a an_event object named E0 using M1. Create ET0 (a eventtype) with a child sub-class "machine" from its TMap type node E0. Put M1 (a machine) into ET0 (a eventtype) to produce ET1. Put ET1 (a eventtype) into E0 (a an_event) to produce E.

1.4.1.5 schedule_event.

schedule_event looks at each job in the events queue recursively summing the relative times of each event. When this sum is greater than the input time, runtime, then event is inserted into the queue. This results in an updated events queue, Es.

(schedule_event.c)

schedule_event uses runtime (which is of type nat), event (which is of type an_event) and events (which is of type Events) to produce Es (which is of type Events). Following is a list of the types of objects being used by this FMap:

Interface: Es:Events=Schedule_Event(runtime:nat,event:an_event)

The decision, Schedule_Event, chooses one of the following alternatives based on the result of isEmpty:events: Events_in_queue or No_events.

If isEmpty:events (of Schedule_Event) returns FALSE, then Events_in_queue is done as follows. Set events, a Events set, to the next element in the "<" direction. events now becomes Es1. The function MOVE_TO_INSERT is to be repeated. The decision, MOVE_TO_INSERT, chooses one of the following alternatives based on the result of atnull:events: Within_current_events or Beyond_all_events.

If atnull:events (of MOVE_TO_INSERT) returns FALSE, then Within_current_events is done as follows. Move to the current an_event element rE of the Events set Es1. Move to time, Et, of an_event, rE. The decision, Runtime_GT_Event_Time_or_not, chooses one of the following alternatives based on the result of GT:nat: Between_two_events or Advance_by_event.

If GT:nat (of Runtime_GT_Event_Time_or_not) returns FALSE, then Between_two_events is done as follows. Put runtime (a nat) into event (a an_event) to produce ME1. Subtract runtime from Et (both NATural numbers) to get newEt. Move to the current an_event element E of the Events set Es1. Get Etx (a nat) from E (a an_event). E now becomes E_. Put newEt (a nat) into E_ (a an_event) to produce E1. Go from the current an_event element named E1 upto the containing Events set named Es4. The current element of Es4 is now E1. Insert a new element ME1 into Es4, in the "L" direction from the current element, to get Es.

If GT:nat (of Runtime_GT_Event_Time_or_not) returns TRUE, then Advance_by_event is done as follows. Subtract Et from runtime (both NATural numbers) to get newRt. Set Es1, a Events set, to the next element in the "R" direction. Es1 now becomes Es3. Repeat the ancestor function MOVE_TO_INSERT with the following input changes: replace runtime with newRt, event with event and Es1 with Es3.

If atnull:events (of MOVE_TO_INSERT) returns TRUE, then Beyond_all_events is done as follows. Put runtime (a nat) into event (a an_event) to produce ME2. Insert a new element ME2 into Es1, in the "L" direction from the current element, to get Es.

If isEmpty:events (of Schedule_Event) returns TRUE, then No_events is done as follows. Put runtime (a nat) into event (a an_event) to produce ME3. Insert a new element ME3 into events, in the "R" direction from the current element, to get Es.

1.5 editdisplay.

editdisplay displays an object t0 (of type TYPE for the user to edit. Once editing is completed, the edited object t0 is returned as t.

()

editdisplay uses t0 (which is of type Any) and path (which is of type str) to produce t (which is of type Any). Following is a list of the types of objects being used by this FMap:

Function, readtmap:TYPE, uses inputs: os to produce: tm (of type tmap). Object typenm is the node name of the TMap object tm. Create the STRing object fnm0 with the value ".omap". Concatenate typenm with fnm0 as indicated by "<". Concatenate path with omfnm0 as indicated by "<". ***** NOT DOCUMENTED --> Case_Str *****Concatenate ".display" with omfnm2 as indicated by ">". Function, convert:omap:TYPE, uses inputs: t0 to produce: tOM (of type omap). Use the omap editor to provide the user with an interactive edit session for the input omap, tOM. The file, displayfnm, is used to provide layout information for the initial display. The output omap, tOM1, is an updated version of tOM, based on the edit session. Function, convert:TYPE:omap, uses inputs: tOM1 to produce: t (of type Any).

1.6 storeomap.

storeomap puts the in memory object t0 into a file as persistent disc storage. The file name is constructed by appending, TYPE.omap, to prefix, the type of t0. t has the same value as t0. See storeomap and it's related functions dstoreomap and destoryomap, all in the a1 resuse library.

()

storeomap uses prefix (which is of type str) and t0 (which is of type Any) to produce t (which is of type Any). Following is a list of the types of objects being used by this FMap:

Function, readtmap:TYPE, uses inputs: os to produce: tm (of type tmap). Object typenm is the node name of the TMap object tm. Create the STRing object omf0 with the value ".omap". Concatenate typenm with omf0 as indicated by "<". Concatenate prefix with omfnm0 as indicated by "<". ***** NOT DOCUMENTED --> Case_Str *****Function, store:TYPE, uses inputs: omfnm2 and t0 to produce: b (of type Any). Ignore b and identify t as the same object as t0.