/**
   * Sorts lookups based on their dependencies with each other. Non-lookups (i.e. everything except
   * #match, #setChoice, and #mapChoice) are in no particular order in this ordering, since they can
   * always be inferred later to occur at the final step after all other variables are bound.
   *
   * @return
   */
  private Stream<KApply> getSortedLookups() {
    List<Tuple2<KApply, KApply>> edges = new ArrayList<>();
    for (KApply k1 : state) {
      Multiset<KVariable> rhsVars = HashMultiset.create();
      if (k1.klabel().name().equals("Set:in")) {
        continue;
      }
      gatherVars(k1.klist().items().get(1), rhsVars);
      for (KApply k2 : state) {
        Multiset<KVariable> lhsVars = HashMultiset.create();
        if (k2.klabel().name().equals("Set:in")) {
          continue;
        }
        gatherVars(k2.klist().items().get(0), lhsVars);
        for (KVariable var : rhsVars) {
          if (lhsVars.contains(var)) {
            if (k1 != k2) {
              edges.add(Tuple2.apply(k2, k1));
              break;
            }
          }
        }
      }
    }

    List<KApply> topologicalSorted = mutable(TopologicalSort.tsort(immutable(edges)).toList());
    return state
        .stream()
        .sorted((k1, k2) -> (topologicalSorted.indexOf(k1) - topologicalSorted.indexOf(k2)));
  }
 public static boolean isLookupKLabel(KApply k) {
   return isLookupKLabel(k.klabel());
 }