rhdunn / cainteoir-engine

The Cainteoir Text-to-Speech core engine
http://reecedunn.co.uk/cainteoir/
GNU General Public License v3.0
43 stars 8 forks source link

implement RDF(S) entailment #2

Open rhdunn opened 13 years ago

rhdunn commented 13 years ago

RDF(S) entailment is about inferring different properties of an RDF graph. For example, given:

A rdfs:subClassOf B .
B rdfs:subClassOf C .

it is possible to infer the triple:

A rdfs:subClassOf C .

This is useful for metadata queries, such as looking for the title of the document (is it a dc:title or dct:title property). With the RDF(S) entailment rules applied, one query can be made since entailment will add the missing relationships.

Care needs to be made to keep the schema, document metadata and entailed triples separable (e.g. for conserving disk space when saving metadata in a document library).

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/1026799-implement-rdf-s-entailment?utm_campaign=plugin&utm_content=tracker%2F254961&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F254961&utm_medium=issues&utm_source=github).
rhdunn commented 12 years ago

RDF Query API

select (s, _, _)    ==> all statements for a subject
select (s, p, _)    ==> all statements for a subject matching a predicate
select (_, p, _)    ==> all statements matching a predicate
select (_, p, o)    ==> all statements matching a predicate with value of object

str(r) = r.value    if r a literal
str(r) = r      if r a uri

subject(t)   : uri      ==> subject of the triple
predicate(t) : uri      ==> predicate of the triple
object(t)    : uri or literal   ==> object of the triple
value(t)     : string       ==> value of the triple

value(t) = str(object(t) as literal)            if object(t) a literal
value(t) = value(select(object(t), rdf:value, _))   if object(t) a uri

Infer Transitive Relationships On Schema Types

|a.s p.s a.o| && |b.s p.s b.o| && |p.s rdf:type owl:TransitiveProperty| ==> |a.s p.s b.o|

g.add(rdf:subClassOf,    rdf:type, owl:TransitiveProperty);
g.add(rdf:subPropertyOf, rdf:type, owl:TransitiveProperty);

for t in g.select(_, rdf:type, owl:TransitiveProperty) {
    for a in g.select(_, t.s, _) {
        if (a.s != a.o) {
            for b in g.select(a.o, t.s, _) {
                g.add(a.s, t.s, b.o);
            }
        }
    }
}

Infer Type Information From Domain And Range

|p.s rdf:domain p.o| && |a.s p.s a.o| ==> |a.s rdf:type p.o|

for p in g.select(_, rdf:domain, _) {
    for a in g.select(_, p.subject, _) {
        g.add(a.subject, rdf:type, p.object);
    }
}

|p.s rdf:range p.o| && |a.s p.s a.o| ==> |a.o rdf:type p.o|

for p in g.select(_, rdf:range, _) {
    for a in g.select(_, p.subject, _) {
        g.add(a.object, rdf:type, p.object);
    }
}

Infer Type Information From Sub-Types

|a.s rdf:type a.o| && |b.s rdf:subClassOf b.o| ==> |a.s rdf:type b.o|

for a in g.select(_, rdf:type, _) {
    for b in g.select(a.object, rdf:subClassOf, _) {
        g.add(a.subject, rdf:type, b.object);
    }
}

Infer Properties From Sub-Properties

|a.s p.s a.o| && |p.s rdf:subPropertyOf p.o| ==> |a.s p.o a.o|

for p in g.select(_, rdf:subPropertyOf, _) {
    for a in g.select(_, p.s, _) {
        g.add(a.s, p.o, a.o);
    }
}