001: /******************************************************************
002: * File: DebugOWL.java
003: * Created by: Dave Reynolds
004: * Created on: 12-Jun-2003
005: *
006: * (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
007: * [See end of file]
008: * $Id: DebugOWL.java,v 1.34 2008/01/02 12:08:20 andy_seaborne Exp $
009: *****************************************************************/package com.hp.hpl.jena.reasoner.rulesys.test;
010:
011: import java.util.Iterator;
012:
013: import com.hp.hpl.jena.graph.*;
014: import com.hp.hpl.jena.graph.compose.Union; //import com.hp.hpl.jena.rdf.model.*;
015: import com.hp.hpl.jena.util.FileManager;
016: import com.hp.hpl.jena.util.PrintUtil;
017: import com.hp.hpl.jena.vocabulary.*;
018: import com.hp.hpl.jena.reasoner.*;
019: import com.hp.hpl.jena.reasoner.rulesys.*;
020: import com.hp.hpl.jena.reasoner.rulesys.impl.oldCode.*;
021: import com.hp.hpl.jena.shared.WrappedIOException; //import com.hp.hpl.jena.reasoner.transitiveReasoner.TransitiveReasonerFactory;
022:
023: import org.apache.commons.logging.Log;
024: import org.apache.commons.logging.LogFactory;
025: import java.util.*;
026:
027: /**
028: * Test harnness for investigating OWL reasoner correctness and performance
029: * on specific local test files. Unit testing is done using OWLWGTester or simplar,
030: * this code is a debugging tools rather than a tester.
031: *
032: * @author <a href="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
033: * @version $Revision: 1.34 $ on $Date: 2008/01/02 12:08:20 $
034: */
035: public class DebugOWL {
036:
037: /** The base reasoner being tested */
038: Reasoner reasoner;
039:
040: /** The raw tests data as a Graph */
041: Graph testdata;
042:
043: /** The (optional) schema graph used in interpreting the test data */
044: Graph schema;
045:
046: /** The inference graph under test */
047: InfGraph infgraph;
048:
049: /** Concepts created by testGenerator, [layer, index] */
050: Node[] concepts;
051:
052: /** Instances of each concept */
053: Node[] instances;
054:
055: /** Instance properties */
056: Node[] properties;
057:
058: static Log logger = LogFactory.getLog(DebugOWL.class);
059:
060: /** reasoner config: experimental ruleset and config */
061: public static final int EXPT = 1;
062:
063: /** reasoner config: normal OWL-FB */
064: public static final int OWLFB = 2;
065:
066: /** reasoner config: normal OWL forward */
067: public static final int OWL = 3;
068:
069: /** reasoner config: normal RDFS */
070: public static final int RDFSFB = 4;
071:
072: /** reasoner config: final RDFS - hybrid + TGC */
073: public static final int RDFSFinal = 5;
074:
075: /** reasoner config: experimental OWL */
076: public static final int OWLExpt = 6;
077:
078: /** reasoner config: LP RDFS exp */
079: public static final int RDFSLPExpt = 7;
080:
081: /**
082: * Construct an empty test harness.
083: */
084: public DebugOWL(int config) {
085: testdata = Factory.createGraphMem();
086: schema = null;
087:
088: switch (config) {
089:
090: case EXPT:
091: reasoner = GenericRuleReasonerFactory.theInstance().create(
092: null);
093: GenericRuleReasoner grr = (GenericRuleReasoner) reasoner;
094: grr.setMode(GenericRuleReasoner.HYBRID);
095: try {
096: grr
097: .setRules(Rule
098: .parseRules(Util
099: .loadRuleParserFromResourceFile("etc/expt.rules")));
100: } catch (WrappedIOException e) {
101: System.out.println("Failed to open rules file: "
102: + e.getCause());
103: System.exit(1);
104: }
105: // grr.setTransitiveClosureCaching(true);
106: // grr.setOWLTranslation(true);
107: // grr.setTraceOn(true);
108: break;
109:
110: case OWLFB:
111: reasoner = OWLFBRuleReasonerFactory.theInstance().create(
112: null);
113: // ((OWLFBRuleReasoner)reasoner).setTraceOn(true);
114: break;
115:
116: case OWL:
117: reasoner = OWLRuleReasonerFactory.theInstance()
118: .create(null);
119: // ((OWLRuleReasoner)reasoner).setTraceOn(true);
120: break;
121:
122: case RDFSFB:
123: reasoner = RDFSFBRuleReasonerFactory.theInstance().create(
124: null);
125: break;
126:
127: case RDFSFinal:
128: reasoner = RDFSRuleReasonerFactory.theInstance().create(
129: null);
130: break;
131:
132: case OWLExpt:
133: reasoner = OWLExptRuleReasonerFactory.theInstance().create(
134: null);
135: // ((OWLExptRuleReasoner)reasoner).setTraceOn(true);
136: break;
137:
138: case RDFSLPExpt:
139: try {
140: List rules = Rule
141: .parseRules(Util
142: .loadRuleParserFromResourceFile("etc/expt.rules"));
143: reasoner = new FBRuleReasoner(rules);
144: } catch (WrappedIOException e) {
145: System.out.println("Failed to open rules file: "
146: + e.getCause());
147: System.exit(1);
148: }
149: break;
150:
151: }
152:
153: }
154:
155: /**
156: * Load a test data set from file.
157: */
158: public void load(String testFile) {
159: testdata = FileManager.get().loadModel(testFile).getGraph();
160: schema = null;
161: }
162:
163: /**
164: * Load both a schema and an instance data file.
165: */
166: public void load(String schemaFile, String testFile) {
167: testdata = FileManager.get().loadModel(testFile).getGraph();
168: schema = FileManager.get().loadModel(schemaFile).getGraph();
169: }
170:
171: /**
172: * Create an artificial data set. This variant puts schema and
173: * instance data into the same testdata graph.
174: * @param depth the depth of the concept tree
175: * @param NS the number of subclasses at each tree level
176: * @param NI the number of instances of each concept
177: * @param withProps if true then properties are created for each concept and instiated for every third instance
178: */
179: public void createTest(int depth, int NS, int NI, boolean withProps) {
180: // Calculate total store sizes and allocate
181: int numClasses = 0;
182: int levelSize = 1;
183: for (int i = 0; i < depth; i++) {
184: levelSize *= NS;
185: numClasses += levelSize;
186: }
187: concepts = new Node[numClasses];
188: properties = new Node[numClasses];
189: instances = new Node[numClasses * NI];
190: logger.info("Classes: " + numClasses + " Instances: "
191: + (numClasses * NI)
192: + (withProps ? " with properties" : ""));
193:
194: // Create the tree
195: testdata = Factory.createGraphMem();
196: // First level
197: int conceptPtr = 0;
198: int levelStart = 0;
199: int levelEnd = 0;
200: int instancePtr = 0;
201: for (int i = 0; i < depth; i++) {
202: // Class tree
203: Node property = null;
204: if (i == 0) {
205: for (int j = 0; j < NS; j++) {
206: Node concept = Node.createURI("concept"
207: + conceptPtr);
208: if (withProps) {
209: property = Node.createURI("prop" + conceptPtr);
210: properties[conceptPtr] = property;
211: }
212: concepts[conceptPtr++] = concept;
213: }
214: } else {
215: for (int j = levelStart; j < levelEnd; j++) {
216: Node super Concept = concepts[j];
217: for (int k = 0; k < NS; k++) {
218: Node concept = Node.createURI("concept"
219: + conceptPtr);
220: if (withProps) {
221: property = Node.createURI("prop"
222: + conceptPtr);
223: properties[conceptPtr] = property;
224: }
225: concepts[conceptPtr++] = concept;
226: testdata
227: .add(new Triple(concept,
228: RDFS.subClassOf.asNode(),
229: super Concept));
230: }
231: }
232: }
233: levelStart = levelEnd;
234: levelEnd = conceptPtr;
235: // Instance data
236: for (int j = levelStart; j < levelEnd; j++) {
237: Node concept = concepts[j];
238: for (int k = 0; k < NI; k++) {
239: Node instance = Node.createURI("instance"
240: + instancePtr);
241: testdata.add(new Triple(instance,
242: RDF.type.asNode(), concept));
243: if (withProps && (k - 1) % 3 == 0) {
244: testdata.add(new Triple(
245: instances[instancePtr - 1], property,
246: instance));
247: }
248: instances[instancePtr++] = instance;
249: }
250: }
251: }
252: }
253:
254: /**
255: * Configure the inference graph ready for testing.
256: */
257: public void init() {
258: if (schema == null) {
259: infgraph = reasoner.bind(testdata);
260: } else {
261: // infgraph = reasoner.bindSchema(schema).bind(testdata);
262: infgraph = reasoner.bind(new Union(schema, testdata));
263: }
264: // if (infgraph instanceof FBRuleInfGraph) {
265: // ((FBRuleInfGraph)infgraph).resetLPProfile(true);
266: // }
267: if (infgraph instanceof FBRuleInfGraph) {
268: System.out.println("Starting prepare");
269: ((FBRuleInfGraph) infgraph).prepare();
270: System.out.println(".. finished");
271: }
272: }
273:
274: /**
275: * Test and time an predefined class extension listing
276: */
277: long listC0(boolean print) {
278: return list(null, RDF.type.asNode(), concepts[0], print);
279: }
280:
281: /**
282: * Test and time an general access operation.
283: */
284: long list(Node s, Node p, Node o, boolean print) {
285: long t1 = System.currentTimeMillis();
286: init();
287: int count = 0;
288: for (Iterator i = infgraph.find(s, p, o); i.hasNext();) {
289: Triple t = (Triple) i.next();
290: count++;
291: if (print) {
292: logger.info(PrintUtil.print(t));
293: }
294: }
295: long t2 = System.currentTimeMillis();
296: System.out.println("Found " + count + " results");
297: return (t2 - t1);
298: }
299:
300: /**
301: * Create and run a list classes test.
302: */
303: public void runListClassesTest(int depth, int NS, int NI,
304: boolean withProps) {
305: createTest(depth, NS, NI, withProps);
306: long t = list(null, RDF.type.asNode(), RDFS.Class.asNode(),
307: false);
308: System.out.println("Took " + t + "ms");
309: }
310:
311: /**
312: * Create and run a volz test.
313: */
314: public void runVolz(int depth, int NS, int NI, boolean withProps) {
315: createTest(depth, NS, NI, withProps);
316: long t = listC0(false);
317: System.out.println("Took " + t + "ms");
318: if (infgraph instanceof FBRuleInfGraph) {
319: ((FBRuleInfGraph) infgraph).printLPProfile();
320: }
321: }
322:
323: /**
324: * Run a standard test squence based on Volz et al sets
325: */
326: public void runVolz() {
327: runVolz(3, 5, 10, false);
328: runVolz(3, 5, 10, false);
329: runVolz(4, 5, 10, false);
330: runVolz(5, 5, 10, false);
331:
332: // runVolz(3,5,30, false);
333: // runVolz(4,5,30, false);
334: // runVolz(5,5,30, false);
335: // run(3,5,10, true);
336: // run(4,5,10, true);
337: // run(5,5,10, true);
338: }
339:
340: /**
341: * Run default test on a named file.
342: */
343: public void listClassesOn(String filename) {
344: load(filename);
345: System.out.println("Testing: " + filename);
346: long t = list(null, RDF.type.asNode(), RDFS.Class.asNode(),
347: false);
348: System.out.println("Took " + t + "ms");
349: }
350:
351: public static void main(String[] args) {
352: try {
353: String dataFile = "file:testing/ontology/owl/list-syntax/test-with-import.rdf";
354: String schemaFile = "file:vocabularies/owl.owl";
355: String schemaFile2 = "file:testing/reasoners/bugs/owl-partial.owl";
356: String dataFile2 = "file:testing/reasoners/bugs/test.owl";
357: String food = "file:testing/reasoners/bugs/food.owl";
358:
359: // Example from ontology development which takes s rather than ms
360: // new DebugOWL(OWLExpt).listClassesOn(dataFile2);
361:
362: // owl.owl goes into meltdown with even the forward rules
363: // new DebugOWL(OWLFB).run(schemaFile);
364: // new DebugOWL(OWL).run("file:temp/owl-subset.owl");
365:
366: // Test volz examples on OWL config
367: // new DebugOWL(OWLFB).runVolz();
368: // new DebugOWL(OWLExpt).runVolz();
369:
370: // Test volz examples on RDFS config
371: System.out
372: .println("Volz tests on normal RDFS, tgc + type rules");
373: new DebugOWL(RDFSFinal).runVolz();
374: // System.out.println("Volz tests on lp + expt RDFS rules");
375: // new DebugOWL(RDFSLPExpt).runVolz();
376:
377: // System.out.println("Volz tests on normal RDFS fb rules");
378: // new DebugOWL(RDFSFB).runVolz();
379: // System.out.println("Volz tests on lp + expt owl rules");
380: // new DebugOWL(OWLExpt).runVolz();
381: // System.out.println("Volz tests on normal OWL-FB");
382: // new DebugOWL(OWLFB).runVolz();
383:
384: // DebugOWL tester = new DebugOWL(OWLFB);
385: // tester.load(dataFile2);
386: // System.out.println("Test schema + data started ...");
387: // long t = tester.list(null, RDF.type.asNode(), RDFS.Class.asNode(), false);
388: // System.out.println("Took " + t + "ms");
389:
390: // DebugOWL tester = new DebugOWL(EXPT);
391: // tester.runListClassesTest(1,4,10,false);
392: // tester.runListClassesTest(1,4,10,false);
393: // tester.runListClassesTest(2,4,10,false);
394: // tester.runListClassesTest(3,4,10,false);
395: // tester.runListClassesTest(3,5,10,false);
396: // tester.runListClassesTest(3,6,10,false);
397:
398: } catch (Exception e) {
399: System.out.println("Problem: " + e);
400: e.printStackTrace();
401: }
402: }
403:
404: }
405:
406: /*
407: (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
408: All rights reserved.
409:
410: Redistribution and use in source and binary forms, with or without
411: modification, are permitted provided that the following conditions
412: are met:
413:
414: 1. Redistributions of source code must retain the above copyright
415: notice, this list of conditions and the following disclaimer.
416:
417: 2. Redistributions in binary form must reproduce the above copyright
418: notice, this list of conditions and the following disclaimer in the
419: documentation and/or other materials provided with the distribution.
420:
421: 3. The name of the author may not be used to endorse or promote products
422: derived from this software without specific prior written permission.
423:
424: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
425: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
426: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
427: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
428: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
429: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
430: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
431: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
432: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
433: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
434: */
|