RDF Applications with Prolog
by Bijan Parsia
|
Pages: 1, 2, 3, 4, 5, 6
At this point, I can parse an RDF/XML document into a list of
Prolog terms using the (now consulted) predicate
load_rdf/2. I'm going to use as my example an RSS 1.0
file from XMLhack.com.
?- load_rdf('bijan/xmlhack.rss', List_of_RDF_statements).
List_of_RDF_statements = [rdf('http://xmlhack.com/rss10.php', rdf:type, 'http://purl.org/rss/1.0/channel'), rdf('http://xmlhack.com/rss10.php', 'http://purl.org/rss/1.0/':title, literal('XMLhack')), rdf('http://xmlhack.com/rss10.php', 'http://purl.org/rss/1.0/':link, literal('http://xmlhack.com/')), rdf('Description__1', 'http://purl.org/dc/elements/1.1/':resource, literal('http://xmlhack.com/')), rdf('http://xmlhack.com/rss10.php', 'http://purl.org/dc/elements/1.1/':source, 'Description__1'), rdf('http://xmlhack.com/rss10.php', 'http://purl.org/rss/1.0/':description, literal('Developer news from the XML community')), rdf('http://xmlhack.com/rss10.php', 'http://purl.org/dc/elements/1.1/':language, literal('en-us')), rdf('http://xmlhack.com/rss10.php', ... :..., literal(...)), rdf(..., ..., ...)|...]
Yes
I've not yet "consulted" the RDF file, I've merely parsed it into a list of terms. What's the difference? For one, none of these statements can be queried, e.g.,:
?- rdf(X,Y,Z).
ERROR: Undefined procedure: rdf/3
Thus far, I haven't ever (in this session) asserted
any clause of an rdf/3 predicate, so the system
has no special understanding of terms like
rdf('http://xmlhack.com/rss10.php', rdf:type,
'http://purl.org/rss/1.0/channel). But, in the symbolic
processing language tradition, that term is a well-formed
data structure (indeed, it's a "term"), and it can be manipulated in
various ways -- including being asserted as a clause of a
predicate. In other words, Prolog has a uniform representation of code
and data and facilities for manipulating a term from either
perspective. Since rdf_load/3 returned a list of terms
that are perfectly legal Prolog clauses, it's no problem to assert
them into the current knowledge base, simply using the
assert/1 predicate.
?- load_rdf('bijan/xmlhack.rss', [H|_]), assert(H).Both the file at that relative path must be parseable into a list of terms with at least one item. The first item is bound to Hwhile the tail of the list is bound to the "anonymous", "throw away", or "don't care" variable_and (remember a comma between predicates in a query is read as "and") that first term must be entered in our knowledge base.H = rdf('http://xmlhack.com/rss10.php', rdf:type, 'http://purl.org/rss/1.0/channel')
YesThe query succeeded with the first parsed item from the document is bound to H.?- rdf(X,Y,Z).Are there any X,Y, andZthat exist in anrdfrelation?X = 'http://xmlhack.com/rss10.php'
Y = rdf:type
Z = 'http://purl.org/rss/1.0/channel' ;
NoYes, there's one with the listed bindings, but if I ask for more (e.g., by entering the semicolon) Prolog doesn't find any.
Two points. First, using rdf_load/3, I can transform a
certain serialization of a set of RDF statements into a form that
Prolog can handle well (i.e. a list of rdf/3 based
terms). Second, given the appropriate output predicates, I can use
that form to compose RDF as well. After all, I can assert any
rdf/3 statement that I'd like at the query prompt,
e.g.,
?- assert(rdf(a, b, c)).
Yes
And I can test to see if it's in fact in the knowledge base:
?- rdf(a, b c).
Yes
Since that's not a particularly useful RDF statement, I'll just retract it:
?- retract(rdf(a, b, c)).
Yes
?- rdf(a, b c).
no
I really don't want to assert these statements tediously one at a
time at the query prompt. But I can get a list of the
rdf/3 terms, which suggests that I could use some sort of
"mapping" predicate to assert all the items in the statement
list. checklist/2 takes a predicate and applies it to
each member of a supplied list:
?
- load_rdf('bijan/xmlhack.rss', List_of_RDF_statements),
| checklist(assert, List_of_RDF_statements).
(Note, the | is the "continuation" prompt in
SWI-Prolog and not a bit of syntax.)
After this query, I have quite a few RDF statements in my Prolog knowledge base:
?- rdf(X,Y,Z).
X = 'http://xmlhack.com/rss10.php'
Y = rdf:type
Z = 'http://purl.org/rss/1.0/channel' ;
X = 'http://xmlhack.com/rss10.php'
Y = rdf:type
Z = 'http://purl.org/rss/1.0/channel' ;
X = 'http://xmlhack.com/rss10.php'
Y = rdf:type
Z = 'http://purl.org/rss/1.0/channel' ;
X = 'http://xmlhack.com/rss10.php'
Y = 'http://purl.org/rss/1.0/':title
Z = literal('XMLhack') ;
...etc.
This is equivalent to consulting a file containing all the
rdf/3 items, written just as they appear in the
list. Thus, one could use the rdf/3 notation to compose
RDF documents (although this notation isn't all that much
more convenient than the dreaded RDF/XML).