View Javadoc
1   package org.thegalactic.lattice;
2   
3   /*
4    * ArrowRelation.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
13   * it under the terms of the CeCILL-B license.
14   */
15  import java.io.IOException;
16  import java.util.TreeSet;
17  
18  import org.thegalactic.context.Context;
19  import org.thegalactic.dgraph.ConcreteDGraph;
20  import org.thegalactic.dgraph.Edge;
21  import org.thegalactic.dgraph.Node;
22  import org.thegalactic.io.Filer;
23  import org.thegalactic.lattice.io.ArrowRelationIOFactory;
24  
25  /**
26   * The ArrowRelation class encodes arrow relation between meet &
27   * join-irreductibles of a lattice.
28   *
29   * Let m and b be respectively meet and join irreductibles of a lattice.
30   * Recall that m has a unique successor say m+ and j has a unique predecessor
31   * say j-, then :
32   *
33   * - j "Up Arrow" m (stored as "Up") iff j is not less or equal than m and
34   * j is less than m+
35   * - j "Down Arrow" m (stored as "Down") iff j is not less or equal than m and
36   * j- is less than m
37   * - j "Up Down Arrow" m (stored as "UpDown") iff j "Up" m and j "Down" m
38   * - j "Cross" m (stored as "Cross") iff j is less or equal than m
39   * - j "Circ" m (stored as "Circ") iff neither j "Up" m nor j "Down" m nor
40   * j "Cross" m
41   *
42   * ![ArrowRelation](ArrowRelation.png)
43   *
44   * @uml ArrowRelation.png
45   * !include resources/org/thegalactic/dgraph/DGraph.iuml
46   * !include resources/org/thegalactic/dgraph/Edge.iuml
47   * !include resources/org/thegalactic/dgraph/Node.iuml
48   * !include resources/org/thegalactic/lattice/ArrowRelation.iuml
49   *
50   * hide members
51   * show ArrowRelation members
52   * class ArrowRelation #LightCyan
53   * title ArrowRelation UML graph
54   */
55  public class ArrowRelation extends ConcreteDGraph {
56  
57      /**
58       * Field used to encode up arrow relation.
59       */
60      private static Object up = "Up";
61  
62      /**
63       * Field used to encode down arrow relation.
64       */
65      private static Object down = "Down";
66  
67      /**
68       * Field used to encode up-down arrow relation.
69       */
70      private static Object updown = "UpDown";
71  
72      /**
73       * Field used to encode cross arrow relation.
74       */
75      private static Object cross = "Cross";
76  
77      /**
78       * Field used to encode circ arrow relation.
79       */
80      private static Object circ = "Circ";
81  
82      /**
83       * Unique constructor of this component from a lattice.
84       *
85       * Nodes are join or meet irreductibles of the lattice. Edges content
86       * encodes arrows as String "Up", "Down", "UpDown", "Cross", "Circ".
87       *
88       * @param lattice Lattice from which this component is deduced.
89       */
90      public ArrowRelation(Lattice lattice) {
91  
92          /*
93           * Nodes are join or meet irreductibles of the lattice.
94           */
95          TreeSet<Node> joins = new TreeSet<Node>(lattice.joinIrreducibles());
96          for (Node node : joins) {
97              this.addNode(node);
98          }
99          TreeSet<Node> meets = new TreeSet<Node>(lattice.meetIrreducibles());
100         for (Node node : meets) {
101             this.addNode(node);
102         }
103         Lattice transitiveClosure = new Lattice(lattice);
104         transitiveClosure.transitiveClosure();
105         Lattice transitiveReduction = new Lattice(lattice);
106         transitiveReduction.transitiveReduction();
107         Node jminus = new Node();
108         Node mplus = new Node();
109         Object arrow = new Object();
110 
111         /*
112          * Content of edges are arrows
113          */
114         for (Node j : joins) {
115             for (Node m : meets) {
116                 mplus = (Node) transitiveReduction.getSuccessorNodes(m).first();
117                 jminus = (Node) transitiveReduction.getPredecessorNodes(j).first();
118                 if (transitiveClosure.getSuccessorNodes(j).contains(m) || j.equals(m)) {
119                     arrow = ArrowRelation.cross;
120                 } else if (transitiveClosure.getSuccessorNodes(jminus).contains(m) || jminus.equals(m)) {
121                     arrow = ArrowRelation.down;
122                     if (transitiveClosure.getPredecessorNodes(mplus).contains(j) || mplus.equals(j)) {
123                         arrow = ArrowRelation.updown;
124                     }
125                 } else if (transitiveClosure.getPredecessorNodes(mplus).contains(j)) {
126                     arrow = ArrowRelation.up;
127                 } else {
128                     arrow = ArrowRelation.circ;
129                 }
130                 this.addEdge(j, m, arrow);
131             }
132         }
133     }
134 
135     /**
136      * Save the description of this component in a file whose name is specified.
137      *
138      * @param filename the name of the file
139      *
140      * @throws IOException When an IOException occurs
141      */
142     @Override
143     public void save(final String filename) throws IOException {
144         Filer.getInstance().save(this, ArrowRelationIOFactory.getInstance(), filename);
145     }
146 
147     /**
148      * Returns the table of the lattice, composed of the join and meet
149      * irreducibles nodes.
150      *
151      * Each attribute of the table is a copy of a join irreducibles node. Each
152      * observation of the table is a copy of a meet irreducibles node. An
153      * attribute is extent of an observation when its join irreducible node is
154      * in double arrow relation with the meet irreducible node in the lattice.
155      *
156      * @return the table of the lattice
157      *
158      * @todo Avoid using for (Object edge : this.getEdges()). Use for (Edge edge : this.getEdges())
159      */
160     public Context getDoubleArrowTable() {
161         Context context = new Context();
162         // observations are join irreductibles
163         // attributes are meet irreductibles
164         for (Object edge : this.getEdges()) {
165             context.addToObservations(((Edge) edge).getSource());
166             context.addToAttributes(((Edge) edge).getTarget());
167         }
168         // generation of extent-intent
169         for (Object edge : this.getEdges()) {
170             if (((Edge) edge).getContent() == ArrowRelation.updown) {
171                 context.addExtentIntent(((Edge) edge).getSource(), ((Edge) edge).getTarget());
172             }
173         }
174         return context;
175     }
176 
177     /**
178      * Returns the table of the lattice, composed of the join and meet
179      * irreducibles nodes.
180      *
181      * Each attribute of the table is a copy of a join irreducibles node. Each
182      * observation of the table is a copy of a meet irreducibles node. An
183      * attribute is extent of an observation when its join irreducible node is
184      * in down arrow relation with the meet irreducible node in the lattice.
185      *
186      * @return the table of the lattice
187      */
188     public Context getDoubleDownArrowTable() {
189         Context context = new Context();
190         // observations are join irreductibles
191         // attributes are meet irreductibles
192         for (Object edge : this.getEdges()) {
193             context.addToObservations(((Edge) edge).getSource());
194             context.addToAttributes(((Edge) edge).getTarget());
195         }
196         // generation of extent-intent
197         for (Object edge : this.getEdges()) {
198             if (((Edge) edge).getContent() == ArrowRelation.down || ((Edge) edge).getContent() == ArrowRelation.updown) {
199                 context.addExtentIntent(((Edge) edge).getSource(), ((Edge) edge).getTarget());
200             }
201         }
202         return context;
203     }
204 
205     /**
206      * Returns the table of the lattice, composed of the join and meet
207      * irreducibles nodes.
208      *
209      * Each attribute of the table is a copy of a join irreducibles node. Each
210      * observation of the table is a copy of a meet irreducibles node. An
211      * attribute is extent of an observation when its join irreducible node is
212      * in up arrow relation with the meet irreducible node in the lattice.
213      *
214      * @return the table of the lattice
215      */
216     public Context getDoubleUpArrowTable() {
217         Context context = new Context();
218         // observations are join irreductibles
219         // attributes are meet irreductibles
220         for (Object edge : this.getEdges()) {
221             context.addToObservations(((Edge) edge).getSource());
222             context.addToAttributes(((Edge) edge).getTarget());
223         }
224         // generation of extent-intent
225         for (Object edge : this.getEdges()) {
226             if (((Edge) edge).getContent() == ArrowRelation.up || ((Edge) edge).getContent() == ArrowRelation.updown) {
227                 context.addExtentIntent(((Edge) edge).getSource(), ((Edge) edge).getTarget());
228             }
229         }
230         return context;
231     }
232 
233     /**
234      * Returns the table of the lattice, composed of the join and meet
235      * irreducibles nodes.
236      *
237      * Each attribute of the table is a copy of a join irreducibles node. Each
238      * observation of the table is a copy of a meet irreducibles node. An
239      * attribute is extent of an observation when its join irreducible node is
240      * in double arrow relation or circ relation with the meet irreducible node
241      * in the lattice.
242      *
243      * @return the table of the lattice
244      */
245     public Context getDoubleCircArrowTable() {
246         Context context = new Context();
247         // observations are join irreductibles
248         // attributes are meet irreductibles
249         for (Object edge : this.getEdges()) {
250             context.addToObservations(((Edge) edge).getSource());
251             context.addToAttributes(((Edge) edge).getTarget());
252         }
253         // generation of extent-intent
254         for (Object edge : this.getEdges()) {
255             if (((Edge) edge).getContent() == ArrowRelation.updown || ((Edge) edge).getContent() == ArrowRelation.circ) {
256                 context.addExtentIntent(((Edge) edge).getSource(), ((Edge) edge).getTarget());
257             }
258         }
259         return context;
260     }
261 
262     /**
263      * Returns true if and only if there is an up arrow between the source and
264      * the target of
265      * edge e.
266      *
267      * @param edge edge to be tested
268      *
269      * @return true if and only if there is an up arrow between the source and
270      *         the target of
271      *         edge e
272      */
273     public boolean isUp(Edge edge) {
274         return edge.getContent() == ArrowRelation.up;
275     }
276 
277     /**
278      * Returns true if and only if there is an down arrow between the source and
279      * the target of
280      * edge e.
281      *
282      * @param edge edge to be tested
283      *
284      * @return true if and only if there is an down arrow between the source and
285      *         the target of
286      *         edge e
287      */
288     public boolean isDown(Edge edge) {
289         return edge.getContent() == ArrowRelation.down;
290     }
291 
292     /**
293      * Returns true if and only if there is an up-down arrow between the source
294      * and the target
295      * of edge e.
296      *
297      * @param edge edge to be tested
298      *
299      * @return true if and only if there is an up-down arrow between the source
300      *         and the target
301      *         of edge e
302      */
303     public boolean isUpDown(Edge edge) {
304         return edge.getContent() == ArrowRelation.updown;
305     }
306 
307     /**
308      * Returns true if and only if there is an cross arrow between the source
309      * and the target
310      * of edge e.
311      *
312      * @param edge edge to be tested
313      *
314      * @return true if and only if there is an cross arrow between the source
315      *         and the target
316      *         of edge e
317      */
318     public boolean isCross(Edge edge) {
319         return edge.getContent() == ArrowRelation.cross;
320     }
321 
322     /**
323      * Returns true if and only if there is an circ arrow between the source and
324      * the target of
325      * edge e.
326      *
327      * @param edge edge to be tested
328      *
329      * @return true if and only if there is an circ arrow between the source and
330      *         the target of
331      *         edge e
332      */
333     public boolean isCirc(Edge edge) {
334         return edge.getContent() == ArrowRelation.circ;
335     }
336 }