Interesting, and now I understand the reason for "isRootClass(cls)" being part of the above check.
FWIW, would there be any reason to have a rule without a ?this that's not attached to rdfs:Resource or owl:Thing? Thanks! Jeff On Apr 10, 2:55 pm, Holger Knublauch <[email protected]> wrote: > It is fine to not have a ?this variable in a rule. In fact these are > essential part of SPIN, for "global" rules. Typically you should store > those at a root class (rdfs:Resource or owl:Thing), and the system > will simply run them once, without iterating over ?this bindings. > > Holger > > On Apr 10, 2009, at 12:51 PM, Boeing Jeff wrote: > > > > > > > Ah yes, I'm thinking a little too globally. Since spin:rule's really > > need to have a ?this variable to make sense, perhaps a check could be > > added to the editing form. I can see not using a ?this variable being > > a common error as people learn how to use rules. > > > Thanks! > > Jeff > > > On Apr 10, 12:50 pm, Holger Knublauch <[email protected]> wrote: > >> Hi Jeff, > > >> I think the scenario you describe, to create new instances of the > >> associated class, cannot happen in spin:rules. When spin:rules are > >> executed, the engine automatically prepends a clause such as > > >> WHERE { > >> ?this rdf:type <class> . > >> ... rest of the original WHERE clause > > >> In cases where there are no instances of the class already, then the > >> rdf:type clause will block the rest of the query evaluation. In other > >> words, the variable ?this is assumed to already have a value. > > >> In your example, as you speculate, the rule should be attached to > >> Rectangle, or maybe higher up if you want, but the life cycle of Area > >> depends on Rectangle. > > >> In some cases, spin:constructors can be used to achieve similar > >> things > >> as you describe. Constructors automatically fire whenever a new > >> instance of a class has been created (e.g. as a result of another > >> rule). This means that you could use a constructor to initialize the > >> Area object when it's created by the Rectangle. However, this > >> approach > >> would not update the Area when width and height change. > > >> Regards, > >> Holger > > >> On Apr 10, 2009, at 10:38 AM, Schmitz, Jeffrey A wrote: > > >>> Thanks Holger, > >>> I have another bit of feedback for your consideration. In the > >>> SpinInferences.runQueryOnClass function, there is the following > >>> check > >>> that is performed before the query is executed on the query model: > > >>> if(isRootClass(cls) || queryModel.contains(null, > >>> RDF.type, cls)) { > > >>> By doing this, spin:rules attached to a class are only executed if > >>> instances of that class already exist in the model being queried > >>> (which > >>> may or may not be the source model actually). At first blush this > >>> may > >>> seem an obvious thing to do, but it does mean spin:rules can't be > >>> used > >>> to construct new instances of the class to which they are attached. > >>> For > >>> a (somewhat contrived) example that shows where this might be a > >>> problem, > >>> in the spinsquare ontology if the area had been modeled as a class > >>> of > >>> its own (say RectArea) and you wanted to attach the spin rule to the > >>> RectArea class, the rule wouldn't fire. Of course for this example > >>> you > >>> could get around it by attaching the spin:rule to the Rectangle > >>> class, > >>> but that's forcing a bit of a design decision on the implementer > >>> (maybe > >>> that's a good thing?). In short, with the check some flexibility is > >>> given up for the sake of what I think is an optimization, or perhaps > >>> you > >>> want to limit spin:rule's in this way? > > >>> Anyway, just something to think about. > > >>> Thanks, > >>> Jeff > > >>> -----Original Message----- > >>> From: Holger Knublauch [mailto:[email protected]] > >>> Sent: Thursday, April 09, 2009 1:34 PM > >>> To: [email protected] > >>> Subject: [tbc-users] Re: SPIN API suggestion > > >>> Hi Jeff, > > >>> thanks for your feedback. Your suggestion makes very much sense, > >>> and I > >>> have added another run method as you propose to the next release. > >>> Your > >>> use case sounds familiar, and we often discover similar patterns in > >>> which finer control over the order of inferences is needed. If these > >>> patterns become better understood we may add new properties to the > >>> SPIN > >>> namespace to allow for distinguishing between transforms and other > >>> rule > >>> types. > > >>> Please feel free to continue to post SPIN API related questions > >>> here. > >>> Ideally put something like [SPIN API] into the subject line so that > >>> people not interested in this topic can skip it. We may set up a > >>> separate mailing list at some point in time if more people start > >>> using > >>> it. > > >>> Holger > > >>> On Apr 9, 2009, at 9:45 AM, Schmitz, Jeffrey A wrote: > > >>>> Hello, > > >>>> Thought I'd give a quick suggestion for the SPIN API. The > >>>> spin:rule > >>>> based inferencing is a very powerful way to assign inference > >>>> rules to > >>>> classes in an object oriented way. However, as currently > >>>> implemented > >>>> it's pretty much an all or nothing way to create and add inferred > >>>> triples to a single model. This is because spin:rule is > >>>> hardcoded in > >>>> the SPINInferences.run function and at runtime all of a class's > >>>> specified spin:rule's (or subproperties thereof) are exectued en- > >>>> mass, > > >>>> with all inferred triples added to the single 'newTriples' model: > > >>>> public static int run( > >>>> Model queryModel, > >>>> Model newTriples, > >>>> SPINExplanations explanations, > >>>> List<SPINStatistics> statistics, > >>>> boolean singlePass, > >>>> ProgressMonitor monitor) { > >>>> Map<QueryWrapper, Map<String,RDFNode>> > >>> initialTemplateBindings = new > >>>> HashMap<QueryWrapper, Map<String,RDFNode>>(); > >>>> Map<Resource,List<QueryWrapper>> cls2Query = > >>>> SPINQueryFinder.getClass2QueryMap(queryModel, queryModel, > >>>> SPIN.rule, > >>>> true, initialTemplateBindings, false); > >>>> return run(queryModel, newTriples, cls2Query, > >>>> initialTemplateBindings, explanations, statistics, singlePass, > >>>> monitor); > >>>> } > > >>>> To make this powerful capability more flexible, what I've done is > >>>> re-create the run function with the rule predicate being > >>>> parameterized. > > >>>> public int runSPINInferences( > >>>> Model queryModel, > >>>> Model newTriples, > >>>> Property rulePredicate , > >>>> SPINExplanations explanations, > >>>> List<SPINStatistics> statistics, > >>>> boolean singlePass, > >>>> ProgressMonitor monitor) { > >>>> Map<QueryWrapper, Map<String,RDFNode>> > >>> initialTemplateBindings = new > >>>> HashMap<QueryWrapper, Map<String,RDFNode>>(); > >>>> Map<Resource,List<QueryWrapper>> cls2Query = > >>>> SPINQueryFinder.getClass2QueryMap(queryModel, queryModel, > >>>> rulePredicate, true, initialTemplateBindings, false); > >>>> return SPINInferences.run(queryModel, newTriples, > >>> cls2Query, > >>>> initialTemplateBindings, explanations, statistics, singlePass, > >>>> monitor); > >>>> } > > >>>> This way I can create sibling subproperties of spin:rule, and in my > >>>> SPARQL engine I can pick and choose exactly which rules get run > >>>> based > >>>> on the current state/progress of the engine, as well as specify the > >>>> model to be updated with the "inferred" triples based on the type > >>>> of > >>>> rule being executed. For example, I've setup two subproperties of > >>>> spin:rule > > >>>> SpinLib:inferenceRule > >>>> SpinLib:transformRule > > >>>> Our SPARQL engine first runs all the SpinLib:inferenceRule's, which > >>>> adds all the triples back into the source model: > > >>>> runSPINInferences(baseModel, baseModel, inferenceRule, exp, null, > >>>> true, null); > > >>>> These are for rules like calculating the area of a rectangle > >>>> based on > >>>> height and width. > > >>>> After these new triples are created, the engine then runs transform > >>>> rules on the source model. > > >>>> runSPINInferences(baseModel, destModel, transformRule, exp, null, > >>>> true, null); > > >>>> For these transforms the triples are added to the model being > >>>> transformed into destModel), and not back into the source model. > > >>>> Anyway, it was a very simple change for me to make locally, but > >>>> thought perhaps allowing this flexibility might be something you > >>>> might > > >>>> want to consider adding directly to the API (and/or perhaps more > >>>> importantly documenting the capability/pattern). Perhaps some > >>>> typical > > >>>> subproperties could even be added to the spin model. I would think > >>>> model transforms such as we're using would be a very useful and > >>>> general type of inference that people could use. Also seems like > >>>> something that might be able to be combined with SPARQLMotion in > >>>> some > >>>> way to allow transforms to be a little more object-oriented (e.g. > >>>> the > >>>> classes transform themselves). > > >>>> Btw, is this the proper forum for SPIN API questions/comments? > > >>>> Thanks, > >>>> Jeff --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "TopBraid Composer Users" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/topbraid-composer-users?hl=en -~----------~----~----~----~------~----~------~--~---
