SWCLOS: A Semantic Web Reasoner on CLOS
RDFS Subsystem
This subsystem provides the tools for the inference in RDFS.
If you want to use NTriple and OWL, load NTriple subsystem and OWL subsystem, respectively.
Slot Definition Module
IT Program Project in Japan:
Building Operation-Support System for Large-scale System using IT
This code is written by Seiji Koide at Galaxy Express Corporation, Japan,
for the realization of the MEXT IT Program in Japan.
Copyright (c) 2002-2005 Galaxy Express Corporation
Copyright (c) 2007, 2009 Seiji Koide
Slot definitions for SWCLOS
The standard slot definition in CLOS (mop:standard-slot-definition) is also a CLOS object
and includes the information for slot creation of instances, i.e., initargs, type,
documentation and so on. Hereafter, we call a slot in slot definition object an option of
slot. So, we say, for example, the standard slot definition has an initargs option, a type
option, and documentation option, and so on.
The slot with respect to rdf property is an instance of Property-direct-slot-definition,
which is a specialized class of mop:standard-direct-slot-definition. In addition to CLOS
native options, Property-direct-slot-definition has a subject-type option, and the slot
with respect to owl specific property is an instance of OwlProperty-direct-slot-definition,
which is a specialized class of Property-direct-slot-definition. It has a maxcardinality
and a mincardinality option.
The type option of CLOS native options is used as the constraint for the slot value type,
and maxcardinality and mincardinality options are used as cardinality constraints for a
number of slot values.
The subject-type option in Property-direct-slot-definition is used as a inverse link to a
subject class to which the slot definition itself is attached. Note that a
subject/predicate/object triple in RDF is realized as instance-object/slot-name/slot-value
in CLOS. Thus, the specialized slot-definition Property-effective-slot-definition and
OwlProperty-effective-slot-definition in SWCLOS represents a set of triples such that the
subject is typed to subject-type and predicate is the same as slot-name. Therefore,
all triples subject/predicate/object can be retrieved by collecting all slot values through
this inverse link from these slot-definitions using slot-value function. Note that all slot
definitions on a property is booked into the property resource objects.
Symbol 'Property-direct-slot-definition' is set to this parameter in RDF. This value is overwritten
by OWL module. This value directs the default class for slot definition. See
mop:direct-slot-definition-class method in RDFboot module. |
defines a subject-type option. |
An instance of this class has a subject-type option in which a class of
subject in triple is stored. |
defines a max and min cardinality options. |
An instance of this class has a max and min cardinality options,
which work as the constraint for settable number of values. |
Slot Predicates
returns true if slotd is an instance of Property-direct-slot-definition. |
returns true if slotd is an instance of Property-effective-slot-definition. |
returns true if slotd is an instance of OwlProperty-direct-slot-definition. |
returns true if slotd is an instance of OwlProperty-effective-slot-definition. |
collect direct and inherited property (slot) names on this class and returns a list of them. |
How a Type Value is set in Direct Slot Definition
There are four ways in RDF and two in OWL to suppy the type option in initargs parameter for
shared-initialize method of Property-direct-slot-definition, i.e.,
- When a property is defined with domain constraint, add-direct-slots-to-domain function adds
a direct slot definition into the domain class. In this case, the range constraint of property
is retrieved from the property object and supplied for type option in the slot definition.
See add-direct-slots-to-domain.
- When an RDF instance or class is newly made or reinitialized, ensure-class-slotds is invoked
for the class of the object to ensure class slot definitions. In this case, the range constraint
of property is retrieved from the property object and supplied for type option in the slot
definition. See ensure-class-slotds.
- When change-class is invoked, if the instance to be changed has a slot value and the new class
has no definition on the slot, the old slot definition is copied into the new class.
See change-class:before(rdfs:Resource rdfs:Class).
- When put-value(rdfs:Resource rdf:Property) is invoked but the subject inherits no slot definition,
the slot definition is added to the class of subject. See put-value.
- When an instance of owl:allValuesFromRestriction is made or redefined, the constraint is transfered
into the type option in the slot definition that is attached to the restriction with slot name
from onProperty value. See shared-initialize:after(owl:allValuesFromRestriction).
- When an instance of owl:someValuesFromRestriction is made or redefined, the constraint is transfered
into the type option in the slot definition that is attached to the restriction with slot name
from onProperty value. See shared-initialize:after(owl:someValuesFromRestriction).
How to Compute a Type Value in Effective Slot Definition
See the same comment as above in RDFboot module.
Note that rdf property name is also slot definition name, and every property object in CLOS keeps effective
slot definition objects for housekeeping.
When an effective-slot-definition object is created, the name of slotd is a property name, and this slotd
is stored into slotd slot of the property. The following method do it.
shared-initialize (slotd
Property-effective-slot-definition) slot-names &key (name
nil) |
[method] |
When the first definition of slotd, updates the value of slotds slot in the property. Namely,
the old relevant slotd in slotds of the property is removed, and this slotd is added into
the slotds of the property. |
Property Predicates
returns true if x is an instance of rdf property. |
returns true if name is an rdf property name |
name (object
standard-effective-slot-definition) |
[method] |
returns a name of object, if it is named, otherwise nil. |
Slot Definition for owl:oneOf
Note that the slot definition for owl:oneOf is an instance of gx::Property-effective-slot-definition
rather than OwlProperty-direct-slot-definition. It depends on method mop:direct-slot-definition-class
and rdfs:Class.
Seiji Koide Sep-04-2009
Rdf Boot module
IT Program Project in Japan:
Building Operation-Support System for Large-scale System using IT
This code is written by Seiji Koide at Galaxy Express Corporation, Japan,
for the realization of the MEXT IT Program in Japan.
Copyright (c) 2002-2005 Galaxy Express Corporation
Copyright (c) 2007-2010 Seiji Koide
The aim of this file is to establish the complex relation of meta-circularity in RDF
incrementally step by step. Loading this file yealds the following hierachical structure
at the end.
........................
: :
: rdfsClass
: ...../..:
: : / ..........
cl:standard-class -- rdf-node ----------:--------rdfs:Class---:---shadowed-class
: :...........: / : ::...:
: ...../.......: :
: : / :
cl:standard-object -- gnode --- rdfs:Resource --- rdf:Property
---, / super/sub class relation, the direction of super is right to left.
..., : class/instance relation, the direction of class is upward and left to right.
The twisted relation between rdfs:Class and rdfsClass, that is, rdfs:Class is a super
class and an instance of rdfsClass produces a trick of (cl:typep rdfs:Class rdfs:Class).
Note that every method defined at rdfs:Class affects rdfs:Class itself. Therefore, the
world is closed by the membership loop of rdfs:Class just like cl:standard-class in CLOS.
The twisted relation between rdfs:Resource and rdfs:Class yields semantics of RDFS, that is,
(cl:typep rdfs:Resource rdfs:Class) and (cl:typep rdfs:Resource rdfs:Resource).
The method class-direct-instances, which maintains direct instances of a class, is
inherited to rdfs:Class and rdfsClass. So, subclasses of rdfs:Resource and rdfs:Class,
including rdfs:Class itself can hold their instances.
First of all,
We make skeltons that provide subtyping and metaclassing.
rdfsClass & rdfs:Class
rdfsClass is invented in order to realize the rdfs:Class membership loop. Namely, the class of
rdfs:Class is rdfs:Class itself in RDF(S) semantics. In SWCLOS rdfs:Class is actually the
class of rdfs:Class, because rdfs:Class is a superclass of rdfsClass and rdfsClass is a class of
rdfs:Class. Thus, all methods are for instances of rdfs:Class is effective for rdfs:Class itself.
This is the proxy of rdfs:Class in order to make the membership loop. |
rdfs:Resource
At initial stage of booting, kernel classes are defined without slots to let class-changing easy.
Every resource in RDF(S) universe including classes is an instance of
rdfs:Resource. |
This is rdfs:Class, and it is a class of all classes in RDF(S) universe. |
This is rdfs:Class and it is a class of all classes in RDF(S) universe. |
rdfs:Resource is the top class in the RDF universe, but subclass of gnode actually. |
OK. The minimal skelton is completed.
Pseudo class of rdfs:Resource is defined.
In order to work around wasteful slot definitions during forward-referencing, we invented a trick
of setting pseudo class of rdfs:Resource. If there would be no information on a forward-referenced
object, the object is defined as an instance of |rdfs:Resource| rather than rdfs:Resource.
Or else, when a slot would be demanded to a tentatively created object in forward-referencing,
it would causes the slot definitions at rdfs:Resource. Then, when a proper definition comes up,
the slot definitions would be created at the proper class. As a result, rdfs:Resource would
become to have wasteful slot definitions for many objects in the universe. To work around this
phenomenum, |rdfs:Resource| is used instead of rdfs:Resource in forward-referencing.
|rdfs:Resource| prevents to create wasteful slots at rdfs:Resource instances.
|rdfs:Resource| is a pseudo rdfs:Resource in order to work around the slot inheritance of temporal definition.
The rule of rdf4 entails a subject and an object as an instance of rdfs:Resource. However the proactive application of
this rule causes the slot definition inheritance to the instances of rdfs:Class and rdfs:Datatype and amounts to
wasteful slots in every objects. To cope with this problem, rdf4 treats |rdfs:Resource| metaobject instead of
rdfs:Resource. |
Then, we proceed slot definitions.
mop:direct-slot-definition-class returns a direct slot definition class for target class.
This method is customized to return an appropriate slot definition class in SWCLOS, i.e.,
Property-direct-slot-definition or OwlProperty-direct-slot-definition. Namely, if an
indicator in initargs is not a keyword, it must be a property name. The name of rdf, rdfs,
and owl propertes are embeded in this routine. In other case, if the domain includes 'owl:Restriction',
then Property-direct-slot-definition is returned. If the property is an instance of 'owl:ObjectProperty',
then OwlProperty-direct-slot-definition is returned, else if the defalut value is returned.
If initargs include non-keyword indicators for slot initarg or include a property name as slot name,
then returns Property-direct-slot-definition or OwlProperty-direct-slot-definition metaobject. |
How to Compute a Type Value in Effective Slot Definition
Since the function of gx:subtypep in RDF is the same as that of cl:subtypep, the
computation of type option in compute-effective-slot-definition-initargs for excl::std-class is
also useful for the effective slot definition for rdf properties. Note that the ACL original
algorithm for type value collection collects the type value in direct-slot-definitions at every
superclass of the target class, and makes the conjunction of them. See the following example.
(defclass C1 () ((s :type cl:number)))
(defclass C2 (C1) ((s :type cl:float)))
(defclass C3 (C1) ((s :type cl:integer)))
(defclass C4 (C3) ((s :type cl:fixnum)))
(defclass C5 (C4 C2) ())
(mop:slot-definition-type (first (mop:compute-slots (find-class 'C5))))
-> (and float fixnum)
This computational result by native routine of ACL is sound, if members of conjunct are not
disjoint each other, whereas it might be not minimal expression as conjunction, since ACL does
not reduce the result such as conjunctive normal form (CNF). However, if you take care of the
disjointness between cl:float and cl:fixnum, then such result will make no sense. In SWCLOS, the
notion of disjointness is taken care for not only OWL universe but also RDF universe. In
SWCLOS, the clash by disjointness is directed as follows.
(defConcept C1 (rdfs:subClassOf (owl:Restriction (owl:onProperty s)
(owl:allValuesFrom xsd:decimal))))
(defConcept C2 (rdfs:subClassOf (owl:Restriction (owl:onProperty s)
(owl:allValuesFrom xsd:float))))
(defConcept C3 (rdfs:subClassOf (owl:Restriction (owl:onProperty s)
(owl:allValuesFrom xsd:integer))))
(defConcept C4 (rdfs:subClassOf (owl:Restriction (owl:onProperty s)
(owl:allValuesFrom xsd:short))))
(defConcept C5 (rdfs:subClassOf C4 C2))
(mop:slot-definition-type (car (mop:compute-slots C5)))
-> Error: Disjoint pair #<forall s xsd:short> and #<forall s xsd:float> found in slot
inheritance computation of #<rdfs:Class C5>.
In this imlementation of compute-effective-slot-definition-initargs in SWCLOS,
we let the native CLOS routine compute the type option.
After the computation for CLOS native effective slots definition, the subject-type option is
filled with the value of class parameter in compute-effective-slot-definition-initargs.
However, compute-effective-slot-definition-initargs is redefined in OWL module.
In OWL system, the satisfiability among conjunctions in type option is checked.
See compute-effective-slot-definition-initargs in OWL system.
If initargs in making an effective-slot-definition includes :subject-type keyword, the slot-definition must be
Property-effective-slot-definition. So, mop:effective-slot-definition-class methods returns the class metaobject.
Then, CLOS system takes care of all after.
Hierarchy and Relation around Property
An rdf property is an instance of rdf:Property. An rdf property as rdf-object has a slot
property-slotds for book-keeping, which holds a list of slot definitions on the property
(e.g., eslotd1, eslotd2 eslotd3 for rdfs:label, see below). Each slot definition keeps a class of
subjective object in subject-type option. Therefore, we can retrieve every triples with
respect to a property (called the extension of property). The object in triple is obtained by
accessing slot value to the object with the predicate (slot-name) in the triple.
rdfs:Resource ---------------------------------- rdf:Property
:
ex. rdfs:label
|
Property-effective-slot-definition | <-- property-slotds
:.....................................|....
| :
+-(eslotd1 eslotd2 eslotd3)
|
| <-- subject-type
|
<a class which this eslotd is attached>
Note that the domain and range of owl:equivalentProperty is rdf:Property rather than
owl:ObjectProperty.
every property in RDF(S) is an instance of rdf:Property. An instance of this class
has a place holder for all related slot definitions. |
rdfs:Class final
rdfs:Class is reinitialized with slots.
I thank smh for teaching me to use 'reinitialize-instance'.
rdfs:Datatype
rdfs:Datatype is a subclass of and an instance of rdfs:Class. |
rdfs:Literal & rdf:XMLLiteral
rdfs:Literal is a subclass of rdfs:Resource and an instance of rdfs:Class. |
rdf:XMLLiteral is a subclass of rdfs:Literal and an instance of rdfs:Datatype.
An instance has a value of XMLLiteral data. |
retrieves a value of XMLLiteral data. |
otherwise returns itself. |
rdfs:Resource final
rdfs:Resource is reinitialized with slots.
rdf:List
rdf:List is a subclass of rdfs:Resource and an instance of rdfs:Class. |
rdf:Property
Now, here many properties are defined.
may be used to provide a human-readable version of a resource's name. |
may be used to provide a human-readable description of a resource. |
is used to indicate a resource defining the subject resource.
This property may be used to indicate an RDF vocabulary in which a resource is described. |
is used to state that any resource that has a given property is an instance of one or more classes. |
is used to state that the values of a property are instances of one or more classes. |
is used to state that all the instances of one class are instances of another. |
is used to state that all resources related by one property are also related by another. |
Seiji Koide Nov-15-2010
GX Type module
IT Program Project in Japan:
Building Operation-Support System for Large-scale System using IT
This code is written by Seiji Koide at Galaxy Express Corporation, Japan,
for the realization of the MEXT IT Program in Japan.
Copyright (c) 2002-2005 Galaxy Express Corporation
Copyright (c) 2007-2008, 2009 Seiji Koide
RDF Type Error Condition
Followings are for type error message.
rdf-type-error inherits data variables and expected-type variables and
type-error-datum and type-error-expected-type readers.
format-control and format-arguments are from simple-condition. |
Cyclic super/subclass relation is not supported in CLOS. |
Non-Unique Name Assumption and Equality
In Semantic Webs, the non Unique Name Assumption (nonUNA) is adopted in principle.
Namely, two and more different names or URIs may denote same object in the universe. It is
just like as people often call a person by both name and nickname. However, it is, so far,
unusual and not adopted in ordinary computer languages. In complete nonUNA principle, we would fall
into troublesome situation. For example, the computation could not conclude that (rdf:Description ex:A)
and (rdf:Description ex:B) are different or a triple ex:A/ex:p/1 is different from ex:B/ex:p/1.
The ex:A and ex:B might denote the same thing in RDF universe, and two graphs might mean same
meaning in the world. We need very laborious work in nonUNA principle to describe common knowledge
such as ex:Automobile is different from ex:Train, ex:Airplane, and ex:Ship. We must state that
xsd:float is different from xsd:integer, xsd:URI, xsd:string, xsd:boolean, etc. for all terms in ontology.
Therefore, we set up the flag for non Unique Name Assumption false as default. Namely,
if two names or URIs are different, then the two bound objects must be different. When you
want to set the nonUNA principle up in program, encode like below.
(let ((*nonUNA* t))
... some codes for nonUNA ...
)
Note that if two names or URIs are identical then they denote and are bound to an identical object
in spite of the value of *nonUNA*. Note also that, for anonymous objects, the graph structures of
objects must be compared in spite of the value of *nonUNA*. If two graphs for anonymous objects
are equal, then they are equal in RDF semantics. So, the question of equality is how to treat
the equality of named objects which have different names when the value of *nonUNA* is true.
In this implementation,
- if two objects are atomic, namely no graph structure or no slot on rdf properties,
if two objects have different names, then they are not equal in spite of the value of *nonUNA*.
if two objects are atomic and anonymous, then they are inevitably equal in spite of the value of *nonUNA*.
- if two objects are not atomic, namely they have composed structure or slots on rdf properties,
they are equal if their structure is equal else not equal in case that the value of *nonUNA* is true.
The name of complex objects are ignored when the value of *nonUNA* is true.
Note that this implementation has no effects yet on owl:equivalentProperty. In SWCLOS,
every property must be named and different names must not be identical in equality checking.
Note that even though *nonUNA* is true or false, owl:sameAs and owl:differentFrom conduct SWCLOS and affect the
computation of equality in OWL.
Note that owl:equivalentClass affects the computation of subsumption in OWL but does not affect the equality as
object or individual. See details in OWL module.
Note that owl:disjointWith affects the computation of subsumption in OWL. Two concepts disjoint each other are
also different as object or individual. See details in OWL module.
A flag for non-UNA, it is false as default. Namely, the logic does not obey nonUNA as default.
In order to set up complete nonUNA for Semantic Webs, set this value true.
Caution: we have seldom experienced on *nonUNA* = true. |
Algorithm of Equality in RDF Universe
The algorithm of equality in RDF is described as follows, See RDF Primer specification from W3C, and
http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#section-Literal-Equality.
- Two plane literals (string) without language tags are equal, if and only if they compare as equal,
character by character.
- Two plane literals with language tags are equal, if and only if the language tags are equal character
by character without case sensitivity and the strings are equal character by character by case sensitivity.
- Two RDF URI references are equal, if and only if they compare as equal, character by character,
as Unicode strings.
- Two plane literals as integer are equal, if and only if they are equal as mapped value in value space.
- Two typed literals (xsd:anySimpleType) are equal, if and only if datatype URIs are equal and mapped values
are equal in value space.
Therefore, in this implementation
- If x and y are equal as lisp object (integer, string, URI, symbol, CLOS object, etc.),
then both are equal in RDF.
- If x and y are instances of any datatype (xsd:anySimpleType), both are equal if both data types are
equal and both values are equal.
- If x and y are named CLOS objects, if both have a same name, then both are equal in RDF.
If both have different names, the both are not equal when *nonUNA* is false, or the graph equality is
checked when *nonUNA* is true.
- If x and y are anonymous CLOS objects, the graph equality is checked.
- If at least one of x and y is an anonymous object then graph equality is checked.
- If either x and y are URI or symbol and the relevant CLOS object exists as value,
then the object is taken and recursively tested.
- If either x and y are URI or symbol and no relevant CLOS object, then both are not equal.
- If x and y are instances of rdf:inLang (literal with language tag), both are equal if both tags are
equal without case sensitivity and the strings are equal with case sensitivity.
To test the equality in semantics of RDF, rdf-equalp is available. See the following example.
(rdf-equalp "this is string." "this is string.") -> true
(rdf-equalp "string" "string"@en) -> false
(rdf-equalp "wine"@en (@ "wine" "EN")) -> true
(rdf-equalp 1 1.0) -> true
(rdf-equalp 1 "1"^^xsd:integer) -> false
(rdf-equalp "1"^^xsd:integer (^^ 1 xsd:integer)) -> true
(rdf-equalp "1"^^xsd:integer (^^ 1 xsd:nonNegativeInteger)) -> false
(rdf-equalp (iri "http://somewhere") (iri "http://somewhere")) -> true
(rdf-equalp (iri "http://somewhere") (iri "http://some%20where")) -> false
(rdf-equalp 'foo 'bar) -> false
(defIndividual foo) -> #<|rdfs:Resource| foo>
(defIndividual bar) -> #<|rdfs:Resource| bar>
(rdf-equalp foo bar) -> false
(let ((gx::*nonUNA* t)) (rdf-equalp foo bar)) -> false
However, if uris are bound to anonymous object, this predicate changes the result,
because SWCLOS retrieves the bound values by resolution, and compares two anonymous
objects.
(rdf-equalp <http://somewhere> <http://anotherplace>) -> false
(setf (iri-value <http://somewhere>)
(addForm '(rdf:Description ))) -> #<|rdfs:Resource| :anonymous>
(setf (iri-value <http://anotherplace>)
(addForm '(rdf:Description ))) -> #<|rdfs:Resource| :anonymous>
(rdf-equalp <http://somewhere> <http://anotherplace>) -> false
(let ((*nonUNA* t))
(rdf-equalp <http://somewhere> <http://anotherplace>)) -> true
At the last case above, in nonUNA condition, two bound values are compared.
Then, two anonymous rdf-object are equal as graph structure, whereas the URIs are
different.
Note that the reader macro '<' gives URI.
this is not revolve version of rdf-equalp. |
returns true if x and y is equal in the semantics of RDF(S).
This function resolves syntactical difference among symbol, uri, and object identification.
This function uses rdf-graph-equalp internally. |
This is supplied as a hook for the eqaulity in OWL system. In this RDF module,
it is same as rdf-equalp. This is overloaded when OWL system is loaded. |
Hook for OWL. In RDFS module. |
Non resolution version. This is used in owl-equalp and owl-equivalent-p. |
Equivalency as Class
owl-equivalent-p tests equivalency as class. Namely, the equivalent two object have
the same class extension, even if the both is not equal as class individual.
However, if two objects are equal as class individuial, then the both are equivalent as class.
This is a hook for OWL. In RDFS module, same as rdf-equalp. |
returns an ordinal property symbol like 'rdf:_n' to which an instance of
rdfs:ContainerMembershipProperty is bound. |
container is an instance of rdfs:Container. This function retrieves all members in container,
and returns a list of them. |
This function is effective for instances of rdf:Bag, rdf:Alt, rdf:Seq, rdf:List, and blank nodes.
For rdf:Bag, both member values of x and y are compared as set. For rdf:Alt, two first member value and two set
of rest member values are compared. For rdf:Seq, two member values are compared as sequence. In other
cases, each value is compared with each slot name. |
x and y must be clos objects but may be anonymous. |
Disjointness
CLOS classes are pairwise disjoint in ANSI Common Lisp, unless they have a common subclass
or one class is a subclass of the other. This agreement is supported by the premise that an
object in CLOS is typed to only one class. In the RDF universe, an entity can be typed to
multiple classes. So, the nature of disjointness in CLOS is not applicable in the RDF
universe. However, in SWCLOS, the pseudo multiple-classing is implemented by the special
mechanism called shadowed-class using CLOS class and metaclass mechanism. Therefore, from
the viewpoint of CLOS, the algorithm of disjointness for CLOS is also applicable in the RDF
universe in the virtue of CLOS.
See also the explanation in OWL module.
returns true if c and d are disjoint in OWL. |
checks disjointWith constraint of c1 against c2 and its subclasses. |
returns all subclasses of class but class itself.
Note that this function uses only mop:class-direct-subclasses. |
Subtypep Utilities
returns true if CLOS metaobject c1 eql c2 or c1 is a subtype of c2
using the class precedence list (cpl) of c1. This is more efficient than (subtypep c1 c2)
when c1 and c2 are CLOS objects. |
same as (subtypep class rdfs:Resource) in CLOS, but more efficient. |
same as (subtypep class rdfs:Class) in CLOS, but more efficient. |
Forall, Exists, and Fills for Slot Definition Type Option
In addition to concepts (classes) of RDFS and OWL, following CLOS classes may be
set into the type option of slot definition objects and used in subsumption computation
between slot-type-constraints in subsumees and restrictions in subsumers.
This is the top abstract constraint for slot type constraints.
A subclass of this class is a metaclass. |
To compare slot-type-constraints with t (which is supplied by system as default type option)
using cl:subtypep in the standard protocol of mop:compute-effective-slot-definition,
we needed slot type constraints as type or class, or else the default value t remains in
the type slot option together with slot type constraints. So, we needed following metaclasses
to create type slot constraints as class so as to eliminate t from type options in slot definitions.
type slot constraint metaclass for universal value constraints |
type slot constraint metaclass for full existential constraints |
type slot constraint metaclass for filler constraints |
Subtyping from Slot Type Option
From range constraints, C(y) comes up as this role extension R(x,y), here x is subjective object, and x is slot value.
From allValuesFrom, R(x,y)->C(y) comes up as this role extension R(x,y).
From someValuesFrom, R(x,y)^C(y) comes up as this role extension R(x,y).
From hasValue, R:b, R(x,b) comes up as this role extension R(x,b).
returns true if c1 is a supertype of c2 in CLOS but not equal. |
transforms any element in tree x to rdf object from QName symbol and uri, if possible. |
Subtypep in Semantics of RDF(S)
To test rdfs:subClassOf relation including the transitivity, use rdf-subtypep for RDF(S) semantics.
Note that the counterpart of rdf-subtypep in OWL semantics is subsumed-p.
Note that cl:subtypep in Common Lisp returns two values, e.g., value1 and value2.
If value1 is true, then value2 is definitely true. So, a pair <t nil> never happens.
The following table is taken from ANSI Common Lisp specs.
value1 value2 meaning
---------------------------------------------------------------------
true true type1 is definitely a subtype of type2.
false true type1 is definitely not a subtype of type2.
false false subtypep could not determine the relationship,
so type1 might or might not be a subtype of type2.
---------------------------------------------------------------------
See, http://www.franz.com/support/documentation/8.1/ansicl/dictentr/subtypep.htm
We carry out this semantics in subtypep, rdf-subtypep, and subsumed-p.
We capture <true true> is true value (expressed as T), <false true> is false value (expressed as F),
and <false false> is unknown value (expressed as U) in RDF(S) and OWL semantics.
subtype relation in RDF(S) is equivalent to CLOS except URIs and QName symbol resolution.
Therefore, after resolving URIs and QNames this function calls cl:subtypep. |
This is a hook for OWL. It is same as rdf-subtypep in RDFS. |
Function subtypep produces same logic as CLOS. However, in OWL semantics, it is wrong in reality.
More precisely, CLOS adopts Unique Name Assumption and do not have the explicit notion of disjointness.
Thus, if two classes are independent (not in relation of super-sub classes), then they seems to be disjoint.
However, if concept C and (not D) is compared in Allegro Common Lisp, ACL tends to fall into conclusion unknown.
It seems that CLOS does not have clear semantics on class extension. In RDF semantics,
every entity is a member of RDF universe, then the complement of xsd:integer or (not xsd:integer) extends out
of xsd:integer extension and xsd:decimal in RDF universe. For example, an instance of vin:Wine is not an
instance of xsd:integer. Therefore, it is obvious that (not xsd:integer) is not a subclass of xsd:integer and
xsd:decimal. However, cl:subtypep does not infer it (at least for ACL).
Furthermore, we have notions of equivalency and disjointness on class relation in OWL.
Therefore, the equivalency and disjointness must be checked in addition of super-sub class relation.
Specifically, if SWCLOS cannot infer two concepts are in relations of rdfs:subClassOf (and owl:intersectionOf,
owl:unionOf in OWL), then the relation of owl:equivalentClass, owl:disjointWith, owl:complementOf, owl:sameAs,
owl:differentFrom must be checked. Function subsumed-p returns unknown value only if there is no information of
super-sub class relation, equality, and disjointness. See subsumed-p in OWL module.
To compute rdf-subtypep and subsumed-p, which takes care of unknown,
the following ternary truth table is used for T, F, and U.
Ternary Truth Table
----------------------
conjunction
| T U F
---+-------------- e.g.,
T | T U F True ^ Unknown => Unknown
U | U U F
F | F F F False ^ Unknown => False
disjunction
| T U F
---+-------------- e.g.,
T | T T T True v Unknown => True
U | T U U
F | T U F False v Unknown => Unknown
negation
x | T U F
----+-------------- e.g.,
~x | F U T ~Unkonw => Unkown
The following table shows rewriting rules for inclusiveness.
Where '<' stands for subtype relation. '^' means conjunction and 'v' means disjunction.
C < (A ^ B) <=> (C < A) ^ (C < B)
C < (A v B) <=> (C < A) v (C < B)
(A ^ B) < C <=> (A < C) v (B < C)
(A v B) < C <=> (A < C) ^ (B < C)
(A v B) < (C ^ D) <=> (A < C) ^ (A < D) ^ (B < C) ^ (B < D)
(A ^ B) < (C v D) <=> (A < C) v (A < D) v (B < C) v (B < D)
(A ^ B) < (C ^ D) <=> ((A < C) ^ (A < D)) v ((B < C) ^ (B < D))
(A v B) < (C v D) <=> ((A < D) v (A < D)) ^ ((B < C) v (B < D))
~A < ~B <=> B < A
rdf-subtypep has almost same logic as subtypep but it is only different with
respect to known/unknown. See following example.
(rdf-subtypep xsd:long xsd:decimal) -> <t t>
(subtypep xsd:long xsd:decimal) -> <t t>
(rdf-subtypep `(not ,xsd:long) xsd:decimal) -> <nil t>
(subtypep `(not ,xsd:long) xsd:decimal) -> <nil nil>
(rdf-subtypep xsd:decimal `(not ,xsd:long)) -> <nil t>
(subtypep xsd:decimal `(not ,xsd:long)) -> <nil nil>
In this example, xsd:long is subsumed by and not equal to xsd:decimal. Therefore,
there is the intersection between xsd:long and xsd:decimal.
The complement of xsd:long extends over the boundary of xsd:decimal, then the extension
of (not xsd:long) is not included by the extension of xsd:decimal, and the extension of
the intersection between xsd:long and xsd:decimal is not included by (not xsd:long).
Function rdf-subtypep obeys the set-theoretic semantics of RDF(S), but subtypep does not follow
the semantics of RDF(S) exactly. Even so, there is no difference between both, if only the
first value is used in program.
returns true if type1 is subsumed by type2 in the sense of RDF(S).
URIs and QName symbols are acceptable and resolved into resource objects.
Instances of Datatypes are also acceptable. |
same as rdf-subtypep but type1 and type2 must be an RDF object or cons. |
Most Specific Concepts (MSCs)
Function most-specific-concepts is used to compute the most specific concepts among classes.
For example, xsd:integer is a superclass of xsd:int, and xsd:nonNegativeInteger is a superclass
of xsd:positiveInteger, then those superclasses disappear in the most specific concepts among them.
(most-specific-concepts
(list xsd:integer xsd:int xsd:positiveInteger
xsd:nonNegativeInteger xsd:unsignedInt))
-> (#<rdfs:Datatype xsd:unsignedInt> #<rdfs:Datatype xsd:positiveInteger>
#<rdfs:Datatype xsd:int>)
returns the most specific concepts in RDF(S) and OWL semantics, or classes minus duplicates
and superclasses of other classes in classes. This function internally uses subsumed-p and
owl-equivalent-p. Note that this function does not check disjointness of classes.
subsumed-p is equal to rdf-subtypep, owl-equivalent-p is same
as rdf-equalp in RDF(S) module. Then, OWL module overwrites them.
This function allows |rdfs:Resource|, a temporal alternative of rdfs:Resource, and can accepts
cons concepts as class. This function is taken from Memory Organization Package by Schank. |
returns the most abstract concepts in RDF(S) semantics, or classes minus duplicates and subclasses
of other classes in classes. |
Is abst strictly (not equal to) superclass of spec? |
Is spec strictly (not equal to) subclass of abst? |
same as most-specific-concepts but uses clos-strict-supertype-p instead of strict-abstp. |
same as most-specific-concepts but uses clos-strict-supertype-p instead of strict-abstp. |
same as most-specific-concepts but understand forall, exists, and has in addition to subtypep.
This is used for slot type reduction. If subtype relation is unknown, then the two remains in the list. |
Miscellaneous Utilities for Typing
returns true if x is an RDF(S) metaclass, class, instance object, and xsd typed data, and not lisp data. |
returns true if x is an RDF(S) metaclass and class object. |
returns true if x is an RDF(S) metaclass resource object. |
returns true if x is an RDF(S) class but not a metaclass. |
returns true if x is an instance of rdfs:Resource but not rdfs:Class.
This returns true if x is a lisp string, a list number, a uri. |
when x is a CLOS object, if x is an instance of rdfs:Resource but not rdfs:Class, this returns true,
otherwise nil. |
Does this symbol denote an instance of rdfs:Datatype? |
Is obj an instance of rdfs:Datatype? |
returns true if x is an instance of rdf:Property. |
returns true if x is an instance of rdf:Property. x must be a CLOS object. |
returns true if name is a symbol that has a value of an RDF(S) metaclass resource
object. If name is not a symbol an error is signaled. |
returns true if name is a symbol that has an RDF(S) metaclass, class,
and instance object. If name is not a symbol an error is signaled. |
returns true if name is a symbol that has an RDF(S) metaclass, class,
and instance object. If name is not a symbol an error is signaled. |
returns true if name is a symbol whose symbol value is an instance of
rdf:Property. If name is not a symbol an error is signaled. |
Subsumption on Property
returns true if subprop is a sub-property of superprop or
superprop itself. Otherwise returns nil |
returns true if subprop is not equal to and subproperty of superprop. |
Type System
Lisp types are mapped to RDF(S) types as shown in the table below.
If you want to use the Lisp nature typep and type-of, use cl:typep and cl:type-of.
Lisp RDF(S)
--------------------------------------
null rdfs:List
cons rdfs:List
uri xsd:anyURI
symbol <type of symbol's value>
string xsd:string
fixnum xsd:byte, xsd:short, xsd:int
bignum xsd:int, xsd:long, xsd:integer
inLang rdf:XMLLiteral
<a shadowed-class> names of multiple classes
<a resource> cl:type-of value
rdfs:Class rdfs:Class
<others> cl:type-of value
--------------------------------------
Example
(type-of 32767) => xsd:short
(type-of 2147483647) => xsd:int
(type-of 9223372036854775807) => xsd:long
(type-of "string?") => xsd:string
(type-of "Literal?"@en) => rdf:XMLLiteral
(type-of ()) => rdf:List
(type-of '(a b c)) => rdf:List
(type-of xsd:true) => rdf:boolean
(type-of rdfs:label) => rdf:Property
(type-of rdf:Property) => rdfs:Class
(type-of rdfs:Class) => rdfs:Class
extended version of cl:type-of function for RDF(S) and OWL.
This function returns type(s) of x as symbol. See above example. |
Type Predicate
Type predicate typep is an extension of cl:typep for RDF(S) and OWL.
The algorithm of the type predicate is described below. Here, a is an argument for
instance, c is an argument for class. I(a) means a resolved CLOS object for a against URI,
QName, and object itself, I(c) also means a resolved CLOS object for c. Namely, I(a) and
I(c) are interpreted and tested as CLOS object. Note that T or true is expressed by two values
<t t>, F(alse) is expressed by two values <nil t>, and U(nknown) is expressed by two values
<nil nil>.
- If c is t, returns T.
- If c is nil, returns F.
- If a is nil, returns T.
- If c is an instance of rdfs:Resource,
- If a is an instance of rdfs:Resource, then calls %type with a and c.
- If a can be resolved, then calls %type with I(a) and c.
- else calls %type with a and c.
- If c is not an instance of rdfs:Resource,
- If c can be resolved, then recursively calls with a and I(c).
- If c is a list and logic form, then returns truth value according to the ternary table.
- else calls %type with a and c.
Here is the algorithm of subfunction %typep.
- If c is an instance of rdfs:Class,
- If a is an instance of rdfs:Resource,
* If (cl:typep a c) is true, then returns T.
* If (cl:typep c a) is true, then returns F.
* Else returns the value of (%%typep a c).
- If c is an instance of rdfsClass, it implies c is rdfs:Class, then
- if a is rdfs:Class, then retursn T.
- if (cl:typep a c) is true, then returs T, else returns F.
- If c is an instance of rdfs:Resource, it implies a strict instance, so returns F.
- Otherwise returns U.
%%typep works for an rdf object and a class as follows.
Here C stands for equivalent classes of c including c itself.
- If for some c of C (%typep-without-type-equivalents a c), then returns T. Otherwise returns F or U
according to the accumulation of each equivalent class of C.
%typep-without-type-equivalents works for an rdf object and a class as follows.
Note that A stands for same objects of a including a itself.
- If for some a of A (typep-without-sames-and-equivalents-in-owl a c), then returns T.
Otherwise returns F or U according to the accumulation of each same object of A.
typep-without-sames-and-equivalents-in-owl works as follows.
- If c is an intersection of concepts, returns the result of owl-intersection-type-p for the intersections.
- If c is an union of concepts, returns the result of owl-union-type-p for the unions.
- If c is an complement concepts, returns the result of owl-complement-type-p for the complement.
- If *autoepistemic-local-closed-world* is true, returns F else returns U.
Examples of xsd data types
(typep 1 xsd:positiveInteger)
(typep -1 xsd:negativeInteger)
(typep 0 xsd:nonNegativeInteger)
(typep 0 xsd:nonPositiveInteger)
(typep 32767 xsd:short)
(typep 32768 xsd:int)
(typep 2147483647 xsd:int)
(typep 2147483648 xsd:long)
(typep 9223372036854775807 xsd:long)
(typep 9223372036854775808 xsd:integer)
(typep 1 xsd:decimal)
(typep (cl:rational 1.0) xsd:decimal)
(typep 1.0e0 xsd:float)
(typep 1.0d0 xsd:double)
(typep "string?" xsd:string)
(typep "string?"@en xsd:string)
(typep (net.uri:uri "http://somewhere") xsd:anyURI)
(typep xsd:false xsd:boolean)
(typep 1 xsd:anySimpleType)
(typep 1 rdf:XMLLiteral)
(typep "1"^^xsd:positiveInteger xsd:positiveInteger)
(typep "1"^^xsd:positiveInteger xsd:anySimpleType)
(typep "1"^^xsd:positiveInteger rdf:XMLLiteral)
Examples of Literals
(typep 1 rdfs:Literal)
(typep 1 rdfs:Resource)
(typep "1"^^xsd:positiveInteger rdfs:Literal)
(typep "1"^^xsd:positiveInteger rdfs:Resource)
(typep "subway"@en rdf:XMLLiteral)
(typep "subway"@en rdfs:Literal)
(typep rdfs:label rdf:Property)
Examples of Others
(typep (list 1 2 3) rdf:List)
(typep 1 (list 'and xsd:integer rdf:XMLLiteral))
(typep 1 (list 'or xsd:integer xsd:float))
(typep rdf:Property rdfs:Class)
(typep rdfs:Class rdfs:Class)
(typep rdfs:label rdfs:Resource)
(typep rdf:Property rdfs:Resource)
(typep rdfs:Class rdfs:Resource)
typep object type |
[function] |
---|
extended typep function for Semantic Web. This function resolves the difference among
URI, QName, and object for parameters. Namely, if a parameter is URI or symbol, then
the related CLOS object is taken to test it. |
object and type is an object in RDF universe. |
Hook for OWL. See OWL module. |
type is a CLOS object including rdfs:Literal including datatypes (instances of rdf:Datatype).
Note that this subfunction is invoked with type that is a CLOS class. |
Negation Normal Form (NNF)
NNF is a logical form in which negation is applied to only logical atom.
In the following routine, non-NNF should be a prefix form in S-expression.
<form> ::= <atom> | (not <form>) | (and <form>*) | (or <form>*) |
(forall <var> <form>*) | (exists <var> <form>*) | (fills <var> <form>)
<NNF> ::= <atom> | (not <atom>) | (and <NNF>*) | (or <NNF>*)
(forall <var> <NNF>) | (exists <var> <NNF>) | (fills <var> <NNF>)
Ex.
(->nnf '(not (and (not (or (not A) (and C (not D)))))))
-> (or (not A) (and C (not D)))
transforms non-NNF S-expression P to NNF and returns it. |
This program is borrowed from AIMA
Note that move-not-inwards returns ~P for P.
Given P, return ~P, but with the negation moved as far in as possible. |
Form a conjunction with these args. |
Form a disjunction with these args. |
makes a form of op and args. |
Operator of an expression |
Arguments of an expression |
Domain and Range module
IT Program Project in Japan:
Building Operation-Support System for Large-scale System using IT.
This code is written by Seiji Koide at Galaxy Express Corporation, Japan,
for the realization of the MEXT IT Program in Japan.
Copyright 2002-2005 Galaxy Express Corporation
Copyright (c) 2007 Seiji Koide
Unsatisfiable Error
Top Class rdfs:Resource and Top Metaclass rdfs:Class
In the RDF universe, the top class, that is a superclass of every class, is rdfs:Resource.
The top metaclass, that is a class of every class, is rdfs:Class.
Note that the direct class of rdfs:Class is (virtually) rdfs:Class (actually rdfsClass in lisp),
but the superclass of rdfs:Resource is (virtually) null (actually gx::gnode in lisp).
In our OWL connection to RDF, the OWL universe is included into and inherites characteristics from
the RDF universe. The top concept is rdfs:Resource and the top meta concept is rdfs:Class in
the OWL universe, too.
The top concept, i.e. rdfs:Resource in RDFS, and in OWL, too. |
The top meta-object, i.e. rdfs:Class in RDFS, and in OWL, too. |
Domain Value
retrieve the domain value of property, or returns nil if not exists.
Note that this method is refined for owl:ObjectProperty. |
returns a list of domains for property or null list. |
returns domain of property or nil. This function searches the super-properties and
returns the most specific domain. |
collects domain information from properties. A property must be a symbol.
If anyone in properties is not defined, this function executes rdf1 entaiment rule. |
returns true if property's domain is a subclass of domain, or if
some of property's super-properties has a subclass domain of domain. |
Range Value
retrieve the range value of property, or returns nil if not exists.
This method is refined for owl:ObjectProperty. |
returns a list of ranges for property or null list. |
returns range of property or nil. This function searches the super-properties and
returns the most specific range. |
collects range information from properties. A property must be a symbol. |
rangep property range |
[function] |
---|
returns true if property's range is a subclass of range, or if
some of property's super-properties has a subclass range of range. |
Is every domain satisfied? |
checks class for domain constraint, if class violates the constraint,
entailment is invoked as much as possible. This function returns either class or domain. |
checks instance for domain constraint, if instance violates the constraint,
entailment is invoked as much as possible. |
checks value for range constraint, if value violates the constraint,
entailment is invoked as much as possible. Otherwise error caused.
This function returns value.
NOTE. this function does not infer on oneOf information. This is important
for establishing oneOf entailment. |
RDFS Objects module
IT Program Project in Japan:
Building Operation-Support System for Large-scale System using IT.
This code is written by Seiji Koide at Galaxy Express Corporation, Japan,
for the realization of the MEXT IT Program in Japan.
Copyright 2002-2005 Galaxy Express Corporation
Copyright (c) 2007 Seiji Koide
Shadow Class
When an object belongs to multiple classes, SWCLOS sets up a class that has the multiple classes in superclass list,
and change the class of the object to the new class instead of multiple classes.
Such a special class is called a shadow class which is an instance of metaclass shadowed-class.
See following example in Wine Ontology.
(mclasses vin:SaucelitoCanyonZinfandel1998)
-> (#<owl:Class vin:Zinfandel> #<owl:Class vin:Vintage>)
(class-of vin:SaucelitoCanyonZinfandel1998)
-> #<shadowed-class vin:Zinfandel.34>
The shadow class for multiple classing. |
The classes of object are stored in mclasses slot of object. In mclasses slot list, every element is
not a shadow class. In order to obtain the most specific non-shadow superclass list of a class
get-mclasses-from function is used.
(get-mclasses-from (class-of vin:SaucelitoCanyonZinfandel1998))
-> (#<owl:Class vin:Zinfandel> #<owl:Class vin:Vintage>)
retrieves all superclasses of class which are not a shadow class. If a super is a shadow class,
recusively its non shadow superclasses are retrieved and collected. Note that the return value
may include duplicates or not-most-special supers. |
creates and returns a name for shadowing class from abst.
Note that 'shadow-name' is expressed as 'abst-name.nn'. If abst is null,
the first class in mclasses that has name is used instead. |
changes old-class to a shadow class with mclasses as superclasses and returns it.
Note that this function does not make a new shadow class, if mclasses of old-class
is a same set to mclasses or if some of subclasses of someone of mclasses is a
same set to mclasses. |
class-direct-instances are maintained by update-instance-for-different-class:after(gnode).
Therefore, old-class is cleared when it falls here.
This function is used for class refining for an instance. So, we treat only rigid classes.
classes must be clos objects. |
Properties Final
is used to indicate a resource that might provide additional information about the subject resource. |
is used to state that a resource is an instance of a class. |
is used to state the predicate of a statement. |
is used to state the subject of a statement. |
is used to state the object of a statement. |
It is intended to represent the class of RDF statements.
An RDF statement is the statement made by a token of an RDF triple. |
rdfs:Datatype and rdf:XMLLiteral
This method is not intended to use by programmer. XMLLiteral data is printed as 1^^xsd:nonNegativeInteger. |
print-object (object
ill-structured-XMLLiteral) stream |
[method] |
Datatype Objects
Every RDFS datatype is defined as lisp type and RDF resource, too.
As lisp type, data as lisp object is typed as follows.
(cl:typep 1 'xsd:nonNegativeInteger)
See XML module.
As RDFS datatype, RDF resource is typed as follows.
(setq foo (^^ 1 xsd:nonNegativeInteger))
(typep foo xsd:nonNegativeInteger)
Note that excl:sub-subtypep works well on the following datatype classes
xsd:anySimpleType class object |
xsd:nonPositiveInteger class object |
xsd:negativeInteger class object |
xsd:nonNegativeInteger class object |
xsd:positiveInteger class object |
xsd:unsignedLong class object |
xsd:unsignedInt class object |
xsd:unsignedShort class object |
xsd:unsignedByte class object |
xsd:duration class object |
This method is not intended to be used by users. |
Containers in RDF
rdfs:Container, rdfs:member, rdfs:ContainerMembershipProperty,
The class of RDF containers. |
The class of RDF containers. |
Rdfs Kernel module
IT Program Project in Japan:
Building Operation-Support System for Large-scale System using IT.
This code is written by Seiji Koide at Galaxy Express Corporation, Japan,
for the realization of the MEXT IT Program in Japan.
Copyright 2002-2005 Galaxy Express Corporation
Copyright (c) 2007 Seiji Koide
MOP Programming Layer out of Three Layers in RDF(S) and OWL Definition
There are three layers for resource definition, i.e.,
(i) top level macro layer,
(ii) intermediate function/method layer, and
(iii) MOP programming layer.
The top level macro layer, which includes three macros, defConcept, defProperty, and defIndividual,
allows users to input RDF(S) and OWL entities in S-expression just in the same feeling as defining classes
or structures in lisp.
The intermediate layer composed of several functions and methods mediates inputs at the top level to the
MOP programming layer.
The MOP programming layer constitutes a bunch of MOP methods that are programmed in order to tailor
the CLOS orignal functionality to RDF(S) and OWL semantics using the Meta-Object Protocol (MOP).
This file includes (iii) the MOP programming layer.
The other layers are contained in Rdfs Core module.
Method Invocation Orders and their Procedures
The procedure of make-instance is as follows.
- make-instance:around ((eql owl:Class)), see leanOWL file
- make sure this class has owl:Thing as superclass
- make-instance:around (owl:Class), see leanOWL file
- make sure this class has owl:Thing as superclass
- make-instance:around (rdfs:Class), see RdfsCore file
- ensure slot definitions for this class, then domain constraints are also taken care
- make-instance:around (rdfsClass), see RdfsCore file
- ensure slot definitions for this class, then domain constraints are also taken care
There is no initialize-instance in this implementation.
The procedure of reinitialize-instance is as follows.
- reinitialize-instance:around (rdfs:Class)
- remove direct-slots initarg and its value, if its value is nil.
- reinitialize-instance:before (rdfs:Resource)
- after ensuring slot definitions at the class of instance, change-class if more special type(s) is derived from domain constraints
The procedure of shared-initialize is as follows.
- shared-initialize:around (rdf:Property)
- if both old and new domain/range exist, rewrite initargs with their MSC
- shared-initialize:around (rdfs:Class)
- assure the MSG for direct-superclasses, if they exist in initargs
- in redefinition, prepare all old slot difinitions and merge them with new definitions in initargs,
- shared-initialize :around (rdfsClass)
- shared-initialize:after(gnode)
- maintain mclasses slot and direct-instances slot
- shared-initialize:after (rdfs:Resource)
- book keeping for reification
- shared-initialize:after (owl:Class)
- subClassOf
- intersectionOf
- unionOf
- equivalentClass
- disjointWith
- complementOf
- shared-initialize:after (owl:Thing)
- owl:sameAs
- owl:differentFrom
- functional property maintenance
- symmetric property maintenance
- transitive property maintenance
- oneOf check
- refine instance in OWL
- shared-initialize:after (OneOf)
- shared-initialize:after(rdf:Property)
- super/sub property book-keeping
- equivalent property maintain
- define this property slot to domain, if suplied
- domain checking and range checking to every related extensions.
The rule rdfs8 indicates the default top class in triple should be rdfs:Resource.
The rule rdfs13 indicates the default data type in triple should be rdfs:Datatype.
The following methods assure rdfs8 and rdfs13 rules.
Rdfs8 rule is implemented at this method. |
Rdfs13 rule is implemented at this method. |
Class Precedence List
Shared-initialize for Property
- shared-initialize:around(rdf:Property)
- When redefining a property, if both olddomains and newdomains are exists,
the most specific concepts (MSC) are set for domain initargs, and if both oldranges and newrages are exists,
the most specific concepts (MSC) are set for range initargs. Otherwise nothing done for initargs. The next method
processes initargs regularly.
- shared-initialize:after (rdf:Property)
- When rdfs:subPropertyOf is supplied, the inverse relation is registered for book-keeping.
- When owl:equivalentPropety is supplied, the equivalent property group is maintained.
- When rdfs:domain is supplied, the direct-slot-definition for this property is added to the directed domain class.
- When rdfs:domain is supplied, the domain constraints are checked for every subject of the extension of this property.
- When rdfs:range is supplied, the range constraints are checked for every object of the extension of this property.
After regular processing, property specific procedure is processed here, i.e., book-keeping for
super/sub relation maintenance, the equivalent property group maintencne, adding slot definition to
the domain class, and finally constraint propergation of domain and range constraints. |
puts this property into the subproperty slot of super property. |
This is hook for OWL module. See equivalentProperty-maintain in OWL module. |
Slot Attaching Functions
add the direct slot definitions to new domains from initargs for this property definition. |
does this domain has directly the slot definition of this role? |
Shared Initialize for rdfs:Resource
When any setting value in initargs is already set in the existing slot, it is eliminated from
initargs. This is for supressing meaningless redefining messages.
Shared Initialize for rdfs:Class
Note that even if you want to add more abstract concept as superclass,
you cannot do it when system knows the MSC concept that is more specific than your indication.
When initialization rewrite direct-superclasses with MSCs of direct-superclasses in
initargs. When reinitialization rewrite direct-superclasses with MSCs of old superclasses
and new superclasses, then, old direct slot definitions are recovered into def-form and
merged with new definition. |
returns MSCs of old-supers and new-supers. |
shared-initialize (class
Class) slot-names &key (direct-superclasses
nil
direct-superclasses-p) |
[method] |
checks C subclassof D and D subclassof C, that implies equality. |
checks C subclassof D and D subclassof C, that implies equality.
Checks the residual mclasses of all instances of class. |
updates mclasses of all instances of class, if mclasses includes shadowed-classes that is unshadowable. |
change-class (instance
Resource) (new-class
cons) &rest initargs |
[method] |
change-class (instance
Resource) (new-class
standard-class) &rest initargs |
[method] |
change-class (instance
Resource) (new-class
Class) &rest initargs |
[method] |
If instance has a slot value and new-class has no slot definitions on it,
then add the slot definitions into new-class. |
change-class (instance
Resource) (new-class
Class) &rest initargs |
[method] |
change-class (instance
Resource) (new-class
Class) &rest initargs |
[method] |
when this flag is true, every statement is reified and strored in system. |
reify subject predicate object |
[function] |
---|
Rdfs Core module
IT Program Project in Japan:
Building Operation-Support System for Large-scale System using IT.
This code is written by Seiji Koide at Galaxy Express Corporation, Japan,
for the realization of the MEXT IT Program in Japan,
Copyright (c) 2002, 2003, 2004, Galaxy Express Corporation
Copyright (c) 2007-2008, Seiji Koide
Top Level Macro and Intermediate Layers out of Three Layers in RDF(S) and OWL Definition
There are three layers for resource definition, i.e.,
(i) top level macro layer,
(ii) intermediate function/method layer, and
(iii) MOP programming layer.
The top level macro layer, which includes three macros, defConcept, defProperty, and defIndividual,
allows users to input RDF(S) and OWL entities in S-expression just in the same feeling as defining classes
or structures in lisp.
The intermediate layer composed of several functions and methods mediates inputs at the top level to the
MOP programming layer.
The MOP programming layer constitutes a bunch of MOP methods that are programmed in order to tailor
the CLOS orignal functionality to RDF(S) and OWL semantics using the Meta-Object Protocol (MOP).
This file includes (i) the top level macro layer and (ii) the intermediate function/method layer.
The MOP programming layer is contained in Rdfs Kernel module.
Some Global Vars
Syntax of Top Level Definition
The syntax of top level macros are as follows.
- defConcept : define a resource class in RDF(S) or OWL.
- defProperty : define a property in RDF(S) or OWL.
- defIndividual : define an individual or instance in RDF(S) or OWL.
<defform> ::= <resource-def> | <property-def> | <individual-def>
<resource-def> ::= (defConcept <resource-name> <slot-form>* )
<property-def> ::= (defProperty <property-name> <slot-form>* )
<individual-def> ::= (defIndvidual <individual-name> <slot-form>* )
<slot-form> ::= (<role> [<lang>] <form> <form>*)
<form> ::= (<typetag> [<name>] [<lang-form>] <slot-form>*)
| (<datatype> <data>) | (<lang> <form>)
| <cl:string> | <cl:number> | <uri>
<lang-form> ::= (xml:lang <lang>)
resource-name, propety-name, individua-name is a symbol that represents QName of resource.
role is a symbol that represents a property QName.
lang is a language tag such as :en or :ja.
typetag is a symbol that represents a resource class QName.
datatype is a symbol that represents a xsd datatype QName.
To direct a class in defining an entity, rdf:type is used in slot-form as same as other slot-forms. For example,
(defIndividual vin::ElyseZinfandel (rdf:type vin::Zinfandel)).
As default, rdf:Property is used for property class in defProperty.
To direct an object property in OWL, rdf:type is used in defProperty as follows.
(defProperty vin::hasColor (rdf:type owl::ObjectProperty))
Note that owl:FunctionalProperty is not a subclass of owl:ObjectProperty, while
owl:InverseFunctionalProperty is a subclass of owl:ObjectProperty. Therefore, it may
be needed to add owl:ObjectProperty with owl:FunctionalProperty as follows.
(defProperty vin::hasMaker
(rdf:type owl:FunctionalProperty owl:ObjectProperty))
(defProperty vin::producesWine
(rdf:type owl:InverseFunctionalProperty)
(owl:inverseOf vin::hasMaker))
defines a class in OWL or a resource class in RDF(S).
This macro sets the class object to the symbol name
and returns the class object. |
defines a class in OWL or a resource class in RDF(S).
This macro sets the class object to the symbol name
and returns the class object. |
defines an instance of rdf:Property.
This macro sets a property object to the symbol name and
returns the property object. |
defines an individual of owl:Resource
with name and slots. This macro sets the individual object to
the symbol name and the object. |
This function lazily addForm when it is forced.
delay must be explicitly called with force function. |
Defining Form in S-expression for RDF Entity
The defining macro at the top level mentioned above internally produces the code for input form
in S-expression and calls function addForm with it.
Reading RDF/XML file also makes a sequence of input forms in S-expression (See addRdfXml and Description-form),
and such input form is processed by addForm.
Input form in S-expression has recursive structures. The BNF syntax for defining an RDF resource in S-expression is as follows.
<form> ::= <cl:string> | <cl:number> | <uri>
| (<lang> <form>)
| (<^^> <data>)
| (<typetag> [<lang-form>] <slot-form>*)
<slot-form> ::= <about-form> | <id-form> | <nodeID-form> | <name-form> | <prop-form>
<about-form> ::= (rdf:about <uri>)
<id-form> ::= (rdf:ID <name>)
<nodeID-form> ::= (rdf:nodeID <name>)
<name-form> ::= (:name <name>)
<lang-form> ::= (xml:lang <lang>)
<prop-form> ::= (<role> [<lang>] <form> <form>*)
<data> ::= <cl:number> | <cl:string>
Here,
- typetag is a class name in symbol or a symbol 'rdf:Description'.
- role is a property name in symbol. Note that this name turns out a name of Property-direct-slot-definition object.
- datatype is a QName symbol or URI or URI string for datatype.
- data is a lisp string or lisp number, but its interpretation must be coinside with designated xsd type definition.
- uri is a uri or uri-string or QName symbol.
- cl:string is a lisp string.
- cl:number is a lisp number.
- lang is a keyword that denotes langugage, e.g., :en, :ja. See lang?
addForm
In lisp, addForm accepts any defining form that defines an entity or a fragment of entity described above
and returns the denotation of the form. Namely,
- If a form is a number in lisp, then it is returned.
- If a form is a string in lisp, then it is read and interpreted as one of RDF datatype
(when role is supplied and the range constraint is effective), or plane literal without language option
or with language option (when some lang is set up in the environment). See read-data.
- If a form is a URI, then if role suggensts URI such as rdf:about or "imports" it is returned,
else its QName is obtained and recurses with the QName.
- If a form is a symbol, then it must be a QName and the denoted object is returned if exists,
else the denoted object is newly created at the minimal constraint from role range or rdfs4b rule.
See make-object-with-minimal-contraint.
- If a form is (lang form), then the form is addFormed in lang environment.
- If a form is (datatype data), then the typed data is created and returned.
- Otherwise the form denotes a complex entity, then each subforms are evaluated through form2slot
and the form replaced with results is computed by %addForm.
addForm form &optional role |
[function] |
---|
form is a form described above, and role is nil in calling at top level
but a role for form as filler in recursive call. |
accepts a slot-form and evaluates the filler using addForm and returns a slot, namely it makes a filler object
or data, and returnes a list of role and filler.
when a slot-form is a non-nil symbol, it should be a name of resource
and a name slot is created and returned. |
This function returns a resource entity (object) of which class is
suggested by range constraint of role or several entailment rules. |
returns an obj that satisfies constraints by role. |
This function collects fillers in several slots on an identical role and makes them in one slot. |
returns range constraint of role if exists, otherwise returns nil. In case that
role is rdf:List, this function returns an appropriate class for the element of list.
See also get-range-constraint-from in OWL module. |
%addForm for RDF
%addForm is a set of methods that are dedicated to each type of RDF entity.
These methods are called with instantiated slots and returns an instance object of type.
Calling sequence: %addForm (type slots role)
- slots - aggregated slots such as ((role1 filler11 filler12 ...) (role2 filler21 filler22 ...) ...),
where every role-n is a symbol and every filler-n is a designated value object.
- role - a role symbol that plays the rage constraint for (role form).
- type - a type of entity to be made.
Main purpose of these methods as a whole is to decide the type of object before the object creation.
In most of cases, the most specific concept (MSC) among domain constraints from roles that are included in slots,
a range constraint of pair role in slot of upper nests, and rdf:type filler in slots is computed and used.
If any roles in slots are not defined, they are tentatively defined as instance of rdf:Property. In case that,
- %addForm((eql 'rdf:Description)) - If MSC from constraints exists it is used, otherwise the value of
*top*(=rdfs:Resource) is type.
- %addForm((eql rdfs:Class)) - If MSC is more special than rdfs:Class,
it is used otherwise rdfs:Class is used for type.
- %addForm((eql owl:Class)) - If MSC is more special than owl:Class,
it is used otherwise owl:Class is used for type.
- %addForm((eql rdfs:Resource)) - If MSC is more special than rdfs:Resource,
it is used otherwise rdfs:Resource is used for type.
- %addForm((eql owl:Thing)) - If MSC exists, it is used, else owl:Thing is used for type.
- %addForm((eql owl:Restriction) t t) - MSC is used for type. Note that more special
restrictions than owl:Restriction are computed from role domain constraints. For exmaple,
owl:allValuesFrom's domain is set to owl:allValuedFromRestriction.
- %addForm(rdfsClass) - Error. Never happen because %addForm((eql rdfs:Class)) supersedes this.
- %addForm(rdfs:Class) - Indicated type is used.
- %addForm(rdfs:Resource) - An instance is indicated for type. After changing it to a class,
it or MSC is used.
- %addForm(symbol) - If the type is already defined, recurse with the symbol value.
Otherwise it is defined by metaclass that is computed from the MSC.
In short, if a more special class than rdfs:Class is indicated for type, it is used
whether or not more special MSC exists. Otherwise, MSC is computed and it is used.
See the following example. Here Species and EndangeredSpecies are defined as metaclass.
(addForm
'(rdfs:Class Species
(rdfs:subClassOf rdfs:Class) ; this makes Species a metaclass
(rdfs:comment "This example is for the demonstration of addForm.")))
(addForm
'(rdfs:Class EndangeredSpecies
(rdfs:subClassOf Species))) ; a subclass of metaclass is a metaclass
(addForm
'(rdf:Property estimatedPopulation
(rdfs:domain EndangeredSpecies)
(rdfs:range xsd:nonNegativeInteger)))
(addForm
'(rdfs:Class Hawk
(estimatedPopulation 2000))) ; MSC is computed as EndangeredSpecies
(addForm '(Hawk Harry))
subfunction for %addForm. To be here, type must be fixed.
This function creates an object with type and slots using addObject. |
This function is called at top level of input form and accumulate the name of entity
as defined name into *defined-resources*. |
addObject
addObjects are a set of methods of which main purpose is to distinguish creating a class or
creating an instance, and additionally recognize an instance of OneOf. See also addObject in OWL module.
- addObject(rdfs:Class) - main routine
- addObject(rdfsClass) - accepts only rdfs:Class, the body is same as the main routine above.
- addObject:around(rdfs:Class) - for OneOf processing, see OneOf module
- addObject:around(rdfsClass) - same as addObject:around(rdfs:Class)
- addObject:before(rdfs:Class) - for container membership property
Note that if there is no information on type or superclasses of an object, due to the forward reference,
the object is created as instance even though it is changed to a class later when the regular expression
are stated.
type is a class or a meta-class except rdfs:Class. Every slot-filler is already objectized if it is an resource object.
This method sets up QName's package in uri-namedspace from name in slot-forms, then calls ensure-meta-absts
to fix the meta class and abst classes for this object. Finally, calls addClass if the meta class or abst exists, else
calls addInstance. If optional domains is not supplied, the domain constrant is computed and it is used for ensuring
the metaclass and abst classes. To suppress domain computing, supply nil. |
Ensuring Meta Classes and Abst(Super) Classes
picks up metaclasses and superclasses from slot-forms. If rdf:type slot is included in slot-forms,
the range constraint supplies meta class(es). If rdfs:subClassOf slot is included, the range constraint
supplies superclasses (absts). |
class must be an instance. |
class must be a class or metaclass. |
addClass
Principles in multiple typing
- The association between a type and slots attached to it should be given by user, except the case that a slot states its domain.
- Even if slots is defined in multiple classes that relates in super/sub class relation, system does not care of the redundancy of slots.
storage where all subjects defined are stored |
addClass classes class absts &optional islots |
[function] |
---|
create a class of metaclass classes with class, absts, and islots.
Each of classes must be an object. An element of islots is '(role . fillers)'.
Note that islots are not slot definition for class but slots for this class.
absts are already entailed and objectized. There is no undefined property in slots.
Slot definitions for islots are automatically defined by system, if
not defined yet. This function can process multiple different typing for existing objects.
If any element in classes is a class but not a mete class, it is changed to a meta class.
This function stores the result object into *subjects-defined*. |
addInstance
addInstance classes instance &optional slots |
[function] |
---|
creates a new instance or redefines the instance with instance and slots.
instance must be a symbol, a URI, or resource object.
Each of classes must be defined and classes must be MSCs.
An element of slots is '(role . fillers)'.
In new creation, the car of classes is used for class of this instance. If there are multiple classes,
a shadow class for classes is made based the car of classes. In redefinition,
* if the old instance belongs to everyone in classes, reinitialize-instance method is invoked.
* if a single new class is indicated, change-class is invoked.
* if every new class is a subclass of some of old classes, then change-class is invoked, and shadowes for multiple classes.
* otherwise, the MSCs are computed and change-class and shadowing are done.
This function stores the result object into *subjects-defined*. |
Make Instance
checks properties in initargs and adds the new slot definitions to class.
Note that initargs are for an instance of class, not for class. |
returns a list of domains for class. |
This method accepts any class and metaclass including rdfs:Class.
Before calling the primary method, ensure slot definitions for this class for initargs.
Domain constraints are also taken care, and make a shadow class if multiple classes indicated. |
Reinitialize Instance
After ensuring that every slot is effectively defined at the class of instance,
if new type option derived from domain constraints are special than the old class,
change-class is invoked before primary method of reinitialize-instance. |
read str as type and returns an instance of type. |
reads str with language option in RDF, and returns an instance of rdf:inLang. See also, lang-env. |
Slots := (role . forms) | (role filler)
Containers in RDF
See, RDFboot module.
Rdfs12
If uuu rdf:type rdfs:ContainerMembershipProperty,
then, uuu rdfs:subPropertyOf rdfs:member.
shared-initialize (instance
ContainerMembershipProperty) slot-names &rest initargs |
[method] |
adds rdfs:member info into instance according to rdfs12 rule. |
Automatated ContainerMembershipProperty Creation
If x rdf:type rdfs:Container and x p vvv,
then p rdf:type rdfs:ContainerMembershipProperty,
and p rdfs:subPropertyOf rdfs:member.
From Schank's M-SEQUENCE in Memory Organization Package (MOP)
returns an instance of rdf:Seq with members from l. The first element of
l fills the first role rdf:_1, the second fills the second role rdf:_2, and so on.
If l is empty, rdf:nil is returned. |
returns an instance of rdf:Seq with members from l. The first element of
l fills the first role rdf:_1, the second fills the second role rdf:_2, and so on.
If l is empty, rdf:nil is returned. |
returns an instance of rdf:Seq with members from l. The first element of
l fills the first role rdf:_1, the second fills the second role rdf:_2, and so on.
If l is empty, rdf:nil is returned. |
book-keeping for reification seiji |
Seiji Koide Aug-04-2009
GXUtils module
IT Program Project in Japan:
Building Operation-Support System for Large-scale System using IT
Copyright (c) 2002, 2003 by Galaxy Express Corporation
Copyright (c) 2008 Seiji Koide
All Entities
Every resource URI in SWCLOS is interned into the default uri space. Note that this default
uri space is independent from Named Spaces for prefix (package) and local name (env) for QName.
prints out all entities as uri to stream. This function does not print blank nodes. |
invokes fun for all entities as uri. fun should be one parameter funcallable object. |
collects all entities as uri, and returs it. Here, entity means ontologies
designated by owl:Ontology+rdf:about and entities in ontologies. |
All NamedSpace
returns an association list of prefix name (package name) and uri on all ones in the system. |
invokes fun for all namedspaces. fun should be one parameter funcallable object. |
These methods return all entities in namespace, namely all external symbol in namespace package.
Note that it is not cared that symbols are bound to resource objects or not. |
When namespace is a string, recursively called with a uri of namespace. |
When namespace is a uri, the related package is retrieved of namespace, then recursively called with the package. |
When namespace is a non-nil symbol, recursively called with a package of namespace. |
When namespace is a package, every external symbol in namespace is collected,
and it is returned as a list of symbol (when uri? is false) or uri (when uri? is true). |
get-slots obj
returns a slot list of obj. Note that nil is returned if obj
is not a resource. |
mop-specs mop
returns a list of direct specials of mop. |
tree->list mop function mop-list
returns a list starting with mop, followed by the elements of
the list returned by calling function with mop and mop-list
updated to include mop. If mop is already in mop-list, just
a list with mop is returned. |
dah mop
prints all the specalizations under mop. The name is short for
'display abstraction hierarchy' |
SPECS->LIST mop mop-list
returns a list starting with mop, followed by the specialization
tree under each specializations of mop. |
path-filler mop path
returns the filler for path in mop. A path is a list of roles, and
path-filler follows that list in order, using get-filler. A role is a
property object. |
-> mop &rest roles |
[function] |
---|
-> mop role1 role2 ...
returns the filler found by tracing role1 role2 ... from the mop.
In other words, inherited filler of mop and role1 is used in next
filler-retlieving with role2, and the result is used in next ..., and so
on. mop is a mop object or a slot-list. |
setf value mop &rest roles |
[function] |
---|
lists all properties. If calling with parameter t, it forces to output
properties including system predefined properties. Otherwise only user
properties. |
collect all properties under prop that have subject as domain. |
collect all properties under prop that have object as range. |
DIG interface
returns all named concept names in ns.
If ns is neither a uri-namedspace uri nor string nor package
nor package name symbol, then returns nil. |
returns all role names in ns.
If ns is neither a uri-namedspace uri nor string nor package
nor package name symbol, then returns nil. |
returns all individuals or instances in ns.
If ns is neither a uri-namedspace uri nor string nor package
nor package name symbol, then returns nil. |
gets all values with sameAs definition. See rdfp11. |
put-value (object
Class) (role
(eql
type)) value |
[method] |
put-value (object
Class) (role
(eql
subClassOf)) value |
[method] |
put-value (object
Resource) (role
(eql
type)) value |
[method] |
put-value (object
Resource) (role
(eql
subClassOf)) value |
[method] |
put-value (object
Resource) (role
Property) value |
[method] |
put-value (object
Resource) (role
symbol) value |
[method] |
Utilities for RDF Semantics
Replace fn-name's global definition with a memoized version. |
Return a memo-function of fn. |
Replace fn-name's global definition with a memoized version with arity 2. |
Return a memo-function of fn with arity 2. |
Seiji Koide Aug-04-2009
RDFWriter module
IT Program Project in Japan:
Building Operation-Support System for Large-scale System using IT.
This code is written by Seiji Koide at Galaxy Express Corporation, Japan,
for the realization of the MEXT IT Program in Japan,
Copyright 2004 by Galaxy Express Corporation
Copyright (c) 2008 Seiji Koide
RDF Writer
prints each element as resource |
prints TYPE rdf:about='uri' |
prints ROLE rdf:datatype='type' value/ROLE |
prints ROLE rdf:resource='uri' / |
asks an common lisp file to user. |
S2RDF instream outstream |
[function] |
---|
returns instance slots with slot form (role filler1 ...) |