Hi Steve,

SPINMap has been designed to help people without a deep understanding of SPIN or SPARQL to build mappings. It covers the most frequently needed use cases, and provides a syntax that is suitable for graphical editing. Like every such language with a simplified scope, the expressivity has been intentionally cut down and not every possible use case of SPIN and SPARQL is covered by SPINMap. You can now guess that my answer is that you may need to bypass the SPINMap syntax for more complex cases like the one that you describe - mapping one rdf:List with multiple target values.

Fortunately, SPINMap is just an application of SPIN templates, and SPIN templates can be executed with the same engine as any other SPIN rules. This means that you can mix SPINMap with conventional "hand-coded" SPIN rules.

On 7/20/2014 10:43, Steve Ray (CMU) wrote:

I have what I think must be a common problem:

Assume I have a source class with property A, and its value is a list of strings.

I want to map this to a destination class with multiple instances of property B, each derived from one of the strings in the list.

My problem is that SPINMap can only call functions, and a function can only return a single value. To my knowledge, you cannot do something tricky with magic properties in a SPINMap mapping, right? So defining my own function doesn't help.

The only workaround I can think of is to just map it over using spinmap:equals, and then write a SPIN rule for the destination class that goes in and uses a pattern like

?list (rdf:rest)*/rdf:first ?item.

...to assert the individual items. This isn't very elegant, and in fact I'm having trouble having the rule clean up after itself and deleting the unwanted list without throwing itself into an infinite loop, so I'm hoping I'm just unaware of some obvious approach to this.

(For what it's worth, my SPIN rule that ran on forever was the following)

# Convert lists of keywords to individual instances of keywords

*DELETE*{

*?this* or:hasKeyword ?listOrItem.

}

*INSERT*{

*?this* or:hasKeyword ?item.

}

*WHERE*{

*?this* or:hasKeyword ?listOrItem.

*FILTER* (!spl:instanceOf(?listOrItem, xsd:string)) .

?listOrItem (rdf:rest)*/rdf:first ?item.

}

What I'd really like is help with my initial problem, but if there's no solution within SPINMap, then I guess I need help with my workaround.


The normal application area of SPINMap is to create new triples (in the target ontology) out of existing triples (in the source ontology). SPINMap for sure has not been designed to delete any triples - it just adds new triples. In your code above, the DELETE may delete the root of your rdfList, but not the intermediate blank nodes that constitute the rdf:List internally. So you would end up with orphan nodes. I do not see why it would run into an infinite loop though.

Sorry I don't have time to work out a complete solution for you right now, maybe tomorrow (or someone else may help out).

Holger

--
-- You received this message because you are subscribed to the Google
Group "TopBraid Suite Users", the topics of which include Enterprise Vocabulary 
Network (EVN), TopBraid Composer, TopBraid Live, TopBraid Insight, SPARQLMotion, SPARQL 
Web Pages and SPIN.
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-users?hl=en
--- You received this message because you are subscribed to the Google Groups "TopBraid Suite Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to