001: package org.mandarax.xkb.ruleml;
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.Iterator;
022: import java.util.List;
023: import java.util.Vector;
024:
025: import org.jdom.Element;
026: import org.mandarax.kernel.ClauseSet;
027: import org.mandarax.kernel.Fact;
028: import org.mandarax.kernel.KnowledgeBase;
029: import org.mandarax.kernel.Query;
030: import org.mandarax.kernel.Rule;
031: import org.mandarax.reference.AdvancedKnowledgeBase;
032: import org.mandarax.xkb.XKBException;
033:
034: /**
035: * Driver implementation for the RULE ML version 0.8.1.
036: * New (comp to 0.8) is support for queries. Labels (<_rbaselab> and <_rlab>)
037: * are accepted but more or less ignored (mandarax does not support them).
038: * Only for queries, the _rlab tag is used to store the common query name.
039: * @author <A href="http://www-ist.massey.ac.nz/JBDietrich" target="_top">Jens Dietrich</A>
040: * @version 3.4 <7 March 05>
041: * @since 1.9
042: */
043: public class RuleML0_8_1Driver extends AbstractRuleMLDriver {
044:
045: // constants for tags and attributes
046: public static final String QUERY = "query";
047: public static final String _RBASELAB = "_rbaselab";
048: public static final String _RLAB = "_rlab";
049:
050: /**
051: * Constructor.
052: */
053: public RuleML0_8_1Driver() {
054: super ();
055: }
056:
057: /**
058: * Export a knowledge base, e.g. convert it into an xml element.
059: * @return an element (of the jdom tree)
060: * @param kb a knowledge base
061: */
062: protected Element export(KnowledgeBase kb) {
063: Element e = new Element(RULEBASE);
064: List clauseSets = kb.getClauseSets();
065: ClauseSet nextClauseSet = null;
066: // export clause sets
067: for (Iterator it = clauseSets.iterator(); it.hasNext();) {
068: nextClauseSet = (ClauseSet) it.next();
069: if (nextClauseSet instanceof Fact)
070: e.addContent(export((Fact) nextClauseSet));
071: else if (nextClauseSet instanceof Rule)
072: e.addContent(export((Rule) nextClauseSet));
073: else
074: LOG_XKB
075: .warn("Only facts and rules are suported by driver "
076: + getName()
077: + ", cannot export "
078: + nextClauseSet);
079: }
080: // export queries
081: for (Iterator iter = kb.queryNames(); iter.hasNext();) {
082: String nextQueryName = (String) iter.next();
083: Query nextQuery = kb.getQuery(nextQueryName);
084: e.addContent(export(nextQuery));
085: }
086: return e;
087: }
088:
089: /**
090: * Get a short text describing the driver.
091: * @return a text
092: */
093: public String getDescription() {
094: return "Driver for rulebases as specified by the RULE ML version 0.8.1 specification (incl. query support)";
095: }
096:
097: /**
098: * Get the location (URL) of the associated DTD.
099: * @return a text
100: */
101: public String getDTD() {
102: return "http://www.dfki.uni-kl.de/ruleml/dtd/0.81/ruleml-datalog.dtd";
103: }
104:
105: /**
106: * Get the name of the driver.
107: * @return a text
108: */
109: public String getName() {
110: return "RuleML 0.8.1";
111: }
112:
113: /**
114: * Import a knowledge base.
115: * @return a knowledge base
116: * @param e an xml element
117: * @throws an XKBException is thrown if import fails
118: */
119: protected KnowledgeBase importKnowledgeBase(Element e)
120: throws XKBException {
121:
122: // since we have no chance to store the class name in this xml format,
123: // we choose the default class
124: KnowledgeBase kb = new AdvancedKnowledgeBase();
125:
126: // build the clause sets
127: List all = e.getChildren();
128: Element next = null;
129: ClauseSet nextCS = null;
130:
131: for (Iterator it = all.iterator(); it.hasNext();) {
132: next = (Element) it.next();
133: if (compare(next.getName(), IMP))
134: kb.add(importRule(next));
135: else if (compare(next.getName(), FACT))
136: kb.add(importFact(next));
137: else if (compare(next.getName(), QUERY))
138: kb.addQuery(importQuery(next));
139: else if (compare(next.getName(), _RBASELAB))
140: LOG_XKB.warn("The tag <" + _RBASELAB
141: + "> is not supported by the driver " + this
142: + ", ignore element");
143: else
144: LOG_XKB.warn("Cannot build clause (set) from element <"
145: + next.getName() + ">..");
146: }
147: return kb;
148: }
149:
150: /**
151: * Import a query.
152: * @return a query
153: * @param e an xml element
154: * @throws an XKBException is thrown if import fails
155: */
156: private Query importQuery(Element e) throws XKBException {
157: // get body
158: Element eBody = e.getChild(_BODY);
159: List body = null;
160: if (eBody == null) {
161: LOG_XKB.debug("No body tag found, assume body is empty");
162: body = new Vector();
163: } else {
164: body = importBody(eBody);
165: }
166: // get label
167: String name = null;
168: Element eName = e.getChild(_RLAB);
169: if (eName != null) {
170: Element eInd = eName.getChild(IND);
171: if (eInd != null)
172: name = (String) importJavaObject(eInd);
173: }
174: if (name == null) {
175: LOG_XKB
176: .debug("No query name found (_rlab tag missing) - use default query name");
177: name = "a query";
178: }
179:
180: // build and return query
181: Fact[] facts = new Fact[body.size()];
182: for (int i = 0; i < body.size(); i++)
183: facts[i] = (Fact) body.get(i);
184: return lfactory.createQuery(facts, name);
185: }
186:
187: /**
188: * Export a query.
189: * @return an element
190: * @param q a query
191: */
192: private Element export(Query q) {
193: Element e1 = new Element(QUERY);
194: Element e2 = new Element(_BODY);
195: Element e3 = new Element(AND);
196: // query facts
197: Fact[] facts = q.getFacts();
198: for (int i = 0; i < facts.length; i++) {
199: e3.addContent(exportFact2Atom(facts[i]));
200: }
201: e2.addContent(e3);
202: e1.addContent(e2);
203: // query name
204: String name = q.getName();
205: if (name != null && name.trim().length() > 0) {
206: Element eName = new Element(_RLAB);
207: Element eName2 = exportJavaObject(name);
208: eName.addContent(eName2);
209: e1.addContent(eName);
210: }
211: return e1;
212: }
213:
214: /**
215: * Indicates whether the driver (and the underlying xml format (=dtd))
216: * supports auto facts.
217: * @return a boolean
218: */
219: public boolean supportsAutoFacts() {
220: return false;
221: }
222:
223: /**
224: * Indicates whether the driver (and the underlying xml format (=dtd))
225: * supports clause sets.
226: * @return a boolean
227: */
228: public boolean supportsClauseSets() {
229: return false;
230: }
231:
232: /**
233: * Indicates whether the driver (and the underlying xml format (=dtd))
234: * supports facts. (some formats might see facts as rules without body)
235: * @return a boolean
236: */
237: public boolean supportsFacts() {
238: return true;
239: }
240:
241: /**
242: * Indicates whether the driver (and the underlying xml format (=dtd))
243: * supports functions.
244: * @return a boolean
245: */
246: public boolean supportsFunctions() {
247: return false;
248: }
249:
250: /**
251: * Indicates whether the driver (and the underlying xml format (=dtd))
252: * supports the java semantics (e.g. JFunctions, JPredicate).
253: * @return a boolean
254: */
255: public boolean supportsJavaSemantics() {
256: return false;
257: }
258:
259: /**
260: * Indicates whether the driver (and the underlying xml format (=dtd))
261: * supports multiple premises.
262: * @return a boolean
263:
264: */
265: public boolean supportsMultiplePremises() {
266: return true;
267: }
268:
269: /**
270: * Indicates whether the driver (and the underlying xml format (=dtd))
271: * supports multiple premises connected by OR.
272: * @return a boolean
273: */
274: public boolean supportsOrPremises() {
275: return false;
276: }
277:
278: /**
279: * Indicates whether the driver (and the underlying xml format (=dtd))
280: * supports types.
281: * @return a boolean
282: */
283: public boolean supportsTypes() {
284: return false;
285: }
286:
287: /**
288: * Indicates whether the driver (and the underlying xml format (=dtd))
289: * supports queries.
290: * @return a boolean
291: */
292: public boolean supportsQueries() {
293: return true;
294: }
295:
296: /**
297: * Indicates whether the driver (and the underlying xml format (=dtd))
298: * supports negation as failure.
299: * @return a boolean
300: */
301: public boolean supportsNegationAsFailure() {
302: return false;
303: }
304: }
|