001: package org.mandarax.util.comparators;
002:
003: /*
004: * Copyright (C) 1999-2004 <A href="http://www-ist.massey.ac.nz/JBDietrich" target="_top">Jens Dietrich</a>
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: */
020:
021: import java.util.Arrays;
022: import java.util.Comparator;
023:
024: import org.mandarax.kernel.ClauseSet;
025: import org.mandarax.kernel.Fact;
026: import org.mandarax.kernel.Rule;
027: import org.mandarax.sql.SQLClauseSet;
028:
029: /**
030: * Default clause set comparator class that can be used in order to
031: * arrange knowledge in an extended knowledge base automatically.
032: * The following policy is employed:
033: * <ol>
034: * <li>SQL clause sets have the highest priority.
035: * <li>Facts have the second highest priority. Among facts, the order is managed by
036: * a chain of fact comparators.
037: * <li>Rules have lower priority than facts. Among rules, the order is managed by
038: * a chain of rule comparators.
039: * <li>All other types of clause sets have a lower priority (this rules
040: * can be critical.
041: * </ol>
042: * @author <A href="http://www-ist.massey.ac.nz/JBDietrich" target="_top">Jens Dietrich</A>
043: * @version 3.4 <7 March 05>
044: * @since 2.2
045: */
046: public class DefaultClauseSetComparator extends
047: AbstractClauseSetComparator {
048: public final String RULES = "rules";
049: public final String FACTS = "facts";
050: public final String SQL_CLAUSE_SETS = "sql clause sets";
051: public final String OTHERS = "others";
052:
053: // properties
054: private String[] topLevelOrder = { FACTS, SQL_CLAUSE_SETS, RULES,
055: OTHERS };
056: private Comparator[] comparators4Facts = { new PreferFactsWithLessVariables() };
057: private Comparator[] comparators4Rules = {
058: new PreferRulesWithMorePrerequisites(),
059: new PreferRulesWithLessNegatedPrerequisites(),
060: new PreferRulesWithLessVariablesInPrerequisites() };
061: private Comparator[] comparators4SQLClauseSets = {};
062: private Comparator[] comparators4Others = {};
063:
064: /**
065: * Constructor.
066: */
067: public DefaultClauseSetComparator() {
068: super ();
069: }
070:
071: /**
072: * Compare two objects.
073: * @return an integer
074: * @param obj1 the first object
075: * @param obj2 the second object
076: */
077: public int compare(Object obj1, Object obj2) {
078: if (obj1 instanceof ClauseSet && obj2 instanceof ClauseSet)
079: return compareClauseSets((ClauseSet) obj1, (ClauseSet) obj2);
080: else
081: throw new IllegalArgumentException(
082: "The clause set comparator can only compare clause sets");
083: }
084:
085: /**
086: * Compare two clause sets.
087: * @return an integer
088: * @param cs1 the first clause set
089: * @param cs2 the second clause set
090: */
091: private int compareClauseSets(ClauseSet cs1, ClauseSet cs2) {
092: int diff = getMajorSortKeyValue(cs2)
093: - getMajorSortKeyValue(cs1);
094: if (diff == 0) {
095: // use special comparators
096: if (cs1 instanceof Rule && cs2 instanceof Rule) {
097: return compareInChain(cs1, cs2, comparators4Rules);
098: } else if (cs1 instanceof Fact && cs2 instanceof Fact) {
099: return compareInChain(cs1, cs2, comparators4Facts);
100: } else if (cs1 instanceof SQLClauseSet
101: && cs2 instanceof SQLClauseSet) {
102: return compareInChain(cs1, cs2,
103: comparators4SQLClauseSets);
104: } else {
105: return compareInChain(cs1, cs2, comparators4Others);
106: }
107: }
108: return diff;
109: }
110:
111: /**
112: * Use a chain of comparators to compare two objects
113: * @param obj1 object 1
114: * @param obj2 object 2
115: * @param comparators the comparator chain
116: * @return the result of comparing the objects
117: */
118: private int compareInChain(Object obj1, Object obj2,
119: Comparator[] comparators) {
120: int diff = 0;
121: for (int i = 0; i < comparators.length; i++) {
122: diff = comparators[i].compare(obj1, obj2);
123: if (diff != 0)
124: return diff;
125: }
126: return diff;
127: }
128:
129: /**
130: * Get the value of the major sort key.
131: * @return an integer
132: * @param cs a clause set
133: */
134: private int getMajorSortKeyValue(ClauseSet cs) {
135: String type = OTHERS;
136: if (cs instanceof Rule)
137: type = RULES;
138: else if (cs instanceof Fact)
139: type = FACTS;
140: else if (cs instanceof SQLClauseSet)
141: type = SQL_CLAUSE_SETS;
142:
143: for (int i = 0; i < topLevelOrder.length; i++) {
144: if (topLevelOrder[i].equals(type))
145: return topLevelOrder.length - i;
146: }
147: return 0;
148: }
149:
150: /**
151: * Get a descriptive name.
152: * @return a string
153: */
154: public String getName() {
155: return "default comparator";
156: }
157:
158: /**
159: * Returns the comparators4Facts.
160: * @return Comparator[]
161: */
162: public Comparator[] getComparators4Facts() {
163: return comparators4Facts;
164: }
165:
166: /**
167: * Returns the comparators4Others.
168: * @return Comparator[]
169: */
170: public Comparator[] getComparators4Others() {
171: return comparators4Others;
172: }
173:
174: /**
175: * Returns the comparators4Rules.
176: * @return Comparator[]
177: */
178: public Comparator[] getComparators4Rules() {
179: return comparators4Rules;
180: }
181:
182: /**
183: * Returns the comparators4SQLClauseSets.
184: * @return Comparator[]
185: */
186: public Comparator[] getComparators4SQLClauseSets() {
187: return comparators4SQLClauseSets;
188: }
189:
190: /**
191: * Returns the topLevelOrder.
192: * @return String[]
193: */
194: public String[] getTopLevelOrder() {
195: return topLevelOrder;
196: }
197:
198: /**
199: * Sets the comparators4Facts.
200: * @param comparators4Facts The comparators4Facts to set
201: */
202: public void setComparators4Facts(Comparator[] comparators4Facts) {
203: this .comparators4Facts = comparators4Facts;
204: }
205:
206: /**
207: * Sets the comparators4Others.
208: * @param comparators4Others The comparators4Others to set
209: */
210: public void setComparators4Others(Comparator[] comparators4Others) {
211: this .comparators4Others = comparators4Others;
212: }
213:
214: /**
215: * Sets the comparators4Rules.
216: * @param comparators4Rules The comparators4Rules to set
217: */
218: public void setComparators4Rules(Comparator[] comparators4Rules) {
219: this .comparators4Rules = comparators4Rules;
220: }
221:
222: /**
223: * Sets the comparators4SQLClauseSets.
224: * @param comparators4SQLClauseSets The comparators4SQLClauseSets to set
225: */
226: public void setComparators4SQLClauseSets(
227: Comparator[] comparators4SQLClauseSets) {
228: this .comparators4SQLClauseSets = comparators4SQLClauseSets;
229: }
230:
231: /**
232: * Sets the topLevelOrder.
233: * @param topLevelOrder The topLevelOrder to set
234: */
235: public void setTopLevelOrder(String[] topLevelOrder) {
236: this .topLevelOrder = topLevelOrder;
237: }
238:
239: /**
240: * Compares objects.
241: * @param obj an object
242: * @return a boolean
243: */
244: public boolean equals(Object obj) {
245: if (obj instanceof DefaultClauseSetComparator) {
246: DefaultClauseSetComparator comp = (DefaultClauseSetComparator) obj;
247: if (!Arrays.equals(topLevelOrder, comp.topLevelOrder))
248: return false;
249: if (!Arrays.equals(comparators4Rules,
250: comp.comparators4Rules))
251: return false;
252: if (!Arrays.equals(comparators4Facts,
253: comp.comparators4Facts))
254: return false;
255: if (!Arrays.equals(comparators4Others,
256: comp.comparators4Others))
257: return false;
258: if (!Arrays.equals(comparators4SQLClauseSets,
259: comp.comparators4SQLClauseSets))
260: return false;
261:
262: return true;
263: }
264: return false;
265: }
266:
267: /**
268: * Get the hash code of this object.
269: * @return an integer
270: */
271: public int hashCode() {
272: return topLevelOrder.hashCode() ^ comparators4Rules.hashCode()
273: ^ comparators4Facts.hashCode();
274: }
275:
276: }
|