There are three different ways that structures are defined in the standard; a Sequence is like a C-struct, a SequenceOf is like a list or array, and a Choice which is one of a set of optional elements:
:ConstructedData a owl:Class ;
owl:equivalentClass
[ rdf:type owl:Class ;
owl:oneOf (:Sequence :SequenceOf :Choice)
] .
[] rdf:type owl:AllDifferent ;
owl:distinctMembers (:Sequence :SequenceOf :Choice) .
The meta-class statement is supposed to state that even though Sequence objects and Choice objects are both made up of Element objects, something cannot be both.
Sequence objects and Choice objects are made up of Elements:
:Element rdf:type owl:Class ;
owl:disjointUnionOf (:ChoiceElement :SequenceElement) .
Every good element definition will have a relationship to its “parent”:
elem:partOf rdf:type owl:FunctionalProperty, owl:ObjectProperty ;
rdfs:domain :Element ;
rdfs:range
[ rdf:type owl:Class ;
owl:unionOf (:Choice :Sequence)
] .
Elements can be application encoded or context encoded which means there is a special value given to the element to make sure it can be resolved correctly during packet decoding:
elem:context rdf:type owl:DatatypeProperty, owl:FunctionalProperty ;
rdfs:domain :Element ;
rdfs:range xsd:nonNegativeInteger .
Should I create ApplicationEncoded and ContextEncoded subclasses of Element and restrict the elem:context to ContextEncoded?
Every element refers to a data type:
elem:datatype a owl:ObjectProperty, owl:FunctionalProperty ;
rdfs:domain :Element .
The range of the elem:datatype should be a class that is one of the primitive datatypes or a class that is a subclass of a constructed data type. How can this be specified in the ontology?
This is an example of an ASN.1 sequence:
BACnetGroupChannelValue ::= SEQUENCE {
channel [0] Unsigned16,
overridingPriority [1] Unsigned (1..16) OPTIONAL,
value BACnetChannelValue
}
There are three elements, the first two are context encoded and the last one, which refers to another data type, is application encoded. The context encoding for the first two unsigned values is necessary because the second value is optional.
Sequences are a class:
:Sequence a owl:Class .
Can this be an rdf:Seq subclass?
Sequence elements are subclasses of Element that are required or optional:
:SequenceElement a owl:Class ;
rdfs:subClassOf :Element ;
owl:disjointUnionOf (:OptionalSequenceElement :RequiredSequenceElement) .
:OptionalSequenceElement a owl:Class ;
rdfs:subClassOf :SequenceElement .
:RequiredSequenceElement a owl:Class ;
rdfs:subClassOf :SequenceElement .
Every sequence element holds a specific position in a list of all of the other elements for the same sequence:
seqe:index a owl:DatatypeProperty, owl:FunctionalProperty ;
rdfs:domain :SequenceElement ;
rdfs:range xsd:nonNegativeInteger .
How can I specify that there cannot be two sequence elements with the same elem:partOf reference that have the same seqe:index value?
This is an example of ASN.1:
BACnetSecurityKeySet ::= SEQUENCE {
key-revision [0] Unsigned8, -- 0 if key set is not configured
activation-time [1] BACnetDateTime, -- UTC time, all wild if unknown
expiration-time [2] BACnetDateTime, -- UTC time, all wild if infinite
key-ids [3] SEQUENCE OF BACnetKeyIdentifier
}
The last element in the sequence is a context encoded list of key identifiers.
SequenceOF could be a subclass of rdf:Seq, but how would the ontology specify that all of the list elements are instances of KeyIdentifier?
An array is just like a sequence, but it has BACnetArray semantics which simply means that items in the array can be individually referenced:
:ArrayOf a owl:Class ;
rdfs:subClassOf :SequenceOf .
This is an example of an ASN.1 choice:
BACnetRecipient ::= CHOICE {
device [0] BACnetObjectIdentifier,
address [1] BACnetAddress
}
This is a long line of text:
:Choice a owl:Class .
This is an ASN.1 sample:
BACnetObjectPropertyValue ::= SEQUENCE {
objectIdentifier [0] BACnetObjectIdentifier,
propertyIdentifier [1] BACnetPropertyIdentifier,
propertyArrayIndex [2] Unsigned OPTIONAL,
-- used only with array datatype
-- if omitted with an array the entire array is referenced
value [3] ABSTRACT-SYNTAX.&Type,
-- any datatype appropriate for the specified property
priority [4] Unsigned (1..16) OPTIONAL
}
Note
huh?