The World Vol 6 · Evolution
ch 66 / 105
Chapter 66

Who Can Breed With Whom

Compatibility before crossover

The last chapter left animals in The Hollow carrying links that other animals in the same valley had never held. A child of two such parents can inherit a wiring that works like neither parent. Reduce the difference between two genomes to one number, and allow a child together only inside 3.00.

The number counts wiring one genome has that the other has never held, distance between settings where both are wired the same way, and distance between the ten body factors. Above 3.00 the two creatures may still live beside each other; they do not breed together.

Crossover became useful because two lineages can hold different discoveries. Structural mutation makes the same mechanism dangerous: two useful wirings can produce a child whose inherited pieces no longer agree on what signal a node carries.

Compatibility is measured before the mate roll chooses among candidates. That keeps the roster rule local: a creature searches the same box six cells across, then filters out candidates whose genomes are too far away.

The page defines the distance, sorts the valley into species by representatives, and runs two hundred years with one kind of animal at the start. Species become a guard on breeding, not a label painted on after the fact.

◆ Note — measurement boundary

Everything here runs on the valley the senses chapter built: sixteen by twelve cells with the rim cracked and the room rule on, twenty-five animals founded on stream 12, a founding wiring of a hundred and forty-four links, and the eight ground channels switched on and billed. Nothing on this page may be set beside a figure from before the graph arrived, because those runs evolved a flat row of three hundred and seventy-eight weights and spent a different count of numbers on every birth.

The rule this chapter adds is off at the zero value like every other rule in this volume, and a pool that leaves it alone breeds the way it always bred.

Genome distance

Four things can differ between two genomes and each of them has to be counted in its own currency before any of them can be added to the others.

Links one of them has and the other has never held. A link carries a number minted against the pair of nodes it joined, so two links are the same link when they carry the same number and are strangers otherwise. Sort both genomes' links by that number and walk the two lists side by side: where the numbers agree the link is matched, and where one list has a number the other does not, the link belongs to one of them alone. Those unmatched links split into two kinds. Past the highest number the other genome holds, the other genome has nothing to say at all: it was never handed a number that high, so the link arrived after the two lines parted. Those are the excess links. Inside that range the other genome was alive and being minted numbers at the time and did not take this one up, and those are the disjoint links.

Settings where they are wired the same. Over the matched links, the mean gap between the two weights. Two controllers wired identically and set differently are one machine at two settings, so this counts for less than a difference in the wiring itself.

Bodies. The mean gap over the ten body factors. This one counts for as much as a link, because a body factor is what an animal weighs, how big a mouthful it takes and what a gram of it costs to keep, and two creatures whose bodies have parted make a child priced like neither of them.

▣ Build · stage 1 — four weights, one threshold, and a divisor
// internal/gene/kinds.go

// Sorting is the rule that decides which two creatures are near enough
// each other to have a child together: the four weights the
// compatibility distance is added up out of, the threshold two genomes
// have to be inside, and whether any of it is switched on at all.
//
// It is off at the zero value, so a pool that leaves it alone breeds the
// way a pool always bred and sorts nothing into anything.
type Sorting struct {
	// On is whether this valley sorts its creatures at all.
	On bool

	// The four weights, in the order the distance adds them.
	Excess   float64
	Disjoint float64
	Weight   float64
	Body     float64

	// Far is the threshold. Two creatures inside it may breed; two
	// outside it may not, and a child that is outside it from every
	// species alive opens one of its own.
	Far float64

	// Drifting is the representative rule as it is tempting to write
	// it: a species held by whichever member joined it last instead of
	// by the one that opened it. It is kept behind a flag so what a
	// moving representative does to a species can be run instead of
	// described, and it is false in every valley this book ships.
	Drifting bool
}

// Sorted is the rule every run in this book breeds under.
var Sorted = Sorting{On: true, Excess: 1.0, Disjoint: 1.0, Weight: 0.4, Body: 1.0, Far: 3.00}
// Small is the link count under which the excess and disjoint counts
// are left undivided.
//
// The two structural terms of the distance are counts of genes divided
// by how many genes the larger of the two wirings holds, so that a
// difference of ten links between two graphs of five hundred is not read
// as the same difference as ten links between two graphs of twelve.
// Under about twenty links that division stops being a fairness
// correction and becomes an eraser: one disjoint gene between two
// six-link wirings is a sixth of the whole controller, and dividing it
// by six calls it 0.17 when it ought to weigh a whole gene. So under
// this count the divisor is one and the counts are used as they stand.
//
// Nothing in this valley reaches it. A founding wiring here is a
// hundred and forty-four links and the operators only ever add, so the
// smallest graph any run of this book builds is seven times this
// number. The clause is here because the distance is written down once
// and used wherever a graph is, and a graph small enough to need it is a
// graph somebody will build one day on a bench.
const Small = 20

The two structural weights are equal and the weight term is under half of them, and those are decisions rather than measurements. A link one animal has and the other has never held is a piece of wiring the crossing cannot line up at all, and there is no small version of it. A weight that has drifted is a dial that has moved. What the four settings cost is easier to see once they have been run: on the widest pair anywhere in this chapter the two structural terms come to 0.54 and 0.65, the weight term to 1.14 and the body term to 0.98. The threshold of 3.00 sits where no single one of the four can carry a pair over it on its own.

▣ Build · stage 2 — two sorted lists, walked side by side
// internal/gene/kinds.go

// Terms is what one comparison of two genomes came to: the counts the
// distance is built out of and the number itself. It is handed back
// whole rather than as one float64 because every one of the four terms
// is a different kind of difference, and a run that prints only the
// total cannot say which of them moved.
type Terms struct {
	Same     int     // links both genomes carry, matched by the number on them
	Excess   int     // links past the last number the other one holds
	Disjoint int     // links inside that range the other one does not hold
	Links    int     // N: the larger link count, or 1 while both are under Small
	Weights  float64 // the mean gap between the weights of matched links
	Bodies   float64 // the mean gap over the ten body factors
	D        float64 // the four terms added up
}
	// Past this number one of the two has nothing to say, because it was
	// never handed a number that high. An unmatched link beyond it is
	// excess: wiring that arrived after the two lines parted. Inside it
	// the link is disjoint: wiring one line took up and the other, alive
	// at the time, did not.
	last := 0
	if len(xs) > 0 && len(ys) > 0 {
		last = xs[len(xs)-1].Innov
		if n := ys[len(ys)-1].Innov; n < last {
			last = n
		}
	}
	count := func(innov int) {
		if innov > last {
			t.Excess++
		} else {
			t.Disjoint++
		}
	}
	i, j := 0, 0
	for i < len(xs) && j < len(ys) {
		switch {
		case xs[i].Innov == ys[j].Innov:
			t.Same++
			t.Weights += abs(xs[i].W - ys[j].W)
			i, j = i+1, j+1
		case xs[i].Innov < ys[j].Innov:
			count(xs[i].Innov)
			i++
		default:
			count(ys[j].Innov)
			j++
		}
	}

The lists have to be sorted before that walk, and they are not sorted when they arrive. A wiring holds its links in the order they were grown, a split takes one out of the middle and puts two on the end, and a crossing appends one parent's unmatched links to the other's. So each genome's links are sorted once, when the genome is first asked about, and kept until the creature carrying it dies. That is not a detail of taste: a valley asks this question of every neighbour of every creature that can afford a child, which in the run at the end of this page is tens of millions of comparisons, and doing it out of a table built fresh each time costs about ten times what walking two sorted lists costs.

$ go run ./cmd/kinds -mode pair | head -30
kinds: the distance between two genomes, term by term

  d = 1.0 x E/N + 1.0 x D/N + 0.4 x Wbar + 1.0 x Bbar, and the threshold is 3.00
  E and D are excess and disjoint link genes, N the larger link count,
  Wbar the mean gap between matched weights and Bbar the mean gap over the ten body factors

  two founders of one valley: 144 links each, every number minted at the same founding
  the two genomes                 E      D      N      Wbar      Bbar         d  may breed
  a founder and itself            0      0    144    0.0000    0.0000    0.0000  yes
  two founders                    0      0    144    0.1056    0.0000    0.0422  yes

  one lineage copied 2000 times off stream 16, with stream 19 growing its wiring
  the two genomes                 E      D      N      Wbar      Bbar         d  may breed
  a parent and its child          0      0    144    0.0452    0.0000    0.0181  yes
  a founder and birth 100         1      0    145    1.6094    0.6113    1.2620  yes
  a founder and birth 500        29     11    162    1.9918    1.1862    2.2299  yes
  a founder and birth 2000      124     21    247    2.0932    1.1587    2.5830  yes

  and the other founder's line, the same length, grown on other ticks
  the two genomes                 E      D      N      Wbar      Bbar         d  may breed
  the two at birth 1              0      0    144    0.1903    0.0075    0.0836  yes
  the two at birth 500           38     51    171    2.5674    1.4448    2.9923  yes
  the two at birth 2000         140    169    260    2.8481    0.9774    3.3051  no

  the last of those, added up in the open
    excess          140 links / 260  x 1.0 = 0.5385
    disjoint        169 links / 260  x 1.0 = 0.6500
    weights          99 matched, mean gap 2.8481 x 0.4 = 1.1392
    bodies           10 factors, mean gap 0.9774 x 1.0 = 0.9774
    d                                            3.3051

Read the first block for what the distance says about creatures that are obviously the same animal. Two founders of one valley share every link they hold, because the numbers for all one hundred and forty-four of them were minted at one founding against the same pairs of nodes, and their bodies are identical because a founder's ten factors are all 1.00 and are not drawn. All that separates them is the weights off stream 14, and the distance between them is 0.0422. A parent and its child are 0.0181 apart, which is one mutation pass and one structural draw.

The second block is one line walking. At a hundred births it has grown one link the founder does not have and its weights have moved a long way, and it reads 1.2620. At two thousand births it holds a hundred and twenty-four links its founder never had, out of two hundred and forty-seven, and reads 2.5830. It is still inside the threshold, and that is not a mistake in the arithmetic. A line and its own ancestor are related by a chain of copies with no other line in between, and the distance says so.

The third block is the one the threshold was written for. Two founders of one valley, each with its own line of two thousand births grown on ticks the other never worked, are 3.3051 apart and may not breed. The four terms underneath are the whole of that number and add up on paper: 140 excess links over a divisor of 260 is 0.5385, 169 disjoint over the same 260 is 0.6500, ninety-nine matched links with a mean weight gap of 2.8481 multiplied by 0.4 is 1.1392, and ten body factors a mean of 0.9774 apart contribute 0.9774. No single term crosses the threshold. It takes all four.

∑ Math Interlude — four differences, three of them divided by something

Numbers first, on two wirings small enough to draw. Wiring A holds four links numbered 1, 2, 3 and 4. Wiring B holds four links numbered 1, 2, 5 and 6. Numbers 1 and 2 are in both, so two links are matched. A's 3 and 4 are not in B, and the highest number B holds is 6, so both are inside B's range: two disjoint. B's 5 and 6 are not in A, and the highest number A holds is 4, so both are past it: two excess.

Now divide. The larger of the two wirings holds four links, so dividing by four gives 2 ÷ 4 = 0.5 of excess and 0.5 of disjoint, and a pair that shares half of its wiring with the other reads 1.00. That is the number the clause exists to refuse. Under twenty links the divisor is one instead, the counts stand as they are, and the same pair reads 4.00: four genes of difference in a controller with eight genes between the two of them. Nothing in this book ever reaches that clause. A founding wiring here is a hundred and forty-four links and the two operators only ever add, so the smallest graph any of these runs holds is seven times the count. It is written down because the distance is written down once and used wherever a graph is, and a reader building a four-node controller on a bench will meet it.

The full distance takes those two divided counts, adds the mean weight gap over the matched links at four tenths of its size, and adds the mean gap over the ten body factors at full size. Write E and D for the excess and disjoint counts, N for the divisor, for the mean weight gap and for the mean body gap. Then

d = c1 × E/N + c2 × D/N + c3 × W̄ + c4 × B̄

with c1 = 1.0, c2 = 1.0, c3 = 0.4, c4 = 1.0. Two creatures breed when d is at most 3.00.

The two means are worth one more sentence each, because a mean is a choice. The weight gap is averaged over the matched links only, so a pair that shares three links out of two hundred is judged on those three; the structural terms are what carry the other hundred and ninety-seven. The body gap is averaged over all ten factors always, because every creature in this world has all ten. Nine of them run from 0.25 to 4.00 and Sight from 0.50 to 2.00, so the widest a single body gap can be is 3.75, and two creatures spread that far across most of the ten would be past the threshold on the body block alone.

dthe compatibility distance: one number for a pair of genomes
Eexcess links: ones past the highest number the other genome holds
Ddisjoint links: unmatched ones inside that range
Nthe divisor: the larger link count, or 1 while both are under 20
the mean gap between the weights of matched links
the mean gap over the ten body factors
c1 c2 c3 c4what each of the four is multiplied by before they are added
̄a bar over a letter: the mean of the thing under it

Species representatives

The mate rule the birth chapter built has two conditions in it. A creature looks inside a box six cells across, takes everybody in it that is over the breeding threshold, and one number off stream 18 picks among them; nothing in it has ever looked at what a neighbour is. Here is a third condition, and it is the only line anywhere in this pass that reads a genome.

▣ Build · stage 3 — the condition the birth chapter left open
// internal/gene/birth.go — inside Pool.suitor
		if !Ready(o) {
			continue
		}
		// The third condition, and the only one that reads a genome.
		// Two creatures whose wirings and bodies have drifted past the
		// threshold would make a child that inherits half of each and
		// works like neither, so past that distance they are not
		// candidates for one another. The comparison costs no number:
		// it is arithmetic over two genomes, and nothing about it can
		// move a stream.
		if p.Kinds.On {
			over++
			if !p.Kinds.inside(mine, p.genes[o.ID], mineAt, p.rank(o.ID)) {
				continue
			}
		}
		p.near = append(p.near, o)
		p.order = append(p.order, j)

One number comes off stream 18 whether the list has fifty candidates in it or none, which is the rule every draw in this volume is under and the reason this condition can be added to a finished pass at all. What it changes is which creatures are in the list the draw indexes into. What it cannot change is how many numbers the pass spends, so a valley that sorts its creatures and a valley that does not read the same streams in the same places.

Refusing a mate is half the job. The other half is the list of species itself, and it turns on one question that has a wrong answer everybody reaches for first: what is a species, in a program? It is not the set of its members, because the set changes every time something is born or dies and there would be nothing to compare a newcomer against. It is one creature, and everything within 3.00 of that creature's genome.

▣ Build · stage 4 — a species, and the creature that holds it
// internal/gene/kinds.go

// Folk is one species: the number it was given, the creature holding it,
// the ticks it opened and closed on, and where it came from.
//
// A species is held by a representative and is nothing more than that
// creature's genome plus the threshold. The first member holds it for as
// long as it lives; when that animal dies the earliest-born member still
// inside the threshold of it takes it over. Holding a species by its
// oldest member and not its newest is the whole of what stops a species
// walking: a list whose yardstick is replaced every time somebody joins
// can carry two animals at either end of it that are nothing like each
// other.
type Folk struct {
	No     int          // its number, and no species ever carries it twice
	Rep    sim.EntityID // the creature holding it now
	First  sim.EntityID // the creature that opened it
	From   int          // the species that creature was born into, 0 for a founding one
	Opened int          // the tick it opened on
	Closed int          // the tick its last member died on, 0 while it stands
	Born   int          // creatures ever sorted into it
	Live   int          // creatures standing in it right now
	Most   int          // the most that ever stood in it at once
	Turns  int          // times it changed hands
	Gap    float64      // how far the creature that opened it was from the nearest species then
}
// sort puts one creature into a species: the first open one whose
// representative it is inside the threshold of, walked in the order the
// numbers were handed out, and a new species of its own when there is no
// such one.
//
// Walking the list in number order rather than trying the parent's
// species first is what makes the answer a fact about the list and not
// about who asked. Two creatures with identical genomes sorted on the
// same tick land in the same species whatever their parents were doing.
func (p *Pool) sort(id sim.EntityID, tick int) int {
	g, ok := p.genes[id]
	if !ok {
		return 0
	}
	mine := p.rank(id)
	nearest := -1.0
	for _, f := range p.Folk {
		if !f.Open() {
			continue
		}
		rep, held := p.genes[f.Rep]
		if !held {
			continue
		}
		d := p.Kinds.terms(g, rep, mine, p.rank(f.Rep)).D
		if nearest < 0 || d < nearest {
			nearest = d
		}
		if d > p.Kinds.Far {
			continue
		}
		f.Born++
		p.kind[id] = f.No
		if p.Kinds.Drifting {
			f.Rep = id
			f.Turns++
		}
		return f.No
	}
	f := &Folk{No: len(p.Folk) + 1, Rep: id, First: id, Opened: tick, Born: 1, Gap: nearest}
	if k, ok := p.kin[id]; ok && k.Parent != 0 {
		f.From = p.kind[k.Parent]
	}
	p.Folk = append(p.Folk, f)
	p.kind[id] = f.No
	p.Opened++
	return f.No
}

Species numbers come off a counter that only goes up and are never handed out twice, for the same reason a link's number is not: a number is a name. A species whose last member dies is closed and keeps its number for ever, and the run that reads the list afterwards can tell the difference between a species that stood for a century and one that opened and shut inside a season.

The creature holding a species will die, and the list has to survive that. Once a phase, before anything is asked for a child, every open species is counted; one whose representative is no longer standing is handed to the earliest-born member still inside the threshold of the genome that was holding it; and one with nothing living in it at all is closed. The awkward case is a representative that dies with no survivor inside the threshold of it, and it is not swept anywhere: the species closes and its survivors are sorted again from the top of the list as though they had just been born.

$ go test -count=1 ./internal/gene/ -run 'AGenomeIsNoDistance|ExcessIsCounted|TheDivisorIsOne|ASpeciesOutlives|SortingSpendsNo' -v
=== RUN   TestAGenomeIsNoDistanceFromItself
--- PASS: TestAGenomeIsNoDistanceFromItself (0.00s)
=== RUN   TestExcessIsCountedPastTheOtherGenomesLastNumber
--- PASS: TestExcessIsCountedPastTheOtherGenomesLastNumber (0.00s)
=== RUN   TestTheDivisorIsOneWhileBothWiringsAreSmall
--- PASS: TestTheDivisorIsOneWhileBothWiringsAreSmall (0.00s)
=== RUN   TestASpeciesOutlivesTheCreatureThatHeldIt
--- PASS: TestASpeciesOutlivesTheCreatureThatHeldIt (0.00s)
=== RUN   TestSortingSpendsNoNumbers
--- PASS: TestSortingSpendsNoNumbers (0.02s)
PASS
ok  	theworld/internal/gene	0.019s

The first four are arithmetic: a genome is nothing at all from a copy of itself, excess and disjoint are counted from the right end of the other genome's numbering, the divisor clause fires under twenty links and not over it, and a species outlives the creature that opened it. The last one is the promise the rest of the volume rests on. It runs one plate of twelve creatures every one of which is a copy of the same genome, once with the sorting on and once with it off, and demands that the two runs spend the same count of numbers and produce the same genomes gene for gene. A population nobody in it is outside the threshold of cannot have its mate choice moved by a threshold, so anything that differed between those two runs would be sorting leaking into a stream.

Before the valley, the smaller question: how far does one line actually walk? The bench grows a single lineage off one founder, six thousand births of copy, mutate and grow, and measures each stop against the genome it started as.

$ go run ./cmd/kinds -mode drift -births 6000
kinds: one lineage walking away from the genome it started as

  d = 1.0 x E/N + 1.0 x D/N + 0.4 x Wbar + 1.0 x Bbar, and the threshold is 3.00
  6000 births, one link in twenty and one node in fifty, off streams 16 and 19

    birth   links  hidden      E      D      N      Wbar      Bbar         d  may breed
        0     144       0      0      0    144    0.0000    0.0000    0.0000  yes
      600     172      14     41     13    172    1.9514    1.2697    2.3642  yes
     1200     212      27     88     20    212    1.8694    1.5404    2.7975  yes
     1800     239      32    116     21    239    2.1315    0.9794    2.4052  yes
     2400     266      32    143     21    266    2.0820    0.6691    2.1184  yes
     3000     300      32    177     21    300    2.0952    0.9642    2.4623  yes
     3600     321      32    198     21    321    2.0424    1.0667    2.5659  yes
     4200     342      32    219     21    342    1.9029    0.9807    2.4436  yes
     4800     367      32    244     21    367    2.0325    0.8573    2.3923  yes
     5400     387      32    264     21    387    1.8387    1.1683    2.6402  yes
     6000     409      32    286     21    409    2.0107    1.1184    2.6733  yes

  the first birth of this line outside the threshold from the founder
    birth 2196, at 3.0001: E 134, D 21, N 257, Wbar 2.2000, Bbar 1.5170

The distance is not a ratchet, and that is the finding in this run. It climbs to 2.7975 by birth 1,200, falls back to 2.1184 by birth 2,400, and is still wandering between 2.39 and 2.67 four thousand births after that. The reason is in the columns. D stops at 21 once the graph reaches its ceiling of thirty-two hidden nodes and never moves again; E climbs from 116 to 286 over the same stretch, but N climbs with it, so the two structural terms together climb from 0.57 to 0.75 over the six thousand births and are still climbing slowly at the last row of them. The weight term hovers near 2.0 times 0.4, because the mutation pass is as likely to move a weight back as onwards. What is left moving is the body block, ten numbers taking a random walk between their clamps, and it is the body block that decides whether any particular birth is inside the threshold or outside it.

So a line does cross. Birth 2,196 of this one is 3.0001 from the founder, over the line by one ten thousandth, and it is the first of six thousand births that gets there. Something has to happen to it.

▣ Build · stage 5 — one line, sorted as it is born

The same lineage again, with every birth sorted into a species the moment it exists. Nothing here is a valley: the creatures are put on a roster and never die, so no species ever changes hands and no species ever closes, which leaves the threshold as the only thing in the run that can do anything.

$ go run ./cmd/kinds -mode chain -births 4000
kinds: one lineage of 4000 births sorted into species, held by the member that opened it

  d = 1.0 x E/N + 1.0 x D/N + 0.4 x Wbar + 1.0 x Bbar, and the threshold is 3.00
  every birth is the one before it copied, mutated and grown, and is sorted
  the moment it exists against the species standing at the time

    kind   opened  held by  members        gap     widest    pairs out
       1        0        0     3956          -     3.9005       824997
       2     2196     2196       41     3.0001     2.9810            0
       3     3675     3675        4     3.0050     0.0840            0

  3 species out of one line of 4000 births
  opened is the birth the species opened at, gap how far that birth was
  from the nearest species standing then, and pairs out how many pairs of
  one species are further apart than the 3.00 the threshold allows

One line of four thousand births is three species. Species 2 opened at birth 2,196, at a distance of 3.0001 from the only species then standing, and took forty-one members with it before the line wandered back inside species 1 and started being sorted there again. Species 3 opened at birth 3,675 at 3.0050 and held four. Those two numbers being barely over the threshold is what a line crossing a line looks like: nothing jumps, the body block wanders over the edge, and the register writes down the birth it happened at.

The last column is the part to be honest about. Species 1 holds 3,956 members and 824,997 pairs of them are further apart than 3.00. A species here is everything within 3.00 of one genome, and two things each within 3.00 of a third can be up to 6.00 from one another, so pairs that far apart are exactly what the rule allows. Being in one species means being able to breed with the creature holding it, and nothing more: the mate rule asks the distance between the two animals actually standing next to each other, not the distance between their species.

⚠ Worked failure — a yardstick that walks with the thing it is measuring

The first version of the register handed the species to whoever joined it last. It reads as the tidier design and it has an argument behind it: the newest member is the most up-to-date description of what the species has become, and comparing a newborn against a genome that has been dead for eighty years feels like measuring against a museum piece. The flag below keeps that version runnable.

// internal/gene/kinds.go — inside type Sorting struct
	// Drifting is the representative rule as it is tempting to write
	// it: a species held by whichever member joined it last instead of
	// by the one that opened it. It is kept behind a flag so what a
	// moving representative does to a species can be run instead of
	// described, and it is false in every valley this book ships.
	Drifting bool
$ go run ./cmd/kinds -mode chain -births 4000 -drifting
kinds: one lineage of 4000 births sorted into species, held by whoever joined it last

  d = 1.0 x E/N + 1.0 x D/N + 0.4 x Wbar + 1.0 x Bbar, and the threshold is 3.00
  every birth is the one before it copied, mutated and grown, and is sorted
  the moment it exists against the species standing at the time

    kind   opened  held by  members        gap     widest    pairs out
       1        0     4000     4001          -     3.9005       847423

  1 species out of one line of 4000 births
  opened is the birth the species opened at, gap how far that birth was
  from the nearest species standing then, and pairs out how many pairs of
  one species are further apart than the 3.00 the threshold allows

One species, four thousand and one members, and it never splits. The reasoning from symptom to cause takes one sentence: every birth is a hundredth or two from the birth before it, which the pair run at the top of this page measures at 0.0181, the species is held by the birth before it, so every birth is inside the threshold of the thing it is being measured against, for ever. The yardstick walks with the line it is supposed to be measuring, and a ruler carried along beside a moving object measures nothing.

The 3.9005 in the widest column is the same 3.9005 the correct rule reports for its own species 1, and catching it matters more than reading past it: under both rules there are members of one species that could not breed with each other. What the correct rule buys is not that a species is a set of animals all of which can interbreed. It is that the species boundary is anchored to a genome that stopped moving, so a line that walks away from it is recorded as having walked away, at a birth that can be named.

A species as everything within one distance of one genome, and what happens when the holder moves Two panels stacked. The upper panel shows the rule this book ships: a circle marked as everything within 3.00 of the genome of the creature that opened species 1, with that creature fixed at its centre, and a line of births walking to the right out of the circle. The birth that lands outside it, marked birth 2196 opening at 3.0001, is the centre of a second circle of its own, species 2. A panel on the right counts the run: three species out of four thousand births, splitting at 2196 and at 3675. The lower panel shows the same line of births under a representative that moves: a circle is redrawn round every new birth as it arrives, each birth sits 0.0181 from the one before it and therefore always inside, and the line walks the whole way across the panel inside one species whose first and last members are 3.9005 apart. HELD BY THE MEMBER THAT OPENED IT SPECIES 1 birth 0 WITHIN 3.00 OF IT one birth, then the next SPECIES 2 birth 2196 it opened at 3.0001 3 species 4000 births split at 2196 and at 3675 HELD BY WHOEVER JOINED IT LAST 1 species 4001 members ends 3.9005 from birth 0 THE CIRCLE IS REDRAWN ROUND EVERY ARRIVAL, SO NOTHING EVER LANDS OUTSIDE
Figure 66.1 — a species is a genome and a radius. Anchor the genome to the member that opened the species and a line walking away from it eventually lands outside and opens one of its own; move the anchor to whoever arrived last and the radius travels with the line, so nothing ever lands outside anything.

The 200-year species run

Now the valley, on the ground the senses chapter built and ran: sixteen by twelve cells, the rim cracked into pockets and walled so nothing leaves, the room rule on, twenty-five animals founded on stream 12 with a hundred and forty-four links apiece, the eight ground channels switched on and billed for. Every child sorted the moment it is born, every mate filtered by the threshold, and two hundred years of it.

$ go run ./cmd/kinds -mode herd -years 200 -every 20
kinds: 16x12 valley, tick 901, year 1 summer, 90 plants standing at 4654.1 grams

  25 creatures founded on stream 12, all of them species 1
  d = 1.0 x E/N + 1.0 x D/N + 0.4 x Wbar + 1.0 x Bbar, and the threshold is 3.00
  a cell of ground carries one body: yes.  the ground speaks: yes
  births with two parents when there is one to be had: 0.75 of them
  a species is held by its earliest-born member: yes

   year   alive     born   kinds   opened    shut     apart    widest
      2       9       14       1        1       0    0.1019    0.1657
      3       8       32       1        1       0    0.1806    0.3276
      4      19       53       1        1       0    0.1585    0.3764
      5      15       74       1        1       0    0.1917    0.5958
     21     333     1091       1        1       0    0.4083    0.8814
     41     333     1696       1        1       0    0.4352    0.8814
     61     336     1718       1        1       0    0.4365    0.8814
     81     335     1718       1        1       0    0.4368    0.8814
    101     336     1720       1        1       0    0.4370    0.8814
    121     337     1722       1        1       0    0.4375    0.8814
    141     336     1724       1        1       0    0.4380    0.8814
    161     336     1724       1        1       0    0.4380    0.8814
    181     336     1724       1        1       0    0.4380    0.8814
    201     336     1725       1        1       0    0.4382    0.8814

  25 founded, 1725 born, 1414 struck off, 336 still walking after 719550 ticks
  154473 creatures were asked for a child: 1725 made one, 17317 could not pay for it
  1540 births found a mate in reach and 185 found nobody at all

  every species this valley opened, and the tick it opened on
     no      tick    year   out of    first    born   most  turns       gap
      1       901       1        -        1    1750    377     13         -

  the 1 species still standing at the end, and 0 closed
     no   living  held by    opened      Bulk     links
      1      336      105       901    0.3685     145.0

  what the threshold was asked, and what it did
    creatures asked for a child                            154473
    of those, ones with a neighbour over the price         151479
    and of those, ones left with somebody to breed with    151479
    asks the threshold refused every neighbour of               0
    births that ended up with one parent                      185
    species opened, closed, and left standing                   1 0 1
    species that changed hands, and lost their holder          13 0

  the two genomes this valley ever held furthest apart, alive or dead
    genomes it made in all                                  1750
    the widest distance between any two of them            1.4647
    which two they were                                       126 1642
    the threshold two creatures have to cross to part         3.00
    generations the deepest creature stood from a founder       50

  the ground: 172 cells a root can live in, 48 of them pockets cracked into the rim
   kind in a crack    on soil
      1         92        244

  ground                cells        grams       a cell
  pockets in the rim       48          0.0          0.0
  open soil               124       2213.9         17.9

  living neighbours within 6 cells, counted once at the end, and how many
  of them are inside the compatibility threshold
  standing           creatures    mean near  mean inside
  in a crack               92       130.43       130.43
  on open soil            244       186.66       186.66

  719550 ticks in 7m12.095s, 1665 ticks a second (measured here; yours will differ)

The kinds column reads 1 on the second year and 1 on the two hundred and first, and on every row in between. One species, opened on tick 901 when the first founder was stood up, holding all 1,750 genomes this valley ever made, still standing at the close and never once split. The creature holding it changed thirteen times as one holder after another died and the species was handed to the earliest-born survivor, which is the one part of the register that got any exercise at all. Seven and a quarter minutes of an eight-core Ryzen 7 3700X went into that one row; the 719,550 ticks are the world and the minutes are the desk, which is what the label at the foot of the run is warning about.

The threshold block says the rest. A hundred and fifty-four thousand creatures were asked for a child; a hundred and fifty-one thousand of them had somebody in reach who was over the price of one; and the number of those the threshold refused every neighbour of is nought. Not a small number. Not one in ten thousand. In two centuries of a valley this rule never once said no to anybody. Everything the last four pages built ran on every one of those asks and changed nothing whatever: the mate every creature took, the child it made and the tick it died on are what they were in the valley that had no threshold in it.

That is the chapter's result and it deserves a straight explanation rather than a shrug. The two blocks underneath contain it. Over two centuries this valley made 1,750 genomes, and the widest distance between any two of them, living or dead, is 1.4647 of the 3.00 the threshold asks for. The deepest creature it ever produced stood fifty generations from a founder. The bench at the top of this page needed about two thousand two hundred births of one unbroken line before that line reached 3.00 from its own ancestor. Fifty against two thousand two hundred. This valley is not close to speciating; it is a fortieth of the way there.

Read the born column to see why fifty generations is all it managed. By the sixty-first year 1,718 animals had been born. By the two hundred and first, 1,725. Seven births in a hundred and forty years. The room rule fills a hundred and ninety-two cells of ground and then a birth has to wait for a cell to come free, and a cell comes free when somebody dies, and in a valley where three hundred and thirty-six well-fed animals are standing on a fixed larder almost nobody does. Two centuries of this ground is about forty years of history followed by a hundred and sixty years of the same three hundred and thirty-six creatures standing still: 1,696 of the run's 1,725 births are in by the forty-first year and twenty-nine arrive in the hundred and sixty after it. Generations are what drive two genomes apart, and after year forty this valley has almost stopped having any.

The widest column says the same thing from the other side, and says it more sharply than anything else in the run: 0.8814 in the twenty-first year, and 0.8814 in the two hundred and first. The two most distant animals alive in this valley have been exactly as distant as each other for a hundred and eighty years. Nothing is drifting. There is one gene pool, everybody in it can breed with everybody else, three births in four are crossings whenever there is anybody to cross with, and crossing is a mixer: it pulls the population back together at least as fast as mutation pushes it apart. That last clause is measurable, and the bench measures it on the one pair on this page that is outside the threshold.

$ go run ./cmd/kinds -mode pair | tail -9
  a child of that pair, every gene the crossing could award awarded
  the two genomes                 E      D      N      Wbar      Bbar         d  may breed
  the two parents               140    169    260    2.8481    0.9774    3.3051  no
  the child and the first         0      0    247    0.5093    0.4178    0.6215  yes
  the child and the second      140    169    260    1.5774    0.5597    2.3791  yes
  with the unmatched links from the parent of record
  the child and the first       140    169    260    1.2707    0.4178    2.1145  yes
  the child and the second        0      0    260    0.6006    0.5597    0.7999  yes
  with the unmatched links from the other parent

Two parents 3.3051 apart, too far to have this child at all under the rule this chapter built, and every child of them is comfortably inside the threshold of both. Taking the unmatched links from the parent of record puts the child 0.6215 from that parent and 2.3791 from the other; taking them from the other side puts it 2.1145 and 0.7999. The two structural terms collapse to nothing on whichever side gave the wiring, because the child holds exactly that parent's links, and the weight term roughly halves on both sides because each matched weight came off a coin. One crossing pulls a pair most of the way back together. A valley in which 1,540 of 1,725 births had a second parent in reach, with every animal in reach of every other, is a valley that cannot come apart.

Rim pockets and breeding cost

There is no shared score in this valley to protect a young lineage with. A new arrangement of wiring is judged against the whole population from the tick it appears, by the only judge there is, which is whether the animal carrying it can put the price of a child in its store. The thing that is supposed to give a new lineage room to be tested is the ground itself: the terrarium volume cracked the rocky rim into pockets a narrow root can hold in, and an animal in one of those is competing with what is in the pocket rather than with the whole valley. The last three blocks of the run are that claim, measured.

What it buys is real and it is small. A creature standing in a pocket has 130.43 other animals within six cells of it; a creature on open soil has 186.66, and on both counts every one of those neighbours is inside the compatibility threshold. Sheltering in the rim means meeting a third fewer of the valley than standing in the middle of it. Ninety-two of the three hundred and thirty-six survivors are doing exactly that.

What it charges is on the line above. The forty-eight pockets carry 0.0 grams of standing tissue between them at the close of the run, against 2,213.9 grams on the hundred and twenty-four cells of open soil. A pocket is a crack in rock holding a quarter of a cell of soil, so it grows a quarter of the food when it grows any, and after two centuries of animals standing on it, it grows none. The shelter and the hunger are the same fact: what thins the crowd is that there is nothing there to bring a crowd.

Two more charges belong on the page, and neither is measured because neither is measurable in a valley holding one species. A refuge has no opinion about what it is sheltering, so it keeps a lineage that is going nowhere alive exactly as well as it keeps a promising one; a shared score at least knows what it is protecting and from what. And a refuge cannot be set: it is a fact about the terrain the world generator handed out, so a run on a map whose rim came out smooth has no refuges at all and no dial anywhere to give it any. What this page can say for the pockets is that they thin the crowd by a third and starve whoever uses them. What it cannot say is that they protected anything, because in two centuries nothing here needed protecting.

One honest sentence about the seed, and then the general point. This is one run, on one ground, from one founding, and a different map with a longer rim or a wider gap between its feeding grounds would give a different answer. But the direction of the answer is not about this seed. Six cells is the distance a creature looks for a mate, and this valley is sixteen cells across; a box thirteen cells on a side laid anywhere on that ground covers most of it. Every animal here can reach every other animal, and a population where everybody can reach everybody is one population by definition, however long you run it.

Why species protect crossings

Strip the valley out and there are three separate things on this page, and only two of them did any work.

A distance turns a comparison into a number, and the units have to be beaten flat first. Four kinds of difference went in: two counts of genes, a mean gap between weights and a mean gap between body factors. Counts of genes were divided by how many genes there were, so that ten differences in five hundred is not the same reading as ten in twelve. Weight gaps were multiplied down, because a dial that has moved is a smaller change than a wire that is missing. What comes out is one number, and everything after it is a comparison against a threshold. That pattern is older than this book and it turns up anywhere two structured things have to be told apart: normalise each kind of difference in its own currency, weight the currencies against each other on purpose and in the open, then add.

A boundary has to be anchored to something that stopped moving. The register holds a species as one genome and a radius. That genome belongs to a creature that may be dead, and when the species changes hands it goes to the earliest-born survivor and not the newest arrival, and the failure above is what the other choice costs. A rule that re-reads its reference point from the thing it is measuring measures nothing, and it will not tell you: it returns confident answers for ever, and a line of four thousand copies comes back as one happy family.

A threshold is a ruler and not a mechanism. This is what the two centuries taught, and it is the part to carry away. Building a compatibility distance and setting it at 3.00 does not make species any more than owning a tape measure makes a building. Two populations become two species when they stop breeding with each other, and they stop breeding with each other because something keeps them apart long enough for drift to do its work: a mountain, a river, a difference in season, a mate box smaller than the ground. The threshold is what notices afterwards. Put it in a valley where every animal can walk to every other animal in a few days and it will notice, correctly and for ever, that there is one kind of animal here.

What this valley is missing is distance, not a rule. A run that wants two kinds of animal in it needs ground wide enough that a six-cell mate box is a small part of it, or a population that turns over often enough for fifty generations to become two thousand, and the honest state of this book is that a ground that wide costs more ticks than a two hundred year run can afford at the pace this one runs at. The machinery is built, it is exact, the arithmetic is pinned by five tests, and it is waiting for a world big enough to need it.

✓ Checkpoint — a distance, a radius, and a valley that did not split
  • Handed two link lists with the numbers on them, You can say which links are matched, which are disjoint and which are excess, and explain what the highest number the other genome holds has to do with the difference between the last two.
  • You can add up the four terms of the distance from a printed table and get the same number the run printed, and say which term is divided by what.
  • You can say what the divisor clause under twenty links is for, work an example of it, and say why no run in this book ever reaches it.
  • You can explain why the species register holds one genome instead of a set of members, and why two creatures in one species may still be too far apart to breed.
  • Given the run's 1.4647 and its fifty generations, You can say why two centuries of this valley produced one species, and name the two things that would have to change.
  • You can state what a pocket in the rim buys an animal standing in it, what it charges, and why neither number is evidence that the pockets protected any lineage.
⚡ Exercises — try first, then reveal
Exercise 1 — set the threshold a quarter of the way down. The widest two genomes the two-century run ever held are 1.4647 apart. Predict what the species list looks like at a threshold of 0.75, which is a quarter of what this book ships, then run go run ./cmd/kinds -mode herd -years 40 -every 10 -far 0.75.

Two species over forty years, and the second was closed before the next row of the table. Species 2 opens on tick 78,757 out of species 1, 0.9237 from the only representative standing at the time; it takes two members and then closes. The valley finishes with 329 animals walking, every one of them in species 1, and the threshold still refuses every neighbour of nobody at all.

Dividing the threshold by four bought one two-member species that died. A threshold reports a distance the animals already have, and being kept apart from each other is the only thing that makes that distance grow; turning the ruler down keeps nobody apart from anybody. A threshold tuned until the answer comes out interesting is a fitness function wearing a different hat.

Exercise 2 — take the mixer out. Most births in the run have a second parent in reach, and crossing pulls a population together. Predict what two centuries of copies alone does to the widest column, then run go run ./cmd/kinds -mode herd -years 60 -every 10 -sex 0.

The widest column climbs faster and further: 1.0336 by the eleventh year and 0.9480 by the twenty-first, against the 0.8814 the crossed run reads on its year twenty-one row. Then the valley dies. Nothing is walking by the forty-first year, 1,825 born against 1,850 struck off, and the one species it ever had is closed. Copies alone got the population further apart and then killed it, and the deepest line it managed was thirty-nine generations against fifty.

Both halves of that are the point. Crossing is what holds a species together, and it is also what keeps this population alive long enough to be a species at all. A world that wants two kinds of animal in it has to separate them in space, because separating them by taking the second parent away separates them from their food as well.

Exercise 3 — take the body block out of the distance. The distance adds four terms and the body block is the one that wanders. Predict what happens to the species list when the body factors stop counting, then edit Sorted in internal/gene/kinds.go to Body: 0.0 and run go run ./cmd/kinds -mode drift -births 6000 and go run ./cmd/kinds -mode chain -births 4000.

The drift table stops wandering: with the body term gone the distance from the founder climbs and then flattens against the graph's ceiling, and the furthest the line gets in six thousand births is 1.5549 of the 3.00 the threshold allows. The chain run then reports one species out of four thousand births, because the two splits the shipped rule found were both the body block crossing the line.

So the three structural and weight terms on their own cannot part two lines in this world, and the one term everybody would call the least principled is carrying the whole of the splitting. Take that as an argument for knowing which term your threshold is really reading, which you find out by taking each of them away in turn, and not as an argument for weighting bodies higher.

Every genome in that two-century run is still sitting in the pool at the end of it, 1,750 of them, and every one of the 1,414 animals struck off left its genome behind. That is a run's whole history held in one process on one machine, readable only for as long as the program is alive and gone the moment it stops. The next thing this valley needs is a place to put it that survives the run.