The COSA System

Latest News

Temporal Intelligence

The Silver Bullet

Project COSA

The COSA System

Software Composition

COSA Examples

Development Plan

 

Execution Kernel
  Execution Thread
  Exceptions to the Single Thread Rule
  Two Update Lists
  Signals
  Master Clock
  Time Slicing
  Verification
Cells
  Two Types of Cells
  Synapses
  Decision Pathways
  Sensors
  The Principle of Sensory Coordination
  Effectors
  Granularity
  Atomicity
  Co-Effectors
  Effector-Sensor Associations
  The Cure for Blind Code
  The Principle Of Motor Coordination
  Temporal Cells
  Invariant Temporal Cells
  Memory Cells
  Invariant Memory Cells
  Watchdogs
  Wait Cells
COSA Innovations
Software Composition

 

Execution Kernel

The execution kernel is the part of a COSA operating system that handles the reactive logic of the system. It decides which objects must be processed at every execution cycle. There are two classes of objects in COSA, active and passive.  Passive objects are common data objects such as variables and properties. There are two types of active objects: perceptors and effectors. Perceptors perceive changes and effectors execute changes.

In COSA, every computation is considered to be a form of either input or output processing. For example, detecting a change in a data variable is just as much a sensory/input event as a key-pressed or button-down signal. Likewise, changing a data variable is no less a motor/output action than moving a dot on the screen. Output signal processing is not limited to external effectors. COSA also has internal data effectors. A computation like (A = A + B) is just as much an effect as sending a byte code to a peripheral device such as a printer or a graphics card.

Execution Thread

An ideal COSA operating system would have no algorithmic processes whatsoever as all objects would be self-processing and would communicate via direct connection pathways, not unlike transistors or neurons. Unfortunately, the architecture of von Neumann computers is such that a software system must have at least one algorithmic thread (a set of CPU instructions). As a result, communication pathways between objects have to be virtual.

In COSA, there is a single loop thread called the execution thread or kernel that runs the entire system, including applications and services. The kernel is essentially a virtual machine similar to a FORTH interpreter or the JavaTM virtual machine. It is designed to be completely transparent to the software designer. It is the only low-level executable code in the entire system. No new executable code is allowed, not even for applications and traditional operating system services such as file I/O, memory management, etc...

Software construction is achieved by connecting elementary cells together using simple signal connectors called synapses. Cells can be combined into larger modules or plug-compatible components for the benefit of the application designer but the kernel sees only the cells, their synapses and assigned data operands, if any. Nothing else. In this light, the kernel can be viewed as a cell or object processor. Hopefully, if the COSA model is widely adopted, CPUs will be optimized for cell processing.

Exceptions to the Single Thread Rule

There are a few exceptions to the single thread rule. Every operating system must be able to handle hardware interrupts in real time. Interrupts are, in essence, asynchronous sensory events indicating that something important has happened which needs immediate handling. Examples are mouse, keyboard, network card or hard drive events. COSA uses small interrupt service routines to modify relevant data/message structures and mark appropriate sensory cells for updating by the kernel at the earliest opportunity. Neither applications nor services have permission to access interrupts. Indeed they cannot do so since no new executable code is allowed. All possible interrupt eventualities must be handled by the operating system and, if need be, corresponding sensors can be provided for use by applications and services. This eliminates a lot of headaches, especially in safety-critical domains.

Another exception has to do with copying memory buffers. Sometimes, it is imperative that such tasks be executed as rapidly as possible. It would be better to delegate them to a dedicated DMA hardware chip. However, this may not always be possible. The alternative is to use a super-optimized assembly language thread. To the software designer, a buffer-copy component would be no different than any other COSA service component. It would have an input connector for service request messages and an output connector for acknowledging when a task is complete.

Two Update Lists

The job of the kernel is to update all cells in the system that need updating at every tick of a master clock. This is done with the help of two update lists, one for input processing and the other for output processing. The lists contain pointers to all objects that need updating at any given time. As one list is processed, the other is filled. The reason for using two lists instead of one is to prevent signal racing conditions that would otherwise arise.

During every cycle, the lists are processed one after the other starting with the input list. During input processing, the kernel performs a primitive operation on behalf of every cell in the input list according to its type. The cell is stamped with an integer value representing the time of activation (I shall explain later why this is important). After each operation is performed, the cell is placed in the output list for subsequent output processing. The input list is emptied after processing is complete. Output processing is much simpler. It consists of placing the destination targets of every cell in the output list into the input list. After completion, the output list is emptied, the master clock is incremented and the cycle begins anew.

As an aside, a COSA-optimized processor could maintain as much of the update lists as possible in the processor's on-chip cache, obviating the need to access main memory to read the lists. In addition, the processor could have intimate knowledge of every cell's type and structure. These optimizations, among others, could bring COSA performance to a level on a par with that of RISC processors.

Signals

There are no tangible signals--comparable to the changes of potential in a digital circuit--that travel from one cell to another in a COSA program. The mere placement of a cell in an update list means that it has either received or transmitted a signal. This is a plus for software because the signal racing conditions that commonly occur in hardware are non-existent in this scheme. It should be noted that signals do not carry any information in COSA. Particularly, a signal does not have Boolean value. A signal is a simple temporal marker that indicates that some phenomenon just occurred. The nature or origin of the phenomenon cannot be determined by examining the signal.

There is a difference between a signal and a message in COSA. As explained, a signal is an abstract temporal marker. With regard to effector cells (see below), it always marks either the end of an elementary operation or the beginning of another or both. With regard to sensor cells it marks either a positive or negative change in the environment. Signals are always processed synchronously (i.e., immediately) by the execution kernel. A message, on the other hand, is a data structure that can be placed in a queue and assigned a priority level. Message queuing is not handled directly by the kernel. That is the job of the message server. There is a need for both synchronous and asynchronous processing in any complex software system.

Virtual Master Clock

One of the most important aspects of using a master clock is that every elementary operation lasts exactly one execution cycle. An uncompromising consistency in the relative order of signals and operations must be maintained at all costs. Logically speaking, it does not matter whether the clock durations of the cycles are not equal. As long as the master clock (really an integer count) is incremented once every cycle and as long as it serves as the reference clock for timing purposes, logical order consistency is maintained. This is because coincidence and sequence detection are based on the master clock, not on a real-time clock. Thus all concurrent operations execute synchronously between heartbeats or clock ticks. Because of this deterministic concurrency, COSA can be said to belong to a class of software systems known as synchronous reactive systems.

The temporal deterministic nature of cell activation is maintained event though the heart rate of a COSA system is non-deterministic relative to real time: each cycle lasts only as long as necessary. This is not entirely unlike the digital processor design approach known as 'clockless computing.' There is no need to waste time waiting for an external clock tick if one does not have to. This does not mean that a COSA system cannot react in real-time. It can. In fact, the software designer will have ample flexibility to tweak priorities to handle the most demanding environments. The important thing is that temporal integrity of cell activations is maintained relative to the virtual clock.

Sometimes (simulation systems, parallel computing, etc...) it is necessary to synchronize a COSA program with an external clock. The best way to achieve this is to use the clock ticks as sensory signals emitted by one of the system's sensors. In such cases, all operations must execute within the fixed interval allotted between ticks. In the event that the execution time exceeds the clock interval, the application designer has several options: a) use a slower external clock; b) use a faster CPU; c) split long operations into shorter ones; d) use slower message servers; and e) lighten CPU load by adding more CPUs to the system and redistributing the load.

Time Slicing

There is no need for multi-threading in COSA. The performance overhead and latency problems associated with context switching is nonexistent. In COSA, every cell is its own tiny task or process, so to speak. Since the system is driven by change, only objects that are directly affected by events need to be processed during any given cycle. This makes for a very efficient approach to concurrency because only a relatively small proportion of objects are active at any one time. As a result, a single-CPU COSA operating system can support tens of thousands of small concurrent objects.

Priority processing is controlled at the message level. High-priority messages are immediately placed at the head of their queues. In addition, all message servers automatically stop serving low-priority messages while any high-priority message is still in a queue. This technique ensures that critical tasks always get a disproportionate share of  processor runtime.

In safety-critical systems where real-time response is vital, asynchronous COSA components can be assigned individual task priority levels. Internally, each component would have its own independent master clock and update lists. The execution kernel is designed to divide its processing time among components according to priority. An asynchronous component is one that uses asynchronous queued messages exclusively to communicate with other components. Messages are placed in a FIFO queue and wait to be processed one at a time by the destination component.

Verification

As mentioned above, one of the things that distinguishes concurrent COSA objects from concurrent algorithms is that all COSA objects execute at the same master cycle rate, i.e., they perform their assigned elementary operations within one execution cycle. This uniformity of execution lends itself to the creation of verification tools and techniques for both static and dynamic analysis. For example, it is easy to determine at run time whether or not a given data operand is being accessed concurrently for modification and/or reading by multiple effectors and/or sensors. It is also possible to determine statically--by counting and analyzing convergent decision pathways--whether the potential exists for conflicting data access. Detecting and flagging logical and temporal conflicts in a COSA system is a simple process. This goes a long way toward improving reliability.

By far, the one aspect of COSA that is the most advantageous to failure analysis, is the principle of complementarity and its corollaries such as the Principle of Motor Coordination (PMC) and the Principle of Sensory Coordination (PSC). These are explained below.

 

Cells

A COSA cell is a primitive concurrent object that uses signals to communicate with other cells. Cells are connected to one another via simple connectors called synapses, to borrow a word from neurobiology. The number of input connections a cell may have depends on its type. The number of output connections is unlimited. Internally, a cell is just a data structure that contains the cell's type, a list of input and output synapses, if any, and pointers to data operands, if any. When a cell is processed by the execution thread during input processing, an elementary operation is performed on its behalf according to the cell's type. After processing, the cell immediately emits an output signal to any destination cell it might be connected to.

The function of cells is to provide a general purpose set of basic behavior and perception objects that can be combined in various ways to produce high-level components and applications. There is no computational problem that can be solved with a general purpose algorithmic language that cannot also be solved with a combination of COSA cells. Cells are the basic building blocks of every software application created under COSA. There are no languages to learn, no scripts to invoke and no subroutines to call. In addition, new types of signal-driven cells that obey a strict protocol can be added to a system. This will allow an application designer to accommodate custom needs while taking advantage of existing components.

Two Types of Cells

Cells are divided into two sub-types: perceptors and effectors. The latter operate on data while the former determine the conditions under which operations are performed. Perceptors comprise normal change sensors (hardware and comparison sensors) and signal pattern detectors (temporal and memory cells).

Synapses

A synapse is a simple data structure that serves as a connector between two cells. It contains two addresses, one for the source cell and another for the destination cell. It is used by the kernel to effect communication between cells. When two cells are connected, they share a synapse together. In a simple system, each synapse would have a single destination address and each cell would maintain a single list for output synapses. However, it is beneficial that each cell maintains two lists, one for inputs and one for outputs. The kernel must be able to trace connections in both directions.

Decision Pathways

All synapses must maintain a strength variable at least during the development phase. The variable is incremented every time a signal arrives at the synapse. Synaptic strength is an indication of age and/or experience and can be powerful as a debugging aid. In case of failure, the culprit is almost invariably a young or rarely exercised synapse. From the point of view of reliability, it is important to verify that every signal pathway has seen activity at least once. Since all signals must pass through synapses and no action can be taken without a signal, the use of synaptic strength variables provides a fail-safe method that will ensure total coverage of all decision pathways during testing. This is a tremendous asset for failure diagnosis (blame assignment) and defect prevention.

Sensors

Sensors have no input synapses but they can have as many output synapses as needed. Their job is to detect changes or state transitions, if you will, either in the computer's hardware or in data variables. When a prescribed change is detected,  a sensor immediately sends a signal to its destination cells, if any. A sensor should be thought as being always active, in the sense that it is continually on the lookout for change. Sensors are always created in complementary-opposite pairs, positive and negative. The following list shows several examples of complementary sensors:

mouse-button-up mouse-button-down
key-up key-down
greater-than not-greater-than
less-than not-less-than
equal not-equal
bit-set bit-clear

Comparison sensors--also called data sensors--are not standalone cells. They must be associated with one or more effectors (see below). Their function is to detect changes in their assigned data. As mentioned earlier, a signal-based system is a change-driven system. As an example of how this works, let us say a given sensor's job is to detect equality between two variables A and B. If A and B are equal both before and after an operation, the sensor will not fire. There has to be a change from not-equal to equal in order for the sensor to fire. The same change requirement applies to all sensors. COSA does not draw a process distinction between external (interrupts) and internal (changes in data) sensory phenomena.

A cell's output synapses are always depicted as small red circles. Note however that, internally, there is only one synapse that connects a source cell to a target cell. Input and output synapses are used in the pictograms as a way to denote signal direction.

The Principle of Sensory Coordination

The complementarity of sensors can be used as a debugging aid during development. It goes without saying that a complementary pair should never fire simultaneously. If they do, something is definitely malfunctioning. This is what I call the Principle of Sensory Coordination or PSC. The PSC dictates further that positive and negative sensory signals must alternate. For example, a mouse-button-up signal cannot be followed by another mouse-button-up signal without an intervening mouse-button-down signal.

Effectors

An effector is roughly analogous to a simple code statement in a conventional program. Usually, it performs a simple operation on data such as (A = B + 1), (A = B x C) or (Pi = 3.1416). An operation is any effect that modifies a passive object (data variable). Effectors operate on assigned data items using either direct, indirect and indexed addressing. Data types (integer, floating point, etc...) are specified at creation time. On receipt of a start signal, an effector immediately performs its assigned operation and emits an outgoing signal.

Effectors are self-activating cells, not unlike the tonically active cells found in the brain's motor system. What this means is that, once triggered, they repeatedly activate for a prescribed number of cycles. The left effector in the figure above is preset to repeat 10 times while the right effector is preset to repeat 100 times. The number may range anywhere from 1 (for one-shot effectors) up to an indefinitely high value. For this reason, all effectors, including one-shot cells, have two types of input synapses, one for starting and the other for stopping. An effector may have any number of start and stop synapses. If an effector does not receive a stop command signal after initial activation, it will repeat its operation until it has run its course, at which time it will emit an output signal. A stop signal always overrides one ore more start signals. In other words, if a stop and a start signals arrive simultaneously, the effector will not respond. In such cases, the stop signal is just an inhibitory signal. Two or more start (or stop) signals arriving simultaneously count as one signal.

Granularity

It is important to pick the right granularity level for basic effector operations. It must be neither too high nor too low. For example, a typical addition operation like A = B + C is performed in several steps by the CPU. First B is fetched from memory and then C is fetched. A binary addition is then performed and the result placed in a temporary register. Finally, the result is stored into A. Should each step be considered a separate action to be performed by a separate cell? The answer is no. As mentioned earlier, a signal-based program is driven by change. The only relevant changes are changes in data operands that reside in memory. Whichever method is used in the processor to effect a change is irrelevant to the program. In the addition example, the only operand that may have changed after the operation is the variable A. The changing of A is the only event caused by the operation that has the potential of affecting the behavior of the program. The application does not need to know about every step of the process that resulted in the change. It only needs to know that A changed. So the entire operation is considered a single effect that takes place during a single cycle. The effect is performed by a single effector cell.

Atomicity

When an application designer creates an effector in COSA, he or she is presented with a choice of operations. For example one can choose between simple assignment (e.g.,  A = B), and complex assignment (A = B + C). Once an operation is chosen, one is given a choice of addressing modes for each variable, direct, indirect, indexed, etc... Here are some examples of possible effector operations:

1.  A = B;
2.  A = B + C;
3.  A[x] = B[x];
4.  A = A / 3.1416;
5.  A = B[x][y][z];

Note that every operation assigns a value to a target variable. This is the general form of all COSA operations: one assignment and one arithmetic operation, if any. This is what is meant by an atomic operation. There are no IF-THEN, DO-WHILE control constructs. All control decisions are made by COSA cells. There are no procedure calls either. A mature software composition system might have a just-in-time (JIT) compiler that instantly compiles operations into optimized native code on creation.

Slave Effectors

A slave effector is one that works only in cooperation with another effector called the master. It has no input or output synapses of its own. There are two types of slave effectors, predecessors and successors. For example, one can assign a pre or post-increment effector to increment an index variable immediately before or after its master performs an operation. This is helpful in implementing iterations that use indexed operations such as (A[j++] = B[k++]). In this case, two effectors would be assigned the job of post-incrementing j and k.

Effector-Sensor Association (ESA)

Using effectors and sensors to implement a traditional 'while loop' that increments or decrements a counter variable and does a comparison test is rather simple (see loop component example). One only needs to associate one or more comparison sensors with one's chosen effector and the execution kernel does the rest. Even though, underneath, the sensor does a comparison test immediately after the operation, both the operation and the comparison should be thought of as happening simultaneously, i.e., within one execution cycle. The sensor should be seen as reacting to the change in the data, as it happens. The loop calculation begins as soon as the effector receives a start signal. To stop the loop when the comparison is successful, the sensor's output is simply connected as a stop input to the effector.

There is another important way to associate a sensor with an effector. The designer can specify that the sensor performs its test only when the effector start and/or stops. This is mainly a way to save processor time. Note also that an indefinite number of comparison sensors can be associated with a given effector. This way, multiple relevant comparisons can be done every time an action is taken. In addition, a given comparison sensor may be associated with more than one effector, that is, to any effector whose actions may potentially trigger a change detection. ESA is a powerful technique that lends itself to many types of computation.

The Cure for Blind Code

In a truly parallel system, i.e., in a system where every cell is its own processor, there would be no need to associate data sensors with effectors. All sensors would automatically keep watch on whatever events they were designed to detect and would fire upon detection. In a von Neumann machine, however, updating every sensor of a complex program at every clock tick would be prohibitively expensive. The reason is that a single big processor must do the work of many small processors. But all is not lost. The effector-sensor association technique described above is an effective way to get around the bottleneck. A sensor needs to be updated only when its related data objects are modified by an associated effector. A further advantage of this technique is that it lends itself rather well to the creation of tools that automatically identify weak data dependencies in an application. Development tools can be designed to automatically detect missing or ineffective associations. The development environment should enforce associations in such a way as to prevent the use of a comparison sensor unless it is associated to every effector that may potentially affect it. Blind code is never a problem in COSA.

The Principle of Motor Coordination

There is a simple principle that governs the timing of command signals arriving at an effector. I call it the Principle of Motor Coordination (PMC), a term I borrowed from my work in biological and robot motor learning. The PMC helps to identify command timing errors as they happen. It stipulates that no action can be started if it has already started or stopped if it is already stopped. In other words, a start signal must not follow another start signal and a stop signal must not follow another stop signal. In biological motor learning, the PMC is used to automatically suppress command connections that fire out of turn. In a development environment, it can be used to alert the application designer of timing conflicts during development. It is a very effective way to spot trouble before it happens because bad timing invariably results in one or more signal arriving out of turn.

Temporal Cells

Temporal cells are used to detect the precise temporal order of arrival of input signals. A temporal cell may have an unlimited number of input synapses one of which is called the master or reference synapse. The other synapses are called slaves. The cell is updated only when a signal arrives at the master synapse. In order for the cell to fire, all slave signals must either precede or arrive concurrently with the master signal according to the prescribed settings for each input connection. In other words, if the slaves fire at their prescribed times relative to the master, then the cell fires.

Most temporal cells are used to detect concurrency, i.e., the cell fires if all the synapses fire concurrently. However, there are times when the right order of arrival is important for decision making. By the way, this is the reason that the kernel must stamp every cell with an integer value that represents its most recent time of activation. The time stamp is used to determine precise firing order or concurrency if needed.

There are two types of temporal cells, positive--as described above--and negative. A negative temporal cell is just like a positive temporal cell, except that if fires if the prescribed temporal conditions of the cell are not met when the master signal arrives.

A temporal cell can be loosely compared to a Boolean AND operator but the comparison is somewhat misleading. This is because a logical AND operator operates on static Boolean states (ON/OFF) whereas a temporal cell processes transient signals. Boolean states mean nothing in COSA because, in order for a COSA cell to respond, there must be a transition from ON to OFF or vice versa. COSA cells have strict temporal expectations. The use of temporal constraints is one of the reasons that make the COSA model so much more reliable than other approaches. Also, there are no logical OR or XOR cells in COSA because they are superfluous. Any logical decision can be accomplished with the use temporal cells and appropriate start or stop synapses. Note that temporal cells have no inhibitory synapses. Inhibition is used only in conjunction with effector cells. The reason is that all sensor cells come in complementary pairs (button-up/button-down, equal/not-equal, etc...). 

Invariant Temporal Cells

A temporal cell can be used as an alarm mechanism to enforce timing constraints. For example, a software designer may have reasons to expect certain events to always occur in a given temporal order called an invariant order. Conversely, there may be reasons to expect certain events to never occur in a particular temporal order. In such cases, a temporal cell can be used to sound an alarm or take an appropriate action whenever the expectation is violated. The COSA development system will automatically create a complementary error cell for any temporal cell that is flagged by the software designer as invariant. It is up to the designer to correct the problem in case of a violation.

This is an important consideration because many catastrophic failures in software have to do with one or more violated assumptions about event timing. This usually happens when a component is reused in a new environment for which it was not originally intended. Adding as many error cells as possible is a good way to detect problems that would otherwise go unnoticed until too late.

Even when a temporal expectation is not deemed invariant, it is always a good idea to test for both eventualities. A good COSA-compliant design tool should automatically create temporal cells in complementary pairs, so as to cover both cases. The nice thing about a graphical design environment is that adding cells and making new connections are just a matter of clicking and dragging the mouse.

Memory Cells

As explained earlier, comparison operations in COSA are passive sensory processes that are triggered by changes in data. For example, let us say we create two complementary sensors A and B to detect specific changes in variable X, as follows:

Sensor A fires when X changes from non-zero to zero.
Sensor B fires when X changes from zero to non-zero.

However, there may be times in between changes in X when we need to know its zero or non-zero status. For this we must use memory cells. A memory cell is a special cell that remembers the last activation order of two or more inputs. Using the X example, we can say that if, of the two sensors, sensor B fired at some unspecified time after sensor A, X may be safely assumed to be non-zero. Conversely, if X is equal to zero, sensor A must have fired last. We can use A and B as the before and after (see figure below) inputs to two memory cells, one for each eventuality.

A memory cell is a type of hybrid effector-perceptor cell. It has the normal start and stop input synapses of an effector but it does not operate on external data variables. It also has two or more special input synapses for receiving sequential signals. These events never cause the cell to fire immediately. They just condition the cell for firing if they arrive in the prescribed order. What this means is that, if the input sequence conditions are met, the cell will fire on receipt of a start signal. It will continue to fire unless the order of the events changes or the cell receives a stop signal.

Note that a memory cell is not limited to just two inputs; any number of sequence combinations may be used. Nor is it limited to sequences; it can also remember concurrent patterns. One of the things that differentiates a memory cell from a temporal cell is that the exact relative timing of a given sequence is not specified in a memory cell. What is important is the arrival order of signals not their time of arrival. Note that the inputs to a memory cell may originate from any type of cell, not just comparison sensors. And not just from complementary pairs either. This means that the order of all sorts of events can be recorded and recalled. For instance, an application may need to determine the order in which certain keys were pressed.

Let us use a Ctrl-Alt-Del detector component as an example. The assumption is that the keys must be pressed in the correct order and held down in order to trigger a detection. First off, we need one memory cell to detect the Ctrl-Alt-Del sequence. Second, we need three 'key-pressed' memory cells to make sure that every key is still pressed down at the time we conduct our test. Third, we must feed the outputs of the four memory cells into a single temporal cell to detect concurrency. Finally, we can use a single input trigger signal to activate all four memory cells simultaneously. In all, the detector used only five cells. Its output can be sent to as many destination components as needed.

As with temporal cells, there are two types of memory cells, positive--as described above--and negative. A negative memory cell is just like its positive counterpart except that if fires if the prescribed arrival order conditions of the cell are not met.

Invariant Memory Cells

Invariant memory cells are like invariant temporal cells. They expect their input signals to always arrive in a particular order. The difference is that an invariant memory cell ignores intervals between signals. Again, as with invariant temporal cells, an invariant memory cell is a good way to enforce temporal determinism among signals.

Watchdogs

Sometimes, especially in embedded applications, it is imperative that a computation finishes within a predetermined interval. Memory cells can be used in conjunction with a real-time wait cell (see below) to set up watchdogs for that purpose. A watchdog cell can easily determine whether or not a given signal A arrived before a timer signal B and alert the user if necessary.

Wait Cells

A wait cell is a type of memory cell, albeit a highly constrained one: at a specific time after receiving a start signal, it suddenly remembers the signal and fires. In other words, a wait cell pauses for a specified number of cycles ranging from 1 to an indefinitely high number. Wait cells are normally used as delay timers. Like an effector, a wait cell can have any number of start and stop input synapses. The arrival of a stop signal inhibits the cell's internal counter.

As with normal effector cells, signals arriving at the start and stop synapses of memory cells must obey the Principle of Motor Coordination or PMC.

The wait cell described above is known as a virtual timer because its internal counter is synchronized to the virtual master clock. There is another type of wait cell called a 'real-time wait cell' that is synchronized to an external clock. It can be used, as part of a watchdog to enforce task performance.

 

COSA Innovations

Reactive software is not a new idea but many of the ideas and principles explained here are new to reactive computing. Most originated from my ongoing research in artificial intelligence and spiking neural networks. False modesty aside, I consider several of them to be genuine advances because of their value to software reliability and productivity. They are listed below, not necessarily in order of importance:

The principle of complementarity (PC).

The principle of motor coordination (PMC).

The principle of sensory coordination (PSC).

The concept of effector-sensor association (ESA).

The separation of implementation details from organizational structure.

All sensory events, whether internal or external, are treated the same way.

All motor actions, whether internal or external, are treated the same way.

A comparison is not an action but a sensory phenomenon. 

Feel free to use any of these ideas in your own software projects.

 

Next: Software Composition 

These pages are under continual revision. Refresh your browser often.

Last Update: 08/07/2002

Send all comments to:  louis.savain@sbcglobal.net

©2002 Louis Savain