-
Notifications
You must be signed in to change notification settings - Fork 25
/
rudolph_computation.clj
48 lines (43 loc) · 1.74 KB
/
rudolph_computation.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
;;
;; Experiments on Sebastian Rudolph's algorithm to compute the canonical base
;;
(ns conexp.example.rudolph-computation
(:use conexp.fca.contexts
conexp.base
conexp.fca.implications))
;;
(defn rudolph-base [ctx]
(let [new-names (reduce! (fn [map g]
(assoc! map g (gensym (str g "-"))))
{}
(objects ctx)),
pairs (for [m (attributes ctx)]
[#{m} (map new-names
(difference (objects ctx)
(aprime ctx #{m})))])]
[(union (set-of (make-implication X Y) | [X Y] pairs)
(set-of (make-implication Y X) | [X Y] pairs))
(set (vals new-names))]))
(defn context-to-imp-set [ctx]
(let [[base auxiliary-names] (rudolph-base ctx),
base (atom base),
impls (atom (transient #{}))]
(doseq [name auxiliary-names]
(reset! impls (transient #{}))
(doseq [A→B @base
:let [A (premise A→B)
B (conclusion A→B)]]
(if (contains? B name)
(do
(swap! impls conj! (make-implication A (disj B name)))
(when (not (contains? A name))
(doseq [C→D @base
:when (contains? (premise C→D) name)
:let [C (premise C→D)
D (conclusion C→D)]]
(swap! impls conj! (make-implication (disj (union A C) name)
D)))))
(when (not (contains? A name))
(swap! impls conj! A→B))))
(reset! base (canonical-base-from-base (persistent! @impls))))
@base))