Open mars0i opened 1 year ago
The issue is what to do if multiple foodspots are found simultaneously. This is unlikely, but more likely with dense random target distributions, especially ones that encourage micro-clumping. The old version run.clj/env_mason.clj version waits until run-and-collect
to implement this, with a call to a function in env-mason
that selects the first found foodspot.
From one point of view, it's good to wait until late in the process--run/run-and-collect
--to decide what to do with multiple foodspots, so that you can use the same underlying search process with different foodspot-selection rules. But then you'd have to pass the rule function to run-and-collect
, and therefore to walk-experiments
which calls it.
But this selection procedure is naturally viewed part of the animal's foraging behavior, and you can build it into the look-fn
s. And that wraps it up for passing to walk-experiments
--which really should not know about this kind of decision. So the approach in env-matrix
is cleaner.
I need to make at least one parallel function in env-mason
for the functions in env-matrix
, or abstract this selection decision from both. And take out the step in run-and-collect
that selects from possibly multiple foodspots found.
OK, here's the plan. Although currently, any model I'd make would have the forager go toward a single foodspot, who knows--maybe there would some foraging model in the future that would benefit from the forager processing mulitple ones in some way. For now, I'm going to ignore that, but I do want to abstract the finding from the selecting from the foodspots found. run-and-collect
will continue to expect that a single foodspot is given to its code. But I'm going to put the selecting functions in walk.clj, if I can, because these foodspot selection procedures should be independent of the environment implementation. they shouldn't be in env-matrix
or env-mason
.
otoh, backward compatibility (?) requires that look-fns return collections.
And why should look-fns know about what is done with what they find? Shouldn't that be abstracted from them?
Maybe I do want to pass a selection function to run-and-collect
?
Also, even if run-and-collect
is only going to use one foodspot, maybe it would be useful to be able to check how many there were (though run-and-collect
doesn't currently do that.)
So: run-and-collect
will take the first foodspot, but a look-fn may reorder the sequence to choose one over others.
otoh you could say that of course look-fns should know about what they find.
Note that run/end-of-walk
and run/end-of-walk-if-found
also assume that found foodspots are in a collection, and they build in the assumption that the first one in the collection should be used.
And these are passed to run-and-collect. I don't want to parameterize them further.
I think that the foodspot choice should be in look-fn. And this should also be used (obviously) by the end-of-walk fns, which are used to start the next walk from where the last one ended.
But I think I'll retain backward compatibility, for now at least, by (a) returning a collection, but (b) making the first foodspot the selected one. This is confusing--why is there a collection? But OK.
(Then again, re backward compatibility, isn't all of the interaction with the foodspots in run.clj? So if I change it there, the experiment scripts won't know. But still: I'll retain the missed opportunities information. Why not?)
TODO: Finish implementing random/shuffle-coll
.
In env-matrix
, choose-foodspot-here-or-whatever
and choose-foodspot-here-or-random
seems to be done, and can be passed to perc-foodspots
. Need to test.
Then move the first two to some other namespace and duplicate perc-foodspots
in env-mason
.
In revising to allow switching between two environment implementations--
env-mason
(old) andenv-matrix
(new)--I discovered thatrun/run-and-collect
callsenv-mason/foodspot-coords-if-found
, which implements functionality that is related toenv-matrix/perc-first-foodspot
. These kind of do the same thing but at different stages of the foraging computation process. The latter is part of a more systematic approach, but I've built the former into the higher-level code that is in run.clj. Need to think through what's best going forward.