         (doseq [X key-set]
           (set-val! closure X (titanic-closure X base-set key-set candidates)))
         (let [next-key-set (set-of X [X candidates,
-                                      :when (not= (get subset-weight X max-weight)
-                                            (get set-weight X max-weight))])]
+                                      :when (not= (subset-weight X)
+                                                  (set-weight X))])]
           (if-not (empty? next-key-set)
             (recur next-key-set
                    (titanic-generate next-key-set)

      (illegal-argument "Given partial order for weights does not have a greatest element."))

    (binding [closure       {},
              set-weight    {},
              subset-weight {},
              max-weight    (first max-weight-values),
              minimum       (partial minimum <=-weight)]

      (set! set-weight (weigh [#{}]))
      (let [empty-weight (set-weight #{})]
        (doseq [m base-set]
          (set-val! subset-weight #{m} empty-weight)))
      (loop [key-set    #{#{}},
             candidates (set-of #{m} [m base-set]),
             key-sets   [key-set]]

  "Holds the closures of sets. To be rebound.")
(defvar- set-weight nil
  "Holds the weights of sets. To be rebound.")

(defn- subset-weight
  "Returns the minimum of the weights of all proper subsets of X."
  [max-weight X]
  (minimum (conj (map #(set-weight (disj X %)) X)
                 max-weight)))

(defn- titanic-closure
  "Computes the closure of X by the weights of its subsets."
  [X base-set key-set candidates]
  (loop [Y (apply union X (map #(closure (disj X %)) X)),
         elements (difference base-set Y)]
    (if-not (empty? elements)
      (let [m   (first elements),
            X+m (conj X m),
            s   (if (contains? candidates X+m)
                  (set-weight X+m)
                  (minimum (for [K key-set,
                                 :when (subset? K X+m)]
                             (set-weight K))))]
        (recur (if (= s (set-weight X))
                 (conj Y m)
                 Y)
               (rest elements)))
      Y)))

(defn- titanic-generate
  "Generates the next candidate set from the given key-set and sets
  subset-weight accordingly."
  [key-set]
  (set-of both [A key-set,
                B key-set,
                :let [both (union A B)]
                :when (and (= (inc (count A)) (count both)) ;one more
                           (forall [x both]                 ;both is candidate
                             (contains? key-set (disj both x))))]))

(defn titanic
  "Implements the titanic algorithm."
