kasei / perlrdf

Deprecated in favor of the Attean package
26 stars 25 forks source link

Statement iterators from binding iterators #104

Closed kjetilk closed 10 years ago

kjetilk commented 10 years ago

So, I needed to add the result of a get_pattern query to a model, and I looked into implementing it, but I found there were TIMTOWDI, and I was unsure which one, and I rewrote my code so that I wouldn't need it, but I still think it is an interesting use case, so I figured I'd submit an issue instead.

The main idea is that if you have a bindings iterator, it could be transformed into a statement iterator if you have a Pattern object that describes the bindings. First, I looked into doing it in Model->add_iterator, but then, I found there's a as_statements method to the bindings iterator, which seems to rely on the order of the bindings, so that the subject has to be first, etc. Right?

Would this be the right place to implement this?

Kjetil

kasei commented 10 years ago

Yes, as_statements assumes that the iterator is going to produce the triple/quad nodes in order, so it's not a general solution here.(Correction: see comment below)

It sounds like you want an API version of SPARQL's INSERT WHERE feature. This reveals a place in the code where we've got multiple places to represent patterns, as you're using a Pattern object, and the implementation for INSERT WHERE (in RDF::Query::Plan::Update) uses a RDF::Query::Algebra::GroupGraphPattern object.

Would you prefer a new method to combine a pattern with a bindings iterator to produce a statement iterator? Something like $pattern->populate( $bindings_iter )?

kjetilk commented 10 years ago

Yeah, I suppose you could say it would be an API version of INSERT WHERE.

I don't have any strong opinions on how it should look. Actually, I was thinking it could be implemented in as_statements, where it could optionally take a RDF::Trine::Pattern (and internally, it could hold a pattern that is the current behavior). Your suggestion would be nice too, though I think I would first look for such a feature in the iterators.

kasei commented 10 years ago

FYI, I think I mis-spoke above. ::Iterator::Bindings->as_statements doesn't depend on the order or the binding variables. You pass in the order you want and it pulls them out of each result in that order. For example, if you had an iterator that was returning bindings with variables x, y, and z, you could call $iter->as_statements(qw(z y x)) to get a triples iterator back for triples { ?z ?y ?x }. Sorry about the confusion.

kasei commented 10 years ago

Hmmm... yeah, it's tricky to know where to put a method when it really belongs to both (or defined as multi-dispatch). Are you suggesting that the bindings iterator would keep a pattern object as an instance variable after being passed in to as_statements? I would think that sort of state would be confusing. And not sure what the API would look like, as as_statements already accepts a list of binding names as arguments. Any explicit API suggestions for what you think would be intuitive?

kjetilk commented 10 years ago

OK, I get the current API. I can see that the state will be confusing, since it has to loop the BGP, since the iterator would have to bring along the pattern internally, but I think an API that is simply

$iter->as_statements( @names | $pattern);

would be pretty intuitive.