1 One way to use CLNL is as a library loaded into a common lisp instance. Once you have the source release from the releases page loaded up into however you configure asdf, you can start writing models using the clnl-* packages. However, a good place to begin is by letting CLNL convert a model to common lisp so you can start from a known place.
3 Everything that the generated code could use is external in the proper packages, so that you could optionally write the code in pure common lisp without using the generator.
5 ## Converting Wolf Sheep Predation as a headless model
7 This code creates the wolf sheep common lisp file:
10 (asdf:load-system :clnl)
12 (with-open-file (out "wolfsheep.lisp" :direction :output)
14 (lambda (form) (pprint form out))
15 (with-open-file (str "resources/clnl/models/Wolf Sheep Predation.nlogo")
16 (clnl:nlogo->lisp str :wolfsheep 'boot))))
19 From there, you can boot the model with
22 sbcl --eval '(asdf:load-system :clnl)' --load 'wolfsheep.lisp' --eval '(wolfsheep::boot)'
25 Then you can run functions headlessly from the REPL with:
32 You can then mix common lisp forms and functions from your model
35 (loop :repeat 50 :do (wolfsheep::go))
38 Then you can start doing headless analysis on your model by using clnl-nvm primitives
44 :repeat 50 :do (wolfsheep::go)
45 :collect (list (clnl-nvm:count :sheep) (clnl-nvm:count :wolves)))
48 ## Wolf Sheep as a non headless model
50 If, however, you'd rather run with the interface as well, you would use
53 (asdf:load-system :clnl)
55 (with-open-file (out "wolfsheep.lisp" :direction :output)
57 (lambda (form) (pprint form out))
58 (with-open-file (str "resources/clnl/models/Wolf Sheep Predation.nlogo")
59 (clnl:nlogo->lisp str :wolfsheep 'boot :initialize-interface t))))
62 Then load up the model as such:
65 sbcl --eval '(asdf:load-system :clnl)' --load 'wolfsheep.lisp' --eval '(wolfsheep::boot)'
68 Then start the interface
71 (sb-thread:make-thread #'clnl-interface:run)
74 Then you can do your normal model functions
82 ## Wolf sheep as a common lisp file after generation
84 The following is a hand edited modification of wolf sheep to remove unnecessary things, and clean it up
88 (defpackage :wolfsheep (:use :common-lisp) (:shadow :go))
89 (in-package :wolfsheep)
91 (defvar initial-number-sheep 100.0d0)
92 (defvar sheep-gain-from-food 4.0d0)
93 (defvar sheep-reproduce 4.0d0)
94 (defvar initial-number-wolves 50.0d0)
95 (defvar wolf-gain-from-food 20.0d0)
96 (defvar wolf-reproduce 5.0d0)
98 (defvar grass-regrowth-time 30.0d0)
99 (defvar show-energy? nil)
104 (clnl-nvm:ask (clnl-nvm:patches)
105 (lambda () (setf (clnl-nvm:agent-value :pcolor) (clnl-nvm:lookup-color :green))))
107 (clnl-nvm:ask (clnl-nvm:patches)
110 (clnl-nvm:agent-value :pcolor)
111 (clnl-nvm:one-of (list (clnl-nvm:lookup-color :green) (clnl-nvm:lookup-color :brown))))
112 (if (equalp (clnl-nvm:agent-value :pcolor) (clnl-nvm:lookup-color :green))
113 (setf (clnl-nvm:agent-value :countdown) grass-regrowth-time)
114 (setf (clnl-nvm:agent-value :countdown) (clnl-nvm:random grass-regrowth-time))))))
115 (clnl-nvm:set-default-shape :sheep "sheep")
116 (clnl-nvm:create-turtles initial-number-sheep :sheep
118 (setf (clnl-nvm:agent-value :color) (clnl-nvm:lookup-color :white))
119 (setf (clnl-nvm:agent-value :size) 1.5d0)
120 (setf (clnl-nvm:agent-value :label-color) (- (clnl-nvm:lookup-color :blue) 2.0d0))
121 (setf (clnl-nvm:agent-value :energy) (clnl-nvm:random (* 2.0d0 sheep-gain-from-food)))
123 (clnl-nvm:random-xcor)
124 (clnl-nvm:random-ycor))))
125 (clnl-nvm:set-default-shape :wolves "wolf")
126 (clnl-nvm:create-turtles initial-number-wolves :wolves
128 (setf (clnl-nvm:agent-value :color) (clnl-nvm:lookup-color :black))
129 (setf (clnl-nvm:agent-value :size) 2.0d0)
130 (setf (clnl-nvm:agent-value :energy) (clnl-nvm:random (* 2.0d0 wolf-gain-from-food)))
131 (clnl-nvm:setxy (clnl-nvm:random-xcor) (clnl-nvm:random-ycor))))
138 (lambda () (equalp (clnl-nvm:agent-value :pcolor) (clnl-nvm:lookup-color :green))))))
139 (clnl-nvm:reset-ticks)
143 (clnl-nvm:with-stop-handler
144 (when (not (> (clnl-nvm:count (clnl-nvm:turtles)) 0)) (clnl-nvm:stop))
148 (when grass? (setf (clnl-nvm:agent-value :energy) (- (clnl-nvm:agent-value :energy) 1.0d0)) (eat-grass))
151 (clnl-nvm:ask :wolves
154 (setf (clnl-nvm:agent-value :energy) (- (clnl-nvm:agent-value :energy) 1.0d0))
158 (when grass? (clnl-nvm:ask (clnl-nvm:patches) (lambda () (grow-grass))))
164 (lambda () (equalp (clnl-nvm:agent-value :pcolor) (clnl-nvm:lookup-color :green))))))
165 (clnl-nvm:tick) (display-labels)
169 (clnl-nvm:turn-right (clnl-nvm:random 50.0d0))
170 (clnl-nvm:turn-left (clnl-nvm:random 50.0d0))
171 (clnl-nvm:forward 1.0d0)
175 (when (equalp (clnl-nvm:agent-value :pcolor) (clnl-nvm:lookup-color :green))
176 (setf (clnl-nvm:agent-value :pcolor) (clnl-nvm:lookup-color :brown))
177 (setf (clnl-nvm:agent-value :energy) (+ (clnl-nvm:agent-value :energy) sheep-gain-from-food)))
180 (defun reproduce-sheep ()
181 (when (< (clnl-nvm:random-float 100.0d0) sheep-reproduce)
182 (setf (clnl-nvm:agent-value :energy) (/ (clnl-nvm:agent-value :energy) 2.0d0))
183 (clnl-nvm:hatch 1.0d0
185 (clnl-nvm:turn-right (clnl-nvm:random-float 360.0d0))
186 (clnl-nvm:forward 1.0d0))))
189 (defun reproduce-wolves ()
190 (when (< (clnl-nvm:random-float 100.0d0) wolf-reproduce)
191 (setf (clnl-nvm:agent-value :energy) (/ (clnl-nvm:agent-value :energy) 2.0d0))
192 (clnl-nvm:hatch 1.0d0
194 (clnl-nvm:turn-right (clnl-nvm:random-float 360.0d0))
195 (clnl-nvm:forward 1.0d0))))
198 (defun catch-sheep ()
200 ((prey (clnl-nvm:one-of (clnl-nvm:turtles-here :sheep))))
201 (when (not (equalp prey :nobody))
202 (clnl-nvm:ask prey (lambda () (clnl-nvm:die)))
203 (setf (clnl-nvm:agent-value :energy) (+ (clnl-nvm:agent-value :energy) wolf-gain-from-food))))
207 (when (< (clnl-nvm:agent-value :energy) 0.0d0) (clnl-nvm:die))
211 (when (equalp (clnl-nvm:agent-value :pcolor) (clnl-nvm:lookup-color :brown))
212 (if (<= (clnl-nvm:agent-value :countdown) 0.0d0)
214 (setf (clnl-nvm:agent-value :pcolor) (clnl-nvm:lookup-color :green))
215 (setf (clnl-nvm:agent-value :countdown) grass-regrowth-time))
216 (setf (clnl-nvm:agent-value :countdown) (- (clnl-nvm:agent-value :countdown) 1.0d0))))
219 (defun display-labels ()
220 (clnl-nvm:ask (clnl-nvm:turtles) (lambda () (setf (clnl-nvm:agent-value :label) "")))
222 (clnl-nvm:ask :wolves
223 (lambda () (setf (clnl-nvm:agent-value :label) (ffloor (+ (clnl-nvm:agent-value :energy) 0.5d0)))))
226 (lambda () (setf (clnl-nvm:agent-value :label) (ffloor (+ (clnl-nvm:agent-value :energy) 0.5d0)))))))
230 (clnl-random:set-seed 15)
231 (clnl-nvm:create-world :dims
232 '(:xmin -25 :xmax 25 :ymin -25 :ymax 25 :patch-size 9.0d0)
235 (list :initial-number-sheep (lambda () initial-number-sheep))
236 (list :sheep-gain-from-food (lambda () sheep-gain-from-food))
237 (list :sheep-reproduce (lambda () sheep-reproduce))
238 (list :initial-number-wolves (lambda () initial-number-wolves))
239 (list :wolf-gain-from-food (lambda () wolf-gain-from-food))
240 (list :wolf-reproduce (lambda () wolf-reproduce))
241 (list :grass? (lambda () grass?))
242 (list :grass-regrowth-time (lambda () grass-regrowth-time))
243 (list :show-energy? (lambda () show-energy?))
244 (list :grass (lambda () grass)))
245 :turtles-own-vars '(:energy) :patches-own-vars '(:countdown) :breeds '(:sheep :wolves))
246 (clnl-interface:initialize :dims '(:xmin -25 :xmax 25 :ymin -25 :ymax 25 :patch-size 9.0d0)))