首页 > 解决方案 > 在 OWLready2 中创建实例会创建一个全新的类,而不是将其分配给现有的类

问题描述

我正在尝试按照官方网站上的教程创建一个简单的本体。代码运行顺利,运行此代码时一切似乎都很好:

import owlready2
owlready2.JAVA_EXE = r"my-path-to-java-exe"          

# new.owl is a non-existing file and therefore onto has no pre-defined classes
# if you know of any nicer way to define an ontology, I'd appreciate it

onto = get_ontology("new.owl")

with onto:
    class Drug(Thing): pass
    class number_of_tablets(Drug >> int, FunctionalProperty): pass          # Creating some properties
    class price(Drug >> float, FunctionalProperty): pass
    class price_per_tablet(Drug >> float, FunctionalProperty): pass

    rule = Imp()

    # Rule: "Drug instance ?d     AND     price of ?d is ?p     AND     drug ?d has number_of_tablets = ?n
    #        AND     ?r = ?p/?n     ->      Drug ?d has price_per_tablet = ?r"
    
    rule.set_as_rule("""Drug(?d), price(?d,?p), number_of_tablets(?d,?n), divide(?r, ?p, ?n) -> price_per_tablet(?d, ?r)""")

    # Create an instance "drug" with properties defined in brackets
    drug = Drug(number_of_tablets = 10, price = 25.0)
    #print(drug.iri)

    # Syncing the reasoner infers new info
    sync_reasoner_pellet(infer_property_values = True, infer_data_property_values = True)

    # New property price_per_tablet is now added to drug and we can use it normally:
    print(drug.price_per_tablet)

# Save this ontology with rules in the same folder, filename: test
onto.save(file = "test", format = "rdfxml")

问题:当我在 Protégé 中打开生成的文件“test”时,我的实例“drug1”不是先前定义的类 Drug 的一部分,而是一个同名的新类Drug(我总是用斜体表示这个,所以它不会让人感到困惑)。有趣的是,这个新类Drug甚至不是 owl:Thing 类的子类。

我不确定有什么问题。根据 Protégé 的说法,定义的类 Drug 具有 IRI: file:/C:/.../new#Drug,而另一个类Drug具有 IRI: new#Drug

当我检查 Python 中所有描述对象的 IRI 时,它们都是同步的。

我对这里发生的事情感到非常困惑。

我检查了“测试”文件,关于这个实例的部分是:

<Drug rdf:about="#drug1">
  <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#NamedIndividual"/>
  <number_of_tablets rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">10</number_of_tablets>
  <price rdf:datatype="http://www.w3.org/2001/XMLSchema#decimal">25.0</price>
  <price_per_tablet rdf:datatype="http://www.w3.org/2001/XMLSchema#decimal">2.5</price_per_tablet>
</Drug>

这很令人困惑,因为当我从著名的 Pizza 教程中打开文件 PizzaTutorial.owl 时,一个实例定义如下:

<owl:NamedIndividual rdf:about="http://www.semanticweb.org/pizzatutorial/ontologies/2020/PizzaTutorial#AmericanaHotPizza2">
        <rdf:type rdf:resource="http://www.semanticweb.org/pizzatutorial/ontologies/2020/PizzaTutorial#AmericanaHotPizza"/>
        <hasCaloricContent rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">675</hasCaloricContent>
    </owl:NamedIndividual>

发生了什么?!

另一个问题:当我检查 Protégé 中的个人时,我注意到属性number_of_tabletsprice被添加为 Annotations,而不是 Data Properties。我认为这就是为什么当我删除 sync_reasoner 行时,我的SWRL 规则(已正确导出)没有得出此人的price_per_tablet属性的原因。

请对您发现的任何错误发表评论,我是本体编程和两种工具的初学者,非常感谢您的帮助!

标签: pythonpython-3.xontologyprotegeowlready

解决方案


我找到了答案!

问题出在基础 IRI 中,“new.owl”是不可接受的。

IRI 必须被格式化为一个链接——即使它是一个假的。例如,如果 IRI 是“http://test.org/new.owl”,我的代码可以完美运行。


推荐阅读