You certainly can change global variables from inside functions:
[1]> (defparameter *visited-lists* nil)
*VISITED-LISTS*
[2]> *visited-lists*
NIL
[3]> (defun change-global-value ()
(setf *visited-lists* (append (list 'new-value)
*visited-lists* )))
CHANGE-GLOBAL-VALUE
[4]> *visited-lists*
NIL
[5]> (change-global-value)
(NEW-VALUE)
[6]> *visited-lists*
(NEW-VALUE)
[7]> (change-global-value)
(NEW-VALUE NEW-VALUE)
[8]> *visited-lists*
(NEW-VALUE NEW-VALUE)
But let's look at your code some more:
(defun bfs-core(node-list)
(let (cur-node tmp-node-list)
(if (null node-list)
NIL
(progn
; (if (= 1 (length node-list))
(setq cur-node (car node-list))
(setq tmp-node-list (cdr node-list))
(if (goalp cur-node)
cur-node
((setq *vlist* (append cur-node *vlist*))
(bfs-core (append tmp-node-list (expand cur-node))))))
)
)
)
First, let's get closing parentheses on the correct lines, and remove the commented-out code. Most Lisp coders don't close their parens like braces in an ALGOL-style language:
(defun bfs-core(node-list)
(let (cur-node tmp-node-list)
(if (null node-list)
NIL
(progn
(setq cur-node (car node-list))
(setq tmp-node-list (cdr node-list))
(if (goalp cur-node)
cur-node
((setq *vlist* (append cur-node *vlist*))
(bfs-core (append tmp-node-list (expand cur-node)))))))))
Now, we have a nil for the first branch of an if. We can change it to unless, which has a built-in progn, so we don't need that either:
(defun bfs-core(node-list)
(let (cur-node tmp-node-list)
(unless (null node-list) ;;changed this line to an unless, dropped nil, progn
(setq cur-node (car node-list))
(setq tmp-node-list (cdr node-list))
(if (goalp cur-node)
cur-node
((setq *vlist* (append cur-node *vlist*))
(bfs-core (append tmp-node-list (expand cur-node))))))))
We're also using a let to set some variables to nil, and when we get inside the unless, we immediately set the variables to the values we actually want to work with. Let's switch it so that we only create the variables if we're going to use them:
(defun bfs-core(node-list)
(unless (null node-list) ;;switched this line and the let below
(let ((cur-node (car node-list)) ;;also set the variables inside the let
(tmp-node-list) (cdr node-list))
(if (goalp cur-node)
cur-node
((setq *vlist* (append cur-node *vlist*))
(bfs-core (append tmp-node-list (expand cur-node))))))))
Ok, we're already at much cleaner code. Yay!
Let's look at one of the calls here:
((setq *vlist* (append cur-node *vlist*))
(bfs-core (append tmp-node-list (expand cur-node))))
Did you mean to put this as a single call, and not two? There's a difference between that and this:
((setq *vlist* (append cur-node *vlist*)))
(bfs-core (append tmp-node-list (expand cur-node)))
Do you see the difference? The first is a single statement; the second is two. You probably want the second, as you want to change *vlist*, then call bfs-core. And, to do that, you'll need progn:
(defun bfs-core(node-list)
(unless (null node-list)
(let ((cur-node (car node-list))
(tmp-node-list) (cdr node-list))
(if (goalp cur-node)
cur-node
(progn (setq *vlist* (append cur-node *vlist*))
(bfs-core (append tmp-node-list (expand cur-node))))))))
*vlist*usingsetq. It's(setq *vlist* (append cur-node *vlist*). It's not clear what you're asking. Your syntax isn't right, though.ifshould look like(if (goalp cur-node) cur-node (progn (setq ...) (bfs-core ...))).