@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix metrology: <http://iupac.org/metrology#> .

# The namespace for metrology shacl shapes.
@prefix metrology-shapes: <http://iupac.org/metrology/metrology-shapes#> .

# The following defines `metrology-shapes` as the ontology for sh:declare prefixes to be added to each SPARQL query.
metrology-shapes:
	a owl:Ontology ;
	owl:imports sh: ;
	sh:declare [
		sh:prefix "metrology" ;
		sh:namespace "http://iupac.org/metrology#"^^xsd:anyURI ;
	] ;
	sh:declare [
		sh:prefix "owl" ;
		sh:namespace "http://www.w3.org/2002/07/owl#"^^xsd:anyURI ;
	] ;
	sh:declare [
		sh:prefix "rdf" ;
		sh:namespace "http://www.w3.org/1999/02/22-rdf-syntax-ns#"^^xsd:anyURI ;
	] .
	
metrology-shapes:Every-Quantity-characterizes-some-Object
  a sh:NodeShape ;
  sh:targetClass metrology:Quantity ;
  sh:sparql [
    a sh:SPARQLConstraint ;
    sh:message "{$this}, a metrology:Quantity, must be a quantity for some metrology:Object." ;
    sh:prefixes metrology-shapes: ;
    sh:select """
      SELECT DISTINCT $this
      WHERE {
        $this rdf:type metrology:Quantity .
        FILTER NOT EXISTS {
          $this metrology:isQuantityOf ?o .
          ?o rdf:type metrology:Object .
        }
      }
    """ ;
  ] ;
  sh:closed false .

metrology-shapes:Every-QuantityValue-has-Number
  a sh:NodeShape ;
  sh:targetClass metrology:QuantityValue ;
  sh:sparql [
    a sh:SPARQLConstraint ;
    sh:message "{$this}, a metrology:QuantityValue, must have a number via metrology:hasDoubleNumber." ;
    sh:prefixes metrology-shapes: ;
    sh:select """
      SELECT DISTINCT $this
      WHERE {
        $this rdf:type metrology:QuantityValue .
        FILTER NOT EXISTS {
          $this metrology:hasDoubleNumber ?value .
        }
      }
    """ ;
  ] ;
  sh:closed false .

metrology-shapes:Every-QuantityValue-has-Reference
  a sh:NodeShape ;
  sh:targetClass metrology:QuantityValue ;
  sh:sparql [
    a sh:SPARQLConstraint ;
    sh:message "{$this}, a metrology:QuantityValue, must have a number via metrology:hasReference." ;
    sh:prefixes metrology-shapes: ;
    sh:select """
      SELECT DISTINCT $this
      WHERE {
        $this rdf:type metrology:QuantityValue .
        FILTER NOT EXISTS {
          $this metrology:hasReference ?ref .
        }
      }
    """ ;
  ] ;
  sh:closed false .

metrology-shapes:Every-UnitaryQuantity-has-UnitaryKindOfQuantity
  a sh:NodeShape ;
  sh:targetClass metrology:UnitaryQuantity ;
  sh:sparql [
    a sh:SPARQLConstraint ;
    sh:message "{$this}, a metrology:UnitaryQuantity, must have a metrology:UnitaryKindOfQuantity." ;
    sh:prefixes metrology-shapes: ;
    sh:select """
      SELECT DISTINCT $this
      WHERE {
        $this rdf:type metrology:UnitaryQuantity .
        FILTER NOT EXISTS {
          $this metrology:hasKindOfQuantity ?qk .
          ?qk rdf:type metrology:UnitaryKindOfQuantity .
        }
      }
    """ ;
  ] ;
  sh:closed false .

metrology-shapes:Every-UnitaryQuantity-hasMagnitude-UnitaryQuantityValue
  a sh:NodeShape ;
  sh:targetClass metrology:UnitaryQuantity ;
  sh:sparql [
    a sh:SPARQLConstraint ;
    sh:message "{$this}, a metrology:UnitaryQuantity, must have a magnitue of a metrology:UnitaryQuantityValue." ;
    sh:prefixes metrology-shapes: ;
    sh:select """
      SELECT DISTINCT $this
      WHERE {
        $this rdf:type metrology:UnitaryQuantity .
        FILTER NOT EXISTS {
          $this metrology:hasMagnitude ?uqv .
          ?uqv rdf:type metrology:UnitaryQuantityValue .
        }
      }
    """ ;
  ] ;
  sh:closed false .
