@prefix sh: <http://www.w3.org/ns/shacl#> . @prefix alchem: <https://w3id.org/alchem/> .
@prefix prov: <http://www.w3.org/ns/prov#> . @prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

alchem:shape-paper a sh:NodeShape ; sh:targetClass alchem:Paper ;
  sh:property [ sh:path alchem:title ; sh:minCount 1 ; sh:message "a paper without a title" ] ;
  sh:sparql [ sh:message "two authorships of one paper at the same position" ; sh:select '''
    PREFIX alchem: <https://w3id.org/alchem/>
    SELECT $this ?pos WHERE { $this alchem:authorships ?a , ?b . FILTER(?a != ?b) ?a alchem:position ?pos . ?b alchem:position ?pos }''' ] .

alchem:shape-authorship a sh:NodeShape ; sh:targetClass alchem:Authorship ;
  sh:property [ sh:path alchem:person ; sh:minCount 1 ; sh:maxCount 1 ; sh:class alchem:Person ;
                sh:message "an authorship needs exactly one person" ] ;
  sh:property [ sh:path alchem:position ; sh:minCount 1 ; sh:maxCount 1 ; sh:minInclusive 1 ;
                sh:message "an authorship needs one position from 1" ] ;
  sh:property [ sh:path alchem:contributions ; sh:class skos:Concept ;
                sh:message "a contribution role must be a concept of the role schemes" ] .

alchem:shape-stated a sh:NodeShape ;
  sh:targetSubjectsOf alchem:attribution ;
  sh:sparql [ sh:message "an activity marked stated has no association with a person and a role" ; sh:select '''
    PREFIX alchem: <https://w3id.org/alchem/> PREFIX prov: <http://www.w3.org/ns/prov#>
    SELECT $this WHERE { $this alchem:attribution <https://w3id.org/alchem/AttributionStatus#stated> .
      FILTER NOT EXISTS { $this prov:qualifiedAssociation ?b . ?b prov:agent ?p ; alchem:association_role ?r } }''' ] ;
  sh:sparql [ sh:message "an activity marked unknown has a performer" ; sh:select '''
    PREFIX alchem: <https://w3id.org/alchem/> PREFIX prov: <http://www.w3.org/ns/prov#>
    SELECT $this WHERE { $this alchem:attribution <https://w3id.org/alchem/AttributionStatus#unknown> ;
      prov:qualifiedAssociation ?b }''' ] ;
  sh:sparql [ sh:message "an association goes through an authorship of another paper" ; sh:select '''
    PREFIX alchem: <https://w3id.org/alchem/> PREFIX prov: <http://www.w3.org/ns/prov#>
    SELECT $this WHERE { ?paper alchem:reports_activity $this . $this prov:qualifiedAssociation ?b .
      ?b alchem:via_authorship ?au . FILTER NOT EXISTS { ?paper alchem:authorships ?au } }''' ] .

alchem:shape-association a sh:NodeShape ; sh:targetClass alchem:Association ;
  sh:property [ sh:path prov:agent ; sh:minCount 1 ; sh:maxCount 1 ; sh:class alchem:Person ] ;
  sh:property [ sh:path alchem:association_role ; sh:minCount 1 ; sh:class skos:Concept ] ;
  sh:property [ sh:path alchem:via_authorship ; sh:minCount 1 ; sh:maxCount 1 ; sh:class alchem:Authorship ] .

alchem:shape-part a sh:NodeShape ; sh:targetClass alchem:PartOfWork ;
  sh:property [ sh:path alchem:activity_kind ; sh:minCount 1 ; sh:maxCount 1 ; sh:message "a part of the work needs one kind" ] ;
  sh:property [ sh:path alchem:basis ; sh:minCount 1 ; sh:maxCount 1 ; sh:in ( <https://w3id.org/alchem/AttributionBasis#stated> <https://w3id.org/alchem/AttributionBasis#inferred> ) ;
                sh:message "a part of the work needs one basis, stated or inferred" ] ;
  sh:property [ sh:path prov:wasAssociatedWith ; sh:class alchem:ResearchGroup ; sh:message "a part is done by research groups" ] ;
  sh:sparql [ sh:message "a partner group of another paper did this part" ; sh:select '''
    PREFIX alchem: <https://w3id.org/alchem/> PREFIX prov: <http://www.w3.org/ns/prov#>
    SELECT $this WHERE { $this prov:wasAssociatedWith ?g . FILTER(?g != alchem:lab)
      FILTER(REPLACE(STR($this), "^(.*/paper/[0-9]+)/.*$", "$1") != REPLACE(STR(?g), "^(.*/paper/[0-9]+)/.*$", "$1")) }''' ] .

alchem:shape-kind a sh:NodeShape ; sh:targetClass alchem:MaterialKind ;
  sh:property [ sh:path rdfs:label ; sh:minCount 1 ] ;
  sh:sparql [ sh:message "a material kind with members from fewer than two papers" ; sh:select '''
    PREFIX alchem: <https://w3id.org/alchem/>
    SELECT $this WHERE { { SELECT $this (COUNT(DISTINCT ?p) AS ?n) WHERE {
      ?m alchem:of_kind $this . BIND(REPLACE(STR(?m), "^(.*/paper/[0-9]+)/.*$", "$1") AS ?p) } GROUP BY $this } FILTER(?n < 2) }''' ] .
