1 package org.thegalactic.lattice;
2
3
4
5
6
7
8
9
10
11
12
13
14 import org.thegalactic.rule.Rule;
15 import org.thegalactic.rule.ImplicationalSystem;
16 import org.thegalactic.rule.AssociationRule;
17 import java.util.TreeMap;
18 import java.util.TreeSet;
19 import java.util.SortedSet;
20 import java.util.ArrayList;
21 import java.util.Iterator;
22 import java.util.LinkedList;
23
24 import org.thegalactic.util.ComparableSet;
25 import org.thegalactic.context.Context;
26 import org.thegalactic.dgraph.DAGraph;
27 import org.thegalactic.dgraph.ConcreteDGraph;
28 import org.thegalactic.dgraph.Edge;
29 import org.thegalactic.dgraph.Node;
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83 public class Lattice<N, E> extends DAGraph<N, E> {
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98 private ConcreteDGraph dependencyGraph = null;
99
100
101
102
103
104
105
106 public Lattice() {
107 super();
108 }
109
110
111
112
113
114
115
116 public Lattice(SortedSet<Node<N>> set) {
117 super(set);
118 }
119
120
121
122
123
124
125
126
127
128
129
130 public Lattice(DAGraph<N, E> graph) {
131 super(graph);
132 if (!this.isAcyclic()) {
133 this.setNodes(new TreeSet<Node<N>>());
134 this.setSuccessors(new TreeMap<Node<N>, TreeSet<Edge<N, E>>>());
135 this.setPredecessors(new TreeMap<Node<N>, TreeSet<Edge<N, E>>>());
136 }
137 }
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153 public boolean isLattice() {
154 if (!this.isAcyclic()) {
155 return false;
156 }
157 for (Node<N> x : this.getNodes()) {
158 for (Node<N> y : this.getNodes()) {
159 if (this.meet(x, y) == null) {
160 return false;
161 }
162 }
163 }
164 return this.max().size() == 1;
165 }
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187 public boolean isCN() {
188 TreeSet<Node<N>> joins = this.joinIrreducibles();
189 TreeSet<Node<N>> meets = this.meetIrreducibles();
190 ArrowRelation arrows = new ArrowRelation(this);
191 Context dbl = arrows.getDoubleArrowTable();
192
193 ArrayList<Concept> steps = new ArrayList<Concept>();
194 while (!joins.isEmpty()) {
195 TreeSet<Comparable> setA = new TreeSet<Comparable>();
196 TreeSet<Comparable> setB = new TreeSet<Comparable>();
197 int cardA = setA.size();
198 setA.add(joins.first());
199 while (cardA != setA.size()) {
200 cardA = setA.size();
201 for (Comparable c : setA) {
202 setB.addAll(dbl.getIntent(c));
203 }
204 for (Comparable c : setB) {
205 setA.addAll(dbl.getExtent(c));
206 }
207 }
208 steps.add(new Concept(setA, setB));
209 joins.removeAll(setA);
210 }
211 for (Concept c : steps) {
212 if (c.getSetB().isEmpty()) {
213 return false;
214 }
215 for (Comparable j : c.getSetA()) {
216 for (Comparable m : c.getSetB()) {
217 if (arrows.getEdge((Node) j, (Node) m).getContent() != "UpDown"
218 && arrows.getEdge((Node) j, (Node) m).getContent() != "Circ") {
219 return false;
220 }
221 }
222 }
223 }
224 joins = this.joinIrreducibles();
225 meets = this.meetIrreducibles();
226 ConcreteDGraph phi = new ConcreteDGraph();
227 for (Node<N> j : joins) {
228 for (Node<N> m : meets) {
229 int indJ = 0;
230 while (indJ < steps.size() && !steps.get(indJ).containsInA(j)) {
231 indJ++;
232 }
233 if (phi.getNodeByContent(indJ) == null && indJ != steps.size()) {
234 phi.addNode(new Node(indJ));
235 }
236 int indM = 0;
237 while (indM < steps.size() && !steps.get(indM).containsInB(m)) {
238 indM++;
239 }
240 if (phi.getNodeByContent(indM) == null && indM != steps.size()) {
241 phi.addNode(new Node(indM));
242 }
243 if (indM != steps.size() && indJ != steps.size()) {
244 if (arrows.getEdge((Node) j, (Node) m).getContent() == "Up") {
245 phi.addEdge(phi.getNodeByContent(indM), phi.getNodeByContent(indJ));
246 }
247 if (arrows.getEdge((Node) j, (Node) m).getContent() == "Down") {
248 phi.addEdge(phi.getNodeByContent(indJ), phi.getNodeByContent(indM));
249 }
250 }
251 }
252 }
253 return (phi.isAcyclic());
254 }
255
256
257
258
259
260
261
262
263
264 public boolean isAtomistic() {
265 TreeSet<Node<N>> join = this.joinIrreducibles();
266 TreeSet<Node> atoms = new TreeSet<Node>(this.getSuccessorNodes(this.bottom()));
267 return join.containsAll(atoms) && atoms.containsAll(join);
268 }
269
270
271
272
273
274
275
276
277
278 public boolean isCoAtomistic() {
279 TreeSet<Node<N>> meet = this.meetIrreducibles();
280 SortedSet<Node<N>> coatoms = this.getPredecessorNodes(this.top());
281 return meet.containsAll(coatoms) && coatoms.containsAll(meet);
282 }
283
284
285
286
287
288
289
290
291
292
293 public Node<N> top() {
294 TreeSet<Node<N>> max = new TreeSet<Node<N>>(this.max());
295 if (max.size() == 1) {
296 return max.first();
297 }
298 return null;
299 }
300
301
302
303
304
305
306
307 public Node<N> bottom() {
308 TreeSet<Node<N>> min = new TreeSet<Node<N>>(this.min());
309 if (min.size() == 1) {
310 return min.first();
311 }
312 return null;
313 }
314
315
316
317
318
319
320
321
322
323
324
325
326 public Node<N> meet(Node<N> x, Node<N> y) {
327
328 SortedSet<Node<N>> xMinorants = new TreeSet<Node<N>>(this.minorants(x));
329 xMinorants.add(x);
330
331 SortedSet<Node<N>> yMinorants = new TreeSet<Node<N>>(this.minorants(y));
332 yMinorants.add(y);
333
334 xMinorants.retainAll(yMinorants);
335 DAGraph<N, E> graph = this.getSubgraphByNodes(xMinorants);
336 TreeSet<Node> meet = new TreeSet<Node>(graph.max());
337 if (meet.size() == 1) {
338 return meet.first();
339 }
340 return null;
341 }
342
343
344
345
346
347
348
349
350
351
352
353
354 public Node<N> join(Node<N> x, Node<N> y) {
355
356 SortedSet<Node<N>> xMajorants = new TreeSet<Node<N>>(this.majorants(x));
357 xMajorants.add(x);
358
359 SortedSet<Node<N>> yMajorants = new TreeSet<Node<N>>(this.majorants(y));
360 yMajorants.add(y);
361
362 xMajorants.retainAll(yMajorants);
363 DAGraph<N, E> graph = this.getSubgraphByNodes(xMajorants);
364 TreeSet<Node> join = new TreeSet<Node>(graph.min());
365 if (join.size() == 1) {
366 return join.first();
367 }
368 return null;
369 }
370
371
372
373
374
375
376
377
378
379
380
381
382
383 public TreeSet<Node<N>> joinIrreducibles() {
384 DAGraph<N, E> graph = new DAGraph(this);
385 graph.reflexiveReduction();
386 graph.transitiveReduction();
387 TreeSet<Node<N>> set = new TreeSet();
388 for (Node<N> node : graph.getNodes()) {
389 if (graph.getPredecessorNodes(node).size() == 1) {
390 set.add(node);
391 }
392 }
393 return set;
394 }
395
396
397
398
399
400
401
402
403
404
405 public TreeSet<Node<N>> meetIrreducibles() {
406 DAGraph<N, E> graph = new DAGraph(this);
407 graph.reflexiveReduction();
408 graph.transitiveReduction();
409 TreeSet<Node<N>> set = new TreeSet();
410 for (Node<N> node : graph.getNodes()) {
411 if (graph.getSuccessorNodes(node).size() == 1) {
412 set.add(node);
413 }
414 }
415 return set;
416 }
417
418
419
420
421
422
423
424
425
426
427 public TreeSet<Node<N>> joinIrreducibles(Node<N> node) {
428 TreeSet<Node<N>> join = new TreeSet<Node<N>>(this.joinIrreducibles());
429 TreeSet<Node<N>> min = new TreeSet<Node<N>>(this.minorants(node));
430 min.add(node);
431 min.retainAll(join);
432 return min;
433 }
434
435
436
437
438
439
440
441
442
443
444 public TreeSet<Node<N>> meetIrreducibles(Node<N> node) {
445 TreeSet<Node<N>> meet = new TreeSet<Node<N>>(this.meetIrreducibles());
446 TreeSet<Node<N>> maj = new TreeSet<Node<N>>(this.majorants(node));
447 maj.retainAll(meet);
448 return maj;
449 }
450
451
452
453
454
455
456
457
458 public DAGraph<N, E> joinIrreduciblesSubgraph() {
459 TreeSet<Node<N>> irr = this.joinIrreducibles();
460 return this.getSubgraphByNodes(irr);
461 }
462
463
464
465
466
467
468
469
470 public DAGraph<N, E> meetIrreduciblesSubgraph() {
471 TreeSet<Node<N>> irr = this.meetIrreducibles();
472 return this.getSubgraphByNodes(irr);
473 }
474
475
476
477
478
479
480 public DAGraph<N, E> irreduciblesSubgraph() {
481 TreeSet<Node<N>> irr = this.meetIrreducibles();
482 irr.addAll(this.joinIrreducibles());
483 return this.getSubgraphByNodes(irr);
484 }
485
486
487
488
489
490
491
492
493
494
495
496 public ConceptLattice joinClosure() {
497 ConceptLattice csl = new ConceptLattice();
498
499 TreeSet<Node<N>> join = this.joinIrreducibles();
500 TreeMap<Node, Concept> closure = new TreeMap<Node, Concept>();
501 Lattice<N, E> lattice = new Lattice(this);
502 lattice.transitiveClosure();
503 lattice.reflexiveClosure();
504 for (Node<N> target : lattice.getNodes()) {
505 ComparableSet jx = new ComparableSet();
506 for (Node<N> source : lattice.getPredecessorNodes(target)) {
507 if (join.contains(source)) {
508 jx.add(source.getContent());
509 }
510 }
511 closure.put(target, new Concept(jx, false));
512 }
513
514 for (Node<N> node : this.getNodes()) {
515 csl.addNode(closure.get(node));
516 }
517
518 for (Edge ed : this.getEdges()) {
519 csl.addEdge(closure.get(ed.getSource()), closure.get(ed.getTarget()));
520 }
521 return csl;
522 }
523
524
525
526
527
528
529
530
531
532
533
534 public ConceptLattice meetClosure() {
535 ConceptLattice csl = new ConceptLattice();
536
537 TreeSet<Node<N>> meet = this.meetIrreducibles();
538 TreeMap<Node, Concept> closure = new TreeMap<Node, Concept>();
539 Lattice<N, E> lattice = new Lattice(this);
540 lattice.transitiveClosure();
541 lattice.reflexiveClosure();
542 for (Node<N> target : lattice.getNodes()) {
543 ComparableSet mx = new ComparableSet();
544 for (Node<N> source : lattice.getSuccessorNodes(target)) {
545 if (meet.contains(source)) {
546 mx.add(source);
547 }
548 }
549 closure.put(target, new Concept(false, mx));
550 }
551
552 for (Node node : this.getNodes()) {
553 csl.addNode(closure.get(node));
554 }
555
556 for (Edge ed : this.getEdges()) {
557 csl.addEdge(closure.get(ed.getSource()), closure.get(ed.getTarget()));
558 }
559 return csl;
560 }
561
562
563
564
565
566
567
568
569
570
571
572 public ConceptLattice irreducibleClosure() {
573 ConceptLattice conceptLatice = new ConceptLattice();
574
575 TreeSet<Node<N>> meet = this.meetIrreducibles();
576 TreeSet<Node<N>> join = this.joinIrreducibles();
577 TreeMap<Node, Concept> closure = new TreeMap<Node, Concept>();
578 Lattice<N, E> lattice = new Lattice(this);
579 lattice.transitiveClosure();
580 lattice.reflexiveClosure();
581 for (Node<N> target : lattice.getNodes()) {
582 ComparableSet jx = new ComparableSet();
583 for (Node<N> source : lattice.getPredecessorNodes(target)) {
584 if (join.contains(source)) {
585 jx.add(source);
586 }
587 }
588 ComparableSet mx = new ComparableSet();
589 for (Node source : lattice.getSuccessorNodes(target)) {
590 if (meet.contains(source)) {
591 mx.add(source);
592 }
593 }
594 closure.put(target, new Concept(jx, mx));
595 }
596
597 for (Node node : this.getNodes()) {
598 conceptLatice.addNode(closure.get(node));
599 }
600
601 for (Edge ed : this.getEdges()) {
602 conceptLatice.addEdge(closure.get(ed.getSource()), closure.get(ed.getTarget()));
603 }
604 return conceptLatice;
605 }
606
607
608
609
610
611
612
613
614
615 public ComparableSet joinClosure(ComparableSet s) {
616
617 ComparableSet stack = new ComparableSet();
618 stack.addAll(s);
619 ComparableSet result = new ComparableSet();
620 while (!stack.isEmpty()) {
621 Node c = (Node) stack.first();
622 stack.remove(c);
623 result.add(c);
624 Iterator<Node> it = stack.iterator();
625 ComparableSet newNodes = new ComparableSet();
626 while (it.hasNext()) {
627 Node node = this.join(it.next(), c);
628 if (!result.contains(node) && !stack.contains(node)) {
629 newNodes.add(node);
630 }
631 }
632 stack.addAll(newNodes);
633 }
634 return result;
635 }
636
637
638
639
640
641
642
643
644
645 public ComparableSet meetClosure(ComparableSet s) {
646
647 ComparableSet stack = new ComparableSet();
648 stack.addAll(s);
649 ComparableSet result = new ComparableSet();
650 while (!stack.isEmpty()) {
651 Node c = (Node) stack.first();
652 stack.remove(c);
653 result.add(c);
654 Iterator<Node> it = stack.iterator();
655 ComparableSet newNodes = new ComparableSet();
656 while (it.hasNext()) {
657 Node node = this.meet(it.next(), c);
658 if (!result.contains(node) && !stack.contains(node)) {
659 newNodes.add(node);
660 }
661 }
662 stack.addAll(newNodes);
663 }
664 return result;
665 }
666
667
668
669
670
671
672
673
674 public ComparableSet fullClosure(ComparableSet s) {
675 ComparableSet result = new ComparableSet();
676 result.addAll(s);
677 int present = result.size();
678 int previous = 0;
679 while (previous != present) {
680 previous = present;
681 result = this.joinClosure(result);
682 result = this.meetClosure(result);
683 present = result.size();
684 }
685 return result;
686 }
687
688
689
690
691
692
693
694 public TreeSet<ComparableSet> hybridGenerators() {
695 TreeSet<Node<N>> joinIrr = this.joinIrreducibles();
696 TreeSet<Node<N>> meetIrr = this.meetIrreducibles();
697 ComparableSet bothIrr = new ComparableSet();
698 for (Node<N> node : joinIrr) {
699 if (meetIrr.contains(node)) {
700 bothIrr.add(node);
701 }
702 }
703
704 TreeSet<ComparableSet> generators = new TreeSet<ComparableSet>();
705
706 LinkedList<ComparableSet> list = new LinkedList<ComparableSet>();
707 list.add(bothIrr);
708 while (!list.isEmpty()) {
709 int test;
710 if (generators.isEmpty()) {
711 test = this.sizeNodes();
712 } else {
713 test = generators.first().size();
714 }
715 if (test < list.peek().size()) {
716
717 list.clear();
718 } else {
719 ComparableSet family = list.poll();
720 if (this.fullClosure(family).size() == this.sizeNodes()) {
721
722 generators.add(family);
723 } else {
724 for (Node node : this.getNodes()) {
725 ComparableSet newFamily = new ComparableSet();
726 newFamily.addAll(family);
727 newFamily.add(node);
728 if (!list.contains(newFamily)) {
729 list.add(newFamily);
730 }
731 }
732 }
733 }
734 }
735 return generators;
736 }
737
738
739
740
741
742
743
744
745
746
747
748
749 public Context getTable() {
750
751 TreeSet<Node<N>> join = this.joinIrreducibles();
752
753 Context context = new Context();
754 for (Node<N> j : join) {
755
756
757 context.addToAttributes(j);
758 }
759
760 TreeSet<Node<N>> meet = this.meetIrreducibles();
761
762 for (Node<N> m : meet) {
763
764 context.addToObservations(m);
765
766 }
767
768 Lattice tmp = new Lattice(this);
769 tmp.transitiveClosure();
770 for (Node j : join) {
771 for (Node m : meet) {
772 if (j.equals(m) || tmp.getSuccessorNodes(j).contains(m)) {
773 context.addExtentIntent(m, j);
774
775 }
776 }
777 }
778 return context;
779 }
780
781
782
783
784
785
786
787
788
789
790 public ImplicationalSystem getImplicationalSystem() {
791
792 TreeSet<Node<N>> join = this.joinIrreducibles();
793 ImplicationalSystem sigma = new ImplicationalSystem();
794 for (Node<N> j : join) {
795 sigma.addElement((Comparable) j.getContent());
796 }
797
798 TreeSet<ComparableSet> family = new TreeSet<ComparableSet>();
799 Lattice lattice = new Lattice(this);
800 ConceptLattice conceptLattice = lattice.joinClosure();
801 for (Object node : conceptLattice.getNodes()) {
802 Concept concept = (Concept) node;
803 ComparableSet setA = new ComparableSet(concept.getSetA());
804 family.add(setA);
805 }
806
807 for (ComparableSet jx : family) {
808 for (Node j : join) {
809 ComparableSet p = new ComparableSet();
810 p.add(j.getContent());
811 p.addAll(jx);
812 if (!family.contains(p)) {
813 ComparableSet min = new ComparableSet();
814 min.addAll(family.last());
815 for (ComparableSet c : family) {
816
817 if (c.containsAll(p) && !p.containsAll(c) && min.containsAll(c)) {
818 min = c.clone();
819 }
820 }
821 Rule r = new Rule();
822 r.addAllToPremise(p);
823 min.removeAll(p);
824 r.addAllToConclusion(min);
825 sigma.addRule(r);
826 }
827 }
828 }
829
830
831
832
833
834
835
836 sigma.makeRightMaximal();
837 return sigma;
838 }
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868 public ConcreteDGraph getDependencyGraph() {
869 if (!(this.dependencyGraph == null)) {
870 return this.dependencyGraph;
871 }
872 this.dependencyGraph = new ConcreteDGraph();
873
874 TreeSet<Node<N>> joins = this.joinIrreducibles();
875 for (Node<N> j : joins) {
876 this.dependencyGraph.addNode(j);
877 }
878
879 DAGraph joinG = this.irreduciblesSubgraph();
880 joinG.transitiveClosure();
881
882
883 for (Node<N> j1 : joins) {
884 SortedSet<Node<N>> majj1 = this.majorants(j1);
885 for (Node<N> j2 : joins) {
886 if (!j1.equals(j2)) {
887
888 TreeSet<Node<N>> set = new TreeSet<Node<N>>(this.getNodes());
889 set.removeAll(majj1);
890 set.removeAll(this.majorants(j2));
891 set.remove(j1);
892 set.remove(j2);
893 for (Node<N> x : set) {
894
895
896 if (majj1.contains(this.join(j2, x))) {
897 Edge ed = this.dependencyGraph.getEdge(j1, j2);
898 if (ed == null) {
899 ed = new Edge(j1, j2, new TreeSet<ComparableSet>());
900 this.dependencyGraph.addEdge(ed);
901 }
902
903
904 TreeSet<ComparableSet> valEd = (TreeSet<ComparableSet>) ed.getContent();
905 ComparableSet newValByNode = new ComparableSet(this.joinIrreducibles(x));
906 for (Node<N> j : this.joinIrreducibles(x)) {
907 newValByNode.removeAll(joinG.getPredecessorNodes(j));
908 }
909 ComparableSet newVal = new ComparableSet();
910 for (Object j : newValByNode) {
911 Node node = (Node) j;
912 newVal.add(node.getContent());
913 }
914 ((TreeSet<ComparableSet>) ed.getContent()).add(newVal);
915
916 valEd = new TreeSet<ComparableSet>((TreeSet<ComparableSet>) ed.getContent());
917 for (ComparableSet x1 : valEd) {
918 if (x1.containsAll(newVal) && !newVal.containsAll(x1)) {
919 ((TreeSet<ComparableSet>) ed.getContent()).remove(x1);
920 }
921 if (!x1.containsAll(newVal) && newVal.containsAll(x1)) {
922 ((TreeSet<ComparableSet>) ed.getContent()).remove(newVal);
923 }
924 }
925 }
926 }
927 }
928 }
929 }
930
931
932
933
934
935
936
937
938
939 return this.dependencyGraph;
940 }
941
942
943
944
945
946
947
948
949 protected Lattice setDependencyGraph(ConcreteDGraph graph) {
950 this.dependencyGraph = graph;
951 return this;
952 }
953
954
955
956
957
958
959 protected boolean hasDependencyGraph() {
960 return this.dependencyGraph != null;
961 }
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978 public ImplicationalSystem getCanonicalDirectBasis() {
979 ConcreteDGraph odGraph = this.getDependencyGraph();
980
981 ImplicationalSystem bcd = new ImplicationalSystem();
982 for (Object node : odGraph.getNodes()) {
983 bcd.addElement((Comparable) ((Node) node).getContent());
984 }
985
986 for (Object ed : odGraph.getEdges()) {
987 Node source = ((Edge) ed).getSource();
988 Node target = ((Edge) ed).getTarget();
989 TreeSet<ComparableSet> l = (TreeSet<ComparableSet>) ((Edge) ed).getContent();
990 for (ComparableSet set : l) {
991 ComparableSet premise = new ComparableSet(set);
992 premise.add((Comparable) target.getContent());
993 ComparableSet conclusion = new ComparableSet();
994 conclusion.add((Comparable) source.getContent());
995 bcd.addRule(new Rule(premise, conclusion));
996 }
997 }
998
999 bcd.makeCompact();
1000 return bcd;
1001 }
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015 public ImplicationalSystem getAssociationBasis(Context context, double support, double confidence) {
1016
1017
1018 int nbObs = context.getObservations().size();
1019
1020
1021 ImplicationalSystem exactRules = this.getCanonicalDirectBasis();
1022 ImplicationalSystem appRules = new ImplicationalSystem();
1023
1024
1025 for (Comparable e : exactRules.getSet()) {
1026 appRules.addElement(e);
1027 }
1028
1029 for (Rule rule : exactRules.getRules()) {
1030
1031
1032 TreeSet<Comparable> gm = rule.getPremise();
1033
1034 TreeSet<Comparable> closedSet = context.closure(gm);
1035
1036
1037 double supportClosedSet = context.getExtentNb(closedSet);
1038 if (supportClosedSet / nbObs > support) {
1039
1040 ArrayList<TreeSet<Comparable>> succs = new Concept(closedSet, new TreeSet()).immediateSuccessorsLOA(context);
1041 for (TreeSet<Comparable> succ : succs) {
1042
1043 double ex = context.getExtentNb(succ);
1044 double supportSucc = ex / supportClosedSet;
1045
1046
1047 TreeSet<Comparable> conclusions = new TreeSet(succ);
1048 conclusions.removeAll(gm);
1049
1050
1051 if (supportSucc > confidence) {
1052 appRules.addRule(new AssociationRule(gm, conclusions, ex / nbObs, supportSucc));
1053 }
1054 }
1055
1056 appRules.addRule(new AssociationRule(rule.getPremise(), rule.getConclusion(), supportClosedSet / nbObs, 1));
1057 }
1058 }
1059 appRules.makeCompactAssociation();
1060 return appRules;
1061 }
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077 public TreeSet getMinimalGenerators() {
1078 ImplicationalSystem bcd = this.getCanonicalDirectBasis();
1079 TreeSet genMin = new TreeSet();
1080 for (Rule r : bcd.getRules()) {
1081 genMin.add(r.getPremise());
1082 }
1083 return genMin;
1084 }
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105 public ArrowRelation getArrowRelation() {
1106 return new ArrowRelation(this);
1107 }
1108 }