1 (in-package #:clnl-nvm)
3 ; Implementations of all the things the nvm can do.
10 VALUE: a NetLogo value
15 A command that prints the given NetLogo value to the command center.
17 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#show"
18 (format t "Showing: ~A~%" (dump-object value)))
20 (defun lookup-color (color)
21 "LOOKUP-COLOR COLOR => COLOR-NUMBER
25 COLOR: a symbol representing a color
26 COLOR-NUMBER: the NetLogo color integer
30 Returns the number used to represent colors in NetLogo.
32 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#Constants"
51 (defun create-turtle (breed &optional base-turtle)
53 ((breed (or breed (and base-turtle (turtle-breed base-turtle)) :turtles))
54 (new-turtle (make-turtle
55 :who (coerce *current-id* 'double-float)
56 :color (if base-turtle
57 (turtle-color base-turtle)
58 (coerce (+ 5 (* 10 (clnl-random:next-int 14))) 'double-float))
59 :heading (if base-turtle
60 (turtle-heading base-turtle)
61 (coerce (clnl-random:next-int 360) 'double-float))
63 :shape (breed-default-shape breed)
64 :xcor (if base-turtle (turtle-xcor base-turtle) 0d0)
65 :ycor (if base-turtle (turtle-ycor base-turtle) 0d0))))
67 ((patch (patch-at (turtle-xcor new-turtle) (turtle-ycor new-turtle))))
68 (setf (patch-turtles patch) (nconc (patch-turtles patch) (list new-turtle))))
69 (setf *turtles* (nconc *turtles* (list new-turtle)))
78 RESULT: undefined, commands don't return
82 The turtle or link dies
84 A dead agent ceases to exist. The effects of this include:
85 - The agent will not execute any further code.
86 - The agent will disappear from any agentsets it was in, reducing the size of those agentsets by one.
87 - Any variable that was storing the agent will now instead have nobody in it.
88 - If the dead agent was a turtle, every link connected to it also dies.
89 - If the observer was watching or following the agent, the observer's perspective resets.
91 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#die"
92 (when (not (turtle-p *self*)) (error "Gotta call die in turtle scope, dude (~A)" *self*))
93 (setf (turtle-who *self*) -1)
94 (setf *turtles* (remove *self* *turtles*))
95 (error (make-condition 'stop)))
98 "PATCHES => ALL-PATCHES
100 ARGUMENTS AND VALUES:
102 ALL-PATCHES: a NetLogo agentset, all patches
106 Reports the agentset consisting of all the patches.
108 This agentset is special in that it represents the living patches
109 each time it's used, so changes depending on the state of the engine.
111 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#patches"
115 "TURTLES => ALL-TURTLES
117 ARGUMENTS AND VALUES:
119 ALL-TURTLES: a NetLogo agentset, all turtles
123 Reports the agentset consisting of all the turtles.
125 This agentset is special in that it represents the living turtles
126 each time it's used, so changes depending on the state of the engine.
128 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#turtles"
131 (defun turtles-here (&optional breed)
132 "TURTLES-HERE => TURTLES
134 ARGUMENTS AND VALUES:
140 Returns the agentset consisting of all the turtles sharing the patch
141 with the agent in by *self*
143 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#turtles-here"
144 (when (not (turtle-p *self*)) (error "Gotta call turtles-here with a turtle"))
146 ((patch-turtles (patch-turtles (patch-at (turtle-xcor *self*) (turtle-ycor *self*)))))
148 (if breed (remove breed patch-turtles :key #'turtle-breed :test-not #'eql) patch-turtles)
149 (or breed :turtles))))
151 (defun ask (agent-or-agentset fn)
152 "ASK AGENT-OR-AGENTSET FN => RESULT
154 AGENT-OR-AGENTSET: AGENT | AGENTSET
156 ARGUMENTS AND VALUES:
158 FN: a function, run on each agent
159 RESULT: undefined, commands don't return
160 AGENT: a NetLogo agent
161 AGENTSET: a NetLogo agentset
165 ASK is equivalent to ask in NetLogo.
167 The specified AGENTSET or AGENT runs the given FN. In the case of an
168 AGENTSET, the order in which the agents are run is random each time,
169 and only agents that are in the set at the beginning of the call.
171 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#ask"
173 ((agentset-p agent-or-agentset)
175 ((iter (shufflerator (agentset-list agent-or-agentset))))
177 :for agent := (funcall iter)
179 :do (let ((*myself* *self*) (*self* agent)) (with-stop-handler (funcall fn))))))
180 ((agent-p agent-or-agentset)
181 (let ((*myself* *self*) (*self* agent-or-agentset)) (with-stop-handler (funcall fn))))
183 (error "Ask requires an agentset or agent but got: ~A" agent-or-agentset))))
185 (defun count (agentset)
188 ARGUMENTS AND VALUES:
190 AGENTSET: a NetLogo agentset
195 COUNT is equivalent to count in NetLogo. Returns N, the number of
198 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#count"
199 (coerce (length (agentset-list agentset)) 'double-float))
204 ARGUMENTS AND VALUES:
210 Clears ticks, turtles, patches, globals (unimplemented).
212 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#clear-all"
220 ARGUMENTS AND VALUES:
226 As of yet, this does nothing. A placeholder method for forced dipslay
227 updates from the engine.
229 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#display"
235 ARGUMENTS AND VALUES:
241 Returns from the current stop block, which will halt the currently running
242 thing, be that the program, current ask block, or procedure. Stop has odd
243 semantics that are best gleaned from the actual NetLogo manual.
245 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#stop"
246 (error (make-condition 'stop)))
248 (defun of (fn agent-or-agentset)
249 "OF FN AGENT-OR-AGENTSET => RESULT
251 AGENT-OR-AGENTSET: AGENT | AGENTSET
252 RESULT: RESULT-LIST | RESULT-VALUE
254 ARGUMENTS AND VALUES:
256 FN: a function, run on each agent
257 AGENT: a NetLogo agent
258 AGENTSET: a NetLogo agentset
260 RESULT-VALUE: a single value
264 OF is equivalent to of in NetLogo.
266 The specified AGENTSET or AGENT runs the given FN. In the case of an
267 AGENTSET, the order in which the agents are run is random each time,
268 and only agents that are in the set at the beginning of the call.
270 RESULT-LIST is returned when the input is an AGENTSET, but RESULT-VALUE
271 is returned when only passed an AGENT.
273 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#of"
275 ((agentset-p agent-or-agentset)
277 ((iter (shufflerator (agentset-list agent-or-agentset))))
279 :for agent := (funcall iter)
281 :collect (let ((*myself* *self*) (*self* agent)) (funcall fn)))))
282 ((agent-p agent-or-agentset)
283 (let ((*myself* *self*) (*self* agent-or-agentset)) (funcall fn)))
285 (error "Of requires an agentset or agent but got: ~A" agent-or-agentset))))
287 (defun with (agentset fn)
288 "WITH AGENTSET FN => RESULT-AGENTSET
290 ARGUMENTS AND VALUES:
292 AGENTSET: a NetLogo agentset
293 FN: a boolean function, run on each agent to determine if included
294 RESULT-AGENTSET: an agentset of valid agents
298 WITH is equivalent to with in NetLogo.
300 Returns a new agentset containing only those agents that reported true
303 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#with"
307 (let ((*myself* *self*) (*self* agent)) (funcall fn)))
308 (agentset-list agentset))
309 (agentset-breed agentset)))
311 (defun shufflerator (agentset-list)
313 ((copy (copy-list agentset-list))
319 ((idx (when (< i (1- (length copy))) (+ i (clnl-random:next-int (- (length copy) i))))))
320 (when idx (setf agent (nth idx copy)))
321 (when idx (setf (nth idx copy) (nth i copy)))
323 (fetch) ; we pre-fetch because netlogo does, rng sync hype!
326 ((> i (length copy)) nil)
327 ((= i (length copy)) (incf i) (car (last copy)))
328 (t (let ((result agent)) (fetch) result)))))))
330 (defun random-float (n)
331 "RANDOM-FLOAT N => RANDOM-NUMBER
333 ARGUMENTS AND VALUES:
335 N: a double, the upper bound of the random float
336 RANDOM-NUMBER: a double, the random result
340 Returns a random number strictly closer to zero than N.
342 If number is positive, returns a random floating point number greater than
343 or equal to 0 but strictly less than number.
345 If number is negative, returns a random floating point number less than or equal
346 to 0, but strictly greater than number.
348 If number is zero, the result is always 0.
350 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#random-float"
351 (clnl-random:next-double n))
354 "RANDOM N => RANDOM-NUMBER
356 ARGUMENTS AND VALUES:
358 N: an integer, the upper bound of the random
359 RANDOM-NUMBER: an integer, the random result
363 Returns a random number strictly closer to zero than N.
365 If number is positive, returns a random integer greater than or equal to 0,
366 but strictly less than number.
368 If number is negative, returns a random integer less than or equal to 0,
369 but strictly greater than number.
371 If number is zero, the result is always 0.
373 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#random"
374 (coerce (clnl-random:next-long (truncate n)) 'double-float))
376 (defun random-xcor ()
377 "RANDOM-XCOR => RANDOM-NUMBER
379 ARGUMENTS AND VALUES:
381 RANDOM-NUMBER: a float, the random result
385 Returns a random floating point number in the allowable range of turtle
386 coordinates along the x axis.
388 These range from min-pxcor - 0.5 (inclusive) to max-pxcor + 0.5 (exclusive)
390 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#random-cor"
392 ((min (- (min-pxcor) 0.5d0))
393 (max (+ (max-pxcor) 0.5d0)))
394 (+ min (clnl-random:next-double (- max min)))))
396 (defun random-ycor ()
397 "RANDOM-YCOR => RANDOM-NUMBER
399 ARGUMENTS AND VALUES:
401 RANDOM-NUMBER: a float, the random result
405 Returns a random floating point number in the allowable range of turtle
406 coordinates along the y axis.
408 These range from min-pycor - 0.5 (inclusive) to max-pycor + 0.5 (exclusive)
410 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#random-cor"
412 ((min (- (min-pycor) 0.5d0))
413 (max (+ (max-pycor) 0.5d0)))
414 (+ min (clnl-random:next-double (- max min)))))
416 (defun one-of (list-or-agentset)
417 "ONE-OF LIST-OR-AGENTSET => RESULT
419 LIST-OR-AGENTSET: LIST | AGENTSET
420 RESULT: RANDOM-VALUE | RANDOM-AGENT | :nobody
422 ARGUMENTS AND VALUES:
425 AGENTSET: An agent set
426 RANDOM-VALUE: a value in LIST
427 RANDOM-AGENT: an agent if AGENTSET is non empty
431 From an AGENTSET, returns a RANDOM-AGENT. If the agentset is empty, returns :nobody.
432 From a list, returns a RANDOM-VALUE. If the list is empty, an error occurs.
434 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#one-of"
436 ((agentset-p list-or-agentset)
438 ((agentset-list (agentset-list list-or-agentset))
439 (length (length agentset-list)))
440 (if (zerop length) :nobody (nth (clnl-random:next-int length) agentset-list))))
441 ((listp list-or-agentset)
443 ((length (length list-or-agentset)))
445 (error "one-of requires a nonempty list")
446 (nth (clnl-random:next-int length) list-or-agentset))))
447 (t (error "one-of requires a list or agentset"))))
450 (when (not (turtle-p *self*)) (error "Gotta call jump in turtle scope, dude (~A)" *self*))
451 (with-patch-update *self*
455 (+ (turtle-xcor *self*) (* n (using-cached-sin (turtle-heading *self*))))))
459 (+ (turtle-ycor *self*) (* n (using-cached-cos (turtle-heading *self*))))))))
464 ARGUMENTS AND VALUES:
472 Sets the x-coordinate and y-coordinate for the turle. Equivalent to
473 set xcor x set ycor y, except it happens in one step inside of two.
475 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#setxy"
476 (when (not (turtle-p *self*)) (error "Gotta call setxy in turtle scope, dude (~A)" *self*))
477 (setf (turtle-xcor *self*) (wrap-x *topology* x))
478 (setf (turtle-ycor *self*) (wrap-y *topology* y)))
480 (defun set-default-shape (breed shape)
481 "SET-DEFAULT-SHAPE BREED SHAPE => RESULT
483 ARGUMENTS AND VALUES:
491 Specifies a default initial shape for a BREED. When a turtle, or it changes breeds,
492 its shape is set to the given shape.
494 SET-DEFAULT-SHAPE doesn't affect existing agents, only agents you create afterwards.
496 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#set-default-shape"
497 (when (not (breed-p breed)) (error "Need a valid breed"))
498 (setf (breed-default-shape breed) shape))
503 ARGUMENTS AND VALUES:
505 N: a double, the amount the turtle moves forward
510 Moves the current turtle forward N steps, one step at a time.
512 This moves forward one at a time in order to make the view updates look
513 good in the case of a purposefully slow running instance. If the number
514 is negative, the turtle moves backward.
516 If the current agent is not a turtle, it raises an error.
518 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#forward"
519 (when (not (turtle-p *self*)) (error "Gotta call fd in turtle scope, dude (~A)" *self*))
523 ((< (abs i) 3.2e-15) nil)
524 ((< (abs i) 1d0) (jump i))
525 (t (jump (if (> i 0d0) 1d0 -1d0)) (internal (- i (if (> i 0d0) 1d0 -1d0)))))))
528 (defun turn-right (n)
529 "TURN-RIGHT N => RESULT
531 ARGUMENTS AND VALUES:
533 N: a double, the amount the turtle turns
538 The turtle turns right by number degrees. (If number is negative, it turns left.)
540 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#right"
541 (when (not (turtle-p *self*)) (error "Gotta call fd in turtle scope, dude (~A)" *self*))
543 ((new-heading (+ (turtle-heading *self*) n)))
544 (setf (turtle-heading *self*)
546 ((< new-heading 0) (+ (mod new-heading -360) 360))
547 ((>= new-heading 360) (mod new-heading 360))
551 "TURN-LEFT N => RESULT
553 ARGUMENTS AND VALUES:
555 N: a double, the amount the turtle turns
560 The turtle turns left by number degrees. (If number is negative, it turns right.)
562 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#right"
565 (defun create-turtles (n &optional breed fn)
566 "CREATE-TURTLES N &optional BREED FN => RESULT
568 ARGUMENTS AND VALUES:
570 N: an integer, the numbers of turtles to create
572 FN: A function, applied to each turtle after creation
577 Creates N new turtles at the origin.
579 New turtles have random integer headings and the color is randomly selected
580 from the 14 primary colors. If FN is supplied, the new turtles immediately
581 run it. If a BREED is supplied, that is the breed the new turtles are set
584 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#create-turtles"
586 ((new-turtles (loop :repeat n :collect (create-turtle breed))))
587 (when fn (ask (list->agentset new-turtles :turtles) fn))))
589 (defun hatch (n &optional fn)
590 "HATCH N &optional FN => RESULT
592 ARGUMENTS AND VALUES:
594 N: an integer, the numbers of turtles to hatch
595 FN: A function, applied to each turtle after creation
600 The turtle in *self* creates N new turtles. Each new turtle inherits of all its
601 variables, including its location, from self.
603 If FN is supplied, the new turtles immediately run it.
605 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#hatch"
606 (when (not (turtle-p *self*)) (error "Can only hatch from turtle scope"))
608 ((new-turtles (loop :repeat n :collect (create-turtle nil *self*))))
609 (when fn (ask (list->agentset new-turtles :turtles) fn))))
611 (defun reset-ticks ()
612 "RESET-TICKS => RESULT
614 ARGUMENTS AND VALUES:
620 Resets the tick counter to zero, sets up all plots, then updates all plots.
622 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#reset-ticks"
626 "RESET-TICKS => RESULT
628 ARGUMENTS AND VALUES:
634 Advances the tick counter by one and updates all plots.
636 If the tick counter has not been started yet with reset-ticks, an error results.
638 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#tick"
640 (when (not *ticks*) (error "reset-ticks must be called"))
644 "TICKS => CURRENT-TICKS
646 ARGUMENTS AND VALUES:
648 CURRENT-TICKS: A positiv double, representing the current number of ticks
652 Reports the current value of the tick counter. The result is always a number and never negative.
654 If the tick counter has not been started yet with reset-ticks, an error results.
656 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#ticks"
657 (when (not *ticks*) (error "reset-ticks must be called"))
660 (defun clear-patches ()
664 :for y :from (max-pycor) :downto (min-pycor)
666 :for x :from (min-pxcor) :to (max-pxcor)
668 :xcor (coerce x 'double-float)
669 :ycor (coerce y 'double-float)
672 (defun clear-turtles ()
674 (setf *current-id* 0))
676 (defun clear-ticks ()
679 (defun create-world (&key dims globals turtles-own-vars patches-own-vars breeds)
680 "CREATE-WORLD &key DIMS GLOBALS TURTLES-OWN-VARS PATCHES-OWN-VARS BREEDS => RESULT
682 DIMS: (:xmin XMIN :xmax XMAX :ymin YMIN :ymax YMAX)
684 TURTLES-OWN-VARS: TURTLES-OWN-VAR*
685 PATCHES-OWN-VARS: PATCHES-OWN-VAR*
687 GLOBAL: (GLOBAL-NAME GLOBAL-ACCESS-FUNC)
689 ARGUMENTS AND VALUES:
692 XMIN: An integer representing the minimum patch coord in X
693 XMAX: An integer representing the maximum patch coord in X
694 YMIN: An integer representing the minimum patch coord in Y
695 YMAX: An integer representing the maximum patch coord in Y
696 TURTLES-OWN-VAR: Symbol for the turtles own variable in the keyword package
697 PATCHES-OWN-VAR: Symbol for the patches own variable in the keyword package
698 BREED: A list of symbols representing the possible preeds
699 GLOBAL-NAME: Symbol for the global in the keyword package
700 GLOBAL-ACCESS-FUNC: Function to get the value of the global
704 Initializes the world in the NVM.
706 This should be called before using the engine in any real capacity. If
707 called when an engine is already running, it may do somethign weird."
708 (setf *turtles-own-vars* turtles-own-vars)
709 (setf *patches-own-vars* patches-own-vars)
710 (setf *dimensions* dims)
711 (setf *globals* globals)
714 (list (list :turtles "default"))
715 (mapcar (lambda (breed) (list breed "default")) breeds)))
720 ; These match netlogo's dump
721 (defgeneric dump-object (o))
723 (defmethod dump-object ((n double-float))
724 (multiple-value-bind (int rem) (floor n)
726 (format nil "~A" int)
728 ((output (format nil "~D" n)))
729 ; Someday we'll have d<posint>, but this is not that day!
730 (cl-ppcre:regex-replace "d-" (cl-ppcre:regex-replace "d0" output "") "E-")))))
732 (defmethod dump-object ((o string)) (format nil "~A" (cl-ppcre:regex-replace-all "\"" (format nil "~S" o) "\"\"")))
734 (defmethod dump-object ((o (eql t))) "true")
735 (defmethod dump-object ((o (eql nil))) "false")
737 (defmethod dump-object ((o list))
739 ((agentset-p o) (format nil "(agentset, ~A ~A)" (dump-object (count o)) (string-downcase (agentset-breed o))))
740 (t (format nil "[~{~A~^ ~}]" (mapcar #'dump-object o)))))
742 (defmethod dump-object ((o patch))
743 (format nil "(patch ~A ~A)" (dump-object (patch-xcor o)) (dump-object (patch-ycor o))))
745 (defmethod dump-object ((o turtle)) (format nil "(turtle ~A)" (dump-object (turtle-who o))))
746 (defmethod dump-object ((o (eql :nobody))) (format nil "nobody"))
747 (defmethod dump-object ((o (eql :turtles))) (format nil "{all-turtles}"))
748 (defmethod dump-object ((o symbol))
750 ((find o *breeds* :key #'car) (format nil "{breed ~(~A~)}" o))
751 (t (error "Keyword unrecognized by dump object: ~A" o))))
753 (defun current-state ()
754 "CURRENT-STATE => WORLD-STATE
756 ARGUMENTS AND VALUES:
758 WORLD-STATE: A list, the current state of the whole world
762 Dumps out the state of the world.
764 This is useful for visualizations and also storing in a common lisp
765 data structure for easy usage in a common lisp instance. It's preferable
766 to use this when working with the nvm than the output done by export-world.
768 Currently this only dumps out turtle and patch information.
770 This is called CURRENT-STATE because export-world is an actual primitive
776 :color (turtle-color turtle)
777 :xcor (turtle-xcor turtle)
778 :ycor (turtle-ycor turtle)
779 :heading (turtle-heading turtle)
780 :size (turtle-size turtle)))
785 :color (patch-color patch)
786 :xcor (patch-xcor patch)
787 :ycor (patch-ycor patch)))
790 (defun export-turtles ()
794 (format nil "~A~A~{,\"~A\"~}"
795 "\"who\",\"color\",\"heading\",\"xcor\",\"ycor\",\"shape\",\"label\",\"label-color\","
796 "\"breed\",\"hidden?\",\"size\",\"pen-size\",\"pen-mode\""
797 (mapcar #'string-downcase *turtles-own-vars*)))
801 "\"~A\",\"~A\",\"~A\",\"~A\",\"~A\",\"~A\",\"~A\",\"~A\",\"~A\",\"false\",\"~A\",~A~{,\"~A\"~}"
802 (dump-object (turtle-who turtle))
803 (dump-object (turtle-color turtle))
804 (dump-object (turtle-heading turtle))
805 (dump-object (turtle-xcor turtle))
806 (dump-object (turtle-ycor turtle))
807 (dump-object (turtle-shape turtle))
808 (dump-object (turtle-label turtle))
809 (dump-object (turtle-label-color turtle))
810 (dump-object (turtle-breed turtle))
811 (dump-object (turtle-size turtle))
812 "\"1\",\"\"\"up\"\"\""
813 (mapcar #'dump-object (mapcar (lambda (var) (agent-value-inner turtle var)) *turtles-own-vars*))))
816 (defun export-patches ()
820 (format nil "\"pxcor\",\"pycor\",\"pcolor\",\"plabel\",\"plabel-color\"~{,\"~A\"~}"
821 (mapcar #'string-downcase *patches-own-vars*)))
825 "\"~A\",\"~A\",\"~A\",\"\"\"\"\"\",\"9.9\"~{,\"~A\"~}"
826 (dump-object (patch-xcor patch))
827 (dump-object (patch-ycor patch))
828 (dump-object (patch-color patch))
829 (mapcar #'dump-object (mapcar (lambda (var) (agent-value-inner patch var)) *patches-own-vars*))))
832 (defun export-world ()
833 "EXPORT-WORLD => WORLD-CSV
835 ARGUMENTS AND VALUES:
837 WORLD-CSV: A string, the csv of the world
841 Dumps out a csv matching NetLogo's export world.
843 This is useful for serializing the current state of the engine in order
844 to compare against NetLogo or to reimport later. Contains everything needed
845 to boot up a NetLogo instance in the exact same state."
846 (format nil "~{~A~%~}"
848 (format nil "~S" "RANDOM STATE")
849 (format nil "~S" (clnl-random:export))
851 (format nil "~S" "GLOBALS")
852 (format nil "~A~A~{\"~A\"~^,~}"
853 "\"min-pxcor\",\"max-pxcor\",\"min-pycor\",\"max-pycor\",\"perspective\",\"subject\","
854 "\"nextIndex\",\"directed-links\",\"ticks\","
855 (mapcar #'string-downcase (mapcar #'car *globals*)))
856 (format nil "\"~A\",\"~A\",\"~A\",\"~A\",\"0\",\"nobody\",\"~A\",\"\"\"NEITHER\"\"\",\"~A\"~{,\"~A\"~}"
857 (min-pxcor) (max-pxcor) (min-pycor) (max-pycor) *current-id* (dump-object (or *ticks* -1d0))
858 (mapcar #'dump-object (mapcar #'funcall (mapcar #'cadr *globals*))))
860 (format nil "~{~A~^~%~}" (export-turtles))
862 (format nil "~{~A~^~%~}" (export-patches))
864 (format nil "~S" "LINKS")
865 "\"end1\",\"end2\",\"color\",\"label\",\"label-color\",\"hidden?\",\"breed\",\"thickness\",\"shape\",\"tie-mode\""