On Tue, 2011-11-15 at 22:52 -0800, Joel Shellman wrote: > Let's say I'm trying to model a type/field system like this: > Type1 hasField field11 // and field12, field13, etc. > field11 isType Type2 // and field12, field13, etc. are also some Type# > Type2 hasField field21 // and field22, field23, etc. > etc. > And with a rule I could convert this to a simpler case of just a > single hasChild link > (?a isType ?b) (?a hasField ?c) -> (?a hasChild ?c)
Should that be: (?a isType ?b) (?b hasField ?c) -> (?a hasChild ?c) ? > So, now if I choose a root: > root isType Type1 > > now I have a tree (possibly recursive as that is allowed) with root as the > root. And that graph (a tree with loops is a graph I think) is a graph of fields, right? > So, let me use a concise notation of a/b/c means a hasChild b and b > hasChild c (as above), I need to be able to query a path for things > associated with it which should both return everything that is > attached to c (c ? ?), plus everything that would apply to the a/b/c > path. What's the difference between something "attached to c" and something which "applies to the a/b/c" path? > And I need make such statements not just one path at a time, but path > expressions such as apply things to a/b/** (all descendants of a/b). Is there a difference between "all descendants of a/b" and "all descendants of b"? If a and b represent nodes in your graph then the path by which you get to a node shouldn't matter surely. > Or a/b/**/d (d if it's a descendant of a/b). And maybe more complex. > > There might be many 10,000's of types and fields. And there might be > 1,000's of statements about path expressions. And there might be > 100,000's of paths that would be queried for. And multiply that by > about 10 for all the other information that would be about each node > besides hasField. Don't follow that last statement. You see to have a tree/graph of fields linked by hasChild. So the nodes are fields whereas hasField applies to types. > Is this something that is reasonable to do in Jena/RDF/OWL? If so, I > would appreciate some help both in how to declare such statements > about path expressions (I assume it would use rules somehow which I > did read about reasoners in the doc) and how to query them. It's a little hard to follow the problem description in the abstract, if you have a concrete example that might help. However, broadly I can see three types of approach to this in Jena/RDF/OWL. (1) Use SPARQL property paths. You could materialize your graph as a set of RDF resources linked by ex:hasChild links. When you want to make a statement about a path expression you do this using a SPARQL CONSTRUCT which uses property paths to find all resources matching that path expression and then asserts the statement about each matching resource. This makes your representation easy to inspect, easy to query at the cost of being very redundant. (2) Use OWL reasoning. Model your hasChild links as (inverted) rdfs:subClassOf links. Then, for example, things that should apply to all descendents of B you express as an OWL restriction on the class representing B (e.g. a hasValue restriction). Then to query you construct an individual which is a member of the appropriate combination of classes and let an OWL reasoner work out what properties that individual should have. Since you talk about "property paths" rather then pure hierarchies it may be that you can't express all the sorts of path expressions you need in this way. Hard to tell from the information so far. (3) Use custom reasoning It's possible that you could express your statements about class paths as a set of rules which match the property path and conclude the assertion. The details depend on what sort of assertions you need to make. For forward rules this would materialize the graph of assertions just as option (1) but using rules instead of SPARQL. For backward rules then you would avoid the storage cost of materialization at the cost of query time reasoning costs. One tricky bit of (3) is that Jena rules have no builtin notion of path expression. In particular you would need to explicitly define the descendentOf closure in order to use that in your rules. That might be better done by relying on the builtin transitive reasoner which would mean using the same trick as (2) of using subClassOf to represent your child relationships but now you would have more power than pure OWL restrictions for expressing your property path assertions. Dave
