Package RDFClosure :: Module RDFSClosure
[hide private]
[frames] | no frames]

Source Code for Module RDFClosure.RDFSClosure

  1  #!/d/Bin/Python/python.exe 
  2  # -*- coding: utf-8 -*- 
  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  # noinspection PyPep8Naming 
 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  ## RDFS Semantics class 
 32  # noinspection PyPep8Naming 
33 -class RDFS_Semantics(Core):
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
56 - def add_axioms(self):
57 """Add axioms 58 """ 59 for t in RDFS_Axiomatic_Triples: 60 self.graph.add(t) 61 for i in xrange(1, self.IMaxNum + 1): 62 ci = ns_rdf[("_%d" % i)] 63 self.graph.add((ci, type, Property)) 64 self.graph.add((ci, domain, Resource)) 65 self.graph.add((ci, range, Resource)) 66 self.graph.add((ci, type, ContainerMembershipProperty))
67
68 - def add_d_axioms(self):
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 # #1 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 # noinspection PyBroadException
80 - def one_time_rules(self):
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 # There is also a hidden sameAs rule in RDF Semantics: if a literal appears in a triple, and another one has the same value, 88 # then the triple should be duplicated with the other value. 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 # In OWL, this line is simply stating a sameAs for the corresponding BNodes, and then let 97 # the usual rules take effect. In RDFS this is not possible, so the sameAs rule is, essentially 98 # replicated... 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 # there may be a problem with one of the python conversions; the rule is imply ignored 105 #raise e 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 # rdf1 116 self.store_triple((p, type, Property)) 117 # rdfs4a 118 if cycle_num == 1: 119 self.store_triple((s, type, Resource)) 120 # rdfs4b 121 if cycle_num == 1: 122 self.store_triple((o, type, Resource)) 123 if p == domain: 124 # rdfs2 125 for uuu, Y, yyy in self.graph.triples((None, s, None)): 126 self.store_triple((uuu, type, o)) 127 if p == range: 128 # rdfs3 129 for uuu, Y, vvv in self.graph.triples((None, s, None)): 130 self.store_triple((vvv, type, o)) 131 if p == subPropertyOf: 132 # rdfs5 133 for Z, Y, xxx in self.graph.triples((o, subPropertyOf, None)): 134 self.store_triple((s, subPropertyOf, xxx)) 135 # rdfs7 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 # rdfs6 140 self.store_triple((s, subPropertyOf, s)) 141 if p == type and o == Class: 142 # rdfs8 143 self.store_triple((s, subClassOf, Resource)) 144 # rdfs10 145 self.store_triple((s, subClassOf, s)) 146 if p == subClassOf: 147 # rdfs9 148 for vvv, Y, Z in self.graph.triples((None, type, s)): 149 self.store_triple((vvv, type, o)) 150 # rdfs11 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 # rdfs12 155 self.store_triple((s, subPropertyOf, member)) 156 if p == type and o == Datatype: 157 self.store_triple((s, subClassOf, Literal))
158