diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c2bfaa..8eedd09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,11 +13,13 @@ For an explanation of the general changes in version 1.0, please refer to the fi * Environments now have a class method to make them easier to use without a simulation`.run`. Notice that this is different from `run_model`, which is an instance method. * Ability to run simulations using mesa models * The `soil.exporters` module to export the results of datacollectors (`model.datacollector`) into files at the end of trials/simulations -* Agents can now have generators as a step function or a state. They work similar to normal functions, with one caveat in the case of `FSM`: only `time` values (or None) can be yielded, not a state. This is because the state will not change, it will be resumed after the yield, at the appropriate time. The return value *can* be a state, or a `(state, time)` tuple, just like in normal states. +* Agents can now have generators or async functions as their step or as states. They work similar to normal functions, with one caveat in the case of `FSM`: only time values (a float, int or None) can be awaited or yielded, not a state. This is because the state will not change, it will be resumed after the yield, at the appropriate time. To return to a different state, use the `delay` and `at` functions of the state. * Simulations can now specify a `matrix` with possible values for every simulation parameter. The final parameters will be calculated based on the `parameters` used and a cartesian product (i.e., all possible combinations) of each parameter. * Simple debugging capabilities in `soil.debugging`, with a custom `pdb.Debugger` subclass that exposes commands to list agents and their status and set breakpoints on states (for FSM agents). Try it with `soil --debug ` +* The `agent.after` and `agent.at` methods, to avoid having to return a time manually. ### Changed * Configuration schema (`Simulation`) is very simplified. All simulations should be checked +* Agents that wish to * Model / environment variables are expected (but not enforced) to be a single value. This is done to more closely align with mesa * `Exporter.iteration_end` now takes two parameters: `env` (same as before) and `params` (specific parameters for this environment). We considered including a `parameters` attribute in the environment, but this would not be compatible with mesa. * `num_trials` renamed to `iterations` @@ -26,6 +28,7 @@ For an explanation of the general changes in version 1.0, please refer to the fi * Simulation results for every iteration of a simulation with the same name are stored in a single `sqlite` database ### Removed +* The `time.When` and `time.Cond` classes are removed * Any `tsih` and `History` integration in the main classes. To record the state of environments/agents, just use a datacollector. In some cases this may be slower or consume more memory than the previous system. However, few cases actually used the full potential of the history, and it came at the cost of unnecessary complexity and worse performance for the majority of cases. ## [0.20.8] diff --git a/docs/example.yml b/docs/example.yml deleted file mode 100644 index 45661b3..0000000 --- a/docs/example.yml +++ /dev/null @@ -1,40 +0,0 @@ ---- -name: MyExampleSimulation -max_time: 50 -num_trials: 3 -interval: 2 -model_params: - topology: - params: - generator: barabasi_albert_graph - n: 100 - m: 2 - agents: - distribution: - - agent_class: SISaModel - topology: True - ratio: 0.1 - state: - state_id: content - - agent_class: SISaModel - topology: True - ratio: .1 - state: - state_id: discontent - - agent_class: SISaModel - topology: True - ratio: 0.8 - state: - state_id: neutral - prob_infect: 0.075 - neutral_discontent_spon_prob: 0.1 - neutral_discontent_infected_prob: 0.3 - neutral_content_spon_prob: 0.3 - neutral_content_infected_prob: 0.4 - discontent_neutral: 0.5 - discontent_content: 0.5 - variance_d_c: 0.2 - content_discontent: 0.2 - variance_c_d: 0.2 - content_neutral: 0.2 - standard_variance: 1 \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 23fc761..129cff3 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -2,7 +2,7 @@ Welcome to Soil's documentation! ================================ Soil is an opinionated Agent-based Social Simulator in Python focused on Social Networks. -To get started developing your own simulations and agent behaviors, check out our :doc:`Tutorial ` and the `examples on GitHub `. +To get started developing your own simulations and agent behaviors, check out our :doc:`Tutorial ` and the `examples on GitHub `. Soil can be installed through pip (see more details in the :doc:`installation` page):. @@ -49,6 +49,7 @@ If you use Soil in your research, do not forget to cite this paper: installation Tutorial notes_v1.0 + soil-vs .. diff --git a/docs/mesa.rst b/docs/mesa.rst deleted file mode 100644 index 51ae1c1..0000000 --- a/docs/mesa.rst +++ /dev/null @@ -1,22 +0,0 @@ -Mesa compatibility ------------------- - -Soil is in the process of becoming fully compatible with MESA. -The idea is to provide a set of modular classes and functions that extend the functionality of mesa, whilst staying compatible. -In the end, it should be possible to add regular mesa agents to a soil simulation, or use a soil agent within a mesa simulation/model. - -This is a non-exhaustive list of tasks to achieve compatibility: - -- [ ] Integrate `soil.Simulation` with mesa's runners: - - [ ] `soil.Simulation` could mimic/become a `mesa.batchrunner` -- [ ] Integrate `soil.Environment` with `mesa.Model`: - - [x] `Soil.Environment` inherits from `mesa.Model` - - [x] `Soil.Environment` includes a Mesa-like Scheduler (see the `soil.time` module. - - [ ] Allow for `mesa.Model` to be used in a simulation. -- [ ] Integrate `soil.Agent` with `mesa.Agent`: - - [x] Rename agent.id to unique_id? - - [x] mesa agents can be used in soil simulations (see `examples/mesa`) -- [ ] Provide examples - - [ ] Using mesa modules in a soil simulation - - [ ] Using soil modules in a mesa simulation -- [ ] Document the new APIs and usage \ No newline at end of file diff --git a/docs/soil-vs.rst b/docs/soil-vs.rst index 53b6891..da0007b 100644 --- a/docs/soil-vs.rst +++ b/docs/soil-vs.rst @@ -1,4 +1,8 @@ -### MESA +Soil vs other ABM frameworks +============================ + +MESA +---- Starting with version 0.3, Soil has been redesigned to complement Mesa, while remaining compatible with it. That means that every component in Soil (i.e., Models, Environments, etc.) can be mixed with existing mesa components. @@ -10,3 +14,42 @@ Here are some reasons to use Soil instead of plain mesa: - Functions to automatically populate a topology with an agent distribution (i.e., different ratios of agent class and state) - The `soil.Simulation` class allows you to run multiple instances of the same experiment (i.e., multiple trials with the same parameters but a different randomness seed) - Reporting functions that aggregate multiple + +Mesa compatibility +~~~~~~~~~~~~~~~~~~ + +Soil is in the process of becoming fully compatible with MESA. +The idea is to provide a set of modular classes and functions that extend the functionality of mesa, whilst staying compatible. +In the end, it should be possible to add regular mesa agents to a soil simulation, or use a soil agent within a mesa simulation/model. + +This is a non-exhaustive list of tasks to achieve compatibility: + +.. |check| raw:: html + + ☑ + +.. |uncheck| raw:: html + + ☐ + +- |check| Integrate `soil.Simulation` with mesa's runners: + + - |check| `soil.Simulation` can replace `mesa.batchrunner` + +- |check| Integrate `soil.Environment` with `mesa.Model`: + + - |check| `Soil.Environment` inherits from `mesa.Model` + - |check| `Soil.Environment` includes a Mesa-like Scheduler (see the `soil.time` module. + - |check| Allow for `mesa.Model` to be used in a simulation. + +- |check| Integrate `soil.Agent` with `mesa.Agent`: + + - |check| Rename agent.id to unique_id + - |check| mesa agents can be used in soil simulations (see `examples/mesa`) + +- |check| Provide examples + + - |check| Using mesa modules in a soil simulation (see `examples/mesa`) + - |uncheck| Using soil modules in a mesa simulation (see `examples/mesa`) + +- |uncheck| Document the new APIs and usage \ No newline at end of file diff --git a/docs/tutorial/soil_tutorial.ipynb b/docs/tutorial/soil_tutorial.ipynb index da8131a..a872bc3 100644 --- a/docs/tutorial/soil_tutorial.ipynb +++ b/docs/tutorial/soil_tutorial.ipynb @@ -69,7 +69,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 64, "metadata": { "ExecuteTime": { "end_time": "2017-11-03T10:58:13.451481Z", @@ -81,6 +81,7 @@ "outputs": [], "source": [ "from soil import *\n", + "from soil import analysis\n", "import networkx as nx\n", "\n", "import matplotlib.pyplot as plt" @@ -183,6 +184,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": { "ExecuteTime": { @@ -223,7 +225,7 @@ "\n", "\n", "Any kind of agent behavior can be implemented with this `step` function.\n", - "However, it has two main drawbacks: 1) complex behaviors can get difficult both write and understand; 2) these behaviors are not composable." + "dead, it has two main drawbacks: 1) complex behaviors can get difficult both write and understand; 2) these behaviors are not composable." ] }, { @@ -275,30 +277,37 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": { "hideCode": false, "hidePrompt": false }, "source": [ - "#### Generator-based agents\n", + "#### Async agents\n", "\n", - "Another design pattern that can be very useful in some cases is to model each step (or a specific state) using generators (the `yield` keyword).\n", + "Another design pattern that can be very useful in some cases is to model each step (or a specific state) using asynchronous functions (and the `await` keyword).\n", + "Asynchronous functions will be paused on `await`, and resumed at a later step from the same point.\n", + "\n", + "The following agent will do something for `self.model.max_steps` and then stop forever.\n", "\n", "\n", "\n", "```python\n", - "class GenExample(BaseAgent):\n", - " def step(self):\n", - " for i in range(self.model.max_steps_neutral):\n", - " ... # Do something\n", - " yield # Signal the scheduler that this step is done for now\n", - " ... # Do something\n", + "class AsyncExample(BaseAgent):\n", + " async def step(self):\n", + " for i in range(self.model.max_steps):\n", + " self.do_something()\n", + " await self.delay() # Signal the scheduler that this agent is done for now\n", " return self.die(\"No need to do anything else\") \n", - "```" + "```\n", + "\n", + "Notice that this trivial example could be implemented with a regular `step` and an attribute with the counts of times the agent has run so far.\n", + "By using an `async` we avoid complicating the logic of our function or adding spurious attributes." ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": { "hideCode": false, @@ -309,10 +318,13 @@ "\n", "By default, every agent will be called in every simulation step, and the time elapsed between two steps is controlled by the `interval` attribute in the environment.\n", "\n", - "But agents may signal the scheduler when they expect to be called again.\n", + "But agents may signal the scheduler how long to wait before calling them again by returning (or `yield`ing) a value other than `None`.\n", "This is especially useful when an agent is going to be dormant for a long time.\n", - "To do so, an agent can return (or `yield`) from a `step` or a `state` a value of type `soil.When` (absolute time), `soil.Delta` (relative time) or `soil.Cond`, telling the scheduler when the agent will be ready to run again.\n", - "If it returns nothing (i.e., `None`), the agent will be ready to run at the next simulation step." + "There are two convenience methods to calculate the value to return: `Agent.delay`, which takes a time delay; and `Agent.at`, which takes an absolute time at which the agent should be awaken.\n", + "A return (or `yield`) value of `None` will default to a wait of 1 unit of time.\n", + "\n", + "When an `FSM` agent returns, it may signal two things: how long to wait, and a state to transition to.\n", + "This can be done by using the `delay` and `at` methods of each state." ] }, { @@ -330,21 +342,25 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": { "hideCode": false, "hidePrompt": false }, "source": [ - "Environment agents allow us to control the state of the environment.\n", - "In this case, we will use an environment agent to simulate a very viral event.\n", + "In our simulation, we need a way to model how TV broadcasts news, and those that have a TV are susceptible to it.\n", + "We will only model one very viral TV broadcast, which we will call an `event`, which has a high chance of infecting users with a TV.\n", + "\n", "\n", - "When the event happens, the agent will modify the probability of spreading the rumor." + "There are several ways to model this behavior.\n", + "We will do it with an Environment Agent.\n", + "Environment agents are regular agents that interact with the environment but are invisible to other agents." ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 65, "metadata": { "ExecuteTime": { "end_time": "2017-11-03T10:58:17.653736Z", @@ -360,21 +376,21 @@ "class EventGenerator(BaseAgent):\n", " level = logging.INFO\n", " \n", - " def step(self):\n", + " async def step(self):\n", " # Do nothing until the time of the event\n", - " yield When(self.model.event_time)\n", + " await self.at(self.model.event_time)\n", " self.info(\"TV event happened\")\n", " self.model.prob_tv_spread = 0.5\n", " self.model.prob_neighbor_spread *= 2\n", " self.model.prob_neighbor_spread = min(self.model.prob_neighbor_spread, 1)\n", - " yield\n", + " await self.delay()\n", " self.model.prob_tv_spread = 0\n", "\n", " while self.alive:\n", " self.model.prob_neighbor_spread = self.model.prob_neighbor_spread * self.model.neighbor_factor\n", " if self.model.prob_neighbor_spread < 0.01:\n", " return self.die(\"neighbors can no longer spread the rumour\")\n", - " yield" + " await self.delay()" ] }, { @@ -393,7 +409,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 66, "metadata": { "hideCode": false, "hidePrompt": false @@ -407,10 +423,10 @@ " prob_tv_spread = 0.1\n", " prob_neighbor_spread = 0.1\n", " event_time = 10\n", - " tv_factor = 0.5\n", " neighbor_factor = 0.9\n", "\n", " \n", + " # This function initializes the model. It is run right at the end of the `__init__` function.\n", " def init(self):\n", " self.add_model_reporter(\"prob_tv_spread\")\n", " self.add_agent(EventGenerator)" @@ -428,7 +444,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 67, "metadata": { "hideCode": false, "hidePrompt": false @@ -437,12 +453,12 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "ff6ebca13a384769a2a783fcb1808d91", + "model_id": "913bbb91650841e6afee444b2c1f4636", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "HBox(children=(IntProgress(value=0, description='NewsEnvSimple', max=1, style=ProgressStyle(description_width=…" + "NewsEnvSimple: 0%| | 0/1 [00:00\n", " \n", " \n", - " 0\n", + " 0.0\n", " 0\n", " 1\n", " 0.1\n", " \n", " \n", - " 10\n", + " 10.0\n", " 1\n", " 1\n", " 0.1\n", " \n", " \n", - " 11\n", + " 11.0\n", " 2\n", " 1\n", " 0.5\n", " \n", " \n", - " 12\n", + " 12.0\n", " 3\n", " 1\n", " 0.0\n", " \n", " \n", - " 13\n", + " 13.0\n", " 4\n", " 1\n", " 0.0\n", " \n", " \n", - " 14\n", + " 14.0\n", " 5\n", " 1\n", " 0.0\n", @@ -545,15 +554,15 @@ "text/plain": [ " step agent_count prob_tv_spread\n", "time \n", - "0 0 1 0.1\n", - "10 1 1 0.1\n", - "11 2 1 0.5\n", - "12 3 1 0.0\n", - "13 4 1 0.0\n", - "14 5 1 0.0" + "0.0 0 1 0.1\n", + "10.0 1 1 0.1\n", + "11.0 2 1 0.5\n", + "12.0 3 1 0.0\n", + "13.0 4 1 0.0\n", + "14.0 5 1 0.0" ] }, - "execution_count": 4, + "execution_count": 67, "metadata": {}, "output_type": "execute_result" } @@ -565,13 +574,14 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": { "hideCode": false, "hidePrompt": false }, "source": [ - "As we can see, the event occurred right after `t=10`, so by `t=11` the value of `prob_tv_spread` was already set to `1.0`.\n", + "As we can see, the event occurred right after `t=10`, so by `t=11` the value of `prob_tv_spread` was already set to `0.5`.\n", "\n", "You may notice nothing happened between `t=0` and `t=1`.\n", "That is because there aren't any other agents in the simulation, and our event generator explicitly waited until `t=10`." @@ -605,7 +615,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 68, "metadata": { "ExecuteTime": { "end_time": "2017-11-03T10:58:16.051690Z", @@ -620,10 +630,14 @@ " has_tv = False\n", " infected_by_friends = False\n", " \n", + " # The state decorator is used to define the states of the agent\n", " @state(default=True)\n", " def neutral(self):\n", + " # The agent might have been infected by their infected friends since the last time they were checked\n", " if self.infected_by_friends:\n", + " # Automatically transition to the infected state\n", " return self.infected\n", + " # If the agent has a TV, they might be infected by the evenn\n", " if self.has_tv:\n", " if self.prob(self.model.prob_tv_spread):\n", " return self.infected\n", @@ -632,7 +646,8 @@ " def infected(self):\n", " for neighbor in self.iter_neighbors(state_id=self.neutral.id):\n", " if self.prob(self.model.prob_neighbor_spread):\n", - " neighbor.infected_by_friends = True" + " neighbor.infected_by_friends = True\n", + " return self.delay(7) # Wait for 7 days before trying to infect their friends again" ] }, { @@ -647,7 +662,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 69, "metadata": { "hideCode": false, "hidePrompt": false @@ -659,7 +674,7 @@ "['dead', 'neutral', 'infected']" ] }, - "execution_count": 6, + "execution_count": 69, "metadata": {}, "output_type": "execute_result" } @@ -694,7 +709,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 70, "metadata": { "cell_style": "split", "hideCode": false, @@ -703,9 +718,9 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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", "text/plain": [ - "
" + "
" ] }, "metadata": {}, @@ -729,7 +744,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 71, "metadata": { "hideCode": false, "hidePrompt": false @@ -741,7 +756,6 @@ " prob_tv_spread = 0\n", " prob_neighbor_spread = 0.1\n", " event_time = 10\n", - " tv_factor = 0.5\n", " neighbor_factor = 0.9\n", "\n", " \n", @@ -756,7 +770,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 72, "metadata": { "hideCode": false, "hidePrompt": false @@ -765,12 +779,12 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "d848b48f031e4c798d7ea246d4c17260", + "model_id": "450bd9491a774e34bbb8d1454744e83f", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "HBox(children=(IntProgress(value=0, description='NewsEnvNetwork', max=1, style=ProgressStyle(description_width…" + "NewsEnvNetwork: 0%| | 0/1 [00:00\n", " \n", " \n", - " 0\n", + " 0.0\n", " 0\n", " 6\n", " 0.0\n", " 0.100000\n", " \n", " \n", - " 1\n", + " 1.0\n", " 1\n", " 6\n", " 0.0\n", " 0.100000\n", " \n", " \n", - " 2\n", + " 2.0\n", " 2\n", " 6\n", " 0.0\n", " 0.100000\n", " \n", " \n", - " 3\n", + " 3.0\n", " 3\n", " 6\n", " 0.0\n", " 0.100000\n", " \n", " \n", - " 4\n", + " 4.0\n", " 4\n", " 6\n", " 0.0\n", " 0.100000\n", " \n", " \n", - " 5\n", + " 5.0\n", " 5\n", " 6\n", " 0.0\n", " 0.100000\n", " \n", " \n", - " 6\n", + " 6.0\n", " 6\n", " 6\n", " 0.0\n", " 0.100000\n", " \n", " \n", - " 7\n", + " 7.0\n", " 7\n", " 6\n", " 0.0\n", " 0.100000\n", " \n", " \n", - " 8\n", + " 8.0\n", " 8\n", " 6\n", " 0.0\n", " 0.100000\n", " \n", " \n", - " 9\n", + " 9.0\n", " 9\n", " 6\n", " 0.0\n", " 0.100000\n", " \n", " \n", - " 10\n", + " 10.0\n", " 10\n", " 6\n", " 0.0\n", " 0.100000\n", " \n", " \n", - " 11\n", + " 11.0\n", " 11\n", " 6\n", " 0.5\n", " 0.200000\n", " \n", " \n", - " 12\n", + " 12.0\n", " 12\n", " 6\n", " 0.0\n", " 0.180000\n", " \n", " \n", - " 13\n", + " 13.0\n", " 13\n", " 6\n", " 0.0\n", " 0.162000\n", " \n", " \n", - " 14\n", + " 14.0\n", " 14\n", " 6\n", " 0.0\n", " 0.145800\n", " \n", " \n", - " 15\n", + " 15.0\n", " 15\n", " 6\n", " 0.0\n", " 0.131220\n", " \n", " \n", - " 16\n", + " 16.0\n", " 16\n", " 6\n", " 0.0\n", " 0.118098\n", " \n", " \n", - " 17\n", + " 17.0\n", " 17\n", " 6\n", " 0.0\n", " 0.106288\n", " \n", " \n", - " 18\n", + " 18.0\n", " 18\n", " 6\n", " 0.0\n", " 0.095659\n", " \n", " \n", - " 19\n", + " 19.0\n", " 19\n", " 6\n", " 0.0\n", " 0.086093\n", " \n", " \n", - " 20\n", + " 20.0\n", " 20\n", " 6\n", " 0.0\n", @@ -986,30 +993,30 @@ "text/plain": [ " step agent_count prob_tv_spread prob_neighbor_spread\n", "time \n", - "0 0 6 0.0 0.100000\n", - "1 1 6 0.0 0.100000\n", - "2 2 6 0.0 0.100000\n", - "3 3 6 0.0 0.100000\n", - "4 4 6 0.0 0.100000\n", - "5 5 6 0.0 0.100000\n", - "6 6 6 0.0 0.100000\n", - "7 7 6 0.0 0.100000\n", - "8 8 6 0.0 0.100000\n", - "9 9 6 0.0 0.100000\n", - "10 10 6 0.0 0.100000\n", - "11 11 6 0.5 0.200000\n", - "12 12 6 0.0 0.180000\n", - "13 13 6 0.0 0.162000\n", - "14 14 6 0.0 0.145800\n", - "15 15 6 0.0 0.131220\n", - "16 16 6 0.0 0.118098\n", - "17 17 6 0.0 0.106288\n", - "18 18 6 0.0 0.095659\n", - "19 19 6 0.0 0.086093\n", - "20 20 6 0.0 0.077484" + "0.0 0 6 0.0 0.100000\n", + "1.0 1 6 0.0 0.100000\n", + "2.0 2 6 0.0 0.100000\n", + "3.0 3 6 0.0 0.100000\n", + "4.0 4 6 0.0 0.100000\n", + "5.0 5 6 0.0 0.100000\n", + "6.0 6 6 0.0 0.100000\n", + "7.0 7 6 0.0 0.100000\n", + "8.0 8 6 0.0 0.100000\n", + "9.0 9 6 0.0 0.100000\n", + "10.0 10 6 0.0 0.100000\n", + "11.0 11 6 0.5 0.200000\n", + "12.0 12 6 0.0 0.180000\n", + "13.0 13 6 0.0 0.162000\n", + "14.0 14 6 0.0 0.145800\n", + "15.0 15 6 0.0 0.131220\n", + "16.0 16 6 0.0 0.118098\n", + "17.0 17 6 0.0 0.106288\n", + "18.0 18 6 0.0 0.095659\n", + "19.0 19 6 0.0 0.086093\n", + "20.0 20 6 0.0 0.077484" ] }, - "execution_count": 9, + "execution_count": 72, "metadata": {}, "output_type": "execute_result" } @@ -1033,22 +1040,27 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 73, "metadata": { "hideCode": false, "hidePrompt": false }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "No agent dataframe provided and no agent reporters found. Skipping agent plot.\n" + ] + }, { "data": { - "image/png": "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IxX0KLp168b48ePp3r07xcXFXHnllbss79ChA3fddRfHHHMMffv2ZcCAAZx2mnetVV5eHnPmzKFXr168/fbb3HrrrdF2AcDo0aMZO3Ys/fr1Y9u2bWRmZjJixAhee+01RowYEfNz69atY+jQofTr14/zzz+fP/3pT+FlOTk59O/fn7FjxzJx4sSon3/wwQcpKiqiT58+9OjRg0cffRSA3/zmN/z2t7+lf//+u8yGufLKK9m6dSvdu3fn1ltvZcCAJj2Jqd5KQj1z57yiLhI0cy41PYnCwkJXfS7z8uXL6d69e0ra41u9ejUjRowIn0xsTIYOHRo+ydrcpeK7dObD7zN/TQkAb91wNAf/JP5rEkTiZWbznHNR/5Grhy6SIMVllbTJzQo91zi6BE8nRavp0qVLwnvnV199Ne+///4u740bN46LL7641s8OGjSIH3/8cZf3nnzySXr37r3buu+++26D2ikNs7G0goN/sifzvizW1EVJCRX0AIwfP77en/3oo48S2BJJlqrtO9hcXsmB7fKY92VxeDxdJEgachFJgE3bKnEODtzbGzffWKqTohI8FXSRBPDHzPdtk8MeLTI0hi4poYIukgD+VaIFednk52YroEtSQgVdJAH8k6D5udnk52Wrhy4poYKeYHXJQ6+rr7/+mrPPPrvebRg9enT4KtamIpnHuy78HnlBXjYFeVma5SIpoYJeD4nKQ6+rfffdN2UFORk56k0pm93Pb8nPDQ25KKBLUiB9py2+dhN8uzix29ynN5x0V42rBJWHDt6VnYMGDeKdd96hpKSEiRMnctRRR7F9+3Zuuukm3n33XX788Ueuvvpqrrjiil2uYi0rK2P06NEsWbKEbt268fXXXzN+/PjwVaI333wzM2bMoGXLlrz88su0b98e8JIW77rrLjZv3sy9997LiBEjKC8v58orr6SoqIgWLVpw7733cswxxzB58mReeOEFtm7dyvbt23nvvfd2+zt88803jBw5ks2bN1NVVcUjjzzCUUcdxZ577slll12223HwIwtmz57NOeecw9ChQ7nhhhvYunUr7dq1Y/LkyXTo0IEJEybw2GOPUVFRwcEHH8yTTz5Jbm4uX3zxBeeeey5bt24Nxy2kg5KySnKyMmiZnRkq6OqhS/DUQ49ixYoVXHXVVSxfvpy99tprtzz0IUOGcOONN/L222+zYMEC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\n", + "image/png": "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JCuGESIiIpIVwwgRERHJimGEiIiIZMUwQkRERLJiGCEiIiJZMYwQERGRrByeDl4Olkli8/PzZS4JERER2cvyvV3bZO+qCCMFBQUAgLCwMJlLQkRERI4qKChAQEBAtZ+rYm0as9mMixcvws/PDxqNxmnnzc/PR1hYGM6fP++2a964+z3y/tTP3e+R96d+7n6Prrw/IQQKCgoQGhpqs4juzVRRM6LVatGmTRuXnd/f398t/4JV5u73yPtTP3e/R96f+rn7Pbrq/mqqEbFgB1YiIiKSFcMIERERyapRhxG9Xo+5c+dCr9fLXRSXcfd75P2pn7vfI+9P/dz9HpVwf6rowEpERETuq1HXjBAREZH8GEaIiIhIVgwjREREJCuGESIiIpKV24eRFStWIDw8HAaDAbGxsTh48GCN+2/evBldu3aFwWBAz5498eWXXzZQSR2XnJyMfv36wc/PDy1btsSoUaNw6tSpGo9Zt24dNBqNzWYwGBqoxI555ZVXbilr165dazxGTc8PAMLDw2+5R41Gg2nTplW5v9Kf37fffov7778foaGh0Gg02Lp1q83nQgjMmTMHrVq1gre3N+Lj4/Hrr7/Wel5Hf49dpab7KysrwwsvvICePXuiSZMmCA0Nxbhx43Dx4sUaz1mXv+euVNsznDBhwi3lHT58eK3nVcMzBFDl76NGo8GiRYuqPaeSnqE93wslJSWYNm0amjdvDl9fXzz00EPIycmp8bx1/d21l1uHkU2bNiEpKQlz585FRkYGevfujWHDhuHy5ctV7r9//36MGTMGkyZNwuHDhzFq1CiMGjUKP//8cwOX3D579+7FtGnTcODAAezatQtlZWUYOnQorl+/XuNx/v7+uHTpknU7d+5cA5XYcd27d7cp6/fff1/tvmp7fgDw448/2tzfrl27AAD/93//V+0xSn5+169fR+/evbFixYoqP3/99dfx5ptvYtWqVfjhhx/QpEkTDBs2DCUlJdWe09HfY1eq6f6KioqQkZGB2bNnIyMjA5999hlOnTqFkSNH1npeR/6eu1ptzxAAhg8fblPef/3rXzWeUy3PEIDNfV26dAlr1qyBRqPBQw89VON5lfIM7fleeO655/Cf//wHmzdvxt69e3Hx4kU8+OCDNZ63Lr+7DhFurH///mLatGnW1yaTSYSGhork5OQq93/kkUfEfffdZ/NebGys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", "text/plain": [ - "
" + "
" ] }, - "metadata": { - "needs_background": "light" - }, + "metadata": {}, "output_type": "display_data" } ], @@ -1080,7 +1092,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 74, "metadata": { "hideCode": false, "hidePrompt": false @@ -1088,31 +1100,29 @@ "outputs": [], "source": [ "class NewsEnvComplete(Environment):\n", - " prob_tv = 0.05\n", + " prob_tv = 0.1\n", " prob_tv_spread = 0\n", - " prob_neighbor_spread = 0\n", + " prob_neighbor_spread = 0.1\n", " event_time = 10\n", - " tv_factor = 0\n", " neighbor_factor = 0.5\n", " generator = \"erdos_renyi_graph\"\n", " n = 100\n", "\n", " def init(self):\n", " self.add_agent(EventGenerator)\n", - " if not self.G:\n", - " opts = {\"n\": self.n}\n", - " if self.generator == \"erdos_renyi_graph\":\n", - " opts[\"p\"] = 0.5\n", - " elif self.generator == \"barabasi_albert_graph\":\n", - " opts[\"m\"] = 4\n", - " self.create_network(generator=self.generator, **opts)\n", + " opts = {\"n\": self.n}\n", + " if self.generator == \"erdos_renyi_graph\":\n", + " opts[\"p\"] = 0.05\n", + " elif self.generator == \"barabasi_albert_graph\":\n", + " opts[\"m\"] = 2\n", + " self.create_network(generator=self.generator, **opts)\n", "\n", " self.populate_network([NewsSpread,\n", " NewsSpread.w(has_tv=True)],\n", " [1-self.prob_tv, self.prob_tv])\n", " self.add_model_reporter('prob_tv_spread')\n", " self.add_model_reporter('prob_neighbor_spread')\n", - " self.add_agent_reporter('state_id')" + " self.add_agent_reporter('state_id', lambda a: getattr(a, \"state_id\", None))" ] }, { @@ -1126,7 +1136,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 75, "metadata": { "hideCode": false, "hidePrompt": false @@ -1136,18 +1146,18 @@ "name": "stderr", "output_type": "stream", "text": [ - "[INFO ][19:22:00] Output directory: /mnt/data/home/j/git/lab.gsi/soil/soil/docs/tutorial/soil_output\n" + "[INFO ][12:09:51] Output directory: /mnt/data/home/j/git/lab.gsi/soil/soil/docs/tutorial/soil_output\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "6e72f871a2d242129f0b848caf6b5bdf", + "model_id": "7218eee842324b00b113e087ae593226", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "HBox(children=(IntProgress(value=0, description='newspread', max=10, style=ProgressStyle(description_width='in…" + "newspread: 0%| | 0/10 [00:00" + "
" ] }, - "metadata": { - "needs_background": "light" - }, + "metadata": {}, "output_type": "display_data" } ], @@ -1643,7 +1593,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 80, "metadata": { "hideCode": false, "hidePrompt": false @@ -1651,14 +1601,12 @@ "outputs": [ { "data": { - "image/png": "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jx6jxYDJoieiqZZWaLYaufNJLcXXXeykYN1JHHuzyEgvxHG6CFnsJGhIc/z6RiOMOtzFTswtgzCEWzFG+GiOO0T75WBs7EtgY98Kr+FKxumRu61NPvzww1rt/3w4nU5WrFiBn59fhQ49JCSEN954g//7v/+rsp8nn3ySRx55hFGjRvHnP/+Zjz76iClTptSS1cqh1yindu3DZjai9/HD4nvmt7JXu6XpVR5uKciEPd/B7kWQslJLH/SNgOumgn8juPmlctWlW5J9qpDTh/MoKXQSn6TNS6yYs5fMNBu+QWYaxQXQ4ZoooloHedtN/s+13sU0ZyOEoN8fz+iFlBzKxZVXgmNXJpkrU3GeLsTSPpTAgc1AJ8j9IQWdnxFjhBVrfBiGCCvmltq5DKE+NHqgyyV/LAv+vfmcYy27RXh/UXz35rZzytv2jqRdn0iKbHaWvFd+pH3bY13Pe06n08mYMWPYvHkzHTp04NNPP8VqtTJ9+nQWLVpEUVERffr04b333tM+s379SEhI4LfffmP06NG0bt2aGTNmYLfbCQ0NZc6cOTRqpOnObNu2jd69e5ORkcETTzzB5MmTsdlsDBs2jOzsbBwOBzNmzGDYsGEUFBQwYsQI0tLScLlcPP3004wcObLcSLsipkyZwoYNGygqKuLOO+/kueeeq7DeI488wrJly2jcuDFz584lPDycgwcPcv/995Oeno7VauWDDz6gbdu2jB8/HovFwpYtW4iOjmb16tXo9Xo+//xz3nzzTa699lpvvxEREURERPD9999X+hlLKfnll1/44gtNq3DcuHFMmzZNOfQrhfx9B8nzsRBQRgO9bLglzCesitYNlJxUMPpoqycP/wqLHtIyT3reA+2GaCGVs9I796w5wd51Jzl9OA97sTay9gs203lADEIIksa1w8fPhF+w+ZzTSenZxd3TZeHW0zjSi3Dn2XHlleDKtWOM8SPkztYAZH6+C3ehU9ucIdiihUdCNIVMnUlP1LO90fk0vP8me/fu5aOPPqJv375MnDiRt99+m8cff5wHHniAZ57REtjuuusuvvvuO4YMGQKA3W6ndHV3dnY2a9euRQjBhx9+yMsvv8y///1vALZv387atWspKCigS5cu3HrrrURERLBgwQICAgLIyMigV69eDB06lCVLlhAVFeV1jLm5udWy//nnnyckJASXy0VSUhLb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\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiMAAAHHCAYAAABtF1i4AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/av/WaAAAACXBIWXMAAA9hAAAPYQGoP6dpAADI4ElEQVR4nOzdd3gUVdvA4d+W7Kb3BiEQOoRO6BZaMKAiKKLiq0hVFFBAVHhVUEADKk1FsQKCFUTk/QBpUqQLCFJClRBKCi092TrfH5ENSzokbMpzX9deZmfOzHlmMZlnzzlzjkpRFAUhhBBCCAdROzoAIYQQQlRtkowIIYQQwqEkGRFCCCGEQ0kyIoQQQgiHkmRECCGEEA4lyYgQQgghHEqSESGEEEI4lCQjQgghhHAoSUaEEEII4VCSjAjhYG+99RYqlcohdf/555906tQJNzc3VCoVBw4cyLfc5s2bUalUbN68+ZbqSUxM5NFHH8XPzw+VSsWcOXNuOeY77XavXQhRNElGhLjJwoULUalUtpdWqyUkJIRBgwZx4cKFWzpnZmYmb731Vrm6oZlMJvr378/Vq1eZPXs2ixcvplatWmVS19ixY1m7di0TJ05k8eLF9OzZs9TrePfdd1mxYkWpn1cIUfa0jg5AiPJqypQp1K5dm+zsbHbt2sXChQvZtm0bhw8fxtnZuUTnyszM5O233wagS5cudvveeOMNJkyYUFphF9vp06c5e/YsX3zxBcOGDSu07L333ktWVhY6ne6W6vr999/p06cP48ePv6Xji+Pdd9/l0UcfpW/fvmVWhxCibEgyIkQBevXqRZs2bQAYNmwY/v7+zJgxg5UrV/LYY4+VWj1arRat9s7/KiYlJQHg7e1dZFm1Wl3iBOzmuopTj7h9VqsVo9F4W/9eQtxp0k0jRDHdc889QE6LwnVGo5FJkyYRERGBl5cXbm5u3HPPPWzatMlWJjY2loCAAADefvttW/fPW2+9BeQ/ZsRsNjN16lTq1q2LXq8nLCyM//73vxgMhmLF+vvvv3PPPffg5uaGt7c3ffr0ISYmxrZ/0KBBdO7cGYD+/fujUqnytNjcKL9xE126dKFp06YcPXqUrl274urqSkhICO+9956tzPUuL0VRmDdvnu3ar0tOTmbMmDGEhoai1+upV68eM2bMwGq12tVvtVqZO3cuzZo1w9nZmYCAAHr27MnevXsBUKlUZGRksGjRIlsdgwYNsh1/4cIFhgwZQlBQEHq9niZNmvD111/nuc7z58/Tt29f3NzcCAwMZOzYscX+zAcNGkRYWFie7fn9+65fv567774bb29v3N3dadiwIf/973/tyhgMBiZPnky9evXQ6/WEhoby6quv5olHpVIxatQovv32W5o0aYJer+e3334D4IcffiAiIgIPDw88PT1p1qwZc+fOLdb1CHEnScuIEMUUGxsLgI+Pj21bamoqX375JQMGDGD48OGkpaXx1VdfERUVxZ49e2jZsiUBAQF8+umnPP/88zz88MM88sgjADRv3rzAuoYNG8aiRYt49NFHefnll9m9ezfR0dHExMTwyy+/FBrnhg0b6NWrF3Xq1OGtt94iKyuLjz76iLvuuov9+/cTFhbGc889R0hICO+++y4vvvgibdu2JSgoqMSfybVr1+jZsyePPPIIjz32GMuWLeO1116jWbNm9OrVi3vvvZfFixfz9NNP06NHDwYOHGg7NjMzk86dO3PhwgWee+45atasyY4dO5g4cSLx8fF2g1yHDh3KwoUL6dWrF8OGDcNsNvPHH3+wa9cu2rRpw+LFixk2bBjt2rXj2WefBaBu3bpAzuDZDh062G7aAQEBrFmzhqFDh5KamsqYMWMAyMrKonv37sTFxfHiiy9SvXp1Fi9ezO+//17iz6UwR44c4cEHH6R58+ZMmTIFvV7PqVOn2L59u62M1WrloYceYtu2bTz77LM0btyYQ4cOMXv2bE6cOJFnbMzvv//OTz/9xKhRo/D39ycsLIz169czYMAAunfvzowZMwCIiYlh+/btvPTSS6V6TULcNkUIYWfBggUKoGzYsEG5dOmScu7cOWXZsmVKQECAotfrlXPnztnKms1mxWAw2B1/7do1JSgoSBkyZIht26VLlxRAmTx5cp76Jk+erNz4q3jgwAEFUIYNG2ZXbvz48Qqg/P7774XG37JlSyUwMFC5cuWKbdvBgwcVtVqtDBw40LZt06ZNCqAsXbq08A/khrKbNm2ybevcubMCKN98841tm8FgUIKDg5V+/frZHQ8oI0eOtNs2depUxc3NTTlx4oTd9gkTJigajUaJi4tTFEVRfv/9dwVQXnzxxTxxWa1W289ubm7KM888k6fM0KFDlWrVqimXL1+22/7EE08oXl5eSmZmpqIoijJnzhwF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QY/etfA1aXZc3EF8RjyeOk961OqRZ3/8mpMApJGFV5P6efaXlhMnpnHy5DRijr1WZnUIIW5fhw4d7FopO3bsyMmTJ7H82527b98+evfuTc2aNfHw8KBz584AeVo42rRpY/c+PT2d8ePH07hxY7y9vXF3dycmJibPcR07dszzPiYmxvZ+w4YNdO/enZCQEDw8PHj66ae5cuUKmZmZALz44otMmzaNu+66i8mTJ/P333/f0udgsViYOnUqzZo1w9fXF3d3d9auXZsn3psVFv/BgwdJT0/Hz88Pd3d32+vMmTOcPn3adkytWrXsEpGqSlpGyrmsy+dBB55hjYosW9jAVavFgibZA9Sgq1V240YuX95EQuIKQE2NGgPLrB4hyrtn53YucJ/qpq+BQ96/p+CyN/VoDnyn0+2EVWwZGRlERUURFRXFt99+S0BAAHFxcURFReUZaOnm5mb3fvz48axfv54PPviAevXq4eLiwqOPPlqiAZqxsbE8+OCDPP/887zzzjv4+vqybds2hg4ditFoxNXVlWHDhhEVFcWqVatYt24d0dHRzJw5k9GjR5foWt9//33mzp3LnDlzbGNUxowZU+IBpTdKT0+nWrVqbN68Oc8+b29v2883f3ZlLTg4mMTERLttiYmJZdIKUxKSjJRjSXHnyXJSABUtHu5baFm7gav5zS2yZheuai1mRaHGYx3KINqcBe2OHX8DgJqhg/HybFHEEUJUXk764k8oWFZli7J7926797t27aJ+/fpoNBqOHTvGlStXmD59um3Mwt69e4t13u3btzNo0CAefvhhIOfGnN8gzF27duV537hxzlIP+/btw2q1MnPmTNTqnOztp59+ynOO0NBQRowYwYgRI5g4cSJffPFFiZOR7du306dPH5566ikArFYrJ06cIDw8vNDjCou/devWJCQkoNVqCQsLK1E8Op3O1jpV2jp27MjGjRvtusDWr1+fp5XnTpNumnJsx+LvUVQq9CYr4XcVPuZixakVWBQLrQNbU9e7bp7913ZfAyBDm4azv2+ZxHvy1HQMhgRcXGpRp87YMqlDCFF64uLiGDduHMePH+f777/no48+4qWXXgKgZs2a6HQ6PvroI/755x9WrlzJ1KlTi3Xe+vXr2wZkHjx4kCeffBKrNe+YmO3bt/Pee+9x4sQJ5s2bx9KlS23116tXD5PJZKt/8eLF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", "text/plain": [ - "
" + "
" ] }, - "metadata": { - "needs_background": "light" - }, + "metadata": {}, "output_type": "display_data" } ], @@ -1700,7 +1648,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 81, "metadata": {}, "outputs": [ { @@ -1743,35 +1691,35 @@ " \n", " 0\n", " 39063f8\n", - " newspread_1682356920.2487948\n", + " newspread_1683108591.8199563\n", " erdos_renyi_graph\n", " 100\n", " 1.0\n", " \n", " \n", " 8f26adb\n", - " newspread_1682356920.2487948\n", + " newspread_1683108591.8199563\n", " barabasi_albert_graph\n", " 100\n", " 0.5\n", " \n", " \n", " 92fdcb9\n", - " newspread_1682356920.2487948\n", + " newspread_1683108591.8199563\n", " erdos_renyi_graph\n", " 100\n", " 0.25\n", " \n", " \n", " cb3dbca\n", - " newspread_1682356920.2487948\n", + " newspread_1683108591.8199563\n", " erdos_renyi_graph\n", " 100\n", " 0.5\n", " \n", " \n", " d1fe9c1\n", - " newspread_1682356920.2487948\n", + " newspread_1683108591.8199563\n", " barabasi_albert_graph\n", " 100\n", " 1.0\n", @@ -1783,22 +1731,22 @@ "text/plain": [ "key generator \\\n", "iteration_id params_id simulation_id \n", - "0 39063f8 newspread_1682356920.2487948 erdos_renyi_graph \n", - " 8f26adb newspread_1682356920.2487948 barabasi_albert_graph \n", - " 92fdcb9 newspread_1682356920.2487948 erdos_renyi_graph \n", - " cb3dbca newspread_1682356920.2487948 erdos_renyi_graph \n", - " d1fe9c1 newspread_1682356920.2487948 barabasi_albert_graph \n", + "0 39063f8 newspread_1683108591.8199563 erdos_renyi_graph \n", + " 8f26adb newspread_1683108591.8199563 barabasi_albert_graph \n", + " 92fdcb9 newspread_1683108591.8199563 erdos_renyi_graph \n", + " cb3dbca newspread_1683108591.8199563 erdos_renyi_graph \n", + " d1fe9c1 newspread_1683108591.8199563 barabasi_albert_graph \n", "\n", "key n prob_neighbor_spread \n", "iteration_id params_id simulation_id \n", - "0 39063f8 newspread_1682356920.2487948 100 1.0 \n", - " 8f26adb newspread_1682356920.2487948 100 0.5 \n", - " 92fdcb9 newspread_1682356920.2487948 100 0.25 \n", - " cb3dbca newspread_1682356920.2487948 100 0.5 \n", - " d1fe9c1 newspread_1682356920.2487948 100 1.0 " + "0 39063f8 newspread_1683108591.8199563 100 1.0 \n", + " 8f26adb newspread_1683108591.8199563 100 0.5 \n", + " 92fdcb9 newspread_1683108591.8199563 100 0.25 \n", + " cb3dbca newspread_1683108591.8199563 100 0.5 \n", + " d1fe9c1 newspread_1683108591.8199563 100 1.0 " ] }, - "execution_count": 18, + "execution_count": 81, "metadata": {}, "output_type": "execute_result" } @@ -1819,7 +1767,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 82, "metadata": {}, "outputs": [ { @@ -1892,7 +1840,7 @@ " \n", " \n", " \n", - " newspread_1682356920.2487948\n", + " newspread_1683108591.8199563\n", " 0\n", " 2\n", " None\n", @@ -1905,7 +1853,7 @@ " True\n", " ...\n", " 1\n", - " [<class 'soil.exporters.default'>]\n", + " [\"<class 'soil.exporters.default'>\"]\n", " {}\n", " {}\n", " {}\n", @@ -1917,42 +1865,42 @@ " \n", " \n", "\n", - "

1 rows × 29 columns

\n", + "

1 rows × 28 columns

\n", "" ], "text/plain": [ " index version source_file name \\\n", "simulation_id \n", - "newspread_1682356920.2487948 0 2 None newspread \n", + "newspread_1683108591.8199563 0 2 None newspread \n", "\n", " description group backup overwrite dry_run dump \\\n", "simulation_id \n", - "newspread_1682356920.2487948 None False True False True \n", + "newspread_1683108591.8199563 None False True False True \n", "\n", " ... num_processes \\\n", "simulation_id ... \n", - "newspread_1682356920.2487948 ... 1 \n", + "newspread_1683108591.8199563 ... 1 \n", "\n", - " exporters \\\n", - "simulation_id \n", - "newspread_1682356920.2487948 [] \n", + " exporters \\\n", + "simulation_id \n", + "newspread_1683108591.8199563 [\"\"] \n", "\n", " model_reporters agent_reporters tables \\\n", "simulation_id \n", - "newspread_1682356920.2487948 {} {} {} \n", + "newspread_1683108591.8199563 {} {} {} \n", "\n", " outdir \\\n", "simulation_id \n", - "newspread_1682356920.2487948 /mnt/data/home/j/git/lab.gsi/soil/soil/docs/tu... \n", + "newspread_1683108591.8199563 /mnt/data/home/j/git/lab.gsi/soil/soil/docs/tu... \n", "\n", " exporter_params level skip_test debug \n", "simulation_id \n", - "newspread_1682356920.2487948 {} 20 False False \n", + "newspread_1683108591.8199563 {} 20 False False \n", "\n", - "[1 rows x 29 columns]" + "[1 rows x 28 columns]" ] }, - "execution_count": 19, + "execution_count": 82, "metadata": {}, "output_type": "execute_result" } @@ -1973,7 +1921,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 83, "metadata": {}, "outputs": [ { @@ -2018,40 +1966,40 @@ " \n", " \n", " \n", - " newspread_1682356920.2487948\n", + " newspread_1683108591.8199563\n", " ff1d24a\n", " 0\n", " 0\n", " 101\n", - " 0\n", + " 0.0\n", " 0.0\n", " 0.0\n", " \n", " \n", " 1\n", " 101\n", - " 1\n", + " 1.0\n", " 0.0\n", " 0.0\n", " \n", " \n", " 2\n", " 101\n", - " 2\n", + " 2.0\n", " 0.0\n", " 0.0\n", " \n", " \n", " 3\n", " 101\n", - " 3\n", + " 3.0\n", " 0.0\n", " 0.0\n", " \n", " \n", " 4\n", " 101\n", - " 4\n", + " 4.0\n", " 0.0\n", " 0.0\n", " \n", @@ -2062,15 +2010,15 @@ "text/plain": [ " agent_count time \\\n", "simulation_id params_id iteration_id step \n", - "newspread_1682356920.2487948 ff1d24a 0 0 101 0 \n", - " 1 101 1 \n", - " 2 101 2 \n", - " 3 101 3 \n", - " 4 101 4 \n", + "newspread_1683108591.8199563 ff1d24a 0 0 101 0.0 \n", + " 1 101 1.0 \n", + " 2 101 2.0 \n", + " 3 101 3.0 \n", + " 4 101 4.0 \n", "\n", " prob_tv_spread \\\n", "simulation_id params_id iteration_id step \n", - "newspread_1682356920.2487948 ff1d24a 0 0 0.0 \n", + "newspread_1683108591.8199563 ff1d24a 0 0 0.0 \n", " 1 0.0 \n", " 2 0.0 \n", " 3 0.0 \n", @@ -2078,14 +2026,14 @@ "\n", " prob_neighbor_spread \n", "simulation_id params_id iteration_id step \n", - "newspread_1682356920.2487948 ff1d24a 0 0 0.0 \n", + "newspread_1683108591.8199563 ff1d24a 0 0 0.0 \n", " 1 0.0 \n", " 2 0.0 \n", " 3 0.0 \n", " 4 0.0 " ] }, - "execution_count": 20, + "execution_count": 83, "metadata": {}, "output_type": "execute_result" } @@ -2108,7 +2056,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 84, "metadata": {}, "outputs": [ { @@ -2149,7 +2097,7 @@ " \n", " \n", " \n", - " newspread_1682356920.2487948\n", + " newspread_1683108591.8199563\n", " ff1d24a\n", " 0\n", " 0\n", @@ -2179,14 +2127,14 @@ "text/plain": [ " state_id\n", "simulation_id params_id iteration_id step agent_id \n", - "newspread_1682356920.2487948 ff1d24a 0 0 0 None\n", + "newspread_1683108591.8199563 ff1d24a 0 0 0 None\n", " 1 neutral\n", " 2 neutral\n", " 3 neutral\n", " 4 neutral" ] }, - "execution_count": 21, + "execution_count": 84, "metadata": {}, "output_type": "execute_result" } diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..bd5dadd --- /dev/null +++ b/examples/README.md @@ -0,0 +1 @@ +Some of these examples are close to real life simulations, whereas some others are only a demonstration of Soil's capatibilities. diff --git a/examples/events_and_messages/README.md b/examples/cars/README.md similarity index 100% rename from examples/events_and_messages/README.md rename to examples/cars/README.md diff --git a/examples/events_and_messages/cars_sim.py b/examples/cars/cars_sim.py similarity index 88% rename from examples/events_and_messages/cars_sim.py rename to examples/cars/cars_sim.py index ceb86e6..3b38a16 100644 --- a/examples/events_and_messages/cars_sim.py +++ b/examples/cars/cars_sim.py @@ -86,7 +86,7 @@ class Driver(Evented, FSM): earnings = 0 def on_receive(self, msg, sender): - """This is not a state. It will run (and block) every time check_messages is invoked""" + """This is not a state. It will run (and block) every time process_messages is invoked""" if self.journey is None and isinstance(msg, Journey) and msg.driver is None: msg.driver = self self.journey = msg @@ -95,15 +95,14 @@ class Driver(Evented, FSM): """If there are no more passengers, stop forever""" c = self.count_agents(agent_class=Passenger) self.debug(f"Passengers left {c}") - if not c: - self.die("No more passengers") + return c - @default_state - @state - def wandering(self): + @state(default=True) + async def wandering(self): """Move around the city until a journey is accepted""" target = None - self.check_passengers() + if not self.check_passengers(): + return self.die("No passengers left") self.journey = None while self.journey is None: # No potential journeys detected (see on_receive) if target is None or not self.move_towards(target): @@ -111,14 +110,15 @@ class Driver(Evented, FSM): self.model.grid.get_neighborhood(self.pos, moore=False) ) - self.check_passengers() + if not self.check_passengers(): + return self.die("No passengers left") # This will call on_receive behind the scenes, and the agent's status will be updated - self.check_messages() - yield Delta(30) # Wait at least 30 seconds before checking again + self.process_messages() + await self.delay(30) # Wait at least 30 seconds before checking again try: # Re-send the journey to the passenger, to confirm that we have been selected - self.journey = yield self.journey.passenger.ask(self.journey, timeout=60) + self.journey = await self.journey.passenger.ask(self.journey, timeout=60, delay=5) except events.TimedOut: # No journey has been accepted. Try again self.journey = None @@ -127,18 +127,19 @@ class Driver(Evented, FSM): return self.driving @state - def driving(self): + async def driving(self): """The journey has been accepted. Pick them up and take them to their destination""" self.info(f"Driving towards Passenger {self.journey.passenger.unique_id}") while self.move_towards(self.journey.origin): - yield + await self.delay() self.info(f"Driving {self.journey.passenger.unique_id} from {self.journey.origin} to {self.journey.destination}") while self.move_towards(self.journey.destination, with_passenger=True): - yield + await self.delay() self.info("Arrived at destination") self.earnings += self.journey.tip self.model.total_earnings += self.journey.tip - self.check_passengers() + if not self.check_passengers(): + return self.die("No passengers left") return self.wandering def move_towards(self, target, with_passenger=False): @@ -167,7 +168,7 @@ class Passenger(Evented, FSM): pos = None def on_receive(self, msg, sender): - """This is not a state. It will be run synchronously every time `check_messages` is run""" + """This is not a state. It will be run synchronously every time `process_messages` is run""" if isinstance(msg, Journey): self.journey = msg @@ -175,7 +176,7 @@ class Passenger(Evented, FSM): @default_state @state - def asking(self): + async def asking(self): destination = ( self.random.randint(0, self.model.grid.height-1), self.random.randint(0, self.model.grid.width-1), @@ -195,9 +196,9 @@ class Passenger(Evented, FSM): while not self.journey: self.debug(f"Waiting for responses at: { self.pos }") try: - # This will call check_messages behind the scenes, and the agent's status will be updated + # This will call process_messages behind the scenes, and the agent's status will be updated # If you want to avoid that, you can call it with: check=False - yield self.received(expiration=expiration) + await self.received(expiration=expiration, delay=10) except events.TimedOut: self.info(f"Still no response. Waiting at: { self.pos }") self.model.broadcast( @@ -208,13 +209,13 @@ class Passenger(Evented, FSM): return self.driving_home @state - def driving_home(self): + async def driving_home(self): while ( self.pos[0] != self.journey.destination[0] or self.pos[1] != self.journey.destination[1] ): try: - yield self.received(timeout=60) + await self.received(timeout=60) except events.TimedOut: pass @@ -228,4 +229,4 @@ simulation = Simulation(name="RideHailing", parameters=dict(n_passengers=2)) if __name__ == "__main__": - easy(simulation) \ No newline at end of file + easy(simulation) diff --git a/examples/custom_generator/generator_sim.py b/examples/custom_generator/generator_sim.py index c3701e7..719917b 100644 --- a/examples/custom_generator/generator_sim.py +++ b/examples/custom_generator/generator_sim.py @@ -33,7 +33,7 @@ class GeneratorEnv(Environment): self.add_agents(CounterModel) -sim = Simulation(model=GeneratorEnv, max_steps=10, interval=1) +sim = Simulation(model=GeneratorEnv, max_steps=10) if __name__ == '__main__': sim.run(dump=False) \ No newline at end of file diff --git a/examples/custom_timeouts/custom_timeouts.py b/examples/custom_timeouts/custom_timeouts.py new file mode 100644 index 0000000..e69de29 diff --git a/examples/custom_timeouts/custom_timeouts_sim.py b/examples/custom_timeouts/custom_timeouts_sim.py index 7a80242..991450b 100644 --- a/examples/custom_timeouts/custom_timeouts_sim.py +++ b/examples/custom_timeouts/custom_timeouts_sim.py @@ -1,5 +1,4 @@ from soil.agents import FSM, state, default_state -from soil.time import Delta class Fibonacci(FSM): @@ -11,17 +10,17 @@ class Fibonacci(FSM): def counting(self): self.log("Stopping at {}".format(self.now)) prev, self["prev"] = self["prev"], max([self.now, self["prev"]]) - return None, Delta(prev) + return self.delay(prev) + class Odds(FSM): """Agent that only executes in odd t_steps""" - @default_state - @state + @state(default=True) def odds(self): self.log("Stopping at {}".format(self.now)) - return None, Delta(1 + self.now % 2) + return self.delay(1 + (self.now % 2)) from soil import Environment, Simulation @@ -35,7 +34,7 @@ class TimeoutsEnv(Environment): self.add_agent(agent_class=Odds, node_id=1) -sim = Simulation(model=TimeoutsEnv, max_steps=10, interval=1) +sim = Simulation(model=TimeoutsEnv, max_steps=10) if __name__ == "__main__": - sim.run(dump=False) \ No newline at end of file + sim.run(dump=False) diff --git a/examples/mesa/mesa_sim.py b/examples/mesa/mesa_sim.py index 1d16c47..e11a362 100644 --- a/examples/mesa/mesa_sim.py +++ b/examples/mesa/mesa_sim.py @@ -1,7 +1,7 @@ from soil import Simulation from social_wealth import MoneyEnv, graph_generator -sim = Simulation(name="mesa_sim", dump=False, max_steps=10, interval=2, model=MoneyEnv, parameters=dict(generator=graph_generator, N=10, width=50, height=50)) +sim = Simulation(name="mesa_sim", dump=False, max_steps=10, model=MoneyEnv, parameters=dict(generator=graph_generator, N=10, width=50, height=50)) if __name__ == "__main__": sim.run() diff --git a/examples/rabbits/rabbit_improved_sim.py b/examples/rabbits/rabbit_improved_sim.py index 278c81d..f4bc8df 100644 --- a/examples/rabbits/rabbit_improved_sim.py +++ b/examples/rabbits/rabbit_improved_sim.py @@ -1,5 +1,4 @@ from soil import FSM, state, default_state, BaseAgent, NetworkAgent, Environment, Simulation -from soil.time import Delta from enum import Enum from collections import Counter import logging @@ -35,7 +34,7 @@ class Rabbit(FSM, NetworkAgent): self.info("I am a newborn.") self.birth = self.now self.offspring = 0 - return self.youngling, Delta(self.sexual_maturity - self.age) + return self.youngling.delay(self.sexual_maturity - self.age) @state def youngling(self): diff --git a/examples/random_delays/random_delays_sim.py b/examples/random_delays/random_delays_sim.py index e0e8759..c259e85 100644 --- a/examples/random_delays/random_delays_sim.py +++ b/examples/random_delays/random_delays_sim.py @@ -1,9 +1,7 @@ """ -Example of setting a Example of a fully programmatic simulation, without definition files. """ from soil import Simulation, agents, Environment -from soil.time import Delta class MyAgent(agents.FSM): @@ -11,22 +9,22 @@ class MyAgent(agents.FSM): An agent that first does a ping """ - defaults = {"pong_counts": 2} + max_pongs = 2 @agents.default_state @agents.state def ping(self): self.info("Ping") - return self.pong, Delta(self.random.expovariate(1 / 16)) + return self.pong.delay(self.random.expovariate(1 / 16)) @agents.state def pong(self): self.info("Pong") - self.pong_counts -= 1 - self.info(str(self.pong_counts)) - if self.pong_counts < 1: + self.max_pongs -= 1 + self.info(str(self.max_pongs), "pongs remaining") + if self.max_pongs < 1: return self.die() - return None, Delta(self.random.expovariate(1 / 16)) + return self.delay(self.random.expovariate(1 / 16)) class RandomEnv(Environment): diff --git a/examples/terrorism/TerroristNetworkModel_sim.py b/examples/terrorism/TerroristNetworkModel_sim.py index 282d874..52e774f 100644 --- a/examples/terrorism/TerroristNetworkModel_sim.py +++ b/examples/terrorism/TerroristNetworkModel_sim.py @@ -1,5 +1,6 @@ import networkx as nx -from soil.agents import Geo, NetworkAgent, FSM, custom, state, default_state +from soil.agents import NetworkAgent, FSM, custom, state, default_state +from soil.agents.geo import Geo from soil import Environment, Simulation from soil.parameters import * from soil.utils import int_seed @@ -39,8 +40,8 @@ class TerroristEnvironment(Environment): HavenModel ], [self.ratio_civil, self.ratio_leader, self.ratio_training, self.ratio_haven]) - def generator(self, *args, **kwargs): - return nx.random_geometric_graph(*args, **kwargs, seed=int_seed(self._seed)) + def generator(self, *args, seed=None, **kwargs): + return nx.random_geometric_graph(*args, **kwargs, seed=seed or int_seed(self._seed)) class TerroristSpreadModel(FSM, Geo): """ diff --git a/examples/torvalds_sim.py b/examples/torvalds_sim.py index 2ee4f22..aa778a0 100644 --- a/examples/torvalds_sim.py +++ b/examples/torvalds_sim.py @@ -21,5 +21,4 @@ class TorvaldsEnv(Environment): sim = Simulation(name='torvalds_example', max_steps=10, - interval=2, model=TorvaldsEnv) \ No newline at end of file diff --git a/soil/VERSION b/soil/VERSION index 8862dba..1bb1990 100644 --- a/soil/VERSION +++ b/soil/VERSION @@ -1 +1 @@ -1.0.0rc2 +1.0.0rc3 diff --git a/soil/__init__.py b/soil/__init__.py index 8aadde8..a4ce59d 100644 --- a/soil/__init__.py +++ b/soil/__init__.py @@ -16,7 +16,6 @@ except NameError: basestring = str from pathlib import Path -from .analysis import * from .agents import * from . import agents from .simulation import * diff --git a/soil/agents/__init__.py b/soil/agents/__init__.py index df2fd15..4de10b7 100644 --- a/soil/agents/__init__.py +++ b/soil/agents/__init__.py @@ -25,6 +25,35 @@ from .. import serialization, network, utils, time, config IGNORED_FIELDS = ("model", "logger") +def decorate_generator_step(func, name): + @wraps(func) + def decorated(self): + while True: + if self._coroutine is None: + self._coroutine = func(self) + try: + if self._last_except: + val = self._coroutine.throw(self._last_except) + else: + val = self._coroutine.send(self._last_return) + except StopIteration as ex: + self._coroutine = None + val = ex.value + finally: + self._last_return = None + self._last_except = None + return float(val) if val is not None else val + return decorated + + +def decorate_normal_func(func, name): + @wraps(func) + def decorated(self): + val = func(self) + return float(val) if val is not None else val + return decorated + + class MetaAgent(ABCMeta): def __new__(mcls, name, bases, namespace): defaults = {} @@ -36,34 +65,23 @@ class MetaAgent(ABCMeta): new_nmspc = { "_defaults": defaults, - "_last_return": None, - "_last_except": None, } for attr, func in namespace.items(): - if attr == "step" and inspect.isgeneratorfunction(func): - orig_func = func - new_nmspc["_coroutine"] = None - - @wraps(func) - def func(self): - while True: - if not self._coroutine: - self._coroutine = orig_func(self) - try: - if self._last_except: - return self._coroutine.throw(self._last_except) - else: - return self._coroutine.send(self._last_return) - except StopIteration as ex: - self._coroutine = None - return ex.value - finally: - self._last_return = None - self._last_except = None - - func.id = name or func.__name__ - func.is_default = False + if attr == "step": + if inspect.isgeneratorfunction(func) or inspect.iscoroutinefunction(func): + func = decorate_generator_step(func, attr) + new_nmspc.update({ + "_last_return": None, + "_last_except": None, + "_coroutine": None, + }) + elif inspect.isasyncgenfunction(func): + raise ValueError("Illegal step function: {}. It probably mixes both async/await and yield".format(func)) + elif inspect.isfunction(func): + func = decorate_normal_func(func, attr) + else: + raise ValueError("Illegal step function: {}".format(func)) new_nmspc[attr] = func elif ( isinstance(func, types.FunctionType) @@ -74,9 +92,13 @@ class MetaAgent(ABCMeta): new_nmspc[attr] = func elif attr == "defaults": defaults.update(func) + elif inspect.isfunction(func): + new_nmspc[attr] = func else: defaults[attr] = copy(func) + + # Add attributes for their use in the decorated functions return super().__new__(mcls, name, bases, new_nmspc) @@ -92,7 +114,7 @@ class BaseAgent(MesaAgent, MutableMapping, metaclass=MetaAgent): Any attribute that is not preceded by an underscore (`_`) will also be added to its state. """ - def __init__(self, unique_id, model, name=None, init=True, interval=None, **kwargs): + def __init__(self, unique_id, model, name=None, init=True, **kwargs): assert isinstance(unique_id, int) super().__init__(unique_id=unique_id, model=model) @@ -102,7 +124,6 @@ class BaseAgent(MesaAgent, MutableMapping, metaclass=MetaAgent): self.alive = True - self.interval = interval or self.get("interval", 1) logger = utils.logger.getChild(getattr(self.model, "id", self.model)).getChild( self.name ) @@ -111,13 +132,18 @@ class BaseAgent(MesaAgent, MutableMapping, metaclass=MetaAgent): if hasattr(self, "level"): self.logger.setLevel(self.level) + for k in self._defaults: + v = getattr(model, k, None) + if v is not None: + setattr(self, k, v) + for (k, v) in self._defaults.items(): if not hasattr(self, k) or getattr(self, k) is None: setattr(self, k, deepcopy(v)) for (k, v) in kwargs.items(): - setattr(self, k, v) + if init: self.init() @@ -189,11 +215,13 @@ class BaseAgent(MesaAgent, MutableMapping, metaclass=MetaAgent): return it def get(self, key, default=None): - if key in self: - return self[key] - elif key in self.model: - return self.model[key] - return default + try: + return getattr(self, key) + except AttributeError: + try: + return getattr(self.model, key) + except AttributeError: + return default @property def now(self): @@ -206,17 +234,18 @@ class BaseAgent(MesaAgent, MutableMapping, metaclass=MetaAgent): def die(self, msg=None): if msg: self.info("Agent dying:", msg) - self.debug(f"agent dying") + else: + self.debug(f"agent dying") self.alive = False try: self.model.schedule.remove(self) except KeyError: pass - return time.NEVER + return time.Delay(time.INFINITY) def step(self): raise NotImplementedError("Agent must implement step method") - + def _check_alive(self): if not self.alive: raise time.DeadAgent(self.unique_id) @@ -265,6 +294,12 @@ class BaseAgent(MesaAgent, MutableMapping, metaclass=MetaAgent): def __repr__(self): return f"{self.__class__.__name__}({self.unique_id})" + + def at(self, at): + return time.Delay(float(at) - self.now) + + def delay(self, delay=1): + return time.Delay(delay) def prob(prob, random): @@ -450,8 +485,10 @@ def filter_agents( state = state or dict() state.update(kwargs) - for k, v in state.items(): - f = filter(lambda agent: getattr(agent, k, None) == v, f) + for k, vs in state.items(): + if not isinstance(vs, list): + vs = [vs] + f = filter(lambda agent: any(getattr(agent, k, None) == v for v in vs), f) if limit is not None: f = islice(f, limit) @@ -658,15 +695,6 @@ from .SISaModel import * from .CounterModel import * -try: - import scipy - from .Geo import Geo -except ImportError: - import sys - - print("Could not load the Geo Agent, scipy is not installed", file=sys.stderr) - - def custom(cls, **kwargs): """Create a new class from a template class and keyword arguments""" return type(cls.__name__, (cls,), kwargs) diff --git a/soil/agents/evented.py b/soil/agents/evented.py index 22e1191..5cf69dc 100644 --- a/soil/agents/evented.py +++ b/soil/agents/evented.py @@ -1,42 +1,8 @@ from . import BaseAgent from ..events import Message, Tell, Ask, TimedOut -from ..time import BaseCond from functools import partial from collections import deque - - -class ReceivedOrTimeout(BaseCond): - def __init__( - self, agent, expiration=None, timeout=None, check=True, ignore=False, **kwargs - ): - if expiration is None: - if timeout is not None: - expiration = agent.now + timeout - self.expiration = expiration - self.ignore = ignore - self.check = check - super().__init__(**kwargs) - - def expired(self, time): - return self.expiration and self.expiration < time - - def ready(self, agent, time): - return len(agent._inbox) or self.expired(time) - - def return_value(self, agent): - if not self.ignore and self.expired(agent.now): - raise TimedOut("No messages received") - if self.check: - agent.check_messages() - return None - - def schedule_next(self, time, delta, first=False): - if self._delta is not None: - delta = self._delta - return (time + delta, self) - - def __repr__(self): - return f"ReceivedOrTimeout(expires={self.expiration})" +from types import coroutine class EventedAgent(BaseAgent): @@ -48,30 +14,45 @@ class EventedAgent(BaseAgent): def on_receive(self, *args, **kwargs): pass - def received(self, *args, **kwargs): - return ReceivedOrTimeout(self, *args, **kwargs) + @coroutine + def received(self, expiration=None, timeout=60, delay=1, process=True): + if not expiration: + expiration = self.now + timeout + while self.now < expiration: + if self._inbox: + msgs = self._inbox + if process: + self.process_messages() + return msgs + yield self.delay(delay) + raise TimedOut("No message received") def tell(self, msg, sender=None): self._inbox.append(Tell(timestamp=self.now, payload=msg, sender=sender)) - def ask(self, msg, timeout=None, **kwargs): + @coroutine + def ask(self, msg, expiration=None, timeout=None, delay=1): ask = Ask(timestamp=self.now, payload=msg, sender=self) self._inbox.append(ask) expiration = float("inf") if timeout is None else self.now + timeout - return ask.replied(expiration=expiration, **kwargs) - - def check_messages(self): - changed = False - while self._inbox: - msg = self._inbox.popleft() + while self.now < expiration: + if ask.reply: + return ask.reply + yield self.delay(delay) + raise TimedOut("No reply received") + + def process_messages(self): + valid = list() + for msg in self._inbox: self._processed += 1 if msg.expired(self.now): continue - changed = True + valid.append(msg) reply = self.on_receive(msg.payload, sender=msg.sender) if isinstance(msg, Ask): msg.reply = reply - return changed + self._inbox.clear() + return valid Evented = EventedAgent diff --git a/soil/agents/fsm.py b/soil/agents/fsm.py index 03070ac..85a5fb5 100644 --- a/soil/agents/fsm.py +++ b/soil/agents/fsm.py @@ -1,47 +1,69 @@ from . import MetaAgent, BaseAgent -from ..time import Delta - +from .. import time +from types import coroutine from functools import partial, wraps import inspect +class State: + __slots__ = ("awaitable", "f", "generator", "name", "default") + + def __init__(self, f, name, default, generator, awaitable): + self.f = f + self.name = name + self.generator = generator + self.awaitable = awaitable + self.default = default + + @coroutine + def step(self, obj): + if self.generator or self.awaitable: + f = self.f + next_state = yield from f(obj) + return next_state + + else: + return self.f(obj) + + @property + def id(self): + return self.name + + def __call__(self, *args, **kwargs): + raise Exception("States should not be called directly") + +class UnboundState(State): + + def bind(self, obj): + bs = BoundState(self.f, self.name, self.default, self.generator, self.awaitable, obj=obj) + setattr(obj, self.name, bs) + return bs + + +class BoundState(State): + __slots__ = ("obj", ) + + def __init__(self, *args, obj): + super().__init__(*args) + self.obj = obj + + def delay(self, delta=0): + return self, self.obj.delay(delta) + + def at(self, when): + return self, self.obj.at(when) + + def state(name=None, default=False): def decorator(func, name=None): """ A state function should return either a state id, or a tuple (state_id, when) The default value for state_id is the current state id. - The default value for when is the interval defined in the environment. """ - if inspect.isgeneratorfunction(func): - orig_func = func - - @wraps(func) - def func(self): - while True: - if not self._coroutine: - self._coroutine = orig_func(self) - - try: - if self._last_except: - n = self._coroutine.throw(self._last_except) - else: - n = self._coroutine.send(self._last_return) - if n: - return None, n - return n - except StopIteration as ex: - self._coroutine = None - next_state = ex.value - if next_state is not None: - self._set_state(next_state) - return next_state - finally: - self._last_return = None - self._last_except = None - - func.id = name or func.__name__ - func.is_default = default - return func + name = name or func.__name__ + generator = inspect.isgeneratorfunction(func) + awaitable = inspect.iscoroutinefunction(func) or inspect.isasyncgen(func) + return UnboundState(func, name, default, generator, awaitable) if callable(name): return decorator(name) @@ -50,7 +72,7 @@ def state(name=None, default=False): def default_state(func): - func.is_default = True + func.default = True return func @@ -62,42 +84,45 @@ class MetaFSM(MetaAgent): for i in bases: if isinstance(i, MetaFSM): for state_id, state in i._states.items(): - if state.is_default: + if state.default: default_state = state states[state_id] = state # Add new states for attr, func in namespace.items(): - if hasattr(func, "id"): - if func.is_default: + if isinstance(func, State): + if func.default: default_state = func - states[func.id] = func + states[func.name] = func namespace.update( { - "_default_state": default_state, + "_state": default_state, "_states": states, } ) - return super(MetaFSM, mcls).__new__( + cls = super(MetaFSM, mcls).__new__( mcls=mcls, name=name, bases=bases, namespace=namespace ) + for (k, v) in states.items(): + setattr(cls, k, v) + return cls class FSM(BaseAgent, metaclass=MetaFSM): - def __init__(self, init=True, **kwargs): + def __init__(self, init=True, state_id=None, **kwargs): super().__init__(**kwargs, init=False) - if not hasattr(self, "state_id"): - if not self._default_state: - raise ValueError( - "No default state specified for {}".format(self.unique_id) - ) - self.state_id = self._default_state.id - - self._coroutine = None - self.default_interval = Delta(self.model.interval) - self._set_state(self.state_id) + if state_id is not None: + self._set_state(state_id) + # If more than "dead" state is defined, but no default state + if len(self._states) > 1 and not self._state: + raise ValueError( + f"No default state specified for {type(self)}({self.unique_id})" + ) + for (k, v) in self._states.items(): + setattr(self, k, v.bind(self)) + if init: self.init() @@ -105,44 +130,46 @@ class FSM(BaseAgent, metaclass=MetaFSM): def states(cls): return list(cls._states.keys()) - def step(self): - self.debug(f"Agent {self.unique_id} @ state {self.state_id}") + @property + def state_id(self): + return self._state.name + + def set_state(self, value): + if self.now > 0: + raise ValueError("Cannot change state after init") + self._set_state(value) + def step(self): self._check_alive() - next_state = self._states[self.state_id](self) + next_state = yield from self._state.step(self) - when = None try: - next_state, *when = next_state - if not when: - when = None - elif len(when) == 1: - when = when[0] - else: - raise ValueError( - "Too many values returned. Only state (and time) allowed" - ) - except TypeError: - pass - - if next_state is not None: - self._set_state(next_state) - - return when or self.default_interval - - def _set_state(self, state, when=None): - if hasattr(state, "id"): - state = state.id - if state not in self._states: + next_state, when = next_state + except (TypeError, ValueError) as ex: + try: + self._set_state(next_state) + return None + except ValueError: + return next_state + + self._set_state(next_state) + return when + + def _set_state(self, state): + if state is None: + return + if isinstance(state, str): + if state not in self._states: + raise ValueError("{} is not a valid state".format(state)) + state = self._states[state] + if not isinstance(state, State): raise ValueError("{} is not a valid state".format(state)) - self.state_id = state - if when is not None: - self.model.schedule.add(self, when=when) - return state + self._state = state def die(self, *args, **kwargs): - return self.dead, super().die(*args, **kwargs) + super().die(*args, **kwargs) + return self.dead.at(time.INFINITY) @state def dead(self): - return self.die() + return time.INFINITY \ No newline at end of file diff --git a/soil/agents/Geo.py b/soil/agents/geo.py similarity index 100% rename from soil/agents/Geo.py rename to soil/agents/geo.py diff --git a/soil/agents/network_agents.py b/soil/agents/network_agents.py index 1633976..2d0a948 100644 --- a/soil/agents/network_agents.py +++ b/soil/agents/network_agents.py @@ -6,7 +6,7 @@ class NetworkAgent(BaseAgent): super().__init__(*args, init=False, **kwargs) self.G = topology or self.model.G - assert self.G + assert self.G is not None, "Network agents should have a network" if node_id is None: nodes = self.random.choices(list(self.G.nodes), k=len(self.G)) for n_id in nodes: @@ -25,8 +25,6 @@ class NetworkAgent(BaseAgent): def count_neighbors(self, state_id=None, **kwargs): return len(self.get_neighbors(state_id=state_id, **kwargs)) - if init: - self.init() def iter_neighbors(self, **kwargs): return self.iter_agents(limit_neighbors=True, **kwargs) diff --git a/soil/analysis.py b/soil/analysis.py index 1854c0f..ab7164c 100644 --- a/soil/analysis.py +++ b/soil/analysis.py @@ -28,7 +28,8 @@ def plot(env, agent_df=None, model_df=None, steps=False, ignore=["agent_count", Results = namedtuple("Results", ["config", "parameters", "env", "agents"]) -#TODO implement reading from CSV and SQLITE +#TODO implement reading from CSV + def read_sql(fpath=None, name=None, include_agents=False): if not (fpath is None) ^ (name is None): raise ValueError("Specify either a path or a simulation name") diff --git a/soil/datacollection.py b/soil/datacollection.py index 79bdc44..9687435 100644 --- a/soil/datacollection.py +++ b/soil/datacollection.py @@ -9,7 +9,7 @@ class SoilCollector(MDC): if 'agent_count' not in model_reporters: model_reporters['agent_count'] = lambda m: m.schedule.get_agent_count() if 'time' not in model_reporters: - model_reporters['time'] = lambda m: m.now + model_reporters['time'] = lambda m: m.schedule.time # if 'state_id' not in agent_reporters: # agent_reporters['state_id'] = lambda agent: getattr(agent, 'state_id', None) diff --git a/soil/environment.py b/soil/environment.py index 1d48e2b..5188739 100644 --- a/soil/environment.py +++ b/soil/environment.py @@ -16,7 +16,7 @@ import networkx as nx from mesa import Model, Agent -from . import agents as agentmod, datacollection, serialization, utils, time, network, events +from . import agents as agentmod, datacollection, utils, time, network, events # TODO: maybe add metaclass to read attributes of a model @@ -35,6 +35,7 @@ class BaseEnvironment(Model): """ collector_class = datacollection.SoilCollector + schedule_class = time.TimedActivation def __new__(cls, *args: Any, @@ -49,7 +50,6 @@ class BaseEnvironment(Model): self = super().__new__(cls, *args, seed=seed, **kwargs) self.dir_path = dir_path or os.getcwd() collector_class = collector_class or cls.collector_class - collector_class = serialization.deserialize(collector_class) self.datacollector = collector_class( model_reporters=model_reporters, agent_reporters=agent_reporters, @@ -60,7 +60,7 @@ class BaseEnvironment(Model): if isinstance(v, property): v = v.fget if getattr(v, "add_to_report", False): - self.add_model_reporter(k, v) + self.add_model_reporter(k, k) return self @@ -70,8 +70,8 @@ class BaseEnvironment(Model): id="unnamed_env", seed="default", dir_path=None, - schedule_class=time.TimedActivation, - interval=1, + schedule=None, + schedule_class=None, logger = None, agents: Optional[Dict] = None, collector_class: type = datacollection.SoilCollector, @@ -94,13 +94,11 @@ class BaseEnvironment(Model): else: self.logger = utils.logger.getChild(self.id) - if schedule_class is None: - schedule_class = time.TimedActivation - else: - schedule_class = serialization.deserialize(schedule_class) - - self.interval = interval - self.schedule = schedule_class(self) + self.schedule = schedule + if schedule is None: + if schedule_class is None: + schedule_class = self.schedule_class + self.schedule = schedule_class(self) for (k, v) in env_params.items(): self[k] = v @@ -161,7 +159,7 @@ class BaseEnvironment(Model): if unique_id is None: unique_id = self.next_id() - a = serialization.deserialize(agent_class)(unique_id=unique_id, model=self, **agent) + a = agent_class(unique_id=unique_id, model=self, **agent) self.schedule.add(a) return a @@ -204,14 +202,14 @@ class BaseEnvironment(Model): def add_model_reporter(self, name, func=None): if not func: - func = lambda env: getattr(env, name) + func = name self.datacollector._new_model_reporter(name, func) - def add_agent_reporter(self, name, agent_type=None): - if agent_type: - reporter = lambda a: getattr(a, name) if isinstance(a, agent_type) else None - else: - reporter = lambda a: getattr(a, name, None) + def add_agent_reporter(self, name, reporter=None, agent_type=None): + if not agent_type and not reporter: + reporter = name + elif agent_type: + reporter = lambda a: reporter(a) if isinstance(a, agent_type) else None self.datacollector._new_agent_reporter(name, reporter) @classmethod @@ -278,8 +276,6 @@ class NetworkEnvironment(BaseEnvironment): super().__init__(*args, **kwargs, init=False) self.agent_class = agent_class - if agent_class: - self.agent_class = serialization.deserialize(agent_class) if self.agent_class: self.populate_network(self.agent_class) self._check_agent_nodes() @@ -309,7 +305,15 @@ class NetworkEnvironment(BaseEnvironment): elif path is not None: topology = network.from_topology(path, dir_path=self.dir_path) elif generator is not None: - topology = network.from_params(generator=generator, dir_path=self.dir_path, **network_params) + params = dict(generator=generator, + dir_path=self.dir_path, + seed=self.random, + **network_params) + try: + topology = network.from_params(**params) + except TypeError: + del params["seed"] + topology = network.from_params(**params) else: raise ValueError("topology must be a networkx.Graph or a string, or network_generator must be provided") self.G = topology diff --git a/soil/events.py b/soil/events.py index 82beaff..275d222 100644 --- a/soil/events.py +++ b/soil/events.py @@ -1,4 +1,3 @@ -from .time import BaseCond from dataclasses import dataclass, field from typing import Any from uuid import uuid4 @@ -24,29 +23,9 @@ class Reply(Message): source: Message -class ReplyCond(BaseCond): - def __init__(self, ask, *args, **kwargs): - self._ask = ask - super().__init__(*args, **kwargs) - - def ready(self, agent, time): - return self._ask.reply is not None or self._ask.expired(time) - - def return_value(self, agent): - if self._ask.expired(agent.now): - raise TimedOut() - return self._ask.reply - - def __repr__(self): - return f"ReplyCond({self._ask.id})" - - class Ask(Message): reply: Message = None - def replied(self, expiration=None): - return ReplyCond(self) - class Tell(Message): pass diff --git a/soil/exporters.py b/soil/exporters.py index d4debdd..8986453 100644 --- a/soil/exporters.py +++ b/soil/exporters.py @@ -2,11 +2,9 @@ import os import sys from time import time as current_time from io import BytesIO -from sqlalchemy import create_engine from textwrap import dedent, indent -import matplotlib.pyplot as plt import networkx as nx import pandas as pd @@ -124,6 +122,9 @@ class SQLite(Exporter): if not self.dump: logger.debug("NOT dumping results") return + + from sqlalchemy import create_engine + self.dbpath = os.path.join(self.outdir, f"{self.simulation.name}.sqlite") logger.info("Dumping results to %s", self.dbpath) if self.simulation.backup: @@ -175,7 +176,6 @@ class csv(Exporter): df.to_csv(f) -# TODO: reimplement GEXF exporting without history class gexf(Exporter): def iteration_end(self, env, *args, **kwargs): if not self.dump: @@ -186,8 +186,7 @@ class gexf(Exporter): "[GEXF] Dumping simulation {} iteration {}".format(self.simulation.name, env.id) ): with self.output("{}.gexf".format(env.id), mode="wb") as f: - network.dump_gexf(env.history_to_graph(), f) - self.dump_gexf(env, f) + nx.write_gexf(env.G, f) class dummy(Exporter): @@ -210,6 +209,7 @@ class dummy(Exporter): class graphdrawing(Exporter): def iteration_end(self, env, *args, **kwargs): + import matplotlib.pyplot as plt # Outside effects f = plt.figure() nx.draw( diff --git a/soil/serialization.py b/soil/serialization.py index 45d0083..6b70554 100644 --- a/soil/serialization.py +++ b/soil/serialization.py @@ -103,7 +103,13 @@ def load_config(cfg): yield from load_files(cfg) -builtins = importlib.import_module("builtins") +_BUILTINS = None + +def builtins(): + global _BUILTINS + if not _BUILTINS: + _BUILTINS = importlib.import_module("builtins") + return _BUILTINS KNOWN_MODULES = { 'soil': None, @@ -163,7 +169,7 @@ def name(value, known_modules=KNOWN_MODULES): if not isinstance(value, type): # Get the class name first value = type(value) tname = value.__name__ - if hasattr(builtins, tname): + if hasattr(builtins(), tname): return tname modname = value.__module__ if modname == "__main__": @@ -178,7 +184,7 @@ def name(value, known_modules=KNOWN_MODULES): def serializer(type_): - if type_ != "str" and hasattr(builtins, type_): + if type_ != "str": return repr return lambda x: x @@ -216,8 +222,8 @@ def deserializer(type_, known_modules=KNOWN_MODULES): return lambda x="": x if type_ == "None": return lambda x=None: None - if hasattr(builtins, type_): # Check if it's a builtin type - cls = getattr(builtins, type_) + if hasattr(builtins(), type_): # Check if it's a builtin type + cls = getattr(builtins(), type_) return lambda x=None: ast.literal_eval(x) if x is not None else cls() match = IS_CLASS.match(type_) if match: diff --git a/soil/simulation.py b/soil/simulation.py index c243208..9d1a20e 100644 --- a/soil/simulation.py +++ b/soil/simulation.py @@ -23,7 +23,7 @@ import json from . import serialization, exporters, utils, basestring, agents -from .environment import Environment +from . import environment from .utils import logger, run_and_return_exceptions from .debugging import set_trace @@ -49,8 +49,6 @@ def _iter_queued(): # TODO: change documentation for simulation -# TODO: rename iterations to iterations -# TODO: make parameters a dict of iterable/any @dataclass class Simulation: """ @@ -68,7 +66,6 @@ class Simulation: dir_path: The directory path to use for the simulation. max_time: The maximum time to run the simulation. max_steps: The maximum number of steps to run the simulation. - interval: The interval to use for the simulation. iterations: The number of iterations (times) to run the simulation. num_processes: The number of processes to use for the simulation. If greater than one, simulations will be performed in parallel. This may make debugging and error handling difficult. tables: The tables to use in the simulation datacollector @@ -96,7 +93,6 @@ class Simulation: dir_path: str = field(default_factory=lambda: os.getcwd()) max_time: float = None max_steps: int = None - interval: int = 1 iterations: int = 1 num_processes: Optional[int] = 1 exporters: Optional[List[str]] = field(default_factory=lambda: [exporters.default]) @@ -126,15 +122,9 @@ class Simulation: if isinstance(self.model, str): self.model = serialization.deserialize(self.model) - def deserialize_reporters(reporters): - for (k, v) in reporters.items(): - if isinstance(v, str) and v.startswith("py:"): - reporters[k] = serialization.deserialize(v.split(":", 1)[1]) - return reporters - - self.agent_reporters = deserialize_reporters(self.agent_reporters) - self.model_reporters = deserialize_reporters(self.model_reporters) - self.tables = deserialize_reporters(self.tables) + self.agent_reporters = self.agent_reporters + self.model_reporters = self.model_reporters + self.tables = self.tables self.id = f"{self.name}_{current_time()}" def run(self, **kwargs): @@ -142,15 +132,6 @@ class Simulation: if kwargs: return replace(self, **kwargs).run() - self.logger.debug( - dedent( - """ - Simulation: - --- - """ - ) - + self.to_yaml() - ) param_combinations = self._collect_params(**kwargs) if _AVOID_RUNNING: _QUEUED.extend((self, param) for param in param_combinations) @@ -244,7 +225,6 @@ class Simulation: id=iteration_id, seed=f"{self.seed}_iteration_{iteration_id}", dir_path=self.dir_path, - interval=self.interval, logger=self.logger.getChild(iteration_id), agent_reporters=agent_reporters, model_reporters=model_reporters, @@ -359,8 +339,11 @@ def iter_from_py(pyfile, module_name='imported_file', **kwargs): for sim in _iter_queued(): sims.append(sim) if not sims: - for (_name, sim) in inspect.getmembers(module, lambda x: inspect.isclass(x) and issubclass(x, Simulation)): - sims.append(sim(**kwargs)) + for (_name, env) in inspect.getmembers(module, + lambda x: inspect.isclass(x) and + issubclass(x, environment.Environment) and + (getattr(x, "__module__", None) != environment.__name__)): + sims.append(Simulation(model=env, **kwargs)) del sys.modules[module_name] assert not _AVOID_RUNNING if not sims: diff --git a/soil/time.py b/soil/time.py index b179bff..de76dcb 100644 --- a/soil/time.py +++ b/soil/time.py @@ -1,7 +1,9 @@ from mesa.time import BaseScheduler from queue import Empty from heapq import heappush, heappop, heapreplace +from collections import deque import math +import logging from inspect import getsource from numbers import Number @@ -13,119 +15,54 @@ from mesa import Agent as MesaAgent INFINITY = float("inf") - -class DeadAgent(Exception): - pass - - -class When: - def __init__(self, time): - if isinstance(time, When): - return time - self._time = time - - def abs(self, time): - return self._time - - def schedule_next(self, time, delta, first=False): - return (self._time, None) - - -NEVER = When(INFINITY) - - -class Delta(When): +class Delay: + """A delay object which can be used both as a return value and as an awaitable (in async code).""" + __slots__ = ("delta", ) def __init__(self, delta): - self._delta = delta - - def abs(self, time): - return self._time + self._delta - - def __eq__(self, other): - if isinstance(other, Delta): - return self._delta == other._delta - return False - - def schedule_next(self, time, delta, first=False): - return (time + self._delta, None) - - def __repr__(self): - return str(f"Delta({self._delta})") - - -class BaseCond: - def __init__(self, msg=None, delta=None, eager=False): - self._msg = msg - self._delta = delta - self.eager = eager - - def schedule_next(self, time, delta, first=False): - if first and self.eager: - return (time, self) - if self._delta: - delta = self._delta - return (time + delta, self) - - def return_value(self, agent): - return None + self.delta = float(delta) - def __repr__(self): - return self._msg or self.__class__.__name__ + def __float__(self): + return self.delta + + def __await__(self): + return (yield self.delta) -class Cond(BaseCond): - def __init__(self, func, *args, **kwargs): - self._func = func - super().__init__(*args, **kwargs) - - def ready(self, agent, time): - return self._func(agent) - - def __repr__(self): - if self._msg: - return self._msg - return str(f'Cond("{dedent(getsource(self._func)).strip()}")') +class DeadAgent(Exception): + pass -class TimedActivation(BaseScheduler): - """A scheduler which activates each agent when the agent requests. +class PQueueActivation(BaseScheduler): + """ + A scheduler which activates each agent with a delay returned by the agent's step method. + If no delay is returned, a default of 1 is used. + In each activation, each agent will update its 'next_time'. """ def __init__(self, *args, shuffle=True, **kwargs): super().__init__(*args, **kwargs) - self._next = {} self._queue = [] self._shuffle = shuffle - # self.step_interval = getattr(self.model, "interval", 1) - self.step_interval = self.model.interval self.logger = getattr(self.model, "logger", logger).getChild(f"time_{ self.model }") self.next_time = self.time def add(self, agent: MesaAgent, when=None): if when is None: when = self.time - elif isinstance(when, When): - when = when.abs() + else: + when = float(when) self._schedule(agent, None, when) super().add(agent) - def _schedule(self, agent, condition=None, when=None, replace=False): - if condition: - if not when: - when, condition = condition.schedule_next( - when or self.time, self.step_interval - ) - else: - if when is None: - when = self.time + self.step_interval - condition = None + def _schedule(self, agent, when=None, replace=False): + if when is None: + when = self.time if self._shuffle: - key = (when, self.model.random.random(), condition) + key = (when, self.model.random.random()) else: - key = (when, agent.unique_id, condition) - self._next[agent.unique_id] = key + key = (when, agent.unique_id) if replace: heapreplace(self._queue, (key, agent)) else: @@ -137,70 +74,104 @@ class TimedActivation(BaseScheduler): an agent will signal when it wants to be scheduled next. """ - self.logger.debug(f"Simulation step {self.time}") - if not self.model.running or self.time == INFINITY: + if self.time == INFINITY: return - self.logger.debug(f"Queue length: %s", len(self._queue)) + next_time = INFINITY + + now = self.time while self._queue: - ((when, _id, cond), agent) = self._queue[0] - if when > self.time: + ((when, _id), agent) = self._queue[0] + if when > now: + next_time = when break - if cond: - if not cond.ready(agent, self.time): - self._schedule(agent, cond, replace=True) - continue - try: - agent._last_return = cond.return_value(agent) - except Exception as ex: - agent._last_except = ex - else: - agent._last_return = None - agent._last_except = None - - self.logger.debug("Stepping agent %s", agent) - self._next.pop(agent.unique_id, None) - try: - returned = agent.step() + when = agent.step() or 1 + when += now except DeadAgent: - agent.alive = False heappop(self._queue) continue - # Check status for MESA agents - if not getattr(agent, "alive", True): + if when == INFINITY: heappop(self._queue) continue - if returned: - next_check = returned.schedule_next( - self.time, self.step_interval, first=True - ) - self._schedule(agent, when=next_check[0], condition=next_check[1], replace=True) - else: - next_check = (self.time + self.step_interval, None) - - self._schedule(agent, replace=True) + self._schedule(agent, when, replace=True) self.steps += 1 - if not self._queue: + self.time = next_time + + if next_time == INFINITY: self.model.running = False self.time = INFINITY return - next_time = self._queue[0][0][0] - if next_time < self.time: - raise Exception( - f"An agent has been scheduled for a time in the past, there is probably an error ({when} < {self.time})" - ) - self.logger.debug("Updating time step: %s -> %s ", self.time, next_time) +class TimedActivation(BaseScheduler): + def __init__(self, *args, shuffle=True, **kwargs): + super().__init__(*args, **kwargs) + self._queue = deque() + self._shuffle = shuffle + self.logger = getattr(self.model, "logger", logger).getChild(f"time_{ self.model }") + self.next_time = self.time - self.time = next_time + def add(self, agent: MesaAgent, when=None): + if when is None: + when = self.time + else: + when = float(when) + self._schedule(agent, None, when) + super().add(agent) + + def _schedule(self, agent, when=None, replace=False): + when = when or self.time + pos = len(self._queue) + for (ix, l) in enumerate(self._queue): + if l[0] == when: + l[1].append(agent) + return + if l[0] > when: + pos = ix + break + self._queue.insert(pos, (when, [agent])) + + def step(self) -> None: + """ + Executes agents in order, one at a time. After each step, + an agent will signal when it wants to be scheduled next. + """ + if not self._queue: + return + + now = self.time + + next_time = self._queue[0][0] + + if next_time > now: + self.time = next_time + return + + bucket = self._queue.popleft()[1] + if self._shuffle: + self.model.random.shuffle(bucket) + for agent in bucket: + try: + when = agent.step() or 1 + when += now + except DeadAgent: + continue + + if when != INFINITY: + self._schedule(agent, when, replace=True) + + self.steps += 1 + if self._queue: + self.time = self._queue[0][0] + else: + self.time = INFINITY class ShuffledTimedActivation(TimedActivation): @@ -211,3 +182,5 @@ class ShuffledTimedActivation(TimedActivation): class OrderedTimedActivation(TimedActivation): def __init__(self, *args, **kwargs): super().__init__(*args, shuffle=False, **kwargs) + + diff --git a/tests/test_agents.py b/tests/test_agents.py index 000049a..613e732 100644 --- a/tests/test_agents.py +++ b/tests/test_agents.py @@ -17,7 +17,7 @@ class TestAgents(TestCase): """The last step of a dead agent should return time.INFINITY""" d = Dead(unique_id=0, model=environment.Environment()) ret = d.step() - assert ret == stime.NEVER + assert ret == stime.INFINITY def test_die_raises_exception(self): """A dead agent should raise an exception if it is stepped after death""" @@ -52,23 +52,25 @@ class TestAgents(TestCase): def test_state_decorator(self): class MyAgent(agents.FSM): - run = 0 + times_run = 0 @agents.state("original", default=True) def root(self): - self.run += 1 return self.other @agents.state def other(self): - self.run += 1 + self.times_run += 1 e = environment.Environment() a = e.add_agent(MyAgent) e.step() - assert a.run == 1 + assert a.times_run == 0 a.step() - print("DONE") + assert a.times_run == 1 + assert a.state_id == MyAgent.other.id + a.step() + assert a.times_run == 2 def test_broadcast(self): """ @@ -86,7 +88,7 @@ class TestAgents(TestCase): except Exception as ex: print(ex) while True: - self.check_messages() + self.process_messages() yield def on_receive(self, msg, sender=None): @@ -132,14 +134,14 @@ class TestAgents(TestCase): while True: if pongs or not pings: # First agent, or anyone after that pings.append(self.now) - response = yield target.ask("PING") + response = yield from target.ask("PING") responses.append(response) else: print("NOT sending ping") print("Checking msgs") # Do not block if we have already received a PING - if not self.check_messages(): - yield self.received() + if not self.process_messages(): + yield from self.received() print("done") def on_receive(self, msg, sender=None): @@ -174,4 +176,200 @@ class TestAgents(TestCase): assert len(ev) == 1 assert ev[0].unique_id == 1 null = list(e.agents(unique_ids=[0, 1], agent_class=agents.NetworkAgent)) - assert not null \ No newline at end of file + assert not null + + def test_agent_return(self): + ''' + An agent should be able to cycle through different states and control when it + should be awaken. + ''' + class TestAgent(agents.Agent): + @agents.state(default=True) + def one(self): + return self.two + + @agents.state + def two(self): + return self.three.at(10) + + @agents.state + def three(self): + return self.four.delay(1) + + @agents.state + def four(self): + yield self.delay(2) + return self.five.delay(3) + + @agents.state + def five(self): + return self.delay(1) + + model = environment.Environment() + a = model.add_agent(TestAgent) + assert a.state_id == TestAgent.one.id + assert a.now == 0 + model.step() + assert a.state_id == TestAgent.two.id + assert a.now == 1 + model.step() + assert a.state_id == TestAgent.three.id + assert a.now == 10 + model.step() + assert a.state_id == TestAgent.four.id + assert a.now == 11 + model.step() + assert a.state_id == TestAgent.four.id + assert a.now == 13 + model.step() + assert a.state_id == TestAgent.five.id + assert a.now == 16 + model.step() + assert a.state_id == TestAgent.five.id + assert a.now == 17 + + def test_agent_async(self): + ''' + Async functions should also be valid states. + ''' + + class TestAgent(agents.Agent): + @agents.state(default=True) + def one(self): + return self.two + + @agents.state + def two(self): + return self.three.at(10) + + @agents.state + def three(self): + return self.four.delay(1) + + @agents.state + async def four(self): + await self.delay(2) + return self.five.delay(3) + + @agents.state + def five(self): + return self.delay(1) + + model = environment.Environment() + a = model.add_agent(TestAgent) + assert a.now == 0 + assert a.state_id == TestAgent.one.id + model.step() + assert a.now == 1 + assert a.state_id == TestAgent.two.id + model.step() + assert a.now == 10 + assert a.state_id == TestAgent.three.id + model.step() + assert a.state_id == TestAgent.four.id + assert a.now == 11 + model.step() + assert a.state_id == TestAgent.four.id + assert a.now == 13 + model.step() + assert a.state_id == TestAgent.five.id + assert a.now == 16 + model.step() + assert a.state_id == TestAgent.five.id + assert a.now == 17 + + def test_agent_return_step(self): + ''' + The same result as the previous test should be achievable by manually + handling the agent state. + ''' + class TestAgent(agents.Agent): + my_state = 1 + my_count = 0 + + def step(self): + if self.my_state == 1: + self.my_state = 2 + return None + elif self.my_state == 2: + self.my_state = 3 + return self.at(10) + elif self.my_state == 3: + self.my_state = 4 + self.my_count = 0 + return self.delay(1) + elif self.my_state == 4: + self.my_count += 1 + if self.my_count == 1: + return self.delay(2) + self.my_state = 5 + return self.delay(3) + elif self.my_state == 5: + return self.delay(1) + + model = environment.Environment() + a = model.add_agent(TestAgent) + assert a.my_state == 1 + assert a.now == 0 + model.step() + assert a.now == 1 + assert a.my_state == 2 + model.step() + assert a.now == 10 + assert a.my_state == 3 + model.step() + assert a.now == 11 + assert a.my_state == 4 + model.step() + assert a.now == 13 + assert a.my_state == 4 + model.step() + assert a.now == 16 + assert a.my_state == 5 + model.step() + assert a.now == 17 + assert a.my_state == 5 + + def test_agent_return_step_async(self): + ''' + The same result as the previous test should be achievable by manually + handling the agent state. + ''' + class TestAgent(agents.Agent): + my_state = 1 + + async def step(self): + self.my_state = 2 + await self.delay() + self.my_state = 3 + await self.at(10) + self.my_state = 4 + await self.delay(1) + await self.delay(2) + self.my_state = 5 + await self.delay(3) + while True: + await self.delay(1) + + model = environment.Environment() + a = model.add_agent(TestAgent) + assert a.my_state == 1 + assert a.now == 0 + model.step() + assert a.now == 1 + assert a.my_state == 2 + model.step() + assert a.now == 10 + assert a.my_state == 3 + model.step() + assert a.now == 11 + assert a.my_state == 4 + model.step() + assert a.now == 13 + assert a.my_state == 4 + model.step() + assert a.now == 16 + assert a.my_state == 5 + model.step() + assert a.now == 17 + assert a.my_state == 5 \ No newline at end of file diff --git a/tests/test_config.py b/tests/test_config.py index 9da72e7..6765dab 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -29,15 +29,12 @@ class TestConfig(TestCase): def test_torvalds_config(self): sim = simulation.from_config(os.path.join(ROOT, "test_config.yml")) MAX_STEPS = 10 - INTERVAL = 2 - assert sim.interval == INTERVAL assert sim.max_steps == MAX_STEPS envs = sim.run() assert len(envs) == 1 env = envs[0] - assert env.interval == 2 assert env.count_agents() == 3 - assert env.now == INTERVAL * MAX_STEPS + assert env.now == MAX_STEPS def make_example_test(path, cfg): diff --git a/tests/test_config.yml b/tests/test_config.yml index db1ffae..49d6fa3 100644 --- a/tests/test_config.yml +++ b/tests/test_config.yml @@ -1,5 +1,4 @@ --- source_file: "../examples/torvalds_sim.py" model: "TorvaldsEnv" -max_steps: 10 -interval: 2 \ No newline at end of file +max_steps: 10 \ No newline at end of file diff --git a/tests/test_exporters.py b/tests/test_exporters.py index 3b815f9..01f7f0e 100644 --- a/tests/test_exporters.py +++ b/tests/test_exporters.py @@ -88,7 +88,7 @@ class Exporters(TestCase): parameters=dict( network_generator="complete_graph", network_params={"n": n_nodes}, - agent_class="CounterModel", + agent_class=agents.CounterModel, agent_reporters={"times": "times"}, ), max_time=max_time, diff --git a/tests/test_main.py b/tests/test_main.py index 0bc7f82..83db5c2 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -7,8 +7,6 @@ from functools import partial from os.path import join from soil import simulation, Environment, agents, network, serialization, utils, config, from_file -from soil.time import Delta - from mesa import Agent as MesaAgent ROOT = os.path.abspath(os.path.dirname(__file__)) @@ -114,7 +112,6 @@ class TestMain(TestCase): def test_serialize_class(self): ser, name = serialization.serialize(agents.BaseAgent, known_modules=[]) assert name == "soil.agents.BaseAgent" - assert ser == agents.BaseAgent ser, name = serialization.serialize( agents.BaseAgent, @@ -123,11 +120,9 @@ class TestMain(TestCase): ], ) assert name == "BaseAgent" - assert ser == agents.BaseAgent ser, name = serialization.serialize(CustomAgent) assert name == "test_main.CustomAgent" - assert ser == CustomAgent pickle.dumps(ser) def test_serialize_builtin_types(self): @@ -168,7 +163,6 @@ class TestMain(TestCase): def test_fsm(self): """Basic state change""" - class ToggleAgent(agents.FSM): @agents.default_state @agents.state @@ -193,7 +187,7 @@ class TestMain(TestCase): @agents.default_state @agents.state def ping(self): - return self.pong, 2 + return self.pong.delay(2) @agents.state def pong(self): @@ -203,7 +197,7 @@ class TestMain(TestCase): when = a.step() assert when == 2 when = a.step() - assert when == Delta(a.interval) + assert when == None def test_load_sim(self): """Make sure at least one of the examples can be loaded""" @@ -232,4 +226,4 @@ class TestMain(TestCase): assert len(configs) == len(a) * len(b) for i in a: for j in b: - assert {"a": i, "b": j} in configs \ No newline at end of file + assert {"a": i, "b": j} in configs diff --git a/tests/test_time.py b/tests/test_time.py index 27d1765..7e12196 100644 --- a/tests/test_time.py +++ b/tests/test_time.py @@ -4,26 +4,6 @@ from soil import time, agents, environment class TestMain(TestCase): - def test_cond(self): - """ - A condition should match a When if the concition is True - """ - - t = time.Cond(lambda t: True) - f = time.Cond(lambda t: False) - for i in range(10): - w = time.When(i) - assert w == t - assert w is not f - - def test_cond(self): - """ - Comparing a Cond to a Delta should always return False - """ - - c = time.Cond(lambda t: False) - d = time.Delta(1) - assert c is not d def test_cond_env(self): """ """ @@ -36,11 +16,12 @@ class TestMain(TestCase): class CondAgent(agents.BaseAgent): def step(self): - nonlocal done + nonlocal done, times_started, times_asleep, times_awakened times_started.append(self.now) while True: times_asleep.append(self.now) - yield time.Cond(lambda agent: agent.now >= 10, delta=2) + while self.now < 10: + yield self.delay(2) times_awakened.append(self.now) if self.now >= 10: break @@ -57,7 +38,6 @@ class TestMain(TestCase): assert times_started == [0] assert times_awakened == [10] assert done == [10] - # The first time will produce the Cond. assert env.schedule.steps == 6 assert len(times) == 6 @@ -65,11 +45,10 @@ class TestMain(TestCase): times.append(env.now) env.step() - assert times == [0, 2, 4, 6, 8, 10, 11] + assert times == [0, 2, 4, 6, 8, 10, 11, 12] assert env.schedule.time == 13 - assert times_started == [0, 11] - assert times_awakened == [10] - assert done == [10] - # Once more to yield the cond, another one to continue - assert env.schedule.steps == 7 - assert len(times) == 7 + assert times_started == [0, 11, 12] + assert times_awakened == [10, 11, 12] + assert done == [10, 11, 12] + assert env.schedule.steps == 8 + assert len(times) == 8