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)