// trace_out collects what the function returns
// returns hashset including input
sclass TransitiveHull implements Steppable {
IF1> f;
new Set seen;
new LinkedList> pool;
Int max;
*(IF1> *f, A starter) { add(starter); }
void add(A a) {
pool.add(singletonIterator(a));
}
public bool step() {
if (max != null && l(seen) >= max) false;
if (empty(pool)) false;
Iterator it = first(pool);
if (!it.hasNext()) {
removeFirst(pool);
true;
}
process(it.next());
true;
}
void process(A entry) {
if (!seen.add(entry)) ret;
// found new entry - return and schedule for further analysis
Iterable newStuff = f.get(entry);
onGotCollection(entry, newStuff);
if (nempty(newStuff))
pool.add(iterator(newStuff));
}
swappable void onGotCollection(A entry, Iterable newStuff) {
}
}