x in A or x in B (or in both)#
Context: https://www.dublincore.org/specifications/openwemi/ , i.e. the following files:
Specification: https://www.dublincore.org/specifications/openwemi/specification/
turtle File: https://dcmi.github.io/openwemi/ns/openWEMI.ttl (Normative)
Vocabulary > yellow: https://dcmi.github.io/openwemi/ns/openWEMI.html#instantiates
Vocabulary > green: https://dcmi.github.io/openwemi/ns/openWEMI.html#manifests
This document mainly addresses the issue dcmi/openwemi#123.
Starting point#
The figure below basically suggests:
yellow arrows:
IF we have a relation
x instantiates z
THEN
z
is a Work; orz
is an Expression; orz
is a Manifestation; or both, or all of the above.
green arrows:
IF we have a relation
p manifests q
THEN
q
is a Work; orq
is an Expression; or both.
(Note that we do not have a natural language like xor, but a math like inclusive or.)
Source: https://www.dublincore.org/specifications/openwemi/specification/
We do have two interpretations of the green dashed line:
(1)
q
is an element of Work; orq
is an element of Expression; or both.(2)
q
is an element of the union of Work and Expression
Similarly we do have two interpretations of the yellow dashed line:
(1)
z
is an element of Work; orz
is an element of Expression; orz
is an element of Manifestation; or both, or all of the above.(2)
z
is an element of the union of Work, Expression and Manifestation.
Note again: we have not an exclusive xor, but an inclusive or.
The image above and also the non normative english text of the open-WEMI Spec suggest (1). And in the normative ttl-file the definition of openwemi:instantiates
it is given:
> "A relationship asserted from an Item to a Manifestation, an Expression, or a Work."@en
However, the normative turtle file https://dcmi.github.io/openwemi/ns/openWEMI.ttl in fact implements (2).
Our contribution#
reconstruct (parts of) the normative ttl file
omit all not necessary or redundant triples
turn implicit classes to explicit named classes
We tried to vizualize the reconstructed class hierarchy. This is an intermediary result (comments are welcome):
open WEMI reconstructed#
import rdflib
import owlrl
from IPython.display import display, Markdown
prefixes = """
@prefix : <http://example.org/ns#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix dct: <http://purl.org/dc/terms/> .
@prefix openwemi: <https://dcmi.github.io/openwemi/ns#> .
"""
TBox, terminology box, ontology in the narrower sense:
ttl = prefixes + """
#
# T-Box
#
# WEMI
# Work OR Expression OR Manifestation OR Item
# i.e. unionOf(Work, Expression, Manifestation, Item)
# i.e. same as openwemi:endeavor
:WEMI a owl:Class;
owl:unionOf (
:Work
:Expression
:Manifestation
:Item ) .
# WEM ... Work OR Expression OR Manifestation
# from https://dcmi.github.io/openwemi/ns/openWEMI.ttl :
#openwemi:instantiates
# a rdf:Property ;
# rdfs:label "instantiates"@en ;
# rdfs:comment "An Endeavor that instantiates a Manifestation, an Expression or a Work."@en ;
# rdfs:isDefinedBy openwemi: ;
# rdfs:subPropertyOf dct:relation ;
# rdfs:domain openwemi:Item ;
# dct:description "A relationship asserted from an Item to a Manifestation, an Expression, or a Work."@en ;
# rdfs:range [
# a owl:Class ;
# owl:unionOf (
# openwemi:Work
# openwemi:Expression
# openwemi:Manifestation
# )
# ] .
:instantiates
a rdf:Property ;
rdfs:domain :Item ;
rdfs:range :WEM .
:instantiatedBy
a rdf:Property ;
owl:inverseOf :instantiates .
# given in openWEMI.ttl, but redundant:
# rdfs:range :Item ;
# rdfs:domain :WEM .
:WEM a owl:Class;
owl:unionOf (
:Work
:Expression
:Manifestation) .
# trivial subclass relationship
# however, we *do* have to assert it explicitly,
# for it cannot be inferred by our owlrl reasoner
# (i.e. profile OWL2 RL)
:WEM rdfs:subClassOf :WEMI .
:manifests
a rdf:Property ;
rdfs:domain :Manifestation ;
rdfs:range :WE .
# WE ... Work OR Expression
:WE a owl:Class;
owl:unionOf (
:Work
:Expression ) .
# assert manually; cannot be inferred in profile OWL2 RL
:WE rdfs:subClassOf :WEM .
:WEM rdfs:subClassOf :WEMI .
"""
ABox, assertion box: We add some example instances, i.e. xxx
and zzz
(we use variables which are aligned with rule rdfs3):
ttl += """
#
# A-Box
#
# x_1 == xxx, z_1 == zzz in rule rdfs3
:x_1 :instantiates :z_1 .
:z_2 :instantiatedBy :x_2 .
:p_3 :manifests :q_3 .
:w_1 a :Work .
"""
After inferencing the resulting graphs may be pretty long. We define a utility function to select only the interesting paragraphs.
def focus(focus_curie_list, ttl, sort = False):
"""Split a text file into paragraps.
Return only these paragraphs which contain at least one string from focus_curie_list."""
par_list = [ paragraph for paragraph in ttl.split("\n\n") \
if any( [ focus_curie in paragraph for focus_curie in focus_curie_list ] ) ]
if sort:
result = "\n\n".join( sorted(par_list) )
else:
result = "\n\n".join( par_list )
return result
def multi_focus(focus_curie_list, graph_dict):
"""apply focus() on a dict of graphs and print the result side by side"""
result = {}
print(f"{focus_curie_list=}\n")
for graph_name, graph in graph_dict.items():
ttl = graph.serialize()
result[graph_name] = focus(focus_curie_list, ttl, sort=True)
print(f"""=== Graph {graph_name}: {len(graph_name)} triples ===\n\n{result[graph_name]}\n""")
return None
gd = {} # graph dict, dict of graphs
gd['original'] = rdflib.Graph().parse(data= ttl)
gd['with_inferencing'] = rdflib.Graph().parse( data=gd['original'].serialize() ) # deep copy
# infer maximum set of triples
owlrl.DeductiveClosure(owlrl.OWLRL_Semantics,
axiomatic_triples = False).expand(gd['with_inferencing'])
# for graph_name, graph in gd.items(): print(f"{graph_name=} has {len(graph)} triples")
interesting = [ ":x_1" ]
multi_focus(interesting, gd )
focus_curie_list=[':x_1']
=== Graph original: 8 triples ===
:x_1 :instantiates :z_1 .
=== Graph with_inferencing: 16 triples ===
:x_1 a :Item,
:WEMI,
owl:Thing ;
:instantiates :z_1 ;
owl:sameAs :x_1 .
:z_1 a :WEM,
:WEMI,
owl:Thing ;
:instantiatedBy :x_1 ;
owl:sameAs :z_1 .
interesting = [ ":p_", ":q_" ]
multi_focus(interesting, gd )
focus_curie_list=[':p_', ':q_']
=== Graph original: 8 triples ===
:p_3 :manifests :q_3 .
=== Graph with_inferencing: 16 triples ===
:p_3 a :Manifestation,
:WEM,
:WEMI,
owl:Thing ;
:manifests :q_3 ;
owl:sameAs :p_3 .
:q_3 a :WE,
:WEM,
:WEMI,
owl:Thing ;
owl:sameAs :q_3 .
interesting = [ ":w_" ]
multi_focus(interesting, gd )
focus_curie_list=[':w_']
=== Graph original: 8 triples ===
:w_1 a :Work .
=== Graph with_inferencing: 16 triples ===
:w_1 a :WE,
:WEM,
:WEMI,
:Work,
owl:Thing ;
owl:sameAs :w_1 .
Background Knowledge#
Sets in Python#
Background knowledge 1: set intersection and union, here by example in Python.
Example: We have the set of some even numbers and some prime numbers.
even = {2,4,6,8}
prime = {2,3,5,7}
We build a new set, the intersection:
even_AND_prime = even & prime
even_AND_prime
{2}
and the union set:
even_OR_prime = even | prime
even_OR_prime
{2, 3, 4, 5, 6, 7, 8}
Add 100
to the union set (but not to the respective subsets):
z = 100
even_OR_prime.add(z)
even_OR_prime
{2, 3, 4, 5, 6, 7, 8, 100}
Now 100
is in (i.e. an element of) the union set, but not in any of it’s subsets:
z in even_OR_prime, z in even, z in prime
(True, False, False)
Rule rdfs3, Semantics of rdfs:range#
rdfs3, https://www.w3.org/TR/rdf11-mt/#patterns-of-rdfs-entailment-informative
Rule rdfs3:
IF an RDF graph contains the triples
aaa rdfs:range xxx
AND
yyy aaa zzz
THEN we can entail the triple
zzz rdf:type xxx
Test 1: multiple rdfs:range statements#
rdfs3, https://www.w3.org/TR/rdf-schema/#ch_range
Where P has more than one rdfs:range property, then the resources denoted by the objects of triples with predicate P are instances of all the classes stated by the rdfs:range properties.
ttl_test_rdfs3 = prefixes + """
# IF
:aaa rdfs:range :xxx1 .
:aaa rdfs:range :xxx2 .
# AND
:yyy :aaa :zzz .
# THEN these triples should be inferred:
# :zzz rdf:type :xxx1 .
# :zzz rdf:type :xxx2 .
"""
test_rdfs3 = {} # graph dict, dict of graphs
test_rdfs3['original'] = rdflib.Graph().parse(data= ttl_test_rdfs3)
test_rdfs3['with_inferencing'] = rdflib.Graph().parse( data=test_rdfs3['original'].serialize() ) # deep copy
# infer maximum set of triples
owlrl.DeductiveClosure(owlrl.OWLRL_Semantics,
axiomatic_triples = False).expand(test_rdfs3['with_inferencing'])
interesting = [ "zzz" ]
multi_focus(interesting, test_rdfs3 )
focus_curie_list=['zzz']
=== Graph original: 8 triples ===
:yyy :aaa :zzz .
=== Graph with_inferencing: 16 triples ===
:yyy :aaa :zzz ;
owl:sameAs :yyy .
:zzz a :xxx1,
:xxx2 ;
owl:sameAs :zzz .
We get :zzz a :xxx1, :xxx2
: QED!
Test 2: union of multiple range classes#
In the WEMI ttl file we do not have multiple ranges. Instead we have a union of more than one classes:
openwemi:instantiates
rdfs:range [
owl:unionOf (
openwemi:Work
openwemi:Expression
openwemi:Manifestation
)
] .
The term openwemi:instantiates rdfs:range [ owl:unionOf ( ... ) ]
has an anonymous class in object position. However, it is trivial to replace it with a named class:
openwemi:instantiates
rdfs:range :WEM .
:WEM owl:unionOf (
openwemi:Work
openwemi:Expression
openwemi:Manifestation
) .
We apply rdfs3 to the WEMI ttl file, i.e. aaa = instantiates
, xxx = WEM
with WEM = unionOf(Work, Expression, Manifestation)
:
IF
:instantiates rdfs:range :WEM .
AND
:yyy :instantiates :zzz .
THEN
:zzz rdf:type :WEM .
Again we test our understanding based on the original definition of rule rdfs3:
rdfs3, https://www.w3.org/TR/rdf11-mt/#patterns-of-rdfs-entailment-informative
Rule rdfs3:
IF:
aaa rdfs:range xxx
AND:
yyy aaa zzz .
THEN:
zzz rdf:type xxx .
ttl2_test_rdfs3 = prefixes + """
@prefix : <http://example.org/ns#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix dct: <http://purl.org/dc/terms/> .
@prefix openwemi: <https://dcmi.github.io/openwemi/ns#> .
# IF
:aaa rdfs:range :xxx .
:xxx owl:unionOf (:xxx1 :xxx2) .
# AND
:yyy :aaa :zzz .
# THEN it should be inferred:
#:zzz a :xxx .
# NOTE: It should be NOT inferred sth. like this:
#:zzz a :xxx1 .
#:zzz a :xxx2 .
"""
# print(ttl2_test_rdfs3)
test2_rdfs3 = {} # graph dict, dict of graphs
test2_rdfs3['original'] = rdflib.Graph().parse(data= ttl2_test_rdfs3)
test2_rdfs3['with_inferencing'] = rdflib.Graph().parse( data=test2_rdfs3['original'].serialize() ) # deep copy
# infer maximum set of triples
owlrl.DeductiveClosure(owlrl.OWLRL_Semantics,
axiomatic_triples = False).expand(test2_rdfs3['with_inferencing'])
interesting = ["zzz" ]
multi_focus(interesting, test2_rdfs3 )
focus_curie_list=['zzz']
=== Graph original: 8 triples ===
:yyy :aaa :zzz .
=== Graph with_inferencing: 16 triples ===
:yyy :aaa :zzz ;
owl:sameAs :yyy .
:zzz a :xxx ;
owl:sameAs :zzz .
We (only) get :zzz a :xxx
: QED!
The full graphs#
print(gd['original'].serialize())
@prefix : <http://example.org/ns#> .
@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#> .
:instantiatedBy a rdf:Property ;
owl:inverseOf :instantiates .
:manifests a rdf:Property ;
rdfs:domain :Manifestation ;
rdfs:range :WE .
:p_3 :manifests :q_3 .
:w_1 a :Work .
:x_1 :instantiates :z_1 .
:z_2 :instantiatedBy :x_2 .
:WE a owl:Class ;
rdfs:subClassOf :WEM ;
owl:unionOf ( :Work :Expression ) .
:WEMI a owl:Class ;
owl:unionOf ( :Work :Expression :Manifestation :Item ) .
:instantiates a rdf:Property ;
rdfs:domain :Item ;
rdfs:range :WEM .
:WEM a owl:Class ;
rdfs:subClassOf :WEMI ;
owl:unionOf ( :Work :Expression :Manifestation ) .
print(gd['with_inferencing'].serialize())
@prefix : <http://example.org/ns#> .
@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#> .
:p_3 a :Manifestation,
:WEM,
:WEMI,
owl:Thing ;
:manifests :q_3 ;
owl:sameAs :p_3 .
:w_1 a :WE,
:WEM,
:WEMI,
:Work,
owl:Thing ;
owl:sameAs :w_1 .
rdf:HTML a rdfs:Datatype ;
owl:sameAs rdf:HTML .
rdf:PlainLiteral a rdfs:Datatype ;
owl:sameAs rdf:PlainLiteral .
rdf:XMLLiteral a rdfs:Datatype ;
owl:sameAs rdf:XMLLiteral .
rdf:first owl:sameAs rdf:first .
rdf:langString a rdfs:Datatype ;
owl:sameAs rdf:langString .
rdf:rest owl:sameAs rdf:rest .
rdf:type owl:sameAs rdf:type .
rdfs:Literal a rdfs:Datatype ;
owl:sameAs rdfs:Literal .
rdfs:comment a owl:AnnotationProperty ;
owl:sameAs rdfs:comment .
rdfs:domain owl:sameAs rdfs:domain .
rdfs:isDefinedBy a owl:AnnotationProperty ;
owl:sameAs rdfs:isDefinedBy .
rdfs:label a owl:AnnotationProperty ;
owl:sameAs rdfs:label .
rdfs:range owl:sameAs rdfs:range .
rdfs:seeAlso a owl:AnnotationProperty ;
owl:sameAs rdfs:seeAlso .
rdfs:subClassOf owl:sameAs rdfs:subClassOf .
rdfs:subPropertyOf owl:sameAs rdfs:subPropertyOf .
xsd:NCName a rdfs:Datatype ;
owl:sameAs xsd:NCName .
xsd:NMTOKEN a rdfs:Datatype ;
owl:sameAs xsd:NMTOKEN .
xsd:Name a rdfs:Datatype ;
owl:sameAs xsd:Name .
xsd:anyURI a rdfs:Datatype ;
owl:sameAs xsd:anyURI .
xsd:base64Binary a rdfs:Datatype ;
owl:sameAs xsd:base64Binary .
xsd:boolean a rdfs:Datatype ;
owl:sameAs xsd:boolean .
xsd:byte a rdfs:Datatype ;
owl:sameAs xsd:byte .
xsd:date a rdfs:Datatype ;
owl:sameAs xsd:date .
xsd:dateTime a rdfs:Datatype ;
owl:sameAs xsd:dateTime .
xsd:dateTimeStamp a rdfs:Datatype ;
owl:sameAs xsd:dateTimeStamp .
xsd:decimal a rdfs:Datatype ;
owl:sameAs xsd:decimal .
xsd:double a rdfs:Datatype ;
owl:sameAs xsd:double .
xsd:float a rdfs:Datatype ;
owl:sameAs xsd:float .
xsd:hexBinary a rdfs:Datatype ;
owl:sameAs xsd:hexBinary .
xsd:int a rdfs:Datatype ;
owl:sameAs xsd:int .
xsd:integer a rdfs:Datatype ;
owl:sameAs xsd:integer .
xsd:language a rdfs:Datatype ;
owl:sameAs xsd:language .
xsd:long a rdfs:Datatype ;
owl:sameAs xsd:long .
xsd:negativeInteger a rdfs:Datatype ;
owl:sameAs xsd:negativeInteger .
xsd:nonNegativeInteger a rdfs:Datatype ;
owl:sameAs xsd:nonNegativeInteger .
xsd:nonPositiveInteger a rdfs:Datatype ;
owl:sameAs xsd:nonPositiveInteger .
xsd:normalizedString a rdfs:Datatype ;
owl:sameAs xsd:normalizedString .
xsd:positiveInteger a rdfs:Datatype ;
owl:sameAs xsd:positiveInteger .
xsd:short a rdfs:Datatype ;
owl:sameAs xsd:short .
xsd:string a rdfs:Datatype ;
owl:sameAs xsd:string .
xsd:time a rdfs:Datatype ;
owl:sameAs xsd:time .
xsd:token a rdfs:Datatype ;
owl:sameAs xsd:token .
xsd:unsignedByte a rdfs:Datatype ;
owl:sameAs xsd:unsignedByte .
xsd:unsignedInt a rdfs:Datatype ;
owl:sameAs xsd:unsignedInt .
xsd:unsignedLong a rdfs:Datatype ;
owl:sameAs xsd:unsignedLong .
xsd:unsignedShort a rdfs:Datatype ;
owl:sameAs xsd:unsignedShort .
owl:backwardCompatibleWith a owl:AnnotationProperty ;
owl:sameAs owl:backwardCompatibleWith .
owl:deprecated a owl:AnnotationProperty ;
owl:sameAs owl:deprecated .
owl:equivalentClass owl:sameAs owl:equivalentClass .
owl:equivalentProperty owl:sameAs owl:equivalentProperty .
owl:incompatibleWith a owl:AnnotationProperty ;
owl:sameAs owl:incompatibleWith .
owl:inverseOf owl:sameAs owl:inverseOf .
owl:priorVersion a owl:AnnotationProperty ;
owl:sameAs owl:priorVersion .
owl:sameAs owl:sameAs owl:sameAs .
owl:unionOf owl:sameAs owl:unionOf .
owl:versionInfo a owl:AnnotationProperty ;
owl:sameAs owl:versionInfo .
:q_3 a :WE,
:WEM,
:WEMI,
owl:Thing ;
owl:sameAs :q_3 .
:x_1 a :Item,
:WEMI,
owl:Thing ;
:instantiates :z_1 ;
owl:sameAs :x_1 .
:x_2 a :Item,
:WEMI,
owl:Thing ;
:instantiates :z_2 ;
owl:sameAs :x_2 .
:z_1 a :WEM,
:WEMI,
owl:Thing ;
:instantiatedBy :x_1 ;
owl:sameAs :z_1 .
:z_2 a :WEM,
:WEMI,
owl:Thing ;
:instantiatedBy :x_2 ;
owl:sameAs :z_2 .
:instantiatedBy a rdf:Property ;
rdfs:subPropertyOf :instantiatedBy ;
owl:equivalentProperty :instantiatedBy ;
owl:inverseOf :instantiates ;
owl:sameAs :instantiatedBy .
:manifests a rdf:Property ;
rdfs:domain :Manifestation,
:WEM,
:WEMI,
owl:Thing ;
rdfs:range :WE,
:WEM,
:WEMI,
owl:Thing ;
rdfs:subPropertyOf :manifests ;
owl:equivalentProperty :manifests ;
owl:sameAs :manifests .
owl:Nothing a owl:Class ;
rdfs:subClassOf :WE,
:WEM,
:WEMI,
owl:Nothing,
owl:Thing ;
owl:equivalentClass owl:Nothing ;
owl:sameAs owl:Nothing .
:Expression rdfs:subClassOf :WE,
:WEM,
:WEMI,
owl:Thing ;
owl:sameAs :Expression .
:instantiates a rdf:Property ;
rdfs:domain :Item,
:WEMI,
owl:Thing ;
rdfs:range :WEM,
:WEMI,
owl:Thing ;
rdfs:subPropertyOf :instantiates ;
owl:equivalentProperty :instantiates ;
owl:sameAs :instantiates .
rdf:Property owl:sameAs rdf:Property .
() owl:sameAs () .
:Item rdfs:subClassOf :WEMI,
owl:Thing ;
owl:sameAs :Item .
:Manifestation rdfs:subClassOf :WEM,
:WEMI,
owl:Thing ;
owl:sameAs :Manifestation .
:Work rdfs:subClassOf :WE,
:WEM,
:WEMI,
owl:Thing ;
owl:sameAs :Work .
owl:Class owl:sameAs owl:Class .
:WE a owl:Class ;
rdfs:subClassOf :WE,
:WEM,
:WEMI,
owl:Thing ;
owl:equivalentClass :WE ;
owl:sameAs :WE ;
owl:unionOf _:nf7c16469ece44a5db0d447cd588522abb1 .
owl:AnnotationProperty owl:sameAs owl:AnnotationProperty .
:WEM a owl:Class ;
rdfs:subClassOf :WEM,
:WEMI,
owl:Thing ;
owl:equivalentClass :WEM ;
owl:sameAs :WEM ;
owl:unionOf _:nf7c16469ece44a5db0d447cd588522abb7 .
:WEMI a owl:Class ;
rdfs:subClassOf :WEMI,
owl:Thing ;
owl:equivalentClass :WEMI ;
owl:sameAs :WEMI ;
owl:unionOf _:nf7c16469ece44a5db0d447cd588522abb3 .
owl:Thing a owl:Class ;
rdfs:subClassOf owl:Thing ;
owl:equivalentClass owl:Thing ;
owl:sameAs owl:Thing .
rdfs:Datatype owl:sameAs rdfs:Datatype .
_:nf7c16469ece44a5db0d447cd588522abb1 rdf:first :Work ;
rdf:rest _:nf7c16469ece44a5db0d447cd588522abb2 ;
owl:sameAs _:nf7c16469ece44a5db0d447cd588522abb1 .
_:nf7c16469ece44a5db0d447cd588522abb2 rdf:first :Expression ;
rdf:rest () ;
owl:sameAs _:nf7c16469ece44a5db0d447cd588522abb2 .
_:nf7c16469ece44a5db0d447cd588522abb3 rdf:first :Work ;
rdf:rest _:nf7c16469ece44a5db0d447cd588522abb4 ;
owl:sameAs _:nf7c16469ece44a5db0d447cd588522abb3 .
_:nf7c16469ece44a5db0d447cd588522abb4 rdf:first :Expression ;
rdf:rest _:nf7c16469ece44a5db0d447cd588522abb5 ;
owl:sameAs _:nf7c16469ece44a5db0d447cd588522abb4 .
_:nf7c16469ece44a5db0d447cd588522abb5 rdf:first :Manifestation ;
rdf:rest _:nf7c16469ece44a5db0d447cd588522abb6 ;
owl:sameAs _:nf7c16469ece44a5db0d447cd588522abb5 .
_:nf7c16469ece44a5db0d447cd588522abb6 rdf:first :Item ;
rdf:rest () ;
owl:sameAs _:nf7c16469ece44a5db0d447cd588522abb6 .
_:nf7c16469ece44a5db0d447cd588522abb7 rdf:first :Work ;
rdf:rest _:nf7c16469ece44a5db0d447cd588522abb8 ;
owl:sameAs _:nf7c16469ece44a5db0d447cd588522abb7 .
_:nf7c16469ece44a5db0d447cd588522abb8 rdf:first :Expression ;
rdf:rest _:nf7c16469ece44a5db0d447cd588522abb9 ;
owl:sameAs _:nf7c16469ece44a5db0d447cd588522abb8 .
_:nf7c16469ece44a5db0d447cd588522abb9 rdf:first :Manifestation ;
rdf:rest () ;
owl:sameAs _:nf7c16469ece44a5db0d447cd588522abb9 .