From: Bryan Comstock
Subject: Problems with LISP program
Date: 
Message-ID: <38F62D5B.9A2DCC40@erc.msstate.edu>
--------------F459FD1EDCAFF9190E4EB9E0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

I don't know how many of you have ever heard of this, but there is this
problem called the farmer, goose, grain and fox problem...The farmer
must get all of his possessions across the river but can't leave the fox
and goose alone nor can he leave the goose and the grain alone... I
wrote the program but I keep getting a bad function error on my first
function call...I'm going to include my code here and if any of you can
see what is wrong help would be much appreciated...The point of the
error is indicated...Please reply to my email address as well as the
newsgroup...Thanks..

(setf side1 '(farmer goose grain fox))
(setf side2 ())
(setf returnval1 ())
(setf returnval2 ())
(setf prevlist ())
(setf goalfnd 'false)
(setf prevstate 'false)
(setf validstate 'false)
(defun main()
 (loop
  (when (= (length side2) 4) (return (setf goalfnd 'true)))

  (if (member 'farmer side1 :test #'equal)
   ((setf returnval1 (create_state side1 side2))            <--------
here is where I get the bad function error
    (setf side1 (first (rest returnval1)))
    (setf side2 (first returnval1)))
   ((setf returnval2 (create_state side2 side1))            <-------- I
suspect I would get one here too
    (setf side2 (first (rest returnval2)))
    (setf side1 (first returnval2))))

 )
 (print 'SIDE1 side1)
 (print 'SIDE2 side2)
 (print 'GOAL 'FOUND)
)

(defun create_state(alist blist)
 (setf temp (list (first alist)))
 (setf size (- (length alist) 1))
 (setf count 0)
 (setf tal (rest alist))
 (loop
  (when (= count size)(return alist))
  (setf temp2 (list (first tal))))
  (setf temp3 (append temp1 temp2))
  (setf validstate check_state(temp3 alist blist))
  (if (equal validstate 'true)
   ((setf temp4 (list (setf blist(append temp3 blist))
        (setf alist(remove temp3 alist
                 :test #'equal))))
    (cons prevlist temp4)
    (return temp4))
   ((setf count (+ count 1))))
  (setf tal (rest tal))
 )
)

(defun check_state(tlist al bl)
 (if (= (length al) 0)
  ((return 'false)))
 (setf t1 (first tlist))
 (setf t2 (second tlist))
 (setf ral (rest al))
 (if (equal t1 (first al))
  ((setf al (remove t1 al)))
  ((check_state tlist ral bl)))
 (if (equal t2 (first al))
  ((setf al (remove t1 al)))
  ((check_state tlist ral bl)))
 (if (equal al '(goose grain))
  ((return 'false)))
 (if (equal al '(grain goose))
  ((return 'false)))
 (if (equal al '(goose fox))
  ((return 'false)))
 (if (equal al '(fox goose))
  ((return 'false)))
 (setf tprev prevlist)
 (loop
  ((when endp tprev)(return 'true))
  (if (equal (first (first tprev)) bl)
   ((return 'false)))
  (if (equal (first (second tprev)) al)
   ((return 'false)))
 )

)





--
Bryan Comstock
MS State University ERC/IDSL
(228) 688-3499
·····@erc.msstate.edu



--------------F459FD1EDCAFF9190E4EB9E0
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit

<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
I don't know how many of you have ever heard of this, but there is this
problem called the farmer, goose, grain and fox problem...The farmer must
get all of his possessions across the river but can't leave the fox and
goose alone nor can he leave the goose and the grain alone... I wrote the
program but I keep getting a bad function error on my first function call...I'm
going to include my code here and if any of you can see what is wrong help
would be much appreciated...The point of the error is indicated...Please
reply to my email address as well as the newsgroup...Thanks..
<p>(setf side1 '(farmer goose grain fox))
<br>(setf side2 ())
<br>(setf returnval1 ())
<br>(setf returnval2 ())
<br>(setf prevlist ())
<br>(setf goalfnd 'false)
<br>(setf prevstate 'false)
<br>(setf validstate 'false)
<br>(defun main()
<br>&nbsp;(loop
<br>&nbsp; (when (= (length side2) 4) (return (setf goalfnd 'true)))
<p>&nbsp; (if (member 'farmer side1 :test #'equal)
<br>&nbsp;&nbsp; ((setf returnval1 (create_state side1 side2))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;-------- here is where I get the bad function error
<br>&nbsp;&nbsp;&nbsp; (setf side1 (first (rest returnval1)))
<br>&nbsp;&nbsp;&nbsp; (setf side2 (first returnval1)))
<br>&nbsp;&nbsp; ((setf returnval2 (create_state side2 side1))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;-------- I suspect I would get one here too
<br>&nbsp;&nbsp;&nbsp; (setf side2 (first (rest returnval2)))
<br>&nbsp;&nbsp;&nbsp; (setf side1 (first returnval2))))
<p>&nbsp;)
<br>&nbsp;(print 'SIDE1 side1)
<br>&nbsp;(print 'SIDE2 side2)
<br>&nbsp;(print 'GOAL 'FOUND)
<br>)
<p>(defun create_state(alist blist)
<br>&nbsp;(setf temp (list (first alist)))
<br>&nbsp;(setf size (- (length alist) 1))
<br>&nbsp;(setf count 0)
<br>&nbsp;(setf tal (rest alist))
<br>&nbsp;(loop
<br>&nbsp; (when (= count size)(return alist))
<br>&nbsp; (setf temp2 (list (first tal))))
<br>&nbsp; (setf temp3 (append temp1 temp2))
<br>&nbsp; (setf validstate check_state(temp3 alist blist))
<br>&nbsp; (if (equal validstate 'true)
<br>&nbsp;&nbsp; ((setf temp4 (list (setf blist(append temp3 blist))
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setf alist(remove temp3
alist
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
:test #'equal))))
<br>&nbsp;&nbsp;&nbsp; (cons prevlist temp4)
<br>&nbsp;&nbsp;&nbsp; (return temp4))
<br>&nbsp;&nbsp; ((setf count (+ count 1))))
<br>&nbsp; (setf tal (rest tal))
<br>&nbsp;)
<br>)
<p>(defun check_state(tlist al bl)
<br>&nbsp;(if (= (length al) 0)
<br>&nbsp; ((return 'false)))
<br>&nbsp;(setf t1 (first tlist))
<br>&nbsp;(setf t2 (second tlist))
<br>&nbsp;(setf ral (rest al))
<br>&nbsp;(if (equal t1 (first al))
<br>&nbsp; ((setf al (remove t1 al)))
<br>&nbsp; ((check_state tlist ral bl)))
<br>&nbsp;(if (equal t2 (first al))
<br>&nbsp; ((setf al (remove t1 al)))
<br>&nbsp; ((check_state tlist ral bl)))
<br>&nbsp;(if (equal al '(goose grain))
<br>&nbsp; ((return 'false)))
<br>&nbsp;(if (equal al '(grain goose))
<br>&nbsp; ((return 'false)))
<br>&nbsp;(if (equal al '(goose fox))
<br>&nbsp; ((return 'false)))
<br>&nbsp;(if (equal al '(fox goose))
<br>&nbsp; ((return 'false)))
<br>&nbsp;(setf tprev prevlist)
<br>&nbsp;(loop
<br>&nbsp; ((when endp tprev)(return 'true))
<br>&nbsp; (if (equal (first (first tprev)) bl)
<br>&nbsp;&nbsp; ((return 'false)))
<br>&nbsp; (if (equal (first (second tprev)) al)
<br>&nbsp;&nbsp; ((return 'false)))
<br>&nbsp;)
<p>)
<br>&nbsp;
<br>&nbsp;
<p>&nbsp;
<pre>--&nbsp;
Bryan Comstock
MS State University ERC/IDSL
(228) 688-3499
·····@erc.msstate.edu</pre>
&nbsp;</html>

--------------F459FD1EDCAFF9190E4EB9E0--

From: Barry Margolin
Subject: Re: Problems with LISP program
Date: 
Message-ID: <q0rJ4.37$b62.1787@burlma1-snr2>
In article <·················@erc.msstate.edu>,
Bryan Comstock  <·····@erc.msstate.edu> wrote:
>(defun main()
> (loop
>  (when (= (length side2) 4) (return (setf goalfnd 'true)))
>
>  (if (member 'farmer side1 :test #'equal)
>   ((setf returnval1 (create_state side1 side2))            <--------
>here is where I get the bad function error
>    (setf side1 (first (rest returnval1)))
>    (setf side2 (first returnval1)))

The syntax of IF is:

(if <test-expression> <then-expression> <else-expression>)

If an expression is a list, it's an invocation of a function, macro, or
special operator, which should be either:

(<operator-name> <args>)

or

((lambda ...) <args>)

In the place where you should have an operator name, you have the list
(setf returnval1 (create_state side1 side2)), which is not the name of an
operator.

If you want an expression to execute several expressions as a unit, you
should use PROGN, i.e.

  (if (member 'farmer side1 :test #'equal)
      (progn
	(setf returnval1 (create_state side1 side2))
	(setf side1 (first (rest returnval1)))
	(setf side2 (first returnval1)))
      ...

Just collecting a bunch of expressions into a list is not the way to do it.

In your particular case, another way to handle it is to combine all the
SETFs into a single expression, since SETF allows multiple assignments:

  (if (member 'farmer side1 :test #'equal)
      (setf returnval1 (create_state side1 side2)
	    side1 (first (rest returnval1))
	    side2 (first returnval1)))

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Thomas A. Russ
Subject: Re: Problems with LISP program
Date: 
Message-ID: <ymivh1lu2b6.fsf@sevak.isi.edu>
Bryan Comstock <·····@erc.msstate.edu> writes:

> (setf side1 '(farmer goose grain fox))
> (setf side2 ())
> (setf returnval1 ())
> (setf returnval2 ())
> (setf prevlist ())
> (setf goalfnd 'false)
> (setf prevstate 'false)
> (setf validstate 'false)
> (defun main()
>  (loop
>   (when (= (length side2) 4) (return (setf goalfnd 'true)))
> 
>   (if (member 'farmer side1 :test #'equal)
>    ((setf returnval1 (create_state side1 side2))            <--------

That is because the first element of this list is
   (setf returnval1 (create_state side1 side2))
which is not a function object.

In Common Lisp, you cannot group a set of statements together inside
parentheses and have that work.  The form needs to be headed by PROGN in
order for things to work the way that you expect.

The other alternative to using IF and PROGN would be to use COND.

> here is where I get the bad function error
>     (setf side1 (first (rest returnval1)))
>     (setf side2 (first returnval1)))
>    ((setf returnval2 (create_state side2 side1))            <-------- I
> suspect I would get one here too

Yes.

>     (setf side2 (first (rest returnval2)))
>     (setf side1 (first returnval2))))
> 
>  )
>  (print 'SIDE1 side1)
>  (print 'SIDE2 side2)
>  (print 'GOAL 'FOUND)
> )
> 

This function doesn't seem to have its parentheses balanced properly.
The line with "(setf temp2 ..." closes (loop.

> (defun create_state(alist blist)
>  (setf temp (list (first alist)))
         ^^^^
This variable doesn't appear to be used anywhere.

>  (setf size (- (length alist) 1))
>  (setf count 0)
>  (setf tal (rest alist))
>  (loop
>   (when (= count size)(return alist))
>   (setf temp2 (list (first tal))))
>   (setf temp3 (append temp1 temp2))
>   (setf validstate check_state(temp3 alist blist))
>   (if (equal validstate 'true)
>    ((setf temp4 (list (setf blist(append temp3 blist))
>         (setf alist(remove temp3 alist
>                  :test #'equal))))
>     (cons prevlist temp4)
>     (return temp4))
>    ((setf count (+ count 1))))

and here

>   (setf tal (rest tal))
>  )
> )

A few other observations, mostly stylistic:

(1)  There are way, way too many global variables being used here.  You
     need to look at using LET in order to introduce local variables.
     Otherwise something will bite you eventually.

(2)  You probably don't need to use as many variables as you do anyway.
     In most cases, you should be able to accomplish the same results
     by nesting calls instead of introducing the variables.

(3)  Normally, Lisp code uses "-" as the word separator rather than
     "_".  This is purely stylistic, but it makes things easier to type
     since you don't need the shift key.

(4)  The calls to MEMBER and REMOVE don't need to specify the test,
     since you don't really need an EQUAL test between the elements.
The default test of EQL should do fine -- you're just checking symbols
against symbols and not comparing lists directly.


-- 
Thomas A. Russ,  USC/Information Sciences Institute          ···@isi.edu