Zero in Greek mathematics

I recently read The Nothing That Is: A Natural History of Zero by Robert M. Kaplan. Zero is an important concept in mathematics. But where did it come from?

The Babylonian zero

From around 2000 BC, the Babylonians used a positional number system with base 60. Initially a space was used to represent zero. Vertical wedges mean 1, and chevrons mean 10:

This number (which we can write as 2 ; 0 ; 13) means 2 × 3600 + 0 × 60 + 13 = 7213. Four thousand years later, we still use the same system when dealing with angles or with time: 2 hours, no minutes, and 13 seconds is 7213 seconds.

Later, the Babylonians introduced a variety of explicit symbols for zero. By 400 BC, a pair of angled wedges was used:

The Babylonian zero was never used at the end of a number. The Babylonians were happy to move the decimal point (actually, “sexagesimal point”) forwards and backwards to facilitate calculation. The number ½, for example, was treated the same as 30 (which is half of 60). In much the same way, 20th century users of the slide rule treated 50, 5, and 0.5 as the same number. What is 0.5 ÷ 20? The calculation is done as 5 ÷ 2 = 2.5. Only at the end do you think about where the decimal point should go (0.025).

Greek mathematics in words

Kaplan says about zero that “the Greeks had no word for it.” Is that true?

Much of Greek mathematics was done in words. For example, the famous Proposition 3 in the Measurement of a Circle (Κύκλου μέτρησις) by Archimedes reads:

Παντὸς κύκλου ἡ περίμετρος τῆς διαμέτρου τριπλασίων ἐστί, καὶ ἔτι ὑπερέχει ἐλάσσονι μὲν ἤ ἑβδόμῳ μέρει τῆς διαμέτρου, μείζονι δὲ ἢ δέκα ἑβδομηκοστομόνοις.

Phonetically, that is:

Pantos kuklou hē perimetros tēs diametrou triplasiōn esti, kai eti huperechei elassoni men ē hebdomō merei tēs diametrou, meizoni de ē deka hebdomēkostomonois.

Or, in English:

The perimeter of every circle is triple the diameter plus an amount less than one seventh of the diameter and greater than ten seventy-firsts.

In modern notation, we would express that far more briefly as 10/71 < π − 3 < 1/7 or 3.141 < π < 3.143.

The Greek words for zero were the two words for “nothing” – μηδέν (mēden) and οὐδέν (ouden). Around 100 AD, Nicomachus of Gerasa (Gerasa is now the city of Jerash, Jordan), wrote in his Introduction to Arithmetic (Book 2, VI, 3) that:

οὐδέν οὐδενί συντεθὲν … οὐδέν ποιεῖ (ouden oudeni suntethen … ouden poiei)

That is, zero (nothing) can be added:

nothing and nothing, added together, … make nothing

However, we cannot divide by zero. Aristotle, in Book 4, Lectio 12 of his Physics tells us that:

οὐδὲ τὸ μηδὲν πρὸς ἀριθμόν (oude to mēden pros arithmon)

That is, 1/0, 2/0, and so forth make no sense:

there is no ratio of zero (nothing) to a number

If we view arithmetic primarily as a game of multiplying, dividing, taking ratios, and finding prime factors, then poor old zero really does have to sit on the sidelines (in modern terms, zero is not part of a multiplicative group).

Greek calculation

For business calculations, surveying, numerical tables, and most other mathematical calculations (e.g. the proof of Archimedes’ Proposition 3), the Greeks used a non-positional decimal system, based on 24 letters and 3 obsolete letters. In its later form, this was as follows:

Units Tens Hundreds
α = 1 ι = 10 ρ = 100
β = 2 κ = 20 σ = 200
γ = 3 λ = 30 τ = 300
δ = 4 μ = 40 υ = 400
ε = 5 ν = 50 φ = 500
ϛ (stigma) = 6 ξ = 60 χ = 600
ζ = 7 ο = 70 ψ = 700
η = 8 π = 80 ω = 800
θ = 9 ϙ (koppa) = 90 ϡ (sampi) = 900

For users of R:

to.greek.digits <- function (v) { # v is a vector of numbers
  if (any(v < 1 | v > 999)) stop("Can only do Greek digits for 1..999")
  else {
    s <- intToUtf8(c(0x3b1:0x3b5,0x3db,0x3b6:0x3c0,0x3d9,0x3c1,0x3c3:0x3c9,0x3e1))
    greek <- strsplit(s, "", fixed=TRUE)[[1]]
    d <- function(i, power=1) { if (i == 0) "" else greek[i + (power - 1) * 9] }
    f <- function(x) { paste0(d(x %/% 100, 3), d((x %/% 10) %% 10, 2), d(x %% 10)) }
    sapply(v, f)

For example, the “number of the beast” (666) as written in Byzantine manuscripts of the Bible is χξϛ (older manuscripts spell the number out in words: ἑξακόσιοι ἑξήκοντα ἕξ = hexakosioi hexēkonta hex).

This Greek system of numerals did not include zero – but then again, it was used in situations where zero was not needed.

Greek geometry

Most of Greek mathematics was geometric in nature, rather than based on calculation. For example, the famous Pythagorean Theorem tells us that the areas of two squares add up to give the area of a third.

In geometry, zero was represented as a line of zero length (i.e. a point) or as a rectangle of zero area (i.e. a line). This is implicit in Euclid’s first two definitions (σημεῖόν ἐστιν, οὗ μέρος οὐθέν = a point is that which has no part; γραμμὴ δὲ μῆκος ἀπλατές = a line is breadthless length).

In the Pythagorean Theorem, lines are multiplied by themselves to give areas, and the sum of the two smaller areas gives the third (image: Ntozis)

Graeco-Babylonian mathematics

In astronomy, the Greeks continued to use the Babylonian sexagesimal system (much as we do today, with our “degrees, minutes, and seconds”). Numbers were written using the alphabetic system described above, and at the time of Ptolemy, zero was written like this (appearing in numerous papyri from 100 AD onwards, with occasional variations):

For example, 7213 seconds would be β ō ιγ = 2 0 13 (for another example, see the image below). The circle here may be an abbreviation for οὐδέν = nothing (just as early Christian Easter calculations used N for Nulla to mean zero). The overbar is necessary to distinguish ō from ο = 70 (it also resembles the overbars used in sacred abbreviations).

This use of a circle to mean zero was passed on to the Arabs and to India, which means that our modern symbol 0 is, in fact, Graeco-Babylonian in origin (the contribution of Indian mathematicians such as Brahmagupta was not the introduction of zero, but the theory of negative numbers). I had not realised this before; from now on I will say ouden every time I read “zero.”

Part of a table from a French edition of Ptolemy’s Almagest of c. 150 AD. For the angles x = ½°, 1°, and 1½°, the table shows 120 sin(x/2). The (sexagesimal) values, in the columns headed ΕΥΘΕΙΩΝ, are ō λα κε = 0 31 25 = 0.5236, α β ν = 1 2 50 = 1.0472, and α λδ ιε = 1 34 15 = 1.5708. The columns on the right are an aid to interpolation. Notice that zero occurs six times.


Eight Greek inscriptions

I love ancient inscriptions. They provide a connection to people of the past, they provide an insight into how people thought, and they demonstrate how the experience of writing has changed over the past five thousand years or so. Here are eight Greek inscriptions and documents that interest me – some historical, some religious, and one mathematical.

Six of the eight inscriptions

1. The inscription that is no longer there, 480 BC

Our first inscription was inscribed at the site of the Battle of Thermopylae (480 BC), where Leonidas and his 300 Spartans (plus several thousand allies) died trying to hold off a vastly superior Persian army. The inscription no longer exists (though there is a modern copy at the site), but the wording has been preserved by Herodotus (Histories 7.228.2):


Phonetically, that reads:

Ō ksein’, angellein
Lakedaimoniois hoti tēide
keimetha, tois keinōn
rhēmasi peithomenoi.

I’ve always thought that there was a degree of sarcasm in this laconic epigram – after all, the Spartans had declared war on the Persians (rather informally, by throwing the Persian ambassadors down a well), but then stayed home, leaving Leonidas and his personal honour guard (plus the allies) to do the actual fighting. My (rather free) personal translation would therefore be:

Go tell the Spartans,
Stranger passing by,
We listened to their words,
And here we lie.

The battle of Thermopylae, 480 BC (illustration: John Steeple Davis)

2. The Rosetta Stone, 196 BC

The rich history of the Rosetta Stone has always fascinated me (and I made a point of seeing the Stone when I visited the British Museum). The Stone records a decree of 196 BC from Ptolemy V, inscribed using three forms of writing – Egyptian hieroglyphs, Egyptian demotic script, and a Greek translation. The Stone was therefore a valuable input to the eventual decoding of Egyptian hieroglyphs. Romance practically drips off the Stone.

The Rosetta Stone in the British Museum (photo: Hans Hillewaert)

3. The Theodotus inscription, before 70 AD

The Theodotus inscription in Jerusalem was located in a 1st century synagogue near the Temple (this dating is generally accepted). It reads as follows (with [square brackets] denoting missing letters):


In translation:

Theodotus, son of Vettenus [or, of the gens Vettia], priest and
archisynagogue [leader of the synagogue], son of an archisynagogue,
grandson of an archisynagogue, built
the synagogue for the reading of
the Law and for teaching the commandments;
also the hostel, and the rooms, and the water
fittings, for lodging
needy strangers. Its foundation was laid
by his fathers, and the
elders, and Simonides.

The inscription is interesting in a number of ways. Along with other similar inscriptions, it demonstrates the existence of Greek-language synagogues in 1st Palestine. The title ἀρχισυνάγωγος (archisynagōgos) also occurs in the New Testament (nine times, starting at Mark 5:22), so is clearly a title of the time-period. Some scholars have suggested that Theodotos was a freed slave, who had made his fortune and returned from Italy to the land of his fathers (in which case there is a very slight possibility that the synagogue with the inscription might have been the “synagogue of the Freedmen” mentioned in Acts 6:9).

The Theodotus inscription in the Israel Museum, Jerusalem (photo: Oren Rozen)

4. The Delphi inscription, 52 AD

The Temple of Apollo at Delphi (photo: Luarvick)

The Delphi inscription is a letter of around 52 AD from the Roman emperor Claudius. It was inscribed on stone at the Temple of Apollo at Delphi (above), although it now exists only as nine fragments. Of particular interest is this line (see also the photograph below):


Phonetically, that reads:

[Jou]nios Galliōn ‘o ph[ilos] mou ka[i anthu]patos …

This is a reference to Lucius Junius Gallio Annaeanus, who was briefly proconsul (anthupatos) of the Roman senatorial province of Achaea (southern Greece) at the time:

Junius Gallio, my friend and proconsul …

This same anthupatos Gallio appears in the New Testament (Acts 18:12–17: “Γαλλίωνος δὲ ἀνθυπάτου ὄντος τῆς Ἀχαΐας …”), and therefore provides a way of dating the events described there.

One of the fragments of the Delphi inscription, highlighting the name ΓΑΛΛΙΩΝ = Gallio (photo: Gérard)

5. Papyrus Oxyrhynchus 29, c. 100 AD

I have written before about Papyrus Oxyrhynchus 29. It contains the statement of Proposition 5 of Book 2 of Euclid’s Elements, with an accompanying diagram (plus just a few letters of the last line of the preceding proposition). In modern Greek capitals, it reads:


However, the actual document (image below) uses “Ϲ” for the modern “Σ,” and “ω” for the modern “Ω”:


This manuscript is important because, being from 75–125 AD, it dates to only four centuries after the original was written in 300 BC – most manuscripts of Euclid are twelve centuries or more after (in fact, it pre-dates the alterations made to the work by Theon of Alexandria in the 4th century AD). The manuscript also contains one of the oldest extant Greek mathematical diagrams. The text is identical to the accepted Greek text, except for two spelling variations and one one grammatical error (τετραγώνου for τετραγώνῳ on the last line, perhaps as the result of the mental influence of the preceding word in the genitive):

ἐὰν εὐθεῖα γραμμὴ
τμηθῇ εἰς ἴσα καὶ ἄνισα,
τὸ ὑπὸ τῶν ἀνίσων τῆς ὅλης τμημάτων περιεχόμενον ὀρθογώνιον
μετὰ τοῦ ἀπὸ τῆς μεταξὺ τῶν τομῶν τετραγώνου
ἴσον ἐστὶ τῷ ἀπὸ τῆς ἡμισείας τετραγώνῳ.

It is really just a geometric way of expressing the equality (x + y)2 = x2 + 2xy + y2, but in English it reads as follows:

If a straight line
be cut into equal and unequal [segments] (x + y + x and y),
the rectangle contained by the unequal segments of the whole (i.e. (x + y + x)y = 2xy + y2)
together with the square on the straight line between the points of section (+ x2)
is equal to the square on the half (= (x + y)2).

The proof of the proposition is missing, however, and there are no labels on the diagram. I suspect that the manuscript was a teaching tool of some kind (either an aide-mémoire or an exam question). Alternatively, it may have been part of an illustrated index to the Elements.

Papyrus Oxyrhynchus 29 (photo: Bill Casselman)

6. Rylands Library Papyrus P52, c. 140 AD

Papyrus P52 is a small fragment written in a similar style to Papyrus Oxyrhynchus 29, but is dated a few decades later (to around 140 AD). In modern Greek capitals, it reads:


The reverse side also has writing:


Some clever detective work has identified the fragment as being from a manuscript of the New Testament gospel of John (John 18:31b–33 and 18:37b–38), permitting the reconstruction of the missing letters. The fragment is from the top inner corner of a book page (books with bound two-sided pages were a relatively new technology at the time, with many people still using scrolls). The fragment dates from less than a century after the gospel of John was written (and possibly just a few decades), thus helping in dating that work. There is no indication of any textual difference from later manuscripts – even the text on the missing parts of the front page seems of the right amount. The only exception is in the second line of the reverse side – there’s not quite enough room for the expected wording, and it seems likely that the duplicated words ΕΙΣ ΤΟΥΤΟ were not present.

In English, the passage reads:

… the Jews, “It is not lawful for us to put anyone to death.” This was to fulfil the word that Jesus had spoken to show by what kind of death he was going to die. So Pilate entered the Praetorium again and called Jesus and said to him, “Are you the King of the Jews?” …
… I am a king. For this purpose I was born and for this purpose I have come into the world – to bear witness to the truth. Everyone who is of the truth listens to my voice.” Pilate said to him, “What is truth?” After he had said this, he went back outside to the Jews and told them, “I find no guilt in him.”

Papyrus P52 (front and back) in the John Rylands Library

7. The Akeptous inscription in the Megiddo church, c. 250 AD

The Akeptous inscription is one of a number of inscriptions found in the mosaic floor of a 3rd century church which was discovered in 2005 while digging inside the Megiddo Prison in Israel (the date is just slightly later than the Dura-Europos church in Syria). The Akeptous inscription reads:

ZΑΝ {Θω} {ΙΥ} {Χω}


Prosēniken Akeptous, ‘ē philotheos, tēn trapezan Th(e)ō Ι(ēso)u Ch(rist)ō mnēmosunon.

In English translation:

A gift of Akeptous, she who loves God, this table is for God Jesus Christ, a memorial.

Brief as it is, the inscription has several interesting features. First, Jesus Christ is being explicitly referred to as God, which tells us something about Christian beliefs of the time. Second, the inscription uses nomina sacra – divine names (“God,” “Jesus,” and “Christ”) are abbreviated with first and last letter, plus an overbar (this is denoted by curly brackets in the Greek text above). Third, the inscription records the gift of a prominent (presumably wealthy) female church member (the feminine definite article shows that Akeptous was female). And fourth, the reference to the construction of a table suggests that there were architectural features in the church to support the celebration of Communion, which tells us something about liturgy.

The Akeptous inscription in the Megiddo church

8. The Codex Sinaiticus, c. 340 AD

Our final inscription is a portion of the Codex Sinaiticus, a 4thcentury manuscript of the Christian Bible, containing the earliest complete copy of the New Testament. This Bible is a century later than the Megiddo church, and two centuries after Papyrus P52. Unlike Papyrus P52, it is written on vellum made from animal skins, and is written in beautiful calligraphic script. I have selected the passage John 1:1–3a:


In English:

In the beginning was the Logos, and the Logos was with God, and the Logos was God. He was in the beginning with God. All things through him were made, and apart from him was not one thing made …

In the Greek, nomina sacra for “God” can be seen, together with a number of corrections (including, on the last line, an expansion of the contraction ΟΥΔΕΝ = “nothing” to ΟΥΔΕ ΕΝ = “not one thing”). Spaces between words had still not been invented, nor had punctuation or lowercase letters, which means that it is almost impossible to make sense of the text unless it is read aloud (or at least subvocalised). Fortunately, things have changed in the last seventeen centuries!

John 1:1–3a in the Codex Sinaiticus

And returning him safely to the earth

In 1961, John F. Kennedy told Congress: “I believe that this nation should commit itself to achieving the goal, before this decade is out, of landing a man on the moon and returning him safely to the earth.

The Moon landing on 20 July 1969 achieved the first part of that goal. The second part was yet to come (in 1970, that would prove to be the hard part).

But on 21 July 1969, at 17:54 UTC, the spacecraft Eagle lifted its metaphorical wings and took off from the Moon (well, the upper ascent stage took off, as shown in the photograph below). There followed a rendezvous with Columbia, a flight back to Earth, and an eventual splashdown on 24 July. Mission accomplished.

A tale of two arrivals

Fifty years ago, on 19 July 1969, the spaceship duo Columbia / Eagle entered orbit around the Moon, roughly 3 days and 4 hours after its launch, as part of the Apollo 11 mission. Eagle (with Neil Armstrong and Buzz Aldrin) went on the land on the moon on 20 July while Columbia (with Michael Collins) continued to orbit the moon. When he announced the space programme, Kennedy had said:

We choose to go to the moon. We choose to go to the moon in this decade and do the other things, not because they are easy, but because they are hard, because that goal will serve to organize and measure the best of our energies and skills, because that challenge is one that we are willing to accept, one we are unwilling to postpone, and one which we intend to win, and the others, too.

Much can be learned from doing hard things, and an enormous amount was learned from the space programme. Solar car teams also learn a great deal from doing hard things. Fifty years after Columbia and Eagle entered orbit, also after hard effort, the University of Michigan Solar Team’s solar car Electrum arrived in public view (at 17:30 Michigan time). They intend to win too!

The Invention of Clouds: a book review

The Invention of Clouds: How an Amateur Meteorologist Forged the Language of the Skies by Richard Hamblyn (2001)

I recently read The Invention of Clouds by Richard Hamblyn, who also wrote Terra (which I reviewed some years ago). The present volume focuses on the Quaker pharmacist Luke Howard, who produced a taxonomy of clouds in 1802. Essentially the same classification is still used today (but not, as Hamblyn points out, without considerable debate during the 1800s):

Although the focus is on Howard’s work and life, Hamblyn in fact provides a brief history of meteorology (or at least of the study of clouds), and there is a chapter on the Beaufort scale. Contemporary literature referred to includes:

Google Ngrams plot for three of the cloud types (with and without hyphens). The words “cirrostratus” and “cirrocumulus” first appear in reprintings of Howard’s pioneering essay, while the word “cumulonimbus” is introduced around 1887. There is a renewed spike of interest in cloud types beginning in the early 1940’s.

The Invention of Clouds also has some interesting comments on clouds in art and on how to get an education at a time when the two English universities banned non-Anglicans from attending. However, the book does have a few small errors. For example, cloud droplets are not “a mere millionth of a millimetre across,” but in the range 0.005 to 0.05 mm. However, that does not stop the book from being both enjoyable and informative (although I did wish for colour images). See also this review from the NY Times.

The Invention of Clouds by Richard Hamblyn: 3½ stars

Ada’s Program

Fragment of the Analytical Engine’s arithmetic/logic unit built by Babbage (photo: Science Museum London) and punched cards for operating it (photo: Karoly Lorentey)

Following on from my post about his Difference Engine, Charles Babbage’s Analytical Engine deserves some discussion. Only small pieces of the Analytical Engine were built. Indeed, Babbage’s ideas were so far ahead of his time that it could not be built with the technology available to him. Babbage was clearly either a true genius – or else he was a time-traveller from the future trying to recreate a modern computer.

It is not quite clear whether Babbage’s Analytical Engine was Turing complete. The kind of abstract computer developed independently by Alan Turing and Emil Post uses an arbitrarily long tape. Even more abstract models of computation use arbitrarily long integers to achieve the same effect. For example, the list (2, 3, 0, 1) can be encoded as the number 582 (1001000110 in binary). Modern computers use a sequence of numbered memory locations, accessed by indexing. The Analytical Engine could not do this. To quote the excellent analysis by Allan G. Bromley, “With hindsight we may note that in the Analytical Engine (at least until 1840) Babbage did not possess the variable-address concept; that is, there was no mechanism by which the machine could, as a result of a calculation, specify a particular variable in the store to be used as the operand for an instruction.

Ada King-Noel, the Countess of Lovelace (1836 portrait by Margaret Sarah Carpenter, cropped)

Babbage was not terribly good at explaining his ideas in writing, unfortunately. The best description is a 13-page summary of of a lecture by Babbage written in French by Luigi Federico Menabrea (later Prime Minister of Italy). This was translated into English in 1843 by Augusta Ada King-Noel (née Byron), the Countess of Lovelace.

Ada added 36 pages of detailed notes of her own. These include several insightful comments regarding the philosophy of computing, such as: “Again, it might act upon other things besides number, were objects found whose mutual fundamental relations could be expressed by those of the abstract science of operations, and which should be also susceptible of adaptations to the action of the operating notation and mechanism of the engine. Supposing, for instance, that the fundamental relations of pitched sounds in the science of harmony and of musical composition were susceptible of such expression and adaptations, the engine might compose elaborate and scientific pieces of music of any degree of complexity or extent. The Analytical Engine is an embodying of the science of operations, constructed with peculiar reference to abstract number as the subject of those operations.” (from Note A).

Also: “The Analytical Engine has no pretensions whatever to originate anything. It can do whatever we know how to order it to perform.” (from Note G).

The diagram from Note G, which shows what is essentially a computer program

Ada is sometimes described as the “first computer programmer,” based on the material in her Note G. This is clearly incorrect, since Charles Babbage had written several dozen programs for the Analytical Engine before 1840. Perhaps “first computer scientist” would be a better title. The program described in Ada’s Note G computes Bernoulli numbers. It does so using the fact that each Bernoulli number can be computed from its predecessors via the relationship:

0 = A0 + A1B1 + A3B3 + A5B5 + … + B2n−1

Here each Ai can be calculated as follows:

a <- function (n, i) {
	if (i == 0) -0.5 * (2*n - 1) / (2*n + 1)
	else if (i == 1) n
	else a(n, i-2) * (2*n + 2 - i) * (2*n + 1 - i) / (i * (i + 1))

Bromley notes that “the ‘user instruction set’ of the Analytical Engine seems nowhere to be clearly stated,” which makes it a little difficult to extract an actual program from Ada’s material. After fixing three small bugs, here is something that actually works (in the language R, and all done using numbered registers):

ada <- function (n.max) {
	b <- rep(0, n.max)  # result registers
	v <- c(1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)  # other registers
	while (v[3] <= n.max) {  # how is this loop done in the Analytical Engine?
		v[4] <- v[5] <- v[6] <- v[2] * v[3]
		v[4] <- v[4] - v[1]  # v[1] is always 1
		v[5] <- v[5] + v[1]
		v[11] <- v[4] / v[5]  # accidentally reversed in Ada’s diagram
		v[11] <- v[11] / v[2]  # v[2] is always 2
		v[13] <- v[13] - v[11]
		v[10] <- v[3] - v[1]
		if (v[10] > 0) {  # how is this conditional execution done in the Analytical Engine?
			v[7] <- v[2] + v[7]
			v[11] <- v[6] / v[7]
			v[12] <- b[1] * v[11]
			v[13] <- v[12] + v[13]
			v[10] <- v[10] - v[1]

		while(v[10] > 0) {  # how is this loop done in the Analytical Engine?
			v[6] <- v[6] - v[1]
			v[7] <- v[1] + v[7]
			v[8] <- v[6] / v[7]
			v[11] <- v[8] * v[11]
			v[6] <- v[6] - v[1]
			v[7] <- v[1] + v[7]
			v[9] <- v[6] / v[7]
			v[11] <- v[9] * v[11]
			i <- v[3] - v[10]   # how is this indexing done in the Analytical Engine?
			v[12] <- b[i] * v[11]
			v[13] <- v[12] + v[13]
			v[10] <- v[10] - v[1]

		n <- v[3]  # how is this indexing done in the Analytical Engine?
		b[n] <- b[n] - v[13]  # another apparent error in Ada's table at line 14 (negation is needed)

		v[3] <- v[1] + v[3]
		v[7] <- 0   # reset the register with a “variable card”
		v[13] <- 0  # a third apparent error in Ada's table (v[13] needs to be reset, not v[6])

There are a number of questions about this. First, I am assuming that all registers are read non-destructively (Ada’s notes indicate that read-and-clear is also possible). Second, the results stored in b require indexing, which the Analytical Engine could not do. Third, Ada writes that “Operation 7 must either bring out a result equal to zero (if n = 1); or a result greater than zero, as in the present case; and the engine follows the one or the other of the two courses just explained, contingently on the one or the other result of Operation 7.” This implies that some kind of conditional branching was possible. But how?

A simple response is simply to “unroll” the loops, breaking the program down into instructions of just three kinds:

  • Set 1 567: place the number 567 in register #1
  • Do 2 + 3: add the contents of register #2 to the content of register #3 (and similarly for −, ×, and ÷)
  • Store 4: store a previously computed result in register #4

The following, rather lengthy, version of the program correctly computes the first three Bernoulli numbers:

Set 1 1, Set 2 2, Set 3 1

# First Bernoulli number
Do 2 * 3, Store 4, Store 5, Store 6
Do 4 - 1, Store 4
Do 5 + 1, Store 5
Do 4 / 5, Store 11
Do 11 / 2, Store 11
Do 13 - 11, Store 13
Do 3 - 1, Store 10

Do 1 + 3, Store 3
Do 21 - 13, Store 21,  # 21 done
Set 7 0, Set 13 0

# Second Bernoulli number
Do 2 * 3, Store 4, Store 5, Store 6
Do 4 - 1, Store 4
Do 5 + 1, Store 5
Do 4 / 5, Store 11
Do 11 / 2, Store 11
Do 13 - 11, Store 13
Do 3 - 1, Store 10

Do 2 + 7, Store 7
Do 6 / 7, Store 11
Do 21 * 11, Store 12,  # use 21
Do 12 + 13, Store 13
Do 10 - 1, Store 10

Do 1 + 3, Store 3
Do 22 - 13, Store 22,  # 22 done
Set 7 0, Set 13 0

# Third Bernoulli number
Do 2 * 3, Store 4, Store 5, Store 6
Do 4 - 1, Store 4
Do 5 + 1, Store 5
Do 4 / 5, Store 11
Do 11 / 2, Store 11
Do 13 - 11, Store 13
Do 3 - 1, Store 10

Do 2 + 7, Store 7
Do 6 / 7, Store 11
Do 21 * 11, Store 12,  # use 21
Do 12 + 13, Store 13
Do 10 - 1, Store 10

# Inner loop
Do 6 - 1, Store 6
Do 1 + 7, Store 7
Do 6 / 7, Store 8
Do 8 * 11, Store 11
Do 6 - 1, Store 6
Do 1 + 7, Store 7
Do 6 / 7, Store 9
Do 9 * 11, Store 11
Do 22 * 11, Store 12,  # use 22
Do 12 + 13, Store 13
Do 10 - 1, Store 10

Do 1 + 3, Store 3
Do 23 - 13, Store 23,  # 23 done
Set 7 0, Set 13 0

Can we do better than that? Bromley notes that “the mechanism by which the sequencing of operations is obtained is obscure.” Furthermore, driven by what was probably a correct intuition about code/data separation, Babbage separated operation and variable cards, and this would have played havoc with control flow (Bromley again: “I am not convinced that Babbage had clearly resolved even the representational difficulties that his separation of operation and variable cards implies”).

I’m resolving those issues by straying into what Babbage might have done had he seen the need. In particular:

  • I assume a conditional jump mechanism, with Ifzero 1 goto A jumping (somehow) to Label A if register #1 is zero (if operation and variable cards are reunited, this can be easily done by moving forward or back the required number of cards)
  • I assume an additional category of card, with its own card queue, with each such card specifying an output register, and with the operations:
    • Q (in Do, Store, Set, or Ifzero): access the register specified by the next card in the card queue
    • ResetQ: wind back the card queue to the start
    • StopifemptyQ: stop if all the cards in the card queue have been read

Yes, that’s all very speculative – but something like that is needed to make Ada’s loops work. In addition, the card queue (plus the associated output registers) performs the role of the tape in Turing/Post machines, or the memory in modern computers. Something like it is therefore needed.

And here is Ada’s program in that modified form. It works, loops and all! I tested it for the first 12 Bernoulli numbers, which are 0.1666667, −0.03333333, 0.02380952
−0.03333333, 0.07575758, −0.2531136, 1.166667, −7.092157, 54.97118, −529.1242, 6192.123, and −86580.25 (numerical errors do accumulate as the sequence is continued).

Set 1 1, Set 2 2, Set 3 1

Label A

Do 2 * 3, Store 4, Store 5, Store 6
Do 4 - 1, Store 4
Do 5 + 1, Store 5
Do 4 / 5, Store 11
Do 11 / 2, Store 11
Do 13 - 11, Store 13
Do 3 - 1, Store 10

Ifzero 10 goto B
Do 2 + 7, Store 7
Do 6 / 7, Store 11
Do Q * 11, Store 12  # Using 21
Do 12 + 13, Store 13
Do 10 - 1, Store 10

Label B

# Inner loop
Ifzero 10 goto C
Do 6 - 1, Store 6
Do 1 + 7, Store 7
Do 6 / 7, Store 8
Do 8 * 11, Store 11
Do 6 - 1, Store 6
Do 1 + 7, Store 7
Do 6 / 7, Store 9
Do 9 * 11, Store 11
Do Q * 11, Store 12  # Using 22, etc.
Do 12 + 13, Store 13
Do 10 - 1, Store 10
Ifzero 14 goto B  # Unconditional jump

Label C

Do 1 + 3, Store 3
Do 14 - 13, Store Q  # Using register 14 as constant zero

Set 7 0, Set 13 0, ResetQ
Ifzero 14 goto A  # Unconditional jump

And for those interested, here is an emulator (in R) which will read and execute that program. For a slightly different approach, see the online emulator here.

read.program <- function (f) {
	p <- readLines(f)
	p <- gsub(" *#.*$", "", p)  # remove comments
	p <- gsub(" *, *", ",", p)  # remove spaces after commas
	p <- p[p != ""]  # remove blank lines
	p <- paste0(p, collapse=",")  # join up lines
	p <- gsub(",+", ",", p)  # remove duplicate commas
	strsplit(p, ",")[[1]]  # split by commas

do.op <- function (x, op, y) {
	if (op == "+") x + y
	else if (op == "-") x - y
	else if (op == "*") x * y
	else if (op == "/") x / y
	else stop(paste0("Bad op: ", op))

emulate <- function(program, maxreg) {
	set.inst <- "^Set (Q|[0-9]*) (Q|[0-9]*)$"
	store.inst <- "^Store (Q|[0-9]*)$"
	do.inst <- "^Do (Q|[0-9]*) ([^ ]) (Q|[0-9]*)$"
	label.inst <- "^Label ([0-9A-Za-z]*)$"
	ifzero.inst <- "^Ifzero ([0-9]*) goto ([0-9A-Za-z]*)$"

	v <- rep(0, maxreg)
	op.result <- 0
	stopping <- FALSE
	pc <- 1
	queue <- 21:maxreg
	qptr <- 1
	while (pc <= length(program) && ! stopping) {
		p <- program[pc]
		if (grepl(set.inst, p)) {
			i <- gsub(set.inst, "\\1", p)
			j <- as.numeric(gsub(set.inst, "\\2", p))
			if (i == "Q") {
				i <- queue[qptr];
				qptr <- qptr + 1
			} else i <- as.numeric(i)
			v[i] <- j

		} else if (grepl(do.inst, p)) {
			i <- gsub(do.inst, "\\1", p)
			op <- gsub(do.inst, "\\2", p)
			j <- gsub(do.inst, "\\3", p)
			if (i == "Q") {
				i <- queue[qptr];
				qptr <- qptr + 1
			} else i <- as.numeric(i)
			if (j == "Q") {
				j <- queue[qptr];
				qptr <- qptr + 1
			} else j <- as.numeric(j)
			op.result <- do.op(v[i], op, v[j])

		} else if (grepl(store.inst, p)) {
			i <- gsub(store.inst, "\\1", p)
			if (i == "Q") {
				i <- queue[qptr];
				qptr <- qptr + 1
			} else i <- as.numeric(i)
			v[i] <- op.result

		} else if (grepl(ifzero.inst, p)) {
			i <- gsub(ifzero.inst, "\\1", p)
			if (i == "Q") {
				i <- queue[qptr];
				qptr <- qptr + 1
			} else i <- as.numeric(i)
			dest <- gsub(ifzero.inst, "\\2", p)
			j <- which(program == paste0("Label ", dest))
			if (v[i] == 0) pc <- j

		} else if (p == "StopifemptyQ") {
			if (qptr > length(queue)) stopping <- TRUE

		} else if (grepl(label.inst, p)) {
			# do nothing
		} else if (p == "ResetQ") {
			qptr <- 1
		} else stop(paste0("Bad instruction: ", p))
		pc <- pc + 1

emulate(program = read.program("ada.program.txt"), maxreg = 32)

Update: If we take Ada’s program as specifying implicit zeroing of unused registers, we get this slightly fancier version (which also works):

Set 1 1, Set 2 2, Set 3 1

Label A

Do 2 * 3, Store 4, Store 5, Store 6
Do 4 - 1, Store 4
Do 5 + 1, Store 5
Do 4 / 5 clearing 4 and 5
Store 11
Do 11 / 2, Store 11
Do 13 - 11 clearing 11
Store 13
Do 3 - 1, Store 10

Ifzero 10 goto B

Do 2 + 7, Store 7
Do 6 / 7, Store 11
Do Q * 11, Store 12  # Using 21
Do 12 + 13 clearing 12
Store 13
Do 10 - 1, Store 10

Label B

Ifzero 10 goto C  # Inner loop test

Do 6 - 1, Store 6
Do 1 + 7, Store 7
Do 6 / 7, Store 8
Do 8 * 11 clearing 8
Store 11
Do 6 - 1, Store 6
Do 1 + 7, Store 7
Do 6 / 7, Store 9
Do 9 * 11 clearing 9
Store 11
Do Q * 11, Store 12  # Using 22, etc.
Do 12 + 13 clearing 12
Store 13
Do 10 - 1, Store 10
Goto B  # End of inner loop

Label C

Do 1 + 3, Store 3
Do 14 - 13 clearing 13
Store Q  # Using register 14 as constant zero

Set 6 0, Set 7 0, Set 11 0, ResetQ
Goto A

ASC 11: Leadership

Nuon Solar Team celebrates their 2017 WSC win (photo: Anthony Dekker)

Ernest Hemingway famously said that “war is fought by human beings.” It’s the same with solar cars – they are built and raced by human beings. Or, as Solar Team Twente likes to say, they are “powered by human energy.

There are many aspects to this human side of solar car racing. I’ve written before about how little things like team clothing contribute to team cohesion. A diversity of skills is important if a team is to succeed. During the race, nutrition is one of the things necessary to keep people working at top efficiency. But today, I want to talk about team leadership.

Engineering leadership is critically important, although surprisingly little is written about it. Tracy Kidder produced a fantastic, almost ethnographic, description of real-world engineering in his 1981 book The Soul of a New Machine, but even that book has the actual leadership happening mostly in the background.

A century earlier, Leo Tolstoy opened his novel Anna Karenina with the words “Happy families are all alike; every unhappy family is unhappy in its own way” (“Все счастливые семьи похожи друг на друга, каждая несчастливая семья несчастлива по-своему”). That is true also for solar car teams. Many things have to be done right if a team is to succeed, but doing one thing badly is enough to stop a team in its tracks.

A team leader must, first of all, motivate team members to do their best – it is no accident that all the solar car team leaders I’ve met have been really nice people. A team leader must make sure that the overall problem of building, racing, and finding sponsorship for a solar car is broken down into manageable pieces, and that the right person is in charge of each piece – this is the essence of engineering.

A solar-car team leader must also have – and promote – a clear vision of the car that the team is going to build. It is possible to have a world-class suspension, a world-class body, world-class solar cells, and world-class everything else, and still fail, because the components were designed under different assumptions, and don’t actually fit together to make a world-class car.

A team leader must keep an eye on the critical path as well. Building a solar car for a race is one of the most challenging kinds of engineering project – one where the delivery date is fixed in stone. What project managers call the critical path is the sequence of activities which, if they take any longer than planned, are guaranteed to delay project completion. Generally, the schedule for building and testing a solar car doesn’t leave much room for that kind of schedule slippage.

One perennial question with solar car team leaders is how long it takes them to realise that there is a problem requiring the team to either (a) change the way it operates or (b) pull out of the competition. Each year, I am reminded by somebody or other of Napoleon’s 1812 invasion of Russia, summarised so well in the famous data visualisation above (by Charles Minard).

Napoleon’s death march (painted by Illarion Pryanishnikov)

Napoleon began his invasion with 422,000 men, and reached Moscow with only 100,000 survivors. This was not enough to do anything, so he turned around and went home again, losing most of his remaining troops to cold and skirmishes in the process. I have often wondered at what point Napoleon realised that his plan was not working the way that it was supposed to. In a similar way, there is always a solar car team that begins a last-minute “death-march,” working until 3:00 AM each night, desperately trying to finish their car. The early hours of the morning are not a good time to be making safety-critical engineering decisions, and teams which leave it so late to panic generally don’t do very well.

But enough of Napoleon. Let us listen to some men and women who know how it’s done (translations from Dutch are my own best attempts):

Olivier Berghuis, Solar Team Twente (2017): “As team leader you are the one ultimately responsible for the success of the project. That means that you have to keep a close eye on the progress of the project’s technical, communication, and financial aspects. The mood of the team and the personal development of each team member are also critically important important responsibilities of the team leader.” (“Als teamleider ben je eindverantwoordelijk voor het slagen van het project. Dat betekent dat je de voortgang van het project op technisch, communicatief en financieel gebied in de gaten moet houden. Daarnaast is de sfeer binnen het team en de persoonlijke ontwikkeling van elk teamlid een zeer belangrijke verantwoordelijkheid van de teamleider.”)

Shihaab Punia, University of Michigan (2016): “… build the best possible team and team culture …”

Photo: Jerome Wassenaar

Irene van den Hof, Solar Team Twente (2015): “I think that I am a good listener for my teammates. I try to put a lot of emphasis on that. Everyone is young and inexperienced, and that can sometimes cause problems, but together we are indeed a team, and everyone has to reach the finish line – I make sure of that.” (“Ik denk dat ik heel goed kan luisteren naar mijn teamgenoten. Daar probeer ik ook veel aandacht aan te besteden. Iedereen is jong en onervaren en dat kan voor problemen zorgen, maar samen zijn we wel een team en iedereen moet de eindstreep halen, daar zorg ik ook voor.”)

And it’s worth repeating the excellent insights from Rachel Abril, who was on the Stanford solar car team for four years (“Go fast, but not recklessly fast. Test it. Test it again. Test it more. Use failure as a foundation for success.”):