001: package org.mandarax.kernel;
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.Hashtable;
022: import java.util.Iterator;
023: import java.util.Map;
024:
025: /**
026: * Represents the result of a query. Comprises information about the derivation (proof)
027: * and the replacements. There are some changes in version 3.0: replacements are now organised
028: * in a hash table (for better performance) and there are new constructors building results
029: * from result sets (using the current cursor position) in order to support the implementation of result filters.
030: * @author <A href="http://www-ist.massey.ac.nz/JBDietrich" target="_top">Jens Dietrich</A>
031: * @version 3.4 <7 March 05>
032: * @since 1.0
033: */
034: public class Result extends LObject {
035:
036: private Derivation proof = null;
037: private Map replacementsByKey = new Hashtable();
038: private Replacement[] replacements = null;
039:
040: /**
041: * Constructor.
042: * @param d the derivation proving this result
043: * @param r the variable replacements
044: */
045: public Result(Derivation d, Replacement[] r) {
046: super ();
047: setProof(d);
048: setReplacements(r);
049: }
050:
051: /**
052: * Constructor.
053: * @param r the variable replacements
054: */
055: public Result(Replacement[] r) {
056: super ();
057: setReplacements(r);
058: }
059:
060: /**
061: * Constructor.
062: * @param r a variable replacement
063: */
064: public Result(Replacement r) {
065: super ();
066: setReplacements(new Replacement[] { r });
067: }
068:
069: /**
070: * Constructor.
071: * @param term1 a term
072: * @param term2 a term
073: */
074: public Result(Term term1, Term term2) {
075: this (new Replacement(term1, term2));
076: }
077:
078: /**
079: * Constructor.
080: * @param rs a result set
081: */
082: public Result(ResultSet rs) throws InferenceException {
083: super ();
084: setProof(rs.getProof());
085: replacementsByKey.putAll(rs.getResults());
086: }
087:
088: /**
089: * Get the derivation.
090: * @return the proof (derivation)
091: */
092: public Derivation getProof() {
093: return proof;
094: }
095:
096: /**
097: * Get an array of replacements of the input (query) variables.
098: * @return an array of replacements
099: * @deprecated as from version 3.0
100: */
101: public Replacement[] getReplacements() {
102: // build if needed
103: if (replacements == null && replacementsByKey != null) {
104: replacements = new Replacement[replacementsByKey.size()];
105: int index = 0;
106: Iterator iter = replacementsByKey.values().iterator();
107: while (iter.hasNext()) {
108: Map.Entry next = (Map.Entry) iter.next();
109: replacements[index] = new Replacement((Term) next
110: .getKey(), (Term) next.getValue());
111: index = index + 1;
112: }
113: }
114: return replacements;
115: }
116:
117: /**
118: * Get the object that replaces the variable with the
119: * given name and type.
120: * If there is no such object, return null.
121: * @return the object that replaced the variable
122: * @param type the type of the variable
123: * @param name the name of the variable
124: */
125: public Object getResult(Class type, String name) {
126: VariableTerm term = LogicFactory.getDefaultFactory()
127: .createVariableTerm(name, type);
128: return getResult(term);
129: }
130:
131: /**
132: * Get the object that replaces the variable with the name.
133: * If there is no such object, return null.<br>
134: * <br><b>Warning:</b> This method is convinient and works well
135: * under most circumstances, but could lead to mislead�ng results
136: * if there are many variables of different types sharing the same
137: * name in a query. In this case, better use <code>getResult(Class,String)</code>.
138: * @return the object that replaced the variable
139: * @param name the name of the variable
140: */
141: public Object getResult(String name) {
142: for (Iterator iter = replacementsByKey.values().iterator(); iter
143: .hasNext();) {
144: Map.Entry next = (Map.Entry) iter.next();
145: Object nextKey = next.getKey();
146: if (nextKey instanceof VariableTerm
147: && name.equals(((VariableTerm) nextKey).getName())) {
148: return getResult((VariableTerm) nextKey);
149: }
150: }
151: return null;
152: }
153:
154: /**
155: * Get the object that replaces the variable.
156: * If there is no such object, return null.
157: * @return the object that replaced the variable
158: * @param term the variable term that is (perhaps) replaced
159: */
160: public Object getResult(VariableTerm term) {
161: Term replacement = (Term) replacementsByKey.get(term);
162: if (replacement instanceof ConstantTerm) {
163: return ((ConstantTerm) replacement).getObject();
164: }
165: // by a.kozlenkov@city.ac.uk from 1.9.1: useful when result is complex term
166: // still containing parameters
167: else
168: return replacement;
169: }
170:
171: /**
172: * Convert the object to a string.
173: * @return the string representation of this object
174: */
175: public String toString() {
176: StringBuffer buf = new StringBuffer();
177: boolean first = true;
178: buf.append("a result (");
179: for (Iterator iter = replacementsByKey.values().iterator(); iter
180: .hasNext();) {
181: Map.Entry next = (Map.Entry) iter.next();
182: if (first) {
183: first = false;
184: } else {
185: buf.append(',');
186: }
187: buf.append(next.getKey());
188: buf.append("->");
189: buf.append(next.getValue());
190: }
191: buf.append(")");
192: return new String(buf);
193: }
194:
195: /**
196: * Set the derivation.
197: * @param proof
198: */
199: protected void setProof(Derivation proof) {
200: this .proof = proof;
201: }
202:
203: /**
204: * Set the replacements.
205: * @param replacements
206: */
207: protected void setReplacements(Replacement[] replacements) {
208: this .replacements = replacements;
209: // organize replacements by key
210: replacementsByKey.clear();
211: for (int i = 0; i < replacements.length; i++)
212: replacementsByKey.put(replacements[i].original,
213: replacements[i].replacement);
214: }
215:
216: /**
217: * Get the results as map containing term -> term associations.
218: * @return a map
219: */
220: public Map getResults() throws InferenceException {
221: return replacementsByKey;
222: }
223: }
|