View Javadoc
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   * ![BijectiveComponents](BijectiveComponents.png)
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