It is now 62 hours since William Dembski posted that the Evolutionary Informatics lab was going to try and reproduce Dawkins Weasel Program according to how it was actually written, as opposed to their fantasy version. In that time I've resurrected an elderly program, and several readers have made their own weasels from scratch. Commenter Anders has even made a Python version that puts "freely mutating" and "locking versions" head to head with great graphs. (Update: Wes Elsberry did a head to head comparison last year, see here for his comparison [scroll down], it differs from my implementation but the basic message is the same).
I've gone back and done a head to head comparison myself between a program with no "locking" (all letters in any given string have a chance to be mutated) and one with "locking" (where the matching letters are preserved against mutation). Trying to implement "locking" al la Dembski proved too hard. You have to keep indices of the letter locations and keep updating them. It is such a pain in the bottom to try and do this that I cannot imagine Dawkins even wanting to try and program a "Locking" implementation in GBASIC. Remember, Dawkins weasel was a quick and dirty program bashed out in a short time. To implement "locking" I just kept a copy of the parent string unmutated (after all, in the real world not every offspring has mutations in genes of interest).
So what happened?
As you can see they were much the same (mean and standard error of an average of 4 independent runs per condition shown, click to embiggen). "Locked" runs finished earlier, on average but most of the trajectory of the run was determined by mutation supply. As you can see, runs done with locked and unlocked versions fell within the error bars of each other, for runs that set the Offspring number at either 100 or 30.
This is easy to understand. Early on, virtually any mutation is of big benefit, while later on most mutations are of small benefit. Only in the final stages that there was any significant backing and forthing, and then only in the 30 Offspring case. In the 100 offspring case, the population was so large that the probability was high that even in the final stages a beneficial mutation would be acquired. Wesley Elsberry has done the mathematics explicitly (go to this link and scroll down). Only in the 30 offspring case was the last 10 or so generations in an "unlocked" run spent bouncing from 3-1 differences.
So Dembski's claims that a list of every 10th output string shows that Dawkins is using a "locking" program are nonsense, Dawkins results are exactly what we would expect to see when sampling sparsely from a high population "freely mutating" weasel run.
Slightly more surprisingly, the median time to convergence (when the program finally reached the target string), was not actually statistically significantly different. I suspect when enough runs are accumulated (say around 20), they will be, but the "locked" runs are only about 20% faster.
So, summary. Whether you "lock" your strings, or allow them to mutate at all positions freely, a weasel program will converge on a solution. The for most of the time, mutation supply dominates, and whether you lock your strings or not there is rapid accumulation of beneficial mutations. Only at the very end run does "locking" matter, and then only for small populations where the probability of a beneficial mutation is low.
But even then, "unlocked", freely mutating programs will converge on a solution in less than a minute (and only 20% slower than the "locking" programs), when simple random sampling will take longer than the lifespan of the Universe to converge.
Still, the point is that against all evidence, Dembski believes that Dawkins wrote a overly complicated program in GBASIC, and then reverted to a simple one for a TV show, and can't be bothered to get around to writing the code that would show him wrong (and show that freely mutating programs converge rapidly on the target string). Again, this shows that cdesign proponetists don't understand the "test your hypothesis" part of science. I'm currently reading Galileo's "Starry Messenger", and the debate over at Uncommon Descent reminds me of Francesco Sizzi, who declared that Galileo really couldn't have seen Moons around Jupiter, as metaphysics demands there only be 7 planets.
Now If only they would put the same degree of effort that they put into critiquing the weasel program, a toy demonstration of selection the same importance as the measuring cylinder/running tap model of drug clearance, into doing some real science.
The freely mutating QBASIC program is here, the "locked" version is here (both write strings to a log file).
Feel free to submit your own weasels, especially ones that compare freely mutating vs "locking" versions of the code, and the PT crew could do with a java applet version if you could do one. A weasel for every 6 hours the Uncommon Descent people do nothing would be great!
See Wesley Elsberries superb Java Weasel as an example!
159 Comments
Giljorak · 19 March 2009
Does anyone have the original Apple Basic source code? I found many versions on the web but can't seem to find the original version.
I still have a functioning Apple ][ computer that I would love to put the source code on.
k,e,, · 19 March 2009
Weasels are weasley recognizable but stoats are stoatally different
DS · 19 March 2009
Now we know why Dawkins called it a weasel program. We're all waiting to see Dembski try to weasel out of this again.
Bethor · 19 March 2009
Thanks for the link to the Python version by Anders, I spent some time making pretty much the same thing yesterday out of curiosity (and as a way to teach myself Python :p).
One big caveat, however : if I understand Dawkins' original description correctly "[...] each position [in each offspring] has a chance of randomly mutating, based upon a set mutation rate." (from http://www.antievolution.org/features/ec/weasel102.html).
Anders' version, however, seems to randomly pick a single position in each offspring to be mutated. This seems to be a pretty different algorithm, unless I'm completely misunderstanding either the original idea or his code.
This doesn't really invalidate the conclusions regarding locking / non-locking versions but I thought this was worth pointing out (even though the resulting graphs tracking progression towards maximum fitness look much the same in my version with a possibility of mutation on each position of each offspring).
Rolf Aalberg · 19 March 2009
This may be entirely irrelevant but here’s what I did many years ago:
When playing a computer game, I think it was ‘Shivers’, one of the hurdles was a game consisting of a horizontal row of ‘holes’, with a number of balls that based on certain rules could be flipped back or forth between vacant holes.
After playing for a while I decided I was lost and wanted to restart - but I had not saved the start configuration of balls so I decided to let the computer solve it for me.
So I wrote a simulation program to toss the balls around according to the rules, and stop at the pre-determined target configuration.
I must have use a randomiser of some sort and the program found the solution for me.
When I examined a printout I found many long repeating and re-repeating sequences that I could eliminate until what was left was a straight sequence that I then entered in the game to move the balls from their present position to the desired end positions. Bingo.
If the program’s output could have been linked to the game it would of course have done the job all by itself, with a lot of redundant, insignificant steps in between.
I don’t remember whether I used assembler, Pascal, Qbasic or Foxbase.
Anders · 19 March 2009
Anders · 19 March 2009
Mike Elzinga · 19 March 2009
It’s great that Ian has posted the discussion of Weasel. It is one of the best pedagogical tools for illustrating the effects of selection without requiring an extensive mathematical or physics background.
If I may summarize a few points I made in some of my previous comments on the other thread covering this, those interested in how this exercise can be integrated into a bigger picture might want to try a few tests with their programs.
One. The selection process represented here is only one of literally thousands of ways to cause a random process to converge to an equilibrium state. In this case, the fact that the string has “meaning” as a recognizable sentence is irrelevant. Any target string could be used.
Two. The solutions to equations (e.g., roots that set the equation equal to zero) are mathematical examples of looking for an “equilibrium” condition. Randomly throwing numbers at the equation is highly unlikely to produce a root. However, pulling candidate roots from domains that are restricted according to how close the equation approached zero when a candidate was selected from a prior set produces a sudden and dramatic convergence to “equilibrium” (locating the root).
Three Physical processes in which matter condenses into self-organized patterns already has a “built-in mechanism” for selecting candidates for the next round of trials; namely, the second law of thermodynamics.
Four There are some tests that one can do on any selection model to see if it has any characteristics of physical reality. These rely on some general characteristics of physical systems that are not necessarily characteristic of some artificial or mathematical algorithms. If the outcomes of these tests indicate some of the features of real, physical systems, then the algorithm can be place in a set of candidate algorithms for use in a more sophisticated model.
Five A caveat in this process is that some algorithms can mimic physical reality closely enough that they are difficult to distinguish from actual physical mechanisms in a stochastic set of tests.
Given these general notions, here is the general recipe for exploring whether or not an algorithm captures any physical reality.
A Something in the model has to be identified as what physicists refer to as a “generalized force” that drives the system toward equilibrium. It could be a “potential energy” or some kind of mechanism that “pushes” the system in the direction of equilibrium.
B The larger this “generalized force”, the more rapidly the system proceeds toward equilibrium. As the system approaches equilibrium, the generalized force diminishes until it becomes zero at equilibrium.
C In any stochastic process, there are fluctuations in the generalized force. These fluctuations generally increase with the magnitude of the generalized force.
C In realistic systems, one expects the ratio of the magnitude of the fluctuations in the generalized force to the magnitude of the generalized force itself to go like the reciprocal of the square-root of the number of contributors to the generalized force. (This assumes that the magnitude of the generalized force is linearly proportional to the number of “carriers” of unit quantities of this generalized force.)
D Therefore, in running the model, it is necessary to capture data on not only the magnitude of the generalized force at each point in the system’s evolution, but also data on how it fluctuates at each point. This means collecting a representative ensemble of the values of the generalized force at each point and calculating its mean and standard deviation.
E Plotting the magnitudes of the fluctuations against the magnitudes of the generalized force itself on a log-log plot will produce a straight line with a slope of negative one-half if the model is behaving anything like physical reality.
There are many other tests one can make that get into the fractal natures of physical systems, but this is a start for those beginning to play around with these kinds of models.
More generally, however, it is probably better to try to build a model from the ground up based on known or suspected physical mechanisms. However, the exercise with Dawkins’ Weasel program is a legitimate form of investigation because it approaches the problem from the perspective of cataloguing candidate models for later use.
Wesley R. Elsberry · 19 March 2009
The graph shown here plots the probability that a population will have at least one candidate that preserves all the correct characters from the parent string. The graph shows population sizes from 1 to 500, mutation probabilities from 0.0 to 1.0, and is done for the case where the number of correct characters in the parent is 27. Once the population is around fifty, increases in population size make very little difference.
If one runs a "weasel" with a reasonable population size and mutation rate, it is highly likely that there will be some candidate in the population that at least keeps the correct characters from the parent, and without the use of elitism (where an unmutated daughter copy is inserted into the next generation). The breakover point for the mutation rate is where it starts becoming likely that more than one character will be changed per candidate.
Bethor · 19 March 2009
Bethor · 19 March 2009
Bruce · 19 March 2009
Should that headline refer to "Weasles" or "Weasels"?
Or is that an intelligently-designed typo?
Anders · 19 March 2009
Ian Musgrave · 19 March 2009
72 hours and still no weasels over at uncommon dissent.
stevaroni · 19 March 2009
Ian Musgrave · 19 March 2009
Philip Kahn · 19 March 2009
Heads-up: on the Python program, it works for 2.7, but on the final line, the print statement should be enclosed in parentheses if you're running Python 3.0.
Mike Elzinga · 19 March 2009
Wesley R. Elsberry · 19 March 2009
The graphs are in PNG format. I'm not positive what browsers know about PNG, but Firefox 3 on Mac OS X certainly does.
Kevin B · 19 March 2009
Mike Elzinga · 19 March 2009
Dean Wentworth · 19 March 2009
Maybe writing even simple programs requires a "pathetic level of detail" that the folks at the Evolutionary Informatics lab are unable to match.
angst · 19 March 2009
Roy · 19 March 2009
Answers in Genesis implemented a fancy version of weasel <note spelling> several years ago, complete with options for population size, fixed vs variable mutation rates, modelling amino-acids, etc. The program worked well (as long as you didn't mind the copious garbage in the accompanying text) and I still have a copy.
AFAICT AiG did this to 'demonstrate' that in reality, you'd never ever reach any optimal solution because after a while the probability of the next generation containing a fitter individual was the same as the probability that all members of the next generation were less fit than the parent, at which point the simulation would simply oscillate back-nd forth, and never reach the set target. They called this 'error catastrophe'. (They cheated, of course, by selecting a set of options that didn't reflect real life; however, I don't think the person who developed the program got the memo, since everything AiG claimed could rapidly be refuted simply by choosing more appropriate options).
So... why didn't Dembski just use AiG's implementation, since it manifestly does not include locking?
Roy
MememicBottleneck · 19 March 2009
mrg · 19 March 2009
Wesley R. Elsberry · 19 March 2009
Thanks, Mike. I've edited the page.
I checked most things I put up via Monte Carlo, but I apparently thought those were OK as they were.
Mike Elzinga · 19 March 2009
Wesley R. Elsberry · 19 March 2009
Mike,
None of the probability stuff was complex, but after a while of raising complements to powers it all gets prone to error. Obviously I was prone to error to begin with, but at least for the stuff related to the "locking/latching" issue I was really cautious and made sure that the calculation and the simulation agreed over a range of parameters. At least I think I did... let me know if you see anything else dodgy.
Wheels · 19 March 2009
A noble click embiggens the smallest thumbnail?
Mike Elzinga · 20 March 2009
Anders · 20 March 2009
Ian Musgrave · 20 March 2009
82 hours and still no weasel programs over at uncommon dissent.
Torbjörn Larsson, OM · 20 March 2009
Sander van Driel · 20 March 2009
Yay! Programming! This whole discussion inspired me to make my own Weasel implementation in C#. This was REALLY, REALLY easy (45 minutes). I can’t wrap my head around it how Dembski c.s. don’t just DO IT.
Porlock Junior · 20 March 2009
Sizzi being mentioned, I can't resist a footnote. This was one of the people whom Galileo declined to fight with; OK, the guy had made a fool of himself, but who needed to make an enemy? The result was that some years later Sizzi told him of an anomalous motion of sunspots, which still later Galileo used to show a nasty problem with geocentric systems, whether Ptolemy's or Tycho's.
And the moral of that is -- something about turning the other cheek or casting bread upon the waters, though it's hard to see how it applies to the die-hard creationists. Maybe upstart creationists still capable of redemption?
stevaroni · 20 March 2009
Sander van Driel · 20 March 2009
Weasel in C# (small update)
I corrected the mutation mechanism so it matches the original algorithm (e.g. with a mutation rate). For an offspring count of 30 and a mutation rate of 4%, the last lines show that the M does not lock in this test run:
Generation 103 - Fitness 85.7% - METHINKS IT IC YIKE A WEQSCLGeneration 123 - Fitness 89.3% - DEDHINKS IT IC LIKE A WEASEL
Generation 146 - Fitness 92.9% - PETHINKS IT IQ LIKE A WEASEL
Generation 150 - Fitness 96.4% - PETHINKS IT IS LIKE A WEASEL
Generation 186 - Fitness 100.0% - METHINKS IT IS LIKE A WEASEL
Mike Elzinga · 20 March 2009
Anders, Ian, Wesley, and Sander:
I see I have a few commitments that will keep me busy for the next day, but here are some thoughts I am working on.
These curves are extremely reminiscent of a number of well-known processes in physics and they can be checked with your programs very easily.
Simply change to a semi-log plot and plot your decaying curve directly against the logarithm of the generations. Then take your increasing data and subtract it from 1 and plot it on the semi-log plot (data vs log of generations). If you get a roughly straight line, we have a winner.
Here are some examples of processes this reminds me of in the stochastic regime:
Radioactive decay in the presence of radioactivation. In this case, a sample of atoms are sitting in a field of neutrons or gammas and being excited into higher energy states from which they decay.
The decay of voltage in a capacitor discharging through a resistor.
A nearly critically damped harmonic oscillator, but at the level where the stochastic hits from the air molecules doing the damping is visible.
In any of these cases, changing the target string is equivalent to shifting the ground state of the system. The system, if it is within a regime in which it can respond, simply tracks the new target (ground state) with a delay and decays into the new equilibrium position.
KP · 20 March 2009
Kevin B · 20 March 2009
Mike Elzinga · 20 March 2009
Kevin B · 20 March 2009
Mike Elzinga · 20 March 2009
If the harmonic oscillator in one of my previous comments seemed like a strained analogy, here is the justification.
When atoms or molecules condense into a crystal, the mutual potential energy among the molecules begins to form a potential well. As the molecules or atoms fall deeper into this well, the well itself can be more closely approximated as having a parabolic shape (for those with some math background, a Taylor series expansion of the potential is quadratic in the second-order term, and the higher orders are small enough to be ignored).
Now, what happens in crystallization is that the atoms or molecules that participate in this are selected (because of the second law of thermodynamics). Atoms are losing energy through collisions with other atoms that are carrying energy out of the system or by way of photons that escape to infinity. What remains are ensembles of atoms with smaller and smaller energies, and these start to fall into the mutual attractive potential wells.
The big hurdle for the ID/Creationists is their carefully constructed misconceptions about the second law. They have continually propagandized for decades against all efforts of the physics community to correct these misconceptions. Thus, the ID/Creationists think the second law prevents this selection process from occurring.
The truth is quite the opposite; the second law is an expression of the fact that this stuff really happens. It is a description of the way nature behaves, not a demon that steps in and prevents or smashes everything into chaos.
The Dawkins’ Weasel program captures some of the aspects of stochastic systems settling into a “potential well”.
Mike Elzinga · 20 March 2009
Bjarne B · 20 March 2009
After having heard of it yesterday for the first time, I decided to put together my own weasel program in python.
Taken that I have written my last program in school in 1993 and that I have never heard about python until yesterday, I am a bit proud on myself :D
Unfortunately, I have no place to post the code (and I believe it not to be too elegant anyway).
Wasn't too hard, actually.
Examples from an offspring count of 25:
Generation 0
Best fit:JCSVWGU HXVY RXJADIWENCNRH Similarities:2
Generation 15
Best fit:JCTVIGU IT YS RXJWDBWWNCSEL Similarities:12
Generation 50
Best fit:MJTHIOF IT XS OIFE U WEWSEL Similarities:19
Generation 79
Best fit:METHINK IT IS LIXE A WEXSEL Similarities:25
Generation 80
Best fit:METHINK IT IS LIXE A WEASEL Similarities:26
Generation 81
Best fit:METHDNK IT IS LIXE A WEASEL Similarities:25
Generation 108
Best fit:METHINK IT IS LILE A WEASEL Similarities:26
Generation 109
Best fit:METHINK IT IS LIKE A WEASEL Similarities:27
Wesley R. Elsberry · 20 March 2009
Kevin B · 20 March 2009
ds1978 · 20 March 2009
Is everyone allowing the most fit critter from each generation to undergo random mutation before breeding? The source code referenced in wikipedia at:
http://home.pacbell.net/s-max/scott/weasel.html
does not. It will always converge on a solution because it limits the result of each generation to improvement or no improvement. There is no going backward. In the biological world of mutation and selection sometimes things fail to converge on a solution and become extinct.
Another problem with these Weasel programs is they begin from random gibberish. In the biological world something that is random gibberish to start with doesn't reproduce at all. Critters start from a highly optimized state and (usually) because of some change in the external environment that diminishes the optimization they adapt through mutation and selection to a better optimized state.
The Weasel programs would be more realistic if the most fit of each generation is subjected to random mutation like all the others in the population and it would also be more realistic if there was a beginning population of semi-fit critters, say with half the characters correct, and if the number of correct characters in the fittest individual ever fell below one quarter the result would be an extinction.
This way if the population was too small and/or the mutation rate too high we'd see what often happens in the biological world under such conditions - the species would become extinct.
On the latching issue that's easy to code. If you don't mutate the most fit individual and all the others are limited to a single character mutation each (which the above referenced program does) then a new most fit individual would require two mutations of previously incorrect letters to a correct letter. If no critter in a single generation can have more than one mutation then replacement of a correct character with an incorrect one is not possible.
It is possible for the program referenced above to unlatch a correct character because of another unrealistic thing that it does. During breeding the most fit individual from the previous generation (let's call him the "stud") injects a random size portion of itself into a randomly selected one eighth of the population. The caveat that can allow a correct character to become incorrect is that each individual mating result is evaluated immediately and if the progeny is more fit than the stud then the current stud is immediately replaced by his more fit offspring. To be more realistic the replacement of one stud by another should wait until all breeding in any one generation has been completed. The way it is the generation count is misleading, especially with larger populations because within a single generation the stud can be replaced by his offspring multiple times. You can see this by setting the population number to a half million. It converges on a solution in less than 10 generations which means an average of almost 3 correct letters are added in each generation. When mutation of any single individual in a single generation is limited to one character then the minimum number of generations should be very near the character count of the string minus any correct characters that happened to be in the fittest individual of the very first generation of random gibberish strings.
Mike Elzinga · 20 March 2009
George · 20 March 2009
I have run the python version now several times and the unlocked, 30 offspring / generation settings do not converge until about 8000-10,000 generations. This is an order of magnitude more than you show above?
Wesley R. Elsberry · 20 March 2009
Wesley R. Elsberry · 20 March 2009
Mike Elzinga · 20 March 2009
This is a really interesting thread, but I have to run off to another engagement. I can only stop by briefly on occasions in the next day or so.
But here are some characteristics to look for.
For systems that converge relatively quickly, (deep in the “potential” well), one should see fluctuation magnitudes of the “potential energy” divided by the magnitude of the mean of the potential energy go like the reciprocal of the square-root of the number of generations. It is in this regime that the semi-log plot should show a straight line as mentioned in a previous comment.
For systems that converge very slowly (i.e., approaching chaotic behavior), the above rule no longer holds and the fluctuations continue to get larger as the system approaches the chaotic threshold.
I wish I had thought about using Dawkins’ program as a teaching tool years ago.
Ian Musgrave · 20 March 2009
Ian Musgrave · 20 March 2009
Gahhh! Why don't PRE tags work properly here!
SteveF · 20 March 2009
Ian,
Speaking of uncommon descent, O'Leary links to some frenzied recent activity on Michael Behe's blog. It concerns this paper:
Durrett, R. and Schmidt, D. (2008) Waiting for two mutations: with applications to regulatory seqeunce evolution and the limits of Darwinian evolution. Genetics, 180, 1501-1509.
Behe has a response in Genetics (to which Durrett and Schmidt reply). He then continues the discussion on his blog:
http://www.amazon.com/gp/blog/A3DGRQ0IO7KYQ2/ref=cm_blog_dp_artist_blog
I was wondering if Pandasthumb would be dealing with any of this? Seems like it might make an interesting series of posts.
Apologies for being off topic (and good work on the weasel front!). Cheers.
George · 20 March 2009
Mr. Elsberry,
Seems you were not replying to my comment. My comment was noting that the Python unlocked version referenced takes longer to converge than Ian's data as shown. There may be parameters that do not match, but I am interested in trying to match those results.
The locked version has a bug that I have not worked on - that will need to be a weekend task. So I have no comparison of the two at this time.
If anyone has run the python version and matched Ian's data I am interesting in the settings for a 30 offspring / generation case.
thanks
Sander van Driel · 20 March 2009
Wesley R. Elsberry · 20 March 2009
George,
I'm not sure why my response to "ds1978" has a header saying that it was a response to you.
What's the link to the implementation of "weasel" that you are having trouble with?
Sander van Driel · 20 March 2009
George · 20 March 2009
Mr. Elsberry, (or may I use Wes? Wesely?)
No worries. I am using Python v3.0.1 - I copied the code from the link provided.
http://www.cbs.dtu.dk/courses/27615.mol/weasel.php
I have not tried many options yet as time has been limited. Yet, 8000+ generations to converge for the 30 offspring case is an order of magnatude more than Ian's data.
Ian Musgrave · 20 March 2009
Ian Musgrave · 20 March 2009
Wesley R. Elsberry · 20 March 2009
George,
"Wesley" should do fine.
I got the Python code and ran it with N=30 and the default mutation rate u=0.09. That mutation rate is pretty high. Yes, the simulation tends to run on and on at those settings. It isn't surprising, though...
1000 runs, N=30, u=0.09000, K=27, C=27, p_pop_c2c calc = 0.93373, MC = 0.93900
Proportion of candidates w/C2I bases calc = 0.91350, MC = 0.91370
p_pop_c2c = 1.0 - (0.91350)^30
A little over 6% of the time, a generation's best candidate will have changed a correct base for an incorrect one. Given that N=30, it also isn't likely that an improvement is going to be found in 16 generations or fewer. Plus this problem is going to be manifested pretty severely prior even to getting to the C=27 level.
SteveF · 20 March 2009
Ian Musgrave · 20 March 2009
George · 20 March 2009
Thanks for the help. I will reduce the mutation rate and run again. Now I will dive into getting the locked code to run.
Mike Elzinga · 20 March 2009
Mike Elzinga · 20 March 2009
If there are some here who are not familiar with, or are rusty on some elementary data analysis techniques, here is a beginning tutorial on data analysis that I and a former colleague wrote some years ago.
Click on the section on Graphical Analysis.
I have no idea of how it wound up at this site. I suspect my colleague used it in a summer workshop at some point.
If you add some graphing output to your programs, make some allowances for semi-log, log-log, and logarithmic plots.
Then as you explore different convergence regimes in your program, you can start looking for patterns that may point to underlying physical mechanisms this program could mimic.
Anders · 21 March 2009
Anders · 21 March 2009
Wesley R. Elsberry · 21 March 2009
ds1978 · 21 March 2009
ds1978 · 21 March 2009
Mike Elzinga · 21 March 2009
stevaroni · 21 March 2009
Mike Elzinga · 21 March 2009
stevaroni · 21 March 2009
Mikko · 21 March 2009
Hi all!
I created another implementation of weasel with Python.
http://users.tkk.fi/~mtnarjan/weasel.py
Some here have commented that the "locking" feature is a pain to implement. It isn't necessarily so. I found it very easy to add it as an option. It probably depends on how the non-locking version was done.
Ian Musgrave · 21 March 2009
It is now over a 100 hours since Dembski said "watch this space", and no one, not Dembski's Evolutionary informatics team, nor any of the Uncommon Dissent commentators has constructed a weasel. Mean why we not only have a bunch of weasel programs here, but people are doing head-to-head comparisons of different implementations of the Dawkins vs Dembski version. Again, this highlights the fact that cdesign proponetists don't get the "test your hypothesis" aspect of science.
I'm going silent for a while. I'm hunting asteroids in the L5 point (yes, seriously)
ds1978 · 21 March 2009
Wesley R. Elsberry · 21 March 2009
Ian,
It's worse than that. I informed "Atom", the code guy for Dembski and Marks, last November that "weasel" doesn't latch correct characters. He basically said that it didn't matter and blew it off.
Brendon Collecutt · 21 March 2009
I'm a lurker no longer, I had to try this. 53 minutes in Java.
Output at every 30 generations with a mutation rate of 3%
Generation 30 : HEDLIDKSCIF IS LEYEYAGYMAQEV
Generation 60 : MESLIDKS II IS LEXEYAGWEAQEL
Generation 90 : METHIDKS IT IS LIXE AGWEASEL
Generation 120 : METHINKS IT IS LIXE AGWEASEL
Generation 150 : METHINKS IT IS LIXE A WEASEL
Generation 160 : METHINKS IT IS LIKE A WEASEL
Mike Elzinga · 22 March 2009
I don’t know if the discussion and results on these two threads have anything to do with it, but over at UD there are actually some more recent comments about evolutionary algorithms that appear to recognize that programs like Weasel can model aspects of evolution. They also know about the antenna designed by a genetic algorithm.
Haven’t people been thrown off that board for supporting any ideas connected with evolution?
Some of the people posting there still seem to think along the lines that the intelligence is built into the program because of a specified target. Another seems to recognize that the target doesn’t have to be known by the programmer. He doesn’t say so, but he appears to recognize that the target string could be randomly generated by the computer before any other activity starts and the program would converge to that target.
As I mentioned in an earlier comment, shifting the target string is analogous to shifting the “ground state” and the system tracks with a slight delay. It’s like a change in the environment reestablishing selective pressures on the population.
That could easily be demonstrated by having the computer generate a different target string after the population converged and then going through the whole process again. All it requires is an outside loop that changes the target at the end of the first pass through the loop and then implementing another pass that converges to the new target (environment, “ground state”).
One could also make only a small change in the target string and allow the population to adjust, make another small change, etc. That would simply simulate a population responding to a changing environment. If the environmental changes are relatively small, the population adjustment catches up fairly quickly and is not a lot different from the previous population.
In a relatively short time one could change a weasel into a walrus. ;-)
Frank J · 22 March 2009
Frank J · 22 March 2009
BTW, in the rare case that anyone is losing sleep, I have 2 words: "ontogenetic depth".
Ian Musgrave · 22 March 2009
If anyone is interested in my search for L4 and L5 asteroids, have a look at this post.
RBH · 22 March 2009
Ian Musgrave · 22 March 2009
It is now over a 144 hours since Dembski said “watch this space”, and no one, not Dembski’s Evolutionary informatics team, nor any of the Uncommon Dissent commentators has constructed a weasel program.
It looks like the commentators have accepted, in general, that Dembski's claim is wrong, but now they are describing what Dawkin's program does as "implicit" or "quasi"-locking. All without constructing an actual program to test their ideas. Amazing!
Flint · 22 March 2009
funkotron · 22 March 2009
Yeah the whole discussion of "quasi-locking" is amusing. The claim the parameters are fine tuned such that the program will always converge, which is true. And they say that the generations are large enough that it is very unlikely to produce a generation where all children are worse than the parent, which is true. But they don't seem to recognize that those things are THE POINT, not problems. Thats what random stuff with selection does.
One funny thing was the guy who claimed that it was easier implement latching than to get the parameters so carefully tuned. The tuning process took me about 30 seconds... I just upped the generation size till it converged in some reasonable time.
Mike Elzinga · 22 March 2009
david w · 22 March 2009
Another python weasel:
http://theatavism.blogspot.com/2009/03/another-weasel.html,
Quite different than Anders one and doubt a less efficient way to do things (i'm not actually a programmer) but gets the job done, and implementing "locking" requires one additional line...
I will set it up to do enough runs to compare the locked and unlocked versions at some stage (but I think we all know the results)
Ian Musgrave · 23 March 2009
It is now over a 168 hours since Dembski said “watch this space”. The Dembski’s Evolutionary informatics team has announced that a weasel program has been constructed, and will be available soon (how many have we built and tested in that time?). None of the Uncommon Dissent commentators has constructed a weasel program, but a new commentator, Hazel, has done the maths for them (why did they not do it earlier). In defiance of William of Occam, and the evidence in Dawkins book, they are still insisting that Dawkins book program implements locking.
Oh yeah, don't feed the trolls folks.
dhogaza · 23 March 2009
RBH · 23 March 2009
Mike Elzinga · 23 March 2009
Dave Thomas · 24 March 2009
I got a couple of hours of programming time on the vanpool to/from Socorro today - here's my Python implementation of latching and no-latching in Weasels. The curves show averages of 10 runs each.
I must say, I'm not surprised anyone at UD has mentioned my 2006 article on Weasels, "Target? TARGET? We don’t need no stinkin’ Target!" (roadmap, here).
That's the summer that Salvador Cordova represented Uncommon Descent in a Design-off, and was handed his hat by an evolutionary algorithm.
Anyhow, a fun couple of hours doing the .py coding.
Cheers, Dave
Mike Elzinga · 24 March 2009
Dave Thomas · 24 March 2009
Mike Elzinga · 24 March 2009
Mike Elzinga · 24 March 2009
I noticed over on UD that they are still stumbling all over the “targeted search” issue.
That is, in fact, a ghost issue. If a target is a problem, then all of nature has a problem whenever potential energy is minimized and the second law of thermodynamics is in effect (which it always is, of course).
Dave Thomas · 24 March 2009
mrg · 24 March 2009
I am no expert on genetic algorithms but I recall that in CLIMBING MOUNT IMPOSSIBLE Dawkins pointed to programs modeling the evolution of spiderwebs as working perfectly well without specifying any more as a target than "mutate and see if it catches flies better" and if it does, try again.
Astoundingly, the programs came up with various forms of spiderwebs that looked like different types of real spiderwebs. Gosh, who knew!
Mike Elzinga · 24 March 2009
Ian Musgrave · 24 March 2009
It is now over a 192 hours since Dembski said “watch this space”. The Dembski’s Evolutionary informatics team has announced that a weasel program has been constructed, but none has been posted on the Evolutionary Informatics site. None of the Uncommon Dissent commentators has constructed a weasel program. In the face of the video evidence and the mathematical evidence, the latest killer argument form the UD crew that Dawkins program really does lock is that Dawkins didn't mention letters reverting in his book, so therefore the program locks.
You couldn't make this stuff up.
Henry J · 24 March 2009
david w · 24 March 2009
Here's a couple of results of playing around with mutation rates and the like with the locking and non-locking versions.
As you might expect the 'locked' version performs much better than unlocked with very high mutation rates, since the letters that match the target in the parent string are protected in the offspring. All pretty obvious but it's fun to play around with!
Torbjörn Larsson, OM · 24 March 2009
Torbjörn Larsson, OM · 24 March 2009
D'oh, I meant to describe Dawkins program as the Weasel, as opposed to the "Weasel" of creationists. In no way or form did I want to imply that the Weasel is necessarily latching. My apologies.
Torbjörn Larsson, OM · 24 March 2009
Actually, if I were a reviewer, I would descend like a hawk deciding who is fit to survive or not on the "especially computer simulations of evolutionary search" in the conclusions. It isn't supported by the paper. Not even by the childish trick of equaling brute search, long existing before the discovery of GA's, as a GA: just because a search is more difficult doesn't mean it is in need of the asked for specification.
Which specification I would also kick around mightily, since it would fill no practical or scientific purpose, even if it wasn't wrongly applied.
Mike Elzinga · 24 March 2009
Mike Elzinga · 25 March 2009
Well, I see over at UD that the Second Law is now being invoked against “locking”. “Errors in genetic transcription are ensured by the Second Law. If you lock certain letters, you are saying the SLoT is suspended for them, but not for others.”
What Morris and Gish put in place with their meme now dictates the entire thinking process of the ID community.
It even degrades their programming abilities. It's not the Second Law doing that.
Sigh.
Henry J · 25 March 2009
Dave Thomas · 25 March 2009
Kevin B · 25 March 2009
Henry J · 25 March 2009
Nah, you guys will just have to ferret out your own weasel. :)
Reed A. Cartwright · 25 March 2009
preis not recognized. Useblockcode. You can also useverseto turn newlines into linebreaks.Mike Elzinga · 25 March 2009
Mike Elzinga · 25 March 2009
Ian Musgrave · 25 March 2009
It is now over a 216 hours since Dembski said “watch this space”. The Dembski’s Evolutionary informatics team has announced that a weasel program has been constructed, but none has been posted on the Evolutionary Informatics site. An actual piece of code is finally being discussed. Unfortunately, Apollo's code has some errors. Commentator Hazel at UD points this out, and Apollo deals with the fRAND error, but not the other one (seriously, with a offspring number of 500 and 5% mutation rate the thing doesn't converge for over a 1,000 generations, when for a real weasel program, even a population of 30 will converge in less). So, now they are debating the results of an obviously flawed program (sigh). More strength to Hazel and Sal_Gal, who are trying to inject some sense over there.
Wesley R. Elsberry · 25 March 2009
Dave Thomas · 26 March 2009
Wesley R. Elsberry · 26 March 2009
Latching and stepbacks in fitness of best candidates are two separate things, but having a stepback makes it obvious that latching cannot be happening.
Mike Elzinga · 26 March 2009
Over at UD some of the folks are getting a glimmer of the point of Weasel.
However, it appears that the fact that there is a target string is still a stumbling block. As long as that is in there, some of them seem to think some sort of teleology is involved, or that the result is somehow connected to design.
Staring into to the abyss of a “purposeless universe” is going to be a big hurdle for the ID community. It not only forces them to question sacred dogma, but it also highlights the fallacy of the lottery winner misconception.
They are going to have to untangle the notions of order/disorder, information, organization, self-organization, complexity, entropy, the second law of thermodynamics, and the fallacy of being special along with all their well-ingrained misconceptions about evolution.
The decades of intense and well-funded misinformation campaigns by the ID/Creationist institutes have clearly made their mark. And the science community has to clean it up. Oh well….
Mike Elzinga · 26 March 2009
Ian Musgrave · 26 March 2009
mrg · 27 March 2009
Divergence of B · 27 March 2009
Mike Elzinga · 27 March 2009
Dave Thomas · 27 March 2009
A.S. · 28 March 2009
Much too late to the party, I guess. With my implementation (in R), it takes around 30 generations with locking, around 130 without locking, using the following parameters: 100 offspring per generation, 10 per cent probability for a mutation at any point in the string, only lowercase letters and whitespaces, best match gets selected and mutated again. Clearly, the lower the mutation probability, the less important locking becomes: with a 1 per cent probability, it takes an estimated average of 160 generations without locking and 120 generations with locking. This follows, I guess, from the fact that the lower the mutation probability, the lower the chance that a match once found will mutate again even without locking. On the other hand, with a mutation probablitiy of 99 percent, the target is never reached without locking, but it takes only a dozen generations to reach it with locking. I'm sure mathematicians and biologists have long known this, but to me it was quite surprising though it makes perfect sense after the fact. Also, I find it very funny that Dembski, who thinks he's a mathematician, doesn't understand the program and apparently cannot write a version that might help him understand it, while I, a mere linguist, was able to write my R script in a few hours. (And it can run with and without locking! And generation size, mutation probability, target string, etc. can be freely determined! And it can draw a pretty plot of what it is doing! And if anyone wants it, they can have it!).
IanR · 28 March 2009
Here I describe a link to an Excel macro weasel program I wrote, and give a run and the actual results that show that a run can revert away from the correct sequence.
Tani Hosokawa · 28 March 2009
Just so Perl gets a voice:
http://tanihosokawa.org/pandasthumb/weasel.pl
takes 5 command line arguments:
* verbose (display the best parent and generation)
* num_trials (how many trials to run of locked vs unlocked -- this is slow, bad perl code, don't go too high)
* target (defaults to "methinks it is a weasel")
* mutation_rate (% chance of a letter being changed)
* offspring (number of offspring per generation)
I think this took around 20 minutes, but I'm pretty wiped right now.
A.S. · 29 March 2009
Ah, forgot to post the link to the R script, here it is:
http://www.stefanowitsch.de/anatol/files/weasel.R.zip
Simply unzip, import into R using
> source("/YOUR_PATH/weasel.R")
and you have a new function in R, called weasle. This function has the following arguments:
weasel(string="SOMESTRING", probability=SOMENUMBER, offspring=SOMENUMBER, locking=(TRUE|FALSE), plot=(TRUE|FALSE))
The defaults are
string="methinks it is like a weasel"
probability=0.1
offspring=100
locking=FALSE
plot=FALSE
As is, the program can only deal with lowercase characters and whitespace in the string, but this is easily modified in the source code (as is everything else, there are extensive comments). Also, if you use plotting, the program exits without clearing the graphics window, i.e., if you run it again, the new plot will be added to the old. If you don't want this, run
> par(new=FALSE)
before running the program again.
Some examples:
> weasel()
This runs the program with the default values.
> weasel(string="evolution beats design", probability=0.08, offspring=30, plot=TRUE)
This runs the script with the target string evolution beats design, the mutation probability is 8 per cent, there are thirty offspring per generation, no locking is used, the output will be plotted)
> weasel(probability=0.01, offspring=250, locking=TRUE, plot=FALSE)
This runs the script on the default "methinks it is like a weasel", with a mutation probability of 1 per cent, 250 offspring per generation, WITH locking and without a plot.
Ellindsey · 30 March 2009
The main objection I can see to the Weasel program as not being a good demonstration of evolution is that the target string is embedded in the program from the start. I realize that the point of the original program was to demonstrate evolutionary generation of that specific string, but real evolution doesn't work towards a specific goal, just one that works.
Someone suggested that a better demonstration would be to evolve a valid, meaningful sentence. I don't know how to write a fitness function to test how meaningful a sentence is, but it's easy to test how much of a text string is made up of valid dictionary words. I have put together a Python script that evolves sentences, staring with random strings and scoring each string based on how close it is to being made up entirely of dictionary words. It works surprisingly well. The sentences it makes aren't terribly meaningful (last run's result was "SOW WHY SIZE FOOT ROOT ESCAPE WOOLEN") but it works surprisingly well, taking less than a hundred generations to settle on a valid sentence. Anyone have a way to mathematically evaluate the meaningfulness of a sentence?
I can email the code to anyone who wants it, or who (even better) wants to put it up where it can be downloaded.
Henry J · 30 March 2009
I have no idea how one could automate an evaluation of meaningfulness, but I'd think the next step would be rules of grammar: distinct subject, verb, object; check that adjectives and adverbs only in appropriate places to modify something; include an object phrase only for verbs that need one, not for those that don't; check that prepositions have an associated object; check that noun phrases appear only as subject, object, or content of prepositional phrases; etc.
That does however sound like a lot of work to implement.
Henry
Rilke's Granddaughter · 30 March 2009
Ellindsey · 30 March 2009
I am fully aware of what the Weasel program was intended to simulate, and stated so in my comment. You need to actually READ what I wrote.
Rilke's Granddaughter · 30 March 2009
Apparently you didn't.
"Weasel program as not being a good demonstration of evolution is that the target string is embedded in the program from the start. I realize that the point of the original program was to demonstrate evolutionary generation of that specific string, but real evolution doesn’t work towards a specific goal, just one that works."
Weasel was not intended to demonstrate evolution. Try again.
Ellindsey · 30 March 2009
Semantics. It was intended to generate how that specific string would be generated through mutation and selection. Which is evolution, although a very specific and limited case of it.
In any event my point was not to criticize the Weasel program itself. It's a fine demonstration of the power of selection. My point was to offer an example which demonstrated selection towards a target not predefined, but determined by a selection function that permits a different solution to be found each time the code is run. I though people might be interested.
Mike Elzinga · 30 March 2009
Henry J · 30 March 2009
Rilke's Granddaughter · 30 March 2009
Dirk Esser · 10 April 2009
Sorry, could not resist. Here is a version in Common Lisp. Also included is a creationism-influenced version, which is amazingly fast: it converges in a single generation on average, even with an initial population of 0. So, ID/creationism might actually have a point...
Dave Thomas · 11 April 2009
Just in case anyone's watching - it has now been 562 hours since Dembski promised that "Evolutionary Informatics lab was going to try and reproduce Dawkins Weasel Program according to how it was actually written"
But, the "Weasel Ware" page is still unchanged, still mired in the past, still hung up on "latching," still wrong.
23 days and counting! Shall we start a pool? I'll pick St. Bartholemew's Day... 2098.
Dave
mrg · 11 April 2009
learnignpython · 15 April 2009
I'm teaching myself python.
Has anyone tried to write a weasel program in python?
Mike Elzinga · 15 April 2009
Henry J · 15 April 2009
Dave Thomas · 22 April 2009
Mike Elzinga · 22 April 2009
Divergence of B · 29 August 2009
Jeb, FCD · 29 August 2009
Anyone got it in Ruby?
Brian Macker · 30 August 2009
Your argument that a locking version is much harder to program is nonsense. Just check the character against he target string before you allow mutation. If it already matches then do not mutate. A single line test.
DiEb · 31 August 2009
- as above, the number of correct letters
- the length of the longest correct substring
- the number of correct vowels times the number of correct consonants
- how many letters are correct at the beginning of the string
- etc.
The fitness function could work as an oracle: you send the strings of a generation to it and it delivers back (one of) the best string(s) (here the problem arises of stopping the program). But this approachDiEb · 31 August 2009
fnxtr · 31 August 2009