@prefix owl:     <http://www.w3.org/2002/07/owl#> .
@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 skos:    <http://www.w3.org/2004/02/skos/core#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix bibo:    <http://purl.org/ontology/bibo/> .
@prefix cc:      <http://creativecommons.org/ns#> .
@prefix vann:    <http://purl.org/vocab/vann/> .
@prefix sh:      <http://www.w3.org/ns/shacl#> .
@prefix arch:    <https://meta.linked.archi/core#> .
@prefix am4vp:   <https://meta.linked.archi/archimate4/viewpoints#> .
@prefix :        <https://meta.linked.archi/archimate4/questions#> .

#################################################################
# Linked.Archi ArchiMate 4.0 Questions
#
# Questions ArchiMate 4.0 stakeholders ask of a model, bound to the
# concerns the ArchiMate 4.0 viewpoints frame (am4vp:ImpactOfChange,
# am4vp:Completeness …) and to the viewpoints they fit, so a modelling
# tool offers them beside an open view and a deliverable section asks
# them for a concern. Written as the core questions are (see
# arch:ModelQuestion).
#
# Domain membership is read from the ArchiMate 4.0 domain classes
# (am4:ApplicationDomainElement …). A set of types under a class is
# read once per query, in two steps — the types under it within each
# document, then their specialisations in any document — so a model's
# own specialisation of an ArchiMate type counts where that type does.
#################################################################

<https://meta.linked.archi/archimate4/questions#>
    a                             arch:QuestionSet ;
    cc:license                    "http://creativecommons.org/licenses/by/4.0/" ;
    vann:preferredNamespaceUri    "https://meta.linked.archi/archimate4/questions#" ;
    vann:preferredNamespacePrefix "am4q" ;
    dcterms:creator               "Kalin Maldzhanski"^^xsd:string ;
    dcterms:title                 "Linked.Archi ArchiMate 4.0 Questions"@en ;
    dcterms:description           '''Questions ArchiMate 4.0 stakeholders ask of a model — impact of change, application
dependencies, data access, responsibilities, realisation and traceability — and the findings that show where a
concern the ArchiMate 4.0 viewpoints frame is not met. Each is executable SPARQL (see arch:ModelQuestion).'''@en ;
    dcterms:created               "2026-10-27"^^xsd:date ;
    dcterms:modified              "2026-10-27"^^xsd:date ;
    dcterms:publisher             "Linked.Archi"@en, <https://linked.archi> ;
    bibo:status                   "draft" ;
    owl:versionInfo               "0.1.0" ;
    sh:declare
        [ sh:prefix "arch" ; sh:namespace "https://meta.linked.archi/core#"^^xsd:anyURI ],
        [ sh:prefix "rdf" ; sh:namespace "http://www.w3.org/1999/02/22-rdf-syntax-ns#"^^xsd:anyURI ],
        [ sh:prefix "rdfs" ; sh:namespace "http://www.w3.org/2000/01/rdf-schema#"^^xsd:anyURI ],
        [ sh:prefix "skos" ; sh:namespace "http://www.w3.org/2004/02/skos/core#"^^xsd:anyURI ],
        [ sh:prefix "am4" ; sh:namespace "https://meta.linked.archi/archimate4/onto#"^^xsd:anyURI ] ;
.

# ── Orientation ─────────────────────────────────────────────────

:elements-by-domain
    a                             arch:ModelQuestion, sh:SPARQLSelectExecutable ;
    dcterms:identifier            "notation/archimate4/elements-by-domain" ;
    skos:prefLabel                "How is the model spread over the ArchiMate domains?"@en ;
    dcterms:description           "Elements counted by ArchiMate 4.0 domain, read from the domain classes their types specialise, so specialisations count where they belong."@en ;
    arch:answers                  "One row per domain, with the number of elements in it."@en ;
    arch:doesNotProve             "Balance. Behaviour of the common domain (process, function, service, event, role …) is counted under am4:CommonDomainElement, because ArchiMate 4.0 gives it no domain of its own."@en ;
    arch:questionStage            arch:OrientationStage ;
    arch:questionAddressesConcern am4vp:ReductionOfComplexity, am4vp:Completeness ;
    arch:questionFitsViewpoint    am4vp:LayeredViewpoint ;
    arch:resultIsFinding          false ;
    arch:requiresDataset          arch:ModelAndMetamodelDataset ;
    arch:requiresMetamodel        <https://meta.linked.archi/archimate4/onto#> ;
    arch:resultKey                "domains" ;
    arch:defaultLimit             50 ;
    sh:parameter [ sh:path arch:model ; sh:name "model" ; sh:class arch:Model ; sh:optional true ; sh:order 1 ;
                   sh:description "The model to count. A modelling tool binds the open model; a deliverable, the model it is produced from."@en ] ;
    sh:prefixes                   <https://meta.linked.archi/archimate4/questions#> ;
    sh:select """
        SELECT ?domain (COUNT(DISTINCT ?element) AS ?elements)
        WHERE {
          # Each domain's types, read once.
          {
            SELECT DISTINCT ?domain ?type
            WHERE {
              VALUES ?domain {
                am4:StrategyElement am4:MotivationElement am4:BusinessDomainElement
                am4:ApplicationDomainElement am4:TechnologyDomainElement am4:ImplementationAndMigrationDomainElement
                am4:CommonDomainElement
              }
              { ?domainType rdfs:subClassOf* ?domain } UNION { GRAPH ?ontologyGraph { ?domainType rdfs:subClassOf* ?domain } }
              { ?type rdfs:subClassOf* ?domainType } UNION { GRAPH ?specialisationGraph { ?type rdfs:subClassOf* ?domainType } }
            }
          }
          ?element rdf:type ?type ;
                   arch:inModel ?model .
        }
        GROUP BY ?domain
        ORDER BY DESC(?elements)
    """ ;
.

# ── Analysis ────────────────────────────────────────────────────

:cross-domain-relationships
    a                             arch:ModelQuestion, sh:SPARQLSelectExecutable ;
    dcterms:identifier            "notation/archimate4/cross-domain-relationships" ;
    skos:prefLabel                "Which relationships cross domains, and of which kind?"@en ;
    dcterms:description           "Relationships whose ends are in different ArchiMate 4.0 domains, counted by pair of domains and relationship type. The domains are read from the domain classes, not from type names."@en ;
    arch:answers                  "One row per source domain, relationship type and target domain, with the number of relationships."@en ;
    arch:doesNotProve             "Coupling. Relationships touching elements of the common domain are not counted: ArchiMate 4.0 assigns those no domain, so whether they cross one is undefined."@en ;
    arch:questionStage            arch:AnalysisStage ;
    arch:questionAddressesConcern am4vp:Consistency, am4vp:ImpactOfChange ;
    arch:questionFitsViewpoint    am4vp:LayeredViewpoint ;
    arch:resultIsFinding          false ;
    arch:requiresDataset          arch:ModelAndMetamodelDataset ;
    arch:requiresMetamodel        <https://meta.linked.archi/archimate4/onto#> ;
    arch:resultKey                "crossings" ;
    arch:defaultLimit             200 ;
    sh:prefixes                   <https://meta.linked.archi/archimate4/questions#> ;
    sh:select """
        SELECT ?sourceDomain ?relationshipType ?targetDomain (COUNT(DISTINCT ?relationship) AS ?relationships)
        WHERE {
          ?relationship arch:source ?source ;
                        arch:target ?target ;
                        rdf:type ?relationshipType .
          FILTER(?relationshipType NOT IN (arch:ModelConcept, arch:Element, arch:QualifiedRelationship))
          MINUS { SELECT DISTINCT ?relationshipType WHERE { { ?relationshipType arch:isAbstractClass true }
                                                            UNION { GRAPH ?abstractClassGraph { ?relationshipType arch:isAbstractClass true } } } }
          ?source rdf:type ?sourceType .
          ?target rdf:type ?targetType .
          {
            SELECT DISTINCT ?sourceDomain ?sourceType
            WHERE {
              VALUES ?sourceDomain {
                am4:StrategyElement am4:MotivationElement am4:BusinessDomainElement
                am4:ApplicationDomainElement am4:TechnologyDomainElement am4:ImplementationAndMigrationDomainElement
              }
              { ?sourceDomainType rdfs:subClassOf* ?sourceDomain } UNION { GRAPH ?sourceOntologyGraph { ?sourceDomainType rdfs:subClassOf* ?sourceDomain } }
              { ?sourceType rdfs:subClassOf* ?sourceDomainType } UNION { GRAPH ?sourceSpecialisationGraph { ?sourceType rdfs:subClassOf* ?sourceDomainType } }
            }
          }
          {
            SELECT DISTINCT ?targetDomain ?targetType
            WHERE {
              VALUES ?targetDomain {
                am4:StrategyElement am4:MotivationElement am4:BusinessDomainElement
                am4:ApplicationDomainElement am4:TechnologyDomainElement am4:ImplementationAndMigrationDomainElement
              }
              { ?targetDomainType rdfs:subClassOf* ?targetDomain } UNION { GRAPH ?targetOntologyGraph { ?targetDomainType rdfs:subClassOf* ?targetDomain } }
              { ?targetType rdfs:subClassOf* ?targetDomainType } UNION { GRAPH ?targetSpecialisationGraph { ?targetType rdfs:subClassOf* ?targetDomainType } }
            }
          }
          FILTER(?sourceDomain != ?targetDomain)
        }
        GROUP BY ?sourceDomain ?relationshipType ?targetDomain
        ORDER BY DESC(?relationships)
    """ ;
.

:responsibility-assignments
    a                             arch:ModelQuestion, sh:SPARQLSelectExecutable ;
    dcterms:identifier            "notation/archimate4/responsibility-assignments" ;
    skos:prefLabel                "Who is responsible for what?"@en ;
    dcterms:description           "Assignment relationships: which actor, role, collaboration, component or node performs which behaviour or plays which role."@en ;
    arch:answers                  "One row per assignment, with both ends and their types."@en ;
    arch:doesNotProve             "Accountability in the RACI sense. An ArchiMate assignment states who performs, not who answers for the outcome."@en ;
    arch:questionStage            arch:AnalysisStage ;
    arch:questionAddressesConcern am4vp:CompetenciesAuthorityResponsibilities, am4vp:Responsibilities ;
    arch:questionTargetsStakeholder am4vp:ProcessArchitect, am4vp:Manager ;
    arch:questionFitsViewpoint    am4vp:OrganizationViewpoint, am4vp:ProcessCooperationViewpoint ;
    arch:resultIsFinding          false ;
    arch:requiresDataset          arch:ModelDataset ;
    arch:requiresMetamodel        <https://meta.linked.archi/archimate4/onto#> ;
    arch:resultKey                "assignments" ;
    arch:defaultLimit             500 ;
    sh:prefixes                   <https://meta.linked.archi/archimate4/questions#> ;
    sh:select """
        SELECT DISTINCT ?performer ?performerLabel ?performerType ?assignment ?assigned ?assignedLabel ?assignedType
        WHERE {
          ?assignment rdf:type am4:Assignment ;
                      arch:source ?performer ;
                      arch:target ?assigned .
          ?performer rdf:type ?performerType .
          ?assigned rdf:type ?assignedType .
          FILTER(?performerType NOT IN (arch:ModelConcept, arch:Element, arch:QualifiedRelationship))
          FILTER(?assignedType NOT IN (arch:ModelConcept, arch:Element, arch:QualifiedRelationship))
          MINUS { SELECT DISTINCT ?performerType WHERE { { ?performerType arch:isAbstractClass true }
                                                         UNION { GRAPH ?abstractClassGraph { ?performerType arch:isAbstractClass true } } } }
          MINUS { SELECT DISTINCT ?assignedType WHERE { { ?assignedType arch:isAbstractClass true }
                                                        UNION { GRAPH ?abstractClassGraph { ?assignedType arch:isAbstractClass true } } } }
          OPTIONAL { ?performer skos:prefLabel ?performerLabel . FILTER(lang(?performerLabel) = "" || langMatches(lang(?performerLabel), "en")) }
          OPTIONAL { ?assigned skos:prefLabel ?assignedLabel . FILTER(lang(?assignedLabel) = "" || langMatches(lang(?assignedLabel), "en")) }
        }
        ORDER BY ?performerLabel ?assignedLabel
    """ ;
.

:application-dependencies
    a                             arch:ModelQuestion, sh:SPARQLSelectExecutable ;
    dcterms:identifier            "notation/archimate4/application-dependencies" ;
    skos:prefLabel                "Which applications depend on which?"@en ;
    dcterms:description           "Application components that serve, flow to or trigger one another, directly or through a service one realises and the other is served by."@en ;
    arch:answers                  "One row per dependency: the provider, how it provides, the relationship or service between, and the consumer."@en ;
    arch:doesNotProve             "Runtime coupling or data volume. A modelled flow says that information moves, not how much or how often."@en ;
    arch:questionStage            arch:AnalysisStage ;
    arch:questionAddressesConcern am4vp:ApplicationDependencies, am4vp:ServiceOrchestration ;
    arch:questionFitsViewpoint    am4vp:ApplicationCooperationViewpoint, am4vp:ApplicationUsageViewpoint ;
    arch:resultIsFinding          false ;
    arch:requiresDataset          arch:ModelDataset ;
    arch:requiresMetamodel        <https://meta.linked.archi/archimate4/onto#> ;
    arch:resultKey                "applicationDependencies" ;
    arch:defaultLimit             500 ;
    sh:prefixes                   <https://meta.linked.archi/archimate4/questions#> ;
    sh:select """
        SELECT DISTINCT ?provider ?providerLabel ?how ?via ?consumer ?consumerLabel
        WHERE {
          # From the relationships to their ends, each branch checking its own: never every pair of components.
          {
            VALUES ?linkType { am4:Serving am4:Flow am4:Triggering }
            ?via rdf:type ?linkType ;
                 arch:source ?provider ;
                 arch:target ?consumer .
            ?provider rdf:type am4:ApplicationComponent .
            ?consumer rdf:type am4:ApplicationComponent .
            BIND(REPLACE(STR(?linkType), "^.*[#/]", "") AS ?how)
          }
          UNION
          {
            ?via rdf:type am4:Service ;
                 am4:serves ?consumer .
            ?consumer rdf:type am4:ApplicationComponent .
            ?provider am4:realizes ?via .
            ?provider rdf:type am4:ApplicationComponent .
            BIND("realises a service serving" AS ?how)
          }
          FILTER(?provider != ?consumer)
          OPTIONAL { ?provider skos:prefLabel ?providerLabel . FILTER(lang(?providerLabel) = "" || langMatches(lang(?providerLabel), "en")) }
          OPTIONAL { ?consumer skos:prefLabel ?consumerLabel . FILTER(lang(?consumerLabel) = "" || langMatches(lang(?consumerLabel), "en")) }
        }
        ORDER BY ?providerLabel ?consumerLabel
    """ ;
.

:data-access
    a                             arch:ModelQuestion, sh:SPARQLSelectExecutable ;
    dcterms:identifier            "notation/archimate4/data-access" ;
    skos:prefLabel                "Who reads and writes which information?"@en ;
    dcterms:description           "Access relationships by kind: ArchiMate 4.0 types the kind (am4:ReadAccess, am4:WriteAccess, am4:ReadWriteAccess, and am4:Access when it is not stated)."@en ;
    arch:answers                  "One row per access: what accesses, the kind of access, and the object accessed."@en ;
    arch:doesNotProve             "Ownership of the data. Write access is not mastery; arch:masterDataSource says where that is recorded."@en ;
    arch:questionStage            arch:AnalysisStage ;
    arch:questionAddressesConcern am4vp:InformationStructure, am4vp:Consistency ;
    arch:questionTargetsStakeholder am4vp:InformationArchitect ;
    arch:questionFitsViewpoint    am4vp:InformationStructureViewpoint, am4vp:ApplicationCooperationViewpoint ;
    arch:resultIsFinding          false ;
    arch:requiresDataset          arch:ModelDataset ;
    arch:requiresMetamodel        <https://meta.linked.archi/archimate4/onto#> ;
    arch:resultKey                "access" ;
    arch:defaultLimit             500 ;
    sh:prefixes                   <https://meta.linked.archi/archimate4/questions#> ;
    sh:select """
        SELECT DISTINCT ?accessor ?accessorLabel ?access ?accessKind ?object ?objectLabel ?objectType
        WHERE {
          VALUES ?accessKind { am4:Access am4:ReadAccess am4:WriteAccess am4:ReadWriteAccess }
          ?access rdf:type ?accessKind ;
                  arch:source ?accessor ;
                  arch:target ?object .
          ?object rdf:type ?objectType .
          FILTER(?objectType NOT IN (arch:ModelConcept, arch:Element, arch:QualifiedRelationship))
          MINUS { SELECT DISTINCT ?objectType WHERE { { ?objectType arch:isAbstractClass true }
                                                      UNION { GRAPH ?abstractClassGraph { ?objectType arch:isAbstractClass true } } } }
          OPTIONAL { ?accessor skos:prefLabel ?accessorLabel . FILTER(lang(?accessorLabel) = "" || langMatches(lang(?accessorLabel), "en")) }
          OPTIONAL { ?object skos:prefLabel ?objectLabel . FILTER(lang(?objectLabel) = "" || langMatches(lang(?objectLabel), "en")) }
        }
        ORDER BY ?objectLabel ?accessKind ?accessorLabel
    """ ;
.

:impact-of-change
    a                             arch:ModelQuestion, sh:SPARQLSelectExecutable ;
    dcterms:identifier            "notation/archimate4/impact-of-change" ;
    skos:prefLabel                "What is affected if this element changes?"@en ;
    dcterms:description           "Everything that depends on the element, transitively, by ArchiMate's dependency relationships: what it serves, realises or is assigned to, and what accesses it."@en ;
    arch:answers                  "One row per element that depends on the element, directly or through others."@en ;
    arch:doesNotProve             "That each is broken by the change. Dynamic relationships (flow, triggering) and structure (composition, aggregation) are not followed, and a dependency may tolerate the change."@en ;
    arch:questionStage            arch:AnalysisStage ;
    arch:questionAddressesConcern am4vp:ImpactOfChange, am4vp:Dependencies ;
    arch:questionTargetsStakeholder am4vp:EnterpriseArchitect, am4vp:ApplicationArchitect, am4vp:InfrastructureArchitect ;
    arch:questionFitsViewpoint    am4vp:LayeredViewpoint, am4vp:TechnologyUsageViewpoint, am4vp:ApplicationCooperationViewpoint ;
    arch:resultIsFinding          false ;
    arch:requiresDataset          arch:ModelDataset ;
    arch:requiresMetamodel        <https://meta.linked.archi/archimate4/onto#> ;
    arch:resultKey                "impacted" ;
    arch:defaultLimit             500 ;
    sh:parameter [ sh:path arch:focus ; sh:name "focus" ; sh:nodeKind sh:IRI ; sh:optional false ; sh:order 1 ;
                   sh:description "The element that changes. A modelling tool binds the selected element; a deliverable, the element it is produced for."@en ] ;
    sh:prefixes                   <https://meta.linked.archi/archimate4/questions#> ;
    sh:select """
        SELECT DISTINCT ?impacted ?label ?type
        WHERE {
          ?focus (am4:serves|am4:realizes|am4:assignedTo|^am4:accesses)+ ?impacted .
          FILTER(?impacted != ?focus)
          FILTER NOT EXISTS { ?impacted arch:source ?anySource }
          ?impacted rdf:type ?type .
          FILTER(?type NOT IN (arch:ModelConcept, arch:Element, arch:QualifiedRelationship))
          MINUS { SELECT DISTINCT ?type WHERE { { ?type arch:isAbstractClass true }
                                                UNION { GRAPH ?abstractClassGraph { ?type arch:isAbstractClass true } } } }
          OPTIONAL { ?impacted skos:prefLabel ?label . FILTER(lang(?label) = "" || langMatches(lang(?label), "en")) }
        }
        ORDER BY ?type ?label
    """ ;
.

:capability-realisation
    a                             arch:ModelQuestion, sh:SPARQLSelectExecutable ;
    dcterms:identifier            "notation/archimate4/capability-realisation" ;
    skos:prefLabel                "What realises each capability?"@en ;
    dcterms:description           "Capabilities with the behaviour, active structure or resources that realise them."@en ;
    arch:answers                  "One row per capability and what realises it; a capability nothing realises appears once, with nothing beside it."@en ;
    arch:doesNotProve             "Maturity. That a capability is realised says it is delivered somehow, not how well."@en ;
    arch:questionStage            arch:AnalysisStage ;
    arch:questionAddressesConcern am4vp:StrategyDevelopment, am4vp:ArchitectureStrategy ;
    arch:questionTargetsStakeholder am4vp:BusinessArchitect, am4vp:CxO ;
    arch:questionFitsViewpoint    am4vp:CapabilityMapViewpoint, am4vp:StrategyViewpoint ;
    arch:resultIsFinding          false ;
    arch:requiresDataset          arch:ModelDataset ;
    arch:requiresMetamodel        <https://meta.linked.archi/archimate4/onto#> ;
    arch:resultKey                "capabilities" ;
    arch:defaultLimit             500 ;
    sh:prefixes                   <https://meta.linked.archi/archimate4/questions#> ;
    sh:select """
        SELECT DISTINCT ?capability ?capabilityLabel ?realizer ?realizerLabel ?realizerType
        WHERE {
          ?capability rdf:type am4:Capability .
          OPTIONAL {
            ?realizer am4:realizes ?capability ;
                      rdf:type ?realizerType .
            FILTER(?realizerType NOT IN (arch:ModelConcept, arch:Element, arch:QualifiedRelationship))
            MINUS { SELECT DISTINCT ?realizerType WHERE { { ?realizerType arch:isAbstractClass true }
                                                          UNION { GRAPH ?abstractClassGraph { ?realizerType arch:isAbstractClass true } } } }
            OPTIONAL { ?realizer skos:prefLabel ?realizerLabel . FILTER(lang(?realizerLabel) = "" || langMatches(lang(?realizerLabel), "en")) }
          }
          OPTIONAL { ?capability skos:prefLabel ?capabilityLabel . FILTER(lang(?capabilityLabel) = "" || langMatches(lang(?capabilityLabel), "en")) }
        }
        ORDER BY ?capabilityLabel ?realizerLabel
    """ ;
.

:stakeholder-motivation
    a                             arch:ModelQuestion, sh:SPARQLSelectExecutable ;
    dcterms:identifier            "notation/archimate4/stakeholder-motivation" ;
    skos:prefLabel                "What do stakeholders care about?"@en ;
    dcterms:description           "Stakeholders and the motivation elements (drivers, assessments, goals, outcomes, principles, requirements, values, meanings) they are related to, in either direction."@en ;
    arch:answers                  "One row per relationship between a stakeholder and a motivation element."@en ;
    arch:doesNotProve             "Priority. That a stakeholder is associated with a goal does not rank it among their concerns."@en ;
    arch:questionStage            arch:AnalysisStage ;
    arch:questionAddressesConcern am4vp:ArchitectureMission, am4vp:Motivation ;
    arch:questionTargetsStakeholder am4vp:BusinessManager, am4vp:EnterpriseArchitect ;
    arch:questionFitsViewpoint    am4vp:StakeholderViewpoint ;
    arch:resultIsFinding          false ;
    arch:requiresDataset          arch:ModelDataset ;
    arch:requiresMetamodel        <https://meta.linked.archi/archimate4/onto#> ;
    arch:resultKey                "stakeholderMotivation" ;
    arch:defaultLimit             500 ;
    sh:prefixes                   <https://meta.linked.archi/archimate4/questions#> ;
    sh:select """
        SELECT DISTINCT ?stakeholder ?stakeholderLabel ?direction ?predicate ?motivation ?motivationLabel ?motivationType
        WHERE {
          VALUES ?predicate { am4:associatedWith am4:influences am4:realizes am4:aggregates am4:composedOf }
          VALUES ?motivationType {
            am4:Stakeholder am4:Driver am4:Assessment am4:Goal am4:Outcome
            am4:Principle am4:Requirement am4:Meaning am4:Value
          }
          ?stakeholder rdf:type am4:Stakeholder .
          { ?stakeholder ?predicate ?motivation . BIND("outgoing" AS ?direction) }
          UNION
          { ?motivation ?predicate ?stakeholder . BIND("incoming" AS ?direction) }
          ?motivation rdf:type ?motivationType .
          OPTIONAL { ?stakeholder skos:prefLabel ?stakeholderLabel . FILTER(lang(?stakeholderLabel) = "" || langMatches(lang(?stakeholderLabel), "en")) }
          OPTIONAL { ?motivation skos:prefLabel ?motivationLabel . FILTER(lang(?motivationLabel) = "" || langMatches(lang(?motivationLabel), "en")) }
        }
        ORDER BY ?stakeholderLabel ?direction ?motivationLabel
    """ ;
.

:requirement-traceability
    a                             arch:ModelQuestion, sh:SPARQLSelectExecutable ;
    dcterms:identifier            "notation/archimate4/requirement-traceability" ;
    skos:prefLabel                "How does each requirement trace to goals and to the elements that realise it?"@en ;
    dcterms:description           "Requirements with what realises them, below, and the goals, outcomes and principles they realise or influence, above, as a list of links."@en ;
    arch:answers                  "One row per traced link: the requirement, the direction, the predicate and the element at the other end."@en ;
    arch:doesNotProve             "Verification. A realisation relationship is a design claim; it does not show the requirement is met."@en ;
    arch:questionStage            arch:AnalysisStage ;
    arch:questionAddressesConcern am4vp:ArchitectureTactics, am4vp:Motivation ;
    arch:questionTargetsStakeholder am4vp:RequirementsManager, am4vp:BusinessAnalyst ;
    arch:questionFitsViewpoint    am4vp:RequirementsRealizationViewpoint, am4vp:GoalRealizationViewpoint ;
    arch:resultIsFinding          false ;
    arch:requiresDataset          arch:ModelDataset ;
    arch:requiresMetamodel        <https://meta.linked.archi/archimate4/onto#> ;
    arch:resultKey                "traceability" ;
    arch:defaultLimit             1000 ;
    sh:prefixes                   <https://meta.linked.archi/archimate4/questions#> ;
    sh:select """
        SELECT DISTINCT ?requirement ?requirementLabel ?direction ?predicate ?other ?otherLabel ?otherType
        WHERE {
          ?requirement rdf:type am4:Requirement .
          {
            ?other am4:realizes ?requirement .
            BIND(am4:realizes AS ?predicate)
            BIND("realised by" AS ?direction)
          }
          UNION
          {
            VALUES ?predicate { am4:realizes am4:influences }
            ?requirement ?predicate ?other .
            BIND("contributes to" AS ?direction)
          }
          ?other rdf:type ?otherType .
          FILTER(?otherType NOT IN (arch:ModelConcept, arch:Element, arch:QualifiedRelationship))
          MINUS { SELECT DISTINCT ?otherType WHERE { { ?otherType arch:isAbstractClass true }
                                                     UNION { GRAPH ?abstractClassGraph { ?otherType arch:isAbstractClass true } } } }
          OPTIONAL { ?requirement skos:prefLabel ?requirementLabel . FILTER(lang(?requirementLabel) = "" || langMatches(lang(?requirementLabel), "en")) }
          OPTIONAL { ?other skos:prefLabel ?otherLabel . FILTER(lang(?otherLabel) = "" || langMatches(lang(?otherLabel), "en")) }
        }
        ORDER BY ?requirementLabel ?direction ?otherLabel
    """ ;
.

:principle-rationale
    a                             arch:ModelQuestion, sh:SPARQLSelectExecutable ;
    dcterms:identifier            "notation/archimate4/principle-rationale" ;
    skos:prefLabel                "What motivates each principle, and what does it constrain?"@en ;
    dcterms:description           "Principles with the elements they relate to in either direction: the drivers and goals behind them, the requirements that realise them."@en ;
    arch:answers                  "One row per relationship between a principle and another element."@en ;
    arch:doesNotProve             "Compliance. A requirement realising a principle states an intent, not that designs follow it."@en ;
    arch:questionStage            arch:AnalysisStage ;
    arch:questionAddressesConcern am4vp:ArchitecturePolicies, am4vp:Motivation ;
    arch:questionFitsViewpoint    am4vp:MotivationViewpoint ;
    arch:resultIsFinding          false ;
    arch:requiresDataset          arch:ModelDataset ;
    arch:requiresMetamodel        <https://meta.linked.archi/archimate4/onto#> ;
    arch:resultKey                "principles" ;
    arch:defaultLimit             500 ;
    sh:prefixes                   <https://meta.linked.archi/archimate4/questions#> ;
    sh:select """
        SELECT DISTINCT ?principle ?principleLabel ?direction ?predicate ?other ?otherLabel ?otherType
        WHERE {
          VALUES ?predicate { am4:realizes am4:influences am4:associatedWith }
          ?principle rdf:type am4:Principle .
          { ?principle ?predicate ?other . BIND("outgoing" AS ?direction) }
          UNION
          { ?other ?predicate ?principle . BIND("incoming" AS ?direction) }
          ?other rdf:type ?otherType .
          FILTER(?otherType NOT IN (arch:ModelConcept, arch:Element, arch:QualifiedRelationship))
          MINUS { SELECT DISTINCT ?otherType WHERE { { ?otherType arch:isAbstractClass true }
                                                     UNION { GRAPH ?abstractClassGraph { ?otherType arch:isAbstractClass true } } } }
          OPTIONAL { ?principle skos:prefLabel ?principleLabel . FILTER(lang(?principleLabel) = "" || langMatches(lang(?principleLabel), "en")) }
          OPTIONAL { ?other skos:prefLabel ?otherLabel . FILTER(lang(?otherLabel) = "" || langMatches(lang(?otherLabel), "en")) }
        }
        ORDER BY ?principleLabel ?direction ?otherLabel
    """ ;
.

:work-package-deliverables
    a                             arch:ModelQuestion, sh:SPARQLSelectExecutable ;
    dcterms:identifier            "notation/archimate4/work-package-deliverables" ;
    skos:prefLabel                "What does each work package deliver, and what does that realise?"@en ;
    dcterms:description           "Work packages, the deliverables they realise, and the architecture elements those deliverables realise."@en ;
    arch:answers                  "One row per work package, deliverable and element realised."@en ;
    arch:doesNotProve             "Schedule or progress. ArchiMate records what a work package produces, not when."@en ;
    arch:questionStage            arch:AnalysisStage ;
    arch:questionAddressesConcern am4vp:ArchitectureVision, am4vp:ArchitecturePolicies ;
    arch:questionTargetsStakeholder am4vp:OperationalManager, am4vp:EnterpriseArchitect ;
    arch:questionFitsViewpoint    am4vp:ProjectViewpoint, am4vp:ImplementationAndMigrationViewpoint ;
    arch:resultIsFinding          false ;
    arch:requiresDataset          arch:ModelDataset ;
    arch:requiresMetamodel        <https://meta.linked.archi/archimate4/onto#> ;
    arch:resultKey                "workPackages" ;
    arch:defaultLimit             500 ;
    sh:prefixes                   <https://meta.linked.archi/archimate4/questions#> ;
    sh:select """
        SELECT DISTINCT ?workPackage ?workPackageLabel ?deliverable ?deliverableLabel ?realized ?realizedLabel ?realizedType
        WHERE {
          ?workPackage rdf:type am4:WorkPackage ;
                       am4:realizes ?deliverable .
          ?deliverable rdf:type am4:Deliverable .
          OPTIONAL {
            ?deliverable am4:realizes ?realized .
            ?realized rdf:type ?realizedType .
            FILTER(?realizedType NOT IN (arch:ModelConcept, arch:Element, arch:QualifiedRelationship))
            MINUS { SELECT DISTINCT ?realizedType WHERE { { ?realizedType arch:isAbstractClass true }
                                                          UNION { GRAPH ?abstractClassGraph { ?realizedType arch:isAbstractClass true } } } }
            OPTIONAL { ?realized skos:prefLabel ?realizedLabel . FILTER(lang(?realizedLabel) = "" || langMatches(lang(?realizedLabel), "en")) }
          }
          OPTIONAL { ?workPackage skos:prefLabel ?workPackageLabel . FILTER(lang(?workPackageLabel) = "" || langMatches(lang(?workPackageLabel), "en")) }
          OPTIONAL { ?deliverable skos:prefLabel ?deliverableLabel . FILTER(lang(?deliverableLabel) = "" || langMatches(lang(?deliverableLabel), "en")) }
        }
        ORDER BY ?workPackageLabel ?deliverableLabel
    """ ;
.

:plateau-difference
    a                             arch:ModelQuestion, sh:SPARQLSelectExecutable ;
    dcterms:identifier            "notation/archimate4/plateau-difference" ;
    skos:prefLabel                "What changes between these two plateaus?"@en ;
    dcterms:description           "Elements a later plateau aggregates or is composed of that an earlier one is not (added), and the reverse (removed)."@en ;
    arch:answers                  "One row per element added or removed."@en ;
    arch:doesNotProve             "The migration path. The difference is the gap; the work packages that close it are another question."@en ;
    arch:questionStage            arch:AnalysisStage ;
    arch:questionAddressesConcern am4vp:ModelHistory, am4vp:ArchitectureVision ;
    arch:questionFitsViewpoint    am4vp:MigrationViewpoint ;
    arch:resultIsFinding          false ;
    arch:requiresDataset          arch:ModelDataset ;
    arch:requiresMetamodel        <https://meta.linked.archi/archimate4/onto#> ;
    arch:resultKey                "plateauChanges" ;
    arch:defaultLimit             1000 ;
    sh:parameter [ sh:path arch:from ; sh:name "from" ; sh:nodeKind sh:IRI ; sh:optional false ; sh:order 1 ;
                   sh:description "The earlier plateau, such as the baseline."@en ] ;
    sh:parameter [ sh:path arch:to ; sh:name "to" ; sh:nodeKind sh:IRI ; sh:optional false ; sh:order 2 ;
                   sh:description "The later plateau, such as the target."@en ] ;
    sh:prefixes                   <https://meta.linked.archi/archimate4/questions#> ;
    sh:select """
        SELECT DISTINCT ?change ?element ?label ?type
        WHERE {
          {
            ?from rdf:type am4:Plateau .
            ?to rdf:type am4:Plateau ;
                am4:aggregates|am4:composedOf ?element .
            FILTER NOT EXISTS { ?from am4:aggregates|am4:composedOf ?element }
            BIND("added" AS ?change)
          }
          UNION
          {
            ?to rdf:type am4:Plateau .
            ?from rdf:type am4:Plateau ;
                  am4:aggregates|am4:composedOf ?element .
            FILTER NOT EXISTS { ?to am4:aggregates|am4:composedOf ?element }
            BIND("removed" AS ?change)
          }
          FILTER(?from != ?to)
          ?element rdf:type ?type .
          FILTER(?type NOT IN (arch:ModelConcept, arch:Element, arch:QualifiedRelationship))
          MINUS { SELECT DISTINCT ?type WHERE { { ?type arch:isAbstractClass true }
                                                UNION { GRAPH ?abstractClassGraph { ?type arch:isAbstractClass true } } } }
          OPTIONAL { ?element skos:prefLabel ?label . FILTER(lang(?label) = "" || langMatches(lang(?label), "en")) }
        }
        ORDER BY ?change ?type ?label
    """ ;
.

# ── Quality: findings against the viewpoints' concerns ──────────

:unassigned-behaviour
    a                             arch:ModelQuestion, sh:SPARQLSelectExecutable ;
    dcterms:identifier            "notation/archimate4/unassigned-behaviour" ;
    skos:prefLabel                "Which processes and functions has nobody been assigned to?"@en ;
    dcterms:description           "Processes and functions that no active structure element is assigned to."@en ;
    arch:answers                  "One row per process or function without a performer."@en ;
    arch:doesNotProve             "That nobody performs it. The performer may be assigned to an enclosing process, or the model may stop above that level of detail."@en ;
    arch:questionStage            arch:QualityStage ;
    arch:questionAddressesConcern am4vp:Responsibilities, am4vp:Completeness ;
    arch:questionFitsViewpoint    am4vp:ProcessCooperationViewpoint, am4vp:OrganizationViewpoint ;
    arch:resultIsFinding          true ;
    arch:findingSeverity          sh:Warning ;
    arch:findingFocus             "behaviour" ;
    arch:requiresDataset          arch:ModelDataset ;
    arch:requiresMetamodel        <https://meta.linked.archi/archimate4/onto#> ;
    arch:resultKey                "unassigned" ;
    arch:defaultLimit             500 ;
    sh:parameter [ sh:path arch:model ; sh:name "model" ; sh:class arch:Model ; sh:optional true ; sh:order 1 ;
                   sh:description "The model to look in. A modelling tool binds the open model; a deliverable, the model it is produced from."@en ] ;
    sh:prefixes                   <https://meta.linked.archi/archimate4/questions#> ;
    sh:select """
        SELECT ?behaviour ?label ?type
        WHERE {
          VALUES ?type { am4:Process am4:Function }
          ?behaviour rdf:type ?type ;
                     arch:inModel ?model .
          FILTER NOT EXISTS { ?performer am4:assignedTo ?behaviour }
          OPTIONAL { ?behaviour skos:prefLabel ?label . FILTER(lang(?label) = "" || langMatches(lang(?label), "en")) }
        }
        ORDER BY ?type ?label
    """ ;
.

:unrealised-services
    a                             arch:ModelQuestion, sh:SPARQLSelectExecutable ;
    dcterms:identifier            "notation/archimate4/unrealised-services" ;
    skos:prefLabel                "Which services does nothing realise?"@en ;
    dcterms:description           "Services that no behaviour or active structure element realises."@en ;
    arch:answers                  "One row per service nothing realises."@en ;
    arch:doesNotProve             "That the service is not delivered: it may be bought in, or realised in a model that is not loaded."@en ;
    arch:questionStage            arch:QualityStage ;
    arch:questionAddressesConcern am4vp:Completeness, am4vp:AddedValueOfProcesses ;
    arch:questionFitsViewpoint    am4vp:ServiceRealizationViewpoint, am4vp:ProcessCooperationViewpoint ;
    arch:resultIsFinding          true ;
    arch:findingSeverity          sh:Warning ;
    arch:findingFocus             "service" ;
    arch:requiresDataset          arch:ModelDataset ;
    arch:requiresMetamodel        <https://meta.linked.archi/archimate4/onto#> ;
    arch:resultKey                "unrealisedServices" ;
    arch:defaultLimit             500 ;
    sh:parameter [ sh:path arch:model ; sh:name "model" ; sh:class arch:Model ; sh:optional true ; sh:order 1 ;
                   sh:description "The model to look in. A modelling tool binds the open model; a deliverable, the model it is produced from."@en ] ;
    sh:prefixes                   <https://meta.linked.archi/archimate4/questions#> ;
    sh:select """
        SELECT ?service ?label
        WHERE {
          ?service rdf:type am4:Service ;
                   arch:inModel ?model .
          FILTER NOT EXISTS { ?realizer am4:realizes ?service }
          OPTIONAL { ?service skos:prefLabel ?label . FILTER(lang(?label) = "" || langMatches(lang(?label), "en")) }
        }
        ORDER BY ?label
    """ ;
.

:applications-without-technology
    a                             arch:ModelQuestion, sh:SPARQLSelectExecutable ;
    dcterms:identifier            "notation/archimate4/applications-without-technology" ;
    skos:prefLabel                "Which application components run on no technology?"@en ;
    dcterms:description           "Application components that no element of the technology domain serves or realises, directly or by realising a service that serves them."@en ;
    arch:answers                  "One row per application component with no technology under it."@en ;
    arch:doesNotProve             "That it runs nowhere. Where it is hosted may be outside the model, or recorded only in a deployment model that is not loaded."@en ;
    arch:questionStage            arch:QualityStage ;
    arch:questionAddressesConcern am4vp:ApplicationPlatforms, am4vp:InfrastructureQuality ;
    arch:questionTargetsStakeholder am4vp:ApplicationArchitect, am4vp:InfrastructureArchitect ;
    arch:questionFitsViewpoint    am4vp:ImplementationAndDeploymentViewpoint, am4vp:TechnologyUsageViewpoint ;
    arch:resultIsFinding          true ;
    arch:findingSeverity          sh:Warning ;
    arch:findingFocus             "application" ;
    arch:requiresDataset          arch:ModelAndMetamodelDataset ;
    arch:requiresMetamodel        <https://meta.linked.archi/archimate4/onto#> ;
    arch:resultKey                "unhosted" ;
    arch:defaultLimit             500 ;
    sh:parameter [ sh:path arch:model ; sh:name "model" ; sh:class arch:Model ; sh:optional true ; sh:order 1 ;
                   sh:description "The model to look in. A modelling tool binds the open model; a deliverable, the model it is produced from."@en ] ;
    sh:prefixes                   <https://meta.linked.archi/archimate4/questions#> ;
    sh:select """
        SELECT ?application ?label
        WHERE {
          ?application rdf:type am4:ApplicationComponent ;
                       arch:inModel ?model .
          MINUS {
            # The technology domain's types, read once.
            {
              SELECT DISTINCT ?technologyType
              WHERE {
                { ?domainType rdfs:subClassOf* am4:TechnologyDomainElement }
                UNION { GRAPH ?ontologyGraph { ?domainType rdfs:subClassOf* am4:TechnologyDomainElement } }
                { ?technologyType rdfs:subClassOf* ?domainType }
                UNION { GRAPH ?specialisationGraph { ?technologyType rdfs:subClassOf* ?domainType } }
              }
            }
            ?technology rdf:type ?technologyType ;
                        am4:serves|am4:realizes|(am4:realizes/am4:serves) ?application .
          }
          OPTIONAL { ?application skos:prefLabel ?label . FILTER(lang(?label) = "" || langMatches(lang(?label), "en")) }
        }
        ORDER BY ?label
    """ ;
.

:data-never-written
    a                             arch:ModelQuestion, sh:SPARQLSelectExecutable ;
    dcterms:identifier            "notation/archimate4/data-never-written" ;
    skos:prefLabel                "Which information is read but never written?"@en ;
    dcterms:description           "Data objects, business objects and artifacts that something reads and nothing writes. Access of an unstated kind (am4:Access) counts as a possible write."@en ;
    arch:answers                  "One row per object, with how many elements read it."@en ;
    arch:doesNotProve             "That the data has no source. It may be written by a system outside the model; that boundary is what the finding asks to discuss."@en ;
    arch:questionStage            arch:QualityStage ;
    arch:questionAddressesConcern am4vp:InformationStructure, am4vp:Completeness ;
    arch:questionFitsViewpoint    am4vp:InformationStructureViewpoint ;
    arch:resultIsFinding          true ;
    arch:findingSeverity          sh:Warning ;
    arch:findingFocus             "object" ;
    arch:requiresDataset          arch:ModelDataset ;
    arch:requiresMetamodel        <https://meta.linked.archi/archimate4/onto#> ;
    arch:resultKey                "neverWritten" ;
    arch:defaultLimit             500 ;
    sh:prefixes                   <https://meta.linked.archi/archimate4/questions#> ;
    sh:select """
        SELECT ?object ?label ?readers
        WHERE {
          {
            SELECT ?object (COUNT(DISTINCT ?reader) AS ?readers)
            WHERE {
              VALUES ?objectType { am4:DataObject am4:BusinessObject am4:Artifact }
              ?read rdf:type am4:ReadAccess ;
                    arch:source ?reader ;
                    arch:target ?object .
              ?object rdf:type ?objectType .
            }
            GROUP BY ?object
          }
          FILTER NOT EXISTS {
            VALUES ?writeKind { am4:WriteAccess am4:ReadWriteAccess am4:Access }
            ?write rdf:type ?writeKind ;
                   arch:target ?object .
          }
          OPTIONAL { ?object skos:prefLabel ?label . FILTER(lang(?label) = "" || langMatches(lang(?label), "en")) }
        }
        ORDER BY DESC(?readers) ?label
    """ ;
.

:unrealised-capabilities
    a                             arch:ModelQuestion, sh:SPARQLSelectExecutable ;
    dcterms:identifier            "notation/archimate4/unrealised-capabilities" ;
    skos:prefLabel                "Which capabilities does nothing realise?"@en ;
    dcterms:description           "Capabilities realised neither directly nor through any capability they are composed of or aggregate."@en ;
    arch:answers                  "One row per capability with no realisation anywhere beneath it."@en ;
    arch:doesNotProve             "That the enterprise lacks the capability; only that the model does not say what delivers it."@en ;
    arch:questionStage            arch:QualityStage ;
    arch:questionAddressesConcern am4vp:StrategyDevelopment, am4vp:Completeness ;
    arch:questionFitsViewpoint    am4vp:CapabilityMapViewpoint ;
    arch:resultIsFinding          true ;
    arch:findingSeverity          sh:Info ;
    arch:findingFocus             "capability" ;
    arch:requiresDataset          arch:ModelDataset ;
    arch:requiresMetamodel        <https://meta.linked.archi/archimate4/onto#> ;
    arch:resultKey                "unrealisedCapabilities" ;
    arch:defaultLimit             500 ;
    sh:parameter [ sh:path arch:model ; sh:name "model" ; sh:class arch:Model ; sh:optional true ; sh:order 1 ;
                   sh:description "The model to look in. A modelling tool binds the open model; a deliverable, the model it is produced from."@en ] ;
    sh:prefixes                   <https://meta.linked.archi/archimate4/questions#> ;
    sh:select """
        SELECT ?capability ?label
        WHERE {
          ?capability rdf:type am4:Capability ;
                      arch:inModel ?model .
          FILTER NOT EXISTS {
            ?capability (am4:composedOf|am4:aggregates)* ?part .
            ?realizer am4:realizes ?part .
          }
          OPTIONAL { ?capability skos:prefLabel ?label . FILTER(lang(?label) = "" || langMatches(lang(?label), "en")) }
        }
        ORDER BY ?label
    """ ;
.

:unrealised-requirements
    a                             arch:ModelQuestion, sh:SPARQLSelectExecutable ;
    dcterms:identifier            "notation/archimate4/unrealised-requirements" ;
    skos:prefLabel                "Which requirements does no architecture element realise?"@en ;
    dcterms:description           "Requirements that no element outside the motivation domain realises: realisation by another motivation element does not count."@en ;
    arch:answers                  "One row per requirement without a realising design element."@en ;
    arch:doesNotProve             "That the requirement is unmet; only that the model does not show what meets it."@en ;
    arch:questionStage            arch:QualityStage ;
    arch:questionAddressesConcern am4vp:ArchitectureTactics, am4vp:Motivation ;
    arch:questionTargetsStakeholder am4vp:RequirementsManager ;
    arch:questionFitsViewpoint    am4vp:RequirementsRealizationViewpoint ;
    arch:resultIsFinding          true ;
    arch:findingSeverity          sh:Warning ;
    arch:findingFocus             "requirement" ;
    arch:requiresDataset          arch:ModelAndMetamodelDataset ;
    arch:requiresMetamodel        <https://meta.linked.archi/archimate4/onto#> ;
    arch:resultKey                "unrealisedRequirements" ;
    arch:defaultLimit             500 ;
    sh:parameter [ sh:path arch:model ; sh:name "model" ; sh:class arch:Model ; sh:optional true ; sh:order 1 ;
                   sh:description "The model to look in. A modelling tool binds the open model; a deliverable, the model it is produced from."@en ] ;
    sh:prefixes                   <https://meta.linked.archi/archimate4/questions#> ;
    sh:select """
        SELECT ?requirement ?label
        WHERE {
          ?requirement rdf:type am4:Requirement ;
                       arch:inModel ?model .
          # Realised by a design element: one whose own type is outside the motivation domain.
          MINUS {
            ?realizer am4:realizes ?requirement ;
                      rdf:type ?realizerType .
            FILTER(?realizerType NOT IN (arch:ModelConcept, arch:Element, arch:QualifiedRelationship))
            MINUS { SELECT DISTINCT ?realizerType WHERE { { ?realizerType arch:isAbstractClass true }
                                                          UNION { GRAPH ?abstractClassGraph { ?realizerType arch:isAbstractClass true } } } }
            MINUS {
              SELECT DISTINCT ?realizerType
              WHERE {
                { ?domainType rdfs:subClassOf* am4:MotivationElement }
                UNION { GRAPH ?ontologyGraph { ?domainType rdfs:subClassOf* am4:MotivationElement } }
                { ?realizerType rdfs:subClassOf* ?domainType }
                UNION { GRAPH ?specialisationGraph { ?realizerType rdfs:subClassOf* ?domainType } }
              }
            }
          }
          OPTIONAL { ?requirement skos:prefLabel ?label . FILTER(lang(?label) = "" || langMatches(lang(?label), "en")) }
        }
        ORDER BY ?label
    """ ;
.

:principles-without-requirements
    a                             arch:ModelQuestion, sh:SPARQLSelectExecutable ;
    dcterms:identifier            "notation/archimate4/principles-without-requirements" ;
    skos:prefLabel                "Which principles has no requirement made concrete?"@en ;
    dcterms:description           "Principles that no requirement realises."@en ;
    arch:answers                  "One row per principle no requirement realises."@en ;
    arch:doesNotProve             "That the principle is ignored. It may be applied by review rather than through stated requirements."@en ;
    arch:questionStage            arch:QualityStage ;
    arch:questionAddressesConcern am4vp:ArchitecturePolicies ;
    arch:questionFitsViewpoint    am4vp:MotivationViewpoint ;
    arch:resultIsFinding          true ;
    arch:findingSeverity          sh:Info ;
    arch:findingFocus             "principle" ;
    arch:requiresDataset          arch:ModelDataset ;
    arch:requiresMetamodel        <https://meta.linked.archi/archimate4/onto#> ;
    arch:resultKey                "unbackedPrinciples" ;
    arch:defaultLimit             500 ;
    sh:parameter [ sh:path arch:model ; sh:name "model" ; sh:class arch:Model ; sh:optional true ; sh:order 1 ;
                   sh:description "The model to look in. A modelling tool binds the open model; a deliverable, the model it is produced from."@en ] ;
    sh:prefixes                   <https://meta.linked.archi/archimate4/questions#> ;
    sh:select """
        SELECT ?principle ?label
        WHERE {
          ?principle rdf:type am4:Principle ;
                     arch:inModel ?model .
          FILTER NOT EXISTS {
            ?requirement am4:realizes ?principle ;
                         rdf:type am4:Requirement .
          }
          OPTIONAL { ?principle skos:prefLabel ?label . FILTER(lang(?label) = "" || langMatches(lang(?label), "en")) }
        }
        ORDER BY ?label
    """ ;
.

# ── Views ───────────────────────────────────────────────────────

:viewpoint-scope
    a                             arch:ModelQuestion, sh:SPARQLSelectExecutable ;
    dcterms:identifier            "notation/archimate4/viewpoint-scope" ;
    skos:prefLabel                "What in the model belongs in a view of this ArchiMate viewpoint?"@en ;
    dcterms:description           '''What belongs in a view of an ArchiMate 4.0 viewpoint. ArchiMate 4.0 places process,
function, service, event and role in a common domain, and viewpoints such as the Technology Viewpoint admit them;
listed whenever their type is admitted, every business process would belong in a technology view. An element of the
common domain therefore belongs when a relationship connects it, in either direction, to an element of a
domain-specific type the same viewpoint admits; every other element belongs when the viewpoint admits its type.'''@en ;
    arch:answers                  "One row per element: name, type, definition and a \"relationship → target\" summary of what it points to."@en ;
    arch:doesNotProve             "That an element of the common domain left out is irrelevant to the viewpoint; only that nothing of a domain-specific type the viewpoint admits is related to it."@en ;
    arch:questionStage            arch:ViewsStage ;
    arch:resultIsFinding          false ;
    arch:requiresDataset          arch:ModelAndMetamodelDataset ;
    arch:requiresMetamodel        <https://meta.linked.archi/archimate4/onto#> ;
    arch:resultKey                "scope" ;
    arch:defaultLimit             1000 ;
    sh:parameter [ sh:path arch:viewpoint ; sh:name "viewpoint" ; sh:class arch:Viewpoint ; sh:optional false ; sh:order 1 ;
                   sh:description "A viewpoint. A modelling tool binds the open view's viewpoint; a deliverable, the section's."@en ] ;
    sh:parameter [ sh:path arch:model ; sh:name "model" ; sh:class arch:Model ; sh:optional true ; sh:order 2 ;
                   sh:description "The model to look in. A modelling tool binds the open model; a deliverable, the model it is produced from."@en ] ;
    sh:prefixes                   <https://meta.linked.archi/archimate4/questions#> ;
    sh:select """
        SELECT ?element (SAMPLE(?anyLabel) AS ?label) ?type (SAMPLE(?anyDefinition) AS ?definition)
               (GROUP_CONCAT(DISTINCT ?link; separator = "; ") AS ?outgoing)
        WHERE {
          {
            # Elements of a domain-specific type the viewpoint admits.
            {
              SELECT DISTINCT ?viewpoint ?type
              WHERE {
                { ?viewpoint arch:includesConcept ?admitted } UNION { GRAPH ?admittingGraph { ?viewpoint arch:includesConcept ?admitted } }
                { ?type rdfs:subClassOf* ?admitted } UNION { GRAPH ?hierarchyGraph { ?type rdfs:subClassOf* ?admitted } }
                MINUS {
                  SELECT DISTINCT ?type
                  WHERE {
                    { ?commonType rdfs:subClassOf* am4:CommonDomainElement } UNION { GRAPH ?commonGraph { ?commonType rdfs:subClassOf* am4:CommonDomainElement } }
                    { ?type rdfs:subClassOf* ?commonType } UNION { GRAPH ?commonSpecialisationGraph { ?type rdfs:subClassOf* ?commonType } }
                  }
                }
              }
            }
            ?element rdf:type ?type ;
                     arch:inModel ?model .
          }
          UNION
          {
            # Elements of a common-domain type the viewpoint admits, connected to one of a domain-specific type it
            # admits. The connected elements are found as a set first: per viewpoint, the elements at the other end
            # of a relationship from an element of an admitted domain-specific type.
            {
              SELECT DISTINCT ?viewpoint ?element
              WHERE {
                {
                  SELECT DISTINCT ?viewpoint ?anchorType
                  WHERE {
                    { ?viewpoint arch:includesConcept ?anchorAdmitted } UNION { GRAPH ?anchorAdmittingGraph { ?viewpoint arch:includesConcept ?anchorAdmitted } }
                    { ?anchorType rdfs:subClassOf* ?anchorAdmitted } UNION { GRAPH ?anchorHierarchyGraph { ?anchorType rdfs:subClassOf* ?anchorAdmitted } }
                    MINUS {
                      SELECT DISTINCT ?anchorType
                      WHERE {
                        { ?anchorCommonType rdfs:subClassOf* am4:CommonDomainElement } UNION { GRAPH ?anchorCommonGraph { ?anchorCommonType rdfs:subClassOf* am4:CommonDomainElement } }
                        { ?anchorType rdfs:subClassOf* ?anchorCommonType } UNION { GRAPH ?anchorCommonSpecialisationGraph { ?anchorType rdfs:subClassOf* ?anchorCommonType } }
                      }
                    }
                  }
                }
                ?anchor rdf:type ?anchorType .
                { ?connection arch:source ?anchor ; arch:target ?element }
                UNION
                { ?connection arch:target ?anchor ; arch:source ?element }
              }
            }
            ?element rdf:type ?type ;
                     arch:inModel ?model .
            {
              SELECT DISTINCT ?viewpoint ?type
              WHERE {
                { ?viewpoint arch:includesConcept ?admitted } UNION { GRAPH ?admittingGraph { ?viewpoint arch:includesConcept ?admitted } }
                { ?type rdfs:subClassOf* ?admitted } UNION { GRAPH ?hierarchyGraph { ?type rdfs:subClassOf* ?admitted } }
                {
                  SELECT DISTINCT ?type
                  WHERE {
                    { ?commonType rdfs:subClassOf* am4:CommonDomainElement } UNION { GRAPH ?commonGraph { ?commonType rdfs:subClassOf* am4:CommonDomainElement } }
                    { ?type rdfs:subClassOf* ?commonType } UNION { GRAPH ?commonSpecialisationGraph { ?type rdfs:subClassOf* ?commonType } }
                  }
                }
              }
            }
          }
          FILTER NOT EXISTS { ?element arch:source ?anySource }
          OPTIONAL { ?element skos:prefLabel ?anyLabel . FILTER(lang(?anyLabel) = "" || langMatches(lang(?anyLabel), "en")) }
          OPTIONAL { ?element skos:definition ?anyDefinition . FILTER(lang(?anyDefinition) = "" || langMatches(lang(?anyDefinition), "en")) }
          OPTIONAL {
            ?relationship arch:source ?element ;
                          arch:target ?other ;
                          rdf:type ?relationshipType .
            FILTER(?relationshipType NOT IN (arch:ModelConcept, arch:Element, arch:QualifiedRelationship))
            MINUS { SELECT DISTINCT ?relationshipType WHERE { { ?relationshipType arch:isAbstractClass true }
                                                              UNION { GRAPH ?abstractClassGraph { ?relationshipType arch:isAbstractClass true } } } }
            OPTIONAL { ?other skos:prefLabel ?otherLabel . FILTER(lang(?otherLabel) = "" || langMatches(lang(?otherLabel), "en")) }
            BIND(CONCAT(REPLACE(STR(?relationshipType), "^.*[#/]", ""), " → ",
                        COALESCE(STR(?otherLabel), STR(?other))) AS ?link)
          }
        }
        GROUP BY ?element ?type
        ORDER BY ?type ?label
    """ ;
.
