|
Main
Date: 22 Jun 2007 11:47:45
From: Guy Macon
Subject: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
tin Brown wrote: > >help bot wrote: > >> But the program advertised at the Chessbase Web site >> called "Shredder" claims to come with the endgame TBs >> on DVD, highly compressed so they won't gobble up >> your hard drive or require a massive (free) download. >> That is what I was referring to. > >Specifically they are so highly compressed that the entire ALL345 TB >in Shredders format is only 140MB ... It will fit entirely in system >ram with corresponding performance advantages over disk based full >size Nalimov tablebases which are roughly 7GB Fifty times smaller than compressed Nalimov tablebases? That's a big reduction in size. Any chance that this is some sort of keting hype and some information is missing? Is the compression algorithm known? It has to be fast to be suitable for decompressing on the fly from a compressed image in memory. -- G o o g l e F o o d : <http://www.guymacon.com > <http://www.guymacon.com/> Guy Macon Guy Macon Guy Macon Guy Macon Guy Macon Guy Macon Guy Macon Guy Macon Guy Macon Guy Macon Guy Macon Guy Macon Guy Macon Guy Macon Guy Macon Guy Macon Guy Macon Guy Macon Guy Macon Guy Macon Guy Macon Guy Macon Guy Macon Guy Macon
|
|
|
Date: 28 Jul 2007 13:12:58
From: [email protected]
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
Thanks very much for the information!!! Another complexity measure, which it might be possible to implement efficiently, might be to keep track of big changes in the evaluations of moves. When probabilities are assigned to moves before the search begins, as to which is most likely the best move, as I believe Rybka does, big changes in the evaluations of a move would seem to indicate there are some tactics involved.
|
|
Date: 18 Jul 2007 21:06:50
From: [email protected]
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
One other interesting topic that has come up recently on the Rybka forum is the issue of complexity and the "contempt" factor. Curiously enough, the best measure of complexity I have found so far, during my research using the tablebases, is the number of "unique" moves in the search tree. I think this is because positions that have tactical solutions often have a unique winning move. A good way to simulate complexity using a chess engine would be to keep track of the score of the 2 best moves at each position in the search tree, and compare them, to see if it looks like there is probably just one winning move. Then "contempt" could mean that higher complexity positions would be given greater weight. This would be useful for computer engines when playing humans. Conversely, a positional engine like Rybka, when playing other chess engines, might want to minimize complexity, in order to maximize the advantage Rybka gets for its superior positional play.
|
| |
Date: 19 Jul 2007 13:38:10
From: Dr A. N. Walker
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
In article <[email protected] >, [email protected] <[email protected] > wrote: > [...] Curiously >enough, the best measure of complexity I have found so far, during my >research using the tablebases, is the number of "unique" moves in the >search tree. [...] >A good way to simulate complexity using a chess engine would be to >keep track of the score of the 2 best moves at each position in the >search tree, and compare them, to see if it looks like there is >probably just one winning move. In the tablebases, this is fine. Once all the hard work has been done, you can just "look up" the result of any proposed move, and easily count how many are winning. But during the game, you do not usually know the two best moves -- not even the *one* best move -- and even less their scores. If all you want to do is to evaluate several or all of the moves at the root, that's not too bad, and you have to do a large part of that work in any case just to establish which move to play. But that would only tell you whether the current position has a unique win, which seems to be a lot less than you are asking for. If you're trying to keep track of the proportion of "only" moves during the search, this interferes very badly with pruning. Very crudely, in a won position [which is getting on for half of all positions in the full, unpruned, game tree], and with decent move ordering, you need to look at only one move to confirm the win. This saves a factor of around 30 on average in each won position. In, say, a depth-14 search, this saves a factor of 30^7, or around 2x10^10 [or, going the other way, if you don't prune, you lose that factor, which turns a 4GHz PC into the equivalent of a 0.2Hz snail], which is why it really isn't optional. To find out whether this is an "only" win, you have to look at *at least* two moves in each won position. This already costs you a factor of 2^7 = 128; in an "only" position, it will cost you a factor of 30 or so each time it happens. In addition, there will be murky effects on the transposition tables, etc. That factor of 128 will cost you around 4-5 ply in the search depth you can reach, or is equivalent to replacing your 4GHz PC by an ancient 30MHz one. You need an awful lot of positional compensation for that loss of speed! I'd be surprised if measuring complexity was worth it. On the other hand, your idea is somewhat related to the old "conspiracy number" idea -- viz that it was useful to know how many nodes needed to "conspire" to change the result of an analysis, in the sense that you could be much more certain of a decision confirmed in many ways than of one that depended on everything going according to plan in a whole series of critical positions. [If your choice is between a safe win of a piece, or sacrificing a queen for a mating attack, then the important thing is to make sure that the attack is absolutely watertight.] -- Andy Walker, School of MathSci., Univ. of Nott'm, UK. [email protected]
|
|
Date: 05 Jul 2007 00:42:49
From: [email protected]
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
Basically what Vas is doing is using a new paradigm that combines several powerful ideas from CS Theory (efficiency of algorithms), namely doing a probabilistic depth first search to *check* on the correctness of standard (but extremely elegantly formulated) heuristics. Reminds me of what Botvinnik was trying to do, but the intellectual tools of CS Theory hadn't been developed at that time. Endgame was a lower priority in the Rybka scheme due to that emphasis on probability, simply because endgame positions were less likely to occur :-) My main interest is endgames, and now that it is becoming clearer that Rybka needs improvement in that area, more work is being done. Tablebases in particular are the most interesting aspect of endgames to me currently, trying to understand the logic behind various arcane winning moves. So I think it will be great when Rybka takes better advantage of the tablebases. One might try to use statistical information garnered from the tablebases to improve more general endgame heuristics, for example. For an engine to beat Rybka, it will probably either have to beat Vas at his own game, using the same paradigm Rybka is using but do it better, or else find an even better paradigm or model of computation. That would seem to be extremely difficult though. Rybka actually plays extremely "normal" (from my human point of view) chess, but plays normal chess extremely well. I can almost always understand the moves Rybka thinks are better than my own when I analyze my games afterwards, while sometimes I can't make any sense of the moves other engines think are better.
|
|
Date:
From: Martin Brown
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
|
|
Date:
From: Martin Brown
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
|
| |
Date: 26 Jun 2007 17:09:39
From: Gian-Carlo Pascutto
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
tin Brown wrote: > On Jun 25, 5:47 pm, Gian-Carlo Pascutto <[email protected]> wrote: >> help bot wrote: >>> Otherwise there will be many cases where the correct >>> evaluation is plugged in, but the engine cannot win the >>> game in practice. >> I am quite sure that this statement is not backed up (and in fact >> refuted) by practise. >> >> How often does Shredder with ShredderBases play into a won endgame it >> cannot win? Hardly ever. Why? Because the normal positional evaluation >> will still steer it towards more easily won endgames. > > But Shredder with Shredderbases enabled quickly returns that same > "Mate in N" (where N can be 50+) answers as Nalimov TBs would when the > position comes in range. I don't think the normal positional > evaluation function is used at all. The eval is used once you are *inside* the 5 man endgame. Outside (with more pieces on the board) the distance-to-conversion is measured. If you have Nalimovs alongside ShredderBases, then the Nalimovs are used instead of the positonal evaluation. -- GCP
|
|
Date:
From: Martin Brown
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
|
|
Date:
From: Martin Brown
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
|
| |
Date: 27 Jun 2007 16:14:13
From: Dr A. N. Walker
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
In article <[email protected] >, tin Brown <
|
| | |
Date: 28 Jun 2007 15:36:42
From: Guy Macon
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
Dr A. N. Walker wrote: >In uncompressed form, that means four outcomes [as in my >previous article], so two bits per node: W/E/L/D, where >E again means an exceptional win. Consider the case where a chess engine sees that no matter what it does it will end up at a tablebase position that is a loss. but it's current move decision determines which lost position it will end up at. Let's assume that a Nalimov tablebase tells the engine that move A leads to a position that is a loss in 3 moves, but move B leads to a position that is a loss in 30 moves. Clearly move B is superior. Perhaps the opponent can't figure out the 30-move win. Perhaps the opponent is in time trouble. Only knowing that both tablebase positions are losses can lead to inferior play leading up to the tablebase positions. I can imagine further information in each tablebase position that, if the engine had it, might improve play. What if the engine knew that one position was an easy-to-figure-out win for the opponent, while the other was full of pitfalls and easy-to-make mistakes for the opponent? My guess is that such easy/hard information would not be worth the storage -- that the storage would be better used by having more positions in the tablebase. Perhaps the same is true in the thought experiment above; perhaps it is better to have a larger tablebase that sometimes leads to inferior play rather than a smaller tablebase that sometimes leads to superior play. Especially if the size difference is fifty to one. -- Guy Macon <http://www.guymacon.com/ >
|
| |
Date: 27 Jun 2007 12:19:13
From: David Richerby
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
tin Brown <
|
|
Date: 25 Jun 2007 23:45:15
From: help bot
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
On Jun 25, 5:49 am, tin Brown <
|
| |
Date: 27 Jun 2007 12:22:15
From: David Richerby
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
help bot <[email protected] > wrote: > Weird. In order to save memory, the author would prefer to write > some tricky code instead of storing just one perfect move per > position? ``Weird. In order to save time, the traveller would prefer to sit in some tricky machine instead of just swimming from London to New York.'' Dave. -- David Richerby Generic Toy (TM): it's like a fun www.chiark.greenend.org.uk/~davidr/ child's toy but it's just like all the others!
|
|
Date:
From: Martin Brown
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
|
| |
Date: 25 Jun 2007 14:42:22
From: Dr A. N. Walker
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
In article <[email protected] >, tin Brown <
|
|
Date: 25 Jun 2007 09:04:43
From: Guy Macon
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
help bot wrote: > >Tony M wrote: > >>help bot wrote: >> >>>Hey, just knowing the distance to mate is no good >>>if a chess engine cannot solve the mate. They need >>>to also include (at least) one "best move", don't they? >>>That way the fetching engine can play the move, and >>>then be one move closer to the goal. Repeat as >>>necessary. >> >> Knowing the distance to mate, or avoid mate, or whether a position is >> a draw, is plenty good. >> >> A chess program that uses a distance to mate tablebase generates all >> possible legal moves from a given position, uses the tablebase to >> figure out the distance to mate for the resulting positions from each >> of those moves, and then chooses the move with the resultant position >> that has the shortest distance to mate. A tablebase doesn't store >> moves, only positions and a value for the position. It is up to a >> program that uses tablebases to generate the moves and figure out what >> to do with them. Clear as mud? > >As mud, yes! Okay, this knowledge will speed up the >search and allow for accurate evaluations, but you still >have to be able to figure out the (or one of the) winning >move. > > For instance, I "know" that KQ vs. KR is generally a >win, and I know that the position score is therefore "a >"win, but is Fritz going to just resign, or do I need to >play a move before notching up the point? Of course >I need to play a move -- duh! > > No, I think this in-memory trick is just for speeding >up the search. Somewhere on disk the full tablebases >need to be stored so the program can fetch the move. >Otherwise there will be many cases where the correct >evaluation is plugged in, but the engine cannot win the >game in practice. I *think* that the minimum information needed to avoid the engine having to find the win is Win/Draw/Loss and number of moves to the Win/Draw/Loss. Once the game arrives at a position that is listed as a win in 40 plies, any move by the opponent will result in a position that is listed as a win in 39 plies or fewer (fewer if the opponent doesn't play perfectly). From that postition, a tablebase search of all positions that can be reached in a single move must contain at least one position that is listed as a win in 39 plies. And so on. -- Guy Macon <http://www.guymacon.com/ >
|
| |
Date: 25 Jun 2007 16:42:27
From: Gian-Carlo Pascutto
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
Guy Macon wrote: > I *think* that the minimum information needed to avoid the > engine having to find the win is Win/Draw/Loss and number > of moves to the Win/Draw/Loss. Which is the same as a regular tablebase (DTC or DTZ), and something entirely different from ShredderBases (bitbases). -- GCP
|
|
Date:
From: Martin Brown
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
|
|
Date: 24 Jun 2007 22:39:55
From: help bot
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
On Jun 22, 9:59 pm, Tony M <[email protected] > wrote: > >> Shredderbases don't store the distance to mate as Nalimov databases > >> do, they only tell you whether a position is won, lost or drawn. > >> Therefore, there is less information to be stored. They are more akin > >> to something like Daniel Shawul's bitbases > >> (http://wbec-ridderkerk.nl/html/details/Scorpio.html) than to Nalimov > >> or Chessmaster tablebases. > > > Hey, just knowing the distance to mate is no good > >if a chess engine cannot solve the mate. They need > >to also include (at least) one "best move", don't they? > >That way the fetching engine can play the move, and > >then be one move closer to the goal. Repeat as > >necessary. > > > -- help bot > > Knowing the distance to mate, or avoid mate, or whether a position is > a draw, is plenty good. > > A chess program that uses a distance to mate tablebase generates all > possible legal moves from a given position, uses the tablebase to > figure out the distance to mate for the resulting positions from each > of those moves, and then chooses the move with the resultant position > that has the shortest distance to mate. A tablebase doesn't store > moves, only positions and a value for the position. It is up to a > program that uses tablebases to generate the moves and figure out what > to do with them. Clear as mud? As mud, yes! Okay, this knowledge will speed up the search and allow for accurate evaluations, but you still have to be able to figure out the (or one of the) winning move. For instance, I "know" that KQ vs. KR is generally a win, and I know that the position score is therefore "a "win, but is Fritz going to just resign, or do I need to play a move before notching up the point? Of course I need to play a move -- duh! No, I think this in-memory trick is just for speeding up the search. Somewhere on disk the full tablebases need to be stored so the program can fetch the move. Otherwise there will be many cases where the correct evaluation is plugged in, but the engine cannot win the game in practice. -- help bot
|
| |
Date: 25 Jun 2007 16:47:55
From: Gian-Carlo Pascutto
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
help bot wrote: > Otherwise there will be many cases where the correct > evaluation is plugged in, but the engine cannot win the > game in practice. I am quite sure that this statement is not backed up (and in fact refuted) by practise. How often does Shredder with ShredderBases play into a won endgame it cannot win? Hardly ever. Why? Because the normal positional evaluation will still steer it towards more easily won endgames. Of course this does mean it will be possible to concot some very difficult won endgame and a way that trading into this endgame is the only way to win. Then the engine *might* be helpless. What's the significance in practise? Almost zero. -- GCP
|
| | |
Date: 25 Jun 2007 21:21:37
From: Guy Macon
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
Gian-Carlo Pascutto wrote: > >help bot wrote: > >> Otherwise there will be many cases where the correct >> evaluation is plugged in, but the engine cannot win the >> game in practice. > >I am quite sure that this statement is not backed up (and in fact >refuted) by practise. > >How often does Shredder with ShredderBases play into a won endgame it >cannot win? Hardly ever. Why? Because the normal positional evaluation >will still steer it towards more easily won endgames. > >Of course this does mean it will be possible to concot some very >difficult won endgame and a way that trading into this endgame is the >only way to win. Then the engine *might* be helpless. What's the >significance in practise? Almost zero. I am quite sure that this statement is not backed up by practice. I don't believe that Gian-Carlo Pascutto has done the experiment. I think he is guessing. -- Guy Macon <http://www.guymacon.com/ >
|
|
Date: 22 Jun 2007 17:36:06
From: help bot
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
On Jun 22, 8:09 pm, Tony M <[email protected] > wrote: > >> Is the compression algorithm known? It has to be fast to be > >> suitable for decompressing on the fly from a compressed image > >> in memory. > > >Indeed. AFAIK almost nothing has been written about it. Trade secret. > >Seems to work OK though. > > >Does anyone know how it has been acheived? > > >Regards, > >tin Brown > > Shredderbases don't store the distance to mate as Nalimov databases > do, they only tell you whether a position is won, lost or drawn. > Therefore, there is less information to be stored. They are more akin > to something like Daniel Shawul's bitbases > (http://wbec-ridderkerk.nl/html/details/Scorpio.html) than to Nalimov > or Chessmaster tablebases. Hey, just knowing the distance to mate is no good if a chess engine cannot solve the mate. They need to also include (at least) one "best move", don't they? That way the fetching engine can play the move, and then be one move closer to the goal. Repeat as necessary. -- help bot
|
| |
Date: 23 Jun 2007 01:59:30
From: Tony M
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
On Fri, 22 Jun 2007 17:36:06 -0700, help bot <[email protected] > wrote: >On Jun 22, 8:09 pm, Tony M <[email protected]> wrote: > >> >> Is the compression algorithm known? It has to be fast to be >> >> suitable for decompressing on the fly from a compressed image >> >> in memory. >> >> >Indeed. AFAIK almost nothing has been written about it. Trade secret. >> >Seems to work OK though. >> >> >Does anyone know how it has been acheived? >> >> >Regards, >> >tin Brown >> >> Shredderbases don't store the distance to mate as Nalimov databases >> do, they only tell you whether a position is won, lost or drawn. >> Therefore, there is less information to be stored. They are more akin >> to something like Daniel Shawul's bitbases >> (http://wbec-ridderkerk.nl/html/details/Scorpio.html) than to Nalimov >> or Chessmaster tablebases. > > > Hey, just knowing the distance to mate is no good >if a chess engine cannot solve the mate. They need >to also include (at least) one "best move", don't they? >That way the fetching engine can play the move, and >then be one move closer to the goal. Repeat as >necessary. > > -- help bot > > Knowing the distance to mate, or avoid mate, or whether a position is a draw, is plenty good. A chess program that uses a distance to mate tablebase generates all possible legal moves from a given position, uses the tablebase to figure out the distance to mate for the resulting positions from each of those moves, and then chooses the move with the resultant position that has the shortest distance to mate. A tablebase doesn't store moves, only positions and a value for the position. It is up to a program that uses tablebases to generate the moves and figure out what to do with them. Clear as mud? Tony
|
| | |
Date: 22 Jun 2007 22:39:49
From: Jud McCranie
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
On Sat, 23 Jun 2007 01:59:30 GMT, Tony M <[email protected] > wrote: > A tablebase doesn't store >moves, only positions and a value for the position. It is up to a >program that uses tablebases to generate the moves and figure out what >to do with them. It seems to me that just having whether the position is a win, loss, or draw would help, in the leaf evaluations. Then it could worry about playing it when it gets there. -- Replace you know what by j to email
|
| | | |
Date: 23 Jun 2007 07:08:46
From: Anders Thulin
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
Jud McCranie wrote: > It seems to me that just having whether the position is a win, loss, > or draw would help, in the leaf evaluations. Then it could worry > about playing it when it gets there. There is a 'but' there: the database and the engine has to be in synch. If there are positions rated as win or draw in the database that the engine doesn't agree about, and can't maintain, the database may end up acting like a black hole, dragging the engine into a position it can't handle. (A similar problem exists in Nalimov endgame tables, of course, particularly in drawn situations.) In general, it would be interesting to try to research alternative storage methods. I remember, a long time ago, there was some discussion if it would be practicable to use some kind of classification engine (such as an ANN), but I think it went off on some subtangent. -- Anders Thulin anders*thulin.name http://www.anders.thulin.name/
|
| | | |
Date: 23 Jun 2007 03:14:42
From: Tony M
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
On Fri, 22 Jun 2007 22:39:49 -0400, Jud McCranie <[email protected] > wrote: >On Sat, 23 Jun 2007 01:59:30 GMT, Tony M <[email protected]> wrote: > >> A tablebase doesn't store >>moves, only positions and a value for the position. It is up to a >>program that uses tablebases to generate the moves and figure out what >>to do with them. > >It seems to me that just having whether the position is a win, loss, >or draw would help, in the leaf evaluations. Then it could worry >about playing it when it gets there. That is how bitbases operate, and win/loss/draw information can certainly prove useful in leaf evaluations. A tablebase that stores distance to mate can provide more useful information in certain situations. Take, for example, a position in a KBB vs. KN endgame. Generally, these endgames are a win for the stronger side, but a mate can take as long as 60 or 70 moves (I'm aware of the FIDE 50 move rule, bear with me here). That would be too deep for a search to ferret out. There can be a couple of dozen moves that lead to mate, some to shorter mates, some to longer mates. If a program only knows about wins, losses and draws, how is it to know which of the moves is best, since they all lead to winning positions? If it chooses a move at random, it can get caught in a cycle of moving from one winning position to another, without actually getting closer to mate. This is the type of situation where distance to mate comes in handy. Tony
|
| | | | |
Date: 25 Jun 2007 16:37:50
From: Gian-Carlo Pascutto
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
Tony M wrote: > If a program only knows about wins, losses and draws, how is it to > know which of the moves is best, since they all lead to winning > positions? If it chooses a move at random, it can get caught in a > cycle of moving from one winning position to another, without actually > getting closer to mate. This is the type of situation where distance > to mate comes in handy. The evaluation still works with bitbases and in the majority of practical endgames this is enough to win, particularly if the bitbases cut away any drawing path for the search. -- GCP
|
| | | | |
Date: 22 Jun 2007 23:32:54
From: Jud McCranie
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
On Sat, 23 Jun 2007 03:14:42 GMT, Tony M <[email protected] > wrote: >getting closer to mate. This is the type of situation where distance >to mate comes in handy. I see your point. In some cases just an evaluation would be helpful. In others (hard endgames) it isn't sufficient. -- Replace you know what by j to email
|
|
Date:
From: Martin Brown
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
|
| |
Date: 23 Jun 2007 00:09:54
From: Tony M
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
On Fri, 22 Jun 2007 08:40:14 -0700, tin Brown <
|
| | |
Date: 27 Jun 2007 12:11:33
From: David Richerby
Subject: Re: Shredder tablebases 1/50th the size of compressed Nalimov tablebases?
|
Tony M <[email protected] > wrote: > Shredderbases don't store the distance to mate as Nalimov databases > do, they only tell you whether a position is won, lost or drawn. That isn't enough information on its own: any legal position of KQ vs K (except stalemates and positions where the queen is en prise) is won for the side with the queen. But you need to choose the right sequence of these positions to reach the checkmate. Dave. -- David Richerby Natural Tree (TM): it's like a tree www.chiark.greenend.org.uk/~davidr/ but it's completely natural!
|
|