1 package org.thegalactic.lattice;
2
3 /*
4 * BijectiveComponents.java
5 *
6 * Copyright: 2010-2015 Karell Bertet, France
7 * Copyright: 2015-2016 The Galactic Organization, France
8 *
9 * License: http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html CeCILL-B license
10 *
11 * This file is part of java-lattices.
12 * You can redistribute it and/or modify it under the terms of the CeCILL-B license.
13 */
14 import org.thegalactic.rule.ImplicationalSystem;
15 import java.io.BufferedWriter;
16 import java.io.File;
17 import java.io.FileWriter;
18 import java.io.IOException;
19 import java.util.Date;
20 import java.util.TreeSet;
21
22 import org.thegalactic.context.Context;
23 import org.thegalactic.dgraph.ConcreteDGraph;
24 import org.thegalactic.util.ComparableSet;
25
26 /**
27 * This class generates bijective components issued from lattice theory for a
28 * specified closure system.
29 *
30 * Bijective components are: closed set lattice or concept lattice, reduced
31 * lattice, reduced context, canonical direct basis, minimal generators and
32 * canonical basis, dependency graph.
33 *
34 * A closure system is described by the abstract class {@link ClosureSystem}. In
35 * this package, a closure system can be instancied by an implicational system
36 * described by class {@link ImplicationalSystem}) or a context described by
37 * class {@link Context}).
38 *
39 * This class provides a constructor, and only two methods: the method
40 * {@link #compute} generates all the bijective components of the specified
41 * closure system; and the method {@link #save} saves theses components in
42 * files.
43 *
44 * This class can be used as follows:
45 *
46 * ~~~Java
47 * BijectiveComponents bc = new BijectiveComponents(initialClosureSystem);
48 * bc.compute();
49 * bc.save(dirString,nameString);
50 * ~~~
51 *
52 * 
53 *
54 * @uml BijectiveComponents.png
55 * !include resources/org/thegalactic/lattice/BijectiveComponents.iuml
56 * !include resources/org/thegalactic/lattice/ClosureSystem.iuml
57 *
58 * hide members
59 * show BijectiveComponents members
60 * class BijectiveComponents #LightCyan
61 * title BijectiveComponents UML graph
62 */
63 public class BijectiveComponents {
64
65 /*
66 * ------------- FIELDS ------------------
67 */
68 /**
69 * The initial closure system.
70 */
71 private ClosureSystem closureSystem;
72
73 /**
74 * The closed set lattice of the closure system when closure system is an
75 * implicational system.
76 *
77 * The concept lattice of the closure system when closure system is a
78 * context
79 */
80 private ConceptLattice lattice = null;
81
82 /**
83 * The reduced lattice.
84 */
85 private Lattice reducedLattice = null;
86
87 /**
88 * The dependency graph of the reduced lattice.
89 */
90 private ConcreteDGraph dependencyGraph = null;
91
92 /**
93 * The minimal generators of the reduced lattice.
94 */
95 private TreeSet<ComparableSet> minimalGenerators = null;
96
97 /**
98 * The canonical direct basis of the reduced lattice.
99 */
100 private ImplicationalSystem canonicalDirectBasis = null;
101
102 /**
103 * The canonical basis of the reduced lattice.
104 */
105 private ImplicationalSystem canonicalBasis = null;
106
107 /**
108 * The table of the reduced lattice.
109 */
110 private Context table = null;
111
112 /**
113 * Constructs this component with the specified Closure System as initial
114 * closure system.
115 *
116 * @param closureSystem initial closure system
117 */
118 public BijectiveComponents(ClosureSystem closureSystem) {
119 this.initialise(closureSystem);
120 }
121
122 /**
123 * Initialise the closure system.
124 *
125 * @param closureSystem initial closure system
126 *
127 * @return this for chaining
128 */
129 public BijectiveComponents initialise(ClosureSystem closureSystem) {
130 this.closureSystem = closureSystem;
131 this.lattice = null;
132 this.reducedLattice = null;
133 this.table = null;
134 this.dependencyGraph = null;
135 this.minimalGenerators = null;
136 this.canonicalDirectBasis = null;
137 this.canonicalBasis = null;
138 return this;
139 }
140
141 /**
142 * Generates all the bijective components included in this component issued
143 * from the initial closure system `closureSystem`.
144 *
145 * The closed set lattice is generated and obtained by
146 *
147 * ~~~Java
148 * this.getClosureSystem().lattice();
149 * ~~~
150 *
151 * The reduced lattice is obtained by
152 *
153 * ~~~Java
154 * this.getLattice().getIrreduciblesReduction();
155 * ~~~
156 *
157 * The reduced table is obtained by
158 *
159 * ~~~Java
160 * this.getReducedLattice().getTable();
161 * ~~~
162 *
163 * The dependency graph is obtained by
164 *
165 * ~~~Java
166 * this.getReducedLattice().getDependencyGraph();
167 * ~~~
168 *
169 * Minimal generators are obtained by
170 *
171 * ~~~Java
172 * this.getReducedLattice().getMinimalGenerators();
173 * ~~~
174 *
175 * The canonical direct basis is obtained by
176 *
177 * ~~~Java
178 * this.getReducedLattice().getCanonicalDirectBasis();
179 * ~~~
180 *
181 * The canonical basis is obtained by
182 *
183 * ~~~Java
184 * (new
185 * ImplicationalSystem(this.canonicalDirectBasis)).makeCanonicalBasis();
186 * ~~~
187 *
188 * @return time of computation
189 */
190 public long compute() {
191 this.initialise(closureSystem);
192 long debut = new Date().getTime();
193 this.getLattice();
194 this.getReducedLattice();
195 this.getTable();
196 this.getDependencyGraph();
197 this.getMinimalGenerators();
198 this.getCanonicalDirectBasis();
199 this.getCanonicalBasis();
200 long fin = new Date().getTime();
201 return fin - debut;
202 }
203
204 /**
205 * Saves all the bijective components included in this component in files
206 * saved in the specified directory. A global description is saved in file
207 * `name+"Readme.txt"`.
208 *
209 * The specified name is used to defined a name for each file.
210 *
211 * @param directory location to save file
212 * @param name name of the files
213 *
214 * @throws IOException When an IOException occurs
215 */
216 public void save(String directory, String name) throws IOException {
217 // create the directory
218 String realDirectory = directory + File.separator + name + "BijectiveComponents" + File.separator;
219 File f = new File(realDirectory);
220 f.mkdir();
221 realDirectory += name;
222 BufferedWriter file = new BufferedWriter(new FileWriter(realDirectory + "Readme.txt"));
223 // saves the inital closure system
224 String nameInit = realDirectory + "InitialClosureSystem.txt";
225 this.closureSystem.save(nameInit);
226 String newLine = System.getProperty("line.separator");
227 file.write("-> Initial closure system saved in " + nameInit + ": " + newLine);
228 file.write(this.closureSystem.toString() + newLine);
229 // saves the closed set lattice
230 String nameLattice = realDirectory + "Lattice.dot";
231 this.getLattice().save(nameLattice);
232 file.write("-> Closed set or concept lattice saved in " + nameLattice + newLine);
233 // saves the reduced lattice
234 String nameReducedLattice = realDirectory + "ReducedLattice.dot";
235 this.getReducedLattice().save(nameReducedLattice);
236 file.write("-> Reduced lattice saved in " + nameReducedLattice + newLine);
237 // saves the reduced table
238 String nameTable = realDirectory + "Table.txt";
239 this.getTable().save(nameTable);
240 file.write("-> Table of the reduced lattice saved in " + nameTable + newLine);
241 file.write(this.table.toString() + newLine);
242 // saves the canonical basis
243 String nameCB = realDirectory + "CanonicalBasis.txt";
244 this.getCanonicalBasis().save(nameCB);
245 file.write("-> Canonical basis saved in " + nameCB + ": " + newLine);
246 file.write(this.canonicalBasis.toString() + newLine);
247 // saves the canonical direct basis
248 String nameCDB = realDirectory + "CanonicalDirectBasis.txt";
249 this.getCanonicalDirectBasis().save(nameCDB);
250 file.write("-> Canonical direct basis of the reduced lattice saved in " + nameCDB + ": " + newLine);
251 file.write(this.canonicalDirectBasis.toString() + newLine);
252 // saves the dependency graph
253 String nameODGraph = realDirectory + "DependencyGraph.dot";
254 this.getDependencyGraph().save(nameODGraph);
255 file.write("-> Dependency Graph of the reduced lattice saved in " + nameODGraph + " " + newLine);
256 // saves the minimal generators
257 file.write("-> Minimal generators of the reduced lattice are " + this.minimalGenerators + newLine);
258 file.close();
259 }
260
261 /**
262 * Returns the closure system of this component.
263 *
264 * @return closure system of this component
265 */
266 public ClosureSystem getClosureSystem() {
267 return closureSystem;
268 }
269
270 /**
271 * Set the closure system of this component.
272 *
273 * @param closureSystem used to define field of this component
274 *
275 * @return this for chaining
276 */
277 protected BijectiveComponents setClosureSystem(ClosureSystem closureSystem) {
278 this.closureSystem = closureSystem;
279 return this;
280 }
281
282 /**
283 * Returns the lattice of this component.
284 *
285 * @return lattice of this component
286 */
287 public ConceptLattice getLattice() {
288 if (lattice == null) {
289 lattice = this.closureSystem.lattice();
290 }
291 return lattice;
292 }
293
294 /**
295 * Set the lattice of this component.
296 *
297 * @param lattice used to define field of this component
298 *
299 * @return this for chaining
300 */
301 protected BijectiveComponents setLattice(ConceptLattice lattice) {
302 this.lattice = lattice;
303 return this;
304 }
305
306 /**
307 * Returns the reduced lattice of this component.
308 *
309 * @return reduced lattice of this component
310 */
311 public Lattice getReducedLattice() {
312 if (reducedLattice == null) {
313 reducedLattice = this.getLattice().getIrreduciblesReduction();
314 }
315 return reducedLattice;
316 }
317
318 /**
319 * Set the reduced lattice of this component.
320 *
321 * @param reducedLattice used to define field of this component
322 *
323 * @return this for chaining
324 */
325 protected BijectiveComponents setReducedLattice(Lattice reducedLattice) {
326 this.reducedLattice = reducedLattice;
327 return this;
328 }
329
330 /**
331 * Returns the dependency graph of this component.
332 *
333 * @return dependencyGraph dependency graph of this component
334 */
335 public ConcreteDGraph getDependencyGraph() {
336 if (dependencyGraph == null) {
337 // FIXME: do we use getLattice or getReducedLattice ?
338 dependencyGraph = this.getReducedLattice().getDependencyGraph();
339 }
340 return dependencyGraph;
341 }
342
343 /**
344 * Set the dependency graph of this component.
345 *
346 * @param dependencyGraph used to define field of this component
347 *
348 * @return this for chaining
349 */
350 protected BijectiveComponents setDependencyGraph(ConcreteDGraph dependencyGraph) {
351 this.dependencyGraph = dependencyGraph;
352 return this;
353 }
354
355 /**
356 * Returns the minimal generators of this component.
357 *
358 * @return minimal generators of this component
359 */
360 public TreeSet<ComparableSet> getMinimalGenerators() {
361 if (minimalGenerators == null) {
362 // FIXME: do we use getLattice or getReducedLattice ?
363 minimalGenerators = this.getReducedLattice().getMinimalGenerators();
364 }
365 return minimalGenerators;
366 }
367
368 /**
369 * Returns the canonical direct basis of this component.
370 *
371 * @return the canonical direct basis of this component
372 */
373 public ImplicationalSystem getCanonicalDirectBasis() {
374 if (canonicalDirectBasis == null) {
375 // FIXME: do we use getLattice or getReducedLattice ?
376 canonicalDirectBasis = this.getReducedLattice().getCanonicalDirectBasis();
377 }
378 return canonicalDirectBasis;
379 }
380
381 /**
382 * Returns the canonical basis of this component.
383 *
384 * @return the canonical basis of this component
385 */
386 public ImplicationalSystem getCanonicalBasis() {
387 if (canonicalBasis == null) {
388 canonicalBasis = new ImplicationalSystem(this.getCanonicalDirectBasis());
389 canonicalBasis.makeCanonicalBasis();
390 }
391 return canonicalBasis;
392 }
393
394 /**
395 * Returns the Table of this component.
396 *
397 * @return table of this component
398 */
399 public Context getTable() {
400 if (table == null) {
401 // FIXME: do we use getLattice or getReducedLattice ?
402 table = this.getReducedLattice().getTable();
403 }
404 return table;
405 }
406
407 /**
408 * Set the minimal generators of this component.
409 *
410 * @param minimalGenerators used to define field of this component
411 *
412 * @return this for chaining
413 */
414 protected BijectiveComponents setMinimalGenerators(TreeSet<ComparableSet> minimalGenerators) {
415 this.minimalGenerators = minimalGenerators;
416 return this;
417 }
418
419 /**
420 * Set the canonical direct basis of this component.
421 *
422 * @param canonicalDirectBasis used to define field of this component
423 *
424 * @return return this for chaining
425 */
426 protected BijectiveComponents setCanonicalDirectBasis(ImplicationalSystem canonicalDirectBasis) {
427 this.canonicalDirectBasis = canonicalDirectBasis;
428 return this;
429 }
430
431 /**
432 * Set the canonical basis of this component.
433 *
434 * @param canonicalBasis used to define field of this component
435 *
436 * @return this for chaining
437 */
438 protected BijectiveComponents setCanonicalBasis(ImplicationalSystem canonicalBasis) {
439 this.canonicalBasis = canonicalBasis;
440 return this;
441 }
442
443 /**
444 * Set the Table of this component.
445 *
446 * @param table used to define field of this component
447 *
448 * @return this for chaining
449 */
450 protected BijectiveComponents setTable(Context table) {
451 this.table = table;
452 return this;
453 }
454
455 /**
456 * Returns the informativ generic basis public IS getApproximativBasis () {
457 * IS IGB = new IS(this.canonicalDirectBasis); IS tmp = new
458 * IS(this.canonicalDirectBasis); for (Rule r : tmp.getRules()) { TreeSet
459 * premise = new TreeSet(r.getPremise()); Concept c = new
460 * Concept(this.closure(premise),false); for (TreeSet conclusion :
461 * this.immediateSuccessors(c)) { TreeSet concl = new TreeSet(conclusion);
462 * conclusion.removeAll(premise); IGB.addRule(new Rule(premise,concl)); } }
463 * return IGB; }
464 *
465 */
466 } // end of BijectiveComponents