Skolemization#

Example 1: “Ringo”#

Example taken from https://github.com/RDFLib/rdflib/issues/1404

from rdflib import Graph


ttl = '''
@prefix wd: <http://www.wikidata.org/entity/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

wd:Q1203 foaf:knows [ a foaf:Person;
    foaf:name "Ringo" ].
    

'''

graph = Graph()
graph.parse(data=ttl, format='turtle')
skolemized = graph.skolemize()
skolemized.namespace_manager.bind('foaf', 'http://xmlns.com/foaf/0.1/')
print(skolemized.serialize(format='turtle'))
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

<http://www.wikidata.org/entity/Q1203> foaf:knows <https://rdflib.github.io/.well-known/genid/rdflib/n2e5dd283b7844e8ba05b67b85cf27b37b1> .

<https://rdflib.github.io/.well-known/genid/rdflib/n2e5dd283b7844e8ba05b67b85cf27b37b1> a foaf:Person ;
    foaf:name "Ringo" .
deskolemized = skolemized.de_skolemize()
deskolemized.namespace_manager.bind('foaf', 'http://xmlns.com/foaf/0.1/')
print(deskolemized.serialize(format='turtle'))
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

<http://www.wikidata.org/entity/Q1203> foaf:knows [ a foaf:Person ;
            foaf:name "Ringo" ] .

Example 2: Husband#

infer = True
skolem = False
from rdflib import Graph
import owlrl
ttl = """
@prefix : <http://example.com/ns#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .


# T-Box

:Person a owl:Class .

:Husband
    a owl:Class ;
    owl:equivalentClass 
        [ a owl:Restriction ;
          owl:onProperty :has_partner ;
          owl:someValuesFrom :Person ] .

:has_partner a owl:ObjectProperty .


# A-Box

:Eve a :Person .
:Helen a :Person.

# Adam is a husband with a known partner 
:Adam
    a :Husband ;
    :has_partner :Eve .

# Hans is a person, who has a known partner.
# The inferencing system should classify him
# beeing a husband. 
:Hans
    a :Person ;
    :has_partner :Helen .

# Hugo is a husband. Thus he has a partner. 
# But we do not know the partner.
# Q: Does the inferencing system allocate a blank node automativally?
# A: no! 

:Hugo
    a :Husband .
"""
graph = Graph()
graph.parse(data = ttl, format='ttl')
print(f"#triples: {len(graph)}")
#triples: 14
if infer:
    owlrl.DeductiveClosure(owlrl.OWLRL_Semantics,
        axiomatic_triples = False).expand(graph)
print(f"infer: {infer}, #triples: {len(graph)}")
infer: True, #triples: 161
skolemized = graph.skolemize() if skolem else graph

skolemized.namespace_manager.bind('', 'http://example.com/ns#')
skolemized.namespace_manager.bind('owl', 'http://www.w3.org/2002/07/owl#')

print("skolem:", skolem, "\n\n", skolemized.serialize(format='turtle'))
skolem: False 

 @prefix : <http://example.com/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#> .

:Adam a _:n5006d37e50c046a4b2b98c94380919d8b1,
        :Husband,
        owl:Thing ;
    :has_partner :Eve ;
    owl:sameAs :Adam .

:Hans a _:n5006d37e50c046a4b2b98c94380919d8b1,
        :Husband,
        :Person,
        owl:Thing ;
    :has_partner :Helen ;
    owl:sameAs :Hans .

:Hugo a _:n5006d37e50c046a4b2b98c94380919d8b1,
        :Husband,
        owl:Thing ;
    owl:sameAs :Hugo .

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:langString a rdfs:Datatype ;
    owl:sameAs rdf:langString .

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:isDefinedBy a owl:AnnotationProperty ;
    owl:sameAs rdfs:isDefinedBy .

rdfs:label a owl:AnnotationProperty ;
    owl:sameAs rdfs:label .

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:onProperty owl:sameAs owl:onProperty .

owl:priorVersion a owl:AnnotationProperty ;
    owl:sameAs owl:priorVersion .

owl:sameAs owl:sameAs owl:sameAs .

owl:someValuesFrom owl:sameAs owl:someValuesFrom .

owl:versionInfo a owl:AnnotationProperty ;
    owl:sameAs owl:versionInfo .

:Eve a :Person,
        owl:Thing ;
    owl:sameAs :Eve .

:Helen a :Person,
        owl:Thing ;
    owl:sameAs :Helen .

owl:ObjectProperty owl:sameAs owl:ObjectProperty .

owl:Restriction owl:sameAs owl:Restriction .

owl:Nothing a owl:Class ;
    rdfs:subClassOf _:n5006d37e50c046a4b2b98c94380919d8b1,
        :Husband,
        :Person,
        owl:Nothing,
        owl:Thing ;
    owl:equivalentClass owl:Nothing ;
    owl:sameAs owl:Nothing .

:has_partner a owl:ObjectProperty ;
    rdfs:subPropertyOf :has_partner ;
    owl:equivalentProperty :has_partner ;
    owl:sameAs :has_partner .

owl:Class owl:sameAs owl:Class .

:Person a owl:Class ;
    rdfs:subClassOf :Person,
        owl:Thing ;
    owl:equivalentClass :Person ;
    owl:sameAs :Person .

:Husband a owl:Class ;
    rdfs:subClassOf _:n5006d37e50c046a4b2b98c94380919d8b1,
        :Husband,
        owl:Thing ;
    owl:equivalentClass _:n5006d37e50c046a4b2b98c94380919d8b1,
        :Husband ;
    owl:sameAs :Husband .

owl:AnnotationProperty owl:sameAs owl:AnnotationProperty .

owl:Thing a owl:Class ;
    rdfs:subClassOf owl:Thing ;
    owl:equivalentClass owl:Thing ;
    owl:sameAs owl:Thing .

rdfs:Datatype owl:sameAs rdfs:Datatype .

_:n5006d37e50c046a4b2b98c94380919d8b1 a owl:Restriction ;
    rdfs:subClassOf _:n5006d37e50c046a4b2b98c94380919d8b1,
        :Husband,
        owl:Thing ;
    owl:equivalentClass _:n5006d37e50c046a4b2b98c94380919d8b1,
        :Husband ;
    owl:onProperty :has_partner ;
    owl:sameAs _:n5006d37e50c046a4b2b98c94380919d8b1 ;
    owl:someValuesFrom :Person .
Q = """
PREFIX : <http://example.com/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#> 

SELECT ?type ?a ?b 
WHERE
  { ?a 
      a ?type;
      :has_partner ?b .}
"""

qres = skolemized.query(Q)
for p,q,r in qres:
    print(p,q,r)
http://example.com/ns#Husband http://example.com/ns#Adam http://example.com/ns#Eve
n5006d37e50c046a4b2b98c94380919d8b1 http://example.com/ns#Adam http://example.com/ns#Eve
http://www.w3.org/2002/07/owl#Thing http://example.com/ns#Adam http://example.com/ns#Eve
http://example.com/ns#Person http://example.com/ns#Hans http://example.com/ns#Helen
n5006d37e50c046a4b2b98c94380919d8b1 http://example.com/ns#Hans http://example.com/ns#Helen
http://www.w3.org/2002/07/owl#Thing http://example.com/ns#Hans http://example.com/ns#Helen
http://example.com/ns#Husband http://example.com/ns#Hans http://example.com/ns#Helen