Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: Symbolic: code example

Author: Steven Edwards

Date: 10:05:57 01/22/04

Go up one level in this thread


On January 22, 2004 at 11:52:47, Tord Romstad wrote:
>On January 22, 2004 at 10:03:55, Steven Edwards wrote:
>
>>Here's some example code for the ChessLisp intepreter in my program Symbolic:
>>
>>;;;; emp.lsp: Enumerate movepaths
>>
>>(defun emp (theFEN theDepth)
>> "Enumerate distinct movepaths from a FEN string to a depth"
>> (cond
>>  ((not (string? theFEN))
>>    "Error: first argument must be a FEN string")
>>  ((not (and (integer? theDepth) (nonnegative? theDepth)))
>>    "Error: second argument must be a nonnegative integer")
>>  (t
>>   (let ((thePos (PosFromFEN theFEN)))
>>    (if (null? thePos)
>>     "Error: invalid position"
>>     (emp-aux thePos theDepth))))))
>>
>>(defun emp-aux (thePos theDepth)
>> "Enumerate distinct movepaths from a position to a depth"
>> (cond
>>  ((= theDepth 0) 1)
>>  ((= theDepth 1) (length (Generate thePos)))
>>  (t
>>   (let ((theSum 0) (theEnv nil) (theMove nil) (theML (Generate thePos)))
>>    (dolist (theMove theML)
>>     (Execute theMove thePos theEnv)
>>     (incf theSum (emp-aux thePos (1- theDepth)))
>>     (Retract theMove thePos theEnv))
>>    theSum))))
>
>From the code above, it looks like you generate moves into a list rather
>than an array.  Isn't this terribly slow?  And another question:  What
>is the purpose of the (theMove nil) in the LET bindings of the EMP-AUX
>function?  Is this necessary because of some quirk in your Lisp dialect?

1. Generating moves into a list is done by the C++ routines and is quite fast.
Also, a list representation of moves enables writing a tail recursive verion of
the abve routine if needed.  I can always write a GenerateArray intrinsic if the
need arises.

I have not made any attempts to optimize the interpreter speed except for
consing and garbage collecting (these it does quite quickly).  Creating a new
lexical closure at the present requires a call to the C++ new() routine, so this
will be a target for optimization aftter I do more work on implementing the
remainder of the function intrinsics.

2. Adding the binding for theMove (and also theEnv) in the let variable list is
a stylism of mine and not strictly necessary.

>Otherwise, the code looks straighforward and clean.  I personally detest
>the convention of using question marks to denote predicates, but that's
>of course a matter of taste.

Most predicates in my ChessLisp come in -p and -? forms.  The former are used
when porting Common Lisp routines for testing and the latter are my preference
for coding.

One of the planned features of the system is the ability to answer natural
language questions about its chess environment much like Winograd's Blocks
World.  I have even included a speak intrinsic function for voice synthesis.
The idea is that the program can explain, in real time, its search process.  For
even better debugging, a "movie" (QuickTime, perhaps) with text/voice and chess
position diagrams can be be constructed during a search and then replayed
afterwards.

There is still a long road to be travelled.  In fact, the further I go on the
road, the longer it seems to be!  It could be months before I get to the point
of actually writing the highest level analysis and planning code.  As to the
strength of the final system, well, that remains to be seen.  But one thing is
sure: the result is not going to be a just another big tree a/b search program.



This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.