@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix sh:      <http://www.w3.org/ns/shacl#> .
@prefix xsd:     <http://www.w3.org/2001/XMLSchema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix skos:    <http://www.w3.org/2004/02/skos/core#> .
@prefix skosxl:  <http://www.w3.org/2008/05/skos-xl#> .
@prefix smart:   <https://w3id.org/standards/smart/ontologies/core/> .
@prefix isq: <https://w3id.org/standards/isq/ontologies/core/> .

##

# Quantity: physical quantity, typed as isq:Quantity + smart:TermEntry

isq:QuantityShape
    a sh:NodeShape ;
    sh:targetClass isq:Quantity ;
    sh:property [
        sh:path rdf:type ;
        sh:hasValue smart:TermEntry ;
        sh:minCount 2 ;
    ] ;
    sh:property [
        sh:path dcterms:identifier ;
        sh:datatype xsd:string ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
    ] ;
    sh:property [
        sh:path skosxl:prefLabel ;
        sh:nodeKind sh:IRI ;
        sh:class smart:Term ;
        sh:minCount 1 ;
    ] ;
    sh:property [
        sh:path skosxl:altLabel ;
        sh:nodeKind sh:IRI ;
        sh:class smart:Term ;
    ] ;
    sh:property [
        sh:path skos:definition ;
        sh:datatype rdf:langString ;
        sh:minCount 1 ;
        sh:uniqueLang true ;
    ] ;
    sh:property [
        sh:path skos:note ;
        sh:datatype rdf:langString ;
    ] ;
    sh:property [
        sh:path isq:hasUnit ;
        sh:nodeKind sh:IRI ;
        sh:class isq:Unit ;
    ] ;
    sh:property [
        sh:path isq:hasDimension ;
        sh:nodeKind sh:IRI ;
        sh:class isq:Dimension ;
        sh:maxCount 1 ;
    ] ;
    sh:property [
        sh:path smart:hasBindingnessType ;
        sh:nodeKind sh:IRI ;
        sh:class smart:BindingnessType ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
    ] ;
    sh:property [
        sh:path dcterms:isPartOf ;
        sh:nodeKind sh:IRI ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
    ] ;
.

# Unit: unit of measurement

isq:UnitShape
    a sh:NodeShape ;
    sh:targetClass isq:Unit ;
    sh:property [
        sh:path rdf:type ;
        sh:hasValue smart:TermEntry ;
        sh:minCount 2 ;
    ] ;
    sh:property [
        sh:path skos:prefLabel ;
        sh:datatype rdf:langString ;
        sh:minCount 1 ;
        sh:uniqueLang true ;
    ] ;
    sh:property [
        sh:path skos:notation ;
        sh:datatype xsd:string ;
        sh:minCount 1 ;
    ] ;
    sh:property [
        sh:path smart:hasBindingnessType ;
        sh:nodeKind sh:IRI ;
        sh:class smart:BindingnessType ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
    ] ;
.

# MathConcept: mathematical concept, typed as isq:MathConcept + smart:TermEntry

isq:MathConceptShape
    a sh:NodeShape ;
    sh:targetClass isq:MathConcept ;
    sh:property [
        sh:path rdf:type ;
        sh:hasValue smart:TermEntry ;
        sh:minCount 2 ;
    ] ;
    sh:property [
        sh:path dcterms:identifier ;
        sh:datatype xsd:string ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
    ] ;
    sh:property [
        sh:path skosxl:prefLabel ;
        sh:nodeKind sh:IRI ;
        sh:class smart:Term ;
        sh:minCount 1 ;
    ] ;
    sh:property [
        sh:path skosxl:altLabel ;
        sh:nodeKind sh:IRI ;
        sh:class smart:Term ;
    ] ;
    sh:property [
        sh:path skos:definition ;
        sh:datatype rdf:langString ;
        sh:minCount 1 ;
        sh:uniqueLang true ;
    ] ;
    sh:property [
        sh:path skos:note ;
        sh:datatype rdf:langString ;
    ] ;
    sh:property [
        sh:path smart:hasBindingnessType ;
        sh:nodeKind sh:IRI ;
        sh:class smart:BindingnessType ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
    ] ;
    sh:property [
        sh:path dcterms:isPartOf ;
        sh:nodeKind sh:IRI ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
    ] ;
.

# Term: each designation/symbol is a smart:Term with skosxl:literalForm

smart:TermShape
    a sh:NodeShape ;
    sh:targetClass smart:Term ;
    sh:property [
        sh:path rdf:type ;
        sh:hasValue skosxl:Label ;
        sh:minCount 2 ;
    ] ;
    sh:property [
        sh:path skosxl:literalForm ;
        sh:datatype rdf:langString ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
    ] ;
    sh:property [
        sh:path smart:hasTermFormType ;
        sh:nodeKind sh:IRI ;
        sh:class smart:TermFormType ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
    ] ;
.

# PublicationDocument instances for ISO/IEC 80000 parts

isq:PartDocumentShape
    a sh:NodeShape ;
    sh:targetObjectsOf dcterms:isPartOf ;
    sh:class smart:PublicationDocument ;
    sh:property [
        sh:path rdf:type ;
        sh:hasValue smart:PublicationDocument ;
        sh:minCount 1 ;
    ] ;
    sh:property [
        sh:path dcterms:title ;
        sh:datatype rdf:langString ;
        sh:minCount 1 ;
    ] ;
    sh:property [
        sh:path smart:hasPublicationType ;
        sh:nodeKind sh:IRI ;
        sh:class smart:PublicationDocumentType ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
    ] ;
    sh:property [
        sh:path smart:hasBindingnessType ;
        sh:nodeKind sh:IRI ;
        sh:class smart:BindingnessType ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
    ] ;
.

# hasUnit property constraint (must point to Unit)

isq:HasUnitShape
    a sh:PropertyShape ;
    sh:targetSubjectsOf isq:hasUnit ;
    sh:path isq:hasUnit ;
    sh:nodeKind sh:IRI ;
    sh:class isq:Unit ;
.

# Dimension: dimensional domain grouping quantities of the same kind

isq:DimensionShape
    a sh:NodeShape ;
    sh:targetClass isq:Dimension ;
    sh:property [
        sh:path rdf:type ;
        sh:hasValue smart:TermEntry ;
        sh:minCount 2 ;
    ] ;
    sh:property [
        sh:path dcterms:identifier ;
        sh:datatype xsd:string ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
    ] ;
    sh:property [
        sh:path skos:prefLabel ;
        sh:datatype rdf:langString ;
        sh:minCount 1 ;
        sh:uniqueLang true ;
    ] ;
    sh:property [
        sh:path skos:definition ;
        sh:datatype rdf:langString ;
        sh:minCount 1 ;
        sh:uniqueLang true ;
    ] ;
.

# hasDimension property constraint (must point to Dimension)

isq:HasDimensionShape
    a sh:PropertyShape ;
    sh:targetSubjectsOf isq:hasDimension ;
    sh:path isq:hasDimension ;
    sh:nodeKind sh:IRI ;
    sh:class isq:Dimension ;
.

# KindOfQuantity: level-0 grouping of same-dimension quantities

isq:KindOfQuantityShape
    a sh:NodeShape ;
    sh:targetClass isq:KindOfQuantity ;
    sh:property [
        sh:path isq:hasMember ;
        sh:nodeKind sh:IRI ;
        sh:class isq:Quantity ;
    ] ;
    sh:property [
        sh:path skos:prefLabel ;
        sh:datatype rdf:langString ;
        sh:minCount 1 ;
        sh:uniqueLang true ;
    ] ;
    sh:property [
        sh:path skos:definition ;
        sh:datatype rdf:langString ;
        sh:minCount 1 ;
        sh:uniqueLang true ;
    ] ;
.

# EntityKind: level-1 category of entities that quantities characterize

isq:EntityKindShape
    a sh:NodeShape ;
    sh:targetClass isq:EntityKind ;
    sh:property [
        sh:path skos:prefLabel ;
        sh:datatype rdf:langString ;
        sh:minCount 1 ;
        sh:uniqueLang true ;
    ] ;
    sh:property [
        sh:path skos:definition ;
        sh:datatype rdf:langString ;
        sh:minCount 1 ;
        sh:uniqueLang true ;
    ] ;
.

# EntityConcept: level-2 entity type (e.g. rod)

isq:EntityConceptShape
    a sh:NodeShape ;
    sh:targetClass isq:EntityConcept ;
    sh:property [
        sh:path skos:prefLabel ;
        sh:datatype rdf:langString ;
        sh:minCount 1 ;
        sh:uniqueLang true ;
    ] ;
    sh:property [
        sh:path skos:definition ;
        sh:datatype rdf:langString ;
        sh:minCount 1 ;
        sh:uniqueLang true ;
    ] ;
.

# DedicatedQuantity: level-2 Sachgrösse — specializes a quantity, characterizes an entity

isq:DedicatedQuantityShape
    a sh:NodeShape ;
    sh:targetClass isq:DedicatedQuantity ;
    sh:property [
        sh:path isq:dedicatedTo ;
        sh:nodeKind sh:IRI ;
        sh:class isq:Quantity ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
    ] ;
    sh:property [
        sh:path isq:characterizes ;
        sh:nodeKind sh:IRI ;
        sh:class isq:EntityConcept ;
        sh:minCount 1 ;
    ] ;
    sh:property [
        sh:path skos:prefLabel ;
        sh:datatype rdf:langString ;
        sh:minCount 1 ;
        sh:uniqueLang true ;
    ] ;
    sh:property [
        sh:path skos:definition ;
        sh:datatype rdf:langString ;
        sh:minCount 1 ;
        sh:uniqueLang true ;
    ] ;
.

# QuantityInstantiation: level-3 particular of an entity instance at a time

isq:QuantityInstantiationShape
    a sh:NodeShape ;
    sh:targetClass isq:QuantityInstantiation ;
    sh:property [
        sh:path isq:instantiationOf ;
        sh:nodeKind sh:IRI ;
        sh:class isq:DedicatedQuantity ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
    ] ;
    sh:property [
        sh:path isq:instantiates ;
        sh:nodeKind sh:IRI ;
        sh:class smart:Entity ;
        sh:minCount 1 ;
    ] ;
    sh:property [
        sh:path isq:instantiatedAt ;
        sh:datatype xsd:dateTime ;
        sh:maxCount 1 ;
    ] ;
    sh:property [
        sh:path skos:prefLabel ;
        sh:datatype rdf:langString ;
        sh:minCount 1 ;
        sh:uniqueLang true ;
    ] ;
.

# MeasuredQuantity: quantity as measured, Qm = {Q}·[Q]

isq:MeasuredQuantityShape
    a sh:NodeShape ;
    sh:targetClass isq:MeasuredQuantity ;
    sh:property [
        sh:path isq:measurementOf ;
        sh:nodeKind sh:IRI ;
        sh:class isq:QuantityInstantiation ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
    ] ;
    sh:property [
        sh:path isq:hasValue ;
        sh:datatype xsd:decimal ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
    ] ;
    sh:property [
        sh:path isq:hasUnit ;
        sh:nodeKind sh:IRI ;
        sh:class isq:Unit ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
    ] ;
    sh:property [
        sh:path isq:uncertainty ;
        sh:datatype xsd:decimal ;
        sh:maxCount 1 ;
    ] ;
    sh:property [
        sh:path isq:measuredAt ;
        sh:datatype xsd:dateTime ;
        sh:maxCount 1 ;
    ] ;
    sh:property [
        sh:path skos:prefLabel ;
        sh:datatype rdf:langString ;
        sh:minCount 1 ;
        sh:uniqueLang true ;
    ] ;
.

# hasKind property constraint (must point to a KindOfQuantity)

isq:HasKindShape
    a sh:PropertyShape ;
    sh:targetSubjectsOf isq:hasKind ;
    sh:path isq:hasKind ;
    sh:nodeKind sh:IRI ;
    sh:class isq:KindOfQuantity ;
.
