sclass ProbabilisticList extends AbstractList { TreeSetWithDuplicates entries = new(byProbability()); bool verbose; // must be >= 0. probability 0 is never added double cutoffProbabilityOnAdd = 0; Comparator byProbability() { ret (a, b) -> cmp(b.probability, a.probability); } persistable class Entry { double probability; A element; *(double *probability, A *element) {} toString { ret str(WithProbability(probability, element)); } } public void add aka at(double probability, A element) { if (element == null) ret; if (probability <= cutoffProbabilityOnAdd) ret; entries.add(new Entry(probability, element)); } A first() { Entry s = first(entries); ret s?.element; } void clear { entries.clear(); } run { stepAll(this); } void run(int maxSteps) { stepMax(maxSteps, this); } void printStats() { Entry first = entries.first(), last = entries.last(); Entry next = nextSteppable(); print("ProbabilisticScheduler. " + nEntries(entries) + ", highest probability in queue: " + (first == null ? "-" : first.probability) + ", lowest probability in queue: " + (last == null ? "-" : last.probability) + ", cutoff probability: " + cutoffProbabilityOnAdd + "/" + cutoffProbabilityOnExecute + ", " + (next == null ? "done" : "next step: " + next.action)); } // Get probability of this thread's Runnable. // Or 1.0 when we are coming from "outside" (so you don't _have_ to // run your first step through the scheduler). public double currentProbability aka current() { ret or(threadProbability!, 1.0); } /*IProbabilisticScheduler freeze() { double prob = currentProbability(); ret new IProbabilisticScheduler { public void at(double probability, Runnable action) { ProbabilisticScheduler.this.at(prob*probability, action); } public double currentProbability() { ret prob; } public long stepCount() { ret stepCount; } }; }*/ double remainingProbability() { Entry s = nextSteppable(); ret s == null ? 0.0 : s.probability; } public double lastExecutedProbability() { ret lastExecutedProbability; } public long stepCount() { ret stepCount; } }