001: /*****************************************************************************
002: * Source code information
003: * -----------------------
004: * Original author Ian Dickinson, HP Labs Bristol
005: * Author email ian.dickinson@hp.com
006: * Package Jena 2
007: * Web http://sourceforge.net/projects/jena/
008: * Created 10-Dec-2003
009: * Filename $RCSfile: DIGQueryIsEquivalentTranslator.java,v $
010: * Revision $Revision: 1.16 $
011: * Release status $State: Exp $
012: *
013: * Last modified on $Date: 2008/01/02 12:07:09 $
014: * by $Author: andy_seaborne $
015: *
016: * (c) Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
017: * [See end of file]
018: *****************************************************************************/package com.hp.hpl.jena.reasoner.dig;
019:
020: // Imports
021: ///////////////
022: import org.apache.commons.logging.LogFactory;
023: import org.w3c.dom.Document;
024: import org.w3c.dom.Element;
025:
026: import com.hp.hpl.jena.graph.Node;
027: import com.hp.hpl.jena.rdf.model.*;
028: import com.hp.hpl.jena.reasoner.TriplePattern;
029: import com.hp.hpl.jena.util.iterator.*;
030:
031: /**
032: * <p>
033: * Translator to map variants of owl:equivalentClass to the DIG <equivalents> query,
034: * where the query is testing if two concepts are indeed equivalent (rather than listing the
035: * atoms that are, in fact, equivalent to a given concept, which is what
036: * {@link DIGQueryEquivalentsTranslator} does).
037: * </p>
038: *
039: * @author Ian Dickinson, HP Labs (<a href="mailto:Ian.Dickinson@hp.com" >email</a>)
040: * @version CVS $Id: DIGQueryIsEquivalentTranslator.java,v 1.16 2008/01/02 12:07:09 andy_seaborne Exp $
041: */
042: public class DIGQueryIsEquivalentTranslator extends DIGQueryTranslator {
043: // Constants
044: //////////////////////////////////
045:
046: // Static variables
047: //////////////////////////////////
048:
049: // Instance variables
050: //////////////////////////////////
051:
052: /** URI of the predicate we are testing for */
053: protected String m_predicate;
054:
055: protected Node m_qSubject;
056: protected Node m_qObject;
057:
058: // Constructors
059: //////////////////////////////////
060:
061: /**
062: * <p>Construct a translator for the DIG query 'equivalents'.</p>
063: * @param predicate The predicate URI to trigger on
064: */
065: public DIGQueryIsEquivalentTranslator(String predicate) {
066: super (null, null, null);
067: m_predicate = predicate;
068: }
069:
070: // External signature methods
071: //////////////////////////////////
072:
073: /**
074: * <p>Answer a query that will generate a query to see if two concepts are equivalent</p>
075: */
076: public Document translatePattern(TriplePattern pattern,
077: DIGAdapter da) {
078: return translatePattern(pattern, da, null);
079: }
080:
081: public Document translatePattern(TriplePattern pattern,
082: DIGAdapter da, Model premises) {
083: DIGConnection dc = da.getConnection();
084: Document query = dc.createDigVerb(DIGProfile.ASKS, da
085: .getProfile());
086:
087: // re-order the argument so that we can ask equivalent between one atom
088: // and one expression (can't do more because of DIG limitations)
089: m_qSubject = pattern.getSubject();
090: m_qObject = pattern.getObject();
091:
092: if (m_qSubject.isBlank() && m_qObject.isBlank()) {
093: LogFactory
094: .getLog(getClass())
095: .warn(
096: "DIG 1.1 cannot handle isConcept query with two expressions");
097: return null;
098: } else if (m_qObject.isBlank()) {
099: // we want subject to be an expression if there is one
100: Node temp = m_qSubject;
101: m_qSubject = m_qObject;
102: m_qObject = temp;
103: }
104:
105: // we have to introduce a bNode, in the mode of the OWL comprehension axioms, if
106: // the query is of the form :c owl:unionOf [A,B]
107: Node p = pattern.getPredicate();
108: if (!m_qObject.isBlank()
109: && (p.getURI().equals(
110: da.getOntLanguage().UNION_OF().getURI())
111: || p.getURI().equals(
112: da.getOntLanguage().INTERSECTION_OF()
113: .getURI()) || p.getURI()
114: .equals(
115: da.getOntLanguage().COMPLEMENT_OF()
116: .getURI()))
117: || p.getURI().equals(
118: da.getOntLanguage().ONE_OF().getURI())) {
119: if (premises == null) {
120: LogFactory
121: .getLog(getClass())
122: .warn(
123: "Cannot add comprehension axiom bNode for query because premises model is null");
124: } else {
125: // create a bNode that has the same relationship to the class expression operands as the given
126: Resource comp = premises.createResource(da
127: .getOntLanguage().CLASS());
128: premises.add(comp, premises.getProperty(p.getURI()),
129: premises.getRDFNode(m_qSubject));
130: m_qSubject = comp.asNode();
131: }
132: }
133:
134: Element equivalents = da.createQueryElement(query,
135: DIGProfile.EQUIVALENTS);
136: da.addClassDescription(equivalents, m_qSubject, premises);
137:
138: return query;
139: }
140:
141: /**
142: * <p>Answer an iterator of triples that match the original find query.</p>
143: */
144: public ExtendedIterator translateResponseHook(Document response,
145: TriplePattern query, DIGAdapter da) {
146: return conceptSetNameCheck(response, da, m_qObject, query
147: .asTriple());
148: }
149:
150: /**
151: * <p>Check whether the pattern matches the preconditions for the translation
152: * step. This means that the subject and object must be concepts or bNodes.
153: * A limitation on DIG means that both cannot be expressions (bNodes). The
154: * predicate must be equivalence, or one of the boolean definition
155: * relations (in which case the query will have to introduce a bNode as a
156: * comprehension step).
157: */
158: public boolean checkTriple(TriplePattern pattern, DIGAdapter da,
159: Model premises) {
160: Node object = pattern.getObject();
161: Node subject = pattern.getSubject();
162: Node pred = pattern.getPredicate();
163:
164: // ignore patterns with vars
165: boolean pass = subject.isConcrete() && object.isConcrete()
166: && pred.isConcrete();
167:
168: // at least one of subject and object is a concept
169: pass = pass
170: && ((object.isBlank() || da.isConcept(object, premises))
171: && (subject.isBlank()) || da.isConcept(subject,
172: premises)
173: && (!subject.isBlank() || !object.isBlank()));
174:
175: // appropriate predicate
176: pass = pass
177: && (pred.getURI().equals(m_predicate)
178: || pred.getURI()
179: .equals(
180: da.getOntLanguage().UNION_OF()
181: .getURI())
182: || pred.getURI().equals(
183: da.getOntLanguage().INTERSECTION_OF()
184: .getURI())
185: || pred.getURI().equals(
186: da.getOntLanguage().COMPLEMENT_OF()
187: .getURI()) || pred.getURI()
188: .equals(da.getOntLanguage().ONE_OF().getURI()));
189:
190: return pass;
191: }
192:
193: public boolean trigger(TriplePattern pattern, DIGAdapter da,
194: Model premises) {
195: return super .trigger(pattern, da, premises);
196: }
197:
198: // Internal implementation methods
199: //////////////////////////////////
200:
201: //==============================================================================
202: // Inner class definitions
203: //==============================================================================
204:
205: }
206:
207: /*
208: * (c) Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
209: * All rights reserved.
210: *
211: * Redistribution and use in source and binary forms, with or without
212: * modification, are permitted provided that the following conditions
213: * are met:
214: * 1. Redistributions of source code must retain the above copyright
215: * notice, this list of conditions and the following disclaimer.
216: * 2. Redistributions in binary form must reproduce the above copyright
217: * notice, this list of conditions and the following disclaimer in the
218: * documentation and/or other materials provided with the distribution.
219: * 3. The name of the author may not be used to endorse or promote products
220: * derived from this software without specific prior written permission.
221: *
222: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
223: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
224: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
225: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
226: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
227: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
228: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
229: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
230: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
231: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
232: */
|