Description
https://github.com/statnett/Talk2PowerSystem/wiki/Inference
In the electrical CIM, a query
Substation Connectivity "List all substations that are connected via an AC-line or a DC line to substation named XYZ"
looks like this (note: CIM properties have a class name as prefix; and each relation has an inverse):
PREFIX cim: <http://iec.ch/TC57/2013/CIM-schema-cim16#>
PREFIX sesame: <http://www.openrdf.org/schema/sesame#>
select ?sub1Name ?lineName ?sub2Name {
{select distinct * {
values ?sub1Name {"ARENDAL"}
?sub1 a cim:Substation;
cim:IdentifiedObject.name ?sub1Name;
(cim:EquipmentContainer.Equipments|cim:Substation.VoltageLevels|cim:VoltageLevel.Bays)+ / # equipment in ?sub1
cim:ConductingEquipment.Terminals / cim:Terminal.ConnectivityNode / cim:ConnectivityNode.Terminals / cim:Terminal.ConductingEquipment / # connected to segment
cim:Equipment.EquipmentContainer ?line. # part of ?line
?line a cim:Line; cim:IdentifiedObject.name ?lineName}}
{select distinct * {
?sub2 a cim:Substation;
cim:IdentifiedObject.name ?sub2Name;
(cim:EquipmentContainer.Equipments|cim:Substation.VoltageLevels|cim:VoltageLevel.Bays)+ / # equipment in ?sub2
cim:ConductingEquipment.Terminals / cim:Terminal.ConnectivityNode / cim:ConnectivityNode.Terminals / cim:Terminal.ConductingEquipment / # connected to segment
cim:Equipment.EquipmentContainer ?line}}
filter(?sub1 != ?sub2)
}
This query is quite impossible for an LLM to generate (this project is Talk2PowerSystem
, I also call it Statnett-LLM
).
The query can be simplified a lot if we add derived props. Assume a namespace cimex:
(CIM Extensions):
- Containers, subcontainers and equipments (Substation has VoltageLevels that may have Bays that have Equipments)
cim:EquipmentContainer.Equipments|cim:Substation.VoltageLevels|cim:VoltageLevel.Bays
=>cimex:hasPart
; inversecimex:isPart
- Equipments (conducting or auxiliary) have Terminals but there's no super-prop to abstract over these two cases:
cim:Terminal.ConductingEquipment|cim:Terminal.AuxiliaryEquipment
=>cimex:Terminal.Equipment
; inversecimex:Equipment.Terminals
- Transitive "part" property:
cimex:hasPart+
=>cimex:hasPartTransitive
; inversecimex:isPartTransitive
- Equipments are connected through their Terminals and a ConnectivityNode:
cim:ConductingEquipment.Terminals / cim:Terminal.ConnectivityNode / cim:ConnectivityNode.Terminals / cim:Terminal.ConductingEquipment
=>cimex:connectedTo
(symmetric) cimex:hasPartTransitive / cimex:connectedTo / cimex:isPartTransitive
=>cimex:connectedThroughPart
(symmetric)
This case is similar to (but simpler than) #343, and mentions it in section "Aside: ASHRAE/Bricks Connections".
I've implemented this using standard OWL2-RL reasoning (more specifically owl2-rl-optimized
, see GraphDB documentation).
rdfs:subClassOf
owl:inverseOf
(all CIM relations have inverses)rdfs:subPropertyOf
: needed forcimex:hasPart, cimex:isPart
owl:TransitiveProperty
: needed forcimex:hasPartTransitive, cimex:isPartTransitive
owl:propertyChainAxiom
: needed forcimex:connectedTo, cimex:connectedThroughPart
owl:SymmetricProperty
:cimex:connectedTo, cimex:connectedThroughPart
are declared symmetric, but we don't need this reasoning since the respective property chains are already symmetric.
Here are the axioms (T-Box):
cimex:hasPart owl:inverseOf cimex:isPart.
cimex:hasPartTransitive owl:inverseOf cimex:isPartTransitive, a owl:TransitiveProperty.
cimex:isPartTransitive owl:inverseOf cimex:hasPartTransitive.
cimex:Terminal.Equipment owl:inverseOf cimex:Equipment.Terminals.
cim:EquipmentContainer.Equipments rdfs:subPropertyOf cimex:hasPart.
cim:Substation.VoltageLevels rdfs:subPropertyOf cimex:hasPart.
cim:VoltageLevel.Bays rdfs:subPropertyOf cimex:hasPart.
cimex:hasPart rdfs:subPropertyOf cimex:hasPartTransitive.
cim:Terminal.ConductingEquipment rdfs:subPropertyOf cimex:Terminal.Equipment.
cim:Terminal.AuxiliaryEquipment rdfs:subPropertyOf cimex:Terminal.Equipment.
cimex:connectedTo owl:propertyChainAxiom
(cimex:Equipment.Terminals cim:Terminal.ConnectivityNode cim:ConnectivityNode.Terminals cimex:Terminal.Equipment).
cimex:connectedThroughPart owl:propertyChainAxiom
(cimex:hasPartTransitive cimex:connectedTo cimex:isPartTransitive).
After adding cimex: derived props, the query becomes much simpler and LLM generates it with no problem:
PREFIX cimex: <https://rawgit2.com/statnett/Talk2PowerSystem/main/demo1/cimex/>
PREFIX cim: <http://iec.ch/TC57/2013/CIM-schema-cim16#>
PREFIX sesame: <http://www.openrdf.org/schema/sesame#>
select ?sub1Name ?lineName ?sub2Name {
values ?sub1Name {"ARENDAL"}
?sub1 a cim:Substation; cim:IdentifiedObject.name ?sub1Name;
cimex:connectedThroughPart ?line.
?line a cim:Line; cim:IdentifiedObject.name ?lineName.
?sub2 a cim:Substation; cim:IdentifiedObject.name ?sub2Name;
cimex:connectedThroughPart ?line.
filter(?sub1 != ?sub2)
}