next up previous contents index
Next: Plant Model Up: SPL Pushlogic Language Reference Previous: Pushlogic Source Language   Contents   Index

Subsections

Standard Environment

Pushlogic programs may rely on the presence of certain libraries at compile time and certain Pebbles at run time.


Bundle Meta Info

Object code from the compiler automatically contains assignments to a tuple called `BundleInfo'. This includes meta-information regarding the compiler version, source file name and so on.

Code in the bundle may also typically store additional meta info, for example

    BundleInfo#Company := "Acme Limited";
    BundleInfo#Release := "Version 21.2";

The execution platform stores the BundleInfo tuple in the local tuple for the bundle. The local tuple is stored in the Bundles tuple of the hosting execution platform under a field name that serves as a unique instance identifier for the re-hydrated bundle.

Additional information can be passed to the BundleInfo tuple using the `meta' statement. This statement takes a comma-spearated list of tag/value pairs. For example

    meta Subassembly= "Motioncontrol", Release= "Version 21.2";

Currently, the meta statement does not do anything other than create a field in the BundleInfo and store a constant expression in it.

Local Variable Store

Pushlogic places its local variables in a tuple called `Local'.

Pushlogic Timer

Every Pushlogic platform provides access to a timer. The timer has a real-time clock and also provides any number of countdown timers.

The local real-time clock may be accessed by first declaring the following fields in the Pebbles tuple of the local platform and then reading them as needed:

  input Pebbles#Timer#Timenow#hour : {0..23},
        Pebbles#Timer#Timenow#minute : {0..59},
        Pebbles#Timer#Timenow#second : {0..59};

If the local bundle also sets the real time clock, then it should declare these fields using the `inout' keyword.

Countdown timers are created by declaring a field inside Timer#Countdowns. Two different bundles on the same platform will interfere if they both declare the same count down counter - this needs blocking. The field must be set to an integer number of milliseconds and it counts down to zero by itself. The following code fragment illustrates how to make a light flash at five hertz.

  inout Pebbles#Timer#Countdown#mytimer : { 0..100 };
  output Somedevice#lights#light : { off: on };

  with Pebbles#Timer#Countdown if (#mytimer == 0)
  {
     #mytimer := 100; // Half cycle every 100 milliseconds
     if (light==on) light:=off; else light:=on;
  }

The rest of this section is obsolete.

Frequently, rules must fire at a particular time of day, or describe constraints that apply only for specific periods of time. Examples are, respectively, ``Turn the light on at 6:30 pm'' and ``All lights must be off between 01:00 and 06:30''. As a basis for execution of temporal rules, a clock device is provided as a local resource at each Pushlogic interpreter. At the object level, it accessed in the same way as any other Pebble, but hooks for handling time are built in to the Pushlogic source language. Time encompasses both a linear, infinite sequence and a set of finite periodic schedules, hourly, daily and weekly. We refer to each of these as a base temporal extent. Any constant time expression mentioned in the rules can be seen as a partition of a base temporal extent into two temporal extents (or epochs): before the mentioned time and after the mentioned time.6.1Taking the union of all partitions on temporal extents leads to a finite number of epochs. It is simple to statically evaluate whether any expression referring to time is true or false in a given epoch. The rule validator must essentially collate the epochs and then check for rulebase consistency in every epoch. It can do this as an explicit datastructure but better would be to do it symbolically.

The tagged fields refer to components of the worldview. The other operators all have their normal meanings. In the future, arithmetic can be supported using Presburger [8] or CVC Lite [7].

Figure 6.1: Pushlogic Source Code: fragment from our DVD player demo.
\begin{figure*}{\small\begin{verbatim}with Pebbles ...

A fragment of Pushlogic Source for our prototype DVD player is listed in Figure 6.1.

Assistance with Network Race Conditions

A number of problems arise when a program is distributed over the network and are well-known in concurrency theory: e.g. the Dining Philosophers, the Byzantine Generals problem, and more general problems in load balancing. Any language design must partition the work of solving these problems between compile-time and run-time and between language-level features, libraries and application code. A distributed implementation of Esterel, for instance, would still maintain the Esterel concept of the atomic event, although there is a heavy penalty in its implementation. Esterel does not have a native, looser, more-efficient, network paradigm. In Pushlogic, however, the basic operation, a write to a remote field, is not itself an atomic test-and-set and hence we need to consider the further support required to avoid problems from network races and unreliability.

Any program that contains a race of the nature shown in figure 4.1 will not unwind during compilation since the final result depends on the order of interleaving.

Races: As fields are names in a global name space, there may be network delays in making access to their values for read or write. Races may also arise in that no synchronisation between reads and writes is implemented at execution time.

The binding part of resource allocation is handled in Pushlogic at re-hydration time. All instances of a given type of device must be given unique identifiers during binding, and, because currently there are no arrays in Pushlogic, each identifier must textually exist in the Pushlogic source program.

Test and Set Facility

Consider a pair of DVD players that are commanded at once to send their output to a single display, where that display can only handle a single stream. If the display has a field that says which stream it is currently receiving, then the most simple form of resource allocation is to allow this to set at any time and the most recent write to it is the current winner. This gives the familiar radio-button method of source selection.

Where it is important that a resource is claimed for a specific interval, terminated by an explicit release, then concurrency theory tells us that an atomic test-and-set is required at some level in the system or else we must essentially have a set of locks, indexed by requester name, that implements a variant Dijkstra's solution.

Pushlogic allows a field to be declared as a `lock', whose safe value is the null string. More than one bundle may store a non-safe value in a lock field (relaxing the normal rule) but such a store is only successful if the previous value was the null string. In a network race, the second client that attempts to store a non-null value will experience a pushback.


Make/break Issues

Where an event triggers the change of two or more fields, sometimes the order in which they are changed is critical. For instance, electrical changeover switches come in make-before-break and break-before-make varieties.

Since Pushlogic is a relatively high-level language, built-in support for make-break ordering should perhaps be provided for the common cases, rather than forcing the programmer to implement his own sequencers. However, this is for future study. What is implemented is checking over various message delivery skew and loss scenarios (§1.4).

Low-level Parallel Composition of Tuples.

Both the `pebble' statement in Pushlogic and the binding performed at re-hydration implement mappings between identifiers in a Pushlogic program and other parts of the Tuplespace, typically tuples in Pebbles. Sometimes it is helpful for there to be more than one, concurrent binding in place. For instance, we might want to address all the klaxons on the floor of a building or throughout the whole building. Also, different Pushlogic bundles might want to use different parallel compositions, such that a pair of pebbles that are in parallel from the point of view of one program are separate from the point of view of another.

There are two basic ways in which a number of pebbels can be addressed at once from a single Pushlogic read or write of a field: either the pushlogic code is macro expanded in some way, such as being rehydrated more than once, or else the pebbles are `hardwired' in parallel at a lower level, such as with additional mechanisms in the tuplecore.

We require that any pair of fields composed by low-level parallel composition have the same tag name and safe value set. The meaning of low-level parallel composition is slightly different for read and write operations. We also need to define the behaviour under unliateral change, pushback and under message delivery errors.

When fields that are paralleled are written by a Pushlogic program the writes are simply sent to all of the fields. This is useful, for instance, when wishing to mimic the status of a hardware Pebble with a software GUI that reflects the most recent fields written to the Pebble. Each write is sent to each of the two destinations. If one of the writes fails or is pushed back to a safe value, then the run-time system must push back the other fields mapped in parallel accordingly. These push backs appear as undo's to code in other bundles that drives the mapped fields and to new writes to code that references the mapped fields.

For fields written unilaterally by external devices, or fields that refuse to accept a pushback, the value of their parallel composition is defined to be the most recent value written to any one of the fields. This provides suitable behaviour when a number of very simple push button pebbles are paralleled: the push logic program receives the up and down strokes of each key with no demarcation as to which button was pressed. However, it is expected that even the most simple push buttons, whether implemented physically or as part of a GUI, will be momentary at the point of operation, but with built-in status indicators as latches, and therefore able to accept a push back. If the off state is safe and the on state not, then ... and any pushback to off will turn off all the indicators. These ideas extend easily to other forms of widget.


next up previous contents index
Next: Plant Model Up: SPL Pushlogic Language Reference Previous: Pushlogic Source Language   Contents   Index
David Greaves 2009-04-20