// TODO what happens if solver hasn't started yet (solve() is called asynchronously)
void stopSolver() {
        if (solverFuture != null) {
            // TODO what happens if solver hasn't started yet (solve() is called asynchronously)
            solver.terminateEarly();
            // make sure solver has terminated and propagate exceptions
            try {
                solverFuture.get();
                solverFuture = null;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new RuntimeException("Failed to stop solver", e);
            } catch (ExecutionException e) {
                throw new RuntimeException("Failed to stop solver", e);
            }
        }
    }
void stopSolver() {
if (solverFuture != null) {
// TODO what happens if solver hasn't started yet (solve() is called asynchronously)
solver.terminateEarly();
// make sure solver has terminated and propagate exceptions
void stopSolver() {
if (solverFuture != null) {
// TODO what happens if solver hasn't started yet (solve() is called asynchronously)
solver.terminateEarly();
// make sure solver has terminated and propagate exceptions
try {
solverFuture.get();
solverFuture = null;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Failed to stop solver", e);
} catch (ExecutionException e) {
throw new RuntimeException("Failed to stop solver", e);
void stopSolver() {
if (solverFuture != null) {
// TODO what happens if solver hasn't started yet (solve() is called asynchronously)
solver.terminateEarly();
// make sure solver has terminated and propagate exceptions
try {
solverFuture.get();
solverFuture = null;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Failed to stop solver", e);
} catch (ExecutionException e) {
throw new RuntimeException("Failed to stop solver", e);
}
}
}