Open dr-shorthair opened 6 months ago
Will roll this into an example for documentation.
One (possibly unrelated and/or wrong) question about this: why are custom datatypes not strictly compatible with OWL? Is this a reference to custom datatypes in general or to Custom Datatypes?
(I was referring to custom data types in general. )
TBH I'm very unsure on this.
On the one hand there is this https://www.w3.org/TR/owl2-primer/#Advanced_Use_of_Datatypes
On the other hand this seems to say that the set of data types in the OWL2 data type map is bounded https://www.w3.org/TR/owl2-syntax/#Datatype_Maps
On the third hand, maybe we don't care about OWL reasoners, since in 2024 we will usually rely on SHACL or Python etc.
What's your take?
From my reading of OWL2 Syntax section 5.2, datatype URLs must fulfil one of three criteria (be rdfs:Literal or one of the datatypes from section 4 or not be part of the reserved vocabulary). Section11.2 insists on this (and adds some constraints), and Section 9.4 even has an example with the definition of a custom SSN type.
It does seem that reasoner support for custom datatypes is... insufficient. But I think it's a sound strategy for defining simple results, I really like it, and IMO it appears to be compliant with the spec. If other RDF/OWL tools (like those you mention) can work with this, I woulnd't even keep the note.
Thanks @avillar - removed the warning in 74e78de
TBQH I don't think we should get hung up on OWL issues so much. Few SSN applications use OWL reasoning. Rather, they will be using RDF (typically as JSON) for data transfer, so validation will be a more relevant approach than reasoning and consistency.
I think we should consider JSON-LD compatibility here - can we serialise to/from custom datatypes into JSON predictably, and is there any control over the JSON schema.
Good point. I took a look at how TopBraid renders this one in JSON-LD
<Observation/234534>
rdf:type sosa:Observation ;
sosa:hasFeatureOfInterest <apartment/134> ;
sosa:hasSimpleResult "-29.9"^^unit:DEG_C ;
.
It comes up with this, which binds the @type to hasSimpleResult
{
"@id" : "Observation/234534",
"@type" : "sosa:Observation",
"hasFeatureOfInterest" : "apartment/134",
"hasSimpleResult" : "-29.9",
"@context" : {
"hasFeatureOfInterest" : {
"@id" : "http://www.w3.org/ns/sosa/hasFeatureOfInterest",
"@type" : "@id"
},
"hasSimpleResult" : {
"@id" : "http://www.w3.org/ns/sosa/hasSimpleResult",
"@type" : "http://qudt.org/vocab/unit/DEG_C"
},
"xsd" : "http://www.w3.org/2001/XMLSchema#",
"rdfs" : "http://www.w3.org/2000/01/rdf-schema#",
"unit" : "http://qudt.org/vocab/unit/",
"rdf" : "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
"sosa" : "http://www.w3.org/ns/sosa/"
}
}
And if there is more than one value with some different unit representations, such as
<Observation/234534>
rdf:type sosa:Observation ;
sosa:hasFeatureOfInterest <apartment/134> ;
sosa:hasSimpleResult "-22"^^unit:DEG_F ;
sosa:hasSimpleResult "-29.8"^^unit:DEG_C ;
sosa:hasSimpleResult "-29.9"^^unit:DEG_C ;
sosa:hasSimpleResult "243.25"^^unit:K ;
.
TopBraid gives
{
"@id" : "Observation/234534",
"@type" : "sosa:Observation",
"hasFeatureOfInterest" : "apartment/134",
"hasSimpleResult" : [ "-29.9", "-29.8" ],
"sosa:hasSimpleResult" : [ {
"@type" : "unit:DEG_F",
"@value" : "-22"
}, {
"@type" : "unit:K",
"@value" : "243.25"
} ],
"@context" : {
"hasFeatureOfInterest" : {
"@id" : "http://www.w3.org/ns/sosa/hasFeatureOfInterest",
"@type" : "@id"
},
"hasSimpleResult" : {
"@id" : "http://www.w3.org/ns/sosa/hasSimpleResult",
"@type" : "http://qudt.org/vocab/unit/DEG_C"
},
"xsd" : "http://www.w3.org/2001/XMLSchema#",
"rdfs" : "http://www.w3.org/2000/01/rdf-schema#",
"unit" : "http://qudt.org/vocab/unit/",
"rdf" : "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
"sosa" : "http://www.w3.org/ns/sosa/"
}
}
So this pattern looks quite predictable
"sosa:hasSimpleResult" : {
"@type" : "unit:UNITAA",
"@value" : "valueAA"
},
JSON-LD can also do this if the source data has different properties for hasSimpleResult
:
{
"@context": {
"unit": "http://qudt.org/vocab/unit/",
"sosa": "http://www.w3.org/ns/sosa/",
"celsius": {
"@id": "sosa:hasSimpleResult",
"@type": "unit:DEG_C"
},
"fahrenheit": {
"@id": "sosa:hasSimpleResult",
"@type": "unit:DEG_F"
}
},
"celsius": 33.2,
"fahrenheit": 91.8
}
which results in:
@prefix sosa: <http://www.w3.org/ns/sosa/> .
@prefix unit: <http://qudt.org/vocab/unit/> .
[] sosa:hasSimpleResult "3.32E1"^^unit:DEG_C, "9.18E1"^^unit:DEG_F .
Following today's sdw teleconference, I will create two exemplars for the documentation that deals with this using two consumer grade devices. Must reference OWL2 datatypes, interpretations of literals and usage in json-ld.
I made a few tests with the Turtle document below:
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix sosa: <http://www.w3.org/ns/sosa/> .
@prefix unit: <http://qudt.org/vocab/unit/> .
<Observation/234534>
rdf:type sosa:Observation ;
sosa:hasFeatureOfInterest <apartment/134> ;
sosa:hasSimpleResult "-22"^^unit:DEG_F ;
sosa:hasSimpleResult "-29.8"^^unit:DEG_C ;
sosa:hasSimpleResult "-29.9"^^unit:DEG_C ;
sosa:hasSimpleResult "243.25"^^unit:K ;
.
This is how Protégé saves it as JSON-LD:
[ {
"@id" : "_:genid1",
"@type" : [ "http://www.w3.org/2002/07/owl#Ontology" ]
}, {
"@id" : "file:/home/user/temp/Observation/234534",
"@type" : [ "http://www.w3.org/2002/07/owl#NamedIndividual", "http://www.w3.org/ns/sosa/Observation" ],
"http://www.w3.org/ns/sosa/hasFeatureOfInterest" : [ {
"@id" : "file:/home/user/temp/apartment/134"
} ],
"http://www.w3.org/ns/sosa/hasSimpleResult" : [ {
"@type" : "http://qudt.org/vocab/unit/DEG_C",
"@value" : "-29.8"
}, {
"@type" : "http://qudt.org/vocab/unit/DEG_C",
"@value" : "-29.9"
}, {
"@type" : "http://qudt.org/vocab/unit/DEG_F",
"@value" : "-22"
}, {
"@type" : "http://qudt.org/vocab/unit/K",
"@value" : "243.25"
} ]
}, {
"@id" : "http://qudt.org/vocab/unit/DEG_C",
"@type" : [ "http://www.w3.org/2000/01/rdf-schema#Datatype" ]
}, {
"@id" : "http://qudt.org/vocab/unit/DEG_F",
"@type" : [ "http://www.w3.org/2000/01/rdf-schema#Datatype" ]
}, {
"@id" : "http://qudt.org/vocab/unit/K",
"@type" : [ "http://www.w3.org/2000/01/rdf-schema#Datatype" ]
}, {
"@id" : "http://www.w3.org/ns/sosa/Observation",
"@type" : [ "http://www.w3.org/2002/07/owl#Class" ]
}, {
"@id" : "http://www.w3.org/ns/sosa/hasFeatureOfInterest",
"@type" : [ "http://www.w3.org/2002/07/owl#AnnotationProperty" ]
}, {
"@id" : "http://www.w3.org/ns/sosa/hasSimpleResult",
"@type" : [ "http://www.w3.org/2002/07/owl#AnnotationProperty" ]
} ]
And below is the same output created with RDFLib. Much cleaner, as this tool is not focused on Ontology as is Protégé.
[
{
"@id": "file:///home/user/temp/Observation/234534",
"@type": [
"http://www.w3.org/ns/sosa/Observation"
],
"http://www.w3.org/ns/sosa/hasFeatureOfInterest": [
{
"@id": "file:///home/user/temp/apartment/134"
}
],
"http://www.w3.org/ns/sosa/hasSimpleResult": [
{
"@type": "http://qudt.org/vocab/unit/DEG_F",
"@value": "-22"
},
{
"@type": "http://qudt.org/vocab/unit/DEG_C",
"@value": "-29.8"
},
{
"@type": "http://qudt.org/vocab/unit/DEG_C",
"@value": "-29.9"
},
{
"@type": "http://qudt.org/vocab/unit/K",
"@value": "243.25"
}
]
}
]
In my experience many Observations need to condition units of measure upstream of the Result (usually as an object property to a QUDT or UNIT class). Units of measure often depend on the Property/Procedure combination in chemistry, e.g. pH, molarity dependent procedures, etc.
Good. It looks like the { @type , @value }
pair is a universal JSON pattern.
We should provide JSON examples as much as possible, so I'll start with this one.
Closed by #201
I've had a go at summarizing various options for providing units-of-measure on simple results - see this non-normative section.
https://raw.githack.com/w3c/sdw-sosa-ssn/update-examples-2/ssn/index.html#quantity-values-and-unit-of-measures
The last option is possibly the neatest - I noticed it as a proposal in a GeoSPARQL thread, from @oldskeptic Do you have any further documentation for this pattern?