Skip to main content Skip to navigation

Lab 1 Exercises

Bret Victor's talk on Inventing on Principle, and his online account of Learnable Programming gives some indication of what is ideally required of a software development environment suitable for the end-user and novice programmer. Victor emphasises the fact that "creators need an immediate connection", and illustrates the role of the computer as a modelling tool that prompts "thoughts that we can't think". Empirical Modelling endorses Victor's principles in many respects, but also is the basis of a critique that will emerge as the module develops. Some relevant issues will be informally illustrated in this lab, which demonstrates how Nick Pope's Cadence interpreter was deployed in game design by the Warwick Games Design society and subsequently related to EM thinking. They include:

  • live editing of the network of dependencies that determines the structure of a model;
  • eliminating the need for an edit/compile/execute cycle;
  • overcoming the disadvantages of scripting techniques that involve reloading scripts and restoring (where possible) the original state by restarting the execution;
  • simultaneously supporting views of the current state, both visual and textual, that are appropriate for several different kinds of agent.

Introducing the Stargate model

This lab is looking at a model of the Stargate. For those not familiar with the films and TV series take a look 'here' with particular reference to the paragraph entitled "Destiny's Gate" under Technical specifications. Empirical Modelling is an open exploratory process where there is some referent artifact (in this case the Stargate as seen in the film) and we are attempting by experiment to recreate this on the computer. The process of modelling the Stargate helps us understand its mechanics better. We are not trying to write a program to accurately simulate a Stargate efficiently but instead are looking to learn something about it and explore possibilities in an interactive fashion. The resulting model (if ever finished) should resemble our understanding of how it works and not be abstracted to how it can be best implemented on a machine. There are actually many flaws in our model - i.e. respects in which it is not faithful to the Stargate as it is portrayed in films - that we have yet to resolve. If you are familiar with Stargate then perhaps you will notice these. Once we have worked out how to model a Stargate it may then be possible to write a more efficient program to simulate it but our modelling comes before a complete understanding exists.

To do this modelling we have, over the years, constructed our own tools. In this lab, Cadence - a research prototype that has been developed by Nick Pope - makes a 'guest appearance'. The Cadence environment comprises an extensible suite of modules that run on the DOSTE engine. In this lab, the focus is on how models can be built in DOSTE using the DASM notation.

Getting Started

First take a look at our attempt to model the Stargate. Open up a shell window (you can do this by pressing Alt+F2 and typing "konsole" into the search box) and copy the following into it:


This should bring up an interface to the Cadence prototype tool. This has two components: a Browser and an interface window that serves several functions, including that of a DASM input box.

One way of interacting with Cadence is via the DASM input box, by entering script. To bring up the Stargate model enter the following into the DASM input box:

%include "stargate/stargate.dasm";

Click 'Accept'. This should load up the model and display a window containing the Stargate.

Another way of interacting with Cadence - more in keeping with the spirit of making an artefact rather than writing program code - is via the Browser. Each node in the browser corresponds to what can be viewed as a different context for observation. Initially the browser displays only a single node, corresponding to the current focus of attention, in this case the key components of the Cadence environment itself (which includes the root context). Clicking on a blue node in the browser will reveal the subcontexts within that context. Contexts that contain no subcontext are indicated by green nodes if they are associated with an explicit observable (e.g. running, time, os) or red nodes if they are null. Contexts are highlighted in bold when they are updated - time and lasttime are being continuously updated for instance. You can open up contexts represented by blue nodes by clicking on them. For example, the ui context, which designates the user interface, contains the browser subcontext which in turn contains a root subcontext.

The most obvious way of using the Browser is for inspecting the status of nodes. Click on the blue node in the browser to reveal the context containing all the observables in the Stargate model. The nodes in the browser are a visual representation of information that is described textually using DASM. Click on the small "Dial" button in the top left which should start an animation of the dialling process with the changes also appearing in the browser.

Explore the browser interface by clicking on nodes and interpreting the results. What is the meaning of the '.' subcontext? In your initial exploration, you should simply view the status of nodes in the browser, but you may also observe in passing how the definitions of nodes can be modified via the GUI.

Entering the following into the DASM input box will display the observables in the @stargate context in textual form in the Konsole window:

%list @stargate;

In the listing, observational contexts containing subcontexts are listed by abstract context identifiers: for instance, orientation = <[1:0:1:2360]>. To explore this subcontext, enter:

%list @stargate orientation;

The %list command displays observables together with their definitions. It is convenient to use the term 'observable' in a broad sense, so that it not only refers to commonsense observables such as the speed of motion of a chevron (chevspeed), but also to observational contexts. This is quite appropriate, since in Cadence observational contexts are also subject to change. To determine the current value of a specific observable, you can simply locate the observable in the Browser, and read off its current status. See if you can use this technique to find out what observational context is currently being displayed in the browser. (This is quite tricky, as this context doesn't relate to an observable that is directly displayed in the Browser. It can actually be displayed indirectly though - if you can find out how!)

Yet another way to explore the Stargate model is to inspect the script itself, as defined by the family of .dasm files specified in the file 'stargate.dasm' in the '~empublic/share/cadence/projects/stargate' directory. To understand the model better, take a look at the 'gate.dasm' file. You can use a text editor called 'kate' to open this file and this can also be run from Alt+F2 or from the start menu. The gate.dasm file describes the key components and behaviour of the model. Other files describe the visual effects and other structures which we are currently not concerned about.

In your initial examination of the gate.dasm file, you will probably find it difficult to understand fully how observables and dependencies are specified.The best way to deepen your understanding is to interact with the model.

Interacting with the Stargate model

For the rest of the lab you will be working with a simplified version of the Stargate model which has had all our work on the dialling sequence removed. Start by closing Cadence.

For this part of the lab, you will find it helpful to use some basic Unix command-line skills, such as the ability to create directories, copy files etc (refer to the CS405 webpage for useful links on this topic). First create a directory called 'stargate' in your home directory and put the 'gate.dasm' file available from here in the stargate directory. In a konsole window, first type 'cd' to make sure that you are in your home directory. Run the following command:


[Note in passing that it matters what directory you are in when the interpreter is invoked. If you have some Unix knowledge, you can explain this by inspecting the shell script that you are actually invoking - see the Supplementary Notes on the right-hand panel of the webpage.]

When Cadence is running, include the Stargate model by entering the following into the Input Window:

%include "stargate/stargate.dasm";

You now have the simplified version of the Stargate model running; the 'gate.dasm' file you downloaded will override the one you looked at previously. To test this try clicking on the 'Dial' button and nothing should happen this time.

Type the following into the DASM Input box:

@stargate chevrons 0 on = 1;

Click Accept and watch the light on the top chevron turn on. The same can be done for any of the chevrons and they can be turned off again by setting them to 0. Now try the next line:

@stargate ready = true;

This will reactivate the Stargate, turning the puddle effect on.

Finally we have the inner ring rotation (given in radians) which can be changed as follows:

@stargate rotation = 2.0;

As explained above, you can use the Browser to explore all the observables in @stargate that you can observe or change, and write queries in the input box to find out the current values of specific observables. Using these features, you can play around with redefining observables for a bit and again take a look at the simplified 'gate.dasm' you downloaded to see what other observables exist in the model. If you look in some of the other files you may find some really interesting observables to change. Note the way in which you can act to change the state of the model freely by entering new observables and dependencies at any point in time and the fact that all other kinds of state change in the model are also carried out by making redefinitions (though possibly automatically). This feature is characteristic of Empirical Modelling.

In the interface, you can recall the previous command etc using Alt-p and Alt-n, or inspect the complete history via the History tab.

Creating dependencies

Now that we know what we can change and what we can see let's try connecting things together using definitions which are similar to spreadsheet formula. A simple definition might be to say that the stargate is 'ready' when chevron 8 is turned on.

@stargate ready is { .chevrons 8 on == 1 };

What we have said is that 'ready' is true if the value of 'chevrons 8 on' is 1. Note the '.' (dot) before chevrons means 'this' or current context which corresponds to the object that the ready observable is in, which in this case is @stargate. You could use '@stargate' instead of '.'.

Now try turning chevron 8 on and see what happens.

There is another observable in the stargate which may be of interest. It is called 'dial' and becomes true whenever the mouse is clicking on the 'Dial' button. Just to check this you can define chevron 8 to come on when that button is depressed:

@stargate chevrons 8 on is { if (@stargate dial) {1} else {0} };

The stargate will also activate when the button is depressed because of the previous definition. We now leave it to you to play with these definitions, ask questions and look at the code for the stargate model. Try getting the puddle to activate only when all the lights are on. We will look at animation and making objects in later labs.

Varieties of definition

You should note three ways in which observables can be defined in DASM, however:

  • by direct assignment of a current value, as is done by using the symbol "="
  • by giving a definition of the current value, as is done with the keyword "is"
  • by specifying the process by which the value of an observable is to be updated, as is done using the symbol ":="

The first and second ways of associating a value with an observable are of the same essential type as traditional procedural assignment and cell definition in a spreadsheet environment respectively.

The third way of defining the value of an observable (also called a "will be" definition) takes account of the fact that the DOSTE engine updates the state of all observables continually. A "becomes equal to" (:=) definition asserts that, on each update, the next value of the observable on the LHS of the := will be equal to the current value of the expression on the RHS. Note that:

  • in an "is" definition, the RHS cannot be linked via a chain of "is" definitions that refers, however indirectly, to the observable on the LHS : this would be a cyclic definition.
  • in a "will be" definition, it is perfectly possible for the RHS to refer to the observable on the LHS, since it makes sense to define the next value of an observable in terms of its current value.
  • the value of an observable is not completely specified by a "will be" definition alone: some initial value has to be assigned in order for the update process to generate a stream of values.

You can test this by contrasting the effect of the two definitions:

.a is {.a};

.a := {.a};

and inspecting the value of .a via the Browser.

Find examples of all three kinds of definition in the gate.dasm file. See if you can figure out what commonsense observables they correspond to in Stargate, and why they have been defined in this particular way.

Further notes and links

Bret Victor's thinking has been the subject of much discussion - and controversy - in online forums. His essay on Learnable Programming is a response to John Resig's blog on techniques for teaching programming from the Khan Academy. Subsequent reactions to Victor's ideas are reviewed here.

Cadence is being used here simply for illustrative purposes, and is not being supported as a platform for coursework in 2013-14. For more background, see labs 1, 2 and 6 for CS405 in 2011-12 and consult Nick Pope's PhD thesis. Ideas prototyped in Cadence have been further developed in Pope's Dynamic Structure Base (DSB), an open source project that can be accessed at

Answerr to crytic question in text!

To reference the observational context at which the browser is focused, enter

@ui browser root

This can be set by a definition such as

@ui browser root = ( @dasm variables );