Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: Symbolic: ChessLisp (Part I)

Author: Steven Edwards

Date: 02:15:15 02/18/04

Go up one level in this thread


On February 17, 2004 at 17:01:49, Gerd Isenberg wrote:
>On February 17, 2004 at 15:13:02, Steven Edwards wrote:

>Even i'm not familar with Lisp, i like your high abstraction level
>approach with performant chess intrinsics.

Thank you.

I first learned about Lisp back around 1970 from a book by Jean Sammet on
programming languages; I was not quite a teenager at the time.  I have written
lotsa Lisp over the years plus an interpreter.  And still I am sometimes
mystitfied by others' Lisp code.  Particularly if said code has tricky nested
defmacro forms.

>The bitboard intrinsics (BBAtkFrSq BBAtkToSq) imply a rotated bitboard
>implementation, i guess. Or do you hide the bitboard implementation at all?
>Do you consider setwise attack generation with Kogge Stone Fill algorithm?

Some of the BB intrinsics are in ChessLisp solely for testing purposes; all of
the usual low level BB code found in a BB program is hidden away in the
underlying toolkit.  ChessLisp BB intrincs like BBAtkToSq take a Position symbol
as their first argument and pull the selected BB value by appropriately
dereferencing the BB database structure associated with the pointer stored in
the atom that is the value of the position symbol.  The bitboard database
associated with a position symbol that is attached to a node (via the Position
property) is produced at the time of node creation and its values do not change.

A single BB value is contained in a Lisp atom as a 64 bit integer.  A ChessLisp
BB atom is a typed value (and is not a Lisp number), so it is used with
intrinsics like BBNot, BBAnd, BBXor, etc.  The intrinsics lognot, logand,
logxor, etc., are also present and do the same operations on 64  bit integer
value atoms; however, they are not used for BB work.  This retains the type
safety features of ChessLisp and encourages better Lisp programming style.

Example:

Lisp: InitialFEN
"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"

Lisp: (PosFromFEN InitialFEN)
Pos0

Lisp: (symbol-plist 'Pos0)
(ActiveColor #<Color White> ActiveMaterial #<Score +40.160> Cstl #<Cstl KQkq>
EnPassantSq nil EnvValStack nil Evaluation #<Score NegInf> HalfMoveClock 0
IsCheckmate nil IsStalemate nil MainHash #<Hash 893b42c4bcfb0cbc> Material
#<Score Even> MoveNumber 1 MoveValStack nil Ord 0 PassiveColor #<Color Black>
PassiveMaterial #<Score +40.160> PawnHash #<Hash a782b164eeb612b3>)

Lisp: (BBAtkToSq 'Pos0 SqD2)
#<BB 0111100000000000000000000000000000000000000000000000000000000000>

Lisp: (SqListFromBB (BBAtkToSq 'Pos0 SqD2))
(#<Sq b1> #<Sq c1> #<Sq d1> #<Sq e1>)

Lisp: (BBAtkByColor 'Pos0 Black)
#<BB 0000000000000000000000000000000000000000111111111111111101111110>

Lisp: (SqListFromBB (BBAtkByColor 'Pos0 Black))
(#<Sq a6> #<Sq b6> #<Sq c6> #<Sq d6> #<Sq e6> #<Sq f6> #<Sq g6> #<Sq h6> #<Sq
a7> #<Sq b7> #<Sq c7> #<Sq d7> #<Sq e7> #<Sq f7> #<Sq g7> #<Sq h7> #<Sq b8> #<Sq
c8> #<Sq d8> #<Sq e8> #<Sq f8> #<Sq g8>)

Lisp: (SqListFromBB (BBAnd (BBAtkByColor 'Pos0 White) (BBLocByColor 'Pos0
White)))
(#<Sq b1> #<Sq c1> #<Sq d1> #<Sq e1> #<Sq f1> #<Sq g1> #<Sq a2> #<Sq b2> #<Sq
c2> #<Sq d2> #<Sq e2> #<Sq f2> #<Sq g2> #<Sq h2>)

Lisp: (SqListFromBB (BBAnd (BBNot (BBAtkByColor 'Pos0 White)) (BBLocByColor
'Pos0 White)))
(#<Sq a1> #<Sq h1>)

Lisp: (BBMerge 'Pos0)
#<BB 1111111111111111000000000000000000000000000000001111111111111111>

Lisp:  (SqListFromBB (BBMerge 'Pos0))
(#<Sq a1> #<Sq b1> #<Sq c1> #<Sq d1> #<Sq e1> #<Sq f1> #<Sq g1> #<Sq h1> #<Sq
a2> #<Sq b2> #<Sq c2> #<Sq d2> #<Sq e2> #<Sq f2> #<Sq g2> #<Sq h2> #<Sq a7> #<Sq
b7> #<Sq c7> #<Sq d7> #<Sq e7> #<Sq f7> #<Sq g7> #<Sq h7> #<Sq a8> #<Sq b8> #<Sq
c8> #<Sq d8> #<Sq e8> #<Sq f8> #<Sq g8> #<Sq h8>)

Lisp: (length (SqListFromBB (BBMerge 'Pos0)))
32

Lisp: (CardOfBB (BBMerge 'Pos0))
32

Lisp: (format nil "%c" (CardOfBB (BBMerge 'Pos0)))
"thirty-two"

>For performance reasons i use node related memory for eval and (pre-)movegen
>purposes with limited validity until expansion, shared by all nodes. They got
>initialized shortly after a node is entered but not restored in unmake.
>How does your Lisp approach handles such node state related validity (if any)
>during search?

In ChessLisp, there are the Tree and Node chesstypes.  A tree, and there may be
more than one, can be made by the TreeFromFEN intrinsic function.  Each tree
symbol has a RootNode property which is the node symbol produced by genertating
the tree.  All other node symbols are manufactured by the intrinsic function
ExpandNode which produces all the subnodes from the supplied node.  No illegal
nodes are ever gererated.  The tree symbol and all the node symbols hang around
for the entire search, at least for now.  So there is currenly no need for using
the Generate/Execute/Retract trio for either building or moving around in the
tree.



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.