 (defn ryssel-base
   "Returns the set of implications computed by Ryssels Algorithm."
   [ctx]
-  (let [oprime (memoize #(object-derivation ctx %)),
+  (let [oprime (memoize #(oprime ctx %)),
         gens   (reduce! (fn [map x]     ;generating elements of attribute extents
-                          (let [extent (attribute-derivation ctx #{x})]
+                          (let [extent (aprime ctx #{x})]
                             (assoc! map extent
                                     (conj (get map extent #{}) x))))
                         {}

            true
            (recur new-rest (next sets))))))))

(defn- redundant? [cover]
  (exists [set cover]
    (forall [x set]
      (exists [other-set (disj cover set)]
        (contains? other-set x)))))

(defn- minimum-covers [base-set sets]
  (let [drop    (memoize drop),
        sets    (vec (sort #(>= (count %1) (count %2)) sets)),
        nr-sets (count sets),
        result  (atom (transient [])),
        search  (fn search [rest-base-set current-cover i]
                  (cond
                   (redundant? current-cover)  nil,
                   (empty? rest-base-set)      (swap! result conj! current-cover),
                   (>= i nr-sets)              nil,
                   :else
                   (when (covers? rest-base-set (drop i sets))
                     (when (exists [x (sets i)]
                             (contains? rest-base-set x))
                       (search (difference rest-base-set (sets i))
                               (conj current-cover (sets i))
                               (inc i)))
                     (search rest-base-set current-cover (inc i)))))]
    (search base-set #{} 0)
    (persistent! @result)))


;;; Collapsing implications with equal premise


;;; Searching for minimum covers

(defn- covers? [sets base-set]
  (if (empty? base-set)
    true
    (loop [rest (transient base-set),
