Model result = sourceModel.find( null, new Resource("...#mypredicate"), null )
finds all triples having predicate "...#mypredicate". If the triples were stored in a relational database DB(subject, predicate, object) the above statement would map onto the following SQL statement:
SELECT triple FROM sourceModel WHERE predicate = "...#mypredicate"
Imagine that we have a schema model tomModel
Subject | Predicate | Object |
Tom | RDF.type | Cat |
Tom | furColor | "Hazel" |
and the following corresponding schema information:
Subject | Predicate | Object |
Cat | RDFS.subClassOf | Animal |
furColor | RDFS.subPropertyOf | animalFeature |
Than, the "query"
(1) Model result = tomModel.find( null, RDF.type, Animal )
would deliver the result:
Subject | Predicate | Object |
Tom | RDF.type | Cat |
and the "query"
(2) Model result = tomModel.find( null, animalFeature, null )
would deliver the result:
Subject | Predicate | Object |
Tom | furColor | "Hazel" |
Note that we try to deliver tuples that are already present in the original model rather than create new tuples where possible. However, there are cases where new tuples have to be created in the result model. Consider the following query:
(3) Model result = tomModel.find( Tom, RDF.type, null )
The response would be
Subject | Predicate | Object |
Tom | RDF.type | Cat |
Tom | RDF.type | Animal |
We tried to defined the semantics of the find operation using the intended interpretation, i.e. the one that seems the most appropriate and natural. However, the SchemaModel that we use is only one possible realization. Thus, for example, an alternative implementation would require to return all statements that are can be derived from a given model and schema.
Further "intended" behavior includes retrieving all the resources used in the model:
(4) Model result = tomModel.find( null, RDF.type, RDFS.Resource )
delivers:
Subject | Predicate | Object |
Tom | RDF.type | RDFS.Resource |
Cat | RDF.type | RDFS.Resource |
Note that the literal "Hazel" is not a resource and therefore is not included in the result model. In the above example we decided not to reuse existing triples for simplicity.
foreach triple in model {
if triple.predicate == RDF.type
/* check whether triple.object is an RDFS.Class
*/
if triple.predicate is a RDFS.ContainerMembershipProperty
/* check whether triple.subject is an RDFS.Container
--- [RDFSchema] specs seems not to require it */
foreach d in validDomains(triple.predicate)
/* check whether triple.subject is RDF.type
of one such d */
if validRange(triple.predicate) != null
// there can be only single range specification
/* check whether triple.object is RDF.type of
validRange(triple.predicate) */
}
Our implementation loads both RDF Model/Syntax and RDF Schema vocabulary and uses in for schema access and validation. However, there are still some special cases left which had to be dealt with extra, i.e. RDFS.Literal as domain or range specification.
Currently, unsupported constraints are ignored.
Both RDF Model/Syntax and RDF Schema can be successfully validated with our implementation.
This approach requires SchemaModel to work very closely with the SchemaRegistry where the schema information is stored. Therefore, our default implementation of SchemaModel is based on the default implementation of SchemaRegistry (i.e. one of them cannot be replaced independently).
We propose that "intelligent models" are constructed as wrappers of "dumb" models. For example, the default implementation wraps a dumb model as follows:
SchemaModel sm = new SchemaModelImpl( registry, dumbModel );