I am currently pondering how best to represent Graph Structured Stacks in Clojure. My first idea was to use maps.
So this GSS would be represented as:
{7 {3 {1 {0 {}}},
4 {1 {0 {}}},
5 {2 {0 {}}}},
8 {6 {2 {0 {}}}}}
Please note that repeated maps in this representation would be shared by construction.
It is all well and good this representation allow me to easily perform stack ops but I want to also be able to traverse the stacks from the bottom. This means to make the graph cyclic so I thought that I need an adjency list or, more realistically, two indexed versions (maps of sets) of this list to be able to traverse the GSS in any direction. Or the map-based representation for direct traversal and an adjency map for reverse traversal.
To me the more boring part with this adjency lists is that I have to name the GSS nodes. Wait! There are natural identifiers for these nodes: their key-value pairs in the map-based representation! [2 {0 {}}]
is a natural identifier for node #2 and [2 {0 {}}]
the one for node #7.
Now I’m able to represent the GSS as:
[;; direct representation
{7 {3 {1 {0 {}}},
4 {1 {0 {}}},
5 {2 {0 {}}}},
8 {6 {2 {0 {}}}}}
;; adjency map for reverse traversal
{nil #{[0 {}]},
[0 {}] #{[1 {0 {}}]
[2 {0 {}}]},
[1 {0 {}}] #{[3 {1 {0 {}}}]
[4 {1 {0 {}}}]},
[2 {0 {}}] #{[5 {2 {0 {}}}]
[6 {2 {0 {}}}]},
[3 {1 {0 {}}}] #{[7 {3 {1 {0 {}}},
4 {1 {0 {}}},
5 {2 {0 {}}}}]},
[4 {1 {0 {}}}] #{[7 {3 {1 {0 {}}},
4 {1 {0 {}}},
5 {2 {0 {}}}}]},
[5 {2 {0 {}}}] #{[7 {3 {1 {0 {}}},
4 {1 {0 {}}},
5 {2 {0 {}}}}]},
[6 {2 {0 {}}}] #{[8 {6 {2 {0 {}}}}]}}]
Granted the serialization is verbose but all nodes are shared in memory by construction and I find this model rather simple.
Does anyone have other ideas on how to functionally implement such a structure?