March 2006


I’ve lately been thinking about whether the named graph support in SPARQL can help us evolve vocabularies and associated code (eg. generators and translators) in parallel, so that we know when the RDF generators are emitting markup that uses properties which aren’t yet documented in the ontology; or when the ontology contains terms that aren’t being used in any actual data.

Here is a quick example in terms of FOAF, in a form that should run directly with Jena’s ARQ commandline tool. The query shown here takes a handful of specified FOAF files and compares their property usage with information about those properties in the RDF/OWL description of the FOAF spec. Query copied below, followed by the results. This is a pretty simple query; there are lots of related ideas we might explore. What I’d like to figure out (help welcomed!) is quite how to check for properties in instance data that don’t have corresponding definitions in the ontology. I expect it has something to do with ‘unbound’, …

Anyway, some basic FOAF-related querying for now:


PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX vs: <http://www.w3.org/2003/06/sw-vocab-status/ns#>

# Experiment with using SPARQL to compare actual property usage
# with the property declarations in FOAF. This query asks which
# properties are in use, and gets their label from the FOAF spec.
# Q: how to do the contrary, and specify which deployed properties
# are not in the spec?

PREFIX danbri: <http://danbri.org/foaf.rdf>
PREFIX libby: <http://swordfish.rdfweb.org/people/libby/rdfweb/webwho.xrdf>
PREFIX kanzaki: <http://www.kanzaki.com/info/webwho.rdf>
PREFIX edd: <http://heddley.com/edd/foaf.rdf>
PREFIX inkel: <http://purl.org/net/inkel/inkel.foaf.rdf>
PREFIX mattb: <http://www.picdiary.com/foaf.rdf>

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT DISTINCT ?prop ?label ?graph ?status

FROM NAMED foaf:
FROM NAMED danbri:
FROM NAMED libby:
FROM NAMED kanzaki:
FROM NAMED edd:
FROM NAMED inkel:
FROM NAMED mattb:

WHERE {
GRAPH foaf: {
{ ?prop rdf:type ?t }
FILTER (?t = owl:ObjectProperty || ?t = owl:DatatypeProperty ||
?t = rdf:Property || ?t = owl:FunctionalProperty ||
?t = owl:InverseFunctionalProperty ) .
?prop rdfs:label ?label . ?prop rdfs:comment ?c .
?prop vs:term_status ?status .
}
OPTIONAL { GRAPH ?graph { ?x ?prop ?y . } }
FILTER ( ?graph != foaf: )
}
ORDER BY ?prop

This gives the following results using ARQ (sparql --query on the commandline):

---------------------------------------------------------------------------------------------
| prop                   | label                                    | graph    | status     |
=============================================================================================
| foaf:aimChatID         | "AIM chat ID"                            | danbri:  | "testing"  |
| foaf:aimChatID         | "AIM chat ID"                            | edd:     | "testing"  |
| foaf:based_near        | "based near"                             | inkel:   | "unstable" |
| foaf:based_near        | "based near"                             | mattb:   | "unstable" |
| foaf:based_near        | "based near"                             | kanzaki: | "unstable" |
| foaf:currentProject    | "current project"                        | inkel:   | "testing"  |
| foaf:currentProject    | "current project"                        | libby:   | "testing"  |
| foaf:currentProject    | "current project"                        | kanzaki: | "testing"  |
| foaf:depiction         | "depiction"                              | inkel:   | "testing"  |
| foaf:depiction         | "depiction"                              | libby:   | "testing"  |
| foaf:depiction         | "depiction"                              | danbri:  | "testing"  |
| foaf:depiction         | "depiction"                              | mattb:   | "testing"  |
| foaf:depiction         | "depiction"                              | kanzaki: | "testing"  |
| foaf:depiction         | "depiction"                              | edd:     | "testing"  |
| foaf:depicts           | "depicts"                                | edd:     | "testing"  |
| foaf:family_name       | "family_name"                            | inkel:   | "testing"  |
| foaf:firstName         | "firstName"                              | inkel:   | "testing"  |
| foaf:gender            | "gender"                                 | kanzaki: | "testing"  |
| foaf:givenname         | "Given name"                             | inkel:   | "testing"  |
| foaf:holdsAccount      | "holds account"                          | kanzaki: | "unstable" |
| foaf:homepage          | "homepage"                               | inkel:   | "stable"   |
| foaf:homepage          | "homepage"                               | danbri:  | "stable"   |
| foaf:homepage          | "homepage"                               | mattb:   | "stable"   |
| foaf:homepage          | "homepage"                               | kanzaki: | "stable"   |
| foaf:homepage          | "homepage"                               | edd:     | "stable"   |
| foaf:icqChatID         | "ICQ chat ID"                            | inkel:   | "testing"  |
| foaf:img               | "image"                                  | danbri:  | "testing"  |
| foaf:img               | "image"                                  | mattb:   | "testing"  |
| foaf:img               | "image"                                  | kanzaki: | "testing"  |
| foaf:img               | "image"                                  | edd:     | "testing"  |
| foaf:interest          | "interest"                               | inkel:   | "testing"  |
| foaf:interest          | "interest"                               | libby:   | "testing"  |
| foaf:interest          | "interest"                               | kanzaki: | "testing"  |
| foaf:isPrimaryTopicOf  | "is primary topic of"                    | danbri:  | "testing"  |
| foaf:jabberID          | "jabber ID"                              | inkel:   | "testing"  |
| foaf:jabberID          | "jabber ID"                              | danbri:  | "testing"  |
| foaf:knows             | "knows"                                  | inkel:   | "testing"  |
| foaf:knows             | "knows"                                  | libby:   | "testing"  |
| foaf:knows             | "knows"                                  | danbri:  | "testing"  |
| foaf:knows             | "knows"                                  | mattb:   | "testing"  |
| foaf:knows             | "knows"                                  | kanzaki: | "testing"  |
| foaf:knows             | "knows"                                  | edd:     | "testing"  |
| foaf:made              | "made"                                   | danbri:  | "testing"  |
| foaf:made              | "made"                                   | kanzaki: | "testing"  |
| foaf:maker             | "maker"                                  | inkel:   | "testing"  |
| foaf:maker             | "maker"                                  | libby:   | "testing"  |
| foaf:maker             | "maker"                                  | kanzaki: | "testing"  |
| foaf:maker             | "maker"                                  | edd:     | "testing"  |
| foaf:mbox              | "personal mailbox"                       | inkel:   | "stable"   |
| foaf:mbox              | "personal mailbox"                       | libby:   | "stable"   |
| foaf:mbox              | "personal mailbox"                       | danbri:  | "stable"   |
| foaf:mbox              | "personal mailbox"                       | kanzaki: | "stable"   |
| foaf:mbox              | "personal mailbox"                       | edd:     | "stable"   |
| foaf:mbox_sha1sum      | "sha1sum of a personal mailbox URI name" | inkel:   | "testing"  |
| foaf:mbox_sha1sum      | "sha1sum of a personal mailbox URI name" | libby:   | "testing"  |
| foaf:mbox_sha1sum      | "sha1sum of a personal mailbox URI name" | danbri:  | "testing"  |
| foaf:mbox_sha1sum      | "sha1sum of a personal mailbox URI name" | mattb:   | "testing"  |
| foaf:mbox_sha1sum      | "sha1sum of a personal mailbox URI name" | kanzaki: | "testing"  |
| foaf:mbox_sha1sum      | "sha1sum of a personal mailbox URI name" | edd:     | "testing"  |
| foaf:msnChatID         | "MSN chat ID"                            | inkel:   | "testing"  |
| foaf:msnChatID         | "MSN chat ID"                            | danbri:  | "testing"  |
| foaf:myersBriggs       | "myersBriggs"                            | danbri:  | "testing"  |
| foaf:myersBriggs       | "myersBriggs"                            | mattb:   | "testing"  |
| foaf:myersBriggs       | "myersBriggs"                            | kanzaki: | "testing"  |
| foaf:myersBriggs       | "myersBriggs"                            | edd:     | "testing"  |
| foaf:name              | "name"                                   | inkel:   | "testing"  |
| foaf:name              | "name"                                   | libby:   | "testing"  |
| foaf:name              | "name"                                   | danbri:  | "testing"  |
| foaf:name              | "name"                                   | mattb:   | "testing"  |
| foaf:name              | "name"                                   | kanzaki: | "testing"  |
| foaf:name              | "name"                                   | edd:     | "testing"  |
| foaf:nick              | "nickname"                               | inkel:   | "testing"  |
| foaf:nick              | "nickname"                               | libby:   | "testing"  |
| foaf:nick              | "nickname"                               | danbri:  | "testing"  |
| foaf:nick              | "nickname"                               | mattb:   | "testing"  |
| foaf:nick              | "nickname"                               | kanzaki: | "testing"  |
| foaf:nick              | "nickname"                               | edd:     | "testing"  |
| foaf:pastProject       | "past project"                           | inkel:   | "testing"  |
| foaf:pastProject       | "past project"                           | kanzaki: | "testing"  |
| foaf:plan              | "plan"                                   | danbri:  | "testing"  |
| foaf:plan              | "plan"                                   | kanzaki: | "testing"  |
| foaf:primaryTopic      | "primary topic"                          | inkel:   | "testing"  |
| foaf:primaryTopic      | "primary topic"                          | kanzaki: | "testing"  |
| foaf:primaryTopic      | "primary topic"                          | edd:     | "testing"  |
| foaf:publications      | "publications"                           | kanzaki: | "unstable" |
| foaf:schoolHomepage    | "schoolHomepage"                         | danbri:  | "testing"  |
| foaf:schoolHomepage    | "schoolHomepage"                         | kanzaki: | "testing"  |
| foaf:schoolHomepage    | "schoolHomepage"                         | edd:     | "testing"  |
| foaf:surname           | "Surname"                                | inkel:   | "testing"  |
| foaf:thumbnail         | "thumbnail"                              | danbri:  | "testing"  |
| foaf:title             | "title"                                  | kanzaki: | "testing"  |
| foaf:weblog            | "weblog"                                 | inkel:   | "testing"  |
| foaf:weblog            | "weblog"                                 | libby:   | "testing"  |
| foaf:weblog            | "weblog"                                 | mattb:   | "testing"  |
| foaf:weblog            | "weblog"                                 | kanzaki: | "testing"  |
| foaf:weblog            | "weblog"                                 | edd:     | "testing"  |
| foaf:workplaceHomepage | "workplace homepage"                     | inkel:   | "testing"  |
| foaf:workplaceHomepage | "workplace homepage"                     | libby:   | "testing"  |
| foaf:workplaceHomepage | "workplace homepage"                     | danbri:  | "testing"  |
| foaf:workplaceHomepage | "workplace homepage"                     | mattb:   | "testing"  |
| foaf:workplaceHomepage | "workplace homepage"                     | edd:     | "testing"  |
| foaf:yahooChatID       | "Yahoo chat ID"                          | inkel:   | "testing"  |
---------------------------------------------------------------------------------------------

IM-chatting with a friend in Iran about Eugène Ionesco I stumbled randomly on this quote that charmed me:

I got the idea of making analogies between cities from Hofstadter, who quoted Ionesco’s remark

The French for London is Paris.

One of the growing frustrations of life online is that there isn’t yet truly one Web for everyone. Alongside other issues (e.g. accessibility, device independence, proprietary content formats, cost of PCs and ‘net access, …), there’s a growing problem with crude and indiscriminate national-level filtering. A lot of users get a “Lite” version of the Web, thanks to their governments and supporting parties (ISPs, western software filtering companies, etc.).

In this case, I didn’t get to share the thought with my friend quite so easily, as the page was blocked by the Iranian ISP:

This page will not be accessible for the reason that in our database it has been assigned to the category of blocked contents.

In the event the URL does not contain materials that are forbidden by laws, please fill this form out then hit send.

From the Wikipedia entry on Ionesco:

He disregards psychology and coherent dialogue, thereby depicting a dehumanized world with mechanical, puppet-like characters who speak in non-sequiturs. Language becomes rarefied, with words and material objects gaining a life of their own, increasingly overwhelming the characters and creating a sense of menace.

I’m more familiar with Hofstadter than Ionesco, but there’s a menacing circularity to the message from the firewall:

user: I’d like to read the page please.

firewall: Sorry, the page is blocked. You can’t see it. If after considering its contents carefully, you’ll vouch for them as being compliant with all relevant laws, please enter your personal details in the register below.

Those of us working on decentralised resource description should keep these little stories in mind. Resource description is a double-edged sword; we can use it to find and locate relevant content, and to personalise, filter and prioritise incoming information. But the same technology can rather easily be used in ways that damage the Web as an international and universal communications platform; somewhere than anyone can talk to anyone about anything. So I know there are no easy answers, and that it feels somewhat naive to keep griping on about filtering in these posts. But I don’t want to get used to national filters being a long-term reality of the Web, and I’ll keep griping…

All I can say for my part, is that for every hour I spend on content labelling technology I’ll try to spend spend a balancing hour on universal access issues. I’m more of an incrementalist on these things than William Loughborough, but the geezer’s got a point when he says:

…until we are all connected, none of us is connected.

Nearby in the Web: “BBC Persian filtered out of Iran, what can we do?” from Ian Forrester, who talks about the use of full-text syndication as a workaround for national Web filters. Instant Messenger-based RSS clients might be an interesting ingredient, to the extent that the IM protocols themselves are unfiltered. Mario Menti has a prototype MSN bot that relays BBC news via chat messages…