The behaviour of @instanceof with chaining

Hello all,

I've dealt separately with what exactly chaining means [1], so in  
this post I'd like to focus only on what happens when using  
@instanceof with chaining. First I'll show how I would mark-up the  
examples given to work with, and then I'd like to go on and explain  
the key principles that lie behind the approach.


BEN'S SIMPLE EXAMPLE

Let's first mark-up Ben's example of:

   I know a person named 'Ralph'

Let's begin with 'a person named 'Ralph'":

========
<div
  instanceof="foaf:Person"
  property="foaf:name" content="Ralph"
/>
========

We also know that to say "I know someone" uses the following pattern:

========
<div about="#me" rel="foaf:knows">
   ...
</div>
========

So all we have to do is to drop Ralph's mark-up into the "I know..."  
statement:

========
<div about="#me" rel="foaf:knows">
   <div
    instanceof="foaf:Person"
    property="foaf:name" content="Ralph"
   />
</div>
========


BEN'S COMPLEX EXAMPLE

Ben's other example was:

   I know a person named 'Ralph' who knows a person named 'Ivan' who  
knows a person named 'Ben'.

I'm going to deal with this in a number of stages, so as to  
illustrate how to approach this. We'll continue on from our previous  
example, and add mark-up for Ivan and Ben:

========
<div
  about="#ivan"
  instanceof="foaf:Person"
  property="foaf:name" content="Ivan"
/>

<div
  about="#ben"
  instanceof="foaf:Person"
  property="foaf:name" content="Ben"
/>
========

Then we modify Ralph so that he knows Ivan, and Ivan so that he knows  
Ben. We now have this (the changes are at lines 5 and 13) :

========
<div about="#me" rel="foaf:knows">
   <div
    instanceof="foaf:Person"
    property="foaf:name" content="Ralph"
    rel="foaf:knows" resource="#ivan"
   />
</div>

<div
  about="#ivan"
  instanceof="foaf:Person"
  property="foaf:name" content="Ivan"
  rel="foaf:knows" resource="#ben"
/>

<div
  about="#ben"
  instanceof="foaf:Person"
  property="foaf:name" content="Ben"
/>
========

Note that this isn't obviously what Ben had in mind, but I'm spelling  
this out before optimising it, because I want to keep drawing  
attention to the consistency of the rules.


MEANING IS POSITION-INDEPENDENT

Now, let's place Ben's mark-up inside Ivan's:

========
<div
  about="#ivan"
  instanceof="foaf:Person"
  property="foaf:name" content="Ivan"
  rel="foaf:knows" resource="#ben"
 >
   <div
    about="#ben"
    instanceof="foaf:Person"
    property="foaf:name" content="Ben"
   />
</div>
========

Note that this is purely about layout, since the mark-up has not  
changed; we still have:

   <#ivan> is a person named 'Ivan', who knows a person named 'Ben'

A key point is therefore that moving mark-up around does not  
_necessarily_ change its meaning.


REPLACING @ABOUT/@RESOURCE PAIRS WITH BNODES

Now...note the redundant "#ben" references; we should be able to  
optimise those out, and make use of the hierarchy to express the  
relationship. To do this we drop @resource from Ivan's element,  
@about from Ben's element, and then declare that the subject and  
object 'align'. That would give us this:

========
<div
  about="#ivan"
  instanceof="foaf:Person"
  property="foaf:name" content="Ivan"
  rel="foaf:knows"
 >
   <div
    instanceof="foaf:Person"
    property="foaf:name" content="Ben"
   />
</div>
========

Note that the rule that says we can drop @resource and @about like  
this is already in the RDFa syntax document, although it's not  
expressed in that way. But the key point here is to understand that  
the @instanceof in the second statement is still applying to the  
'subject' of the element, even though that 'subject' has not been  
expressed explicitly.


REPEATING THE PROCESS

We're now going to repeat the process we just saw, of moving one  
element inside another, and removing @about and @resource in favour  
of a bnode.

First, a recap of what we have at the moment:

========
<div about="#me" rel="foaf:knows">
   <div
    instanceof="foaf:Person"
    property="foaf:name" content="Ralph"
    rel="foaf:knows" resource="#ivan"
   />
</div>

<div
  about="#ivan"
  instanceof="foaf:Person"
  property="foaf:name" content="Ivan"
  rel="foaf:knows"
 >
   <div
    instanceof="foaf:Person"
    property="foaf:name" content="Ben"
   />
</div>
========

Now, as before we're going to move one structure inside another; this  
time it's Ivan's structure into Ralph's, and as before, the meaning  
is unaltered:

========
<div about="#me" rel="foaf:knows">
   <div
    instanceof="foaf:Person"
    property="foaf:name" content="Ralph"
    rel="foaf:knows" resource="#ivan"
   />
   <div
    about="#ivan"
    instanceof="foaf:Person"
    property="foaf:name" content="Ivan"
    rel="foaf:knows"
   >
     <div
      instanceof="foaf:Person"
      property="foaf:name" content="Ben"
     />
   </div>
</div>
========

The final step is to remove the redundant duplicate "#ivan"  
references, leaving us with this:

========
<div about="#me" rel="foaf:knows">
   <div
    instanceof="foaf:Person"
    property="foaf:name" content="Ralph"
    rel="foaf:knows"
   />
   <div
    instanceof="foaf:Person"
    property="foaf:name" content="Ivan"
    rel="foaf:knows"
   >
     <div
      instanceof="foaf:Person"
      property="foaf:name" content="Ben"
     />
   </div>
</div>
========

Since we have followed exactly the same steps as we did previously,  
there is no reason to expect that the meaning of our mark-up should  
have changed in any way. And provided that we treat @instanceof like  
a normal predicate (more on this below), then the meaning will _not_  
have changed, and we can go on with this kind of nesting forever,  
with no problems.

However, if @instanceof behaves in the way proposed by Ben, then this  
whole structure falls apart--Ivan is no longer a person, because his  
@instanceof attribute now applies to Ben (due to the presence of  
@rel, and the absence of @about). Ben already has his own  
@instanceof, so he doesn't need this extra property. To get back to  
the meaning that we intended, we have to start introducing extra  
mediating elements, in the way that I explained in detail in another  
thread [2]. This is quite a change from the simple cut-and-paste  
consistency that I have been trying to illustrate.


CONCLUSION

We need to ensure in the RDFa syntax document that 'alignment' in  
chaining ensures that all parsing that requires a bnode makes use of  
the same anonymous identifier. If we do, then structures like 'I know  
a person named 'Ralph'" are easily marked up in RDFa, and perhaps  
more importantly, will behave consistently as they are moved around.

If we do this then @instanceof can be treated just like any other  
predicate (see Additional Notes, below), and there is no need for  
rules that make it flip from using the subject or object from an  
element depending on other attributes.


ADDITIONAL NOTES

So as to try to reduce the size of the explanation, I've moved some  
of the supporting arguments out of the main explanation. Here they are:


USING PREDICATES

One of the main aspects to what we just saw is that @instanceof  
should be treated just like any other predicate-setting attribute.  
I'll now motivate why that should be the case. Let's start with a  
simple case where an item has a predicate which is another item. The  
two patterns that give rise to this situation are:

========
<div about="A" rel="p1">
   <div about="B" rel="p2" resource="C" />
</div>
========

and:

========
<div about="A" rel="p1" resource="B">
   <div rel="p2" resource="C" />
</div>
========

In other words, the object on the first statement in the first  
example is 'B', and the subject in the second statement in the second  
example is also 'B'. So far then, we have only one interpretation,  
even though it is marked up in two different ways, and that is:

   A predicate1 B predicate2 C


ADDING PREDICATES

Now, it would seem reasonable that if we were to add predicates to  
the two elements in our mark-up, those predicates should augment the  
existing statements, which should continue to refer to items A and B.  
Taking our two slightly different ways of marking up the same thing,  
let's add predicates 3 and 4:

========
<div about="A" rel="p1" property="p3" content="v1">
   <div about="B" rel="p2" resource="C" property="p4" content="v2" />
</div>
========

and:

========
<div about="A" rel="p1" resource="B" property="p3" content="v1">
   <div rel="p2" resource="C" property="p4" content="v2" />
</div>
========

Regardless of the mark-up used (whether 'B' is expressed as the 'end'  
of one statement or the 'beginning' of another in our chain), we  
still have two 'items' standing in a relationship to each other of  
'p1'. Before we added the predicates we had this:

A:
   p1: B

B:
   p2: C

And now we have this:

A:
   p1: B
   p3: "v1"

B:
   p2: C
   p4: "v2"

In other words, adding an additional property hasn't altered the  
relationship between the two items.


ADDING TYPE INFORMATION

Adding rdf:type information is just the same as adding any other  
predicate. We could add it like this, with @rel="rdf:type":

========
<div
  about="http://www.w3.org/People/Ivan/#me"
  rel="rdf:type" resource="foaf:Person"
  property="foaf:name" content="Ivan"
/>
========

or we could add it like this, using @instanceof:

========
<div
  about="http://www.w3.org/People/Ivan/#me"
  instanceof="foaf:Person"
  property="foaf:name" content="Ivan"
/>
========

and in XHTML 2 we could even add it like this, using a nested <link>:

========
<div
  about="http://www.w3.org/People/Ivan/#me"
  property="foaf:name" content="Ivan"
 >
   <link rel="rdf:type" resource="foaf:Person" />
</div>
========

But whatever technique is used, applying rdf:type to the subject of  
the element is clearly consistent with how other predicates behave.


ALL PREDICATES

As we saw with the example of Ivan, earlier, it is actually quite  
easy to end up with all attributes on an element:

========
<div
  about="#ivan"
  instanceof="foaf:Person"
  property="foaf:name" content="Ivan"
  rel="foaf:knows" resource="#ben"
 >
========

In this situation we have a named item with various properties,  
however removing the name from that item should in no way affect the  
properties of that item. For example:

========
<div
  instanceof="foaf:Person"
  property="foaf:name" content="Ivan"
  rel="foaf:knows" resource="#ben"
 >
========

In this case, the 'item' named 'Ivan' should remain of type  
foaf:Person, regardless of the fact that it no longer has a name.

Regards,

Mark

[1] <http://lists.w3.org/Archives/Public/public-rdf-in-xhtml-tf/ 
2007Nov/0053.html>
[2] <http://lists.w3.org/Archives/Public/public-rdf-in-xhtml-tf/ 
2007Nov/0041.html>

-- 
   Mark Birbeck, formsPlayer

   mark.birbeck@formsPlayer.com | +44 (0) 20 7689 9232
   http://www.formsPlayer.com | http://internet-apps.blogspot.com

   standards. innovation.

Received on Thursday, 15 November 2007 14:33:45 UTC