adding a swrl rule through owlready2

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