w3c / sdw-sosa-ssn

Repository of the Spatial Data on the Web Working Group for the SOSA/SSN vocabulary
9 stars 5 forks source link

System types and individuals #107

Closed maximelefrancois86 closed 1 week ago

maximelefrancois86 commented 1 year ago

It is still unclear when one wants to model a generic kind of system (aka, model, category, class, ...), whether they should model it as an instance of ssn:System, or a subclass of ssn:System.

As ssn:System is a superclass of sosa:Sensor, sosa:Actuator, sosa:Sampler, this confusion also applies to these class.

This ambiguity is reported in https://www.w3.org/TR/vocab-ssn/#SSNSystem-instances

In the SOSA/SSN examples, systems/sensors/actuators sometimes model generic sensor kinds, and sometimes a unique actual instance of sensor:

It would help a lot to be able to identify kinds of systems generically, the same way we do with property kinds. One advantage would be that we could reuse existing code lists, vocabularies, and taxonomies. Identifiers could be for example:

Another advantage is that it would encourage manufacturers and vendors to define permanent URIs for their devices, and to expose structured data at the page that describes a device in a catalogue. Some examples of product IDs from manufacturer and vendor catalogues:

My proposal to disambiguate the concept while maintaining backward compatibility with previous usages would be to split ssn:System in two classes:

sosa:SystemOfInterest

System is a unit of abstraction for real-world pieces of infrastructure that implement Procedures. A System may have components, its subsystems, which are other Systems.

By the way, we should extend this definition to account for use cases when one wants to identify the digital twin of a system using that same class in SOSA (the digital model of a system of interest is also a system of interest).

sosa:SystemKind

An instance of sosa:SystemKind describes a datasheet, vendor specification, or normative specification, of a sensor (in the sense of a prototypical description).

EXAMPLE: system with European Union energy label A++ , Energy Star labeled appliance, BMP282, DHT22, Adafruit 5187, ...

NOTE: Concepts from existing code lists, vocabularies, and taxonomies, may be used as instances of sosa:SystemKind.

NOTE: alternative names could be: sosa:SystemModel, sosa:SystemType, ...

alexrobin commented 5 months ago

@dr-shorthair I would rather not do that since it clearly goes the opposite way from what connected system is doing. We agreed earlier that sosa:SystemKind would describe types/kinds of systems and sosa:System would describe instances. We rewrote the CS API specs accordingly.

I also think in OMS, Observer is supposed to be an instance, isn't it?

dr-shorthair commented 5 months ago

We agreed earlier that sosa:SystemKind would describe types/kinds of systems and sosa:System would describe instances.

I can see that this was proposed by @maximelefrancois86 in https://github.com/w3c/sdw-sosa-ssn/issues/107#issuecomment-1999727667 and that the following discussion went along with that. However, I don't believe we reached consensus in the working group yet. Which is why the issue is still open and the PRs are not merged.

I would now push in the other direction. If we need both levels in SSN/SOSA, then I would propose to

My understanding is that this has been the general usage in deployments until now.

If this also needs

then so be it.

I agree that clarifying all this is overdue and I apologise for not paying enough attention before. I apologise in particular to @alexrobin if this looks like back-tracking with respect to the changes made to CS API, but I don't believe it is too late or too hard to adjust that now. It is a small change in the mapping. And SSN/SOSA has a legacy that has some weight.

dr-shorthair commented 5 months ago

@kjano could you comment on the usage of System and Sensor in KWG?

maximelefrancois86 commented 5 months ago

Hi,

I disagree with this proposed change, it's the opposite of our common use in iot application, and it would clear break backward compatibility with such applications.

Many are already pushed aside with Property being only for the generic now. I'm afraid we need some more inclusive way to make SOSA evolve.

One third option is to leave Device ambiguous, but introduce DeviceInstance and DeviceKind subclasses

(We could do the same for Property, Feature, etc.)

This solution, applied to Features, had a vote against by @rgcmme . See

https://labs.etsi.org/rep/saref/saref-portal/-/issues/108

dr-shorthair commented 5 months ago

Thanks for weighing in @maximelefrancois86 .

You say

opposite of our common use in iot application

So, is it the case that IOT applications usually refer to individual sensors/actuators (i.e. with serial numbers) rather than types (i.e. with model numbers)? Indeed, your example B.1 right at the top of this issue shows an individual. However, example B.2 shows a type.

So we have precedents both directions.

(The notional examples from O&M in B.12 are ambiguous.)

Now I think I understand better your argument for both type and instance, and appreciate your compromise proposal "to leave Device [System] ambiguous, but introduce DeviceInstance and DeviceKind subclasses" (presumably with a predicate to point from the former to the latter).

alexrobin commented 5 months ago

@dr-shorthair Yes, that's actually the problem. The class System was used before to describe both types and instances, depending on the context/project/author.

I don't know if one way was used more than another but we have to pick one approach now.

If we decide to not use System as the instance, then I would rather use SystemInstance instead of SystemOfInterest. I think having instance in the name makes the intent very clear.

dr-shorthair commented 5 months ago

Like this?

SystemKind SystemInstance

Of course, having SystemKind and SystemInstance on the same meta-level might offend some analysts. But if the goal is to have a system where we can potentially catalogue both - i.e. the members of both classes are in the a-box - then we would have to do it this way.

maximelefrancois86 commented 5 months ago

right.

I'd rather use a unidirectional link from SystemInstance to SystemKind, and name it generically such as hasKind , so that:

image

kjano commented 5 months ago

One third option is to leave Device ambiguous, but introduce DeviceInstance and DeviceKind subclasses.

With all due respect, I would rather strongly disagree with having three classes (or even two). I have not yet seen an example where this cannot be done via patterns, CGI, metamodeling, etc. We have known how to deal with most of these cases since Noy's work 20 years ago. Also, SOSA was supposed to be the inner module (this is why it is so popular); let us add modules (if you really want to have *Type/Kind) , not directly mess with SOSA.

Best, Jano

On Thu, Jun 13, 2024 at 6:28 AM Maxime Lefrançois @.***> wrote:

Hi,

I disagree with this proposed change, it's the opposite of our common use in iot application, and it would clear break backward compatibility with such applications.

Many are already pushed aside with Property being only for the generic now. I'm afraid we need some more inclusive way to make SOSA evolve.

One third option is to leave Device ambiguous, but introduce DeviceInstance and DeviceKind subclasses

(We could do the same for Property, Feature, etc.)

This solution, applied to Features, had a vote against by @rgcmme https://github.com/rgcmme . See

https://labs.etsi.org/rep/saref/saref-portal/-/issues/108

— Reply to this email directly, view it on GitHub https://github.com/w3c/sdw-sosa-ssn/issues/107#issuecomment-2164346731, or unsubscribe https://github.com/notifications/unsubscribe-auth/AANMP5WUMPS2UDH7GBK4JPLZHENU5AVCNFSM6AAAAAA6PIEVEOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNRUGM2DMNZTGE . You are receiving this because you were mentioned.Message ID: @.***>

alexrobin commented 5 months ago

If need be, I'm ok with doing this in a separate tree or module, but no namespace proliferation please! I would like to keep everything in sosa namespace or we'll be back to where we were before.

Also, I think I would favor a two classes pattern: System + SystemKind. What do we gain with 3 classes? How would the System class be used in this case? Is it just for backward compatibility since System could be both instance and type before?

rob-metalinkage commented 5 months ago

Can we find a compromise with a range Includes System,SystemKind. Personally I'd like an unambiguous predicate for each, and leave a deprecated ambiguous one for backwards compatibility

dr-shorthair commented 5 months ago

@kjano wrote

I have not yet seen an example where this cannot be done via patterns, CGI, metamodeling, etc. We have known how to deal with most of these cases since Noy's work 20 years ago.

Could you spell out some small examples please?

kjano commented 5 months ago

For instance, you could have subclasses of sensors with certain properties, such as measurement accuracy, and then any instance of this class will share the same accuracy, thereby making the class act more like the datasheet we discussed. I sent you an example by email. Jano

On Sun, Jun 16, 2024 at 5:03 AM Simon Cox @.***> wrote:

@kjano https://github.com/kjano wrote

I have not yet seen an example where this cannot be done via patterns, CGI, metamodeling, etc. We have known how to deal with most of these cases since Noy's work 20 years ago.

Could you spell out some small examples please?

— Reply to this email directly, view it on GitHub https://github.com/w3c/sdw-sosa-ssn/issues/107#issuecomment-2171025373, or unsubscribe https://github.com/notifications/unsubscribe-auth/AANMP5ULLITKD6C7OWMZDVLZHT6ARAVCNFSM6AAAAAA6PIEVEOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNZRGAZDKMZXGM . You are receiving this because you were mentioned.Message ID: @.***>

rgcmme commented 5 months ago

If the couple <*>Kind and <*>Instance are created, I would try to avoid making them subclass of the <*> class.

<*>Kinds are abstract entities (e.g., datasheets) and <*>Instances are physical ones. The class <*> would be something that represents both abstract and physical entities:

Also, creating this structure for FeaturesOfInterest, Systems, Sensors, Actuators, etc. would make SOSA not so straightforward as already mentioned. I would move all the <*>Kinds to some existing module.

For example, for me this information about <*>Kinds fits well in the "System Capabilities" module (at least for SystemKinds).

For the rest of kinds, maybe we have to ask ourselves is SOSA/SSN is the ontology to be used to represent (for example) kinds of features of interest. In other words, is it in our requirements to cover this?

oldskeptic commented 5 months ago

I'm writing this after an extra-ordinary Sosa session that @rob-metalinkage and myself had last night over a few drinks. I think we were on our way to solving all the world's problems before I had to run and catch a train.

My understanding of the System + SystemKind or Sensor + SensorKind is this: Untitled

However, it seems to me we are not using the RDF/OWL tools already available. Sub-classing would make things a lot easier using established type / subclass patterns (PR #196 works like this).

Untitled

As @kjano noted, the addition of OWL restrictions by implementers can force all sensors to share the same characteristics or can allow for local properties to document the idiosyncrasies of individual sensors.

To my mind, a data sheet is a human oriented document that Sosa should reference without specifying a format. I'd suggest using foaf:Document or something as a placeholder. I agree that a Procedure is not a Data Sheet but this is how our current examples are presenting it which needs to change.

As an implementer, I really want a normative property to link SystemCapabilities, and the Procedure used, to its authoritative human-readable source. I'd also like to point out the need for both the System and Platform classes: as with the case in PR #196, several sensors are often bundled together within the same immutable tangible "thing" and then bolted onto a Platform to actually record Observations within a Deployment.

I don't think we are all far apart; it's the linkages between the things that is tricky.

oldskeptic commented 5 months ago

How about using prov:hadPrimarySource to link the SystemCapabilities to the data sheet?

dr-shorthair commented 5 months ago

Apologies for letting this sit a week.

I believe I now understand what @kjano is proposing, and broadly how it relates to the sketch by @oldskeptic immediately above.

Pattern A. Here is an InkBird example done using sub-classing:

<https://example.org/sensor/IBS-TH2> rdf:type owl:Class ;
    rdfs:subClassOf sosa:Sensor ;
    gs1:pip <https://inkbird.com/products/hygrometer-ibs-th2> ;
    rdfs:label "Bluetooth Temperature and Humidity Sensor IBS-TH2" ;
    skos:notation "IBS-TH2" ;    skos:note "using skos:notation for the model number " ;
    sosa:observes <http://qudt.org/vocab/quantitykind/Temperature> ;
    system:hasSystemCapability [ ... details omitted ...    ] ;
. 

<https://example.org/sensorInstance/IBS-TH2-56> rdf:type <https://example.org/sensor/IBS-TH2> ;
    skos:notation "12gth456a-23190" ;    skos:note "using skos:notation for the serial number " ;
. 

<https://example.org/observation/O-3451> rdf:type sosa:Observation ;
    sosa:observedProperty <http://qudt.org/vocab/quantitykind/Temperature> ;
    sosa:madeBySensor <https://example.org/sensorInstance/IBS-TH2-56> ;
    sosa:resultTime "2024-06-21T15:33:00.00+10:00" ;
    sosa:hasSimpleResult "19.4"^^unit:DEG_C ;
. 

Here's a visual representation Inkbird-examples-subclass

(@oldskeptic I think you have some arrows the wrong way round.)

Pattern B. Compare this with the same example done using the proposed SensorKind and SensorInstance classes:

<https://example.org/sensorKind/IBS-TH2> rdf:type sosa:SensorKind ;
    gs1:pip <https://inkbird.com/products/hygrometer-ibs-th2> ;
    rdfs:label "Bluetooth Temperature and Humidity Sensor IBS-TH2" ;
    skos:notation "IBS-TH2" ;    skos:note "using skos:notation for the model number " ;
    sosa:observes <http://qudt.org/vocab/quantitykind/Temperature> ;
    system:hasSystemCapability [ ... details omitted ... ] ;
. 

<https://example.org/sensorInstance/IBS-TH2-56> rdf:type sosa:SensorInstance ;
    sosa:ofSystemKind <https://example.org/sensorKind/IBS-TH2> ;
    skos:notation "12gth456a-23190" ;    skos:note "using skos:notation for the serial number " ;
. 

<https://example.org/observation/O-3451> rdf:type sosa:Observation ;
    sosa:observedProperty <http://qudt.org/vocab/quantitykind/Temperature> ;
    sosa:madeBySensor <https://example.org/sensorInstance/IBS-TH2-56> ;
    sosa:resultTime "2024-06-21T15:33:00.00+10:00" ;
    sosa:hasSimpleResult "19.4"^^unit:DEG_C ;
. 

Inkbird-examples-sensorKind

The a-box in the bottom half of the diagrams are essentially isomorphic. Pattern B. uses two new classes, and requires one additional triple to link an instance to a kind.

Since there is no actual benefit from introducing the SensorKind and SensorInstance classes, then I'm inclined not to do so. Pattern A. (using sub-classing for sensor-kinds (datasheet), with individual sensors using rdf:type to link to the kind), (i) loses no information, and (ii) is arguably better OWL/RDFS.

However, some thought is required over the domains and ranges of some of the predicates, in particular:

  1. is the range of sosa:madeBySensor a class (i.e. a sub-class of sosa:Sensor) or an instance of sosa:Sensor (or one of its subclasses, including SensorKind and SensorInstance), or either
    • until now I had expected it to be an instance of sosa:Sensor which is why an explicit instance is added in the top example
    • however I believe @kjano would prefer it to be a 'kind' whenever the additional details of an individual sensor instance are not important - I agree
    • so to support that case, using the sub-classing pattern, then would madeBySensor need to link to a class?
  2. similarly, is the domain of sosa:observes a class (i.e. a sub-class of sosa:Sensor) or an instance of sosa:Sensor (or one of its subclasses, including SensorKind and SensorInstance), or either
    • for the sub-classing pattern, sosa:observes must be attached to a class
  3. ditto system:hasSystemCapability

Finally, it means that a register of Sensor kinds would be populated by OWL classes not OWL individuals. A register of Sensor instances would still contain OWL individuals. I don't see any problem with that.

alexrobin commented 5 months ago

@dr-shorthair Thanks Simon for the detailed example.

I think using individuals for instances and classes for types makes a lot of sense, as it follows general OWL practices. I don't mind dropping the SystemKind/SystemInstance stuff completely because we can use the original classes (System/Sensor/Actuator/Sampler) to tag both instances and types in our application (i.e. SensorML and Connected Systems API).

If we do stick with pattern A, is there still a need for clarification about property ranges in this case? For example, will sosa:madeBySensor always link an Observation individual to a Sensor individual or could it also link to a Sensor subclass (question mark on your first diagram)? I think technically, in OWL, "Object properties always connect pairs of individuals" so it should NOT be used to reference the class itself. Instead, it should ALWAYS be done through a Sensor instance that then references the type using the rdf:type predicate (like in your example).

Also I think some of the issues come up in the hasSystemCapability part that you omitted because it's more cumbersome to set capabilities values in the class (I think you have to use OWL restrictions, etc...). I'm not sure that's a good enough reason to break the well known individual/class pattern though, so we probably just have to live with the verbosity of OWL in this case.

dr-shorthair commented 5 months ago

For datasheets modeled as classes, the capabilities would be expressed as owl:Restrictions.

(Note: a simplified version in https://github.com/w3c/sdw-sosa-ssn/issues/107#issuecomment-2198967662 was subsequently developed, which improves on the first part of this code)

<https://example.org/sensor/IBS-TH2-Plus>
  a owl:Class ;
  dcterms:isVersionOf <https://inkbird.com/products/ibs-th2-plus> ;
  rdfs:comment """
    An InkBird IBS-TH2-Plus is a combined Temperature/RH sensor. 
    Here I have modeled the whole thing as a System with a SubSystem for each of temperature and RH
    """ ;
  rdfs:label "IBS-TH2 PLUS Temperature and Humidity Sensor System" ;
  rdfs:subClassOf sosa:System ;
  rdfs:subClassOf [
      a owl:Restriction ;
      rdfs:comment """
          In this Restriction I'm trying to say that every instance of IBS-TH2-Plus 
          - must have two sub-systems
          - the value of one sub-system must be an instance of IBS-TH2-Plus-T - a temperature Sensor
          - the value of the other sub-system must be an instance of IBS-TH2-Plus-H - a relative-humidity sensor

          I don't think I've got there yet 
          """ ;
      owl:allValuesFrom [
          a owl:Class ;
          owl:unionOf (
              [
                a owl:Restriction ;
                owl:hasValue [
                    a owl:Class ;
                    owl:oneOf (
                        <https://example.org/sensor/IBS-TH2-Plus-T>
                      ) ;
                  ] ;
                owl:onProperty sosa:hasSubSystem ;
              ]
              [
                a owl:Restriction ;
                owl:hasValue [
                    a owl:Class ;
                    owl:oneOf (
                        <https://example.org/sensor/IBS-TH2-Plus-H>
                      ) ;
                  ] ;
                owl:onProperty sosa:hasSubSystem ;
              ]
            ) ;
        ] ;
      owl:cardinality "2"^^xsd:nonNegativeInteger ;
      owl:onProperty sosa:hasSubSystem ;
    ] ;
  rdfs:subClassOf [
      a owl:Restriction ;
      rdfs:comment """
          This Restriction says that every instance of IBS-TH2-Plus has the same overall system capability, 
          relating to sampling frequency 
          """ ;
      owl:hasValue <https://example.org/sensor/IBS-TH2-Plus/systemCapability> ;
      owl:onProperty system:hasSystemCapability ;
    ] ;
  prov:wasDerivedFrom <https://inkbird.com/products/ibs-th2-plus> ;
.
<https://example.org/sensor/IBS-TH2-Plus-H>
  a owl:Class ;
  rdfs:label "IBS-TH2 PLUS Humidity Sensor type" ;
  rdfs:subClassOf sosa:Sensor ;
  rdfs:subClassOf [
      a owl:Restriction ;
      owl:hasValue <http://qudt.org/vocab/quantitykind/RelativeHumidity> ;
      owl:onProperty sosa:observes ;
    ] ;
  rdfs:subClassOf [
      a owl:Restriction ;
      owl:hasValue <https://example.org/sensor/IBS-TH2-H/systemCapability> ;
      owl:onProperty system:hasSystemCapability ;
    ] ;
.
<https://example.org/sensor/IBS-TH2-Plus-T>
  a owl:Class ;
  rdfs:label "IBS-TH2 PLUS Temperature Sensor type" ;
  rdfs:subClassOf sosa:Sensor ;
  rdfs:subClassOf [
      a owl:Restriction ;
      owl:hasValue <http://qudt.org/vocab/quantitykind/Temperature> ;
      owl:onProperty sosa:observes ;
    ] ;
  rdfs:subClassOf [
      a owl:Restriction ;
      owl:hasValue <https://example.org/sensor/IBS-TH2-T/systemCapability> ;
      owl:onProperty system:hasSystemCapability ;
    ] ;
.
<https://example.org/sensor/IBS-TH2-Plus/systemCapability>
  a system:SystemCapability ;
  system:hasSystemProperty [
      a system:Frequency ;
      schema:maxValue "0.1"^^unit:HZ ;
      schema:minValue "5.556e-4"^^unit:HZ ;
      rdfs:comment """
          This SystemCapability describes the range of sampling frequencies available. 
          It could also be modelled as an enumeration of specific values
          """ ;
    ] ;
.
<https://example.org/sensor/IBS-TH2-H/systemCapability>
  a system:SystemCapability ;
  system:hasSystemProperty [
      a system:Accuracy ;
      schema:value "4.5"^^unit:PERCENT_RH ;
    ] ;
  system:hasSystemProperty [
      a system:MeasurementRange ;
      schema:maxValue "99.0"^^unit:PERCENT_RH ;
      schema:minValue "0.0"^^unit:PERCENT_RH ;
    ] ;
.
<https://example.org/sensor/IBS-TH2-T/systemCapability>
  a system:SystemCapability ;
  system:hasSystemProperty [
      a system:Accuracy ;
      schema:value "0.5"^^unit:DEG_C ;
    ] ;
  system:hasSystemProperty [
      a system:MeasurementRange ;
      schema:maxValue "60.0"^^unit:DEG_C ;
      schema:minValue "-40.0"^^unit:DEG_C ;
    ] ;
.
dr-shorthair commented 5 months ago

Consensus of 2024-06-26 telecon (+ @alexrobin asynchronously) is to proceed with Pattern A. - i.e. system-types (data-sheets) are subclasses of sosa:System (and its subclasses sosa:Sensor, sosa:Actuator, sosa:Sampler)

dr-shorthair commented 5 months ago

@kjano could you confirm that I got it right in https://github.com/w3c/sdw-sosa-ssn/issues/107#issuecomment-2191401499

dr-shorthair commented 5 months ago

and is there something better than schema.org for the value/minValue/maxValue properties of the system properties??

dr-shorthair commented 5 months ago

The version above is possibly overcomplicating. Recalling that many OWL design problems are easier when you go back to set-theory, this is simpler and maybe better:

<https://example.org/sensor/IBS-TH2-Plus>
  a owl:Class ;
  rdfs:label "IBS-TH2 PLUS Temperature and Humidity Sensor System" ;
  rdfs:subClassOf sosa:System ;
  rdfs:subClassOf [
      a owl:Restriction ;
      owl:hasValue <https://example.org/sensor/IBS-TH2-Plus/systemCapability> ;
      owl:onProperty system:hasSystemCapability ;
    ] ;
  rdfs:subClassOf [
      a owl:Restriction ;
      owl:cardinality "2"^^xsd:nonNegativeInteger ;
      owl:onProperty sosa:hasSubSystem ;
    ] ;
  rdfs:subClassOf [
      a owl:Restriction ;
      owl:onProperty sosa:hasSubSystem ;
      owl:someValuesFrom <https://example.org/sensor/IBS-TH2-Plus-H> ;
    ] ;
  rdfs:subClassOf [
      a owl:Restriction ;
      owl:onProperty sosa:hasSubSystem ;
      owl:someValuesFrom <https://example.org/sensor/IBS-TH2-Plus-T> ;
    ] ;
  prov:wasDerivedFrom <https://inkbird.com/products/ibs-th2-plus> ;
.

This says: IBS-TH2-Plus is

I think this is pretty close to what we want.

Cross-references are to the same things shown above.

@oldskeptic I went with https://inkbird.com/products/ibs-th2-plus because the spec-sheet is more explicit

dr-shorthair commented 5 months ago

I've had a go at documenting this, with some examples. See previews at

rob-metalinkage commented 4 months ago

Using rdf:type will not allow systems that use rdf:subClassOf reasoning to forward chain/entail to determine which value of rdf:type references the specific objectType. Agree we dont need a SystemKind class.

maximelefrancois86 commented 4 months ago

I'm unhappy with the result.

Recommending to use OWL for simple descriptions seems to me like pushing out of the way a lot of interesting use cases for SOSA. The description in https://github.com/w3c/sdw-sosa-ssn/issues/107#issuecomment-2191401499 is not something I feel comfortable to recommend to anyone. The one in https://github.com/w3c/sdw-sosa-ssn/issues/107#issuecomment-2198967662 is OWL full because of cardinality=2

Note that if we apply the same decision to properties, this would mean taxonomies of properties should be rewritten as hierarchies of property classes... This seems like a double standards policy

Plus, datasheets describe archetypes of sensors. We cannot be sure that a specific instance of a sensor will conserve over time the characteristics specified in its datasheet.

oldskeptic commented 4 months ago

Maxime,

I think that you are misinterpreting it. We're designing it to allow OWL for complex descriptions; the problem with SystemKind was that it was fundamentally re-creating rdf:type.

For properties, we have the following use cases:

  1. A one-off sensor with properties.
  2. A model of a sensor that has properties specified by a data sheet where all of the instances in existence are explicitly assumed to always perfectly conform to the sensor model properties.
  3. A model of a sensor that has properties specified by a data sheet where all of the instances in existence are implicitly assumed to always perfectly conform to the sensor model properties. This may not be correct from an ontology / dl perspective, but that's the practice.
  4. A model of a sensor that has multiple instances in existence where sensor instance properties may or have deviated from their specifications and additional properties may be attached to some sensors.
  5. Lastly, a model of a sensor that has multiple instances in existence where no one wrote anything down.

The example shows how case 2 can be documented by OWL, through other implementers will enumerate this using rdfs only. The examples aren't normative but they communicate how Sosa can leverage OWL/RDFS to deal with and document operating conditions that are usually buried in a report narrative.

We have not addressed this in the current version of Sosa and this is a pattern that applies to #221 also. Some implementations assume that accuracy and precision properties apply to all results evenly. Obviously, this isn't so for use cases such as GPS readings where both vary across results. The example demonstrate owl-full, the rule could just as well be encoded in the software generating the rdf.

dr-shorthair commented 4 months ago

Using rdf:type will not allow systems that use rdf:subClassOf reasoning to forward chain/entail to determine which value of rdf:type references the specific objectType. Agree we dont need a SystemKind class.

I have updated the Mums-clinical-thermometer example so that the individual refers to all the classes up the hierarchy - simulating the closure I think you were concerned about.

Then this relatively simple SPARQL query can find the 'most specialized type' for the thermometer:

SELECT *
WHERE 
{
    ex:Mums-clinical-thermometer rdf:type ?c .
    FILTER NOT EXISTS { 
          ?s rdfs:subClassOf ?c . 
    }
}

The result is ?c = sensor:Mercury-in-glass-thermometer as required.

Is that OK @rob-metalinkage ?

dr-shorthair commented 4 months ago

Plus, datasheets describe archetypes of sensors. We cannot be sure that a specific instance of a sensor will conserve over time the characteristics specified in its datasheet.

Indeed. However, the description of the individual can add system capabilities to the ones specified for the class. If these are within the ranges specified on the class (archetype), then that's fine. If they conflict with the class, then the individual is no longer a member of the class (i.e. does not conform to the archetype) so should not make that claim.

dr-shorthair commented 4 months ago

The one in https://github.com/w3c/sdw-sosa-ssn/issues/107#issuecomment-2198967662 is OWL full because of cardinality=2

In practice we could drop the cardinality restriction with only minor loss of detail for this example.

Many variations in the dialects of OWL and even SHACL will be used for the description of system-types. I can imagine that some users would just drop some text into a comment or description. The degree of support for reasoning within the graph will vary similarly.

The intention of the examples here is merely to illustrate the general principle, for those OWL-ish users who want to approach it that way, that specialized sensors types can be represented as subclasses of sosa:Sensor with precision matching that of a typical datasheet. The key discovery is that there is no need for a SystemKind class, so introducing it would risk diminishing interoperability using SSN/SOSA.

rob-metalinkage commented 4 months ago

This is a fair bit of work to find the most specific type, compared to a simple non-transitive property. There is no need for SPARQL in many applications, where graph traversal can be done in other ways. This is introducing a significant implementation burden compared to accessing a known property IMHO.

Also I don't think you can assume there are no subclasses of the specific type - even more specific types. So the SPARQL would need to be more like


SELECT *
WHERE 
{
    ex:Mums-clinical-thermometer rdf:type ?c .
    FILTER NOT EXISTS { 
              ex:Mums-clinical-thermometer rdf:type ?s .
          ?s rdfs:subClassOf ?c . 
    }
}```
rob-metalinkage commented 4 months ago

A corollary would be an entailment rule for a node ($this)


CONSTRUCT $this sosa:systemKind ?c
WHERE 
{
    $this rdf:type ?c .
    FILTER NOT EXISTS { 
              ?s rdf:type ?s .
          ?s rdfs:subClassOf ?c . 
    }
}```
dr-shorthair commented 4 months ago

Thanks for that correction @rob-metalinkage - indeed, my version would find additional sub-classes below the ones associated with $this. Your correction fixes that.

Thinking about the proposed sosa:hasSystemKind predicate: I have not seen sub-properties of rdf:type before, but I don't believe it is prohibited. I think it would have to be formulated this way:

sosa:hasSystemKind
  rdf:type rdf:Property ;
  rdfs:subPropertyOf rdf:type ;
.

sosa:System
  rdfs:subClassOf [
      rdf:type owl:Restriction ;
      owl:hasValue sosa:System ;
      owl:onProperty sosa:hasSystemKind ;
    ] ;
  rdfs:subClassOf [
      rdf:type owl:Restriction ;
      owl:maxCardinality "1"^^xsd:nonNegativeInteger ;
      owl:onProperty sosa:hasSystemKind ;
    ] ;
.

The prototype rdf:type has rdfs:range rdfs:Class (which covers owl:Class as well of course). So the object of a rdf:type property is a thing of type Class.

So how do we fix the behaviour of sosa:hasSystemKind?

Any other suggestions?

oldskeptic commented 4 months ago

This is a fair bit of work to find the most specific type, compared to a simple non-transitive property. There is no need for SPARQL in many applications, where graph traversal can be done in other ways. This is introducing a significant implementation burden compared to accessing a known property IMHO.

I can see people trying to use multiple hierarchies of SystemTypes which would recreate the same problem.

dr-shorthair commented 1 month ago

I'd like to progress this issue please. See previews linked in https://github.com/w3c/sdw-sosa-ssn/issues/107#issuecomment-2204973373