GRValidator Implemented E16

Error 16

E16: Check that certain properties should be used only once for the same object (i.e. the max. cardinality is 1). However, this is not formally specified in the ontology --> Object properties

Validator Tool: Step # 28

Error Message

Cardinalities must follow the specification of GoodRelations Ontology.

Potential Problem

Care must be taken that cardinalities in object properties (from a class to a class) follow the prime suggestions.

Examples of Wrong Data

No gr:hasBusinessFunction is included (According to the GR prime: hasBusinessFunction (1..*), at least one should be specified, validation # 7 in the SPARQL section)

@prefix gr: <http://purl.org/goodrelations/v1#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix toy: <http://www.heppnetz.de/ontologies/examples/toy#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
<http://www.heppnetz.de/ontologies/examples/gr> rdf:type owl:Ontology ;
    owl:imports <http://www.heppnetz.de/ontologies/examples/toy> ,
        <http://purl.org/goodrelations/v1> .
<http://www.heppnetz.de/ontologies/examples/gr#Offering_1> rdf:type gr:Offering .
<http://www.heppnetz.de/ontologies/examples/gr#UnitPriceSpecification_1> rdf:type gr:UnitPriceSpecification ;
    gr:hasCurrency "COP"^^<http://www.w3.org/2001/XMLSchema#string> ;
    gr:hasCurrencyValue "550.0"^^<http://www.w3.org/2001/XMLSchema#float> .
<http://www.heppnetz.de/ontologies/examples/gr#Offering_1> gr:hasPriceSpecification
<http://www.heppnetz.de/ontologies/examples/gr#UnitPriceSpecification_1> .
<http://www.heppnetz.de/ontologies/examples/gr#UnitPriceSpecification_2> rdf:type gr:UnitPriceSpecification ;
    gr:hasCurrency "COP"^^<http://www.w3.org/2001/XMLSchema#string> ;
    gr:hasCurrencyValue "450.0"^^<http://www.w3.org/2001/XMLSchema#float> .
<http://www.heppnetz.de/ontologies/examples/gr#Offering_1> gr:hasPriceSpecification
<http://www.heppnetz.de/ontologies/examples/gr#UnitPriceSpecification_2> .
<http://www.heppnetz.de/ontologies/examples/gr#DeliveryChargeSpecification_1> rdf:type gr:DeliveryChargeSpecification ;
    gr:hasMinCurrencyValue "100.0"^^<http://www.w3.org/2001/XMLSchema#float> ;
    gr:hasMaxCurrencyValue "400.0"^^<http://www.w3.org/2001/XMLSchema#float> .
<http://www.heppnetz.de/ontologies/examples/gr#Offering_1> gr:hasPriceSpecification
<http://www.heppnetz.de/ontologies/examples/gr#DeliveryChargeSpecification_1> .

SPARQL Query

PREFIX gr:<http://purl.org/goodrelations/v1#>

SELECT ?object
WHERE
{
# 3. appliesToPaymentMethod (1..*), count >= 1 is OK, check count < 1
  {
    ?object a gr:PaymentChargeSpecification .
    FILTER (1 > (
      SELECT count(?appliesToPaymentMethod)
      WHERE {
          ?object gr:appliesToPaymentMethod ?appliesToPaymentMethod
      }
    ))
  }
# 7. hasBusinessFunction (1..*), count >= 1 is OK, check count < 1
  {
    ?object a gr:Offering .
    FILTER (1 > (
      SELECT count(?hasBusinessFunction)
      WHERE {
          ?object gr:hasBusinessFunction ?hasBusinessFunction
      }
    ))
  }
# 8. hasEligibleQuantity (0..1), count = 0 and count = 1 is OK, check count >= 2
  UNION {
    ?object a gr:PriceSpecification .
    FILTER (2 <= (
      SELECT count(?hasEligibleQuantity)
      WHERE {
          ?object gr:hasEligibleQuantity ?hasEligibleQuantity
      }
    ))
  } UNION {
    ?object a gr:DeliveryChargeSpecification .
    FILTER (2 <= (
      SELECT count(?hasEligibleQuantity)
      WHERE {
          ?object gr:hasEligibleQuantity ?hasEligibleQuantity
      }
    ))
  } UNION {
    ?object a gr:PaymentChargeSpecification .
    FILTER (2 <= (
      SELECT count(?hasEligibleQuantity)
      WHERE {
          ?object gr:hasEligibleQuantity ?hasEligibleQuantity
      }
    ))
  } UNION {
    ?object a gr:UnitPriceSpecification .
    FILTER (2 <= (
      SELECT count(?hasEligibleQuantity)
      WHERE {
          ?object gr:hasEligibleQuantity ?hasEligibleQuantity
      }
    ))
  }
# 9. hasInventoryLevel (0..1), count = 0 and count = 1 is OK, check count >= 2
  UNION {
    ?object a gr:ProductOrServicesSomeInstancesPlaceholder .
    FILTER (2 <= (
      SELECT count(?hasInventoryLevel)
      WHERE {
          ?object gr:hasInventoryLevel ?hasInventoryLevel
      }
    ))
  }
# 10. hasMakeAndModel (0..1), count = 0 and count = 1 is OK, check count >= 2
  UNION {
    ?object a gr:ActualProductOrServiceInstance .
    FILTER (2 <= (
      SELECT count(?hasMakeAndModel)
      WHERE {
          ?object gr:hasMakeAndModel ?hasMakeAndModel
      }
    ))
  } UNION {
    ?object a gr:ProductOrServicesSomeInstancesPlaceholder .
    FILTER (2 <= (
      SELECT count(?hasMakeAndModel)
      WHERE {
          ?object gr:hasMakeAndModel ?hasMakeAndModel
      }
    ))
  }
# 11. hasManufacturer (0..1), count = 0 and count = 1 is OK, check count >= 2
  UNION {
    ?object a gr:ProductOrService .
    FILTER (2 <= (
      SELECT count(?hasManufacturer)
      WHERE {
          ?object gr:hasManufacturer ?hasManufacturer
      }
    ))
  } UNION {
    ?object a gr:ActualProductOrServiceInstance .
    FILTER (2 <= (
      SELECT count(?hasManufacturer)
      WHERE {
          ?object gr:hasManufacturer ?hasManufacturer
      }
    ))
  } UNION {
    ?object a gr:ProductOrServiceModel .
    FILTER (2 <= (
      SELECT count(?hasManufacturer)
      WHERE {
          ?object gr:hasManufacturer ?hasManufacturer
      }
    ))
  } UNION {
    ?object a gr:ProductOrServiceSomeInstancesPlaceholder .
    FILTER (2 <= (
      SELECT count(?hasManufacturer)
      WHERE {
          ?object gr:hasManufacturer ?hasManufacturer
      }
    ))
  }
# 12. hasOpeningHoursDayOfWeek (1..*), count >= 1 is OK, check count < 1
  UNION {
    ?object a gr:OpeningHoursSpecification .
    FILTER (1 > (
      SELECT count(?hasOpeningHoursDayOfWeek)
      WHERE {
          ?object gr:hasOpeningHoursDayOfWeek ?hasOpeningHoursDayOfWeek
      }
    ))
  }
# 17. hasWarrantyScope (0..1), count = 0 and count = 1 is OK, check count >= 2
  UNION {
    ?object a gr:WarrantyPromise .
    FILTER (2 <= (
      SELECT count(?hasWarrantyScope)
      WHERE {
          ?object gr:hasWarrantyScope ?hasWarrantyScope
      }
    ))
  }
# 18. includes (0..1), count = 0 and count = 1 is OK, check count >= 2
  UNION {
    ?object a gr:Offering .
    FILTER (2 <= (
      SELECT count(?includes)
      WHERE {
          ?object gr:includes ?includes
      }
    ))
  }
# 19. includesObject (1..*), count >= 1 is OK, check count < 1
  UNION {
    ?object a gr:Offering .
    FILTER (1 > (
      SELECT count(?includesObject)
      WHERE {
          ?object gr:includesObject ?includesObject
      }
    ))
  }
#23 isVariantOf(0..1) Domain? Range?, count = 0 and count = 1 is OK, check count >= 2
  UNION {
    ?object ?pred ?range .
    FILTER (2 <= (
      SELECT count(?isVariantOf)
      WHERE {
          ?object gr:isVariantOf ?isVariantOf
      }
    ))
  }
# 27. seeks (0..1), count = 0 and count = 1 is OK, check count >= 2
  UNION {
    ?object a gr:BusinessEntity .
    FILTER (2 <= (
      SELECT count(?seeks)
      WHERE {
          ?object gr:seeks ?seeks
      }
    ))
  }
# 28. typeOfGood (1..1), only count = 1 is OK, check count != 1
  UNION {
    ?object a gr:TypeAndQuantityNode .
    FILTER (1 != (
      SELECT count(?typeOfGood)
      WHERE {
          ?object gr:typeOfGood ?typeOfGood
      }
    ))
  }
}