这是我如何做事以及启用哪些类型的推理/建模的要点
我们使用的几乎所有内容都属于 OWL Lite,但owl:hasValue
属性除外,我们使用该属性来定义标签集和类名称之间的 1-1 映射。因此,当前的解决方案属于 OWL DL。
这也意味着我们需要一个推理器,但幸运的是不是一个支持 OWL Full 的推理器:)。 OWL-RL 是与 RDFlib 配合使用的不错选择。
# G is our RDFlib Graph
# apply reasoning to expand all of the inferred triples
import owlrl
owlrl . DeductiveClosure ( owlrl . OWLRL_Semantics ). expand ( G )
# get namespaces
print ( list ( G . namespaces ()))
G . query ( "SELECT ?x WHERE { ?x brick:hasTag tag:Equip }" )
如果我们需要使用不支持推理的 SPARQL 查询处理器,我们可以将图的扩展形式序列化到磁盘。
https://brickschema.org/schema/1.1.0/Brick#
owl:Class
并通过rdfs:subClassOf
排列成层次结构owl:equivalentClass
属性相关skos:definition
给出的定义brick:AHU_Average_Exhaust_Air_Static_Pressure_Sensor
只是一个Average_Exhaust_Air_Static_Pressure_Sensor
,它是 AHU 的一个点。我们定义的根类是:
Equipment
Location
Point
Tag
Substance
Quantity
(关系是类实例之间 owl ObjectProperties 的 Brick 术语)
从表面上看,关系的运作方式与原始砖块中的运作方式相同。所有相同的关系仍然存在(我记得定义它们),并且它们的逆关系使用owl:inverseOf
定义。
域和范围是根据类来定义的。声明关系的rdfs:range
属于类brick:Equipment
意味着关系的对象应该是brick:Equipment
类的实例。
该原型除了关系之外还包括子关系。可以使用子关系代替超级关系,以向该关系的性质添加更多细节。到目前为止唯一的例子是feedsAir
是feeds
的子属性。
需要弄清楚的是我们如何推断feedsAir
关系;也许两个端点设备具有air
标签和feeds
关系?这可能需要明确指定而不是推断。
https://brickschema.org/schema/1.1.0/BrickTag#
skos:definition
属性给出的定义这是通过将 Brick 类(例如Air_Temperature_Sensor
)声明为等效于匿名类来实现的,匿名类是一个owl:Restriction
,它是具有某些标签的实体的交集。
# in turtle format
brick:Temperature_Sensor a owl:Class ;
rdfs:subClassOf brick:Sensor ;
owl:equivalentClass [ owl:intersectionOf (
[ a owl:Restriction ;
owl:hasValue tag:Sensor ;
owl:onProperty brick:hasTag
]
[ a owl:Restriction ;
owl:hasValue tag:Temperature ;
owl:onProperty brick:hasTag
]
) ] .
第一个owl:Restriction
是所有将tag:Sensor
作为其brick:hasTag
属性之一的值的类的集合。
这意味着温度传感器:ts1
可以用两种不同的方式定义,并且推理机将推断其他三元组:
# using classes
:ts1 a brick:Temperature_Sensor
# using tags
:ts1 brick:hasTag tag:Temp
:ts1 brick:hasTag tag:Sensor
Brick 现在定义了物质层次结构 ( substances.py
) 和数量层次结构 ( quantities.py
)。物质和数量可以与设备和点相关。
并非所有这些都得到实施。在当前的原型中,传感器通过“ brick:measures
关系与物质和数量相关。
:ts1 a brick:Temperature_Sensor
:ts1 brick:measures :Air
# this implies the following
:ts1 a brick:Air_Temperature_Sensor
我们可以进一步对物质进行子类化,为其定义提供系统或过程级别的上下文:
:ts1 a brick:Sensor
:ts1 brick:measures brick:Return_Air
:ts1 brick:measures brick:Temperature
# implies...
:ts1 a brick:Return_Air_Temperature_Sensor
Brick 使用 OWL 限制来根据此类关系细化类。对于此示例,因为:ts1
测量空气(特别是brick:Air
类),所以 OWL 将我们的传感器推断为brick:Air_Temperature_Sensor
。
海龟中的定义如下:
brick:Air_Temperature_Sensor a owl:Class ;
rdfs:subClassOf brick:Temperature_Sensor ;
owl:equivalentClass [ owl:intersectionOf ( [ a owl:Restriction ;
owl:hasValue brick:Temperature ;
owl:onProperty brick:measures ] [ a owl:Restriction ;
owl:hasValue brick:Air ;
owl:onProperty brick:measures ] ) ] .
注意:我们在这里使用类作为值,这与 Brick 的其余部分不同。这称为“双关语”。这是为了避免必须为我们的传感器创建要测量的物质实例等,但保留了将来实现这一点的可能性。物质的实例可以对过程阶段中的“物质”区域/块进行建模,例如进入冷却器的水或空气处理单元的混合空气区域。
我们没有迷失在如何将所有内容格式化为 YAML 的西西弗斯式自行车中,而是只使用 Python 字典,因此我们不必担心任何(好吧,不是那么多)解析逻辑。
definitions = {
"Lighting_System" : {
"tagvalues" : [ # Lighting_System class is equivalent to the Lighting tag
( BRICK . hasTag , TAG . Lighting ),
# if you have more required tags add them as their own tuple in the list
],
# defining subclasses. This can be nested ad-infinitum
"subclasses" : {
"Lighting" : {
"subclasses" : {
"Luminaire" : {},
"Luminaire_Driver" : {},
},
},
"Interface" : {
"subclasses" : {
"Switch" : {
"subclasses" : {
"Dimmer" : {},
},
},
"Touchpanel" : {},
},
},
},
}
}
define_subclasses ( definitions , BRICK . Equipment )
目前,代码就是文档。查看equipment.py
、 point.py
等示例以及如何添加到每个类层次结构。
作者:加布·菲耶罗