code: public static <S, I, O> Optional<ADSNode<S, I, O>> compute(final MealyMachine<S, I, ?, O> automaton,
                                                                 final Alphabet<I> input,
                                                                 final Set<S> states) {
  
          if (states.isEmpty()) {
              return Optional.empty();
          } else if (states.size() == 1) {
              final S singleState = states.iterator().next();
              return Optional.of(new ADSLeafNode<>(null, singleState));
          } else if (states.size() == 2) {
              return StateEquivalence.compute(automaton, input, states);
          } else if (states.size() == automaton.getStates().size()) {
              final LYResult<S, I, O> result = LeeYannakakis.compute(automaton, input);
              if (result.isPresent()) {
                  return Optional.of(result.get());
              }
              return Optional.empty();
          } else {
              return BacktrackingSearch.compute(automaton, input, states);
          }
      }
docs: Compute an adaptive distinguishing sequence for the given automaton and the given set of states.
  
  @param automaton
  the automaton for which an ADS should be computed
  @param input
  the input alphabet of the automaton
  @param states
  the set of states which should be distinguished by the computed ADS
  @param <S>
  (hypothesis) state type
  @param <I>
  input alphabet type
  @param <O>
  output alphabet type
  
  @return {@code Optional.empty()} if there exists no ADS that distinguishes the given states, a valid ADS
  otherwise.