Wilbur Query Language Comparison

Ora Lassila
Nokia Research Center
$Id: 11-comparison.shtml,v 1.2 2004/05/13 03:20:50 ora Exp $

Introduction

This document is the first draft of an attempt to compare the Wilbur Query Language (WQL, the query language of the Nokia Research Center's "Wilbur" Semantic Web toolkit) to other RDF query languages. The comparison is based on the recently published comparison of some RDF query languages.

Summary of Comparison Results

Two query languages are discussed:

Combining the "plain" query language with Common Lisp makes sense, since WQL was originally designed to be integrated with the programming language, and to be used for providing more expressive data access for programmers. Since Common Lisp can be dynamically interpreted at run time (via the standard function EVAL), it is not unreasonable to think of using CL as parts of queries. Think of it as a scripting language...

Test "Plain" WQL WQL+CL
Path Expression Yes Yes
Optional Path No Yes
Union No Yes
Difference No Yes
Quantification No Yes
Aggregation No Yes
Recursion Yes Yes
Reification Restricted Yes "Plain" WQL case restricted just like RDQL etc.
Collections and Containers Yes Yes
Namespace No Yes
Language No Restricted Will work after a bug in xml:lang support is fixed
Lexical Space No Yes
Value Space No Restricted Will work w/ inference once datatype support is completed
Entailment Yes Yes

Query Details

Note that many "Plain" WQL and WQL+CL queries contain a path expression (:inv (:seq !rdf:type (:rep* !rdfs:subClassOf))). This is because Wilbur, out-of-the-box, does not support inference/entailment, and the particular query expression allows one to reach all instances of all subclasses of a class. Because of this, we have added query expressions for something called WQL+CL+inference; this language is basically the same as WQL+CL except that the queries are run against a tuple store that supports the "hidden inference" as described in our paper in ISWC 2002.

Also note that the correct treatment of sub-properties is not included in queries for "Plain" WQL or WQL+CL (although it would be possible, using a similar technique as described above). WQL+CL+inference supports sub-properties without any additional attention from the programmer.

In the following query examples, "plain" queries and "buggy" features (that is, features not functioning properly in the current release) are highlighted in color. It is also assumed that the following Common Lisp forms are evaluated prior to issuing any of the test queries:

(setf *db* (make-instance 'db))

(load-db (make-url "http://www.aifb.uni-karlsruhe.de/WBS/pha/rdf-query/queries/sample.rdf")
         :locator "http://www.aifb.uni-karlsruhe.de/WBS/pha/rdf-query/sample.rdf")

(add-namespace "q" "http://www.aifb.uni-karlsruhe.de/WBS/pha/rdf-query/sample.rdf")

Wilbur "harvests" (during the execution of LOAD-DB) all the other namespace prefixes used.

1. Path Expression

"Plain" WQL:
(all-values !q:Paper '(:seq !q:author :members))
WQL+CL: same as "Plain" WQL
WQL+CL+inference: same as "Plain" WQL

2. Optional Path

"Plain" WQL: n/a
WQL+CL:
(mapcar #'(lambda (author)
            (cons author (value author !q:email)))
        (all-values !q:Paper '(:seq !q:author :members)))
WQL+CL+inference: same as WQL+CL

3. Union

"Plain" WQL: n/a
WQL+CL:
(union (all-values !acm:Topic
                   '(:seq (:inv (:seq !rdf:type (:rep* !rdfs:subClassOf))) !rdfs:label))
       (all-values !q:Publication
                   '(:seq (:inv (:seq !rdf:type (:rep* !rdfs:subClassOf))) !q:title))
       :test #'literal=)
WQL+CL+inference:
(union (all-values !acm:Topic '(:seq (:inv !rdf:type) !rdfs:label))
       (all-values !q:Publication '(:seq (:inv !rdf:type) !q:title))
       :test #'literal=)

4. Difference

"Plain" WQL: n/a
WQL+CL:
(difference (all-values !acm:Topic
                        '(:seq (:inv (:seq !rdf:type (:rep* !rdfs:subClassOf))) !rdfs:label))
            (all-values !q:Publication
                        '(:seq (:inv (:seq !rdf:type (:rep* !rdfs:subClassOf))) !q:title))
            :test #'literal=)
WQL+CL+inference:
(difference (all-values !acm:Topic '(:seq (:inv !rdf:type) !rdfs:label))
            (all-values !q:Publication '(:seq (:inv !rdf:type) !q:title))
            :test #'literal=)

5. Quantification

"Plain" WQL: n/a
WQL+CL:
(let ((pubs (all-values !q:Publication '(:inv (:seq !rdf:type (:rep* !rdfs:subClassOf))))))
  (remove-if-not #'(lambda (person)
                     (every #'(lambda (pub)
                                (relatedp pub '(:seq !q:author :members) person))
                            pubs))
                 (all-values !q:Publication
                             '(:seq (:inv (:seq !rdf:type (:rep* !rdfs:subClassOf)))
                                    !q:author :members))))
WQL+CL+inference:
(let ((pubs (all-values !q:Publication '(:inv !rdf:type))))
  (remove-if-not #'(lambda (person)
                     (every #'(lambda (pub)
                                (relatedp pub '(:seq !q:author :members) person))
                            pubs))
                 (all-values !q:Publication '(:seq (:inv !rdf:type) !q:author :members))))

6. Aggregation

"Plain" WQL: n/a
WQL+CL:
(length (all-values !q:Paper '(:seq !q:author :members)))
WQL+CL+inference: same as WQL+CL

7. Recursion

"Plain" WQL:
(all-values
  !"http://www.aifb.uni-karlsruhe.de/WBS/pha/rdf-query/sample.rdf#ACMTopic/Information_Systems"
  '(:rep* !acm:SubTopic))
WQL+CL: same as "Plain" WQL
WQL+CL+inference: same as "Plain" WQL

8. Reification

"Plain" WQL:
(all-values !q:Paper '(:seq (:inv !rdf:subject) !dc:creator))
WQL+CL:
(mapcan #'(lambda (statement)
            (when (eq (value statement !rdf:predicate) !q:isAbout)
              (list (value statement !dc:creator))))
        (all-values !q:Paper '(:inv !rdf:subject)))
WQL+CL+inference: same as WQL+CL

9. Collections and Containers

"Plain" WQL:
(value !q:Paper '(:seq !q:author :members))
WQL+CL: same as "Plain" WQL
WQL+CL+inference: same as "Plain" WQL

10. Namespace

"Plain" WQL: n/a
WQL+CL:
(dictionary-apropos-list *nodes* "http://aifb.uni-karlsruhe.de/")
WQL+CL+inference: same as "Plain" WQL

The Wilbur API includes the function dictionary-apropos-list which can be used for satisfying this test. The current implementation is not particularly efficient.

11. Language

"Plain" WQL: n/a
WQL+CL:
(dolist (topic (all-values !acm:Topic (:inv (:seq !rdf:type (:rep* !rdfs:subClassOf)))))
  (let ((labels (all-values topic !rdfs:label)))
    (when (find-if #'(lambda (label)
                       (and (string= (literal-language label) "en")
                            (string= (literal-string label) "Database Management")))
                   labels)
      (return (find "de" labels :test #'string= :key #'literal-language)))))
WQL+CL+inference:
(dolist (topic (all-values !acm:Topic (:inv !rdf:type)))
  (let ((labels (all-values topic !rdfs:label)))
    (when (find-if #'(lambda (label)
                       (and (string= (literal-language label) "en")
                            (string= (literal-string label) "Database Management")))
                   labels)
      (return (find "de" labels :test #'string= :key #'literal-language)))))

These examples are cumbersome, as they require linear searches and string comparisons, but they illustrate that even this test can be satisfied.

12. Lexical Space

"Plain" WQL: n/a
WQL+CL:
(remove-if-not #'(lambda (resource)
                   (string= (literal-string (value resource !q:pages)) "08"))
               (all-values !q:Publication
                           '(:inv (:seq !rdf:type (:rep* !rdfs:subClassOf)))))
WQL+CL+inference:
(remove-if-not #'(lambda (resource)
                   (string= (literal-string (value resource !q:pages)) "08"))
               (all-values !q:Publication '(:inv !rdf:type)))

13. Value Space

"Plain" WQL: n/a
WQL+CL: n/a
WQL+CL+inference:
(remove-if-not #'(lambda (resource)
                   (= (literal-value (value resource !q:pages)) 8))
               (all-values !q:Publication '(:inv !rdf:type)))

14. Entailment

"Plain" WQL:
(all-values !q:Publication '(:inv (:seq !rdf:type (:rep* !rdfs:subClassOf))))
WQL+CL: same as "Plain" WQL
WQL+CL+inference:
(all-values !q:Publication '(:inv !rdf:type))

Bibliography

Wilbur: Copyright Nokia 2004-05-13