NetLogo / NW-Extension

This is the NetLogo Network Extension. For general information about NetLogo, see:
http://ccl.northwestern.edu/netlogo/
Other
62 stars 25 forks source link

List-valued variables restored as strings using nw:load-graphml #136

Closed finkga closed 9 years ago

finkga commented 9 years ago

I have a set of agents that have list-valued attributes (e.g., `set matchPat (list 0 1 0 0 0). When I save the agent and link set via:

nw:set-context turtles links
nw:save-graphml "example.graphml"

it appears the list-valued ones are correctly saved (e.g., <data key="MATCHPAT">[0 1 0 0 0]</data>). However when these agent variables are restored using nw:load-graphml "example.graphml" the list-valued attributes are interpreted as strings (e.g., matchPat = "[0 1 0 0 0]" which is not interpretable as a list.

finkga commented 9 years ago

A different but related issue is that agent identifiers that are saved references in the turtle variables are neither interpreted correctly on restore nor do they retain their meaning. For instance, if a turtle has a variable owner that contains (turtle 2503) nw:load-graphml will interpret it as a string. Furthermore, if one is able to retrieve the breed and who number from the string, it will not refer to the same turtle.

finkga commented 9 years ago

Closed issue by mistake.

nicolaspayette commented 9 years ago

This is "by design"... well... sort of. The only attribute types supported by GraphML are boolean, int, long, float, double, or string. And since NetLogo stores all numbers as double, the only attribute types effectively used when exporting to GraphML are boolean, double and string. Everything else is converted to a string.

In the case of lists, it is easy to convert them back to list using read-from-string. For example, read-from-string "[0 1 0 0 0]" will give you back the actual [0 1 0 0 0] list.

In the case of references to other agents, the workaround would be to store them as link rather than references. If your turtles have owners, you could have a directed-link-breed [ ownerships ownership ] and then use create-ownership from one-of other turtles where you would have used set owner one-of other turtles. This should be restored properly by nw:load-graphml.

Perhaps there would be a way to make all of this more convenient. The save/load GraphML primitives are one of the most unpolished parts of the extension and could use a lot of improvement.

In any case, these limitations would need to be better documented.

SethTisue commented 9 years ago

does the nw extension support export-world and import-world? if so, you could recommend using those for round trips, and only recommend export-graphml and import-graphml for one-way trips in or out of NetLogo.

nicolaspayette commented 9 years ago

Yes, the extension should be compatible with export-world/import-world. The only caveat is that the nw context will be reset to turtles and links after import-world. If a user doesn't need to preserve some other part of the world's state that could be overwritten by import-world, using it would, indeed, be a good workaround.

qiemem commented 9 years ago

@finkga Seth and Nicolas have sufficiently covered why these must be stored as strings. Regarding the turtle who numbers not referring to the correct turtle when reloaded, not that upon reloading, the who numbers of the turtles in the network may have changed. For instance, if you save a network, then clear-all, then create 100 turtles, then reload the network, the who numbers of the network will all have increased by 100.

As Nicolas points out, all these things should be documented, so I'll leave this open for now.

finkga commented 9 years ago

I appreciate the comments and help, thanks. Seth, export-world and import-world do too much in my case. I only want to save a subset of agents and none of the patches or other settings. I would prefer not to introduce a breed of links for the sole purpose of establishing ownership, but this is possible. Right now what I do is store the owner who ID when exporting both the owner and the slave. When importing, I build two tables: one whose keys are new slave who numbers and old owner who ids as values, the other with old owner who ids for keys and new owner who values. After all the agents are read in and instantiated I can rebuild the connections without links. Not pretty but it works.