b419f97f73a21ecfb51113b8e9dd2da2bde60562
[clnl] / src / main / clnl / nvm / agentset.lisp
1 (in-package #:clnl-nvm)
2
3 (defun count (agentset)
4  "COUNT AGENTSET => N
5
6 ARGUMENTS AND VALUES:
7
8   AGENTSET: a NetLogo agentset
9   N: a number
10
11 DESCRIPTION:
12
13   COUNT is equivalent to count in NetLogo.  Returns N, the number of
14   agents in AGENTSET.
15
16   See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#count"
17  (coerce (length (agentset-list agentset)) 'double-float))
18
19 (defun of (fn agent-or-agentset)
20  "OF FN AGENT-OR-AGENTSET => RESULT
21
22   AGENT-OR-AGENTSET: AGENT | AGENTSET
23   RESULT: RESULT-LIST | RESULT-VALUE
24
25 ARGUMENTS AND VALUES:
26
27   FN: a function, run on each agent
28   AGENT: a NetLogo agent
29   AGENTSET: a NetLogo agentset
30   RESULT-LIST: a list
31   RESULT-VALUE: a single value
32
33 DESCRIPTION:
34
35   OF is equivalent to of in NetLogo.
36
37   The specified AGENTSET or AGENT runs the given FN.  In the case of an
38   AGENTSET, the order in which the agents are run is random each time,
39   and only agents that are in the set at the beginning of the call.
40
41   RESULT-LIST is returned when the input is an AGENTSET, but RESULT-VALUE
42   is returned when only passed an AGENT.
43
44   See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#of"
45  (cond
46   ((agentset-p agent-or-agentset)
47    (let
48     ((iter (shufflerator (agentset-list agent-or-agentset))))
49     (loop
50      :for agent := (funcall iter)
51      :while agent
52      :collect (let ((*myself* *self*) (*self* agent)) (funcall fn)))))
53   ((agent-p agent-or-agentset)
54    (let ((*myself* *self*) (*self* agent-or-agentset)) (funcall fn)))
55   (t
56    (error "Of requires an agentset or agent but got: ~A" agent-or-agentset))))
57
58 (defun one-of (list-or-agentset)
59  "ONE-OF LIST-OR-AGENTSET => RESULT
60
61   LIST-OR-AGENTSET: LIST | AGENTSET
62   RESULT: RANDOM-VALUE | RANDOM-AGENT | :nobody
63
64 ARGUMENTS AND VALUES:
65
66   LIST: A list
67   AGENTSET: An agent set
68   RANDOM-VALUE: a value in LIST
69   RANDOM-AGENT: an agent if AGENTSET is non empty
70
71 DESCRIPTION:
72
73   From an AGENTSET, returns a RANDOM-AGENT. If the agentset is empty, returns :nobody.
74   From a list, returns a RANDOM-VALUE.  If the list is empty, an error occurs.
75
76   See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#one-of"
77  (cond
78   ((agentset-p list-or-agentset)
79    (let*
80     ((agentset-list (agentset-list list-or-agentset))
81      (length (length agentset-list)))
82     (if (zerop length) :nobody (nth (clnl-random:next-int length) agentset-list))))
83   ((listp list-or-agentset)
84    (let*
85     ((length (length list-or-agentset)))
86     (if (zerop length)
87      (error "one-of requires a nonempty list")
88      (nth (clnl-random:next-int length) list-or-agentset))))
89   (t (error "one-of requires a list or agentset"))))
90
91 (defun patches ()
92  "PATCHES => ALL-PATCHES
93
94 ARGUMENTS AND VALUES:
95
96   ALL-PATCHES: a NetLogo agentset, all patches
97
98 DESCRIPTION:
99
100   Reports the agentset consisting of all the patches.
101
102   This agentset is special in that it represents the living patches
103   each time it's used, so changes depending on the state of the engine.
104
105   See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#patches"
106  :patches)
107
108 (defun turtles ()
109  "TURTLES => ALL-TURTLES
110
111 ARGUMENTS AND VALUES:
112
113   ALL-TURTLES: a NetLogo agentset, all turtles
114
115 DESCRIPTION:
116
117   Reports the agentset consisting of all the turtles.
118
119   This agentset is special in that it represents the living turtles
120   each time it's used, so changes depending on the state of the engine.
121
122   See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#turtles"
123  :turtles)
124
125 (defun with (agentset fn)
126  "WITH AGENTSET FN => RESULT-AGENTSET
127
128 ARGUMENTS AND VALUES:
129
130   AGENTSET: a NetLogo agentset
131   FN: a boolean function, run on each agent to determine if included
132   RESULT-AGENTSET: an agentset of valid agents
133
134 DESCRIPTION:
135
136   WITH is equivalent to with in NetLogo.
137
138   Returns a new agentset containing only those agents that reported true
139   when FN is called.
140
141   See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#with"
142  (list->agentset
143   (remove-if-not
144    (lambda (agent)
145     (let ((*myself* *self*) (*self* agent)) (funcall fn)))
146    (agentset-list agentset))
147   (agentset-breed agentset)))