The Resource Description Framework (RDF) is a language for representing information about resources in the World Wide Webs, and it has a special syntax in XML called RDF/XML for short. In RDF, every resource, except literals and blank nodes, is identified with URI references. This idea originates from the meta-data markup for web resources. However, you do not need to mind in Semantic Webs or ontology descriptions whether resources in RDF really exist on the Webs or not.
In theory, a URI reference in RDF denotes an entity in the universe of discourse, namely a virtual world that reflects ideas on the real world. If a URI reference is a terminology in ontology, the URI reference in SWCLOS is bound with a CLOS object that represents a part of ontology on the denotation of a URI reference. You can input a URI reference object in SWCLOS using angle bracket reader macro ‘<’, where URI reference reading is terminated by ‘>’. In the following demonstration, note that expressions enveloped with ‘<’ and ‘>’ designate URIs, and expressions starting with a sharp character and enveloped with ‘<’ and ‘>’ designate objects in Lisp.
gx-user(3):
<http://www.w3.org/2000/01/rdf-schema#Resource>
#<uri
http://www.w3.org/2000/01/rdf-schema#Resource>
gx-user(4):
(iri-value
<http://www.w3.org/2000/01/rdf-schema#Resource>)
#<rdfs:Class
rdfs:Resource>
The QName is an abbreviation of URI reference with the namespace function for XML. For example, “<http://www.w3.org/2000/01/rdf-schema#Resource>” is abbreviated to “rdfs:Resource”. Here, the fragment-less URI or “http://www.w3.org/2000/01/rdf-schema” is mapped to “rdfs”, which is a prefix of QName, while a fragment “Resource” turns out a local part of QName. Franz Inc. provides URI APIs, in which a URI is implemented of CLOS objects typed to net.uri:uri. In SWCLOS, a part of URI that corresponds to a prefix part of QName is connected to a lisp package, whereby a URI corresponds to a QName as lisp symbol in a package. Thus, a URI reference may have one by one mapping to a lisp symbol (QName), and vice versa, if it has a namespace. See the followings.
gx-user(5):
(uri2symbol
<http://www.w3.org/2000/01/rdf-schema#Resource>)
rdfs:Resource
gx-user(6):
(symbol2uri 'rdfs:Resource)
#<uri
http://www.w3.org/2000/01/rdf-schema#Resource>
At the line 5 in the demonstration above, the URI is converted to the corresponding QName, and at line 6, the reverse operation is directed. Note that such correspondence can be established when SWCLOS loads an ontology including URI references, or when you input URI references as RDF entity in the lisp top level window.
In theory, the substance of RDF can be modeled as labeled uni-directional graph of edge and node called RDF graph. A start node of edge is called subject, an end node is called object, and an edge is called predicate in triple. So, a triple subject/predicate/object in text stands for the minimal structure in graph. A set of triples in text turns out a whole RDF graph.
A predicate in triple is a URI reference or QName, and the statement of predicate requires or produces the corresponding resource called property in RDF vocabulary. Note that any edge must be named by a URI in RDF. Furthermore, it must have a QName in SWCLOS, because it turns a slot name in CLOS. A subject in triple designates a non-literal resource, that is, the node must be expressed by a URI, otherwise it must be a blank node. The blank node has no URI but may be assigned with a blank node ID. An object in triple is either a resource (with or without URI) or a literal. The following shows an example of statement in N-Triple.
<John_Doe>
<http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <Man> .
In SWCLOS, a resource or an entity in RDF is realized as a CLOS object. A denotation of triple subject/predicate/object is represented by a subjective CLOS object and its slot of which the slot name is corresponding to a predicate. The slot value is an objective CLOS object (called resource) or lisp data (literal).
The subjective CLOS object is bound to the QName lisp symbol, if it is not a blank node.
gx-user(7): rdfs:Resource
#<rdfs:Class
rdfs:Resource>
As well as a subjective CLOS object is bound to the QName, every subjective CLOS object, even if a blank node, is bound to the relevant URI. See the following demonstration.
gx-user(8):
(iri-value
<http://www.w3.org/2000/01/rdf-schema#Resource>)
#<rdfs:Class
rdfs:Resource>
gx-user(9):
<<http://www.w3.org/2000/01/rdf-schema#Resource>>
#<rdfs:Class
rdfs:Resource>
Note that at line 9, the special reader macro for double angle brackets ‘<<’ reads the character sequence of URI up to characters ‘>>’ and then a bound value to the converted URI is returned. A CLOS object that represents a resource in RDF is called resource object in SWCLOS.
SWCLOS utilizes the URI APIs of Allegro Common Lisp (ACL). Please see the details http://www.franz.com/support/documentation/8.2/doc/uri.htm. To implement value-bindable URI, a subclass of net.uri:uri is defined with an extra value slot. This subclass is named IRI. Every IRI in SWCLOS is interned to ensure the uniqueness of IRI in system.
There are several utilities for handling all uri and iri entries. See print-all-entity-uris, do-all-entity-uris, and list-all-entity-uris in doc folder.
A uri and iri in SWCLOS may be converted to the corresponding QName. The prefix of QName in XML is mapped to a lisp package in SWCLOS, and the local part is mapped to a symbol name in the package. A QName symbol is exported, because an exported lisp symbol has the same appearance as the QName in XML. A QName symbol is used to designate a resource name in S-expression. In fact, the description at the top level in SWCLOS requires a QName symbol instead of a URI in the context of define macros such as defConcept and defIndividual. Some URI(IRI)s that have no prefix definition cannot be converted to QNames and remain as URI(IRI).
The mapping rule from URI to QName in SWCLOS is as follows.
See the following demonstration.
gx-user(17):
(uri2symbol
<http://somewhere/maindir/subdir/JohnSmith>)
swsd:JohnSmith
gx-user(18):
(uri2symbol <http://somewhere/JohnSmith>)
sw:JohnSmith
gx-user(19):
(uri2symbol <http://JohnSmith/>)
no:J.S.
At line 17, prefix query to users is carried out for “<http://somewhere/somedirectory/subdir/>”, and “swsd” is replied by a user. At line 18 for “<http://somewhere/>”, “sw” is replied. At line 19, the local name is required at first, then “J.S.” is supplied, then, “no”" is replied for the prefix query.
A URI reference is unique in WWWs, and then XML namespace supports the uniqueness of QName with a local part, which is unique in a name space. In SWCLOS, a local part of QName corresponds to symbol name in a package, and a namespace for a prefix part corresponds to a lisp package. To realize such mapping, we need the connection between a prefix part in URI and a lisp package, and when URI-to-symbol mapping is irregular such as demonstrated above, we further need the mapping from a URI to a symbol name in the lisp package. An instance of uri-namedspace, that is a subclass of net.uri:uri, has two extra slots, package and environment, and it enables such named space environments for the URI name space. See the following demonstration.
gx-user(2): (defpackage
:ex
(:documentation
"http://somewhere/main/sub/file"))
#<The ex package>
gx-user(3):
(set-uri-namedspace-from-pkg (find-package :ex))
#<The ex
package>
gx-user(4): (get-uri-namedspace
<http://somewhere/main/sub/file>)
#<uri-namedspace
http://somewhere/main/sub/file>
gx-user(5): (uri2package
"http://somewhere/main/sub/file")
#<The ex package>
gx-user(6):
(uri2symbol "http://somewhere/main/sub/file#JohnSmith")
ex:JohnSmith
In the above demonstration, a URI string is set to a new package named gexh as its documentation option at first, and then the regular mapping is set as prefix named space in system at line 3. So, URI to package mapping is established here as shown later on line 5. In regular mapping for a URI with fragment, regular URI to QName conversion is carried out in default rules without using the URI's symbol mapping environment.
A user may set any user-defined functions to global variable *uri2symbol-name-mapping-fun* and *uri2symbol-package-mapping-fun* in order to implement application-oriented rules for the irregular mapping in default. See the detail in the description of the documentation file of program in the doc folder and the source program.
When SWCLOS reads RDF/XML files, the namespace directions with PrefixedAttName 'xmlns:' and DefaultAttName 'xmlns' make the mapping from a URI to the package name. On the other hand, from the standpoint of lisp expression, SWCLOS users can direct the mapping from a package to a uri in the package documentation as demonstrated above, in which a user put a corresponding URI as documentation of package.
Sometime you may be embarrassed at an error message of no package for a base-URI or a default namespace, when SWCLOS reads an RDF/XML file. It happens if an RDF/XML file does not include any Prefix name in the file for the file itself. In such a case, it is recommended that you supply two sentences, something like “xmlns:base = 'somewhere'” and “xmlns:PREFIX = 'somewhere'” into RDF attributes in the file.
Each uri-namedspace is stored in a hasharray which is bound to a global variable *NameSpaces*. The converting functions, uri2symbol and symbol2uri use these mappings bound to *NameSpaces*.
Note that all resource names or QName symbols are exported. Therefore, in a dedicated package for a resource namespace, the following code is an example that lists up all defined uri in the namespace.
gx-user(7): (loop for x being each external-symbol
in (find-package
:rdfs)
collect (symbol2uri x))
(#<uri
http://www.w3.org/2000/01/rdf-schema#subPropertyOf>
#<uri
http://www.w3.org/2000/01/rdf-schema#Datatype>
#<uri
http://www.w3.org/2000/01/rdf-schema#domain>
#<uri
http://www.w3.org/2000/01/rdf-schema#label>
#<uri
http://www.w3.org/2000/01/rdf-schema#seeAlso>
#<uri
http://www.w3.org/2000/01/rdf-schema#Container>
#<uri
http://www.w3.org/2000/01/rdf-schema#subClassOf>
#<uri
http://www.w3.org/2000/01/rdf-schema#isDefinedBy>
#<uri
http://www.w3.org/2000/01/rdf-schema#Resource>
#<uri
http://www.w3.org/2000/01/rdf-schema#range> ...)
list-all-entities-in performs almost same work.
gx-user(4): (list-all-entities-in :rdfs)
(rdfs:subPropertyOf
rdfs:Datatype rdfs:domain rdfs:label rdfs:seeAlso
rdfs:Container
rdfs:subClassOf rdfs:isDefinedBy
rdfs:Resource rdfs:range ...)
Precisely speaking, we have some semantic gap between a URI namespace and a lisp package. The lisp package is always global in the current session. Namely, a lisp package for the namespace should be unique anywhere and anytime. The URI is also globally unique, but its namespace is a temporal setting for the URI abbreviation in the scope of a RDF/XML file or a Web page. In a RDF/XML file, a settled namespace for a URI is scoped within the file, and it is legal that someone set a different name of namespace for the identical URI in another RDF/XML file. Thus, in ideal the two files should be correctly merged regardless of namespaces but regarding URIs. For example, if you have two ontology files, one has a namespace ‘wine’ for some URI and another has a namespace ‘vin’ for the same URI, the system must read both in the same namespace. However, Lisp cannot read symbols in different packages into some one package. To solve this problem, the lisp package nicknames are utilized here. When SWCLOS detects the mapping different package names onto a same URI, the newly indicated prefix turns out a nickname for the previously mapped package. Even so, note that the first encountered package name is a nominal name and nickname's prefixes do not appear in S-expression.
In addition to the URI-value mapping mentioned above, a CLOS object as resource is also set as symbol-value to the QName symbol, if it has a QName, or to an assigned nodeID symbol, if it has a nodeID. To test whether a CLOS object is a resource object or not, you may use lisp native type predicate cl:typep as follows. Note to use gx:typep predicate, if you need a type-testing predicate that exactly obeys RDFS semantics up to the range of URIs and Literals.
gx-user(2): (cl:typep rdfs:Resource
rdfs:Resource)
t
gx-user(3): (cl:typep rdfs:Class
rdfs:Resource)
t
gx-user(4): (cl:typep rdf:Property
rdfs:Resource)
t
In the example above, three resource objects, named rdfs:Resource, rdfs:Class, and rdf:Property, are tested whether they are instances of class rdfs:Resource.
Predicate rsc-object-p is prepared for testing whether an CLOS object is a resource object or not. It is same as (cl:typep x rdfs:Resource) in the semantics but it is faster a bit and simplifies your code. Note that object? is used for testing a QName symbol or a nodeID symbol to which a resource object is bound.
gx-user(5): (object? 'rdfs:Resource)
t
gx-user(6):
(object? 'rdfs:Class)
t
gx-user(7): (object?
'rdf:Property)
t
To list up all resources defined in the system, you can use list-all-resources as follows.
gx(8): (list-all-resources
t)
(#<rdfs:Class rdfs:Resource> #<rdfs:Class rdfs:Container>
#<rdfs:Class rdf:Alt> #<rdfs:Class rdf:Seq>
#<rdfs:Class rdf:Bag>
#<rdfs:Class
gx::ill-structured-XMLLiteral> #<rdfs:Class rdf:Statement>
#<rdfs:Class rdf:List> #<rdf:List rdf:nil> #<rdfs:Class
rdfs:Literal>
...)
In most cases, a resource object is named with a QName. The method name gets the name from a resource object and returns its QName symbol. The resource object is set to the QName symbol. On the other hand, resource objects that have no name are called anonymous resource, or blank node, or bnode for short, and you can access them through iri-value function rather than symbol value.
gx-user(2): (name
rdfs:Resource)
rdfs:Resource
gx-user(3): (addObject rdfs:Resource
'((rdf:about "NothingElseURI")))
#<rdfs:Resource
:anonymous>
gx-user(4):
<<NothingElseURI>>
#<rdfs:Resource
:anonymous>
gx-user(5): (slot-value <<NothingElseURI>>
'rdf:about)
"NothingElseURI"
gx-user(6): (anonymous-p
<<NothingElseURI>>)
t
Note that in the above demonstration, an anonymous object is created at line 3, whose URI string is "NothingElseURI". So, <NothingElseURI> at line 4 is parsed to a uri, and the resource object is retrieved through iri-value and returned it.
A nodeID is used for referring anonymous node, especially in N-Triple notation. It looks like QName that has ‘_’ as prefix and meaningless local name such as ‘a01’. However, a nodeID is not associated to any URI and has no global identification. There is a package dedicated for nodeID in SWCLOS, its package name is ‘_’, and a nodeID is also a lisp symbol in SWCLOS. You can bind any blank node to a nodeID symbol in the current session, but there is no way to store and reload the information on nodeID bindings by SWCLOS. The following functions are for the nodeID. However, there are useful functions no more on NodeIDs in SWCLOS. Be careful to use NodeIDs with respect to the identity of blank nodes according to RDF Semantics. See RDF Semantics.
As well as character ‘<’ being a reader macro on for URI, character ‘_’ is also a reader macro so that the character sequence of the succeeding colon and other characters makes an exported lisp symbol, and the symbol is handed to eval function if it is bound. Otherwise new anonymous resource object is created and bound to the symbol, then the symbol is handed to eval function. See the following demonstration.
gx-user(2):
_:a01
#<|rdfs:Resource| :anonymous>
gx-user(3): (quote
_:a01)
_:a01
gx-user(4): (list _:a01 _:a02)
(#<|rdfs:Resource|
:anonymous> #<|rdfs:Resource| :anonymous>)
gx-user(5): (eq _:a01
_:a01)
t
gx-user(6): (eq _:a01 _:a02)
nil
Where |rdfs:Resource| denotes the alternative to rdfs:Resource in SWCLOS, which is provided instead of rdfs:Resource when rdfs:Resource is specified as class of instances. It is expected that rdfs:Resource should be an abstract class in CLOS and finally all slots are defined at subclasses of rdfs:Resource, even if some slot definitions might be tentatively designated to rdfs:Resource. |rdfs:Resource| is useful to suppress making wasteful slot definitions at rdfs:Resource.