Suppose you have a whole bunch of dominoes that spring back up precisely three seconds after they’ve fallen down. Can you build a computer out of them?

It turns out that you can. But let’s start out by reasoning about the basics. To keep things simple, assume we have a big flat 2d floor on which to stand the dominoes. When playing with dominoes, the typical thing you do is put them in a line on the floor, and knock one over. Let’s call the line of dominoes a *stream*, and say that as they fall, a *wave* of falling dominoes travels down the stream. We’re supposed to be modeling a computer, so let’s say that a wave represents a `1`

and the lack of a wave represents `0`

. Of course we can connect several streams together, so call a bunch of connected streams with some waves a *circuit*.

What sorts of circuits can we build? Let’s start simple. The most basic thing we can do with a stream is put a fork in it. Here’s a diagram:

On the left is a picture of what the tops of the dominoes would look like, and on the right is a more abstract representation. I’m lazy about drawing, so we’ll use only abstract drawings from now on. I’ve labelled this circuit `COPY GATE`

because if a wave comes down from ‘in’, it will be duplicated to each ‘out’. Hence we can take a bit sequence – that is, a sequence of waves and lack of waves – and duplicate it.

Ok, so that’s what a fork does. Well, at least that’s what it does if the wave is coming towards the fork. If we instead put that circuit upside down, we get an `OR GATE`

instead:

There’s a weakness to our circuits so far: they can duplicate `1`

s, but can’t produce any if there are none to start with. Fortunately we can produce an infinite sequence of `1`

s with a simple loop. Since the dominoes stand back up, a wave in a loop (of sufficient circumference) will circle it forever, and a `COPY`

gate will emit a `1`

each time it goes around. Adjusting the circumference of the loop controls the timing of the sequence.

This can easily be extended to implement *memory*. In the circuit below, the left input is used to “set” the memory, after which the output is a sequence of `1`

s; and the right input is used to “unset” it, returning the output to `0`

.

It’s also possible to build a *diode*; a circuit that allows “current” (i.e. waves) in one direction but not the other. Here a wave from the left will run into itself and “cancel out”, while an input from the top will continue on to the left unimpeded.

We can use a diode and a `1`

input to construct a not gate. To do so, you have to be very careful about the delays that streams introduce, just like in a real computer. I’ve labelled parts of this circuit with numbers indicating how many seconds a wave should take to traverse them. There’s also two little boxes; these don’t correspond to anything physical, they just mark interesting locations where waves in opposite directions will cancel out.

Now we have both OR and NOT gates. It’s well known that these gates together are *universal*, meaning that they can be combined to construct any logic gate. For instance, you can construct AND because `x AND y`

is the same as `NOT ((NOT x) OR (NOT y))`

. (It’s important that we have a ONE and COPY gate too, though those are usually taken for granted.) Thus we can build arbitrary logic gates.

Actually, I just lied. Do you see the hidden assumption?

When combining various circuits, it’s generally assumed that you can attach any circuit’s output to any other circuit’s input. But can we do that? The floor we’re placing dominoes on is 2-dimensional, and we can’t just have two streams cross because they’d crash into one another.

Fortunately there’s a workaround. There’s a circuit made up of `OR`

and `NOT`

gates whose outputs are its inputs, but swapped. Below is a picture. The inputs are labelled `x`

and `y`

, and intermediate values are labelled. Juxtaposition means `AND`

, `+`

means `OR`

, and a bar on top of a letter means `NOT`

. Streams splitting and joining together mean `COPY`

and `OR`

gates, as you would expect, and each veritcal bar is a `NOT`

gate. By using this circuit we can swap streams, so with enough of them we can arrange streams however we need to, and so these circuits really are universal.

Therefore you can make memory and arbitrary logic gates out of stand-up-again-dominoes, and, with enough patience, a general-purpose computer.