     (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 keys,
-                                 :when (subset? K X+m)]
-                             (set-weight K))))]
+            s   (or (set-weight X+m)
+                    (let [weight (minimum (doall (for [K keys, ;bottleneck!
+                                                       :when (subset? K X+m)]
+                                                   (set-weight K))))]
+                      (set-val! set-weight X+m weight)
+                      weight))]
         (recur (if (= s (set-weight X))
                  (conj Y m)
                  Y)

  (let [intents (titanic (attributes context)
                         (supports context minsupp)
                         1.0
                         <=)]
    (if (<= (* (count (objects context)) minsupp)
            (count (attribute-derivation context (attributes context))))
      intents

(defn titanic
  "Implements the titanic algorithm. weigh must return for a
  collection of sets a hash-map mapping every set to its weight, with
  max-weight being the maximal weight possbile. weight-minimum is a
  function of one argument being a sequence of weights and returning
  the minimal of those."
  [base-set weigh max-weight weight-minimum]
  (binding [closure       {},
            set-weight    (weigh [#{}]),
            subset-weight (memoize (partial subset-weight max-weight)),
            minimum       weight-minimum]

    (loop [key-set    #{#{}},
           candidates (set-of #{m} [m base-set]),
