// f : A -> Collection // trace_out collects what the function returns // returns hashset including input static Set mapLike transitiveHullOfFunction(O f, A input, O... _) { final Set seen = optPar(_, seen := (Set) lithashset(input)); final Int max = cast optPar max(_); Map trace_out = cast optPar trace_out(_); // Make pool of iterators final new LinkedList> pool; pool.add(iterator((Iterable) callF(f, input))); int n = 0; while ping (!empty(pool) && (max == null || n < max)) { Iterator it = first(pool); if (!it.hasNext()) continue with removeFirst(pool); // Get entry and check if seen already A entry = it.next(); if (!seen.add(entry)) continue; // found new entry - return and schedule for further analysis Collection newStuff = cast callF(f, entry); mapPut(trace_out, entry, newStuff); if (nempty(newStuff)) pool.add(iterator(newStuff)); ++n; } ret seen; } static Set transitiveHullOfFunction(IF1> f, A input, O... _) { ret transitiveHullOfFunction((O) f, input, _); }