@prefix : <https://ontology.inferal.com/modules/ontology-discovery/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .

:DiscoveryTopicShape
    a sh:NodeShape ;
    rdfs:label "discovery topic shape" ;
    rdfs:comment "Validates named discovery topics, their human semantics, scheme membership, and shallow hierarchy." ;
    sh:targetClass :DiscoveryTopic ;
    sh:nodeKind sh:IRI ;
    sh:class skos:Concept ;
    sh:property [
        sh:path rdfs:label ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
    ] ;
    sh:property [
        sh:path rdfs:comment ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
    ] ;
    sh:property [
        sh:path skos:prefLabel ;
        sh:languageIn ( "en" ) ;
        sh:uniqueLang true ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
    ] ;
    sh:property [
        sh:path skos:definition ;
        sh:languageIn ( "en" ) ;
        sh:uniqueLang true ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
    ] ;
    sh:property [
        sh:path skos:inScheme ;
        sh:hasValue :DiscoveryTopics ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
    ] ;
    sh:property [
        sh:path skos:broader ;
        sh:class :DiscoveryTopic ;
        sh:maxCount 1 ;
    ] ;
    sh:property [
        sh:path skos:topConceptOf ;
        sh:in ( :DiscoveryTopics ) ;
        sh:maxCount 1 ;
    ] ;
    sh:sparql [
        sh:message "A discovery topic must be either a declared top concept or have one broader topic, but not both." ;
        sh:select """
            PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
            SELECT $this WHERE {
                {
                    FILTER NOT EXISTS { $this skos:topConceptOf ?scheme }
                    FILTER NOT EXISTS { $this skos:broader ?broader }
                }
                UNION
                {
                    $this skos:topConceptOf ?scheme ;
                        skos:broader ?broader .
                }
            }
        """ ;
    ] ;
    sh:sparql [
        sh:message "A discovery topic hierarchy must not contain a skos:broader cycle." ;
        sh:select """
            PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
            SELECT $this WHERE {
                $this skos:broader+ $this .
            }
        """ ;
    ] .

:DiscoveryTopicSchemeShape
    a sh:NodeShape ;
    rdfs:label "discovery topic scheme shape" ;
    rdfs:comment "Validates the identity and declared top concepts of the ontology discovery scheme." ;
    sh:targetNode :DiscoveryTopics ;
    sh:class skos:ConceptScheme ;
    sh:property [
        sh:path skos:prefLabel ;
        sh:languageIn ( "en" ) ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
    ] ;
    sh:property [
        sh:path skos:definition ;
        sh:languageIn ( "en" ) ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
    ] ;
    sh:property [
        sh:path skos:hasTopConcept ;
        sh:class :DiscoveryTopic ;
        sh:minCount 1 ;
    ] .
