1 package org.thegalactic.context;
2
3
4
5
6
7
8
9
10
11
12
13
14 import java.io.IOException;
15 import java.util.ArrayList;
16 import java.util.BitSet;
17 import java.util.Iterator;
18 import java.util.LinkedList;
19 import java.util.Random;
20 import java.util.SortedSet;
21 import java.util.TreeMap;
22 import java.util.TreeSet;
23 import java.util.Vector;
24
25 import org.thegalactic.context.io.ContextIOFactory;
26 import org.thegalactic.dgraph.Node;
27 import org.thegalactic.io.Filer;
28 import org.thegalactic.lattice.ArrowRelation;
29 import org.thegalactic.lattice.ClosureSystem;
30 import org.thegalactic.lattice.Concept;
31 import org.thegalactic.lattice.ConceptLattice;
32 import org.thegalactic.lattice.Lattice;
33 import org.thegalactic.util.ComparableSet;
34 import org.thegalactic.util.Couple;
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93 public class Context extends ClosureSystem {
94
95
96
97
98
99
100
101
102
103
104
105
106 public static Context random(int nbObs, int nbGrp, int nbAttrPerGrp) {
107 Context ctx = new Context();
108 StringBuilder name = new StringBuilder();
109
110 for (int i = 1; i <= nbObs; i++) {
111 ctx.addToObservations(Integer.toString(i));
112 }
113
114 for (int i = 1; i <= nbGrp; i++) {
115 for (int j = 1; j <= nbAttrPerGrp; j++) {
116 int q = i;
117 name.setLength(0);
118 do {
119 int rem = q % 26;
120 q = q / 26;
121 name.append((char) (rem + 65));
122 } while (q != 0);
123 name.append(j);
124 ctx.addToAttributes(name.toString());
125 }
126 }
127
128 Random r = new Random();
129 int attr = r.nextInt(nbAttrPerGrp) + 1;
130 for (int i = 1; i <= nbObs; i++) {
131
132 for (int j = 1; j <= nbGrp; j++) {
133
134 int q = j;
135
136 name.setLength(0);
137 do {
138 int rem = q % 26;
139 q = q / 26;
140 name.append((char) (rem + 65));
141 } while (q != 0);
142 name.append(attr);
143 ctx.addExtentIntent(Integer.toString(i), name.toString());
144 attr = r.nextInt(nbAttrPerGrp) + 1;
145 }
146 }
147 ctx.setBitSets();
148 return ctx;
149 }
150
151
152
153
154
155
156
157 private TreeSet<Comparable> observations;
158
159
160
161
162 private TreeSet<Comparable> attributes;
163
164
165
166
167 private TreeMap<Comparable, TreeSet<Comparable>> intent;
168
169
170
171
172 private TreeMap<Comparable, TreeSet<Comparable>> extent;
173
174
175
176
177
178
179
180 private TreeMap<Comparable, BitSet> bitsetIntent;
181
182
183
184
185 private TreeMap<Comparable, BitSet> bitsetExtent;
186
187
188
189
190 private ArrayList<Comparable> arrayObservations;
191
192
193
194
195 private ArrayList<Comparable> arrayAttributes;
196
197
198
199
200
201
202
203 public Context() {
204 this.init();
205 }
206
207
208
209
210
211
212 public Context(Context context) {
213 this();
214 this.attributes.addAll(context.getAttributes());
215 this.observations.addAll(context.getObservations());
216 for (Comparable o : context.getObservations()) {
217 this.intent.put(o, new TreeSet(context.getIntent(o)));
218 }
219 for (Comparable a : context.getAttributes()) {
220 this.extent.put(a, new TreeSet(context.getExtent(a)));
221 }
222 this.setBitSets();
223 }
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253 public Context(String filename) throws IOException {
254 this.parse(filename);
255 }
256
257
258
259
260
261
262 public Context init() {
263 this.observations = new TreeSet();
264 this.attributes = new TreeSet();
265 this.intent = new TreeMap();
266 this.extent = new TreeMap();
267 this.bitsetIntent = new TreeMap();
268 this.bitsetExtent = new TreeMap();
269 this.arrayObservations = new ArrayList();
270 this.arrayAttributes = new ArrayList();
271 return this;
272 }
273
274
275
276
277
278
279
280
281
282 public Context getSubContext(TreeSet<Comparable> obs, TreeSet<Comparable> attr) {
283 Context ctx = new Context();
284 ctx.addAllToAttributes(attr);
285 ctx.addAllToObservations(obs);
286 for (Comparable o : obs) {
287 for (Comparable a : attr) {
288 if (this.getIntent(o).contains(a)) {
289 ctx.addExtentIntent(o, a);
290 }
291 }
292 }
293 ctx.setBitSets();
294 return ctx;
295 }
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311 public Context getArrowClosedSubContext() {
312 Context result = new Context();
313 result.addAllToAttributes(this.getAttributes());
314 for (Comparable o : this.getObservations()) {
315 result.addToObservations(o);
316 TreeSet<Comparable> setO = new TreeSet<Comparable>();
317 setO.add(o);
318 Context c = this.arrowClosureObject(setO);
319 for (Comparable a : c.getAttributes()) {
320 result.addExtentIntent(o, a);
321 }
322 }
323 return result;
324 }
325
326
327
328
329
330
331
332
333
334
335
336
337
338 public ArrayList<Context> getDivisionContext() {
339 Context arrowCtx = this.getArrowClosedSubContext();
340 arrowCtx.reverse();
341 ConceptLattice clArrowClosed = arrowCtx.conceptLattice(true);
342 Vector<TreeSet<Comparable>> coAtoms = clArrowClosed.immediateSuccessors(clArrowClosed.bottom(), arrowCtx);
343
344
345 ArrayList<Context> goodCoAtoms = new ArrayList<Context>();
346
347 for (int i = 0; i < coAtoms.size(); i++) {
348 TreeSet<Comparable> attrComp = (TreeSet<Comparable>) this.getAttributes().clone();
349 TreeSet<Comparable> attr = arrowCtx.getExtent(coAtoms.get(i));
350 attrComp.removeAll(attr);
351 TreeSet<Comparable> obsComp = (TreeSet<Comparable>) this.getObservations().clone();
352 TreeSet<Comparable> obs = this.arrowClosureObject(coAtoms.get(i)).getObservations();
353 obsComp.removeAll(obs);
354 boolean cross = false;
355 for (Comparable o : obsComp) {
356 for (Comparable a : attrComp) {
357 cross = cross || this.getIntent(o).contains(a);
358 }
359 }
360 if (!cross) {
361 Context subContext = this.getSubContext(obs, attr);
362 goodCoAtoms.add(subContext);
363 }
364 }
365 return goodCoAtoms;
366 }
367
368
369
370
371
372
373
374
375
376
377
378
379
380 public TreeSet<Node> getDivisionConvex(Context ctx) {
381 ConceptLattice factor = ctx.conceptLattice(true);
382 TreeSet<Node> convex = new TreeSet<Node>();
383
384 for (Node node : (SortedSet<Node>) factor.getNodes()) {
385 Concept c = (Concept) node;
386 if (!c.getSetB().containsAll(this.getExtent(c.getSetA()))
387 && !c.getSetA().containsAll(this.getIntent(c.getSetB()))) {
388 convex.add(node);
389 }
390 }
391 return convex;
392 }
393
394
395
396
397
398
399
400
401
402
403 public TreeSet<Comparable> getAttributes() {
404 return this.attributes;
405 }
406
407
408
409
410
411
412
413
414 public boolean containsAttribute(Comparable att) {
415 return this.attributes.contains(att);
416 }
417
418
419
420
421
422
423
424
425 public boolean containsAllAttributes(TreeSet<Comparable> set) {
426 return this.attributes.containsAll(set);
427 }
428
429
430
431
432
433
434
435
436 public boolean addToAttributes(Comparable att) {
437 if (!this.containsAttribute(att)) {
438 this.extent.put(att, new TreeSet<Comparable>());
439 }
440 boolean ok = this.attributes.add(att);
441 this.setBitSets();
442 return ok;
443 }
444
445
446
447
448
449
450
451
452
453 public boolean addAllToAttributes(TreeSet<Comparable> set) {
454 boolean all = true;
455 for (Comparable att : set) {
456 if (!this.addToAttributes(att)) {
457 all = false;
458 }
459 }
460 this.setBitSets();
461 return all;
462 }
463
464
465
466
467
468
469
470
471
472
473 public boolean removeFromAttributes(Comparable att) {
474 this.extent.remove(att);
475 for (Comparable o : this.getObservations()) {
476 this.intent.get(o).remove(att);
477 }
478 boolean ok = this.attributes.remove(att);
479 this.setBitSets();
480 return ok;
481 }
482
483
484
485
486
487
488 public TreeSet<Comparable> getObservations() {
489 return this.observations;
490 }
491
492
493
494
495
496
497
498
499 public boolean containsObservation(Comparable obs) {
500 return this.observations.contains(obs);
501 }
502
503
504
505
506
507
508
509
510 public boolean containsAllObservations(TreeSet<Comparable> set) {
511 return this.observations.containsAll(set);
512 }
513
514
515
516
517
518
519
520
521 public boolean addToObservations(Comparable obs) {
522 if (!this.containsObservation(obs)) {
523 this.intent.put(obs, new TreeSet<Comparable>());
524 }
525 boolean ok = this.observations.add(obs);
526 this.setBitSets();
527 return ok;
528 }
529
530
531
532
533
534
535
536
537
538 public boolean addAllToObservations(TreeSet<Comparable> set) {
539 boolean all = true;
540 for (Comparable obs : set) {
541 if (!this.addToObservations(obs)) {
542 all = false;
543 }
544 }
545 this.setBitSets();
546 return all;
547 }
548
549
550
551
552
553
554
555
556
557
558 public boolean removeFromObservations(Comparable obs) {
559 this.intent.remove(obs);
560 for (Comparable att : this.getAttributes()) {
561 this.extent.get(att).remove(obs);
562 }
563 boolean ok = this.observations.remove(obs);
564 this.setBitSets();
565 return ok;
566 }
567
568
569
570
571
572 public void setBitSets() {
573 this.setMaps();
574 this.setBitSetsIntentExtent();
575 }
576
577
578
579
580 private void setMaps() {
581 this.arrayAttributes = new ArrayList();
582 this.arrayObservations = new ArrayList();
583 Iterator<Comparable> i = this.attributes.iterator();
584 while (i.hasNext()) {
585 this.arrayAttributes.add(i.next());
586 }
587 i = this.observations.iterator();
588 while (i.hasNext()) {
589 this.arrayObservations.add(i.next());
590 }
591 }
592
593
594
595
596 private void setBitSetsIntentExtent() {
597 this.bitsetIntent = new TreeMap();
598 this.bitsetExtent = new TreeMap();
599 Iterator<Comparable> i = this.attributes.iterator();
600 BitSet b = new BitSet(this.observations.size());
601 while (i.hasNext()) {
602 Comparable att = i.next();
603 for (Comparable c : this.extent.get(att)) {
604 b.set(this.arrayObservations.indexOf(c));
605 }
606 this.bitsetExtent.put(att, (BitSet) b.clone());
607 b.clear();
608 }
609 i = this.observations.iterator();
610 b = new BitSet(this.attributes.size());
611 while (i.hasNext()) {
612 Comparable obs = i.next();
613 for (Comparable c : this.intent.get(obs)) {
614 b.set(this.arrayAttributes.indexOf(c));
615 }
616 this.bitsetIntent.put(obs, (BitSet) b.clone());
617 b.clear();
618 }
619 }
620
621
622
623
624
625
626
627
628
629
630
631
632 public TreeSet<Comparable> getIntent(Comparable obs) {
633 if (this.containsObservation(obs)) {
634 return this.intent.get(obs);
635 } else {
636 return new TreeSet();
637 }
638 }
639
640
641
642
643
644
645
646
647
648 public TreeSet<Comparable> getIntent(TreeSet<Comparable> set) {
649 TreeSet<Comparable> resIntent = new TreeSet(this.getAttributes());
650 for (Comparable obs : set) {
651 resIntent.retainAll(this.getIntent(obs));
652 }
653 return resIntent;
654 }
655
656
657
658
659
660
661
662
663
664 public int getIntentNb(TreeSet<Comparable> set) {
665 int size = this.getAttributes().size();
666 BitSet obsIntent = new BitSet(size);
667 obsIntent.set(0, size);
668 for (Comparable obs : set) {
669 try {
670 obsIntent.and(this.bitsetIntent.get(obs));
671 } catch (NullPointerException e) {
672 return 0;
673 }
674 }
675 return obsIntent.cardinality();
676 }
677
678
679
680
681
682
683
684
685
686
687 public boolean containAsIntent(Comparable obs, Comparable att) {
688 if (this.containsObservation(obs) && this.containsAttribute(att)) {
689 return this.intent.get(obs).contains(att);
690 } else {
691 return false;
692 }
693 }
694
695
696
697
698
699
700
701
702
703 public TreeSet<Comparable> getExtent(Comparable att) {
704 if (this.containsAttribute(att)) {
705 return this.extent.get(att);
706 } else {
707 return new TreeSet();
708 }
709 }
710
711
712
713
714
715
716
717
718
719 public TreeSet<Comparable> getExtent(TreeSet<Comparable> set) {
720 TreeSet<Comparable> attExtent = new TreeSet(this.getObservations());
721 for (Comparable att : set) {
722 attExtent.retainAll(this.getExtent(att));
723 }
724 return attExtent;
725 }
726
727
728
729
730
731
732
733
734
735 public int getExtentNb(TreeSet<Comparable> set) {
736 int size = this.getObservations().size();
737 BitSet attExtent = new BitSet(size);
738 attExtent.set(0, size);
739 for (Comparable att : set) {
740 try {
741 attExtent.and(this.bitsetExtent.get(att));
742 } catch (NullPointerException e) {
743 return 0;
744 }
745 }
746 return attExtent.cardinality();
747 }
748
749
750
751
752
753
754
755
756
757
758 public boolean containAsExtent(Comparable att, Comparable obs) {
759 if (this.containsObservation(obs) && this.containsAttribute(att)) {
760 return this.extent.get(att).contains(obs);
761 } else {
762 return false;
763 }
764 }
765
766
767
768
769
770
771
772
773
774
775
776
777 public boolean addExtentIntent(Comparable obs, Comparable att) {
778 if (this.containsObservation(obs) && this.containsAttribute(att)) {
779 boolean ok = this.intent.get(obs).add(att) && this.extent.get(att).add(obs);
780 this.setBitSets();
781 return ok;
782 } else {
783 return false;
784 }
785 }
786
787
788
789
790
791
792
793
794
795
796
797
798 public boolean removeExtentIntent(Comparable obs, Comparable att) {
799 if (this.containsObservation(obs) && this.containsAttribute(att)) {
800 boolean ok = this.intent.get(obs).remove(att) && this.extent.get(att).remove(obs);
801 this.setBitSets();
802 return ok;
803 } else {
804 return false;
805 }
806 }
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833 @Override
834 public String toString() {
835 String string;
836 StringBuilder builder = new StringBuilder();
837 builder.append("Observations: ");
838 for (Comparable o : this.observations) {
839
840
841
842 string = o.toString();
843 if (string.contains(" ") || string.contains("\"") || string.contains("\n") || string.contains("\t")) {
844 string = "\"" + string.replace("\"", "\\\"").replace("\n", "\\n").replace("\t", "\\t") + "\"";
845 }
846 builder.append(string).append(" ");
847 }
848
849 String newLine = System.getProperty("line.separator");
850 builder.append(newLine).append("Attributes: ");
851 for (Comparable a : this.attributes) {
852
853
854
855 string = a.toString();
856 if (string.contains(" ") || string.contains("\"") || string.contains("\n") || string.contains("\t")) {
857 string = "\"" + string.replace("\"", "\\\"").replace("\n", "\\n").replace("\t", "\\t") + "\"";
858 }
859 builder.append(string).append(" ");
860 }
861
862
863
864
865
866 builder.append(newLine);
867 for (Comparable o : this.observations) {
868 string = o.toString();
869 if (string.contains(" ") || string.contains("\"") || string.contains("\n") || string.contains("\t")) {
870 string = "\"" + string.replace("\"", "\\\"").replace("\n", "\\n").replace("\t", "\\t") + "\"";
871 }
872 builder.append(string).append(": ");
873 for (Comparable a : this.getIntent(o)) {
874 string = a.toString();
875 if (string.contains(" ") || string.contains("\"") || string.contains("\n") || string.contains("\t")) {
876 string = "\"" + string.replace("\"", "\\\"").replace("\n", "\\n").replace("\t", "\\t") + "\"";
877 }
878 builder.append(string).append(" ");
879 }
880 builder.append(newLine);
881 }
882 return builder.toString();
883 }
884
885
886
887
888
889
890
891
892 public void save(final String filename) throws IOException {
893 Filer.getInstance().save(this, ContextIOFactory.getInstance(), filename);
894 }
895
896
897
898
899
900
901
902
903
904
905
906 public Context parse(final String filename) throws IOException {
907 this.init();
908 Filer.getInstance().parse(this, ContextIOFactory.getInstance(), filename);
909 return this;
910 }
911
912
913
914
915
916
917
918
919
920
921
922
923 public TreeMap<Comparable, TreeSet<Comparable>> attributesReduction() {
924
925 TreeMap red = this.getReducibleElements();
926
927 for (Object att : red.keySet()) {
928 this.removeFromAttributes((Comparable) att);
929 }
930 return red;
931 }
932
933
934
935
936
937
938
939
940
941
942
943
944 public TreeMap<Comparable, TreeSet<Comparable>> observationsReduction() {
945
946 this.reverse();
947 TreeMap red = this.getReducibleElements();
948 this.reverse();
949
950 for (Object att : red.keySet()) {
951 this.removeFromObservations((Comparable) att);
952 }
953 return red;
954 }
955
956
957
958
959
960
961
962
963
964
965 public TreeMap<Comparable, TreeSet<Comparable>> reduction() {
966 TreeMap<Comparable, TreeSet<Comparable>> red = this.attributesReduction();
967 red.putAll(this.observationsReduction());
968 return red;
969 }
970
971
972
973
974
975
976 public void reverse() {
977 TreeSet<Comparable> tmp = this.attributes;
978 this.attributes = this.observations;
979 this.observations = tmp;
980 TreeMap<Comparable, TreeSet<Comparable>> sauv = this.intent;
981 this.intent = this.extent;
982 this.extent = sauv;
983 }
984
985
986
987
988
989
990 public Context getReverseContext() {
991 Context context = new Context(this);
992 context.reverse();
993 context.setBitSets();
994 return context;
995 }
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008 public Context arrowClosureObject(TreeSet<Comparable> obs) {
1009 ConceptLattice cl = this.getReverseContext().conceptLattice(true);
1010 ArrowRelation ar = cl.getArrowRelation();
1011
1012
1013
1014
1015 Context down = ar.getDoubleDownArrowTable();
1016 Context up = ar.getDoubleUpArrowTable();
1017 Context ctx = new Context();
1018 ctx.addAllToObservations(obs);
1019 int sizeObs = ctx.getObservations().size();
1020 int sizeAttr = ctx.getAttributes().size();
1021 int prevObs = 0;
1022 int prevAttr = 0;
1023 while ((prevObs < sizeObs) || (prevAttr < sizeAttr)) {
1024 for (Comparable o : ctx.getObservations()) {
1025
1026 TreeSet<Comparable> setBo = this.getIntent(o);
1027 TreeSet<Comparable> setAo = this.getExtent(setBo);
1028 Concept cptO = new Concept(setAo, setBo);
1029 TreeSet<Comparable> attrUp = up.getIntent(cl.getNode(cptO));
1030 for (Comparable a : this.getAttributes()) {
1031
1032 TreeSet<Comparable> setAa = this.getExtent(a);
1033 TreeSet<Comparable> setBa = this.getIntent(setAa);
1034 Concept cptA = new Concept(setAa, setBa);
1035 if (attrUp.contains(cl.getNode(cptA))) {
1036 ctx.addToAttributes(a);
1037 }
1038 }
1039 }
1040 for (Comparable a : ctx.getAttributes()) {
1041
1042 TreeSet<Comparable> setAa = this.getExtent(a);
1043 TreeSet<Comparable> setBa = this.getIntent(setAa);
1044 Concept cptA = new Concept(setAa, setBa);
1045 TreeSet<Comparable> obsDown = down.getExtent(cl.getNode(cptA));
1046 for (Comparable o : this.getObservations()) {
1047
1048 TreeSet<Comparable> setBo = this.getIntent(o);
1049 TreeSet<Comparable> setAo = this.getExtent(setBo);
1050 Concept cptO = new Concept(setAo, setBo);
1051 if (obsDown.contains(cl.getNode(cptO))) {
1052 ctx.addToObservations(o);
1053 }
1054 }
1055 }
1056 prevObs = sizeObs;
1057 prevAttr = sizeAttr;
1058 sizeObs = ctx.getObservations().size();
1059 sizeAttr = ctx.getAttributes().size();
1060 }
1061 return this.getSubContext(ctx.getObservations(), ctx.getAttributes());
1062 }
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075 public Context arrowClosureAttribute(TreeSet<Comparable> attr) {
1076 ConceptLattice cl = this.getReverseContext().conceptLattice(true);
1077 ArrowRelation ar = cl.getArrowRelation();
1078 Context down = ar.getDoubleDownArrowTable();
1079 Context up = ar.getDoubleUpArrowTable();
1080 Context ctx = new Context();
1081 ctx.addAllToAttributes(attr);
1082 int sizeObs = ctx.getObservations().size();
1083 int sizeAttr = ctx.getAttributes().size();
1084 int prevObs = 0;
1085 int prevAttr = 0;
1086 while ((prevObs < sizeObs) || (prevAttr < sizeAttr)) {
1087 for (Comparable a : ctx.getAttributes()) {
1088
1089 TreeSet<Comparable> setAa = this.getExtent(a);
1090 TreeSet<Comparable> setBa = this.getIntent(setAa);
1091 Concept cptA = new Concept(setAa, setBa);
1092 TreeSet<Comparable> obsDown = down.getExtent(cl.getNode(cptA));
1093 for (Comparable o : this.getObservations()) {
1094
1095 TreeSet<Comparable> setBo = this.getIntent(o);
1096 TreeSet<Comparable> setAo = this.getExtent(setBo);
1097 Concept cptO = new Concept(setAo, setBo);
1098 if (obsDown.contains(cl.getNode(cptO))) {
1099 ctx.addToObservations(o);
1100 }
1101 }
1102 }
1103 for (Comparable o : ctx.getObservations()) {
1104
1105 TreeSet<Comparable> setBo = this.getIntent(o);
1106 TreeSet<Comparable> setAo = this.getExtent(setBo);
1107 Concept cptO = new Concept(setAo, setBo);
1108 TreeSet<Comparable> attrUp = up.getIntent(cl.getNode(cptO));
1109 for (Comparable a : this.getAttributes()) {
1110
1111 TreeSet<Comparable> setAa = this.getExtent(a);
1112 TreeSet<Comparable> setBa = this.getIntent(setAa);
1113 Concept cptA = new Concept(setAa, setBa);
1114 if (attrUp.contains(cl.getNode(cptA))) {
1115 ctx.addToAttributes(a);
1116 }
1117 }
1118 }
1119 prevObs = sizeObs;
1120 prevAttr = sizeAttr;
1121 sizeObs = ctx.getObservations().size();
1122 sizeAttr = ctx.getAttributes().size();
1123 }
1124 return this.getSubContext(ctx.getObservations(), ctx.getAttributes());
1125 }
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143 @Override
1144 public TreeSet<Comparable> getSet() {
1145 return this.attributes;
1146 }
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160 @Override
1161 public TreeSet<Comparable> closure(TreeSet<Comparable> set) {
1162 return this.getIntent(this.getExtent(set));
1163 }
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173 public TreeSet<Comparable> getExtentUnion(TreeSet<Comparable> set) {
1174 TreeSet<Comparable> ext = new TreeSet();
1175 for (Comparable att : set) {
1176 for (Comparable obs : this.getExtent(att)) {
1177 if (this.containAsExtent(att, obs) && !ext.contains(obs)) {
1178 ext.add(obs);
1179 }
1180 }
1181 }
1182 return ext;
1183 }
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197 public ComparableSet inverseClosure(ComparableSet set) {
1198 return new ComparableSet(this.getExtent(this.getIntent((TreeSet) set)));
1199 }
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218 public ConceptLattice conceptLattice(boolean diagram) {
1219 ConceptLattice csl = this.closedSetLattice(diagram);
1220
1221 for (Object node : csl.getNodes()) {
1222 Concept cl = (Concept) node;
1223 cl.putSetB(new ComparableSet(this.getExtent(cl.getSetA())));
1224 }
1225 return csl;
1226 }
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236 private ArrayList<Couple> recursiveGenProd(Couple c, LinkedList<ConceptLattice> clParts) {
1237 LinkedList<ConceptLattice> copy = (LinkedList<ConceptLattice>) clParts.clone();
1238 if (copy.isEmpty()) {
1239 ArrayList<Couple> result = new ArrayList<Couple>();
1240 result.add(c);
1241 return result;
1242 } else {
1243 ConceptLattice cl = (ConceptLattice) copy.poll();
1244 ArrayList<Couple> nodes = new ArrayList<Couple>();
1245 for (Object node : cl.getNodes()) {
1246 ArrayList<Concept> listCopy = new ArrayList<Concept>();
1247 for (Concept cpt : (ArrayList<Concept>) c.getLeft()) {
1248 listCopy.add(cpt);
1249 }
1250 Couple coupleCopy = new Couple(listCopy, c.getRight());
1251 ((ArrayList<Concept>) coupleCopy.getLeft()).add((Concept) node);
1252 nodes.addAll(recursiveGenProd(coupleCopy, copy));
1253 }
1254 return nodes;
1255 }
1256 }
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267 public Lattice subDirectDecomposition() {
1268
1269 ArrayList<Context> parts = new ArrayList<Context>();
1270 for (Comparable o : this.getObservations()) {
1271 TreeSet<Comparable> setO = new TreeSet<Comparable>();
1272 setO.add(o);
1273 parts.add(this.arrowClosureObject(setO));
1274 }
1275
1276
1277 ArrayList<Context> single = new ArrayList<Context>();
1278 for (int i = 0; i < parts.size(); i++) {
1279 boolean containedNext = false;
1280 for (int j = i + 1; j < parts.size(); j++) {
1281 containedNext = containedNext || (parts.get(i).containsAllObservations(parts.get(j).getObservations())
1282 && parts.get(j).containsAllObservations(parts.get(i).getObservations())
1283 && parts.get(i).containsAllAttributes(parts.get(j).getAttributes())
1284 && parts.get(j).containsAllAttributes(parts.get(i).getAttributes()));
1285 }
1286 if (!containedNext) {
1287 single.add(parts.get(i));
1288 }
1289 }
1290 parts = single;
1291 ArrayList<Context> toBeRemoved = new ArrayList<Context>();
1292 for (Context remove : parts) {
1293 for (Context test : parts) {
1294 if ((parts.indexOf(test) != parts.indexOf(remove))
1295 && (test.containsAllObservations(remove.getObservations()))
1296 && (test.containsAllAttributes(remove.getAttributes()))) {
1297 toBeRemoved.add(remove);
1298 }
1299 }
1300 }
1301 parts.removeAll(toBeRemoved);
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311 LinkedList<ConceptLattice> clParts = new LinkedList<ConceptLattice>();
1312 for (Context ctx : parts) {
1313 clParts.add(ctx.conceptLattice(true));
1314 }
1315 Lattice prod = new Lattice();
1316
1317 ArrayList<Couple> nodes = new ArrayList<Couple>();
1318 LinkedList<ConceptLattice> copy = (LinkedList<ConceptLattice>) clParts.clone();
1319 ConceptLattice firstCL = (ConceptLattice) copy.poll();
1320 for (Object node : firstCL.getNodes()) {
1321 Couple couple = new Couple(new ArrayList<Concept>(), false);
1322 ArrayList<Concept> prodCPT = new ArrayList<Concept>();
1323 prodCPT.add((Concept) node);
1324 couple.setLeft(prodCPT);
1325 nodes.addAll(recursiveGenProd(couple, copy));
1326 }
1327 for (Couple c : nodes) {
1328 prod.addNode(new Node(c));
1329 }
1330
1331 for (Object source : prod.getNodes()) {
1332 for (Object target : prod.getNodes()) {
1333 Couple contentSource = (Couple) ((Node) source).getContent();
1334 Couple contentTarget = (Couple) ((Node) target).getContent();
1335 boolean haveEdge = true;
1336 boolean equals = true;
1337 for (int i = 0; i < clParts.size(); i++) {
1338 Concept cptSource = ((ArrayList<Concept>) contentSource.getLeft()).get(i);
1339 Concept cptTarget = ((ArrayList<Concept>) contentTarget.getLeft()).get(i);
1340 equals = equals && cptSource.equals(cptTarget);
1341 haveEdge = haveEdge && (clParts.get(i).containsEdge(cptSource, cptTarget) || cptSource.equals(cptTarget));
1342 }
1343 if (haveEdge && !equals) {
1344 prod.addEdge(((Node) source), ((Node) target));
1345 }
1346 }
1347 }
1348 prod.transitiveReduction();
1349
1350
1351
1352 ConceptLattice cl = this.conceptLattice(true);
1353 for (Object cpt : cl.getNodes()) {
1354
1355 ArrayList<Concept> subCpt = new ArrayList<Concept>();
1356 for (int i = 0; i < parts.size(); i++) {
1357 Context ctx = parts.get(i);
1358 ConceptLattice term = clParts.get(i);
1359 ComparableSet setA = new ComparableSet();
1360 setA.addAll(((Concept) cpt).getSetA());
1361 ComparableSet setB = new ComparableSet();
1362 setB.addAll(((Concept) cpt).getSetB());
1363 setA.retainAll(ctx.getAttributes());
1364 setB.retainAll(ctx.getObservations());
1365 subCpt.add(term.getConcept((ComparableSet) setA, (ComparableSet) setB));
1366 }
1367
1368 for (Object nodeProd : prod.getNodes()) {
1369 if (((Couple) ((Node) nodeProd).getContent()).getLeft().equals(subCpt)) {
1370 ((Couple) ((Node) nodeProd).getContent()).setRight(true);
1371 }
1372 }
1373 }
1374 return prod;
1375 }
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389 public ConceptLattice closedSetIceberg(double support) {
1390 return ConceptLattice.diagramIceberg(this, support);
1391 }
1392
1393
1394
1395
1396
1397
1398 @Override
1399 public ConceptLattice lattice() {
1400 return this.conceptLattice(true);
1401 }
1402 }