1 package org.thegalactic.lattice;
2
3
4
5
6
7
8
9
10
11
12
13
14 import org.thegalactic.context.Context;
15 import java.util.SortedSet;
16 import java.util.TreeMap;
17 import java.util.TreeSet;
18 import java.util.Vector;
19 import java.io.IOException;
20 import java.util.List;
21
22 import org.thegalactic.util.ComparableSet;
23 import org.thegalactic.dgraph.DAGraph;
24 import org.thegalactic.dgraph.ConcreteDGraph;
25 import org.thegalactic.dgraph.Edge;
26 import org.thegalactic.dgraph.Node;
27 import org.thegalactic.io.Filer;
28 import org.thegalactic.lattice.io.ConceptLatticeIOFactory;
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 public class ConceptLattice extends Lattice {
66
67
68
69
70
71
72
73
74
75
76
77
78 public static ConceptLattice idealLattice(DAGraph dag) {
79 if (!dag.isAcyclic()) {
80 return null;
81 }
82
83 ConceptLattice conceptLattice = new ConceptLattice();
84 conceptLattice.addNode(new Concept(true, false));
85
86 DAGraph graph = new DAGraph(dag);
87 graph.transitiveClosure();
88
89 List<Node> sort = graph.topologicalSort();
90 for (Node x : sort) {
91
92 TreeSet<Node> jxmoins = new TreeSet<Node>(graph.getPredecessorNodes(x));
93
94 TreeSet<Concept> toAdd = new TreeSet<Concept>();
95 for (Object j1 : conceptLattice.getNodes()) {
96 if (((Concept) j1).containsAllInA(jxmoins)) {
97 Concept newJ = new Concept(true, false);
98 newJ.addAllToA(((TreeSet) ((Concept) j1).getSetA()));
99 newJ.addToA(x);
100 toAdd.add(newJ);
101 }
102 }
103
104 for (Concept newJ : toAdd) {
105 conceptLattice.addNode(newJ);
106 }
107 }
108
109 for (Object node1 : conceptLattice.getNodes()) {
110 for (Object node2 : conceptLattice.getNodes()) {
111 if (((Concept) node1).containsAllInA(((Concept) node2).getSetA())) {
112 conceptLattice.addEdge((Node) node2, (Node) node1);
113 }
114 }
115 }
116 conceptLattice.transitiveReduction();
117 return conceptLattice;
118 }
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137 public static ConceptLattice completeLattice(ClosureSystem init) {
138 ConceptLattice lattice = new ConceptLattice();
139
140 Vector<Concept> allclosure = init.allClosures();
141 for (Concept cl : allclosure) {
142 lattice.addNode(cl);
143 }
144
145
146 for (Object source : lattice.getNodes()) {
147 for (Object target : lattice.getNodes()) {
148 if (((Concept) target).containsAllInA(((Concept) source).getSetA())) {
149 lattice.addEdge((Node) source, (Node) target);
150 }
151 }
152 }
153
154 return lattice;
155 }
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179 public static ConceptLattice diagramLattice(ClosureSystem init) {
180 ConceptLattice lattice = new ConceptLattice();
181
182
183
184 ConcreteDGraph graph = new ConcreteDGraph();
185 for (Comparable c : init.getSet()) {
186 graph.addNode(new Node(c));
187 }
188 lattice.setDependencyGraph(graph);
189
190 Concept bot = new Concept(init.closure(new ComparableSet()), false);
191 lattice.addNode(bot);
192
193 lattice.recursiveDiagramLattice(bot, init);
194
195
196
197
198
199
200
201
202
203 return lattice;
204 }
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230 public static ConceptLattice diagramIceberg(Context init, double support) {
231 ConceptLattice lattice = new ConceptLattice();
232
233
234 ConcreteDGraph graph = new ConcreteDGraph();
235 for (Comparable c : init.getSet()) {
236 graph.addNode(new Node(c));
237 }
238 lattice.setDependencyGraph(graph);
239
240 Concept bot = new Concept(init.closure(new ComparableSet()), false);
241 lattice.addNode(bot);
242 int threshold = (int) (support * init.getExtent(bot.getSetA()).size());
243
244 lattice.recursiveDiagramIceberg(bot, init, threshold);
245 return lattice;
246 }
247
248
249
250
251
252
253
254 public ConceptLattice() {
255 super();
256 }
257
258
259
260
261
262
263
264 public ConceptLattice(TreeSet<Concept> set) {
265 super((TreeSet) set);
266 }
267
268
269
270
271
272
273
274
275
276 public ConceptLattice(Lattice lattice) {
277 super(lattice);
278 if (!this.isConceptLattice()) {
279 this.setNodes(new TreeSet<Node>());
280 this.setSuccessors(new TreeMap<Node, SortedSet<Edge>>());
281 this.setPredecessors(new TreeMap<Node, SortedSet<Edge>>());
282 }
283 }
284
285
286
287
288
289
290
291
292
293
294
295 public boolean containsConcepts() {
296 for (Object node : this.getNodes()) {
297 if (!(node instanceof Concept)) {
298 return false;
299 }
300 }
301 return true;
302 }
303
304
305
306
307
308
309
310
311 public boolean isConceptLattice() {
312 return this.isLattice() && this.containsConcepts();
313 }
314
315
316
317
318
319
320
321
322
323 public boolean containsAllSetA() {
324 if (!this.containsConcepts()) {
325 return false;
326 }
327 for (Object node : this.getNodes()) {
328 if (!((Concept) node).hasSetA()) {
329 return false;
330 }
331 }
332 return true;
333 }
334
335
336
337
338
339
340
341
342
343 public boolean containsAllSetB() {
344 if (!this.containsConcepts()) {
345 return false;
346 }
347 for (Object node : this.getNodes()) {
348 if (!((Concept) node).hasSetB()) {
349 return false;
350 }
351 }
352 return true;
353 }
354
355
356
357
358
359
360
361 @Override
362 public ConceptLattice clone() {
363 ConceptLattice conceptLattice = new ConceptLattice();
364 TreeMap<Concept, Concept> copy = new TreeMap<Concept, Concept>();
365 for (Object node : this.getNodes()) {
366 Concept c = (Concept) node;
367 Concept c2 = c.clone();
368 copy.put(c, c2);
369 conceptLattice.addNode(c2);
370 }
371 for (Object ed : this.getEdges()) {
372 conceptLattice.addEdge(new Edge(
373 copy.get(((Edge) ed).getSource()),
374 copy.get(((Edge) ed).getTarget()),
375 ((Edge) ed).getContent()
376 ));
377 }
378 return conceptLattice;
379 }
380
381
382
383
384
385
386
387
388
389
390
391
392 public Concept getConcept(ComparableSet setA, ComparableSet setB) {
393 SortedSet<Node> setNodes = this.getNodes();
394 Concept cpt = null;
395 for (Node node : setNodes) {
396 if ((setA.equals(((Concept) node).getSetA())) && (setB.equals(((Concept) node).getSetB()))) {
397 cpt = (Concept) node;
398 }
399 }
400 return cpt;
401 }
402
403
404
405
406
407
408
409
410 public boolean removeAllSetA() {
411 if (!this.containsConcepts()) {
412 return false;
413 }
414 for (Object node : this.getNodes()) {
415 Concept c = (Concept) node;
416 c.putSetA(null);
417 }
418 return true;
419 }
420
421
422
423
424
425
426
427
428 public boolean removeAllSetB() {
429 if (!this.containsConcepts()) {
430 return false;
431 }
432 for (Object node : this.getNodes()) {
433 Concept c = (Concept) node;
434 c.putSetB(null);
435 }
436 return true;
437 }
438
439
440
441
442
443
444
445
446
447 public boolean initialiseSetAForJoin() {
448 if (!this.containsConcepts()) {
449 return false;
450 }
451 TreeSet<Node> joinIrr = this.joinIrreducibles();
452 for (Object node : this.getNodes()) {
453 Concept c = (Concept) node;
454 if (!c.hasSetA() && joinIrr.contains(c)) {
455 ComparableSet setX = new ComparableSet();
456 setX.add(Integer.valueOf(c.getIdentifier()));
457 c.putSetA(setX);
458 }
459 }
460 return true;
461 }
462
463
464
465
466
467
468
469
470
471 public boolean initialiseSetBForMeet() {
472 if (!this.containsConcepts()) {
473 return false;
474 }
475 TreeSet<Node> meetIrr = this.meetIrreducibles();
476 for (Object node : this.getNodes()) {
477 Concept c = (Concept) node;
478 if (!c.hasSetB() && meetIrr.contains(c)) {
479 ComparableSet setX = new ComparableSet();
480 setX.add(Integer.valueOf(c.getIdentifier()));
481 c.putSetB(setX);
482 }
483 }
484 return true;
485 }
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500 public boolean makeInclusionReduction() {
501 if (!this.containsConcepts()) {
502 return false;
503 }
504 boolean setA = this.containsAllSetA();
505 boolean setB = this.containsAllSetB();
506 if (!setA && !setB) {
507 return false;
508 }
509
510 if (setA) {
511
512 this.transpose();
513 List<Node> sort = this.topologicalSort();
514 this.transpose();
515
516 for (Node to : sort) {
517 Concept cto = (Concept) to;
518 for (Object source : this.getPredecessorNodes(to)) {
519 Concept csource = (Concept) source;
520 cto.getSetA().removeAll(csource.getSetA());
521 }
522 }
523 }
524
525 if (setB) {
526
527 List<Node> sort = this.topologicalSort();
528
529 for (Node to : sort) {
530 Concept cto = (Concept) to;
531 for (Object source : this.getSuccessorNodes(to)) {
532 Concept csource = (Concept) source;
533 cto.getSetB().removeAll(csource.getSetB());
534 }
535 }
536 }
537 return true;
538 }
539
540
541
542
543
544
545
546
547
548
549
550 public boolean makeIrreduciblesReduction() {
551
552 if (this.makeInclusionReduction()) {
553
554
555 TreeSet<Node> joinIrr = this.joinIrreducibles();
556 TreeSet<Node> meetIrr = this.meetIrreducibles();
557 for (Object node : this.getNodes()) {
558 Concept c = (Concept) node;
559 if (c.hasSetA() && !c.getSetA().isEmpty() && !joinIrr.contains(c)) {
560 c.putSetA(new ComparableSet());
561 }
562 if (c.hasSetB() && !c.getSetB().isEmpty() && !meetIrr.contains(c)) {
563 c.putSetB(new ComparableSet());
564 }
565 }
566 }
567 return true;
568 }
569
570
571
572
573
574
575
576
577
578 public boolean makeEdgeValuation() {
579 if (!this.containsConcepts()) {
580 return false;
581 }
582 for (Object n1 : this.getNodes()) {
583 for (Object ed : this.getSuccessorEdges((Node) n1)) {
584 if (!((Edge) ed).hasContent()) {
585 Node n2 = ((Edge) ed).getTarget();
586 TreeSet diff = new TreeSet();
587 diff.addAll(((Concept) n2).getSetA());
588 diff.removeAll(((Concept) n1).getSetA());
589 ((Edge) ed).setContent(diff);
590 }
591 }
592 }
593 return true;
594 }
595
596
597
598
599
600
601
602
603
604
605
606
607 public Lattice getJoinReduction() {
608 if (!this.containsConcepts()) {
609 return null;
610 }
611 if (!this.containsAllSetA()) {
612 return null;
613 }
614 Lattice lattice = new Lattice();
615
616 ConceptLattice csl = this.clone();
617 csl.makeIrreduciblesReduction();
618 TreeSet<Node> joinIrr = csl.joinIrreducibles();
619
620 TreeMap<Node, Node> reduced = new TreeMap<Node, Node>();
621 for (Object node : csl.getNodes()) {
622 Concept c = (Concept) node;
623 Node nred;
624 if (c.hasSetA() && joinIrr.contains(node)) {
625 nred = new Node(c.getSetA().first());
626 } else {
627 nred = new Node();
628 }
629 reduced.put((Node) node, nred);
630 }
631
632 for (Object node : csl.getNodes()) {
633 lattice.addNode(reduced.get(node));
634 }
635
636 for (Object source : csl.getNodes()) {
637 for (Object target : csl.getSuccessorNodes((Node) source)) {
638 lattice.addEdge(reduced.get(source), reduced.get(target));
639 }
640 }
641 return lattice;
642 }
643
644
645
646
647
648
649
650
651
652 public Lattice getMeetReduction() {
653 if (!this.containsConcepts()) {
654 return null;
655 }
656 if (!this.containsAllSetB()) {
657 return null;
658 }
659 Lattice lattice = new Lattice();
660 if (!this.containsConcepts()) {
661 return lattice;
662 }
663
664 ConceptLattice csl = this.clone();
665 csl.makeIrreduciblesReduction();
666 TreeSet<Node> meetIrr = csl.meetIrreducibles();
667
668 TreeMap<Node, Node> reduced = new TreeMap<Node, Node>();
669 for (Object node : csl.getNodes()) {
670 Concept c = (Concept) node;
671 Node nred;
672 if (c.hasSetB() && meetIrr.contains(node)) {
673 nred = new Node(c.getSetB().first());
674 } else {
675 nred = new Node();
676 }
677 reduced.put((Node) node, nred);
678 }
679 for (Object node : csl.getNodes()) {
680 lattice.addNode(reduced.get(node));
681 }
682
683 for (Object source : csl.getNodes()) {
684 for (Object target : csl.getSuccessorNodes((Node) source)) {
685 lattice.addEdge(reduced.get(source), reduced.get(target));
686 }
687 }
688 return lattice;
689 }
690
691
692
693
694
695
696
697
698
699
700
701
702 public Lattice getIrreduciblesReduction() {
703 Lattice lattice = new Lattice();
704 if (!this.containsConcepts()) {
705 return lattice;
706 }
707
708 ConceptLattice csl = this.clone();
709 csl.makeIrreduciblesReduction();
710 TreeSet<Node> joinIrr = csl.joinIrreducibles();
711 TreeSet<Node> meetIrr = csl.meetIrreducibles();
712
713 TreeMap<Node, Node> reduced = new TreeMap<Node, Node>();
714 for (Object node : csl.getNodes()) {
715 Concept c = (Concept) node;
716
717 if (c.hasSetA() && c.hasSetB() && meetIrr.contains(c) && joinIrr.contains(c)) {
718 TreeSet<Comparable> content = new TreeSet<Comparable>();
719 content.add(c.getSetA().first());
720 content.add(c.getSetB().first());
721 Node nred = new Node(content);
722 reduced.put((Node) node, nred);
723 } else if (c.hasSetA() && joinIrr.contains(node)) {
724
725 Node nred = new Node(((Concept) node).getSetA().first());
726 reduced.put((Node) node, nred);
727 } else if (c.hasSetB() && meetIrr.contains(node)) {
728
729 Node nred = new Node(((Concept) node).getSetB().first());
730 reduced.put((Node) node, nred);
731 } else {
732 reduced.put((Node) node, new Node());
733 }
734 }
735
736 for (Object node : csl.getNodes()) {
737 lattice.addNode(reduced.get(node));
738 }
739
740 for (Object source : csl.getNodes()) {
741 for (Object target : csl.getSuccessorNodes((Node) source)) {
742 lattice.addEdge(reduced.get(source), reduced.get(target));
743 }
744 }
745 return lattice;
746 }
747
748
749
750
751
752
753
754
755
756
757
758
759 @Deprecated
760 public ConceptLattice iceberg(float threshold) {
761 ConceptLattice l = new ConceptLattice();
762 Concept b = (Concept) this.bottom();
763 int card = b.getSetB().size();
764 for (Object node : this.getNodes()) {
765 Concept cpt = (Concept) node;
766 if ((float) cpt.getSetB().size() / (float) card >= threshold) {
767 l.addNode((Node) node);
768 }
769 }
770 for (Object f : l.getNodes()) {
771 for (Object t : l.getNodes()) {
772 if (this.containsEdge((Node) f, (Node) t)) {
773 l.addEdge((Node) f, (Node) t);
774 }
775 }
776 }
777 Node t = this.top();
778 l.addNode(t);
779
780 for (Object node : l.getWells()) {
781 if (!node.equals(t)) {
782 l.addEdge((Node) node, t);
783 }
784 }
785 return l;
786 }
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805 public void recursiveDiagramLattice(Concept n, ClosureSystem init) {
806 Vector<TreeSet<Comparable>> immSucc = this.immediateSuccessors(n, init);
807 for (TreeSet<Comparable> setX : immSucc) {
808 Concept c = new Concept(new TreeSet(setX), false);
809 Concept ns = (Concept) this.getNode(c);
810 if (ns != null) {
811
812 this.addEdge(n, ns);
813 } else {
814 this.addNode(c);
815 this.addEdge(n, c);
816 this.recursiveDiagramLattice(c, init);
817 }
818 }
819 }
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839 private void recursiveDiagramIceberg(Concept n, ClosureSystem init, int threshold) {
840 Context context = (Context) init;
841 Vector<TreeSet<Comparable>> immSucc = this.immediateSuccessors(n, init);
842 for (TreeSet<Comparable> setX : immSucc) {
843 if (context.getExtentNb(setX) >= threshold) {
844 Concept c = new Concept(new TreeSet(setX), false);
845 Concept ns = (Concept) this.getNode(c);
846 if (ns != null) {
847 this.addEdge(n, ns);
848 } else {
849 this.addNode(c);
850 this.addEdge(n, c);
851 this.recursiveDiagramIceberg(c, init, threshold);
852 }
853 }
854 }
855 }
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882 public Vector<TreeSet<Comparable>> immediateSuccessors(Node n, ClosureSystem init) {
883
884 if (!this.hasDependencyGraph()) {
885 ConcreteDGraph graph = new ConcreteDGraph();
886 for (Comparable c : init.getSet()) {
887 graph.addNode(new Node(c));
888 }
889 this.setDependencyGraph(graph);
890 }
891
892
893
894
895 ComparableSet setF = new ComparableSet(((Concept) n).getSetA());
896 ConcreteDGraph prec = init.precedenceGraph();
897 DAGraph acyclPrec = prec.getStronglyConnectedComponent();
898 ComparableSet newVal = new ComparableSet();
899 newVal.addAll(setF);
900 for (Object x : setF) {
901
902 Node nx = null;
903 for (Object cc : acyclPrec.getNodes()) {
904 TreeSet<Node> setCC = (TreeSet<Node>) ((Node) cc).getContent();
905 for (Node y : setCC) {
906 if (x.equals(y.getContent())) {
907 nx = (Node) cc;
908 }
909 }
910 }
911
912 SortedSet<Node> ccMinNx = acyclPrec.minorants(nx);
913
914 for (Node cc : ccMinNx) {
915 TreeSet<Node> setCC = (TreeSet<Node>) cc.getContent();
916 for (Node y : setCC) {
917 newVal.remove(y.getContent());
918 }
919 }
920 }
921
922 TreeSet<Node> nodes = new TreeSet<Node>();
923 for (Object in : this.getDependencyGraph().getNodes()) {
924 if (!setF.contains(((Node) in).getContent())) {
925 nodes.add((Node) in);
926 }
927 }
928
929
930 TreeSet<Edge> edges = new TreeSet<Edge>();
931 for (Node source : nodes) {
932 for (Node target : nodes) {
933 if (!source.equals(target)) {
934
935
936 ComparableSet fPlusTo = new ComparableSet(setF);
937 fPlusTo.add(target.getContent());
938 fPlusTo = new ComparableSet(init.closure(fPlusTo));
939 if (fPlusTo.contains(source.getContent())) {
940
941
942 Edge ed = this.getDependencyGraph().getEdge(source, target);
943 if (ed == null) {
944 ed = new Edge(source, target, new TreeSet<ComparableSet>());
945 this.getDependencyGraph().addEdge(ed);
946 }
947 edges.add(ed);
948
949 ((TreeSet<ComparableSet>) ed.getContent()).add(newVal);
950 TreeSet<ComparableSet> valEd = new TreeSet<ComparableSet>((TreeSet<ComparableSet>) ed.getContent());
951 for (ComparableSet x1 : valEd) {
952 if (x1.containsAll(newVal) && !newVal.containsAll(x1)) {
953 ((TreeSet<ComparableSet>) ed.getContent()).remove(x1);
954 }
955 if (!x1.containsAll(newVal) && newVal.containsAll(x1)) {
956 ((TreeSet<ComparableSet>) ed.getContent()).remove(newVal);
957 }
958 }
959 }
960 }
961 }
962 }
963
964
965 ConcreteDGraph sub = this.getDependencyGraph().getSubgraphByNodes(nodes);
966 ConcreteDGraph delta = sub.getSubgraphByEdges(edges);
967
968
969 DAGraph cfc = delta.getStronglyConnectedComponent();
970 SortedSet<Node> sccMin = cfc.getSinks();
971 Vector<TreeSet<Comparable>> immSucc = new Vector<TreeSet<Comparable>>();
972 for (Node n1 : sccMin) {
973 TreeSet s = new TreeSet(setF);
974 TreeSet<Node> toadd = (TreeSet<Node>) n1.getContent();
975 for (Node n2 : toadd) {
976 s.add(n2.getContent());
977 }
978 immSucc.add(s);
979 }
980 return immSucc;
981 }
982
983
984
985
986
987
988
989
990 @Override
991 public void save(final String filename) throws IOException {
992 Filer.getInstance().save(this, ConceptLatticeIOFactory.getInstance(), filename);
993 }
994 }