2

I specified an "isPartOf" object property in Protege, and I asserted that

"Room_1 isPartOf Apartment_1".

Both "Room_1" and "Apartment_1" are individuals. The relevant codes in the OWL file are like the following:

<rdf:RDF xmlns="http://www.xxx.come/example#"
 xml:base="http://www.xxx.come/example"
 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 xmlns:owl="http://www.w3.org/2002/07/owl#"
 xmlns:xml="http://www.w3.org/XML/1998/namespace"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
 xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">


<!-- http://www.xxx.come/example#isPartOf -->

<owl:ObjectProperty rdf:about="http://www.xxx.come/example#isTemporalPartOf">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#AsymmetricProperty"/>
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#TransitiveProperty"/>
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#ReflexiveProperty"/>
    <rdfs:domain rdf:resource="http://www.xxx.come/example#Room"/>
    <rdfs:range rdf:resource="http://www.xxx.come/example#Apartment"/>
</owl:ObjectProperty>


<!-- http://www.xxx.come/example#Room_1 -->

<owl:NamedIndividual rdf:about="http://www.xxx.come/example#Room_1">
    <rdf:type rdf:resource="http://www.xxx.come/example#Room"/>
    <isPartOf rdf:resource="http://http://www.xxx.come/example#Apartment_1"/>
    <hasSize rdf:datatype="http://www.w3.org/2001/XMLSchema#double">99.6</hasSize>
    <hasSize rdf:datatype="http://www.w3.org/2001/XMLSchema#double">145.5</hasSize>
</owl:NamedIndividual>
</rdf:RDF>

How would you query such a triple using Prolog? I thought it would be something like:

is_part_of(Ind1, Ind2):- 
    rdf(Ind1, 
        "http://www.w3.org/1999/02/22-rdf-syntax-ns#isPartOf, 
        Ind2).

which apparently doesn't work.

I also saw rdf_has(S,P,O,RealP) from rdf library that looks kindof usable, but the specification is vague.

Following this question, what if the two individuals are classes? What if the object property is a datatype property instead?

I think I'm stuck on an easy problem, but I've searched a long time for an example or similar question but didn't find anything.

Thanks in advance!

Stanislav Kralin
  • 11,070
  • 4
  • 35
  • 58
vw511
  • 171
  • 10

2 Answers2

3

Probably the problem is the absence of a quick start example in the semweb/rdf_db documentation. Here is an example session.


?- use_module(library(semweb/rdf_db)).
true.

?- rdf_load('example.owl', [format(xml)]).
% Parsed "example.owl" in 0.01 sec; 11 triples
true.

?- rdf(Ind1, 'http://www.xxx.come/example#isPartOf',  Ind2).
Ind1 = 'http://www.xxx.come/example#Room_1',
Ind2 = 'http://http://www.xxx.come/example#Apartment_1'.

?- rdf(Ind1, 'http://www.xxx.come/example#hasSize',  Ind2).
Ind1 = 'http://www.xxx.come/example#Room_1',
Ind2 = literal(type('http://www.w3.org/2001/XMLSchema#double', '99.6')) .

?- % is_part_of(Ind1, Ind2):- rdf(Ind1, 'http://www.xxx.come/example#isPartOf', Ind2).
|    ['rules.pl'].
true.

?- is_part_of(Ind1, Ind2).
Ind1 = 'http://www.xxx.come/example#Room_1',
Ind2 = 'http://http://www.xxx.come/example#Apartment_1'.

?- rdf_register_prefix(ex, 'http://www.xxx.come/example#').
true.

?- rdf(Ind1, ex:isPartOf,  Ind2).
Ind1 = 'http://www.xxx.come/example#Room_1',
Ind2 = 'http://http://www.xxx.come/example#Apartment_1'.

Errors in your code:

  1. Atoms in Prolog should be enclosed within single quotes.
    As for double quotes — see e.g this question. My SWI-Prolog says:

    Type error: `atom' expected, found `"http://www.xxx.come/example#isPartOf"' (a string)

    Anyway, double quotes should be closed, too.

  2. You should use correct full URIs: http://www.xxx.come/example#isPartOf instead of http://www.w3.org/1999/02/22-rdf-syntax-ns#isPartOf.

  3. This malformed URI — http://http://www.xxx.come/example#Apartment_1 — may cause additional problems.

Stanislav Kralin
  • 11,070
  • 4
  • 35
  • 58
  • Thank you so so much! Now it works! I think I missed something small and didn't put all details together. Sorry for the quotation problem and the modified malformed URI... – vw511 Aug 16 '17 at 16:20
1

If you have an RDFS or OWL schema already defined you can use rdfs2pl to convert it into prolog rules.

The results are largely the same as the example provided by Stanislav. It's useful to look at the explicit code provided to learn what is going on, but if you have a large number of predicates it can be tedious and error prone to write explicit rules for them all.

One difference between the generated code and the example providedis that rdfs2pl uses rdf_has/3 in its generated rules. You asked about this predicate. It provides limited inference over the RDF graph. For example, if you had:

ex:isPartOf owl:inverseOf ex:hasPart .
ex:apartment1 ex:hasPart ex:room1.

Then a query rdf_has(X,myont:isPartOf,Y) will return a result with X=ex:room1 and Y=ex:apartment1, even though it is not explicitly stated, it is entailed by the semantics of OWL and by your inverseOf declaration. In contrast rdf/3 will only query the asserted model.

When you should rdf/3 vs rdf_has/3 depends on your use case. It can be very useful to be able to use inference when making queries.

Chris Mungall
  • 629
  • 5
  • 13