# SPDX-License-Identifier: MPL-2.0
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix prov: <http://www.w3.org/ns/prov#> .
@prefix prov-ext: <https://secorolab.github.io/metamodels/prov#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix schema: <https://schema.org/> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix spdx-sw: <https://spdx.org/rdf/3.0.1/terms/Software/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

prov-ext:Specification
  a rdfs:Class ;
  rdfs:subClassOf prov:Activity ;
  rdfs:label "specification" ;
  rdfs:comment "A person or a software agent writes a model specification." .

prov-ext:Transformation
  a rdfs:Class ;
  rdfs:subClassOf prov:Activity ;
  rdfs:label "transformation" ;
  rdfs:comment "A software package turns source entities into target entities, model-to-model or model-to-code." .

prov-ext:Generalization
  a rdfs:Class ;
  rdfs:subClassOf prov:Activity ;
  rdfs:label "generalization" ;
  rdfs:comment "Instances are drawn from a sampled quantity, e.g. poses sampled from a distribution." .

prov-ext:Execution
  a rdfs:Class ;
  rdfs:subClassOf prov:Activity ;
  rdfs:label "execution" ;
  rdfs:comment "An agent runs a model, or is to run it; its logs are entities generated by this activity." .

prov-ext:Assurance
  a rdfs:Class ;
  rdfs:subClassOf prov:Activity ;
  rdfs:label "assurance" ;
  rdfs:comment "Observations are evaluated to a verdict." .

prov-ext:RelativeLocation
  a rdfs:Class ;
  rdfs:subClassOf prov:Location, prov:Entity ;
  rdfs:label "relative location" ;
  rdfs:comment "A location given by a path relative to the location it is at, e.g. a file under a generation root." .

# Shared by every prov-ext activity: what it used and who ran it. Times are
# left to prov:ActivityShape, since an activity may still be running.
prov-ext:RecordedActivityShape
  a sh:NodeShape ;
  sh:property [
    sh:path prov:used ;
    sh:minCount 1 ;
    sh:class prov:Entity ;
    sh:nodeKind sh:IRI
  ] ;
  sh:property [
    sh:path prov:wasAssociatedWith ;
    sh:minCount 1 ;
    sh:class prov:Agent ;
    sh:nodeKind sh:IRI
  ] .

prov-ext:GeneratingActivityShape
  a sh:NodeShape ;
  sh:property [
    sh:path [ sh:inversePath prov:wasGeneratedBy ] ;
    sh:minCount 1 ;
    sh:class prov:Entity ;
    sh:nodeKind sh:IRI
  ] .

# A specification may start from nothing, so it need not have used anything.
prov-ext:SpecificationShape
  a sh:NodeShape ;
  sh:targetClass prov-ext:Specification ;
  sh:message "A specification generates at least one entity and names the person or software agent that wrote it." ;
  sh:node prov-ext:GeneratingActivityShape ;
  sh:property [
    sh:path prov:wasAssociatedWith ;
    sh:minCount 1 ;
    sh:nodeKind sh:IRI ;
    sh:or (
      [ sh:class prov:Person ]
      [ sh:class prov:SoftwareAgent ]
    )
  ] .

prov-ext:TransformationShape
  a sh:NodeShape ;
  sh:targetClass prov-ext:Transformation ;
  sh:message "A transformation uses at least one source entity, generates at least one target entity, and is run by a software package." ;
  sh:node prov-ext:RecordedActivityShape, prov-ext:GeneratingActivityShape ;
  sh:property [
    sh:path prov:wasAssociatedWith ;
    sh:class prov:SoftwareAgent
  ] .

prov-ext:GeneralizationShape
  a sh:NodeShape ;
  sh:targetClass prov-ext:Generalization ;
  sh:message "A generalization uses the quantity it samples and generates at least one sampled entity." ;
  sh:node prov-ext:RecordedActivityShape, prov-ext:GeneratingActivityShape .

prov-ext:AssuranceShape
  a sh:NodeShape ;
  sh:targetClass prov-ext:Assurance ;
  sh:message "An assurance uses the observations it evaluated and generates a verdict." ;
  sh:node prov-ext:RecordedActivityShape, prov-ext:GeneratingActivityShape .

# A software package is a software agent with a name, and at most one version,
# source repository and revision identifier.
prov-ext:SoftwarePackageShape
  a sh:NodeShape ;
  sh:targetClass prov:SoftwareAgent ;
  sh:property [
    sh:path schema:name ;
    sh:minCount 1 ;
    sh:maxCount 1 ;
    sh:datatype xsd:string
  ] ;
  sh:property [
    sh:path schema:softwareVersion ;
    sh:maxCount 1 ;
    sh:datatype xsd:string
  ] ;
  sh:property [
    sh:path schema:codeRepository ;
    sh:maxCount 1 ;
    sh:nodeKind sh:IRI
  ] ;
  sh:property [
    sh:path schema:identifier ;
    sh:maxCount 1 ;
    sh:datatype xsd:string
  ] .

# A package is found by its name: a ros:Package in the ROS package index, any other as installed.
prov-ext:PackageShape
  a sh:NodeShape ;
  sh:targetClass spdx-sw:Package ;
  sh:property [
    sh:path schema:name ;
    sh:minCount 1 ;
    sh:maxCount 1 ;
    sh:datatype xsd:string ;
    sh:message "A package needs exactly one schema:name as a string, the name it is found by."
  ] ;
  sh:property [
    sh:path schema:softwareVersion ;
    sh:maxCount 1 ;
    sh:datatype xsd:string ;
    sh:message "A package states at most one schema:softwareVersion, as a string."
  ] ;
  sh:property [
    sh:path schema:codeRepository ;
    sh:maxCount 1 ;
    sh:nodeKind sh:IRI ;
    sh:message "A package states at most one schema:codeRepository, the IRI of its source repository."
  ] ;
  sh:property [
    sh:path schema:identifier ;
    sh:maxCount 1 ;
    sh:datatype xsd:string ;
    sh:message "A package states at most one schema:identifier, the revision of its source, as a string."
  ] .

# rel-path is an RFC 3986 relative reference, resolved against the IRI of the location it is at.
prov-ext:RelativeLocationShape
  a sh:NodeShape ;
  sh:targetClass prov-ext:RelativeLocation ;
  sh:message "A relative location has one path and is at one location that path is relative to." ;
  sh:property [
    sh:path prov-ext:rel-path ;
    sh:minCount 1 ;
    sh:maxCount 1 ;
    sh:datatype xsd:anyURI
  ] ;
  sh:property [
    sh:path prov:atLocation ;
    sh:minCount 1 ;
    sh:maxCount 1 ;
    sh:class prov:Location ;
    sh:nodeKind sh:IRI
  ] .

prov-ext:FormatShape
  a sh:NodeShape ;
  sh:targetSubjectsOf dcterms:format ;
  sh:property [
    sh:path dcterms:format ;
    sh:maxCount 1 ;
    sh:datatype xsd:string
  ] .
