16.14.9. Identity With Inverse Functional Properties
A graph used used with rdfs_rule_set may declare certain properties to be inversely functional. If one or more inverse functional properties (IFP's) are declared in the inference context used with the query, enabled with define input:inference = "context_name", then the following semantics apply:
-
If a literal is compared with an IRI, then the literal is substituted by all the subject IRI's where this literal occurs as a value of an IFP.
-
If two IRI's are compared for equality, they will be considered the same if there is an IFP P such that the same P has the same value on both subjects.
-
If an IRI is processed for distinctness in either distinct or group by, the IRI is first translated to be the IRI with the lowest ID among all IRI's that share an IFP value with this IRI.
Thus, if two IRI's are compared for distinctness, they will count as one if there is an IFP P with the same value with both IRI's. Literal data types are not translated into IRI's even if these literals occurred as IFP values of some subject.
It is possible to declare that specific values, even if they occur as values of an IFP in more than onme subject do not constitute identity between the subjects. For example, if two subjects were inferred to be the same because they had the same foaf:mbox_sha1sum, the SHA1 hash of mailto:// would be excluded. Two individuals have an email address that has a common default value are not the same.
In an ontology graph, a property IRI is declared to be inversely functional by making it an instance of the owl:InverseFunctionalProperty class. A value of an IFP can be declared null, i.e. sharing the value does not imply identity by by giving the IFP IRI a <http://www.openlinksw.com/schemas/virtrdf#nullIFPValue> property with the value to be ignored as the object.
Example
SQL>ttlp (' <john1> a <person> . <john2> a <person> . <mary> a <person> . <mike> a <person> . <john1> <name> "John" . <john2> <name> "John" . <john1> <address> "101 A street" . <john2> <address> "102 B street" . <john2> <knows> <mike> . <john1> <http://www.w3.org/2002/07/owl#sameAs> <john2> . <mary> <knows> "John" . <mike> <knows> <john1> . <mike> <knows> <john2> . <john1> <name> "Tarzan" . <mike> <nam> "Tarzan" . ', '', 'ifps'); SQL>ttlp (' <name> a <http://www.w3.org/2002/07/owl#InverseFunctionalProperty> . <name> <http://www.openlinksw.com/schemas/virtrdf#nullIFPValue> "Tarzan" . ', '', 'ifp_list'); SQL>rdfs_rule_set ('ifps', 'ifp_list'); SQL>SPARQL define input:inference "ifps" SELECT * FROM <ifps> WHERE {<john1> ?p ?o}; p o VARCHAR VARCHAR _______________________________________________________________________________ address 101 A street name John http://www.w3.org/2002/07/owl#sameAs john2 http://www.w3.org/1999/02/22-rdf-syntax-ns#type person name Tarzan name John knows mike http://www.w3.org/1999/02/22-rdf-syntax-ns#type person address 102 B street
We see that we get the properties of <john2> also.
SQL>SPARQL define input:inference "ifps" SELECT distinct ?p FROM <ifps> WHERE { ?p a <person>}; john2 mike mary
We see that we get only one John. But John is not the same as Mike because they share the name Tarzan which is not considered as implying identity. Which John we get is a matter of which gets the lowest internal ID. This is variable and arbitrary at load time but once loaded this is permanent as long as the set of subjects with the name John does not change.