001: /******************************************************************
002: * File: OWLRuleTranslationHook.java
003: * Created by: Dave Reynolds
004: * Created on: 22-Jun-2003
005: *
006: * (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
007: * [See end of file]
008: * $Id: OWLRuleTranslationHook.java,v 1.11 2008/01/02 12:06:15 andy_seaborne Exp $
009: *****************************************************************/package com.hp.hpl.jena.reasoner.rulesys.impl;
010:
011: import com.hp.hpl.jena.reasoner.rulesys.*;
012: import com.hp.hpl.jena.reasoner.*;
013: import com.hp.hpl.jena.graph.*;
014: import com.hp.hpl.jena.vocabulary.*;
015:
016: import java.util.*;
017:
018: /**
019: * A rule preprocessor that scans the data looking for interesection
020: * definitions and augements the rule base by translations of the
021: * intersection statement.
022: *
023: * @author <a href="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
024: * @version $Revision: 1.11 $ on $Date: 2008/01/02 12:06:15 $
025: */
026: public class OWLRuleTranslationHook implements RulePreprocessHook {
027:
028: /**
029: * Invoke the preprocessing hook. This will be called during the
030: * preparation time of the hybrid reasoner.
031: * @param infGraph the inference graph which is being prepared,
032: * the hook code can use this to addDeductions or add additional
033: * rules (using addRuleDuringPrepare).
034: * @param dataFind the finder which packages up the raw data (both
035: * schema and data bind) and any cached transitive closures.
036: * @param inserts a temporary graph into which the hook should insert
037: * all new deductions that should be seen by the rules.
038: */
039: public void run(FBRuleInfGraph infGraph, Finder dataFind,
040: Graph inserts) {
041: Iterator it = dataFind.find(new TriplePattern(null,
042: OWL.intersectionOf.asNode(), null));
043: while (it.hasNext()) {
044: Triple decl = (Triple) it.next();
045: Node className = decl.getSubject();
046: List elements = new ArrayList();
047: translateIntersectionList(decl.getObject(), dataFind,
048: elements);
049: // Generate the corresponding ruleset
050: List recognitionBody = new ArrayList();
051: Node var = new Node_RuleVariable("?x", 0);
052: for (Iterator i = elements.iterator(); i.hasNext();) {
053: Node description = (Node) i.next();
054: // Implication rule
055: Rule ir = new Rule("intersectionImplication",
056: new ClauseEntry[] { new TriplePattern(
057: className, RDFS.subClassOf.asNode(),
058: description) }, new ClauseEntry[0]);
059: ir.setBackward(false);
060: // System.out.println("translation hook => " + ir);
061: infGraph.addRuleDuringPrepare(ir);
062: // Recognition rule elements
063: recognitionBody.add(new TriplePattern(var, RDF.type
064: .asNode(), description));
065: }
066: List recognitionHead = new ArrayList(1);
067: recognitionHead.add(new TriplePattern(var, RDF.type
068: .asNode(), className));
069: Rule rr = new Rule("intersectionRecognition",
070: recognitionHead, recognitionBody);
071: rr.setBackward(true);
072: // System.out.println("translation hook => " + rr);
073: infGraph.addRuleDuringPrepare(rr);
074: }
075: }
076:
077: /**
078: * Translation code to translate a list of intersection elements into a
079: * Java list of corresponding class names or restriction functors.
080: * @param node the list node currently being processed
081: * @param data the source data to use as a context for this processing
082: * @param elements the list of elements found so far
083: */
084: protected static void translateIntersectionList(Node node,
085: Finder dataFind, List elements) {
086: if (node == null) {
087: throw new ReasonerException(
088: "Illegal list structure in owl:intersectionOf");
089: }
090: if (node.equals(RDF.nil.asNode())) {
091: return; // end of list
092: }
093: Node description = Util.getPropValue(node, RDF.first.asNode(),
094: dataFind);
095: if (description == null) {
096: throw new ReasonerException(
097: "Illegal list structure in owl:intersectionOf");
098: }
099: // Translate the first description element
100: /* - temp comment out during debugging
101: if (dataFind.contains(new TriplePattern(description, RDF.type.asNode(), OWL.Restriction.asNode()))) {
102: // Process a restriction element
103: Node onprop = Util.getPropValue(description, OWL.onProperty.asNode(), dataFind);
104: Node value;
105: if ((value = Util.getPropValue(description, OWL.allValuesFrom.asNode(), dataFind)) != null) {
106: elements.add(Functor.makeFunctorNode("all", new Node[] {onprop, value}));
107: } else if ((value = Util.getPropValue(description, OWL.someValuesFrom.asNode(), dataFind)) != null) {
108: elements.add(Functor.makeFunctorNode("some", new Node[] {onprop, value}));
109: } else if ((value = Util.getPropValue(description, OWL.hasValue.asNode(), dataFind)) != null) {
110: elements.add(Functor.makeFunctorNode("hasValue", new Node[] {onprop, value}));
111: } else if ((value = Util.getPropValue(description, OWL.minCardinality.asNode(), dataFind)) != null) {
112: elements.add(Functor.makeFunctorNode("min", new Node[] {onprop, value}));
113: } else if ((value = Util.getPropValue(description, OWL.maxCardinality.asNode(), dataFind)) != null) {
114: elements.add(Functor.makeFunctorNode("max", new Node[] {onprop, value}));
115: } else if ((value = Util.getPropValue(description, OWL.cardinality.asNode(), dataFind)) != null) {
116: elements.add(Functor.makeFunctorNode("max", new Node[] {onprop, value}));
117: elements.add(Functor.makeFunctorNode("min", new Node[] {onprop, value}));
118: } else {
119: elements.add(description);
120: }
121: } else {
122: // Assume its a class name
123: elements.add(description);
124: }
125: */
126: // Above used to translated intersections into direct functor tests but in fact the
127: // references to the restriction bNode is sufficent and a better match to the current rules
128: elements.add(description);
129: // Process the list tail
130: Node next = Util
131: .getPropValue(node, RDF.rest.asNode(), dataFind);
132: translateIntersectionList(next, dataFind, elements);
133: }
134:
135: /**
136: * Validate a triple add to see if it should reinvoke the hook. If so
137: * then the inference will be restarted at next prepare time. Incremental
138: * re-processing is not yet supported.
139: */
140: public boolean needsRerun(FBRuleInfGraph infGraph, Triple t) {
141: return (t.getPredicate().equals(OWL.intersectionOf.asNode()));
142: }
143:
144: }
145:
146: /*
147: (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
148: All rights reserved.
149:
150: Redistribution and use in source and binary forms, with or without
151: modification, are permitted provided that the following conditions
152: are met:
153:
154: 1. Redistributions of source code must retain the above copyright
155: notice, this list of conditions and the following disclaimer.
156:
157: 2. Redistributions in binary form must reproduce the above copyright
158: notice, this list of conditions and the following disclaimer in the
159: documentation and/or other materials provided with the distribution.
160:
161: 3. The name of the author may not be used to endorse or promote products
162: derived from this software without specific prior written permission.
163:
164: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
165: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
166: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
167: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
168: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
169: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
170: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
171: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
172: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
173: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
174: */
|