6.  String, Number, Datatype, and Lang

6.1  Literal

The string and number that appear in RDF are called literal. Every literal in RDF is an instance of rdfs:Literal. The class rdf:XMLLiteral is a subclass of rdfs:Literal and a class of all XML Schema data, which includes xsd:string and xsd:decimal and so on. It implies that every XML Schema data is also an instance of rdfs:Literal, and every literal is also an instance of rdfs:Resource, because rdfs:Literal is a subclass of rdfs:Resource.

gx-user(11): (subtypep xsd:string rdfs:Literal)
t
t
gx-user(12): (typep "this is a string." rdfs:Literal)
t
t
gx-user(13): (typep "this is an XML string."@en rdf:XMLLiteral)
t
t
gx-user(14): (typep 1.23 rdfs:Literal)
t
t
gx-user(15): (typep 1.23 xsd:float)
t
t
gx-user(16): (typep 1.23 rdfs:Literal)
t
t
gx-user(17): (typep "1.23"^^xsd:float xsd:float)
t
t
gx-user(18): (typep "1.23"^^xsd:float rdfs:Literal)
t
t
gx-user(19): (typep "this is a string." rdfs:Resource)
t
t
gx-user(20): (typep 1.23 rdfs:Resource)
t
t

Note that gx:typep and gx:subtypep are used in the above demonstration. SWCLOS can accept language-taged string as shown in line number 13, and xsd-typed data notation as shown in line number 17 and 18 through special reader macro rdf::read-string for succeeding character '@' and double characters '^^' after a string, respectively, instead of Common Lisp original reader macro for string. In read-eval-print loop (REPL) of lisp, a lexical token of string is read, the evaluation immediately returns the string object, if it is a plane string, then it is printed by lisp system as string so that the same character sequence as input is printed. As well as plane string, a language-taged string is read in SWCLOS's REPL. Then, the reader macro makes a form that creates an instance of rdf:inLang structure and hands it to the eval function in REPL. So, the lisp system returns an instance of rdf:inLang structure. Similarly, for a string with xsd-type,

gx-user(8): (quote "This is a test."@en)
(@ "This is a test." "en")
gx-user(9): (eval '"This is a test."@en)
"This is a test."@en
gx-user(10): "This is a test."@en
"This is a test."@en
gx-user(11): (quote "1.23"^^xsd:float)
(^^ "1.23" xsd:float)
gx-user(12): (eval '"1.23"^^xsd:float)
"1.23"^^xsd:float
gx-user(13): "1.23"^^xsd:float
"1.23"^^xsd:float

Method value-of allows users to get mapped value in lisp.

gx-user(15): (value-of "1.23"^^xsd:float)
1.23

@ content lang
[Function]
makes an instance of rdf:inLang and returns it. content must be a string. lang may be a string, or a symbol.

^^ value type
[Function]
creates an instance of XML data type type with value and returns it. value is a string or a lisp data that conforms to type. type may be an CLOS object or a symbol.

value-of datum
[Method]
When datum is an instance of rdf:XMLLiteral, this method returns the value of datum.

6.2  XSD Datatypes in SWCLOS

In RDF semantics, specific ones out of built-in datatypes in XML Schema are introduced in RDF. In SWCLOS, further limited numbers of datatypes out of datatypes in RDF are defined as lisp datatypes as follows.

Lisp Type Definition in Lisp Ex. in S-expression
xsd:unsignedByte (cl:unsigned-byte 8) 255
xsd:unsignedShort (cl:unsigned-byte 16) 65535
xsd:unsignedInt (cl:unsigned-byte 32) 4294967295
xsd:unsignedLong (cl:unsigned-byte 64) 18446744073709551615
xsd:nonNegativeInteger cl:unsigned-byte 0
xsd:byte (cl:signed-byte 8) 127
xsd:short (cl:signed-byte 16) 32767
xsd:int (cl:signed-byte 32) 2147483647
xsd:long (cl:signed-byte 64) 9223372036854775807
xsd:integer cl:integer 1234567890
xsd:positiveInteger (cl:integer 1 *) 1
xsd:nonPositiveInteger (cl:integer * 0) 0
xsd:negativeInteger (cl:integer cl:* -1) -1
xsd:float cl:single-float 1.0
xsd:double cl:double-float 1.0d0
xsd:decimal cl:rational (rational 1.0)
xsd:string cl:string "string?"
xsd:boolean (cl:member xsd:true xsd:false) xsd:false
xsd:anyURI net.uri:uri (uri "http://somewhere/")
xsd:anySimpleType (or xsd:boolean xsd:anyURI xsd:string xsd:float xsd:double xsd:decimal) "simple-type?"

Therefore, you may check a lisp datum in S-expression against the xsd types defined as lisp type as follows.

gx-user(7): (cl:typep 1 'xsd:positiveInteger)
t
gx-user(8): (cl:typep 1 'xsd:nonNegativeInteger)
t
gx-user(9): (cl:typep 1 'xsd:integer)
t
gx-user(10): (cl:typep 1 'xsd:int)
t
gx-user(11): (cl:typep 1 'xsd:decimal)
t
gx-user(12): (cl:typep 1 'xsd:unsignedByte)
t
gx-user(13): (cl:typep 1 'xsd:anySimpleType)
t

Moreover, each xsd type in lisp has an RDF datatype object as symbol value of the datatype, and gx:typep interprets a datum in lisp not only as lisp datatype but also as RDF datatype, if it is a plane literal (non-typed-literal) or a lisp datum.

gx-user(14): xsd:positiveInteger
#<rdfs:Datatype xsd:positiveInteger>
gx-user(15): xsd:integer
#<rdfs:Datatype xsd:integer>
gx-user(16): (typep 1 xsd:positiveInteger)
t
t
gx-user(17): (typep 1 xsd:nonNegativeInteger)
t
t
gx-user(18): (typep 1 xsd:integer)
t
t
gx-user(19): (typep 1 xsd:int)
t
t
gx-user(20): (typep 1 xsd:decimal)
t
t
gx-user(21): (typep 1 xsd:unsignedByte)
t
t
gx-user(22): (typep 1 xsd:anySimpleType)
t

On the other hand, a typed literal in RDF is mapped to an instance of RDF data type class in SWCLOS, and each typed-data instance is also interpreted by gx:typep as follows.

gx-user(8): (typep "1"^^xsd:integer xsd:integer)
t
t
gx-user(9): (typep "1"^^xsd:integer xsd:positiveInteger)
nil
t
gx-user(10): (typep "1"^^xsd:positiveInteger xsd:integer)
t
t
gx-user(11): (typep "1"^^xsd:positiveInteger xsd:positiveInteger)
t
t

Note that xsd:integer subsumes xsd:positiveInteger, so that "1"^^positiveInteger is an instance of xsd:positiveInteger and xsd:integer, too, but "1"^^integer is not an instance of xsd:positiveInteger, although the values of both in the value space are equal.

Every datatype is an instance of rdfs:Datatype. Note that rdf:XMLLiteral and xsd:integer, etc. are a class. So, rdfs:Datatype is a metaclass.

gx-user(21): (typep xsd:integer rdfs:Datatype)
t
t
gx-user(22): (typep rdf:XMLLiteral rdfs:Datatype)
t
t
gx-user(23): (strict-class-p xsd:integer)
t
gx-user(24): (rdf-metaclass-p rdfs:Datatype)
t

Function datatype? checks whether it is an XSD datatype or not for a symbol parameter, and datatype-p checks for a datatype object (an instance of rdfs:Datatype).

gx-user(31): (datatype? 'xsd:integer)
t
gx-user(32): (datatype-p xsd:integer)
t

datatype? symbol
[Function]
This predicate returns true if symbol is bound, and the symbol-value is an instance of rdfs:Datatype.

datatype-p x
[Function]
This predicate returns true if x an instance of rdfs:Datatype.

6.3  xml:lang in SWCLOS

The xml:lang attribute in RDF syntax can be used on any node element or property element in RDF/XML syntax to indicate that the included content is in the given language. See the following example, which is taken from W3C RDF/XML Syntax Specification (Revised).

<?xml version="1.0" encoding="utf-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:dc="http://purl.org/dc/elements/1.1/">
  <rdf:Description rdf:about="http://www.w3.org/TR/rdf-syntax-grammar">
    <dc:title>RDF/XML Syntax Specification (Revised)</dc:title>
    <dc:title xml:lang="en">RDF/XML Syntax Specification (Revised)</dc:title>
    <dc:title xml:lang="en-US">RDF/XML Syntax Specification (Revised)</dc:title>
  </rdf:Description>

  <rdf:Description rdf:about="http://example.org/buecher/baum" xml:lang="de">
    <dc:title>Der Baum</dc:title>
    <dc:description>Das Buch ist außergewöhnlich</dc:description>
    <dc:title xml:lang="en">The Tree</dc:title>
  </rdf:Description>
</rdf:RDF>

In reading RDF/XML forms, the xml:lang attribute on node elements is parsed as it is an attribute. The xml:lang attribute on property element is transformed as if it envelopes the role value as sub-role. Therefore, the above RDF/XML forms are interpreted and transformed to the following S-expressions.

(rdf:Description (rdf:about <uri http://www.w3.org/TR/rdf-syntax-grammar>)
                 (dc:title "RDF/XML Syntax Specification (Revised)")
                 (dc:title (:en "RDF/XML Syntax Specification (Revised)"))
                 (dc:title (:en-us "RDF/XML Syntax Specification (Revised)")))
(rdf:Description (rdf:about <uri http://example.org/buecher/baum>)
                 (xml:lang :de)
                 (dc:title "Der Baum")
                 (dc:description "Das Buch ist außergewöhnlich")
                 (dc:title (:en "The Tree")))

SWCLOS keeps and maintains the language environment according to the order and the nest structure of RDF/XML language designation. Therefore, at the second rdf:Description form in the above example, the German environment is set up at the language tag ':de' at first, then the English environment is established in the German environment at the ':en' envelope. As a result, We obtain the followings.

gx-user(9): (read-rdf-file #'addRdfXml "example08.rdf")
Warning: Entail by rdf1: dc:title rdf:type rdf:Property.
Warning: Entail by rdf1: dc:description rdf:type rdf:Property.
:done
gx-user(10): (slot-value <<http://www.w3.org/TR/rdf-syntax-grammar>> 'dc:title)
("RDF/XML Syntax Specification (Revised)"
"RDF/XML Syntax Specification (Revised)"@en
"RDF/XML Syntax Specification (Revised)"@en-US)
gx-user(11): (slot-value <<http://example.org/buecher/baum>> 'dc:title)
("Der Baum"@de "The Tree"@en)
gx-user(12): (slot-value <<http://example.org/buecher/baum>> 'dc:description)
"Das Buch ist außergewöhnlich"@de

Where such an expression as "Der Baum"@de and "The Tree"@en is an instance of rdf:inLang structure, which is printed as it looks like a lexcal form of plain literal with language option. See ISO 639-1 alpha-2 language code about the optional lang code.

rdf:inLang
[Structure]
A structure for plain literal with language option. The instance has two values for lang slot and content slot. Lisp prints this object like plain literal with option, content@lang.

lang? x
[Function]
returns true if x is the keyword symbol that matches one of the ISO 639-1 alpha-2 language code.


Author: Seiji Koide. Copyright (c) 2005, 2006 GALAXY EXPRESS CORPORATION. Feb. 2006
Copyright (c) 2007-2010 Seiji Koide. Oct.2010