1
2
3
4 """
5 This module is brute force implementation of the RDFS semantics on the top of RDFLib (with some caveats, see in the introductory text).
6
7
8 @requires: U{RDFLib<https://github.com/RDFLib/rdflib>}, 4.0.0 and higher
9 @license: This software is available for use under the U{W3C Software License<http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231>}
10 @organization: U{World Wide Web Consortium<http://www.w3.org>}
11 @author: U{Ivan Herman<a href="http://www.w3.org/People/Ivan/">}
12
13 """
14
15 __author__ = 'Ivan Herman'
16 __contact__ = 'Ivan Herman, ivan@w3.org'
17 __license__ = u'W3C® SOFTWARE NOTICE AND LICENSE, http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231'
18
19 from RDFClosure.RDFS import Property, type
20 from RDFClosure.RDFS import Resource, Class, subClassOf, subPropertyOf, domain, range
21 from RDFClosure.RDFS import Literal, ContainerMembershipProperty, member, Datatype
22
23 from RDFClosure.RDFS import RDFNS as ns_rdf
24
25 from RDFClosure.Closure import Core
26 from RDFClosure.AxiomaticTriples import RDFS_Axiomatic_Triples, RDFS_D_Axiomatic_Triples
27
28
29
30
31
32
34 """RDFS Semantics class, ie, implementation of the RDFS closure graph.
35
36 Note that the module does I{not} implement the so called Datatype entailment rules, simply because the underlying RDFLib does
37 not implement the datatypes (ie, RDFLib will not make the literal "1.00" and "1.00000" identical, although
38 even with all the ambiguities on datatypes, this I{should} be made equal...). Also, the so-called extensional entailment rules
39 (Section 7.3.1 in the RDF Semantics document) have not been implemented either.
40
41 The comments and references to the various rule follow the names as used in the U{RDF Semantics document<http://www.w3.org/TR/rdf-mt/>}.
42 """
43 - def __init__(self, graph, axioms, daxioms, rdfs):
44 """
45 @param graph: the RDF graph to be extended
46 @type graph: rdflib.Graph
47 @param axioms: whether (non-datatype) axiomatic triples should be added or not
48 @type axioms: bool
49 @param daxioms: whether datatype axiomatic triples should be added or not
50 @type daxioms: bool
51 @param rdfs: whether RDFS inference is also done (used in subclassed only)
52 @type rdfs: boolean
53 """
54 Core.__init__(self, graph, axioms, daxioms, rdfs)
55
67
69 """This is not really complete, because it just uses the comparison possibilities that rdflib provides."""
70 literals = self.literal_proxies.lit_to_bnode.keys()
71
72 for lt in literals:
73 if lt.dt is not None:
74 self.graph.add((self.literal_proxies.lit_to_bnode[lt], type, lt.dt))
75
76 for t in RDFS_D_Axiomatic_Triples :
77 self.graph.add(t)
78
79
81 """Some of the rules in the rule set are axiomatic in nature, meaning that they really have to be added only
82 once, there is no reason to add these in a cycle. These are performed by this method that is invoked only once
83 at the beginning of the process.
84
85 In this case this is related to a 'hidden' same as rules on literals with identical values (though different lexical values)
86 """
87
88
89 for lt1 in self.literal_proxies.lit_to_bnode.keys():
90 for lt2 in self.literal_proxies.lit_to_bnode.keys():
91 if lt1 != lt2:
92 try:
93 lt1_d = lt1.lit.toPython()
94 lt2_d = lt2.lit.toPython()
95 if lt1_d == lt2_d :
96
97
98
99 bn1 = self.literal_proxies.lit_to_bnode[lt1]
100 bn2 = self.literal_proxies.lit_to_bnode[lt2]
101 for (s, p, o) in self.graph.triples((None, None, bn1)) :
102 self.graph.add((s, p, bn2))
103 except:
104
105
106 pass
107
108 - def rules(self,t,cycle_num):
109 """
110 Go through the RDFS entailment rules rdf1, rdfs4-rdfs12, by extending the graph.
111 @param t: a triple (in the form of a tuple)
112 @param cycle_num: which cycle are we in, starting with 1. Can be used for some (though minor) optimization.
113 """
114 s, p, o = t
115
116 self.store_triple((p, type, Property))
117
118 if cycle_num == 1:
119 self.store_triple((s, type, Resource))
120
121 if cycle_num == 1:
122 self.store_triple((o, type, Resource))
123 if p == domain:
124
125 for uuu, Y, yyy in self.graph.triples((None, s, None)):
126 self.store_triple((uuu, type, o))
127 if p == range:
128
129 for uuu, Y, vvv in self.graph.triples((None, s, None)):
130 self.store_triple((vvv, type, o))
131 if p == subPropertyOf:
132
133 for Z, Y, xxx in self.graph.triples((o, subPropertyOf, None)):
134 self.store_triple((s, subPropertyOf, xxx))
135
136 for zzz, Z, www in self.graph.triples((None, s, None)):
137 self.store_triple((zzz, o, www))
138 if p == type and o == Property:
139
140 self.store_triple((s, subPropertyOf, s))
141 if p == type and o == Class:
142
143 self.store_triple((s, subClassOf, Resource))
144
145 self.store_triple((s, subClassOf, s))
146 if p == subClassOf:
147
148 for vvv, Y, Z in self.graph.triples((None, type, s)):
149 self.store_triple((vvv, type, o))
150
151 for Z, Y, xxx in self.graph.triples((o, subClassOf, None)):
152 self.store_triple((s, subClassOf, xxx))
153 if p == type and o == ContainerMembershipProperty :
154
155 self.store_triple((s, subPropertyOf, member))
156 if p == type and o == Datatype:
157 self.store_triple((s, subClassOf, Literal))
158