Posted by
d.onto on
URL: http://owlready.306.s1.nabble.com/adding-a-swrl-rule-through-owlready2-tp3346.html
Hi all
These days I read the complete owlready2 documentation
My goal was to add a swrl rule to an existing ontology.
First, I created an ontology in ttl, added the rule through protégé, save it as rdfxml, then run the owlready2 reasonner and it worked correctly
Here's the ontology, it's about machines that have packages that may have CVE (vulnerabilities)
I want the reasonner to infer that if a machine has a package that has a CVE then the machine contains the CVE
(I know that we can do it without reasonning with owl:propertyChainAxiom, but it's a simple example for my first swrl rule.)
@prefix : <http://maccve/onto#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
:Machine a owl:Class .
:CVE a owl:Class .
:Package a owl:Class .
# Machine contains Package
:contains a owl:ObjectProperty ;
rdfs:domain :Machine ;
rdfs:range :Package .
# Package has_CVE CVE
:has_CVE a owl:ObjectProperty ;
rdfs:domain :Package ;
rdfs:range :CVE .
# Cette property est determinée par swrl
:contains_CVE a owl:ObjectProperty ;
rdfs:domain :Machine ;
rdfs:range :CVE .
:www1 a owl:NamedIndividual, :Machine .
:www2 a owl:NamedIndividual, :Machine .
:apache12 a owl:NamedIndividual, :Package .
:apache22 a owl:NamedIndividual, :Package .
:CVE1212 a owl:NamedIndividual, :CVE .
:www1 :contains :apache12 .
:www2 :contains :apache22 .
:apache22 :has_CVE :CVE1212 .
When the reasonner is doing its job, it must answer that machine
:www2 :contains_CVE :CVE1212
Then I wanted to do the same in python, just adding the rule to a existing file
I fully understood that owlready2 is reading rdfxml, so i convert my ttl before using it
I wrote this python (addrule.py) example : open, add, save
import argparse
import pprint
import sys
import owlready2 as owl
from rdflib import Graph
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--ontology", help="ontology file", required=True)
parser.add_argument( "--destination", help="destination ontology file", required=True)
args = parser.parse_args()
input_file = args.ontology
output_file = args.destination
onto = owl.get_ontology(input_file).load()
with onto:
print("\n\n")
print(list(onto.classes()))
onto.set_base_iri("http://maccve/onto#")
print("\n\n")
print(list(onto.classes()))
print("\n\n")
print(list(onto.individuals()))
print("\n\n")
class Machine(owl.Thing):
pass
class Package(owl.Thing):
pass
class CVE(owl.Thing):
pass
class contains(owl.ObjectProperty):
domain = [Machine]
range = [Package]
class has_CVE(owl.ObjectProperty):
domain = [Package]
range = [CVE]
class contains_CVE(owl.ObjectProperty):
domain = [Machine]
range = [CVE]
print(Machine.iri)
swrl_rule = """ Machine(?m) ^ Package(?p) ^ CVE(?c) ^ contains(?m, ?p) ^ has_CVE(?p, ?c) -> contains_CVE(?m, ?c) """
rule = owl.Imp()
rule.set_as_rule(swrl_rule)
onto.save(file = output_file, format = "rdfxml")
if __name__ == "__main__":
main()
But when running the reasonner on the output file, the inference is not done.
I compared onto-x1.xml (protégé generated) and onto-y1.xml (addrule.py generated) and seems very similar but onto-y1.xml is not working.
If someone could explain what I'm doing wrong I would be pleased
Thanks in advance