| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.jena.reasoner.rulesys.test; |
| |
| import org.apache.jena.graph.* ; |
| import org.apache.jena.graph.compose.Union ; |
| import org.apache.jena.reasoner.* ; |
| import org.apache.jena.reasoner.rulesys.* ; |
| import org.apache.jena.shared.WrappedIOException ; |
| import org.apache.jena.util.FileManager ; |
| import org.apache.jena.util.PrintUtil ; |
| import org.apache.jena.vocabulary.* ; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import java.util.*; |
| |
| /** |
| * Test harnness for investigating OWL reasoner correctness and performance |
| * on specific local test files. Unit testing is done using OWLWGTester or simplar, |
| * this code is a debugging tools rather than a tester. |
| */ |
| public class DebugOWL { |
| |
| /** The base reasoner being tested */ |
| Reasoner reasoner; |
| |
| /** The raw tests data as a Graph */ |
| Graph testdata; |
| |
| /** The (optional) schema graph used in interpreting the test data */ |
| Graph schema; |
| |
| /** The inference graph under test */ |
| InfGraph infgraph; |
| |
| /** Concepts created by testGenerator, [layer, index] */ |
| Node[] concepts; |
| |
| /** Instances of each concept */ |
| Node[] instances; |
| |
| /** Instance properties */ |
| Node[] properties; |
| |
| static Logger logger = LoggerFactory.getLogger(DebugOWL.class); |
| |
| /** reasoner config: experimental ruleset and config */ |
| public static final int EXPT = 1; |
| |
| /** reasoner config: normal OWL-FB */ |
| public static final int OWLFB = 2; |
| |
| /** reasoner config: normal OWL forward */ |
| public static final int OWL = 3; |
| |
| /** reasoner config: normal RDFS */ |
| public static final int RDFSFB = 4; |
| |
| /** reasoner config: final RDFS - hybrid + TGC */ |
| public static final int RDFSFinal = 5; |
| |
| /** reasoner config: experimental OWL */ |
| public static final int OWLExpt = 6; |
| |
| /** reasoner config: LP RDFS exp */ |
| public static final int RDFSLPExpt = 7; |
| |
| |
| /** |
| * Construct an empty test harness. |
| */ |
| public DebugOWL(int config) { |
| testdata = Factory.createGraphMem(); |
| schema = null; |
| |
| switch(config) { |
| |
| case EXPT: |
| reasoner = GenericRuleReasonerFactory.theInstance().create(null); |
| GenericRuleReasoner grr = (GenericRuleReasoner)reasoner; |
| grr.setMode(GenericRuleReasoner.HYBRID); |
| try { |
| grr.setRules(Rule.parseRules(Util.loadRuleParserFromResourceFile("etc/expt.rules"))); |
| } catch (WrappedIOException e) { |
| System.out.println("Failed to open rules file: " + e.getCause() ); |
| System.exit(1); |
| } |
| // grr.setTransitiveClosureCaching(true); |
| // grr.setOWLTranslation(true); |
| // grr.setTraceOn(true); |
| break; |
| |
| case OWLFB: |
| reasoner = OWLFBRuleReasonerFactory.theInstance().create(null); |
| // ((OWLFBRuleReasoner)reasoner).setTraceOn(true); |
| break; |
| |
| case RDFSFB: |
| reasoner = RDFSFBRuleReasonerFactory.theInstance().create(null); |
| break; |
| |
| case RDFSFinal: |
| reasoner = RDFSRuleReasonerFactory.theInstance().create(null); |
| break; |
| |
| case RDFSLPExpt: |
| try { |
| List<Rule> rules = Rule.parseRules(Util.loadRuleParserFromResourceFile("etc/expt.rules")); |
| reasoner = new FBRuleReasoner(rules); |
| } catch (WrappedIOException e) { |
| System.out.println("Failed to open rules file: " + e.getCause()); |
| System.exit(1); |
| } |
| break; |
| |
| } |
| |
| } |
| |
| /** |
| * Load a test data set from file. |
| */ |
| public void load(String testFile) { |
| testdata = FileManager.getInternal().loadModelInternal(testFile).getGraph(); |
| schema = null; |
| } |
| |
| /** |
| * Load both a schema and an instance data file. |
| */ |
| public void load(String schemaFile, String testFile) { |
| testdata = FileManager.getInternal().loadModelInternal(testFile).getGraph(); |
| schema = FileManager.getInternal().loadModelInternal(schemaFile).getGraph(); |
| } |
| |
| /** |
| * Create an artificial data set. This variant puts schema and |
| * instance data into the same testdata graph. |
| * @param depth the depth of the concept tree |
| * @param NS the number of subclasses at each tree level |
| * @param NI the number of instances of each concept |
| * @param withProps if true then properties are created for each concept and instiated for every third instance |
| */ |
| public void createTest(int depth, int NS, int NI, boolean withProps) { |
| // Calculate total store sizes and allocate |
| int numClasses = 0; |
| int levelSize = 1; |
| for (int i = 0; i < depth; i++) { |
| levelSize *= NS; |
| numClasses += levelSize; |
| } |
| concepts = new Node[numClasses]; |
| properties = new Node[numClasses]; |
| instances = new Node[numClasses * NI]; |
| logger.info("Classes: " + numClasses +" Instances: " + (numClasses * NI) |
| + (withProps ? " with properties" : "")); |
| |
| // Create the tree |
| testdata = Factory.createGraphMem(); |
| // First level |
| int conceptPtr = 0; |
| int levelStart = 0; |
| int levelEnd = 0; |
| int instancePtr = 0; |
| for (int i = 0; i < depth; i++) { |
| // Class tree |
| Node property = null; |
| if (i == 0) { |
| for (int j = 0; j < NS; j++) { |
| Node concept = NodeFactory.createURI("concept" + conceptPtr); |
| if (withProps) { |
| property = NodeFactory.createURI("prop" + conceptPtr); |
| properties[conceptPtr] = property; |
| } |
| concepts[conceptPtr++] = concept; |
| } |
| } else { |
| for (int j = levelStart; j < levelEnd; j++) { |
| Node superConcept = concepts[j]; |
| for (int k = 0; k < NS; k++) { |
| Node concept = NodeFactory.createURI("concept" + conceptPtr); |
| if (withProps) { |
| property = NodeFactory.createURI("prop" + conceptPtr); |
| properties[conceptPtr] = property; |
| } |
| concepts[conceptPtr++] = concept; |
| testdata.add(new Triple(concept, RDFS.subClassOf.asNode(), superConcept)); |
| } |
| } |
| } |
| levelStart = levelEnd; |
| levelEnd = conceptPtr; |
| // Instance data |
| for (int j = levelStart; j < levelEnd; j++) { |
| Node concept = concepts[j]; |
| for (int k = 0; k < NI; k++) { |
| Node instance = NodeFactory.createURI("instance"+instancePtr); |
| testdata.add(new Triple(instance, RDF.type.asNode(), concept)); |
| if (withProps && (k-1)%3 == 0) { |
| testdata.add(new Triple(instances[instancePtr-1], property, instance)); |
| } |
| instances[instancePtr++] = instance; |
| } |
| } |
| } |
| } |
| |
| /** |
| * Configure the inference graph ready for testing. |
| */ |
| public void init() { |
| if (schema == null) { |
| infgraph = reasoner.bind(testdata); |
| } else { |
| // infgraph = reasoner.bindSchema(schema).bind(testdata); |
| infgraph = reasoner.bind(new Union(schema, testdata)); |
| } |
| // if (infgraph instanceof FBRuleInfGraph) { |
| // ((FBRuleInfGraph)infgraph).resetLPProfile(true); |
| // } |
| if (infgraph instanceof FBRuleInfGraph) { |
| System.out.println("Starting prepare"); |
| ((FBRuleInfGraph)infgraph).prepare(); |
| System.out.println(".. finished"); |
| } |
| } |
| |
| /** |
| * Test and time an predefined class extension listing |
| */ |
| long listC0(boolean print) { |
| return list(null, RDF.type.asNode(), concepts[0], print); |
| } |
| |
| /** |
| * Test and time an general access operation. |
| */ |
| long list(Node s, Node p, Node o, boolean print) { |
| long t1 = System.currentTimeMillis(); |
| init(); |
| int count = 0; |
| for (Iterator<Triple> i = infgraph.find(s,p,o); i.hasNext(); ) { |
| Triple t = i.next(); |
| count++; |
| if (print) { |
| logger.info(PrintUtil.print(t)); |
| } |
| } |
| long t2 = System.currentTimeMillis(); |
| System.out.println("Found " + count + " results"); |
| return (t2 - t1); |
| } |
| |
| /** |
| * Create and run a list classes test. |
| */ |
| public void runListClassesTest(int depth, int NS, int NI, boolean withProps) { |
| createTest(depth, NS, NI, withProps); |
| long t = list(null, RDF.type.asNode(), RDFS.Class.asNode(), false); |
| System.out.println("Took " + t + "ms"); |
| } |
| |
| /** |
| * Create and run a volz test. |
| */ |
| public void runVolz(int depth, int NS, int NI, boolean withProps) { |
| createTest(depth, NS, NI, withProps); |
| long t = listC0(false); |
| System.out.println("Took " + t + "ms"); |
| if (infgraph instanceof FBRuleInfGraph) { |
| ((FBRuleInfGraph)infgraph).printLPProfile(); |
| } |
| } |
| |
| /** |
| * Run a standard test squence based on Volz et al sets |
| */ |
| public void runVolz() { |
| runVolz(3,5,10, false); |
| runVolz(3,5,10, false); |
| runVolz(4,5,10, false); |
| runVolz(5,5,10, false); |
| |
| // runVolz(3,5,30, false); |
| // runVolz(4,5,30, false); |
| // runVolz(5,5,30, false); |
| // run(3,5,10, true); |
| // run(4,5,10, true); |
| // run(5,5,10, true); |
| } |
| |
| /** |
| * Run default test on a named file. |
| */ |
| public void listClassesOn(String filename) { |
| load(filename); |
| System.out.println("Testing: " + filename); |
| long t = list(null, RDF.type.asNode(), RDFS.Class.asNode(), false); |
| System.out.println("Took " + t + "ms"); |
| } |
| |
| public static void main(String[] args) { |
| try { |
| String dataFile = "file:testing/ontology/owl/list-syntax/test-with-import.rdf"; |
| String schemaFile = "file:vocabularies/owl.owl"; |
| String schemaFile2 = "file:testing/reasoners/bugs/owl-partial.owl"; |
| String dataFile2 = "file:testing/reasoners/bugs/test.owl"; |
| String food = "file:testing/reasoners/bugs/food.owl"; |
| |
| // Example from ontology development which takes s rather than ms |
| // new DebugOWL(OWLExpt).listClassesOn(dataFile2); |
| |
| // owl.owl goes into meltdown with even the forward rules |
| // new DebugOWL(OWLFB).run(schemaFile); |
| // new DebugOWL(OWL).run("file:temp/owl-subset.owl"); |
| |
| // Test volz examples on OWL config |
| // new DebugOWL(OWLFB).runVolz(); |
| // new DebugOWL(OWLExpt).runVolz(); |
| |
| // Test volz examples on RDFS config |
| System.out.println("Volz tests on normal RDFS, tgc + type rules"); |
| new DebugOWL(RDFSFinal).runVolz(); |
| // System.out.println("Volz tests on lp + expt RDFS rules"); |
| // new DebugOWL(RDFSLPExpt).runVolz(); |
| |
| // System.out.println("Volz tests on normal RDFS fb rules"); |
| // new DebugOWL(RDFSFB).runVolz(); |
| // System.out.println("Volz tests on lp + expt owl rules"); |
| // new DebugOWL(OWLExpt).runVolz(); |
| // System.out.println("Volz tests on normal OWL-FB"); |
| // new DebugOWL(OWLFB).runVolz(); |
| |
| // DebugOWL tester = new DebugOWL(OWLFB); |
| // tester.load(dataFile2); |
| // System.out.println("Test schema + data started ..."); |
| // long t = tester.list(null, RDF.type.asNode(), RDFS.Class.asNode(), false); |
| // System.out.println("Took " + t + "ms"); |
| |
| // DebugOWL tester = new DebugOWL(EXPT); |
| // tester.runListClassesTest(1,4,10,false); |
| // tester.runListClassesTest(1,4,10,false); |
| // tester.runListClassesTest(2,4,10,false); |
| // tester.runListClassesTest(3,4,10,false); |
| // tester.runListClassesTest(3,5,10,false); |
| // tester.runListClassesTest(3,6,10,false); |
| |
| } catch (Exception e) { |
| System.out.println("Problem: " + e); |
| e.printStackTrace(); |
| } |
| } |
| |
| } |