November 28 2009: san_engine revisions
This is a summary of the changes to the san_engine code in the November 28, 2009
release. The code is not under revision control, but releases
are archived at
However it is usable by the adventurous.
The internal structure and the interface have both been significantly altered. Some of the changes
were made to make the code simpler and robust, and some were made to improve the interface.
The list of changes given below probably is not complete.
The whole system of source functions has been eliminated. The effect of a source function, i.e.,
a function that executes on every cycle, can be effected in user code by having a function that sends a
message to itself. Here is some representative code from a birth function:
In this code "self" is the agent's handle, "to_self" is a connection type (see below),
and "response_function" is the function that will be executed whenver there is a delivery
at the inport.
The first line creates an inport, the second an outport, and the third connects the
outport to the inport. Finally, the fourth line starts the cycle going. The first line of
the response function should be the same as line four.
A parms argument has been added to the calling sequences for the agent creation functions
and to the agent birth calling sequence. The purpose of this argument is to permit passing
data to an agent at birth time.
The objtab code has been moved into a separate utility, objtab.c and objtab.h. Agents now
have two object tables, one for inports and one for outports. Inports and outports are now
internally referenced using object table references
The connection rules were changed. The new rules are that connections can be made from
any agent to self or children where "self" is the agent making the connection. The rule is
the same for disconnection.
The san_emit command was renamed san_send.
A type system for connections has been created. This is a fairly radical change. Originally
the engine used numbered ports for inports and outports. Connect commands specified agents by
reference and ports by port number. This turned out to be fairly cumbersome and uninformative.
My first cut at a better way was to introduce the notion of a message type. The thought is that
the message type specifies both the format and the semantic content of an emission. Ports are
identified by the message type they handle. A connection specifies the source and destination
agents and the message type. Inports and outports are specified by the type of message that
they handle. The constructors generate handles but these are not visible in user code. The san_send
command specifies the message type and the message; it does not have to name the outport being used.
The scheme was simple and elegant; however there is a problem. An agent may have two destinations,
each getting the same kind of message but with different messages. Similary an agent may have two
receptors, each with the same message type but with different message types. These issues can be
dealt with by creating multiple copies of the base message type and giving each copy a distinct type
name. That approach did not appeal; it ends up being messy and misleading.
I resolved these problems by adding send and receive types that are only used to differentiate
between multiple ports at the send and receive agents. Connections and the corresponging ports
are represented by triplets, (send type, receive type, message type). Triplets make life complicated.
I made it simple again by adding yet another type, the connection type, that is a handle for
a corresponding triplet. The upshot is that connection types have the same nice properties as
message types, but they can handle the special cases.
Connections between parent and child are no longer predefined.
Most of the API functions have been converted to wrappers.
The old info routines have been replaced by san_get_agent_data and san_info. San_get_agent_data returns
a pointer to a struct that contains a variety of information about the current agent, including lists
of children and siblings. San_info returns a struct that contains the current epoch and handles for
the current agent and its parent.
Table of deleted and API functions.
This page was last updated november 28, 2009.