Python Owlready2 Ontology Creation and Reasoning, Cannot save function error, while saving equivalent_to
Python Owlready2 Ontology Creation and Reasoning, Cannot save function error, while saving equivalent_to
我尝试创建一些语义规则并想使用 owlready2 为 python 保存它们。我想推理与时间范围相关的错误,所以我创建了一个错误 class 和一个 timerangeWithError class。现在我想检查传入的错误是否是 TimeRangeRelatedError,所以我尝试使用 equivalent_to-method 设置一些规则,隐士推理器可以区分错误和 TimeRelatedError。尽管如此,编译器还是报错说我无法存储函数:
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'>'!
我不知道还有什么其他方法可以检查时间跨度是否在特定范围内。我想我在 ontology 描述中建模有误。你能帮我构建一个 ontology 能够检查值是否在日期之间吗?
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()
编辑://
在 AWSK 评论之后,我尝试使用 constraintedDatatype 设置 error_at (如果日期时间超出范围,应该在推理后抛出异常,最后我有一个方法来检查日期是否在范围内),但是它也失败并出现错误:
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()
错误信息:
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.
经过一些工作后,我得到了以下结果,但 pellet 内的推理失败了:
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__)
对于以下 Pellet 异常,我认为 pellet 找不到 ?d 变量(我认为这是我预先定义的一个错误的实例):
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.
这是我生成的 OWL 文件,可能生成的方式有误(我只是这个领域的初学者,抱歉,进阶):
<?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>
编辑3://
我不知道如何 return lessThan 的 return 值,所以我假设只有 lessEqual 为真时才会触发该规则。这是我的新代码:
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()
这是我的新 rdf 文件:
<?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>
我终于成功了!非常感谢@AKSW!我假设只有 lessThan 或 greaterThan 为真时才会调用该规则,这是正确的。最后,您必须 return 一个布尔值,您不必使用 ^^xsd:boolean 标记它,只需 return true,库会为我们完成剩下的工作。感谢 类 的提示,您必须使用 .value(True) 将其与 returned true 进行比较(注意不区分大小写)。但是 python True 将映射到 "true"^^xsd:boolean。
这是我的最终代码,再次感谢 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()
输出为:
* 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)
我尝试创建一些语义规则并想使用 owlready2 为 python 保存它们。我想推理与时间范围相关的错误,所以我创建了一个错误 class 和一个 timerangeWithError class。现在我想检查传入的错误是否是 TimeRangeRelatedError,所以我尝试使用 equivalent_to-method 设置一些规则,隐士推理器可以区分错误和 TimeRelatedError。尽管如此,编译器还是报错说我无法存储函数:
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'>'!
我不知道还有什么其他方法可以检查时间跨度是否在特定范围内。我想我在 ontology 描述中建模有误。你能帮我构建一个 ontology 能够检查值是否在日期之间吗?
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()
编辑:// 在 AWSK 评论之后,我尝试使用 constraintedDatatype 设置 error_at (如果日期时间超出范围,应该在推理后抛出异常,最后我有一个方法来检查日期是否在范围内),但是它也失败并出现错误:
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()
错误信息:
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.
经过一些工作后,我得到了以下结果,但 pellet 内的推理失败了:
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__)
对于以下 Pellet 异常,我认为 pellet 找不到 ?d 变量(我认为这是我预先定义的一个错误的实例):
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.
这是我生成的 OWL 文件,可能生成的方式有误(我只是这个领域的初学者,抱歉,进阶):
<?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>
编辑3:// 我不知道如何 return lessThan 的 return 值,所以我假设只有 lessEqual 为真时才会触发该规则。这是我的新代码:
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()
这是我的新 rdf 文件:
<?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>
我终于成功了!非常感谢@AKSW!我假设只有 lessThan 或 greaterThan 为真时才会调用该规则,这是正确的。最后,您必须 return 一个布尔值,您不必使用 ^^xsd:boolean 标记它,只需 return true,库会为我们完成剩下的工作。感谢 类 的提示,您必须使用 .value(True) 将其与 returned true 进行比较(注意不区分大小写)。但是 python True 将映射到 "true"^^xsd:boolean。 这是我的最终代码,再次感谢 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()
输出为:
* 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)