sclass BStack > VStack { static int idCounter; int stackID = ++idCounter; // alternative to backtrack to IF0 alternative; // steps to undo before switching to the alternative L undos; *() {} *(Computable computation) { push(computation); } *(Iterable l) { pushAll(l); } BStack cloneStack() { new BStack s; s.stack = shallowCloneElements(stack); ret s; } void addUndo(AutoCloseable undo) { if (undo == null) ret; if (undos == null) undos = new L; undos.add(undo); } void options(A function, IVF1... options) { // Check if there is more than one option if (l(options) > 1) { // Then remember this option in a cloned stack IVF1 option2 = second(options); addAlternative(clonedStack -> { A clonedFunction = (A) last(clonedStack.stack); option2.get(clonedFunction); }); } // Execute the first option first(options).get(function); } void addAlternative(IVF1 action) { BStack clonedStack = cloneStack(); alternative = -> { action.get(clonedStack); ret clonedStack; }; } // Try to backtrack one step and return a new stack // Returns null if no backtracking possible BStack backtrack() ctex { if (undos != null) for (undo : reversed(getAndClearList(undos))) undo.close(); ret alternative?!; } Object nextResult() { stepAll(this); return latestResult; } // calculate next result and print stack at every step Object nextResultWithPrintStruct() { stepAllWithPrintStruct(this); return latestResult; } }