From: cdombroski
Subject: -2 is not a real number?!?
Date: 
Message-ID: <pan.2007.02.27.23.07.23.796875@icanttype.org>
I'm currently working on a class project in Lisp, and I've run into a
problem. I'm trying to write a tic-tac-toe program that uses alpha-beta
searching for an AI player. Whenever the AI takes a turn the program blows
up saying that a particular variable is "not a real number". Further
proding shows that the variable is an integer whose value is -2 

As this class is my first experience in Lisp, I'm at a loss of what the
problem could be. I tried emailing the teacher and didn't get very far.

Here's the function where the error occurs and the GNU CLISP interpreter
output of the error:

(defun min-value(turns turn alpha beta)
  (let ((v most-positive-fixnum)
	(best-move -1))
    (if (evaluate turns)
      (return-from min-value (list (evaluate turns))))
    (dolist (x (find-moves))
      (setf (aref *board* (floor x 3) (mod x 3)) (if turn "X" "O"))
      (setf v (min v (car (max-value (+ turns 1) (not turn) alpha beta))))
      (setf (aref *board* (floor x 3) (mod x 3)) " ")
      (if (<= v alpha) (return-from min-value '(v x)))
      (setf beta (min v beta)))
    (return-from min-value (list v best-move))))


*** - MIN: V is not a real number
The following restarts are available:
USE-VALUE      :R1      You may input a value to be used instead.
ABORT          :R2      ABORT
Break 1 [3]> v
-2
Break 1 [3]> (type-of v)
(INTEGER -16777216 (0))
Break 1 [3]>

I'm willing to post or email the rest of the code if necessary, I just
didn't want to possibly annoy somebody by posting the entire thing if not
needed/wanted. 

From: Mattias Nilsson
Subject: Re: -2 is not a real number?!?
Date: 
Message-ID: <1172618527.057042.177990@p10g2000cwp.googlegroups.com>
On Feb 28, 12:07 am, cdombroski <··········@icanttype.org> wrote:

> *** - MIN: V is not a real number

Well, it is. If you use roman numerals. And so is X.

(There's a hint in there...)

Mattias
From: ·······@gmail.com
Subject: Re: -2 is not a real number?!?
Date: 
Message-ID: <1172618783.163511.224930@m58g2000cwm.googlegroups.com>
cdombroski wrote:

> GNU CLISP interpreter

There's also a compiler in there, BTW... :)

>       (if (<= v alpha) (return-from min-value '(v x)))

Without looking at the rest of the code this is most likely not what
you want - you're returning a literal value which is a list consisting
of the symbols V and X.  I think you want (LIST V X) instead.

> *** - MIN: V is not a real number

Note that it says that (the symbol) V is not a real number.  It
doesn't say that -2 is not a real number as in your subject line.

HTH,
Edi.
From: Chris Dombroski
Subject: Re: -2 is not a real number?!?
Date: 
Message-ID: <pan.2007.02.27.23.58.02.0@icanttype.org>
On Tue, 27 Feb 2007 15:26:23 -0800, nhabedi wrote:

> cdombroski wrote:
> 
>> GNU CLISP interpreter
> 
> There's also a compiler in there, BTW... :)
> 
>>       (if (<= v alpha) (return-from min-value '(v x)))
> 
> Without looking at the rest of the code this is most likely not what
> you want - you're returning a literal value which is a list consisting
> of the symbols V and X.  I think you want (LIST V X) instead.
> 


You're correct, that is what I needed to change. Hopefully I can figure
out the new error that I get without help.

Thanks for your help.
From: Ken Tilton
Subject: Re: -2 is not a real number?!?
Date: 
Message-ID: <GE4Fh.52$gh2.9@newsfe12.lga>
cdombroski wrote:
> I'm currently working on a class project in Lisp, and I've run into a
> problem. I'm trying to write a tic-tac-toe program that uses alpha-beta
> searching for an AI player. Whenever the AI takes a turn the program blows
> up saying that a particular variable is "not a real number". Further
> proding shows that the variable is an integer whose value is -2 
> 
> As this class is my first experience in Lisp, I'm at a loss of what the
> problem could be. I tried emailing the teacher and didn't get very far.
> 
> Here's the function where the error occurs and the GNU CLISP interpreter
> output of the error:
> 
> (defun min-value(turns turn alpha beta)
>   (let ((v most-positive-fixnum)
> 	(best-move -1))
>     (if (evaluate turns)
>       (return-from min-value (list (evaluate turns))))
>     (dolist (x (find-moves))
>       (setf (aref *board* (floor x 3) (mod x 3)) (if turn "X" "O"))
>       (setf v (min v (car (max-value (+ turns 1) (not turn) alpha beta))))
>       (setf (aref *board* (floor x 3) (mod x 3)) " ")
>       (if (<= v alpha) (return-from min-value '(v x)))

Ah, one of my favorite rants! It's not your fault. You have been 
sandbagged by introductory Lisp texts, which like to use the very 
convenient notation '(1 2) to avoid the more verbose (list 1 2), but 
neglect to make clear they are using the equivalent of (quote (1 2)), 
and the whole story of what quote does, namely take (let ((x 42)) '(x)) 
and return a list of the symbol x.

hth, kt


-- 
Well, I've wrestled with reality for 35 years, Doctor, and
I'm happy to state I finally won out over it.
                                   -- Elwood P. Dowd

In this world, you must be oh so smart or oh so pleasant.
                                   -- Elwood's Mom
From: ···············@yahoo.com
Subject: Re: -2 is not a real number?!?
Date: 
Message-ID: <1172683718.844250.193560@h3g2000cwc.googlegroups.com>
Other posters have explained the problem with v.  But this is good
code for a (relative?) beginner.  I thought I'd suggest a few changes
to the style.

(defun min-value (turns turn alpha beta)
  (let ((v most-positive-fixnum)
        (best-move -1))
    (if (evaluate turns)
        (list (evaluate turns))
      (dolist (x (find-moves) (list v best-move))
        (setf (aref *board* (floor x 3) (mod x 3)) (if turn "X" "O"))
        (setf v (min v (car (max-value (+ turns 1) (not turn) alpha
beta))))
        (setf (aref *board* (floor x 3) (mod x 3)) " ")
        (when (<= v alpha) (return-from min-value (list v x)))
        (setf beta (min v beta))))))

For a better "functional" style, avoid return-from.  I got rid of the
first return-from using the full meaning of "if": the else clause
returns the value of the dolist.  I got rid of the third return-from
by putting what you're returning into the third position of the
initial form of the dolist.

"when" is good for ifs that only have a then-clause.  See also
"unless".

Most important, the two calls to (evaluate turns) are dangerous.  The
first call may take a long time, and it all has to be repeated in
order to return (list [same thing]).  You might want to say

(let ((ev-turns (evaluate turns)))
  (if ev-turns
      (list ev-turns)
    [the rest, starting with (let ((v ...)))]))

For another approach, see "anaphoric if" in Paul Graham's book _On
Lisp_ (available in pdf by Googling).
From: Ken Tilton
Subject: Re: -2 is not a real number?!?
Date: 
Message-ID: <ktlFh.26$XI4.11@newsfe12.lga>
···············@yahoo.com wrote:
> Other posters have explained the problem with v.  But this is good
> code for a (relative?) beginner.  I thought I'd suggest a few changes
> to the style.
> 
> (defun min-value (turns turn alpha beta)
>   (let ((v most-positive-fixnum)
>         (best-move -1))
>     (if (evaluate turns)
>         (list (evaluate turns))

Can't we just add BIF to the standard?

        (bif (et (evaluate turns))
             (list et)
           ....

(defmacro bif ((bindvar boundform) yup &optional nope)
   `(let ((,bindvar ,boundform))
       (if ,bindvar
          ,yup
          ,nope)))


Or PGs AIF:

         (aif (evaluate turns)
             (list it)....


kt

>       (dolist (x (find-moves) (list v best-move))
>         (setf (aref *board* (floor x 3) (mod x 3)) (if turn "X" "O"))
>         (setf v (min v (car (max-value (+ turns 1) (not turn) alpha
> beta))))
>         (setf (aref *board* (floor x 3) (mod x 3)) " ")
>         (when (<= v alpha) (return-from min-value (list v x)))
>         (setf beta (min v beta))))))
> 
> For a better "functional" style, avoid return-from.  I got rid of the
> first return-from using the full meaning of "if": the else clause
> returns the value of the dolist.  I got rid of the third return-from
> by putting what you're returning into the third position of the
> initial form of the dolist.
> 
> "when" is good for ifs that only have a then-clause.  See also
> "unless".
> 
> Most important, the two calls to (evaluate turns) are dangerous.  The
> first call may take a long time, and it all has to be repeated in
> order to return (list [same thing]).  You might want to say
> 
> (let ((ev-turns (evaluate turns)))
>   (if ev-turns
>       (list ev-turns)
>     [the rest, starting with (let ((v ...)))]))
> 
> For another approach, see "anaphoric if" in Paul Graham's book _On
> Lisp_ (available in pdf by Googling).
> 

-- 
Well, I've wrestled with reality for 35 years, Doctor, and
I'm happy to state I finally won out over it.
                                   -- Elwood P. Dowd

In this world, you must be oh so smart or oh so pleasant.
                                   -- Elwood's Mom
From: Chris Dombroski
Subject: Re: -2 is not a real number?!?
Date: 
Message-ID: <pan.2007.02.28.22.19.34.31250@icanttype.org>
On Wed, 28 Feb 2007 09:28:38 -0800, mmcconnell17704 wrote:

> Other posters have explained the problem with v.  But this is good
> code for a (relative?) beginner.  I thought I'd suggest a few changes
> to the style.

Yep. (let (me total-noob))

> 
> (defun min-value (turns turn alpha beta)
>   (let ((v most-positive-fixnum)
>         (best-move -1))
>     (if (evaluate turns)
>         (list (evaluate turns))
>       (dolist (x (find-moves) (list v best-move))
>         (setf (aref *board* (floor x 3) (mod x 3)) (if turn "X" "O"))
>         (setf v (min v (car (max-value (+ turns 1) (not turn) alpha
> beta))))
>         (setf (aref *board* (floor x 3) (mod x 3)) " ")
>         (when (<= v alpha) (return-from min-value (list v x)))
>         (setf beta (min v beta))))))
> 
> For a better "functional" style, avoid return-from.  I got rid of the
> first return-from using the full meaning of "if": the else clause
> returns the value of the dolist.  I got rid of the third return-from
> by putting what you're returning into the third position of the
> initial form of the dolist.
> 
> "when" is good for ifs that only have a then-clause.  See also
> "unless".

I'm more used to c style programming, although they say that multiple exit
points are bad there too...
More to the point it took me awhile to figure out that progn is necessary
to execute more than one statement in a then/else block. I'm still not
entirely used to the last statement executed is the value returned stuff.

> 
> Most important, the two calls to (evaluate turns) are dangerous.  The
> first call may take a long time, and it all has to be repeated in
> order to return (list [same thing]).  You might want to say
> 
> (let ((ev-turns (evaluate turns)))
>   (if ev-turns
>       (list ev-turns)
>     [the rest, starting with (let ((v ...)))]))
> 
> For another approach, see "anaphoric if" in Paul Graham's book _On
> Lisp_ (available in pdf by Googling).

This I was somewhat aware of, but evaluate shouldn't be too expensive.
When I changed the (setf v (min v (car .... line to be an 'if' instead of
'min' (because I realized I needed to set two values if the current v was
larger than the returned value) I did use a temporary variable to hold the
value because {max,min}-value together form a recursive function of sorts.

Just to update the general situation, I did get the program running more
or less correctly. It plays without crashing and the AI will block you
from winning, but when I was playing with it I got it to where the AI
should have won but didn't. I'll probably have to trace through it or
print out some debugging information to find out why. Thanks again
everybody for the helpful and timely suggestions.