($and/ <==do note remove - switch for preventing MathML interpretation of dollar signs)

About

This page was authored by TC member Nick Nicholas to help explore the XRI 3.0 syntax proposals -- specifically the XriThree/GcsDelimiter and XriThree/XrefDelimiter proposals -- as explained below.

Note: Commentary from other XRI TC members is interspersed in italics.

Intro

This is an explication of XRI segments, leading up to an interpretation of the recent XriThree/GcsDelimiter proposal for Global Context Symbols as delimiters.

I don't necessarily agree with the proposal, but I need to work through what story the proposal is telling before I can concur with it or refute it. Nick Nicholas 2008-12-04

At issue is, how to make sense of XRIs composed of segments and subsegments. XRI 2.0 had a particular way of making sense of them. XDI, which uses XRIs in a Semantic Web context, finds that way of making sense of them limiting. As a result, the XDI TC has proposed a less restrictive syntax for XRI subsegments, resulting in the proposals above that the XRI TC is considering for XRI 3.0.

The distinctions are subtle, and hard to explain, but they are real. Although the source of the requirements for these distinctions is XDI, to work they need to be represented through XRI syntax. Which means they must also have meaning in XRI resolution, independent of how XDI in particular (or any other application of XRI) makes semantic sense of them.

Note that while XDI, as an application of XRIs, is one important source of requirements for XRI 3.0 syntax (since it is an entire data interchange protocol based on XRIs) -- it's still only one context in which XRIs will be used: it should not be the only source of requirements. Any conclusions we reach regarding XRI 3.0 syntax should be uniform to all uses of XRIs.

Ok, here goes.

1

An XRI authority can consist of one segment (the first segment in an absolute XRI). That segment is introduced by one of XRI's endearing GCS characters, indicating who the authority is for interpreting that segment: = for individuals, @ for organisations, $ for reserved words, + for vocabulary words. So:

An XRI resolver takes that XRI, and "makes sense of it" by resolving it into some service endpoint. That service endpoint could be something that understands XDI as a service, or it could be an OpenID endpoint, or anything else. Whatever the service endpoint is, it has something to do with what the XRI identifier means:

2

An XRI can consist of a authority segment, followed by a path (delimited by slashes) and/or a query (delimited by question mark) and/or a fragment (delimited by a # sign). Just like normal URLs do. The authority segment is resolved by an XRI resolver. What follows in the path and query, though, is the business of the service endpoint that the first segment has resolved to; it is out of scope of XRI resolution proper.

That's just like URLs: DNS resolves the domain from English to an IP address, but what's after the slash is that IP address's problem, not DNS's. So DNS takes the domain of http://www.oasis-open.org/committees , and maps www.oasis-open.org to 66.151.234.59 . DNS doesn't care about /committees ; that's 66.151.234.59's problem to deal with.

In the same way, in

=drummond/$has$a/+friend,

the authority segment, =drummond, is resolved via XRDS to some appropriate service endpoint, say http://equalsdrummond.net/xdi/. The XRI resolution does not also try to do anything with the path /$has$a/+friend. It's resolved the authority, its work is done.

Instead, XRI resolution involves the formulation of a Next Authority URI, in which the XRI segment is resolved to a URI for a service endpoint; and the path is somehow passed on to that URI. (By default it's appended, but it needn't be.)

The Path is used to determine the service endpoint, out of the choices in XRD. But if there is no match in the XRD, then it just gets passed on to the default service endpoint. So:

3

An XRI can contain what has been called a cross-reference: a string in parenthetical brackets ( ). The string in brackets is not parsed by the XRI resolver, but merely passed on to the Next Authority URI: it is opaque. This allows an XRI to contain strings that themselves are not XRIs at all, such as a URL. So (http://equalsdrummond.net) is a relative XRI. So is (http://equalsdrummond.net)/$has$a/+friend. And, per the XriThree/XrefResolution proposal, if the latter XRI is turned into the absolute XRI $(http://equalsdrummond.net)/$has$a/+friend (note the  $  at the start), then an XRI resolver will resolve it to http://equalsdrummond.net/$has$a/+friend, i.e., the resolver will just pass the contents of the parentheses through. It quotes it, if you will. (We'll come back to that.)

4

An XRI authority segment can consist of multiple subsegments, delimited by  *  in XRI 2.0 syntax. (I'm ignoring  ! , the persistent subsegment delimiter, for simplicity, however it too serves as a subsegment delimiter in XRI 2.0 syntax.) In XRI resolution, this means that the first subsegment is resolved, returns an XRDS document, and that XRDS document specifies the XRI authority resolution service endpoint that is the authority for resolving the following subsegment, and so on. This is authority delegation.

So the XRI...

@cordance*hr*hirings/+submit

...describes an organisational structure within Cordance, the company. Cordance is an XRI authority: it has service endpoints, because that's what XRI authorities do. The HR department within Cordance is its own XRI authority, which does its own XRDS thing. The Hirings subdepartment is its own XRI authority again. But you need to navigate from Cordance and Cordance HR, to get to the Cordance HR Hirings subdepartment. XRI resolution respects that, changing the Next Authority URL with each step of the resolution, so that control passes from Cordance to Cordance HR to Cordance HR Hirings:

(Note: in the following examples, the squiggly brackets  { }  are not part of the actual XRI, but are indicating the portion of the XRI that is "replaced" at each resolution step by a concrete URL.)

5

Following section recast. Nick Nicholas 2008-12-04

What does that mean semantically? For starters, HR and Hirings are both words. They are used to describe suborganisations of Cordance in this context, but they have meanings of their own. This means they have XRIs of their own, +hr and +hirings. In fact, we can write the XRI that way, using the XRIs for the words instead of the bare strings:

@cordance*(+hr)*(+hirings)/+submit

To do this, we've had to treat the subsegments as cross-references, and that makes sense: "hr" and "hirings" are not being resolved by xri.net. They are merely being passed along to the next step of resolution, which then works out what they're doing there. At the start of resolution, they are opaque to the resolver: the first resolver, xri.net, is not itself dealing with them.

Of course, that's not the XRI I'd first written. Nor does it necessarily have the same meaning: @cordance*hr*hirings/+submit contains some strings which need not have anything to do with (+hr) and (+hirings). But it's a more interesting XRI, because it forces us to treat the subsegment as meaningful in some way.

So what is the relationship between the word +hr and @cordance*(+hr)?

We have a notion of contexts now. And it's not specific to XDI: it's inherent in any attempt to make sense of subsegments. The context is how you make sense of an XRI segment. And it is bound up with the resolver currently used for the XRI -- which in turn is specific to the XRI authority currently being invoked. There is a global context, bound to the default resolver, xri.net. There are local contexts, e.g. Cordance's context, bound to Cordance's resolver.

@cordance*(+hr) binds the interpretation of (+hr) to the local context of the authority preceding it. It means "the Cordance understanding of 'HR'", as opposed to "the common understanding of 'HR'".

(A context here is like Peirce's "interpretant" in semiotics. Not a dude doing the interpreting of signs; but a convention for interpreting signs. In the real world, these conventions are slippery, and Peirce had a whole hierarchy of how they emerge and converge, to make communication possible. But here we are dealing with IT (information technology), so we assume everything magically works just by having a resolver. And we have a touchingly naive faith that there is anything like a global context...)

6

@authority*(+subsegment) and @authority/+path are doing similar things: both the subsegment and the path are opaque to the resolver, and are passed on to the next stage of resolution. They have different behaviours when it comes to selecting endpoints; but if XRI was being developed in ignorance of URI, I'm not sure it would maintain the distinction. Oh well.

Also, nothing explicitly says that @authority*(subsegment) is the same as @authority*(+subsegment). I'm assuming it as a useful device. The thing in brackets can also be an organisation, or an individual, or a reserved word. So @cordance*(=drummond) is Drummond in the context of Cordance: Drummond, the Cordance employee. Cordance, not Drummond, get to determine what @cordance*(=drummond) means and how it interacts with the outside world. They may not be the same person. (Context gets used to disambiguate things.) They certainly won't have the same service endpoints.

7

The parentheses (cross-references) get used to pass around anything into XRI opaquely, and it will get treated as a single subsegment, without the XRI resolver peering inside. The thing in brackets could be a URI. It can also be a single-subsegment XRI, or a compound (multi-subsegment and/or multi-segment) XRI. For example, it could be a proposition (also called a statement in RDF), being treated as a single thing --- what in RDF is called reification. So:

The parentheses are good news: they let us show that the whole proposition needs to be dealt with as a single chunk. The ability to do this kind of second order logic is a difficulty with Web-based semantics in general, and a selling point for XDI. And they are consistent with our notion of cross-references as quoting stuff: John Bradley says "Drummond has a friend".

8

Under the old dispensation (XRI 2.0), a subsegment can *only* be locally bound to its preceding authority. That means that you can only put together @cordance and +hr as @cordance*(+hr): whenever you express the concept "Cordance HR", you always allow Cordance to decide what it means by HR.

This makes sense: Cordance gets to disambiguate the "HR" term; Cordance gets to provide its own services; Cordance establishes its own delegation of authority. But if you think, not in terms of resolution and authority, but just in terms of semantics, that's not necessarily what you want.

The reason is that XRIs are not only composed of segments in order to establish organisational hierarchies. They are also used simply to express composite notions. Consider Drummond's skateboard.

But =drummond*(+skateboard) does not mean "Drummond's skateboard". It means "Drummond's notion of what might be represented by the word 'skateboard'." Drummond has complete control of what "skateboard" means in that XRI, because "skateboard" is locally bound to Drummond as a context (* is called a "local context symbol" – meaning that the identifier that follows it is assigned and only meaningful in that local context). If Drummond wants to call his cat a skateboard, there's nothing you can do about it. (The cat may be a different story.) Of course, Drummond could play fair, and mean the same thing by "skateboard" as you do. In fact, for communication to be possible, that's what we end up doing (for some notion of "same thing"). But if Drummond had no discretion over how he is able to express this, we could never use him as a context to disambiguate things, or establish his own meanings where they are needed.

So this particular limitation of XRI 2.0 syntax makes it really hard to reason about any compound identifiers at all. If =drummond*(+skateboard) is not necessarily the same thing as a +skateboard, then you can't apply any of your reasoning about +skateboard to =drummond*(+skateboard). You can't do any inheritance, any common services, any generalisations. The fact that +skateboard has been reused within that cross-reference has bought you nothing: you're not allowed to make the cross-reference from +skateboard to =drummond*(+skateboard) at all, because the * local context symbol binds you to Drummond's whim.

This is an even more acute problem by the time you get to XRI RDF. When you have an XRI like...

=jbradley/+says/(=drummond/$has$a/+friend)

...then XRI 2.0 syntax requires that it actually means...

=jbradley/*(+says)/*(=drummond/*($has)*($a)/*(+friend))

...with the unpleasant consequences that:

That...is bad news.

9

The solution --- which XDI has been happily assuming for the past year, but XRI has not yet documented, is to allow subsegments to be globally bound, as well as locally bound.

The way this is done is to remove the  *  and the parentheses, and just concatenate the subsegments. So

(Those of you familiar with Lojban will recognise this as the old veridical and non-veridical distinction pervasive in that language. Those of you who are not, might anyway.)

The distinction is subtle, but it's real enough to be needed in XDI.

The notation can only work in XRI syntax if the global context symbols,  = @ + $ , are also allowed to be delimiters between XRI segments.

The notation has non-trivial consequences for readability; once you embed corporate identifiers, you start seeing =drummond@cordance, which is emphatically not an email address. (In fact it's the other way round: it's Cordance at Drummond -- i.e. Cordance as it relates to Drummond, though not necessarily as Drummond construes it.) Those used to XDI will not sweat readability, and in any case XDI RDF can always be expressed in an expanded notation, with lots of whitespace. Those new to XRI, maybe not so much.

10

Allow me the luxury of some meta-XRI:

We now have an understanding that a*b in XRI depends on the meaning of b (and not just what a says about b). If we are to reason about a*b, we need to be able to say what a*b is in terms of b -- what do they have in common. Clearly, a*b is a kind of b. "Drummond's skateboard" is a skateboard --- properly an instance of the class of skateboards (or maybe a subclass). So any qualities true of skateboards also hold of Drummond's skateboard. Individuals and groups are messier, because they don't readily subclass. (There's literature about "a Mr Jones" and "the Joneses", and how they are meaningful if "Jones" is meant to be a unique name.) The take is, that a*@b is the same entity as @b, and a*=b is the same entity as =b. The authority a provides some context for @b and =b, but it does not change their denotation.

On the other hand, because XRI resolution stops with the authority, a/b is a kind of a. As far as XRI resolution is concerned, at least, =drummond/$has$a/+friend refers to the same entity as =drummond: their authority is identical. It turns out that's what you want with predicates: inasmuch as they have a denotation, it's the denotation of their subject (though the rest of the predicate can constrain that denotation.)

11

So we want an understanding of =drummond+skateboard that's different from =drummond*(+skateboard). And outside XDI, understanding is tied up with resolution, so we want the resolution of =drummond+skateboard and =drummond*(+skateboard) to be different. The resolution of =drummond*(+skateboard) has nothing to do with how xri.net resolves +skateboard. The resolution of =drummond+skateboard must have *something* to do with how xri.net resolves +skateboard.

The thing is, =drummond is still the first authority segment of =drummond+skateboard; so any resolution of =drummond+skateboard still goes through =drummond. In concrete terms, that means that Drummond, not xri.net, serves up any XRD to do with skateboards. If Drummond is completely free to serve up what he wants, then =drummond+skateboard is no different from =drummond*(+skateboard): they're both Drummond's notion of what a skateboard is, and I cannot trust Drummond to talk about a skateboard in the first instance any more than in the second.

Keeping Drummond the authority over =drummond+skateboard does still make sense. After all, =drummond+skateboard is not the same thing as +skateboard; Drummond is presumably a better authority than xri.net on what the differences are between "skateboards" and "Drummond's skateboard". (I don't think that's universally true, but never mind.) But someone other than Drummond must still assert that +skateboard in =drummond+skateboard means what we think it means.

The "weak" version of that assertion is that the identity of reference is implied out of band.

The "strong" version, which I prefer, is that the identity of reference is made explicit somewhere in the machinery of XRI resolution --- so that XRI resolvers are informed that =drummond+skateboard refers back to xri.net for its understanding of +skateboard, even if they end up fetching the XRDS from Drummond anyway. We know that =drummond+skateboard is a +skateboard, because that's how we've defined compounding to work. So resolution could confirm that the XRDS for =drummond+skateboard does not conflict with the XRDS for +skateboard, just like it confirms that the XRDS for =drummond does not conflict with the XRDS for !213.43.343 (or whatever Drummond's i-number is.) Or, +skateboard could be asserted as a synomym in whatever XRDS =drummond+skateboard ends up fetching.

Great point. In the new XRD 1.0 work, the XRD itself has a Type element, and this is where the XRDS resolved from =drummond+skateboard could assert that its Type was the CanonicalID of +skateboard. =Drummond 2009-12-03

12

Under XRI 2.0, subsegments were always in parentheses, and always locally scoped. Cross-references were always locally scoped in fact, except when they were the first authority in the XRI string. So we always knew what the context for the cross-reference was.

With the possibility of global scoping as per the XriThree/GcsDelimiter proposal, and relative scoping as per the XriThree/XrefDelimiter proposal, things get murkier. The proposed notation would allow:

How do these differ in meaning? Which ones are allowed by the XRI 3.0 syntax? Which ones should be allowed by the XRI 3.0 syntax? Are there inconsistencies between what can be allowed in various types of cross-reference?

I have my own conclusions about what's going on (parentheses are being overloaded), but I'm going to here go through what Drummond and I agreed these three choices currently mean. We'll start with the skateboards, which are the least problematic semantically.

This gives us a hierarchy of XRI claims:

Scare quotes come from normal quotes. If we quote what someone says, and take it at face value, we allow that they mean by those words what we mean by those words. In "Drummond says 'Jbradley has a cat'", we presume that words 'Jbradley has a cat' mean the same thing to Drummond as they do to us, so we just report them without fuss. But if we start pulling faces, putting on funny voices, and making air quotes, we no longer presume that the phrase means the same thing when Drummond says it and when we say it. In fact, we presume Drummond is being misleading.

That becomes even more obvious with single words. I say "tomato", you say "tomato": if we mean the same thing, there is no dispute -- the word is just mentioned. But if I put scare quotes around "tomato", I'm highlighting the fact that "tomato" isn't my word; and it only makes sense for me to highlight that, if I don't agree with how the word is being used.

But you may be using the word "tomato" perversely even when I don't highlight the fact that you said it with lots of air quotes. When you say a word, you ultimately decide what you mean by it. I presume we're talking about the same thing; but I can't be sure.

13

If we bring that back to the XRI notion of contexts for things in brackets, we get the following (in pseudo-XRI):

or:

Generalising:

Nick, the last one is a legal XRI under XRI 3.0 syntax as proposed. However it's not yet a legal XDI statement in an XDI context because of XDI grammar rules, which require one slight modification. If you want to "spell out" a cross-reference as an object in XDI, you need to make it a complete subgraph, which in XDI addressing requires double slashes before the XDI object (the third segment). So the statement would be =drummond/$says//=jbradley/$has$a/+cat (note the double slash after $says). That represents the following XDI graph in X3 Simple format.

=drummond
        $says
                /
                        =jbradley
                                $has$a
                                        +cat

The difference is subtle enough it doesn't routinely get made, and need not. =drummond/$says//=jbradley/$has$a/+cat in an XDI context is "Drummond spoke the truth that Jbradley has a cat"; but =drummond/$says//*(=jbradley/$has$a/+cat) is not necessarily "Drummond lied that Jbradley has a cat". However, =drummond/$says//*(=jbradley/$has$a/+cat) does give up on the possibility of a common understanding with Drummond; =drummond/$says//(=jbradley/$has$a/+cat) leaves it open.

Whether XRI should be expressing that distinction, well, that's a different story. Human language isn't orthogonal about these distinctions anyway. The semantics we've introduced for (+tomato) are right for when we're reporting what someone said: people can speak predictions and fictions, and we would not want to commit to the validity of what something said, every time we reported it. For simple references on the other hand, we don't really need =drummond(+tomato) alongside =drummond+tomato and =drummond*(+tomato). If we wanted to report that Drummond called it a tomato without passing judgement, we'd say the whole claim: =drummond/+says/(+this/$is$a/+tomato). (Or some lambda calculus variant of it: ($lambda/$x/(=drummond/+says/($x/$is$a/+tomato))). Say.)

Another reminder that the RDF semantics of "claims" and "statements" with regard to segment order and cross-references in these XRIs exists only when they are used in an XDI context (or some other XRI application that applies these semantics). In a pure XRI context, they are just valid XRIs per the proposed XRI 3.0 syntax. =Drummond 2009-12-03

Whether XRI should allow global bindings of URL and complex cross-references is also a different story: it may be that establishing binding is not the business of parentheses at all, and that we need either different brackets for binding as opposed to syntactic scope, or a globally-binding counterpart to  * . That's a conversation for another time.

Yes, and one that's been had a number of times – our biggest challenge is that we have to live within the restrictions of generic URI syntax, which means there is an extremely limited set of characters available for use as delimiters. In fact I think we've already used almost all of them. =Drummond 2009-12-03

So does =nika/(+contact) mean something different from =nika/+contact? Yes, but only slightly (so long as XRI contexts range over paths): =nika/+contact commits to the service it identifies matching the dictionary definition of +contact: "Nika's What-I-call-a-contact-service". =nika/*(+contact) commits to the opposite: Nika's "contact" service, which could in fact be anything (though it might turn out to be a contact service after all). =nika/(+contact) leaves this open: "This is what Nika is saying is his contact service. I'm not vouching for it, but I'll assume it is accurate."

(Once again, I'm not saying I think that's why people type =nika/(+contact): I think this is more syntactic than semantic scoping. But that's the current story if the brackets are about semantic scope.)

Note: the main reason that people type =nika/(+contact) today is that it is the ONLY syntax that is legal under XRI 2.0. That's one major reason we want to move to XRI 3.0. =Drummond 2009-12-03

14

A final subtlety left hanging. We have allowed two ways to combine fragments in an XRI:

The other interpretation of slash as a delimiter is hierarchy, i.e., a/b means b is a part of a (in terms of "whole/part" composition relationships). For example, nested directories. =Drummond 2009-12-03

To use natural language terms, these account for adjective-noun and verb-noun relations (or to be more general, qualifier-qualified and predicate-argument). You can go to town with this stuff in semantic frameworks --- see keywords such as predicate calculus, categorial grammar, and second order logic. But that's not primarily XRI's issue: you can mediate on how to say "I rollerbladed on the skateboard that Drummond had given Jbradley" in your own time.

But one type of compounding this does not capture is coordinate compounding, as in "and", "mixed with" or "jointly with". =drummond+skateboard is a skateboard, but +black+white is not white, and you cannot apply inferences from +white to +black+white. This probably doesn't need anything inside XRI to deal with: XDI can introduce an and() functor in its own time; but be careful that semantic inferencing is best left to professionals.

Nick, I can tell we need you as a professional on the XDI TC! We already have a proposal for the XDI dictionary words $and and $or. =Drummond 2009-12-03

Examples of XRIs used in XDI RDF

This section of the page is being developed to answer questions about the use of XRIs in XDI RDF arising from the examples in the previous sections. It is still under construction. =Drummond 2009-12-10

The following examples are based on the XDI RDF model current as of 2009-12-10.

XRIs as RDF Statements

The core premise of XDI RDF is that every XRI identifying a node in the XDI RDF graph is an expression of an XDI RDF statement, and every XDI RDF statement represents a path through the XDI RDF graph.

To implement this design principle, XRIs representing paths through the XDI RDF graph model are composed according to some very simple rules. For example, a standard XDI RDF subject-predicate-object statement (where the object is not a literal or a subgraph) MUST use the following ABNF pattern:

        subject-xri "/" predicate-xri "/" object-xri

Examples:

        =drummond/$is/=drummond.reed
        =drummond/+employer/@cordance
        =drummond/$has/+friend

$has Statement Rule

In the XDI RDF metamodel (see Appendix A of The XDI RDF Model, $has is the predicate used to express an aggregation relationship between an XDI subject and XDI object. Such a relationship is expressed between each subsegment of multi-subsegment XRI contained within an XDI RDF segment, i.e., the relationship between the parent subsegment and the child subsegment expresses the following XDI RDF statement (in ABNF):

        parent-subsegment "/$has/" child-subsegment

For example, the following XRI:

        =drummond+friend

expresses the following XDI RDF statement:

        =drummond/$has/+friend

The inverse also applies, i.e., the XDI RDF statement:

        =drummond/$has/+friend

is expressed in the following XRI:

        =drummond+friend

This rule applies precisely with no transformations or special rules. For example, the following two-subsegment XRIs:

=drummond+skateboard
=drummond(+skateboard)
=drummond*(+skateboard)
=drummond!(+skateboard)
=drummond+(http://en.wikipedia.org/skateboard)
=drummond(http://en.wikipedia.org/skateboard)
=drummond*(http://en.wikipedia.org/skateboard)
=drummond!(http://en.wikipedia.org/skateboard)

express the following XDI RDF statements:

=drummond/$has/+skateboard
=drummond/$has/(+skateboard)
=drummond/$has/*(+skateboard)
=drummond/$has/!(+skateboard)
=drummond/$has/+(http://en.wikipedia.org/skateboard)
=drummond/$has/(http://en.wikipedia.org/skateboard)
=drummond/$has/*(http://en.wikipedia.org/skateboard)
=drummond/$has/!(http://en.wikipedia.org/skateboard)

$has$a Statement Rule

In the XDI RDF metamodel, $has$a is the predicate used to express an composition relationship between an XDI subject and XDI object. In ABNF:

        xdi-subject "/$has$a/" xdi-object

Such an XDI RDF statement produces an XRI in which the object of the $has$a statement becomes a XDI RDF predicate of the subject. For example, the following XRI: For example, the following XRI:

        =drummond/+friend

expresses the following XDI RDF statement:

        =drummond/$has$a/+friend

The inverse also applies, i.e., the XDI RDF statement:

        =drummond/$has$a/+friend

is expressed in the following XRI:

        =drummond/+friend

This rule applies precisely with no transformations or special rules. For example, the following XRIs:

=drummond/+skateboard
=drummond/(+skateboard)
=drummond/*(+skateboard)
=drummond/!(+skateboard)
=drummond/+(http://en.wikipedia.org/skateboard)
=drummond/(http://en.wikipedia.org/skateboard)
=drummond/*(http://en.wikipedia.org/skateboard)
=drummond/!(http://en.wikipedia.org/skateboard)

express the following XDI RDF statements:

=drummond/$has$a/+skateboard
=drummond/$has$a/(+skateboard)
=drummond/$has$a/*(+skateboard)
=drummond/$has$a/!(+skateboard)
=drummond/$has$a/+(http://en.wikipedia.org/skateboard)
=drummond/$has$a/(http://en.wikipedia.org/skateboard)
=drummond/$has$a/*(http://en.wikipedia.org/skateboard)
=drummond/$has$a/!(http://en.wikipedia.org/skateboard)

XriThree/XrefWalkthrough (last edited 2009-08-12 18:07:14 by localhost)