chapter 7 Land of lisp

107 views
Skip to first unread message

Guillo

unread,
May 15, 2012, 10:17:29 AM5/15/12
to Land of Lisp
Hello all, I have been working on the book Land of Lisp and running
into some problems on chapter 7. After writing the following code:
(defparameter *wizard-nodes* '((living-room (you are in the
the living-room. a wizard is snoring loudly on the couch.))
(garden (you are in a beautiful garden. there is a well in front
of you.))
(attic (you are in the attic. there is a giant welding torch in the
corner.))))
;; wizard edges
(defparameter *wizard-edges* '((living-room (garden west door) (attic
upstairs ladder))
(garden (living-room east door))
(attic ( living-room downstairs ladder))))
;; covering node identifiers

(defun dot-name (exp)
(substitute-if #\_ (complement #' alphanumericp) (prin1-to-string
exp)))
;; adding labels to graph nodes
(defparameter *max-label-length* 30)
(defun dot-label (exp)
(if exp
(let ((s (write-to-string exp :pretty nil)))
(if (> (length s) *max-label-length*)
(concatenate 'string (subseq s 0 (- *max-label-length* 3)) "...")
s))
""))
;; generating the dot information for the
;; nodes
(defun nodes->dot (nodes)
(mapc (lambda (node)
(fresh-line)
(princ (dot-name (car node)))
(princ "[label=\"")
(princ (dot-label node))
(princ "\"];"))
nodes))
;; testing the above code
(nodes->dot *wizard-nodes*)
;;converting edges into DOT format

(defun edges->dot (edges)
(mapc (lambda (node)
(mapc (lambda (edge)
(fresh-line)
(princ (dot-name (car node)))
(princ "->")
(princ (dot-name (car edge)))
(princ "label=\"")
(princ (dot-label (cdr edge) ))
(princ "\"];"))
(cdr node)))
edges))
(edges->dot *wizard-edges*)
;;generating all the dot format

(defun graph->dot (nodes edges)
(princ "digraph{")
(nodes->dot nodes)
(edges->dot edges)
(princ "}" ))
(graph->dot *wizard-nodes* *wizard-edges*)
;;turning the DOT FILE into a picture
(defun dot->png (fname thunk)
(with-open-file (*standard-output*
fname
:direction :output
:if-exists :supersede)
(funcall thunk))
(ext:shell (concatenate 'string "dot -Tpng -O " fname)))
;; capturing the consoles output
;;finally creating a pictire of our graph
(defun graph->png (fname nodes edges)
(dot->png fname
(lambda ()
(graph->dot nodes edges))))
(graph->png "wizard.dot" *wizard-nodes* *wizard-edges*)

I get an error saying:
Error: wizard.dot:5: syntax error near line 5
context: >>> LIVING_ROOM->GARDENlabel= <<< "(WEST DOOR)"];
24
I really can't figure out what this means.I'm new to Lisp and don't
understand why this is an error. This code is directly from the book.

Ciaran Bradley

unread,
May 15, 2012, 11:05:13 AM5/15/12
to land-o...@googlegroups.com
In your code for the "edges->dot" function, you need to open a bracket in the label so that it outputs "[label=etc".  So you should write (princ "[label=\"").  Currently, you have (princ "label=\"") which is incorrect.

Guillermo Ithier

unread,
May 16, 2012, 8:26:10 AM5/16/12
to land-o...@googlegroups.com

Thankyou so much Ciaran for finding that typo in my code. It finally compiles but now it keeps saying "nil". Where as I suppose to get a graph form the graphiz software I'm using. This is my first time using graphiz and am not knowledgeable in using external software in CLISP. Can can someone give me some advice on how to make the graphviz software work with CLISP in this example?

Ciaran Bradley

unread,
May 16, 2012, 9:42:00 AM5/16/12
to land-o...@googlegroups.com
The code uses side effects to work.  So it will very often do it's stuff correctly then return "nil". 

To debug, be clear on what the code is doing.  There are three tasks.  The first few functions print the nodes and edges in a format readable to graphviz.  Then the "dot->png" has two operations.  It creates a "dot" file which the can be turned into a png using graphviz.  Then it calls Graphviz to convert the "dot" file into a "png" file.
 
Firstly, check if there is a png file in the folder?  If it's there, the code worked.

If there isn't a png, is there a "wizard.dot" file?  If there's a dot file the code worked up until the last line of the "dot->png" function.  (Is graphviz installed correctly?) (Can you call graphviz from your normal command line and turn the dot file into a png?)

If there isn't a dot or png file in your folder, then the code is failing much earlier.  To test it, take each function and run it in your REPL.  For 
example, type in:

(dot-name "foobar")
(dot-label "writinglotsinheretotakeitpast30asthatisthemaxlabelsize")
(nodes->dot *nodes*)
(edges->dot *edges*)
...etc

Do you get back what you expect from each function?  It should become apparent that one of them is not working as expected. 

Happy bug hunting :)



Check in the folder to see whether you have a png file in there.  If not, do you have a "dot" file there?  
Reply all
Reply to author
Forward
0 new messages