I try to create some semantic rules and want to save them using owlready2 for python. I want to reason over timerange related errors, so i created a error class and a timerangeWithError class. Now i want to check if the incoming error is a TimeRangeRelatedError, so i try to use the equivalent_to-method to set up some rule, that the hermit reasoner can distinguish between an Error and a TimeRelatedError. Nevertheless, the compiler raise the an error saying i can't store a function:
File "C:\Users\-name-\AppData\Local\Programs\Python\Python36\lib\site-packages\owlready2\base.py", line 49, in to_literal
if datatype is None: raise ValueError("Cannot store literal '%s' of type '%s'!" % (o, type(o))) ValueError: Cannot store literal '<function TimeRangeWithError.is_in_timerange at 0x000002797417B6A8>' of type '<class 'function'>'!
I don't know any other way to check if the timespan is in a specific range. I think i modelled something wrong within my ontology description. Could you help me to build an ontology that is capable of checking if the value is inbetween dates?
from owlready2 import *
onto = get_ontology("http://test.org/rules.owl")
with onto:
class Error(Thing):
pass
class appeared_at(Error >> datetime.datetime): pass
class TimeRangeWithError(Thing):
def is_in_timerange(self):
return self.timerange_start_at <= self.error_at and self.timerange_end_at >= self.error_at
class timerange_start_at(TimeRangeWithError >> datetime.datetime): pass
class timerange_end_at(TimeRangeWithError >> datetime.datetime): pass
class error_at(TimeRangeWithError >> datetime.datetime): pass
class TimeRangeRelatedError(Error):
equivalent_to = [Error & TimeRangeWithError.is_in_timerange]
onto.save()
Edit:// After AWSK comment i tried to set error_at with a constraintedDatatype (should be throw an exception after reasoning if the datetime is out of bounds and in the end i have a method to check if a date is in range), but it also fails with an error:
from owlready2 import *
onto = get_ontology("http://test.org/onto")
with onto:
class Error(Thing):pass
class appeared_at(Error >> datetime.datetime): pass
class TimeRangeWithError(Thing):pass
class timerange_start_at(TimeRangeWithError >> datetime.datetime, FunctionalProperty): pass
class timerange_end_at(TimeRangeWithError >> datetime.datetime, FunctionalProperty): pass
class error_at(TimeRangeWithError >> ConstrainedDatatype(int, min_inclusive = timerange_start_at, max_inclusive = timerange_end_at), FunctionalProperty): pass
class is_during_timerange(TimeRangeWithError >> bool, FunctionalProperty) : pass
class TimeRangeRelatedError(Error):
equivalent_to = [Error & is_during_timerange]
rule = Imp()
rule.set_as_rule("""TimeRangeWithError(?d), timerange_start_at(?d, ?s), timerange_end_at(?d, ?e), error_at(?d, ?b), lessThanOrEqual(?b, ?s, ?r1), greaterThanOrEqual(?b, ?e, ?r2), equal(?r1, ?r2, ?r4) -> is_during_timerange(?d, ?r4)""")
error = Error()
timeRange = TimeRangeWithError()
timeRange.shift_start_at = datetime.datetime.now()
timeRange.shift_end_at = datetime.datetime.now()
timeRange.error_at = datetime.datetime.now()
onto.save()
Error message:
File "C:\Users\----\AppData\Local\Programs\Python\Python36\lib\site-packages\owlready2\triplelite.py", line 1180, in _set_data_triple_raw_spod
self.execute("INSERT INTO datas VALUES (?, ?, ?, ?, ?)", (self.c, s, p, o, d))
sqlite3.InterfaceError: Error binding parameter 3 - probably unsupported type.
After some work i got the following, but reasoning within pellet failed:
from datetime import timedelta
from owlready2 import *
onto = get_ontology("http://test.org/onto.owl")
with onto:
class Error(Thing):pass
class timerange_start_at(Error >> datetime.datetime, FunctionalProperty):
python_name = "start"
class timerange_end_at(Error >> datetime.datetime, FunctionalProperty):
python_name = "end"
class error_at(Error >> datetime.datetime, FunctionalProperty):
python_name = "appeared"
class is_after_start(Error >> bool, FunctionalProperty) : pass
class is_before_end(Error >> bool, FunctionalProperty): pass
class TimeRangeRelatedError(Error):
equivalent_to = [Error & is_after_start & is_before_end]
rule1 = Imp()
rule1.set_as_rule("""Error(?d), timerange_start_at(?d, ?s), error_at(?d, ?b), greaterThan(?s, ?b) -> is_after_start(?d)""")
rule2 = Imp()
rule2.set_as_rule("""Error(?d), timerange_end_at(?d, ?e), error_at(?d, ?b), lessThan(?e, ?b) -> is_before_end(?d)""")
current = datetime.datetime.now()
start = current - timedelta(days=1)
end = current + timedelta(days=1)
error = Error(start = start, end = end, appeared = current)
close_world(Error)
print("Error old Classes:", error.__class__)
onto.save(file="C:/Users/---/PycharmProjects/owlreasoner/rules.owl")
sync_reasoner_pellet(infer_property_values = True, infer_data_property_values = True)
print("Error new Classes:", error.__class__)
With the following Pellet Exception, i think pellet cannot find ?d Variable (which is i thought the instance for the one error i defined upfront):
File "C:/Users/---/PycharmProjects/owlreasoner/__main__.py", line 41, in <module>
sync_reasoner_pellet(infer_property_values = True, infer_data_property_values = True)
File "C:\Users\---\AppData\Local\Programs\Python\Python36\lib\site-packages\owlready2\reasoning.py", line 244, in sync_reasoner_pellet
raise OwlReadyJavaError("Java error message is:\n%s" % (e.stderr or b"").decode("utf8"))
owlready2.base.OwlReadyJavaError: Java error message is:
[main] WARN org.apache.jena.riot.RDFLanguages - java-jsonld classes not on the classpath - JSON-LD input-output not available.
[main] WARN org.apache.jena.riot.RDFLanguages - Minimum jarfiles are jsonld-java, jackson-core, jackson-annotations
[main] WARN org.apache.jena.riot.RDFLanguages - If using a Jena distribution, put all jars in the lib/ directory on the classpath
[main] WARN org.semanticweb.owlapi.util.SAXParsers - http://www.oracle.com/xml/jaxp/properties/entityExpansionLimit not supported by parser type org.apache.xerces.jaxp.SAXParserImpl
[main] WARN org.semanticweb.owlapi.util.SAXParsers - entityExpansionLimit not supported by parser type org.apache.xerces.jaxp.SAXParserImpl
[main] WARN org.semanticweb.owlapi.util.SAXParsers - http://www.oracle.com/xml/jaxp/properties/entityExpansionLimit not supported by parser type org.apache.xerces.jaxp.SAXParserImpl
[main] WARN org.semanticweb.owlapi.util.SAXParsers - entityExpansionLimit not supported by parser type org.apache.xerces.jaxp.SAXParserImpl
Could not translate SWRL Atom D-Object
Use -v for detail.
Here is my generated OWL File, maybe something gets generated in a wrong way (i am just a beginner in this domain, sorry in advanced):
<?xml version="1.0"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xml:base="http://test.org/onto.owl"
xmlns="http://test.org/onto.owl#"
xmlns:swrl="http://www.w3.org/2003/11/swrl#"
xmlns:owlr="http://www.lesfleursdunormal.fr/static/_downloads/owlready_ontology.owl#">
<owl:Ontology rdf:about="http://test.org/onto.owl"/>
<owl:Class rdf:about="#Error">
<rdfs:subClassOf rdf:resource="http://www.w3.org/2002/07/owl#Thing"/>
<rdfs:subClassOf>
<owl:Class>
<owl:oneOf>
<rdf:Description>
<rdf:first rdf:resource="#error1"/>
<rdf:rest rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"/>
</rdf:Description>
</owl:oneOf>
</owl:Class>
</rdfs:subClassOf>
</owl:Class>
<owl:DatatypeProperty rdf:about="#timerange_start_at">
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#FunctionalProperty"/>
<rdfs:domain rdf:resource="#Error"/>
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#dateTime"/>
<owlr:python_name rdf:datatype="http://www.w3.org/2001/XMLSchema#string">start</owlr:python_name>
</owl:DatatypeProperty>
<owl:DatatypeProperty rdf:about="#timerange_end_at">
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#FunctionalProperty"/>
<rdfs:domain rdf:resource="#Error"/>
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#dateTime"/>
<owlr:python_name rdf:datatype="http://www.w3.org/2001/XMLSchema#string">end</owlr:python_name>
</owl:DatatypeProperty>
<owl:DatatypeProperty rdf:about="#error_at">
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#FunctionalProperty"/>
<rdfs:domain rdf:resource="#Error"/>
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#dateTime"/>
<owlr:python_name rdf:datatype="http://www.w3.org/2001/XMLSchema#string">appeared</owlr:python_name>
</owl:DatatypeProperty>
<owl:DatatypeProperty rdf:about="#is_after_start">
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#FunctionalProperty"/>
<rdfs:domain rdf:resource="#Error"/>
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#boolean"/>
</owl:DatatypeProperty>
<owl:DatatypeProperty rdf:about="#is_before_end">
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#FunctionalProperty"/>
<rdfs:domain rdf:resource="#Error"/>
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#boolean"/>
</owl:DatatypeProperty>
<owl:Class rdf:about="#TimeRangeRelatedError">
<rdfs:subClassOf rdf:resource="#Error"/>
<owl:equivalentClass>
<owl:Class>
<owl:intersectionOf rdf:parseType="Collection">
<rdf:Description rdf:about="#Error"/>
<rdf:Description rdf:about="#is_after_start"/>
<rdf:Description rdf:about="#is_before_end"/>
</owl:intersectionOf>
</owl:Class>
</owl:equivalentClass>
</owl:Class>
<swrl:Variable rdf:about="urn:swrl#d"/>
<swrl:Variable rdf:about="urn:swrl#s"/>
<swrl:Variable rdf:about="urn:swrl#b"/>
<swrl:Variable rdf:about="urn:swrl#e"/>
<Error rdf:about="#error1">
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#NamedIndividual"/>
<timerange_start_at rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2019-07-25T12:44:10.526106</timerange_start_at>
<timerange_end_at rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2019-07-27T12:44:10.526106</timerange_end_at>
<error_at rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2019-07-26T12:44:10.526106</error_at>
</Error>
<swrl:Imp>
<swrl:body>
<rdf:Description>
<rdf:first>
<swrl:ClassAtom>
<swrl:classPredicate rdf:resource="#Error"/>
<swrl:argument1 rdf:resource="urn:swrl#d"/>
</swrl:ClassAtom>
</rdf:first>
<rdf:rest>
<rdf:Description>
<rdf:first>
<swrl:DatavaluedPropertyAtom>
<swrl:propertyPredicate rdf:resource="#timerange_end_at"/>
<swrl:argument1 rdf:resource="urn:swrl#d"/>
<swrl:argument2 rdf:resource="urn:swrl#e"/>
</swrl:DatavaluedPropertyAtom>
</rdf:first>
<rdf:rest>
<rdf:Description>
<rdf:first>
<swrl:DatavaluedPropertyAtom>
<swrl:propertyPredicate rdf:resource="#error_at"/>
<swrl:argument1 rdf:resource="urn:swrl#d"/>
<swrl:argument2 rdf:resource="urn:swrl#b"/>
</swrl:DatavaluedPropertyAtom>
</rdf:first>
<rdf:rest>
<rdf:Description>
<rdf:first>
<swrl:BuiltinAtom>
<swrl:builtin rdf:resource="http://www.w3.org/2003/11/swrlb#lessThan"/>
<swrl:arguments>
<rdf:Description>
<rdf:first rdf:resource="urn:swrl#e"/>
<rdf:rest>
<rdf:Description>
<rdf:first rdf:resource="urn:swrl#b"/>
<rdf:rest rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"/>
</rdf:Description>
</rdf:rest>
</rdf:Description>
</swrl:arguments>
</swrl:BuiltinAtom>
</rdf:first>
<rdf:rest rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"/>
</rdf:Description>
</rdf:rest>
</rdf:Description>
</rdf:rest>
</rdf:Description>
</rdf:rest>
</rdf:Description>
</swrl:body>
<swrl:head>
<rdf:Description>
<rdf:first>
<swrl:DatavaluedPropertyAtom>
<swrl:propertyPredicate rdf:resource="#is_before_end"/>
<swrl:argument1 rdf:resource="urn:swrl#d"/>
</swrl:DatavaluedPropertyAtom>
</rdf:first>
<rdf:rest rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"/>
</rdf:Description>
</swrl:head>
</swrl:Imp>
<swrl:Imp>
<swrl:body>
<rdf:Description>
<rdf:first>
<swrl:ClassAtom>
<swrl:classPredicate rdf:resource="#Error"/>
<swrl:argument1 rdf:resource="urn:swrl#d"/>
</swrl:ClassAtom>
</rdf:first>
<rdf:rest>
<rdf:Description>
<rdf:first>
<swrl:DatavaluedPropertyAtom>
<swrl:propertyPredicate rdf:resource="#timerange_start_at"/>
<swrl:argument1 rdf:resource="urn:swrl#d"/>
<swrl:argument2 rdf:resource="urn:swrl#s"/>
</swrl:DatavaluedPropertyAtom>
</rdf:first>
<rdf:rest>
<rdf:Description>
<rdf:first>
<swrl:DatavaluedPropertyAtom>
<swrl:propertyPredicate rdf:resource="#error_at"/>
<swrl:argument1 rdf:resource="urn:swrl#d"/>
<swrl:argument2 rdf:resource="urn:swrl#b"/>
</swrl:DatavaluedPropertyAtom>
</rdf:first>
<rdf:rest>
<rdf:Description>
<rdf:first>
<swrl:BuiltinAtom>
<swrl:builtin rdf:resource="http://www.w3.org/2003/11/swrlb#greaterThan"/>
<swrl:arguments>
<rdf:Description>
<rdf:first rdf:resource="urn:swrl#s"/>
<rdf:rest>
<rdf:Description>
<rdf:first rdf:resource="urn:swrl#b"/>
<rdf:rest rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"/>
</rdf:Description>
</rdf:rest>
</rdf:Description>
</swrl:arguments>
</swrl:BuiltinAtom>
</rdf:first>
<rdf:rest rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"/>
</rdf:Description>
</rdf:rest>
</rdf:Description>
</rdf:rest>
</rdf:Description>
</rdf:rest>
</rdf:Description>
</swrl:body>
<swrl:head>
<rdf:Description>
<rdf:first>
<swrl:DatavaluedPropertyAtom>
<swrl:propertyPredicate rdf:resource="#is_after_start"/>
<swrl:argument1 rdf:resource="urn:swrl#d"/>
</swrl:DatavaluedPropertyAtom>
</rdf:first>
<rdf:rest rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"/>
</rdf:Description>
</swrl:head>
</swrl:Imp>
</rdf:RDF>
Edit3:// Idk how to return the return value of lessThan, so i presume that the rule will only fire if lessEqual is true. Here is my new Code:
from datetime import timedelta
from owlready2 import *
onto = get_ontology("http://test.org/onto.owl")
with onto:
class Error(Thing):
def who(self):
print("Error")
class timerange_start_at(Error >> datetime.datetime, FunctionalProperty):
python_name = "start"
class timerange_end_at(Error >> datetime.datetime, FunctionalProperty):
python_name = "end"
class error_at(Error >> datetime.datetime, FunctionalProperty):
python_name = "appeared"
class is_after_start(Error >> bool, FunctionalProperty) : pass
class is_before_end(Error >> bool, FunctionalProperty): pass
class TimeRangeRelatedError(Error):
equivalent_to = [Error & is_after_start.value(True) & is_before_end.value(True)]
def who(self):
print("TimeRange")
rule1 = Imp()
rule1.set_as_rule("""Error(?d), timerange_start_at(?d, ?s), error_at(?d, ?b), greaterThan(?s, ?b) -> is_after_start(?d, true)""")
rule2 = Imp()
rule2.set_as_rule("""Error(?d), timerange_end_at(?d, ?e), error_at(?d, ?b), lessThan(?e, ?b) -> is_before_end(?d, true)""")
current = datetime.datetime.now()
start = current - timedelta(days=1)
end = current + timedelta(days=1)
error = Error(start = start, end = end, appeared = current)
close_world(Error)
error.who()
onto.save(file="C:/Users/---/PycharmProjects/owlreasoner/rules.owl")
sync_reasoner_pellet(infer_property_values = True, infer_data_property_values = True)
time.sleep(5)
onto.save(file="C:/Users/---/PycharmProjects/owlreasoner/rules2.owl")
error.who()
And here is my new rdf file:
<?xml version="1.0"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xml:base="http://test.org/onto.owl"
xmlns="http://test.org/onto.owl#"
xmlns:swrl="http://www.w3.org/2003/11/swrl#"
xmlns:owlr="http://www.lesfleursdunormal.fr/static/_downloads/owlready_ontology.owl#">
<owl:Ontology rdf:about="http://test.org/onto.owl"/>
<owl:Class rdf:about="#Error">
<rdfs:subClassOf rdf:resource="http://www.w3.org/2002/07/owl#Thing"/>
<rdfs:subClassOf>
<owl:Class>
<owl:oneOf>
<rdf:Description>
<rdf:first rdf:resource="#error1"/>
<rdf:rest rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"/>
</rdf:Description>
</owl:oneOf>
</owl:Class>
</rdfs:subClassOf>
</owl:Class>
<owl:DatatypeProperty rdf:about="#timerange_start_at">
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#FunctionalProperty"/>
<rdfs:domain rdf:resource="#Error"/>
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#dateTime"/>
<owlr:python_name rdf:datatype="http://www.w3.org/2001/XMLSchema#string">start</owlr:python_name>
</owl:DatatypeProperty>
<owl:DatatypeProperty rdf:about="#timerange_end_at">
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#FunctionalProperty"/>
<rdfs:domain rdf:resource="#Error"/>
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#dateTime"/>
<owlr:python_name rdf:datatype="http://www.w3.org/2001/XMLSchema#string">end</owlr:python_name>
</owl:DatatypeProperty>
<owl:DatatypeProperty rdf:about="#error_at">
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#FunctionalProperty"/>
<rdfs:domain rdf:resource="#Error"/>
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#dateTime"/>
<owlr:python_name rdf:datatype="http://www.w3.org/2001/XMLSchema#string">appeared</owlr:python_name>
</owl:DatatypeProperty>
<owl:DatatypeProperty rdf:about="#is_after_start">
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#FunctionalProperty"/>
<rdfs:domain rdf:resource="#Error"/>
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#boolean"/>
</owl:DatatypeProperty>
<owl:DatatypeProperty rdf:about="#is_before_end">
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#FunctionalProperty"/>
<rdfs:domain rdf:resource="#Error"/>
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#boolean"/>
</owl:DatatypeProperty>
<owl:Class rdf:about="#TimeRangeRelatedError">
<rdfs:subClassOf rdf:resource="#Error"/>
<owl:equivalentClass>
<owl:Class>
<owl:intersectionOf rdf:parseType="Collection">
<rdf:Description rdf:about="#Error"/>
<owl:Restriction>
<owl:onProperty rdf:resource="#is_after_start"/>
<owl:hasValue rdf:datatype="http://www.w3.org/2001/XMLSchema#boolean">true</owl:hasValue>
</owl:Restriction>
<owl:Restriction>
<owl:onProperty rdf:resource="#is_before_end"/>
<owl:hasValue rdf:datatype="http://www.w3.org/2001/XMLSchema#boolean">true</owl:hasValue>
</owl:Restriction>
</owl:intersectionOf>
</owl:Class>
</owl:equivalentClass>
</owl:Class>
<swrl:Variable rdf:about="urn:swrl#d"/>
<swrl:Variable rdf:about="urn:swrl#s"/>
<swrl:Variable rdf:about="urn:swrl#b"/>
<swrl:Variable rdf:about="urn:swrl#e"/>
<Error rdf:about="#error1">
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#NamedIndividual"/>
<timerange_start_at rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2019-07-25T14:23:29.941201</timerange_start_at>
<timerange_end_at rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2019-07-27T14:23:29.941201</timerange_end_at>
<error_at rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2019-07-26T14:23:29.941201</error_at>
</Error>
<swrl:Imp>
<swrl:body>
<rdf:Description>
<rdf:first>
<swrl:ClassAtom>
<swrl:classPredicate rdf:resource="#Error"/>
<swrl:argument1 rdf:resource="urn:swrl#d"/>
</swrl:ClassAtom>
</rdf:first>
<rdf:rest>
<rdf:Description>
<rdf:first>
<swrl:DatavaluedPropertyAtom>
<swrl:propertyPredicate rdf:resource="#timerange_end_at"/>
<swrl:argument1 rdf:resource="urn:swrl#d"/>
<swrl:argument2 rdf:resource="urn:swrl#e"/>
</swrl:DatavaluedPropertyAtom>
</rdf:first>
<rdf:rest>
<rdf:Description>
<rdf:first>
<swrl:DatavaluedPropertyAtom>
<swrl:propertyPredicate rdf:resource="#error_at"/>
<swrl:argument1 rdf:resource="urn:swrl#d"/>
<swrl:argument2 rdf:resource="urn:swrl#b"/>
</swrl:DatavaluedPropertyAtom>
</rdf:first>
<rdf:rest>
<rdf:Description>
<rdf:first>
<swrl:BuiltinAtom>
<swrl:builtin rdf:resource="http://www.w3.org/2003/11/swrlb#lessThan"/>
<swrl:arguments>
<rdf:Description>
<rdf:first rdf:resource="urn:swrl#e"/>
<rdf:rest>
<rdf:Description>
<rdf:first rdf:resource="urn:swrl#b"/>
<rdf:rest rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"/>
</rdf:Description>
</rdf:rest>
</rdf:Description>
</swrl:arguments>
</swrl:BuiltinAtom>
</rdf:first>
<rdf:rest rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"/>
</rdf:Description>
</rdf:rest>
</rdf:Description>
</rdf:rest>
</rdf:Description>
</rdf:rest>
</rdf:Description>
</swrl:body>
<swrl:head>
<rdf:Description>
<rdf:first>
<swrl:DatavaluedPropertyAtom>
<swrl:propertyPredicate rdf:resource="#is_before_end"/>
<swrl:argument1 rdf:resource="urn:swrl#d"/>
<swrl:argument2 rdf:datatype="http://www.w3.org/2001/XMLSchema#boolean">true</swrl:argument2>
</swrl:DatavaluedPropertyAtom>
</rdf:first>
<rdf:rest rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"/>
</rdf:Description>
</swrl:head>
</swrl:Imp>
<swrl:Imp>
<swrl:body>
<rdf:Description>
<rdf:first>
<swrl:ClassAtom>
<swrl:classPredicate rdf:resource="#Error"/>
<swrl:argument1 rdf:resource="urn:swrl#d"/>
</swrl:ClassAtom>
</rdf:first>
<rdf:rest>
<rdf:Description>
<rdf:first>
<swrl:DatavaluedPropertyAtom>
<swrl:propertyPredicate rdf:resource="#timerange_start_at"/>
<swrl:argument1 rdf:resource="urn:swrl#d"/>
<swrl:argument2 rdf:resource="urn:swrl#s"/>
</swrl:DatavaluedPropertyAtom>
</rdf:first>
<rdf:rest>
<rdf:Description>
<rdf:first>
<swrl:DatavaluedPropertyAtom>
<swrl:propertyPredicate rdf:resource="#error_at"/>
<swrl:argument1 rdf:resource="urn:swrl#d"/>
<swrl:argument2 rdf:resource="urn:swrl#b"/>
</swrl:DatavaluedPropertyAtom>
</rdf:first>
<rdf:rest>
<rdf:Description>
<rdf:first>
<swrl:BuiltinAtom>
<swrl:builtin rdf:resource="http://www.w3.org/2003/11/swrlb#greaterThan"/>
<swrl:arguments>
<rdf:Description>
<rdf:first rdf:resource="urn:swrl#s"/>
<rdf:rest>
<rdf:Description>
<rdf:first rdf:resource="urn:swrl#b"/>
<rdf:rest rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"/>
</rdf:Description>
</rdf:rest>
</rdf:Description>
</swrl:arguments>
</swrl:BuiltinAtom>
</rdf:first>
<rdf:rest rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"/>
</rdf:Description>
</rdf:rest>
</rdf:Description>
</rdf:rest>
</rdf:Description>
</rdf:rest>
</rdf:Description>
</swrl:body>
<swrl:head>
<rdf:Description>
<rdf:first>
<swrl:DatavaluedPropertyAtom>
<swrl:propertyPredicate rdf:resource="#is_after_start"/>
<swrl:argument1 rdf:resource="urn:swrl#d"/>
<swrl:argument2 rdf:datatype="http://www.w3.org/2001/XMLSchema#boolean">true</swrl:argument2>
</swrl:DatavaluedPropertyAtom>
</rdf:first>
<rdf:rest rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"/>
</rdf:Description>
</swrl:head>
</swrl:Imp>
</rdf:RDF>
I got it working finally! Thank you so much @AKSW! My assumption that the rule will only be called if lessThan or greaterThan is true, was correct. Finally you have to return a boolean, which you don't have to Flag with ^^xsd:boolean, just return true, the library do the Rest for us. And thanks for the Hint with the classes, you have to use .value(True) to compare it with the returned true (notice case-insentivity). But the python True will be mapped onto "true"^^xsd:boolean. Here is my final code, thanks again AKSW!:
from datetime import timedelta
from owlready2 import *
onto = get_ontology("http://test.org/onto.owl")
with onto:
class Error(Thing):
def who(self):
print("Error")
class timerange_start_at(Error >> datetime.datetime, FunctionalProperty):
python_name = "start"
class timerange_end_at(Error >> datetime.datetime, FunctionalProperty):
python_name = "end"
class error_at(Error >> datetime.datetime, FunctionalProperty):
python_name = "appeared"
class is_after_start(Error >> bool, FunctionalProperty) : pass
class is_before_end(Error >> bool, FunctionalProperty): pass
class TimeRangeRelatedError(Error):
equivalent_to = [Error & is_after_start.value(True) & is_before_end.value(True)]
def who(self):
print("TimeRange")
rule1 = Imp()
rule1.set_as_rule("""Error(?d), timerange_start_at(?d, ?s), error_at(?d, ?b), greaterThan(?b, ?s) -> is_after_start(?d, true)""")
rule2 = Imp()
rule2.set_as_rule("""Error(?d), timerange_end_at(?d, ?e), error_at(?d, ?b), lessThan(?b, ?e) -> is_before_end(?d, true)""")
current = datetime.datetime.now()
start = current - timedelta(days=1)
end = current + timedelta(days=1)
error = Error(start = start, end = end, appeared = current)
close_world(Error)
error.who()
onto.save(file="C:/Users/---/PycharmProjects/owlreasoner/rules.owl")
sync_reasoner_pellet(infer_property_values = True, infer_data_property_values = True)
onto.save(file="C:/Users/---/PycharmProjects/owlreasoner/rules2.owl")
error.who()
Output is:
* Owlready2 * Warning: optimized Cython parser module 'owlready2_optimized' is not available, defaulting to slower Python implementation
Error
* Owlready2 * Running Pellet...
........
* Owlready2 * Pellet took 3.5119872093200684 seconds
* Owlready * Equivalenting: onto.Error onto.TimeRangeRelatedError
* Owlready * Equivalenting: onto.TimeRangeRelatedError onto.Error
* Owlready * Reparenting onto.error1: {onto.Error} => {onto.TimeRangeRelatedError}
* Owlready * Adding relation onto.error1 is_after_start true
* Owlready * Adding relation onto.error1 is_before_end true
TimeRange
* Owlready * (NB: only changes on entities loaded in Python are shown, other changes are done but not listed)