sclass BreadthFirstPathFinder implements Steppable {
new LinkedList queue;
new MultiMap> links; // second of pair is link type
IF1> getChildren; // must set
*() {}
*(IF1> *getChildren) {}
*(IF1> *getChildren, A startNode) { add(startNode); }
void add(A a) {
add(a, null, null);
}
void add(A a, A prev, O linkType) {
if (!links.containsKey(a)) {
links.put(a, prev == null ?: pair(prev, linkType));
queue.add(a);
}
}
public bool step() {
ping();
if (empty(queue)) false;
A a = popFirst(queue);
fOr (A b : getChildren.get(a))
add(b, a);
true;
}
bool nodeReached(A a) {
ret links.containsKey(a);
}
Cl getBackLinks(A a) {
ret pairsA(links.get(a));
}
Cl> getBackLinksWithTypes(A a) {
ret links.get(a);
}
L examplePath(A start, A dest) {
new L path;
A node = dest;
path.add(node);
do {
if (node == null) null; // no path found
node = pairA(first(getBackLinks(node)));
path.add(node);
} while (node != start);
ret reversed(path);
}
}