Introduction

It seems that the Intelligent Design Creationists still can't let go of, or even understand, Richard Dawkins' Weasel program from The Blind Watchmaker. There are two articles at The Panda's Thumb with references to the brouhaha. What seems to have the IDCists' tails in a knot currently is whether or not Dr. Dawkins' original program "latches" correct letters. That is, when a correct letter is found, is it protected from mutation in subsequent generations?

I became aware of this when I noticed a link to my Weasel implementation from Uncommon Descent, a site not known for its interest in Dawkins or any other material critical of Intelligent Design Creationism. After reading through the thread, I thought the easiest way to resolve the dispute was to ask on Richard Dawkins' website. A helpful participant with the handle mp1 linked to a video of Richard Dawkins running the Weasel program. This video clearly shows, approximately 15 minutes in, that correct letters are not protected from mutation in subsequent generations.

I sent the link to David Kellogg, one of the few non-IDCists in the discussion and assumed that would end the debate. Not so. Rather than admit error, the IDCists pointed out that, while The Blind Watchmaker was published in 1986, the video was produced in 1987. Obviously Dr. Dawkins had changed the Weasel program to remove the latching behavior for the video.

Let's see how well that claim corresponds to reality.

The Weasel Description

First, let's look at exactly how Dr. Dawkins described the Weasel program on pages 47 and 48 of The Blind Watchmaker.

So much for single-step selection of random variation. What about cumulative selection; how much more effective should this be? Very very much more effective, perhaps more so than we at first realize, although it is almost obvious when we reflect further. We again use our computer monkey, but with a crucial difference in its program. It again begins by choosing a random sequence of 28 letters, just as before:

WDLMNLT DTJBKWIRZREZLMQCO P

It now 'breeds from' this random phrase. It duplicates it repeatedly, but with a certain chance of random error - 'mutation' - in the copying. The computer examines the mutant nonsense phrases, the 'progeny' of the original phrase, and chooses the one which, however slightly, most resembles the target phrase, METHINKS IT IS LIKE A WEASEL. In this instance the winning phrase of the next 'generation' happened to be:

WDLTMNLT DTJBSWIRZREZLMQCO P

Not an obvious improvement! But the procedure is repeated, again mutant 'progeny' are 'bred from' the phrase, and a new 'winner' is chosen. This goes on, generation after generation. After 10 generations, the phrase chosen for 'breeding' was:

MDLDMNLS ITpSWHRZREZ MECS P

After 20 generations it was:

MELDINLS IT ISWPRKE Z WECSEL

By now, the eye of faith fancies that it can see a resemblance to the target phrase. By 30 generations there can be no doubt:

METHINGS IT ISWLIKE B WECSEL

Generation 40 takes us to within one letter of the target:

METHINKS IT IS LIKE I WEASEL

And the target was finally reached in generation 43. A second run of the computer began with the phrase:

Y YVMQKZPFfXWVHGLAWFVCHQXYOPY,

passed through (again reporting only every tenth generation):

Y YVMQKSPFTXWSHLIKEFV HQYSPY
YETHINKSPITXISHLIKEFA WQYSEY
METHINKS IT ISSLIKE A WEFSEY
METHINKS IT ISBLIKE A WEASES
METHINKS IT ISJLIKE A WEASEO
METHINKS IT IS LIKE A WEASEP

and reached the target phrase in generation 64. m a third run the computer started with:

GEWRGZRPBCTPGQMCKHFDBGW ZCCF

and reached METHINKS IT IS LIKE A WEASEL in 41 generations of selective 'breeding'.

The Uncommon Descent assertion of explicit latching is based solely on the six lines of output from the second reported run of the program. Because no letter regression appeared between the best members of generations 10, 20, 30, 40, 50, and 60, the IDCists find the most credible explanation to be that Dr. Dawkins used one program in his book and rewrote it for the video.

I'll come back to the issue of parsimony shortly. First, let's see if there is any justification in Dr. Dawkins' description of the Weasel program for the claim that correct letters are not subject to mutation in subsequent generations.

Implementing the Weasel

I'm going to go through the Weasel description and translate it into code step-by-step. While Common Lisp would be more efficient, I'll use ANSI C so the code will be readily understandable by more programmers.

We again use our computer monkey, but with a crucial difference in its program. It again begins by choosing a random sequence of 28 letters, just as before:
WDLMNLT DTJBKWIRZREZLMQCO P

I need a function to create random phrases of the same length as the target phrase, made up of characters in the set of uppercase letters and the space.

/* * This is an implementation of Richard Dawkins' Weasel program from The * Blind Watchmaker. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define ALPHABET "ABCDEFGHIJKLMNOPQRSTUVWXYZ " #define TARGET_PHRASE "METHINKS IT IS LIKE A WEASEL" /* Return a value between 0.0 and 1.0 */ float random_percentage() { return (float)random() / (RAND_MAX + 1.0); } /* Generate a random letter from the ALPHABET. */ int random_letter() { return ALPHABET[(int)(strlen(ALPHABET) * random_percentage())]; } /* * Create a random phrase of the same length as TARGET_PHRASE from the * characters in ALPHABET. */ char *random_phrase(char *phrase) { int i; for (i = 0;i < strlen(TARGET_PHRASE);i++) phrase[i] = random_letter(); return phrase; }
It now 'breeds from' this random phrase. It duplicates it repeatedly, but with a certain chance of random error - 'mutation' - in the copying.

I need a function to generate new phrases that are mutated versions of the original phrase.

/* Mutate a phrase and return the result. */ char *mutate_phrase(char *phrase,char *mutated_phrase,float mutation_rate) { int i; strcpy(mutated_phrase,phrase); for (i = 0;i < strlen(phrase);i++) if (random_percentage() < mutation_rate) mutated_phrase[i] = random_letter(); return mutated_phrase; } /* * Breed the phrase by creating the number of strings stored in progeny * from it with each letter subject to change at the specified mutation * rate. */ char **breed(char *phrase,char **progeny,float mutation_rate) { int i = 0; while (progeny[i]) { progeny[i] = mutate_phrase(phrase,progeny[i],mutation_rate); ++i; } return progeny; }

Note that nowhere in Dr. Dawkins' description does he suggest that correct letters in the parent phrase should be explicitly preserved. In fact, he uses the term "random error" to describe the copy and mutate process.

The computer examines the mutant nonsense phrases, the 'progeny' of the original phrase, and chooses the one which, however slightly, most resembles the target phrase, METHINKS IT IS LIKE A WEASEL.

Now I need to look through the progeny and determine which string is closest to the target phrase.

/* Return the number of differences between the phrase and TARGET_PHRASE. */ int fitness(char *phrase) { int i; int result = 0; for (i = 0;i < strlen(TARGET_PHRASE);i++) if (phrase[i] == TARGET_PHRASE[i]) ++result; return result; } /* Return the progeny that is closest to TARGET_PHRASE. */ char *best_progeny(char **progeny,char *phrase) { int i = 0; strcpy(phrase,progeny[0]); while (progeny[i]) { if (fitness(progeny[i]) < fitness(phrase)) strcpy(phrase,progeny[i]); ++i; } return phrase; }

Note that Dr. Dawkins again fails to suggest that the progeny should preserve correct letters from the parent phrase. Nothing in his description even indicates that the progeny should be expected to more closely resemble the target phrase than does the parent.

But the procedure is repeated, again mutant 'progeny' are 'bred from' the phrase, and a new 'winner' is chosen. This goes on, generation after generation.

I need to call these functions repeatedly until the target phrase is matched.

int main(int argc,char *argv[]) { char *phrase = 0; char **progeny = 0; int number_of_progeny = 0; float mutation_rate = 0.0; int generation = 0; if (argc == 3) { srandom(time(0)); /* initialize the random number generator */ number_of_progeny = atoi(argv[1]); mutation_rate = atof(argv[2]); phrase = initialize_phrase(); progeny = initialize_progeny(number_of_progeny); phrase = random_phrase(phrase); while (strcmp(phrase,TARGET_PHRASE) != 0) { printf("Generation %d: %s\n",generation++,phrase); phrase = best_progeny(breed(phrase,progeny,mutation_rate),phrase); } printf("\nTarget phrase found in %d generations.\n",generation); } else printf("Usage: %s <number-of-progeny> <mutation-rate>\n",argv[0]); }

Results

Dr. Dawkins doesn't specify the number of progeny nor the mutation rate he used in The Blind Watchmaker. I'll try a population of 100 children and a mutation rate of 5% for a test. The first random phrase generated is:

URD HKFYSUAZQNXQKMVSGKGFNEWU

The best child, sampled every 10 generations, is:

PRTHENFSSGR QQXXIKVSG GUASWR
MQTHINFSLIT YQXGIKEVF WHASER
METHINESJIT YSNGIKE F WHASEL
METHINESJIT YSNLIKE A WEASEL
METHINESJIT CS LIKE A WEASEL
METHINESAIT IS LIKE A WEASEL
METHINES IT IS LIKE A WEASEL

The target phrase is found after 74 generations.

Conclusions

The first conclusion that can be drawn from these results is that the correct letters do appear to be latched in the output, even though there is no explicit latching in the program. The primary reason for this is that only the best phrase from every ten generations is shown. That coarse sampling introduces a bias.

Careful readers will have noted another source of bias. If more than one phrase in the set of progeny has the same fitness, the selection function arbitrarily keeps the first one found. A different selection algorithm might show more reversion.

In short, the perception of latching is an artifact of the implementation and sampling bias. Running the program repeatedly and monitoring all generations will, in fact, show occasional reversions of correct letters. The odds of such a reversion are simply rather low.

This leads to a second conclusion, that the assertions on Uncommon Descent that Dr. Dawkins rewrote the Weasel program to remove latching before filming the video are unsupported by any evidence. The most parsimonious explanation is that the Uncommon Descent IDCists were fooled by sampling bias and refuse to admit their error.

Why Does It Matter?

Implementing the Weasel program is a mildly amusing lunch hour hack, but ultimately why does it matter what some Intelligent Design Creationist blathers about on an anti-science blog?

The real reason this is worth addressing is that the spurious claims about the Weasel program are also being made by William Dembski and Robert Marks in a paper that is supposedly due to be published in a peer reviewed journal. Since IDCists are desperate for any suggestion that their intellectually vacuous maunderings might have scientific legitimacy, an hour engaged in disabusing them of that notion is time well spent.

Incidentally, neither Dembski nor Marks have any excuse for their mischaracterization of Dr. Dawkins' work. Wesley Elsberry informed Dembski of the issue back in 2000. Marks has to have known since the date of that post, October of 2007, at the latest.

Source Code

The code is available in a single file: weasel.c

www.softwarematters.org