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)
109 (setf (clnl-nvm:agent-value :pcolor) (clnl-nvm:one-of (list (clnl-nvm:lookup-color :green) (clnl-nvm:lookup-color :brown))))
110 (if (equalp (clnl-nvm:agent-value :pcolor) (clnl-nvm:lookup-color :green))
111 (setf (clnl-nvm:agent-value :countdown) grass-regrowth-time)
112 (setf (clnl-nvm:agent-value :countdown) (clnl-nvm:random grass-regrowth-time))))))
113 (clnl-nvm:set-default-shape :sheep "sheep")
114 (clnl-nvm:create-turtles initial-number-sheep :sheep
116 (setf (clnl-nvm:agent-value :color) (clnl-nvm:lookup-color :white))
117 (setf (clnl-nvm:agent-value :size) 1.5d0)
118 (setf (clnl-nvm:agent-value :label-color) (- (clnl-nvm:lookup-color :blue) 2.0d0))
119 (setf (clnl-nvm:agent-value :energy) (clnl-nvm:random (* 2.0d0 sheep-gain-from-food)))
121 (clnl-nvm:random-xcor)
122 (clnl-nvm:random-ycor))))
123 (clnl-nvm:set-default-shape :wolves "wolf")
124 (clnl-nvm:create-turtles initial-number-wolves :wolves
126 (setf (clnl-nvm:agent-value :color) (clnl-nvm:lookup-color :black))
127 (setf (clnl-nvm:agent-value :size) 2.0d0)
128 (setf (clnl-nvm:agent-value :energy) (clnl-nvm:random (* 2.0d0 wolf-gain-from-food)))
129 (clnl-nvm:setxy (clnl-nvm:random-xcor) (clnl-nvm:random-ycor))))
131 (setf grass (clnl-nvm:count (clnl-nvm:with (clnl-nvm:patches) (lambda () (equalp (clnl-nvm:agent-value :pcolor) (clnl-nvm:lookup-color :green))))))
132 (clnl-nvm:reset-ticks)
136 (clnl-nvm:with-stop-handler
137 (when (not (> (clnl-nvm:count (clnl-nvm:turtles)) 0)) (clnl-nvm:stop))
141 (when grass? (setf (clnl-nvm:agent-value :energy) (- (clnl-nvm:agent-value :energy) 1.0d0)) (eat-grass))
144 (clnl-nvm:ask :wolves
147 (setf (clnl-nvm:agent-value :energy) (- (clnl-nvm:agent-value :energy) 1.0d0))
151 (when grass? (clnl-nvm:ask (clnl-nvm:patches) (lambda () (grow-grass))))
152 (setf grass (clnl-nvm:count (clnl-nvm:with (clnl-nvm:patches) (lambda () (equalp (clnl-nvm:agent-value :pcolor) (clnl-nvm:lookup-color :green))))))
153 (clnl-nvm:tick) (display-labels)
157 (clnl-nvm:turn-right (clnl-nvm:random 50.0d0))
158 (clnl-nvm:turn-left (clnl-nvm:random 50.0d0))
159 (clnl-nvm:forward 1.0d0)
163 (when (equalp (clnl-nvm:agent-value :pcolor) (clnl-nvm:lookup-color :green))
164 (setf (clnl-nvm:agent-value :pcolor) (clnl-nvm:lookup-color :brown))
165 (setf (clnl-nvm:agent-value :energy) (+ (clnl-nvm:agent-value :energy) sheep-gain-from-food)))
168 (defun reproduce-sheep ()
169 (when (< (clnl-nvm:random-float 100.0d0) sheep-reproduce)
170 (setf (clnl-nvm:agent-value :energy) (/ (clnl-nvm:agent-value :energy) 2.0d0))
171 (clnl-nvm:hatch 1.0d0
173 (clnl-nvm:turn-right (clnl-nvm:random-float 360.0d0))
174 (clnl-nvm:forward 1.0d0))))
177 (defun reproduce-wolves ()
178 (when (< (clnl-nvm:random-float 100.0d0) wolf-reproduce)
179 (setf (clnl-nvm:agent-value :energy) (/ (clnl-nvm:agent-value :energy) 2.0d0))
180 (clnl-nvm:hatch 1.0d0
182 (clnl-nvm:turn-right (clnl-nvm:random-float 360.0d0))
183 (clnl-nvm:forward 1.0d0))))
186 (defun catch-sheep ()
188 ((prey (clnl-nvm:one-of (clnl-nvm:turtles-here :sheep))))
189 (when (not (equalp prey :nobody))
190 (clnl-nvm:ask prey (lambda () (clnl-nvm:die)))
191 (setf (clnl-nvm:agent-value :energy) (+ (clnl-nvm:agent-value :energy) wolf-gain-from-food))))
195 (when (< (clnl-nvm:agent-value :energy) 0.0d0) (clnl-nvm:die))
199 (when (equalp (clnl-nvm:agent-value :pcolor) (clnl-nvm:lookup-color :brown))
200 (if (<= (clnl-nvm:agent-value :countdown) 0.0d0)
202 (setf (clnl-nvm:agent-value :pcolor) (clnl-nvm:lookup-color :green))
203 (setf (clnl-nvm:agent-value :countdown) grass-regrowth-time))
204 (setf (clnl-nvm:agent-value :countdown) (- (clnl-nvm:agent-value :countdown) 1.0d0))))
207 (defun display-labels ()
208 (clnl-nvm:ask (clnl-nvm:turtles) (lambda () (setf (clnl-nvm:agent-value :label) "")))
210 (clnl-nvm:ask :wolves
211 (lambda () (setf (clnl-nvm:agent-value :label) (ffloor (+ (clnl-nvm:agent-value :energy) 0.5d0)))))
214 (lambda () (setf (clnl-nvm:agent-value :label) (ffloor (+ (clnl-nvm:agent-value :energy) 0.5d0)))))))
218 (clnl-random:set-seed 15)
219 (clnl-nvm:create-world :dims
220 '(:xmin -25 :xmax 25 :ymin -25 :ymax 25 :patch-size 9.0d0)
223 (list :initial-number-sheep (lambda () initial-number-sheep))
224 (list :sheep-gain-from-food (lambda () sheep-gain-from-food))
225 (list :sheep-reproduce (lambda () sheep-reproduce))
226 (list :initial-number-wolves (lambda () initial-number-wolves))
227 (list :wolf-gain-from-food (lambda () wolf-gain-from-food))
228 (list :wolf-reproduce (lambda () wolf-reproduce))
229 (list :grass? (lambda () grass?))
230 (list :grass-regrowth-time (lambda () grass-regrowth-time))
231 (list :show-energy? (lambda () show-energy?))
232 (list :grass (lambda () grass)))
233 :turtles-own-vars '(:energy) :patches-own-vars '(:countdown) :breeds '(:sheep :wolves))
234 (clnl-interface:initialize :dims '(:xmin -25 :xmax 25 :ymin -25 :ymax 25 :patch-size 9.0d0)))