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<http://rdflib.net>}, 2.2.2. 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  """ 
 16  $Id: RDFSClosure.py,v 1.14 2009/09/19 17:23:42 ivan Exp $ $Date: 2009/09/19 17:23:42 $ 
 17  """ 
 18   
 19  __author__  = 'Ivan Herman' 
 20  __contact__ = 'Ivan Herman, ivan@w3.org' 
 21  __license__ = u'W3C® SOFTWARE NOTICE AND LICENSE, http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231' 
 22   
 23  from rdflib.RDF         import Property, type 
 24  from rdflib.RDFS        import Resource, Class, subClassOf, subPropertyOf, domain, range 
 25  from rdflib.RDFS        import Literal, ContainerMembershipProperty, member, Datatype 
 26   
 27  from rdflib.RDF         import RDFNS as ns_rdf 
 28   
 29  from RDFClosure.Closure          import Core 
 30  from RDFClosure.AxiomaticTriples import RDFS_Axiomatic_Triples, RDFS_D_Axiomatic_Triples 
 31   
 32   
 33  ###################################################################################################### 
 34   
 35  ## RDFS Semantics class 
36 -class RDFS_Semantics(Core) :
37 """RDFS Semantics class, ie, implementation of the RDFS closure graph. 38 39 Note that the module does I{not} implement the so called Datatype entailement rules, simply because the underlying RDFLib does 40 not implement the datatypes (ie, RDFLib will not make the literal "1.00" and "1.00000" identical, although 41 even with all the ambiguities on datatypes, this I{should} be made equal...). Also, the so-called extensional entailement rules 42 (Section 7.3.1 in the RDF Semantics document) have not been implemented either. 43 44 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/>}. 45 """
46 - def __init__(self,graph, axioms, daxioms, rdfs) :
47 """ 48 @param graph: the RDF graph to be extended 49 @type graph: rdflib.Graph 50 @param axioms: whether (non-datatype) axiomatic triples should be added or not 51 @type axioms: Boolean 52 @param daxioms: whether datatype axiomatic triples should be added or not 53 @type daxioms: Boolean 54 @param rdfs: whether RDFS inference is also done (used in subclassed only) 55 @type rdfs: boolean 56 """ 57 Core.__init__(self, graph, axioms, daxioms, rdfs)
58
59 - def add_axioms(self) :
60 """Add axioms 61 """ 62 for t in RDFS_Axiomatic_Triples : self.graph.add(t) 63 for i in xrange(1,self.IMaxNum+1) : 64 ci = ns_rdf[("_%d" % i)] 65 self.graph.add((ci,type,Property)) 66 self.graph.add((ci,domain,Resource)) 67 self.graph.add((ci,range,Resource)) 68 self.graph.add((ci,type,ContainerMembershipProperty))
69
70 - def add_d_axioms(self) :
71 """This is not really complete, because it just uses the comparison possibilities that rdflib provides.""" 72 literals = self.literal_proxies.lit_to_bnode.keys() 73 # #1 74 for lt in literals : 75 if lt.dt != None : 76 self.graph.add((self.literal_proxies.lit_to_bnode[lt], type, lt.dt)) 77 78 for t in RDFS_D_Axiomatic_Triples : self.graph.add(t)
79
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 Exception, e : 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 entailement 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 : self.store_triple((s, type, Resource)) 119 # rdfs4b 120 if cycle_num == 1 : self.store_triple((o, type, Resource)) 121 if p == domain : 122 # rdfs2 123 for uuu,Y,yyy in self.graph.triples((None, s, None)) : 124 self.store_triple((uuu, type, o)) 125 if p == range : 126 # rdfs3 127 for uuu,Y,vvv in self.graph.triples((None, s, None)) : 128 self.store_triple((vvv, type, o)) 129 if p == subPropertyOf : 130 # rdfs5 131 for Z,Y,xxx in self.graph.triples((o, subPropertyOf, None)) : 132 self.store_triple((s,subPropertyOf,xxx)) 133 # rdfs7 134 for zzz,Z,www in self.graph.triples((None, s, None)) : 135 self.store_triple((zzz, o, www)) 136 if p == type and o == Property : 137 # rdfs6 138 self.store_triple((s, subPropertyOf, s)) 139 if p == type and o == Class : 140 # rdfs8 141 self.store_triple((s, subClassOf, Resource)) 142 # rdfs10 143 self.store_triple((s, subClassOf, s)) 144 if p == subClassOf : 145 # rdfs9 146 for vvv,Y,Z in self.graph.triples((None, type, s)) : 147 self.store_triple((vvv, type, o)) 148 # rdfs11 149 for Z,Y,xxx in self.graph.triples((o, subClassOf, None)) : 150 self.store_triple((s, subClassOf, xxx)) 151 if p == type and o == ContainerMembershipProperty : 152 # rdfs12 153 self.store_triple((s, subPropertyOf, member)) 154 if p == type and o == Datatype : 155 self.store_triple((s, subClassOf, Literal))
156