1 package org.thegalactic.rule;
2
3 /*
4 * Rule.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 java.util.Collection;
15 import java.util.SortedSet;
16
17 import org.thegalactic.util.ComparableSet;
18
19 /**
20 * This class gives a representation for an implicational rule.
21 *
22 * A rule is composed of a premise and a conclusion that are comparable sets,
23 * i.e. sets of elements that can be sorted by the lectic order defined by class
24 * `ComparableSet`.
25 *
26 * This class implements class `Comparable` aiming at sorting rules by providing
27 * the {@link #compareTo} method.
28 *
29 * Comparison between this component and those in parameter is realised by
30 * sorting their premises (lecticaly order), or their conclusion in case of
31 * equality of the premises.
32 *
33 * The coherence of the lectically sort between rules isn't ensured in case of
34 * modification of the rule. Therefore, it is strongly advised to replace each
35 * modified rule by a new one.
36 *
37 * ![Rule](Rule.png)
38 *
39 * @uml
40 *
41 * Rule.png
42 *
43 * !include resources/org/thegalactic/lattice/Rule.iuml
44 *
45 * hide members
46 * show Rule members
47 * class Rule #LightCyan
48 * title Rule UML graph
49 */
50 public class Rule implements Comparable<Rule> {
51
52 /*
53 * ------------- FIELDS ------------------
54 */
55 /**
56 * The premise of the rule.
57 */
58 private final ComparableSet premise;
59
60 /**
61 * The conclusion of the rule.
62 */
63 private final ComparableSet conclusion;
64
65 /* ------------- CONSTRUCTORS ------------------ */
66 /**
67 * Constructs a new empty Rule with a empty premise and an empty conclusion.
68 */
69 public Rule() {
70 this.premise = new ComparableSet();
71 this.conclusion = new ComparableSet();
72 }
73
74 /**
75 * Constructs a new Rule with the premise and the conclusion given in
76 * parameters.
77 *
78 * @param premise a set of indexed elements
79 * @param conclusion a set of indexed elements
80 */
81 public Rule(final SortedSet<Comparable> premise, final SortedSet<Comparable> conclusion) {
82 this.premise = new ComparableSet(premise);
83 this.conclusion = new ComparableSet(conclusion);
84 }
85
86 /*
87 * ------------- ACCESSORS METHODS ------------------
88 */
89 /**
90 * Returns a copy of the premise of the Rule.
91 *
92 * @return premises of this component
93 */
94 public final ComparableSet getPremise() {
95 return this.premise;
96 }
97
98 /**
99 * Returns a copy of the conclusion of the Rule.
100 *
101 * @return conclusions of this component
102 */
103 public final ComparableSet getConclusion() {
104 return this.conclusion;
105 }
106
107 /*
108 * ------------- MODIFICATION METHODS ------------------
109 */
110 /**
111 * Adds the specified comparable to the premise of this component.
112 *
113 * @param a Comparable to add to this component's premises.
114 *
115 * @return true if addition is successfull.
116 */
117 public final boolean addToPremise(final Comparable a) {
118 return this.premise.add(a);
119 }
120
121 /**
122 * Removes the specified comparable from the premise of this component.
123 *
124 * @param a Comparable to remove to this component's premises.
125 *
126 * @return true if addition is successfull.
127 */
128 public final boolean removeFromPremise(final Comparable a) {
129 return this.premise.remove(a);
130 }
131
132 /**
133 * Adds the specified element to the conclusion of this component.
134 *
135 * @param a Comparable to add to this component's conclusions.
136 *
137 * @return true if addition is successfull.
138 */
139 public final boolean addToConclusion(final Comparable a) {
140 return this.conclusion.add(a);
141 }
142
143 /**
144 * Removes the specified comparable from the conclusion of this component.
145 *
146 * @param a Comparable to remove to this component's conclusions.
147 *
148 * @return true if addition is successfull.
149 */
150 public final boolean removeFromConclusion(final Object a) {
151 return this.conclusion.remove(a);
152 }
153
154 /**
155 * Adds the specified collection of indexed elements to the premise of this
156 * component.
157 *
158 * @param a Collection of comparables to add to this component's premises.
159 *
160 * @return true if addition is successfull.
161 */
162 public final boolean addAllToPremise(final Collection<Comparable> a) {
163 return this.premise.addAll(a);
164 }
165
166 /**
167 * Removes the specified collection of indexed elements from the premise of
168 * this component.
169 *
170 * @param a Collection of comparables to remove to this component's
171 * premises.
172 *
173 * @return true if addition is successfull.
174 */
175 public final boolean removeAllFromPremise(final Collection<Comparable> a) {
176 return this.premise.removeAll(a);
177 }
178
179 /**
180 * Adds the specified collection of indexed elements to the conclusion of
181 * this component.
182 *
183 * @param a Collection of comparables to add to this component's
184 * conclusions.
185 *
186 * @return true if addition is successfull.
187 */
188 public final boolean addAllToConclusion(final Collection<Comparable> a) {
189 return this.conclusion.addAll(a);
190 }
191
192 /**
193 * Removes the specified collection of indexed elements from the conclusion
194 * of this component.
195 *
196 * @param a Collection of comparables to remove to this component's
197 * conclusions.
198 *
199 * @return true if addition is successfull.
200 */
201 public final boolean removeAllFromConclusion(final Collection<Comparable> a) {
202 return this.conclusion.removeAll(a);
203 }
204
205 /*
206 * ------------- OVERRIDDEN METHODS ------------------
207 */
208 /**
209 * Returns a String representation of this component.
210 *
211 * The following format is used:
212 *
213 * ~~~
214 * [elements of the premise separated by a space] -> [elements of the conclusion separated by a space]
215 * ~~~
216 *
217 * a StringTokenizer is used to delete spaces in the string description of
218 * each element of premise and conclusion
219 *
220 * @return a string made of premises followed by -> and the conclusions.
221 */
222 @Override
223 public String toString() {
224 final StringBuilder builder = new StringBuilder();
225 for (final Object e : this.getPremise()) {
226 builder.append(e).append(' ');
227 }
228 builder.append("->");
229 for (final Object e : this.getConclusion()) {
230 builder.append(' ').append(e);
231 }
232 return builder.toString();
233 }
234
235 /**
236 * Returns the hash code of this component.
237 *
238 * @return hash code of this component
239 */
240 @Override
241 public int hashCode() {
242 return 1013 * this.premise.hashCode() ^ 1009 * this.conclusion.hashCode();
243 }
244
245 /**
246 * Compares this component with the specified one.
247 *
248 * @param object object to compare to this component.
249 *
250 * @return true or false as this componant is equals to the specified
251 * object.
252 */
253 @Override
254 public boolean equals(final Object object) {
255 return this == object || object != null && this.getClass() == object.getClass()
256 && this.getPremise().equals(((Rule) object).getPremise())
257 && this.getConclusion().equals(((Rule) object).getConclusion());
258 }
259
260 /**
261 * Compares this component with the specified one by comparing their
262 * premises, or their conclusion in case of equality of the premises.
263 *
264 * @param rule object to compare to this component.
265 *
266 * @return a negative integer, zero, or a positive integer as this component
267 * is less than, equal to, or greater than the specified object.
268 */
269 public final int compareTo(final Rule rule) {
270 final ComparableSet thisPremise = (ComparableSet) this.getPremise();
271 final ComparableSet thisConclusion = (ComparableSet) this.getConclusion();
272 int cmp = thisPremise.compareTo(rule.getPremise());
273 if (cmp == 0) {
274 cmp = thisConclusion.compareTo(rule.getConclusion());
275 }
276 return cmp;
277 }
278 }