I'm looking for a clear approach to use SWRL clearly in virtuoso server. For example, I designed an ontology using Protege 4.3 and I wrote the SWRL rules using Rules tab in Protege.
Product(?P),hasName(?P,?N),inGroupB(?P,?B)->hasBug(?P)
I uploaded my RDF data (~3GB) into Virtuoso server, along with the Ontology schema. I tried to recall the data that is supposed to be inferred based on the Rules in the ontology but the query return empty results. Example of the SPARQL query that it should clearly return the inferred relation form the rule above as follow:
DEFINE input:inference <http://example.com/2/owl>
PREFIX e:<http://example.com/e/>
SELECT *
FROM <http://example.com/2/data>
WHERE
{
?P a e:Product ;
e:hasBug ?B
}
I believe that I have problem on integrating the things together (RDF data ,OWL schema and SWRL rules). I used Jena and Virtuoso Jena driver in order to load data, ontology and run the SPARQL queries. Any advice on how to let the reasoning part work properly?
Virtuoso 7.x does not support SWRL.
Virtuoso 8.x implements SPIN, into which SWRL can be translated, among other complex reasoning.
See Creating Custom Inference Rules using the SPIN Vocabulary and Virtuoso 8.0 for one walk-through.
Your rough SWRL above translates roughly to --
CONSTRUCT { ?P <hasBug> ?B }
WHERE
{
?P a <Product> ;
<hasName> ?N ;
<inGroupB> ?B .
}
-- or --
CONSTRUCT { ?P a <BuggyProduct> }
WHERE
{
?P a <Product> ;
<hasName> ?N ;
<inGroupB> ?B .
}
Once you have a SPARQL CONSTRUCT, making a Custom Inference Rule boils down to a few steps:
Describe (with a collection of RDF statements in a Turtle doc) your Rule using SPIN terms
EXEC ('SPARQL ' || SPARQL_SPIN_GRAPH_TO_DEFSPIN('{turtle-doc-with-rule-description-iri'))
Test your Rule
More complete user documentation is in progress; you can get assistance via the Virtuoso Users mailing list or the OpenLink Support Case System.
Related
I have been making some tests using Jena OWL Reasoner, but I don´t understand some results obtained, for example, if I have the following KB:
Class A
Class B
Class C rdfs:subClassOf A
A owl:disjointWith B
...and if I ask "C owl:disjointWith B"? to the inference model, the answer sould be "yes", but the Jena OWL Reasoner answer is NO...I check this using...
if (infmodel.contains(A, OWL.disjointWith, C)) {
...
}
....
So, is there some limitations to make inferences with this reasoner?
Thanks
Your query contains A owl:disjointWith C, which cannot be inferred from your ontology. Are you sure it's the correct query?
I've multiple personal inference rules in Datalog Form.
I can extend Jena GenericRuleReasoner in order to take them into account during the inference step. Here is an example of code to do that :
String rules = "[r1: (?e1 st:runningTask st:gic_eth0) -> (?e1 rdf:type st:dataFromEthernet2IP)]";
Reasoner reasoner = new GenericRuleReasoner(Rule.parseRules(rules));
reasoner.setDerivationLogging(true);
InfModel inf = ModelFactory.createInfModel(reasoner, rawData);
Actually, I'm want to use Pellet reasoner since it is easy to plug to Jena. I wonder if Pellet is extensible as GenericRuleReasoner ? and if it is, how to add my Datalog rules in it ?
I created an ontology based Security alerts.
After reading in some data(Individuals) it got pretty big, so I decided to use a Jena Rule Reasoner to determine some facts. I mostly give Individuals types and attributes and use some regex. Heres a small (constructed) example which gives an individual the type "multiple", when its information matches the regex:
[testRuleContent: (?X ns:hasClassification ?Y), (?Y ns:hasText ?Z), regex(?Z, '.Multiple.')
-> (?X rdf:type ns:Multiple)]
To use the reasoner i create an infModel based on my previous loaded ontology:
RuleReasoner ruleReasoner = new RuleReasoner("GenaralRuleReasoner");
//read rules from file
List<Rule> ruleList = Rule.parseRules(Rule.parseRules(rd));
com.hp.hpl.jena.reasoner.Reasoner reasoner = new GenericRuleReasoner(ruleList);
//jenaOntology is the ontology with the data
InfModel inferredOntotlogy = ModelFactory.createInfModel(reasoner, jenaOntology);
inferredOntotlogy.prepare();
This works without a problem and i can write the infModel into a file with the added types.
Whats the preferable method to query the inferred ontology for certain individuals (in this example those with the type: "Multiple")?
At the moment I use "listStatements()" on the Inferred Model:
Resource multiple = inferredOntotlogy.getResource("file:/C:/ns#Multiple");
StmtIterator iter = inferredOntotlogy.listStatements(null, RDF.type, multiple);
while (iter.hasNext()) {
Resource subject = iter.next().getSubject();
//Individual ind = subject.as(Individual.class);
String indUri = iter.next().getSubject().getURI();
The cast throws an exception(Its only a node with the Uri). But I get the valid Uri of the individual and could work with the basic ontology model without the new proprties (I only need them to get the searched individual so its a possible solution).
A similar attempt would be to use getDeductionsModel() on the Inferred Model to get a Model -> OntModel and query it (potentially with SPARQL).
But id prefere an easy way to query the Inferred Model. Is there such a solution? Or can u give me a tip how to handle this situaion the best way?
I will just work with the resources fow now. It provides all the functionality I need. I should have taken a closer look at the API.
I answered my own question to mark it as solved tomorrow.
I was unable to find some decent simple code examples of using SWRL and Jena with
Pellet, or at least using SWRL? I have studied some examples in Pellet documentation, but there is no example about using SWRL. Most examples on the web are incomplete and confusing.
The only solution I found was with the Jess Rule Engine but it is not free and is under commercial license. I found that Pellet support SWRL rules but could not find running example.
The only example I found is this, but I do not understand it:
OWLOntologyManager m = create();
OWLOntology o = m.createOntology(example_iri);
// Get hold of references to class A and class B.
OWLClass clsA = df.getOWLClass( IRI.create(example_iri + "#A" ));
OWLClass clsB = df.getOWLClass(IRI.create(example_iri + "#B" ));
SWRLVariable var = df.getSWRLVariable(IRI.create(example_iri + "#x" ));
SWRLClassAtom body = df.getSWRLClassAtom(clsA, var);
SWRLClassAtom head = df.getSWRLClassAtom(clsB, var);
SWRLRule rule = df.getSWRLRule(Collections.singleton(body),
Collections.singleton(head));
m.applyChange(new AddAxiom(o, rule));
Pellet Rules and Jena Rules are Very Different™
The short answer is that Pellet supports SWRL rules. If you have an ontology that contains SWRL rules and ask Pellet to reason over it, it will take them into consideration.
Jena has its own rules language, which is described in the documentation page, Reasoners and rule engines: Jena inference support. It supports both forward and backward chaining rules.
However, though both Pellet and Jena support a notion of rules, the intended domains of SWRL rules and Jena rules are very different. SWRL rules are OWL-level constructs; the unary predicates in a SWRL rule are class expressions, and the binary predicates are object and data properties. Additionally, SWRL rules only match on named individuals; they don't match for individuals whose existence is only inferred. Jena rules, on the other hand, are RDF-level, and designed to work on RDF-graphs. While RDF and OWL are often used together, (e.g., OWL data is serialized in RDF), the two are conceptually distinct. An OWL reasoner could be implemented that makes no use of RDF, and a SWRL engine could be built that make no use of RDF graphs.
Jena or OWL API?
The code that you've shown, based on the presence of an OWLOntologyManager, is based on the OWL API, not on Jena's API. The OWL API will have more direct functionality for working with OWL and SWRL rules, while Jena will not. (Jena's OntModels work well with OWL1, but support for OWL2 is not complete (and still “open for contributors”).
Rather than using the OWL API or trying to use Jena's API, you'll probably find it easier to create rules using an editor such as Protégé. Martin Kuba has written a very nice OWL2 and SWRL Tutorial that can help you here.
SWRL rules work with Pellet API. I created my ontology and SWRL rules using Protégé and I was able to create OWL individuals dynamically using Java code. This whole ontology is used as aggregatedOwl in the following code. This code loads ontology (base OWL + individuals if any + SWRL rules) and runs the Pellet reasoner on it and saves the inferred result in a string.
import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.io.StringDocumentTarget;
import org.semanticweb.owlapi.model.OWLAxiom;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyCreationException;
import org.semanticweb.owlapi.model.OWLOntologyManager;
import org.semanticweb.owlapi.model.OWLOntologyStorageException;
import org.semanticweb.owlapi.util.InferredAxiomGenerator;
import org.semanticweb.owlapi.util.InferredOntologyGenerator;
import org.semanticweb.owlapi.util.InferredPropertyAssertionGenerator;
import com.clarkparsia.pellet.owlapiv3.PelletReasoner;
import com.clarkparsia.pellet.owlapiv3.PelletReasonerFactory;
try {
manager = OWLManager.createOWLOntologyManager();
InputStream owlInputStream = new ByteArrayInputStream(aggregatedOwl.getBytes("UTF-8"));
inferredOntology = manager.loadOntologyFromOntologyDocument(owlInputStream);
PelletReasoner reasoner = PelletReasonerFactory.getInstance().createReasoner(inferredOntology);
reasoner.getKB().realize();
List<InferredAxiomGenerator<? extends OWLAxiom>> axiomGenerators = new ArrayList<InferredAxiomGenerator<? extends OWLAxiom>>();
axiomGenerators.add( new InferredPropertyAssertionGenerator() );
InferredOntologyGenerator iog = new InferredOntologyGenerator(reasoner,axiomGenerators);
iog.fillOntology(manager, inferredOntology);
// Save the new ontology
OutputStream owlOutputStream = new ByteArrayOutputStream();
manager.saveOntology(inferredOntology, owlOutputStream);
inferredData = owlOutputStream.toString();
}
catch ( Exception e ) {
throw new Exception("Exception occurred in applying reasoner");
}
Hope this is helpful to you.
I have a owl ontology, I read it into Jena OntModel. then I update it at runtime. Now I want to write it back as a OWL ontology. I am using the code below:
RDFWriter writer = model.getWriter("RDF/XML");
writer.write(model, out, root_uri);
... gives me RDF syntax and not the OWL syntax. How can I write the OntModel into OWL syntax?
Any solution?
Welcome to StackOverflow! Jena doesn't support the OWL/XML syntax. It only support various RDF syntaxes, including RDF/XML and Turtle. See here for Jena's supported formats.
So you either need to work with one of these syntaxes (which can express all of OWL just fine).
Or switch to a different library that supports OWL/XML, like the OWL API.
Of course, if you are using getWriter("RDF/XML"), it will be written in RDF/XML, which is one serialisation format for RDF and all RDF formats are serialisation syntaxes for OWL.
There is very few cases when one needs to use a non-RDF syntax when writing OWL programmatically but if you want to do so, try using the OWL API, which can write OWL in OWL/XML, in OWL 2 Manchester syntax, or in OWL 2 functional syntax.