w3c-lbd-cg / bot

Building Topology Ontology
https://w3id.org/bot
53 stars 15 forks source link

Defining properties at type level #29

Closed MadsHolten closed 4 years ago

MadsHolten commented 6 years ago

I think it would be great if BOT supported the concept of types/instances although I am having a hard time figuring out how to implement it.

I have worked on an example, which we should discuss at LDAC.

Example

mathib commented 6 years ago

Interesting approach. I wondered why you don't define these 'types' on Tbox level, e.g. as a user defined extension of PRODUCT? Maybe because it will be difficult to assign properties to classes in a similar way as to instances of bot:Element?

If you keep on using your current method, I think you'll have to add an additional class to the range of bot:instanceOf, e.g. bot:ElementType. In this way, you could query for all object types, even the ones that are unassigned to real elements. You can use a similar approach for defining types of spaces?

MadsHolten commented 6 years ago

The approach is similar to skos:generalizes and skos:specializes. It might be that we can just define ex:OfficeTypeA as an owl:Class, but I am not sure if this is the right approach. @maximelefrancois86, do you have any thoughts on this? The space type is itself also an instance of bot:Space as we have defined that it can be used to define conceptual spaces, so there I start to see the mess.

PRODUCT specifies general classes such as prod:Wall but not project specific classes such as ex:SandwichWallConcreteMineralWoolConcreteType2, so defining it as an extension would make very little sense. In fact any of the types I would like to describe are types that only exist at project level, and this is why I would like to describe them at ABox level.

We could have range bot:Type to implement this mechanism indeed. That would be useful.

MadsHolten commented 6 years ago

What I am asking in short: Is it wrong to assign props-properties to an owl:Class? If not, then I agree that one can just create TBox level concepts at project level.

pipauwel commented 6 years ago

I am not a fan of describing types in the ABox. I have never been in favor, because that is what a TBox is for (rdf:type). Import and extend the ontology... Putting TBox types and instances in the ABox leads to what it is now in IFC, and I don't think that works. More information on how this is now done in IFC can be found in https://www.researchgate.net/publication/272816988_Towards_an_Ontological_Grounding_of_IFC? (Fig. 2 and 3).


Van: Mads Holten Rasmussen notifications@github.com Verzonden: vrijdag 15 juni 2018 13:25 Aan: w3c-lbd-cg/bot CC: Pieter Pauwels; Assign Onderwerp: Re: [w3c-lbd-cg/bot] Defining properties at type level (#29)

What I am asking in short: Is it wrong to assign props-properties to an owl:Class? If not, then I agree that one can just create TBox level concepts at project level.

- You are receiving this because you were assigned. Reply to this email directly, view it on GitHubhttps://github.com/w3c-lbd-cg/bot/issues/29#issuecomment-397592207, or mute the threadhttps://github.com/notifications/unsubscribe-auth/ABjr0sJIu0KV4-c90NtvVXczCpMPzYkTks5t85mxgaJpZM4UmKks.

maximelefrancois86 commented 6 years ago

Describing ex:ZoneWithAreaOf10m2 as a Class in the TBox would look like this:

ex:WallWithWidthOf10cm a owl:Class ;
  rdfs:subClassOf [ a owl:Restriction ; owl:onProperty ex:width ; owl:hasValue "10 cm"^^cdt:length ] .

This makes sense, and a OWL reasoner (e.g., HermiT) will be able infer that an instance of that class has a width of 10cm.

But you need to be sure you understand what you're doing here:

maximelefrancois86 commented 6 years ago

To be honest, I think we did made the decision during LDAC 2017 to mimic what has been done in the GoodRelations vocabulary: cf. slide 3 at https://drive.google.com/drive/folders/1p0AHsedMPW146Uw7dtzkq5eHrNG5TI_X

So why not define in the Product ontology:

Then it's easy to imagine SPARQL rules to mimic default inheritance of some properties. In fact, let's also assume we define two object properties in the product ontology:

product:defaultInheritedProperty a owl:ObjectProperty ;
  rdfs:comment "links a generic element to one of the L1 properties (ObjectProperties) of which the value should be inherited by product:IndividualElement that inherit from this generic element" ;
  rdfs:domain product:GenericElement .

product:inheritsFrom a owl:ObjectProperty ;
  rdfs:comment "links a individual element to the generic element, some property values of which it will inherit by default (unless explicit value overrides this default value)" ;
  rdfs:domain product:IndividualElement ;
  rdfs:range product:GenericElement .

What we could do is define a single SPARQL Construct query to define the "default inheritance mechanism":

CONSTRUCT {

?individualElement ?property ?defaultValue .

} WHERE {

?genericElement a product:GenericElement ;
  ?property ?defaultValue;
  product:defaultInheritedProperty ?property .

?individualElement a product:IndividualElement ;
  product:inheritsFrom ?genericElement .

NOT EXISTS { ?individualElement ?property ?value . }
}

Therefore, applying this rule on the following ABox:

ex:WallWithDefaultWidthOf10cm a product:GenericElement ;
  ex:width "10 cm"^^cdt:length ;
  product:defaultInheritedProperty ex:width .

<wall1245> a product:IndividualElement ;
  product:inheritsFrom ex:WallWithDefaultWidthOf10cm .

<wall1246> a product:IndividualElement ;
  ex:width "10.65 cm"^^cdt:length ;
  product:inheritsFrom ex:WallWithDefaultWidthOf10cm .

One would obtain one additional triple:

<wall1245>   ex:width "10 cm"^^cdt:length .

(We just play here with OWL 2 punning, using the same identifier ex:width for an ObjectProperty, and an Individual. The W3C Data Cube vocabulary also uses this kind of trick https://www.w3.org/TR/vocab-data-cube/#outline )

MadsHolten commented 6 years ago

I did some tests with the OWL restriction approach, and actually I feel like this is maybe not such a bad approach. It works with L1, L2 and L3 properties (tested in Stardog w. reasoning)

@prefix ex:   <http://example.org/ex#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix inst: <http://example.org/inst#> .
@prefix schema: <http://schema.org/> .
@prefix prov: <http://www.w3.org/ns/prov#> .
@prefix owl:  <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix opm:  <https://www.w3id.org/opm#> .
@prefix cdt:  <http://w3id.org/lindt/custom_datatypes#> .

ex:WallWithWidthOf10cm a owl:Class ;
  rdfs:subClassOf [ a owl:Restriction ; owl:onProperty ex:thickness ; owl:hasValue "20 mm"^^cdt:length ] ;             #L1
  rdfs:subClassOf [ a owl:Restriction ; owl:onProperty ex:width ; owl:hasValue ex:widthPropOfWallWithWidthOf10cm ] ;   #L2
  rdfs:subClassOf [ a owl:Restriction ; owl:onProperty ex:height ; owl:hasValue ex:heightPropOfWallWithWidthOf10cm ] . #L3

# L2 property
ex:widthPropOfWallWithWidthOf10cm
   schema:hasValue "10 cm"^^cdt:ucum ;
   prov:wasAttributedWith ex:mhra .

# L3 property
ex:heightPropOfWallWithWidthOf10cm
   opm:hasPropertyState ex:heightPropOfWallWithWidthOf10cm_1 .
ex:heightPropOfWallWithWidthOf10cm_1
   a opm:CurrentPropertyState ;
   schema:hasValue "10 cm"^^cdt:ucum ;
   prov:wasAttributedWith ex:mhra .

ex:mhra a foaf:Person .

# INSTANCE
inst:wall_A a ex:WallWithWidthOf10cm .

SELECT * WHERE {inst:wall_A ?p ?o} returns the following (as expected):

inst:wall_A a ex:WallWithWidthOf10cm ;
   ex:thickness "20 mm"^^cdt:ucum ;
   ex:height ex:heightPropOfWallWithWidthOf10cm ;
   ex:width ex:widthPropOfWallWithWidthOf10cm .
pipauwel commented 6 years ago

I am in favor of that last approach as well. It would be good to make the ontologies specific (Wall, width, ConcreteSlab, ThermalResistance), rather than making them rather generic (hasProperty, GenericElement, DefaultValue, ...).

And, I think this discussion should be moved to the product ontology repository.

mathib commented 6 years ago

I think the most appropriate approach depends if there should be a functionality to override properties of Abox instances of the types (= inheritance mechanism). It is not possible in the OWL restrictions approach, but maybe it is not really necessary as users can change the values in the Tbox (modifying the properties of the existing class OR creating a new class).

Another issue is the efficiency of both approaches (and the inheritance mechanism in the first approach - if applicable) regarding querying (modifying and finding properties). This needs more research, before we can take a good decision.

Regarding the inheritance mechanism: If you would have multiple hierarchical layers of Abox types (instances of product:GenericElement), it becomes very cumbersome to do the inheritance with SPARQL. See tab 6 and subtabs for an older example regarding space types in Abox: https://madsholten.github.io/sparql-visualizer. The example is not up to date anymore, but the querying mechanism for inheritance would probably be similar in our case if there would be a hierarchical system of such Abox types...

Regarding the other proposal with OWL restrictions, I was wondering if some inheritance of properties could be done by defining subclasses. This will infer two times the same property but with different values, so care has to be taken that a certain property is only defined on one level.

@prefix ex:   <http://example.org/ex#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix inst: <http://example.org/inst#> .
@prefix schema: <http://schema.org/> .
@prefix prov: <http://www.w3.org/ns/prov#> .
@prefix owl:  <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix opm:  <https://www.w3id.org/opm#> .
@prefix cdt:  <http://w3id.org/lindt/custom_datatypes#> .

ex:WallWithWidthOf10cm a owl:Class ;
  rdfs:subClassOf [ a owl:Restriction ; owl:onProperty ex:thickness ; owl:hasValue "20 mm"^^cdt:length ] ;             #L1
  rdfs:subClassOf [ a owl:Restriction ; owl:onProperty ex:width ; owl:hasValue ex:widthPropOfWallWithWidthOf10cm ] ;   #L2
  rdfs:subClassOf [ a owl:Restriction ; owl:onProperty ex:height ; owl:hasValue ex:heightPropOfWallWithWidthOf10cm ] . #L3

ex:subclThickness30 rdfs:subClassOf ex:WallWithWidthOf10cm ; a owl:Class ;
  rdfs:subClassOf [ a owl:Restriction ; owl:onProperty ex:thickness ; owl:hasValue "30 mm"^^cdt:length ] ;             #L1
  rdfs:subClassOf [ a owl:Restriction ; owl:onProperty ex:material ; owl:hasValue ex:bricks ] .   #L1

# L2 property
ex:widthPropOfWallWithWidthOf10cm
   schema:hasValue "10 cm"^^cdt:ucum ;
   prov:wasAttributedWith ex:mhra .

# L3 property
ex:heightPropOfWallWithWidthOf10cm
   opm:hasPropertyState ex:heightPropOfWallWithWidthOf10cm_1 .
ex:heightPropOfWallWithWidthOf10cm_1
   a opm:CurrentPropertyState ;
   schema:hasValue "10 cm"^^cdt:ucum ;
   prov:wasAttributedWith ex:mhra .

ex:mhra a foaf:Person .

# INSTANCE
inst:wall_A a ex:subclThickness30 .

SELECT * WHERE {inst:wall_A ?p ?o} gives the following results:

inst:wall_A a ex:subclThickness30 , ex:WallWithWidthOf10cm ;
   ex:thickness "20 mm"^^cdt:ucum  .
   ex:thickness "30 mm"^^cdt:ucum  .
   ex:material ex:bricks .
   ex:width ex:widthPropOfWallWithWidthOf10cm .
   ex:height ex:heightPropOfWallWithWidthOf10cm .
maximelefrancois86 commented 6 years ago

Regarding the other proposal with OWL restrictions, I was wondering if some inheritance of properties could be done by defining subclasses. This will infer two times the same property but with different values, so care has to be taken that a certain property is only defined on one level.

That's it, no default inheritance mechanism of any kid is possible with Description Logics...

If you would have multiple hierarchical layers of Abox types (instances of product:GenericElement), it becomes very cumbersome to do the inheritance with SPARQL.

with just the product:defaultInheritedProperty and product:inheritsFrom properties, the following query would do the job just fine, and end at some point. One should just check there is no inheritance cycle

CONSTRUCT {

?individualElement ?property ?defaultValue .

} WHERE {

?genericElement 
  ?property ?defaultValue;
  product:defaultInheritedProperty ?property .

?individualElement 
  product:inheritsFrom ?genericElement .

NOT EXISTS { ?individualElement ?property ?value . }
}
mathib commented 6 years ago

When using the method with Abox types for inheriting properties from a hierarchy of genericElements, the domain of product:defaultInheritedProperty has to be removed, as a genericElement can inherit properties from another genericElement.

The SPARQL query to inherit properties has to be slightly modified (INSERT instead of CONSTRUCT):

INSERT {
     ?individualElement ?property ?defaultValue ; 
          product:defaultInheritedProperty ?property .  # has to be added
} WHERE {
     ?genericElement ?property ?defaultValue ;
          product:defaultInheritedProperty ?property .
     ?individualElement product:inheritsFrom ?genericElement .

     FILTER NOT EXISTS { ?individualElement ?property ?value . }
}

This INSERT has to be executed multiple times, according to the number of hierarchical genericElements:

SELECT (count(?mid) as ?length)
WHERE {
    ?start a product:GenericElement .
    FILTER NOT EXISTS { ?start product:inheritsFrom ?otherGenericElement }
    OPTIONAL {
    ?end a product:IndividualElement .
    ?end product:inheritsFrom+ ?mid .
    ?mid product:inheritsFrom* ?start .
    }
}

GROUP BY ?start ?end

# only return highest path lenth
ORDER BY DESC(?length) LIMIT 1

Same mechanism can be used for product:ManufacturerElement, but then the range/domain has to be removed of the extra PRODUCT properties product:inheritsFrom (range) and product:defaultInheritedProperty (domain).

GeorgFerdinandSchneider commented 4 years ago

This discussion seems to be ended. The issue can be reopened if needed.