In SWCLOS, all RDF and RDFS axioms are implemented. For exmaple, the following example shows RDF axiomatic triples.
gx-user(2): (typep rdf:type
rdf:Property)
t
t
gx-user(3): (typep rdf:subject
rdf:Property)
t
t
gx-user(4): (typep rdf:predicate
rdf:Property)
t
t
gx-user(5): (typep rdf:object
rdf:Property)
t
t
gx-user(6): (typep rdf:first
rdf:Property)
t
t
gx-user(7): (typep rdf:rest
rdf:Property)
t
t
gx-user(8): (typep rdf:value
rdf:Property)
t
t
gx-user(9): (typep rdf:nil
rdf:List)
t
t
The following example shows a part of RDFS axiomatic triples.
gx-user(14): (rdfs:domain
rdf:type)
#<rdfs:Class rdfs:Resource>
gx-user(15): (rdfs:domain
rdfs:domain)
#<rdfs:Class rdf:Property>
gx-user(16): (rdfs:domain
rdfs:range)
#<rdfs:Class rdf:Property>
gx-user(17): (rdfs:domain
rdfs:subPropertyOf)
#<rdfs:Class rdf:Property>
gx-user(18):
(rdfs:domain rdfs:subClassOf)
#<RDFSclass rdfs:Class>
gx-user(19):
(rdfs:domain rdf:subject)
#<rdfs:Class
rdf:Statement>
gx-user(24): (rdfs:range rdf:type)
#<rdfsClass
rdfs:Class>
gx-user(25): (rdfs:range rdfs:domain)
#<rdfsClass
rdfs:Class>
gx-user(26): (rdfs:range rdfs:range)
#<rdfsClass
rdfs:Class>
gx-user(27): (rdfs:range
rdfs:subPropertyOf)
#<rdfs:Class rdf:Property>
gx-user(28):
(rdfs:range rdfs:subClassOf)
#<rdfsClass
rdfs:Class>
gx-user(31): (rdfs:subClassOf
rdf:Alt)
#<rdfs:Class rdfs:Container>
gx-user(32):
(rdfs:subClassOf rdf:Bag)
#<rdfs:Class
rdfs:Container>
gx-user(33): (rdfs:subClassOf
rdf:Seq)
#<rdfs:Class rdfs:Container>
gx-user(34):
(rdfs:subClassOf rdfs:ContainerMembershipProperty)
#<rdfs:Class
rdf:Property>
gx-user(35): (rdfs:subPropertyOf
rdfs:isDefinedBy)
(#<rdf:Property rdfs:seeAlso>)
gx-user(36):
(typep rdf:XMLLiteral rdfs:Datatype)
t
t
gx-user(37):
(rdfs:subClassOf rdf:XMLLiteral)
#<rdfs:Class
rdfs:Literal>
gx-user(38): (rdfs:subClassOf
rdfs:Datatype)
#<rdfsClass rdfs:Class>
The followings also show important axiomatic triples on RDFS.
gx-user(39): (typep rdfs:Resource
rdfs:Class)
t
t
gx-user(40): (typep rdfs:Class
rdfs:Resource)
t
t
gx-user(41): (typep rdfs:Resource
rdfs:Resource)
t
t
gx-user(42): (typep rdfs:Class
rdfs:Class)
t
t
gx-user(43): (typep rdf:XMLLiteral
rdfs:Class)
t
t
gx-user(44): (typep rdfs:Datatype
rdfs:Class)
t
t
The class-instance relation in RDF is directly defined with rdf:type property. The notion of RDF class is different from the class notion in CLOS, but the subsumption relation among objects is the same as that in CLOS. The straightforward mapping of rdf:type relation to CLOS class instance relation conveys gains and benefits such as the potential of CLOS is available. However, this straightforward mapping causes only one obstacle to implement RDF on top of CLOS, namely rdfs:Class that is an instance of rdfs:Class itself. Allegro Common Lisp rejects such membership loop among classes, whereas cl:standard-object is an instance of itself in CLOS. Therefore, to work around this obstacle, the internal proxy class, rdfsClass, is introduced as a class of rdfs:Class and simultaneously as a subclass of rdfs:Class. Note that this twisted relation of class/instance and superclass/subclass between rdfs:Class and rdfsClass in CLOS produces a membership loop of rdfs:Class as well as the relation between rdfs:Resource and rdfs:Class in CLOS. See the followings.
gx-user(2): (cl:typep rdfs:Resource
rdfs:Class)
t
gx-user(3): (cl:subtypep rdfs:Class
rdfs:Resource)
t
t
gx-user(4): (cl:typep rdfs:Resource
rdfs:Resource)
t
gx-user(5): (cl:typep rdfs:Class
'rdfsClass)
t
gx-user(6): (cl:subtypep 'rdfsClass
rdfs:Class)
t
t
gx-user(7): (cl:typep rdfs:Class
rdfs:Class)
t
Note that the membership loop on rdfs:Class is really implemented in CLOS semantics by means of a trick called twisted relation between rdfs:Class and its direct class rdfsClass.
The RDFS entailment directs that every resource in RDF is typed to rdfs:Resource. The following shows some examples.
gx-user(13): (typep rdfs:Resource
rdfs:Resource)
t
t
gx-user(14): (typep rdfs:Class
rdfs:Resource)
t
t
gx-user(15): (typep rdf:nil
rdfs:Resource)
t
t
gx-user(16): (typep rdfs:comment
rdfs:Resource)
t
t
gx-user(17): (typep "This is a plain literal."
rdfs:Resource)
t
t
gx-user(18): (typep 1
rdfs:Resource)
t
t
gx-user(19): (typep <http://www.somewhere>
rdfs:Resource)
t
t
There are two RDF entailment rules, rdf1 and rdf2 as follows.
gx-user(9): (defIndividual uuu (aaa
yyy))
Warning: Entail by rdfs1: aaa rdf:type
rdf:Property.
#<|rdfs:Resource| uuu>
gx-user(10): (typep aaa
rdf:Property)
t
t
gx-user(11): (defIndividual vvv (aaa (xsd:integer
1)))
#<|rdfs:Resource| vvv>
gx-user(12): (get-form
vvv)
(|rdfs:Resource| vvv (aaa "1"^^xsd:integer))
gx-user(13): (typep
(slot-value vvv 'aaa) rdf:XMLLiteral)
t
t
In any input triple, a predicate is an instance of rdf:Property (entailment rule rdf1). When an object of an input triple is a well-typed XML literal, SWCLOS creates an data object that is an instance of rdf:XMLLiteral typed to the designated type (entailment rule rdf2).
There are 13 rules in RDFS as shown in RDFS Entailment Rules in RDF Semantics.
However a lisp string and number is interpreted as a plain literal in RDFS by SWCLOS. Therefore, rdfs1 rule is implicitly realized for a plain literal.
Note that hereafter if line numbers are renewed some younger number, it means the system is newly booted and refleshed.
gx-user(2): (typep "This is a string in
lisp." rdfs:Literal)
t
t
gx-user(3): (typep 1
rdfs:Literal)
t
t
For a plain literal with language tag, SWCLOS creates an instance object of rdf:inLang, then the result for a literal with language tag also satisfies rdfs1 rule.
Note that the system is rebooted, before each of the following examples, otherwise uuu or aaa in the example are collides.
gx-user(4): (defIndividual uuu (aaa (:en "This is an English
text.")))
Warning: Entail by rdf1: aaa rdf:type
rdf:Property.
#<|rdfs:Resource| uuu>
gx-user(5): (get-form
uuu)
(|rdfs:Resource| uuu (aaa (:en "This is an English
text.")))
gx-user(6): (slot-value uuu 'aaa)
"This is an English
text."@en
gx-user(7): (typep (slot-value uuu 'aaa)
rdfs:Literal)
t
t
Rdfs2 is a domain entailment as follows. SWCLOS proactively performs this entailment rule. In other words, SWCLOS newly creates an instance or refines the existing instance according to this rule.
gx-user(2): (defProperty aaa (rdfs:domain xxx))
Warning: Range
entailX3 by rdfs:domain: xxx rdf:type rdfs:Class.
#<rdf:Property
aaa>
gx-user(3): (defIndividual uuu (aaa yyy))
#<xxx
uuu>
gx-user(4): (typep uuu xxx)
t
t
Rdfs3 is a range entailment same as domain rule rdfs2.
gx-user(2): (defProperty aaa
(rdfs:range xxx))
Warning: Range entailX3 by rdfs:range: xxx rdf:type
rdfs:Class.
#<rdf:Property aaa>
gx-user(3): (defIndividual uuu (aaa
vvv))
Warning: Range entailX3 by aaa: vvv rdf:type
xxx.
#<|rdfs:Resource| uuu>
gx-user(4): (typep vvv
xxx)
t
t
Rdfs4a rule entails a subject in any triple is an instance of rdfs:Resource. In a description of form for addForm input parameter, individual's type is designated by a classspecifier in the form. If 'rdf:Description' is indicated for class description, or cl:nil is passed for the resource object creation as no type indication, rdfs4a rule may be applicable. However, there is a sensitive question in SWCLOS. In RDF(S) semantics, rdfs:Resource is a type of every resource, despite that a resource is an instance of rdfs:Class or an instance of rdfs:Resource. On the other hand, in CLOS level at SWCLOS implementation, we have two possibilities for the instance of rdfs:Resource. It may be either as an instance of rdfs:Resource CLOS class (namely instance), or as an instance of rdfs:Class metaclass (namely class). As a default in SWCLOS, an instance of rdfs:Resource as CLOS instance of rdfs:Resource is created. Thus, SWCLOS changes the category of created object from instance to class later on, if a metaclass is indicated for the object at the proper definition.
Rdfs4b has the same logic and the same problem as rdfs4a for the range entailment. See the following example.
gx-user(2): (addForm '(cl:nil (:name uuu) (aaa xxx)))
Warning:
Entail by rdf1: aaa rdf:type rdf:Property.
#<|rdfs:Resource|
uuu>
gx-user(3): (typep uuu rdfs:Resource)
t
t
gx-user(4): (typep
xxx rdfs:Resource)
t
t
Rdfs5 is a transitivity rule on rdfs:subPropertyOf. We implemented it on properties.
gx-user(2): (defProperty uuu
(rdfs:subPropertyOf vvv))
Warning: Range entailX3 by rdfs:subPropertyOf: vvv
rdf:type rdf:Property.
#<rdf:Property uuu>
gx-user(3): (defProperty
vvv (rdfs:subPropertyOf xxx))
Warning: Range entailX3 by rdfs:subPropertyOf:
xxx rdf:type rdf:Property.
#<rdf:Property vvv>
gx-user(4):
(subproperty-p uuu xxx)
t
Rdfs6 is very natural rule on rdfs:subPropertyOf as well as rdfs10 on rdfs:subClassOf.
gx-user(9): (subproperty-p uuu
uuu)
t
Rdfs7 may be a little bit confusing.
gx-user(2): (defProperty aaa (rdfs:subPropertyOf
bbb))
Warning: Range entailX3 by rdfs:subPropertyOf: bbb rdf:type
rdf:Property.
#<rdf:Property aaa>
gx-user(3): (defIndividual uuu
(aaa yyy))
#<|rdfs:Resource| uuu>
gx-user(4): (slot-value uuu
'bbb)
Error: The slot bbb is missing from the object #<|rdfs:Resource|
uuu>
of class #<rdfs:Class |rdfs:Resource|> during
operation slot-value.
[condition type: program-error]
gx-user(5): (->
uuu bbb)
#<|rdfs:Resource| yyy>
In the form, (slot-value uuu 'bbb), although getting a slot value of bbb that is attached to uuu object was attempted, the value yyy is attached by slot named aaa, then CLOS signaled an slot missing alarm. The function “->” is for RDF graph traversing and getting the value at the final place arrived. It takes account of not only designated properties as travel path but also their super-properties.
Rdfs8 means that the default superclass of instance of rdfs:CLass metaclass is rdfs:Resource.
gx-user(2): (defResource uuu (rdf:type
rdfs:Class))
#<rdfs:Class uuu>
gx-user(3): (subtypep uuu
rdfs:Resource)
t
t
Rdfs9 subsumption rule and rdfs10 are natively equipped with in CLOS.
gx-user(2): (defResource uuu (rdfs:subClassOf
xxx))
Warning: Range entailX1 by rdfs:subClassOf: xxx rdf:type
rdfs:Class.
#<rdfs:Class uuu>
gx-user(3): (defIndividual vvv
(rdf:type uuu))
#<uuu vvv>
gx-user(4): (typep vvv
xxx)
t
t
gx-user(5): (cl:typep vvv xxx)
t
gx-user(6): (subtypep
uuu uuu)
t
t
gx-user(7): (cl:subtypep uuu
uuu)
t
t
Rdfs11 transitivity rule of rdfs:subClassOf is also natively equipped with in CLOS.
gx-user(2): (defResource uuu
(rdfs:subClassOf vvv))
Warning: Range entailX1 by rdfs:subClassOf: vvv
rdf:type rdfs:Class.
#<rdfs:Class uuu>
gx-user(3): (defResource vvv
(rdfs:subClassOf xxx))
Warning: Range entailX1 by rdfs:subClassOf: xxx
rdf:type rdfs:Class.
#<rdfs:Class vvv>
gx-user(4): (subtypep uuu
xxx)
t
t
gx-user(5): (cl:subtypep uuu xxx)
t
t
Rdfs12 is a special rule for rdfs:ContainerMembershipProperty. SWCLOS proactively adds the entailment that an instance of rdfs:ContainerMembershipProperty is a subproperty of rdfs:member.
gx-user(2): (defIndividual uuu (rdf:type
rdfs:ContainerMembershipProperty))
#<rdfs:ContainerMembershipProperty
uuu>
gx-user(3): (subproperty-p uuu rdfs:member)
t
The last rule rdfs13 is for data type definition.
gx-user(2): (defResource uuu (rdf:type
rdfs:Datatype))
Warning: Datatype uuu is defined. Please define lisp type
with same name.
#<rdfs:Datatype uuu>
gx-user(3): (subtypep uuu
rdfs:Literal)
t
t
SWCLOS satisfies rdfs13 by creating an instance of rdfs:Datatype. However, the lisp system cannot interpret this type until the same name lisp type is defined.