static bool ctxDoNextActionInRule(WoodyRule rule) { L actions = ctxCases(rule.body); if (nempty(actions)) { S actionSelector = rule.properties.get('ACTIONSELECTOR); if (empty(actionSelector)) actionSelector = 'TILLEND; bool random = eqOneOf(actionSelector, 'RANDOMLOOP, 'RANDOM); //bool loop = eqOneOf(actionSelector, 'RANDOMLOOP); S name = rule.longName(); BitSet bs = conversation->randomLoopMap.get(name); if (bs == null) { conversation->randomLoopMap.put(name, bs = new BitSet); conversation->change(); } new L candidates; for i over actions: if (!bs.get(i)) candidates.add(i); // start over with all candidates if (empty(candidates)) { bs.clear(); conversation->change(); for i over actions: candidates.add(i); } int idx = random ? random(candidates) : first(candidates); bs.set(idx); candidates.remove((Int) idx); conversation->change(); CtxCase action = actions.get(idx); ctxProcessAction(action.action); S a = mapGet(action.properties, 'ANALYZER); print("doNextAction analyzer=" + a); if (a != null) ctxContext().activeAnalyzer = a; ctxContext().nextRule = rule.properties.get('GOTO); S goTo = action.properties.get('GOTO); if (goTo != null) ctxContext().nextRule = goTo; print("Candidates left: " + l(candidates) + " of " + l(actions)); if (empty(candidates) && l(actions) > 1) { print("No more candidates. nextRule=" + ctxContext().nextRule); if (/*loop &&*/ ctxContext().nextRule == null) ctxContext().thinkagain = true; } true; } false; }