W3C home > Mailing lists > Public > w3c-rdfcore-wg@w3.org > November 2001

Re: datatypes and MT

From: Sergey Melnik <melnik@db.stanford.edu>
Date: Thu, 01 Nov 2001 19:26:24 -0800
Message-ID: <3BE21260.C91F5B60@db.stanford.edu>
To: Pat Hayes <phayes@ai.uwf.edu>
CC: RDFCore WG <w3c-rdfcore-wg@w3.org>, "Peter F. Patel-Schneider" <pfps@research.bell-labs.com>

thank you very much for you input. I'm sorry to hear that you were

In this posting I originally wanted to consider the tradeoff between
the two approaches to datatyping we have on the table. However, as you
mentioned, there are indeed some substantial misunderstandings. I was
particularly struck by the fact that our understanding of the *syntax*
seems to be fluctuating. Before we proceed with semantics and MT, we
should at least agree on that. In my opinion, the syntax should be
fixed once and for all, no matter what path we go with respect to

Specifically, as of now I don't have a precise idea of *what* exactly
we are trying to interpret by comparing your posting and [1]. Are tidy
graphs our syntax? How then could there be two distinct literal nodes
with the same label in a graph? Why would we care about labels at all
if nodes with same labels fall into one? I feel a strong urge to pin
those things down.

I cannot follow your concerns about mention/use/occurrence phenomena
and the claim that this is what I supposedly have in mind. [1] makes
it clear enough that there is no such distinction, and that "7" and
"7" are the same symbol (or are the same labeled rectangle in a graph)
no matter how often and in which context they are used - right?

Now, to have something to talk about tomorrow ;), let me reiterate
what I believe the "straightforward" interpretation of datatyping
is. I'll have to address your posting in detail in a separate message.

Straightforward approach

To remind, the "straightforward" approach (consistent with [1]) works
as follows. A triple (s, p, o) is interpreted by means of a pair
<I(s),I(o)> contained in IEXT(I(p)). (Your Fig. 1 in [1] is a nice
graphical illustration of IEXT and I at work). Each literal symbol (or
literal node, whatsoever) like `o' above has a fixed interpretation
I(o), same in all possible worlds.

Explicitly defined datatypes

Consider a simplified example, in which we define a new "built-in"
datatype "Byte". As explained in [2], datatyping amounts to specifying
a lexical space, a value space, and a mapping from between them (XML
Schema DT does just that using plain English). To specify the mapping
from "byte literals" to "byte values" explicitly, we can define a
property say "byte" with the following "standard" interpretation:

IEXT(I(byte)) = {<b0,I("0")>, <b1,I("1")>, ..., <b255,I("255")>}

In the above, I("1") is the literal value that corresponds to the
literal symbol "1", whereas b0,...,b255 are some distinct elements in

XML Schema defines additional "features" of datatypes like order. The
ordering of "bytes" can be defined explicitly using

ORDER <= {<b0,b1>, <b0,b2>, <b0,b3>, ...,
          <b1,b2>, <b1,b3>, ...,

Notice that in the above example it is possible to provide a precise
definition of the datatype, its value space, its lexical space, and
the order within the value space by explicitly enumerating all
relevant relations in the interpretation.

Relating datatypes to each other

As another example, consider how two datatypes can be related to each
other. Imagine that a datatype Integer is defined using the property
"int" as

IEXT(I(int)) = {..., <i_1,I("-1")>, <i0,I("0")>, <i1,I("1")>, ...}

Now, the `bytes' can be tied to `integers' by requiring that in each
valid interpretation the following holds:

forall <b,x> in IEXT(I(byte)):
  <i,x> in IEXT(I(int)) -> b=i

Notice that it is not sufficient to just say that the value space of
bytes is included in the value space of integers - it is necessary to
describe *how* bytes are embedded into integers. For example, we don't
want b1 map to i5 and b10 to i20. The above expression links the two
datatypes together.

By the way, for convenience we could introduce a shortcut (T)L defined
as (T)L = x iff <x,I(L)> in IEXT(I(T)) to refer to the typed values in
the interpretation. Thus, for b1 we could write (byte)"1", for i_2 we
could write (int)"-2" etc. Thus, the `bytes' datatype could be defined
given the existing `int' type as
IEXT(I(byte)) = {<(int)"0",I("0")>, <(int)"1",I("1")>, ...}

In a similar fashion, different literal representations of datatypes
can be tied to each other. For example

{<(us-decimal)"5.8", I("5,8")>, ...} in IEXT(I(de-decimal))

illustrates that 5.8 and 5,8 represent the same data value. Literal
representations could be linked using some pseudo-language for string

Enumerated datatypes

As a final example, consider how the interpretation of months can be
introduced formally. Again, imagine that the property "month"
establishes the datatyping relationship between the corresponding data
values and lexical values:

IEXT(I(month)) = {<m1, I("Jan")>, <m1,I("January")>,...

In the above, each of the 12 data values corresponds to two lexical

Canonical representation (in terms of XML Schema) for month could be
defined as

IEXT(I(month-canonical)) = {<m1,I("Jan")>,...,<m12,I("Dec")>}

Summary of "straightforward" approach

The above approach allows us to define datatypes in very precise terms
and to relate them to each other formally. No special vocabulary is
required. No support for RDF Schema is required. (More examples can be
found in [2].)

The criticized disadvantage of the approach is that some constructs
cannot be expressed as "conveniently" as we wish. In particular, one
or several intermediate bNodes need to be introduced in certain cases.

I'll stop at this point. I still have to digest your posting, and I do
have many questions. One issue I'd like to resolve after the syntax
issue is whether the above way of introducing datatyping is valid -
I'm not saying it's the best. If you think there are other reasons
rather than "convenience" arguments why it is bad, please let me
know. Furthermore, I disagree that the above approach is reflected
adequately in your summary; it's not "2. Bnodes as literal values",
I'm not even mentioning rdf:value anywhere in this posting except in
this same sentence.

I think there are several issues that need to be dashed out by drawing
pictures rather than writing plain text.

Pat, I hope you get well soon. Thanks again for your feedback, talk to
you tomorrow.


[1] MT draft (editor's version).
[2] http://lists.w3.org/Archives/Public/w3c-rdfcore-wg/2001Oct/0530.html

Pat Hayes wrote:
> I'm sorry I dropped the ball on this issue just as it heated up. Ive
> been (literally) laid low with flu since Friday and unable to do
> anything much except whimper and cough.
> Let me try to first summarize the MT changes that I managed to
> extract from the pfps/ph interchange - I think these are all pretty
> much the same as what Peter got out of it, in all but stylistic
> details - and then use this extended MT to respond to a lot of the
> recent comments, some of which I think are based on
> misunderstandings. I will also try to show how *all* the various
> proposals for encoding datatyping information in RDF syntax can be
> incorporated into this MT extension in a uniform way, and so can a
> few others that havn't been made yet.
> OK. The basic idea of the MT extension arises from the fact that
> while the same literal label might mean different things in different
> contexts, datatyping information seems to remove what would otherwise
> be an 'ambiguity' when one looks at particular occurrences of literal
> labels. For example, it seems perfectly clear, just speaking
> intuitively, that the following graph
> aaa rdfs:range xsd:integer .
> bbb rdfs:range xsd:string .
> foo aaa "101001" .
> baz bbb "101001" .
> can be unambiguously interpreted as saying that the aaa-value of foo
> is the integer (89456 + 11545) and the bbb-value of baz is the
> character string "101001". (The double quotes in the RDF triples are
> not to be interpreted as actual quotation marks, of course, but only
> as literal-markers, a convention which I abhor but will stick with
> throughout this message.) The fact that there is no ambiguity in this
> graph, even though the same syntactic label is used with two
> different meanings, suggests that the datatyping information should
> not be thought of as a mapping from the literal labels - which is
> what one would get by extending the MT in a very straightforward way
> by simply including literal labels into the vocabulary of an
> interpretation - but rather as attached to the node itself. The
> datatyping extension to the MT therefore introduces a new kind of
> mapping, which is very similar to an interpretation mapping, but
> which applies to the nodes of the graph rather than to the literals
> which are used to label those nodes. We might call such a thing a
> 'datatyping interpretation', but I think that might be confusing, so
> I will call it a 'typing'.  An interpretation is a mapping from a URI
> vocabulary to entities; a typing is a mapping from nodes of the graph
> to datatypes. (I'll tell you what a datatype is in a minute.)
> The current MT does need to be altered in a tiny degree to make this
> possible. Currently it says that XL is a global mapping from literals
> to LV, and then it uses that mapping once, and never mentions it
> again. We need to change that so we define XL to be a mapping from
> *occurrences* (tokens, inscriptions, whatever) of literals to LV; or,
> less mysteriously, from *literal nodes* to LV. Then the model theory
> works exactly as before; this mapping is still 'global' (though that
> is now perhaps an unfortunate word to use) in the sense that it is
> independent of the interpretation.  (When we introduce a datatyping
> scheme, however, there is some connection between them, as we will
> see.)
> Technicalities.
> A datatype is a mapping from a lexical domain (a subset of literals)
> to a range of values (a set). A datatype scheme is a set DT plus a
> fixed mapping DTS from DT to datatypes.  It is convenient to define
> DTC(x) to be the range (not rdfs:Range, just range) of the datatype
> DTS(x). If nnn is the URI of a type, we will write XD(nnn) for the
> member of DT that the uri identifies. This mapping XD is similar in
> some ways to an interpretation mapping I, but unlike I, it is assumed
> that XD is computable (in some way), ie given the uri of a datatyping
> scheme, the machine can somehow access the actual DTS and DTC
> mappings associated with that datatyping scheme and apply them.
> (DTS and  DT aren't *strictly* needed, in fact; one could have a
> single global mapping directly from urirefs to datatypes; but it is
> in the same spirit as the rest of the model theory so I will go on
> doing it this way. Think of the member of DT as the abstract
> datatype-thingie and DTS as the datatype version of the IEXT mapping
> in the MT.  DTC is analogous to ICEXT.)
> Now, a datatyping of a graph is simply a mapping from the literal
> nodes of the graph to a datatype scheme, ie an assignment of a type
> to each literal node of the graph. Of course, a graph by itself might
> have any number of datatypings, just as a vocabulary can have any
> number of interpretations, but we want to make sure that if we have
> one of each than that fixes the interpretation of every part of a
> labelled graph unambiguously, by placing mutual constraints on how
> they act together. So, in this spirit, a typed interpretation is a
> pair <I,D> of an interpretation (of the uri vocabulary) and a
> datyping D (of the literal nodes of the graph) which together satisfy
> the following constraints:
> 1. XL(n) = DTS(D(n))(label(n))
> 2. ICEXT(d) is a subset of DTC(d) for any d in (DT intersect IR)
> (In 1 we are using two rather different kinds of function; label(n)
> is just a kind of syntactic selection function which refers to the
> label on the node n, while the other mappings are semantic.
> Mathematically these are all just functions, but intuitively they
> have different roles.)
> What these mean, intuitively, is exactly what one would expect; that
> the value of a literal (in the interpretation) is understood to be
> determined by the datatyping of the node on which it occurs; and that
> datatypes are treated appropriately as rdfs classes, in the sense
> that the RDFS class of a given datatype in the interpretation is a
> subset of set of things which actually have that datatype according
> to D.
> Now, the only other semantic condition we need on an interpretation
> is that it 'understands' that the urirefs that denote datatypes are
> in fact interpreted to refer to those datatypes, which can be stated
> as the condition
> 3. I(nnn)= XD(nnn)
> If I satisfies condition 3 for the datatype named nnn then we will
> say that I 'recognizes' that datatype, and it is natural to require
> that I recognizes every datatype which is mentioned in the graph (ie
> where nnn occurs in the graph as a node label), so we will add this
> as a third condition on a typed interpretation <I,D>.
> OK, that is all we require. We could sum all this up by saying that I
> has to 'respect'  D by agreeing to use the datatype URIs in the
> appropriate ways, and by agreeing to interpret the datatype mappings
> as rdf:properties in a consistent way (consistent with D, that is.)
> In return, D will undertake to guarantee that all literal occurrences
> are interpreted in a way that will be consistent with anything that
> is said in the RDF triples. As long as I and D promise to keep to
> their respective vows concerning each other, we can be sure that
> their marriage will be happy.
> (A less anthropomorphic analogy might be to think of D as a kind of
> datatyping network between nodes along which datatyping information
> can flow, and which can carry different information to different
> nodes.)
> This isn't really very different from extending the interpretation
> idea from urirefs to literals, but it acknowledges explicitly the
> ways that literal evaluation differs from uriref interpretations; the
> fact that once the datatyping has been determined, the value of the
> literal is *fixed* and is not subject to variation from one
> interpretation to another; but that also, in an odd way, the precise
> meaning of any given literal is hostage to the datatyping that is
> used to interpret it, and different occurrences might be interpreted
> differently. It also makes it clear how the rest of the RDF graph,
> while it may not change the datatyping mappings themselves (they are
> still 'global' to the graph) , can provide information (ie constrain
> the satisfying interpretations) which forces a particular literal
> label to be interpreted according to one or another datatyping scheme.
> [Aside. Heres how to say this without using the DT /DTS/DTC stuff.
> Just  assume a global mapping XD from urirefs to datatypes, and
> define a datatyping as a mapping D from nodes to datatypes.  Then the
> first two conditions above can be stated:
> 1. LV(n)=D(n)(label(n))
> 2. ICEXT(I(x)) is a subset of {y: XD(x)(lit)=y & lit is a literal}
> This shows how very simply it really is, but I still prefer the
> earlier way of stating it.]
> How this works.
> To illustrate this idea I will use the example graph given earlier.
> Since I want to refer to the actual nodes of the graph, however, I
> will use Ntriples++ notation to give the literal nodes labels, OK?
> Remember, this is the *same* graph, Ive just given two of the nodes
> unique labels in the Ntriples, is all.
> aaa rdfs:range xsd:integer .
> bbb rdfs:range xsd:string .
> foo aaa _:1:"101001" .
> baz bbb _:2:"101001" .
> Here is one datatyping of this graph:
> DTS(D(_:1)) = (lambda (?x)(eval ?x))
> DTS(D(_:2)) = (lambda (?x) 17)
> This says that literals on node#1 are interpreted by LISP and
> anything on node#2 is interpreted to be the number 17. Fortunately,
> that datatyping scheme has no URI, but it is a scheme. There are
> infinitely many damn silly schemes, but most of them wouldn't make
> the graph come out to be true no matter what interpretation you were
> to combine them with.
> Obviously the scheme we want is this:
> DTS(D(_:1)) = XD(xsd:integer)
> DTS(D(_:2)) = XD(xsd:string))
> And the cute thing is that this is guaranteed by the semantic
> conditions, since the graph says enough to lock down this as the only
> possible datatyping that would yield a satisfying typed interpetation
> <I,D>. Let me just do this for the integer case. If  <I,D> is a typed
> interpretation satisfying this graph, then I must recognize
> xsd:integer, so from 3:
> I(xsd:integer) = XD(xsd:integer)
> and by 2,
> ICEXT(I(xsd:integer)) must be a subset of DTC(I(xsd:integer)), ie of
> DTC(XD(xsd:integer)), ie the value space of xsd: integers. It follows
> from the ordinary rdfs:range semantic conditions that the only way
> that I could make the fourth triple true is if XL(_:1) is in the
> class DTC(XD(xsd:integer)), which requires (by the first semantic
> condition) that the datatyping D(_:1) on _:1 be the lexical-value
> mapping specified by xsd:integer, since
> XL(_:1)= DTS(D(_:1))("101001").
> (Actually what I said above isn't exactly true. The conditions do not
> guarantee that this datatyping is specified uniquely; but they do
> impose that whatever datatyping is used, it must *agree* with
> xsd:integer and xsd:string on all the literal nodes in the graph. I
> could invent a silly datatyping which was like xsd on all numerals
> less than a googleplex, but switched to hexadecimal, say.  That would
> work. The point being that you wouldn't know the difference, so it
> doesn't matter.)
> Alternative syntaxes
> Now let me illustrate how a variety of alternative ideas for
> specifying datatyping information in RDF graphs can be seen as
> extensions to this, by adding different kinds of constraints on
> datatyped interpretations.
> 1. Explicit schema datatyping.
> Assume that every occurrence of a literal is somehow explicitly
> labelled with a datatype in the graph itself, eg by redefining
> 'literal labels' to be pairs of a literal and a uri indicating a
> datatype. Let me use label(n) and dtype(n) respectively for these two
> parts of the literal label at a node; then simply define a datatyping
> scheme in the obvious way, by requiring it to be defined by the dtype
> labels:
>   4.1   D(n)=I(dtype(n))
> Substituting 4.1 into 1 gives:
> LV(n) = DTS(I(dtype(n)))(label(n))
> and assuming that dtype(n) is indeed a datatype uriref, then 3 in turn gives:
> LV(n)= DTS(XD(dtype(n)))(label(n))
> showing that in this case we can eliminate D from the equations
> altogether, and simply use the single 'global fixed' mapping XD to
> determine the literal value of a literal independently of the
> interpretation I and hence independently of the rest of the RDF
> graph. (This is in fact what I had in the back of my mind when
> defining the original MT, by declaring XL to be a global, fixed
> mapping.) So if we were to impose this very strict local datatype
> labelling scheme, in effect incorporating the datatype into the
> literal label itself, then there really is no need for this extension
> to the model theory. However, what this does show is that this kind
> of strict labelling scheme does not contradict the more flexible
> scheme, so they could be used together without any risk of being
> mutually incompatible.
> 2. Bnodes as literal values.
> Let me put together here under one heading a variety of variations of
> the following theme: that occurrences of literals in value position
> in a triple should be understood as an abbreviation of a pair of
> triples with an 'intermediate' bnode, where the bnode denotes the
> triple value and the literal label itself is relegated to a minor
> role of somehow 'illustrating' how that value could be written in
> some notation. For example: rewrite
> aaa bbb lit .
> as
> aaa bbb _:1 .
> _:1 rdf:value lit .
> Before analyzing this, I note that it has the advantage of putting a
> node that denotes the literal value in subject position, where other
> properties (such as rdf:type) can be asserted of it. This is indeed a
> major advantage - I think the *only* advantage - of this proposal,
> but we could render this moot simply by declaring that RDF shall
> allow literals in subject position. I will return to this point later.
> The first of these triples seems easy to interpret: it means exactly
> what the original triple meant, in fact. It's the second triple that
> seems rather odd. Since _:1 is supposed to denote the literal value,
> it would seem to have the same value at both ends. We have provided
> now two nodes to refer to the same thing: one blank, but in subject
> position; the other with a literal label to say what it is. The
> first, blank, node can now safely be asserted to have an rdf:type
> which is a datatype, and if we make reasonable assumptions about
> interpretations being in accordance with the global XD mappings from
> datatype URIs, (similar to the conditions listed here) then we will
> be able to infer the datatypes of those blank nodes by normal rdfs
> inference.  But the only way to know what the first node actually
> *means* is to look at the label on the second node. So we now have an
> odd juxtaposition, where rdf:value has a literal label at one end
> which has no assigned datatype, and a datatype at the other but no
> literal there to use it on.
> There are several ways to get around this. The simplest, in the
> current framework, is simply to declare that rdf:value is equality,
> ie that <x,y> is in IEXT(I(rdf:value)) iff x=y. This effectively
> forces I(_:1) to be the same as XL(lit), and then the <I,D> semantic
> machinery works in this case in exactly the same way that it works in
> the 'plain' case.  This however is not how the proponents of this
> kind of scheme usually think of it.
> Another way is to insist that the literal label in the second triple
> is treated in a nonstandard way: rather than denoting a literal
> value, it is being mentioned rather than used; it simply indicates
> the literal itself. (Or, equivalently, all literals are treated as
> strings.) The intuitive meaning of rdf:value is then a kind of
> inversion of the denotation mapping itself: it assigns a literal
> label to the literal value that is the semantic value of that label
> in the given interpretation. This seems to be what Sergey has in
> mind, and it is also I think what Dan C. suggested a while back as
> the best way to handle literals.
> Now, this seems to me to have a fatal flaw, which arises from the
> fact that the value spaces of two different datatypes might overlap.
> For example, suppose that there are datatypes xxd:octal and
> xxd:decimal, then the following would seem to be perfectly true:
> _:1 rdf:type xxd:octal
> _:1 rdf:type xxd:decimal
> _:1 rdf:value "32"
> _:1 rdf:value "26"
> since indeed the number twenty-six is the value of both a decimal and
> an octal numeral, so that number, which is what I(_:1) should be in
> any satisfying interpretation, is in both class extensions, and <26,
> "26"> is in IEXT(I(rdf:value)) when 26 is of type xxd:decimal, and
> <26,"32"> is in it when 26 is of type xxd:octal, so *both* of those
> pairs have to be in it. The point being that in cases like this, it
> isn't enough to just attach a datatype to the *interpretation* of the
> literal, ie the literal value denoted by the blank node. You have to
> somehow get it attached *to the literal itself*, and by making the
> separation a syntactic separation, there is no way to do that. The
> only way to do that in this kind of scheme would be to impose a
> syntactic constraint on RDF graphs that required any node to be the
> subject of at most one rdf:value arc; and since literals only appear
> at the object ends of those arcs, the only function of the rdf:value
> edge in the graph is to attach a unique literal label to the blank
> node. It seems less trouble, and much clearer in meaning, to simply
> attach it directly to the 'blank' node and throw that edge away, and
> then we are back where we started. (Notice that if we did that, then
> this kind of pathological example becomes impossible, since we would
> have to attach two different literal labels to the 'blank' node. The
> syntactic separation of lexical and value spaces in the RDF graph
> simply creates new opportunities for confusion, which is what usually
> happens when one gets use and mention mixed up in this kind of way.)
> On balance, therefore, I would prefer to adopt the first
> interpretation of rdf:value as simply meaning equality. However, if
> we are going to introduce equality into RDF, let us do so properly.
> This is quite a significant change to the language, making it much
> more expressive. We ought to be able to make inferences which follow
> from the transitivity and substutivity of equality, for example, and
> to be able to assert equalities between urirefs as well as literals
> and blank nodes.
> On the other hand, we could also gain all the expressive advantages
> of this device for literals without going this far, by making one
> simple change.
> 3. Literals as subjects.
> This proposal modifies the RDF syntax in a small way, by allowing
> literals to be subjects. The current MT goes through in exactly the
> same way, except of course the artificial restrictions in the closure
> rules for RDFS closures are removed. This would have several notable
> advantages for literals.
> First, information about literal nodes - in particular, their data
> type - can be expressed directly, instead of resorting to subterfuges
> like the introduction of blank nodes. In fact, as pointed out above,
> you can think of this as what you would get just by taking the
> notational devices used in the 'blank-node' syntax proposals and
> conflating the blank node with the literal node that it is linked to.
> For example, the following graph written in bnode-style:
> aaa bbb _:1 .
> _:1 rdf:value "345" .
> _:1 rdf:type xsd:integer .
> would be boiled down into:
> aaa bbb _:1:"345" .
> _:1 rdf:type xsd:integer .
> where I have been obliged to use Ntriples++ to indicate that the
> subject node of the second triple is the object node of the first one.
> (Notice that the use of nodeIDs in this style of Ntriples++ notation
> is *exactly* parallel to its use in the 'bnode' graph; the only
> difference is that some of the nodes being identified are no longer
> blank. In fact, one could get the Ntriples++ for the second graph
> from the Ntriples for the first one simply by making sure that the
> rdf:value triples occur after the triples that generated them, and
> then replacing all strings of the form
> A<white>. <white>?<newline><white>?A<white>rdf:value<white>
> where A is a nodeID, with
> A:
> and leaving the rest alone. )
> Second, this now gives us a very sweet way to characterize how to
> determine the datatype of any given literal node: Generate the rdfs
> closure of the graph, and see if it contains
> _:node rdf:type <datatype> .
> where _:node is the ID of the node and <datatype> is a datatype URI.
> If it does, then the literal on that node has to be interpreted in
> accordance with that datatype; if not, it doesn't. This works no
> matter how the datatyping information is provided; it could be said
> directly, or inferred from range information or even by
> subclass-transitivity inference; all those variations are absorbed in
> the details of the rdfs closure rules. (If it is provided by explicit
> node labelling then we would need to incorporate an extra closure
> rule to get it from the label into the graph explicitly.) The key
> point is, that if the graph somehow establishes membership in a class
> known to be a datatype, then that fixes it; if not, it is not fixed.
> OK, that's all for now. I have to go to bed, I'm bushed.
> Pat
> PS. How about having an rdfs class called rdfs:Datatype? Then the
> semantic rule on recognition could be relativised to membership in
> that class, and an rdfs graph would have an explicit internal note of
> the datatype/simple-class distinction.
> --
> ---------------------------------------------------------------------
> IHMC                                    (850)434 8903   home
> 40 South Alcaniz St.                    (850)202 4416   office
> Pensacola,  FL 32501                    (850)202 4440   fax
> phayes@ai.uwf.edu
> http://www.coginst.uwf.edu/~phayes
Received on Thursday, 1 November 2001 22:01:54 UTC

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 20:24:06 UTC