This query returns the sub-classes of the given class, restricted to sub-classes that are part of the same space and published by admins, maintainers, or members of that space. Each sub-class appears exactly once, taken from its winning definition: the newest non-invalidated nanopublication signed by a member+ of the maintaining space that describes the sub-class as part of the same resource. That resolution matters because an override records only prov:wasDerivedFrom and never npx:supersedes, so nothing is invalidated and every version of a term stays live -- without it a sub-class is listed once per version. Judging on the winner also makes the listing follow later edits: a version that drops the rdfs:subClassOf triple removes the row, and a version that adds gen:WithdrawnTerm hides the sub-class, while publishing a newer version without that type reinstates it.
Get sub-classes for class (from space members)
prefix owl: <http://www.w3.org/2002/07/owl#> prefix dct: <http://purl.org/dc/terms/> prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> prefix np: <http://www.nanopub.org/nschema#> prefix npa: <http://purl.org/nanopub/admin/> prefix npx: <http://purl.org/nanopub/x/> prefix nt: <https://w3id.org/np/o/ntemplate/> prefix gen: <https://w3id.org/kpxl/gen/terms/> select ?subclass (coalesce(min(?untaggedLabel), min(?anyLabel)) as ?subclass_label) ?date ?np where { # the resource/ontology that the given (parent) class belongs to graph ?pg { ?_class_iri dct:isPartOf ?resource . } # collect the public keys of admins, maintainers, and members of the space maintaining that resource service <https://w3id.org/np/l/nanopub-query-1.1/repo/spaces> { select ?resource (group_concat(?mpk; separator=" ") as ?memberPubkeys) where { graph npa:graph { npa:thisRepo npa:hasCurrentSpaceState ?stateG . } graph ?stateG { ?resource npa:isMaintainedBy? ?space . ?ri a gen:RoleInstantiation ; npa:forSpace ?space ; npa:forAgent ?agent ; npa:hasRoleType ?rt . filter(?rt in (gen:AdminRole, gen:MaintainerRole, gen:MemberRole)) ?acct a npa:AccountState ; npa:agent ?agent ; npa:pubkey ?mpk . } } group by ?resource } # sub-classes of the given class, that are part of the same resource and signed by a space member graph ?g { ?subclass rdfs:subClassOf ?_class_iri . ?subclass dct:isPartOf ?resource . } graph npa:graph { ?np npa:hasValidSignatureForPublicKeyHash ?pubkey . filter not exists { ?npx npx:invalidates ?np ; npa:hasValidSignatureForPublicKeyHash ?pubkey . } ?np npa:hasGraph ?g . ?np np:hasPublicationInfo ?i . ?np dct:created ?date . } filter(contains(?memberPubkeys, ?pubkey)) # Keep only the winning definition of each sub-class: the newest live member-signed # nanopub describing it as part of this resource. Without this, an override -- which # records prov:wasDerivedFrom but never npx:supersedes, so nothing is invalidated -- # leaves every version live and the sub-class is listed once per version. Judging on # the winner also means a version that drops the rdfs:subClassOf triple removes the # row, and a withdrawal can be undone by publishing a newer version without the type. filter not exists { graph ?g2 { ?subclass dct:isPartOf ?resource . } graph npa:graph { ?np2 npa:hasValidSignatureForPublicKeyHash ?pubkey2 . filter not exists { ?np2x npx:invalidates ?np2 ; npa:hasValidSignatureForPublicKeyHash ?pubkey2 . } ?np2 npa:hasGraph ?g2 . ?np2 dct:created ?date2 . } filter(contains(?memberPubkeys, ?pubkey2)) filter(?date2 > ?date || (?date2 = ?date && str(?np2) > str(?np))) } # a sub-class withdrawn from the resource is not listed filter not exists { graph ?g { ?subclass a gen:WithdrawnTerm } } optional { graph ?g { ?subclass rdfs:label ?subclassLabel1 . } } optional { graph ?g { ?subclass dct:title ?subclassLabel2 . } } optional { graph ?i { ?subclass rdfs:label ?subclassLabel3 . } } optional { graph ?i { ?subclass nt:hasLabelFromApi ?subclassLabel4 . } } bind(coalesce(?subclassLabel1, ?subclassLabel2, ?subclassLabel3, ?subclassLabel4) as ?anyLabel) bind(if(lang(?anyLabel) = "", ?anyLabel, ?noLabel) as ?untaggedLabel) } group by ?subclass ?date ?np order by desc(?date)